@almadar/ui 5.143.0 → 5.145.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.
@@ -2,7 +2,7 @@ import React3, { createContext, forwardRef, useRef, useState, useMemo, useEffect
2
2
  import { EventBusContext, useTraitScopeChain } from '@almadar/ui/providers';
3
3
  import { createLogger } from '@almadar/logger';
4
4
  import { Canvas, useThree, useFrame } from '@react-three/fiber';
5
- import * as THREE11 from 'three';
5
+ import * as THREE5 from 'three';
6
6
  import { Vector3, QuadraticBezierCurve3, MathUtils, Quaternion } from 'three';
7
7
  import { RoomEnvironment } from 'three/examples/jsm/environments/RoomEnvironment.js';
8
8
  import { Grid, OrbitControls, Billboard, Text, Stars, Sparkles, Html, RoundedBox } from '@react-three/drei';
@@ -507,7 +507,7 @@ function Lighting3D({
507
507
  "directionalLightHelper",
508
508
  {
509
509
  args: [
510
- new THREE11.DirectionalLight(directionalColor, directionalIntensity),
510
+ new THREE5.DirectionalLight(directionalColor, directionalIntensity),
511
511
  5
512
512
  ]
513
513
  }
@@ -564,8 +564,8 @@ function FollowCamera3D({
564
564
  offset
565
565
  }) {
566
566
  const { camera } = useThree();
567
- const look = useRef(new THREE11.Vector3(target[0], target[1], target[2]));
568
- const goal = useRef(new THREE11.Vector3());
567
+ const look = useRef(new THREE5.Vector3(target[0], target[1], target[2]));
568
+ const goal = useRef(new THREE5.Vector3());
569
569
  useFrame((_, delta) => {
570
570
  const t = Math.min(1, delta * 5);
571
571
  goal.current.set(target[0] + offset[0], target[1] + offset[1], target[2] + offset[2]);
@@ -765,6 +765,10 @@ var atlasCache = /* @__PURE__ */ new Map();
765
765
  function isTilesheet(a) {
766
766
  return typeof a.tileWidth === "number";
767
767
  }
768
+ function isSpriteSheetAtlas(a) {
769
+ const s = a;
770
+ return typeof s.frameWidth === "number" && typeof s.frameHeight === "number" && typeof s.animations === "object";
771
+ }
768
772
  function getAtlas(url, onReady) {
769
773
  if (atlasCache.has(url)) return atlasCache.get(url) ?? void 0;
770
774
  atlasCache.set(url, void 0);
@@ -801,6 +805,7 @@ function subRectFor(atlas, sprite) {
801
805
  sh: atlas.tileHeight
802
806
  };
803
807
  }
808
+ if (isSpriteSheetAtlas(atlas)) return null;
804
809
  const st = atlas.subTextures[sprite];
805
810
  if (!st) return null;
806
811
  return { sx: st.x, sy: st.y, sw: st.width, sh: st.height };
@@ -894,12 +899,12 @@ function ModelLoader({
894
899
  if (!loadedModel) return null;
895
900
  const cloned = clone(loadedModel);
896
901
  cloned.updateMatrixWorld(true);
897
- const tintColor = tint ? new THREE11.Color(tint) : null;
902
+ const tintColor = tint ? new THREE5.Color(tint) : null;
898
903
  cloned.traverse((child) => {
899
- if (child instanceof THREE11.Mesh) {
904
+ if (child instanceof THREE5.Mesh) {
900
905
  child.castShadow = castShadow;
901
906
  child.receiveShadow = receiveShadow;
902
- if (tintColor && child.material instanceof THREE11.MeshStandardMaterial) {
907
+ if (tintColor && child.material instanceof THREE5.MeshStandardMaterial) {
903
908
  const mat = child.material.clone();
904
909
  mat.color.multiply(tintColor);
905
910
  child.material = mat;
@@ -908,7 +913,7 @@ function ModelLoader({
908
913
  });
909
914
  return cloned;
910
915
  }, [loadedModel, castShadow, receiveShadow, tint]);
911
- const mixer = useMemo(() => model ? new THREE11.AnimationMixer(model) : null, [model]);
916
+ const mixer = useMemo(() => model ? new THREE5.AnimationMixer(model) : null, [model]);
912
917
  useEffect(() => {
913
918
  if (!mixer || !animation || clips.length === 0) return;
914
919
  const wanted = animation.toLowerCase();
@@ -925,8 +930,8 @@ function ModelLoader({
925
930
  });
926
931
  const normFactor = useMemo(() => {
927
932
  if (!model) return 1;
928
- const box = new THREE11.Box3().setFromObject(model);
929
- const size = new THREE11.Vector3();
933
+ const box = new THREE5.Box3().setFromObject(model);
934
+ const size = new THREE5.Vector3();
930
935
  box.getSize(size);
931
936
  const maxDim = Math.max(size.x, size.y, size.z);
932
937
  if (!Number.isFinite(maxDim) || maxDim < 0.05) return 1;
@@ -1016,7 +1021,7 @@ var warnUnsupported3d = (kind) => {
1016
1021
  warnedUnsupported.add(kind);
1017
1022
  mesh3dLog.warn("unsupported drawable kind on the 3D backend \u2014 skipped", { kind });
1018
1023
  };
1019
- var CrossOriginTextureLoader = class extends THREE11.TextureLoader {
1024
+ var CrossOriginTextureLoader = class extends THREE5.TextureLoader {
1020
1025
  constructor() {
1021
1026
  super();
1022
1027
  this.crossOrigin = "anonymous";
@@ -1034,7 +1039,7 @@ function useBillboardTexture(url) {
1034
1039
  url,
1035
1040
  (texture) => {
1036
1041
  if (!active) return;
1037
- texture.colorSpace = THREE11.SRGBColorSpace;
1042
+ texture.colorSpace = THREE5.SRGBColorSpace;
1038
1043
  setState({ texture, error: false });
1039
1044
  },
1040
1045
  void 0,
@@ -1087,7 +1092,7 @@ function SpriteBillboard({ node, world, cellSize = 1, groupOpacity = 1 }) {
1087
1092
  }, [texture, frame, node.height, node.width, anchor, cellSize]);
1088
1093
  const groundGeometry = React3.useMemo(() => {
1089
1094
  if (anchor !== "top-left" || !texture || !atlasReady) return null;
1090
- const g = new THREE11.PlaneGeometry(size.width, size.height);
1095
+ const g = new THREE5.PlaneGeometry(size.width, size.height);
1091
1096
  g.rotateX(-Math.PI / 2);
1092
1097
  return g;
1093
1098
  }, [anchor, texture, atlasReady, size.width, size.height]);
@@ -1095,15 +1100,15 @@ function SpriteBillboard({ node, world, cellSize = 1, groupOpacity = 1 }) {
1095
1100
  if (anchor === "top-left") {
1096
1101
  return /* @__PURE__ */ jsx("group", { position: [world[0] + size.width / 2, 0.02, world[2] + size.height / 2], children: /* @__PURE__ */ jsxs("mesh", { rotation: [-Math.PI / 2, 0, 0], children: [
1097
1102
  /* @__PURE__ */ jsx("planeGeometry", { args: [size.width, size.height] }),
1098
- /* @__PURE__ */ jsx("meshBasicMaterial", { color: textureError ? 16729156 : 8947848, transparent: true, opacity: 0.6, side: THREE11.DoubleSide })
1103
+ /* @__PURE__ */ jsx("meshBasicMaterial", { color: textureError ? 16729156 : 8947848, transparent: true, opacity: 0.6, side: THREE5.DoubleSide })
1099
1104
  ] }) });
1100
1105
  }
1101
1106
  return /* @__PURE__ */ jsx("group", { position: [world[0], world[1] + size.height / 2, world[2]], children: /* @__PURE__ */ jsxs("mesh", { children: [
1102
1107
  /* @__PURE__ */ jsx("planeGeometry", { args: [size.width, size.height] }),
1103
- /* @__PURE__ */ jsx("meshBasicMaterial", { color: textureError ? 16729156 : 8947848, transparent: true, opacity: 0.6, side: THREE11.DoubleSide })
1108
+ /* @__PURE__ */ jsx("meshBasicMaterial", { color: textureError ? 16729156 : 8947848, transparent: true, opacity: 0.6, side: THREE5.DoubleSide })
1104
1109
  ] }) });
1105
1110
  }
1106
- texture.magFilter = texture.minFilter = THREE11.NearestFilter;
1111
+ texture.magFilter = texture.minFilter = THREE5.NearestFilter;
1107
1112
  texture.needsUpdate = true;
1108
1113
  if (frame) {
1109
1114
  texture.repeat.set(frame.w / size.imgW, frame.h / size.imgH);
@@ -1116,7 +1121,7 @@ function SpriteBillboard({ node, world, cellSize = 1, groupOpacity = 1 }) {
1116
1121
  map: texture,
1117
1122
  transparent: true,
1118
1123
  alphaTest: 0.1,
1119
- side: THREE11.DoubleSide,
1124
+ side: THREE5.DoubleSide,
1120
1125
  opacity: (node.opacity ?? 1) * groupOpacity
1121
1126
  }
1122
1127
  ) }) });
@@ -1129,7 +1134,7 @@ function SpriteBillboard({ node, world, cellSize = 1, groupOpacity = 1 }) {
1129
1134
  map: texture,
1130
1135
  transparent: true,
1131
1136
  alphaTest: 0.1,
1132
- side: THREE11.DoubleSide,
1137
+ side: THREE5.DoubleSide,
1133
1138
  opacity: node.opacity ?? 1
1134
1139
  }
1135
1140
  )
@@ -1198,7 +1203,7 @@ function Shape3D({ node, projector, groupOpacity = 1 }) {
1198
1203
  }
1199
1204
  case "poly": {
1200
1205
  if (!node.points || node.points.length === 0) return null;
1201
- const s = new THREE11.Shape();
1206
+ const s = new THREE5.Shape();
1202
1207
  node.points.forEach((p, i) => {
1203
1208
  if (i === 0) s.moveTo(p.x, p.y);
1204
1209
  else s.lineTo(p.x, p.y);
@@ -1216,7 +1221,7 @@ function Shape3D({ node, projector, groupOpacity = 1 }) {
1216
1221
  }
1217
1222
  return /* @__PURE__ */ jsx("group", { ref: groupRef, position: [world[0], world[1] + 0.02, world[2]], children: /* @__PURE__ */ jsxs("mesh", { rotation: [-Math.PI / 2, 0, 0], children: [
1218
1223
  geometry,
1219
- /* @__PURE__ */ jsx("meshBasicMaterial", { ref: materialRef, color, transparent: true, opacity: (node.opacity ?? 1) * groupOpacity, side: THREE11.DoubleSide })
1224
+ /* @__PURE__ */ jsx("meshBasicMaterial", { ref: materialRef, color, transparent: true, opacity: (node.opacity ?? 1) * groupOpacity, side: THREE5.DoubleSide })
1220
1225
  ] }) });
1221
1226
  }
1222
1227
  function Text3D({ node, projector, groupOpacity = 1 }) {
@@ -1238,6 +1243,18 @@ function Text3D({ node, projector, groupOpacity = 1 }) {
1238
1243
  ) });
1239
1244
  }
1240
1245
  var GROUND_ROTATION = [-Math.PI / 2, 0, 0];
1246
+ var textureCache = /* @__PURE__ */ new Map();
1247
+ function getMeshTexture(url) {
1248
+ const cached = textureCache.get(url);
1249
+ if (cached) return cached;
1250
+ const texture = new THREE5.TextureLoader().load(url);
1251
+ texture.flipY = false;
1252
+ texture.colorSpace = THREE5.SRGBColorSpace;
1253
+ texture.wrapS = THREE5.RepeatWrapping;
1254
+ texture.wrapT = THREE5.RepeatWrapping;
1255
+ textureCache.set(url, texture);
1256
+ return texture;
1257
+ }
1241
1258
  function polyhedronGeometry(node, cellSize) {
1242
1259
  const verts = node.vertices;
1243
1260
  const faces = node.faces;
@@ -1258,8 +1275,16 @@ function polyhedronGeometry(node, cellSize) {
1258
1275
  index.push(a, c, b);
1259
1276
  }
1260
1277
  if (index.length === 0) return null;
1261
- const geometry = new THREE11.BufferGeometry();
1262
- geometry.setAttribute("position", new THREE11.BufferAttribute(positions, 3));
1278
+ const geometry = new THREE5.BufferGeometry();
1279
+ geometry.setAttribute("position", new THREE5.BufferAttribute(positions, 3));
1280
+ if (node.uvs && node.uvs.length === verts.length) {
1281
+ const uv = new Float32Array(verts.length * 2);
1282
+ for (let i = 0; i < verts.length; i++) {
1283
+ uv[i * 2] = node.uvs[i][0];
1284
+ uv[i * 2 + 1] = node.uvs[i][1];
1285
+ }
1286
+ geometry.setAttribute("uv", new THREE5.BufferAttribute(uv, 2));
1287
+ }
1263
1288
  geometry.setIndex(index);
1264
1289
  geometry.computeVertexNormals();
1265
1290
  const skin = node.skin;
@@ -1272,8 +1297,8 @@ function polyhedronGeometry(node, cellSize) {
1272
1297
  skinWeight[i * 4 + k] = skin.weights[i][k] ?? 0;
1273
1298
  }
1274
1299
  }
1275
- geometry.setAttribute("skinIndex", new THREE11.BufferAttribute(skinIndex, 4));
1276
- geometry.setAttribute("skinWeight", new THREE11.BufferAttribute(skinWeight, 4));
1300
+ geometry.setAttribute("skinIndex", new THREE5.BufferAttribute(skinIndex, 4));
1301
+ geometry.setAttribute("skinWeight", new THREE5.BufferAttribute(skinWeight, 4));
1277
1302
  }
1278
1303
  const size = Math.max(bounds.max[0] - bounds.min[0], bounds.max[1] - bounds.min[1], bounds.max[2] - bounds.min[2]) * cellSize;
1279
1304
  return { geometry, lift: -bounds.min[2] * cellSize, size };
@@ -1315,9 +1340,9 @@ function meshGeometry(node, cellSize) {
1315
1340
  }
1316
1341
  var warnedPolyhedronOutline = false;
1317
1342
  var SIDE_MAP = {
1318
- front: THREE11.FrontSide,
1319
- back: THREE11.BackSide,
1320
- double: THREE11.DoubleSide
1343
+ front: THREE5.FrontSide,
1344
+ back: THREE5.BackSide,
1345
+ double: THREE5.DoubleSide
1321
1346
  };
1322
1347
  function meshMaterial(mat, opacity, ref) {
1323
1348
  const m = mat ?? {};
@@ -1326,7 +1351,8 @@ function meshMaterial(mat, opacity, ref) {
1326
1351
  color: m.color ?? "#ffffff",
1327
1352
  transparent: opacity < 1,
1328
1353
  opacity,
1329
- side: SIDE_MAP[m.side ?? "front"]
1354
+ side: SIDE_MAP[m.side ?? "front"],
1355
+ ...m.map ? { map: getMeshTexture(m.map) } : {}
1330
1356
  };
1331
1357
  const emissive = m.emissive ? { emissive: m.emissive, emissiveIntensity: m.emissiveIntensity ?? 1 } : {};
1332
1358
  switch (m.kind ?? "standard") {
@@ -1384,13 +1410,13 @@ function SkinnedPolyhedron3D({
1384
1410
  if (mesh.skeleton && mesh.skeleton.bones.length === bones.length && mesh.skeleton.bones.every((b, i) => b === bones[i])) return;
1385
1411
  if (skin.inverseBindMatrices.length !== bones.length) return;
1386
1412
  const inverses = skin.inverseBindMatrices.map((m) => {
1387
- const mat = new THREE11.Matrix4().fromArray(m);
1413
+ const mat = new THREE5.Matrix4().fromArray(m);
1388
1414
  mat.elements[12] *= cellSize;
1389
1415
  mat.elements[13] *= cellSize;
1390
1416
  mat.elements[14] *= cellSize;
1391
1417
  return mat;
1392
1418
  });
1393
- mesh.bind(new THREE11.Skeleton(bones, inverses), new THREE11.Matrix4());
1419
+ mesh.bind(new THREE5.Skeleton(bones, inverses), new THREE5.Matrix4());
1394
1420
  }, [registryTick, skin, boneStore, geometry, cellSize]);
1395
1421
  useEffect(() => {
1396
1422
  const mesh = meshRef.current;
@@ -1497,7 +1523,7 @@ function Mesh3D({
1497
1523
  "meshBasicMaterial",
1498
1524
  {
1499
1525
  color: node.outline.color ?? "#101014",
1500
- side: THREE11.BackSide,
1526
+ side: THREE5.BackSide,
1501
1527
  transparent: opacity < 1,
1502
1528
  opacity
1503
1529
  }
@@ -1543,7 +1569,7 @@ function Group3D({
1543
1569
  const parentStore = useContext(BoneRegistryContext);
1544
1570
  const scopedStore = useMemo(() => node.skeleton ? new BoneStore() : null, [node.skeleton]);
1545
1571
  const boneStore = scopedStore ?? parentStore;
1546
- const boneObject = useMemo(() => node.bone ? new THREE11.Bone() : null, [node.bone]);
1572
+ const boneObject = useMemo(() => node.bone ? new THREE5.Bone() : null, [node.bone]);
1547
1573
  useEffect(() => {
1548
1574
  if (!node.bone || !boneStore || !boneObject) return;
1549
1575
  return boneStore.register(node.bone, boneObject);
@@ -1583,10 +1609,26 @@ function cn(...inputs) {
1583
1609
  }
1584
1610
  var DEFAULT_GRID_CONFIG = {
1585
1611
  cellSize: 1};
1612
+ function CameraPose({
1613
+ position,
1614
+ fov,
1615
+ controls
1616
+ }) {
1617
+ const camera = useThree((s) => s.camera);
1618
+ useEffect(() => {
1619
+ camera.position.set(position[0], position[1], position[2]);
1620
+ if (camera.isPerspectiveCamera) {
1621
+ camera.fov = fov;
1622
+ camera.updateProjectionMatrix();
1623
+ }
1624
+ controls.current?.update();
1625
+ }, [camera, position, fov, controls]);
1626
+ return null;
1627
+ }
1586
1628
  function RoomEnvironment3D() {
1587
1629
  const { gl, scene } = useThree(({ gl: gl2, scene: scene2 }) => ({ gl: gl2, scene: scene2 }));
1588
1630
  useEffect(() => {
1589
- const pmremGenerator = new THREE11.PMREMGenerator(gl);
1631
+ const pmremGenerator = new THREE5.PMREMGenerator(gl);
1590
1632
  const envTexture = pmremGenerator.fromScene(new RoomEnvironment(), 0.04).texture;
1591
1633
  scene.environment = envTexture;
1592
1634
  return () => {
@@ -1622,6 +1664,7 @@ var Canvas3DHost = forwardRef(
1622
1664
  keyUpMap,
1623
1665
  pixelsPerUnit,
1624
1666
  fov,
1667
+ azimuth,
1625
1668
  lighting,
1626
1669
  post,
1627
1670
  children,
@@ -1715,7 +1758,7 @@ var Canvas3DHost = forwardRef(
1715
1758
  getCameraPosition: () => {
1716
1759
  if (controlsRef.current) {
1717
1760
  const pos = controlsRef.current.object.position;
1718
- return new THREE11.Vector3(pos.x, pos.y, pos.z);
1761
+ return new THREE5.Vector3(pos.x, pos.y, pos.z);
1719
1762
  }
1720
1763
  return null;
1721
1764
  },
@@ -1755,20 +1798,28 @@ var Canvas3DHost = forwardRef(
1755
1798
  const cz = cameraTarget[2];
1756
1799
  const d = size * 1;
1757
1800
  const fovDeg = fov ?? 45;
1758
- switch (cameraMode) {
1759
- case "isometric":
1760
- return { position: [cx + d, d * 0.8, cz + d], fov: fovDeg };
1761
- case "top-down":
1762
- return { position: [cx, d * 2, cz + d * 0.35], fov: fovDeg };
1763
- case "front":
1764
- return { position: [cx, d * 0.32, cz + d * 1.15], fov: fovDeg };
1765
- case "follow":
1766
- return { position: [cx, d * 0.5, cz + d], fov: fovDeg };
1767
- case "perspective":
1768
- default:
1769
- return { position: [cx + d, d, cz + d], fov: fovDeg };
1770
- }
1771
- }, [cameraMode, gridBounds, cellSize, cameraTarget, fov]);
1801
+ const base = (() => {
1802
+ switch (cameraMode) {
1803
+ case "isometric":
1804
+ return { position: [cx + d, d * 0.8, cz + d], fov: fovDeg };
1805
+ case "top-down":
1806
+ return { position: [cx, d * 2, cz + d * 0.35], fov: fovDeg };
1807
+ case "front":
1808
+ return { position: [cx, d * 0.32, cz + d * 1.15], fov: fovDeg };
1809
+ case "follow":
1810
+ return { position: [cx, d * 0.5, cz + d], fov: fovDeg };
1811
+ case "perspective":
1812
+ default:
1813
+ return { position: [cx + d, d, cz + d], fov: fovDeg };
1814
+ }
1815
+ })();
1816
+ if (!azimuth) return base;
1817
+ const ox = base.position[0] - cx;
1818
+ const oz = base.position[2] - cz;
1819
+ const c = Math.cos(azimuth);
1820
+ const s = Math.sin(azimuth);
1821
+ return { position: [cx + ox * c - oz * s, base.position[1], cz + ox * s + oz * c], fov: base.fov };
1822
+ }, [cameraMode, gridBounds, cellSize, cameraTarget, fov, azimuth]);
1772
1823
  const followWorld = useMemo(() => {
1773
1824
  if (followTarget) return drawableProjector.toWorld(followTarget);
1774
1825
  return cameraTarget;
@@ -1829,6 +1880,7 @@ var Canvas3DHost = forwardRef(
1829
1880
  {
1830
1881
  shadows,
1831
1882
  flat: lighting?.toneMapping === "none",
1883
+ gl: { preserveDrawingBuffer: true },
1832
1884
  camera: {
1833
1885
  position: cameraConfig.position,
1834
1886
  fov: cameraConfig.fov,
@@ -1843,6 +1895,7 @@ var Canvas3DHost = forwardRef(
1843
1895
  },
1844
1896
  children: [
1845
1897
  /* @__PURE__ */ jsx(CameraController3D, { onCameraChange: eventHandlers.handleCameraChange }),
1898
+ /* @__PURE__ */ jsx(CameraPose, { position: cameraConfig.position, fov: cameraConfig.fov, controls: controlsRef }),
1846
1899
  (cameraMode === "follow" || cameraMode === "chase") && /* @__PURE__ */ jsx(FollowCamera3D, { target: followWorld, offset: followOffset }),
1847
1900
  /* @__PURE__ */ jsx(
1848
1901
  Lighting3D,
@@ -1923,7 +1976,7 @@ var Canvas3DHost = forwardRef(
1923
1976
  dampingFactor: 0.05,
1924
1977
  enableZoom: true,
1925
1978
  enablePan: true,
1926
- touches: { ONE: THREE11.TOUCH.ROTATE, TWO: THREE11.TOUCH.DOLLY_PAN },
1979
+ touches: { ONE: THREE5.TOUCH.ROTATE, TWO: THREE5.TOUCH.DOLLY_PAN },
1927
1980
  minDistance: 2,
1928
1981
  maxDistance: 100,
1929
1982
  maxPolarAngle: Math.PI / 2 - 0.1
@@ -1946,15 +1999,15 @@ function Scene3D({ background = "#1a1a2e", fog, children }) {
1946
1999
  if (initializedRef.current) return;
1947
2000
  initializedRef.current = true;
1948
2001
  if (background.startsWith("#") || background.startsWith("rgb")) {
1949
- scene.background = new THREE11.Color(background);
2002
+ scene.background = new THREE5.Color(background);
1950
2003
  } else {
1951
- const loader = new THREE11.TextureLoader();
2004
+ const loader = new THREE5.TextureLoader();
1952
2005
  loader.load(background, (texture) => {
1953
2006
  scene.background = texture;
1954
2007
  });
1955
2008
  }
1956
2009
  if (fog) {
1957
- scene.fog = new THREE11.Fog(fog.color, fog.near, fog.far);
2010
+ scene.fog = new THREE5.Fog(fog.color, fog.near, fog.far);
1958
2011
  }
1959
2012
  return () => {
1960
2013
  scene.background = null;
@@ -1977,14 +2030,14 @@ var Camera3D = forwardRef(
1977
2030
  }, ref) => {
1978
2031
  const { camera, set, viewport } = useThree();
1979
2032
  const controlsRef = useRef(null);
1980
- const initialPosition = useRef(new THREE11.Vector3(...position));
1981
- const initialTarget = useRef(new THREE11.Vector3(...target));
2033
+ const initialPosition = useRef(new THREE5.Vector3(...position));
2034
+ const initialTarget = useRef(new THREE5.Vector3(...target));
1982
2035
  useEffect(() => {
1983
2036
  let newCamera;
1984
2037
  if (mode === "isometric") {
1985
2038
  const aspect = viewport.aspect;
1986
2039
  const size = 10 / zoom;
1987
- newCamera = new THREE11.OrthographicCamera(
2040
+ newCamera = new THREE5.OrthographicCamera(
1988
2041
  -size * aspect,
1989
2042
  size * aspect,
1990
2043
  size,
@@ -1993,7 +2046,7 @@ var Camera3D = forwardRef(
1993
2046
  1e3
1994
2047
  );
1995
2048
  } else {
1996
- newCamera = new THREE11.PerspectiveCamera(fov, viewport.aspect, 0.1, 1e3);
2049
+ newCamera = new THREE5.PerspectiveCamera(fov, viewport.aspect, 0.1, 1e3);
1997
2050
  }
1998
2051
  newCamera.position.copy(initialPosition.current);
1999
2052
  newCamera.lookAt(initialTarget.current.x, initialTarget.current.y, initialTarget.current.z);
@@ -2034,8 +2087,8 @@ var Camera3D = forwardRef(
2034
2087
  }
2035
2088
  },
2036
2089
  getViewBounds: () => {
2037
- const min = new THREE11.Vector3(-10, -10, -10);
2038
- const max = new THREE11.Vector3(10, 10, 10);
2090
+ const min = new THREE5.Vector3(-10, -10, -10);
2091
+ const max = new THREE5.Vector3(10, 10, 10);
2039
2092
  return { min, max };
2040
2093
  }
2041
2094
  }));
@@ -2077,7 +2130,7 @@ var AssetLoader = class {
2077
2130
  __publicField(this, "textureCache");
2078
2131
  __publicField(this, "loadingPromises");
2079
2132
  this.objLoader = new OBJLoader();
2080
- this.textureLoader = new THREE11.TextureLoader();
2133
+ this.textureLoader = new THREE5.TextureLoader();
2081
2134
  this.modelCache = /* @__PURE__ */ new Map();
2082
2135
  this.textureCache = /* @__PURE__ */ new Map();
2083
2136
  this.loadingPromises = /* @__PURE__ */ new Map();
@@ -2151,7 +2204,7 @@ var AssetLoader = class {
2151
2204
  return this.loadingPromises.get(`texture:${url}`);
2152
2205
  }
2153
2206
  const loadPromise = this.textureLoader.loadAsync(url).then((texture) => {
2154
- texture.colorSpace = THREE11.SRGBColorSpace;
2207
+ texture.colorSpace = THREE5.SRGBColorSpace;
2155
2208
  this.textureCache.set(url, texture);
2156
2209
  this.loadingPromises.delete(`texture:${url}`);
2157
2210
  return texture;
@@ -2225,7 +2278,7 @@ var AssetLoader = class {
2225
2278
  });
2226
2279
  this.modelCache.forEach((model) => {
2227
2280
  model.scene.traverse((child) => {
2228
- if (child instanceof THREE11.Mesh) {
2281
+ if (child instanceof THREE5.Mesh) {
2229
2282
  child.geometry.dispose();
2230
2283
  if (Array.isArray(child.material)) {
2231
2284
  child.material.forEach((m) => m.dispose());
@@ -2275,21 +2328,21 @@ function useThree5(options = {}) {
2275
2328
  const [isReady, setIsReady] = useState(false);
2276
2329
  const [dimensions, setDimensions] = useState({ width: 0, height: 0 });
2277
2330
  const initialCameraPosition = useMemo(
2278
- () => new THREE11.Vector3(...opts.cameraPosition),
2331
+ () => new THREE5.Vector3(...opts.cameraPosition),
2279
2332
  []
2280
2333
  );
2281
2334
  useEffect(() => {
2282
2335
  if (!containerRef.current) return;
2283
2336
  const container = containerRef.current;
2284
2337
  const { clientWidth, clientHeight } = container;
2285
- const scene = new THREE11.Scene();
2286
- scene.background = new THREE11.Color(opts.backgroundColor);
2338
+ const scene = new THREE5.Scene();
2339
+ scene.background = new THREE5.Color(opts.backgroundColor);
2287
2340
  sceneRef.current = scene;
2288
2341
  let camera;
2289
2342
  const aspect = clientWidth / clientHeight;
2290
2343
  if (opts.cameraMode === "isometric") {
2291
2344
  const size = 10;
2292
- camera = new THREE11.OrthographicCamera(
2345
+ camera = new THREE5.OrthographicCamera(
2293
2346
  -size * aspect,
2294
2347
  size * aspect,
2295
2348
  size,
@@ -2298,11 +2351,11 @@ function useThree5(options = {}) {
2298
2351
  1e3
2299
2352
  );
2300
2353
  } else {
2301
- camera = new THREE11.PerspectiveCamera(45, aspect, 0.1, 1e3);
2354
+ camera = new THREE5.PerspectiveCamera(45, aspect, 0.1, 1e3);
2302
2355
  }
2303
2356
  camera.position.copy(initialCameraPosition);
2304
2357
  cameraRef.current = camera;
2305
- const renderer = new THREE11.WebGLRenderer({
2358
+ const renderer = new THREE5.WebGLRenderer({
2306
2359
  antialias: true,
2307
2360
  alpha: true,
2308
2361
  canvas: canvasRef.current || void 0
@@ -2310,7 +2363,7 @@ function useThree5(options = {}) {
2310
2363
  renderer.setSize(clientWidth, clientHeight);
2311
2364
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
2312
2365
  renderer.shadowMap.enabled = opts.shadows;
2313
- renderer.shadowMap.type = THREE11.PCFSoftShadowMap;
2366
+ renderer.shadowMap.type = THREE5.PCFSoftShadowMap;
2314
2367
  rendererRef.current = renderer;
2315
2368
  const controls = new OrbitControls$1(camera, renderer.domElement);
2316
2369
  controls.enableDamping = true;
@@ -2319,16 +2372,16 @@ function useThree5(options = {}) {
2319
2372
  controls.maxDistance = 100;
2320
2373
  controls.maxPolarAngle = Math.PI / 2 - 0.1;
2321
2374
  controlsRef.current = controls;
2322
- const ambientLight = new THREE11.AmbientLight(16777215, 0.6);
2375
+ const ambientLight = new THREE5.AmbientLight(16777215, 0.6);
2323
2376
  scene.add(ambientLight);
2324
- const directionalLight = new THREE11.DirectionalLight(16777215, 0.8);
2377
+ const directionalLight = new THREE5.DirectionalLight(16777215, 0.8);
2325
2378
  directionalLight.position.set(10, 20, 10);
2326
2379
  directionalLight.castShadow = opts.shadows;
2327
2380
  directionalLight.shadow.mapSize.width = 2048;
2328
2381
  directionalLight.shadow.mapSize.height = 2048;
2329
2382
  scene.add(directionalLight);
2330
2383
  if (opts.showGrid) {
2331
- const gridHelper = new THREE11.GridHelper(
2384
+ const gridHelper = new THREE5.GridHelper(
2332
2385
  opts.gridSize,
2333
2386
  opts.gridSize,
2334
2387
  4473924,
@@ -2346,10 +2399,10 @@ function useThree5(options = {}) {
2346
2399
  const handleResize = () => {
2347
2400
  const { clientWidth: width, clientHeight: height } = container;
2348
2401
  setDimensions({ width, height });
2349
- if (camera instanceof THREE11.PerspectiveCamera) {
2402
+ if (camera instanceof THREE5.PerspectiveCamera) {
2350
2403
  camera.aspect = width / height;
2351
2404
  camera.updateProjectionMatrix();
2352
- } else if (camera instanceof THREE11.OrthographicCamera) {
2405
+ } else if (camera instanceof THREE5.OrthographicCamera) {
2353
2406
  const aspect2 = width / height;
2354
2407
  const size = 10;
2355
2408
  camera.left = -size * aspect2;
@@ -2380,7 +2433,7 @@ function useThree5(options = {}) {
2380
2433
  let newCamera;
2381
2434
  if (opts.cameraMode === "isometric") {
2382
2435
  const size = 10;
2383
- newCamera = new THREE11.OrthographicCamera(
2436
+ newCamera = new THREE5.OrthographicCamera(
2384
2437
  -size * aspect,
2385
2438
  size * aspect,
2386
2439
  size,
@@ -2389,7 +2442,7 @@ function useThree5(options = {}) {
2389
2442
  1e3
2390
2443
  );
2391
2444
  } else {
2392
- newCamera = new THREE11.PerspectiveCamera(45, aspect, 0.1, 1e3);
2445
+ newCamera = new THREE5.PerspectiveCamera(45, aspect, 0.1, 1e3);
2393
2446
  }
2394
2447
  newCamera.position.copy(currentPos);
2395
2448
  cameraRef.current = newCamera;
@@ -2719,8 +2772,8 @@ function useSceneGraph() {
2719
2772
  }
2720
2773
  function useRaycaster(options) {
2721
2774
  const { camera, canvas, cellSize = 1, offsetX = 0, offsetZ = 0 } = options;
2722
- const raycaster = useRef(new THREE11.Raycaster());
2723
- const mouse = useRef(new THREE11.Vector2());
2775
+ const raycaster = useRef(new THREE5.Raycaster());
2776
+ const mouse = useRef(new THREE5.Vector2());
2724
2777
  const clientToNDC = useCallback(
2725
2778
  (clientX, clientY) => {
2726
2779
  if (!canvas) {
@@ -2790,8 +2843,8 @@ function useRaycaster(options) {
2790
2843
  const ndc = clientToNDC(clientX, clientY);
2791
2844
  mouse.current.set(ndc.x, ndc.y);
2792
2845
  raycaster.current.setFromCamera(mouse.current, camera);
2793
- const plane = new THREE11.Plane(new THREE11.Vector3(0, 1, 0), 0);
2794
- const target = new THREE11.Vector3();
2846
+ const plane = new THREE5.Plane(new THREE5.Vector3(0, 1, 0), 0);
2847
+ const target = new THREE5.Vector3();
2795
2848
  const intersection = raycaster.current.ray.intersectPlane(plane, target);
2796
2849
  if (intersection) {
2797
2850
  const gridX = Math.round((target.x - offsetX) / cellSize);
@@ -2829,7 +2882,7 @@ function useRaycaster(options) {
2829
2882
  return {
2830
2883
  gridX: gridCoords.x,
2831
2884
  gridZ: gridCoords.z,
2832
- worldPosition: new THREE11.Vector3(
2885
+ worldPosition: new THREE5.Vector3(
2833
2886
  gridCoords.x * cellSize + offsetX,
2834
2887
  0,
2835
2888
  gridCoords.z * cellSize + offsetZ
@@ -2859,7 +2912,7 @@ var DEFAULT_CONFIG = {
2859
2912
  };
2860
2913
  function gridToWorld(gridX, gridZ, config = DEFAULT_CONFIG) {
2861
2914
  const opts = { ...DEFAULT_CONFIG, ...config };
2862
- return new THREE11.Vector3(
2915
+ return new THREE5.Vector3(
2863
2916
  gridX * opts.cellSize + opts.offsetX,
2864
2917
  opts.elevation,
2865
2918
  gridZ * opts.cellSize + opts.offsetZ
@@ -2873,17 +2926,17 @@ function worldToGrid(worldX, worldZ, config = DEFAULT_CONFIG) {
2873
2926
  };
2874
2927
  }
2875
2928
  function raycastToPlane(camera, mouseX, mouseY, planeY = 0) {
2876
- const raycaster = new THREE11.Raycaster();
2877
- const mouse = new THREE11.Vector2(mouseX, mouseY);
2929
+ const raycaster = new THREE5.Raycaster();
2930
+ const mouse = new THREE5.Vector2(mouseX, mouseY);
2878
2931
  raycaster.setFromCamera(mouse, camera);
2879
- const plane = new THREE11.Plane(new THREE11.Vector3(0, 1, 0), -planeY);
2880
- const target = new THREE11.Vector3();
2932
+ const plane = new THREE5.Plane(new THREE5.Vector3(0, 1, 0), -planeY);
2933
+ const target = new THREE5.Vector3();
2881
2934
  const intersection = raycaster.ray.intersectPlane(plane, target);
2882
2935
  return intersection ? target : null;
2883
2936
  }
2884
2937
  function raycastToObjects(camera, mouseX, mouseY, objects) {
2885
- const raycaster = new THREE11.Raycaster();
2886
- const mouse = new THREE11.Vector2(mouseX, mouseY);
2938
+ const raycaster = new THREE5.Raycaster();
2939
+ const mouse = new THREE5.Vector2(mouseX, mouseY);
2887
2940
  raycaster.setFromCamera(mouse, camera);
2888
2941
  const intersects = raycaster.intersectObjects(objects, true);
2889
2942
  return intersects.length > 0 ? intersects[0] : null;
@@ -2935,14 +2988,14 @@ function getCellsInRadius(centerX, centerZ, radius) {
2935
2988
  return cells;
2936
2989
  }
2937
2990
  function createGridHighlight(color = 16776960, opacity = 0.3) {
2938
- const geometry = new THREE11.PlaneGeometry(0.95, 0.95);
2939
- const material = new THREE11.MeshBasicMaterial({
2991
+ const geometry = new THREE5.PlaneGeometry(0.95, 0.95);
2992
+ const material = new THREE5.MeshBasicMaterial({
2940
2993
  color,
2941
2994
  transparent: true,
2942
2995
  opacity,
2943
- side: THREE11.DoubleSide
2996
+ side: THREE5.DoubleSide
2944
2997
  });
2945
- const mesh = new THREE11.Mesh(geometry, material);
2998
+ const mesh = new THREE5.Mesh(geometry, material);
2946
2999
  mesh.rotation.x = -Math.PI / 2;
2947
3000
  mesh.position.y = 0.01;
2948
3001
  return mesh;
@@ -2955,31 +3008,31 @@ function normalizeMouseCoordinates(clientX, clientY, element) {
2955
3008
  };
2956
3009
  }
2957
3010
  function isInFrustum(position, camera, padding = 0) {
2958
- const frustum = new THREE11.Frustum();
2959
- const projScreenMatrix = new THREE11.Matrix4();
3011
+ const frustum = new THREE5.Frustum();
3012
+ const projScreenMatrix = new THREE5.Matrix4();
2960
3013
  projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
2961
3014
  frustum.setFromProjectionMatrix(projScreenMatrix);
2962
- const sphere = new THREE11.Sphere(position, padding);
3015
+ const sphere = new THREE5.Sphere(position, padding);
2963
3016
  return frustum.intersectsSphere(sphere);
2964
3017
  }
2965
3018
  function filterByFrustum(positions, camera, padding = 0) {
2966
- const frustum = new THREE11.Frustum();
2967
- const projScreenMatrix = new THREE11.Matrix4();
3019
+ const frustum = new THREE5.Frustum();
3020
+ const projScreenMatrix = new THREE5.Matrix4();
2968
3021
  projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
2969
3022
  frustum.setFromProjectionMatrix(projScreenMatrix);
2970
3023
  return positions.filter((position) => {
2971
- const sphere = new THREE11.Sphere(position, padding);
3024
+ const sphere = new THREE5.Sphere(position, padding);
2972
3025
  return frustum.intersectsSphere(sphere);
2973
3026
  });
2974
3027
  }
2975
3028
  function getVisibleIndices(positions, camera, padding = 0) {
2976
- const frustum = new THREE11.Frustum();
2977
- const projScreenMatrix = new THREE11.Matrix4();
3029
+ const frustum = new THREE5.Frustum();
3030
+ const projScreenMatrix = new THREE5.Matrix4();
2978
3031
  const visible = /* @__PURE__ */ new Set();
2979
3032
  projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
2980
3033
  frustum.setFromProjectionMatrix(projScreenMatrix);
2981
3034
  positions.forEach((position, index) => {
2982
- const sphere = new THREE11.Sphere(position, padding);
3035
+ const sphere = new THREE5.Sphere(position, padding);
2983
3036
  if (frustum.intersectsSphere(sphere)) {
2984
3037
  visible.add(index);
2985
3038
  }
@@ -3003,7 +3056,7 @@ function updateInstanceLOD(instancedMesh, positions, camera, lodDistances) {
3003
3056
  return lodIndices;
3004
3057
  }
3005
3058
  function cullInstancedMesh(instancedMesh, positions, visibleIndices) {
3006
- const dummy = new THREE11.Object3D();
3059
+ const dummy = new THREE5.Object3D();
3007
3060
  let visibleCount = 0;
3008
3061
  positions.forEach((position, index) => {
3009
3062
  if (visibleIndices.has(index)) {
@@ -5786,12 +5839,12 @@ function useAvl3DConfig() {
5786
5839
  }
5787
5840
  function CameraController({ targetPosition, targetLookAt, animated }) {
5788
5841
  const { camera } = useThree();
5789
- const targetPosVec = useRef(new THREE11.Vector3(...targetPosition));
5790
- const targetLookVec = useRef(new THREE11.Vector3(...targetLookAt));
5842
+ const targetPosVec = useRef(new THREE5.Vector3(...targetPosition));
5843
+ const targetLookVec = useRef(new THREE5.Vector3(...targetLookAt));
5791
5844
  const isAnimating = useRef(false);
5792
5845
  useEffect(() => {
5793
- const newTarget = new THREE11.Vector3(...targetPosition);
5794
- const newLookAt = new THREE11.Vector3(...targetLookAt);
5846
+ const newTarget = new THREE5.Vector3(...targetPosition);
5847
+ const newLookAt = new THREE5.Vector3(...targetLookAt);
5795
5848
  if (!newTarget.equals(targetPosVec.current) || !newLookAt.equals(targetLookVec.current)) {
5796
5849
  targetPosVec.current.copy(newTarget);
5797
5850
  targetLookVec.current.copy(newLookAt);
@@ -5806,9 +5859,9 @@ function CameraController({ targetPosition, targetLookAt, animated }) {
5806
5859
  useFrame((_, delta) => {
5807
5860
  if (!isAnimating.current) return;
5808
5861
  const speed = 3;
5809
- camera.position.x = THREE11.MathUtils.damp(camera.position.x, targetPosVec.current.x, speed, delta);
5810
- camera.position.y = THREE11.MathUtils.damp(camera.position.y, targetPosVec.current.y, speed, delta);
5811
- camera.position.z = THREE11.MathUtils.damp(camera.position.z, targetPosVec.current.z, speed, delta);
5862
+ camera.position.x = THREE5.MathUtils.damp(camera.position.x, targetPosVec.current.x, speed, delta);
5863
+ camera.position.y = THREE5.MathUtils.damp(camera.position.y, targetPosVec.current.y, speed, delta);
5864
+ camera.position.z = THREE5.MathUtils.damp(camera.position.z, targetPosVec.current.z, speed, delta);
5812
5865
  camera.lookAt(targetLookVec.current);
5813
5866
  const dist = camera.position.distanceTo(targetPosVec.current);
5814
5867
  if (dist < 0.05) {
@@ -5823,7 +5876,7 @@ function SceneFade({ animating, children }) {
5823
5876
  useFrame((_, delta) => {
5824
5877
  if (!groupRef.current) return;
5825
5878
  const target = animating ? 0 : 1;
5826
- opacityRef.current = THREE11.MathUtils.damp(opacityRef.current, target, 5, delta);
5879
+ opacityRef.current = THREE5.MathUtils.damp(opacityRef.current, target, 5, delta);
5827
5880
  groupRef.current.visible = opacityRef.current > 0.05;
5828
5881
  const s = 0.9 + opacityRef.current * 0.1;
5829
5882
  groupRef.current.scale.setScalar(s);