@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.
- package/core/binary/BinaryBuffer.js +42 -17
- package/core/bvh2/BinaryNode.js +1 -1
- package/core/bvh2/aabb3/AABB3.js +2 -2
- package/core/bvh2/aabb3/aabb3_array_combine.js +20 -0
- package/core/bvh2/aabb3/aabb3_array_intersects_frustum_array.js +20 -0
- package/core/bvh2/aabb3/aabb3_array_intersects_ray.js +1 -0
- package/core/bvh2/aabb3/aabb3_array_intersects_ray_array.js +14 -0
- package/core/bvh2/{aabb3_combined_surface_area.js → aabb3/aabb3_combined_surface_area.js} +3 -3
- package/core/bvh2/aabb3/aabb3_intersects_frustum_array.js +1 -19
- package/core/bvh2/bvh3/BVHNodeProxy.js +53 -0
- package/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +848 -0
- package/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.spec.js +142 -0
- package/core/bvh2/bvh3/bvh_query_leaves_generic.js +79 -0
- package/core/bvh2/bvh3/bvh_query_leaves_ray.js +95 -0
- package/core/bvh2/bvh3/query/BVHQuery.js +11 -0
- package/core/bvh2/bvh3/query/BVHQueryIntersectsFrustum.js +36 -0
- package/core/bvh2/bvh3/query/BVHQueryIntersectsRay.js +36 -0
- package/core/collection/array/copyArray.js +2 -2
- package/core/collection/array/typed/uint_array_for_count.js +17 -0
- package/core/collection/table/RowFirstTable.js +25 -7
- package/core/collection/table/RowFirstTableSpec.js +4 -4
- package/core/geom/3d/aabb/aabb3_matrix4_project.spec.js +1 -1
- package/{engine/graphics/util → core/geom/3d/aabb}/computeBoundingBoxFromVertexData.js +1 -1
- package/core/geom/3d/compose_matrix4_array.js +53 -0
- package/{engine/graphics/util → core/geom/3d}/decompose_matrix_4_array.js +0 -0
- package/core/geom/Vector1.js +2 -3
- package/engine/asset/loaders/GLTFAssetLoader.js +3 -0
- package/engine/asset/loaders/gltf/GLTFAssetTransformMikkTSpaceTangents.js +27 -0
- package/engine/ecs/EntityComponentDataset.js +7 -4
- package/engine/ecs/foliage/InstancedFoliage.js +1 -1
- package/engine/ecs/foliage/ViewState.js +1 -1
- package/engine/ecs/transform/Transform.js +2 -2
- package/engine/graphics/ecs/mesh-v2/ShadedGeometry.d.ts +5 -0
- package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +46 -12
- package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +81 -95
- package/engine/graphics/ecs/mesh-v2/render/ShadedGeometryRendererContext.js +16 -5
- package/engine/graphics/ecs/mesh-v2/sample/load_gltf.js +1 -0
- package/engine/graphics/ecs/mesh-v2/sample/prototypeShadedGeometry.js +3 -4
- package/engine/graphics/ecs/path/PathDisplaySystem.js +2 -1
- package/engine/graphics/ecs/path/testPathDisplaySystem.js +8 -8
- package/engine/graphics/ecs/path/tube/CapType.d.ts +5 -0
- package/engine/graphics/ecs/path/tube/CapType.js +9 -0
- package/engine/graphics/ecs/path/tube/TubePathStyle.d.ts +2 -0
- package/engine/graphics/ecs/path/tube/TubePathStyle.js +10 -1
- package/engine/graphics/ecs/path/tube/build/GeometryOutput.js +90 -0
- package/engine/graphics/ecs/path/tube/build/build_geometry_catmullrom.js +3 -2
- package/engine/graphics/ecs/path/tube/build/build_geometry_linear.js +1 -1
- package/engine/graphics/ecs/path/tube/build/computeFrenetFrames.js +1 -2
- package/engine/graphics/ecs/path/tube/build/makeTubeGeometry.js +353 -91
- package/engine/graphics/ecs/path/tube/prototypeAnimatedPathMask.js +390 -0
- package/engine/graphics/geometry/MikkT/MikkTSpace.js +2210 -0
- package/engine/graphics/geometry/MikkT/MikkTSpace.spec.js +22 -0
- package/engine/graphics/geometry/MikkT/buffer_geometry_ensure_tangents.js +34 -0
- package/engine/graphics/geometry/MikkT/buffer_geometry_generate_tangents.js +28 -0
- package/engine/graphics/{compute_geometry_polycount.js → geometry/compute_geometry_polycount.js} +0 -0
- package/engine/graphics/geometry/skining/computeSkinnedMeshBoundingVolumes.js +1 -1
- package/engine/graphics/micron/build/fill_patch_geometry_data.js +1 -18
- package/engine/graphics/micron/format/MicronGeometry.js +7 -4
- package/engine/graphics/micron/format/micron_build_proxy_geometry.js +203 -0
- package/engine/graphics/micron/format/serialization/collection/geometry_collection_serialization.js +83 -0
- package/engine/graphics/micron/plugin/GLTFAssetTransformer.js +63 -19
- package/engine/graphics/micron/plugin/GLTF_MICRON_ID_FIELD.js +5 -0
- package/engine/graphics/micron/plugin/MicronRenderPlugin.js +0 -4
- package/engine/graphics/micron/prototypeMicronProxyBuild.js +227 -0
- package/engine/graphics/micron/render/refinement/ActivePatchList.js +2 -2
- package/engine/graphics/micron/render/refinement/get_geometry_patch_cut.js +2 -2
- package/engine/graphics/render/forward_plus/LightManager.js +5 -5
- package/engine/graphics/render/forward_plus/data/channelCountToThreIntegerTextureType.js +3 -3
- package/engine/graphics/texture/channelCountToThreeTextureFormat.js +2 -2
- package/engine/graphics/util/composeMatrix4.js +1 -53
- package/engine/graphics/util/composeMatrix4RotationScale.js +1 -1
- package/engine/intelligence/behavior/ecs/BehaviorComponent.js +1 -1
- package/engine/intelligence/blackboard/AbstractBlackboard.js +9 -0
- package/engine/navigation/grid/FastBinaryHeap.js +13 -2
- package/engine/notify/Notification.js +1 -1
- package/engine/ui/notification/ViewEmitter.js +7 -1
- package/engine/ui/notification/notificationGenerator.js +1 -1
- package/engine/ui/scene/SceneGUIContext.js +11 -130
- package/engine/ui/scene/initializeNotifications.js +141 -0
- package/package.json +1 -1
- 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,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 {
|
|
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 {
|
|
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 {
|
|
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 {
|
|
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 = [];
|
|
@@ -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
|
+
}
|
|
File without changes
|
package/core/geom/Vector1.js
CHANGED
|
@@ -68,9 +68,8 @@ class Vector1 extends Number {
|
|
|
68
68
|
* @returns {Vector1}
|
|
69
69
|
*/
|
|
70
70
|
set(x) {
|
|
71
|
-
assert.
|
|
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(
|
|
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
|
) {
|