11// Armature.js -- base skeleton abstraction across a well-known joint topology (independent of mesh)
22
3- import { _decoupledSkeletonClone } from './armature. utils.js' ;
3+ import { _decoupledSkeletonClone } from './utils.js' ;
44import remapJointNames from './remapJointNames.js' ;
5- import { NamedJointWrappers } from './NamedJointWrappers.js' ;
6- import { AutoIKChain , walkBoneChain } from './AutoIKChain.js' ;
7- import SkeletonMetrics from './SkeletonMetrics.js' ;
5+ import { SpaceHelper } from './experiments.js' ;
86
97class Armature {
108 static get version ( ) { return '0.0.0a' ; }
@@ -36,15 +34,6 @@ class Armature {
3634 Object . assign ( this , new NamedJointWrappers ( skeleton , idNames ) ) ;
3735 }
3836
39- walk ( a , b , silent = false ) {
40- var bc = walkBoneChain ( this . get ( a ) , this . get ( b ) ) ;
41- if ( ! silent && ! bc . valid ) {
42- debugger ;
43- throw new Error ( 'bad chain: ' + [ a , b ] . join ( '=>' ) ) ;
44- }
45- return bc ;
46- }
47-
4837 // experimental support for "tearing off" subskeleton chains
4938 virtualSegment ( from , to ) {
5039 var container = {
@@ -143,6 +132,131 @@ class Armature {
143132 }
144133} ;
145134
146- export default Armature ;
147135export { Armature } ;
148- try { Object . assign ( self , { Armature } ) ; } catch ( e ) { }
136+ try { Object . assign ( self , { Armature } ) ; } catch ( e ) { }
137+
138+ // ---------------------------------------------------------------------------
139+ // ---------------------------------------------------------------------------
140+ // NamedJointWrappers.js -- wraps a set of skeleton joints with SpaceHelper instances
141+
142+ class NamedJointWrappers {
143+ constructor ( skeleton , map , biasmap ) {
144+ if ( skeleton . skeleton ) skeleton = skeleton . skeleton ;
145+ biasmap = biasmap || { } ;
146+ this . keys = Object . keys ( map ) ;
147+ for ( var name in map ) {
148+ var boneName = map [ name ] ;
149+ if ( boneName === 'Armature' ) {
150+ this [ name ] = new SpaceHelper ( skeleton . getBoneByName ( 'Hips' ) . parent , { boneName : boneName } ) ;
151+ } else {
152+ this [ name ] = new SpaceHelper ( skeleton . getBoneByName ( boneName ) , { boneName : boneName } ) ;
153+ }
154+ this [ name ] . bias = biasmap [ name ] || biasmap [ boneName ] ;
155+ }
156+ }
157+ toString ( ) { return `[NamedJointWrappers ${ this . keys } ]` ; }
158+ } ;
159+
160+ export { NamedJointWrappers } ;
161+ try { Object . assign ( self , { NamedJointWrappers } ) ; } catch ( e ) { }
162+
163+ // ---------------------------------------------------------------------------
164+ // SkeletonMetrics.js -- calculates various metrics about a given THREE Skeleton
165+
166+ class SkeletonMetrics {
167+ static get version ( ) { return '0.0.0' ; }
168+ get scale ( ) {
169+ return this . eyeHeight / 1.6 * this . bones . Hips . parent . scale . x ;
170+ }
171+ constructor ( skeleton ) {
172+ this . skeleton = skeleton ;
173+ this . bones = this . skeleton . bones . reduce ( ( out , b ) => {
174+ out [ b . name ] = b ;
175+ return out ;
176+ } , { } ) ;
177+ this . boneNames = this . skeleton . bones . map ( ( b ) => b . name ) ;
178+ }
179+ get ( name , fallback ) {
180+ var b = name instanceof THREE . Bone ? name : this . bones [ name ] || this . bones [ fallback ] ;
181+ if ( ! b ) throw new Error ( '!b:' + [ name , fallback || '' ] ) ;
182+ return b ;
183+ }
184+
185+ _pos ( bone , target ) { return bone . getWorldPosition ( target ) ; }
186+ _rot ( bone , target ) { return bone . getWorldQuaternion ( target ) ; }
187+ pos ( name , fallback ) {
188+ return this . _pos ( this . get ( name , fallback ) , new THREE . Vector3 ( ) ) ;
189+ }
190+ rot ( name , fallback ) {
191+ return this . _rot ( this . get ( name , fallback ) , new THREE . Quaternion ( ) ) ;
192+ }
193+ centroid ( names ) {
194+ var center = new THREE . Vector3 ( ) ;
195+ for ( let name of names ) center . add ( this . pos ( name ) ) ;
196+ return center . divideScalar ( names . length ) ;
197+ }
198+ // maybe LeftToeBase? or if lowest joint in skeleton is epsilon of zero, take feet to be at zero?
199+ get feet ( ) { return this . pos ( 'LeftFoot' ) . add ( this . pos ( 'RightFoot' ) ) . multiplyScalar ( .5 ) ; }
200+ get midEyes ( ) { return this . pos ( 'LeftEye' ) . add ( this . pos ( 'RightEye' ) ) . multiplyScalar ( .5 ) ; }
201+ get midHead ( ) {
202+ var pt = this . pos ( 'LeftEye' ) . add ( this . pos ( 'RightEye' ) ) . multiplyScalar ( .5 ) ;
203+ pt . z = this . pos ( 'Head' ) . z ;
204+ return pt ;
205+ }
206+
207+ get headTop ( ) { return this . pos ( 'HeadTop_End' , 'Head' ) ; }
208+ get headPivot ( ) { return this . pos ( 'Head' ) ; }
209+ get head ( ) { return this . pos ( 'Head' ) ; }
210+ get hips ( ) { return this . pos ( 'Hips' ) ; }
211+
212+ get armLength ( ) { return this . pos ( 'LeftShoulder' ) . sub ( this . pos ( 'LeftHand' ) ) . length ( ) ; }
213+ get legLength ( ) { return this . pos ( 'LeftUpLeg' ) . sub ( this . pos ( 'LeftToeBase' , 'LeftFoot' ) ) . length ( ) ; }
214+
215+ get eyesOffset ( ) { return this . midEyes . sub ( this . headPivot ) ; }
216+ get headOffset ( ) { return this . midHead . sub ( this . midEyes ) ; }
217+ get cameraOffset ( ) { return this . midEyes . sub ( this . head ) ; }
218+ get hipsOffset ( ) { return this . midEyes . sub ( this . hips ) ; }
219+
220+ //get height() { return this.headTop.y; }
221+ get lowestBone ( ) { return this . _mmbone ( this . bones . Hips , - 1 ) . bone ; }
222+ get highestBone ( ) { return this . _mmbone ( this . bones . Hips , 1 ) . bone ; }
223+ _mmbone ( root , dir ) {
224+ var out = {
225+ root : root ,
226+ dir : dir ,
227+ bone : null ,
228+ pos : dir < 0 ? new THREE . Vector3 ( Infinity , Infinity , Infinity ) : new THREE . Vector3 ( - Infinity , - Infinity , - Infinity ) ,
229+ } ;
230+ root . traverse ( ( b ) => {
231+ var pt = this . pos ( b ) ;
232+ var better = dir < 0 ? ( pt . y < out . pos . y ) : ( pt . y > out . pos . y ) ;
233+ if ( better ) {
234+ out . bone = b ;
235+ out . pos . copy ( pt ) ;
236+ }
237+ } ) ;
238+ return out ;
239+ }
240+
241+ get height ( ) { return this . headTop . distanceTo ( this . feet ) ; }
242+ get eyeHeight ( ) { return this . midEyes . distanceTo ( this . feet ) ; }
243+
244+ get altitude ( ) { return this . hips . y ; }
245+
246+ relativeTo ( bone , names ) {
247+ names = names || this . boneNames ;
248+ var bones = names . map ( ( x ) => this . get ( x ) ) ;
249+ var inv = new THREE . Matrix4 ( ) . getInverse ( bone . matrixWorld ) ;
250+ return bones . reduce ( ( out , bone ) => {
251+ out [ bone . name ] = this . pos ( bone ) . applyMatrix4 ( inv ) ;
252+ return out ;
253+ } , { } ) ;
254+ }
255+ } ;
256+
257+ export { SkeletonMetrics } ;
258+
259+ try { Object . assign ( self , { SkeletonMetrics } ) ; } catch ( e ) { }
260+ // ---------------------------------------------------------------------------
261+
262+ // ---------------------------------------------------------------------------
0 commit comments