@woosh/meep-engine 2.34.42 → 2.34.46
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/core/bvh2/BinaryNode.js +60 -32
- package/core/bvh2/LeafNode.js +2 -1
- package/core/bvh2/aabb3/AABB3.js +879 -1059
- package/core/bvh2/aabb3/AABB3.spec.js +5 -7
- package/core/bvh2/aabb3/aabb3_array_intersects_ray.js +2 -2
- package/core/bvh2/aabb3/aabb3_box_surface_area_2.js +10 -0
- package/core/bvh2/aabb3/aabb3_compute_half_surface_area.js +16 -0
- package/core/bvh2/aabb3/aabb3_compute_surface_area.js +18 -0
- package/core/bvh2/aabb3/aabb3_expand_array.js +15 -0
- package/core/bvh2/aabb3/aabb3_intersect_aabb3.js +28 -0
- package/core/bvh2/aabb3/aabb3_intersect_ray_slab.js +73 -0
- package/core/bvh2/aabb3/{aabb3_intersects_frustum.js → aabb3_intersects_frustum_array.js} +16 -1
- package/core/bvh2/aabb3/aabb3_intersects_line_segment.js +79 -0
- package/core/bvh2/aabb3/aabb3_intersects_ray.js +92 -0
- package/core/bvh2/aabb3/{AABB3Math.spec.js → aabb3_intersects_ray.spec.js} +3 -3
- package/core/bvh2/aabb3/aabb3_intersects_ray_fast.js +176 -0
- package/core/bvh2/aabb3/aabb3_score_boxes_SAH.js +43 -0
- package/core/bvh2/aabb3/aabb_score_boxes_SAH_delta.js +37 -0
- package/core/bvh2/aabb3/deserializeAABB3.js +17 -0
- package/core/bvh2/aabb3/deserializeAABB3Encoded_v0.js +73 -0
- package/core/bvh2/aabb3/deserializeAABB3Quantized16Uint.js +36 -0
- package/core/bvh2/aabb3/serializeAABB3.js +13 -0
- package/core/bvh2/aabb3/serializeAABB3Quantized16Uint.js +33 -0
- package/core/bvh2/binary/2/BinaryUint32BVH.js +3 -3
- package/core/bvh2/binary/BinaryBVH.js +2 -2
- package/core/bvh2/binary/RayLeafIntersectionVisitor.js +2 -2
- package/core/bvh2/serialization/deserializeBinaryNode.js +1 -1
- package/core/bvh2/serialization/deserializeBinaryNodeFromBinaryBuffer.js +2 -1
- package/core/bvh2/serialization/serializeBinaryNode.js +1 -1
- package/core/bvh2/serialization/serializeBinaryNodeToBinaryBuffer.js +2 -1
- package/core/bvh2/transform/BottomUpOptimizingRebuilder.js +6 -5
- package/core/bvh2/transform/tryRotateSingleNode.js +2 -1
- package/core/bvh2/traversal/bvh_traverse_pre_order_using_stack.js +43 -0
- package/core/bvh2/visual/convert_bvh_to_dot_format_string.js +50 -0
- package/core/geom/3d/frustum/{array_setFromProjectionMatrix.js → frustum_from_projection_matrix_array.js} +1 -1
- package/core/geom/3d/topology/TopoMesh.js +0 -8
- package/core/geom/3d/topology/TopoVertex.js +7 -6
- package/core/geom/3d/topology/simplify/quadratic/Quadratic3.js +93 -5
- package/core/geom/3d/topology/simplify/quadratic/build_vertex_quadratics.js +7 -4
- package/core/geom/3d/topology/simplify/quadratic/compute_edge_collapse_cost_quadratic.js +7 -1
- package/core/geom/3d/topology/simplify/simplifyTopoMesh.js +1 -14
- package/core/graph/convertGraphToDotString.js +4 -4
- package/core/graph/v2/Graph.js +4 -0
- package/core/math/fabsf.js +8 -0
- package/engine/development/performance/MetricCollection.js +6 -0
- package/engine/ecs/foliage/ecs/Foliage2System.js +6 -2
- package/engine/graphics/compute_geometry_polycount.js +21 -0
- package/engine/graphics/ecs/light/binding/three/ThreeLightBinding.js +1 -1
- package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +2 -2
- package/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +77 -7
- package/engine/graphics/geometry/buffered/query/RaycastNearestHitComputingVisitor.js +2 -2
- package/engine/graphics/micron/build/buildMicronGeometryFromBufferGeometry.js +4 -0
- package/engine/graphics/micron/build/hierarchy/merge_patches.js +1 -1
- package/engine/graphics/micron/convert_three_object_to_micron.js +2 -0
- package/engine/graphics/micron/format/MicronGeometryPatchOccurance.js +3 -2
- package/engine/graphics/micron/plugin/GLTFAssetTransformer.js +176 -0
- package/engine/graphics/micron/plugin/MicronRenderPlugin.js +1 -135
- package/engine/graphics/micron/prototypeVirtualGeometry.js +12 -7
- package/engine/graphics/micron/render/PatchCacheKey.js +1 -1
- package/engine/graphics/micron/render/VirtualGeometryBuilder.js +16 -43
- package/engine/graphics/micron/render/instanced/ThreeInstancedAdapter.js +5 -1
- package/engine/graphics/micron/render/refinement/ActivePatchList.js +4 -10
- package/engine/graphics/micron/render/refinement/RefinementSpec.js +16 -20
- package/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +316 -11
- package/engine/graphics/render/layers/RenderLayer.js +22 -14
- package/engine/graphics/render/visibility/IncrementalDeltaSet.js +18 -5
- package/engine/graphics/render/visibility/VisibilityComputer.js +11 -15
- package/package.json +1 -1
- package/core/bvh2/aabb3/AABB3Math.js +0 -579
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { BinaryBuffer } from "../../binary/BinaryBuffer.js";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
serializeAABB3Quantized16Uint
|
|
8
|
-
} from "./AABB3.js";
|
|
2
|
+
import { AABB3 } from "./AABB3.js";
|
|
3
|
+
import { serializeAABB3Quantized16Uint } from "./serializeAABB3Quantized16Uint.js";
|
|
4
|
+
import { deserializeAABB3Quantized16Uint } from "./deserializeAABB3Quantized16Uint.js";
|
|
5
|
+
import { serializeAABB3 } from "./serializeAABB3.js";
|
|
6
|
+
import { deserializeAABB3 } from "./deserializeAABB3.js";
|
|
9
7
|
|
|
10
8
|
|
|
11
9
|
function compareBounds(expected, actual, numDigits = 10) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
//
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { aabb3_intersects_ray } from "./aabb3_intersects_ray.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
*
|
|
@@ -13,7 +13,7 @@ import { intersectRay } from "./AABB3Math.js";
|
|
|
13
13
|
* @param {number} direction_z
|
|
14
14
|
*/
|
|
15
15
|
export function aabb3_array_intersects_ray(aabb, origin_x, origin_y, origin_z, direction_x, direction_y, direction_z) {
|
|
16
|
-
return
|
|
16
|
+
return aabb3_intersects_ray(aabb[0], aabb[1], aabb[2], aabb[3], aabb[4], aabb[5],
|
|
17
17
|
origin_x, origin_y, origin_z,
|
|
18
18
|
direction_x, direction_y, direction_z
|
|
19
19
|
);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { aabb3_compute_half_surface_area } from "./aabb3_compute_half_surface_area.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {AABB3} node
|
|
6
|
+
* @returns {number}
|
|
7
|
+
*/
|
|
8
|
+
export function aabb3_box_surface_area_2(node) {
|
|
9
|
+
return aabb3_compute_half_surface_area(node.x0, node.y0, node.z0, node.x1, node.y1, node.z1);
|
|
10
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {number} x0
|
|
4
|
+
* @param {number} y0
|
|
5
|
+
* @param {number} z0
|
|
6
|
+
* @param {number} x1
|
|
7
|
+
* @param {number} y1
|
|
8
|
+
* @param {number} z1
|
|
9
|
+
* @returns {number}
|
|
10
|
+
*/
|
|
11
|
+
export function aabb3_compute_half_surface_area(x0, y0, z0, x1, y1, z1) {
|
|
12
|
+
const dx = x1 - x0;
|
|
13
|
+
const dy = y1 - y0;
|
|
14
|
+
const dz = z1 - z0;
|
|
15
|
+
return dy * (dx + dz) + dz * dx; //1 side, since it's a heuristic only
|
|
16
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {number} x0
|
|
4
|
+
* @param {number} y0
|
|
5
|
+
* @param {number} z0
|
|
6
|
+
* @param {number} x1
|
|
7
|
+
* @param {number} y1
|
|
8
|
+
* @param {number} z1
|
|
9
|
+
* @returns {number}
|
|
10
|
+
*/
|
|
11
|
+
function aabb3_compute_surface_area(x0, y0, z0, x1, y1, z1) {
|
|
12
|
+
const dx = x1 - x0;
|
|
13
|
+
const dy = y1 - y0;
|
|
14
|
+
const dz = z1 - z0;
|
|
15
|
+
return (dy * (dx + dz) + dz * dx) * 2; //2 of each side
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { aabb3_compute_surface_area };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* @param {ArrayLike<number>|number[]|Float64Array|Float32Array} input
|
|
4
|
+
* @param {ArrayLike<number>|number[]|Float64Array|Float32Array} output
|
|
5
|
+
* @param {number} distance
|
|
6
|
+
*/
|
|
7
|
+
export function aabb3_expand_array(input, output, distance) {
|
|
8
|
+
output[0] = input[0] - distance;
|
|
9
|
+
output[1] = input[1] - distance;
|
|
10
|
+
output[2] = input[2] - distance;
|
|
11
|
+
|
|
12
|
+
output[3] = input[3] + distance;
|
|
13
|
+
output[4] = input[4] + distance;
|
|
14
|
+
output[5] = input[5] + distance;
|
|
15
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { intersects1D } from "../../math/intersects1D.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {number} ax0
|
|
6
|
+
* @param {number} ay0
|
|
7
|
+
* @param {number} az0
|
|
8
|
+
* @param {number} ax1
|
|
9
|
+
* @param {number} ay1
|
|
10
|
+
* @param {number} az1
|
|
11
|
+
* @param {number} bx0
|
|
12
|
+
* @param {number} by0
|
|
13
|
+
* @param {number} bz0
|
|
14
|
+
* @param {number} bx1
|
|
15
|
+
* @param {number} by1
|
|
16
|
+
* @param {number} bz1
|
|
17
|
+
* @returns {boolean}
|
|
18
|
+
*/
|
|
19
|
+
export function aabb3_intersect_aabb3(
|
|
20
|
+
ax0, ay0, az0,
|
|
21
|
+
ax1, ay1, az1,
|
|
22
|
+
bx0, by0, bz0,
|
|
23
|
+
bx1, by1, bz1
|
|
24
|
+
) {
|
|
25
|
+
return intersects1D(ax0, ax1, bx0, bx1)
|
|
26
|
+
&& intersects1D(ay0, ay1, by0, by1)
|
|
27
|
+
&& intersects1D(az0, az1, bz0, bz1);
|
|
28
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { min2 } from "../../math/min2.js";
|
|
2
|
+
import { max2 } from "../../math/max2.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* see: https://tavianator.com/fast-branchless-raybounding-box-intersections-part-2-nans/
|
|
6
|
+
* NOTE: this solution forgoes consistent handling of NaNs in favor of execution speed
|
|
7
|
+
* FIXME some manual tests have shown deviation in results between this implementation and others. Possible bugs?
|
|
8
|
+
* @param {number} x0
|
|
9
|
+
* @param {number} y0
|
|
10
|
+
* @param {number} z0
|
|
11
|
+
* @param {number} x1
|
|
12
|
+
* @param {number} y1
|
|
13
|
+
* @param {number} z1
|
|
14
|
+
* @param {number} oX
|
|
15
|
+
* @param {number} oY
|
|
16
|
+
* @param {number} oZ
|
|
17
|
+
* @param {number} dirX
|
|
18
|
+
* @param {number} dirY
|
|
19
|
+
* @param {number} dirZ
|
|
20
|
+
* @returns {boolean}
|
|
21
|
+
*/
|
|
22
|
+
export function aabb3_intersect_ray_slab(
|
|
23
|
+
x0, y0, z0,
|
|
24
|
+
x1, y1, z1,
|
|
25
|
+
oX, oY, oZ,
|
|
26
|
+
dirX, dirY, dirZ
|
|
27
|
+
) {
|
|
28
|
+
/*
|
|
29
|
+
Java CODE:
|
|
30
|
+
bool intersection(box b, ray r) {
|
|
31
|
+
double t1 = (b.min[0] - r.origin[0])*r.dir_inv[0];
|
|
32
|
+
double t2 = (b.max[0] - r.origin[0])*r.dir_inv[0];
|
|
33
|
+
|
|
34
|
+
double tmin = min(t1, t2);
|
|
35
|
+
double tmax = max(t1, t2);
|
|
36
|
+
|
|
37
|
+
for (int i = 1; i < 3; ++i) {
|
|
38
|
+
t1 = (b.min[i] - r.origin[i])*r.dir_inv[i];
|
|
39
|
+
t2 = (b.max[i] - r.origin[i])*r.dir_inv[i];
|
|
40
|
+
|
|
41
|
+
tmin = max(tmin, min(t1, t2));
|
|
42
|
+
tmax = min(tmax, max(t1, t2));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return tmax > max(tmin, 0.0);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
*/
|
|
49
|
+
const dir_inv_x = -dirX;
|
|
50
|
+
const dir_inv_y = -dirY;
|
|
51
|
+
const dir_inv_z = -dirZ;
|
|
52
|
+
|
|
53
|
+
const t1_x = (x0 - oX) * dir_inv_x;
|
|
54
|
+
const t2_x = (x1 - oX) * dir_inv_x;
|
|
55
|
+
|
|
56
|
+
const tMin_x = min2(t1_x, t2_x);
|
|
57
|
+
const tMax_x = max2(t1_x, t2_x);
|
|
58
|
+
|
|
59
|
+
const t1_y = (y0 - oY) * dir_inv_y;
|
|
60
|
+
const t2_y = (y1 - oY) * dir_inv_y;
|
|
61
|
+
|
|
62
|
+
const tMin_y = max2(tMin_x, min2(t1_y, t2_y));
|
|
63
|
+
const tMax_y = min2(tMax_x, max2(t1_y, t2_y));
|
|
64
|
+
|
|
65
|
+
const t1_z = (z0 - oZ) * dir_inv_z;
|
|
66
|
+
const t2_z = (z1 - oZ) * dir_inv_z;
|
|
67
|
+
|
|
68
|
+
const tMin_z = max2(tMin_y, min2(t1_z, t2_z));
|
|
69
|
+
const tMax_z = min2(tMax_y, max2(t1_z, t2_z));
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
return tMax_z > max2(tMin_z, 0.0);
|
|
73
|
+
}
|
|
@@ -6,7 +6,7 @@ import { aabb3_computeDistanceAbovePlane } from "../../geom/3d/aabb/aabb3_comput
|
|
|
6
6
|
* @param {Float32Array|number[]} frustum
|
|
7
7
|
* @return {boolean}
|
|
8
8
|
*/
|
|
9
|
-
export function
|
|
9
|
+
export function aabb3_intersects_frustum_array(aabb, frustum) {
|
|
10
10
|
|
|
11
11
|
const x0 = aabb[0];
|
|
12
12
|
const y0 = aabb[1];
|
|
@@ -15,6 +15,21 @@ export function aabb3_intersects_frustum(aabb, frustum) {
|
|
|
15
15
|
const y1 = aabb[4];
|
|
16
16
|
const z1 = aabb[5];
|
|
17
17
|
|
|
18
|
+
return aabb3_intersects_frustum(x0, y0, z0, x1, y1, z1, frustum);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
*
|
|
23
|
+
* @param {number} x0
|
|
24
|
+
* @param {number} y0
|
|
25
|
+
* @param {number} z0
|
|
26
|
+
* @param {number} x1
|
|
27
|
+
* @param {number} y1
|
|
28
|
+
* @param {number} z1
|
|
29
|
+
* @param {ArrayLike<number>|number[]|Float32Array|Float64Array} frustum
|
|
30
|
+
* @return {boolean}
|
|
31
|
+
*/
|
|
32
|
+
export function aabb3_intersects_frustum(x0, y0, z0, x1, y1, z1, frustum) {
|
|
18
33
|
for (let i = 0; i < 24; i += 4) {
|
|
19
34
|
|
|
20
35
|
const plane_n_x = frustum[i];
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { fabsf } from "../../math/fabsf.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {number} x0
|
|
6
|
+
* @param {number} y0
|
|
7
|
+
* @param {number} z0
|
|
8
|
+
* @param {number} x1
|
|
9
|
+
* @param {number} y1
|
|
10
|
+
* @param {number} z1
|
|
11
|
+
* @param {number} startX
|
|
12
|
+
* @param {number} startY
|
|
13
|
+
* @param {number} startZ
|
|
14
|
+
* @param {number} endX
|
|
15
|
+
* @param {number} endY
|
|
16
|
+
* @param {number} endZ
|
|
17
|
+
* @returns {boolean}
|
|
18
|
+
*/
|
|
19
|
+
function aabb3_intersects_line_segment(
|
|
20
|
+
x0, y0, z0,
|
|
21
|
+
x1, y1, z1,
|
|
22
|
+
startX, startY, startZ,
|
|
23
|
+
endX, endY, endZ
|
|
24
|
+
) {
|
|
25
|
+
|
|
26
|
+
let boxExtentsX,
|
|
27
|
+
boxExtentsY,
|
|
28
|
+
boxExtentsZ,
|
|
29
|
+
diffX,
|
|
30
|
+
diffY,
|
|
31
|
+
diffZ,
|
|
32
|
+
dirX,
|
|
33
|
+
dirY,
|
|
34
|
+
dirZ,
|
|
35
|
+
centerX,
|
|
36
|
+
centerY,
|
|
37
|
+
centerZ;
|
|
38
|
+
//
|
|
39
|
+
let a, b, c;
|
|
40
|
+
|
|
41
|
+
dirX = 0.5 * (endX - startX);
|
|
42
|
+
boxExtentsX = (x1 - x0) / 2;
|
|
43
|
+
centerX = x0 + boxExtentsX;
|
|
44
|
+
diffX = (0.5 * (endX + startX)) - centerX;
|
|
45
|
+
a = fabsf(dirX);
|
|
46
|
+
if (fabsf(diffX) > boxExtentsX + a) return false;
|
|
47
|
+
//
|
|
48
|
+
dirY = 0.5 * (endY - startY);
|
|
49
|
+
boxExtentsY = (y1 - y0) / 2;
|
|
50
|
+
centerY = y0 + boxExtentsY;
|
|
51
|
+
diffY = (0.5 * (endY + startY)) - centerY;
|
|
52
|
+
b = fabsf(dirY);
|
|
53
|
+
if (fabsf(diffY) > boxExtentsY + b) return false;
|
|
54
|
+
//
|
|
55
|
+
dirZ = 0.5 * (endZ - startZ);
|
|
56
|
+
boxExtentsZ = (z1 - z0) / 2;
|
|
57
|
+
centerZ = z0 + boxExtentsZ;
|
|
58
|
+
diffZ = (0.5 * (endZ + startZ)) - centerZ;
|
|
59
|
+
c = fabsf(dirZ);
|
|
60
|
+
if (fabsf(diffZ) > boxExtentsZ + c) return false;
|
|
61
|
+
|
|
62
|
+
//Dir.y = 0.5f * (segment.mP1.y - segment.mP0.y);
|
|
63
|
+
//BoxExtents.y = aabb.GetExtents(1);
|
|
64
|
+
//Diff.y = (0.5f * (segment.mP1.y + segment.mP0.y)) - aabb.GetCenter(1);
|
|
65
|
+
//b = fabsf(Dir.y);
|
|
66
|
+
//if(fabsf(Diff.y)>BoxExtents.y + b) return false;
|
|
67
|
+
|
|
68
|
+
let f;
|
|
69
|
+
f = dirY * diffZ - dirZ * diffY;
|
|
70
|
+
if (fabsf(f) > boxExtentsY * c + boxExtentsZ * b) return false;
|
|
71
|
+
f = dirZ * diffX - dirX * diffZ;
|
|
72
|
+
if (fabsf(f) > boxExtentsX * c + boxExtentsZ * a) return false;
|
|
73
|
+
f = dirX * diffY - dirY * diffX;
|
|
74
|
+
if (fabsf(f) > boxExtentsX * b + boxExtentsY * a) return false;
|
|
75
|
+
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export { aabb3_intersects_line_segment };
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { fabsf } from "../../math/fabsf.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* NOTES:
|
|
5
|
+
* https://web.archive.org/web/20090803054252/http://tog.acm.org/resources/GraphicsGems/gems/RayBox.c
|
|
6
|
+
* https://tavianator.com/fast-branchless-raybounding-box-intersections/
|
|
7
|
+
* https://gamedev.stackexchange.com/questions/18436/most-efficient-aabb-vs-ray-collision-algorithms
|
|
8
|
+
*
|
|
9
|
+
* @param {number} x0
|
|
10
|
+
* @param {number} y0
|
|
11
|
+
* @param {number} z0
|
|
12
|
+
* @param {number} x1
|
|
13
|
+
* @param {number} y1
|
|
14
|
+
* @param {number} z1
|
|
15
|
+
* @param {number} oX
|
|
16
|
+
* @param {number} oY
|
|
17
|
+
* @param {number} oZ
|
|
18
|
+
* @param {number} dirX
|
|
19
|
+
* @param {number} dirY
|
|
20
|
+
* @param {number} dirZ
|
|
21
|
+
* @returns {boolean}
|
|
22
|
+
*/
|
|
23
|
+
function aabb3_intersects_ray(x0, y0, z0, x1, y1, z1, oX, oY, oZ, dirX, dirY, dirZ) {
|
|
24
|
+
|
|
25
|
+
// Z Projection
|
|
26
|
+
const boxExtentsX = (x1 - x0) / 2;
|
|
27
|
+
|
|
28
|
+
const centerX = x0 + boxExtentsX;
|
|
29
|
+
|
|
30
|
+
const diffX = oX - centerX;
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
if (fabsf(diffX) > boxExtentsX && diffX * dirX >= 0.0) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Y projection
|
|
38
|
+
const boxExtentsY = (y1 - y0) / 2;
|
|
39
|
+
|
|
40
|
+
const centerY = y0 + boxExtentsY;
|
|
41
|
+
|
|
42
|
+
const diffY = oY - centerY;
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
if (fabsf(diffY) > boxExtentsY && diffY * dirY >= 0.0) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Z projection
|
|
50
|
+
const boxExtentsZ = (z1 - z0) / 2;
|
|
51
|
+
|
|
52
|
+
const centerZ = z0 + boxExtentsZ;
|
|
53
|
+
|
|
54
|
+
const diffZ = oZ - centerZ;
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
if (fabsf(diffZ) > boxExtentsZ && diffZ * dirZ >= 0.0) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
//Dir.y = 0.5f * (segment.mP1.y - segment.mP0.y);
|
|
62
|
+
//BoxExtents.y = aabb.GetExtents(1);
|
|
63
|
+
//Diff.y = (0.5f * (segment.mP1.y + segment.mP0.y)) - aabb.GetCenter(1);
|
|
64
|
+
//b = fabsf(Dir.y);
|
|
65
|
+
//if(fabsf(Diff.y)>BoxExtents.y + b) return false;
|
|
66
|
+
|
|
67
|
+
const a = fabsf(dirX);
|
|
68
|
+
const b = fabsf(dirY);
|
|
69
|
+
const c = fabsf(dirZ);
|
|
70
|
+
|
|
71
|
+
const f0 = dirY * diffZ - dirZ * diffY;
|
|
72
|
+
|
|
73
|
+
if (fabsf(f0) > boxExtentsY * c + boxExtentsZ * b) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const f1 = dirZ * diffX - dirX * diffZ;
|
|
78
|
+
|
|
79
|
+
if (fabsf(f1) > boxExtentsX * c + boxExtentsZ * a) {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const f2 = dirX * diffY - dirY * diffX;
|
|
84
|
+
|
|
85
|
+
if (fabsf(f2) > boxExtentsX * b + boxExtentsY * a) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export { aabb3_intersects_ray };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { seededRandom } from "../../math/random/seededRandom.js";
|
|
2
|
-
import {
|
|
2
|
+
import { aabb3_intersects_ray } from "./aabb3_intersects_ray.js";
|
|
3
3
|
|
|
4
4
|
test.skip("performance raycast", () => {
|
|
5
5
|
const rng = seededRandom(42);
|
|
@@ -13,7 +13,7 @@ test.skip("performance raycast", () => {
|
|
|
13
13
|
//warm up
|
|
14
14
|
for (i = 0; i < 10000; i++) {
|
|
15
15
|
rng();
|
|
16
|
-
|
|
16
|
+
aabb3_intersects_ray(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
//isolate timing of random function
|
|
@@ -57,7 +57,7 @@ test.skip("performance raycast", () => {
|
|
|
57
57
|
const dirY = rng();
|
|
58
58
|
const dirZ = rng();
|
|
59
59
|
|
|
60
|
-
if (
|
|
60
|
+
if (aabb3_intersects_ray(x0, y0, z0, x1, y1, z1, oX, oY, oZ, dirX, dirY, dirZ)) {
|
|
61
61
|
p++;
|
|
62
62
|
}
|
|
63
63
|
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fast Ray-Box intersection
|
|
3
|
+
* From "Graphics Gems", Academic Press, 1990
|
|
4
|
+
* ported from C
|
|
5
|
+
* see: https://web.archive.org/web/20090803054252/http://tog.acm.org/resources/GraphicsGems/gems/RayBox.c
|
|
6
|
+
* @param {number} x0
|
|
7
|
+
* @param {number} y0
|
|
8
|
+
* @param {number} z0
|
|
9
|
+
* @param {number} x1
|
|
10
|
+
* @param {number} y1
|
|
11
|
+
* @param {number} z1
|
|
12
|
+
* @param {number} oX
|
|
13
|
+
* @param {number} oY
|
|
14
|
+
* @param {number} oZ
|
|
15
|
+
* @param {number} dirX
|
|
16
|
+
* @param {number} dirY
|
|
17
|
+
* @param {number} dirZ
|
|
18
|
+
* @returns {boolean}
|
|
19
|
+
*/
|
|
20
|
+
export function aabb3_intersects_ray_fast(x0, y0, z0, x1, y1, z1, oX, oY, oZ, dirX, dirY, dirZ) {
|
|
21
|
+
let inside = true;
|
|
22
|
+
|
|
23
|
+
let quadrantX = 0;
|
|
24
|
+
let quadrantY = 0;
|
|
25
|
+
let quadrantZ = 0;
|
|
26
|
+
|
|
27
|
+
let maxTX = 0;
|
|
28
|
+
let maxTY = 0;
|
|
29
|
+
let maxTZ = 0;
|
|
30
|
+
|
|
31
|
+
let maxT = 0;
|
|
32
|
+
|
|
33
|
+
let candidatePlaneX = 0;
|
|
34
|
+
let candidatePlaneY = 0;
|
|
35
|
+
let candidatePlaneZ = 0;
|
|
36
|
+
|
|
37
|
+
let coordX = 0;
|
|
38
|
+
let coordY = 0;
|
|
39
|
+
let coordZ = 0;
|
|
40
|
+
|
|
41
|
+
/*
|
|
42
|
+
find candidate planes
|
|
43
|
+
*/
|
|
44
|
+
if (oX < x0) {
|
|
45
|
+
quadrantX = 1; //LEFT
|
|
46
|
+
candidatePlaneX = x0;
|
|
47
|
+
inside = false;
|
|
48
|
+
} else if (oX > x1) {
|
|
49
|
+
quadrantX = 0; //RIGHT
|
|
50
|
+
candidatePlaneX = x1;
|
|
51
|
+
inside = false;
|
|
52
|
+
} else {
|
|
53
|
+
quadrantX = 2; //MIDDLE
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (oY < y0) {
|
|
57
|
+
quadrantY = 1; //LEFT
|
|
58
|
+
candidatePlaneY = y0;
|
|
59
|
+
inside = false;
|
|
60
|
+
} else if (oY > y1) {
|
|
61
|
+
quadrantY = 0; //RIGHT
|
|
62
|
+
candidatePlaneY = y1;
|
|
63
|
+
inside = false;
|
|
64
|
+
} else {
|
|
65
|
+
quadrantY = 2; //MIDDLE
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (oZ < z0) {
|
|
69
|
+
quadrantZ = 1; //LEFT
|
|
70
|
+
candidatePlaneZ = z0;
|
|
71
|
+
inside = false;
|
|
72
|
+
} else if (oZ > z1) {
|
|
73
|
+
quadrantZ = 0; //RIGHT
|
|
74
|
+
candidatePlaneZ = z1;
|
|
75
|
+
inside = false;
|
|
76
|
+
} else {
|
|
77
|
+
quadrantZ = 2; //MIDDLE
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Ray origin inside the bounding box
|
|
81
|
+
if (inside) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Calculate T distances to candidate planes
|
|
86
|
+
if (quadrantX !== 2 && dirX !== 0) {
|
|
87
|
+
maxTX = (candidatePlaneX - oX) / dirX;
|
|
88
|
+
} else {
|
|
89
|
+
maxTX = -1;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (quadrantY !== 2 && dirY !== 0) {
|
|
93
|
+
maxTY = (candidatePlaneY - oY) / dirY;
|
|
94
|
+
} else {
|
|
95
|
+
maxTY = -1;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (quadrantZ !== 2 && dirZ !== 0) {
|
|
99
|
+
maxTZ = (candidatePlaneZ - oZ) / dirZ;
|
|
100
|
+
} else {
|
|
101
|
+
maxTZ = -1;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Get largest of maxT's for final choice of intersection
|
|
105
|
+
if (maxTX < maxTY) {
|
|
106
|
+
if (maxTY < maxTZ) {
|
|
107
|
+
maxT = maxTZ;
|
|
108
|
+
// Check if final candidate actually inside the box
|
|
109
|
+
if (maxT < 0) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
coordX = oX + maxT * dirX;
|
|
114
|
+
if (coordX < x0 || coordX > x1) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
coordY = oY + maxT * dirY;
|
|
119
|
+
if (coordY < y0 || coordY > y1) {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
} else {
|
|
124
|
+
maxT = maxTY;
|
|
125
|
+
// Check if final candidate actually inside the box
|
|
126
|
+
if (maxT < 0) {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
coordX = oX + maxT * dirX;
|
|
131
|
+
if (coordX < x0 || coordX > x1) {
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
coordZ = oZ + maxT * dirZ;
|
|
136
|
+
if (coordZ < z0 || coordZ > z1) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
} else if (maxTX < maxTZ) {
|
|
141
|
+
maxT = maxTZ;
|
|
142
|
+
// Check if final candidate actually inside the box
|
|
143
|
+
if (maxT < 0) {
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
coordX = oX + maxT * dirX;
|
|
148
|
+
if (coordX < x0 || coordX > x1) {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
coordY = oY + maxT * dirY;
|
|
153
|
+
if (coordY < y0 || coordY > y1) {
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
} else {
|
|
157
|
+
maxT = maxTX;
|
|
158
|
+
// Check if final candidate actually inside the box
|
|
159
|
+
if (maxT < 0) {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
coordY = oY + maxT * dirY;
|
|
164
|
+
if (coordY < y0 || coordY > y1) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
coordZ = oZ + maxT * dirZ;
|
|
169
|
+
if (coordZ < z0 || coordZ > z1) {
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
//ray hits the box
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { aabb3_compute_half_surface_area } from "./aabb3_compute_half_surface_area.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Compute surface area for a box contain both inputs
|
|
5
|
+
* @param {AABB3} a
|
|
6
|
+
* @param {AABB3} b
|
|
7
|
+
* @returns {number}
|
|
8
|
+
*/
|
|
9
|
+
function aabb3_score_boxes_SAH(a, b) {
|
|
10
|
+
let x0, y0, z0, x1, y1, z1;
|
|
11
|
+
|
|
12
|
+
//
|
|
13
|
+
|
|
14
|
+
const ax0 = a.x0;
|
|
15
|
+
const ay0 = a.y0;
|
|
16
|
+
const az0 = a.z0;
|
|
17
|
+
const ax1 = a.x1;
|
|
18
|
+
const ay1 = a.y1;
|
|
19
|
+
const az1 = a.z1;
|
|
20
|
+
|
|
21
|
+
const bx0 = b.x0;
|
|
22
|
+
const by0 = b.y0;
|
|
23
|
+
const bz0 = b.z0;
|
|
24
|
+
const bx1 = b.x1;
|
|
25
|
+
const by1 = b.y1;
|
|
26
|
+
const bz1 = b.z1;
|
|
27
|
+
|
|
28
|
+
//
|
|
29
|
+
|
|
30
|
+
x0 = ax0 < bx0 ? ax0 : bx0;
|
|
31
|
+
y0 = ay0 < by0 ? ay0 : by0;
|
|
32
|
+
z0 = az0 < bz0 ? az0 : bz0;
|
|
33
|
+
|
|
34
|
+
x1 = ax1 > bx1 ? ax1 : bx1;
|
|
35
|
+
y1 = ay1 > by1 ? ay1 : by1;
|
|
36
|
+
z1 = az1 > bz1 ? az1 : bz1;
|
|
37
|
+
|
|
38
|
+
//
|
|
39
|
+
|
|
40
|
+
return aabb3_compute_half_surface_area(x0, y0, z0, x1, y1, z1);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { aabb3_score_boxes_SAH };
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { aabb3_compute_half_surface_area } from "./aabb3_compute_half_surface_area.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {AABB3} b0
|
|
6
|
+
* @param {AABB3} b1
|
|
7
|
+
* @return {number}
|
|
8
|
+
*/
|
|
9
|
+
function aabb3_score_boxes_SAH_delta(b0, b1) {
|
|
10
|
+
let x0, y0, z0, x1, y1, z1;
|
|
11
|
+
//
|
|
12
|
+
const b0x0 = b0.x0;
|
|
13
|
+
const b0y0 = b0.y0;
|
|
14
|
+
const b0z0 = b0.z0;
|
|
15
|
+
const b0x1 = b0.x1;
|
|
16
|
+
const b0y1 = b0.y1;
|
|
17
|
+
const b0z1 = b0.z1;
|
|
18
|
+
|
|
19
|
+
const b1x0 = b1.x0;
|
|
20
|
+
const b1y0 = b1.y0;
|
|
21
|
+
const b1z0 = b1.z0;
|
|
22
|
+
const b1x1 = b1.x1;
|
|
23
|
+
const b1y1 = b1.y1;
|
|
24
|
+
const b1z1 = b1.z1;
|
|
25
|
+
//
|
|
26
|
+
x0 = b0x0 < b1x0 ? b0x0 : b1x0;
|
|
27
|
+
y0 = b0y0 < b1y0 ? b0y0 : b1y0;
|
|
28
|
+
z0 = b0z0 < b1z0 ? b0z0 : b1z0;
|
|
29
|
+
x1 = b0x1 > b1x1 ? b0x1 : b1x1;
|
|
30
|
+
y1 = b0y1 > b1y1 ? b0y1 : b1y1;
|
|
31
|
+
z1 = b0z1 > b1z1 ? b0z1 : b1z1;
|
|
32
|
+
//
|
|
33
|
+
const totalArea = aabb3_compute_half_surface_area(x0, y0, z0, x1, y1, z1);
|
|
34
|
+
const area0 = b0.getSurfaceArea();
|
|
35
|
+
const area1 = b1.getSurfaceArea();
|
|
36
|
+
return totalArea - Math.max(area0, area1);
|
|
37
|
+
}
|