@woosh/meep-engine 2.39.13 → 2.39.16
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/int32_to_binary_string.js +18 -0
- package/core/cache/Cache.js +1 -1
- package/core/geom/3d/decompose_matrix_4_array.js +3 -1
- package/core/geom/3d/ray/ray3_array_apply_matrix4.js +15 -1
- package/core/geom/3d/topology/bounds/computeTopoMeshBoundingSphere.js +2 -1
- package/editor/tools/v2/TransformControls.js +1782 -0
- package/editor/tools/v2/prototypeTransformControls.js +79 -0
- package/engine/asset/AssetManager.js +82 -23
- package/engine/ecs/parent/EntityNode.js +41 -13
- package/engine/ecs/terrain/ecs/Terrain.js +49 -39
- package/engine/ecs/terrain/ecs/layers/TerrainLayers.js +12 -5
- package/engine/ecs/terrain/ecs/splat/SplatMapping.js +5 -1
- package/engine/ecs/transform/Transform.d.ts +2 -0
- package/engine/ecs/transform/Transform.js +6 -0
- package/engine/ecs/transform-attachment/TransformAttachment.js +13 -0
- package/engine/ecs/transform-attachment/TransformAttachmentSystem.js +138 -16
- package/engine/graphics/FrameRunner.js +8 -2
- package/engine/graphics/ecs/mesh-v2/DrawMode.js +4 -0
- package/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +77 -0
- package/engine/graphics/ecs/mesh-v2/ShadedGeometryFlags.js +10 -0
- package/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +2 -30
- package/engine/graphics/ecs/mesh-v2/render/ShadedGeometryRendererContext.js +11 -0
- package/engine/graphics/ecs/mesh-v2/render/adapters/InstancedRendererAdapter.js +8 -32
- package/engine/graphics/ecs/mesh-v2/render/optimization/RuntimeDrawMethodOptimizer.js +6 -0
- package/engine/graphics/geometry/buffered/makeGeometryIndexed.js +23 -0
- package/engine/graphics/geometry/buffered/query/GeometrySpatialQueryAccelerator.js +16 -4
- package/engine/graphics/geometry/buffered/query/GeometryVisitor.js +8 -1
- package/engine/graphics/geometry/buffered/query/RaycastNearestHitComputingVisitor.js +14 -5
- package/engine/graphics/geometry/bvh/buffered/BinaryBVHFromBufferGeometry.js +56 -0
- package/engine/graphics/micron/build/hierarchy/build_merge_graph.js +1 -0
- package/engine/graphics/micron/build/hierarchy/computePatchMergeScore.js +18 -4
- package/engine/graphics/micron/plugin/GLTFAssetTransformer.js +15 -5
- package/package.json +1 -1
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { System } from "../System.js";
|
|
2
2
|
import { TransformAttachment, TransformAttachmentFlags } from "./TransformAttachment.js";
|
|
3
3
|
import { Transform } from "../transform/Transform.js";
|
|
4
|
+
import { min2 } from "../../../core/math/min2.js";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @readonly
|
|
8
|
+
* @type {number}
|
|
9
|
+
*/
|
|
10
|
+
const QUEUE_ITERATION_COUNT = 32;
|
|
4
11
|
|
|
5
12
|
class UpdateContext {
|
|
6
13
|
constructor() {
|
|
@@ -27,22 +34,63 @@ class UpdateContext {
|
|
|
27
34
|
* @type {Transform|null}
|
|
28
35
|
*/
|
|
29
36
|
this.parent_transform = null;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
*
|
|
40
|
+
* @type {EntityComponentDataset|null}
|
|
41
|
+
*/
|
|
42
|
+
this.ecd = null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
toString() {
|
|
46
|
+
return `UpdateContext{ attachment:${this.attachment}, entity:${this.entity} }`;
|
|
30
47
|
}
|
|
31
48
|
|
|
32
49
|
update() {
|
|
33
50
|
this.transform.multiplyTransforms(this.parent_transform, this.attachment.transform);
|
|
34
51
|
}
|
|
35
52
|
|
|
53
|
+
/**
|
|
54
|
+
*
|
|
55
|
+
* @returns {boolean}
|
|
56
|
+
*/
|
|
57
|
+
bind_parent() {
|
|
58
|
+
|
|
59
|
+
const parent_transform = this.ecd.getComponent(this.attachment.parent, Transform);
|
|
60
|
+
|
|
61
|
+
if (parent_transform === undefined) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
this.parent_transform = parent_transform;
|
|
66
|
+
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
|
|
36
70
|
link() {
|
|
37
|
-
this.parent_transform
|
|
38
|
-
|
|
39
|
-
|
|
71
|
+
const t_parent = this.parent_transform;
|
|
72
|
+
|
|
73
|
+
t_parent.position.onChanged.add(this.update, this);
|
|
74
|
+
t_parent.rotation.onChanged.add(this.update, this);
|
|
75
|
+
t_parent.scale.onChanged.add(this.update, this);
|
|
76
|
+
|
|
77
|
+
const t_attachment = this.attachment.transform;
|
|
78
|
+
t_attachment.position.onChanged.add(this.update,this);
|
|
79
|
+
t_attachment.rotation.onChanged.add(this.update,this);
|
|
80
|
+
t_attachment.scale.onChanged.add(this.update,this);
|
|
40
81
|
}
|
|
41
82
|
|
|
42
83
|
unlink() {
|
|
43
|
-
this.parent_transform
|
|
44
|
-
|
|
45
|
-
|
|
84
|
+
const transform = this.parent_transform;
|
|
85
|
+
|
|
86
|
+
transform.position.onChanged.remove(this.update, this);
|
|
87
|
+
transform.rotation.onChanged.remove(this.update, this);
|
|
88
|
+
transform.scale.onChanged.remove(this.update, this);
|
|
89
|
+
|
|
90
|
+
const t_attachment = this.attachment.transform;
|
|
91
|
+
t_attachment.position.onChanged.remove(this.update,this);
|
|
92
|
+
t_attachment.rotation.onChanged.remove(this.update,this);
|
|
93
|
+
t_attachment.scale.onChanged.remove(this.update,this);
|
|
46
94
|
}
|
|
47
95
|
}
|
|
48
96
|
|
|
@@ -58,6 +106,54 @@ export class TransformAttachmentSystem extends System {
|
|
|
58
106
|
* @private
|
|
59
107
|
*/
|
|
60
108
|
this.__contexts = [];
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
*
|
|
112
|
+
* @type {UpdateContext[]}
|
|
113
|
+
* @private
|
|
114
|
+
*/
|
|
115
|
+
this.__queue = [];
|
|
116
|
+
this.__queue_size = 0;
|
|
117
|
+
this.__queue_cursor = 0;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
*
|
|
122
|
+
* @param {UpdateContext} ctx
|
|
123
|
+
* @private
|
|
124
|
+
*/
|
|
125
|
+
__finalize_link(ctx) {
|
|
126
|
+
|
|
127
|
+
ctx.link();
|
|
128
|
+
|
|
129
|
+
this.__contexts[ctx.entity] = ctx;
|
|
130
|
+
|
|
131
|
+
if ((ctx.attachment.flags & TransformAttachmentFlags.Immediate) !== 0) {
|
|
132
|
+
ctx.update();
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
*
|
|
138
|
+
* @param {UpdateContext} ctx
|
|
139
|
+
* @private
|
|
140
|
+
*/
|
|
141
|
+
__enqueue(ctx) {
|
|
142
|
+
this.__queue[this.__queue_size++] = ctx;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
__dequeue_entity(entity) {
|
|
146
|
+
for (let i = 0; i < this.__queue_size; i++) {
|
|
147
|
+
const ctx = this.__queue[i];
|
|
148
|
+
|
|
149
|
+
if (ctx.entity === entity) {
|
|
150
|
+
this.__queue.splice(i, 1);
|
|
151
|
+
this.__queue_size--;
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return false;
|
|
61
157
|
}
|
|
62
158
|
|
|
63
159
|
/**
|
|
@@ -68,22 +164,23 @@ export class TransformAttachmentSystem extends System {
|
|
|
68
164
|
*/
|
|
69
165
|
link(attachment, transform, entity) {
|
|
70
166
|
const ctx = new UpdateContext();
|
|
71
|
-
ctx.system = this;
|
|
72
167
|
|
|
73
168
|
ctx.attachment = attachment;
|
|
74
169
|
ctx.transform = transform;
|
|
75
170
|
ctx.entity = entity;
|
|
76
171
|
|
|
77
172
|
|
|
78
|
-
|
|
173
|
+
const ecd = this.entityManager.dataset;
|
|
79
174
|
|
|
80
|
-
ctx.
|
|
81
|
-
|
|
82
|
-
this.__contexts[entity] = ctx;
|
|
175
|
+
ctx.ecd = ecd;
|
|
83
176
|
|
|
84
|
-
if ((
|
|
85
|
-
|
|
177
|
+
if (ctx.bind_parent()) {
|
|
178
|
+
this.__finalize_link(ctx);
|
|
179
|
+
} else {
|
|
180
|
+
// failed to bind parent, queue up instead
|
|
181
|
+
this.__enqueue(ctx);
|
|
86
182
|
}
|
|
183
|
+
|
|
87
184
|
}
|
|
88
185
|
|
|
89
186
|
/**
|
|
@@ -93,12 +190,37 @@ export class TransformAttachmentSystem extends System {
|
|
|
93
190
|
* @param {number} entity
|
|
94
191
|
*/
|
|
95
192
|
unlink(attachment, transform, entity) {
|
|
193
|
+
const ctx = this.__contexts[entity];
|
|
96
194
|
|
|
195
|
+
if (ctx !== undefined) {
|
|
97
196
|
|
|
98
|
-
|
|
197
|
+
delete this.__contexts[entity];
|
|
99
198
|
|
|
100
|
-
|
|
199
|
+
ctx.unlink();
|
|
200
|
+
|
|
201
|
+
} else {
|
|
202
|
+
// no context found, check the queue
|
|
203
|
+
this.__dequeue_entity(entity);
|
|
204
|
+
}
|
|
101
205
|
|
|
102
|
-
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
update(timeDelta) {
|
|
209
|
+
const step_count = min2(this.__queue_size, QUEUE_ITERATION_COUNT);
|
|
210
|
+
for (let i = 0; i < step_count; i++) {
|
|
211
|
+
const index = this.__queue_cursor % this.__queue_size;
|
|
212
|
+
|
|
213
|
+
const ctx = this.__queue[index];
|
|
214
|
+
|
|
215
|
+
if (ctx.bind_parent()) {
|
|
216
|
+
this.__finalize_link(ctx);
|
|
217
|
+
|
|
218
|
+
this.__queue.splice(index, 1);
|
|
219
|
+
this.__queue_size--;
|
|
220
|
+
|
|
221
|
+
} else {
|
|
222
|
+
this.__queue_cursor++;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
103
225
|
}
|
|
104
226
|
}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
let global_count = 0;
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
*
|
|
3
5
|
*/
|
|
@@ -33,7 +35,9 @@ export class FrameRunner {
|
|
|
33
35
|
return false;
|
|
34
36
|
}
|
|
35
37
|
|
|
36
|
-
console.warn(
|
|
38
|
+
console.warn(`FrameFunner.started[${global_count}]`);
|
|
39
|
+
|
|
40
|
+
global_count++;
|
|
37
41
|
|
|
38
42
|
this.running = true;
|
|
39
43
|
|
|
@@ -66,7 +70,9 @@ export class FrameRunner {
|
|
|
66
70
|
return false;
|
|
67
71
|
}
|
|
68
72
|
|
|
69
|
-
|
|
73
|
+
global_count--;
|
|
74
|
+
|
|
75
|
+
console.warn(`FrameFunner.stopped[${global_count}]`);
|
|
70
76
|
|
|
71
77
|
this.running = false;
|
|
72
78
|
cancelAnimationFrame(this.animationFrameId);
|
|
@@ -3,6 +3,9 @@ import { AABB3 } from "../../../../core/bvh2/aabb3/AABB3.js";
|
|
|
3
3
|
import { DrawMode } from "./DrawMode.js";
|
|
4
4
|
import { ShadedGeometryFlags } from "./ShadedGeometryFlags.js";
|
|
5
5
|
import { aabb3_matrix4_project } from "../../../../core/geom/3d/aabb/aabb3_matrix4_project.js";
|
|
6
|
+
import { mat4 } from "gl-matrix";
|
|
7
|
+
import { ray3_array_apply_matrix4 } from "../../../../core/geom/3d/ray/ray3_array_apply_matrix4.js";
|
|
8
|
+
import { GeometrySpatialQueryAccelerator } from "../../geometry/buffered/query/GeometrySpatialQueryAccelerator.js";
|
|
6
9
|
|
|
7
10
|
/**
|
|
8
11
|
* @readonly
|
|
@@ -12,12 +15,27 @@ const scratch_aabb3_array = new Float32Array(6);
|
|
|
12
15
|
|
|
13
16
|
const DEFAULT_FLAGS = ShadedGeometryFlags.CastShadow
|
|
14
17
|
| ShadedGeometryFlags.ReceiveShadow
|
|
18
|
+
| ShadedGeometryFlags.Visible
|
|
15
19
|
;
|
|
16
20
|
|
|
17
21
|
const FLAG_SET_EQUALITY = ShadedGeometryFlags.CastShadow
|
|
18
22
|
| ShadedGeometryFlags.ReceiveShadow
|
|
23
|
+
| ShadedGeometryFlags.DrawMethodLocked
|
|
24
|
+
| ShadedGeometryFlags.Visible
|
|
19
25
|
;
|
|
20
26
|
|
|
27
|
+
/**
|
|
28
|
+
*
|
|
29
|
+
* @type {Float32Array|mat4}
|
|
30
|
+
*/
|
|
31
|
+
const scratch_m4 = new Float32Array(16);
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @readonly
|
|
35
|
+
* @type {Float32Array}
|
|
36
|
+
*/
|
|
37
|
+
const scratch_ray_0 = new Float32Array(6);
|
|
38
|
+
|
|
21
39
|
export class ShadedGeometry {
|
|
22
40
|
constructor() {
|
|
23
41
|
/**
|
|
@@ -160,6 +178,30 @@ export class ShadedGeometry {
|
|
|
160
178
|
;
|
|
161
179
|
}
|
|
162
180
|
|
|
181
|
+
/**
|
|
182
|
+
*
|
|
183
|
+
* @param {ShadedGeometry} other
|
|
184
|
+
*/
|
|
185
|
+
copy(other) {
|
|
186
|
+
this.geometry = other.geometry;
|
|
187
|
+
this.material = other.material;
|
|
188
|
+
this.draw_method = other.draw_method;
|
|
189
|
+
this.mode = other.mode;
|
|
190
|
+
this.flags = other.flags;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
*
|
|
195
|
+
* @returns {ShadedGeometry}
|
|
196
|
+
*/
|
|
197
|
+
clone() {
|
|
198
|
+
const r = new ShadedGeometry();
|
|
199
|
+
|
|
200
|
+
r.copy(this);
|
|
201
|
+
|
|
202
|
+
return r;
|
|
203
|
+
}
|
|
204
|
+
|
|
163
205
|
/**
|
|
164
206
|
* Current cached entity that this component is attached to
|
|
165
207
|
* @return {number}
|
|
@@ -251,6 +293,41 @@ export class ShadedGeometry {
|
|
|
251
293
|
|
|
252
294
|
aabb3_matrix4_project(this.__bvh_aabb, scratch_aabb3_array, this.transform);
|
|
253
295
|
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
*
|
|
299
|
+
* @param {SurfacePoint3} contact if found, contact is written here
|
|
300
|
+
* @param {ArrayLike<number>|number[]|Float32Array} ray 6-tuple: [origin_x, origin_y, origin_z, direction_x, direction_y, direction_z]
|
|
301
|
+
* @param {ArrayLike<number>|number[]|Float32Array} transform_matrix4
|
|
302
|
+
* @returns {boolean}
|
|
303
|
+
*/
|
|
304
|
+
query_raycast_nearest(contact, ray, transform_matrix4) {
|
|
305
|
+
|
|
306
|
+
// get transform in local space
|
|
307
|
+
mat4.invert(scratch_m4, transform_matrix4);
|
|
308
|
+
|
|
309
|
+
// transform ray to local space
|
|
310
|
+
if (!ray3_array_apply_matrix4(scratch_ray_0, ray, scratch_m4)) {
|
|
311
|
+
// invalid transform matrix
|
|
312
|
+
return false;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const hit_found = GeometrySpatialQueryAccelerator.INSTANCE.queryRaycastNearest_array(
|
|
316
|
+
contact,
|
|
317
|
+
this.geometry,
|
|
318
|
+
scratch_ray_0
|
|
319
|
+
);
|
|
320
|
+
|
|
321
|
+
if (!hit_found) {
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// transform hit contact into global space
|
|
326
|
+
contact.applyMatrix4(transform_matrix4);
|
|
327
|
+
|
|
328
|
+
return true;
|
|
329
|
+
|
|
330
|
+
}
|
|
254
331
|
}
|
|
255
332
|
|
|
256
333
|
/**
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { ShadedGeometry } from "./ShadedGeometry.js";
|
|
2
2
|
import { Transform } from "../../../ecs/transform/Transform.js";
|
|
3
3
|
import { System } from "../../../ecs/System.js";
|
|
4
|
-
import { GeometrySpatialQueryAccelerator } from "../../geometry/buffered/query/GeometrySpatialQueryAccelerator.js";
|
|
5
4
|
import { SurfacePoint3 } from "../../../../core/geom/3d/SurfacePoint3.js";
|
|
6
5
|
import { v3_distance_sqr } from "../../../../core/geom/v3_distance_sqr.js";
|
|
7
6
|
import { mat4 } from "gl-matrix";
|
|
@@ -9,7 +8,6 @@ import { returnTrue } from "../../../../core/function/Functions.js";
|
|
|
9
8
|
import { ShadedGeometryRendererContext } from "./render/ShadedGeometryRendererContext.js";
|
|
10
9
|
import { assert } from "../../../../core/assert.js";
|
|
11
10
|
import { ray3_array_compose } from "../../../../core/geom/3d/ray/ray3_array_compose.js";
|
|
12
|
-
import { ray3_array_apply_matrix4 } from "../../../../core/geom/3d/ray/ray3_array_apply_matrix4.js";
|
|
13
11
|
import {
|
|
14
12
|
ExplicitBinaryBoundingVolumeHierarchy
|
|
15
13
|
} from "../../../../core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js";
|
|
@@ -382,31 +380,18 @@ export class ShadedGeometrySystem extends System {
|
|
|
382
380
|
|
|
383
381
|
const m4 = sg.transform;
|
|
384
382
|
|
|
385
|
-
// get transform in local space
|
|
386
|
-
mat4.invert(scratch_m4, m4);
|
|
387
|
-
|
|
388
383
|
ray3_array_compose(
|
|
389
384
|
scratch_ray_0,
|
|
390
385
|
origin_x, origin_y, origin_z,
|
|
391
386
|
direction_x, direction_y, direction_z
|
|
392
387
|
);
|
|
393
388
|
|
|
394
|
-
|
|
395
|
-
ray3_array_apply_matrix4(scratch_ray_0, scratch_ray_0, scratch_m4);
|
|
396
|
-
|
|
397
|
-
const geometry_hit_found = GeometrySpatialQueryAccelerator.INSTANCE.queryRaycastNearest_array(
|
|
398
|
-
scratch_point,
|
|
399
|
-
sg.geometry,
|
|
400
|
-
scratch_ray_0
|
|
401
|
-
);
|
|
389
|
+
const geometry_hit_found = sg.query_raycast_nearest(scratch_point,scratch_ray_0,m4);
|
|
402
390
|
|
|
403
391
|
if (!geometry_hit_found) {
|
|
404
392
|
continue;
|
|
405
393
|
}
|
|
406
394
|
|
|
407
|
-
// transform hit contact into global space
|
|
408
|
-
scratch_point.applyMatrix4(m4);
|
|
409
|
-
|
|
410
395
|
result.push({
|
|
411
396
|
entity,
|
|
412
397
|
mesh: sg,
|
|
@@ -476,31 +461,18 @@ export class ShadedGeometrySystem extends System {
|
|
|
476
461
|
*/
|
|
477
462
|
const m4 = sg.transform;
|
|
478
463
|
|
|
479
|
-
// get transform in local space
|
|
480
|
-
mat4.invert(scratch_m4, m4);
|
|
481
|
-
|
|
482
464
|
ray3_array_compose(
|
|
483
465
|
scratch_ray_0,
|
|
484
466
|
origin_x, origin_y, origin_z,
|
|
485
467
|
direction_x, direction_y, direction_z
|
|
486
468
|
);
|
|
487
469
|
|
|
488
|
-
|
|
489
|
-
ray3_array_apply_matrix4(scratch_ray_0, scratch_ray_0, scratch_m4);
|
|
490
|
-
|
|
491
|
-
const geometry_hit_found = GeometrySpatialQueryAccelerator.INSTANCE.queryRaycastNearest_array(
|
|
492
|
-
scratch_point,
|
|
493
|
-
sg.geometry,
|
|
494
|
-
scratch_ray_0
|
|
495
|
-
);
|
|
470
|
+
const geometry_hit_found = sg.query_raycast_nearest(scratch_point,scratch_ray_0,m4);
|
|
496
471
|
|
|
497
472
|
if (!geometry_hit_found) {
|
|
498
473
|
continue;
|
|
499
474
|
}
|
|
500
475
|
|
|
501
|
-
// transform hit contact into global space
|
|
502
|
-
scratch_point.applyMatrix4(m4);
|
|
503
|
-
|
|
504
476
|
found_hit = true;
|
|
505
477
|
|
|
506
478
|
const hit_position = scratch_point.position;
|
|
@@ -6,6 +6,7 @@ import { ShadedGeometry } from "../ShadedGeometry.js";
|
|
|
6
6
|
import {
|
|
7
7
|
bvh_query_user_data_overlaps_frustum
|
|
8
8
|
} from "../../../../../core/bvh2/bvh3/bvh_query_user_data_overlaps_frustum.js";
|
|
9
|
+
import { ShadedGeometryFlags } from "../ShadedGeometryFlags.js";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
*
|
|
@@ -104,6 +105,16 @@ export class ShadedGeometryRendererContext {
|
|
|
104
105
|
*/
|
|
105
106
|
const sg = ecd.getComponentByIndex(entity, sg_component_index);
|
|
106
107
|
|
|
108
|
+
if ((sg.flags & ShadedGeometryFlags.Visible) === 0) {
|
|
109
|
+
// not visible
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (!sg.material.visible) {
|
|
114
|
+
// material is not visible, skip
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
|
|
107
118
|
const adapter = adapters[sg.draw_method];
|
|
108
119
|
|
|
109
120
|
adapter.add(sg);
|
|
@@ -9,36 +9,6 @@ const INSTANCED_EQUALITY_FLAGS = ShadedGeometryFlags.CastShadow
|
|
|
9
9
|
| ShadedGeometryFlags.ReceiveShadow
|
|
10
10
|
;
|
|
11
11
|
|
|
12
|
-
/**
|
|
13
|
-
*
|
|
14
|
-
* @param {ShadedGeometry} a
|
|
15
|
-
* @param {ShadedGeometry} b
|
|
16
|
-
* @returns {number}
|
|
17
|
-
*/
|
|
18
|
-
function compare(a, b) {
|
|
19
|
-
const d_geometry = a.geometry.id - b.geometry.id;
|
|
20
|
-
if (d_geometry !== 0) {
|
|
21
|
-
return d_geometry;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const d_material = a.material.id - b.material.id;
|
|
25
|
-
if (d_material !== 0) {
|
|
26
|
-
return d_material;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
const d_flags = (a.flags & INSTANCED_EQUALITY_FLAGS) - (b.flags & INSTANCED_EQUALITY_FLAGS);
|
|
30
|
-
if (d_flags !== 0) {
|
|
31
|
-
return d_flags;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const d_mode = a.mode - b.mode;
|
|
35
|
-
if (d_mode !== 0) {
|
|
36
|
-
return d_mode;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return 0;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
12
|
export class InstancedRendererAdapter extends AbstractRenderAdapter {
|
|
43
13
|
constructor() {
|
|
44
14
|
super();
|
|
@@ -159,17 +129,23 @@ export class InstancedRendererAdapter extends AbstractRenderAdapter {
|
|
|
159
129
|
clear() {
|
|
160
130
|
super.clear();
|
|
161
131
|
|
|
162
|
-
|
|
132
|
+
const meshes = this.__active_meshes;
|
|
133
|
+
|
|
134
|
+
for (const activeMesh of meshes) {
|
|
163
135
|
activeMesh.setCount(0);
|
|
164
136
|
}
|
|
165
137
|
|
|
166
|
-
|
|
138
|
+
meshes.clear();
|
|
167
139
|
}
|
|
168
140
|
|
|
169
141
|
dispose() {
|
|
142
|
+
this.clear();
|
|
143
|
+
|
|
170
144
|
// release GPU memory
|
|
171
145
|
this.__instanced_meshes.forEach((value, key) => {
|
|
172
146
|
value.dispose();
|
|
173
147
|
});
|
|
148
|
+
|
|
149
|
+
this.__instanced_meshes.clear();
|
|
174
150
|
}
|
|
175
151
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ShadedGeometry } from "../../ShadedGeometry.js";
|
|
2
|
+
import { ShadedGeometryFlags } from "../../ShadedGeometryFlags.js";
|
|
2
3
|
|
|
3
4
|
export class RuntimeDrawMethodOptimizer {
|
|
4
5
|
constructor() {
|
|
@@ -70,6 +71,11 @@ export class RuntimeDrawMethodOptimizer {
|
|
|
70
71
|
return false;
|
|
71
72
|
}
|
|
72
73
|
|
|
74
|
+
if (sg.getFlag(ShadedGeometryFlags.DrawMethodLocked)) {
|
|
75
|
+
// draw mode is locked, can't change
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
|
|
73
79
|
const use_count = system.getGeometryUsageCounters().get(sg.geometry.id);
|
|
74
80
|
|
|
75
81
|
/**
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Float32BufferAttribute } from "three";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param {THREE.BufferGeometry} geometry
|
|
6
|
+
*/
|
|
7
|
+
export function makeGeometryIndexed(geometry) {
|
|
8
|
+
let index_attribute = geometry.getIndex();
|
|
9
|
+
|
|
10
|
+
if (index_attribute === null || index_attribute === undefined) {
|
|
11
|
+
const position_attribute = geometry.getAttribute('position');
|
|
12
|
+
// non-indexed geometry, build index
|
|
13
|
+
const array = new Float32Array(position_attribute.count * 3);
|
|
14
|
+
|
|
15
|
+
for (let i = 0; i < array.length; i++) {
|
|
16
|
+
array[i] = i;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
index_attribute = new Float32BufferAttribute(array, 1, false);
|
|
20
|
+
|
|
21
|
+
geometry.setIndex(index_attribute);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Cache } from "../../../../../core/cache/Cache.js";
|
|
2
|
-
import { buildUnsorted } from "../../bvh/buffered/BinaryBVHFromBufferGeometry.js";
|
|
2
|
+
import { buildUnsorted, buildUnsortedUnindexed } from "../../bvh/buffered/BinaryBVHFromBufferGeometry.js";
|
|
3
3
|
import { ClippingPlaneContainmentComputingVisitor } from "./ClippingPlaneContainmentComputingVisitor.js";
|
|
4
4
|
import { RaycastNearestHitComputingVisitor } from "./RaycastNearestHitComputingVisitor.js";
|
|
5
5
|
import { assert } from "../../../../../core/assert.js";
|
|
@@ -93,7 +93,15 @@ export class GeometrySpatialQueryAccelerator {
|
|
|
93
93
|
assert.notNull(geometry, 'geometry');
|
|
94
94
|
assert.defined(geometry, 'geometry');
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
|
|
97
|
+
let bvh;
|
|
98
|
+
|
|
99
|
+
try {
|
|
100
|
+
bvh = this.__acquireBVH(geometry);
|
|
101
|
+
} catch (e) {
|
|
102
|
+
console.error(e);
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
97
105
|
|
|
98
106
|
this.__visitor_raycast.reset();
|
|
99
107
|
|
|
@@ -174,9 +182,13 @@ export class GeometrySpatialQueryAccelerator {
|
|
|
174
182
|
const index_attribute = geometry.getIndex();
|
|
175
183
|
|
|
176
184
|
const de_interleaved_position_attribute = deinterleaveBufferAttribute(position_attribute);
|
|
177
|
-
const de_interleaved_index_attribute = deinterleaveBufferAttribute(index_attribute);
|
|
178
|
-
|
|
179
185
|
const vertices = de_interleaved_position_attribute.array;
|
|
186
|
+
|
|
187
|
+
if(index_attribute === undefined || index_attribute === null){
|
|
188
|
+
return buildUnsortedUnindexed(vertices);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const de_interleaved_index_attribute = deinterleaveBufferAttribute(index_attribute);
|
|
180
192
|
const indices = de_interleaved_index_attribute.array;
|
|
181
193
|
|
|
182
194
|
return buildUnsorted(vertices, indices);
|
|
@@ -60,7 +60,14 @@ export class GeometrySpatialAcceleratorVisitor extends IndexedBinaryBVHVisitor {
|
|
|
60
60
|
setGeometry(geometry) {
|
|
61
61
|
this.geometry = geometry;
|
|
62
62
|
|
|
63
|
-
|
|
63
|
+
const index_attribute = geometry.getIndex();
|
|
64
|
+
|
|
65
|
+
if (index_attribute) {
|
|
66
|
+
this.__buffer_indices = index_attribute.array;
|
|
67
|
+
} else {
|
|
68
|
+
// no index attribute
|
|
69
|
+
this.__buffer_indices = null;
|
|
70
|
+
}
|
|
64
71
|
|
|
65
72
|
const position_attribute = geometry.getAttribute('position');
|
|
66
73
|
|
|
@@ -110,11 +110,20 @@ export class RaycastNearestHitComputingVisitor extends GeometrySpatialAccelerato
|
|
|
110
110
|
|
|
111
111
|
const indices = this.__buffer_indices;
|
|
112
112
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
113
|
+
let a, b, c;
|
|
114
|
+
|
|
115
|
+
if(indices !== null) {
|
|
116
|
+
assert.lessThan(index3 + 2, indices.length, 'triangle index overflow, possibly geometry changed but tree was not rebuilt?');
|
|
117
|
+
|
|
118
|
+
a = indices[index3];
|
|
119
|
+
b = indices[index3 + 1];
|
|
120
|
+
c = indices[index3 + 2];
|
|
121
|
+
}else{
|
|
122
|
+
// implicit indices
|
|
123
|
+
a = index3;
|
|
124
|
+
b = index3+1;
|
|
125
|
+
c = index3+2;
|
|
126
|
+
}
|
|
118
127
|
|
|
119
128
|
const vertices = this.__buffer_vertices;
|
|
120
129
|
|