David Catuhe před 10 roky
rodič
revize
b2060b3c54

+ 1 - 1
Babylon/Culling/Octrees/babylon.octree.js

@@ -87,7 +87,7 @@
         };
 
         Octree.CreationFuncForMeshes = function (entry, block) {
-            if (entry.getBoundingInfo().boundingBox.intersectsMinMax(block.minPoint, block.maxPoint)) {
+            if (!entry.isBlocked && entry.getBoundingInfo().boundingBox.intersectsMinMax(block.minPoint, block.maxPoint)) {
                 block.entries.push(entry);
             }
         };

+ 1 - 1
Babylon/Culling/Octrees/babylon.octree.ts

@@ -96,7 +96,7 @@
         }
 
         public static CreationFuncForMeshes = (entry: AbstractMesh, block: OctreeBlock<AbstractMesh>): void => {
-            if (entry.getBoundingInfo().boundingBox.intersectsMinMax(block.minPoint, block.maxPoint)) {
+            if (!entry.isBlocked && entry.getBoundingInfo().boundingBox.intersectsMinMax(block.minPoint, block.maxPoint)) {
                 block.entries.push(entry);
             }
         }

+ 7 - 9
Babylon/Loading/Plugins/babylon.babylonFileLoader.js

@@ -896,8 +896,6 @@
                         var subMesh = new BABYLON.SubMesh(materialIndex, verticesStart, verticesCount, indexStart, indexCount, mesh);
                     }
                 }
-
-                return;
             } else if (parsedGeometry.positions && parsedGeometry.normals && parsedGeometry.indices) {
                 mesh.setVerticesData(BABYLON.VertexBuffer.PositionKind, parsedGeometry.positions, false);
                 mesh.setVerticesData(BABYLON.VertexBuffer.NormalKind, parsedGeometry.normals, false);
@@ -939,15 +937,15 @@
                 }
 
                 mesh.setIndices(parsedGeometry.indices);
-            }
 
-            // SubMeshes
-            if (parsedGeometry.subMeshes) {
-                mesh.subMeshes = [];
-                for (var subIndex = 0; subIndex < parsedGeometry.subMeshes.length; subIndex++) {
-                    var parsedSubMesh = parsedGeometry.subMeshes[subIndex];
+                // SubMeshes
+                if (parsedGeometry.subMeshes) {
+                    mesh.subMeshes = [];
+                    for (var subIndex = 0; subIndex < parsedGeometry.subMeshes.length; subIndex++) {
+                        var parsedSubMesh = parsedGeometry.subMeshes[subIndex];
 
-                    var subMesh = new BABYLON.SubMesh(parsedSubMesh.materialIndex, parsedSubMesh.verticesStart, parsedSubMesh.verticesCount, parsedSubMesh.indexStart, parsedSubMesh.indexCount, mesh);
+                        var subMesh = new BABYLON.SubMesh(parsedSubMesh.materialIndex, parsedSubMesh.verticesStart, parsedSubMesh.verticesCount, parsedSubMesh.indexStart, parsedSubMesh.indexCount, mesh);
+                    }
                 }
             }
 

+ 7 - 10
Babylon/Loading/Plugins/babylon.babylonFileLoader.ts

@@ -908,9 +908,6 @@
                     var subMesh = new BABYLON.SubMesh(materialIndex, verticesStart, verticesCount, indexStart, indexCount, mesh);
                 }
             }
-
-            return;
-
         } else if (parsedGeometry.positions && parsedGeometry.normals && parsedGeometry.indices) {
             mesh.setVerticesData(BABYLON.VertexBuffer.PositionKind, parsedGeometry.positions, false);
             mesh.setVerticesData(BABYLON.VertexBuffer.NormalKind, parsedGeometry.normals, false);
@@ -952,15 +949,15 @@
             }
 
             mesh.setIndices(parsedGeometry.indices);
-        }
 
-        // SubMeshes
-        if (parsedGeometry.subMeshes) {
-            mesh.subMeshes = [];
-            for (var subIndex = 0; subIndex < parsedGeometry.subMeshes.length; subIndex++) {
-                var parsedSubMesh = parsedGeometry.subMeshes[subIndex];
+            // SubMeshes
+            if (parsedGeometry.subMeshes) {
+                mesh.subMeshes = [];
+                for (var subIndex = 0; subIndex < parsedGeometry.subMeshes.length; subIndex++) {
+                    var parsedSubMesh = parsedGeometry.subMeshes[subIndex];
 
-                var subMesh = new BABYLON.SubMesh(parsedSubMesh.materialIndex, parsedSubMesh.verticesStart, parsedSubMesh.verticesCount, parsedSubMesh.indexStart, parsedSubMesh.indexCount, mesh);
+                    var subMesh = new BABYLON.SubMesh(parsedSubMesh.materialIndex, parsedSubMesh.verticesStart, parsedSubMesh.verticesCount, parsedSubMesh.indexStart, parsedSubMesh.indexCount, mesh);
+                }
             }
         }
 

+ 12 - 0
Babylon/Materials/babylon.effect.js

@@ -194,6 +194,7 @@
         Effect.prototype._prepareEffect = function (vertexSourceCode, fragmentSourceCode, attributesNames, defines, fallbacks) {
             try  {
                 var engine = this._engine;
+
                 this._program = engine.createShaderProgram(vertexSourceCode, fragmentSourceCode, defines);
 
                 this._uniforms = engine.getUniforms(this._program, this._uniformsNames);
@@ -215,6 +216,17 @@
                     this.onCompiled(this);
                 }
             } catch (e) {
+                // Is it a problem with precision?
+                if (e.message.indexOf("highp") !== -1) {
+                    vertexSourceCode = vertexSourceCode.replace("precision highp float", "precision mediump float");
+                    fragmentSourceCode = fragmentSourceCode.replace("precision highp float", "precision mediump float");
+
+                    this._prepareEffect(vertexSourceCode, fragmentSourceCode, attributesNames, defines, fallbacks);
+
+                    return;
+                }
+
+                // Let's go through fallbacks then
                 if (fallbacks && fallbacks.isMoreFallbacks) {
                     defines = fallbacks.reduce(defines);
                     this._prepareEffect(vertexSourceCode, fragmentSourceCode, attributesNames, defines, fallbacks);

+ 12 - 1
Babylon/Materials/babylon.effect.ts

@@ -203,6 +203,7 @@
         private _prepareEffect(vertexSourceCode: string, fragmentSourceCode: string, attributesNames: string[], defines: string, fallbacks?: EffectFallbacks): void {
             try {
                 var engine = this._engine;
+
                 this._program = engine.createShaderProgram(vertexSourceCode, fragmentSourceCode, defines);
 
                 this._uniforms = engine.getUniforms(this._program, this._uniformsNames);
@@ -224,10 +225,20 @@
                     this.onCompiled(this);
                 }
             } catch (e) {
+                // Is it a problem with precision?
+                if (e.message.indexOf("highp") !== -1) {
+                    vertexSourceCode = vertexSourceCode.replace("precision highp float", "precision mediump float");
+                    fragmentSourceCode = fragmentSourceCode.replace("precision highp float", "precision mediump float");
+
+                    this._prepareEffect(vertexSourceCode, fragmentSourceCode, attributesNames, defines, fallbacks);
+
+                    return;
+                }
+                // Let's go through fallbacks then
                 if (fallbacks && fallbacks.isMoreFallbacks) {
                     defines = fallbacks.reduce(defines);
                     this._prepareEffect(vertexSourceCode, fragmentSourceCode, attributesNames, defines, fallbacks);
-                } else {
+                } else { // SOrry we did everything we can
                     Tools.Error("Unable to compile effect: " + this.name);
                     Tools.Error("Defines: " + defines);
                     Tools.Error("Error: " + e.message);

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

@@ -103,7 +103,19 @@ var BABYLON;
             configurable: true
         });
 
-        // Methods
+        Object.defineProperty(AbstractMesh.prototype, "isBlocked", {
+            // Methods
+            get: function () {
+                return false;
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        AbstractMesh.prototype.getLOD = function (camera) {
+            return this;
+        };
+
         AbstractMesh.prototype.getTotalVertices = function () {
             return 0;
         };

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

@@ -79,7 +79,7 @@
         private _localPivotScaling = BABYLON.Matrix.Zero();
         private _localPivotScalingRotation = BABYLON.Matrix.Zero();
         private _localWorld = BABYLON.Matrix.Zero();
-        private _worldMatrix = BABYLON.Matrix.Zero();
+        public _worldMatrix = BABYLON.Matrix.Zero();
         private _rotateYByPI = BABYLON.Matrix.RotationY(Math.PI);
         private _absolutePosition = BABYLON.Vector3.Zero();
         private _collisionsTransformMatrix = BABYLON.Matrix.Zero();
@@ -103,6 +103,14 @@
         }
 
         // Methods
+        public get isBlocked(): boolean {
+            return false;
+        }
+
+        public getLOD(camera: Camera): AbstractMesh {
+            return this;
+        }
+
         public getTotalVertices(): number {
             return 0;
         }

+ 91 - 3
Babylon/Mesh/babylon.mesh.js

@@ -23,6 +23,7 @@ var BABYLON;
             // Members
             this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_NONE;
             this.instances = new Array();
+            this._LODLevels = new Array();
             this._onBeforeRenderCallbacks = new Array();
             this._onAfterRenderCallbacks = new Array();
             this._visibleInstances = {};
@@ -30,6 +31,84 @@ var BABYLON;
             this._batchCache = new _InstancesBatch();
             this._instancesBufferSize = 32 * 16 * 4;
         }
+        // Methods
+        Mesh.prototype._sortLODLevels = function () {
+            this._LODLevels.sort(function (a, b) {
+                if (a.distance < b.distance) {
+                    return 1;
+                }
+                if (a.distance > b.distance) {
+                    return -1;
+                }
+
+                return 0;
+            });
+        };
+
+        Mesh.prototype.addLODLevel = function (distance, mesh) {
+            var level = new BABYLON.Internals.MeshLODLevel(distance, mesh);
+            this._LODLevels.push(level);
+
+            if (mesh) {
+                mesh._attachedLODLevel = level;
+            }
+
+            this._sortLODLevels();
+
+            return this;
+        };
+
+        Mesh.prototype.removeLODLevel = function (mesh) {
+            if (mesh && !mesh._attachedLODLevel) {
+                return this;
+            }
+
+            var index;
+
+            if (mesh) {
+                index = this._LODLevels.indexOf(mesh._attachedLODLevel);
+                mesh._attachedLODLevel = null;
+
+                this._LODLevels.splice(index, 1);
+
+                this._sortLODLevels();
+            } else {
+                for (index = 0; index < this._LODLevels.length; index++) {
+                    if (this._LODLevels[index].mesh === null) {
+                        this._LODLevels.splice(index, 1);
+                        break;
+                    }
+                }
+            }
+
+            return this;
+        };
+
+        Mesh.prototype.getLOD = function (camera) {
+            if (!this._LODLevels || this._LODLevels.length === 0) {
+                return this;
+            }
+
+            var distanceToCamera = this.getBoundingInfo().boundingSphere.centerWorld.subtract(camera.position).length();
+
+            if (this._LODLevels[this._LODLevels.length - 1].distance > distanceToCamera) {
+                return this;
+            }
+
+            for (var index = 0; index < this._LODLevels.length; index++) {
+                var level = this._LODLevels[index];
+
+                if (level.distance < distanceToCamera) {
+                    if (level.mesh) {
+                        level.mesh._worldMatrix = this._worldMatrix;
+                    }
+                    return level.mesh;
+                }
+            }
+
+            return this;
+        };
+
         Mesh.prototype.getTotalVertices = function () {
             if (!this._geometry) {
                 return 0;
@@ -88,6 +167,14 @@ var BABYLON;
             return this._geometry.getIndices();
         };
 
+        Object.defineProperty(Mesh.prototype, "isBlocked", {
+            get: function () {
+                return this._attachedLODLevel !== null && this._attachedLODLevel !== undefined;
+            },
+            enumerable: true,
+            configurable: true
+        });
+
         Mesh.prototype.isReady = function () {
             if (this.delayLoadState === BABYLON.Engine.DELAYLOADSTATE_LOADING) {
                 return false;
@@ -252,14 +339,15 @@ var BABYLON;
             var indexToBind;
 
             switch (fillMode) {
-                case BABYLON.Material.TriangleFillMode:
-                    indexToBind = this._geometry.getIndexBuffer();
+                case BABYLON.Material.PointFillMode:
+                    indexToBind = null;
                     break;
                 case BABYLON.Material.WireFrameFillMode:
                     indexToBind = subMesh.getLinesIndexBuffer(this.getIndices(), engine);
                     break;
                 default:
-                    indexToBind = null;
+                case BABYLON.Material.TriangleFillMode:
+                    indexToBind = this._geometry.getIndexBuffer();
                     break;
             }
 

+ 88 - 3
Babylon/Mesh/babylon.mesh.ts

@@ -11,6 +11,7 @@
         public instances = new Array<InstancedMesh>();
         public delayLoadingFile: string;
         public _binaryInfo: any;
+        private _LODLevels = new Array<BABYLON.Internals.MeshLODLevel>();
 
         // Private
         public _geometry: Geometry;
@@ -26,11 +27,90 @@
         private _instancesBufferSize = 32 * 16 * 4; // let's start with a maximum of 32 instances
         public _shouldGenerateFlatShading: boolean;
         private _preActivateId: number;
+        private _attachedLODLevel: BABYLON.Internals.MeshLODLevel;
 
         constructor(name: string, scene: Scene) {
             super(name, scene);
         }
 
+        // Methods
+        private _sortLODLevels(): void {
+            this._LODLevels.sort((a, b) => {
+                if (a.distance < b.distance) {
+                    return 1;
+                }
+                if (a.distance > b.distance) {
+                    return -1;
+                }
+
+                return 0;
+            });
+        }
+
+        public addLODLevel(distance: number, mesh: Mesh): Mesh {
+            var level = new BABYLON.Internals.MeshLODLevel(distance, mesh);
+            this._LODLevels.push(level);
+
+            if (mesh) {
+                mesh._attachedLODLevel = level;
+            }
+
+            this._sortLODLevels();
+
+            return this;
+        }
+
+        public removeLODLevel(mesh: Mesh): Mesh {
+            if (mesh && !mesh._attachedLODLevel) {
+                return this;
+            }
+
+            var index;
+
+            if (mesh) {
+                index = this._LODLevels.indexOf(mesh._attachedLODLevel);
+                mesh._attachedLODLevel = null;
+
+                this._LODLevels.splice(index, 1);
+
+                this._sortLODLevels();
+            } else {
+                for (index = 0; index < this._LODLevels.length; index++) {
+                    if (this._LODLevels[index].mesh === null) {
+                        this._LODLevels.splice(index, 1);
+                        break;
+                    }
+                }
+            }
+
+            return this;
+        }
+
+        public getLOD(camera: Camera): AbstractMesh {
+            if (!this._LODLevels || this._LODLevels.length === 0) {
+                return this;
+            }
+
+            var distanceToCamera = this.getBoundingInfo().boundingSphere.centerWorld.subtract(camera.position).length();
+
+            if (this._LODLevels[this._LODLevels.length - 1].distance > distanceToCamera) {
+                return this;
+            }
+
+            for (var index = 0; index < this._LODLevels.length; index++) {
+                var level = this._LODLevels[index];
+
+                if (level.distance < distanceToCamera) {
+                    if (level.mesh) {
+                        level.mesh._worldMatrix = this._worldMatrix;
+                    }
+                    return level.mesh;
+                }
+            }
+
+            return this;
+        }
+
         public getTotalVertices(): number {
             if (!this._geometry) {
                 return 0;
@@ -89,6 +169,10 @@
             return this._geometry.getIndices();
         }
 
+        public get isBlocked(): boolean {
+            return this._attachedLODLevel !== null && this._attachedLODLevel !== undefined;
+        }
+
         public isReady(): boolean {
             if (this.delayLoadState === BABYLON.Engine.DELAYLOADSTATE_LOADING) {
                 return false;
@@ -258,14 +342,15 @@
             var indexToBind;
 
             switch (fillMode) {
-                case Material.TriangleFillMode:
-                    indexToBind = this._geometry.getIndexBuffer();
+                case Material.PointFillMode:
+                    indexToBind = null;
                     break;
                 case Material.WireFrameFillMode:
                     indexToBind = subMesh.getLinesIndexBuffer(this.getIndices(), engine);
                     break;
                 default:
-                    indexToBind = null;
+                case Material.TriangleFillMode:
+                    indexToBind = this._geometry.getIndexBuffer();
                     break;
             }
 

+ 6 - 0
Babylon/Mesh/babylon.meshLODLevel.ts

@@ -0,0 +1,6 @@
+module BABYLON.Internals {
+    export class MeshLODLevel {
+        constructor(public distance: number, public mesh: Mesh) {
+        }
+    }
+} 

+ 44 - 0
Babylon/Shaders/cloud.fragment.fx

@@ -0,0 +1,44 @@
+#ifdef GL_ES
+precision highp float;
+#endif
+
+uniform float iGlobalTime;
+uniform vec3 c1;
+uniform vec3 c2;
+uniform vec3 c3;
+uniform vec3 c4;
+uniform vec3 c5;
+uniform vec3 c6;
+uniform vec2 speed;
+uniform float shift;
+uniform float alpha;
+
+varying vec2 vUV;
+
+float rand(vec2 n) {
+	return fract(cos(dot(n, vec2(12.9898, 4.1414))) * 43758.5453);
+}
+
+float noise(vec2 n) {
+	const vec2 d = vec2(0.0, 1.0);
+	vec2 b = floor(n), f = smoothstep(vec2(0.0), vec2(1.0), fract(n));
+	return mix(mix(rand(b), rand(b + d.yx), f.x), mix(rand(b + d.xy), rand(b + d.yy), f.x), f.y);
+}
+
+float fbm(vec2 n) {
+	float total = 0.0, amplitude = 1.0;
+	for (int i = 0; i < 4; i++) {
+		total += noise(n) * amplitude;
+		n += n;
+		amplitude *= 0.5;
+	}
+	return total;
+}
+
+void main() {
+
+	vec2 p = vUV * 12.0;
+	vec3 c = mix(vec3(0.15, 0.68, 1.0), vec3(1,1,1), fbm(p));
+	gl_FragColor = vec4(c, 1);
+
+}

+ 11 - 5
Babylon/babylon.scene.js

@@ -716,6 +716,10 @@
             for (var meshIndex = 0; meshIndex < len; meshIndex++) {
                 var mesh = meshes[meshIndex];
 
+                if (mesh.isBlocked) {
+                    continue;
+                }
+
                 this._totalVertices += mesh.getTotalVertices();
 
                 if (!mesh.isReady()) {
@@ -768,25 +772,27 @@
                 this._boundingBoxRenderer.renderList.push(mesh.getBoundingInfo().boundingBox);
             }
 
-            if (mesh.subMeshes) {
+            var activeMesh = mesh.getLOD(this.activeCamera);
+
+            if (activeMesh && activeMesh.subMeshes) {
                 // Submeshes Octrees
                 var len;
                 var subMeshes;
 
-                if (mesh._submeshesOctree && mesh.useOctreeForRenderingSelection) {
-                    var intersections = mesh._submeshesOctree.select(this._frustumPlanes);
+                if (activeMesh._submeshesOctree && activeMesh.useOctreeForRenderingSelection) {
+                    var intersections = activeMesh._submeshesOctree.select(this._frustumPlanes);
 
                     len = intersections.length;
                     subMeshes = intersections.data;
                 } else {
-                    subMeshes = mesh.subMeshes;
+                    subMeshes = activeMesh.subMeshes;
                     len = subMeshes.length;
                 }
 
                 for (var subIndex = 0; subIndex < len; subIndex++) {
                     var subMesh = subMeshes[subIndex];
 
-                    this._evaluateSubMesh(subMesh, mesh);
+                    this._evaluateSubMesh(subMesh, activeMesh);
                 }
             }
         };

+ 12 - 6
Babylon/babylon.scene.ts

@@ -792,6 +792,10 @@
             for (var meshIndex = 0; meshIndex < len; meshIndex++) {
                 var mesh = meshes[meshIndex];
 
+                if (mesh.isBlocked) {
+                    continue;
+                }
+
                 this._totalVertices += mesh.getTotalVertices();
 
                 if (!mesh.isReady()) {
@@ -842,27 +846,29 @@
 
             if (mesh.showBoundingBox) {
                 this._boundingBoxRenderer.renderList.push(mesh.getBoundingInfo().boundingBox);
-            }
+            }            
+
+            var activeMesh = mesh.getLOD(this.activeCamera);
 
-            if (mesh.subMeshes) {
+            if (activeMesh && activeMesh.subMeshes) {
                 // Submeshes Octrees
                 var len: number;
                 var subMeshes: SubMesh[];
 
-                if (mesh._submeshesOctree && mesh.useOctreeForRenderingSelection) {
-                    var intersections = mesh._submeshesOctree.select(this._frustumPlanes);
+                if (activeMesh._submeshesOctree && activeMesh.useOctreeForRenderingSelection) {
+                    var intersections = activeMesh._submeshesOctree.select(this._frustumPlanes);
 
                     len = intersections.length;
                     subMeshes = intersections.data;
                 } else {
-                    subMeshes = mesh.subMeshes;
+                    subMeshes = activeMesh.subMeshes;
                     len = subMeshes.length;
                 }
 
                 for (var subIndex = 0; subIndex < len; subIndex++) {
                     var subMesh = subMeshes[subIndex];
 
-                    this._evaluateSubMesh(subMesh, mesh);
+                    this._evaluateSubMesh(subMesh, activeMesh);
                 }
             }
         }

+ 1 - 0
Tools/BuildOurOwnBabylonJS/BuildOurOwnBabylonJS/babylonJS.xml

@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <files xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="babylonJS.xsd">
+  <script src="Babylon/Mesh/babylon.meshLODLevel.js"></script>
   <script src="Babylon/Tools/babylon.sceneOptimizer.js"></script>
   <script src="Babylon/Cameras/babylon.vrDeviceOrientationCamera.js"></script>
   <script src="Babylon/Cameras/babylon.webVRCamera.js"></script>

+ 1 - 0
Tools/Gulp/gulpfile.js

@@ -157,6 +157,7 @@ gulp.task('scripts', ['shaders'] ,function() {
       '../../Babylon/Cameras/babylon.vrDeviceOrientationCamera.js',
       '../../Babylon/Cameras/babylon.webVRCamera.js',
       '../../Babylon/Tools/babylon.sceneOptimizer.js',
+      '../../Babylon/Mesh/babylon.meshLODLevel.js'
     ])
     .pipe(concat('babylon.js'))
     .pipe(gulp.dest('build/'))

+ 149 - 19
babylon.2.0-alpha.debug.js

@@ -8819,6 +8819,10 @@ var BABYLON;
             for (var meshIndex = 0; meshIndex < len; meshIndex++) {
                 var mesh = meshes[meshIndex];
 
+                if (mesh.isBlocked) {
+                    continue;
+                }
+
                 this._totalVertices += mesh.getTotalVertices();
 
                 if (!mesh.isReady()) {
@@ -8871,25 +8875,27 @@ var BABYLON;
                 this._boundingBoxRenderer.renderList.push(mesh.getBoundingInfo().boundingBox);
             }
 
-            if (mesh.subMeshes) {
+            var activeMesh = mesh.getLOD(this.activeCamera);
+
+            if (activeMesh && activeMesh.subMeshes) {
                
                 var len;
                 var subMeshes;
 
-                if (mesh._submeshesOctree && mesh.useOctreeForRenderingSelection) {
-                    var intersections = mesh._submeshesOctree.select(this._frustumPlanes);
+                if (activeMesh._submeshesOctree && activeMesh.useOctreeForRenderingSelection) {
+                    var intersections = activeMesh._submeshesOctree.select(this._frustumPlanes);
 
                     len = intersections.length;
                     subMeshes = intersections.data;
                 } else {
-                    subMeshes = mesh.subMeshes;
+                    subMeshes = activeMesh.subMeshes;
                     len = subMeshes.length;
                 }
 
                 for (var subIndex = 0; subIndex < len; subIndex++) {
                     var subMesh = subMeshes[subIndex];
 
-                    this._evaluateSubMesh(subMesh, mesh);
+                    this._evaluateSubMesh(subMesh, activeMesh);
                 }
             }
         };
@@ -9846,7 +9852,19 @@ var BABYLON;
             configurable: true
         });
 
-       
+        Object.defineProperty(AbstractMesh.prototype, "isBlocked", {
+           
+            get: function () {
+                return false;
+            },
+            enumerable: true,
+            configurable: true
+        });
+
+        AbstractMesh.prototype.getLOD = function (camera) {
+            return this;
+        };
+
         AbstractMesh.prototype.getTotalVertices = function () {
             return 0;
         };
@@ -10580,6 +10598,7 @@ var BABYLON;
            
             this.delayLoadState = BABYLON.Engine.DELAYLOADSTATE_NONE;
             this.instances = new Array();
+            this._LODLevels = new Array();
             this._onBeforeRenderCallbacks = new Array();
             this._onAfterRenderCallbacks = new Array();
             this._visibleInstances = {};
@@ -10587,6 +10606,84 @@ var BABYLON;
             this._batchCache = new _InstancesBatch();
             this._instancesBufferSize = 32 * 16 * 4;
         }
+       
+        Mesh.prototype._sortLODLevels = function () {
+            this._LODLevels.sort(function (a, b) {
+                if (a.distance < b.distance) {
+                    return 1;
+                }
+                if (a.distance > b.distance) {
+                    return -1;
+                }
+
+                return 0;
+            });
+        };
+
+        Mesh.prototype.addLODLevel = function (distance, mesh) {
+            var level = new BABYLON.Internals.MeshLODLevel(distance, mesh);
+            this._LODLevels.push(level);
+
+            if (mesh) {
+                mesh._attachedLODLevel = level;
+            }
+
+            this._sortLODLevels();
+
+            return this;
+        };
+
+        Mesh.prototype.removeLODLevel = function (mesh) {
+            if (mesh && !mesh._attachedLODLevel) {
+                return this;
+            }
+
+            var index;
+
+            if (mesh) {
+                index = this._LODLevels.indexOf(mesh._attachedLODLevel);
+                mesh._attachedLODLevel = null;
+
+                this._LODLevels.splice(index, 1);
+
+                this._sortLODLevels();
+            } else {
+                for (index = 0; index < this._LODLevels.length; index++) {
+                    if (this._LODLevels[index].mesh === null) {
+                        this._LODLevels.splice(index, 1);
+                        break;
+                    }
+                }
+            }
+
+            return this;
+        };
+
+        Mesh.prototype.getLOD = function (camera) {
+            if (!this._LODLevels || this._LODLevels.length === 0) {
+                return this;
+            }
+
+            var distanceToCamera = this.getBoundingInfo().boundingSphere.centerWorld.subtract(camera.position).length();
+
+            if (this._LODLevels[this._LODLevels.length - 1].distance > distanceToCamera) {
+                return this;
+            }
+
+            for (var index = 0; index < this._LODLevels.length; index++) {
+                var level = this._LODLevels[index];
+
+                if (level.distance < distanceToCamera) {
+                    if (level.mesh) {
+                        level.mesh._worldMatrix = this._worldMatrix;
+                    }
+                    return level.mesh;
+                }
+            }
+
+            return this;
+        };
+
         Mesh.prototype.getTotalVertices = function () {
             if (!this._geometry) {
                 return 0;
@@ -10645,6 +10742,14 @@ var BABYLON;
             return this._geometry.getIndices();
         };
 
+        Object.defineProperty(Mesh.prototype, "isBlocked", {
+            get: function () {
+                return this._attachedLODLevel !== null && this._attachedLODLevel !== undefined;
+            },
+            enumerable: true,
+            configurable: true
+        });
+
         Mesh.prototype.isReady = function () {
             if (this.delayLoadState === BABYLON.Engine.DELAYLOADSTATE_LOADING) {
                 return false;
@@ -10809,14 +10914,15 @@ var BABYLON;
             var indexToBind;
 
             switch (fillMode) {
-                case BABYLON.Material.TriangleFillMode:
-                    indexToBind = this._geometry.getIndexBuffer();
+                case BABYLON.Material.PointFillMode:
+                    indexToBind = null;
                     break;
                 case BABYLON.Material.WireFrameFillMode:
                     indexToBind = subMesh.getLinesIndexBuffer(this.getIndices(), engine);
                     break;
                 default:
-                    indexToBind = null;
+                case BABYLON.Material.TriangleFillMode:
+                    indexToBind = this._geometry.getIndexBuffer();
                     break;
             }
 
@@ -13774,6 +13880,7 @@ var BABYLON;
         Effect.prototype._prepareEffect = function (vertexSourceCode, fragmentSourceCode, attributesNames, defines, fallbacks) {
             try  {
                 var engine = this._engine;
+
                 this._program = engine.createShaderProgram(vertexSourceCode, fragmentSourceCode, defines);
 
                 this._uniforms = engine.getUniforms(this._program, this._uniformsNames);
@@ -13795,6 +13902,17 @@ var BABYLON;
                     this.onCompiled(this);
                 }
             } catch (e) {
+               
+                if (e.message.indexOf("highp") !== -1) {
+                    vertexSourceCode = vertexSourceCode.replace("precision highp float", "precision mediump float");
+                    fragmentSourceCode = fragmentSourceCode.replace("precision highp float", "precision mediump float");
+
+                    this._prepareEffect(vertexSourceCode, fragmentSourceCode, attributesNames, defines, fallbacks);
+
+                    return;
+                }
+
+               
                 if (fallbacks && fallbacks.isMoreFallbacks) {
                     defines = fallbacks.reduce(defines);
                     this._prepareEffect(vertexSourceCode, fragmentSourceCode, attributesNames, defines, fallbacks);
@@ -16705,7 +16823,7 @@ var BABYLON;
         };
 
         Octree.CreationFuncForMeshes = function (entry, block) {
-            if (entry.getBoundingInfo().boundingBox.intersectsMinMax(block.minPoint, block.maxPoint)) {
+            if (!entry.isBlocked && entry.getBoundingInfo().boundingBox.intersectsMinMax(block.minPoint, block.maxPoint)) {
                 block.entries.push(entry);
             }
         };
@@ -20148,8 +20266,6 @@ var BABYLON;
                         var subMesh = new BABYLON.SubMesh(materialIndex, verticesStart, verticesCount, indexStart, indexCount, mesh);
                     }
                 }
-
-                return;
             } else if (parsedGeometry.positions && parsedGeometry.normals && parsedGeometry.indices) {
                 mesh.setVerticesData(BABYLON.VertexBuffer.PositionKind, parsedGeometry.positions, false);
                 mesh.setVerticesData(BABYLON.VertexBuffer.NormalKind, parsedGeometry.normals, false);
@@ -20191,15 +20307,15 @@ var BABYLON;
                 }
 
                 mesh.setIndices(parsedGeometry.indices);
-            }
 
-           
-            if (parsedGeometry.subMeshes) {
-                mesh.subMeshes = [];
-                for (var subIndex = 0; subIndex < parsedGeometry.subMeshes.length; subIndex++) {
-                    var parsedSubMesh = parsedGeometry.subMeshes[subIndex];
+               
+                if (parsedGeometry.subMeshes) {
+                    mesh.subMeshes = [];
+                    for (var subIndex = 0; subIndex < parsedGeometry.subMeshes.length; subIndex++) {
+                        var parsedSubMesh = parsedGeometry.subMeshes[subIndex];
 
-                    var subMesh = new BABYLON.SubMesh(parsedSubMesh.materialIndex, parsedSubMesh.verticesStart, parsedSubMesh.verticesCount, parsedSubMesh.indexStart, parsedSubMesh.indexCount, mesh);
+                        var subMesh = new BABYLON.SubMesh(parsedSubMesh.materialIndex, parsedSubMesh.verticesStart, parsedSubMesh.verticesCount, parsedSubMesh.indexStart, parsedSubMesh.indexCount, mesh);
+                    }
                 }
             }
 
@@ -27625,3 +27741,17 @@ var BABYLON;
     })();
     BABYLON.SceneOptimizer = SceneOptimizer;
 })(BABYLON || (BABYLON = {}));
+var BABYLON;
+(function (BABYLON) {
+    (function (Internals) {
+        var MeshLODLevel = (function () {
+            function MeshLODLevel(distance, mesh) {
+                this.distance = distance;
+                this.mesh = mesh;
+            }
+            return MeshLODLevel;
+        })();
+        Internals.MeshLODLevel = MeshLODLevel;
+    })(BABYLON.Internals || (BABYLON.Internals = {}));
+    var Internals = BABYLON.Internals;
+})(BABYLON || (BABYLON = {}));

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 9 - 9
babylon.2.0-alpha.js


+ 61 - 1
babylon.2.0.d.ts

@@ -1775,6 +1775,50 @@ declare module BABYLON {
     }
 }
 declare module BABYLON {
+    class ProceduralTexture extends Texture {
+        private _size;
+        public _generateMipMaps: boolean;
+        private _doNotChangeAspectRatio;
+        private _currentRefreshId;
+        private _refreshRate;
+        private _vertexBuffer;
+        private _indexBuffer;
+        private _effect;
+        private _vertexDeclaration;
+        private _vertexStrideSize;
+        private _uniforms;
+        private _samplers;
+        private _fragment;
+        private _textures;
+        private _floats;
+        private _floatsArrays;
+        private _colors3;
+        private _colors4;
+        private _vectors2;
+        private _vectors3;
+        private _matrices;
+        constructor(name: string, size: any, fragment: any, scene: Scene, generateMipMaps?: boolean);
+        public isReady(): boolean;
+        public resetRefreshCounter(): void;
+        public refreshRate : number;
+        public _shouldRender(): boolean;
+        public getRenderSize(): number;
+        public resize(size: any, generateMipMaps: any): void;
+        private _checkUniform(uniformName);
+        public setTexture(name: string, texture: Texture): ProceduralTexture;
+        public setFloat(name: string, value: number): ProceduralTexture;
+        public setFloats(name: string, value: number[]): ProceduralTexture;
+        public setColor3(name: string, value: Color3): ProceduralTexture;
+        public setColor4(name: string, value: Color4): ProceduralTexture;
+        public setVector2(name: string, value: Vector2): ProceduralTexture;
+        public setVector3(name: string, value: Vector3): ProceduralTexture;
+        public setMatrix(name: string, value: Matrix): ProceduralTexture;
+        public render(useCameraPostProcess?: boolean): void;
+        public clone(): ProceduralTexture;
+        public dispose(): void;
+    }
+}
+declare module BABYLON {
     class RenderTargetTexture extends Texture {
         public renderList: AbstractMesh[];
         public renderParticles: boolean;
@@ -2353,7 +2397,7 @@ declare module BABYLON {
         private _localPivotScaling;
         private _localPivotScalingRotation;
         private _localWorld;
-        private _worldMatrix;
+        public _worldMatrix: Matrix;
         private _rotateYByPI;
         private _absolutePosition;
         private _collisionsTransformMatrix;
@@ -2368,6 +2412,8 @@ declare module BABYLON {
         public _submeshesOctree: Octree<SubMesh>;
         public _intersectionsInProgress: AbstractMesh[];
         constructor(name: string, scene: Scene);
+        public isBlocked : boolean;
+        public getLOD(camera: Camera): AbstractMesh;
         public getTotalVertices(): number;
         public getIndices(): number[];
         public getVerticesData(kind: string): number[];
@@ -2644,6 +2690,7 @@ declare module BABYLON {
         public instances: InstancedMesh[];
         public delayLoadingFile: string;
         public _binaryInfo: any;
+        private _LODLevels;
         public _geometry: Geometry;
         private _onBeforeRenderCallbacks;
         private _onAfterRenderCallbacks;
@@ -2657,7 +2704,12 @@ declare module BABYLON {
         private _instancesBufferSize;
         public _shouldGenerateFlatShading: boolean;
         private _preActivateId;
+        private _attachedLODLevel;
         constructor(name: string, scene: Scene);
+        private _sortLODLevels();
+        public addLODLevel(distance: number, mesh: Mesh): Mesh;
+        public removeLODLevel(mesh: Mesh): Mesh;
+        public getLOD(camera: Camera): AbstractMesh;
         public getTotalVertices(): number;
         public getVerticesData(kind: string): number[];
         public getVertexBuffer(kind: any): VertexBuffer;
@@ -2665,6 +2717,7 @@ declare module BABYLON {
         public getVerticesDataKinds(): string[];
         public getTotalIndices(): number;
         public getIndices(): number[];
+        public isBlocked : boolean;
         public isReady(): boolean;
         public isDisposed(): boolean;
         public _preActivate(): void;
@@ -2775,6 +2828,13 @@ declare module BABYLON {
         static ComputeNormals(positions: number[], indices: number[], normals: number[]): void;
     }
 }
+declare module BABYLON.Internals {
+    class MeshLODLevel {
+        public distance: number;
+        public mesh: Mesh;
+        constructor(distance: number, mesh: Mesh);
+    }
+}
 declare module BABYLON {
     class SubMesh {
         public materialIndex: number;