@rings-webgpu/core 1.0.38 → 1.0.40

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.
@@ -24081,10 +24081,44 @@ class Uint8ArrayTexture extends Texture {
24081
24081
  }
24082
24082
  return this;
24083
24083
  }
24084
- updateTexture(width, height, data) {
24084
+ updateTexture(width, height, data, startRow, rowCount) {
24085
24085
  let device = webGPUContext.device;
24086
24086
  const bytesPerRow = Math.ceil(width * 4 / 256) * 256;
24087
24087
  this.mipmapCount = Math.floor(Math.log2(width) );
24088
+ if (startRow !== void 0 && rowCount !== void 0 && rowCount < height) {
24089
+ const updateHeight = rowCount;
24090
+ const updateOffset = startRow * width * 4;
24091
+ const updateData = data.subarray(updateOffset, updateOffset + updateHeight * width * 4);
24092
+ const neededSize = updateData.byteLength;
24093
+ if (!this._dataBuffer || this._dataBuffer.size < neededSize) {
24094
+ this._dataBuffer && this._dataBuffer.destroy();
24095
+ this._dataBuffer = device.createBuffer({
24096
+ size: neededSize,
24097
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC
24098
+ });
24099
+ }
24100
+ device.queue.writeBuffer(this._dataBuffer, 0, updateData.buffer, updateData.byteOffset, updateData.byteLength);
24101
+ const commandEncoder2 = GPUContext.beginCommandEncoder();
24102
+ commandEncoder2.copyBufferToTexture(
24103
+ {
24104
+ buffer: this._dataBuffer,
24105
+ bytesPerRow,
24106
+ offset: 0
24107
+ },
24108
+ {
24109
+ texture: this.getGPUTexture(),
24110
+ origin: [0, startRow, 0]
24111
+ // Start at row startRow
24112
+ },
24113
+ {
24114
+ width,
24115
+ height: updateHeight,
24116
+ depthOrArrayLayers: 1
24117
+ }
24118
+ );
24119
+ GPUContext.endCommandEncoder(commandEncoder2);
24120
+ return;
24121
+ }
24088
24122
  this._dataBuffer && this._dataBuffer.destroy();
24089
24123
  this._dataBuffer = null;
24090
24124
  const textureDataBuffer = this._dataBuffer = device.createBuffer({
@@ -24140,9 +24174,28 @@ class Uint32ArrayTexture extends Texture {
24140
24174
  this.gpuSampler = device.createSampler({});
24141
24175
  return this;
24142
24176
  }
24143
- updateTexture(width, height, data) {
24177
+ updateTexture(width, height, data, startRow, rowCount) {
24144
24178
  let device = webGPUContext.device;
24145
24179
  const bytesPerRow = width * 4 * 4;
24180
+ if (startRow !== void 0 && rowCount !== void 0 && rowCount < height) {
24181
+ const updateHeight = rowCount;
24182
+ const updateOffset = startRow * width * 4;
24183
+ const updateData = data.subarray(updateOffset, updateOffset + updateHeight * width * 4);
24184
+ device.queue.writeTexture(
24185
+ {
24186
+ texture: this.getGPUTexture(),
24187
+ origin: [0, startRow, 0]
24188
+ // Start at row startRow
24189
+ },
24190
+ updateData.buffer,
24191
+ {
24192
+ bytesPerRow,
24193
+ offset: updateData.byteOffset
24194
+ },
24195
+ { width, height: updateHeight, depthOrArrayLayers: 1 }
24196
+ );
24197
+ return;
24198
+ }
24146
24199
  device.queue.writeTexture(
24147
24200
  { texture: this.getGPUTexture() },
24148
24201
  data.buffer,
@@ -24189,30 +24242,37 @@ class R32UintTexture extends Texture {
24189
24242
  }
24190
24243
  }
24191
24244
 
24192
- const _floatView = new Float32Array(1);
24193
- const _int32View = new Int32Array(_floatView.buffer);
24194
- let toHalfFloat = function(val) {
24195
- _floatView[0] = val;
24196
- const x = _int32View[0];
24197
- let bits = x >> 16 & 32768;
24198
- let m = x >> 12 & 2047;
24199
- const e = x >> 23 & 255;
24200
- if (e < 103) return bits;
24201
- if (e > 142) {
24202
- bits |= 31744;
24203
- bits |= (e == 255 ? 1 : 0) && x & 8388607;
24204
- return bits;
24205
- }
24206
- if (e < 114) {
24207
- m |= 2048;
24208
- bits |= (m >> 114 - e) + (m >> 113 - e & 1);
24209
- return bits;
24245
+ const _floatView$1 = new Float32Array(1);
24246
+ const _int32View$1 = new Int32Array(_floatView$1.buffer);
24247
+ function batchConvertToHalfFloat(src, dst, offset, length) {
24248
+ for (let i = 0; i < length; i++) {
24249
+ const val = src[offset + i];
24250
+ _floatView$1[0] = val;
24251
+ const x = _int32View$1[0];
24252
+ let bits = x >> 16 & 32768;
24253
+ let m = x >> 12 & 2047;
24254
+ const e = x >> 23 & 255;
24255
+ if (e < 103) {
24256
+ dst[offset + i] = bits;
24257
+ continue;
24258
+ }
24259
+ if (e > 142) {
24260
+ bits |= 31744;
24261
+ bits |= (e == 255 ? 1 : 0) && x & 8388607;
24262
+ dst[offset + i] = bits;
24263
+ continue;
24264
+ }
24265
+ if (e < 114) {
24266
+ m |= 2048;
24267
+ bits |= (m >> 114 - e) + (m >> 113 - e & 1);
24268
+ dst[offset + i] = bits;
24269
+ continue;
24270
+ }
24271
+ bits |= e - 112 << 10 | m >> 1;
24272
+ bits += m & 1;
24273
+ dst[offset + i] = bits;
24210
24274
  }
24211
- bits |= e - 112 << 10 | m >> 1;
24212
- bits += m & 1;
24213
- return bits;
24214
- };
24215
-
24275
+ }
24216
24276
  class Float16ArrayTexture extends Texture {
24217
24277
  uint16Array;
24218
24278
  floatArray;
@@ -24241,8 +24301,10 @@ class Float16ArrayTexture extends Texture {
24241
24301
  * @param height 纹理高度
24242
24302
  * @param numbers 像素数据数组
24243
24303
  * @param mipmap 是否生成Mipmap
24304
+ * @param startRow 起始行(部分更新)
24305
+ * @param rowCount 更新的行数(部分更新)
24244
24306
  */
24245
- updateTexture(width, height, numbers, mipmap = true) {
24307
+ updateTexture(width, height, numbers, mipmap = true, startRow, rowCount) {
24246
24308
  if (width != this.width || height != this.height) {
24247
24309
  this._dataBuffer && this._dataBuffer.destroy();
24248
24310
  this._dataBuffer = null;
@@ -24255,22 +24317,70 @@ class Float16ArrayTexture extends Texture {
24255
24317
  this.format = GPUTextureFormat.rgba16float;
24256
24318
  this.mipmapCount = Math.floor(mipmap ? Math.log2(width) : 1);
24257
24319
  this.createTextureDescriptor(width, height, this.mipmapCount, this.format);
24320
+ if (startRow !== void 0 && rowCount !== void 0 && rowCount < height) {
24321
+ const updateHeight = rowCount;
24322
+ const updateOffset = startRow * width * 4;
24323
+ const updateLength = updateHeight * width * 4;
24324
+ if (!this.uint16Array || this.uint16Array.length < updateOffset + updateLength) {
24325
+ if (!this.uint16Array || this.uint16Array.length < numbers.length) {
24326
+ this.uint16Array = new Uint16Array(numbers.length);
24327
+ }
24328
+ }
24329
+ const uint16Array2 = this.uint16Array;
24330
+ batchConvertToHalfFloat(numbers, uint16Array2, updateOffset, updateLength);
24331
+ const updateData = uint16Array2.subarray(updateOffset, updateOffset + updateLength);
24332
+ const neededSize2 = updateData.byteLength;
24333
+ if (!this._dataBuffer || this._dataBuffer.size < neededSize2) {
24334
+ this._dataBuffer && this._dataBuffer.destroy();
24335
+ this._dataBuffer = device.createBuffer({
24336
+ size: neededSize2,
24337
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC
24338
+ });
24339
+ }
24340
+ device.queue.writeBuffer(this._dataBuffer, 0, updateData.buffer, updateData.byteOffset, updateData.byteLength);
24341
+ const commandEncoder2 = GPUContext.beginCommandEncoder();
24342
+ commandEncoder2.copyBufferToTexture(
24343
+ {
24344
+ buffer: this._dataBuffer,
24345
+ bytesPerRow,
24346
+ offset: 0
24347
+ },
24348
+ {
24349
+ texture: this.getGPUTexture(),
24350
+ origin: [0, startRow, 0]
24351
+ // Start at row startRow
24352
+ },
24353
+ {
24354
+ width,
24355
+ height: updateHeight,
24356
+ depthOrArrayLayers: 1
24357
+ }
24358
+ );
24359
+ if (!this.useMipmap) {
24360
+ this.samplerBindingLayout.type = `filtering`;
24361
+ this.textureBindingLayout.sampleType = `float`;
24362
+ }
24363
+ GPUContext.endCommandEncoder(commandEncoder2);
24364
+ return;
24365
+ }
24258
24366
  if (!this.uint16Array || this.uint16Array.length != numbers.length) {
24259
24367
  this.uint16Array = new Uint16Array(numbers.length);
24260
24368
  }
24261
- let uint16Array = this.uint16Array;
24262
- for (let i = 0, c = uint16Array.length; i < c; i++) {
24263
- uint16Array[i] = toHalfFloat(numbers[i]);
24369
+ const uint16Array = this.uint16Array;
24370
+ batchConvertToHalfFloat(numbers, uint16Array, 0, numbers.length);
24371
+ const neededSize = uint16Array.byteLength;
24372
+ if (!this._dataBuffer || this._dataBuffer.size < neededSize) {
24373
+ this._dataBuffer && this._dataBuffer.destroy();
24374
+ this._dataBuffer = device.createBuffer({
24375
+ size: neededSize,
24376
+ usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC
24377
+ });
24264
24378
  }
24265
- const textureDataBuffer = this._dataBuffer = device.createBuffer({
24266
- size: uint16Array.byteLength,
24267
- usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.COPY_SRC
24268
- });
24269
- device.queue.writeBuffer(textureDataBuffer, 0, uint16Array);
24379
+ device.queue.writeBuffer(this._dataBuffer, 0, uint16Array.buffer, uint16Array.byteOffset, uint16Array.byteLength);
24270
24380
  const commandEncoder = GPUContext.beginCommandEncoder();
24271
24381
  commandEncoder.copyBufferToTexture(
24272
24382
  {
24273
- buffer: textureDataBuffer,
24383
+ buffer: this._dataBuffer,
24274
24384
  bytesPerRow
24275
24385
  },
24276
24386
  {
@@ -24293,6 +24403,30 @@ class Float16ArrayTexture extends Texture {
24293
24403
  }
24294
24404
  }
24295
24405
 
24406
+ const _floatView = new Float32Array(1);
24407
+ const _int32View = new Int32Array(_floatView.buffer);
24408
+ let toHalfFloat = function(val) {
24409
+ _floatView[0] = val;
24410
+ const x = _int32View[0];
24411
+ let bits = x >> 16 & 32768;
24412
+ let m = x >> 12 & 2047;
24413
+ const e = x >> 23 & 255;
24414
+ if (e < 103) return bits;
24415
+ if (e > 142) {
24416
+ bits |= 31744;
24417
+ bits |= (e == 255 ? 1 : 0) && x & 8388607;
24418
+ return bits;
24419
+ }
24420
+ if (e < 114) {
24421
+ m |= 2048;
24422
+ bits |= (m >> 114 - e) + (m >> 113 - e & 1);
24423
+ return bits;
24424
+ }
24425
+ bits |= e - 112 << 10 | m >> 1;
24426
+ bits += m & 1;
24427
+ return bits;
24428
+ };
24429
+
24296
24430
  var __getOwnPropDesc$m = Object.getOwnPropertyDescriptor;
24297
24431
  var __decorateClass$m = (decorators, target, key, kind) => {
24298
24432
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc$m(target, key) : target;
@@ -42151,7 +42285,7 @@ class PostProcessingComponent extends ComponentBase {
42151
42285
  }
42152
42286
  }
42153
42287
 
42154
- const version = "1.0.36";
42288
+ const version = "1.0.39";
42155
42289
 
42156
42290
  class Engine3D {
42157
42291
  /**
@@ -54401,6 +54535,7 @@ let GSplatStreamRenderer = class extends RenderNode {
54401
54535
  transformB;
54402
54536
  texParams;
54403
54537
  // [numSplats, texWidth, validCount, visBoost]
54538
+ _texParamDirty = true;
54404
54539
  splatOrder;
54405
54540
  // Material and geometry
54406
54541
  gsplatMaterial;
@@ -54542,7 +54677,6 @@ let GSplatStreamRenderer = class extends RenderNode {
54542
54677
  if (!wasSet) {
54543
54678
  this._splatSetFlags[index] = true;
54544
54679
  this._validCount++;
54545
- this.texParams[2] = this._validCount;
54546
54680
  }
54547
54681
  this._pendingUpdates.add(index);
54548
54682
  }
@@ -54630,14 +54764,32 @@ let GSplatStreamRenderer = class extends RenderNode {
54630
54764
  /**
54631
54765
  * Flush pending updates to GPU
54632
54766
  * Updates GPU textures with all pending changes
54767
+ * Uses partial updates when possible for better performance
54633
54768
  */
54634
54769
  flushUpdates() {
54635
54770
  if (this._pendingUpdates.size === 0) return;
54636
54771
  const w = this.size.x | 0;
54637
54772
  const h = this.size.y | 0;
54638
- this.splatColor.updateTexture(w, h, this._colorData);
54639
- this.transformA.updateTexture(w, h, this._transformAData);
54640
- this.transformB.updateTexture(w, h, this._transformBData, false);
54773
+ const pendingIndices = Array.from(this._pendingUpdates);
54774
+ if (pendingIndices.length === 0) return;
54775
+ let minRow = h;
54776
+ let maxRow = 0;
54777
+ for (const index of pendingIndices) {
54778
+ const row = Math.floor(index / w);
54779
+ if (row < minRow) minRow = row;
54780
+ if (row > maxRow) maxRow = row;
54781
+ }
54782
+ const rowCount = maxRow - minRow + 1;
54783
+ const updateRatio = rowCount / h;
54784
+ if (updateRatio < 0.5 && rowCount < h) {
54785
+ this.splatColor.updateTexture(w, h, this._colorData, minRow, rowCount);
54786
+ this.transformA.updateTexture(w, h, this._transformAData, minRow, rowCount);
54787
+ this.transformB.updateTexture(w, h, this._transformBData, false, minRow, rowCount);
54788
+ } else {
54789
+ this.splatColor.updateTexture(w, h, this._colorData);
54790
+ this.transformA.updateTexture(w, h, this._transformAData);
54791
+ this.transformB.updateTexture(w, h, this._transformBData, false);
54792
+ }
54641
54793
  this.updatePendingWorldPositions();
54642
54794
  this._pendingUpdates.clear();
54643
54795
  }
@@ -54663,13 +54815,13 @@ let GSplatStreamRenderer = class extends RenderNode {
54663
54815
  * Update splat sorting before rendering
54664
54816
  * Uses the same logic as GSplatRenderer for reliable sorting
54665
54817
  */
54666
- onBeforeUpdate(view) {
54667
- if (this._validCount > 0 && view?.camera) {
54668
- if (view.camera.viewMatrix) {
54669
- this.scheduleOrder(view.camera.viewMatrix);
54670
- }
54671
- }
54672
- }
54818
+ // public onBeforeUpdate(view?: View3D) {
54819
+ // if (this._validCount > 0 && view?.camera) {
54820
+ // if (view.camera.viewMatrix) {
54821
+ // this.scheduleOrder(view.camera.viewMatrix);
54822
+ // }
54823
+ // }
54824
+ // }
54673
54825
  /**
54674
54826
  * Update world space positions when transform changes
54675
54827
  */
@@ -54743,8 +54895,7 @@ let GSplatStreamRenderer = class extends RenderNode {
54743
54895
  }
54744
54896
  this.splatOrder.updateTexture(this.size.x, this.size.y, this._orderData);
54745
54897
  const valid = Math.max(0, Math.min(this._validCount, ev.data.count | 0));
54746
- this.texParams[2] = valid;
54747
- this.texParams[0] = valid;
54898
+ this.setCount(valid);
54748
54899
  this._updateTexParams();
54749
54900
  const newInstanceCount = Math.ceil(valid / this._batchSize);
54750
54901
  this.instanceCount = newInstanceCount;
@@ -54950,12 +55101,17 @@ let GSplatStreamRenderer = class extends RenderNode {
54950
55101
  */
54951
55102
  setVisBoost(v) {
54952
55103
  this.texParams[3] = Math.max(0, v);
55104
+ this._texParamDirty = true;
54953
55105
  }
54954
55106
  setCount(c) {
54955
55107
  this.texParams[0] = Math.max(0, c);
55108
+ this._texParamDirty = true;
54956
55109
  }
54957
55110
  _updateTexParams() {
54958
- this.gsplatMaterial.setTexParams(this.texParams);
55111
+ if (this._texParamDirty) {
55112
+ this.gsplatMaterial.setTexParams(this.texParams);
55113
+ this._texParamDirty = false;
55114
+ }
54959
55115
  }
54960
55116
  /**
54961
55117
  * Set sort throttle interval (milliseconds)
@@ -55015,6 +55171,11 @@ let GSplatStreamRenderer = class extends RenderNode {
55015
55171
  * Update node before rendering
55016
55172
  */
55017
55173
  nodeUpdate(view, passType, renderPassState, clusterLightingBuffer) {
55174
+ if (this._validCount > 0 && view?.camera && this._frameCount >= 60) {
55175
+ if (view.camera.viewMatrix) {
55176
+ this.scheduleOrder(view.camera.viewMatrix);
55177
+ }
55178
+ }
55018
55179
  if (this._pendingUpdates.size > 0 && this._frameCount >= 60) {
55019
55180
  this.flushUpdates();
55020
55181
  }
@@ -55022,6 +55183,7 @@ let GSplatStreamRenderer = class extends RenderNode {
55022
55183
  this._frameCount = 0;
55023
55184
  }
55024
55185
  this._frameCount++;
55186
+ this._updateTexParams();
55025
55187
  const worldMatrix = this.object3D.transform.worldMatrix;
55026
55188
  this.gsplatMaterial.setTransformMatrix(worldMatrix);
55027
55189
  const currentParams = `${this._minPixelCoverage},${this._maxPixelCoverage},${this._maxPixelCullDistance},${this._batchSize}`;
@@ -65755,11 +65917,11 @@ function toggleTiles(tile, renderer) {
65755
65917
  const wasVisible = tile.__wasSetVisible;
65756
65918
  const wasActive = tile.__wasSetActive;
65757
65919
  if (wasActive !== setActive) {
65758
- renderer.setTileActive(tile, setActive);
65920
+ renderer.setTileDelayedActive(tile, setActive);
65759
65921
  tile.__wasSetActive = setActive;
65760
65922
  }
65761
65923
  if (wasVisible !== setVisible) {
65762
- renderer.setTileVisible(tile, setVisible);
65924
+ renderer.setTileDelayedVisible(tile, setVisible);
65763
65925
  tile.__wasSetVisible = setVisible;
65764
65926
  }
65765
65927
  }
@@ -66132,6 +66294,8 @@ class TilesRenderer {
66132
66294
  _activeTiles = /* @__PURE__ */ new Set();
66133
66295
  // Tiles that should be hidden but are delayed due to children loading
66134
66296
  _delayedHideTiles = /* @__PURE__ */ new Set();
66297
+ _delayedVisibleTiles = /* @__PURE__ */ new Set();
66298
+ _delayedActiveTiles = /* @__PURE__ */ new Set();
66135
66299
  // Rings-specific: Scene group
66136
66300
  group;
66137
66301
  // Rings-specific: Camera management
@@ -66250,6 +66414,8 @@ class TilesRenderer {
66250
66414
  _usedSet.clear();
66251
66415
  this.updateCameraInfo();
66252
66416
  this._checkDelayedHideTiles();
66417
+ this._checkDelayedActiveTiles();
66418
+ this._checkDelayedVisibleTiles();
66253
66419
  markUsedTiles(root, this);
66254
66420
  markUsedSetLeaves(root, this);
66255
66421
  markVisibleTiles(root, this);
@@ -66683,7 +66849,6 @@ class TilesRenderer {
66683
66849
  }
66684
66850
  if (scene) {
66685
66851
  tile.cached.scene = scene;
66686
- tile.loadingState = LOADED;
66687
66852
  const bytesUsed = this._estimateBytesUsed(scene);
66688
66853
  this._bytesUsed.set(scene, bytesUsed);
66689
66854
  this.lruCache.setMemoryUsage(tile, bytesUsed);
@@ -66701,10 +66866,21 @@ class TilesRenderer {
66701
66866
  });
66702
66867
  }
66703
66868
  {
66704
- this.setTileActive(tile, true);
66869
+ this.setTileImmediateActive(tile);
66705
66870
  tile.active = true;
66871
+ tile.__wasSetActive = true;
66706
66872
  this.stats.active++;
66707
66873
  }
66874
+ {
66875
+ this.setTileImmediateVisible(tile);
66876
+ tile.visible = true;
66877
+ tile.__wasSetVisible = true;
66878
+ this.stats.visible++;
66879
+ }
66880
+ tile.loadingState = LOADED;
66881
+ tile.usedLastFrame = true;
66882
+ markVisibleTiles(tile, this);
66883
+ toggleTiles(tile, this);
66708
66884
  } else {
66709
66885
  tile.loadingState = FAILED;
66710
66886
  this.stats.failed++;
@@ -66720,33 +66896,46 @@ class TilesRenderer {
66720
66896
  /**
66721
66897
  * Set tile active state
66722
66898
  */
66723
- setTileActive(tile, active) {
66899
+ setTileDelayedActive(tile, active) {
66724
66900
  if (active) {
66725
66901
  this._activeTiles.add(tile);
66726
66902
  if (this._delayedHideTiles.has(tile)) {
66727
66903
  this._delayedHideTiles.delete(tile);
66728
66904
  }
66905
+ if (!this._delayedActiveTiles.has(tile)) {
66906
+ this._delayedActiveTiles.add(tile);
66907
+ }
66729
66908
  } else {
66730
66909
  this._activeTiles.delete(tile);
66910
+ if (!this._delayedHideTiles.has(tile)) {
66911
+ this._delayedHideTiles.add(tile);
66912
+ }
66913
+ if (this._delayedActiveTiles.has(tile)) {
66914
+ this._delayedActiveTiles.delete(tile);
66915
+ }
66731
66916
  }
66732
- const scene = tile.cached.scene;
66733
- if (!scene) {
66734
- return;
66735
- }
66736
- if (active) {
66737
- if (!this.group.entityChildren.includes(scene)) {
66738
- if (scene.parent) {
66739
- scene.parent.object3D.removeChild(scene);
66917
+ }
66918
+ setTileImmediateActive(tile) {
66919
+ if (tile.hasRenderableContent) {
66920
+ const scene = tile.cached.scene;
66921
+ if (scene) {
66922
+ if (!this.group.entityChildren.includes(scene)) {
66923
+ if (scene.parent) {
66924
+ scene.parent.object3D.removeChild(scene);
66925
+ }
66926
+ this.group.addChild(scene);
66927
+ }
66928
+ if (tile.cached.worldTransform) {
66929
+ this._applyWorldTransform(scene.transform, tile.cached.worldTransform);
66740
66930
  }
66741
- this.group.addChild(scene);
66742
- }
66743
- if (tile.cached.worldTransform) {
66744
- this._applyWorldTransform(scene.transform, tile.cached.worldTransform);
66745
66931
  }
66746
- scene.transform.enable = true;
66747
- } else {
66748
- if (!this._delayedHideTiles.has(tile)) {
66749
- this._delayedHideTiles.add(tile);
66932
+ }
66933
+ }
66934
+ setTileImmediateVisible(tile) {
66935
+ if (tile.hasRenderableContent) {
66936
+ const scene = tile.cached.scene;
66937
+ if (scene) {
66938
+ scene.transform.enable = true;
66750
66939
  }
66751
66940
  }
66752
66941
  }
@@ -66758,35 +66947,67 @@ class TilesRenderer {
66758
66947
  return;
66759
66948
  }
66760
66949
  for (const tile of this._delayedHideTiles) {
66761
- this._delayedHideTiles.delete(tile);
66762
66950
  const scene = tile.cached.scene;
66763
66951
  if (scene) {
66764
66952
  scene.transform.enable = false;
66953
+ this._delayedHideTiles.delete(tile);
66954
+ }
66955
+ }
66956
+ }
66957
+ _checkDelayedActiveTiles() {
66958
+ for (const tile of this._delayedActiveTiles) {
66959
+ if (tile.hasRenderableContent) {
66960
+ const scene = tile.cached.scene;
66961
+ if (scene) {
66962
+ if (!this.group.entityChildren.includes(scene)) {
66963
+ if (scene.parent) {
66964
+ scene.parent.object3D.removeChild(scene);
66965
+ }
66966
+ this.group.addChild(scene);
66967
+ }
66968
+ if (tile.cached.worldTransform) {
66969
+ this._applyWorldTransform(scene.transform, tile.cached.worldTransform);
66970
+ }
66971
+ this._delayedActiveTiles.delete(tile);
66972
+ }
66973
+ } else {
66974
+ this._delayedActiveTiles.delete(tile);
66975
+ }
66976
+ }
66977
+ }
66978
+ _checkDelayedVisibleTiles() {
66979
+ for (const tile of this._delayedVisibleTiles) {
66980
+ if (tile.hasRenderableContent) {
66981
+ const scene = tile.cached.scene;
66982
+ if (scene) {
66983
+ scene.transform.enable = true;
66984
+ this._delayedVisibleTiles.delete(tile);
66985
+ }
66986
+ } else {
66987
+ this._delayedVisibleTiles.delete(tile);
66765
66988
  }
66766
66989
  }
66767
66990
  }
66768
66991
  /**
66769
66992
  * Set tile visibility
66770
66993
  */
66771
- setTileVisible(tile, visible) {
66994
+ setTileDelayedVisible(tile, visible) {
66772
66995
  if (visible) {
66773
66996
  this._visibleTiles.add(tile);
66774
66997
  if (this._delayedHideTiles.has(tile)) {
66775
66998
  this._delayedHideTiles.delete(tile);
66776
66999
  }
67000
+ if (!this._delayedVisibleTiles.has(tile)) {
67001
+ this._delayedVisibleTiles.add(tile);
67002
+ }
66777
67003
  } else {
66778
67004
  this._visibleTiles.delete(tile);
66779
- }
66780
- const scene = tile.cached.scene;
66781
- if (!scene) {
66782
- return;
66783
- }
66784
- if (visible) {
66785
- scene.transform.enable = true;
66786
- } else {
66787
67005
  if (!this._delayedHideTiles.has(tile)) {
66788
67006
  this._delayedHideTiles.add(tile);
66789
67007
  }
67008
+ if (this._delayedVisibleTiles.has(tile)) {
67009
+ this._delayedVisibleTiles.delete(tile);
67010
+ }
66790
67011
  }
66791
67012
  }
66792
67013
  /**