Selaa lähdekoodia

Merge pull request #2893 from BitOfGold/master

clean bone matrice weights - shadow problem #2
David Catuhe 7 vuotta sitten
vanhempi
commit
d1929e056a
1 muutettua tiedostoa jossa 60 lisäystä ja 15 poistoa
  1. 60 15
      src/Mesh/babylon.geometry.ts

+ 60 - 15
src/Mesh/babylon.geometry.ts

@@ -959,12 +959,11 @@
                 }
 
                 if (parsedGeometry.matricesWeights) {
-                    Geometry._CleanMatricesWeights(parsedGeometry.matricesWeights, parsedGeometry.numBoneInfluencers);
+                    Geometry._CleanMatricesWeights(parsedGeometry, mesh);
                     mesh.setVerticesData(VertexBuffer.MatricesWeightsKind, parsedGeometry.matricesWeights, parsedGeometry.matricesWeights._updatable);
                 }
 
-                if (parsedGeometry.matricesWeightsExtra) {                    
-                    Geometry._CleanMatricesWeights(parsedGeometry.matricesWeightsExtra, parsedGeometry.numBoneInfluencers);
+                if (parsedGeometry.matricesWeightsExtra) {       
                     mesh.setVerticesData(VertexBuffer.MatricesWeightsExtraKind, parsedGeometry.matricesWeightsExtra, parsedGeometry.matricesWeights._updatable);
                 }
 
@@ -996,25 +995,71 @@
             }
         }
 
-        private static _CleanMatricesWeights(matricesWeights: number[], influencers: number): void {
+        private static _CleanMatricesWeights(parsedGeometry:any, mesh:Mesh): void {
+            const epsilon: number = 1e-3;
             if (!SceneLoader.CleanBoneMatrixWeights) {
                 return;
             }
+            let noInfluenceBoneIndex = 0.0;
+            if (parsedGeometry.skeletonId > -1) {
+                let skeleton = mesh.getScene().getLastSkeletonByID(parsedGeometry.skeletonId);
+                noInfluenceBoneIndex = skeleton.bones.length;
+            } else {
+                return;
+            }
+            let matricesIndices = mesh.getVerticesData(VertexBuffer.MatricesIndicesKind);
+            let matricesIndicesExtra = mesh.getVerticesData(VertexBuffer.MatricesIndicesExtraKind);
+            let matricesWeights = parsedGeometry.matricesWeights;
+            let matricesWeightsExtra = parsedGeometry.matricesWeightsExtra;
+            let influencers = parsedGeometry.numBoneInfluencer;
             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 < epsilon && firstZeroWeight < 0) {
+                        firstZeroWeight = j;
                     }
                 }
+                if (matricesWeightsExtra) {
+                    for (var j = 0; j < 4; j++) {
+                        let w = matricesWeightsExtra[i + j];
+                        weight += w;
+                        if (w < epsilon && firstZeroWeight < 0) {
+                            firstZeroWeight = j + 4;
+                        }
+                    }
+                }
+                if (firstZeroWeight < 0  || firstZeroWeight > (influencers - 1)) {
+                    firstZeroWeight = influencers - 1;
+                }
+                if (weight > epsilon) {
+                    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] = noInfluenceBoneIndex;
+                    } else {
+                        matricesWeights[i + firstZeroWeight] = 1.0 - weight;
+                        matricesIndices[i + firstZeroWeight] = noInfluenceBoneIndex;
+                    }
+                }
+            }
 
-                matricesWeights[biggerIndex] += Math.max(0, 1.0 - weight);
+            mesh.setVerticesData(VertexBuffer.MatricesIndicesKind, matricesIndices);
+            if (parsedGeometry.matricesWeightsExtra) {       
+                mesh.setVerticesData(VertexBuffer.MatricesIndicesExtraKind, matricesIndicesExtra);
             }
         }