瀏覽代碼

new scene.createDefaultCameraOrLight() function
SSAO first step

David Catuhe 10 年之前
父節點
當前提交
489a70efa1

文件差異過大導致無法顯示
+ 1 - 1
Babylon/Debug/babylon.debugLayer.js.map


+ 0 - 1
Babylon/Mesh/babylon.abstractMesh.js

@@ -693,7 +693,6 @@ var BABYLON;
                 var world = this.getWorldMatrix();
                 var worldOrigin = BABYLON.Vector3.TransformCoordinates(ray.origin, world);
                 var direction = ray.direction.clone();
-                //  direction.normalize();
                 direction = direction.scale(intersectInfo.distance);
                 var worldDirection = BABYLON.Vector3.TransformNormal(direction, world);
                 var pickedPoint = worldOrigin.add(worldDirection);

+ 0 - 1
Babylon/Mesh/babylon.abstractMesh.ts

@@ -832,7 +832,6 @@
                 var world = this.getWorldMatrix();
                 var worldOrigin = BABYLON.Vector3.TransformCoordinates(ray.origin, world);
                 var direction = ray.direction.clone();
-              //  direction.normalize();
                 direction = direction.scale(intersectInfo.distance);
                 var worldDirection = BABYLON.Vector3.TransformNormal(direction, world);
 

+ 162 - 0
Babylon/PostProcess/babylon.ssaoRenderingPipeline.js

@@ -0,0 +1,162 @@
+var __extends = this.__extends || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    __.prototype = b.prototype;
+    d.prototype = new __();
+};
+var BABYLON;
+(function (BABYLON) {
+    var SSAORenderingPipeline = (function (_super) {
+        __extends(SSAORenderingPipeline, _super);
+        function SSAORenderingPipeline(name, scene, ratio) {
+            var _this = this;
+            if (ratio === void 0) { ratio = 1.0; }
+            _super.call(this, scene.getEngine(), name);
+            // Members
+            this.SSAOOriginalSceneColorEffect = "SSAOOriginalSceneColorEffect";
+            this.SSAORenderEffect = "SSAORenderEffect";
+            this.SSAOBlurHRenderEffect = "SSAOBlurHRenderEffect";
+            this.SSAOBlurVRenderEffect = "SSAOBlurVRenderEffect";
+            this.SSAOCombineRenderEffect = "SSAOCombineRenderEffect";
+            this._scene = null;
+            this._depthTexture = null;
+            this._randomTexture = null;
+            this._originalColorPostProcess = null;
+            this._ssaoPostProcess = null;
+            this._blurHPostProcess = null;
+            this._blurVPostProcess = null;
+            this._ssaoCombinePostProcess = null;
+            this._firstUpdate = true;
+            this._scene = scene;
+            // Set up assets
+            this._createRandomTexture();
+            this._depthTexture = scene.enableDepthRenderer().getDepthMap(); // Force depth renderer "on"
+            this._originalColorPostProcess = new BABYLON.PassPostProcess("SSAOOriginalSceneColor", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false);
+            this._createSSAOPostProcess(ratio);
+            this._blurHPostProcess = new BABYLON.BlurPostProcess("SSAOBlur", new BABYLON.Vector2(1.0, 0.0), 1.0, ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false);
+            this._blurVPostProcess = new BABYLON.BlurPostProcess("SSAOBlur", new BABYLON.Vector2(0.0, 1.0), 1.0, ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false);
+            this._createSSAOCombinePostProcess();
+            // Set up pipeline
+            this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), this.SSAOOriginalSceneColorEffect, function () {
+                return _this._originalColorPostProcess;
+            }, true));
+            this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), this.SSAORenderEffect, function () {
+                return _this._ssaoPostProcess;
+            }, true));
+            this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), this.SSAOBlurHRenderEffect, function () {
+                return _this._blurHPostProcess;
+            }, true));
+            this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), this.SSAOBlurVRenderEffect, function () {
+                return _this._blurVPostProcess;
+            }, true));
+            this.addEffect(new BABYLON.PostProcessRenderEffect(scene.getEngine(), this.SSAOCombineRenderEffect, function () {
+                return _this._ssaoCombinePostProcess;
+            }, true));
+            // Finish
+            scene.postProcessRenderPipelineManager.addPipeline(this);
+        }
+        // Public Methods
+        SSAORenderingPipeline.prototype.getBlurHPostProcess = function () {
+            return this._blurHPostProcess;
+        };
+        SSAORenderingPipeline.prototype.getBlurVPostProcess = function () {
+            return this._blurVPostProcess;
+        };
+        // Private Methods
+        SSAORenderingPipeline.prototype._createSSAOPostProcess = function (ratio) {
+            var _this = this;
+            var sampleSphere = [
+                0.5381,
+                0.1856,
+                -0.4319,
+                0.1379,
+                0.2486,
+                0.4430,
+                0.3371,
+                0.5679,
+                -0.0057,
+                -0.6999,
+                -0.0451,
+                -0.0019,
+                0.0689,
+                -0.1598,
+                -0.8547,
+                0.0560,
+                0.0069,
+                -0.1843,
+                -0.0146,
+                0.1402,
+                0.0762,
+                0.0100,
+                -0.1924,
+                -0.0344,
+                -0.3577,
+                -0.5301,
+                -0.4358,
+                -0.3169,
+                0.1063,
+                0.0158,
+                0.0103,
+                -0.5869,
+                0.0046,
+                -0.0897,
+                -0.4940,
+                0.3287,
+                0.7119,
+                -0.0154,
+                -0.0918,
+                -0.0533,
+                0.0596,
+                -0.5411,
+                0.0352,
+                -0.0631,
+                0.5460,
+                -0.4776,
+                0.2847,
+                -0.0271
+            ];
+            this._ssaoPostProcess = new BABYLON.PostProcess("ssao", "ssao", ["sampleSphere"], ["randomSampler"], ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false);
+            this._ssaoPostProcess.onApply = function (effect) {
+                if (_this._firstUpdate === true) {
+                    effect.setArray3("sampleSphere", sampleSphere);
+                    _this._firstUpdate = false;
+                }
+                effect.setTexture("textureSampler", _this._depthTexture);
+                effect.setTexture("randomSampler", _this._randomTexture);
+            };
+            return this._ssaoPostProcess;
+        };
+        SSAORenderingPipeline.prototype._createSSAOCombinePostProcess = function () {
+            var _this = this;
+            this._ssaoCombinePostProcess = new BABYLON.PostProcess("ssaoCombine", "ssaoCombine", [], ["originalColor"], 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, this._scene.getEngine(), false);
+            this._ssaoCombinePostProcess.onApply = function (effect) {
+                effect.setTextureFromPostProcess("originalColor", _this._originalColorPostProcess);
+            };
+            return this._ssaoCombinePostProcess;
+        };
+        SSAORenderingPipeline.prototype._createRandomTexture = function () {
+            var size = 512;
+            this._randomTexture = new BABYLON.DynamicTexture("SSAORandomTexture", size, this._scene, false, BABYLON.Texture.BILINEAR_SAMPLINGMODE);
+            this._randomTexture.wrapU = BABYLON.Texture.WRAP_ADDRESSMODE;
+            this._randomTexture.wrapV = BABYLON.Texture.WRAP_ADDRESSMODE;
+            var context = this._randomTexture.getContext();
+            var rand = function (min, max) {
+                return Math.random() * (max - min) + min;
+            };
+            for (var x = 0; x < size; x++) {
+                for (var y = 0; y < size; y++) {
+                    var randVector = BABYLON.Vector3.Zero();
+                    randVector.x = Math.floor(rand(0.0, 1.0) * 255);
+                    randVector.y = Math.floor(rand(0.0, 1.0) * 255);
+                    randVector.z = Math.floor(rand(0.0, 1.0) * 255);
+                    context.fillStyle = 'rgb(' + randVector.x + ', ' + randVector.y + ', ' + randVector.z + ')';
+                    context.fillRect(x, y, 1, 1);
+                }
+            }
+            this._randomTexture.update(false);
+        };
+        return SSAORenderingPipeline;
+    })(BABYLON.PostProcessRenderPipeline);
+    BABYLON.SSAORenderingPipeline = SSAORenderingPipeline;
+})(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.ssaoRenderingPipeline.js.map

+ 135 - 0
Babylon/PostProcess/babylon.ssaoRenderingPipeline.ts

@@ -0,0 +1,135 @@
+module BABYLON {
+    export class SSAORenderingPipeline extends PostProcessRenderPipeline {
+        // Members
+        public SSAOOriginalSceneColorEffect: string = "SSAOOriginalSceneColorEffect";
+        public SSAORenderEffect: string = "SSAORenderEffect";
+        public SSAOBlurHRenderEffect: string = "SSAOBlurHRenderEffect";
+        public SSAOBlurVRenderEffect: string = "SSAOBlurVRenderEffect";
+        public SSAOCombineRenderEffect: string = "SSAOCombineRenderEffect";
+
+        private _scene: Scene = null;
+        private _depthTexture: RenderTargetTexture = null;
+        private _randomTexture: DynamicTexture = null;
+
+        private _originalColorPostProcess: PassPostProcess = null;
+        private _ssaoPostProcess: PostProcess = null;
+        private _blurHPostProcess: BlurPostProcess = null;
+        private _blurVPostProcess: BlurPostProcess = null;
+        private _ssaoCombinePostProcess: PostProcess = null;
+
+        private _firstUpdate: boolean = true;
+
+        constructor(name: string, scene: Scene, ratio: number = 1.0) {
+            super(scene.getEngine(), name);
+
+            this._scene = scene;
+
+            // Set up assets
+            this._createRandomTexture();
+            this._depthTexture = scene.enableDepthRenderer().getDepthMap(); // Force depth renderer "on"
+
+            this._originalColorPostProcess = new PassPostProcess("SSAOOriginalSceneColor", 1.0, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false);
+            this._createSSAOPostProcess(ratio);
+            this._blurHPostProcess = new BlurPostProcess("SSAOBlur", new Vector2(1.0, 0.0), 1.0, ratio, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false);
+            this._blurVPostProcess = new BlurPostProcess("SSAOBlur", new Vector2(0.0, 1.0), 1.0, ratio, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false);
+            this._createSSAOCombinePostProcess();
+
+            // Set up pipeline
+            this.addEffect(new PostProcessRenderEffect(scene.getEngine(), this.SSAOOriginalSceneColorEffect, () => { return this._originalColorPostProcess; }, true));
+            this.addEffect(new PostProcessRenderEffect(scene.getEngine(), this.SSAORenderEffect, () => { return this._ssaoPostProcess; }, true));
+            this.addEffect(new PostProcessRenderEffect(scene.getEngine(), this.SSAOBlurHRenderEffect, () => { return this._blurHPostProcess; }, true));
+            this.addEffect(new PostProcessRenderEffect(scene.getEngine(), this.SSAOBlurVRenderEffect, () => { return this._blurVPostProcess; }, true));
+            this.addEffect(new PostProcessRenderEffect(scene.getEngine(), this.SSAOCombineRenderEffect, () => { return this._ssaoCombinePostProcess; }, true));
+            
+            // Finish
+            scene.postProcessRenderPipelineManager.addPipeline(this);
+        }
+
+        // Public Methods
+        public getBlurHPostProcess(): BlurPostProcess {
+            return this._blurHPostProcess;
+        }
+
+        public getBlurVPostProcess(): BlurPostProcess {
+            return this._blurVPostProcess;
+        }
+
+        // Private Methods
+        private _createSSAOPostProcess(ratio: number): PostProcess {
+            var sampleSphere = [
+                0.5381, 0.1856, -0.4319,
+                0.1379, 0.2486, 0.4430,
+                0.3371, 0.5679, -0.0057,
+                -0.6999, -0.0451, -0.0019,
+                0.0689, -0.1598, -0.8547,
+                0.0560, 0.0069, -0.1843,
+                -0.0146, 0.1402, 0.0762,
+                0.0100, -0.1924, -0.0344,
+                -0.3577, -0.5301, -0.4358,
+                -0.3169, 0.1063, 0.0158,
+                0.0103, -0.5869, 0.0046,
+                -0.0897, -0.4940, 0.3287,
+                0.7119, -0.0154, -0.0918,
+                -0.0533, 0.0596, -0.5411,
+                0.0352, -0.0631, 0.5460,
+                -0.4776, 0.2847, -0.0271
+            ];
+
+            this._ssaoPostProcess = new PostProcess("ssao", "ssao", ["sampleSphere"], ["randomSampler"],
+                                                    ratio, null, Texture.BILINEAR_SAMPLINGMODE,
+                                                    this._scene.getEngine(), false);
+
+            this._ssaoPostProcess.onApply = (effect: Effect) => {
+                if (this._firstUpdate === true) {
+                    effect.setArray3("sampleSphere", sampleSphere);
+                    this._firstUpdate = false;
+                }
+
+                effect.setTexture("textureSampler", this._depthTexture);
+                effect.setTexture("randomSampler", this._randomTexture);
+            };
+
+            return this._ssaoPostProcess;
+        }
+
+        private _createSSAOCombinePostProcess(): PostProcess {
+            this._ssaoCombinePostProcess = new PostProcess("ssaoCombine", "ssaoCombine", [], ["originalColor"],
+                                                           1.0, null, Texture.BILINEAR_SAMPLINGMODE,
+                                                           this._scene.getEngine(), false);
+
+            this._ssaoCombinePostProcess.onApply = (effect: Effect) => {
+                effect.setTextureFromPostProcess("originalColor", this._originalColorPostProcess);
+            };
+
+            return this._ssaoCombinePostProcess;
+        }
+
+        private _createRandomTexture(): void {
+            var size = 512;
+
+            this._randomTexture = new BABYLON.DynamicTexture("SSAORandomTexture", size, this._scene, false, BABYLON.Texture.BILINEAR_SAMPLINGMODE);
+            this._randomTexture.wrapU = BABYLON.Texture.WRAP_ADDRESSMODE;
+            this._randomTexture.wrapV = BABYLON.Texture.WRAP_ADDRESSMODE;
+
+            var context = this._randomTexture.getContext();
+
+            var rand = (min, max) => {
+                return Math.random() * (max - min) + min;
+            }
+
+            for (var x = 0; x < size; x++) {
+                for (var y = 0; y < size; y++) {
+                    var randVector = BABYLON.Vector3.Zero();
+
+                    randVector.x = Math.floor(rand(0.0, 1.0) * 255);
+                    randVector.y = Math.floor(rand(0.0, 1.0) * 255);
+                    randVector.z = Math.floor(rand(0.0, 1.0) * 255);
+
+                    context.fillStyle = 'rgb(' + randVector.x + ', ' + randVector.y + ', ' + randVector.z + ')';
+                    context.fillRect(x, y, 1, 1);
+                }
+            }
+            this._randomTexture.update(false);
+        }
+    }
+}

+ 64 - 0
Babylon/Shaders/ssao.fragment.fx

@@ -0,0 +1,64 @@
+#ifdef GL_ES
+precision mediump float;
+#endif
+
+uniform sampler2D textureSampler;
+uniform sampler2D randomSampler;
+
+uniform vec3 sampleSphere[16];
+
+varying vec2 vUV;
+
+vec3 normalFromDepth(float depth, vec2 coords) {
+    const vec2 offset1 = vec2(0.0, 0.001);
+    const vec2 offset2 = vec2(0.001, 0.0);
+
+    float depth1 = texture2D(textureSampler, coords + offset1).r;
+    float depth2 = texture2D(textureSampler, coords + offset2).r;
+
+    vec3 p1 = vec3(offset1, depth1 - depth);
+    vec3 p2 = vec3(offset2, depth2 - depth);
+
+    vec3 normal = cross(p1, p2);
+    normal.z = -normal.z;
+
+    return normalize(normal);
+}
+
+void main(void) {
+
+	const float totalStrength = 1.0;
+	const float base = 0.2;
+	const float area = 0.0075;
+	const float fallOff = 0.000001;
+	const float radius = 0.002;
+
+	vec3 random = normalize(texture2D(randomSampler, vUV * 4.0).rgb);
+	float depth = texture2D(textureSampler, vUV).r;
+
+	vec3 position = vec3(vUV, depth);
+	vec3 normal = normalFromDepth(depth, vUV);
+
+	float radiusDepth = radius / depth;
+	float occlusion = 0.0;
+
+	const int samples = 16;
+	for (int i = 0; i < samples; i++) {
+		vec3 ray = radiusDepth * reflect(sampleSphere[i], random);
+		vec3 hemiRay = position + sign(dot(ray, normal)) * ray;
+
+		float occlusionDepth = texture2D(textureSampler, clamp(hemiRay.xy, 0.0, 1.0)).r;
+		float difference = depth - occlusionDepth;
+
+		occlusion += step(fallOff, difference) * (1.0 - smoothstep(fallOff, area, difference));
+	}
+
+	float ao = 1.0 - totalStrength * occlusion * (1.0 / float(samples));
+
+	float result = clamp(ao + base, 0.0, 1.0);
+	gl_FragColor.r = result;
+	gl_FragColor.g = result;
+	gl_FragColor.b = result;
+	gl_FragColor.a = 1.0;
+
+}

+ 12 - 0
Babylon/Shaders/ssaoCombine.fragment.fx

@@ -0,0 +1,12 @@
+#ifdef GL_ES
+precision mediump float;
+#endif
+
+uniform sampler2D textureSampler;
+uniform sampler2D originalColor;
+
+varying vec2 vUV;
+
+void main(void) {
+	gl_FragColor = texture2D(textureSampler, vUV) * texture2D(originalColor, vUV);
+}

+ 6 - 0
Babylon/Tools/babylon.filesInput.js

@@ -75,6 +75,12 @@ var BABYLON;
                             break;
                         case "image/targa":
                         case "image/vnd.ms-dds":
+                        case "audio/wav":
+                        case "audio/x-wav":
+                        case "audio/mpeg":
+                        case "audio/mpeg3":
+                        case "audio/x-mpeg-3":
+                        case "audio/ogg":
                             BABYLON.FilesInput.FilesToLoad[filesToLoad[i].name] = filesToLoad[i];
                             break;
                         default:

+ 6 - 0
Babylon/Tools/babylon.filesInput.ts

@@ -90,6 +90,12 @@
                             break;
                         case "image/targa":
                         case "image/vnd.ms-dds":
+                        case "audio/wav":
+                        case "audio/x-wav":
+                        case "audio/mpeg":
+                        case "audio/mpeg3":
+                        case "audio/x-mpeg-3":
+                        case "audio/ogg":
                             BABYLON.FilesInput.FilesToLoad[filesToLoad[i].name] = filesToLoad[i];
                             break;
                         default:

+ 32 - 9
Babylon/babylon.scene.js

@@ -1111,7 +1111,7 @@ var BABYLON;
         };
         Scene.prototype._updateAudioParameters = function () {
             var listeningCamera;
-            var audioEngine = this._engine.getAudioEngine();
+            var audioEngine = BABYLON.Engine.audioEngine;
             if (this.activeCameras.length > 0) {
                 listeningCamera = this.activeCameras[0];
             }
@@ -1259,12 +1259,7 @@ var BABYLON;
             this._collideWithWorld(position, velocity, collider, maximumRetry, finalPosition, excludedMesh);
         };
         // Octrees
-        Scene.prototype.createOrUpdateSelectionOctree = function (maxCapacity, maxDepth) {
-            if (maxCapacity === void 0) { maxCapacity = 64; }
-            if (maxDepth === void 0) { maxDepth = 2; }
-            if (!this._selectionOctree) {
-                this._selectionOctree = new BABYLON.Octree(BABYLON.Octree.CreationFuncForMeshes, maxCapacity, maxDepth);
-            }
+        Scene.prototype.getWorldExtends = function () {
             var min = new BABYLON.Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
             var max = new BABYLON.Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
             for (var index = 0; index < this.meshes.length; index++) {
@@ -1275,8 +1270,20 @@ var BABYLON;
                 BABYLON.Tools.CheckExtends(minBox, min, max);
                 BABYLON.Tools.CheckExtends(maxBox, min, max);
             }
+            return {
+                min: min,
+                max: max
+            };
+        };
+        Scene.prototype.createOrUpdateSelectionOctree = function (maxCapacity, maxDepth) {
+            if (maxCapacity === void 0) { maxCapacity = 64; }
+            if (maxDepth === void 0) { maxDepth = 2; }
+            if (!this._selectionOctree) {
+                this._selectionOctree = new BABYLON.Octree(BABYLON.Octree.CreationFuncForMeshes, maxCapacity, maxDepth);
+            }
+            var worldExtends = this.getWorldExtends();
             // Update octree
-            this._selectionOctree.update(min, max, this.meshes);
+            this._selectionOctree.update(worldExtends.min, worldExtends.max, this.meshes);
             return this._selectionOctree;
         };
         // Picking
@@ -1405,7 +1412,6 @@ var BABYLON;
             }
             return this._physicsEngine._registerMeshesAsCompound(parts, options);
         };
-        //ANY
         Scene.prototype.deleteCompoundImpostor = function (compound) {
             for (var index = 0; index < compound.parts.length; index++) {
                 var mesh = compound.parts[index].mesh;
@@ -1413,6 +1419,23 @@ var BABYLON;
                 this._physicsEngine._unregisterMesh(mesh);
             }
         };
+        // Misc.
+        Scene.prototype.createDefaultCameraOrLight = function () {
+            // Light
+            if (this.lights.length === 0) {
+                new BABYLON.HemisphericLight("default light", BABYLON.Vector3.Up(), this);
+            }
+            // Camera
+            if (!this.activeCamera) {
+                var camera = new BABYLON.FreeCamera("default camera", BABYLON.Vector3.Zero(), this);
+                // Compute position
+                var worldExtends = this.getWorldExtends();
+                var worldCenter = worldExtends.min.add(worldExtends.max.subtract(worldExtends.min).scale(0.5));
+                camera.position = new BABYLON.Vector3(worldCenter.x, worldCenter.y, worldExtends.min.z - (worldExtends.max.z - worldExtends.min.z));
+                camera.setTarget(worldCenter);
+                this.activeCamera = camera;
+            }
+        };
         // Tags
         Scene.prototype._getByTags = function (list, tagsQuery, forEach) {
             if (tagsQuery === undefined) {

+ 39 - 9
Babylon/babylon.scene.ts

@@ -1284,7 +1284,7 @@
                             if (indexOfOther > -1) {
                                 sourceMesh._intersectionsInProgress.splice(indexOfOther, 1);
                             }
-                        } 
+                        }
                     }
                 }
             }
@@ -1447,7 +1447,7 @@
 
         private _updateAudioParameters() {
             var listeningCamera: Camera;
-            var audioEngine = this._engine.getAudioEngine();
+            var audioEngine = Engine.audioEngine;
 
             if (this.activeCameras.length > 0) {
                 listeningCamera = this.activeCameras[0];
@@ -1644,11 +1644,7 @@
         }
 
         // Octrees
-        public createOrUpdateSelectionOctree(maxCapacity = 64, maxDepth = 2): Octree<AbstractMesh> {
-            if (!this._selectionOctree) {
-                this._selectionOctree = new Octree<AbstractMesh>(Octree.CreationFuncForMeshes, maxCapacity, maxDepth);
-            }
-
+        public getWorldExtends(): { min: Vector3; max: Vector3 } {
             var min = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
             var max = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
             for (var index = 0; index < this.meshes.length; index++) {
@@ -1662,8 +1658,21 @@
                 Tools.CheckExtends(maxBox, min, max);
             }
 
+            return {
+                min: min,
+                max: max
+            };
+        }
+
+        public createOrUpdateSelectionOctree(maxCapacity = 64, maxDepth = 2): Octree<AbstractMesh> {
+            if (!this._selectionOctree) {
+                this._selectionOctree = new Octree<AbstractMesh>(Octree.CreationFuncForMeshes, maxCapacity, maxDepth);
+            }
+
+            var worldExtends = this.getWorldExtends();
+
             // Update octree
-            this._selectionOctree.update(min, max, this.meshes);
+            this._selectionOctree.update(worldExtends.min, worldExtends.max, this.meshes);
 
             return this._selectionOctree;
         }
@@ -1827,7 +1836,6 @@
             return this._physicsEngine._registerMeshesAsCompound(parts, options);
         }
 
-        //ANY
         public deleteCompoundImpostor(compound: any): void {
             for (var index = 0; index < compound.parts.length; index++) {
                 var mesh = compound.parts[index].mesh;
@@ -1836,6 +1844,28 @@
             }
         }
 
+        // Misc.
+        public createDefaultCameraOrLight() {
+            // Light
+            if (this.lights.length === 0) {
+                new HemisphericLight("default light", Vector3.Up(), this);
+            }
+
+            // Camera
+            if (!this.activeCamera) {
+                var camera = new FreeCamera("default camera", Vector3.Zero(), this);
+
+                // Compute position
+                var worldExtends = this.getWorldExtends();
+                var worldCenter = worldExtends.min.add(worldExtends.max.subtract(worldExtends.min).scale(0.5));
+
+                camera.position = new Vector3(worldCenter.x, worldCenter.y, worldExtends.min.z - (worldExtends.max.z - worldExtends.min.z));
+                camera.setTarget(worldCenter);
+
+                this.activeCamera = camera;
+            }
+        }
+
         // Tags
         private _getByTags(list: any[], tagsQuery: string, forEach?: (item: any) => void): any[] {
             if (tagsQuery === undefined) {

+ 37 - 8
babylon.2.0-beta.debug.js

@@ -8646,12 +8646,7 @@ var BABYLON;
             this._collideWithWorld(position, velocity, collider, maximumRetry, finalPosition, excludedMesh);
         };
         // Octrees
-        Scene.prototype.createOrUpdateSelectionOctree = function (maxCapacity, maxDepth) {
-            if (maxCapacity === void 0) { maxCapacity = 64; }
-            if (maxDepth === void 0) { maxDepth = 2; }
-            if (!this._selectionOctree) {
-                this._selectionOctree = new BABYLON.Octree(BABYLON.Octree.CreationFuncForMeshes, maxCapacity, maxDepth);
-            }
+        Scene.prototype.getWorldExtends = function () {
             var min = new BABYLON.Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
             var max = new BABYLON.Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
             for (var index = 0; index < this.meshes.length; index++) {
@@ -8662,8 +8657,20 @@ var BABYLON;
                 BABYLON.Tools.CheckExtends(minBox, min, max);
                 BABYLON.Tools.CheckExtends(maxBox, min, max);
             }
+            return {
+                min: min,
+                max: max
+            };
+        };
+        Scene.prototype.createOrUpdateSelectionOctree = function (maxCapacity, maxDepth) {
+            if (maxCapacity === void 0) { maxCapacity = 64; }
+            if (maxDepth === void 0) { maxDepth = 2; }
+            if (!this._selectionOctree) {
+                this._selectionOctree = new BABYLON.Octree(BABYLON.Octree.CreationFuncForMeshes, maxCapacity, maxDepth);
+            }
+            var worldExtends = this.getWorldExtends();
             // Update octree
-            this._selectionOctree.update(min, max, this.meshes);
+            this._selectionOctree.update(worldExtends.min, worldExtends.max, this.meshes);
             return this._selectionOctree;
         };
         // Picking
@@ -8792,7 +8799,6 @@ var BABYLON;
             }
             return this._physicsEngine._registerMeshesAsCompound(parts, options);
         };
-        //ANY
         Scene.prototype.deleteCompoundImpostor = function (compound) {
             for (var index = 0; index < compound.parts.length; index++) {
                 var mesh = compound.parts[index].mesh;
@@ -8800,6 +8806,23 @@ var BABYLON;
                 this._physicsEngine._unregisterMesh(mesh);
             }
         };
+        // Misc.
+        Scene.prototype.createDefaultCameraOrLight = function () {
+            // Light
+            if (this.lights.length === 0) {
+                new BABYLON.HemisphericLight("default light", BABYLON.Vector3.Up(), this);
+            }
+            // Camera
+            if (!this.activeCamera) {
+                var camera = new BABYLON.FreeCamera("default camera", BABYLON.Vector3.Zero(), this);
+                // Compute position
+                var worldExtends = this.getWorldExtends();
+                var worldCenter = worldExtends.min.add(worldExtends.max.subtract(worldExtends.min).scale(0.5));
+                camera.position = new BABYLON.Vector3(worldCenter.x, worldCenter.y, worldExtends.min.z - (worldExtends.max.z - worldExtends.min.z));
+                camera.setTarget(worldCenter);
+                this.activeCamera = camera;
+            }
+        };
         // Tags
         Scene.prototype._getByTags = function (list, tagsQuery, forEach) {
             if (tagsQuery === undefined) {
@@ -16754,6 +16777,12 @@ var BABYLON;
                             break;
                         case "image/targa":
                         case "image/vnd.ms-dds":
+                        case "audio/wav":
+                        case "audio/x-wav":
+                        case "audio/mpeg":
+                        case "audio/mpeg3":
+                        case "audio/x-mpeg-3":
+                        case "audio/ogg":
                             BABYLON.FilesInput.FilesToLoad[filesToLoad[i].name] = filesToLoad[i];
                             break;
                         default:

文件差異過大導致無法顯示
+ 9 - 9
babylon.2.0-beta.js