UNPKG

2.78 kBJavaScriptView Raw
1import { LineSegments } from '../objects/LineSegments.js';
2import { Matrix4 } from '../math/Matrix4.js';
3import { LineBasicMaterial } from '../materials/LineBasicMaterial.js';
4import { Color } from '../math/Color.js';
5import { Vector3 } from '../math/Vector3.js';
6import { BufferGeometry } from '../core/BufferGeometry.js';
7import { Float32BufferAttribute } from '../core/BufferAttribute.js';
8
9const _vector = /*@__PURE__*/ new Vector3();
10const _boneMatrix = /*@__PURE__*/ new Matrix4();
11const _matrixWorldInv = /*@__PURE__*/ new Matrix4();
12
13
14class SkeletonHelper extends LineSegments {
15
16 constructor( object ) {
17
18 const bones = getBoneList( object );
19
20 const geometry = new BufferGeometry();
21
22 const vertices = [];
23 const colors = [];
24
25 const color1 = new Color( 0, 0, 1 );
26 const color2 = new Color( 0, 1, 0 );
27
28 for ( let i = 0; i < bones.length; i ++ ) {
29
30 const bone = bones[ i ];
31
32 if ( bone.parent && bone.parent.isBone ) {
33
34 vertices.push( 0, 0, 0 );
35 vertices.push( 0, 0, 0 );
36 colors.push( color1.r, color1.g, color1.b );
37 colors.push( color2.r, color2.g, color2.b );
38
39 }
40
41 }
42
43 geometry.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) );
44 geometry.setAttribute( 'color', new Float32BufferAttribute( colors, 3 ) );
45
46 const material = new LineBasicMaterial( { vertexColors: true, depthTest: false, depthWrite: false, toneMapped: false, transparent: true } );
47
48 super( geometry, material );
49
50 this.type = 'SkeletonHelper';
51 this.isSkeletonHelper = true;
52
53 this.root = object;
54 this.bones = bones;
55
56 this.matrix = object.matrixWorld;
57 this.matrixAutoUpdate = false;
58
59 }
60
61 updateMatrixWorld( force ) {
62
63 const bones = this.bones;
64
65 const geometry = this.geometry;
66 const position = geometry.getAttribute( 'position' );
67
68 _matrixWorldInv.copy( this.root.matrixWorld ).invert();
69
70 for ( let i = 0, j = 0; i < bones.length; i ++ ) {
71
72 const bone = bones[ i ];
73
74 if ( bone.parent && bone.parent.isBone ) {
75
76 _boneMatrix.multiplyMatrices( _matrixWorldInv, bone.matrixWorld );
77 _vector.setFromMatrixPosition( _boneMatrix );
78 position.setXYZ( j, _vector.x, _vector.y, _vector.z );
79
80 _boneMatrix.multiplyMatrices( _matrixWorldInv, bone.parent.matrixWorld );
81 _vector.setFromMatrixPosition( _boneMatrix );
82 position.setXYZ( j + 1, _vector.x, _vector.y, _vector.z );
83
84 j += 2;
85
86 }
87
88 }
89
90 geometry.getAttribute( 'position' ).needsUpdate = true;
91
92 super.updateMatrixWorld( force );
93
94 }
95
96}
97
98
99function getBoneList( object ) {
100
101 const boneList = [];
102
103 if ( object && object.isBone ) {
104
105 boneList.push( object );
106
107 }
108
109 for ( let i = 0; i < object.children.length; i ++ ) {
110
111 boneList.push.apply( boneList, getBoneList( object.children[ i ] ) );
112
113 }
114
115 return boneList;
116
117}
118
119
120export { SkeletonHelper };