소스 검색

clean bone weights

László Matuska 8 년 전
부모
커밋
064c6d3d9b
2개의 변경된 파일86개의 추가작업 그리고 20개의 파일을 삭제
  1. 38 1
      src/Loading/babylon.sceneLoader.ts
  2. 48 19
      src/Mesh/babylon.geometry.ts

+ 38 - 1
src/Loading/babylon.sceneLoader.ts

@@ -189,6 +189,37 @@
             }
         }
 
+        private static _CleanMatricesIndices(meshes:AbstractMesh[]): void {
+            if (!SceneLoader._CleanBoneMatrixWeights) {
+                return;
+            }
+            for (var i = 0; i < meshes.length; i++) {
+                var mesh = meshes[i];
+                if (mesh.skeleton) {
+                    var noinfluenceBoneIndex = mesh.skeleton.bones.length;
+                    var matricesIndices: number[] | Float32Array = mesh.getVerticesData(VertexBuffer.MatricesIndicesKind);
+                    var matricesIndicesExtra: number[] | Float32Array = mesh.getVerticesData(VertexBuffer.MatricesIndicesExtraKind);    
+                    if (matricesIndices) {
+                        let size = matricesIndices.length;
+                        for (var j = 0; j < size; j++) {
+                            if (matricesIndices[j] < 0) {
+                                matricesIndices[j] = noinfluenceBoneIndex;
+                            }
+                        }
+                        mesh.setVerticesData(VertexBuffer.MatricesIndicesKind, matricesIndices);
+                        if (matricesIndicesExtra) {
+                            for (var j = 0; j < size; j++) {
+                                if (matricesIndicesExtra[j] < 0.0) {
+                                    matricesIndicesExtra[j] = noinfluenceBoneIndex;
+                                }
+                            }
+                            mesh.setVerticesData(VertexBuffer.MatricesIndicesExtraKind, matricesIndicesExtra);
+                        }                    
+                    }    
+                }
+            }
+        }
+
         // Public functions
         public static GetPluginForExtension(extension: string): ISceneLoaderPlugin | ISceneLoaderPluginAsync {
             return SceneLoader._getPluginForExtension(extension).plugin;
@@ -258,7 +289,9 @@
                     if (!syncedPlugin.importMesh(meshNames, scene, data, rootUrl, meshes, particleSystems, skeletons, errorHandler)) {
                         return;
                     }
-
+                    
+                    SceneLoader._CleanMatricesIndices(meshes);
+                    
                     if (onSuccess) {
                         // wrap onSuccess with try-catch to know if something went wrong.
                         try {
@@ -274,6 +307,9 @@
                 else {
                     var asyncedPlugin = <ISceneLoaderPluginAsync>plugin;
                     asyncedPlugin.importMeshAsync(meshNames, scene, data, rootUrl, (meshes, particleSystems, skeletons) => {
+
+                        SceneLoader._CleanMatricesIndices(meshes);
+
                         if (onSuccess) {
                             try {
                                 scene.importedMeshesFiles.push(rootUrl + sceneFilename);
@@ -362,6 +398,7 @@
                 } else {
                     var asyncedPlugin = <ISceneLoaderPluginAsync>plugin;
                     asyncedPlugin.loadAsync(scene, data, rootUrl, () => {
+                        SceneLoader._CleanMatricesIndices(scene.meshes);
                         if (onSuccess) {
                             onSuccess(scene);
                         }

+ 48 - 19
src/Mesh/babylon.geometry.ts

@@ -959,13 +959,15 @@
                 }
 
                 if (parsedGeometry.matricesWeights) {
-                    Geometry._CleanMatricesWeights(parsedGeometry.matricesWeights, parsedGeometry.numBoneInfluencers);
+                    var matricesIndices: number[] | Float32Array = mesh.getVerticesData(VertexBuffer.MatricesIndicesKind);
+                    var matricesIndicesExtra: number[] | Float32Array = mesh.getVerticesData(VertexBuffer.MatricesIndicesExtraKind);
+                    Geometry._CleanMatricesWeights(parsedGeometry.matricesWeights,matricesIndex,parsedGeometry.matricesWeightsExtra,matricesIndicesExtra,parsedGeometry.numBoneInfluencers);
                     mesh.setVerticesData(VertexBuffer.MatricesWeightsKind, parsedGeometry.matricesWeights, parsedGeometry.matricesWeights._updatable);
-                }
-
-                if (parsedGeometry.matricesWeightsExtra) {                    
-                    Geometry._CleanMatricesWeights(parsedGeometry.matricesWeightsExtra, parsedGeometry.numBoneInfluencers);
-                    mesh.setVerticesData(VertexBuffer.MatricesWeightsExtraKind, parsedGeometry.matricesWeightsExtra, parsedGeometry.matricesWeights._updatable);
+                    mesh.setVerticesData(VertexBuffer.MatricesIndicesKind, matricesIndices);
+                    if (parsedGeometry.matricesWeightsExtra) {       
+                        mesh.setVerticesData(VertexBuffer.MatricesWeightsExtraKind, parsedGeometry.matricesWeightsExtra, parsedGeometry.matricesWeights._updatable);
+                        mesh.setVerticesData(VertexBuffer.MatricesIndicesExtraKind, matricesIndicesExtra);
+                    }
                 }
 
                 mesh.setIndices(parsedGeometry.indices);
@@ -996,25 +998,52 @@
             }
         }
 
-        private static _CleanMatricesWeights(matricesWeights: number[], influencers: number): void {
+        private static _CleanMatricesWeights(matricesWeights: number[] | Float32Array, matricesIndices: number[] | Float32Array, matricesWeightsExtra: number[] | Float32Array, matricesIndicesExtra: number[] | Float32Array, influencers: number): void {
             if (!SceneLoader.CleanBoneMatrixWeights) {
                 return;
             }
             let size = matricesWeights.length;
-            for (var i = 0; i < size; i += influencers) {
-                let weight = 0;
-                let biggerIndex = i;
-                let biggerWeight = 0;
-                for (var j = 0; j < influencers - 1; j++) {
-                    weight += matricesWeights[i + j];
-
-                    if (matricesWeights[i + j] > biggerWeight) {
-                        biggerWeight = matricesWeights[i + j];
-                        biggerIndex = i + j;
+            for (var i = 0; i < size; i += 4) {
+                let weight = 0.0;
+                let firstZeroWeight = -1;
+                for (var j = 0; j < 4; j++) {
+                    let w = matricesWeights[i + j];
+                    weight += w;
+                    if (w < 1e-3 && firstZeroWeight < 0) {
+                        firstZeroWeight = j;
+                    }
+                }
+                if (matricesWeightsExtra) {
+                    for (var j = 0; j < 4; j++) {
+                        let w = matricesWeightsExtra[i + j];
+                        weight += w;
+                        if (w < 1e-3 && firstZeroWeight < 0) {
+                            firstZeroWeight = j + 4;
+                        }
+                    }
+                }
+                if (firstZeroWeight < 0  || firstZeroWeight > (influencers-1)) {
+                    firstZeroWeight = influencers-1;
+                }
+                if (weight > 1e-3) {
+                    let mweight = 1.0/weight;
+                    for (var j = 0; j < 4; j++) {
+                        matricesWeights[i + j] *= mweight;
+                    }
+                    if (matricesWeightsExtra) {
+                        for (var j = 0; j < 4; j++) {
+                            matricesWeightsExtra[i + j] *= mweight;
+                        }    
+                    }
+                } else {
+                    if (firstZeroWeight>=4) {
+                        matricesWeightsExtra[i+firstZeroWeight-4] = 1.0 - weight;
+                        matricesIndicesExtra[i+firstZeroWeight-4] = -1.0;
+                    } else {
+                        matricesWeights[i+firstZeroWeight] = 1.0 - weight;
+                        matricesIndices[i+firstZeroWeight] = -1.0;    
                     }
                 }
-
-                matricesWeights[biggerIndex] += Math.max(0, 1.0 - weight);
             }
         }