three-zoo 0.11.4 → 0.11.6

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/dist/index.js CHANGED
@@ -319,7 +319,7 @@ class InstancedMeshInstance {
319
319
  }
320
320
  }
321
321
 
322
- const TEMP_ZERO_MATRIX = new Matrix4().makeScale(0, 0, 0);
322
+ const TEMP_MATRIX = new Matrix4();
323
323
  class InstancedMeshPool {
324
324
  constructor(options) {
325
325
  var _a, _b;
@@ -330,29 +330,51 @@ class InstancedMeshPool {
330
330
  }
331
331
  allocate(geometry, material) {
332
332
  const entry = this._private_getOrCreateEntry(geometry, material);
333
- if (entry.freeIndices.length === 0) {
333
+ if (entry.count === entry.capacity) {
334
334
  this._private_growEntry(entry);
335
335
  }
336
- const index = entry.freeIndices.pop();
336
+ const index = entry.count;
337
+ entry.count++;
337
338
  const instance = new InstancedMeshInstance(this, entry, index);
338
- // identity transform
339
339
  instance.setScale3f(1, 1, 1);
340
- entry.instances.add(instance);
341
- this._private_updateMeshCount(entry);
340
+ entry.instances.set(index, instance);
341
+ entry.mesh.count = entry.count;
342
342
  return instance;
343
343
  }
344
344
  deallocate(instance) {
345
345
  if (instance.index === -1)
346
346
  return;
347
347
  const entry = instance["entry"];
348
- entry.instances.delete(instance);
349
- entry.freeIndices.push(instance.index);
350
- // hide instance
351
- entry.mesh.setMatrixAt(instance.index, TEMP_ZERO_MATRIX);
348
+ const removedIndex = instance.index;
349
+ const lastIndex = entry.count - 1;
350
+ entry.instances.delete(removedIndex);
351
+ if (removedIndex !== lastIndex) {
352
+ // swap: move last to removed position
353
+ const lastInstance = entry.instances.get(lastIndex);
354
+ entry.mesh.getMatrixAt(lastIndex, TEMP_MATRIX);
355
+ entry.mesh.setMatrixAt(removedIndex, TEMP_MATRIX);
356
+ lastInstance.index = removedIndex;
357
+ entry.instances.delete(lastIndex);
358
+ entry.instances.set(removedIndex, lastInstance);
359
+ }
360
+ entry.count--;
361
+ entry.mesh.count = entry.count;
352
362
  instance.index = -1;
353
- this._private_updateMeshCount(entry);
354
363
  this["notifyUpdate"](entry);
355
364
  }
365
+ sortMeshes(compare) {
366
+ const meshes = [];
367
+ for (const entry of this._private_meshes.values()) {
368
+ meshes.push(entry.mesh);
369
+ }
370
+ meshes.sort(compare);
371
+ for (const mesh of meshes) {
372
+ this._private_scene.remove(mesh);
373
+ }
374
+ for (const mesh of meshes) {
375
+ this._private_scene.add(mesh);
376
+ }
377
+ }
356
378
  _private_getOrCreateEntry(geometry, material) {
357
379
  const key = `${geometry.uuid}:${material.uuid}`;
358
380
  let entry = this._private_meshes.get(key);
@@ -366,8 +388,8 @@ class InstancedMeshPool {
366
388
  geometry,
367
389
  material,
368
390
  capacity: this._private_initialCapacity,
369
- instances: new Set(),
370
- freeIndices: this._private_createIndexRange(0, this._private_initialCapacity),
391
+ count: 0,
392
+ instances: new Map(),
371
393
  };
372
394
  this._private_meshes.set(key, entry);
373
395
  }
@@ -377,40 +399,16 @@ class InstancedMeshPool {
377
399
  const newCapacity = entry.capacity + this._private_capacityStep;
378
400
  const newMesh = new InstancedMesh(entry.geometry, entry.material, newCapacity);
379
401
  newMesh.frustumCulled = false;
380
- // copy existing matrix data
381
402
  const oldArray = entry.mesh.instanceMatrix.array;
382
403
  const newArray = newMesh.instanceMatrix.array;
383
404
  newArray.set(oldArray);
384
405
  newMesh.instanceMatrix.needsUpdate = true;
385
- // swap meshes
386
406
  this._private_scene.remove(entry.mesh);
387
407
  entry.mesh.dispose();
388
408
  this._private_scene.add(newMesh);
389
- // add new free indices
390
- entry.freeIndices.push(...this._private_createIndexRange(entry.capacity, newCapacity));
391
409
  entry.mesh = newMesh;
392
410
  entry.capacity = newCapacity;
393
- this._private_updateMeshCount(entry);
394
- }
395
- _private_updateMeshCount(entry) {
396
- if (entry.instances.size === 0) {
397
- entry.mesh.count = 0;
398
- return;
399
- }
400
- let maxIndex = -1;
401
- for (const inst of entry.instances) {
402
- if (inst.index > maxIndex) {
403
- maxIndex = inst.index;
404
- }
405
- }
406
- entry.mesh.count = maxIndex + 1;
407
- }
408
- _private_createIndexRange(start, end) {
409
- const result = [];
410
- for (let i = start; i < end; i++) {
411
- result.push(i);
412
- }
413
- return result;
411
+ entry.mesh.count = entry.count;
414
412
  }
415
413
  ["notifyUpdate"](entry) {
416
414
  entry.mesh.instanceMatrix.needsUpdate = true;