@woosh/meep-engine 2.34.23 → 2.34.27

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
+ }
@@ -0,0 +1,14 @@
1
+ import { v3_dot } from "../../v3_dot.js";
2
+
3
+ export function ray_distance_to_point(origin_x, origin_y, origin_z, direction_x, direction_y, direction_z,ref_x, ref_y, ref_z){
4
+ // find closest point
5
+ const sp0_x = ref_x - origin_x;
6
+ const sp0_y = ref_y - origin_y;
7
+ const sp0_z = ref_z - origin_z;
8
+
9
+ //
10
+ const d2 = v3_dot(direction_x, direction_y, direction_z, direction_x, direction_y, direction_z);
11
+ const d3 = v3_dot(direction_x, direction_y, direction_z, sp0_x, sp0_y, sp0_z);
12
+
13
+ return d3 / d2;
14
+ }
@@ -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,52 @@
1
+ //
2
+
3
+ import { v3_dot } from "../../v3_dot.js";
4
+ import { ray_distance_to_point } from "../ray/ray_distance_to_point.js";
5
+
6
+ /**
7
+ *
8
+ * @param {number} center_x
9
+ * @param {number} center_y
10
+ * @param {number} center_z
11
+ * @param {number} radius
12
+ * @param {number} origin_x
13
+ * @param {number} origin_y
14
+ * @param {number} origin_z
15
+ * @param {number} direction_x
16
+ * @param {number} direction_y
17
+ * @param {number} direction_z
18
+ * @returns {boolean}
19
+ */
20
+ export function sphere_intersects_ray(
21
+ center_x, center_y, center_z, radius,
22
+ origin_x, origin_y, origin_z,
23
+ direction_x, direction_y, direction_z
24
+ ) {
25
+ const delta_x = center_x - origin_x;
26
+ const delta_y = center_y - origin_y;
27
+ const delta_z = center_z - origin_z;
28
+
29
+ const tca = v3_dot(delta_x, delta_y, delta_z, direction_x, direction_y, direction_z);
30
+ const d2 = v3_dot(delta_x, delta_y, delta_z, delta_x, delta_y, delta_z) - tca * tca;
31
+
32
+ const radius2 = radius * radius;
33
+
34
+ if (d2 > radius2) {
35
+ return false;
36
+ }
37
+
38
+ const thc = Math.sqrt(radius2 - d2);
39
+
40
+ // t0 = first intersect point - entrance on front of sphere
41
+ const t0 = tca - thc;
42
+
43
+ // t1 = second intersect point - exit point on back of sphere
44
+ const t1 = tca + thc;
45
+
46
+ // test to see if both t0 and t1 are behind the ray - if so, no intersection
47
+ if (t0 < 0 && t1 < 0) {
48
+ return false;
49
+ }
50
+
51
+ return true;
52
+ }
@@ -10,6 +10,7 @@ import { vec4 } from "gl-matrix";
10
10
  import { computeTopoMeshBoundiningBox } from "../../../../core/geom/3d/topology/bounds/computeTopoMeshBoundiningBox.js";
11
11
  import { computeTopoMeshBoundingSphere } from "../../../../core/geom/3d/topology/bounds/computeTopoMeshBoundingSphere.js";
12
12
  import { meshopt_optimizeVertexCache } from "../../geometry/optimization/VertexCacheOptimizer.js";
13
+ import { array_copy } from "../../../../core/collection/array/copyArray.js";
13
14
 
14
15
  /**
15
16
  *
@@ -190,15 +191,11 @@ export class PatchRepresentation {
190
191
  return result;
191
192
  }
192
193
 
193
- computeBoundingBox() {
194
+ computeBounds() {
194
195
  computeTopoMeshBoundiningBox(this.bounding_box, this.topology_snapshot);
195
196
  computeTopoMeshBoundingSphere(this.bounding_sphere, this.topology_snapshot);
196
197
  }
197
198
 
198
- computeBounds() {
199
- this.computeBoundingBox();
200
- }
201
-
202
199
  /**
203
200
  * @returns {number}
204
201
  */
@@ -403,11 +400,11 @@ export class PatchRepresentation {
403
400
 
404
401
  this.group_aabb.getCorners(result.group_bounding_box_corners);
405
402
 
406
- vec4.copy(result.group_bounding_sphere, this.group_bounding_sphere);
403
+ array_copy(this.group_bounding_sphere, 0, result.group_bounding_sphere, 0, 4);
407
404
 
408
405
  result.group_error = this.group_error;
409
406
 
410
- vec4.copy(result.bounding_sphere, this.bounding_sphere);
407
+ array_copy(this.bounding_sphere, 0, result.bounding_sphere, 0, 4);
411
408
 
412
409
  result.normal_cone.copy(this.normal_cone);
413
410
 
@@ -134,7 +134,13 @@ async function assemble_graph(nodes) {
134
134
  }
135
135
 
136
136
  // return root
137
- return __nodes[0];
137
+ const root = __nodes[0];
138
+
139
+ //set group bounds to produce a valid root
140
+ root.group_aabb.copy(root.bounding_box);
141
+ root.group_bounding_sphere.set(root.bounding_sphere);
142
+
143
+ return root;
138
144
  }
139
145
 
140
146
 
@@ -477,7 +477,8 @@ async function many_to_many_merge(
477
477
 
478
478
  rep.group_aabb.copy(group_aabb);
479
479
  rep.group_bounding_sphere.set(group_bounding_sphere);
480
- computeTopoMeshBoundiningBox(rep.bounding_box, piece_mesh);
480
+
481
+ rep.computeBounds();
481
482
 
482
483
  rep.group_error = group_per_pixel_error;
483
484
 
@@ -515,10 +516,6 @@ export async function merge_patches(
515
516
  // only 1 patch, no merge opportunity, forward it to output directly
516
517
  const node = nodes[0];
517
518
 
518
- //set group bounds to produce a valid root
519
- node.group_aabb.copy(node.bounding_box);
520
- node.group_bounding_sphere.set(node.bounding_sphere);
521
-
522
519
  output[output_offset.value++] = node;
523
520
  return 1;
524
521
  } else {
@@ -78,6 +78,8 @@ export class MicronGeometry {
78
78
  origin_x, origin_y, origin_z,
79
79
  direction_x, direction_y, direction_z
80
80
  ) {
81
+ let i;
82
+ let stack_cursor = 1;
81
83
 
82
84
  /**
83
85
  *
@@ -86,7 +88,6 @@ export class MicronGeometry {
86
88
  const hits = [];
87
89
 
88
90
  // initialize stack
89
- let stack_cursor = 1;
90
91
  const stack = scratch_traversal_stack;
91
92
  stack[0] = this.root;
92
93
 
@@ -104,16 +105,25 @@ 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
+
110
+ // sphere test
111
+
112
+ // TODO check what's wrong with sphere tests and re-enable them
113
+ // if (!sphere_array_intersects_ray(patch.group_bounding_sphere,
114
+ // origin_x, origin_y, origin_z,
115
+ // direction_x, direction_y, direction_z
116
+ // )) {
117
+ // continue;
118
+ // }
119
+
109
120
 
110
- const bb_intersection_exists = aabb3_array_intersects_ray(
111
- bb,
121
+ // box test (more expensive, different volume)
122
+ if (!aabb3_array_intersects_ray(
123
+ patch.group_bounding_box,
112
124
  origin_x, origin_y, origin_z,
113
125
  direction_x, direction_y, direction_z
114
- );
115
-
116
- if (!bb_intersection_exists) {
126
+ )) {
117
127
  // no intersection
118
128
  continue;
119
129
  }
@@ -122,6 +132,18 @@ export class MicronGeometry {
122
132
  // LOD 0 - source geometry
123
133
 
124
134
  // cast against bounds
135
+
136
+ // sphere test
137
+
138
+ // TODO check what's wrong with sphere tests and re-enable them
139
+ // if (!sphere_array_intersects_ray(patch.bounding_sphere,
140
+ // origin_x, origin_y, origin_z,
141
+ // direction_x, direction_y, direction_z
142
+ // )) {
143
+ // continue;
144
+ // }
145
+
146
+ // box test
125
147
  if (!aabb3_array_intersects_ray(
126
148
  patch.bounding_box,
127
149
  origin_x, origin_y, origin_z,
@@ -136,7 +158,7 @@ export class MicronGeometry {
136
158
 
137
159
  const vertices = patch.vertex_attribute_arrays[position_attribute_index];
138
160
 
139
- for (let i = 0; i < index_count;) {
161
+ for (i = 0; i < index_count;) {
140
162
  const a = indices[i++];
141
163
  const b = indices[i++];
142
164
  const c = indices[i++];
@@ -183,7 +205,7 @@ export class MicronGeometry {
183
205
 
184
206
  const child_count = children.length;
185
207
 
186
- for (let i = 0; i < child_count; i++) {
208
+ for (i = 0; i < child_count; i++) {
187
209
  const child = children[i];
188
210
 
189
211
  // push to stack
@@ -1,7 +1,6 @@
1
1
  import { aabb3_build_corners } from "../../../../../core/geom/3d/aabb/aabb3_build_corners.js";
2
2
  import { DataTypeByteSizes } from "../../../../../core/collection/table/DataTypeByteSizes.js";
3
3
  import { DataType2TypedArrayConstructorMapping } from "../../../../../core/collection/table/DataType2TypedArrayConstructorMapping.js";
4
- import { v3_distance } from "../../../../../core/geom/v3_distance.js";
5
4
 
6
5
  /**
7
6
  *
@@ -19,7 +18,6 @@ export function deserialize_patch(buffer, patch, vertex_spec, patch_array) {
19
18
  buffer.readFloat32Array(gbb, 0, 6);
20
19
  buffer.readFloat32Array(patch.group_bounding_sphere, 0, 4);
21
20
 
22
-
23
21
  patch.group_error = buffer.readFloat32();
24
22
  patch.lod = buffer.readUintVar();
25
23
  patch.polygon_count = buffer.readUintVar();
@@ -92,33 +90,6 @@ export function deserialize_patch(buffer, patch, vertex_spec, patch_array) {
92
90
  patch.vertex_attribute_arrays[i] = array;
93
91
  }
94
92
 
95
-
96
- // validate and fix group bounds as necessary
97
- if (
98
- patch.group_bounding_box[0] > patch.bounding_box[0] // x0
99
- || patch.group_bounding_box[1] > patch.bounding_box[1] // y0
100
- || patch.group_bounding_box[2] > patch.bounding_box[2] // x0
101
- || patch.group_bounding_box[3] < patch.bounding_box[3] // x1
102
- || patch.group_bounding_box[4] < patch.bounding_box[4] // y1
103
- || patch.group_bounding_box[5] < patch.bounding_box[5] // z1
104
- ) {
105
- // bounds are violated, fix
106
- patch.group_bounding_box.set(patch.bounding_box);
107
- }
108
-
109
- if (v3_distance(
110
- patch.group_bounding_sphere[0],
111
- patch.group_bounding_sphere[1],
112
- patch.group_bounding_sphere[2],
113
- patch.bounding_sphere[0],
114
- patch.bounding_sphere[1],
115
- patch.bounding_sphere[2]
116
- ) + patch.bounding_sphere[3] > patch.group_bounding_sphere[3]) {
117
- // group's sphere bounds are violated, fix
118
- patch.group_bounding_sphere.set(patch.bounding_sphere);
119
- }
120
-
121
-
122
93
  // reconstruct corners
123
94
  aabb3_build_corners(
124
95
  patch.group_bounding_box_corners,
@@ -455,7 +455,7 @@ function init() {
455
455
  }
456
456
 
457
457
  // sample_gltf_sponza();
458
- // sample_gltf_rts_factory();
458
+ gltf_sample('data/models/RTS_Buildings_Humans/18/Building_R_18_out/Building_R_18.gltf');
459
459
  // sample_lucy();
460
460
  // sample_gltf_hapro_2();
461
461
  // sample_gltf_hapro_1();
@@ -467,7 +467,7 @@ function init() {
467
467
  // gltf_sample('data/models/moicon/isiflow_Oct_15_21/0/model.gltf');
468
468
  // gltf_sample('moicon/29_Dec_2021_Nammo/1/model.gltf');
469
469
  // gltf_sample('moicon/29_Dec_2021_Nammo/1-onematerial/model.gltf');
470
- gltf_sample('moicon/29_Dec_2021_Nammo/2/model.gltf');
470
+ // gltf_sample('moicon/29_Dec_2021_Nammo/2/model.gltf');
471
471
 
472
472
  document.addEventListener("mousemove", onDocumentMouseMove);
473
473
 
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.27",
9
9
  "dependencies": {
10
10
  "gl-matrix": "3.4.3",
11
11
  "fast-levenshtein": "2.0.6",