@woosh/meep-engine 2.84.5 → 2.84.8
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/build/meep.cjs +139 -84
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +139 -84
- package/package.json +1 -1
- package/src/core/collection/array/arrayIndexByEquality.js +1 -0
- package/src/core/collection/list/List.js +26 -18
- package/src/core/collection/list/List.spec.js +73 -0
- package/src/core/primitives/numbers/number_count_decimals.js +30 -0
- package/src/core/primitives/numbers/number_pretty_print.js +7 -29
- package/src/core/primitives/strings/string_format_camel_to_kebab.js +2 -0
- package/src/core/primitives/strings/string_strip_trailing.js +22 -0
- package/src/core/primitives/strings/string_strip_trailing.spec.js +27 -0
- package/src/core/process/worker/WorkerBuilder.js +5 -1
- package/src/core/process/worker/WorkerProxy.js +3 -2
- package/src/engine/ecs/Entity.spec.js +33 -0
- package/src/engine/ecs/EntityComponentDataset.js +17 -11
- package/src/engine/ecs/storage/BinaryBufferDeSerializer.js +8 -1
- package/src/engine/graphics/camera/CameraShake.js +1 -127
- package/src/engine/graphics/camera/CameraShakeBehavior.js +91 -0
- package/src/engine/graphics/camera/CameraShakeTraumaBehavior.js +38 -0
- package/src/engine/graphics/ecs/animation/animator/AnimationGraphSystem.js +9 -23
- package/src/engine/graphics/ecs/animation/animator/blending/BlendStateMatrix.js +11 -6
- package/src/engine/graphics/ecs/animation/animator/graph/AnimationGraph.js +20 -12
- package/src/engine/graphics/ecs/animation/animator/graph/AnimationState.js +3 -3
- package/src/engine/graphics/ecs/path/tube/build/estimatePathViaIterativeIntegral.js +1 -1
- package/src/view/View.js +52 -30
- package/src/view/writeCssTransformMatrix.js +26 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { string_strip_trailing } from "./string_strip_trailing.js";
|
|
2
|
+
|
|
3
|
+
test("strip empty from empty", () => {
|
|
4
|
+
expect(
|
|
5
|
+
string_strip_trailing("", "")
|
|
6
|
+
).toBe("");
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
test("strip repeating 2 character sequence", () => {
|
|
10
|
+
|
|
11
|
+
expect(
|
|
12
|
+
string_strip_trailing("Cabab", "ab")
|
|
13
|
+
).toBe("C");
|
|
14
|
+
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test("mistakes", () => {
|
|
18
|
+
|
|
19
|
+
expect(
|
|
20
|
+
string_strip_trailing("food", "o")
|
|
21
|
+
).toBe("food");
|
|
22
|
+
|
|
23
|
+
expect(
|
|
24
|
+
string_strip_trailing("food", "f")
|
|
25
|
+
).toBe("food");
|
|
26
|
+
|
|
27
|
+
});
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
import {convertPathToURL} from "../../../engine/network/convertPathToURL.js";
|
|
6
|
+
import { convertPathToURL } from "../../../engine/network/convertPathToURL.js";
|
|
7
7
|
import LineBuilder from "../../codegen/LineBuilder.js";
|
|
8
8
|
import WorkerProxy from "./WorkerProxy.js";
|
|
9
9
|
|
|
@@ -16,6 +16,10 @@ class WorkerBuilder {
|
|
|
16
16
|
functions = [];
|
|
17
17
|
preamble = new LineBuilder();
|
|
18
18
|
|
|
19
|
+
/**
|
|
20
|
+
*
|
|
21
|
+
* @param {string} code
|
|
22
|
+
*/
|
|
19
23
|
addCode(code) {
|
|
20
24
|
this.preamble.add(code);
|
|
21
25
|
}
|
|
@@ -66,10 +66,11 @@ class WorkerProxy {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
/**
|
|
69
|
+
* Invoke a given method on the worker, as defined by the `WorkerBuilder`
|
|
69
70
|
* @template T
|
|
70
|
-
* @param {number} name
|
|
71
|
+
* @param {number} name Method's name
|
|
71
72
|
* @param {Array} args
|
|
72
|
-
* @return {Promise<T>}
|
|
73
|
+
* @return {Promise<T>} eventual result of the invoked method
|
|
73
74
|
*/
|
|
74
75
|
$submitRequest(name, args) {
|
|
75
76
|
const pending = this.__pending[name];
|
|
@@ -153,3 +153,36 @@ test("promiseEvent", async () => {
|
|
|
153
153
|
|
|
154
154
|
await promise;
|
|
155
155
|
});
|
|
156
|
+
|
|
157
|
+
test("generation correctly set for build", () => {
|
|
158
|
+
|
|
159
|
+
const entity = new Entity();
|
|
160
|
+
|
|
161
|
+
const ecd = sampleDataset();
|
|
162
|
+
|
|
163
|
+
entity.build(ecd);
|
|
164
|
+
|
|
165
|
+
expect(entity.generation).toEqual(ecd.getEntityGeneration(entity.id));
|
|
166
|
+
|
|
167
|
+
// rebuild
|
|
168
|
+
entity.destroy();
|
|
169
|
+
|
|
170
|
+
entity.build(ecd);
|
|
171
|
+
|
|
172
|
+
expect(entity.generation).toEqual(ecd.getEntityGeneration(entity.id));
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
test("generation correctly set when binding live entity", () => {
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
const ecd = sampleDataset();
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
const entity_a = ecd.createEntity();
|
|
182
|
+
const entity_b = ecd.createEntity();
|
|
183
|
+
const entity_c = ecd.createEntity();
|
|
184
|
+
|
|
185
|
+
const entity = Entity.readFromDataset(entity_b, ecd);
|
|
186
|
+
|
|
187
|
+
expect(entity.generation).toEqual(ecd.getEntityGeneration(entity_b));
|
|
188
|
+
});
|
|
@@ -836,10 +836,10 @@ export class EntityComponentDataset {
|
|
|
836
836
|
|
|
837
837
|
/**
|
|
838
838
|
*
|
|
839
|
-
* @param {number}
|
|
839
|
+
* @param {number} entity_id
|
|
840
840
|
*/
|
|
841
|
-
removeEntity(
|
|
842
|
-
if (!this.entityExists(
|
|
841
|
+
removeEntity(entity_id) {
|
|
842
|
+
if (!this.entityExists(entity_id)) {
|
|
843
843
|
// entity doesn't exist
|
|
844
844
|
return;
|
|
845
845
|
}
|
|
@@ -847,26 +847,31 @@ export class EntityComponentDataset {
|
|
|
847
847
|
const componentOccupancy = this.componentOccupancy;
|
|
848
848
|
const typeCount = this.componentTypeCount;
|
|
849
849
|
|
|
850
|
-
const occupancyStart =
|
|
850
|
+
const occupancyStart = entity_id * typeCount;
|
|
851
851
|
const occupancyEnd = occupancyStart + typeCount;
|
|
852
852
|
|
|
853
|
-
|
|
853
|
+
// remove all components from the entity
|
|
854
|
+
for (
|
|
855
|
+
let i = componentOccupancy.nextSetBit(occupancyStart);
|
|
856
|
+
i < occupancyEnd && i !== -1;
|
|
857
|
+
i = componentOccupancy.nextSetBit(i + 1)
|
|
858
|
+
) {
|
|
854
859
|
const componentIndex = i % typeCount;
|
|
855
|
-
this.removeComponentFromEntityByIndex_Unchecked(
|
|
860
|
+
this.removeComponentFromEntityByIndex_Unchecked(entity_id, componentIndex, i);
|
|
856
861
|
}
|
|
857
862
|
|
|
858
863
|
//dispatch event
|
|
859
|
-
this.sendEvent(
|
|
864
|
+
this.sendEvent(entity_id, EventType.EntityRemoved, entity_id);
|
|
860
865
|
|
|
861
866
|
//purge all event listeners
|
|
862
|
-
delete this.__entityEventListeners[
|
|
863
|
-
delete this.__entityAnyEventListeners[
|
|
867
|
+
delete this.__entityEventListeners[entity_id];
|
|
868
|
+
delete this.__entityAnyEventListeners[entity_id];
|
|
864
869
|
|
|
865
|
-
this.entityOccupancy.set(
|
|
870
|
+
this.entityOccupancy.set(entity_id, false);
|
|
866
871
|
|
|
867
872
|
this.entityCount--;
|
|
868
873
|
|
|
869
|
-
this.onEntityRemoved.send1(
|
|
874
|
+
this.onEntityRemoved.send1(entity_id);
|
|
870
875
|
}
|
|
871
876
|
|
|
872
877
|
/**
|
|
@@ -919,6 +924,7 @@ export class EntityComponentDataset {
|
|
|
919
924
|
}
|
|
920
925
|
|
|
921
926
|
/**
|
|
927
|
+
* This method doesn't perform any checks, make sure you understand what you are doing when using it
|
|
922
928
|
* @private
|
|
923
929
|
* @param {number} entityIndex
|
|
924
930
|
* @param {number} componentIndex
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { assert } from "../../../core/assert.js";
|
|
2
|
+
import { number_pretty_print } from "../../../core/primitives/numbers/number_pretty_print.js";
|
|
2
3
|
import Task from "../../../core/process/task/Task.js";
|
|
3
4
|
import { TaskSignal } from "../../../core/process/task/TaskSignal.js";
|
|
4
5
|
import { emptyTask } from "../../../core/process/task/util/emptyTask.js";
|
|
@@ -24,6 +25,7 @@ class BinaryBufferDeSerializer {
|
|
|
24
25
|
assert.notEqual(engine, undefined, 'engine is undefined');
|
|
25
26
|
assert.notEqual(dataset, undefined, 'dataset is undefined');
|
|
26
27
|
|
|
28
|
+
const entity_count_before = dataset.entityCount;
|
|
27
29
|
|
|
28
30
|
const version = buffer.readUint16();
|
|
29
31
|
const numSerializedTypes = buffer.readUint16();
|
|
@@ -37,7 +39,12 @@ class BinaryBufferDeSerializer {
|
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
task.on.completed.add(function () {
|
|
40
|
-
|
|
42
|
+
const entity_count_after = dataset.entityCount;
|
|
43
|
+
|
|
44
|
+
const execution_time = task.getExecutedCpuTime();
|
|
45
|
+
const entity_count = entity_count_after - entity_count_before;
|
|
46
|
+
|
|
47
|
+
console.log(`Binary Buffer De-Serialization took ${number_pretty_print(execution_time)}ms. ${entity_count} Entities`);
|
|
41
48
|
});
|
|
42
49
|
|
|
43
50
|
return task;
|
|
@@ -1,132 +1,6 @@
|
|
|
1
|
-
import Vector3 from "../../../core/geom/Vector3.js";
|
|
2
|
-
|
|
3
1
|
import SimplexNoise from 'simplex-noise';
|
|
2
|
+
import Vector3 from "../../../core/geom/Vector3.js";
|
|
4
3
|
import { seededRandom } from "../../../core/math/random/seededRandom.js";
|
|
5
|
-
import { Behavior } from "../../intelligence/behavior/Behavior.js";
|
|
6
|
-
import { BehaviorStatus } from "../../intelligence/behavior/BehaviorStatus.js";
|
|
7
|
-
import Quaternion from "../../../core/geom/Quaternion.js";
|
|
8
|
-
import { clamp01 } from "../../../core/math/clamp01.js";
|
|
9
|
-
import { makeCubicCurve } from "../../../core/math/spline/makeCubicCurve.js";
|
|
10
|
-
|
|
11
|
-
export class CameraShakeTraumaBehavior extends Behavior {
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
*
|
|
15
|
-
* @param {CameraShakeBehavior} shakeBehavior
|
|
16
|
-
* @param {number} decay amount by which trauma decays per second
|
|
17
|
-
*/
|
|
18
|
-
constructor({
|
|
19
|
-
shakeBehavior,
|
|
20
|
-
decay = 1,
|
|
21
|
-
}) {
|
|
22
|
-
super();
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
this.decay = decay;
|
|
26
|
-
this.trauma = 0;
|
|
27
|
-
|
|
28
|
-
this.shakeBehavior = shakeBehavior;
|
|
29
|
-
|
|
30
|
-
this.formula = makeCubicCurve(0, 0.1, 0.1, 1);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
tick(timeDelta) {
|
|
34
|
-
const shake = this.formula(clamp01(this.trauma));
|
|
35
|
-
|
|
36
|
-
this.trauma = clamp01(this.trauma - timeDelta * this.decay);
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
this.shakeBehavior.strength = shake;
|
|
40
|
-
|
|
41
|
-
return BehaviorStatus.Running;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export class CameraShakeBehavior extends Behavior {
|
|
46
|
-
/**
|
|
47
|
-
*
|
|
48
|
-
* @param {number} maxPitch
|
|
49
|
-
* @param {number} maxYaw
|
|
50
|
-
* @param {number} maxRoll
|
|
51
|
-
* @param {number} maxOffsetX
|
|
52
|
-
* @param {number} maxOffsetY
|
|
53
|
-
* @param {number} maxOffsetZ
|
|
54
|
-
* @param {number} strength
|
|
55
|
-
* @param {TopDownCameraController} controller
|
|
56
|
-
*/
|
|
57
|
-
constructor(
|
|
58
|
-
{
|
|
59
|
-
maxPitch = 0,
|
|
60
|
-
maxYaw = 0,
|
|
61
|
-
maxRoll = 0,
|
|
62
|
-
maxOffsetX = 0,
|
|
63
|
-
maxOffsetY = 0,
|
|
64
|
-
maxOffsetZ = 0,
|
|
65
|
-
strength = 0,
|
|
66
|
-
|
|
67
|
-
controller
|
|
68
|
-
}
|
|
69
|
-
) {
|
|
70
|
-
super();
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
*
|
|
74
|
-
* @type {TopDownCameraController}
|
|
75
|
-
*/
|
|
76
|
-
this.controller = controller;
|
|
77
|
-
|
|
78
|
-
this.time = 0;
|
|
79
|
-
|
|
80
|
-
this.timeScale = 1;
|
|
81
|
-
|
|
82
|
-
this.strength = strength;
|
|
83
|
-
|
|
84
|
-
this.shake = new CameraShake();
|
|
85
|
-
|
|
86
|
-
this.shake.limitsRotation.set(maxPitch, maxYaw, maxRoll);
|
|
87
|
-
this.shake.limitsOffset.set(maxOffsetX, maxOffsetY, maxOffsetZ);
|
|
88
|
-
|
|
89
|
-
this.__target = new Vector3();
|
|
90
|
-
this.__rotation = new Vector3();
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
initialize() {
|
|
94
|
-
super.initialize();
|
|
95
|
-
|
|
96
|
-
//remember controller transform
|
|
97
|
-
this.__rotation.set(this.controller.pitch, this.controller.yaw, this.controller.roll);
|
|
98
|
-
this.__target.copy(this.controller.target);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
tick(timeDelta) {
|
|
102
|
-
this.time += timeDelta * this.timeScale;
|
|
103
|
-
|
|
104
|
-
const offset = new Vector3();
|
|
105
|
-
const rotation = new Vector3();
|
|
106
|
-
|
|
107
|
-
//read out shake values
|
|
108
|
-
this.shake.read(this.strength, this.time, offset, rotation);
|
|
109
|
-
|
|
110
|
-
const q = new Quaternion();
|
|
111
|
-
|
|
112
|
-
q.fromEulerAngles(this.__rotation.x, this.__rotation.y, this.__rotation.z);
|
|
113
|
-
|
|
114
|
-
offset.applyQuaternion(q);
|
|
115
|
-
|
|
116
|
-
//update controller
|
|
117
|
-
this.controller.target.set(
|
|
118
|
-
this.__target.x + offset.x,
|
|
119
|
-
this.__target.y + offset.y,
|
|
120
|
-
this.__target.z + offset.z,
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
this.controller.pitch = this.__rotation.x + rotation.x;
|
|
124
|
-
this.controller.yaw = this.__rotation.y + rotation.y;
|
|
125
|
-
this.controller.roll = this.__rotation.z + rotation.z;
|
|
126
|
-
|
|
127
|
-
return BehaviorStatus.Running;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
4
|
|
|
131
5
|
/**
|
|
132
6
|
* Based on a 2016 GDC talk by Squirrel Eiserloh "Math for Game Programmers: Juicing Your Cameras With Math"
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import Quaternion from "../../../core/geom/Quaternion.js";
|
|
2
|
+
import Vector3 from "../../../core/geom/Vector3.js";
|
|
3
|
+
import { Behavior } from "../../intelligence/behavior/Behavior.js";
|
|
4
|
+
import { BehaviorStatus } from "../../intelligence/behavior/BehaviorStatus.js";
|
|
5
|
+
import { CameraShake } from "./CameraShake.js";
|
|
6
|
+
|
|
7
|
+
export class CameraShakeBehavior extends Behavior {
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* @param {number} maxPitch
|
|
11
|
+
* @param {number} maxYaw
|
|
12
|
+
* @param {number} maxRoll
|
|
13
|
+
* @param {number} maxOffsetX
|
|
14
|
+
* @param {number} maxOffsetY
|
|
15
|
+
* @param {number} maxOffsetZ
|
|
16
|
+
* @param {number} strength
|
|
17
|
+
* @param {TopDownCameraController} controller
|
|
18
|
+
*/
|
|
19
|
+
constructor(
|
|
20
|
+
{
|
|
21
|
+
maxPitch = 0,
|
|
22
|
+
maxYaw = 0,
|
|
23
|
+
maxRoll = 0,
|
|
24
|
+
maxOffsetX = 0,
|
|
25
|
+
maxOffsetY = 0,
|
|
26
|
+
maxOffsetZ = 0,
|
|
27
|
+
strength = 0,
|
|
28
|
+
|
|
29
|
+
controller
|
|
30
|
+
}
|
|
31
|
+
) {
|
|
32
|
+
super();
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
*
|
|
36
|
+
* @type {TopDownCameraController}
|
|
37
|
+
*/
|
|
38
|
+
this.controller = controller;
|
|
39
|
+
|
|
40
|
+
this.time = 0;
|
|
41
|
+
|
|
42
|
+
this.timeScale = 1;
|
|
43
|
+
|
|
44
|
+
this.strength = strength;
|
|
45
|
+
|
|
46
|
+
this.shake = new CameraShake();
|
|
47
|
+
|
|
48
|
+
this.shake.limitsRotation.set(maxPitch, maxYaw, maxRoll);
|
|
49
|
+
this.shake.limitsOffset.set(maxOffsetX, maxOffsetY, maxOffsetZ);
|
|
50
|
+
|
|
51
|
+
this.__target = new Vector3();
|
|
52
|
+
this.__rotation = new Vector3();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
initialize() {
|
|
56
|
+
super.initialize();
|
|
57
|
+
|
|
58
|
+
//remember controller transform
|
|
59
|
+
this.__rotation.set(this.controller.pitch, this.controller.yaw, this.controller.roll);
|
|
60
|
+
this.__target.copy(this.controller.target);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
tick(timeDelta) {
|
|
64
|
+
this.time += timeDelta * this.timeScale;
|
|
65
|
+
|
|
66
|
+
const offset = new Vector3();
|
|
67
|
+
const rotation = new Vector3();
|
|
68
|
+
|
|
69
|
+
//read out shake values
|
|
70
|
+
this.shake.read(this.strength, this.time, offset, rotation);
|
|
71
|
+
|
|
72
|
+
const q = new Quaternion();
|
|
73
|
+
|
|
74
|
+
q.fromEulerAngles(this.__rotation.x, this.__rotation.y, this.__rotation.z);
|
|
75
|
+
|
|
76
|
+
offset.applyQuaternion(q);
|
|
77
|
+
|
|
78
|
+
//update controller
|
|
79
|
+
this.controller.target.set(
|
|
80
|
+
this.__target.x + offset.x,
|
|
81
|
+
this.__target.y + offset.y,
|
|
82
|
+
this.__target.z + offset.z,
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
this.controller.pitch = this.__rotation.x + rotation.x;
|
|
86
|
+
this.controller.yaw = this.__rotation.y + rotation.y;
|
|
87
|
+
this.controller.roll = this.__rotation.z + rotation.z;
|
|
88
|
+
|
|
89
|
+
return BehaviorStatus.Running;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { clamp01 } from "../../../core/math/clamp01.js";
|
|
2
|
+
import { makeCubicCurve } from "../../../core/math/spline/makeCubicCurve.js";
|
|
3
|
+
import { Behavior } from "../../intelligence/behavior/Behavior.js";
|
|
4
|
+
import { BehaviorStatus } from "../../intelligence/behavior/BehaviorStatus.js";
|
|
5
|
+
|
|
6
|
+
export class CameraShakeTraumaBehavior extends Behavior {
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
* @param {CameraShakeBehavior} shakeBehavior
|
|
11
|
+
* @param {number} decay amount by which trauma decays per second
|
|
12
|
+
*/
|
|
13
|
+
constructor({
|
|
14
|
+
shakeBehavior,
|
|
15
|
+
decay = 1,
|
|
16
|
+
}) {
|
|
17
|
+
super();
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
this.decay = decay;
|
|
21
|
+
this.trauma = 0;
|
|
22
|
+
|
|
23
|
+
this.shakeBehavior = shakeBehavior;
|
|
24
|
+
|
|
25
|
+
this.formula = makeCubicCurve(0, 0.1, 0.1, 1);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
tick(timeDelta) {
|
|
29
|
+
const shake = this.formula(clamp01(this.trauma));
|
|
30
|
+
|
|
31
|
+
this.trauma = clamp01(this.trauma - timeDelta * this.decay);
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
this.shakeBehavior.strength = shake;
|
|
35
|
+
|
|
36
|
+
return BehaviorStatus.Running;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -1,31 +1,17 @@
|
|
|
1
|
+
import { Matrix4 } from "three";
|
|
2
|
+
import { assert } from "../../../../../core/assert.js";
|
|
3
|
+
import Vector4 from "../../../../../core/geom/Vector4.js";
|
|
1
4
|
import { max3 } from "../../../../../core/math/max3.js";
|
|
5
|
+
import { ResourceAccessKind } from "../../../../../core/model/ResourceAccessKind.js";
|
|
6
|
+
import { ResourceAccessSpecification } from "../../../../../core/model/ResourceAccessSpecification.js";
|
|
2
7
|
import { System } from "../../../../ecs/System.js";
|
|
3
|
-
import {
|
|
8
|
+
import { projectSphere } from "../../../util/projectSphere.js";
|
|
9
|
+
import { CameraSystem } from "../../camera/CameraSystem.js";
|
|
4
10
|
import Mesh, { MeshFlags } from "../../mesh/Mesh.js";
|
|
11
|
+
import { MeshEvents } from "../../mesh/MeshEvents.js";
|
|
5
12
|
import { MeshSystem } from "../../mesh/MeshSystem.js";
|
|
6
|
-
import {
|
|
7
|
-
import Vector4 from "../../../../../core/geom/Vector4.js";
|
|
8
|
-
import { Matrix4 } from "three";
|
|
9
|
-
import { CameraSystem } from "../../camera/CameraSystem.js";
|
|
13
|
+
import { AnimationGraph } from "./graph/AnimationGraph.js";
|
|
10
14
|
import { AnimationGraphFlag } from "./graph/AnimationGraphFlag.js";
|
|
11
|
-
import { projectSphere } from "../../../util/projectSphere.js";
|
|
12
|
-
import { MeshEvents } from "../../mesh/MeshEvents.js";
|
|
13
|
-
import { ResourceAccessSpecification } from "../../../../../core/model/ResourceAccessSpecification.js";
|
|
14
|
-
import { ResourceAccessKind } from "../../../../../core/model/ResourceAccessKind.js";
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
*
|
|
18
|
-
* @param {AnimationGraph} graph
|
|
19
|
-
* @param {Mesh} mesh
|
|
20
|
-
* @param {number} entity
|
|
21
|
-
* @param {EntityComponentDataset} ecd
|
|
22
|
-
*/
|
|
23
|
-
function attach(graph, mesh, entity, ecd) {
|
|
24
|
-
graph.attach(mesh);
|
|
25
|
-
|
|
26
|
-
graph.link(entity, ecd);
|
|
27
|
-
|
|
28
|
-
}
|
|
29
15
|
|
|
30
16
|
/**
|
|
31
17
|
* @type {Vector4}
|
|
@@ -1,7 +1,14 @@
|
|
|
1
|
+
import { assert } from "../../../../../../core/assert.js";
|
|
1
2
|
import { lerp } from "../../../../../../core/math/lerp.js";
|
|
2
3
|
|
|
3
4
|
export class BlendStateMatrix {
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {number} size
|
|
8
|
+
*/
|
|
4
9
|
constructor(size) {
|
|
10
|
+
assert.isNonNegativeInteger(size, 'size');
|
|
11
|
+
|
|
5
12
|
this.weights = new Float32Array(size);
|
|
6
13
|
this.timeScales = new Float32Array(size);
|
|
7
14
|
}
|
|
@@ -64,15 +71,13 @@ export class BlendStateMatrix {
|
|
|
64
71
|
*
|
|
65
72
|
* @param {number} v
|
|
66
73
|
*/
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
const tTS = this.timeScales;
|
|
74
|
+
weightsMultiplyScalar(v) {
|
|
75
|
+
const weights = this.weights;
|
|
70
76
|
|
|
71
|
-
const n =
|
|
77
|
+
const n = weights.length;
|
|
72
78
|
|
|
73
79
|
for (let i = 0; i < n; i++) {
|
|
74
|
-
|
|
75
|
-
tTS[i] /= v;
|
|
80
|
+
weights[i] *= v;
|
|
76
81
|
}
|
|
77
82
|
}
|
|
78
83
|
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { AnimationState } from "./AnimationState.js";
|
|
2
|
-
import { AnimationTransition } from "./AnimationTransition.js";
|
|
3
|
-
import { AnimationStateType } from "./AnimationStateType.js";
|
|
4
1
|
import { AnimationMixer } from "three";
|
|
2
|
+
import { assert } from "../../../../../../core/assert.js";
|
|
3
|
+
import { computeHashIntegerArray } from "../../../../../../core/collection/array/computeHashIntegerArray.js";
|
|
4
|
+
import { computeHashFloat } from "../../../../../../core/primitives/numbers/computeHashFloat.js";
|
|
5
|
+
import { threeUpdateTransform } from "../../../../util/threeUpdateTransform.js";
|
|
5
6
|
import { AnimationGraphFlag } from "./AnimationGraphFlag.js";
|
|
6
|
-
import {
|
|
7
|
+
import { AnimationState } from "./AnimationState.js";
|
|
8
|
+
import { AnimationStateType } from "./AnimationStateType.js";
|
|
9
|
+
import { AnimationTransition } from "./AnimationTransition.js";
|
|
7
10
|
import {
|
|
8
11
|
readAnimationGraphDefinitionFromJSON
|
|
9
12
|
} from "./definition/serialization/readAnimationGraphDefinitionFromJSON.js";
|
|
10
|
-
import {
|
|
11
|
-
import { threeUpdateTransform } from "../../../../util/threeUpdateTransform.js";
|
|
12
|
-
import { computeHashIntegerArray } from "../../../../../../core/collection/array/computeHashIntegerArray.js";
|
|
13
|
-
import { computeHashFloat } from "../../../../../../core/primitives/numbers/computeHashFloat.js";
|
|
13
|
+
import { writeAnimationGraphDefinitionToJSON } from "./definition/serialization/writeAnimationGraphDefinitionToJSON.js";
|
|
14
14
|
|
|
15
15
|
export class AnimationGraph {
|
|
16
16
|
constructor() {
|
|
@@ -142,15 +142,22 @@ export class AnimationGraph {
|
|
|
142
142
|
};
|
|
143
143
|
}
|
|
144
144
|
|
|
145
|
+
/**
|
|
146
|
+
*
|
|
147
|
+
* @param {*} def Graph definition JSON
|
|
148
|
+
* @param {number} state
|
|
149
|
+
* @param {number} debtTime
|
|
150
|
+
* @param {number} flags
|
|
151
|
+
*/
|
|
145
152
|
fromJSON({ def, state, debtTime = 0, flags = 0 }) {
|
|
146
|
-
const
|
|
153
|
+
const graph_definition = readAnimationGraphDefinitionFromJSON(def);
|
|
147
154
|
|
|
148
155
|
this.debtTime = debtTime;
|
|
149
156
|
this.flags = flags;
|
|
150
|
-
this.initialize(
|
|
157
|
+
this.initialize(graph_definition);
|
|
151
158
|
|
|
152
159
|
if (state === undefined) {
|
|
153
|
-
state =
|
|
160
|
+
state = graph_definition.states.indexOf(graph_definition.startingSate);
|
|
154
161
|
}
|
|
155
162
|
|
|
156
163
|
this.state = this.states[state];
|
|
@@ -522,7 +529,7 @@ export class AnimationGraph {
|
|
|
522
529
|
}
|
|
523
530
|
|
|
524
531
|
// normalize
|
|
525
|
-
currentBlendState.
|
|
532
|
+
currentBlendState.weightsMultiplyScalar(1 / nAT);
|
|
526
533
|
}
|
|
527
534
|
} else {
|
|
528
535
|
//no active transitions, copy current state's blend matrix
|
|
@@ -553,6 +560,7 @@ export class AnimationGraph {
|
|
|
553
560
|
|
|
554
561
|
if (action === undefined) {
|
|
555
562
|
console.warn(`Action[${i}] is undefined`);
|
|
563
|
+
continue;
|
|
556
564
|
}
|
|
557
565
|
|
|
558
566
|
action.weight = weight;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AnimationStateType } from "./AnimationStateType.js";
|
|
2
1
|
import { BlendStateMatrix } from "../blending/BlendStateMatrix.js";
|
|
2
|
+
import { AnimationStateType } from "./AnimationStateType.js";
|
|
3
3
|
|
|
4
4
|
export class AnimationState {
|
|
5
5
|
constructor() {
|
|
@@ -11,13 +11,13 @@ export class AnimationState {
|
|
|
11
11
|
this.def = null;
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
|
-
*
|
|
14
|
+
* Incoming transitions
|
|
15
15
|
* @type {AnimationTransition[]}
|
|
16
16
|
*/
|
|
17
17
|
this.inEdges = [];
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
20
|
+
* Outgoing transitions
|
|
21
21
|
* @type {AnimationTransition[]}
|
|
22
22
|
*/
|
|
23
23
|
this.outEdges = [];
|