@woosh/meep-engine 2.122.2 → 2.122.4

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 (31) hide show
  1. package/package.json +1 -1
  2. package/src/core/bvh2/bvh3/BVH.d.ts.map +1 -1
  3. package/src/core/bvh2/bvh3/BVH.js +22 -6
  4. package/src/core/bvh2/bvh3/ebvh_build_for_geometry_morton.d.ts.map +1 -1
  5. package/src/core/bvh2/bvh3/ebvh_build_for_geometry_morton.js +0 -12
  6. package/src/core/bvh2/bvh3/ebvh_build_hierarchy.d.ts.map +1 -1
  7. package/src/core/bvh2/bvh3/ebvh_build_hierarchy.js +14 -15
  8. package/src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.d.ts +11 -0
  9. package/src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.d.ts.map +1 -0
  10. package/src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.js +281 -0
  11. package/src/core/bvh2/bvh3/ebvh_optimize_treelet.d.ts.map +1 -1
  12. package/src/core/bvh2/bvh3/ebvh_optimize_treelet.js +1 -0
  13. package/src/core/bvh2/bvh3/ebvh_update_hierarchy_bounds.d.ts +8 -0
  14. package/src/core/bvh2/bvh3/ebvh_update_hierarchy_bounds.d.ts.map +1 -0
  15. package/src/core/bvh2/bvh3/ebvh_update_hierarchy_bounds.js +147 -0
  16. package/src/core/geom/Vector1.d.ts +177 -35
  17. package/src/core/graph/Edge.d.ts +0 -1
  18. package/src/core/graph/Edge.d.ts.map +1 -1
  19. package/src/core/graph/Edge.js +1 -1
  20. package/src/core/graph/v2/Graph.d.ts +24 -9
  21. package/src/core/graph/v2/Graph.d.ts.map +1 -1
  22. package/src/core/graph/v2/Graph.js +48 -10
  23. package/src/engine/ecs/animation/AnimationClip.d.ts +2 -2
  24. package/src/engine/ecs/fow/FogOfWarRevealer.d.ts +1 -1
  25. package/src/engine/graphics/ecs/water/Water.d.ts +1 -1
  26. package/src/engine/intelligence/behavior/ecs/WaitForEventBehavior.d.ts +7 -5
  27. package/src/engine/intelligence/behavior/ecs/WaitForEventBehavior.d.ts.map +1 -1
  28. package/src/engine/intelligence/behavior/ecs/WaitForEventBehavior.js +13 -12
  29. package/src/engine/intelligence/behavior/util/DelayBehavior.d.ts.map +1 -1
  30. package/src/engine/intelligence/behavior/util/DelayBehavior.js +12 -15
  31. package/src/engine/sound/ecs/emitter/SoundEmitter.d.ts +1 -1
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.122.2",
8
+ "version": "2.122.4",
9
9
  "main": "build/meep.module.js",
10
10
  "module": "build/meep.module.js",
11
11
  "exports": {
@@ -1 +1 @@
1
- {"version":3,"file":"BVH.d.ts","sourceRoot":"","sources":["../../../../../src/core/bvh2/bvh3/BVH.js"],"names":[],"mappings":"AASA,4BAA6B,CAAC,CAAC;AAC/B,6BAA8B,CAAC,CAAC;AAChC,6BAA8B,CAAC,CAAC;AAChC,4BAA6B,CAAC,CAAC;AAE/B;;;;;GAKG;AACH,+BAFU,MAAM,CAE+B;AAE/C;;;GAGG;AACH,wBAFU,MAAM,CAEoB;AAcpC;;;;;GAKG;AACH,iCAFU,MAAM,CAEqB;AAiBrC;;;;;;GAMG;AACH;IAEI;;;;OAIG;IACH,sBAA2E;IAE3E;;;;;OAKG;IACH,mBAFa,WAAW,CAIvB;IAED;;;;OAIG;IACH,uBAAsD;IAEtD;;;OAGG;IACH,oBAFY,YAAY,CAIvB;IAED;;;;OAIG;IACH,sBAAoD;IAEpD;;;;OAIG;IACH,mBAA8B;IAE9B;;;;OAIG;IACH,eAAW;IAEX;;;;OAIG;IACH,eAAY;IAEZ;;;;OAIG;IACH,uBAAmB;IAEnB;;;;OAIG;IACH,eAAmB;IAUnB;;;OAGG;IACH,YAFW,MAAM,EAIhB;IAdD;;;OAGG;IACH,YAFa,MAAM,CAIlB;IAUD;;;;OAIG;IACH,YAFY,MAAM,CAIjB;IAUD;;;OAGG;IACH,qBAFW,MAAM,EAQhB;IAlBD;;;OAGG;IACH,qBAFa,MAAM,CAIlB;IAcD,wBAgBC;IAED;;;;OAIG;IACH,uBA6BC;IAED;;OAEG;IACH,aAIC;IAED;;;OAGG;IACH,iBAFa,MAAM,CAqDlB;IAED;;;;OAIG;IACH,iBAFW,MAAM,QAMhB;IAED;;;;OAIG;IACH,iBAHW,MAAM,GACJ,OAAO,CAOnB;IAED;;;;OAIG;IACH,uBAHW,MAAM,GACJ,MAAM,CAKlB;IAED;;;;OAIG;IACH,uBAHW,MAAM,SACN,MAAM,QAOhB;IAED;;;;OAIG;IACH,oBAHW,MAAM,GACJ,MAAM,CAKlB;IAED;;;;OAIG;IACH,sBAHW,MAAM,UACN,MAAM,QAIhB;IAED;;;;OAIG;IACH,oBAHW,MAAM,GACJ,MAAM,CAKlB;IAED;;;;OAIG;IACH,sBAHW,MAAM,UACN,MAAM,QAIhB;IAED;;;;OAIG;IACH,oBAHW,MAAM,GACJ,MAAM,CAKlB;IAED;;;;OAIG;IACH,sBAHW,MAAM,UACN,MAAM,QAIhB;IAGD;;;;OAIG;IACH,oBAHW,MAAM,GACJ,MAAM,CAKlB;IAED;;;;OAIG;IACH,oBAHW,MAAM,UACN,MAAM,QAKhB;IAED;;;;OAIG;IACH,kBAHW,MAAM,UACN,MAAM,EAAE,GAAC,YAAY,QAe/B;IAED;;;;OAIG;IACH,kBAHW,MAAM,QACN,MAAM,EAAE,GAAC,SAAS,CAAC,MAAM,CAAC,GAAC,KAAK,QAsB1C;IAED;;;;OAIG;IACH,mBAHW,MAAM,QACN,MAAM,EAAE,QAWlB;IAED;;;;;;;;;OASG;IACH,4BARW,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,QAmBhB;IAED;;;;OAIG;IACH,0BAHW,MAAM,GACJ,MAAM,CAoBlB;IAED;;;;;OAKG;IACH,wCAJW,MAAM,WACN,MAAM,GACJ,MAAM,CAoClB;IAED;;;;;OAKG;IACH,oCAJW,MAAM,WACN,MAAM,WACN,MAAM,QAgBhB;IAED;;;;OAIG;IACH,kBAHW,MAAM,GACJ,IAAI,CA0GhB;IAED;;;;;OAKG;IACH,wBAqBC;IAED;;;;OAIG;IACH,yBA4BC;IAED;;;;OAIG;IACH,kBAHW,MAAM,GACJ,IAAI,CA6ChB;IAED;;;;;;OAMG;IACH,gBAoMC;IAED;;;;;;OAMG;IACH,6BAJW,MAAM,WACN,MAAM,WACN,MAAM,QAiBhB;IAED;;;OAGG;IACH,oBAIC;IAED;;;;OAIG;IACH,8BAFW,GAAC,QAgCX;IAED;;;;;OAKG;IACH,+BAJW,MAAM,EAAE,sBACR,MAAM,GACJ,MAAM,CAWlB;IAED;;;;;OAKG;IACH,0BA6BC;IAED;;;;;OAKG;IACH,cAJW,MAAM,KACN,MAAM,GACJ,OAAO,CAsCnB;CACJ"}
1
+ {"version":3,"file":"BVH.d.ts","sourceRoot":"","sources":["../../../../../src/core/bvh2/bvh3/BVH.js"],"names":[],"mappings":"AASA,4BAA6B,CAAC,CAAC;AAC/B,6BAA8B,CAAC,CAAC;AAChC,6BAA8B,CAAC,CAAC;AAChC,4BAA6B,CAAC,CAAC;AAE/B;;;;;GAKG;AACH,+BAFU,MAAM,CAE+B;AAE/C;;;GAGG;AACH,wBAFU,MAAM,CAEoB;AAcpC;;;;;GAKG;AACH,iCAFU,MAAM,CAEqB;AAiBrC;;;;;;GAMG;AACH;IAEI;;;;OAIG;IACH,sBAA2E;IAE3E;;;;;OAKG;IACH,mBAFa,WAAW,CAIvB;IAED;;;;OAIG;IACH,uBAAsD;IAEtD;;;OAGG;IACH,oBAFY,YAAY,CAIvB;IAED;;;;OAIG;IACH,sBAAoD;IAEpD;;;;OAIG;IACH,mBAA8B;IAE9B;;;;OAIG;IACH,eAAW;IAEX;;;;OAIG;IACH,eAAY;IAEZ;;;;OAIG;IACH,uBAAmB;IAEnB;;;;OAIG;IACH,eAAmB;IAUnB;;;OAGG;IACH,YAFW,MAAM,EAIhB;IAdD;;;OAGG;IACH,YAFa,MAAM,CAIlB;IAUD;;;;OAIG;IACH,YAFY,MAAM,CAIjB;IAUD;;;OAGG;IACH,qBAFW,MAAM,EAQhB;IAlBD;;;OAGG;IACH,qBAFa,MAAM,CAIlB;IAcD,wBAgBC;IAED;;;;OAIG;IACH,uBA6BC;IAED;;OAEG;IACH,aAIC;IAED;;;OAGG;IACH,iBAFa,MAAM,CAqDlB;IAED;;;;OAIG;IACH,iBAFW,MAAM,QAMhB;IAED;;;;OAIG;IACH,iBAHW,MAAM,GACJ,OAAO,CAOnB;IAED;;;;OAIG;IACH,uBAHW,MAAM,GACJ,MAAM,CAKlB;IAED;;;;OAIG;IACH,uBAHW,MAAM,SACN,MAAM,QAOhB;IAED;;;;OAIG;IACH,oBAHW,MAAM,GACJ,MAAM,CAKlB;IAED;;;;OAIG;IACH,sBAHW,MAAM,UACN,MAAM,QAIhB;IAED;;;;OAIG;IACH,oBAHW,MAAM,GACJ,MAAM,CAKlB;IAED;;;;OAIG;IACH,sBAHW,MAAM,UACN,MAAM,QAIhB;IAED;;;;OAIG;IACH,oBAHW,MAAM,GACJ,MAAM,CAKlB;IAED;;;;OAIG;IACH,sBAHW,MAAM,UACN,MAAM,QAIhB;IAGD;;;;OAIG;IACH,oBAHW,MAAM,GACJ,MAAM,CAKlB;IAED;;;;OAIG;IACH,oBAHW,MAAM,UACN,MAAM,QAKhB;IAED;;;;OAIG;IACH,kBAHW,MAAM,UACN,MAAM,EAAE,GAAC,YAAY,QAe/B;IAED;;;;OAIG;IACH,kBAHW,MAAM,QACN,MAAM,EAAE,GAAC,SAAS,CAAC,MAAM,CAAC,GAAC,KAAK,QAsB1C;IAED;;;;OAIG;IACH,mBAHW,MAAM,QACN,MAAM,EAAE,QAWlB;IAED;;;;;;;;;OASG;IACH,4BARW,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,QAmBhB;IAED;;;;OAIG;IACH,0BAHW,MAAM,GACJ,MAAM,CAoBlB;IAED;;;;;OAKG;IACH,wCAJW,MAAM,WACN,MAAM,GACJ,MAAM,CAoClB;IAED;;;;;OAKG;IACH,oCAJW,MAAM,WACN,MAAM,WACN,MAAM,QAgBhB;IAED;;;;OAIG;IACH,kBAHW,MAAM,GACJ,IAAI,CA0GhB;IAED;;;;;OAKG;IACH,wBAqBC;IAED;;;;OAIG;IACH,yBA4BC;IAED;;;;OAIG;IACH,kBAHW,MAAM,GACJ,IAAI,CA6ChB;IAED;;;;;;OAMG;IACH,gBAoMC;IAED;;;;;;OAMG;IACH,6BAJW,MAAM,WACN,MAAM,WACN,MAAM,QAMhB;IAED;;;;;;;OAOG;IACH,kCAJW,MAAM,WACN,MAAM,WACN,MAAM,QAmBhB;IAED;;;OAGG;IACH,oBAIC;IAED;;;;OAIG;IACH,8BAFW,GAAC,QAgCX;IAED;;;;;OAKG;IACH,+BAJW,MAAM,EAAE,sBACR,MAAM,GACJ,MAAM,CAWlB;IAED;;;;;OAKG;IACH,0BA6BC;IAED;;;;;OAKG;IACH,cAJW,MAAM,KACN,MAAM,GACJ,OAAO,CAsCnB;CACJ"}
@@ -1051,20 +1051,36 @@ export class BVH {
1051
1051
  * @param {number} child_2
1052
1052
  */
1053
1053
  node_assign_children(parent, child_1, child_2) {
1054
- this.node_set_child1(parent, child_1);
1055
- this.node_set_child2(parent, child_2);
1054
+ this.node_set_combined_aabb(parent, child_1, child_2);
1055
+
1056
+ this.node_assign_children_only(parent, child_1, child_2);
1057
+ }
1058
+
1059
+ /**
1060
+ * Utility method for assigning both children at once
1061
+ * Children must be valid nodes (non-null)
1062
+ * Does not update bounds.
1063
+ * @param {number} parent
1064
+ * @param {number} child_1
1065
+ * @param {number} child_2
1066
+ */
1067
+ node_assign_children_only(parent, child_1, child_2) {
1068
+ assert.isNonNegativeInteger(parent, 'parent');
1069
+ assert.isNonNegativeInteger(child_1, 'child_1');
1070
+ assert.isNonNegativeInteger(child_2, 'child_2');
1056
1071
 
1057
1072
  this.node_set_parent(child_1, parent);
1058
1073
  this.node_set_parent(child_2, parent);
1059
1074
 
1075
+ this.node_set_child1(parent, child_1);
1076
+ this.node_set_child2(parent, child_2);
1077
+
1060
1078
  this.node_set_height(parent,
1061
- Math.max(
1079
+ 1 + Math.max(
1062
1080
  this.node_get_height(child_1),
1063
1081
  this.node_get_height(child_2),
1064
- ) + 1
1082
+ )
1065
1083
  );
1066
-
1067
- this.node_set_combined_aabb(parent, child_1, child_2);
1068
1084
  }
1069
1085
 
1070
1086
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"ebvh_build_for_geometry_morton.d.ts","sourceRoot":"","sources":["../../../../../src/core/bvh2/bvh3/ebvh_build_for_geometry_morton.js"],"names":[],"mappings":"AAYA;;;;;;;;;GASG;AACH,oDAPW,GAAG,eACH,MAAM,EAAE,GAAC,WAAW,GAAC,WAAW,kBAChC,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,iBAClC,WAAW,WACX,KAAK,YACL,MAAM,QAiIhB;sBAlJqB,6BAA6B"}
1
+ {"version":3,"file":"ebvh_build_for_geometry_morton.d.ts","sourceRoot":"","sources":["../../../../../src/core/bvh2/bvh3/ebvh_build_for_geometry_morton.js"],"names":[],"mappings":"AAWA;;;;;;;;;GASG;AACH,oDAPW,GAAG,eACH,MAAM,EAAE,GAAC,WAAW,GAAC,WAAW,kBAChC,MAAM,EAAE,GAAC,YAAY,GAAC,YAAY,iBAClC,WAAW,WACX,KAAK,YACL,MAAM,QAsHhB;sBAtIqB,6BAA6B"}
@@ -8,7 +8,6 @@ import { max2 } from "../../math/max2.js";
8
8
  import { build_triangle_morton_codes } from "./build_triangle_morton_codes.js";
9
9
  import { COLUMN_CHILD_1, COLUMN_HEIGHT, COLUMN_USER_DATA, ELEMENT_WORD_COUNT, NULL_NODE } from "./BVH.js";
10
10
  import { ebvh_build_hierarchy } from "./ebvh_build_hierarchy.js";
11
- import { ebvh_nodes_sort_sah_local4 } from "./ebvh_nodes_sort_sah_local4.js";
12
11
 
13
12
  /**
14
13
  * Build the BVH bottom-up using spatial hash sorting
@@ -131,18 +130,7 @@ export function ebvh_build_for_geometry_morton(
131
130
 
132
131
  typed_array_copy(nodes, unprocessed_nodes);
133
132
 
134
- // do long-distance swaps, starting high and coming down
135
- for (let power = 5; power > Math.max(5 - quality, 1); power--) {
136
133
 
137
- ebvh_nodes_sort_sah_local4(
138
- bvh,
139
- unprocessed_nodes,
140
- 0,
141
- 1 << power,
142
- tri_count
143
- );
144
-
145
- }
146
134
 
147
135
 
148
136
  // assign root
@@ -1 +1 @@
1
- {"version":3,"file":"ebvh_build_hierarchy.d.ts","sourceRoot":"","sources":["../../../../../src/core/bvh2/bvh3/ebvh_build_hierarchy.js"],"names":[],"mappings":"AAKA;;;;;;;;;;;;GAYG;AACH,0CATW,GAAG,qBACH,MAAM,EAAE,GAAC,WAAW,oBACpB,MAAM,aACN,MAAM,EAAE,GAAC,WAAW,oBACpB,MAAM,2BACN,MAAM,0BACN,MAAM,GACJ,MAAM,CAmFlB"}
1
+ {"version":3,"file":"ebvh_build_hierarchy.d.ts","sourceRoot":"","sources":["../../../../../src/core/bvh2/bvh3/ebvh_build_hierarchy.js"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AACH,0CATW,GAAG,qBACH,MAAM,EAAE,GAAC,WAAW,oBACpB,MAAM,aACN,MAAM,EAAE,GAAC,WAAW,oBACpB,MAAM,2BACN,MAAM,0BACN,MAAM,GACJ,MAAM,CAmFlB"}
@@ -1,5 +1,4 @@
1
1
  import { assert } from "../../assert.js";
2
- import { max2 } from "../../math/max2.js";
3
2
  import { NULL_NODE } from "./BVH.js";
4
3
  import { ebvh_nodes_sort_sah_local4 } from "./ebvh_nodes_sort_sah_local4.js";
5
4
 
@@ -40,6 +39,19 @@ export function ebvh_build_hierarchy(
40
39
 
41
40
  const sah_optimization_cycle_count = Math.floor(sah_optimization_level + sah_optimization_bias * current_construction_depth);
42
41
 
42
+ // do long-distance swaps, starting high and coming down
43
+ for (let power = 5; power > Math.max(5 - sah_optimization_cycle_count, 1); power--) {
44
+
45
+ ebvh_nodes_sort_sah_local4(
46
+ bvh,
47
+ unprocessed_nodes,
48
+ 0,
49
+ 1 << power,
50
+ unprocessed_node_count
51
+ );
52
+
53
+ }
54
+
43
55
  for (let i = 0; i < sah_optimization_cycle_count; i++) {
44
56
 
45
57
  // Sort intermediate nodes using small locality and SAH metric
@@ -65,20 +77,7 @@ export function ebvh_build_hierarchy(
65
77
 
66
78
  const parent = node_pool[used_index++];
67
79
 
68
- bvh.node_set_combined_aabb(parent, child_1, child_2);
69
-
70
- bvh.node_set_parent(child_1, parent);
71
- bvh.node_set_parent(child_2, parent);
72
-
73
- bvh.node_set_child1(parent, child_1);
74
- bvh.node_set_child2(parent, child_2);
75
-
76
- bvh.node_set_height(parent,
77
- 1 + max2(
78
- bvh.node_get_height(child_1),
79
- bvh.node_get_height(child_2)
80
- )
81
- );
80
+ bvh.node_assign_children(parent, child_1, child_2);
82
81
 
83
82
  unprocessed_nodes[added_nodes++] = parent;
84
83
  }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * DO NOT USE, currently broken
3
+ * @param {BVH} bvh
4
+ * @param {number[]|Uint32Array} leaf_nodes
5
+ * @param {number[]} sorted_morton_codes
6
+ * @param {number} leaf_count
7
+ * @param {number[]} internal_nodes
8
+ * @returns {number} new root
9
+ */
10
+ export function ebvh_build_hierarchy_radix(bvh: BVH, leaf_nodes: number[] | Uint32Array, sorted_morton_codes: number[], leaf_count: number, internal_nodes: number[]): number;
11
+ //# sourceMappingURL=ebvh_build_hierarchy_radix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ebvh_build_hierarchy_radix.d.ts","sourceRoot":"","sources":["../../../../../src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.js"],"names":[],"mappings":"AA4MA;;;;;;;;GAQG;AACH,gDAPW,GAAG,cACH,MAAM,EAAE,GAAC,WAAW,uBACpB,MAAM,EAAE,cACR,MAAM,kBACN,MAAM,EAAE,GACN,MAAM,CAqElB"}
@@ -0,0 +1,281 @@
1
+ import { assert } from "../../assert.js";
2
+ import { clz32 } from "../../binary/clz32.js";
3
+ import { clamp } from "../../math/clamp.js";
4
+ import { NULL_NODE } from "./BVH.js";
5
+ import { ebvh_update_hierarchy_bounds } from "./ebvh_update_hierarchy_bounds.js";
6
+
7
+ /**
8
+ *
9
+ * @see "Thinking Parallel, Part III: Tree Construction on the GPU", 2012 by Tero Karras
10
+ *
11
+ * @param {number[]|Uint32Array} sortedMortonCodes
12
+ * @param {number} first
13
+ * @param {number} last
14
+ * @return {number}
15
+ */
16
+ function find_split(
17
+ sortedMortonCodes,
18
+ first,
19
+ last
20
+ ) {
21
+ // Identical Morton codes => split the range in the middle.
22
+
23
+ const firstCode = sortedMortonCodes[first];
24
+ const lastCode = sortedMortonCodes[last];
25
+
26
+ if (firstCode === lastCode) {
27
+ return (first + last) >>> 1;
28
+ }
29
+
30
+ // Calculate the number of highest bits that are the same
31
+ // for all objects, using the count-leading-zeros intrinsic.
32
+
33
+ const commonPrefix = clz32(firstCode ^ lastCode);
34
+
35
+ // Use binary search to find where the next bit differs.
36
+ // Specifically, we are looking for the highest object that
37
+ // shares more than commonPrefix bits with the first one.
38
+
39
+ let split = first; // initial guess
40
+ let step = last - first;
41
+
42
+ do {
43
+ step = (step + 1) >>> 1; // exponential decrease
44
+ const newSplit = split + step; // proposed new position
45
+
46
+ if (newSplit < last) {
47
+ const splitCode = sortedMortonCodes[newSplit];
48
+ const splitPrefix = clz32(firstCode ^ splitCode);
49
+ if (splitPrefix > commonPrefix) {
50
+ split = newSplit; // accept proposal
51
+ }
52
+ }
53
+ }
54
+ while (step > 1);
55
+
56
+ return split;
57
+ }
58
+
59
+ /**
60
+ *
61
+ * @param {number} indexA
62
+ * @param {number} indexB
63
+ * @param {number} elementCount
64
+ * @param {number[]} mortonCodes
65
+ * @return {number}
66
+ * @see https://github.com/turanszkij/WickedEngine/blob/506749de321c2ab66fd33fbe41efb95afbbb7ff8/WickedEngine/shaders/bvh_hierarchyCS.hlsl#L28C1-L48C2
67
+ */
68
+ function GetLongestCommonPrefix(indexA, indexB, elementCount, mortonCodes) {
69
+ assert.isNonNegativeInteger(indexA, 'indexA');
70
+ assert.isNonNegativeInteger(indexB, 'indexB');
71
+
72
+ if (indexA >= elementCount || indexB >= elementCount) {
73
+ return -1;
74
+ } else {
75
+ const mortonCodeA = mortonCodes[indexA];
76
+ const mortonCodeB = mortonCodes[indexB];
77
+ if (mortonCodeA !== mortonCodeB) {
78
+ return clz32(mortonCodeA ^ mortonCodeB);
79
+ } else {
80
+ // TODO: Technically this should be primitive ID
81
+ return clz32(indexA ^ indexB) + 31;
82
+ }
83
+ }
84
+ }
85
+
86
+ /**
87
+ * @see https://github.com/turanszkij/WickedEngine/blob/506749de321c2ab66fd33fbe41efb95afbbb7ff8/WickedEngine/shaders/bvh_hierarchyCS.hlsl#L28C1-L48C2
88
+ * @param {number[]|Uint32Array} output
89
+ * @param {number[]} sortedMortonCodes
90
+ * @param {number} numTriangles
91
+ * @param {number} idx
92
+ */
93
+ function determineRangeW(output, sortedMortonCodes, numTriangles, idx) {
94
+ if (idx === 0) {
95
+ // root
96
+ output[0] = 0;
97
+ output[1] = numTriangles - 1;
98
+ return;
99
+ }
100
+
101
+ let d = GetLongestCommonPrefix(idx, idx + 1, numTriangles, sortedMortonCodes) - GetLongestCommonPrefix(idx, idx - 1, numTriangles, sortedMortonCodes);
102
+ d = clamp(d, -1, 1);
103
+
104
+ let minPrefix = GetLongestCommonPrefix(idx, idx - d, numTriangles, sortedMortonCodes);
105
+
106
+ // TODO: Consider starting this at a higher number
107
+ let maxLength = 2;
108
+ while (GetLongestCommonPrefix(idx, idx + maxLength * d, numTriangles, sortedMortonCodes) > minPrefix) {
109
+ maxLength <<= 2;
110
+ }
111
+
112
+ let length = 0;
113
+ for (let t = maxLength >>> 1; t > 0; t >>>= 1) {
114
+ if (GetLongestCommonPrefix(idx, idx + (length + t) * d, numTriangles, sortedMortonCodes) > minPrefix) {
115
+ length = length + t;
116
+ }
117
+ }
118
+
119
+ let j = idx + length * d;
120
+
121
+ output[0] = Math.min(idx, j);
122
+ output[1] = Math.max(idx, j);
123
+
124
+ }
125
+
126
+
127
+ /**
128
+ * @see https://github.com/mbartling/cuda-bvh/blob/7f2f98d9d29956c3559632e59104ba66f31f80b8/kernels/bvh.cu#L276C1-L352C2
129
+ * @param {number[]|Uint32Array} output
130
+ * @param {number[]} sortedMortonCodes
131
+ * @param {number} numTriangles
132
+ * @param {number} idx
133
+ */
134
+ function determineRange(output, sortedMortonCodes, numTriangles, idx) {
135
+
136
+ //determine the range of keys covered by each internal node (as well as its children)
137
+ //direction is found by looking at the neighboring keys ki-1 , ki , ki+1
138
+ //the index is either the beginning of the range or the end of the range
139
+ let direction = 0;
140
+ let common_prefix_with_left = 0;
141
+ let common_prefix_with_right = 0;
142
+
143
+ common_prefix_with_right = clz32(sortedMortonCodes[idx] ^ sortedMortonCodes[idx + 1]);
144
+
145
+ if (idx === 0) {
146
+ common_prefix_with_left = -1;
147
+ } else {
148
+ common_prefix_with_left = clz32(sortedMortonCodes[idx] ^ sortedMortonCodes[idx - 1]);
149
+
150
+ }
151
+
152
+ direction = ((common_prefix_with_right - common_prefix_with_left) > 0) ? 1 : -1;
153
+
154
+ let min_prefix_range = 0;
155
+
156
+ if (idx === 0) {
157
+ min_prefix_range = -1;
158
+
159
+ } else {
160
+ min_prefix_range = clz32(sortedMortonCodes[idx] ^ sortedMortonCodes[idx - direction]);
161
+ }
162
+
163
+ let lmax = 2;
164
+ let next_key = idx + lmax * direction;
165
+
166
+ while ((next_key >= 0) && (next_key < numTriangles) && (clz32(sortedMortonCodes[idx] ^ sortedMortonCodes[next_key]) > min_prefix_range)) {
167
+ lmax *= 2;
168
+ next_key = idx + lmax * direction;
169
+ }
170
+ //find the other end using binary search
171
+ let l = 0;
172
+
173
+ do {
174
+ lmax = (lmax + 1) >> 1; // exponential decrease
175
+ const new_val = idx + (l + lmax) * direction;
176
+
177
+ if (new_val >= 0 && new_val < numTriangles) {
178
+ const Code = sortedMortonCodes[new_val];
179
+ const Prefix = clz32(sortedMortonCodes[idx] ^ Code);
180
+ if (Prefix > min_prefix_range) {
181
+ l = l + lmax;
182
+ }
183
+ }
184
+ } while (lmax > 1);
185
+
186
+ const j = idx + l * direction;
187
+
188
+ let left = 0;
189
+ let right = 0;
190
+
191
+ if (idx < j) {
192
+ left = idx;
193
+ right = j;
194
+ } else {
195
+ left = j;
196
+ right = idx;
197
+ }
198
+
199
+ // printf("idx : (%d) returning range (%d, %d) \n" , idx , left, right);
200
+
201
+ output[0] = left
202
+ output[1] = right;
203
+ }
204
+
205
+ /**
206
+ * DO NOT USE, currently broken
207
+ * @param {BVH} bvh
208
+ * @param {number[]|Uint32Array} leaf_nodes
209
+ * @param {number[]} sorted_morton_codes
210
+ * @param {number} leaf_count
211
+ * @param {number[]} internal_nodes
212
+ * @returns {number} new root
213
+ */
214
+ export function ebvh_build_hierarchy_radix(
215
+ bvh,
216
+ leaf_nodes,
217
+ sorted_morton_codes,
218
+ leaf_count,
219
+ internal_nodes,
220
+ ) {
221
+ console.warn("IMPLEMENTATION IS INCOMPLETE, DO NOT USE")
222
+
223
+ assert.isNonNegativeInteger(leaf_count, 'leaf_count');
224
+
225
+ // Construct leaf nodes.
226
+ // Note: This step can be avoided by storing
227
+ // the tree in a slightly different way.
228
+
229
+ const range = new Uint32Array(2);
230
+
231
+ // Construct internal nodes.
232
+ const intermediate_node_count = leaf_count - 1;
233
+ for (let idx = 0; idx < intermediate_node_count; idx++) // in parallel
234
+ {
235
+ // Find out which range of objects the node corresponds to.
236
+ // (This is where the magic happens!)
237
+
238
+ determineRange(range, sorted_morton_codes, leaf_count, idx);
239
+
240
+ const first = range[0];
241
+ const last = range[1];
242
+
243
+ // Determine where to split the range.
244
+
245
+ const split = find_split(sorted_morton_codes, first, last);
246
+ assert.isNonNegativeInteger(split, 'split');
247
+
248
+ // Select childA.
249
+
250
+ let childA;
251
+ if (split === first) {
252
+ childA = leaf_nodes[split];
253
+ } else {
254
+ childA = internal_nodes[split];
255
+ }
256
+
257
+ // Select childB.
258
+
259
+ let childB;
260
+ if (split + 1 === last) {
261
+ childB = leaf_nodes[split + 1];
262
+ } else {
263
+ childB = internal_nodes[split + 1];
264
+ }
265
+
266
+ // Record parent-child relationships.
267
+ const parent = internal_nodes[idx];
268
+
269
+ bvh.node_assign_children_only(parent, childA, childB);
270
+ }
271
+
272
+ // Node 0 is the root.
273
+ const root = internal_nodes[0];
274
+
275
+ bvh.node_set_parent(root, NULL_NODE);
276
+
277
+ // update bounds
278
+ ebvh_update_hierarchy_bounds(bvh, root);
279
+
280
+ return root;
281
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"ebvh_optimize_treelet.d.ts","sourceRoot":"","sources":["../../../../../src/core/bvh2/bvh3/ebvh_optimize_treelet.js"],"names":[],"mappings":"AAuNA;;;;;;;GAOG;AACH,2CAJW,GAAG,SACH,MAAM,iBACN,MAAM,QA8IhB"}
1
+ {"version":3,"file":"ebvh_optimize_treelet.d.ts","sourceRoot":"","sources":["../../../../../src/core/bvh2/bvh3/ebvh_optimize_treelet.js"],"names":[],"mappings":"AAuNA;;;;;;;GAOG;AACH,2CAJW,GAAG,SACH,MAAM,iBACN,MAAM,QA+IhB"}
@@ -256,6 +256,7 @@ export function ebvh_optimize_treelet(
256
256
 
257
257
  const min_height = Math.ceil(Math.log2(treelet_size));
258
258
 
259
+ // do a stackless traversal
259
260
  while (true) {
260
261
 
261
262
 
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Traverses the tree bottom-up, updating bounds as it goes
3
+ * @param {BVH} bvh
4
+ * @param {number} root
5
+ * @returns {void}
6
+ */
7
+ export function ebvh_update_hierarchy_bounds(bvh: BVH, root?: number): void;
8
+ //# sourceMappingURL=ebvh_update_hierarchy_bounds.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ebvh_update_hierarchy_bounds.d.ts","sourceRoot":"","sources":["../../../../../src/core/bvh2/bvh3/ebvh_update_hierarchy_bounds.js"],"names":[],"mappings":"AAOA;;;;;GAKG;AACH,kDAJW,GAAG,SACH,MAAM,GACJ,IAAI,CAuIhB"}
@@ -0,0 +1,147 @@
1
+ import { assert } from "../../assert.js";
2
+ import { NULL_NODE } from "./BVH.js";
3
+
4
+ const CAME_FROM_TYPE_PARENT = 0;
5
+ const CAME_FROM_TYPE_CHILD_1 = 1;
6
+ const CAME_FROM_TYPE_CHILD_2 = 2;
7
+
8
+ /**
9
+ * Traverses the tree bottom-up, updating bounds as it goes
10
+ * @param {BVH} bvh
11
+ * @param {number} root
12
+ * @returns {void}
13
+ */
14
+ export function ebvh_update_hierarchy_bounds(bvh, root = bvh.root) {
15
+ assert.isNonNegativeInteger(root, 'root');
16
+
17
+ if (root === NULL_NODE) {
18
+ // special case
19
+ return;
20
+ }
21
+
22
+ if (bvh.node_is_leaf(root)) {
23
+ // special case
24
+ return;
25
+ }
26
+
27
+ // we traverse depth-first using stack-less scheme
28
+ let came_from_node = root;
29
+
30
+ let came_from_type = CAME_FROM_TYPE_PARENT;
31
+
32
+ let node = bvh.node_get_child1(came_from_node);
33
+ if (node === NULL_NODE) {
34
+ node = bvh.node_get_child2(came_from_node);
35
+ }
36
+
37
+ if (node === NULL_NODE) {
38
+ // no children, done
39
+ return;
40
+ }
41
+
42
+ // do a stackless traversal
43
+ while (true) {
44
+
45
+
46
+ if (
47
+ came_from_type === CAME_FROM_TYPE_CHILD_2
48
+ ) {
49
+ // moving up last time, lets calculate
50
+ const child_1 = bvh.node_get_child1(node);
51
+ const child_2 = bvh.node_get_child2(node);
52
+
53
+ bvh.node_set_combined_aabb(node, child_1, child_2);
54
+ }
55
+
56
+ // only add to treelet when traversing up, not down
57
+
58
+ if (bvh.node_is_leaf(node)) {
59
+
60
+ assert.equal(came_from_type, CAME_FROM_TYPE_PARENT);
61
+
62
+ const parent = came_from_node;
63
+ const parent_child_1 = bvh.node_get_child1(parent);
64
+
65
+ if (parent_child_1 === node) {
66
+ came_from_type = CAME_FROM_TYPE_CHILD_1;
67
+ } else {
68
+ came_from_type = CAME_FROM_TYPE_CHILD_2;
69
+ }
70
+
71
+ came_from_node = node;
72
+
73
+ node = parent;
74
+ } else if (came_from_type === CAME_FROM_TYPE_CHILD_2) {
75
+ // finishing traversal of this branch
76
+ came_from_node = node;
77
+ const parent = bvh.node_get_parent(node);
78
+
79
+ if (bvh.node_get_child1(parent) === node) {
80
+ came_from_type = CAME_FROM_TYPE_CHILD_1;
81
+ } else {
82
+ came_from_type = CAME_FROM_TYPE_CHILD_2;
83
+ }
84
+
85
+ if (node === root) {
86
+ // traversed all the way back up
87
+ break;
88
+ }
89
+
90
+ node = parent;
91
+
92
+ } else if (came_from_type === CAME_FROM_TYPE_CHILD_1) {
93
+ // traversing up from left child
94
+ const child2 = bvh.node_get_child2(node);
95
+
96
+ came_from_node = node;
97
+
98
+ if (child2 === NULL_NODE) {
99
+ // no right child, finish this branch
100
+ came_from_type = CAME_FROM_TYPE_CHILD_2; // indicate end
101
+
102
+ node = bvh.node_get_parent(node);
103
+ } else {
104
+ came_from_type = CAME_FROM_TYPE_PARENT;
105
+ node = child2;
106
+ }
107
+
108
+ } else if (came_from_type === CAME_FROM_TYPE_PARENT) {
109
+ const child1 = bvh.node_get_child1(node);
110
+ const child2 = bvh.node_get_child1(node);
111
+
112
+ if (child1 !== NULL_NODE) {
113
+ came_from_type = CAME_FROM_TYPE_PARENT;
114
+ came_from_node = node;
115
+ node = child1;
116
+ } else if (child2 !== NULL_NODE) {
117
+ came_from_type = CAME_FROM_TYPE_PARENT;
118
+ came_from_node = node;
119
+ node = child2;
120
+ } else {
121
+ // this should not happen, as this would mean that node is empty and completely pointless
122
+ // we remove the node and traverse up
123
+
124
+
125
+ const parent_child1 = bvh.node_get_child1(came_from_node);
126
+
127
+ bvh.release_node(node);
128
+
129
+ if (parent_child1 === node) {
130
+ // we are left child
131
+ bvh.node_set_child1(came_from_node, NULL_NODE);
132
+ came_from_node = NULL_NODE;
133
+ came_from_type = CAME_FROM_TYPE_CHILD_1;
134
+ } else {
135
+ bvh.node_set_child2(came_from_node, NULL_NODE);
136
+ came_from_node = NULL_NODE;
137
+ came_from_type = CAME_FROM_TYPE_CHILD_2;
138
+ }
139
+
140
+ node = came_from_node;
141
+ }
142
+
143
+
144
+ }
145
+
146
+ }
147
+ }