Переглянути джерело

Simplification improvements and bug fixes

It was assumes that all meshes have UVs. which is false. Color3 is now
supported.
The color3 FromArray function had to be extended to support the offset
need.
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 роки тому
батько
коміт
dc9b3f48bc

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

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

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

@@ -95,7 +95,7 @@
         }
         }
 
 
         // Statics
         // 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]);
             return new Color3(array[0], array[1], array[2]);
         }
         }
 
 
@@ -349,11 +349,7 @@
             return new Vector2(0, 0);
             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]);
             return new Vector2(array[offset], array[offset + 1]);
         }
         }
 
 

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

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

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

@@ -1053,7 +1053,8 @@
                         });
                         });
                 }, () => {
                 }, () => {
                     //execution ended, run the success callback.
                     //execution ended, run the success callback.
-                    successCallback();
+                    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 threshold = 0.000000001 * Math.pow((iteration + 3), _this.aggressiveness);
 
 
                     var trianglesIterator = function (i) {
                     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)
                         if (!t)
                             return;
                             return;
-                        if (t.error[3] > threshold) {
-                            return;
-                        }
-                        if (t.deleted) {
-                            return;
-                        }
-                        if (t.isDirty) {
+                        if (t.error[3] > threshold || t.deleted || t.isDirty) {
                             return;
                             return;
                         }
                         }
                         for (var j = 0; j < 3; ++j) {
                         for (var j = 0; j < 3; ++j) {
@@ -239,13 +234,23 @@
             this.triangles = [];
             this.triangles = [];
 
 
             this._mesh = mesh;
             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 positionData = this._mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
             var normalData = this._mesh.getVerticesData(BABYLON.VertexBuffer.NormalKind);
             var normalData = this._mesh.getVerticesData(BABYLON.VertexBuffer.NormalKind);
             var uvs = this._mesh.getVerticesData(BABYLON.VertexBuffer.UVKind);
             var uvs = this._mesh.getVerticesData(BABYLON.VertexBuffer.UVKind);
+            var colorsData = this._mesh.getVerticesData(BABYLON.VertexBuffer.ColorKind);
             var indices = mesh.getIndices();
             var indices = mesh.getIndices();
 
 
             var vertexInit = function (i) {
             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);
                 _this.vertices.push(vertex);
             };
             };
             var totalVertices = mesh.getTotalVertices();
             var totalVertices = mesh.getTotalVertices();
@@ -332,6 +337,7 @@
             var newPositionData = [];
             var newPositionData = [];
             var newNormalData = [];
             var newNormalData = [];
             var newUVsData = [];
             var newUVsData = [];
+            var newColorsData = [];
 
 
             for (i = 0; i < newVerticesOrder.length; ++i) {
             for (i = 0; i < newVerticesOrder.length; ++i) {
                 newPositionData.push(this.vertices[i].position.x);
                 newPositionData.push(this.vertices[i].position.x);
@@ -340,8 +346,14 @@
                 newNormalData.push(this.vertices[i].normal.x);
                 newNormalData.push(this.vertices[i].normal.x);
                 newNormalData.push(this.vertices[i].normal.y);
                 newNormalData.push(this.vertices[i].normal.y);
                 newNormalData.push(this.vertices[i].normal.z);
                 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 = [];
             var newIndicesArray = [];
@@ -351,13 +363,17 @@
                 newIndicesArray.push(newTriangles[i].vertices[2]);
                 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());
             var newMesh = new BABYLON.Mesh(this._mesh + "Decimated", this._mesh.getScene());
             newMesh.material = this._mesh.material;
             newMesh.material = this._mesh.material;
             newMesh.parent = this._mesh.parent;
             newMesh.parent = this._mesh.parent;
             newMesh.setIndices(newIndicesArray);
             newMesh.setIndices(newIndicesArray);
             newMesh.setVerticesData(BABYLON.VertexBuffer.PositionKind, newPositionData);
             newMesh.setVerticesData(BABYLON.VertexBuffer.PositionKind, newPositionData);
             newMesh.setVerticesData(BABYLON.VertexBuffer.NormalKind, newNormalData);
             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
             //preparing the skeleton support
             if (this._mesh.skeleton) {
             if (this._mesh.skeleton) {

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

@@ -59,6 +59,9 @@
         public triangleStart: number;
         public triangleStart: number;
         public triangleCount: 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) {
         constructor(public position: Vector3, public normal: Vector3, public uv: Vector2, public id) {
             this.isBorder = true;
             this.isBorder = true;
             this.q = new QuadraticMatrix();
             this.q = new QuadraticMatrix();
@@ -171,11 +174,10 @@
                     var threshold = 0.000000001 * Math.pow((iteration + 3), this.aggressiveness);
                     var threshold = 0.000000001 * Math.pow((iteration + 3), this.aggressiveness);
 
 
                     var trianglesIterator = (i) => {
                     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) 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) {
                         for (var j = 0; j < 3; ++j) {
                             if (t.error[j] < threshold) {
                             if (t.error[j] < threshold) {
                                 var deleted0: Array<boolean> = [];
                                 var deleted0: Array<boolean> = [];
@@ -248,13 +250,22 @@
             this.triangles = [];
             this.triangles = [];
 
 
             this._mesh = mesh;
             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 positionData = this._mesh.getVerticesData(VertexBuffer.PositionKind);
             var normalData = this._mesh.getVerticesData(VertexBuffer.NormalKind);
             var normalData = this._mesh.getVerticesData(VertexBuffer.NormalKind);
             var uvs = this._mesh.getVerticesData(VertexBuffer.UVKind);
             var uvs = this._mesh.getVerticesData(VertexBuffer.UVKind);
+            var colorsData = this._mesh.getVerticesData(VertexBuffer.ColorKind);
             var indices = mesh.getIndices();
             var indices = mesh.getIndices();
 
 
             var vertexInit = (i) => {
             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);
                 this.vertices.push(vertex);
             };
             };
             var totalVertices = mesh.getTotalVertices();
             var totalVertices = mesh.getTotalVertices();
@@ -343,6 +354,7 @@
             var newPositionData = [];
             var newPositionData = [];
             var newNormalData = [];
             var newNormalData = [];
             var newUVsData = [];
             var newUVsData = [];
+            var newColorsData = [];
 
 
             for (i = 0; i < newVerticesOrder.length; ++i) {
             for (i = 0; i < newVerticesOrder.length; ++i) {
                 newPositionData.push(this.vertices[i].position.x);
                 newPositionData.push(this.vertices[i].position.x);
@@ -351,8 +363,14 @@
                 newNormalData.push(this.vertices[i].normal.x);
                 newNormalData.push(this.vertices[i].normal.x);
                 newNormalData.push(this.vertices[i].normal.y);
                 newNormalData.push(this.vertices[i].normal.y);
                 newNormalData.push(this.vertices[i].normal.z);
                 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> = [];
             var newIndicesArray: Array<number> = [];
@@ -362,13 +380,17 @@
                 newIndicesArray.push(newTriangles[i].vertices[2]);
                 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());
             var newMesh = new Mesh(this._mesh + "Decimated", this._mesh.getScene());
             newMesh.material = this._mesh.material;
             newMesh.material = this._mesh.material;
             newMesh.parent = this._mesh.parent;
             newMesh.parent = this._mesh.parent;
             newMesh.setIndices(newIndicesArray);
             newMesh.setIndices(newIndicesArray);
             newMesh.setVerticesData(VertexBuffer.PositionKind, newPositionData);
             newMesh.setVerticesData(VertexBuffer.PositionKind, newPositionData);
             newMesh.setVerticesData(VertexBuffer.NormalKind, newNormalData);
             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
             //preparing the skeleton support
             if (this._mesh.skeleton) {
             if (this._mesh.skeleton) {
                 //newMesh.skeleton = this._mesh.skeleton.clone("", "");
                 //newMesh.skeleton = this._mesh.skeleton.clone("", "");

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

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

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

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