Browse Source

SubMeshes in reconstruction

Sub meshes are now being processed in the decimation function using the
AsyncLoop.
After all submeshes has finished, the successcallback is executed.
reconstctedMesh should have all submeshes.
Raanan Weber 10 years ago
parent
commit
e380e72d01

+ 15 - 10
Babylon/Mesh/babylon.mesh.js

@@ -137,6 +137,15 @@ var BABYLON;
             this._sortLODLevels();
             return this;
         };
+        Mesh.prototype.getLODLevelAtDistance = function (distance) {
+            for (var index = 0; index < this._LODLevels.length; index++) {
+                var level = this._LODLevels[index];
+                if (level.distance === distance) {
+                    return level.mesh;
+                }
+            }
+            return null;
+        };
         /**
          * Remove a mesh from the LOD array
          * @param {BABYLON.Mesh} mesh - the mesh to be removed.
@@ -872,18 +881,14 @@ var BABYLON;
          * successCallback optional success callback to be called after the simplification finished processing all settings.
          */
         Mesh.prototype.simplify = function (settings, parallelProcessing, simplificationType, successCallback) {
-            var _this = this;
             if (parallelProcessing === void 0) { parallelProcessing = true; }
             if (simplificationType === void 0) { simplificationType = BABYLON.SimplificationType.QUADRATIC; }
-            this.subMeshes.forEach(function (submesh, index) {
-                _this.getScene().simplificationQueue.addTask({
-                    settings: settings,
-                    parallelProcessing: parallelProcessing,
-                    mesh: _this,
-                    submeshIndex: index,
-                    simplificationType: simplificationType,
-                    successCallback: successCallback
-                });
+            this.getScene().simplificationQueue.addTask({
+                settings: settings,
+                parallelProcessing: parallelProcessing,
+                mesh: this,
+                simplificationType: simplificationType,
+                successCallback: successCallback
             });
         };
         // Statics

+ 19 - 11
Babylon/Mesh/babylon.mesh.ts

@@ -148,6 +148,17 @@
             return this;
         }
 
+        public getLODLevelAtDistance(distance: number) : Mesh {
+            for (var index = 0; index < this._LODLevels.length; index++) {
+                var level = this._LODLevels[index];
+
+                if (level.distance === distance) {
+                    return level.mesh;
+                }
+            }
+            return null;
+        }
+
         /**
          * Remove a mesh from the LOD array
          * @param {BABYLON.Mesh} mesh - the mesh to be removed.
@@ -1069,17 +1080,14 @@
          * @param type the type of simplification to run.
          * successCallback optional success callback to be called after the simplification finished processing all settings.
          */
-        public simplify(settings: Array<ISimplificationSettings>, parallelProcessing: boolean = true, simplificationType: SimplificationType = SimplificationType.QUADRATIC, successCallback?: () => void) {
-            this.subMeshes.forEach((submesh, index) => {
-                this.getScene().simplificationQueue.addTask({
-                    settings: settings,
-                    parallelProcessing: parallelProcessing,
-                    mesh: this,
-                    submeshIndex:index,
-                    simplificationType: simplificationType,
-                    successCallback: successCallback
-                });  
-            }); 
+        public simplify(settings: Array<ISimplificationSettings>, parallelProcessing: boolean = true, simplificationType: SimplificationType = SimplificationType.QUADRATIC, successCallback?: (mesh?: Mesh, submeshIndex?: number) => void) {
+            this.getScene().simplificationQueue.addTask({
+                settings: settings,
+                parallelProcessing: parallelProcessing,
+                mesh: this,
+                simplificationType: simplificationType,
+                successCallback: successCallback
+            });  
         }
 
         // Statics

+ 40 - 24
Babylon/Mesh/babylon.meshSimplification.js

@@ -28,6 +28,8 @@ var BABYLON;
         };
         SimplificationQueue.prototype.runSimplification = function (task) {
             var _this = this;
+            function setLODLevel(distance, mesh) {
+            }
             if (task.parallelProcessing) {
                 //parallel simplifier
                 task.settings.forEach(function (setting) {
@@ -70,7 +72,7 @@ var BABYLON;
             switch (task.simplificationType) {
                 case 0 /* QUADRATIC */:
                 default:
-                    return new QuadraticErrorSimplification(task.mesh, task.submeshIndex);
+                    return new QuadraticErrorSimplification(task.mesh);
             }
         };
         return SimplificationQueue;
@@ -167,10 +169,8 @@ var BABYLON;
      * @author RaananW
      */
     var QuadraticErrorSimplification = (function () {
-        function QuadraticErrorSimplification(_mesh, _submeshIndex) {
-            if (_submeshIndex === void 0) { _submeshIndex = 0; }
+        function QuadraticErrorSimplification(_mesh) {
             this._mesh = _mesh;
-            this._submeshIndex = _submeshIndex;
             this.initialised = false;
             this.syncIterations = 5000;
             this.aggressiveness = 7;
@@ -179,8 +179,17 @@ var BABYLON;
         }
         QuadraticErrorSimplification.prototype.simplify = function (settings, successCallback) {
             var _this = this;
-            this.initWithMesh(this._mesh, this._submeshIndex, function () {
-                _this.runDecimation(settings, successCallback);
+            //iterating through the submeshes array, one after the other.
+            BABYLON.AsyncLoop.Run(this._mesh.subMeshes.length, function (loop) {
+                _this.initWithMesh(_this._mesh, loop.index, function () {
+                    _this.runDecimation(settings, loop.index, function () {
+                        loop.executeNext();
+                    });
+                });
+            }, function () {
+                setTimeout(function () {
+                    successCallback(_this._reconstructedMesh);
+                }, 0);
             });
         };
         QuadraticErrorSimplification.prototype.isTriangleOnBoundingBox = function (triangle) {
@@ -206,7 +215,7 @@ var BABYLON;
             }
             return gCount > 1;
         };
-        QuadraticErrorSimplification.prototype.runDecimation = function (settings, successCallback) {
+        QuadraticErrorSimplification.prototype.runDecimation = function (settings, submeshIndex, successCallback) {
             var _this = this;
             var targetCount = ~~(this.triangles.length * settings.quality);
             var deletedTriangles = 0;
@@ -296,7 +305,8 @@ var BABYLON;
                 }
             }, function () {
                 setTimeout(function () {
-                    successCallback(_this.reconstructMesh());
+                    _this.reconstructMesh(submeshIndex);
+                    successCallback();
                 }, 0);
             });
         };
@@ -365,7 +375,7 @@ var BABYLON;
                 });
             });
         };
-        QuadraticErrorSimplification.prototype.reconstructMesh = function () {
+        QuadraticErrorSimplification.prototype.reconstructMesh = function (submeshIndex) {
             var newTriangles = [];
             var i;
             for (i = 0; i < this.vertices.length; ++i) {
@@ -403,10 +413,10 @@ var BABYLON;
                 }
             }
             this.vertices = this.vertices.slice(0, dst);
-            var newPositionData = [];
-            var newNormalData = [];
-            var newUVsData = [];
-            var newColorsData = [];
+            var newPositionData = this._reconstructedMesh.getVerticesData(BABYLON.VertexBuffer.PositionKind); //[];
+            var newNormalData = this._reconstructedMesh.getVerticesData(BABYLON.VertexBuffer.NormalKind); //[];
+            var newUVsData = this._reconstructedMesh.getVerticesData(BABYLON.VertexBuffer.UVKind); //[];
+            var newColorsData = this._reconstructedMesh.getVerticesData(BABYLON.VertexBuffer.ColorKind); //[];
             for (i = 0; i < newVerticesOrder.length; ++i) {
                 newPositionData.push(this.vertices[i].position.x);
                 newPositionData.push(this.vertices[i].position.y);
@@ -425,27 +435,33 @@ var BABYLON;
                     newColorsData.push(this.vertices[i].color.a);
                 }
             }
-            var newIndicesArray = [];
+            var newIndicesArray = this._reconstructedMesh.getIndices(); //[];
             for (i = 0; i < newTriangles.length; ++i) {
                 newIndicesArray.push(newTriangles[i].vertices[0]);
                 newIndicesArray.push(newTriangles[i].vertices[1]);
                 newIndicesArray.push(newTriangles[i].vertices[2]);
             }
-            //not cloning, to avoid geometry problems. Creating a whole new mesh.
-            var newMesh = new BABYLON.Mesh(this._mesh.name + "Decimated", this._mesh.getScene());
-            newMesh.material = this._mesh.material;
-            newMesh.parent = this._mesh.parent;
-            newMesh.setIndices(newIndicesArray);
-            newMesh.setVerticesData(BABYLON.VertexBuffer.PositionKind, newPositionData);
-            newMesh.setVerticesData(BABYLON.VertexBuffer.NormalKind, newNormalData);
+            var startingVertex = this._reconstructedMesh.getTotalVertices();
+            var startingIndex = this._reconstructedMesh.getTotalIndices();
+            this._reconstructedMesh.setIndices(newIndicesArray);
+            this._reconstructedMesh.setVerticesData(BABYLON.VertexBuffer.PositionKind, newPositionData);
+            this._reconstructedMesh.setVerticesData(BABYLON.VertexBuffer.NormalKind, newNormalData);
             if (newUVsData.length > 0)
-                newMesh.setVerticesData(BABYLON.VertexBuffer.UVKind, newUVsData);
+                this._reconstructedMesh.setVerticesData(BABYLON.VertexBuffer.UVKind, newUVsData);
             if (newColorsData.length > 0)
-                newMesh.setVerticesData(BABYLON.VertexBuffer.ColorKind, newColorsData);
+                this._reconstructedMesh.setVerticesData(BABYLON.VertexBuffer.ColorKind, newColorsData);
             //preparing the skeleton support
             if (this._mesh.skeleton) {
             }
-            return newMesh;
+            //create submesh
+            var originalSubmesh = this._mesh.subMeshes[submeshIndex];
+            var newSubmesh = new BABYLON.SubMesh(originalSubmesh.materialIndex, startingVertex, newVerticesOrder.length, startingIndex, newTriangles.length, this._reconstructedMesh);
+            //return newMesh;
+        };
+        QuadraticErrorSimplification.prototype.initDecimatedMesh = function () {
+            this._reconstructedMesh = new BABYLON.Mesh(this._mesh.name + "Decimated", this._mesh.getScene());
+            this._reconstructedMesh.material = this._mesh.material;
+            this._reconstructedMesh.parent = this._mesh.parent;
         };
         QuadraticErrorSimplification.prototype.isFlipped = function (vertex1, index2, point, deletedArray, borderFactor, delTr) {
             for (var i = 0; i < vertex1.triangleCount; ++i) {

+ 49 - 25
Babylon/Mesh/babylon.meshSimplification.ts

@@ -34,7 +34,6 @@
         simplificationType: SimplificationType;
         mesh: Mesh;
         successCallback? : () => void;
-        submeshIndex: number;
         parallelProcessing: boolean;
     }
     
@@ -62,6 +61,11 @@
         }
 
         public runSimplification(task: ISimplificationTask) {
+
+            function setLODLevel(distance: number, mesh: Mesh) {
+
+            }
+
             if (task.parallelProcessing) {
                 //parallel simplifier
                 task.settings.forEach((setting) => {
@@ -106,7 +110,7 @@
             switch (task.simplificationType) {
                 case SimplificationType.QUADRATIC:
                 default:
-                    return new QuadraticErrorSimplification(task.mesh, task.submeshIndex);
+                    return new QuadraticErrorSimplification(task.mesh);
             }
         }
     }
@@ -221,6 +225,8 @@
 
         private initialised: boolean = false;
 
+        private _reconstructedMesh: Mesh;
+
         public syncIterations = 5000;
 
         public aggressiveness: number;
@@ -228,16 +234,25 @@
 
         public boundingBoxEpsilon: number;
 
-        constructor(private _mesh: Mesh, private _submeshIndex:number = 0) {
+        constructor(private _mesh: Mesh) {
             this.aggressiveness = 7;
             this.decimationIterations = 100;
             this.boundingBoxEpsilon = Engine.Epsilon;
         }
 
-        public simplify(settings: ISimplificationSettings, successCallback: (simplifiedMeshes: Mesh) => void) {
-            this.initWithMesh(this._mesh, this._submeshIndex, () => {
-                this.runDecimation(settings, successCallback);
-            });
+        public simplify(settings: ISimplificationSettings, successCallback: (simplifiedMesh: Mesh) => void) {
+            //iterating through the submeshes array, one after the other.
+            AsyncLoop.Run(this._mesh.subMeshes.length,(loop: AsyncLoop) => {
+                this.initWithMesh(this._mesh, loop.index,() => {
+                    this.runDecimation(settings, loop.index, () => {
+                        loop.executeNext();
+                    });
+                });
+            },() => {
+                    setTimeout(() => {
+                        successCallback(this._reconstructedMesh);
+                    }, 0);
+                });
         }
 
         private isTriangleOnBoundingBox(triangle: DecimationTriangle): boolean {
@@ -267,7 +282,7 @@
             
         }
 
-        private runDecimation(settings: ISimplificationSettings, successCallback: (simplifiedMeshes: Mesh) => void) {
+        private runDecimation(settings: ISimplificationSettings, submeshIndex:number, successCallback: () => void) {
             var targetCount = ~~(this.triangles.length * settings.quality);
             var deletedTriangles = 0;
 
@@ -365,7 +380,8 @@
                 }
             },() => {
                     setTimeout(() => {
-                        successCallback(this.reconstructMesh());
+                        this.reconstructMesh(submeshIndex);
+                        successCallback();
                     }, 0);
                 });
         }
@@ -438,7 +454,7 @@
             });
         }
 
-        private reconstructMesh(): Mesh {
+        private reconstructMesh(submeshIndex: number) {
 
             var newTriangles: Array<DecimationTriangle> = [];
             var i: number;
@@ -481,10 +497,10 @@
             }
             this.vertices = this.vertices.slice(0, dst);
 
-            var newPositionData = [];
-            var newNormalData = [];
-            var newUVsData = [];
-            var newColorsData = [];
+            var newPositionData = this._reconstructedMesh.getVerticesData(VertexBuffer.PositionKind);//[];
+            var newNormalData = this._reconstructedMesh.getVerticesData(VertexBuffer.NormalKind);//[];
+            var newUVsData = this._reconstructedMesh.getVerticesData(VertexBuffer.UVKind);//[];
+            var newColorsData = this._reconstructedMesh.getVerticesData(VertexBuffer.ColorKind);//[];
 
             for (i = 0; i < newVerticesOrder.length; ++i) {
                 newPositionData.push(this.vertices[i].position.x);
@@ -504,24 +520,23 @@
                 }
             }
 
-            var newIndicesArray: Array<number> = [];
+            var newIndicesArray: Array<number> = this._reconstructedMesh.getIndices(); //[];
             for (i = 0; i < newTriangles.length; ++i) {
                 newIndicesArray.push(newTriangles[i].vertices[0]);
                 newIndicesArray.push(newTriangles[i].vertices[1]);
                 newIndicesArray.push(newTriangles[i].vertices[2]);
             }
+            
+            var startingVertex = this._reconstructedMesh.getTotalVertices();
+            var startingIndex = this._reconstructedMesh.getTotalIndices();
 
-            //not cloning, to avoid geometry problems. Creating a whole new mesh.
-            var newMesh = new Mesh(this._mesh.name + "Decimated", this._mesh.getScene());
-            newMesh.material = this._mesh.material;
-            newMesh.parent = this._mesh.parent;
-            newMesh.setIndices(newIndicesArray);
-            newMesh.setVerticesData(VertexBuffer.PositionKind, newPositionData);
-            newMesh.setVerticesData(VertexBuffer.NormalKind, newNormalData);
+            this._reconstructedMesh.setIndices(newIndicesArray);
+            this._reconstructedMesh.setVerticesData(VertexBuffer.PositionKind, newPositionData);
+            this._reconstructedMesh.setVerticesData(VertexBuffer.NormalKind, newNormalData);
             if (newUVsData.length > 0)
-                newMesh.setVerticesData(VertexBuffer.UVKind, newUVsData);
+                this._reconstructedMesh.setVerticesData(VertexBuffer.UVKind, newUVsData);
             if (newColorsData.length > 0)
-                newMesh.setVerticesData(VertexBuffer.ColorKind, newColorsData);
+                this._reconstructedMesh.setVerticesData(VertexBuffer.ColorKind, newColorsData);
 
             //preparing the skeleton support
             if (this._mesh.skeleton) {
@@ -529,7 +544,16 @@
                 //newMesh.getScene().beginAnimation(newMesh.skeleton, 0, 100, true, 1.0);
             }
 
-            return newMesh;
+            //create submesh
+            var originalSubmesh = this._mesh.subMeshes[submeshIndex];
+            var newSubmesh = new SubMesh(originalSubmesh.materialIndex, startingVertex, newVerticesOrder.length, startingIndex, newTriangles.length, this._reconstructedMesh);
+            //return newMesh;
+        }
+
+        private initDecimatedMesh() {
+            this._reconstructedMesh = new Mesh(this._mesh.name + "Decimated", this._mesh.getScene());
+            this._reconstructedMesh.material = this._mesh.material;
+            this._reconstructedMesh.parent = this._mesh.parent;
         }
 
         private isFlipped(vertex1: DecimationVertex, index2: number, point: Vector3, deletedArray: Array<boolean>, borderFactor: number, delTr: Array<DecimationTriangle>): boolean {