@drawcall/acta 0.1.21 → 0.1.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/behavior.d.ts +3 -0
- package/dist/behavior.js +30 -4
- package/package.json +1 -1
package/dist/behavior.d.ts
CHANGED
|
@@ -28,6 +28,9 @@ export declare class CharacterBehavior extends EventDispatcher<CharacterBehavior
|
|
|
28
28
|
private readonly computedProperties;
|
|
29
29
|
worldHeadDirection: Vector3 | undefined;
|
|
30
30
|
worldAimDirection: Vector3 | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* vector representing the movement velocity in world space with meter per second as unit
|
|
33
|
+
*/
|
|
31
34
|
readonly worldMoveVelocity: Vector3;
|
|
32
35
|
private abortController;
|
|
33
36
|
private updateTimeline?;
|
package/dist/behavior.js
CHANGED
|
@@ -18,6 +18,28 @@ const localQuaternionHelper = new Quaternion();
|
|
|
18
18
|
const eulerHelper = new Euler();
|
|
19
19
|
const directionHelper = new Vector3();
|
|
20
20
|
const vectorHelper = new Vector3();
|
|
21
|
+
const worldQuaternionHelper = new Quaternion();
|
|
22
|
+
const parentWorldQuaternionHelper = new Quaternion();
|
|
23
|
+
const parentWorldQuaternionInvHelper = new Quaternion();
|
|
24
|
+
const worldEulerHelper = new Euler(0, 0, 0, 'YXZ');
|
|
25
|
+
const worldYawDirectionHelper = new Vector3();
|
|
26
|
+
const getWorldYaw = (object) => {
|
|
27
|
+
object.getWorldQuaternion(worldQuaternionHelper);
|
|
28
|
+
worldEulerHelper.setFromQuaternion(worldQuaternionHelper, 'YXZ');
|
|
29
|
+
return worldEulerHelper.y;
|
|
30
|
+
};
|
|
31
|
+
const setWorldYaw = (object, desiredWorldYaw) => {
|
|
32
|
+
if (object.parent == null) {
|
|
33
|
+
object.rotation.y = desiredWorldYaw;
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
worldYawDirectionHelper.set(Math.sin(desiredWorldYaw), 0, Math.cos(desiredWorldYaw));
|
|
37
|
+
object.parent.getWorldQuaternion(parentWorldQuaternionHelper);
|
|
38
|
+
parentWorldQuaternionInvHelper.copy(parentWorldQuaternionHelper).invert();
|
|
39
|
+
worldYawDirectionHelper.applyQuaternion(parentWorldQuaternionInvHelper);
|
|
40
|
+
const localYaw = Math.atan2(worldYawDirectionHelper.x, worldYawDirectionHelper.z);
|
|
41
|
+
object.rotation.y = localYaw;
|
|
42
|
+
};
|
|
21
43
|
//TODO: support direction AND position targets for head and aim
|
|
22
44
|
export class CharacterBehavior extends EventDispatcher {
|
|
23
45
|
model;
|
|
@@ -25,11 +47,15 @@ export class CharacterBehavior extends EventDispatcher {
|
|
|
25
47
|
applyJump;
|
|
26
48
|
properties = {};
|
|
27
49
|
computedProperties = {
|
|
28
|
-
|
|
50
|
+
// < 0.02 m/s (2 cm per second) is generally imperceptible to the human eye
|
|
51
|
+
isMoving: () => this.worldMoveVelocity.length() > 0.05,
|
|
29
52
|
};
|
|
30
53
|
// Direction and movement properties
|
|
31
54
|
worldHeadDirection;
|
|
32
55
|
worldAimDirection;
|
|
56
|
+
/**
|
|
57
|
+
* vector representing the movement velocity in world space with meter per second as unit
|
|
58
|
+
*/
|
|
33
59
|
worldMoveVelocity = new Vector3(0, 0, 0);
|
|
34
60
|
abortController = new AbortController();
|
|
35
61
|
updateTimeline;
|
|
@@ -145,14 +171,14 @@ export class CharacterBehavior extends EventDispatcher {
|
|
|
145
171
|
}
|
|
146
172
|
// Lerp body yaw with angle wrapping
|
|
147
173
|
this.currentBodyYaw = lerpAngle(this.currentBodyYaw, targetBodyYaw, BodyRotationSpeed * delta);
|
|
148
|
-
this.model.scene
|
|
174
|
+
setWorldYaw(this.model.scene, this.currentBodyYaw);
|
|
149
175
|
this.updateTimeline?.(undefined, delta);
|
|
150
176
|
this.model.mixer.update(delta);
|
|
151
177
|
// Stabilize spine during aiming to face the aim direction
|
|
152
178
|
if (this.isAiming) {
|
|
153
179
|
const spineBone = this.model.scene.getObjectByName('spine');
|
|
154
180
|
// Extract yaw from aim direction and add PI offset for model facing
|
|
155
|
-
const aimYaw = this.model.scene
|
|
181
|
+
const aimYaw = getWorldYaw(this.model.scene) + Math.PI + SpineAimYawOffset;
|
|
156
182
|
// Create target quaternion with just the yaw (no pitch/roll)
|
|
157
183
|
eulerHelper.set(0, aimYaw, 0, 'YXZ');
|
|
158
184
|
quaternionHelper.setFromEuler(eulerHelper);
|
|
@@ -260,7 +286,7 @@ export class CharacterBehavior extends EventDispatcher {
|
|
|
260
286
|
return () => parallel('all', action({
|
|
261
287
|
update: () => {
|
|
262
288
|
// Transform world velocity to model's local space by rotating by inverse of model's Y rotation
|
|
263
|
-
vectorHelper.copy(this.worldMoveVelocity).applyAxisAngle(UpVector, -this.model.scene
|
|
289
|
+
vectorHelper.copy(this.worldMoveVelocity).applyAxisAngle(UpVector, -getWorldYaw(this.model.scene));
|
|
264
290
|
const speed = normalizedLocalMoveDirection.set(vectorHelper.x, -vectorHelper.z).length();
|
|
265
291
|
normalizedLocalMoveDirection.divideScalar(speed);
|
|
266
292
|
jogFwdAction.timeScale = 0.222 * speed;
|