@woosh/meep-engine 2.80.0 → 2.81.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.
@@ -86056,7 +86056,7 @@ function computeStatisticalPartialMedian(values, start, end) {
86056
86056
 
86057
86057
  const range = end - start;
86058
86058
 
86059
- const position = (start + range) >> 1;
86059
+ const position = start + (range >> 1);
86060
86060
 
86061
86061
  return copy[position];
86062
86062
  }
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.80.0",
8
+ "version": "2.81.0",
9
9
  "main": "build/meep.module.js",
10
10
  "module": "build/meep.module.js",
11
11
  "exports": {
@@ -43,7 +43,7 @@
43
43
  "pako": "2.0.3"
44
44
  },
45
45
  "peerDependencies": {
46
- "three": ">=0.135.0 & <0.137.0"
46
+ "three": ">=0.135.0"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@babel/core": "7.22.9",
@@ -3,7 +3,7 @@
3
3
  * @see "dbellmf" function from Matlab
4
4
  * @see https://codecrucks.com/what-is-fuzzy-membership-function-complete-guide/
5
5
  * @see https://researchhubs.com/post/maths/fundamentals/bell-shaped-function.html
6
- * @param {number} v
6
+ * @param {number} v value to be filtered (have membership adjustment applied to)
7
7
  * @param {number} a Controls window, larger value = larger window. Function will return exactly 0.5 at this distance away from center
8
8
  * @param {number} b Slope, larger slope makes function's tails sharper, meaning that values fall off faster away from center
9
9
  * @param {number} c Controls center of the bell curve
@@ -1,8 +1,8 @@
1
1
  /**
2
- *
2
+ * Compute apex angle of an isosceles triangle (triangle with two equal sides)
3
3
  * @param {number} side length of the side
4
4
  * @param {number} base length of the base
5
- * @returns {number}
5
+ * @returns {number} Apex angle in radians
6
6
  */
7
7
  export function computeIsoscelesTriangleApexAngle(side, base) {
8
8
  const b2 = base * base;
@@ -0,0 +1,6 @@
1
+ import { computeIsoscelesTriangleApexAngle } from "./computeIsoscelesTriangleApexAngle.js";
2
+
3
+ test("sanity", () => {
4
+ // right-angle triangle
5
+ expect(computeIsoscelesTriangleApexAngle(1, Math.SQRT2)).toBeCloseTo(Math.PI / 2);
6
+ });
@@ -10,15 +10,21 @@ import { number_compare_ascending } from "../../primitives/numbers/number_compar
10
10
  */
11
11
  export function computeStatisticalPartialMedian(values, start, end) {
12
12
  assert.isArrayLike(values, 'values');
13
+ assert.isNumber(start, 'start');
14
+ assert.greaterThanOrEqual(start, 0);
15
+
16
+ assert.isNumber(end, 'end');
13
17
  assert.lessThan(end, values.length);
14
18
 
19
+ assert.lessThanOrEqual(start, end);
20
+
15
21
  const copy = values.slice();
16
22
 
17
23
  copy.sort(number_compare_ascending);
18
24
 
19
25
  const range = end - start;
20
26
 
21
- const position = (start + range) >> 1;
27
+ const position = start + (range >> 1);
22
28
 
23
29
  return copy[position];
24
30
  }
@@ -1,14 +1,23 @@
1
- import { computeStatisticalPartialMedian } from "./computeStatisticalPartialMedian.js";
1
+ import { assert } from "../../assert.js";
2
2
  import { clamp } from "../clamp.js";
3
+ import { computeStatisticalPartialMedian } from "./computeStatisticalPartialMedian.js";
3
4
 
4
5
  /**
5
6
  *
6
7
  * @param {number[]} values
7
- * @param {number} percentile_low
8
- * @param {number} percentile_high
8
+ * @param {number} percentile_low 0..1
9
+ * @param {number} percentile_high 0..1
9
10
  * @returns {number}
10
11
  */
11
12
  export function computeStatisticalPercentile(values, percentile_low, percentile_high) {
13
+ assert.isNumber(percentile_low, 'percentile_low');
14
+ assert.notNaN(percentile_low, 'percentile_low');
15
+
16
+ assert.isNumber(percentile_high, 'percentile_high');
17
+ assert.notNaN(percentile_high, 'percentile_high');
18
+
19
+ assert.greaterThanOrEqual(percentile_high, percentile_low);
20
+
12
21
  const n = values.length;
13
22
 
14
23
  const start = clamp(Math.floor(n * percentile_low), 0, n - 1);
@@ -0,0 +1,11 @@
1
+ import { computeStatisticalPercentile } from "./computeStatisticalPercentile.js";
2
+
3
+ test("half", () => {
4
+ expect(computeStatisticalPercentile([
5
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
6
+ ], 0, 0.5)).toBeCloseTo(2);
7
+
8
+ expect(computeStatisticalPercentile([
9
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
10
+ ], 0.5, 1)).toBeCloseTo(7);
11
+ });
@@ -0,0 +1,12 @@
1
+ import { computeStatisticalVariance } from "./computeStatisticalVariance.js";
2
+
3
+ /**
4
+ *
5
+ * @param {number[]} sample
6
+ * @returns {number}
7
+ */
8
+ export function computeStatisticalStandardDeviation(sample) {
9
+ const variance = computeStatisticalVariance(sample);
10
+
11
+ return Math.sqrt(variance);
12
+ }
@@ -1,11 +1,11 @@
1
1
  import { computeStatisticalMean } from "./computeStatisticalMean.js";
2
2
 
3
3
  /**
4
- *
4
+ * Compute statistical variance for a given sample of numbers
5
5
  * @param {number[]} sample
6
6
  * @returns {number}
7
7
  */
8
- export function computeSampleStandardDeviation(sample) {
8
+ export function computeStatisticalVariance(sample) {
9
9
  //compute sample mean
10
10
  const mean = computeStatisticalMean(sample);
11
11
 
@@ -22,7 +22,5 @@ export function computeSampleStandardDeviation(sample) {
22
22
  SUM += delta2;
23
23
  }
24
24
 
25
- const variance = SUM / (N - 1);
26
-
27
- return Math.sqrt(variance);
28
- }
25
+ return SUM / N;
26
+ }
@@ -0,0 +1,10 @@
1
+ import { computeStatisticalVariance } from "./computeStatisticalVariance.js";
2
+
3
+ test("sanity", () => {
4
+
5
+ expect(computeStatisticalVariance([
6
+ 1, 2, 3, 4, 5, 6
7
+ ]))
8
+ .toBeCloseTo(2.92);
9
+
10
+ });
@@ -1,7 +1,7 @@
1
- import {assert} from "../../assert.js";
2
- import {noop} from "../../function/Functions.js";
3
- import {objectKeyByValue} from "../object/objectKeyByValue.js";
4
- import {PortDirection} from "./node/PortDirection.js";
1
+ import { assert } from "../../assert.js";
2
+ import { noop } from "../../function/Functions.js";
3
+ import { objectKeyByValue } from "../object/objectKeyByValue.js";
4
+ import { PortDirection } from "./node/PortDirection.js";
5
5
 
6
6
  /**
7
7
  *
@@ -102,7 +102,8 @@ export class Connection {
102
102
  assert.isNumber(id, 'id');
103
103
  assert.isInteger(id, 'id');
104
104
 
105
- return this.source.instance.id === id || this.target.instance.id === id;
105
+ return this.source?.instance?.id === id
106
+ || this.target?.instance?.id === id;
106
107
  }
107
108
 
108
109
  /**
@@ -19,3 +19,15 @@ test("equality on self", () => {
19
19
 
20
20
  expect(thing.equals(thing)).toBe(true);
21
21
  });
22
+
23
+ test("isAttachedToNode", () => {
24
+ const connection = new Connection();
25
+
26
+ expect(connection.isAttachedToNode(0)).toBe(false);
27
+ });
28
+
29
+ test("toString", () => {
30
+ const ut = new Connection();
31
+
32
+ expect(typeof ut.toString()).toBe("string");
33
+ });
@@ -26,3 +26,22 @@ test('equals', () => {
26
26
 
27
27
  expect(c.equals(d)).toBe(false);
28
28
  });
29
+
30
+ test("hash", () => {
31
+
32
+ const a = DataType.from(7, 'kitty');
33
+ const b = DataType.from(7, 'kitty');
34
+
35
+ expect(a.hash()).toEqual(a.hash()); //stability
36
+ expect(typeof a.hash()).toBe("number");
37
+ expect(Number.isInteger(a.hash())).toBe(true);
38
+
39
+
40
+ expect(a.hash()).toEqual(b.hash());
41
+ });
42
+
43
+ test("toString", () => {
44
+ const type = DataType.from(7, 'kitty');
45
+
46
+ expect(typeof type.toString()).toBe("string");
47
+ });
@@ -24,4 +24,42 @@ test("get port by ID", () => {
24
24
 
25
25
  expect(port).not.toBeNull();
26
26
  expect(port.name).toBe("a");
27
+ });
28
+
29
+ test("get ports by name", () => {
30
+
31
+ const node = new NodeDescription();
32
+
33
+ expect(node.getPortsByName("a")).toEqual([]);
34
+
35
+ node.createPort(DUMMY_TYPE, "a", PortDirection.In);
36
+
37
+ const result_0 = node.getPortsByName("a");
38
+ expect(result_0.length).toBe(1);
39
+ expect(result_0[0].name).toBe("a");
40
+
41
+ node.createPort(DUMMY_TYPE, "b", PortDirection.In);
42
+
43
+ const result_1 = node.getPortsByName("a");
44
+ expect(result_1.length).toBe(1);
45
+ expect(result_1[0].name).toBe("a");
46
+ });
47
+
48
+ test("delete port", () => {
49
+ const node = new NodeDescription();
50
+
51
+ expect(node.deletePort(1)).toBe(false);
52
+
53
+ const id = node.createPort(DUMMY_TYPE, "a", PortDirection.In);
54
+
55
+ expect(node.deletePort(id)).toBe(true);
56
+
57
+ expect(node.getPorts()).toEqual([]);
58
+ });
59
+
60
+ test("toString", () => {
61
+ const node = new NodeDescription();
62
+
63
+ expect(typeof node.toString()).toBe("string");
64
+ expect(node.toString().length).toBeGreaterThan(0);
27
65
  });
@@ -0,0 +1,66 @@
1
+ import { DataType } from "../DataType.js";
2
+ import { NodeGraph } from "../NodeGraph.js";
3
+ import { NodeDescription } from "./NodeDescription.js";
4
+ import { NodeInstancePortReference } from "./NodeInstancePortReference.js";
5
+ import { PortDirection } from "./PortDirection.js";
6
+
7
+ const DUMMY_TYPE = DataType.from(0, 'dummy');
8
+ test("constructor does not throw", () => {
9
+ new NodeInstancePortReference()
10
+ });
11
+
12
+ test("outgoing connections", () => {
13
+ const nd = new NodeDescription();
14
+ const port_a_id = nd.createPort(DUMMY_TYPE, "a", PortDirection.Out);
15
+ const port_b_id = nd.createPort(DUMMY_TYPE, "b", PortDirection.In);
16
+
17
+
18
+ const graph = new NodeGraph();
19
+ const node_instance_id = graph.createNode(nd);
20
+
21
+ const port_a_ref = graph.getConnectionEndpoint(node_instance_id, port_a_id);
22
+
23
+ expect(port_a_ref.outConnections).toEqual([]);
24
+
25
+ const connection_id = graph.createConnection(node_instance_id, port_a_id, node_instance_id, port_b_id);
26
+
27
+ const connection = graph.getConnection(connection_id);
28
+
29
+ expect(port_a_ref.outConnections).toEqual([connection]);
30
+ });
31
+
32
+ test("incoming connections", () => {
33
+ const nd = new NodeDescription();
34
+ const port_a_id = nd.createPort(DUMMY_TYPE, "a", PortDirection.Out);
35
+ const port_b_id = nd.createPort(DUMMY_TYPE, "b", PortDirection.In);
36
+
37
+
38
+ const graph = new NodeGraph();
39
+ const node_instance_id = graph.createNode(nd);
40
+
41
+ const port_b_ref = graph.getConnectionEndpoint(node_instance_id, port_b_id);
42
+
43
+ expect(port_b_ref.inConnections).toEqual([]);
44
+
45
+ const connection_id = graph.createConnection(node_instance_id, port_a_id, node_instance_id, port_b_id);
46
+
47
+ const connection = graph.getConnection(connection_id);
48
+
49
+ expect(port_b_ref.inConnections).toEqual([connection]);
50
+ });
51
+
52
+ test("hash", () => {
53
+
54
+ const nd = new NodeDescription();
55
+ const port_a_id = nd.createPort(DUMMY_TYPE, "a", PortDirection.Out);
56
+
57
+
58
+ const graph = new NodeGraph();
59
+ const node_instance_id = graph.createNode(nd);
60
+
61
+ const port_a_ref = graph.getConnectionEndpoint(node_instance_id, port_a_id);
62
+
63
+ expect(port_a_ref.hash()).toEqual(port_a_ref.hash());
64
+ expect(typeof port_a_ref.hash()).toBe("number");
65
+ expect(Number.isInteger(port_a_ref.hash())).toBe(true);
66
+ });
@@ -1,16 +1,13 @@
1
- import { NodeGraph } from "../NodeGraph.js";
2
1
  import { assert } from "../../../assert.js";
2
+ import { NodeGraph } from "../NodeGraph.js";
3
3
  import { graph_collect_connections_amongst_nodes } from "./graph_collect_connections_amongst_nodes.js";
4
4
 
5
5
  /**
6
6
  * Clone portion of a graph as a new graph, retaining connections amongst those nodes
7
- * @param {NodeGraph} graph
8
7
  * @param {NodeInstance[]} nodes
8
+ * @returns {NodeGraph}
9
9
  */
10
- export function graph_clone_by_node_subset({ graph, nodes }) {
11
-
12
- assert.defined(graph, 'graph');
13
- assert.notNull(graph, 'graph');
10
+ export function graph_clone_by_node_subset({ nodes }) {
14
11
 
15
12
  assert.defined(nodes, 'nodes');
16
13
  assert.notNull(nodes, 'nodes');
@@ -18,7 +15,7 @@ export function graph_clone_by_node_subset({ graph, nodes }) {
18
15
 
19
16
  const result = new NodeGraph();
20
17
 
21
- const connections = graph_collect_connections_amongst_nodes({ graph, nodes });
18
+ const connections = graph_collect_connections_amongst_nodes({ nodes });
22
19
 
23
20
  result.mergeFragment({
24
21
  nodes,
@@ -1,11 +1,9 @@
1
1
  /**
2
2
  * Given a graph and a set of nodes, get all connections that connect these nodes amongst themselves
3
- * @param {NodeGraph} graph
4
3
  * @param {NodeInstance[]} nodes
5
4
  * @returns {Connection[]}
6
5
  */
7
6
  export function graph_collect_connections_amongst_nodes({
8
- graph,
9
7
  nodes
10
8
  }) {
11
9