-
Notifications
You must be signed in to change notification settings - Fork 0
/
Box3Utils.js
114 lines (97 loc) · 3.61 KB
/
Box3Utils.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
module.exports = THREE.Box3Utils = (function() {
/*
* POLYFILL
*/
var boneTransformPolyfill = null;
if (typeof THREE.SkinnedMesh.prototype.boneTransform !== "function") {
boneTransformPolyfill = (function(mesh, target, index) {
var vertex = new THREE.Vector3();
var temp = new THREE.Vector3();
var skinned = new THREE.Vector3();
var skinIndices = new THREE.Vector4();
var skinWeights = new THREE.Vector4();
var boneMatrix = new THREE.Matrix4();
var skeleton,
boneMatrices,
geometry,
position,
skinIndex,
skinWeight,
bindMatrix,
bindMatrixInverse,
sw,
si;
return function(skinnedMesh, index, target) {
skeleton = skinnedMesh.skeleton;
boneMatrices = skeleton.boneMatrices;
geometry = skinnedMesh.geometry;
position = geometry.attributes.position;
skinIndex = geometry.attributes.skinIndex;
skinWeight = geometry.attributes.skinWeight;
bindMatrix = skinnedMesh.bindMatrix;
bindMatrixInverse = skinnedMesh.bindMatrixInverse;
vertex.fromBufferAttribute(position, index);
skinIndices.fromBufferAttribute(skinIndex, index);
skinWeights.fromBufferAttribute(skinWeight, index);
/*
* Re-create the vertex shader job - just the vertices positions
* see https://www.khronos.org/opengl/wiki/Skeletal_Animation
* see Mugen87 answer https://discourse.threejs.org/t/object-bounds-not-updated-with-animation/3749/12
*/
vertex.applyMatrix4(bindMatrix); // transform to bind space
target.set(0, 0, 0);
for (var j = 0; j < 4; j++) {
sw = skinWeights.getComponent(j);
if (sw === 0) continue;
si = skinIndices.getComponent(j);
sw = skinWeights.getComponent(j);
boneMatrix.fromArray(boneMatrices, si * 16);
// weighted vertex transformation
temp
.copy(vertex)
.applyMatrix4(boneMatrix)
.multiplyScalar(sw);
target.add(temp);
}
return target.applyMatrix4(bindMatrixInverse); // back to local space
};
})();
}
/*
* POLYFILL END
*/
var skinnedVertex = new THREE.Vector3();
var tmpBox = new THREE.Box3();
function updateAABB(skinnedMesh, box, expand) {
var geometry = skinnedMesh.geometry;
var geometryIndex = geometry.index;
var position = geometry.attributes.position;
var idx = 0;
var index = 0;
var aabb = expand ? tmpBox : box;
aabb.makeEmpty()
// Distinguish indexed and non-indexed geometry
var idx_max = geometryIndex ? geometryIndex.count : position.count;
for (idx = 0; idx < idx_max; idx++) {
index = geometryIndex ? geometryIndex.array[idx] : idx;
if (boneTransformPolyfill)
boneTransformPolyfill(skinnedMesh, index, skinnedVertex);
else
skinnedMesh.boneTransform(index, skinnedVertex);
//skinnedVertex.applyQuaternion(skinnedMesh.parent.parent.quaternion)
// expand aabb
aabb.expandByPoint(skinnedVertex);
}
aabb.applyMatrix4(skinnedMesh.matrixWorld);
if (expand)
box.union(aabb);
}
return {
expandFromSkinnedMesh: function(skinnedMesh, aabb) {
updateAABB(skinnedMesh, aabb, true);
},
fromSkinnedMesh: function(skinnedMesh, aabb) {
updateAABB(skinnedMesh, aabb, false);
}
};
})();