@woosh/meep-engine 2.78.0 → 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
 
@@ -70583,10 +70594,19 @@ class Edge {
70583
70594
  return this.first === node || this.second === node;
70584
70595
  }
70585
70596
 
70597
+ /**
70598
+ *
70599
+ * @param {N} source
70600
+ * @param {N} target
70601
+ * @returns {boolean} True iff the edge contains both source and target and allows transition from source to target
70602
+ */
70586
70603
  validateTransition(source, target) {
70587
70604
  const a = this.first;
70588
70605
  const b = this.second;
70589
- return (a === source && b === target && this.traversableForward()) || (b === source && a === target && this.traversableBackward());
70606
+
70607
+ return (a === source && b === target && this.traversableForward())
70608
+ || (b === source && a === target && this.traversableBackward())
70609
+ ;
70590
70610
  }
70591
70611
 
70592
70612
  /**
@@ -70634,16 +70654,6 @@ class Edge {
70634
70654
  || (this.second === node && this.direction === EdgeDirectionType.Backward)
70635
70655
  }
70636
70656
 
70637
- /**
70638
- * @deprecated
70639
- * @returns {number}
70640
- */
70641
- angle() {
70642
-
70643
- const delta = this.second.clone().sub(this.first);
70644
- return Math.atan2(delta.y, delta.x);
70645
- }
70646
-
70647
70657
  /**
70648
70658
  *
70649
70659
  * @returns {N[]}
@@ -70652,15 +70662,6 @@ class Edge {
70652
70662
  return [this.first, this.second];
70653
70663
  }
70654
70664
 
70655
-
70656
- /**
70657
- * @deprecated
70658
- * @returns {number}
70659
- */
70660
- get length() {
70661
-
70662
- return this.first.distanceTo(this.second);
70663
- }
70664
70665
  }
70665
70666
 
70666
70667
  /**
@@ -70691,6 +70692,7 @@ class NodeContainer {
70691
70692
  /**
70692
70693
  *
70693
70694
  * @type {Map<N,number>}
70695
+ * Maps neighbour node to number of edges to that node from this one
70694
70696
  * @private
70695
70697
  */
70696
70698
  __neighbors = new Map();
@@ -71084,6 +71086,7 @@ class Graph {
71084
71086
  /**
71085
71087
  *
71086
71088
  * @param {N} node
71089
+ * @returns {boolean}
71087
71090
  */
71088
71091
  removeNode(node) {
71089
71092
 
@@ -71157,7 +71160,7 @@ class Graph {
71157
71160
  }
71158
71161
 
71159
71162
  /**
71160
- *
71163
+ * Node degree is the number of attached edges
71161
71164
  * @param {N} node
71162
71165
  * @return {number}
71163
71166
  */
@@ -71199,13 +71202,18 @@ class Graph {
71199
71202
  *
71200
71203
  * @param {N} source
71201
71204
  * @param {N} target
71202
- * @param {EdgeDirectionType} [type] Undirected by default
71205
+ * @param {EdgeDirectionType} [direction] Undirected by default
71203
71206
  * @returns {Edge<N>}
71204
71207
  */
71205
- createEdge(source, target, type = EdgeDirectionType.Undirected) {
71208
+ createEdge(
71209
+ source,
71210
+ target,
71211
+ direction = EdgeDirectionType.Undirected
71212
+ ) {
71213
+
71206
71214
  const edge = new Edge(source, target);
71207
71215
 
71208
- edge.direction = type;
71216
+ edge.direction = direction;
71209
71217
 
71210
71218
  this.addEdge(edge);
71211
71219
 
@@ -71213,9 +71221,10 @@ class Graph {
71213
71221
  }
71214
71222
 
71215
71223
  /**
71216
- *
71224
+ * Both nodes that the edge is attached to must be present
71217
71225
  * @param {Edge<N>} edge
71218
- * @returns {boolean}
71226
+ * @returns {boolean} true if edge was added, false if edge was already present
71227
+ * @throws if one or both nodes are not contained in the graph
71219
71228
  */
71220
71229
  addEdge(edge) {
71221
71230
  if (this.hasEdge(edge)) {
@@ -71417,10 +71426,10 @@ class Graph {
71417
71426
  }
71418
71427
 
71419
71428
  /**
71420
- *
71429
+ * Find a path through the graph
71421
71430
  * @param {N} start
71422
71431
  * @param {N} goal
71423
- * @returns {null|N[]}
71432
+ * @returns {null|N[]} null if no path exists
71424
71433
  */
71425
71434
  findPath(start, goal) {
71426
71435
  const start_node_container = this.__nodes.get(start);
@@ -71460,6 +71469,7 @@ class Graph {
71460
71469
  const b = edge.second;
71461
71470
 
71462
71471
  let other = null;
71472
+
71463
71473
  if (a === current_node && (edge.direction === EdgeDirectionType.Forward || edge.direction === EdgeDirectionType.Undirected)) {
71464
71474
  other = b;
71465
71475
  } else if (b === current_node && (edge.direction === EdgeDirectionType.Backward || edge.direction === EdgeDirectionType.Undirected)) {
@@ -71488,6 +71498,9 @@ class Graph {
71488
71498
  return null;
71489
71499
  }
71490
71500
 
71501
+ /**
71502
+ * Remove all data from the graph, resetting it to empty state
71503
+ */
71491
71504
  clear() {
71492
71505
  this.__nodes.clear();
71493
71506
  this.__edges.clear();
@@ -72956,6 +72969,7 @@ class TransformAttachment {
72956
72969
 
72957
72970
  /**
72958
72971
  * transform relative to the attachment target
72972
+ * Think of it as "local transform"
72959
72973
  * @type {Transform}
72960
72974
  */
72961
72975
  transform = new Transform();
@@ -73569,7 +73583,10 @@ class UpdateContext {
73569
73583
  }
73570
73584
 
73571
73585
  update() {
73572
- this.transform.multiplyTransforms(this.parent_transform, this.attachment.transform);
73586
+ this.transform.multiplyTransforms(
73587
+ this.parent_transform,
73588
+ this.attachment.transform
73589
+ );
73573
73590
  }
73574
73591
 
73575
73592
  /**
@@ -73592,51 +73609,51 @@ class UpdateContext {
73592
73609
  link() {
73593
73610
  const t_parent = this.parent_transform;
73594
73611
 
73595
- t_parent.position.onChanged.add(this.update, this);
73596
- t_parent.rotation.onChanged.add(this.update, this);
73597
- t_parent.scale.onChanged.add(this.update, this);
73612
+ t_parent.subscribe(this.update, this);
73598
73613
 
73599
73614
  const t_attachment = this.attachment.transform;
73600
- t_attachment.position.onChanged.add(this.update,this);
73601
- t_attachment.rotation.onChanged.add(this.update,this);
73602
- t_attachment.scale.onChanged.add(this.update,this);
73615
+
73616
+ t_attachment.subscribe(this.update, this);
73603
73617
  }
73604
73618
 
73605
73619
  unlink() {
73606
73620
  const transform = this.parent_transform;
73607
73621
 
73608
- transform.position.onChanged.remove(this.update, this);
73609
- transform.rotation.onChanged.remove(this.update, this);
73610
- transform.scale.onChanged.remove(this.update, this);
73622
+ transform.unsubscribe(this.update, this);
73611
73623
 
73612
73624
  const t_attachment = this.attachment.transform;
73613
- t_attachment.position.onChanged.remove(this.update,this);
73614
- t_attachment.rotation.onChanged.remove(this.update,this);
73615
- t_attachment.scale.onChanged.remove(this.update,this);
73625
+
73626
+ t_attachment.unsubscribe(this.update, this);
73616
73627
  }
73617
73628
  }
73618
73629
 
73619
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
+
73620
73648
  constructor() {
73621
73649
  super();
73622
73650
 
73623
73651
  this.dependencies = [TransformAttachment, Transform];
73624
73652
 
73625
- /**
73626
- *
73627
- * @type {UpdateContext[]}
73628
- * @private
73629
- */
73630
- this.__contexts = [];
73631
-
73632
- /**
73633
- *
73634
- * @type {UpdateContext[]}
73635
- * @private
73636
- */
73637
- this.__queue = [];
73638
- this.__queue_size = 0;
73639
- this.__queue_cursor = 0;
73653
+ this.components_used = [
73654
+ ResourceAccessSpecification.from(TransformAttachment, ResourceAccessKind.Read),
73655
+ ResourceAccessSpecification.from(Transform, ResourceAccessKind.Read | ResourceAccessKind.Write),
73656
+ ];
73640
73657
  }
73641
73658
 
73642
73659
  /**
@@ -73664,6 +73681,12 @@ class TransformAttachmentSystem extends System {
73664
73681
  this.__queue[this.__queue_size++] = ctx;
73665
73682
  }
73666
73683
 
73684
+ /**
73685
+ *
73686
+ * @param {number} entity
73687
+ * @returns {boolean}
73688
+ * @private
73689
+ */
73667
73690
  __dequeue_entity(entity) {
73668
73691
  for (let i = 0; i < this.__queue_size; i++) {
73669
73692
  const ctx = this.__queue[i];
@@ -73692,9 +73715,7 @@ class TransformAttachmentSystem extends System {
73692
73715
  ctx.entity = entity;
73693
73716
 
73694
73717
 
73695
- const ecd = this.entityManager.dataset;
73696
-
73697
- ctx.ecd = ecd;
73718
+ ctx.ecd = this.entityManager.dataset;
73698
73719
 
73699
73720
  if (ctx.bind_parent()) {
73700
73721
  this.__finalize_link(ctx);
@@ -73729,12 +73750,14 @@ class TransformAttachmentSystem extends System {
73729
73750
 
73730
73751
  update(timeDelta) {
73731
73752
  const step_count = min2(this.__queue_size, QUEUE_ITERATION_COUNT);
73753
+
73732
73754
  for (let i = 0; i < step_count; i++) {
73733
73755
  const index = this.__queue_cursor % this.__queue_size;
73734
73756
 
73735
73757
  const ctx = this.__queue[index];
73736
73758
 
73737
73759
  if (ctx.bind_parent()) {
73760
+ // parent obtained
73738
73761
  this.__finalize_link(ctx);
73739
73762
 
73740
73763
  this.__queue.splice(index, 1);
@@ -73744,6 +73767,7 @@ class TransformAttachmentSystem extends System {
73744
73767
  this.__queue_cursor++;
73745
73768
  }
73746
73769
  }
73770
+
73747
73771
  }
73748
73772
  }
73749
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.0",
8
+ "version": "2.79.0",
9
9
  "main": "build/meep.module.js",
10
10
  "module": "build/meep.module.js",
11
11
  "exports": {
@@ -1,8 +1,8 @@
1
- import { Graph } from "./v2/Graph.js";
2
- import { MultiNode } from "./MultiNode.js";
3
- import { compute_face_connection_weight } from "../geom/3d/topology/util/compute_face_connection_weight.js";
4
- import { WeightedEdge } from "./WeightedEdge.js";
5
- import { graph_compute_disconnected_clusters } from "./graph_compute_disconnected_clusters.js";
1
+ import { graph_compute_disconnected_clusters } from "../../../graph/graph_compute_disconnected_clusters.js";
2
+ import { MultiNode } from "../../../graph/MultiNode.js";
3
+ import { Graph } from "../../../graph/v2/Graph.js";
4
+ import { WeightedEdge } from "../../../graph/WeightedEdge.js";
5
+ import { compute_face_connection_weight } from "./util/compute_face_connection_weight.js";
6
6
 
7
7
 
8
8
  /**
@@ -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
  }
@@ -55,10 +55,19 @@ export class Edge {
55
55
  return this.first === node || this.second === node;
56
56
  }
57
57
 
58
+ /**
59
+ *
60
+ * @param {N} source
61
+ * @param {N} target
62
+ * @returns {boolean} True iff the edge contains both source and target and allows transition from source to target
63
+ */
58
64
  validateTransition(source, target) {
59
65
  const a = this.first;
60
66
  const b = this.second;
61
- return (a === source && b === target && this.traversableForward()) || (b === source && a === target && this.traversableBackward());
67
+
68
+ return (a === source && b === target && this.traversableForward())
69
+ || (b === source && a === target && this.traversableBackward())
70
+ ;
62
71
  }
63
72
 
64
73
  /**
@@ -106,17 +115,6 @@ export class Edge {
106
115
  || (this.second === node && this.direction === EdgeDirectionType.Backward)
107
116
  }
108
117
 
109
- /**
110
- * @deprecated
111
- * @returns {number}
112
- */
113
- angle() {
114
- console.error('method is deprecated, do not use');
115
-
116
- const delta = this.second.clone().sub(this.first);
117
- return Math.atan2(delta.y, delta.x);
118
- }
119
-
120
118
  /**
121
119
  *
122
120
  * @returns {N[]}
@@ -125,16 +123,6 @@ export class Edge {
125
123
  return [this.first, this.second];
126
124
  }
127
125
 
128
-
129
- /**
130
- * @deprecated
131
- * @returns {number}
132
- */
133
- get length() {
134
- console.error('method is deprecated, do not use');
135
-
136
- return this.first.distanceTo(this.second);
137
- }
138
126
  }
139
127
 
140
128
  /**
@@ -48,3 +48,38 @@ test('other', () => {
48
48
  expect(edge.other(3)).toBe(7);
49
49
  expect(edge.other(7)).toBe(3);
50
50
  });
51
+
52
+
53
+ test("isDirectedTowards", () => {
54
+ const e = new Edge(1, 3);
55
+
56
+ e.direction = EdgeDirectionType.Forward;
57
+
58
+ expect(e.isDirectedTowards(3)).toBe(true);
59
+ expect(e.isDirectedTowards(1)).toBe(false);
60
+
61
+ e.direction = EdgeDirectionType.Backward;
62
+
63
+ expect(e.isDirectedTowards(3)).toBe(false);
64
+ expect(e.isDirectedTowards(1)).toBe(true);
65
+ });
66
+
67
+ test("isDirectedAwayFrom", () => {
68
+ const e = new Edge(1, 3);
69
+
70
+ e.direction = EdgeDirectionType.Forward;
71
+
72
+ expect(e.isDirectedAwayFrom(3)).toBe(false);
73
+ expect(e.isDirectedAwayFrom(1)).toBe(true);
74
+
75
+ e.direction = EdgeDirectionType.Backward;
76
+
77
+ expect(e.isDirectedAwayFrom(3)).toBe(true);
78
+ expect(e.isDirectedAwayFrom(1)).toBe(false);
79
+ });
80
+
81
+ test("nodes accessor", () => {
82
+ const e = new Edge(1, 3);
83
+
84
+ expect(e.nodes).toEqual([1, 3]);
85
+ });
@@ -1,14 +1,13 @@
1
1
  /**
2
+ * A grouping node, intended mainly for meta-graphs, or hierarchical graphs
2
3
  * @template T
3
4
  */
4
5
  export class MultiNode {
5
- constructor() {
6
- /**
7
- *
8
- * @type {T[]}
9
- */
10
- this.source_nodes = [];
11
- }
6
+ /**
7
+ *
8
+ * @type {T[]}
9
+ */
10
+ source_nodes = [];
12
11
 
13
12
  /**
14
13
  *
@@ -92,6 +92,7 @@ export class Graph {
92
92
  /**
93
93
  *
94
94
  * @param {N} node
95
+ * @returns {boolean}
95
96
  */
96
97
  removeNode(node) {
97
98
 
@@ -165,7 +166,7 @@ export class Graph {
165
166
  }
166
167
 
167
168
  /**
168
- *
169
+ * Node degree is the number of attached edges
169
170
  * @param {N} node
170
171
  * @return {number}
171
172
  */
@@ -207,13 +208,19 @@ export class Graph {
207
208
  *
208
209
  * @param {N} source
209
210
  * @param {N} target
210
- * @param {EdgeDirectionType} [type] Undirected by default
211
+ * @param {EdgeDirectionType} [direction] Undirected by default
211
212
  * @returns {Edge<N>}
212
213
  */
213
- createEdge(source, target, type = EdgeDirectionType.Undirected) {
214
+ createEdge(
215
+ source,
216
+ target,
217
+ direction = EdgeDirectionType.Undirected
218
+ ) {
219
+ assert.enum(direction, EdgeDirectionType, 'direction');
220
+
214
221
  const edge = new Edge(source, target);
215
222
 
216
- edge.direction = type;
223
+ edge.direction = direction;
217
224
 
218
225
  this.addEdge(edge);
219
226
 
@@ -221,9 +228,10 @@ export class Graph {
221
228
  }
222
229
 
223
230
  /**
224
- *
231
+ * Both nodes that the edge is attached to must be present
225
232
  * @param {Edge<N>} edge
226
- * @returns {boolean}
233
+ * @returns {boolean} true if edge was added, false if edge was already present
234
+ * @throws if one or both nodes are not contained in the graph
227
235
  */
228
236
  addEdge(edge) {
229
237
  if (this.hasEdge(edge)) {
@@ -431,10 +439,10 @@ export class Graph {
431
439
  }
432
440
 
433
441
  /**
434
- *
442
+ * Find a path through the graph
435
443
  * @param {N} start
436
444
  * @param {N} goal
437
- * @returns {null|N[]}
445
+ * @returns {null|N[]} null if no path exists
438
446
  */
439
447
  findPath(start, goal) {
440
448
  const start_node_container = this.__nodes.get(start);
@@ -474,6 +482,7 @@ export class Graph {
474
482
  const b = edge.second;
475
483
 
476
484
  let other = null;
485
+
477
486
  if (a === current_node && (edge.direction === EdgeDirectionType.Forward || edge.direction === EdgeDirectionType.Undirected)) {
478
487
  other = b;
479
488
  } else if (b === current_node && (edge.direction === EdgeDirectionType.Backward || edge.direction === EdgeDirectionType.Undirected)) {
@@ -502,6 +511,9 @@ export class Graph {
502
511
  return null;
503
512
  }
504
513
 
514
+ /**
515
+ * Remove all data from the graph, resetting it to empty state
516
+ */
505
517
  clear() {
506
518
  this.__nodes.clear();
507
519
  this.__edges.clear();
@@ -22,6 +22,7 @@ export class NodeContainer {
22
22
  /**
23
23
  *
24
24
  * @type {Map<N,number>}
25
+ * Maps neighbour node to number of edges to that node from this one
25
26
  * @private
26
27
  */
27
28
  __neighbors = new Map();
@@ -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,