@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.
- package/package.json +1 -1
- package/src/core/bvh2/bvh3/BVH.d.ts.map +1 -1
- package/src/core/bvh2/bvh3/BVH.js +22 -6
- package/src/core/bvh2/bvh3/ebvh_build_for_geometry_morton.d.ts.map +1 -1
- package/src/core/bvh2/bvh3/ebvh_build_for_geometry_morton.js +0 -12
- package/src/core/bvh2/bvh3/ebvh_build_hierarchy.d.ts.map +1 -1
- package/src/core/bvh2/bvh3/ebvh_build_hierarchy.js +14 -15
- package/src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.d.ts +11 -0
- package/src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.d.ts.map +1 -0
- package/src/core/bvh2/bvh3/ebvh_build_hierarchy_radix.js +281 -0
- package/src/core/bvh2/bvh3/ebvh_optimize_treelet.d.ts.map +1 -1
- package/src/core/bvh2/bvh3/ebvh_optimize_treelet.js +1 -0
- package/src/core/bvh2/bvh3/ebvh_update_hierarchy_bounds.d.ts +8 -0
- package/src/core/bvh2/bvh3/ebvh_update_hierarchy_bounds.d.ts.map +1 -0
- package/src/core/bvh2/bvh3/ebvh_update_hierarchy_bounds.js +147 -0
- package/src/core/geom/Vector1.d.ts +177 -35
- package/src/core/graph/Edge.d.ts +0 -1
- package/src/core/graph/Edge.d.ts.map +1 -1
- package/src/core/graph/Edge.js +1 -1
- package/src/core/graph/v2/Graph.d.ts +24 -9
- package/src/core/graph/v2/Graph.d.ts.map +1 -1
- package/src/core/graph/v2/Graph.js +48 -10
- package/src/engine/ecs/animation/AnimationClip.d.ts +2 -2
- package/src/engine/ecs/fow/FogOfWarRevealer.d.ts +1 -1
- package/src/engine/graphics/ecs/water/Water.d.ts +1 -1
- package/src/engine/intelligence/behavior/ecs/WaitForEventBehavior.d.ts +7 -5
- package/src/engine/intelligence/behavior/ecs/WaitForEventBehavior.d.ts.map +1 -1
- package/src/engine/intelligence/behavior/ecs/WaitForEventBehavior.js +13 -12
- package/src/engine/intelligence/behavior/util/DelayBehavior.d.ts.map +1 -1
- package/src/engine/intelligence/behavior/util/DelayBehavior.js +12 -15
- package/src/engine/sound/ecs/emitter/SoundEmitter.d.ts +1 -1
package/package.json
CHANGED
|
@@ -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,
|
|
1
|
+
{"version":3,"file":"BVH.d.ts","sourceRoot":"","sources":["../../../../../src/core/bvh2/bvh3/BVH.js"],"names":[],"mappings":"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"}
|
|
@@ -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.
|
|
1055
|
-
|
|
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
|
-
)
|
|
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":"
|
|
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":"
|
|
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.
|
|
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,
|
|
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"}
|
|
@@ -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
|
+
}
|