@woosh/meep-engine 2.35.15 → 2.36.0

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.
Files changed (81) hide show
  1. package/core/binary/BinaryBuffer.js +42 -17
  2. package/core/bvh2/BinaryNode.js +1 -1
  3. package/core/bvh2/aabb3/AABB3.js +2 -2
  4. package/core/bvh2/aabb3/aabb3_array_combine.js +20 -0
  5. package/core/bvh2/aabb3/aabb3_array_intersects_frustum_array.js +20 -0
  6. package/core/bvh2/aabb3/aabb3_array_intersects_ray.js +1 -0
  7. package/core/bvh2/aabb3/aabb3_array_intersects_ray_array.js +14 -0
  8. package/core/bvh2/{aabb3_combined_surface_area.js → aabb3/aabb3_combined_surface_area.js} +3 -3
  9. package/core/bvh2/aabb3/aabb3_intersects_frustum_array.js +1 -19
  10. package/core/bvh2/bvh3/BVHNodeProxy.js +53 -0
  11. package/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +848 -0
  12. package/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.spec.js +142 -0
  13. package/core/bvh2/bvh3/bvh_query_leaves_generic.js +79 -0
  14. package/core/bvh2/bvh3/bvh_query_leaves_ray.js +95 -0
  15. package/core/bvh2/bvh3/query/BVHQuery.js +11 -0
  16. package/core/bvh2/bvh3/query/BVHQueryIntersectsFrustum.js +36 -0
  17. package/core/bvh2/bvh3/query/BVHQueryIntersectsRay.js +36 -0
  18. package/core/collection/array/copyArray.js +2 -2
  19. package/core/collection/array/typed/uint_array_for_count.js +17 -0
  20. package/core/collection/table/RowFirstTable.js +25 -7
  21. package/core/collection/table/RowFirstTableSpec.js +4 -4
  22. package/core/geom/3d/aabb/aabb3_matrix4_project.spec.js +1 -1
  23. package/{engine/graphics/util → core/geom/3d/aabb}/computeBoundingBoxFromVertexData.js +1 -1
  24. package/core/geom/3d/compose_matrix4_array.js +53 -0
  25. package/{engine/graphics/util → core/geom/3d}/decompose_matrix_4_array.js +0 -0
  26. package/core/geom/Vector1.js +2 -3
  27. package/engine/asset/loaders/GLTFAssetLoader.js +3 -0
  28. package/engine/asset/loaders/gltf/GLTFAssetTransformMikkTSpaceTangents.js +27 -0
  29. package/engine/ecs/EntityComponentDataset.js +7 -4
  30. package/engine/ecs/foliage/InstancedFoliage.js +1 -1
  31. package/engine/ecs/foliage/ViewState.js +1 -1
  32. package/engine/ecs/transform/Transform.js +2 -2
  33. package/engine/graphics/ecs/mesh-v2/ShadedGeometry.d.ts +5 -0
  34. package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +46 -12
  35. package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +81 -95
  36. package/engine/graphics/ecs/mesh-v2/render/ShadedGeometryRendererContext.js +16 -5
  37. package/engine/graphics/ecs/mesh-v2/sample/load_gltf.js +1 -0
  38. package/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +3 -4
  39. package/engine/graphics/ecs/path/PathDisplaySystem.js +2 -1
  40. package/engine/graphics/ecs/path/testPathDisplaySystem.js +8 -8
  41. package/engine/graphics/ecs/path/tube/CapType.d.ts +5 -0
  42. package/engine/graphics/ecs/path/tube/CapType.js +9 -0
  43. package/engine/graphics/ecs/path/tube/TubePathStyle.d.ts +2 -0
  44. package/engine/graphics/ecs/path/tube/TubePathStyle.js +10 -1
  45. package/engine/graphics/ecs/path/tube/build/GeometryOutput.js +90 -0
  46. package/engine/graphics/ecs/path/tube/build/build_geometry_catmullrom.js +3 -2
  47. package/engine/graphics/ecs/path/tube/build/build_geometry_linear.js +1 -1
  48. package/engine/graphics/ecs/path/tube/build/computeFrenetFrames.js +1 -2
  49. package/engine/graphics/ecs/path/tube/build/makeTubeGeometry.js +353 -91
  50. package/engine/graphics/ecs/path/tube/prototypeAnimatedPathMask.js +390 -0
  51. package/engine/graphics/geometry/MikkT/MikkTSpace.js +2210 -0
  52. package/engine/graphics/geometry/MikkT/MikkTSpace.spec.js +22 -0
  53. package/engine/graphics/geometry/MikkT/buffer_geometry_ensure_tangents.js +34 -0
  54. package/engine/graphics/geometry/MikkT/buffer_geometry_generate_tangents.js +28 -0
  55. package/engine/graphics/{compute_geometry_polycount.js → geometry/compute_geometry_polycount.js} +0 -0
  56. package/engine/graphics/geometry/skining/computeSkinnedMeshBoundingVolumes.js +1 -1
  57. package/engine/graphics/micron/build/fill_patch_geometry_data.js +1 -18
  58. package/engine/graphics/micron/format/MicronGeometry.js +7 -4
  59. package/engine/graphics/micron/format/micron_build_proxy_geometry.js +203 -0
  60. package/engine/graphics/micron/format/serialization/collection/geometry_collection_serialization.js +83 -0
  61. package/engine/graphics/micron/plugin/GLTFAssetTransformer.js +63 -19
  62. package/engine/graphics/micron/plugin/GLTF_MICRON_ID_FIELD.js +5 -0
  63. package/engine/graphics/micron/plugin/MicronRenderPlugin.js +0 -4
  64. package/engine/graphics/micron/prototypeMicronProxyBuild.js +227 -0
  65. package/engine/graphics/micron/render/refinement/ActivePatchList.js +2 -2
  66. package/engine/graphics/micron/render/refinement/get_geometry_patch_cut.js +2 -2
  67. package/engine/graphics/render/forward_plus/LightManager.js +5 -5
  68. package/engine/graphics/render/forward_plus/data/channelCountToThreIntegerTextureType.js +3 -3
  69. package/engine/graphics/texture/channelCountToThreeTextureFormat.js +2 -2
  70. package/engine/graphics/util/composeMatrix4.js +1 -53
  71. package/engine/graphics/util/composeMatrix4RotationScale.js +1 -1
  72. package/engine/intelligence/behavior/ecs/BehaviorComponent.js +1 -1
  73. package/engine/intelligence/blackboard/AbstractBlackboard.js +9 -0
  74. package/engine/navigation/grid/FastBinaryHeap.js +13 -2
  75. package/engine/notify/Notification.js +1 -1
  76. package/engine/ui/notification/ViewEmitter.js +7 -1
  77. package/engine/ui/notification/notificationGenerator.js +1 -1
  78. package/engine/ui/scene/SceneGUIContext.js +11 -130
  79. package/engine/ui/scene/initializeNotifications.js +141 -0
  80. package/package.json +1 -1
  81. package/view/elements/notify/NotificationView.js +1 -2
@@ -0,0 +1,142 @@
1
+ import { ExplicitBinaryBoundingVolumeHierarchy, NULL_NODE } from "./ExplicitBinaryBoundingVolumeHierarchy.js";
2
+
3
+ test("constructor doesn't throw", () => {
4
+ expect(() => new ExplicitBinaryBoundingVolumeHierarchy()).not.toThrow();
5
+ });
6
+
7
+ test("initial root is NULL", () => {
8
+ const bvh = new ExplicitBinaryBoundingVolumeHierarchy();
9
+
10
+ expect(bvh.root).toBe(NULL_NODE);
11
+ });
12
+
13
+ test("allocate a node", () => {
14
+ const bvh = new ExplicitBinaryBoundingVolumeHierarchy();
15
+
16
+ const id = bvh.allocate_node();
17
+
18
+ expect(typeof id).toBe("number");
19
+ expect(Number.isInteger(id)).toBe(true);
20
+ expect(id).toBeGreaterThanOrEqual(0);
21
+ });
22
+
23
+ test("set/get aabb", () => {
24
+ const bvh = new ExplicitBinaryBoundingVolumeHierarchy();
25
+
26
+ const node = bvh.allocate_node();
27
+
28
+ bvh.node_set_aabb(node, [1, -2, 3, -5, 7, 11]);
29
+
30
+ const result = [];
31
+
32
+ bvh.node_get_aabb(node, result);
33
+
34
+ expect(result).toEqual([
35
+ 1, -2, 3, -5, 7, 11
36
+ ]);
37
+ });
38
+
39
+ test("insert one leaf", () => {
40
+ const bvh = new ExplicitBinaryBoundingVolumeHierarchy();
41
+
42
+ const node = bvh.allocate_node();
43
+
44
+ bvh.insert_leaf(node);
45
+
46
+ expect(bvh.root).toBe(node);
47
+ });
48
+
49
+ test("node reuse after de-allocation", () => {
50
+
51
+ const bvh = new ExplicitBinaryBoundingVolumeHierarchy();
52
+
53
+ const a = bvh.allocate_node();
54
+
55
+ bvh.release_node(a);
56
+
57
+ const b = bvh.allocate_node();
58
+
59
+ expect(b).toEqual(a);
60
+ });
61
+
62
+ test("insert two leaves", () => {
63
+
64
+ const bvh = new ExplicitBinaryBoundingVolumeHierarchy();
65
+
66
+ const a = bvh.allocate_node();
67
+ bvh.insert_leaf(a);
68
+
69
+ const b = bvh.allocate_node();
70
+ bvh.insert_leaf(b);
71
+
72
+ const nodes = [];
73
+ bvh.collect_nodes_all(nodes, 0);
74
+
75
+ expect(nodes).toContain(a);
76
+ expect(nodes).toContain(b);
77
+ });
78
+
79
+
80
+ test("set/get user data", () => {
81
+
82
+ const bvh = new ExplicitBinaryBoundingVolumeHierarchy();
83
+
84
+ const a = bvh.allocate_node();
85
+
86
+ bvh.node_set_user_data(a, 42);
87
+
88
+ expect(bvh.node_get_user_data(a)).toBe(42);
89
+ });
90
+
91
+ test("remove single leaf", () => {
92
+ const bvh = new ExplicitBinaryBoundingVolumeHierarchy();
93
+
94
+ const a = bvh.allocate_node();
95
+ bvh.insert_leaf(a);
96
+
97
+ bvh.remove_leaf(a);
98
+
99
+ const nodes = [];
100
+ bvh.collect_nodes_all(nodes, 0);
101
+
102
+ expect(nodes).not.toContain(a);
103
+ });
104
+
105
+ test("add and remove 5 nodes", () => {
106
+
107
+ const bvh = new ExplicitBinaryBoundingVolumeHierarchy();
108
+
109
+ const leaves = [];
110
+ const removed_leaves = [];
111
+
112
+ for (let i = 0; i < 5; i++) {
113
+ const a = bvh.allocate_node();
114
+ bvh.insert_leaf(a);
115
+
116
+ leaves.push(a);
117
+ }
118
+
119
+ while (leaves.length > 0) {
120
+ const nodes = [];
121
+ bvh.collect_nodes_all(nodes, 0);
122
+
123
+ for (let j = 0; j < leaves.length; j++) {
124
+ const leaf = leaves[j];
125
+ expect(nodes).toContain(leaf);
126
+ }
127
+
128
+ const leaf = leaves.shift();
129
+
130
+ bvh.remove_leaf(leaf);
131
+
132
+ removed_leaves.push(leaf);
133
+
134
+ }
135
+
136
+ const nodes = [];
137
+ bvh.collect_nodes_all(nodes, 0);
138
+ for (let i = 0; i < removed_leaves.length; i++) {
139
+ expect(nodes).not.toContain(removed_leaves[i]);
140
+ }
141
+
142
+ });
@@ -0,0 +1,79 @@
1
+ import { NULL_NODE } from "./ExplicitBinaryBoundingVolumeHierarchy.js";
2
+
3
+ /**
4
+ *
5
+ * @type {number[]}
6
+ */
7
+ const traversal_stack = [];
8
+
9
+ /**
10
+ *
11
+ * @type {number}
12
+ */
13
+ let traversal_cursor = 0;
14
+
15
+
16
+ /**
17
+ *
18
+ * @param {ExplicitBinaryBoundingVolumeHierarchy} bvh
19
+ * @param {number[]} result
20
+ * @param {number} result_offset
21
+ * @param {BVHQuery} query
22
+ * @returns {number}
23
+ */
24
+ export function bvh_query_leaves_generic(
25
+ result, result_offset,
26
+ bvh, query
27
+ ) {
28
+ const stack_frame_address = traversal_cursor;
29
+
30
+ const root = bvh.root;
31
+
32
+ if (root === NULL_NODE) {
33
+ return 0;
34
+ }
35
+
36
+ traversal_stack[traversal_cursor++] = root;
37
+
38
+ let result_cursor = result_offset;
39
+
40
+ while (traversal_cursor > stack_frame_address) {
41
+ traversal_cursor--;
42
+
43
+ /**
44
+ *
45
+ * @type {number}
46
+ */
47
+ const node = traversal_stack[traversal_cursor];
48
+
49
+ // test node against the ray
50
+ const pass = query.evaluate(node, bvh);
51
+
52
+ if (!pass) {
53
+ continue;
54
+ }
55
+
56
+ const node_is_leaf = bvh.node_is_leaf(node);
57
+
58
+ if (!node_is_leaf) {
59
+
60
+ // read in-order
61
+ const child1 = bvh.node_get_child1(node);
62
+ const child2 = bvh.node_get_child2(node);
63
+
64
+ // write to stack in reverse order, so that fist child ends up being visited first
65
+ traversal_stack[traversal_cursor++] = child2;
66
+ traversal_stack[traversal_cursor++] = child1;
67
+
68
+ } else {
69
+ // leaf node
70
+
71
+ result[result_cursor++] = node;
72
+ }
73
+ }
74
+
75
+ // drop stack frame
76
+ traversal_cursor = stack_frame_address;
77
+
78
+ return result_cursor - result_offset;
79
+ }
@@ -0,0 +1,95 @@
1
+ import { aabb3_intersects_ray } from "../aabb3/aabb3_intersects_ray.js";
2
+ import { NULL_NODE } from "./ExplicitBinaryBoundingVolumeHierarchy.js";
3
+
4
+ /**
5
+ *
6
+ * @type {number[]}
7
+ */
8
+ const traversal_stack = [];
9
+
10
+ /**
11
+ *
12
+ * @type {number[]}
13
+ */
14
+ const scratch_aabb = [];
15
+
16
+ /**
17
+ *
18
+ * @type {number}
19
+ */
20
+ let traversal_cursor = 0;
21
+
22
+
23
+ /**
24
+ *
25
+ * @param {ExplicitBinaryBoundingVolumeHierarchy} bvh
26
+ * @param {number[]} result
27
+ * @param {number} result_offset
28
+ * @param {number} origin_x
29
+ * @param {number} origin_y
30
+ * @param {number} origin_z
31
+ * @param {number} direction_x
32
+ * @param {number} direction_y
33
+ * @param {number} direction_z
34
+ * @returns {number}
35
+ */
36
+ export function bvh_query_leaves_ray(
37
+ bvh,
38
+ result, result_offset,
39
+ origin_x, origin_y, origin_z,
40
+ direction_x, direction_y, direction_z
41
+ ) {
42
+ const stack_frame_address = traversal_cursor;
43
+
44
+ const root = bvh.root;
45
+
46
+ if (root === NULL_NODE) {
47
+ return 0;
48
+ }
49
+
50
+ traversal_stack[traversal_cursor++] = root;
51
+
52
+ let result_cursor = result_offset;
53
+
54
+ while (traversal_cursor > stack_frame_address) {
55
+ traversal_cursor--;
56
+
57
+ /**
58
+ *
59
+ * @type {number}
60
+ */
61
+ const node = traversal_stack[traversal_cursor];
62
+
63
+ bvh.node_get_aabb(node, scratch_aabb);
64
+
65
+ // test node against the ray
66
+ const intersects = aabb3_intersects_ray(
67
+ scratch_aabb[0], scratch_aabb[1], scratch_aabb[2],
68
+ scratch_aabb[3], scratch_aabb[4], scratch_aabb[5],
69
+ origin_x, origin_y, origin_z,
70
+ direction_x, direction_y, direction_z
71
+ );
72
+
73
+ if (!intersects) {
74
+ continue;
75
+ }
76
+
77
+ const node_is_leaf = bvh.node_is_leaf(node);
78
+
79
+ if (!node_is_leaf) {
80
+
81
+ traversal_stack[traversal_cursor++] = bvh.node_get_child1(node);
82
+ traversal_stack[traversal_cursor++] = bvh.node_get_child2(node);
83
+
84
+ } else {
85
+ // leaf node
86
+
87
+ result[result_cursor++] = node;
88
+ }
89
+ }
90
+
91
+ // drop stack frame
92
+ traversal_cursor = stack_frame_address;
93
+
94
+ return result_cursor - result_offset;
95
+ }
@@ -0,0 +1,11 @@
1
+ export class BVHQuery {
2
+ /**
3
+ *
4
+ * @param {number} node
5
+ * @param {ExplicitBinaryBoundingVolumeHierarchy} tree
6
+ * @returns {boolean}
7
+ */
8
+ evaluate(node, tree) {
9
+ throw new Error('Not Implemented');
10
+ }
11
+ }
@@ -0,0 +1,36 @@
1
+ import { BVHQuery } from "./BVHQuery.js";
2
+ import { aabb3_array_intersects_frustum_array } from "../../aabb3/aabb3_array_intersects_frustum_array.js";
3
+
4
+ const scratch_aabb = [];
5
+
6
+ export class BVHQueryIntersectsFrustum extends BVHQuery {
7
+ constructor() {
8
+ super();
9
+
10
+ /**
11
+ * Collection of 6 planes: normal_x, normal_y, normal_z, offset
12
+ * @type {number[]}
13
+ */
14
+ this.frustum = [];
15
+ }
16
+
17
+ /**
18
+ *
19
+ * @param {number[]|ArrayLike<number>|Float32Array} frustum
20
+ * @returns {BVHQueryIntersectsFrustum}
21
+ */
22
+ static from(frustum) {
23
+ const r = new BVHQueryIntersectsFrustum();
24
+
25
+ r.frustum = frustum;
26
+
27
+ return r;
28
+ }
29
+
30
+ evaluate(node, tree) {
31
+
32
+ tree.node_get_aabb(node, scratch_aabb);
33
+
34
+ return aabb3_array_intersects_frustum_array(scratch_aabb, this.frustum);
35
+ }
36
+ }
@@ -0,0 +1,36 @@
1
+ import { BVHQuery } from "./BVHQuery.js";
2
+ import { aabb3_array_intersects_ray_array } from "../../aabb3/aabb3_array_intersects_ray_array.js";
3
+
4
+ const scratch_aabb = [];
5
+
6
+ export class BVHQueryIntersectsRay extends BVHQuery {
7
+ constructor() {
8
+ super();
9
+
10
+ this.ray = [];
11
+ }
12
+
13
+ /**
14
+ *
15
+ * @param {number[]|ArrayLike<number>} ray
16
+ * @returns {BVHQueryIntersectsRay}
17
+ */
18
+ static from(ray){
19
+ const r = new BVHQueryIntersectsRay();
20
+
21
+ r.ray = ray;
22
+
23
+ return r;
24
+ }
25
+
26
+ evaluate(node, tree) {
27
+
28
+ tree.node_get_aabb(node, scratch_aabb);
29
+
30
+ // test node against the ray
31
+ return aabb3_array_intersects_ray_array(
32
+ scratch_aabb,
33
+ this.ray
34
+ );
35
+ }
36
+ }
@@ -25,9 +25,9 @@ export function copyArray(source, target) {
25
25
  * Follows Java System.arraycopy interface
26
26
  * Copy data from one array to another
27
27
  * @template T
28
- * @param {T[]|ArrayLike<T>|TypedArray|Uint8ClampedArray|Uint8Array|Float32Array|Float64Array} source The source array
28
+ * @param {T[]|ArrayLike<T>|TypedArray|Uint8ClampedArray|Uint8Array|Uint32Array|Int32Array|Float32Array|Float64Array} source The source array
29
29
  * @param {number} source_position Starting position where to copy from inside the source array
30
- * @param {T[]|ArrayLike<T>|TypedArray|Uint8ClampedArray|Uint8Array|Float32Array|Float64Array} destination The destination array
30
+ * @param {T[]|ArrayLike<T>|TypedArray|Uint8ClampedArray|Uint8Array|Uint32Array|Int32Array|Float32Array|Float64Array} destination The destination array
31
31
  * @param {number} destination_position Starting position where to copy to inside the destination array
32
32
  * @param {number} length How many elements should be copied
33
33
  */
@@ -0,0 +1,17 @@
1
+ /**
2
+ *
3
+ * @param {number} count
4
+ * @returns {function}
5
+ */
6
+ export function UintArrayForCount(count) {
7
+
8
+ if (count <= 256) {
9
+ return Uint8Array;
10
+ } else if (count <= 65536) {
11
+ return Uint16Array;
12
+ } else if (count <= 4294967295) {
13
+ return Uint32Array;
14
+ } else {
15
+ throw new Error(`Unsupported size ${count}`)
16
+ }
17
+ }
@@ -75,7 +75,16 @@ RowFirstTable.prototype.initialize = function () {
75
75
  this.types = spec.types;
76
76
  this.bytesPerRecord = spec.bytesPerRecord;
77
77
 
78
+ /**
79
+ *
80
+ * @type {function(DataView, number, number[]): void}
81
+ */
78
82
  this.readRowMethod = spec.readRowMethod;
83
+
84
+ /**
85
+ *
86
+ * @type {function(DataView, number, number[]): void}
87
+ */
79
88
  this.writeRowMethod = spec.writeRowMethod;
80
89
  };
81
90
 
@@ -180,12 +189,12 @@ RowFirstTable.prototype.resize = function (rowCount) {
180
189
  * @param {number} value
181
190
  */
182
191
  RowFirstTable.prototype.writeCellValue = function (rowIndex, columnIndex, value) {
183
- const spec = this.spec;
184
-
185
192
  const bytesPerRecord = this.bytesPerRecord;
186
193
 
187
194
  const rowAddress = rowIndex * bytesPerRecord;
188
195
 
196
+ const spec = this.spec;
197
+
189
198
  const cellWriters = spec.cellWriters;
190
199
 
191
200
  const cellWriter = cellWriters[columnIndex];
@@ -200,12 +209,12 @@ RowFirstTable.prototype.writeCellValue = function (rowIndex, columnIndex, value)
200
209
  * @returns {number}
201
210
  */
202
211
  RowFirstTable.prototype.readCellValue = function (rowIndex, columnIndex) {
203
- const spec = this.spec;
204
-
205
212
  const bytesPerRecord = this.bytesPerRecord;
206
213
 
207
214
  const rowAddress = rowIndex * bytesPerRecord;
208
215
 
216
+ const spec = this.spec;
217
+
209
218
  const cellReaders = spec.cellReaders;
210
219
 
211
220
  const cellReader = cellReaders[columnIndex];
@@ -225,14 +234,14 @@ RowFirstTable.prototype.removeRows = function (index, rowCount) {
225
234
 
226
235
  const data = this.data;
227
236
 
228
- const bytesPerRecord = this.bytesPerRecord;
229
-
230
237
  const array = new Uint8Array(data);
231
238
 
239
+ const bytesPerRecord = this.bytesPerRecord;
240
+
232
241
  //shift tail of the table forward
233
242
  const target = index * bytesPerRecord;
234
- const end = this.length * bytesPerRecord;
235
243
  const start = target + rowCount * bytesPerRecord;
244
+ const end = this.length * bytesPerRecord;
236
245
 
237
246
  array.copyWithin(target, start, end);
238
247
 
@@ -396,6 +405,15 @@ RowFirstTable.prototype.getRow = function (index, result) {
396
405
  this.readRowMethod(this.dataView, this.bytesPerRecord * index, result);
397
406
  };
398
407
 
408
+ /**
409
+ *
410
+ * @param {number} index
411
+ * @param {number[]} record
412
+ */
413
+ RowFirstTable.prototype.setRow = function (index, record) {
414
+ this.writeRowMethod(this.dataView, this.bytesPerRecord * index, record);
415
+ }
416
+
399
417
  /**
400
418
  * clear out all the data and free memory
401
419
  */
@@ -52,7 +52,7 @@ export const DataType2DataViewWriters = {
52
52
  *
53
53
  * @param {DataType[]} types
54
54
  * @param {EndianType} [endianType]
55
- * @returns {Function}
55
+ * @returns {(data_view:DataView, byte_offset:number, result:number[])=>void}
56
56
  */
57
57
  function genRowReader(types, endianType = EndianType.BigEndian) {
58
58
  let offset = 0;
@@ -86,7 +86,7 @@ function genRowReader(types, endianType = EndianType.BigEndian) {
86
86
  *
87
87
  * @param {DataType[]} types
88
88
  * @param {EndianType} [endianType]
89
- * @returns {Function}
89
+ * @returns {(data_view:DataView, byte_offset:number, record:number[])=>void}
90
90
  */
91
91
  function genRowWriter(types, endianType = EndianType.BigEndian) {
92
92
  let offset = 0;
@@ -195,13 +195,13 @@ export function RowFirstTableSpec(types, endianType = EndianType.BigEndian) {
195
195
 
196
196
  /**
197
197
  * @readonly
198
- * @type {Function}
198
+ * @type {function(DataView, number, number[]): void}
199
199
  */
200
200
  this.readRowMethod = genRowReader(types, endianType);
201
201
 
202
202
  /**
203
203
  * @readonly
204
- * @type {Function}
204
+ * @type {function(DataView, number, number[]): void}
205
205
  */
206
206
  this.writeRowMethod = genRowWriter(types, endianType);
207
207
 
@@ -1,7 +1,7 @@
1
1
  import { aabb3_matrix4_project } from "./aabb3_matrix4_project.js";
2
- import { compose_matrix4_array } from "../../../../engine/graphics/util/composeMatrix4.js";
3
2
  import Vector3 from "../../Vector3.js";
4
3
  import Quaternion from "../../Quaternion.js";
4
+ import { compose_matrix4_array } from "../compose_matrix4_array.js";
5
5
 
6
6
  test('identity', () => {
7
7
  const r = [];
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  *
3
- * @param {Float32Array} data
3
+ * @param {Float32Array} data must be x,y,z sequence
4
4
  * @param {AABB3} aabb
5
5
  */
6
6
  export function computeBoundingBoxFromVertexData(data, aabb) {
@@ -0,0 +1,53 @@
1
+ /**
2
+ *
3
+ * @param {number[]|Float32Array|mat4} result
4
+ * @param {Vector3} position
5
+ * @param {Quaternion} rotation
6
+ * @param {Vector3} scale
7
+ */
8
+ export function compose_matrix4_array(result, position, rotation, scale) {
9
+ const x = rotation.x;
10
+ const y = rotation.y;
11
+ const z = rotation.z;
12
+ const w = rotation.w;
13
+
14
+ const x2 = x + x;
15
+ const y2 = y + y;
16
+ const z2 = z + z;
17
+
18
+ const xx = x * x2;
19
+ const xy = x * y2;
20
+ const xz = x * z2;
21
+
22
+ const yy = y * y2;
23
+ const yz = y * z2;
24
+ const zz = z * z2;
25
+
26
+ const wx = w * x2;
27
+ const wy = w * y2;
28
+ const wz = w * z2;
29
+
30
+ const sx = scale.x;
31
+ const sy = scale.y;
32
+ const sz = scale.z;
33
+
34
+ result[0] = (1 - (yy + zz)) * sx;
35
+ result[1] = (xy + wz) * sx;
36
+ result[2] = (xz - wy) * sx;
37
+ result[3] = 0;
38
+
39
+ result[4] = (xy - wz) * sy;
40
+ result[5] = (1 - (xx + zz)) * sy;
41
+ result[6] = (yz + wx) * sy;
42
+ result[7] = 0;
43
+
44
+ result[8] = (xz + wy) * sz;
45
+ result[9] = (yz - wx) * sz;
46
+ result[10] = (1 - (xx + yy)) * sz;
47
+ result[11] = 0;
48
+
49
+ result[12] = position.x;
50
+ result[13] = position.y;
51
+ result[14] = position.z;
52
+ result[15] = 1;
53
+ }
@@ -68,9 +68,8 @@ class Vector1 extends Number {
68
68
  * @returns {Vector1}
69
69
  */
70
70
  set(x) {
71
- assert.equal(typeof x, "number", `X must be of type "number", instead was "${typeof x}"`);
72
-
73
- assert.ok(!Number.isNaN(x), `X must be a valid number, instead was NaN`);
71
+ assert.isNumber( x,'x');
72
+ assert.notNaN(x, 'x');
74
73
 
75
74
  const oldValue = this.x;
76
75
  if (oldValue !== x) {
@@ -406,6 +406,9 @@ export class GLTFAssetLoader extends AssetLoader {
406
406
  asset.has_root_transform = has_root_transform;
407
407
  asset.root_transform = root_transform;
408
408
 
409
+ // remember GLTF metadata
410
+ asset.gltf = gltf;
411
+
409
412
  if (gltf.animations !== undefined) {
410
413
  /**
411
414
  *
@@ -0,0 +1,27 @@
1
+ import { AssetTransformer } from "../../AssetTransformer.js";
2
+ import { buffer_geometry_ensure_tangents } from "../../../graphics/geometry/MikkT/buffer_geometry_ensure_tangents.js";
3
+
4
+ /**
5
+ * Ensures that all geometries have proper tangents
6
+ */
7
+ export class GLTFAssetTransformMikkTSpaceTangents extends AssetTransformer {
8
+ /**
9
+ *
10
+ * @param {Asset} source
11
+ * @param {AssetDescription} asset_description
12
+ * @return {Promise<Asset>}
13
+ */
14
+ async transform(source, asset_description) {
15
+ const root = source.create();
16
+
17
+ root.traverse(o => {
18
+ if (o.isMesh && o.geometry !== null) {
19
+ buffer_geometry_ensure_tangents(o.geometry);
20
+ }
21
+ });
22
+
23
+ return source;
24
+ }
25
+
26
+ static INSTANCE = new GLTFAssetTransformMikkTSpaceTangents();
27
+ }
@@ -56,13 +56,16 @@ function validateIndexValue(index, name) {
56
56
  * @param {BitSet} mask
57
57
  * @returns {boolean} true if mask matches completely, false otherwise
58
58
  */
59
- function matchComponentMask(componentOccupancy, entityIndex, componentTypeCount, mask) {
59
+ function matchComponentMask(
60
+ componentOccupancy,
61
+ entityIndex,
62
+ componentTypeCount,
63
+ mask
64
+ ) {
60
65
  const offset = entityIndex * componentTypeCount;
61
66
 
62
- let componentIndex;
63
-
64
67
  for (
65
- componentIndex = mask.nextSetBit(0);
68
+ let componentIndex = mask.nextSetBit(0);
66
69
  componentIndex !== -1;
67
70
  componentIndex = mask.nextSetBit(componentIndex + 1)
68
71
  ) {