@woosh/meep-engine 2.55.0 → 2.56.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.
Files changed (155) hide show
  1. package/editor/view/node-graph/PortView.js +2 -2
  2. package/package.json +1 -1
  3. package/src/core/binary/BinaryBuffer.js +2 -1
  4. package/src/core/cache/LoadingCache.js +10 -5
  5. package/src/core/collection/array/array_remove_element.js +6 -9
  6. package/src/core/collection/array/array_remove_first.js +13 -6
  7. package/src/core/collection/array/array_remove_first.spec.js +39 -0
  8. package/src/core/collection/array/binarySearchHighIndex.spec.js +10 -9
  9. package/src/core/collection/heap/Uin32Heap.spec.js +36 -0
  10. package/src/core/collection/heap/Uint32Heap.js +10 -5
  11. package/src/core/function/FunctionCompiler.js +4 -4
  12. package/src/core/function/Functions.js +0 -19
  13. package/src/core/geom/3d/SurfacePoint3.js +30 -20
  14. package/src/core/geom/3d/SurfacePoint3.spec.js +116 -0
  15. package/src/core/geom/3d/aabb/AABB3.js +10 -9
  16. package/src/core/geom/3d/aabb/{aabb3_array_contains_point.js → aabb3_array_intersects_point.js} +4 -1
  17. package/src/core/geom/3d/aabb/aabb3_from_min_max.js +25 -1
  18. package/src/core/geom/3d/aabb/aabb3_from_threejs_geometry.js +2 -25
  19. package/src/core/geom/3d/aabb/aabb3_signed_distance_sqr_to_point.js +5 -1
  20. package/src/core/geom/3d/apply_mat4_transform_to_direction_v3_array.js +5 -1
  21. package/src/core/geom/3d/apply_mat4_transform_to_v3_array.js +5 -1
  22. package/src/core/geom/3d/tetrahedra/TetrahedralMesh.js +2 -2
  23. package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentric.spec.js +26 -0
  24. package/src/core/geom/3d/v3_compute_triangle_normal.spec.js +18 -0
  25. package/src/core/geom/Vector2.js +1 -1
  26. package/src/core/geom/Vector3.js +1 -1
  27. package/src/core/geom/packing/miniball/Miniball.spec.js +24 -0
  28. package/src/core/math/statistics/computeStatisticalPartialMedian.js +2 -2
  29. package/src/core/model/object/read_property.js +2 -2
  30. package/src/core/model/object/write_property.js +3 -3
  31. package/src/core/primitives/numbers/compareNumbers.js +4 -4
  32. package/src/core/primitives/numbers/number_compare_ascending.js +9 -0
  33. package/src/core/primitives/numbers/number_compare_ascending.spec.js +9 -0
  34. package/src/core/primitives/numbers/number_compare_descending.js +9 -0
  35. package/src/core/primitives/numbers/number_compare_descending.spec.js +9 -0
  36. package/src/core/primitives/numbers/number_format_by_thousands.spec.js +12 -0
  37. package/src/core/primitives/numbers/number_pretty_print.js +1 -1
  38. package/src/core/primitives/strings/compareStrings.spec.js +12 -0
  39. package/src/core/primitives/strings/string_capitalize.js +15 -0
  40. package/src/core/primitives/strings/string_capitalize.spec.js +13 -0
  41. package/src/core/primitives/strings/string_compute_byte_size.js +21 -0
  42. package/src/core/primitives/strings/string_compute_common_prefix.js +44 -0
  43. package/src/core/primitives/strings/string_compute_common_prefix.spec.js +23 -0
  44. package/src/core/primitives/strings/string_format_camel_to_kebab.js +9 -0
  45. package/src/core/primitives/strings/string_format_camel_to_kebab.spec.js +8 -0
  46. package/src/core/primitives/strings/string_format_kebab_to_underscore.js +8 -0
  47. package/src/core/time/current_time_in_seconds.js +11 -0
  48. package/src/engine/Clock.js +3 -13
  49. package/src/engine/animation/curve/AnimationCurve.spec.js +27 -0
  50. package/src/engine/asset/AssetManager.js +2 -2
  51. package/src/engine/ecs/EntityManager.js +8 -1
  52. package/src/engine/ecs/EntityManager.spec.js +56 -6
  53. package/src/engine/ecs/animation/Animation.spec.js +22 -0
  54. package/src/engine/ecs/attachment/Attachment.js +24 -25
  55. package/src/engine/ecs/attachment/AttachmentBinding.js +27 -30
  56. package/src/engine/ecs/attachment/AttachmentSystem.js +21 -24
  57. package/src/engine/ecs/attachment/BoneAttachmentBinding.js +6 -9
  58. package/src/engine/ecs/attachment/TransformAttachmentBinding.js +0 -3
  59. package/src/engine/ecs/components/CharacterController.js +24 -18
  60. package/src/engine/ecs/dynamic_actions/DynamicActorSystem.js +3 -2
  61. package/src/engine/ecs/fow/FogOfWarRevealer.js +2 -3
  62. package/src/engine/ecs/ik/IKMath.js +6 -1
  63. package/src/engine/ecs/ik/IKProblem.js +17 -17
  64. package/src/engine/ecs/ik/InverseKinematics.js +6 -7
  65. package/src/engine/ecs/ik/InverseKinematicsSystem.js +24 -26
  66. package/src/engine/ecs/storage/BinaryBufferSerializer.js +3 -3
  67. package/src/engine/ecs/systems/TagSystem.js +1 -6
  68. package/src/engine/ecs/terrain/ecs/layers/TerrainLayer.js +2 -2
  69. package/src/engine/graphics/ecs/mesh/skeleton/BoneMapping.js +2 -2
  70. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.spec.js +14 -0
  71. package/src/engine/graphics/ecs/mesh-v2/render/adapters/SGCacheKey.js +21 -9
  72. package/src/engine/graphics/ecs/mesh-v2/render/adapters/SGCacheKey.spec.js +79 -0
  73. package/src/engine/graphics/render/visibility/IncrementalDeltaSet.spec.js +7 -6
  74. package/src/engine/simulation/Ticker.js +17 -20
  75. package/src/generation/GridTaskGroup.js +5 -9
  76. package/src/generation/filtering/numeric/CellFilterCache.js +12 -16
  77. package/src/generation/filtering/numeric/complex/CellFilterFXAA.js +31 -32
  78. package/src/generation/filtering/numeric/complex/CellFilterLookupTable.js +6 -9
  79. package/src/generation/filtering/numeric/complex/CellFilterSimplexNoise.js +7 -10
  80. package/src/generation/filtering/numeric/complex/CellFilterSobel.js +6 -9
  81. package/src/generation/filtering/numeric/math/CellFilterMembershipGeneralizedBell.js +18 -21
  82. package/src/generation/filtering/numeric/sampling/AbstractCellFilterSampleGridLayer.js +24 -25
  83. package/src/generation/filtering/numeric/sampling/CellFilterSampleLayerLinear.js +1 -1
  84. package/src/generation/grid/GridData.js +23 -22
  85. package/src/generation/grid/GridData.spec.js +41 -0
  86. package/src/generation/grid/GridTaskGenerator.js +7 -8
  87. package/src/generation/grid/layers/GridDataLayer.js +23 -25
  88. package/src/generation/markers/GridActionRuleSet.js +20 -22
  89. package/src/generation/markers/GridCellActionPlaceMarker.js +40 -43
  90. package/src/generation/markers/GridCellActionPlaceMarkerGroup.js +7 -9
  91. package/src/generation/markers/MarkerNode.js +44 -44
  92. package/src/generation/markers/actions/MarkerNodeActionEntityPlacement.js +15 -18
  93. package/src/generation/markers/actions/MarkerNodeActionSequence.js +6 -9
  94. package/src/generation/markers/actions/MarkerNodeProcessingRuleSet.js +5 -7
  95. package/src/generation/markers/actions/MarkerProcessingRule.js +25 -26
  96. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorClingToTerrain.js +12 -15
  97. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorRandomRotation.js +2 -5
  98. package/src/generation/markers/actions/placement/MarkerNodeEntityProcessorSequence.js +6 -9
  99. package/src/generation/markers/actions/probability/MarkerNodeActionSelectWeighted.js +8 -11
  100. package/src/generation/markers/actions/probability/MarkerNodeActionWeightedElement.js +13 -13
  101. package/src/generation/markers/actions/util/GridCellActionDebugBreak.js +5 -8
  102. package/src/generation/markers/actions/util/GridCellActionLogToConsole.js +1 -4
  103. package/src/generation/markers/emitter/MarkerNodeConsumerBuffer.js +10 -13
  104. package/src/generation/markers/emitter/MarkerNodeEmitterFromAction.js +5 -9
  105. package/src/generation/markers/emitter/MarkerNodeEmitterGridCellAction.js +12 -15
  106. package/src/generation/markers/emitter/MarkerNodeEmitterGroup.js +5 -8
  107. package/src/generation/markers/emitter/MarkerNodeEmitterPredicated.js +18 -21
  108. package/src/generation/markers/matcher/MarkerNodeMatcher.js +2 -1
  109. package/src/generation/markers/matcher/MarkerNodeMatcherBinary.js +12 -13
  110. package/src/generation/markers/matcher/MarkerNodeMatcherContainsTag.js +7 -9
  111. package/src/generation/markers/matcher/MarkerNodeMatcherNot.js +7 -9
  112. package/src/generation/markers/predicate/GridDataNodePredicateBinary.js +10 -14
  113. package/src/generation/markers/predicate/GridDataNodePredicateNot.js +9 -11
  114. package/src/generation/markers/predicate/GridDataNodePredicateOverlaps.js +6 -9
  115. package/src/generation/markers/transform/MarkerNodeTransformRotateRandom.js +2 -6
  116. package/src/generation/markers/transform/MarkerNodeTransformerAddPositionYFromFilter.js +6 -9
  117. package/src/generation/markers/transform/MarkerNodeTransformerOffsetPosition.js +1 -4
  118. package/src/generation/markers/transform/MarkerNodeTransformerRecordProperty.js +12 -15
  119. package/src/generation/markers/transform/MarkerNodeTransformerRecordPropertyClosure.js +14 -17
  120. package/src/generation/markers/transform/MarkerNodeTransformerRecordUniqueRandomEnum.js +21 -23
  121. package/src/generation/markers/transform/MarkerNodeTransformerRemoveTag.js +1 -4
  122. package/src/generation/markers/transform/MarkerNodeTransformerSequence.js +6 -9
  123. package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilter.js +13 -17
  124. package/src/generation/markers/transform/MarkerNodeTransformerYRotateByFilterGradient.js +12 -16
  125. package/src/generation/placement/GridCellActionTransformNearbyMarkers.js +26 -29
  126. package/src/generation/placement/GridCellPlacementRule.js +30 -32
  127. package/src/generation/placement/action/GridCellActionPlaceTags.js +26 -28
  128. package/src/generation/placement/action/GridCellActionWriteFilterToLayer.js +16 -20
  129. package/src/generation/placement/action/random/weighted/CellActionSelectWeightedRandom.js +13 -16
  130. package/src/generation/placement/action/random/weighted/WeightedGridCellAction.js +11 -14
  131. package/src/generation/placement/action/util/CellMatcherWithinAABB.js +2 -6
  132. package/src/generation/placement/action/util/GridCellActionSequence.js +7 -9
  133. package/src/generation/placement/action/util/GridCellDisplacedAction.js +9 -12
  134. package/src/generation/rules/CellMatcherFromFilter.js +6 -9
  135. package/src/generation/rules/CellMatcherLayerBitMaskTest.js +6 -9
  136. package/src/generation/rules/GridLayerCellMatcher.js +11 -14
  137. package/src/generation/rules/cell/CellMatcherContainsMarkerWithinRadius.js +11 -14
  138. package/src/generation/rules/cell/CellMatcherGridPattern.js +6 -8
  139. package/src/generation/rules/cell/GridPatternMatcherCell.js +11 -12
  140. package/src/generation/rules/logic/CellMatcherBinary.js +10 -14
  141. package/src/generation/rules/logic/CellMatcherDecorator.js +5 -8
  142. package/src/generation/theme/AreaMask.js +15 -17
  143. package/src/generation/theme/AreaTheme.js +7 -8
  144. package/src/generation/theme/TerrainLayerDescription.js +10 -12
  145. package/src/generation/theme/TerrainLayerRule.js +11 -13
  146. package/src/generation/theme/TerrainTheme.js +6 -7
  147. package/src/generation/theme/Theme.js +15 -17
  148. package/src/generation/theme/ThemeEngine.js +16 -18
  149. package/src/view/string_tag_to_css_class_name.js +2 -2
  150. package/src/view/tooltip/gml/TooltipParser.js +2 -2
  151. package/src/core/cache/PersistentCacheAdapter.js +0 -378
  152. package/src/core/primitives/strings/StringUtils.js +0 -105
  153. package/src/core/primitives/strings/StringUtils.spec.js +0 -42
  154. package/src/engine/ecs/components/MonsterAI.js +0 -15
  155. package/src/generation/markers/MarkerRelation.js +0 -13
@@ -1,10 +1,10 @@
1
1
  import View from "../../../src/view/View.js";
2
2
  import { PortDirection } from "../../../src/core/model/node-graph/node/PortDirection.js";
3
- import { camelToKebab } from "../../../src/core/primitives/strings/StringUtils.js";
4
3
  import LabelView from "../../../src/view/common/LabelView.js";
5
4
  import EmptyView from "../../../src/view/elements/EmptyView.js";
6
5
  import { Color } from "../../../src/core/color/Color.js";
7
6
  import { objectKeyByValue } from "../../../src/core/model/object/objectKeyByValue.js";
7
+ import { string_format_camel_to_kebab } from "../../../src/core/primitives/strings/string_format_camel_to_kebab.js";
8
8
 
9
9
  const DEFAULT_TYPE_COLOR = new Color(1, 1, 1);
10
10
 
@@ -35,7 +35,7 @@ export class PortView extends View {
35
35
 
36
36
  this.addClass(`direction-${objectKeyByValue(PortDirection, port.direction).toLocaleLowerCase()}`);
37
37
 
38
- this.addClass(`data-type-${camelToKebab(port.dataType.name)}`);
38
+ this.addClass(`data-type-${string_format_camel_to_kebab(port.dataType.name)}`);
39
39
 
40
40
  //add port name label
41
41
  const vName = new LabelView(port.name, {
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.55.0",
8
+ "version": "2.56.0",
9
9
  "main": "build/meep.module.js",
10
10
  "module": "build/meep.module.js",
11
11
  "exports": {
@@ -52,7 +52,8 @@ export class BinaryBuffer {
52
52
  position = 0;
53
53
 
54
54
  /**
55
- * @deprecated
55
+ * Same as {@link capacity}
56
+ * @deprecated use {@link position} or {@link capacity} instead
56
57
  * @type {number}
57
58
  */
58
59
  length = 0;
@@ -1,6 +1,7 @@
1
1
  //
2
2
 
3
3
  import { Cache } from "./Cache.js";
4
+ import { current_time_in_seconds } from "../time/current_time_in_seconds.js";
4
5
 
5
6
  /**
6
7
  * @template R
@@ -18,13 +19,16 @@ class Record {
18
19
  }
19
20
  }
20
21
 
21
- function current_time_in_seconds() {
22
- return performance.now() * 1e-3;
23
- }
24
-
25
- const DEFAULT_TIME_TO_LIVE = 10;
22
+ /**
23
+ * In seconds
24
+ * @readonly
25
+ * @type {number}
26
+ */
27
+ const DEFAULT_TIME_TO_LIVE = 300; // 5 Minutes
26
28
 
27
29
  /**
30
+ * Asynchronous cache capable of resolving its own values by keys
31
+ * Modelled on Guava's LoadingCache concept
28
32
  * @template K,V
29
33
  */
30
34
  export class LoadingCache {
@@ -33,6 +37,7 @@ export class LoadingCache {
33
37
  */
34
38
  #internal
35
39
  /**
40
+ * Time until records are marked as invalid, invalid records are not served back and trigger re-loading of the value
36
41
  * In seconds
37
42
  * @type {number}
38
43
  */
@@ -1,4 +1,7 @@
1
+ import { array_remove_first } from "./array_remove_first.js";
2
+
1
3
  /**
4
+ * @deprecated
2
5
  * @template T
3
6
  * @param {T[]} array
4
7
  * @param {number} start_index
@@ -7,13 +10,7 @@
7
10
  * @return {boolean}
8
11
  */
9
12
  export function array_remove_element(array, start_index, end_index, element) {
10
- for (let i = start_index; i < end_index; i++) {
11
- if (array[i] === element) {
12
- array.splice(i, 1);
13
-
14
- return true;
15
- }
16
- }
13
+ console.warn('deprecated, use array_remove_first instead');
17
14
 
18
- return false;
19
- }
15
+ array_remove_first(array, element, start_index, end_index - start_index);
16
+ }
@@ -1,15 +1,22 @@
1
1
  /**
2
+ * Remove first occurrence of element from the array
2
3
  * @template T
3
4
  * @param {T[]} array
4
5
  * @param {T} element
5
- * @return {boolean}
6
+ * @param {number} [start_index]
7
+ * @param {number} [length]
8
+ * @return {boolean} true if element was removed, false if it was not found
6
9
  */
7
- export function array_remove_first(array, element){
8
- const i = array.indexOf(element);
10
+ export function array_remove_first(array, element, start_index = 0, length = array.length) {
9
11
 
10
- if(i !== -1){
11
- array.splice(i,1);
12
- return true;
12
+ const end_index = start_index + length;
13
+
14
+ for (let i = start_index; i < end_index; i++) {
15
+ if (array[i] === element) {
16
+ array.splice(i, 1);
17
+
18
+ return true;
19
+ }
13
20
  }
14
21
 
15
22
  return false;
@@ -0,0 +1,39 @@
1
+ import { array_remove_first } from "./array_remove_first.js";
2
+
3
+ test("basics", () => {
4
+
5
+ expect(array_remove_first([], 1)).toBe(false);
6
+ expect(array_remove_first([2], 1)).toBe(false);
7
+ expect(array_remove_first([2, 3], 1)).toBe(false);
8
+
9
+ let array = [1];
10
+
11
+ expect(array_remove_first(array, 1)).toBe(true);
12
+
13
+ expect(array).toEqual([]);
14
+
15
+ array = [1, 1];
16
+
17
+ expect(array_remove_first(array, 1)).toBe(true);
18
+
19
+ expect(array).toEqual([1]);
20
+
21
+ array = [2, 1];
22
+
23
+ expect(array_remove_first(array, 1)).toBe(true);
24
+
25
+ expect(array).toEqual([2]);
26
+
27
+ array = [1, 2];
28
+
29
+ expect(array_remove_first(array, 1)).toBe(true);
30
+
31
+ expect(array).toEqual([2]);
32
+
33
+ array = [1, 2, 1];
34
+
35
+ expect(array_remove_first(array, 1)).toBe(true);
36
+
37
+ expect(array).toEqual([2, 1]);
38
+
39
+ });
@@ -1,50 +1,51 @@
1
1
  import { binarySearchHighIndex } from "./binarySearchHighIndex.js";
2
- import { compareNumbersAscending } from "../../function/Functions.js";
2
+
3
+ import { number_compare_ascending } from "../../primitives/numbers/number_compare_ascending.js";
3
4
 
4
5
  test('exact match single element 1', () => {
5
6
  expect(
6
- binarySearchHighIndex([1], 1, compareNumbersAscending, 0, 0)
7
+ binarySearchHighIndex([1], 1, number_compare_ascending, 0, 0)
7
8
  ).toBe(0);
8
9
  });
9
10
 
10
11
  test('exact match single element 0', () => {
11
12
  expect(
12
- binarySearchHighIndex([0], 0, compareNumbersAscending, 0, 0)
13
+ binarySearchHighIndex([0], 0, number_compare_ascending, 0, 0)
13
14
  ).toBe(0);
14
15
  });
15
16
 
16
17
  test('exact match single element -1', () => {
17
18
  expect(
18
- binarySearchHighIndex([-1], -1, compareNumbersAscending, 0, 0)
19
+ binarySearchHighIndex([-1], -1, number_compare_ascending, 0, 0)
19
20
  ).toBe(0);
20
21
  });
21
22
 
22
23
  test('0 -> 0,0', () => {
23
24
  expect(
24
- binarySearchHighIndex([0, 0], 0, compareNumbersAscending, 0, 1)
25
+ binarySearchHighIndex([0, 0], 0, number_compare_ascending, 0, 1)
25
26
  ).toBe(0);
26
27
  });
27
28
 
28
29
  test('0 -> 0,1', () => {
29
30
  expect(
30
- binarySearchHighIndex([0, 1], 0, compareNumbersAscending, 0, 1)
31
+ binarySearchHighIndex([0, 1], 0, number_compare_ascending, 0, 1)
31
32
  ).toBe(0);
32
33
  });
33
34
 
34
35
  test('1 -> 1,1', () => {
35
36
  expect(
36
- binarySearchHighIndex([1, 1], 1, compareNumbersAscending, 0, 1)
37
+ binarySearchHighIndex([1, 1], 1, number_compare_ascending, 0, 1)
37
38
  ).toBe(0);
38
39
  });
39
40
 
40
41
  test('0 -> 1,2', () => {
41
42
  expect(
42
- binarySearchHighIndex([1, 2], 0, compareNumbersAscending, 0, 1)
43
+ binarySearchHighIndex([1, 2], 0, number_compare_ascending, 0, 1)
43
44
  ).toBe(0);
44
45
  });
45
46
 
46
47
  test('1.5 -> 1,2', () => {
47
48
  expect(
48
- binarySearchHighIndex([1, 2], 1.5, compareNumbersAscending, 0, 1)
49
+ binarySearchHighIndex([1, 2], 1.5, number_compare_ascending, 0, 1)
49
50
  ).toBe(1);
50
51
  });
@@ -1,4 +1,5 @@
1
1
  import { Uint32Heap } from "./Uint32Heap.js";
2
+ import { seededRandom } from "../../math/random/seededRandom.js";
2
3
 
3
4
  test('initial capacity setting via constructor', () => {
4
5
  const heap = new Uint32Heap(3);
@@ -93,6 +94,9 @@ test("update_score", () => {
93
94
 
94
95
  expect(heap.pop_min()).toEqual(7);
95
96
  expect(heap.pop_min()).toEqual(1);
97
+
98
+ // expect request to a missing element to throw
99
+ expect(() => heap.update_score(7, 0)).toThrow();
96
100
  });
97
101
 
98
102
  test("get_score", () => {
@@ -121,3 +125,35 @@ test("insert_or_update", () => {
121
125
  expect(heap.get_score(7)).toBe(17);
122
126
 
123
127
  });
128
+
129
+
130
+ test.skip("performance 1,000,000 random element fill / drain", () => {
131
+
132
+ const random = seededRandom(7);
133
+
134
+ const COUNT = 1000000;
135
+
136
+ const random_values = new Float32Array(COUNT);
137
+
138
+ for (let i = 0; i < COUNT; i++) {
139
+ random_values[i] = random();
140
+ }
141
+
142
+ const heap = new Uint32Heap();
143
+
144
+ const t0 = performance.now();
145
+ for (let i = 0; i < COUNT; i++) {
146
+ heap.insert(i, random_values[i]);
147
+ }
148
+ const t1 = performance.now();
149
+
150
+ for (let i = 0; i < COUNT; i++) {
151
+ heap.pop_min();
152
+ }
153
+ const t2 = performance.now();
154
+
155
+ const fill_time = t1 - t0;
156
+ const drain_time = t2 - t1;
157
+
158
+ console.log(`Fill took ${fill_time}ms (${COUNT / (fill_time * 0.001)} elements per second), drain took ${drain_time}ms (${COUNT / (drain_time * 0.001)} elements per second)`);
159
+ });
@@ -87,10 +87,10 @@ export class Uint32Heap {
87
87
  __capacity_grow() {
88
88
  const old_capacity = this.__capacity;
89
89
 
90
- const new_capacity = max2(
90
+ const new_capacity = Math.ceil(max2(
91
91
  old_capacity * RESIZE_GROW_FACTOR,
92
92
  old_capacity + RESIZE_GROW_MIN_COUNT
93
- );
93
+ ));
94
94
 
95
95
  assert.greaterThan(new_capacity, old_capacity, 'invalid growth');
96
96
 
@@ -117,7 +117,10 @@ export class Uint32Heap {
117
117
  compare(a, b) {
118
118
  const float32 = this.__data_float32;
119
119
 
120
- return float32[a * 2] < float32[b * 2];
120
+ const a2 = a << 1; // same as a*2
121
+ const b2 = b << 1; // same as b*2
122
+
123
+ return float32[a2] < float32[b2];
121
124
  }
122
125
 
123
126
  /**
@@ -127,8 +130,9 @@ export class Uint32Heap {
127
130
  * @param {number} j element index
128
131
  */
129
132
  swap(i, j) {
130
- const i2 = i * 2;
131
- const j2 = j * 2;
133
+ // fast multiplication by 2
134
+ const i2 = i << 1; // same as i*2
135
+ const j2 = j << 1; // same as j*2
132
136
 
133
137
  const uint32 = this.__data_uint32;
134
138
 
@@ -385,6 +389,7 @@ export class Uint32Heap {
385
389
  insert(id, score) {
386
390
  assert.isNonNegativeInteger(id, 'value');
387
391
  assert.lessThanOrEqual(id, UINT32_MAX - 1, 'must be less than or equal to (2^32 - 2)');
392
+ assert.isNumber(score, 'score');
388
393
 
389
394
  if (this.__size >= this.__capacity) {
390
395
  // need to re-allocate
@@ -4,9 +4,9 @@ import { isArrayEqualStrict } from "../collection/array/isArrayEqualStrict.js";
4
4
  import { invokeObjectEquals } from "../model/object/invokeObjectEquals.js";
5
5
  import { invokeObjectHash } from "../model/object/invokeObjectHash.js";
6
6
  import { computeStringHash } from "../primitives/strings/computeStringHash.js";
7
- import { computeUTF8StringByteSize } from "../primitives/strings/StringUtils.js";
8
7
  import { computeHashArray } from "../collection/array/computeHashArray.js";
9
8
  import { computeHashIntegerArray } from "../collection/array/computeHashIntegerArray.js";
9
+ import { string_compute_byte_size } from "../primitives/strings/string_compute_byte_size.js";
10
10
 
11
11
  /**
12
12
  * Hash is an integer value, so this is an invalid value for a computed hash
@@ -62,17 +62,17 @@ class FunctionDefinition {
62
62
  */
63
63
  computeByteSize() {
64
64
 
65
- let result = computeUTF8StringByteSize(this.body);
65
+ let result = string_compute_byte_size(this.body);
66
66
 
67
67
  if (this.name !== undefined) {
68
- result += computeUTF8StringByteSize(this.name);
68
+ result += string_compute_byte_size(this.name);
69
69
  }
70
70
 
71
71
  const n = this.args.length;
72
72
  for (let i = 0; i < n; i++) {
73
73
  const arg = this.args[i];
74
74
 
75
- result += computeUTF8StringByteSize(arg);
75
+ result += string_compute_byte_size(arg);
76
76
  }
77
77
 
78
78
  return result;
@@ -101,22 +101,3 @@ export function chainFunctions(...processes) {
101
101
  }
102
102
 
103
103
 
104
- /**
105
- *
106
- * @param {number} a
107
- * @param {number} b
108
- * @return {number}
109
- */
110
- export function compareNumbersAscending(a, b) {
111
- return a - b;
112
- }
113
-
114
- /**
115
- *
116
- * @param {number} a
117
- * @param {number} b
118
- * @return {number}
119
- */
120
- export function compareNumbersDescending(a, b) {
121
- return b - a;
122
- }
@@ -6,26 +6,25 @@ import { assert } from "../../assert.js";
6
6
  * Used for representing points on a 3D surface. Used for raycasting contacts
7
7
  */
8
8
  export class SurfacePoint3 {
9
- constructor() {
10
- /**
11
- * @readonly
12
- * @type {Vector3}
13
- */
14
- this.normal = new Vector3(0, 1, 0);
15
-
16
- /**
17
- * @readonly
18
- * @type {Vector3}
19
- */
20
- this.position = new Vector3(0, 0, 0);
21
-
22
- /**
23
- * Primitive index, such as triangle/point/line from the source geometry
24
- * optional
25
- * @type {number}
26
- */
27
- this.index = -1;
28
- }
9
+
10
+ /**
11
+ * @readonly
12
+ * @type {Vector3}
13
+ */
14
+ normal = new Vector3(0, 1, 0);
15
+
16
+ /**
17
+ * @readonly
18
+ * @type {Vector3}
19
+ */
20
+ position = new Vector3(0, 0, 0);
21
+
22
+ /**
23
+ * Primitive index, such as triangle/point/line from the source geometry
24
+ * optional
25
+ * @type {number}
26
+ */
27
+ index = -1;
29
28
 
30
29
  get 0() {
31
30
  return this.position.x;
@@ -129,6 +128,17 @@ export class SurfacePoint3 {
129
128
  this.normal.writeToArray(array, offset + 3);
130
129
  }
131
130
 
131
+ /**
132
+ *
133
+ * @param {SurfacePoint3} other
134
+ * @returns {boolean}
135
+ */
136
+ equals(other) {
137
+ return this.index === other.index
138
+ && this.position.equals(other.position)
139
+ && this.normal.equals(other.normal);
140
+ }
141
+
132
142
  /**
133
143
  *
134
144
  * @param {SurfacePoint3} other
@@ -0,0 +1,116 @@
1
+ import { SurfacePoint3 } from "./SurfacePoint3.js";
2
+ import { MATRIX_4_IDENTITY } from "./matrix/MATRIX_4_IDENTITY.js";
3
+
4
+
5
+ test("equals", () => {
6
+
7
+ const a = new SurfacePoint3();
8
+
9
+ a.position.set(1, 3, 5);
10
+ a.normal.set(7, 11, 13);
11
+ a.index = 97;
12
+
13
+ const b = new SurfacePoint3();
14
+
15
+ expect(a.equals(b)).toBe(false);
16
+
17
+ b.index = 97;
18
+
19
+ expect(a.equals(b)).toBe(false);
20
+
21
+ b.position.set(1, 3, 5);
22
+
23
+ expect(a.equals(b)).toBe(false);
24
+
25
+ b.normal.set(7, 11, 13);
26
+
27
+ expect(a.equals(b)).toBe(true);
28
+
29
+ b.index = 91;
30
+
31
+ expect(a.equals(b)).toBe(false);
32
+ });
33
+
34
+ test("copy", () => {
35
+ const a = new SurfacePoint3();
36
+
37
+ a.position.set(1, 3, 5);
38
+ a.normal.set(7, 11, 13);
39
+ a.index = 97;
40
+
41
+ const b = new SurfacePoint3();
42
+
43
+ b.copy(a);
44
+
45
+ expect(b.position.x).toBe(1);
46
+ expect(b.position.y).toBe(3);
47
+ expect(b.position.z).toBe(5);
48
+
49
+ expect(b.normal.x).toBe(7);
50
+ expect(b.normal.y).toBe(11);
51
+ expect(b.normal.z).toBe(13);
52
+
53
+ expect(b.index).toBe(97);
54
+ });
55
+
56
+ test("array-style getters", () => {
57
+
58
+ const point = new SurfacePoint3();
59
+
60
+ point.position.set(1, 3, 5);
61
+ point.normal.set(7, 11, 13);
62
+
63
+ expect(point[0]).toBe(1);
64
+ expect(point[1]).toBe(3);
65
+ expect(point[2]).toBe(5);
66
+
67
+ expect(point[3]).toBe(7);
68
+ expect(point[4]).toBe(11);
69
+ expect(point[5]).toBe(13);
70
+
71
+ });
72
+
73
+ test("toArray", () => {
74
+
75
+ const point = new SurfacePoint3();
76
+
77
+ point.position.set(1, 3, 5);
78
+ point.normal.set(7, 11, 13);
79
+
80
+ const array = [99];
81
+
82
+ point.toArray(array, 1);
83
+
84
+ expect(array).toEqual([99, 1, 3, 5, 7, 11, 13]);
85
+ });
86
+
87
+ test("fromArray", () => {
88
+ const point = new SurfacePoint3();
89
+
90
+ point.fromArray([99, 1, 3, 5, 7, 11, 13], 1);
91
+
92
+ expect(point.position.x).toBe(1);
93
+ expect(point.position.y).toBe(3);
94
+ expect(point.position.z).toBe(5);
95
+
96
+ expect(point.normal.x).toBe(7);
97
+ expect(point.normal.y).toBe(11);
98
+ expect(point.normal.z).toBe(13);
99
+
100
+ });
101
+
102
+ test("applyMatrix4 with identity matrix", () => {
103
+
104
+ const original = new SurfacePoint3();
105
+
106
+ original.position.set(1, 3, 5);
107
+ original.normal.set(7, 11, 13);
108
+
109
+ original.normal.normalize();
110
+
111
+ const transformed = original.clone();
112
+
113
+ transformed.applyMatrix4(MATRIX_4_IDENTITY);
114
+
115
+ expect(transformed.equals(original)).toBe(true);
116
+ });
@@ -15,7 +15,7 @@ import { aabb3_compute_surface_area } from "./aabb3_compute_surface_area.js";
15
15
  import { aabb3_intersects_frustum_array } from "./aabb3_intersects_frustum_array.js";
16
16
  import { aabb3_matrix4_project } from "./aabb3_matrix4_project.js";
17
17
  import { aabb3_signed_distance_sqr_to_point } from "./aabb3_signed_distance_sqr_to_point.js";
18
- import { aabb3_array_contains_point } from "./aabb3_array_contains_point.js";
18
+ import { aabb3_array_intersects_point } from "./aabb3_array_intersects_point.js";
19
19
 
20
20
  /**
21
21
  * Axis-Aligned bounding box in 3D
@@ -106,14 +106,14 @@ export class AABB3 {
106
106
  }
107
107
 
108
108
  /**
109
- * @deprecated use {@link aabb3_array_contains_point} directly
109
+ * @deprecated use {@link aabb3_array_intersects_point} directly
110
110
  * @param {number} x
111
111
  * @param {number} y
112
112
  * @param {number} z
113
113
  * @returns {boolean}
114
114
  */
115
115
  containsPoint(x, y, z) {
116
- return aabb3_array_contains_point(this, x, y, z);
116
+ return aabb3_array_intersects_point(this, x, y, z);
117
117
  }
118
118
 
119
119
  /**
@@ -251,6 +251,8 @@ export class AABB3 {
251
251
  * @param {Number} z1
252
252
  */
253
253
  setBoundsUnordered(x0, y0, z0, x1, y1, z1) {
254
+
255
+ // sort bound coordinates
254
256
  let _x0, _y0, _z0, _x1, _y1, _z1;
255
257
  if (x0 < x1) {
256
258
  _x0 = x0;
@@ -273,7 +275,10 @@ export class AABB3 {
273
275
  _z0 = z1;
274
276
  _z1 = z0;
275
277
  }
278
+
279
+ // write sorted
276
280
  this.setBounds(_x0, _y0, _z0, _x1, _y1, _z1);
281
+
277
282
  }
278
283
 
279
284
  setNegativelyInfiniteBounds() {
@@ -293,12 +298,8 @@ export class AABB3 {
293
298
  */
294
299
  distanceToPoint2(x, y, z) {
295
300
  return aabb3_signed_distance_sqr_to_point(
296
- this.x0,
297
- this.y0,
298
- this.z0,
299
- this.x1,
300
- this.y1,
301
- this.z1,
301
+ this.x0, this.y0, this.z0,
302
+ this.x1, this.y1, this.z1,
302
303
  x, y, z
303
304
  );
304
305
  }
@@ -8,7 +8,10 @@
8
8
  * @param {number} z
9
9
  * @return {boolean}
10
10
  */
11
- export function aabb3_array_contains_point(aabb, x, y, z) {
11
+ export function aabb3_array_intersects_point(
12
+ aabb,
13
+ x, y, z
14
+ ) {
12
15
  return x >= aabb[0]
13
16
  && x <= aabb[3]
14
17
  && y >= aabb[1]
@@ -1,10 +1,34 @@
1
+ import { assert } from "../../../assert.js";
2
+
1
3
  /**
2
4
  *
3
5
  * @param {number[]|Float32Array|Float64Array} result
4
6
  * @param {{x:number,y:number,z:number}} min
5
7
  * @param {{x:number,y:number,z:number}} max
6
8
  */
7
- export function aabb3_from_min_max(result, min, max) {
9
+ export function aabb3_from_min_max(
10
+ result,
11
+ min, max
12
+ ) {
13
+ // read out bounds
14
+ const x0 = min.x;
15
+ const y0 = min.y;
16
+ const z0 = min.z;
17
+
18
+ const x1 = max.x;
19
+ const y1 = max.y;
20
+ const z1 = max.z;
21
+
22
+ // validate bounds
23
+ assert.notNaN(x0, 'x0');
24
+ assert.notNaN(y0, 'y0');
25
+ assert.notNaN(z0, 'z0');
26
+
27
+ assert.notNaN(x1, 'x1');
28
+ assert.notNaN(y1, 'y1');
29
+ assert.notNaN(z1, 'z1');
30
+
31
+ // marshal to output
8
32
  result[0] = min.x;
9
33
  result[1] = min.y;
10
34
  result[2] = min.z;