@woosh/meep-engine 2.78.1 → 2.79.0

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.
@@ -1978,10 +1978,15 @@ function v3_length(x, y, z) {
1978
1978
  * @param {number} z1
1979
1979
  * @returns {number}
1980
1980
  */
1981
- function v3_angle_between(x0, y0, z0, x1, y1, z1) {
1981
+ function v3_angle_between(
1982
+ x0, y0, z0,
1983
+ x1, y1, z1
1984
+ ) {
1985
+
1982
1986
  const theta = v3_angle_cos_between(x0, y0, z0, x1, y1, z1);
1983
1987
 
1984
1988
  return Math.acos(theta);
1989
+
1985
1990
  }
1986
1991
 
1987
1992
  /**
@@ -1992,9 +1997,13 @@ function v3_angle_between(x0, y0, z0, x1, y1, z1) {
1992
1997
  * @param {number} x1
1993
1998
  * @param {number} y1
1994
1999
  * @param {number} z1
1995
- * @returns {number}
2000
+ * @returns {number} value between -1 and 1, cosine of the angle between vectors
1996
2001
  */
1997
- function v3_angle_cos_between(x0, y0, z0, x1, y1, z1){
2002
+ function v3_angle_cos_between(
2003
+ x0, y0, z0,
2004
+ x1, y1, z1
2005
+ ) {
2006
+
1998
2007
  const d = v3_dot(x0, y0, z0, x1, y1, z1);
1999
2008
 
2000
2009
  const magnitude_0 = v3_length(x0, y0, z0);
@@ -2004,10 +2013,12 @@ function v3_angle_cos_between(x0, y0, z0, x1, y1, z1){
2004
2013
 
2005
2014
  if (l === 0) {
2006
2015
  // collective magnitude is 0, provide arbitrary angle
2016
+ // avoid division by 0
2007
2017
  return 0;
2008
2018
  }
2009
2019
 
2010
2020
  return clamp$1(d / l, -1, 1);
2021
+
2011
2022
  }
2012
2023
 
2013
2024
  /**
@@ -4706,7 +4717,7 @@ let Quaternion$1 = class Quaternion {
4706
4717
  * @param {Quaternion} result
4707
4718
  * @param {Quaternion} from
4708
4719
  * @param {Quaternion} to
4709
- * @param {number} max_delta
4720
+ * @param {number} max_delta in radians
4710
4721
  */
4711
4722
  static rotateTowards(result, from, to, max_delta) {
4712
4723
 
@@ -72958,6 +72969,7 @@ class TransformAttachment {
72958
72969
 
72959
72970
  /**
72960
72971
  * transform relative to the attachment target
72972
+ * Think of it as "local transform"
72961
72973
  * @type {Transform}
72962
72974
  */
72963
72975
  transform = new Transform();
@@ -73571,7 +73583,10 @@ class UpdateContext {
73571
73583
  }
73572
73584
 
73573
73585
  update() {
73574
- this.transform.multiplyTransforms(this.parent_transform, this.attachment.transform);
73586
+ this.transform.multiplyTransforms(
73587
+ this.parent_transform,
73588
+ this.attachment.transform
73589
+ );
73575
73590
  }
73576
73591
 
73577
73592
  /**
@@ -73594,51 +73609,51 @@ class UpdateContext {
73594
73609
  link() {
73595
73610
  const t_parent = this.parent_transform;
73596
73611
 
73597
- t_parent.position.onChanged.add(this.update, this);
73598
- t_parent.rotation.onChanged.add(this.update, this);
73599
- t_parent.scale.onChanged.add(this.update, this);
73612
+ t_parent.subscribe(this.update, this);
73600
73613
 
73601
73614
  const t_attachment = this.attachment.transform;
73602
- t_attachment.position.onChanged.add(this.update,this);
73603
- t_attachment.rotation.onChanged.add(this.update,this);
73604
- t_attachment.scale.onChanged.add(this.update,this);
73615
+
73616
+ t_attachment.subscribe(this.update, this);
73605
73617
  }
73606
73618
 
73607
73619
  unlink() {
73608
73620
  const transform = this.parent_transform;
73609
73621
 
73610
- transform.position.onChanged.remove(this.update, this);
73611
- transform.rotation.onChanged.remove(this.update, this);
73612
- transform.scale.onChanged.remove(this.update, this);
73622
+ transform.unsubscribe(this.update, this);
73613
73623
 
73614
73624
  const t_attachment = this.attachment.transform;
73615
- t_attachment.position.onChanged.remove(this.update,this);
73616
- t_attachment.rotation.onChanged.remove(this.update,this);
73617
- t_attachment.scale.onChanged.remove(this.update,this);
73625
+
73626
+ t_attachment.unsubscribe(this.update, this);
73618
73627
  }
73619
73628
  }
73620
73629
 
73621
73630
  class TransformAttachmentSystem extends System {
73631
+
73632
+ /**
73633
+ *
73634
+ * @type {UpdateContext[]}
73635
+ * @private
73636
+ */
73637
+ __contexts = [];
73638
+
73639
+ /**
73640
+ *
73641
+ * @type {UpdateContext[]}
73642
+ * @private
73643
+ */
73644
+ __queue = [];
73645
+ __queue_size = 0;
73646
+ __queue_cursor = 0;
73647
+
73622
73648
  constructor() {
73623
73649
  super();
73624
73650
 
73625
73651
  this.dependencies = [TransformAttachment, Transform];
73626
73652
 
73627
- /**
73628
- *
73629
- * @type {UpdateContext[]}
73630
- * @private
73631
- */
73632
- this.__contexts = [];
73633
-
73634
- /**
73635
- *
73636
- * @type {UpdateContext[]}
73637
- * @private
73638
- */
73639
- this.__queue = [];
73640
- this.__queue_size = 0;
73641
- this.__queue_cursor = 0;
73653
+ this.components_used = [
73654
+ ResourceAccessSpecification.from(TransformAttachment, ResourceAccessKind.Read),
73655
+ ResourceAccessSpecification.from(Transform, ResourceAccessKind.Read | ResourceAccessKind.Write),
73656
+ ];
73642
73657
  }
73643
73658
 
73644
73659
  /**
@@ -73666,6 +73681,12 @@ class TransformAttachmentSystem extends System {
73666
73681
  this.__queue[this.__queue_size++] = ctx;
73667
73682
  }
73668
73683
 
73684
+ /**
73685
+ *
73686
+ * @param {number} entity
73687
+ * @returns {boolean}
73688
+ * @private
73689
+ */
73669
73690
  __dequeue_entity(entity) {
73670
73691
  for (let i = 0; i < this.__queue_size; i++) {
73671
73692
  const ctx = this.__queue[i];
@@ -73694,9 +73715,7 @@ class TransformAttachmentSystem extends System {
73694
73715
  ctx.entity = entity;
73695
73716
 
73696
73717
 
73697
- const ecd = this.entityManager.dataset;
73698
-
73699
- ctx.ecd = ecd;
73718
+ ctx.ecd = this.entityManager.dataset;
73700
73719
 
73701
73720
  if (ctx.bind_parent()) {
73702
73721
  this.__finalize_link(ctx);
@@ -73731,12 +73750,14 @@ class TransformAttachmentSystem extends System {
73731
73750
 
73732
73751
  update(timeDelta) {
73733
73752
  const step_count = min2(this.__queue_size, QUEUE_ITERATION_COUNT);
73753
+
73734
73754
  for (let i = 0; i < step_count; i++) {
73735
73755
  const index = this.__queue_cursor % this.__queue_size;
73736
73756
 
73737
73757
  const ctx = this.__queue[index];
73738
73758
 
73739
73759
  if (ctx.bind_parent()) {
73760
+ // parent obtained
73740
73761
  this.__finalize_link(ctx);
73741
73762
 
73742
73763
  this.__queue.splice(index, 1);
@@ -73746,6 +73767,7 @@ class TransformAttachmentSystem extends System {
73746
73767
  this.__queue_cursor++;
73747
73768
  }
73748
73769
  }
73770
+
73749
73771
  }
73750
73772
  }
73751
73773
 
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "description": "Fully featured ECS game engine written in JavaScript",
6
6
  "type": "module",
7
7
  "author": "Alexander Goldring",
8
- "version": "2.78.1",
8
+ "version": "2.79.0",
9
9
  "main": "build/meep.module.js",
10
10
  "module": "build/meep.module.js",
11
11
  "exports": {
@@ -1546,7 +1546,7 @@ class Quaternion {
1546
1546
  * @param {Quaternion} result
1547
1547
  * @param {Quaternion} from
1548
1548
  * @param {Quaternion} to
1549
- * @param {number} max_delta
1549
+ * @param {number} max_delta in radians
1550
1550
  */
1551
1551
  static rotateTowards(result, from, to, max_delta) {
1552
1552
  assert.isNumber(max_delta, 'max_delta');
@@ -1,6 +1,6 @@
1
+ import { clamp } from "../../math/clamp.js";
1
2
  import { v3_dot } from "./v3_dot.js";
2
3
  import { v3_length } from "./v3_length.js";
3
- import { clamp } from "../../math/clamp.js";
4
4
 
5
5
  /**
6
6
  *
@@ -12,10 +12,15 @@ import { clamp } from "../../math/clamp.js";
12
12
  * @param {number} z1
13
13
  * @returns {number}
14
14
  */
15
- export function v3_angle_between(x0, y0, z0, x1, y1, z1) {
15
+ export function v3_angle_between(
16
+ x0, y0, z0,
17
+ x1, y1, z1
18
+ ) {
19
+
16
20
  const theta = v3_angle_cos_between(x0, y0, z0, x1, y1, z1);
17
21
 
18
22
  return Math.acos(theta);
23
+
19
24
  }
20
25
 
21
26
  /**
@@ -26,9 +31,13 @@ export function v3_angle_between(x0, y0, z0, x1, y1, z1) {
26
31
  * @param {number} x1
27
32
  * @param {number} y1
28
33
  * @param {number} z1
29
- * @returns {number}
34
+ * @returns {number} value between -1 and 1, cosine of the angle between vectors
30
35
  */
31
- export function v3_angle_cos_between(x0, y0, z0, x1, y1, z1){
36
+ export function v3_angle_cos_between(
37
+ x0, y0, z0,
38
+ x1, y1, z1
39
+ ) {
40
+
32
41
  const d = v3_dot(x0, y0, z0, x1, y1, z1);
33
42
 
34
43
  const magnitude_0 = v3_length(x0, y0, z0);
@@ -38,10 +47,12 @@ export function v3_angle_cos_between(x0, y0, z0, x1, y1, z1){
38
47
 
39
48
  if (l === 0) {
40
49
  // collective magnitude is 0, provide arbitrary angle
50
+ // avoid division by 0
41
51
  return 0;
42
52
  }
43
53
 
44
54
  return clamp(d / l, -1, 1);
55
+
45
56
  }
46
57
 
47
58
  /**
@@ -8,8 +8,9 @@
8
8
  * @param {number} directionX
9
9
  * @param {number} directionY
10
10
  * @param {number} directionZ
11
+ * @returns {boolean} true if displaced successfully, false if direction had 0 magnitude
11
12
  */
12
- export function v3_computeOffsetVector(
13
+ export function v3_displace_in_direction(
13
14
  result,
14
15
  distance,
15
16
  sourceX, sourceY, sourceZ,
@@ -17,13 +18,19 @@ export function v3_computeOffsetVector(
17
18
  ) {
18
19
  if (distance === 0) {
19
20
  result.set(sourceX, sourceY, sourceZ);
20
- return;
21
+ return true;
21
22
  }
22
23
 
23
24
  //scale direction to have length equal to distance
24
25
 
25
26
  const directionLength = Math.sqrt(directionX * directionX + directionY * directionY + directionZ * directionZ);
26
27
 
28
+ if(directionLength === 0){
29
+ // direction vector is zero length, avoid division by zero, clamp to source instead
30
+ result.set(sourceX, sourceY, sourceZ);
31
+ return false;
32
+ }
33
+
27
34
  const m = distance / directionLength;
28
35
 
29
36
  const x = sourceX + directionX * m;
@@ -31,4 +38,6 @@ export function v3_computeOffsetVector(
31
38
  const z = sourceZ + directionZ * m;
32
39
 
33
40
  result.set(x, y, z);
41
+
42
+ return true;
34
43
  }
@@ -1,6 +1,6 @@
1
1
  import { SurfacePoint3 } from "../../../core/geom/3d/SurfacePoint3.js";
2
2
  import Quaternion from "../../../core/geom/Quaternion.js";
3
- import { v3_computeOffsetVector } from "../../../core/geom/vec3/v3_computeOffsetVector.js";
3
+ import { v3_displace_in_direction } from "../../../core/geom/vec3/v3_displace_in_direction.js";
4
4
  import { v3_dot } from "../../../core/geom/vec3/v3_dot.js";
5
5
  import { v3_length } from "../../../core/geom/vec3/v3_length.js";
6
6
  import Vector3 from "../../../core/geom/Vector3.js";
@@ -116,7 +116,7 @@ export class OneBoneSurfaceAlignmentSolver extends IKSolver {
116
116
 
117
117
  const targetOffsetDistance = constraint.offset * bone_scale;
118
118
 
119
- v3_computeOffsetVector(
119
+ v3_displace_in_direction(
120
120
  targetPosition,
121
121
  targetOffsetDistance,
122
122
  contactPosition.x, contactPosition.y, contactPosition.z,
@@ -1,7 +1,7 @@
1
1
  import { assert } from "../../../core/assert.js";
2
2
  import { SurfacePoint3 } from "../../../core/geom/3d/SurfacePoint3.js";
3
3
  import Quaternion from "../../../core/geom/Quaternion.js";
4
- import { v3_computeOffsetVector } from "../../../core/geom/vec3/v3_computeOffsetVector.js";
4
+ import { v3_displace_in_direction } from "../../../core/geom/vec3/v3_displace_in_direction.js";
5
5
  import { v3_dot } from "../../../core/geom/vec3/v3_dot.js";
6
6
  import { v3_length } from "../../../core/geom/vec3/v3_length.js";
7
7
  import Vector3 from "../../../core/geom/Vector3.js";
@@ -255,7 +255,7 @@ export class TwoBoneInverseKinematicsSolver extends IKSolver {
255
255
 
256
256
  const targetOffsetDistance = constraint.offset * limbLength;
257
257
 
258
- v3_computeOffsetVector(
258
+ v3_displace_in_direction(
259
259
  targetPosition,
260
260
  targetOffsetDistance,
261
261
  contactPosition.x, contactPosition.y, contactPosition.z,
@@ -1,5 +1,5 @@
1
- import { Transform } from "../transform/Transform.js";
2
1
  import { assert } from "../../../core/assert.js";
2
+ import { Transform } from "../transform/Transform.js";
3
3
 
4
4
  export const TransformAttachmentFlags = {
5
5
  /**
@@ -15,6 +15,7 @@ export class TransformAttachment {
15
15
 
16
16
  /**
17
17
  * transform relative to the attachment target
18
+ * Think of it as "local transform"
18
19
  * @type {Transform}
19
20
  */
20
21
  transform = new Transform();
@@ -1,7 +1,9 @@
1
+ import { min2 } from "../../../core/math/min2.js";
2
+ import { ResourceAccessKind } from "../../../core/model/ResourceAccessKind.js";
3
+ import { ResourceAccessSpecification } from "../../../core/model/ResourceAccessSpecification.js";
1
4
  import { System } from "../System.js";
2
- import { TransformAttachment, TransformAttachmentFlags } from "./TransformAttachment.js";
3
5
  import { Transform } from "../transform/Transform.js";
4
- import { min2 } from "../../../core/math/min2.js";
6
+ import { TransformAttachment, TransformAttachmentFlags } from "./TransformAttachment.js";
5
7
 
6
8
  /**
7
9
  * @readonly
@@ -47,7 +49,10 @@ class UpdateContext {
47
49
  }
48
50
 
49
51
  update() {
50
- this.transform.multiplyTransforms(this.parent_transform, this.attachment.transform);
52
+ this.transform.multiplyTransforms(
53
+ this.parent_transform,
54
+ this.attachment.transform
55
+ );
51
56
  }
52
57
 
53
58
  /**
@@ -70,51 +75,51 @@ class UpdateContext {
70
75
  link() {
71
76
  const t_parent = this.parent_transform;
72
77
 
73
- t_parent.position.onChanged.add(this.update, this);
74
- t_parent.rotation.onChanged.add(this.update, this);
75
- t_parent.scale.onChanged.add(this.update, this);
78
+ t_parent.subscribe(this.update, this);
76
79
 
77
80
  const t_attachment = this.attachment.transform;
78
- t_attachment.position.onChanged.add(this.update,this);
79
- t_attachment.rotation.onChanged.add(this.update,this);
80
- t_attachment.scale.onChanged.add(this.update,this);
81
+
82
+ t_attachment.subscribe(this.update, this);
81
83
  }
82
84
 
83
85
  unlink() {
84
86
  const transform = this.parent_transform;
85
87
 
86
- transform.position.onChanged.remove(this.update, this);
87
- transform.rotation.onChanged.remove(this.update, this);
88
- transform.scale.onChanged.remove(this.update, this);
88
+ transform.unsubscribe(this.update, this);
89
89
 
90
90
  const t_attachment = this.attachment.transform;
91
- t_attachment.position.onChanged.remove(this.update,this);
92
- t_attachment.rotation.onChanged.remove(this.update,this);
93
- t_attachment.scale.onChanged.remove(this.update,this);
91
+
92
+ t_attachment.unsubscribe(this.update, this);
94
93
  }
95
94
  }
96
95
 
97
96
  export class TransformAttachmentSystem extends System {
97
+
98
+ /**
99
+ *
100
+ * @type {UpdateContext[]}
101
+ * @private
102
+ */
103
+ __contexts = [];
104
+
105
+ /**
106
+ *
107
+ * @type {UpdateContext[]}
108
+ * @private
109
+ */
110
+ __queue = [];
111
+ __queue_size = 0;
112
+ __queue_cursor = 0;
113
+
98
114
  constructor() {
99
115
  super();
100
116
 
101
117
  this.dependencies = [TransformAttachment, Transform];
102
118
 
103
- /**
104
- *
105
- * @type {UpdateContext[]}
106
- * @private
107
- */
108
- this.__contexts = [];
109
-
110
- /**
111
- *
112
- * @type {UpdateContext[]}
113
- * @private
114
- */
115
- this.__queue = [];
116
- this.__queue_size = 0;
117
- this.__queue_cursor = 0;
119
+ this.components_used = [
120
+ ResourceAccessSpecification.from(TransformAttachment, ResourceAccessKind.Read),
121
+ ResourceAccessSpecification.from(Transform, ResourceAccessKind.Read | ResourceAccessKind.Write),
122
+ ];
118
123
  }
119
124
 
120
125
  /**
@@ -142,6 +147,12 @@ export class TransformAttachmentSystem extends System {
142
147
  this.__queue[this.__queue_size++] = ctx;
143
148
  }
144
149
 
150
+ /**
151
+ *
152
+ * @param {number} entity
153
+ * @returns {boolean}
154
+ * @private
155
+ */
145
156
  __dequeue_entity(entity) {
146
157
  for (let i = 0; i < this.__queue_size; i++) {
147
158
  const ctx = this.__queue[i];
@@ -170,9 +181,7 @@ export class TransformAttachmentSystem extends System {
170
181
  ctx.entity = entity;
171
182
 
172
183
 
173
- const ecd = this.entityManager.dataset;
174
-
175
- ctx.ecd = ecd;
184
+ ctx.ecd = this.entityManager.dataset;
176
185
 
177
186
  if (ctx.bind_parent()) {
178
187
  this.__finalize_link(ctx);
@@ -207,12 +216,14 @@ export class TransformAttachmentSystem extends System {
207
216
 
208
217
  update(timeDelta) {
209
218
  const step_count = min2(this.__queue_size, QUEUE_ITERATION_COUNT);
219
+
210
220
  for (let i = 0; i < step_count; i++) {
211
221
  const index = this.__queue_cursor % this.__queue_size;
212
222
 
213
223
  const ctx = this.__queue[index];
214
224
 
215
225
  if (ctx.bind_parent()) {
226
+ // parent obtained
216
227
  this.__finalize_link(ctx);
217
228
 
218
229
  this.__queue.splice(index, 1);
@@ -222,5 +233,6 @@ export class TransformAttachmentSystem extends System {
222
233
  this.__queue_cursor++;
223
234
  }
224
235
  }
236
+
225
237
  }
226
238
  }