@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.
@@ -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
- // figure out closest face to the reference point
22
- const ar_x = Math.abs(r_x);
23
- const ar_y = Math.abs(r_y);
24
- const ar_z = Math.abs(r_z);
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) {
@@ -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 bounding box because it's conservative, as we want to be able to hit LOD_0
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
- const bb_intersection_exists = aabb3_array_intersects_ray(
111
- bb,
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
- if (!bb_intersection_exists) {
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.23",
8
+ "version": "2.34.24",
9
9
  "dependencies": {
10
10
  "gl-matrix": "3.4.3",
11
11
  "fast-levenshtein": "2.0.6",