@ifc-lite/renderer 1.43.0 → 1.44.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.
Files changed (85) hide show
  1. package/dist/camera-animation.d.ts +20 -32
  2. package/dist/camera-animation.d.ts.map +1 -1
  3. package/dist/camera-animation.js +71 -358
  4. package/dist/camera-animation.js.map +1 -1
  5. package/dist/camera-controls.d.ts +11 -51
  6. package/dist/camera-controls.d.ts.map +1 -1
  7. package/dist/camera-controls.js +140 -12
  8. package/dist/camera-controls.js.map +1 -1
  9. package/dist/camera-first-person.d.ts +52 -0
  10. package/dist/camera-first-person.d.ts.map +1 -0
  11. package/dist/camera-first-person.js +119 -0
  12. package/dist/camera-first-person.js.map +1 -0
  13. package/dist/camera-framing.d.ts +86 -0
  14. package/dist/camera-framing.d.ts.map +1 -0
  15. package/dist/camera-framing.js +230 -0
  16. package/dist/camera-framing.js.map +1 -0
  17. package/dist/camera-guards.d.ts +148 -0
  18. package/dist/camera-guards.d.ts.map +1 -0
  19. package/dist/camera-guards.js +150 -0
  20. package/dist/camera-guards.js.map +1 -0
  21. package/dist/camera-matrices.d.ts +14 -0
  22. package/dist/camera-matrices.d.ts.map +1 -0
  23. package/dist/camera-matrices.js +146 -0
  24. package/dist/camera-matrices.js.map +1 -0
  25. package/dist/camera-preset-view.d.ts +56 -0
  26. package/dist/camera-preset-view.d.ts.map +1 -0
  27. package/dist/camera-preset-view.js +180 -0
  28. package/dist/camera-preset-view.js.map +1 -0
  29. package/dist/camera-projection.d.ts +1 -1
  30. package/dist/camera-projection.d.ts.map +1 -1
  31. package/dist/camera-projection.js +83 -30
  32. package/dist/camera-projection.js.map +1 -1
  33. package/dist/camera-state.d.ts +62 -0
  34. package/dist/camera-state.d.ts.map +1 -0
  35. package/dist/camera-state.js +5 -0
  36. package/dist/camera-state.js.map +1 -0
  37. package/dist/camera.d.ts +22 -11
  38. package/dist/camera.d.ts.map +1 -1
  39. package/dist/camera.js +75 -120
  40. package/dist/camera.js.map +1 -1
  41. package/dist/environment.d.ts.map +1 -1
  42. package/dist/environment.js +23 -1
  43. package/dist/environment.js.map +1 -1
  44. package/dist/index.d.ts +154 -8
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +294 -45
  47. package/dist/index.js.map +1 -1
  48. package/dist/math.d.ts +49 -1
  49. package/dist/math.d.ts.map +1 -1
  50. package/dist/math.js +122 -67
  51. package/dist/math.js.map +1 -1
  52. package/dist/renderer-symbolic-overlays.d.ts.map +1 -1
  53. package/dist/renderer-symbolic-overlays.js +20 -25
  54. package/dist/renderer-symbolic-overlays.js.map +1 -1
  55. package/dist/scene-geometry.d.ts +32 -0
  56. package/dist/scene-geometry.d.ts.map +1 -1
  57. package/dist/scene-geometry.js +66 -0
  58. package/dist/scene-geometry.js.map +1 -1
  59. package/dist/scene.d.ts.map +1 -1
  60. package/dist/scene.js +22 -97
  61. package/dist/scene.js.map +1 -1
  62. package/dist/section-2d-lift.d.ts +105 -0
  63. package/dist/section-2d-lift.d.ts.map +1 -0
  64. package/dist/section-2d-lift.js +162 -0
  65. package/dist/section-2d-lift.js.map +1 -0
  66. package/dist/section-2d-line-buffer.d.ts +58 -0
  67. package/dist/section-2d-line-buffer.d.ts.map +1 -0
  68. package/dist/section-2d-line-buffer.js +109 -0
  69. package/dist/section-2d-line-buffer.js.map +1 -0
  70. package/dist/section-2d-overlay.d.ts +28 -77
  71. package/dist/section-2d-overlay.d.ts.map +1 -1
  72. package/dist/section-2d-overlay.js +161 -593
  73. package/dist/section-2d-overlay.js.map +1 -1
  74. package/dist/section-plane-basis.d.ts +22 -3
  75. package/dist/section-plane-basis.d.ts.map +1 -1
  76. package/dist/section-plane-basis.js +51 -10
  77. package/dist/section-plane-basis.js.map +1 -1
  78. package/dist/section-plane.d.ts.map +1 -1
  79. package/dist/section-plane.js +10 -1
  80. package/dist/section-plane.js.map +1 -1
  81. package/dist/shaders/section-2d-overlay.wgsl.d.ts +102 -0
  82. package/dist/shaders/section-2d-overlay.wgsl.d.ts.map +1 -0
  83. package/dist/shaders/section-2d-overlay.wgsl.js +281 -0
  84. package/dist/shaders/section-2d-overlay.wgsl.js.map +1 -0
  85. package/package.json +3 -2
package/dist/scene.js CHANGED
@@ -4,7 +4,7 @@
4
4
  import { BATCH_CONSTANTS } from './constants.js';
5
5
  import { prepareRayDirInv, raycastBoundingBoxes, raycastTriangles, rayIntersectsBox, } from './scene-raycaster.js';
6
6
  import { selectBoundingBoxesInRect } from './scene-rect-select.js';
7
- import { mergeGeometry, splitMeshDataForBufferLimit, colorSaltByte, packEntityLane } from './scene-geometry.js';
7
+ import { mergeGeometry, splitMeshDataForBufferLimit, colorSaltByte, packEntityLane, worldAabbFromPieces } from './scene-geometry.js';
8
8
  import { sumResidentGpuBytes } from './render-stats.js';
9
9
  import { simplifyIndicesByClustering, lodCellSizeForBounds, LOD_MIN_TRIANGLES } from './lod-simplify.js';
10
10
  import { quantizeInterleaved } from './quantize.js';
@@ -2049,40 +2049,17 @@ export class Scene {
2049
2049
  return;
2050
2050
  }
2051
2051
  // Preserve lightweight per-entity bounds so large-model picking and
2052
- // selection can continue to work after we discard CPU mesh arrays.
2052
+ // selection can continue to work after we discard CPU mesh arrays. An
2053
+ // entity with no usable vertex gets NO entry: after release, the keys of
2054
+ // `boundingBoxes` become the authoritative id set (`getAllMeshDataExpressIds`),
2055
+ // so caching the inverted-empty sentinel here would publish a geometry-less
2056
+ // entity to every CPU consumer with a garbage box (#2480).
2053
2057
  for (const [expressId, pieces] of this.meshDataMap) {
2054
2058
  if (this.boundingBoxes.has(expressId))
2055
2059
  continue;
2056
- let minX = Infinity, minY = Infinity, minZ = Infinity;
2057
- let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity;
2058
- for (const piece of pieces) {
2059
- const positions = piece.positions;
2060
- // world = origin + position (per-element local frame); bake WORLD bbox.
2061
- const ox = piece.origin ? piece.origin[0] : 0;
2062
- const oy = piece.origin ? piece.origin[1] : 0;
2063
- const oz = piece.origin ? piece.origin[2] : 0;
2064
- for (let i = 0; i < positions.length; i += 3) {
2065
- const x = positions[i] + ox;
2066
- const y = positions[i + 1] + oy;
2067
- const z = positions[i + 2] + oz;
2068
- if (x < minX)
2069
- minX = x;
2070
- if (y < minY)
2071
- minY = y;
2072
- if (z < minZ)
2073
- minZ = z;
2074
- if (x > maxX)
2075
- maxX = x;
2076
- if (y > maxY)
2077
- maxY = y;
2078
- if (z > maxZ)
2079
- maxZ = z;
2080
- }
2081
- }
2082
- this.boundingBoxes.set(expressId, {
2083
- min: { x: minX, y: minY, z: minZ },
2084
- max: { x: maxX, y: maxY, z: maxZ },
2085
- });
2060
+ const bbox = worldAabbFromPieces(pieces);
2061
+ if (bbox)
2062
+ this.boundingBoxes.set(expressId, bbox);
2086
2063
  }
2087
2064
  this.streamingFragments = [];
2088
2065
  this.buckets.clear();
@@ -2126,40 +2103,15 @@ export class Scene {
2126
2103
  `Call finalizeStreaming()/rebuildPendingBatches() first.`);
2127
2104
  return;
2128
2105
  }
2129
- // 1. Precompute and cache ALL entity bounding boxes before releasing data
2106
+ // 1. Precompute and cache ALL entity bounding boxes before releasing data.
2107
+ // Same rule as `finishEphemeralStreaming`: an entity with no usable vertex
2108
+ // gets no entry rather than the inverted-empty sentinel (#2480).
2130
2109
  for (const [expressId, pieces] of this.meshDataMap) {
2131
2110
  if (this.boundingBoxes.has(expressId))
2132
2111
  continue;
2133
- let minX = Infinity, minY = Infinity, minZ = Infinity;
2134
- let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity;
2135
- for (const piece of pieces) {
2136
- const positions = piece.positions;
2137
- // world = origin + position (per-element local frame); bake WORLD bbox.
2138
- const ox = piece.origin ? piece.origin[0] : 0;
2139
- const oy = piece.origin ? piece.origin[1] : 0;
2140
- const oz = piece.origin ? piece.origin[2] : 0;
2141
- for (let i = 0; i < positions.length; i += 3) {
2142
- const x = positions[i] + ox;
2143
- const y = positions[i + 1] + oy;
2144
- const z = positions[i + 2] + oz;
2145
- if (x < minX)
2146
- minX = x;
2147
- if (y < minY)
2148
- minY = y;
2149
- if (z < minZ)
2150
- minZ = z;
2151
- if (x > maxX)
2152
- maxX = x;
2153
- if (y > maxY)
2154
- maxY = y;
2155
- if (z > maxZ)
2156
- maxZ = z;
2157
- }
2158
- }
2159
- this.boundingBoxes.set(expressId, {
2160
- min: { x: minX, y: minY, z: minZ },
2161
- max: { x: maxX, y: maxY, z: maxZ },
2162
- });
2112
+ const bbox = worldAabbFromPieces(pieces);
2113
+ if (bbox)
2114
+ this.boundingBoxes.set(expressId, bbox);
2163
2115
  }
2164
2116
  // 2. Clear the heavy data structures — typed arrays become GC-eligible
2165
2117
  this.meshDataMap.clear();
@@ -3713,41 +3665,14 @@ export class Scene {
3713
3665
  const cached = this.boundingBoxes.get(expressId);
3714
3666
  if (cached)
3715
3667
  return cached;
3716
- // Compute from mesh data
3717
- const pieces = this.meshDataMap.get(expressId);
3718
- if (!pieces || pieces.length === 0)
3668
+ // Compute from mesh data. `null` covers both "no pieces at all" and
3669
+ // "pieces with no vertex a box can be built from" — and, critically, is
3670
+ // NOT cached (#2480): a transient empty piece must not poison the entry
3671
+ // for an entity that later gains real geometry, and this cache has no
3672
+ // invalidation tied to that.
3673
+ const bbox = worldAabbFromPieces(this.meshDataMap.get(expressId));
3674
+ if (!bbox)
3719
3675
  return null;
3720
- let minX = Infinity, minY = Infinity, minZ = Infinity;
3721
- let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity;
3722
- for (const piece of pieces) {
3723
- const positions = piece.positions;
3724
- // world = origin + position (per-element local frame); origin absent/[0,0,0]
3725
- // for legacy absolute meshes.
3726
- const ox = piece.origin ? piece.origin[0] : 0;
3727
- const oy = piece.origin ? piece.origin[1] : 0;
3728
- const oz = piece.origin ? piece.origin[2] : 0;
3729
- for (let i = 0; i < positions.length; i += 3) {
3730
- const x = positions[i] + ox;
3731
- const y = positions[i + 1] + oy;
3732
- const z = positions[i + 2] + oz;
3733
- if (x < minX)
3734
- minX = x;
3735
- if (y < minY)
3736
- minY = y;
3737
- if (z < minZ)
3738
- minZ = z;
3739
- if (x > maxX)
3740
- maxX = x;
3741
- if (y > maxY)
3742
- maxY = y;
3743
- if (z > maxZ)
3744
- maxZ = z;
3745
- }
3746
- }
3747
- const bbox = {
3748
- min: { x: minX, y: minY, z: minZ },
3749
- max: { x: maxX, y: maxY, z: maxZ },
3750
- };
3751
3676
  this.boundingBoxes.set(expressId, bbox);
3752
3677
  return bbox;
3753
3678
  }