@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.
Files changed (27) hide show
  1. package/build/meep.cjs +139 -84
  2. package/build/meep.min.js +1 -1
  3. package/build/meep.module.js +139 -84
  4. package/package.json +1 -1
  5. package/src/core/collection/array/arrayIndexByEquality.js +1 -0
  6. package/src/core/collection/list/List.js +26 -18
  7. package/src/core/collection/list/List.spec.js +73 -0
  8. package/src/core/primitives/numbers/number_count_decimals.js +30 -0
  9. package/src/core/primitives/numbers/number_pretty_print.js +7 -29
  10. package/src/core/primitives/strings/string_format_camel_to_kebab.js +2 -0
  11. package/src/core/primitives/strings/string_strip_trailing.js +22 -0
  12. package/src/core/primitives/strings/string_strip_trailing.spec.js +27 -0
  13. package/src/core/process/worker/WorkerBuilder.js +5 -1
  14. package/src/core/process/worker/WorkerProxy.js +3 -2
  15. package/src/engine/ecs/Entity.spec.js +33 -0
  16. package/src/engine/ecs/EntityComponentDataset.js +17 -11
  17. package/src/engine/ecs/storage/BinaryBufferDeSerializer.js +8 -1
  18. package/src/engine/graphics/camera/CameraShake.js +1 -127
  19. package/src/engine/graphics/camera/CameraShakeBehavior.js +91 -0
  20. package/src/engine/graphics/camera/CameraShakeTraumaBehavior.js +38 -0
  21. package/src/engine/graphics/ecs/animation/animator/AnimationGraphSystem.js +9 -23
  22. package/src/engine/graphics/ecs/animation/animator/blending/BlendStateMatrix.js +11 -6
  23. package/src/engine/graphics/ecs/animation/animator/graph/AnimationGraph.js +20 -12
  24. package/src/engine/graphics/ecs/animation/animator/graph/AnimationState.js +3 -3
  25. package/src/engine/graphics/ecs/path/tube/build/estimatePathViaIterativeIntegral.js +1 -1
  26. package/src/view/View.js +52 -30
  27. 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} entityIndex
839
+ * @param {number} entity_id
840
840
  */
841
- removeEntity(entityIndex) {
842
- if (!this.entityExists(entityIndex)) {
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 = entityIndex * typeCount;
850
+ const occupancyStart = entity_id * typeCount;
851
851
  const occupancyEnd = occupancyStart + typeCount;
852
852
 
853
- for (let i = componentOccupancy.nextSetBit(occupancyStart); i < occupancyEnd && i !== -1; i = componentOccupancy.nextSetBit(i + 1)) {
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(entityIndex, componentIndex, i);
860
+ this.removeComponentFromEntityByIndex_Unchecked(entity_id, componentIndex, i);
856
861
  }
857
862
 
858
863
  //dispatch event
859
- this.sendEvent(entityIndex, EventType.EntityRemoved, entityIndex);
864
+ this.sendEvent(entity_id, EventType.EntityRemoved, entity_id);
860
865
 
861
866
  //purge all event listeners
862
- delete this.__entityEventListeners[entityIndex];
863
- delete this.__entityAnyEventListeners[entityIndex];
867
+ delete this.__entityEventListeners[entity_id];
868
+ delete this.__entityAnyEventListeners[entity_id];
864
869
 
865
- this.entityOccupancy.set(entityIndex, false);
870
+ this.entityOccupancy.set(entity_id, false);
866
871
 
867
872
  this.entityCount--;
868
873
 
869
- this.onEntityRemoved.send1(entityIndex);
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
- console.log(`Binary Buffer De-Serialization took ${task.getExecutedCpuTime()}ms`);
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 { AnimationGraph } from "./graph/AnimationGraph.js";
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 { assert } from "../../../../../core/assert.js";
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
- divideScalar(v) {
68
- const tW = this.weights;
69
- const tTS = this.timeScales;
74
+ weightsMultiplyScalar(v) {
75
+ const weights = this.weights;
70
76
 
71
- const n = tW.length;
77
+ const n = weights.length;
72
78
 
73
79
  for (let i = 0; i < n; i++) {
74
- tW[i] /= v;
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 { writeAnimationGraphDefinitionToJSON } from "./definition/serialization/writeAnimationGraphDefinitionToJSON.js";
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 { assert } from "../../../../../../core/assert.js";
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 graphDefinition = readAnimationGraphDefinitionFromJSON(def);
153
+ const graph_definition = readAnimationGraphDefinitionFromJSON(def);
147
154
 
148
155
  this.debtTime = debtTime;
149
156
  this.flags = flags;
150
- this.initialize(graphDefinition);
157
+ this.initialize(graph_definition);
151
158
 
152
159
  if (state === undefined) {
153
- state = graphDefinition.states.indexOf(graphDefinition.startingSate);
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.divideScalar(nAT);
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 = [];
@@ -18,7 +18,7 @@ export function estimatePathViaIterativeIntegral(path, epsilon) {
18
18
  return 0;
19
19
  }
20
20
 
21
- for (let p = epsilon; ; i += epsilon) {
21
+ for (let p = epsilon; ; p += epsilon) {
22
22
  const ended = path.sample(p1, p);
23
23
 
24
24
  if (ended) {