Browse Source

first implementation - optimize

Mesh optimize will search for duplicate positions and will update the
indices to reference only one of them.
Raanan Weber 10 years ago
parent
commit
8e6fcdddcc
2 changed files with 72 additions and 1 deletions
  1. 35 1
      Babylon/Mesh/babylon.mesh.js
  2. 37 0
      Babylon/Mesh/babylon.mesh.ts

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

@@ -882,7 +882,7 @@ var BABYLON;
          */
         Mesh.prototype.simplify = function (settings, parallelProcessing, simplificationType, successCallback) {
             if (parallelProcessing === void 0) { parallelProcessing = true; }
-            if (simplificationType === void 0) { simplificationType = 0 /* QUADRATIC */; }
+            if (simplificationType === void 0) { simplificationType = BABYLON.SimplificationType.QUADRATIC; }
             this.getScene().simplificationQueue.addTask({
                 settings: settings,
                 parallelProcessing: parallelProcessing,
@@ -891,6 +891,40 @@ var BABYLON;
                 successCallback: successCallback
             });
         };
+        //The function doesn't delete unused vertex data, it simply restructure the indices to ignore them.
+        Mesh.prototype.optimize = function (successCallback) {
+            var indices = this.getIndices();
+            var positions = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
+            //optimize each submesh individually.
+            this.subMeshes.forEach(function (subMesh) {
+                var total = subMesh.indexStart + subMesh.indexCount;
+                var i;
+                var subMeshPositions = [];
+                for (i = subMesh.indexStart; i < total; ++i) {
+                    subMeshPositions[indices[i]] = subMeshPositions[indices[i]] || (BABYLON.Vector3.FromArray(positions, indices[i]));
+                }
+                var dupes = [];
+                for (i = subMeshPositions.length - 1; i >= 1; --i) {
+                    var testedPosition = subMeshPositions[i];
+					if(!testedPosition) continue;
+                    for (var j = 0; j < i; ++j) {
+                        var againstPosition = subMeshPositions[j];
+						if(!againstPosition) continue; 
+                        if (testedPosition.equals(againstPosition)) {
+                            dupes[i] = j;
+                            break;
+                        }
+                    }
+                }
+                for (i = subMesh.indexStart; i < total; ++i) {
+                    indices[i] = dupes[indices[i]] || indices[i];
+                }
+            });
+            //indices are now reordered
+            var originalSubMeshes = this.subMeshes.slice(0);
+            this.setIndices(indices);
+            this.subMeshes = originalSubMeshes;
+        };
         // Statics
         Mesh.CreateRibbon = function (name, pathArray, closeArray, closePath, offset, scene, updatable, sideOrientation) {
             if (sideOrientation === void 0) { sideOrientation = Mesh.DEFAULTSIDE; }

+ 37 - 0
Babylon/Mesh/babylon.mesh.ts

@@ -1090,6 +1090,43 @@
             });
         }
 
+        //The function doesn't delete unused vertex data, it simply restructure the indices to ignore them.
+        public optimize(successCallback?: (mesh?: Mesh) => void) {
+            var indices = this.getIndices();
+            var positions = this.getVerticesData(VertexBuffer.PositionKind);
+            
+            //optimize each submesh individually.
+            this.subMeshes.forEach(subMesh => {
+                var total = subMesh.indexStart + subMesh.indexCount;
+                var i;
+                var subMeshPositions: Array<Vector3> = []
+                for (i = subMesh.indexStart; i < total; ++i) {
+                    subMeshPositions[indices[i]] = subMeshPositions[indices[i]] || (BABYLON.Vector3.FromArray(positions, indices[i]));
+                }
+                var dupes = [];
+                //find duplicates
+                for (i = subMeshPositions.length - 1; i >= 1; --i) {
+                    var testedPosition = subMeshPositions[i];
+                    for (var j = 0; j < i; ++j) {
+                        var againstPosition = subMeshPositions[j];
+                        if (testedPosition.equals(againstPosition)) {
+                            dupes[i] = j;
+                            break;
+                        }
+                    }
+                }
+
+                
+                for (i = subMesh.indexStart; i < total; ++i) {
+                    indices[i] = dupes[indices[i]] || indices[i];
+                }
+            });
+            //indices are now reordered
+            var originalSubMeshes = this.subMeshes.slice(0);
+            this.setIndices(indices);
+            this.subMeshes = originalSubMeshes;
+        }
+
         // Statics
         public static CreateRibbon(name: string, pathArray: Vector3[][], closeArray: boolean, closePath: boolean, offset: number, scene: Scene, updatable?: boolean, sideOrientation: number = Mesh.DEFAULTSIDE): Mesh {
             var ribbon = new Mesh(name, scene);