Browse Source

Simplification improvements and bug fixes

It was assumed that all meshes have UVs. which is false. Color3 is now
supported.
The color3 FromArray function had to be extended to support the offset
needed.
Bug fix in async iteration (when not parallel, too may iterations would
be executed).
Triangles are now selected from the middle,. The assumption is that the
first and last indices are usually more "important". After inspection -
it improves almost all simplifications.
Raanan Weber 10 years ago
parent
commit
82016169e4

+ 3 - 5
Babylon/Math/babylon.math.js

@@ -102,7 +102,8 @@
         };
 
         // Statics
-        Color3.FromArray = function (array) {
+        Color3.FromArray = function (array, offset) {
+            if (typeof offset === "undefined") { offset = 0; }
             return new Color3(array[0], array[1], array[2]);
         };
 
@@ -384,10 +385,7 @@
         };
 
         Vector2.FromArray = function (array, offset) {
-            if (!offset) {
-                offset = 0;
-            }
-
+            if (typeof offset === "undefined") { offset = 0; }
             return new Vector2(array[offset], array[offset + 1]);
         };
 

+ 2 - 6
Babylon/Math/babylon.math.ts

@@ -95,7 +95,7 @@
         }
 
         // Statics
-        public static FromArray(array: number[]): Color3 {
+        public static FromArray(array: number[], offset:number = 0): Color3 {
             return new Color3(array[0], array[1], array[2]);
         }
 
@@ -349,11 +349,7 @@
             return new Vector2(0, 0);
         }
 
-        public static FromArray(array: number[], offset?: number): Vector2 {
-            if (!offset) {
-                offset = 0;
-            }
-
+        public static FromArray(array: number[], offset: number = 0): Vector2 {
             return new Vector2(array[offset], array[offset + 1]);
         }
 

+ 2 - 1
Babylon/Mesh/babylon.mesh.js

@@ -1049,7 +1049,8 @@ var BABYLON;
                     });
                 }, function () {
                     //execution ended, run the success callback.
-                    successCallback();
+                    if (successCallback)
+                        successCallback();
                 });
             }
         };

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

@@ -1052,9 +1052,10 @@
                         loop.executeNext();
                     });
                 }, () => {
-                        //execution ended, run the success callback.
+                    //execution ended, run the success callback.
+                    if(successCallback)
                         successCallback();
-                    });
+                });
             }
         }
 

+ 28 - 12
Babylon/Mesh/babylon.meshSimplification.js

@@ -147,16 +147,11 @@
                     var threshold = 0.000000001 * Math.pow((iteration + 3), _this.aggressiveness);
 
                     var trianglesIterator = function (i) {
-                        var t = _this.triangles[i];
+                        var tIdx = ((_this.triangles.length / 2) + i) % _this.triangles.length;
+                        var t = _this.triangles[tIdx];
                         if (!t)
                             return;
-                        if (t.error[3] > threshold) {
-                            return;
-                        }
-                        if (t.deleted) {
-                            return;
-                        }
-                        if (t.isDirty) {
+                        if (t.error[3] > threshold || t.deleted || t.isDirty) {
                             return;
                         }
                         for (var j = 0; j < 3; ++j) {
@@ -239,13 +234,23 @@
             this.triangles = [];
 
             this._mesh = mesh;
+
+            //It is assumed that a mesh has positions, normals and either uvs or colors.
             var positionData = this._mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
             var normalData = this._mesh.getVerticesData(BABYLON.VertexBuffer.NormalKind);
             var uvs = this._mesh.getVerticesData(BABYLON.VertexBuffer.UVKind);
+            var colorsData = this._mesh.getVerticesData(BABYLON.VertexBuffer.ColorKind);
             var indices = mesh.getIndices();
 
             var vertexInit = function (i) {
-                var vertex = new DecimationVertex(BABYLON.Vector3.FromArray(positionData, i * 3), BABYLON.Vector3.FromArray(normalData, i * 3), BABYLON.Vector2.FromArray(uvs, i * 2), i);
+                var uv;
+                if (uvs[i * 2]) {
+                    uv = BABYLON.Vector2.FromArray(uvs, i * 2);
+                }
+                var vertex = new DecimationVertex(BABYLON.Vector3.FromArray(positionData, i * 3), BABYLON.Vector3.FromArray(normalData, i * 3), uv, i);
+                if (!uv && colorsData[i * 3]) {
+                    vertex.color = BABYLON.Color3.FromArray(colorsData, i * 3);
+                }
                 _this.vertices.push(vertex);
             };
             var totalVertices = mesh.getTotalVertices();
@@ -332,6 +337,7 @@
             var newPositionData = [];
             var newNormalData = [];
             var newUVsData = [];
+            var newColorsData = [];
 
             for (i = 0; i < newVerticesOrder.length; ++i) {
                 newPositionData.push(this.vertices[i].position.x);
@@ -340,8 +346,14 @@
                 newNormalData.push(this.vertices[i].normal.x);
                 newNormalData.push(this.vertices[i].normal.y);
                 newNormalData.push(this.vertices[i].normal.z);
-                newUVsData.push(this.vertices[i].uv.x);
-                newUVsData.push(this.vertices[i].uv.y);
+                if (this.vertices[i].uv) {
+                    newUVsData.push(this.vertices[i].uv.x);
+                    newUVsData.push(this.vertices[i].uv.y);
+                } else if (this.vertices[i].color) {
+                    newColorsData.push(this.vertices[i].color.r);
+                    newColorsData.push(this.vertices[i].color.g);
+                    newColorsData.push(this.vertices[i].color.b);
+                }
             }
 
             var newIndicesArray = [];
@@ -351,13 +363,17 @@
                 newIndicesArray.push(newTriangles[i].vertices[2]);
             }
 
+            //not cloning, to avoid geometry problems. Creating a whole new mesh.
             var newMesh = new BABYLON.Mesh(this._mesh + "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);
-            newMesh.setVerticesData(BABYLON.VertexBuffer.UVKind, newUVsData);
+            if (newUVsData.length > 0)
+                newMesh.setVerticesData(BABYLON.VertexBuffer.UVKind, newUVsData);
+            if (newColorsData.length > 0)
+                newMesh.setVerticesData(BABYLON.VertexBuffer.ColorKind, newColorsData);
 
             //preparing the skeleton support
             if (this._mesh.skeleton) {

+ 30 - 8
Babylon/Mesh/babylon.meshSimplification.ts

@@ -59,6 +59,9 @@
         public triangleStart: number;
         public triangleCount: number;
 
+        //if color is present instead of uvs.
+        public color: Color3;
+
         constructor(public position: Vector3, public normal: Vector3, public uv: Vector2, public id) {
             this.isBorder = true;
             this.q = new QuadraticMatrix();
@@ -171,11 +174,10 @@
                     var threshold = 0.000000001 * Math.pow((iteration + 3), this.aggressiveness);
 
                     var trianglesIterator = (i) => {
-                        var t = this.triangles[i];
+                        var tIdx = ((this.triangles.length / 2) + i) % this.triangles.length;
+                        var t = this.triangles[tIdx];
                         if (!t) return;
-                        if (t.error[3] > threshold) { return }
-                        if (t.deleted) { return }
-                        if (t.isDirty) {  return }
+                        if (t.error[3] > threshold || t.deleted || t.isDirty ) { return }
                         for (var j = 0; j < 3; ++j) {
                             if (t.error[j] < threshold) {
                                 var deleted0: Array<boolean> = [];
@@ -248,13 +250,22 @@
             this.triangles = [];
 
             this._mesh = mesh;
+            //It is assumed that a mesh has positions, normals and either uvs or colors.
             var positionData = this._mesh.getVerticesData(VertexBuffer.PositionKind);
             var normalData = this._mesh.getVerticesData(VertexBuffer.NormalKind);
             var uvs = this._mesh.getVerticesData(VertexBuffer.UVKind);
+            var colorsData = this._mesh.getVerticesData(VertexBuffer.ColorKind);
             var indices = mesh.getIndices();
 
             var vertexInit = (i) => {
-                var vertex = new DecimationVertex(Vector3.FromArray(positionData, i * 3), Vector3.FromArray(normalData, i * 3), Vector2.FromArray(uvs, i * 2), i);
+                var uv;
+                if (uvs[i*2]) {
+                    uv = Vector2.FromArray(uvs, i * 2)
+                }
+                var vertex = new DecimationVertex(Vector3.FromArray(positionData, i * 3), Vector3.FromArray(normalData, i * 3), uv, i);
+                if (!uv && colorsData[i*3]) {
+                    vertex.color = Color3.FromArray(colorsData, i * 3);
+                }
                 this.vertices.push(vertex);
             };
             var totalVertices = mesh.getTotalVertices();
@@ -343,6 +354,7 @@
             var newPositionData = [];
             var newNormalData = [];
             var newUVsData = [];
+            var newColorsData = [];
 
             for (i = 0; i < newVerticesOrder.length; ++i) {
                 newPositionData.push(this.vertices[i].position.x);
@@ -351,8 +363,14 @@
                 newNormalData.push(this.vertices[i].normal.x);
                 newNormalData.push(this.vertices[i].normal.y);
                 newNormalData.push(this.vertices[i].normal.z);
-                newUVsData.push(this.vertices[i].uv.x);
-                newUVsData.push(this.vertices[i].uv.y);
+                if (this.vertices[i].uv) {
+                    newUVsData.push(this.vertices[i].uv.x);
+                    newUVsData.push(this.vertices[i].uv.y);
+                } else if (this.vertices[i].color) {
+                    newColorsData.push(this.vertices[i].color.r);
+                    newColorsData.push(this.vertices[i].color.g);
+                    newColorsData.push(this.vertices[i].color.b);
+                }
             }
 
             var newIndicesArray: Array<number> = [];
@@ -362,13 +380,17 @@
                 newIndicesArray.push(newTriangles[i].vertices[2]);
             }
 
+            //not cloning, to avoid geometry problems. Creating a whole new mesh.
             var newMesh = new Mesh(this._mesh + "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);
-            newMesh.setVerticesData(VertexBuffer.UVKind, newUVsData);
+            if(newUVsData.length > 0)
+                newMesh.setVerticesData(VertexBuffer.UVKind, newUVsData);
+            if (newColorsData.length > 0) 
+                newMesh.setVerticesData(VertexBuffer.ColorKind, newColorsData);
             //preparing the skeleton support
             if (this._mesh.skeleton) {
                 //newMesh.skeleton = this._mesh.skeleton.clone("", "");

+ 1 - 1
Babylon/Tools/babylon.tools.js

@@ -839,7 +839,7 @@
         */
         AsyncLoop.prototype.executeNext = function () {
             if (!this._done) {
-                if (this.index < this.iterations) {
+                if (this.index + 1 < this.iterations) {
                     ++this.index;
                     this._fn(this);
                 } else {

+ 1 - 1
Babylon/Tools/babylon.tools.ts

@@ -823,7 +823,7 @@
          */
         public executeNext(): void {
             if (!this._done) {
-                if (this.index < this.iterations) {
+                if (this.index + 1 < this.iterations) {
                     ++this.index;
                     this._fn(this);
                 } else {