@woosh/meep-engine 2.34.25 → 2.34.29

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,18 @@
1
+ //
2
+
3
+ /**
4
+ *
5
+ * @param {ArrayLike<number>|number[]} aabb
6
+ * @param {number} x
7
+ * @param {number} y
8
+ * @param {number} z
9
+ * @return {boolean}
10
+ */
11
+ export function aabb3_array_contains_point(aabb, x, y, z) {
12
+ return x >= aabb[0]
13
+ && x <= aabb[3]
14
+ && y >= aabb[1]
15
+ && y <= aabb[4]
16
+ && z >= aabb[2]
17
+ && z <= aabb[5];
18
+ }
@@ -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
+ }
@@ -0,0 +1,15 @@
1
+ import { sphereIntersectsPoint } from "./sphereIntersectsPoint.js";
2
+
3
+ //
4
+
5
+ /**
6
+ *
7
+ * @param {ArrayLike<number>|number[]} sphere
8
+ * @param {number} x
9
+ * @param {number} y
10
+ * @param {number} z
11
+ * @return {boolean}
12
+ */
13
+ export function sphere_array_intersects_point(sphere, x, y, z) {
14
+ return sphereIntersectsPoint(sphere[0], sphere[1], sphere[2], sphere[3], x, y, z);
15
+ }
@@ -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
  *
@@ -30,6 +31,10 @@ export class PatchRepresentation {
30
31
  Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY
31
32
  );
32
33
 
34
+ /**
35
+ *
36
+ * @type {AABB3}
37
+ */
33
38
  this.group_aabb = new AABB3(0, 0, 0, 0, 0, 0);
34
39
 
35
40
  /**
@@ -399,11 +404,11 @@ export class PatchRepresentation {
399
404
 
400
405
  this.group_aabb.getCorners(result.group_bounding_box_corners);
401
406
 
402
- vec4.copy(result.group_bounding_sphere, this.group_bounding_sphere);
407
+ array_copy(this.group_bounding_sphere, 0, result.group_bounding_sphere, 0, 4);
403
408
 
404
409
  result.group_error = this.group_error;
405
410
 
406
- vec4.copy(result.bounding_sphere, this.bounding_sphere);
411
+ array_copy(this.bounding_sphere, 0, result.bounding_sphere, 0, 4);
407
412
 
408
413
  result.normal_cone.copy(this.normal_cone);
409
414
 
@@ -202,6 +202,11 @@ export async function buildMicronGeometryFromBufferGeometry(input) {
202
202
 
203
203
 
204
204
  const t_build_hierarchy_start = current_time_millis();
205
+
206
+ /**
207
+ *
208
+ * @type {PatchRepresentation}
209
+ */
205
210
  const root = await buildAbstractPatchHierarchy(patches);
206
211
 
207
212
  if (PRINT_VERBOSE_STATS) {
@@ -48,13 +48,15 @@ async function assemble_graph(nodes) {
48
48
  */
49
49
  let __nodes = nodes.slice();
50
50
 
51
+ const initial_node_count = __nodes.length;
52
+
51
53
  /**
52
54
  *
53
55
  * @type {{value: number}}
54
56
  * @private
55
57
  */
56
58
  const __node_count = {
57
- value: __nodes.length
59
+ value: initial_node_count
58
60
  };
59
61
 
60
62
  let level = 0;
@@ -136,9 +138,12 @@ async function assemble_graph(nodes) {
136
138
  // return root
137
139
  const root = __nodes[0];
138
140
 
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);
141
+ if (initial_node_count === 1) {
142
+ // there are no children, whole hierarchy is just one node, set group bounds to equal node bounds
143
+ root.group_bounding_sphere.set(root.bounding_sphere);
144
+ root.group_aabb.copy(root.bounding_box);
145
+ }
146
+
142
147
 
143
148
  return root;
144
149
  }
@@ -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
 
@@ -1,6 +1,7 @@
1
1
  import {BufferGeometry} from "three";
2
2
  import {VertexDataSpec} from "../../geometry/VertexDataSpec";
3
3
  import {SurfacePoint3} from "../../../../core/geom/3d/SurfacePoint3";
4
+ import {MicronGeometryPatch} from "./MicronGeometryPatch";
4
5
 
5
6
  export class MicronGeometry {
6
7
  vertex_spec: VertexDataSpec
@@ -14,4 +15,6 @@ export class MicronGeometry {
14
15
  ): SurfacePoint3[]
15
16
 
16
17
  readonly isMicronGeometry: boolean
18
+
19
+ readonly patches: MicronGeometryPatch[]
17
20
  }
@@ -3,7 +3,6 @@ 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";
7
6
 
8
7
  let id_counter = 0;
9
8
 
@@ -109,12 +108,14 @@ export class MicronGeometry {
109
108
  // using group bounds because it's conservative, as we want to be able to hit LOD_0
110
109
 
111
110
  // sphere test
112
- if (!sphere_array_intersects_ray(patch.group_bounding_sphere,
113
- origin_x, origin_y, origin_z,
114
- direction_x, direction_y, direction_z
115
- )) {
116
- continue;
117
- }
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
+ // }
118
119
 
119
120
 
120
121
  // box test (more expensive, different volume)
@@ -133,12 +134,14 @@ export class MicronGeometry {
133
134
  // cast against bounds
134
135
 
135
136
  // sphere test
136
- if (!sphere_array_intersects_ray(patch.bounding_sphere,
137
- origin_x, origin_y, origin_z,
138
- direction_x, direction_y, direction_z
139
- )) {
140
- continue;
141
- }
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
+ // }
142
145
 
143
146
  // box test
144
147
  if (!aabb3_array_intersects_ray(
@@ -155,7 +158,7 @@ export class MicronGeometry {
155
158
 
156
159
  const vertices = patch.vertex_attribute_arrays[position_attribute_index];
157
160
 
158
- for ( i = 0; i < index_count;) {
161
+ for (i = 0; i < index_count;) {
159
162
  const a = indices[i++];
160
163
  const b = indices[i++];
161
164
  const c = indices[i++];
@@ -202,7 +205,7 @@ export class MicronGeometry {
202
205
 
203
206
  const child_count = children.length;
204
207
 
205
- for ( i = 0; i < child_count; i++) {
208
+ for (i = 0; i < child_count; i++) {
206
209
  const child = children[i];
207
210
 
208
211
  // push to stack
@@ -0,0 +1,3 @@
1
+ export class MicronGeometryPatch {
2
+
3
+ }
@@ -0,0 +1,63 @@
1
+ import { MicronGeometryPatch } from "../MicronGeometryPatch.js";
2
+ import { BinaryBuffer } from "../../../../../core/binary/BinaryBuffer.js";
3
+ import { MicronGeometry } from "../MicronGeometry.js";
4
+ import { VertexDataSpec } from "../../../geometry/VertexDataSpec.js";
5
+ import { AttributeSpec } from "../../../geometry/AttributeSpec.js";
6
+ import { DataType } from "../../../../../core/collection/table/DataType.js";
7
+ import { MicronGeometryBinarySerializationAdapter } from "./MicronGeometryBinarySerializationAdapter.js";
8
+
9
+ function sampleGeometry() {
10
+ const a = new MicronGeometryPatch();
11
+
12
+ a.vertex_attribute_arrays[0] = new Uint8Array([
13
+ 7, 11, 13,
14
+ 17, 23, 29,
15
+ 31, 39, 43
16
+ ]);
17
+ a.vertex_count = 3;
18
+
19
+ a.face_indices = new Uint8Array([1, 2, 3]);
20
+ a.polygon_count = 1;
21
+
22
+ a.group_error = 1.234;
23
+
24
+ a.bounding_box.set([7, 11, 13, 31, 39, 43]);
25
+ a.group_bounding_box.set([7, 11, 13, 31, 39, 43]);
26
+ a.bounding_sphere.set([19, 25, 28, 50.1]);
27
+ a.group_bounding_sphere.set([19, 25, 28, 50.1]);
28
+
29
+ const g_a = new MicronGeometry();
30
+
31
+ const vertex_spec = new VertexDataSpec();
32
+ vertex_spec.add(AttributeSpec.fromJSON({
33
+ name: 'position',
34
+ type: DataType.Uint8,
35
+ itemSize: 3,
36
+ normalized: false
37
+ }));
38
+
39
+ g_a.vertex_spec = vertex_spec;
40
+ g_a.root = a;
41
+ g_a.initialize();
42
+
43
+ return g_a;
44
+ }
45
+
46
+ test("serialization/deserialization consistency", () => {
47
+ const g_a = sampleGeometry();
48
+
49
+ const buffer = new BinaryBuffer();
50
+
51
+ const adapter = new MicronGeometryBinarySerializationAdapter();
52
+
53
+ adapter.serialize(buffer, g_a);
54
+
55
+
56
+ const g_b = new MicronGeometry();
57
+
58
+ buffer.position = 0;
59
+ adapter.deserialize(buffer, g_b);
60
+
61
+ expect(g_b.vertex_spec.equals(g_a.vertex_spec)).toBe(true);
62
+ expect(g_b.patches.length).toEqual(g_a.patches.length);
63
+ });
@@ -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,
@@ -0,0 +1,69 @@
1
+ import { noop } from "../../../../core/function/Functions.js";
2
+ import { aabb3_array_contains_point } from "../../../../core/bvh2/aabb3/aabb3_array_contains_point.js";
3
+ import { sphere_array_intersects_point } from "../../../../core/geom/3d/sphere/sphere_array_intersects_point.js";
4
+
5
+ /**
6
+ *
7
+ * @param {MicronGeometryPatch} patch
8
+ * @param {VertexDataSpec} vertex_spec
9
+ * @param {function(string)} [error_consumer]
10
+ * @returns {boolean}
11
+ */
12
+ export function validate_patch_bounds(patch, vertex_spec, error_consumer = noop) {
13
+ const position_attribute_index = vertex_spec.getAttributeIndexByName('position');
14
+
15
+ if (position_attribute_index === -1) {
16
+ error_consumer(`No 'position' attribute found`);
17
+ // technically any bounds are valid if there is no position
18
+ return true;
19
+ }
20
+
21
+ const position_data = patch.vertex_attribute_arrays[position_attribute_index];
22
+
23
+ let b_sphere_valid = true;
24
+ let b_box_valid = true;
25
+ let gb_sphere_valid = true;
26
+ let gb_box_valid = true;
27
+
28
+ for (let i = 0; i < this.vertex_count; i++) {
29
+ const i3 = i * 3;
30
+
31
+ const x = position_data[i3];
32
+ const y = position_data[i3 + 1];
33
+ const z = position_data[i3 + 2];
34
+
35
+ if (!aabb3_array_contains_point(patch.bounding_box, x, y, z)) {
36
+ b_box_valid = false;
37
+ }
38
+
39
+ if (!aabb3_array_contains_point(patch.group_bounding_box, x, y, z)) {
40
+ gb_box_valid = false;
41
+ }
42
+
43
+ if (!sphere_array_intersects_point(patch.bounding_sphere, x, y, z)) {
44
+ b_sphere_valid = false;
45
+ }
46
+
47
+ if (!sphere_array_intersects_point(patch.group_bounding_sphere, x, y, z)) {
48
+ gb_sphere_valid = false;
49
+ }
50
+ }
51
+
52
+ if (!b_sphere_valid) {
53
+ error_consumer('.bounding_sphere is violated');
54
+ }
55
+
56
+ if (!gb_sphere_valid) {
57
+ error_consumer('.group_bounding_sphere is violated');
58
+ }
59
+
60
+ if (!b_box_valid) {
61
+ error_consumer('.bounding_box is violated');
62
+ }
63
+
64
+ if (!gb_box_valid) {
65
+ error_consumer('.group_bounding_box is violated');
66
+ }
67
+
68
+ return b_sphere_valid && gb_sphere_valid && b_box_valid && gb_box_valid;
69
+ }
@@ -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.25",
8
+ "version": "2.34.29",
9
9
  "dependencies": {
10
10
  "gl-matrix": "3.4.3",
11
11
  "fast-levenshtein": "2.0.6",