Skip to content

Commit

Permalink
Merge pull request #2520 from webaverse/2519-app-avatar.js-should-be-…
Browse files Browse the repository at this point in the history
…broken-up-to-better-separate-concerns

2519 app avatar.js should be broken up to better separate concerns
  • Loading branch information
Avaer Kazmer authored Mar 10, 2022
2 parents 26a999a + 9873979 commit 51acb44
Show file tree
Hide file tree
Showing 7 changed files with 1,818 additions and 1,675 deletions.
72 changes: 72 additions & 0 deletions avatars/AnimationMapping.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
class AnimationMapping {
constructor(animationTrackName, boneName, isTop, isPosition) {
this.animationTrackName = animationTrackName;
this.boneName = boneName;
this.isTop = isTop;
this.isPosition = isPosition;
}

clone() {
return new AnimationMapping(this.animationTrackName, this.boneName, this.isTop, this.isPosition);
}
}

export const animationMappingConfig = [
new AnimationMapping('mixamorigHips.position', 'Hips', false, true),
new AnimationMapping('mixamorigHips.quaternion', 'Hips', false, false),
new AnimationMapping('mixamorigSpine.quaternion', 'Spine', true, false),
new AnimationMapping('mixamorigSpine1.quaternion', 'Chest', true, false),
new AnimationMapping('mixamorigSpine2.quaternion', 'UpperChest', true, false),
new AnimationMapping('mixamorigNeck.quaternion', 'Neck', true, false),
new AnimationMapping('mixamorigHead.quaternion', 'Head', true, false),

new AnimationMapping('mixamorigLeftShoulder.quaternion', 'Left_shoulder', true, false),
new AnimationMapping('mixamorigLeftArm.quaternion', 'Left_arm', true, false),
new AnimationMapping('mixamorigLeftForeArm.quaternion', 'Left_elbow', true, false),
new AnimationMapping('mixamorigLeftHand.quaternion', 'Left_wrist', true, false),
new AnimationMapping('mixamorigLeftHandMiddle1.quaternion', 'Left_middleFinger1', true, false),
new AnimationMapping('mixamorigLeftHandMiddle2.quaternion', 'Left_middleFinger2', true, false),
new AnimationMapping('mixamorigLeftHandMiddle3.quaternion', 'Left_middleFinger3', true, false),
new AnimationMapping('mixamorigLeftHandThumb1.quaternion', 'Left_thumb0', true, false),
new AnimationMapping('mixamorigLeftHandThumb2.quaternion', 'Left_thumb1', true, false),
new AnimationMapping('mixamorigLeftHandThumb3.quaternion', 'Left_thumb2', true, false),
new AnimationMapping('mixamorigLeftHandIndex1.quaternion', 'Left_indexFinger1', true, false),
new AnimationMapping('mixamorigLeftHandIndex2.quaternion', 'Left_indexFinger2', true, false),
new AnimationMapping('mixamorigLeftHandIndex3.quaternion', 'Left_indexFinger3', true, false),
new AnimationMapping('mixamorigLeftHandRing1.quaternion', 'Left_ringFinger1', true, false),
new AnimationMapping('mixamorigLeftHandRing2.quaternion', 'Left_ringFinger2', true, false),
new AnimationMapping('mixamorigLeftHandRing3.quaternion', 'Left_ringFinger3', true, false),
new AnimationMapping('mixamorigLeftHandPinky1.quaternion', 'Left_littleFinger1', true, false),
new AnimationMapping('mixamorigLeftHandPinky2.quaternion', 'Left_littleFinger2', true, false),
new AnimationMapping('mixamorigLeftHandPinky3.quaternion', 'Left_littleFinger3', true, false),

new AnimationMapping('mixamorigRightShoulder.quaternion', 'Right_shoulder', true, false),
new AnimationMapping('mixamorigRightArm.quaternion', 'Right_arm', true, false),
new AnimationMapping('mixamorigRightForeArm.quaternion', 'Right_elbow', true, false),
new AnimationMapping('mixamorigRightHand.quaternion', 'Right_wrist', true, false),
new AnimationMapping('mixamorigRightHandMiddle1.quaternion', 'Right_middleFinger1', true, false),
new AnimationMapping('mixamorigRightHandMiddle2.quaternion', 'Right_middleFinger2', true, false),
new AnimationMapping('mixamorigRightHandMiddle3.quaternion', 'Right_middleFinger3', true, false),
new AnimationMapping('mixamorigRightHandThumb1.quaternion', 'Right_thumb0', true, false),
new AnimationMapping('mixamorigRightHandThumb2.quaternion', 'Right_thumb1', true, false),
new AnimationMapping('mixamorigRightHandThumb3.quaternion', 'Right_thumb2', true, false),
new AnimationMapping('mixamorigRightHandIndex1.quaternion', 'Right_indexFinger1', true, false),
new AnimationMapping('mixamorigRightHandIndex2.quaternion', 'Right_indexFinger2', true, false),
new AnimationMapping('mixamorigRightHandIndex3.quaternion', 'Right_indexFinger3', true, false),
new AnimationMapping('mixamorigRightHandRing1.quaternion', 'Right_ringFinger1', true, false),
new AnimationMapping('mixamorigRightHandRing2.quaternion', 'Right_ringFinger2', true, false),
new AnimationMapping('mixamorigRightHandRing3.quaternion', 'Right_ringFinger3', true, false),
new AnimationMapping('mixamorigRightHandPinky1.quaternion', 'Right_littleFinger1', true, false),
new AnimationMapping('mixamorigRightHandPinky2.quaternion', 'Right_littleFinger2', true, false),
new AnimationMapping('mixamorigRightHandPinky3.quaternion', 'Right_littleFinger3', true, false),

new AnimationMapping('mixamorigRightUpLeg.quaternion', 'Right_leg', false, false),
new AnimationMapping('mixamorigRightLeg.quaternion', 'Right_knee', false, false),
new AnimationMapping('mixamorigRightFoot.quaternion', 'Right_ankle', false, false),
new AnimationMapping('mixamorigRightToeBase.quaternion', 'Right_toe', false, false),

new AnimationMapping('mixamorigLeftUpLeg.quaternion', 'Left_leg', false, false),
new AnimationMapping('mixamorigLeftLeg.quaternion', 'Left_knee', false, false),
new AnimationMapping('mixamorigLeftFoot.quaternion', 'Left_ankle', false, false),
new AnimationMapping('mixamorigLeftToeBase.quaternion', 'Left_toe', false, false),
];
51 changes: 51 additions & 0 deletions avatars/Blinker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
export default class Blinker {
constructor() {
this.mode = 'ready';
this.waitTime = 0;
this.lastTimestamp = 0;
}

update(now) {
const _setOpen = () => {
this.mode = 'open';
this.waitTime = (0.5 + 0.5 * Math.random()) * 3000;
this.lastTimestamp = now;
};

switch (this.mode) {
case 'ready': {
_setOpen();
return 0;
}
case 'open': {
const timeDiff = now - this.lastTimestamp;
if (timeDiff > this.waitTime) {
this.mode = 'closing';
this.waitTime = 100;
this.lastTimestamp = now;
}
return 0;
}
case 'closing': {
const f = Math.min(Math.max((now - this.lastTimestamp) / this.waitTime, 0), 1);
if (f < 1) {
return f;
} else {
this.mode = 'opening';
this.waitTime = 100;
this.lastTimestamp = now;
return 1;
}
}
case 'opening': {
const f = Math.min(Math.max((now - this.lastTimestamp) / this.waitTime, 0), 1);
if (f < 1) {
return 1 - f;
} else {
_setOpen();
return 0;
}
}
}
}
}
9 changes: 9 additions & 0 deletions avatars/Emoter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default class Emoter {
constructor() {

}

update() {

}
}
135 changes: 135 additions & 0 deletions avatars/Looker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import * as THREE from 'three';
import {
getEyePosition,
} from './util.mjs';

const localVector = new THREE.Vector3();
const localVector2 = new THREE.Vector3();
const localQuaternion = new THREE.Quaternion();
const localPlane = new THREE.Plane();
export default class Looker {
constructor(avatar) {
this.avatar = avatar;

this.mode = 'ready';
this.startTarget = new THREE.Vector3();
this.endTarget = new THREE.Vector3();
this.waitTime = 0;
this.lastTimestamp = 0;

this._target = new THREE.Vector3();
}

// returns the world space eye target
update(now) {
const _getEndTargetRandom = target => {
const root = this.avatar.modelBoneOutputs.Root;
const eyePosition = getEyePosition(this.avatar.modelBones);
return target.copy(eyePosition)
.add(
localVector.set(0, 0, 1.5 + 3 * Math.random())
.applyQuaternion(localQuaternion.setFromRotationMatrix(root.matrixWorld)),
)
.add(
localVector.set(-0.5 + Math.random(), (-0.5 + Math.random()) * 0.3, -0.5 + Math.random())
.normalize(),
// .multiplyScalar(1)
);
};
const _getEndTargetForward = target => {
const root = this.avatar.modelBoneOutputs.Root;
const eyePosition = getEyePosition(this.avatar.modelBones);
return target.copy(eyePosition)
.add(
localVector.set(0, 0, 2)
.applyQuaternion(localQuaternion.setFromRotationMatrix(root.matrixWorld)),
);
};
const _startMove = () => {
this.mode = 'moving';
// const head = this.avatar.modelBoneOutputs['Head'];
// const root = this.avatar.modelBoneOutputs['Root'];
this.startTarget.copy(this.endTarget);
_getEndTargetRandom(this.endTarget);
this.waitTime = 100;
this.lastTimestamp = now;
};
const _startDelay = () => {
this.mode = 'delay';
this.waitTime = Math.random() * 2000;
this.lastTimestamp = now;
};
const _startWaiting = () => {
this.mode = 'waiting';
this.waitTime = Math.random() * 3000;
this.lastTimestamp = now;
};
const _isSpeedTooFast = () => this.avatar.velocity.length() > 0.5;
const _isPointTooClose = () => {
const root = this.avatar.modelBoneOutputs.Root;
// const head = this.avatar.modelBoneOutputs['Head'];
localVector.set(0, 0, 1)
.applyQuaternion(localQuaternion.setFromRotationMatrix(root.matrixWorld));
localVector2.setFromMatrixPosition(root.matrixWorld);
localPlane.setFromNormalAndCoplanarPoint(
localVector,
localVector2,
);
const distance = localPlane.distanceToPoint(this.endTarget);
return distance < 1;
};

// console.log('got mode', this.mode, this.waitTime);

if (_isSpeedTooFast()) {
_getEndTargetForward(this.endTarget);
// this.startTarget.copy(this.endTarget);
_startDelay();
return null;
} else if (_isPointTooClose()) {
_getEndTargetForward(this.endTarget);
// this.startTarget.copy(this.endTarget);
_startDelay();
return null;
} else {
switch (this.mode) {
case 'ready': {
_startMove();
return this.startTarget;
}
case 'delay': {
const timeDiff = now - this.lastTimestamp;
if (timeDiff > this.waitTime) {
_startMove();
return this.startTarget;
} else {
return null;
}
}
case 'moving': {
const timeDiff = now - this.lastTimestamp;
const f = Math.min(Math.max(timeDiff / this.waitTime, 0), 1);
// console.log('got time diff', timeDiff, this.waitTime, f);
const target = this._target.copy(this.startTarget)
.lerp(this.endTarget, f);
// _setTarget(target);

if (f >= 1) {
_startWaiting();
}

return target;
}
case 'waiting': {
const f = Math.min(Math.max((now - this.lastTimestamp) / this.waitTime, 0), 1);
if (f >= 1) {
_startMove();
return this.startTarget;
} else {
return this.endTarget;
}
}
}
}
}
}
9 changes: 9 additions & 0 deletions avatars/Nodder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default class Nodder {
constructor() {

}

update() {

}
}
Loading

0 comments on commit 51acb44

Please sign in to comment.