@woosh/meep-engine 2.62.0 → 2.64.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/build/meep.cjs +1061 -1058
- package/build/meep.min.js +1 -1
- package/build/meep.module.js +1061 -1058
- package/package.json +1 -1
- package/src/core/binary/EncodingBinaryBuffer.js +7 -43
- package/src/core/binary/EncodingBinaryBuffer.spec.js +16 -0
- package/src/core/binary/UINT16_MAX.js +5 -0
- package/src/core/bvh2/bvh3/EBBVHLeafProxy.js +4 -2
- package/src/core/bvh2/bvh3/ExplicitBinaryBoundingVolumeHierarchy.js +5 -5
- package/src/core/bvh2/bvh3/query/BVHQueryIntersectsFrustum.js +8 -10
- package/src/core/bvh2/bvh3/query/BVHQueryIntersectsRay.js +7 -7
- package/src/core/bvh2/bvh3/query/BVHQueryIntersectsSphere.js +37 -0
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_generic.js +12 -4
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_generic.spec.js +29 -0
- package/src/core/cache/LoadingCache.js +4 -1
- package/src/core/collection/list/List.js +9 -3
- package/src/core/collection/map/BiMap.js +49 -0
- package/src/core/geom/3d/aabb/aabb3_from_v3_array.js +11 -4
- package/src/core/geom/Vector2.js +6 -4
- package/src/engine/ecs/components/Tag.d.ts +2 -0
- package/src/engine/ecs/components/Tag.js +19 -28
- package/src/engine/ecs/components/Tag.spec.js +47 -0
- package/src/engine/ecs/fow/FogOfWar.js +4 -0
- package/src/engine/ecs/fow/FogOfWarEditor.js +3 -0
- package/src/engine/ecs/terrain/TerrainPreview.js +45 -44
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrain.js +22 -4
- package/src/engine/ecs/terrain/tiles/TerrainTile.js +17 -12
- package/src/engine/graphics/ecs/mesh/Mesh.d.ts +0 -4
- package/src/engine/graphics/ecs/mesh/Mesh.js +0 -11
- package/src/engine/graphics/ecs/mesh/MeshSystem.js +57 -67
- package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +49 -86
- package/src/engine/graphics/particles/particular/engine/emitter/ParticlePool.js +41 -72
- package/src/engine/graphics/particles/particular/engine/emitter/write_particle_patch_uv.js +28 -0
- package/src/engine/grid/ORTHOGONAL_NEIGHBOURHOOD_MASK.js +11 -0
- package/src/engine/sound/ecs/emitter/SoundEmitterSystem.js +17 -17
- package/src/core/binary/stringToByteArray.js +0 -24
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_sphere.js +0 -81
- package/src/engine/ecs/foliage/Foliage.js +0 -151
- package/src/engine/ecs/foliage/FoliageLoader.js +0 -39
- package/src/engine/ecs/foliage/FoliageVisibilitySetBuilder.js +0 -27
- package/src/engine/ecs/foliage/ImpostorFoliage.js +0 -106
- package/src/engine/ecs/foliage/InstancedFoliage.js +0 -395
- package/src/engine/ecs/foliage/ViewState.js +0 -181
- package/src/engine/ecs/foliage/ecs/Foliage2System.js +0 -333
- package/src/engine/ecs/foliage/ecs/InstancedMeshComponent.js +0 -70
- package/src/engine/ecs/foliage/ecs/InstancedMeshLayer.js +0 -138
- package/src/engine/ecs/foliage/ecs/InstancedMeshSerializationAdapter.js +0 -28
- package/src/engine/ecs/foliage/ecs/convertInstancedMeshComponents2Entities.js +0 -64
- package/src/engine/ecs/foliage/ecs/optimizeIndividualMeshesEntitiesToInstances.js +0 -233
- package/src/engine/save/storage/GooglePlayStorage.js +0 -47
- package/src/engine/save/storage/JsonStringCodec.js +0 -24
- package/src/engine/save/storage/LocalStorage.js +0 -148
- package/src/engine/save/storage/MsgPackCodec.js +0 -22
- /package/src/engine/sound/ecs/emitter/{SoundEmitter.spec.js → SoundEmitterSerializationAdapter.spec.js} +0 -0
|
@@ -1,395 +0,0 @@
|
|
|
1
|
-
import { BinaryNode } from "../../../core/bvh2/BinaryNode.js";
|
|
2
|
-
import { RowFirstTable } from "../../../core/collection/table/RowFirstTable.js";
|
|
3
|
-
import { LeafNode } from "../../../core/bvh2/LeafNode.js";
|
|
4
|
-
import Vector4 from "../../../core/geom/Vector4.js";
|
|
5
|
-
|
|
6
|
-
import { BufferGeometry } from 'three';
|
|
7
|
-
import { BinaryDataType } from "../../../core/binary/type/BinaryDataType.js";
|
|
8
|
-
import { RowFirstTableSpec } from "../../../core/collection/table/RowFirstTableSpec.js";
|
|
9
|
-
import {
|
|
10
|
-
serializeBinaryNodeToBinaryBuffer
|
|
11
|
-
} from "../../../core/bvh2/serialization/serializeBinaryNodeToBinaryBuffer.js";
|
|
12
|
-
import {
|
|
13
|
-
deserializeBinaryNodeFromBinaryBuffer
|
|
14
|
-
} from "../../../core/bvh2/serialization/deserializeBinaryNodeFromBinaryBuffer.js";
|
|
15
|
-
import {
|
|
16
|
-
computeGeometryBoundingSphereMiniball
|
|
17
|
-
} from "../../graphics/geometry/buffered/computeGeometryBoundingSphereMiniball.js";
|
|
18
|
-
import { serializeRowFirstTable } from "../../../core/collection/table/serializeRowFirstTable.js";
|
|
19
|
-
import { deserializeRowFirstTable } from "../../../core/collection/table/deserializeRowFirstTable.js";
|
|
20
|
-
import { aabb3_from_v3_array_transformed } from "../../../core/geom/3d/aabb/aabb3_from_v3_array_transformed.js";
|
|
21
|
-
import { ViewState } from "./ViewState.js";
|
|
22
|
-
import { compose_matrix4_array } from "../../../core/geom/3d/compose_matrix4_array.js";
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* @readonly
|
|
26
|
-
* @type {RowFirstTableSpec}
|
|
27
|
-
*/
|
|
28
|
-
const dataSpec = new RowFirstTableSpec([
|
|
29
|
-
BinaryDataType.Float32, BinaryDataType.Float32, BinaryDataType.Float32, //position
|
|
30
|
-
BinaryDataType.Uint32, //rotation
|
|
31
|
-
BinaryDataType.Float32, BinaryDataType.Float32, BinaryDataType.Float32 //scale
|
|
32
|
-
]);
|
|
33
|
-
|
|
34
|
-
export class InstancedFoliage {
|
|
35
|
-
/**
|
|
36
|
-
*
|
|
37
|
-
* @constructor
|
|
38
|
-
*/
|
|
39
|
-
constructor() {
|
|
40
|
-
/**
|
|
41
|
-
* Minimum area on the screen to be occupied by an instance, if instance bounding sphere occupies less than this - it will be culled
|
|
42
|
-
* Measured in pixels
|
|
43
|
-
* @type {number}
|
|
44
|
-
*/
|
|
45
|
-
this.minScreenArea = 32;
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
*
|
|
49
|
-
* @type {BinaryNode}
|
|
50
|
-
*/
|
|
51
|
-
this.bvh = new BinaryNode();
|
|
52
|
-
this.bvh.setNegativelyInfiniteBounds();
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
*
|
|
56
|
-
* @type {RowFirstTable}
|
|
57
|
-
*/
|
|
58
|
-
this.data = new RowFirstTable(dataSpec);
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
*
|
|
62
|
-
* @type {THREE.BufferGeometry|null}
|
|
63
|
-
*/
|
|
64
|
-
this.geometry = null;
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
*
|
|
68
|
-
* @type {THREE.Material|null}
|
|
69
|
-
* @private
|
|
70
|
-
*/
|
|
71
|
-
this.__material = null;
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
*
|
|
75
|
-
* @type {Vector4|Vector4}
|
|
76
|
-
*/
|
|
77
|
-
this.instanceBoundingSphere = new Vector4(0, 0, 0, 0);
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
*
|
|
81
|
-
* @type {Map<CameraView, ViewState>}
|
|
82
|
-
* @private
|
|
83
|
-
*/
|
|
84
|
-
this.__views = new Map();
|
|
85
|
-
|
|
86
|
-
this.__cast_shadow = true;
|
|
87
|
-
this.__receive_shadow = true;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
set castShadow(v) {
|
|
91
|
-
this.__cast_shadow = v;
|
|
92
|
-
|
|
93
|
-
for (const [view, state] of this.__views) {
|
|
94
|
-
state.instances.mesh.castShadow = v;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
get castShadow() {
|
|
99
|
-
return this.__cast_shadow;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
set receiveShadow(v) {
|
|
103
|
-
this.__receive_shadow = v;
|
|
104
|
-
|
|
105
|
-
for (const [view, state] of this.__views) {
|
|
106
|
-
state.instances.mesh.receiveShadow = v;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
get receiveShadow() {
|
|
111
|
-
return this.__receive_shadow;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
*
|
|
116
|
-
* @returns {number}
|
|
117
|
-
*/
|
|
118
|
-
hash() {
|
|
119
|
-
return this.data.hash();
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
clear() {
|
|
123
|
-
|
|
124
|
-
this.data.clear();
|
|
125
|
-
this.bvh.reset();
|
|
126
|
-
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
/**
|
|
130
|
-
*
|
|
131
|
-
* @param {SurfacePoint3} contact
|
|
132
|
-
* @param {number} origin_x
|
|
133
|
-
* @param {number} origin_y
|
|
134
|
-
* @param {number} origin_z
|
|
135
|
-
* @param {number} direction_x
|
|
136
|
-
* @param {number} direction_y
|
|
137
|
-
* @param {number} direction_z
|
|
138
|
-
* @returns {number} index of the contact instance, or -1 if no hit found
|
|
139
|
-
*/
|
|
140
|
-
raypick(
|
|
141
|
-
contact,
|
|
142
|
-
origin_x, origin_y, origin_z,
|
|
143
|
-
direction_x, direction_y, direction_z
|
|
144
|
-
) {
|
|
145
|
-
throw new Error('Not implemented');
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
dispose() {
|
|
149
|
-
for (const [view, state] of this.__views) {
|
|
150
|
-
state.dispose();
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
this.__views.clear();
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
initialize() {
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
*
|
|
162
|
-
* @param {Vector3} position
|
|
163
|
-
* @param {Quaternion} rotation
|
|
164
|
-
* @param {Vector3} scale
|
|
165
|
-
*/
|
|
166
|
-
add(position, rotation, scale) {
|
|
167
|
-
const index = this.data.length;
|
|
168
|
-
|
|
169
|
-
const encodedRotation = rotation.encodeToUint32();
|
|
170
|
-
|
|
171
|
-
//update data
|
|
172
|
-
this.data.addRow([
|
|
173
|
-
position.x, position.y, position.z,
|
|
174
|
-
encodedRotation,
|
|
175
|
-
scale.x, scale.y, scale.z
|
|
176
|
-
]);
|
|
177
|
-
|
|
178
|
-
const leaf = new LeafNode(
|
|
179
|
-
index,
|
|
180
|
-
Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY,
|
|
181
|
-
Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY
|
|
182
|
-
);
|
|
183
|
-
|
|
184
|
-
//compute bounding box for this instance
|
|
185
|
-
this.computeInstanceBoundsTight(position, rotation, scale, leaf);
|
|
186
|
-
|
|
187
|
-
//insert bounding box into the spatial index
|
|
188
|
-
this.bvh.insertNode(leaf);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
*
|
|
193
|
-
* @param {int} index Instance index
|
|
194
|
-
* @param {Vector3} position Position of instance will be read into this vector
|
|
195
|
-
* @param {Quaternion} rotation Rotation of instance will be read into this quaternion
|
|
196
|
-
* @param {Vector3} scale Scale of the instance will be read into this Vector
|
|
197
|
-
*/
|
|
198
|
-
read(index, position, rotation, scale) {
|
|
199
|
-
const elementData = [];
|
|
200
|
-
//read transform data for instance
|
|
201
|
-
this.data.getRow(index, elementData);
|
|
202
|
-
|
|
203
|
-
const positionX = elementData[0];
|
|
204
|
-
const positionY = elementData[1];
|
|
205
|
-
const positionZ = elementData[2];
|
|
206
|
-
|
|
207
|
-
const encodedRotation = elementData[3];
|
|
208
|
-
|
|
209
|
-
const scaleX = elementData[4];
|
|
210
|
-
const scaleY = elementData[5];
|
|
211
|
-
const scaleZ = elementData[6];
|
|
212
|
-
|
|
213
|
-
position.set(positionX, positionY, positionZ);
|
|
214
|
-
|
|
215
|
-
rotation.decodeFromUint32(encodedRotation);
|
|
216
|
-
|
|
217
|
-
scale.set(scaleX, scaleY, scaleZ);
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/**
|
|
221
|
-
*
|
|
222
|
-
* @param {AABB3} result
|
|
223
|
-
* @param {Vector3} position
|
|
224
|
-
* @param {Quaternion} rotation
|
|
225
|
-
* @param {Vector3} scale
|
|
226
|
-
*/
|
|
227
|
-
computeInstanceBoundsTight(position, rotation, scale, result) {
|
|
228
|
-
|
|
229
|
-
const vertexData = this.geometry.attributes.position.array;
|
|
230
|
-
|
|
231
|
-
const transform = new Float32Array(16);
|
|
232
|
-
|
|
233
|
-
compose_matrix4_array(transform, position, rotation, scale);
|
|
234
|
-
|
|
235
|
-
aabb3_from_v3_array_transformed(result, vertexData, vertexData.length, transform);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
computeInstanceBoundingSphere() {
|
|
239
|
-
this.instanceBoundingSphere = computeGeometryBoundingSphereMiniball(this.geometry);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
*
|
|
244
|
-
* @param {BufferGeometry} geometry
|
|
245
|
-
* @param {Material} material
|
|
246
|
-
*/
|
|
247
|
-
setInstance(geometry, material) {
|
|
248
|
-
if (material === undefined) {
|
|
249
|
-
throw new Error(`Material is undefined`);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
if (geometry === undefined) {
|
|
253
|
-
throw new Error(`Geometry is undefined`);
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
let bufferGeometry;
|
|
258
|
-
if ((geometry instanceof BufferGeometry)) {
|
|
259
|
-
bufferGeometry = geometry;
|
|
260
|
-
} else {
|
|
261
|
-
bufferGeometry = new BufferGeometry();
|
|
262
|
-
bufferGeometry.fromGeometry(geometry);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
this.geometry = bufferGeometry;
|
|
267
|
-
this.__material = material;
|
|
268
|
-
|
|
269
|
-
for (const [view, state] of this.__views) {
|
|
270
|
-
state.instances.setMaterial(material);
|
|
271
|
-
state.instances.setGeometry(bufferGeometry);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
this.computeInstanceBoundingSphere();
|
|
275
|
-
|
|
276
|
-
//TODO: compute haul for the mesh, to use for fast AABB computation
|
|
277
|
-
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
/**
|
|
281
|
-
*
|
|
282
|
-
* @param {BinaryBuffer} buffer
|
|
283
|
-
*/
|
|
284
|
-
deserialize(buffer) {
|
|
285
|
-
deserializeRowFirstTable(buffer, this.data);
|
|
286
|
-
|
|
287
|
-
deserializeBinaryNodeFromBinaryBuffer(this.bvh, buffer, deserializeLeafValueUintVar);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
/**
|
|
291
|
-
*
|
|
292
|
-
* @param {BinaryBuffer} buffer
|
|
293
|
-
*/
|
|
294
|
-
serialize(buffer) {
|
|
295
|
-
|
|
296
|
-
//serialize data
|
|
297
|
-
serializeRowFirstTable(buffer, this.data);
|
|
298
|
-
|
|
299
|
-
const numRows = this.data.length;
|
|
300
|
-
|
|
301
|
-
if (numRows > 2147483647) {
|
|
302
|
-
throw new Error(`Data is too large to be written (length=${numRows})`);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
serializeBinaryNodeToBinaryBuffer(this.bvh, buffer, serializeLeafValueUintVar);
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
/**
|
|
310
|
-
*
|
|
311
|
-
* @param {CameraView} view
|
|
312
|
-
*/
|
|
313
|
-
add_view(view) {
|
|
314
|
-
|
|
315
|
-
if (this.__views.has(view)) {
|
|
316
|
-
throw new Error('View already registered');
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
const state = new ViewState();
|
|
320
|
-
|
|
321
|
-
state.__view = view;
|
|
322
|
-
|
|
323
|
-
if (this.geometry !== null) {
|
|
324
|
-
state.instances.setGeometry(this.geometry);
|
|
325
|
-
}
|
|
326
|
-
if (this.__material !== null) {
|
|
327
|
-
state.instances.setMaterial(this.__material);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
state.instances.mesh.castShadow = this.castShadow;
|
|
331
|
-
state.instances.mesh.receiveShadow = this.receiveShadow;
|
|
332
|
-
|
|
333
|
-
this.__views.set(view, state);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
/**
|
|
337
|
-
*
|
|
338
|
-
* @param {CameraView} view
|
|
339
|
-
*/
|
|
340
|
-
remove_view(view) {
|
|
341
|
-
const state = this.__views.get(view);
|
|
342
|
-
|
|
343
|
-
if (state === undefined) {
|
|
344
|
-
return false;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
state.dispose();
|
|
348
|
-
|
|
349
|
-
this.__views.delete(view);
|
|
350
|
-
|
|
351
|
-
return true;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
/**
|
|
355
|
-
*
|
|
356
|
-
* @param {CameraView} view
|
|
357
|
-
* @returns {boolean}
|
|
358
|
-
*/
|
|
359
|
-
has_view(view){
|
|
360
|
-
return this.__views.has(view);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
/**
|
|
364
|
-
*
|
|
365
|
-
* @param {CameraView} view
|
|
366
|
-
* @return {ViewState}
|
|
367
|
-
*/
|
|
368
|
-
update(view) {
|
|
369
|
-
const state = this.__views.get(view);
|
|
370
|
-
|
|
371
|
-
state.update(this.bvh, this.data);
|
|
372
|
-
|
|
373
|
-
return state;
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
/**
|
|
378
|
-
*
|
|
379
|
-
* @param {BinaryBuffer} buffer
|
|
380
|
-
* @returns {number}
|
|
381
|
-
*/
|
|
382
|
-
function deserializeLeafValueUintVar(buffer) {
|
|
383
|
-
return buffer.readUintVar();
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
/**
|
|
387
|
-
*
|
|
388
|
-
* @param {BinaryBuffer} buffer
|
|
389
|
-
* @param {number} value
|
|
390
|
-
*/
|
|
391
|
-
function serializeLeafValueUintVar(buffer, value) {
|
|
392
|
-
buffer.writeUintVar(value);
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
import { BitSet } from "../../../core/binary/BitSet.js";
|
|
2
|
-
import { InstancedMeshGroup } from "../../graphics/geometry/instancing/InstancedMeshGroup.js";
|
|
3
|
-
import {
|
|
4
|
-
queryBinaryNode_FrustumIntersections_Data
|
|
5
|
-
} from "../../../core/bvh2/traversal/queryBinaryNode_FrustumIntersections.js";
|
|
6
|
-
import Quaternion from "../../../core/geom/Quaternion.js";
|
|
7
|
-
import Vector3 from "../../../core/geom/Vector3.js";
|
|
8
|
-
import { compose_matrix4_array } from "../../../core/geom/3d/compose_matrix4_array.js";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
*
|
|
12
|
-
* @type {number[]}
|
|
13
|
-
*/
|
|
14
|
-
const scratch_array = [];
|
|
15
|
-
|
|
16
|
-
export class ViewState {
|
|
17
|
-
constructor() {
|
|
18
|
-
/**
|
|
19
|
-
*
|
|
20
|
-
* @type {CameraView|null}
|
|
21
|
-
* @private
|
|
22
|
-
*/
|
|
23
|
-
this.__view = null;
|
|
24
|
-
|
|
25
|
-
this.__visible_set = new BitSet();
|
|
26
|
-
|
|
27
|
-
//prevent re-allocation
|
|
28
|
-
this.__visible_set.preventShrink();
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
*
|
|
32
|
-
* @type {InstancedMeshGroup}
|
|
33
|
-
*/
|
|
34
|
-
this.instances = new InstancedMeshGroup();
|
|
35
|
-
|
|
36
|
-
// make shrinking unlikely to prevent thrashing
|
|
37
|
-
this.instances.shrinkFactor = 0.4;
|
|
38
|
-
this.instances.shrinkConstant = 1024;
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
*
|
|
42
|
-
* @type {number[]}
|
|
43
|
-
* @private
|
|
44
|
-
*/
|
|
45
|
-
this.__garbage = [];
|
|
46
|
-
/**
|
|
47
|
-
*
|
|
48
|
-
* @type {number}
|
|
49
|
-
* @private
|
|
50
|
-
*/
|
|
51
|
-
this.__garbagePointer = 0;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
dispose() {
|
|
55
|
-
this.instances.dispose();
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
__compute_visibility_update() {
|
|
59
|
-
const instances = this.instances;
|
|
60
|
-
|
|
61
|
-
const indices = instances.indices;
|
|
62
|
-
|
|
63
|
-
const index_count = indices.length;
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
*
|
|
67
|
-
* @type {BitSet}
|
|
68
|
-
*/
|
|
69
|
-
const visible_set = this.__visible_set;
|
|
70
|
-
|
|
71
|
-
const garbage = this.__garbage;
|
|
72
|
-
|
|
73
|
-
for (let ref = 0; ref < index_count; ref++) {
|
|
74
|
-
const index = indices[ref];
|
|
75
|
-
|
|
76
|
-
if (index === undefined) {
|
|
77
|
-
// unoccupied
|
|
78
|
-
continue;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if (!visible_set.get(ref)) {
|
|
82
|
-
//no longer visible
|
|
83
|
-
garbage[this.__garbagePointer++] = ref;
|
|
84
|
-
} else {
|
|
85
|
-
//visible, and is already in the group, update the set
|
|
86
|
-
visible_set.set(ref, false);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
__removeGarbage() {
|
|
92
|
-
|
|
93
|
-
const garbagePointer = this.__garbagePointer;
|
|
94
|
-
const instances = this.instances;
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const garbage = this.__garbage;
|
|
98
|
-
|
|
99
|
-
for (let i = 0; i < garbagePointer; i++) {
|
|
100
|
-
const ref = garbage[i];
|
|
101
|
-
instances.remove(ref);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
*
|
|
108
|
-
* @param {BinaryNode<number>} bvh
|
|
109
|
-
* @param {RowFirstTable} data
|
|
110
|
-
*/
|
|
111
|
-
update(bvh, data) {
|
|
112
|
-
|
|
113
|
-
const visible_instance_set = this.__visible_set;
|
|
114
|
-
|
|
115
|
-
const instances = this.instances;
|
|
116
|
-
|
|
117
|
-
// reset visible set
|
|
118
|
-
visible_instance_set.reset();
|
|
119
|
-
|
|
120
|
-
//reset garbage pointer
|
|
121
|
-
this.__garbagePointer = 0;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
// collect visible instances
|
|
125
|
-
const collected_nodes = queryBinaryNode_FrustumIntersections_Data(scratch_array, 0, bvh, this.__view.frustum);
|
|
126
|
-
|
|
127
|
-
for (let i = 0; i < collected_nodes; i++) {
|
|
128
|
-
const instance_id = scratch_array[i];
|
|
129
|
-
|
|
130
|
-
// mark them as visible
|
|
131
|
-
visible_instance_set.set(instance_id, true);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
//remove those that are no longer visible
|
|
135
|
-
this.__compute_visibility_update();
|
|
136
|
-
|
|
137
|
-
//cull instances that are no longer visible
|
|
138
|
-
this.__removeGarbage();
|
|
139
|
-
|
|
140
|
-
//process entities that have become newly visible
|
|
141
|
-
for (
|
|
142
|
-
let index = visible_instance_set.nextSetBit(0);
|
|
143
|
-
index !== -1;
|
|
144
|
-
index = visible_instance_set.nextSetBit(index + 1)
|
|
145
|
-
) {
|
|
146
|
-
//read transform data for instance
|
|
147
|
-
data.getRow(index, rowData);
|
|
148
|
-
|
|
149
|
-
const positionX = rowData[0];
|
|
150
|
-
const positionY = rowData[1];
|
|
151
|
-
const positionZ = rowData[2];
|
|
152
|
-
|
|
153
|
-
const encodedRotation = rowData[3];
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const scaleX = rowData[4];
|
|
157
|
-
const scaleY = rowData[5];
|
|
158
|
-
const scaleZ = rowData[6];
|
|
159
|
-
|
|
160
|
-
const i = instances.add(index);
|
|
161
|
-
|
|
162
|
-
tempQuaternion.decodeFromUint32(encodedRotation);
|
|
163
|
-
|
|
164
|
-
scratch_v3_0.set(positionX, positionY, positionZ);
|
|
165
|
-
scratch_v3_1.set(scaleX, scaleY, scaleZ);
|
|
166
|
-
|
|
167
|
-
// compose transform
|
|
168
|
-
compose_matrix4_array(scratch_transform, scratch_v3_0, tempQuaternion, scratch_v3_1);
|
|
169
|
-
|
|
170
|
-
//apply instance transforms
|
|
171
|
-
instances.setTransformAt(i, scratch_transform);
|
|
172
|
-
instances.requestAttributeUpdate();
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const tempQuaternion = new Quaternion();
|
|
178
|
-
const scratch_v3_0 = new Vector3();
|
|
179
|
-
const scratch_v3_1 = new Vector3();
|
|
180
|
-
const rowData = [];
|
|
181
|
-
const scratch_transform = new Float32Array(16);
|