Skip to content

Commit 16a08e5

Browse files
author
Avaer Kazmer
committed
Update avatar proto code
1 parent 3a7835a commit 16a08e5

29 files changed

+1314
-1385
lines changed

proto/Armature.js

Lines changed: 129 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
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';
44
import 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

97
class 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;
147135
export { 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

Comments
 (0)