@woosh/meep-engine 2.34.23 → 2.34.24
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/aabb3/aabb3_nearest_point_on_surface.js +65 -0
- package/core/geom/3d/shape/UnitCubeShape3D.js +7 -37
- package/core/geom/3d/{sphereIntersectsPoint.js → sphere/sphereIntersectsPoint.js} +0 -0
- package/core/geom/3d/sphere/sphere_array_intersects_ray.js +25 -0
- package/core/geom/3d/sphere/sphere_intersects_ray.js +51 -0
- package/engine/graphics/micron/format/MicronGeometry.js +24 -6
- package/package.json +1 -1
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { clamp } from "../../math/clamp.js";
|
|
2
|
+
import { min2 } from "../../math/min2.js";
|
|
3
|
+
|
|
4
|
+
//
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @param {number[]|ArrayLike<number>} result
|
|
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} r_x
|
|
16
|
+
* @param {number} r_y
|
|
17
|
+
* @param {number} r_z
|
|
18
|
+
*/
|
|
19
|
+
export function aabb3_nearest_point_on_surface(result, x0, y0, z0, x1, y1, z1, r_x, r_y, r_z) {
|
|
20
|
+
const ar_x0 = Math.abs(r_x - x0);
|
|
21
|
+
const ar_x1 = Math.abs(r_x - x1);
|
|
22
|
+
const ar_x_min = min2(ar_x0, ar_x1);
|
|
23
|
+
|
|
24
|
+
const ar_y0 = Math.abs(r_y - y0);
|
|
25
|
+
const ar_y1 = Math.abs(r_y - y1);
|
|
26
|
+
const ar_y_min = min2(ar_y0, ar_y1);
|
|
27
|
+
|
|
28
|
+
const ar_z0 = Math.abs(r_z - z0);
|
|
29
|
+
const ar_z1 = Math.abs(r_z - z1);
|
|
30
|
+
const ar_z_min = min2(ar_z0, ar_z1);
|
|
31
|
+
|
|
32
|
+
// figure out closest face to the reference point
|
|
33
|
+
if (ar_x_min > ar_y_min && ar_x_min > ar_z_min) {
|
|
34
|
+
// X is smallest, project onto X axis
|
|
35
|
+
if (ar_x0 <= ar_x1) {
|
|
36
|
+
result[0] = x0;
|
|
37
|
+
} else {
|
|
38
|
+
result[0] = x1;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
result[1] = clamp(r_y, y0, y1);
|
|
42
|
+
result[2] = clamp(r_z, z0, z1);
|
|
43
|
+
} else if (ar_y_min > ar_x_min && ar_y_min > ar_z_min) {
|
|
44
|
+
// Y is smallest, project onto X axis
|
|
45
|
+
if (ar_y0 <= ar_y1) {
|
|
46
|
+
result[1] = y0;
|
|
47
|
+
} else {
|
|
48
|
+
result[1] = y1;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
result[0] = clamp(r_x, x0, x1);
|
|
52
|
+
result[2] = clamp(r_z, z0, z1);
|
|
53
|
+
} else {
|
|
54
|
+
// project onto Z axis
|
|
55
|
+
|
|
56
|
+
if (ar_z0 <= ar_z1) {
|
|
57
|
+
result[2] = z0;
|
|
58
|
+
} else {
|
|
59
|
+
result[2] = z1;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
result[0] = clamp(r_x, x0, x1);
|
|
63
|
+
result[1] = clamp(r_y, y0, y1);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -4,8 +4,8 @@ import { v3_length } from "../../v3_length.js";
|
|
|
4
4
|
import { max2 } from "../../../math/max2.js";
|
|
5
5
|
import { max3 } from "../../../math/max3.js";
|
|
6
6
|
import { min2 } from "../../../math/min2.js";
|
|
7
|
-
import { clamp } from "../../../math/clamp.js";
|
|
8
7
|
import { compute_signed_distance_gradient_by_sampling } from "./util/compute_signed_distance_gradient_by_sampling.js";
|
|
8
|
+
import { aabb3_nearest_point_on_surface } from "../../../bvh2/aabb3/aabb3_nearest_point_on_surface.js";
|
|
9
9
|
|
|
10
10
|
export class UnitCubeShape3D extends AbstractShape3D {
|
|
11
11
|
|
|
@@ -18,43 +18,13 @@ export class UnitCubeShape3D extends AbstractShape3D {
|
|
|
18
18
|
const r_y = reference[1];
|
|
19
19
|
const r_z = reference[2];
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
aabb3_nearest_point_on_surface(
|
|
22
|
+
result,
|
|
23
|
+
-0.5, -0.5, -0.5,
|
|
24
|
+
0.5, 0.5, 0.5,
|
|
25
|
+
r_x, r_y, r_z
|
|
26
|
+
);
|
|
25
27
|
|
|
26
|
-
if (ar_x > ar_y && ar_x > ar_z) {
|
|
27
|
-
// X is smallest, project onto X axis
|
|
28
|
-
if (r_x <= 0) {
|
|
29
|
-
result[0] = -0.5;
|
|
30
|
-
} else {
|
|
31
|
-
result[0] = 0.5;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
result[1] = clamp(r_y, -0.5, 0.5);
|
|
35
|
-
result[2] = clamp(r_z, -0.5, 0.5);
|
|
36
|
-
} else if (ar_y > ar_x && ar_y > ar_z) {
|
|
37
|
-
// Y is smallest, project onto X axis
|
|
38
|
-
if (r_y <= 0) {
|
|
39
|
-
result[1] = -0.5;
|
|
40
|
-
} else {
|
|
41
|
-
result[1] = 0.5;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
result[0] = clamp(r_x, -0.5, 0.5);
|
|
45
|
-
result[2] = clamp(r_z, -0.5, 0.5);
|
|
46
|
-
} else {
|
|
47
|
-
// project onto Z axis
|
|
48
|
-
|
|
49
|
-
if (r_z <= 0) {
|
|
50
|
-
result[2] = -0.5;
|
|
51
|
-
} else {
|
|
52
|
-
result[2] = 0.5;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
result[0] = clamp(r_x, -0.5, 0.5);
|
|
56
|
-
result[1] = clamp(r_y, -0.5, 0.5);
|
|
57
|
-
}
|
|
58
28
|
}
|
|
59
29
|
|
|
60
30
|
signed_distance_gradient_at_point(result, point) {
|
|
File without changes
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import { sphere_intersects_ray } from "./sphere_intersects_ray.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {number[]|ArrayLike<number>} sphere
|
|
8
|
+
* @param {number} origin_x
|
|
9
|
+
* @param {number} origin_y
|
|
10
|
+
* @param {number} origin_z
|
|
11
|
+
* @param {number} direction_x
|
|
12
|
+
* @param {number} direction_y
|
|
13
|
+
* @param {number} direction_z
|
|
14
|
+
* @returns {boolean}
|
|
15
|
+
*/
|
|
16
|
+
export function sphere_array_intersects_ray(
|
|
17
|
+
sphere,
|
|
18
|
+
origin_x, origin_y, origin_z,
|
|
19
|
+
direction_x, direction_y, direction_z
|
|
20
|
+
) {
|
|
21
|
+
return sphere_intersects_ray(sphere[0], sphere[1], sphere[2], sphere[3],
|
|
22
|
+
origin_x, origin_y, origin_z,
|
|
23
|
+
direction_x, direction_y, direction_z
|
|
24
|
+
);
|
|
25
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
//
|
|
2
|
+
|
|
3
|
+
import { v3_dot } from "../../v3_dot.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param {number} center_x
|
|
8
|
+
* @param {number} center_y
|
|
9
|
+
* @param {number} center_z
|
|
10
|
+
* @param {number} radius
|
|
11
|
+
* @param {number} origin_x
|
|
12
|
+
* @param {number} origin_y
|
|
13
|
+
* @param {number} origin_z
|
|
14
|
+
* @param {number} direction_x
|
|
15
|
+
* @param {number} direction_y
|
|
16
|
+
* @param {number} direction_z
|
|
17
|
+
* @returns {boolean}
|
|
18
|
+
*/
|
|
19
|
+
export function sphere_intersects_ray(
|
|
20
|
+
center_x, center_y, center_z, radius,
|
|
21
|
+
origin_x, origin_y, origin_z,
|
|
22
|
+
direction_x, direction_y, direction_z
|
|
23
|
+
) {
|
|
24
|
+
const delta_x = center_x - origin_x;
|
|
25
|
+
const delta_y = center_y - origin_y;
|
|
26
|
+
const delta_z = center_z - origin_z;
|
|
27
|
+
|
|
28
|
+
const tca = v3_dot(delta_x, delta_y, delta_z, direction_x, direction_y, direction_z);
|
|
29
|
+
const d2 = v3_dot(delta_x, delta_y, delta_z, delta_x, delta_y, delta_z) - tca * tca;
|
|
30
|
+
|
|
31
|
+
const radius2 = radius * radius;
|
|
32
|
+
|
|
33
|
+
if (d2 > radius2) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const thc = Math.sqrt(radius2 - d2);
|
|
38
|
+
|
|
39
|
+
// t0 = first intersect point - entrance on front of sphere
|
|
40
|
+
const t0 = tca - thc;
|
|
41
|
+
|
|
42
|
+
// t1 = second intersect point - exit point on back of sphere
|
|
43
|
+
const t1 = tca + thc;
|
|
44
|
+
|
|
45
|
+
// test to see if both t0 and t1 are behind the ray - if so, no intersection
|
|
46
|
+
if (t0 < 0 && t1 < 0) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
@@ -3,6 +3,7 @@ import { assert } from "../../../../core/assert.js";
|
|
|
3
3
|
import { computeTriangleRayIntersection } from "../../../../core/geom/3d/triangle/computeTriangleRayIntersection.js";
|
|
4
4
|
import { SurfacePoint3 } from "../../../../core/geom/3d/SurfacePoint3.js";
|
|
5
5
|
import { aabb3_array_intersects_ray } from "../../../../core/bvh2/aabb3/aabb3_array_intersects_ray.js";
|
|
6
|
+
import { sphere_array_intersects_ray } from "../../../../core/geom/3d/sphere/sphere_array_intersects_ray.js";
|
|
6
7
|
|
|
7
8
|
let id_counter = 0;
|
|
8
9
|
|
|
@@ -104,16 +105,23 @@ export class MicronGeometry {
|
|
|
104
105
|
|
|
105
106
|
const patch = stack[stack_cursor];
|
|
106
107
|
|
|
107
|
-
// using group
|
|
108
|
-
const bb = patch.group_bounding_box;
|
|
108
|
+
// using group bounds because it's conservative, as we want to be able to hit LOD_0
|
|
109
109
|
|
|
110
|
-
|
|
111
|
-
|
|
110
|
+
// sphere test
|
|
111
|
+
if (!sphere_array_intersects_ray(patch.group_bounding_sphere,
|
|
112
112
|
origin_x, origin_y, origin_z,
|
|
113
113
|
direction_x, direction_y, direction_z
|
|
114
|
-
)
|
|
114
|
+
)) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
|
|
115
118
|
|
|
116
|
-
|
|
119
|
+
// box test (more expensive, different volume)
|
|
120
|
+
if (!aabb3_array_intersects_ray(
|
|
121
|
+
patch.group_bounding_box,
|
|
122
|
+
origin_x, origin_y, origin_z,
|
|
123
|
+
direction_x, direction_y, direction_z
|
|
124
|
+
)) {
|
|
117
125
|
// no intersection
|
|
118
126
|
continue;
|
|
119
127
|
}
|
|
@@ -122,6 +130,16 @@ export class MicronGeometry {
|
|
|
122
130
|
// LOD 0 - source geometry
|
|
123
131
|
|
|
124
132
|
// cast against bounds
|
|
133
|
+
|
|
134
|
+
// sphere test
|
|
135
|
+
if (!sphere_array_intersects_ray(patch.bounding_sphere,
|
|
136
|
+
origin_x, origin_y, origin_z,
|
|
137
|
+
direction_x, direction_y, direction_z
|
|
138
|
+
)) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// box test
|
|
125
143
|
if (!aabb3_array_intersects_ray(
|
|
126
144
|
patch.bounding_box,
|
|
127
145
|
origin_x, origin_y, origin_z,
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"productName": "Meep",
|
|
6
6
|
"description": "production-ready JavaScript game engine based on Entity Component System Architecture",
|
|
7
7
|
"author": "Alexander Goldring",
|
|
8
|
-
"version": "2.34.
|
|
8
|
+
"version": "2.34.24",
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"gl-matrix": "3.4.3",
|
|
11
11
|
"fast-levenshtein": "2.0.6",
|