|
@@ -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);
|
|
|
}
|
|
|
}
|
|
|
|