feat: add subtle full-body sheep walking motion
This commit is contained in:
+12
-2
@@ -108,8 +108,12 @@ test('exported sheep has working joints and renders the final idle pose after wa
|
||||
const leg = sheep.group.getObjectByName('LegLeft')!;
|
||||
const rest = leg.quaternion.clone();
|
||||
assert.equal(sheep.pose('idle', 0, true, 1), true);
|
||||
sheep.pose('idle', 0, true, 1.2);
|
||||
assert.ok(leg.quaternion.angleTo(rest) > .01);
|
||||
assert.equal(sheep.pose('idle', 0, false, 1), true, 'stopping must invalidate one frame');
|
||||
const walking = leg.quaternion.clone();
|
||||
assert.equal(sheep.pose('idle', 0, false, 1.2), true, 'stopping must invalidate one frame');
|
||||
assert.ok(leg.quaternion.angleTo(walking) < 1e-6, 'stopping blends instead of snapping');
|
||||
sheep.pose('idle', 0, false, 4);
|
||||
assert.ok(leg.quaternion.angleTo(rest) < 1e-6);
|
||||
assert.equal(sheep.pose('idle', 0, false, 1), true, 'idle breathing keeps rendering');
|
||||
const arm = sheep.group.getObjectByName('ArmRight')!;
|
||||
@@ -146,7 +150,13 @@ test('idle breathing moves torso and head while feet stay planted and clones ret
|
||||
assert.ok(!body.scale.equals(bodyRest), 'breathing blends out instead of snapping');
|
||||
sheep.pose('idle', 0, true, 1.2);
|
||||
assert.deepEqual(body.scale, bodyRest);
|
||||
assert.deepEqual(head.position, headRest);
|
||||
assert.ok(head.position.distanceTo(headRest) > .001, 'walking carries the head');
|
||||
assert.ok(body.position.x !== 0, 'walking shifts the torso weight');
|
||||
const walkingHead = head.position.clone();
|
||||
sheep.pose('idle', 0, true, 1.2);
|
||||
assert.deepEqual(head.position, walkingHead, 'walking offsets cannot accumulate');
|
||||
sheep.pose('pray', 0, false, 1.5);
|
||||
assert.deepEqual(head.position, headRest, 'emotes clear walking offsets');
|
||||
remote.dispose(); sheep.dispose();
|
||||
});
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import { Vector3 } from 'three';
|
||||
|
||||
test('idle breathing carries the coat and hood without lifting the feet or changing the umbrella grip', async () => {
|
||||
const [model, umbrella, raincoat] = await Promise.all(['red-sheep', 'umbrella', 'raincoat'].map(asset));
|
||||
raincoat.name = 'TestRaincoat';
|
||||
const sheep = createSheep(model, { umbrella, raincoat });
|
||||
sheep.setEquipment(true, true, true);
|
||||
const body = model.getObjectByName('Body')!, head = model.getObjectByName('Head')!;
|
||||
@@ -26,6 +27,15 @@ test('idle breathing carries the coat and hood without lifting the feet or chang
|
||||
sheep.pose('idle', 0, false, 2);
|
||||
assert.ok(arm.quaternion.angleTo(grip) < 1e-8);
|
||||
assert.ok(foot.getWorldPosition(new Vector3()).distanceTo(footPosition) < 1e-8);
|
||||
const remote = sheep.clone();
|
||||
remote.pose('idle', 0, false, 0);
|
||||
remote.pose('idle', 0, false, 1);
|
||||
const remoteCoat = remote.group.getObjectByName('TestRaincoat')!;
|
||||
const remoteCoatPosition = remoteCoat.position.clone();
|
||||
sheep.pose('idle', 0, true, 3);
|
||||
remote.pose('idle', 0, false, 1);
|
||||
assert.deepEqual(remoteCoat.position, remoteCoatPosition, 'local walking cannot change a remote coat pivot');
|
||||
remote.dispose();
|
||||
sheep.dispose();
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user