@almadar/ui 5.142.0 → 5.144.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.
@@ -4,7 +4,7 @@ var React3 = require('react');
4
4
  var providers = require('@almadar/ui/providers');
5
5
  var logger = require('@almadar/logger');
6
6
  var fiber = require('@react-three/fiber');
7
- var THREE10 = require('three');
7
+ var THREE5 = require('three');
8
8
  var RoomEnvironment_js = require('three/examples/jsm/environments/RoomEnvironment.js');
9
9
  var drei = require('@react-three/drei');
10
10
  var jsxRuntime = require('react/jsx-runtime');
@@ -39,7 +39,7 @@ function _interopNamespace(e) {
39
39
  }
40
40
 
41
41
  var React3__default = /*#__PURE__*/_interopDefault(React3);
42
- var THREE10__namespace = /*#__PURE__*/_interopNamespace(THREE10);
42
+ var THREE5__namespace = /*#__PURE__*/_interopNamespace(THREE5);
43
43
 
44
44
  var __defProp = Object.defineProperty;
45
45
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -531,7 +531,7 @@ function Lighting3D({
531
531
  "directionalLightHelper",
532
532
  {
533
533
  args: [
534
- new THREE10__namespace.DirectionalLight(directionalColor, directionalIntensity),
534
+ new THREE5__namespace.DirectionalLight(directionalColor, directionalIntensity),
535
535
  5
536
536
  ]
537
537
  }
@@ -588,8 +588,8 @@ function FollowCamera3D({
588
588
  offset
589
589
  }) {
590
590
  const { camera } = fiber.useThree();
591
- const look = React3.useRef(new THREE10__namespace.Vector3(target[0], target[1], target[2]));
592
- const goal = React3.useRef(new THREE10__namespace.Vector3());
591
+ const look = React3.useRef(new THREE5__namespace.Vector3(target[0], target[1], target[2]));
592
+ const goal = React3.useRef(new THREE5__namespace.Vector3());
593
593
  fiber.useFrame((_, delta) => {
594
594
  const t = Math.min(1, delta * 5);
595
595
  goal.current.set(target[0] + offset[0], target[1] + offset[1], target[2] + offset[2]);
@@ -610,7 +610,109 @@ function create3DProjector(opts = {}) {
610
610
  toWorld: (pos) => [pos.x * cellSize + offsetX, pos.z ?? 0, pos.y * cellSize + offsetZ]
611
611
  };
612
612
  }
613
+ var BoneStore = class {
614
+ constructor() {
615
+ __publicField(this, "bones", /* @__PURE__ */ new Map());
616
+ __publicField(this, "listeners", /* @__PURE__ */ new Set());
617
+ }
618
+ register(name, bone) {
619
+ this.bones.set(name, bone);
620
+ this.notify();
621
+ return () => {
622
+ if (this.bones.get(name) === bone) {
623
+ this.bones.delete(name);
624
+ this.notify();
625
+ }
626
+ };
627
+ }
628
+ get(name) {
629
+ return this.bones.get(name);
630
+ }
631
+ subscribe(listener) {
632
+ this.listeners.add(listener);
633
+ return () => this.listeners.delete(listener);
634
+ }
635
+ notify() {
636
+ for (const l of this.listeners) l();
637
+ }
638
+ };
639
+ var BoneRegistryContext = React3.createContext(null);
640
+ function isAnimatedGroup(node) {
641
+ return Boolean(node.animation && node.animation.durationMs > 0 && node.animation.keyframes.length > 0);
642
+ }
643
+ var MESH_SEGMENTS_DEFAULT = 24;
644
+ function polyhedronBounds(vertices) {
645
+ if (!vertices || vertices.length < 3) return null;
646
+ const min = [Infinity, Infinity, Infinity];
647
+ const max = [-Infinity, -Infinity, -Infinity];
648
+ for (const v of vertices) {
649
+ if (v.length < 3 || !v.every((c) => Number.isFinite(c))) return null;
650
+ for (let axis = 0; axis < 3; axis++) {
651
+ min[axis] = Math.min(min[axis], v[axis]);
652
+ max[axis] = Math.max(max[axis], v[axis]);
653
+ }
654
+ }
655
+ return { min, max };
656
+ }
657
+ function clampSegments(segments) {
658
+ const s = segments ?? MESH_SEGMENTS_DEFAULT;
659
+ return Math.min(64, Math.max(3, Math.round(s)));
660
+ }
661
+ function isAnimatedMesh(node) {
662
+ return Boolean(node.animation && node.animation.durationMs > 0 && node.animation.keyframes.length > 0);
663
+ }
664
+ var lerp = (a, b, k) => a + (b - a) * k;
613
665
  var NUMERIC_TRACKS = [
666
+ "offsetX",
667
+ "offsetY",
668
+ "offsetZ",
669
+ "rotateX",
670
+ "rotateY",
671
+ "rotateZ",
672
+ "scale",
673
+ "opacity",
674
+ "emissiveIntensity"
675
+ ];
676
+ function applyMeshAnimation(node, timeMs) {
677
+ const anim = node.animation;
678
+ if (!anim || !(anim.durationMs > 0) || anim.keyframes.length === 0) return null;
679
+ const frames = [...anim.keyframes].sort((a, b) => a.at - b.at);
680
+ const cycle = timeMs / anim.durationMs;
681
+ const t = anim.loop === false ? Math.min(cycle, 1) : cycle - Math.floor(cycle);
682
+ const trackValue = (key) => {
683
+ const defined = frames.filter((f) => f[key] !== void 0);
684
+ if (defined.length === 0) return void 0;
685
+ let prev;
686
+ let next;
687
+ for (const f of defined) {
688
+ if (f.at <= t) prev = f;
689
+ else if (!next) next = f;
690
+ }
691
+ if (!prev) return defined[0][key];
692
+ if (!next) return prev[key];
693
+ const span = next.at - prev.at;
694
+ const k = span > 0 ? (t - prev.at) / span : 1;
695
+ const a = prev[key];
696
+ const b = next[key];
697
+ if (typeof a === "number" && typeof b === "number") return lerp(a, b, k);
698
+ return a;
699
+ };
700
+ const num = {};
701
+ for (const key of NUMERIC_TRACKS) {
702
+ const v = trackValue(key);
703
+ if (v !== void 0) num[key] = v;
704
+ }
705
+ return {
706
+ offset: [num.offsetX ?? 0, num.offsetY ?? 0, num.offsetZ ?? 0],
707
+ rotate: [num.rotateX ?? 0, num.rotateY ?? 0, num.rotateZ ?? 0],
708
+ scale: num.scale ?? 1,
709
+ opacity: num.opacity,
710
+ emissiveIntensity: num.emissiveIntensity,
711
+ color: trackValue("color"),
712
+ emissive: trackValue("emissive")
713
+ };
714
+ }
715
+ var NUMERIC_TRACKS2 = [
614
716
  "offsetX",
615
717
  "offsetY",
616
718
  "rotate",
@@ -626,7 +728,7 @@ var NUMERIC_TRACKS = [
626
728
  function isAnimatedShape(node) {
627
729
  return Boolean(node.animation && node.animation.durationMs > 0 && node.animation.keyframes.length > 0);
628
730
  }
629
- var lerp = (a, b, k) => a + (b - a) * k;
731
+ var lerp2 = (a, b, k) => a + (b - a) * k;
630
732
  function applyShapeAnimation(node, timeMs) {
631
733
  const anim = node.animation;
632
734
  if (!anim || !(anim.durationMs > 0) || anim.keyframes.length === 0) return node;
@@ -649,10 +751,10 @@ function applyShapeAnimation(node, timeMs) {
649
751
  const k = span > 0 ? (t - prev.at) / span : 1;
650
752
  const a = prev[key];
651
753
  const b = next[key];
652
- if (typeof a === "number" && typeof b === "number") return lerp(a, b, k);
754
+ if (typeof a === "number" && typeof b === "number") return lerp2(a, b, k);
653
755
  return a;
654
756
  };
655
- for (const key of NUMERIC_TRACKS) {
757
+ for (const key of NUMERIC_TRACKS2) {
656
758
  const v = trackValue(key);
657
759
  if (v !== void 0) out[key] = v;
658
760
  }
@@ -673,7 +775,7 @@ function applyShapeAnimation(node, timeMs) {
673
775
  if (prevSh?.shadow && nextSh?.shadow) {
674
776
  const span = nextSh.at - prevSh.at;
675
777
  const k = span > 0 ? (t - prevSh.at) / span : 1;
676
- out.shadow = { color: prevSh.shadow.color, blur: lerp(prevSh.shadow.blur, nextSh.shadow.blur, k) };
778
+ out.shadow = { color: prevSh.shadow.color, blur: lerp2(prevSh.shadow.blur, nextSh.shadow.blur, k) };
677
779
  } else {
678
780
  out.shadow = sh;
679
781
  }
@@ -687,6 +789,10 @@ var atlasCache = /* @__PURE__ */ new Map();
687
789
  function isTilesheet(a) {
688
790
  return typeof a.tileWidth === "number";
689
791
  }
792
+ function isSpriteSheetAtlas(a) {
793
+ const s = a;
794
+ return typeof s.frameWidth === "number" && typeof s.frameHeight === "number" && typeof s.animations === "object";
795
+ }
690
796
  function getAtlas(url, onReady) {
691
797
  if (atlasCache.has(url)) return atlasCache.get(url) ?? void 0;
692
798
  atlasCache.set(url, void 0);
@@ -723,6 +829,7 @@ function subRectFor(atlas, sprite) {
723
829
  sh: atlas.tileHeight
724
830
  };
725
831
  }
832
+ if (isSpriteSheetAtlas(atlas)) return null;
726
833
  const st = atlas.subTextures[sprite];
727
834
  if (!st) return null;
728
835
  return { sx: st.x, sy: st.y, sw: st.width, sh: st.height };
@@ -816,12 +923,12 @@ function ModelLoader({
816
923
  if (!loadedModel) return null;
817
924
  const cloned = SkeletonUtils.clone(loadedModel);
818
925
  cloned.updateMatrixWorld(true);
819
- const tintColor = tint ? new THREE10__namespace.Color(tint) : null;
926
+ const tintColor = tint ? new THREE5__namespace.Color(tint) : null;
820
927
  cloned.traverse((child) => {
821
- if (child instanceof THREE10__namespace.Mesh) {
928
+ if (child instanceof THREE5__namespace.Mesh) {
822
929
  child.castShadow = castShadow;
823
930
  child.receiveShadow = receiveShadow;
824
- if (tintColor && child.material instanceof THREE10__namespace.MeshStandardMaterial) {
931
+ if (tintColor && child.material instanceof THREE5__namespace.MeshStandardMaterial) {
825
932
  const mat = child.material.clone();
826
933
  mat.color.multiply(tintColor);
827
934
  child.material = mat;
@@ -830,7 +937,7 @@ function ModelLoader({
830
937
  });
831
938
  return cloned;
832
939
  }, [loadedModel, castShadow, receiveShadow, tint]);
833
- const mixer = React3.useMemo(() => model ? new THREE10__namespace.AnimationMixer(model) : null, [model]);
940
+ const mixer = React3.useMemo(() => model ? new THREE5__namespace.AnimationMixer(model) : null, [model]);
834
941
  React3.useEffect(() => {
835
942
  if (!mixer || !animation || clips.length === 0) return;
836
943
  const wanted = animation.toLowerCase();
@@ -847,8 +954,8 @@ function ModelLoader({
847
954
  });
848
955
  const normFactor = React3.useMemo(() => {
849
956
  if (!model) return 1;
850
- const box = new THREE10__namespace.Box3().setFromObject(model);
851
- const size = new THREE10__namespace.Vector3();
957
+ const box = new THREE5__namespace.Box3().setFromObject(model);
958
+ const size = new THREE5__namespace.Vector3();
852
959
  box.getSize(size);
853
960
  const maxDim = Math.max(size.x, size.y, size.z);
854
961
  if (!Number.isFinite(maxDim) || maxDim < 0.05) return 1;
@@ -938,7 +1045,7 @@ var warnUnsupported3d = (kind) => {
938
1045
  warnedUnsupported.add(kind);
939
1046
  mesh3dLog.warn("unsupported drawable kind on the 3D backend \u2014 skipped", { kind });
940
1047
  };
941
- var CrossOriginTextureLoader = class extends THREE10__namespace.TextureLoader {
1048
+ var CrossOriginTextureLoader = class extends THREE5__namespace.TextureLoader {
942
1049
  constructor() {
943
1050
  super();
944
1051
  this.crossOrigin = "anonymous";
@@ -956,7 +1063,7 @@ function useBillboardTexture(url) {
956
1063
  url,
957
1064
  (texture) => {
958
1065
  if (!active) return;
959
- texture.colorSpace = THREE10__namespace.SRGBColorSpace;
1066
+ texture.colorSpace = THREE5__namespace.SRGBColorSpace;
960
1067
  setState({ texture, error: false });
961
1068
  },
962
1069
  void 0,
@@ -1009,7 +1116,7 @@ function SpriteBillboard({ node, world, cellSize = 1, groupOpacity = 1 }) {
1009
1116
  }, [texture, frame, node.height, node.width, anchor, cellSize]);
1010
1117
  const groundGeometry = React3__default.default.useMemo(() => {
1011
1118
  if (anchor !== "top-left" || !texture || !atlasReady) return null;
1012
- const g = new THREE10__namespace.PlaneGeometry(size.width, size.height);
1119
+ const g = new THREE5__namespace.PlaneGeometry(size.width, size.height);
1013
1120
  g.rotateX(-Math.PI / 2);
1014
1121
  return g;
1015
1122
  }, [anchor, texture, atlasReady, size.width, size.height]);
@@ -1017,15 +1124,15 @@ function SpriteBillboard({ node, world, cellSize = 1, groupOpacity = 1 }) {
1017
1124
  if (anchor === "top-left") {
1018
1125
  return /* @__PURE__ */ jsxRuntime.jsx("group", { position: [world[0] + size.width / 2, 0.02, world[2] + size.height / 2], children: /* @__PURE__ */ jsxRuntime.jsxs("mesh", { rotation: [-Math.PI / 2, 0, 0], children: [
1019
1126
  /* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [size.width, size.height] }),
1020
- /* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: textureError ? 16729156 : 8947848, transparent: true, opacity: 0.6, side: THREE10__namespace.DoubleSide })
1127
+ /* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: textureError ? 16729156 : 8947848, transparent: true, opacity: 0.6, side: THREE5__namespace.DoubleSide })
1021
1128
  ] }) });
1022
1129
  }
1023
1130
  return /* @__PURE__ */ jsxRuntime.jsx("group", { position: [world[0], world[1] + size.height / 2, world[2]], children: /* @__PURE__ */ jsxRuntime.jsxs("mesh", { children: [
1024
1131
  /* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [size.width, size.height] }),
1025
- /* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: textureError ? 16729156 : 8947848, transparent: true, opacity: 0.6, side: THREE10__namespace.DoubleSide })
1132
+ /* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: textureError ? 16729156 : 8947848, transparent: true, opacity: 0.6, side: THREE5__namespace.DoubleSide })
1026
1133
  ] }) });
1027
1134
  }
1028
- texture.magFilter = texture.minFilter = THREE10__namespace.NearestFilter;
1135
+ texture.magFilter = texture.minFilter = THREE5__namespace.NearestFilter;
1029
1136
  texture.needsUpdate = true;
1030
1137
  if (frame) {
1031
1138
  texture.repeat.set(frame.w / size.imgW, frame.h / size.imgH);
@@ -1038,7 +1145,7 @@ function SpriteBillboard({ node, world, cellSize = 1, groupOpacity = 1 }) {
1038
1145
  map: texture,
1039
1146
  transparent: true,
1040
1147
  alphaTest: 0.1,
1041
- side: THREE10__namespace.DoubleSide,
1148
+ side: THREE5__namespace.DoubleSide,
1042
1149
  opacity: (node.opacity ?? 1) * groupOpacity
1043
1150
  }
1044
1151
  ) }) });
@@ -1051,7 +1158,7 @@ function SpriteBillboard({ node, world, cellSize = 1, groupOpacity = 1 }) {
1051
1158
  map: texture,
1052
1159
  transparent: true,
1053
1160
  alphaTest: 0.1,
1054
- side: THREE10__namespace.DoubleSide,
1161
+ side: THREE5__namespace.DoubleSide,
1055
1162
  opacity: node.opacity ?? 1
1056
1163
  }
1057
1164
  )
@@ -1120,7 +1227,7 @@ function Shape3D({ node, projector, groupOpacity = 1 }) {
1120
1227
  }
1121
1228
  case "poly": {
1122
1229
  if (!node.points || node.points.length === 0) return null;
1123
- const s = new THREE10__namespace.Shape();
1230
+ const s = new THREE5__namespace.Shape();
1124
1231
  node.points.forEach((p, i) => {
1125
1232
  if (i === 0) s.moveTo(p.x, p.y);
1126
1233
  else s.lineTo(p.x, p.y);
@@ -1138,7 +1245,7 @@ function Shape3D({ node, projector, groupOpacity = 1 }) {
1138
1245
  }
1139
1246
  return /* @__PURE__ */ jsxRuntime.jsx("group", { ref: groupRef, position: [world[0], world[1] + 0.02, world[2]], children: /* @__PURE__ */ jsxRuntime.jsxs("mesh", { rotation: [-Math.PI / 2, 0, 0], children: [
1140
1247
  geometry,
1141
- /* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { ref: materialRef, color, transparent: true, opacity: (node.opacity ?? 1) * groupOpacity, side: THREE10__namespace.DoubleSide })
1248
+ /* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { ref: materialRef, color, transparent: true, opacity: (node.opacity ?? 1) * groupOpacity, side: THREE5__namespace.DoubleSide })
1142
1249
  ] }) });
1143
1250
  }
1144
1251
  function Text3D({ node, projector, groupOpacity = 1 }) {
@@ -1159,64 +1266,66 @@ function Text3D({ node, projector, groupOpacity = 1 }) {
1159
1266
  }
1160
1267
  ) });
1161
1268
  }
1162
- var MESH_SEGMENTS_DEFAULT = 24;
1163
- function clampSegments(segments) {
1164
- const s = segments ?? MESH_SEGMENTS_DEFAULT;
1165
- return Math.min(64, Math.max(3, Math.round(s)));
1269
+ var GROUND_ROTATION = [-Math.PI / 2, 0, 0];
1270
+ var textureCache = /* @__PURE__ */ new Map();
1271
+ function getMeshTexture(url) {
1272
+ const cached = textureCache.get(url);
1273
+ if (cached) return cached;
1274
+ const texture = new THREE5__namespace.TextureLoader().load(url);
1275
+ texture.flipY = false;
1276
+ texture.colorSpace = THREE5__namespace.SRGBColorSpace;
1277
+ texture.wrapS = THREE5__namespace.RepeatWrapping;
1278
+ texture.wrapT = THREE5__namespace.RepeatWrapping;
1279
+ textureCache.set(url, texture);
1280
+ return texture;
1166
1281
  }
1167
- function isAnimatedMesh(node) {
1168
- return Boolean(node.animation && node.animation.durationMs > 0 && node.animation.keyframes.length > 0);
1169
- }
1170
- var lerp2 = (a, b, k) => a + (b - a) * k;
1171
- var NUMERIC_TRACKS2 = [
1172
- "offsetX",
1173
- "offsetY",
1174
- "offsetZ",
1175
- "rotateX",
1176
- "rotateY",
1177
- "rotateZ",
1178
- "scale",
1179
- "opacity",
1180
- "emissiveIntensity"
1181
- ];
1182
- function applyMeshAnimation(node, timeMs) {
1183
- const anim = node.animation;
1184
- if (!anim || !(anim.durationMs > 0) || anim.keyframes.length === 0) return null;
1185
- const frames = [...anim.keyframes].sort((a, b) => a.at - b.at);
1186
- const cycle = timeMs / anim.durationMs;
1187
- const t = anim.loop === false ? Math.min(cycle, 1) : cycle - Math.floor(cycle);
1188
- const trackValue = (key) => {
1189
- const defined = frames.filter((f) => f[key] !== void 0);
1190
- if (defined.length === 0) return void 0;
1191
- let prev;
1192
- let next;
1193
- for (const f of defined) {
1194
- if (f.at <= t) prev = f;
1195
- else if (!next) next = f;
1282
+ function polyhedronGeometry(node, cellSize) {
1283
+ const verts = node.vertices;
1284
+ const faces = node.faces;
1285
+ const bounds = polyhedronBounds(verts);
1286
+ if (!verts || !bounds || !faces || faces.length === 0) return null;
1287
+ const positions = new Float32Array(verts.length * 3);
1288
+ for (let i = 0; i < verts.length; i++) {
1289
+ positions[i * 3] = verts[i][0] * cellSize;
1290
+ positions[i * 3 + 1] = verts[i][2] * cellSize;
1291
+ positions[i * 3 + 2] = verts[i][1] * cellSize;
1292
+ }
1293
+ const index = [];
1294
+ for (const face of faces) {
1295
+ if (face.length < 3) continue;
1296
+ const [a, b, c] = face;
1297
+ if (a === b || b === c || a === c) continue;
1298
+ if (![a, b, c].every((i) => Number.isInteger(i) && i >= 0 && i < verts.length)) continue;
1299
+ index.push(a, c, b);
1300
+ }
1301
+ if (index.length === 0) return null;
1302
+ const geometry = new THREE5__namespace.BufferGeometry();
1303
+ geometry.setAttribute("position", new THREE5__namespace.BufferAttribute(positions, 3));
1304
+ if (node.uvs && node.uvs.length === verts.length) {
1305
+ const uv = new Float32Array(verts.length * 2);
1306
+ for (let i = 0; i < verts.length; i++) {
1307
+ uv[i * 2] = node.uvs[i][0];
1308
+ uv[i * 2 + 1] = node.uvs[i][1];
1196
1309
  }
1197
- if (!prev) return defined[0][key];
1198
- if (!next) return prev[key];
1199
- const span = next.at - prev.at;
1200
- const k = span > 0 ? (t - prev.at) / span : 1;
1201
- const a = prev[key];
1202
- const b = next[key];
1203
- if (typeof a === "number" && typeof b === "number") return lerp2(a, b, k);
1204
- return a;
1205
- };
1206
- const num = {};
1207
- for (const key of NUMERIC_TRACKS2) {
1208
- const v = trackValue(key);
1209
- if (v !== void 0) num[key] = v;
1310
+ geometry.setAttribute("uv", new THREE5__namespace.BufferAttribute(uv, 2));
1210
1311
  }
1211
- return {
1212
- offset: [num.offsetX ?? 0, num.offsetY ?? 0, num.offsetZ ?? 0],
1213
- rotate: [num.rotateX ?? 0, num.rotateY ?? 0, num.rotateZ ?? 0],
1214
- scale: num.scale ?? 1,
1215
- opacity: num.opacity,
1216
- emissiveIntensity: num.emissiveIntensity,
1217
- color: trackValue("color"),
1218
- emissive: trackValue("emissive")
1219
- };
1312
+ geometry.setIndex(index);
1313
+ geometry.computeVertexNormals();
1314
+ const skin = node.skin;
1315
+ if (skin && skin.indices.length === verts.length && skin.weights.length === verts.length) {
1316
+ const skinIndex = new Uint16Array(verts.length * 4);
1317
+ const skinWeight = new Float32Array(verts.length * 4);
1318
+ for (let i = 0; i < verts.length; i++) {
1319
+ for (let k = 0; k < 4; k++) {
1320
+ skinIndex[i * 4 + k] = skin.indices[i][k] ?? 0;
1321
+ skinWeight[i * 4 + k] = skin.weights[i][k] ?? 0;
1322
+ }
1323
+ }
1324
+ geometry.setAttribute("skinIndex", new THREE5__namespace.BufferAttribute(skinIndex, 4));
1325
+ geometry.setAttribute("skinWeight", new THREE5__namespace.BufferAttribute(skinWeight, 4));
1326
+ }
1327
+ const size = Math.max(bounds.max[0] - bounds.min[0], bounds.max[1] - bounds.min[1], bounds.max[2] - bounds.min[2]) * cellSize;
1328
+ return { geometry, lift: -bounds.min[2] * cellSize, size };
1220
1329
  }
1221
1330
  function meshGeometry(node, cellSize) {
1222
1331
  const seg = clampSegments(node.segments);
@@ -1244,17 +1353,20 @@ function meshGeometry(node, cellSize) {
1244
1353
  return { element: /* @__PURE__ */ jsxRuntime.jsx("torusGeometry", { args: [r, tube, Math.max(3, Math.round(seg / 2)), seg] }), lift: r + tube, size: (r + tube) * 2 };
1245
1354
  }
1246
1355
  case "plane":
1247
- return { element: /* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [w, d] }), lift: 0, size: Math.max(w, d) };
1356
+ return { element: /* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [w, d] }), lift: 0, size: Math.max(w, d), baseRotation: GROUND_ROTATION };
1248
1357
  case "circle":
1249
- return { element: /* @__PURE__ */ jsxRuntime.jsx("circleGeometry", { args: [r, seg] }), lift: 0, size: r * 2 };
1358
+ return { element: /* @__PURE__ */ jsxRuntime.jsx("circleGeometry", { args: [r, seg] }), lift: 0, size: r * 2, baseRotation: GROUND_ROTATION };
1359
+ case "polyhedron":
1360
+ return polyhedronGeometry(node, cellSize);
1250
1361
  default:
1251
1362
  return null;
1252
1363
  }
1253
1364
  }
1365
+ var warnedPolyhedronOutline = false;
1254
1366
  var SIDE_MAP = {
1255
- front: THREE10__namespace.FrontSide,
1256
- back: THREE10__namespace.BackSide,
1257
- double: THREE10__namespace.DoubleSide
1367
+ front: THREE5__namespace.FrontSide,
1368
+ back: THREE5__namespace.BackSide,
1369
+ double: THREE5__namespace.DoubleSide
1258
1370
  };
1259
1371
  function meshMaterial(mat, opacity, ref) {
1260
1372
  const m = mat ?? {};
@@ -1263,7 +1375,8 @@ function meshMaterial(mat, opacity, ref) {
1263
1375
  color: m.color ?? "#ffffff",
1264
1376
  transparent: opacity < 1,
1265
1377
  opacity,
1266
- side: SIDE_MAP[m.side ?? "front"]
1378
+ side: SIDE_MAP[m.side ?? "front"],
1379
+ ...m.map ? { map: getMeshTexture(m.map) } : {}
1267
1380
  };
1268
1381
  const emissive = m.emissive ? { emissive: m.emissive, emissiveIntensity: m.emissiveIntensity ?? 1 } : {};
1269
1382
  switch (m.kind ?? "standard") {
@@ -1298,6 +1411,53 @@ function meshMaterial(mat, opacity, ref) {
1298
1411
  );
1299
1412
  }
1300
1413
  }
1414
+ function SkinnedPolyhedron3D({
1415
+ node,
1416
+ skin,
1417
+ geometry,
1418
+ cellSize,
1419
+ opacity
1420
+ }) {
1421
+ const boneStore = React3.useContext(BoneRegistryContext);
1422
+ const meshRef = React3.useRef(null);
1423
+ const [registryTick, setRegistryTick] = React3.useState(0);
1424
+ React3.useEffect(() => boneStore?.subscribe(() => setRegistryTick((t) => t + 1)), [boneStore]);
1425
+ React3.useEffect(() => {
1426
+ const mesh = meshRef.current;
1427
+ if (!mesh || !boneStore) return;
1428
+ const bones = [];
1429
+ for (const name of skin.bones) {
1430
+ const bone = boneStore.get(name);
1431
+ if (!bone) return;
1432
+ bones.push(bone);
1433
+ }
1434
+ if (mesh.skeleton && mesh.skeleton.bones.length === bones.length && mesh.skeleton.bones.every((b, i) => b === bones[i])) return;
1435
+ if (skin.inverseBindMatrices.length !== bones.length) return;
1436
+ const inverses = skin.inverseBindMatrices.map((m) => {
1437
+ const mat = new THREE5__namespace.Matrix4().fromArray(m);
1438
+ mat.elements[12] *= cellSize;
1439
+ mat.elements[13] *= cellSize;
1440
+ mat.elements[14] *= cellSize;
1441
+ return mat;
1442
+ });
1443
+ mesh.bind(new THREE5__namespace.Skeleton(bones, inverses), new THREE5__namespace.Matrix4());
1444
+ }, [registryTick, skin, boneStore, geometry, cellSize]);
1445
+ React3.useEffect(() => {
1446
+ const mesh = meshRef.current;
1447
+ return () => mesh?.skeleton?.dispose();
1448
+ }, []);
1449
+ return /* @__PURE__ */ jsxRuntime.jsx(
1450
+ "skinnedMesh",
1451
+ {
1452
+ ref: meshRef,
1453
+ geometry,
1454
+ frustumCulled: false,
1455
+ castShadow: node.castShadow ?? true,
1456
+ receiveShadow: node.receiveShadow ?? true,
1457
+ children: meshMaterial(node.material, opacity)
1458
+ }
1459
+ );
1460
+ }
1301
1461
  function Mesh3D({
1302
1462
  node,
1303
1463
  projector,
@@ -1310,6 +1470,10 @@ function Mesh3D({
1310
1470
  const validPos = isValidScenePos(node.position);
1311
1471
  const baseWorld = validPos ? projector.toWorld(node.position) : [0, 0, 0];
1312
1472
  const geo = React3.useMemo(() => meshGeometry(node, projector.cellSize), [node, projector.cellSize]);
1473
+ React3.useEffect(() => {
1474
+ const g = geo?.geometry;
1475
+ return () => g?.dispose();
1476
+ }, [geo]);
1313
1477
  fiber.useFrame(({ clock }) => {
1314
1478
  if (!animated || !groupRef.current) return;
1315
1479
  const state = applyMeshAnimation(node, clock.elapsedTime * 1e3);
@@ -1322,8 +1486,13 @@ function Mesh3D({
1322
1486
  );
1323
1487
  groupRef.current.scale.setScalar(state.scale);
1324
1488
  if (meshRef.current) {
1489
+ const shapeRot = geo?.baseRotation ?? [0, 0, 0];
1325
1490
  const base = node.rotation ?? [0, 0, 0];
1326
- meshRef.current.rotation.set(base[0] + state.rotate[0], base[1] + state.rotate[1], base[2] + state.rotate[2]);
1491
+ meshRef.current.rotation.set(
1492
+ shapeRot[0] + base[0] + state.rotate[0],
1493
+ shapeRot[1] + base[1] + state.rotate[1],
1494
+ shapeRot[2] + base[2] + state.rotate[2]
1495
+ );
1327
1496
  }
1328
1497
  const mat = materialRef.current;
1329
1498
  if (mat) {
@@ -1340,13 +1509,28 @@ function Mesh3D({
1340
1509
  if (!validPos || !geo) return null;
1341
1510
  const lift = (node.pivot ?? "bottom") === "bottom" ? geo.lift : 0;
1342
1511
  const opacity = (node.opacity ?? 1) * (node.material?.opacity ?? 1) * groupOpacity;
1343
- const rotation = node.rotation ?? [0, 0, 0];
1512
+ if (node.skin && geo.geometry) {
1513
+ return /* @__PURE__ */ jsxRuntime.jsx("group", { position: baseWorld, children: /* @__PURE__ */ jsxRuntime.jsx(SkinnedPolyhedron3D, { node, skin: node.skin, geometry: geo.geometry, cellSize: projector.cellSize, opacity }) });
1514
+ }
1515
+ const nodeRotation = node.rotation ?? [0, 0, 0];
1516
+ const shapeRotation = geo.baseRotation ?? [0, 0, 0];
1517
+ const rotation = [
1518
+ shapeRotation[0] + nodeRotation[0],
1519
+ shapeRotation[1] + nodeRotation[1],
1520
+ shapeRotation[2] + nodeRotation[2]
1521
+ ];
1344
1522
  const outlineScale = geo.size > 0 ? 1 + (node.outline?.width ?? 0.05) * projector.cellSize / geo.size : 1;
1523
+ if (node.outline && geo.geometry && !warnedPolyhedronOutline) {
1524
+ warnedPolyhedronOutline = true;
1525
+ console.warn('[draw-mesh] outline is not yet supported on shape "polyhedron" \u2014 skipped');
1526
+ }
1527
+ const geometryProp = geo.geometry ? { geometry: geo.geometry } : {};
1345
1528
  return /* @__PURE__ */ jsxRuntime.jsxs("group", { ref: groupRef, position: baseWorld, children: [
1346
1529
  /* @__PURE__ */ jsxRuntime.jsxs(
1347
1530
  "mesh",
1348
1531
  {
1349
1532
  ref: meshRef,
1533
+ ...geometryProp,
1350
1534
  position: [0, lift, 0],
1351
1535
  rotation,
1352
1536
  castShadow: node.castShadow ?? true,
@@ -1357,13 +1541,13 @@ function Mesh3D({
1357
1541
  ]
1358
1542
  }
1359
1543
  ),
1360
- node.outline && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, lift, 0], rotation, scale: outlineScale, children: [
1544
+ node.outline && !geo.geometry && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, lift, 0], rotation, scale: outlineScale, children: [
1361
1545
  geo.element,
1362
1546
  /* @__PURE__ */ jsxRuntime.jsx(
1363
1547
  "meshBasicMaterial",
1364
1548
  {
1365
1549
  color: node.outline.color ?? "#101014",
1366
- side: THREE10__namespace.BackSide,
1550
+ side: THREE5__namespace.BackSide,
1367
1551
  transparent: opacity < 1,
1368
1552
  opacity
1369
1553
  }
@@ -1390,14 +1574,53 @@ function Drawable3D({ node, projector, groupOpacity = 1 }) {
1390
1574
  case "draw-group": {
1391
1575
  if (!isValidScenePos(node.position) || !Array.isArray(node.items)) return null;
1392
1576
  if (node.clip) warnUnsupported3d("draw-group:clip");
1393
- const world = projector.toWorld(node.position);
1394
- const inner = create3DProjector({ cellSize: projector.cellSize });
1395
- const opacity = (node.opacity ?? 1) * groupOpacity;
1396
- const s = node.scale ?? 1;
1397
- return /* @__PURE__ */ jsxRuntime.jsx("group", { position: world, rotation: [0, -(node.rotate ?? 0), 0], scale: [s, s, s], children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Drawable3D, { node: item, projector: inner, groupOpacity: opacity }, i)) });
1577
+ return /* @__PURE__ */ jsxRuntime.jsx(Group3D, { node, projector, groupOpacity });
1398
1578
  }
1399
1579
  }
1400
1580
  }
1581
+ function Group3D({
1582
+ node,
1583
+ projector,
1584
+ groupOpacity
1585
+ }) {
1586
+ const ref = React3.useRef(null);
1587
+ const animated = isAnimatedGroup(node);
1588
+ const world = projector.toWorld(node.position);
1589
+ const inner = create3DProjector({ cellSize: projector.cellSize });
1590
+ const opacity = (node.opacity ?? 1) * groupOpacity;
1591
+ const s = node.scale ?? 1;
1592
+ const baseRotation = node.rotation ?? [0, -(node.rotate ?? 0), 0];
1593
+ const parentStore = React3.useContext(BoneRegistryContext);
1594
+ const scopedStore = React3.useMemo(() => node.skeleton ? new BoneStore() : null, [node.skeleton]);
1595
+ const boneStore = scopedStore ?? parentStore;
1596
+ const boneObject = React3.useMemo(() => node.bone ? new THREE5__namespace.Bone() : null, [node.bone]);
1597
+ React3.useEffect(() => {
1598
+ if (!node.bone || !boneStore || !boneObject) return;
1599
+ return boneStore.register(node.bone, boneObject);
1600
+ }, [node.bone, boneStore, boneObject]);
1601
+ fiber.useFrame(({ clock }) => {
1602
+ if (!animated || !ref.current) return;
1603
+ const state = applyMeshAnimation(node, clock.elapsedTime * 1e3);
1604
+ if (!state) return;
1605
+ const cell = projector.cellSize;
1606
+ ref.current.position.set(
1607
+ world[0] + state.offset[0] * cell,
1608
+ world[1] + state.offset[2] * cell,
1609
+ world[2] + state.offset[1] * cell
1610
+ );
1611
+ ref.current.rotation.set(
1612
+ baseRotation[0] + state.rotate[0],
1613
+ baseRotation[1] + state.rotate[1],
1614
+ baseRotation[2] + state.rotate[2]
1615
+ );
1616
+ ref.current.scale.setScalar(s * state.scale);
1617
+ });
1618
+ const children = /* @__PURE__ */ jsxRuntime.jsxs("group", { ref, position: world, rotation: baseRotation, scale: [s, s, s], children: [
1619
+ boneObject && /* @__PURE__ */ jsxRuntime.jsx("primitive", { object: boneObject }),
1620
+ node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Drawable3D, { node: item, projector: inner, groupOpacity: opacity }, i))
1621
+ ] });
1622
+ return scopedStore ? /* @__PURE__ */ jsxRuntime.jsx(BoneRegistryContext.Provider, { value: scopedStore, children }) : children;
1623
+ }
1401
1624
 
1402
1625
  // lib/drawable/three/game3dTheme.ts
1403
1626
  var GRID_COLORS_3D = {
@@ -1410,10 +1633,26 @@ function cn(...inputs) {
1410
1633
  }
1411
1634
  var DEFAULT_GRID_CONFIG = {
1412
1635
  cellSize: 1};
1636
+ function CameraPose({
1637
+ position,
1638
+ fov,
1639
+ controls
1640
+ }) {
1641
+ const camera = fiber.useThree((s) => s.camera);
1642
+ React3.useEffect(() => {
1643
+ camera.position.set(position[0], position[1], position[2]);
1644
+ if (camera.isPerspectiveCamera) {
1645
+ camera.fov = fov;
1646
+ camera.updateProjectionMatrix();
1647
+ }
1648
+ controls.current?.update();
1649
+ }, [camera, position, fov, controls]);
1650
+ return null;
1651
+ }
1413
1652
  function RoomEnvironment3D() {
1414
1653
  const { gl, scene } = fiber.useThree(({ gl: gl2, scene: scene2 }) => ({ gl: gl2, scene: scene2 }));
1415
1654
  React3.useEffect(() => {
1416
- const pmremGenerator = new THREE10__namespace.PMREMGenerator(gl);
1655
+ const pmremGenerator = new THREE5__namespace.PMREMGenerator(gl);
1417
1656
  const envTexture = pmremGenerator.fromScene(new RoomEnvironment_js.RoomEnvironment(), 0.04).texture;
1418
1657
  scene.environment = envTexture;
1419
1658
  return () => {
@@ -1449,6 +1688,7 @@ var Canvas3DHost = React3.forwardRef(
1449
1688
  keyUpMap,
1450
1689
  pixelsPerUnit,
1451
1690
  fov,
1691
+ azimuth,
1452
1692
  lighting,
1453
1693
  post,
1454
1694
  children,
@@ -1529,6 +1769,7 @@ var Canvas3DHost = React3.forwardRef(
1529
1769
  }),
1530
1770
  [gridBounds, cellSize]
1531
1771
  );
1772
+ const boneStore = React3.useMemo(() => new BoneStore(), []);
1532
1773
  const drawableProjector = React3.useMemo(
1533
1774
  () => create3DProjector({
1534
1775
  cellSize: gridConfig.cellSize,
@@ -1541,7 +1782,7 @@ var Canvas3DHost = React3.forwardRef(
1541
1782
  getCameraPosition: () => {
1542
1783
  if (controlsRef.current) {
1543
1784
  const pos = controlsRef.current.object.position;
1544
- return new THREE10__namespace.Vector3(pos.x, pos.y, pos.z);
1785
+ return new THREE5__namespace.Vector3(pos.x, pos.y, pos.z);
1545
1786
  }
1546
1787
  return null;
1547
1788
  },
@@ -1581,18 +1822,28 @@ var Canvas3DHost = React3.forwardRef(
1581
1822
  const cz = cameraTarget[2];
1582
1823
  const d = size * 1;
1583
1824
  const fovDeg = fov ?? 45;
1584
- switch (cameraMode) {
1585
- case "isometric":
1586
- return { position: [cx + d, d * 0.8, cz + d], fov: fovDeg };
1587
- case "top-down":
1588
- return { position: [cx, d * 2, cz + d * 0.35], fov: fovDeg };
1589
- case "follow":
1590
- return { position: [cx, d * 0.5, cz + d], fov: fovDeg };
1591
- case "perspective":
1592
- default:
1593
- return { position: [cx + d, d, cz + d], fov: fovDeg };
1594
- }
1595
- }, [cameraMode, gridBounds, cellSize, cameraTarget, fov]);
1825
+ const base = (() => {
1826
+ switch (cameraMode) {
1827
+ case "isometric":
1828
+ return { position: [cx + d, d * 0.8, cz + d], fov: fovDeg };
1829
+ case "top-down":
1830
+ return { position: [cx, d * 2, cz + d * 0.35], fov: fovDeg };
1831
+ case "front":
1832
+ return { position: [cx, d * 0.32, cz + d * 1.15], fov: fovDeg };
1833
+ case "follow":
1834
+ return { position: [cx, d * 0.5, cz + d], fov: fovDeg };
1835
+ case "perspective":
1836
+ default:
1837
+ return { position: [cx + d, d, cz + d], fov: fovDeg };
1838
+ }
1839
+ })();
1840
+ if (!azimuth) return base;
1841
+ const ox = base.position[0] - cx;
1842
+ const oz = base.position[2] - cz;
1843
+ const c = Math.cos(azimuth);
1844
+ const s = Math.sin(azimuth);
1845
+ return { position: [cx + ox * c - oz * s, base.position[1], cz + ox * s + oz * c], fov: base.fov };
1846
+ }, [cameraMode, gridBounds, cellSize, cameraTarget, fov, azimuth]);
1596
1847
  const followWorld = React3.useMemo(() => {
1597
1848
  if (followTarget) return drawableProjector.toWorld(followTarget);
1598
1849
  return cameraTarget;
@@ -1652,6 +1903,8 @@ var Canvas3DHost = React3.forwardRef(
1652
1903
  fiber.Canvas,
1653
1904
  {
1654
1905
  shadows,
1906
+ flat: lighting?.toneMapping === "none",
1907
+ gl: { preserveDrawingBuffer: true },
1655
1908
  camera: {
1656
1909
  position: cameraConfig.position,
1657
1910
  fov: cameraConfig.fov,
@@ -1666,6 +1919,7 @@ var Canvas3DHost = React3.forwardRef(
1666
1919
  },
1667
1920
  children: [
1668
1921
  /* @__PURE__ */ jsxRuntime.jsx(CameraController3D, { onCameraChange: eventHandlers.handleCameraChange }),
1922
+ /* @__PURE__ */ jsxRuntime.jsx(CameraPose, { position: cameraConfig.position, fov: cameraConfig.fov, controls: controlsRef }),
1669
1923
  (cameraMode === "follow" || cameraMode === "chase") && /* @__PURE__ */ jsxRuntime.jsx(FollowCamera3D, { target: followWorld, offset: followOffset }),
1670
1924
  /* @__PURE__ */ jsxRuntime.jsx(
1671
1925
  Lighting3D,
@@ -1710,7 +1964,7 @@ var Canvas3DHost = React3.forwardRef(
1710
1964
  fadeStrength: 1
1711
1965
  }
1712
1966
  ),
1713
- allDrawables.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("group", { children: allDrawables.map((node, i) => /* @__PURE__ */ jsxRuntime.jsx(Drawable3D, { node, projector: drawableProjector }, i)) }),
1967
+ allDrawables.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(BoneRegistryContext.Provider, { value: boneStore, children: /* @__PURE__ */ jsxRuntime.jsx("group", { children: allDrawables.map((node, i) => /* @__PURE__ */ jsxRuntime.jsx(Drawable3D, { node, projector: drawableProjector }, i)) }) }),
1714
1968
  (tileClickEvent || unitClickEvent) && /* @__PURE__ */ jsxRuntime.jsxs(
1715
1969
  "mesh",
1716
1970
  {
@@ -1746,7 +2000,7 @@ var Canvas3DHost = React3.forwardRef(
1746
2000
  dampingFactor: 0.05,
1747
2001
  enableZoom: true,
1748
2002
  enablePan: true,
1749
- touches: { ONE: THREE10__namespace.TOUCH.ROTATE, TWO: THREE10__namespace.TOUCH.DOLLY_PAN },
2003
+ touches: { ONE: THREE5__namespace.TOUCH.ROTATE, TWO: THREE5__namespace.TOUCH.DOLLY_PAN },
1750
2004
  minDistance: 2,
1751
2005
  maxDistance: 100,
1752
2006
  maxPolarAngle: Math.PI / 2 - 0.1
@@ -1769,15 +2023,15 @@ function Scene3D({ background = "#1a1a2e", fog, children }) {
1769
2023
  if (initializedRef.current) return;
1770
2024
  initializedRef.current = true;
1771
2025
  if (background.startsWith("#") || background.startsWith("rgb")) {
1772
- scene.background = new THREE10__namespace.Color(background);
2026
+ scene.background = new THREE5__namespace.Color(background);
1773
2027
  } else {
1774
- const loader = new THREE10__namespace.TextureLoader();
2028
+ const loader = new THREE5__namespace.TextureLoader();
1775
2029
  loader.load(background, (texture) => {
1776
2030
  scene.background = texture;
1777
2031
  });
1778
2032
  }
1779
2033
  if (fog) {
1780
- scene.fog = new THREE10__namespace.Fog(fog.color, fog.near, fog.far);
2034
+ scene.fog = new THREE5__namespace.Fog(fog.color, fog.near, fog.far);
1781
2035
  }
1782
2036
  return () => {
1783
2037
  scene.background = null;
@@ -1800,14 +2054,14 @@ var Camera3D = React3.forwardRef(
1800
2054
  }, ref) => {
1801
2055
  const { camera, set, viewport } = fiber.useThree();
1802
2056
  const controlsRef = React3.useRef(null);
1803
- const initialPosition = React3.useRef(new THREE10__namespace.Vector3(...position));
1804
- const initialTarget = React3.useRef(new THREE10__namespace.Vector3(...target));
2057
+ const initialPosition = React3.useRef(new THREE5__namespace.Vector3(...position));
2058
+ const initialTarget = React3.useRef(new THREE5__namespace.Vector3(...target));
1805
2059
  React3.useEffect(() => {
1806
2060
  let newCamera;
1807
2061
  if (mode === "isometric") {
1808
2062
  const aspect = viewport.aspect;
1809
2063
  const size = 10 / zoom;
1810
- newCamera = new THREE10__namespace.OrthographicCamera(
2064
+ newCamera = new THREE5__namespace.OrthographicCamera(
1811
2065
  -size * aspect,
1812
2066
  size * aspect,
1813
2067
  size,
@@ -1816,7 +2070,7 @@ var Camera3D = React3.forwardRef(
1816
2070
  1e3
1817
2071
  );
1818
2072
  } else {
1819
- newCamera = new THREE10__namespace.PerspectiveCamera(fov, viewport.aspect, 0.1, 1e3);
2073
+ newCamera = new THREE5__namespace.PerspectiveCamera(fov, viewport.aspect, 0.1, 1e3);
1820
2074
  }
1821
2075
  newCamera.position.copy(initialPosition.current);
1822
2076
  newCamera.lookAt(initialTarget.current.x, initialTarget.current.y, initialTarget.current.z);
@@ -1857,8 +2111,8 @@ var Camera3D = React3.forwardRef(
1857
2111
  }
1858
2112
  },
1859
2113
  getViewBounds: () => {
1860
- const min = new THREE10__namespace.Vector3(-10, -10, -10);
1861
- const max = new THREE10__namespace.Vector3(10, 10, 10);
2114
+ const min = new THREE5__namespace.Vector3(-10, -10, -10);
2115
+ const max = new THREE5__namespace.Vector3(10, 10, 10);
1862
2116
  return { min, max };
1863
2117
  }
1864
2118
  }));
@@ -1900,7 +2154,7 @@ var AssetLoader = class {
1900
2154
  __publicField(this, "textureCache");
1901
2155
  __publicField(this, "loadingPromises");
1902
2156
  this.objLoader = new OBJLoader_js.OBJLoader();
1903
- this.textureLoader = new THREE10__namespace.TextureLoader();
2157
+ this.textureLoader = new THREE5__namespace.TextureLoader();
1904
2158
  this.modelCache = /* @__PURE__ */ new Map();
1905
2159
  this.textureCache = /* @__PURE__ */ new Map();
1906
2160
  this.loadingPromises = /* @__PURE__ */ new Map();
@@ -1974,7 +2228,7 @@ var AssetLoader = class {
1974
2228
  return this.loadingPromises.get(`texture:${url}`);
1975
2229
  }
1976
2230
  const loadPromise = this.textureLoader.loadAsync(url).then((texture) => {
1977
- texture.colorSpace = THREE10__namespace.SRGBColorSpace;
2231
+ texture.colorSpace = THREE5__namespace.SRGBColorSpace;
1978
2232
  this.textureCache.set(url, texture);
1979
2233
  this.loadingPromises.delete(`texture:${url}`);
1980
2234
  return texture;
@@ -2048,7 +2302,7 @@ var AssetLoader = class {
2048
2302
  });
2049
2303
  this.modelCache.forEach((model) => {
2050
2304
  model.scene.traverse((child) => {
2051
- if (child instanceof THREE10__namespace.Mesh) {
2305
+ if (child instanceof THREE5__namespace.Mesh) {
2052
2306
  child.geometry.dispose();
2053
2307
  if (Array.isArray(child.material)) {
2054
2308
  child.material.forEach((m) => m.dispose());
@@ -2098,21 +2352,21 @@ function useThree5(options = {}) {
2098
2352
  const [isReady, setIsReady] = React3.useState(false);
2099
2353
  const [dimensions, setDimensions] = React3.useState({ width: 0, height: 0 });
2100
2354
  const initialCameraPosition = React3.useMemo(
2101
- () => new THREE10__namespace.Vector3(...opts.cameraPosition),
2355
+ () => new THREE5__namespace.Vector3(...opts.cameraPosition),
2102
2356
  []
2103
2357
  );
2104
2358
  React3.useEffect(() => {
2105
2359
  if (!containerRef.current) return;
2106
2360
  const container = containerRef.current;
2107
2361
  const { clientWidth, clientHeight } = container;
2108
- const scene = new THREE10__namespace.Scene();
2109
- scene.background = new THREE10__namespace.Color(opts.backgroundColor);
2362
+ const scene = new THREE5__namespace.Scene();
2363
+ scene.background = new THREE5__namespace.Color(opts.backgroundColor);
2110
2364
  sceneRef.current = scene;
2111
2365
  let camera;
2112
2366
  const aspect = clientWidth / clientHeight;
2113
2367
  if (opts.cameraMode === "isometric") {
2114
2368
  const size = 10;
2115
- camera = new THREE10__namespace.OrthographicCamera(
2369
+ camera = new THREE5__namespace.OrthographicCamera(
2116
2370
  -size * aspect,
2117
2371
  size * aspect,
2118
2372
  size,
@@ -2121,11 +2375,11 @@ function useThree5(options = {}) {
2121
2375
  1e3
2122
2376
  );
2123
2377
  } else {
2124
- camera = new THREE10__namespace.PerspectiveCamera(45, aspect, 0.1, 1e3);
2378
+ camera = new THREE5__namespace.PerspectiveCamera(45, aspect, 0.1, 1e3);
2125
2379
  }
2126
2380
  camera.position.copy(initialCameraPosition);
2127
2381
  cameraRef.current = camera;
2128
- const renderer = new THREE10__namespace.WebGLRenderer({
2382
+ const renderer = new THREE5__namespace.WebGLRenderer({
2129
2383
  antialias: true,
2130
2384
  alpha: true,
2131
2385
  canvas: canvasRef.current || void 0
@@ -2133,7 +2387,7 @@ function useThree5(options = {}) {
2133
2387
  renderer.setSize(clientWidth, clientHeight);
2134
2388
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
2135
2389
  renderer.shadowMap.enabled = opts.shadows;
2136
- renderer.shadowMap.type = THREE10__namespace.PCFSoftShadowMap;
2390
+ renderer.shadowMap.type = THREE5__namespace.PCFSoftShadowMap;
2137
2391
  rendererRef.current = renderer;
2138
2392
  const controls = new OrbitControls_js.OrbitControls(camera, renderer.domElement);
2139
2393
  controls.enableDamping = true;
@@ -2142,16 +2396,16 @@ function useThree5(options = {}) {
2142
2396
  controls.maxDistance = 100;
2143
2397
  controls.maxPolarAngle = Math.PI / 2 - 0.1;
2144
2398
  controlsRef.current = controls;
2145
- const ambientLight = new THREE10__namespace.AmbientLight(16777215, 0.6);
2399
+ const ambientLight = new THREE5__namespace.AmbientLight(16777215, 0.6);
2146
2400
  scene.add(ambientLight);
2147
- const directionalLight = new THREE10__namespace.DirectionalLight(16777215, 0.8);
2401
+ const directionalLight = new THREE5__namespace.DirectionalLight(16777215, 0.8);
2148
2402
  directionalLight.position.set(10, 20, 10);
2149
2403
  directionalLight.castShadow = opts.shadows;
2150
2404
  directionalLight.shadow.mapSize.width = 2048;
2151
2405
  directionalLight.shadow.mapSize.height = 2048;
2152
2406
  scene.add(directionalLight);
2153
2407
  if (opts.showGrid) {
2154
- const gridHelper = new THREE10__namespace.GridHelper(
2408
+ const gridHelper = new THREE5__namespace.GridHelper(
2155
2409
  opts.gridSize,
2156
2410
  opts.gridSize,
2157
2411
  4473924,
@@ -2169,10 +2423,10 @@ function useThree5(options = {}) {
2169
2423
  const handleResize = () => {
2170
2424
  const { clientWidth: width, clientHeight: height } = container;
2171
2425
  setDimensions({ width, height });
2172
- if (camera instanceof THREE10__namespace.PerspectiveCamera) {
2426
+ if (camera instanceof THREE5__namespace.PerspectiveCamera) {
2173
2427
  camera.aspect = width / height;
2174
2428
  camera.updateProjectionMatrix();
2175
- } else if (camera instanceof THREE10__namespace.OrthographicCamera) {
2429
+ } else if (camera instanceof THREE5__namespace.OrthographicCamera) {
2176
2430
  const aspect2 = width / height;
2177
2431
  const size = 10;
2178
2432
  camera.left = -size * aspect2;
@@ -2203,7 +2457,7 @@ function useThree5(options = {}) {
2203
2457
  let newCamera;
2204
2458
  if (opts.cameraMode === "isometric") {
2205
2459
  const size = 10;
2206
- newCamera = new THREE10__namespace.OrthographicCamera(
2460
+ newCamera = new THREE5__namespace.OrthographicCamera(
2207
2461
  -size * aspect,
2208
2462
  size * aspect,
2209
2463
  size,
@@ -2212,7 +2466,7 @@ function useThree5(options = {}) {
2212
2466
  1e3
2213
2467
  );
2214
2468
  } else {
2215
- newCamera = new THREE10__namespace.PerspectiveCamera(45, aspect, 0.1, 1e3);
2469
+ newCamera = new THREE5__namespace.PerspectiveCamera(45, aspect, 0.1, 1e3);
2216
2470
  }
2217
2471
  newCamera.position.copy(currentPos);
2218
2472
  cameraRef.current = newCamera;
@@ -2542,8 +2796,8 @@ function useSceneGraph() {
2542
2796
  }
2543
2797
  function useRaycaster(options) {
2544
2798
  const { camera, canvas, cellSize = 1, offsetX = 0, offsetZ = 0 } = options;
2545
- const raycaster = React3.useRef(new THREE10__namespace.Raycaster());
2546
- const mouse = React3.useRef(new THREE10__namespace.Vector2());
2799
+ const raycaster = React3.useRef(new THREE5__namespace.Raycaster());
2800
+ const mouse = React3.useRef(new THREE5__namespace.Vector2());
2547
2801
  const clientToNDC = React3.useCallback(
2548
2802
  (clientX, clientY) => {
2549
2803
  if (!canvas) {
@@ -2613,8 +2867,8 @@ function useRaycaster(options) {
2613
2867
  const ndc = clientToNDC(clientX, clientY);
2614
2868
  mouse.current.set(ndc.x, ndc.y);
2615
2869
  raycaster.current.setFromCamera(mouse.current, camera);
2616
- const plane = new THREE10__namespace.Plane(new THREE10__namespace.Vector3(0, 1, 0), 0);
2617
- const target = new THREE10__namespace.Vector3();
2870
+ const plane = new THREE5__namespace.Plane(new THREE5__namespace.Vector3(0, 1, 0), 0);
2871
+ const target = new THREE5__namespace.Vector3();
2618
2872
  const intersection = raycaster.current.ray.intersectPlane(plane, target);
2619
2873
  if (intersection) {
2620
2874
  const gridX = Math.round((target.x - offsetX) / cellSize);
@@ -2652,7 +2906,7 @@ function useRaycaster(options) {
2652
2906
  return {
2653
2907
  gridX: gridCoords.x,
2654
2908
  gridZ: gridCoords.z,
2655
- worldPosition: new THREE10__namespace.Vector3(
2909
+ worldPosition: new THREE5__namespace.Vector3(
2656
2910
  gridCoords.x * cellSize + offsetX,
2657
2911
  0,
2658
2912
  gridCoords.z * cellSize + offsetZ
@@ -2682,7 +2936,7 @@ var DEFAULT_CONFIG = {
2682
2936
  };
2683
2937
  function gridToWorld(gridX, gridZ, config = DEFAULT_CONFIG) {
2684
2938
  const opts = { ...DEFAULT_CONFIG, ...config };
2685
- return new THREE10__namespace.Vector3(
2939
+ return new THREE5__namespace.Vector3(
2686
2940
  gridX * opts.cellSize + opts.offsetX,
2687
2941
  opts.elevation,
2688
2942
  gridZ * opts.cellSize + opts.offsetZ
@@ -2696,17 +2950,17 @@ function worldToGrid(worldX, worldZ, config = DEFAULT_CONFIG) {
2696
2950
  };
2697
2951
  }
2698
2952
  function raycastToPlane(camera, mouseX, mouseY, planeY = 0) {
2699
- const raycaster = new THREE10__namespace.Raycaster();
2700
- const mouse = new THREE10__namespace.Vector2(mouseX, mouseY);
2953
+ const raycaster = new THREE5__namespace.Raycaster();
2954
+ const mouse = new THREE5__namespace.Vector2(mouseX, mouseY);
2701
2955
  raycaster.setFromCamera(mouse, camera);
2702
- const plane = new THREE10__namespace.Plane(new THREE10__namespace.Vector3(0, 1, 0), -planeY);
2703
- const target = new THREE10__namespace.Vector3();
2956
+ const plane = new THREE5__namespace.Plane(new THREE5__namespace.Vector3(0, 1, 0), -planeY);
2957
+ const target = new THREE5__namespace.Vector3();
2704
2958
  const intersection = raycaster.ray.intersectPlane(plane, target);
2705
2959
  return intersection ? target : null;
2706
2960
  }
2707
2961
  function raycastToObjects(camera, mouseX, mouseY, objects) {
2708
- const raycaster = new THREE10__namespace.Raycaster();
2709
- const mouse = new THREE10__namespace.Vector2(mouseX, mouseY);
2962
+ const raycaster = new THREE5__namespace.Raycaster();
2963
+ const mouse = new THREE5__namespace.Vector2(mouseX, mouseY);
2710
2964
  raycaster.setFromCamera(mouse, camera);
2711
2965
  const intersects = raycaster.intersectObjects(objects, true);
2712
2966
  return intersects.length > 0 ? intersects[0] : null;
@@ -2758,14 +3012,14 @@ function getCellsInRadius(centerX, centerZ, radius) {
2758
3012
  return cells;
2759
3013
  }
2760
3014
  function createGridHighlight(color = 16776960, opacity = 0.3) {
2761
- const geometry = new THREE10__namespace.PlaneGeometry(0.95, 0.95);
2762
- const material = new THREE10__namespace.MeshBasicMaterial({
3015
+ const geometry = new THREE5__namespace.PlaneGeometry(0.95, 0.95);
3016
+ const material = new THREE5__namespace.MeshBasicMaterial({
2763
3017
  color,
2764
3018
  transparent: true,
2765
3019
  opacity,
2766
- side: THREE10__namespace.DoubleSide
3020
+ side: THREE5__namespace.DoubleSide
2767
3021
  });
2768
- const mesh = new THREE10__namespace.Mesh(geometry, material);
3022
+ const mesh = new THREE5__namespace.Mesh(geometry, material);
2769
3023
  mesh.rotation.x = -Math.PI / 2;
2770
3024
  mesh.position.y = 0.01;
2771
3025
  return mesh;
@@ -2778,31 +3032,31 @@ function normalizeMouseCoordinates(clientX, clientY, element) {
2778
3032
  };
2779
3033
  }
2780
3034
  function isInFrustum(position, camera, padding = 0) {
2781
- const frustum = new THREE10__namespace.Frustum();
2782
- const projScreenMatrix = new THREE10__namespace.Matrix4();
3035
+ const frustum = new THREE5__namespace.Frustum();
3036
+ const projScreenMatrix = new THREE5__namespace.Matrix4();
2783
3037
  projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
2784
3038
  frustum.setFromProjectionMatrix(projScreenMatrix);
2785
- const sphere = new THREE10__namespace.Sphere(position, padding);
3039
+ const sphere = new THREE5__namespace.Sphere(position, padding);
2786
3040
  return frustum.intersectsSphere(sphere);
2787
3041
  }
2788
3042
  function filterByFrustum(positions, camera, padding = 0) {
2789
- const frustum = new THREE10__namespace.Frustum();
2790
- const projScreenMatrix = new THREE10__namespace.Matrix4();
3043
+ const frustum = new THREE5__namespace.Frustum();
3044
+ const projScreenMatrix = new THREE5__namespace.Matrix4();
2791
3045
  projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
2792
3046
  frustum.setFromProjectionMatrix(projScreenMatrix);
2793
3047
  return positions.filter((position) => {
2794
- const sphere = new THREE10__namespace.Sphere(position, padding);
3048
+ const sphere = new THREE5__namespace.Sphere(position, padding);
2795
3049
  return frustum.intersectsSphere(sphere);
2796
3050
  });
2797
3051
  }
2798
3052
  function getVisibleIndices(positions, camera, padding = 0) {
2799
- const frustum = new THREE10__namespace.Frustum();
2800
- const projScreenMatrix = new THREE10__namespace.Matrix4();
3053
+ const frustum = new THREE5__namespace.Frustum();
3054
+ const projScreenMatrix = new THREE5__namespace.Matrix4();
2801
3055
  const visible = /* @__PURE__ */ new Set();
2802
3056
  projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
2803
3057
  frustum.setFromProjectionMatrix(projScreenMatrix);
2804
3058
  positions.forEach((position, index) => {
2805
- const sphere = new THREE10__namespace.Sphere(position, padding);
3059
+ const sphere = new THREE5__namespace.Sphere(position, padding);
2806
3060
  if (frustum.intersectsSphere(sphere)) {
2807
3061
  visible.add(index);
2808
3062
  }
@@ -2826,7 +3080,7 @@ function updateInstanceLOD(instancedMesh, positions, camera, lodDistances) {
2826
3080
  return lodIndices;
2827
3081
  }
2828
3082
  function cullInstancedMesh(instancedMesh, positions, visibleIndices) {
2829
- const dummy = new THREE10__namespace.Object3D();
3083
+ const dummy = new THREE5__namespace.Object3D();
2830
3084
  let visibleCount = 0;
2831
3085
  positions.forEach((position, index) => {
2832
3086
  if (visibleIndices.has(index)) {
@@ -3993,25 +4247,25 @@ function orbitRingPositions(count, radius, tilt) {
3993
4247
  return positions;
3994
4248
  }
3995
4249
  function arcCurve3D(from, to, offset) {
3996
- const start = new THREE10.Vector3(...from);
3997
- const end = new THREE10.Vector3(...to);
3998
- const mid = new THREE10.Vector3().addVectors(start, end).multiplyScalar(0.5);
3999
- const dir = new THREE10.Vector3().subVectors(end, start).normalize();
4000
- const up = new THREE10.Vector3(0, 1, 0);
4001
- const perp = new THREE10.Vector3().crossVectors(dir, up).normalize();
4250
+ const start = new THREE5.Vector3(...from);
4251
+ const end = new THREE5.Vector3(...to);
4252
+ const mid = new THREE5.Vector3().addVectors(start, end).multiplyScalar(0.5);
4253
+ const dir = new THREE5.Vector3().subVectors(end, start).normalize();
4254
+ const up = new THREE5.Vector3(0, 1, 0);
4255
+ const perp = new THREE5.Vector3().crossVectors(dir, up).normalize();
4002
4256
  if (perp.length() < 1e-3) {
4003
- perp.crossVectors(dir, new THREE10.Vector3(1, 0, 0)).normalize();
4257
+ perp.crossVectors(dir, new THREE5.Vector3(1, 0, 0)).normalize();
4004
4258
  }
4005
4259
  const control = mid.clone().add(perp.multiplyScalar(offset));
4006
4260
  control.y += Math.abs(offset) * 0.3;
4007
- return new THREE10.QuadraticBezierCurve3(start, control, end);
4261
+ return new THREE5.QuadraticBezierCurve3(start, control, end);
4008
4262
  }
4009
4263
  function selfLoopCurve3D(position, loopRadius) {
4010
- const base = new THREE10.Vector3(...position);
4011
- const start = base.clone().add(new THREE10.Vector3(-loopRadius * 0.3, 0, 0));
4012
- const end = base.clone().add(new THREE10.Vector3(loopRadius * 0.3, 0, 0));
4013
- const control = base.clone().add(new THREE10.Vector3(0, loopRadius, 0));
4014
- return new THREE10.QuadraticBezierCurve3(start, control, end);
4264
+ const base = new THREE5.Vector3(...position);
4265
+ const start = base.clone().add(new THREE5.Vector3(-loopRadius * 0.3, 0, 0));
4266
+ const end = base.clone().add(new THREE5.Vector3(loopRadius * 0.3, 0, 0));
4267
+ const control = base.clone().add(new THREE5.Vector3(0, loopRadius, 0));
4268
+ return new THREE5.QuadraticBezierCurve3(start, control, end);
4015
4269
  }
4016
4270
  function treeLayout3D(node, origin, horizontalSpacing, verticalSpacing = 2) {
4017
4271
  const results = [];
@@ -4178,7 +4432,7 @@ var Avl3DOrbitalNode = ({
4178
4432
  if (!groupRef.current) return;
4179
4433
  groupRef.current.rotation.y += delta * (hovered ? 0.4 : 0.2);
4180
4434
  groupRef.current.rotation.x += delta * 0.05;
4181
- currentScale.current = THREE10.MathUtils.damp(currentScale.current, targetScale, 6, delta);
4435
+ currentScale.current = THREE5.MathUtils.damp(currentScale.current, targetScale, 6, delta);
4182
4436
  });
4183
4437
  const baseBrightness = 0.3 + Math.min(pageCount, 5) * 0.05;
4184
4438
  const emissiveIntensity = hovered ? 0.8 : baseBrightness;
@@ -4820,7 +5074,7 @@ var Avl3DStateNode = ({
4820
5074
  const targetScale = hovered ? 1.08 : 1;
4821
5075
  const currentScale = React3.useRef(1);
4822
5076
  fiber.useFrame((_, delta) => {
4823
- currentScale.current = THREE10.MathUtils.damp(currentScale.current, targetScale, 6, delta);
5077
+ currentScale.current = THREE5.MathUtils.damp(currentScale.current, targetScale, 6, delta);
4824
5078
  });
4825
5079
  const scale = currentScale.current;
4826
5080
  return /* @__PURE__ */ jsxRuntime.jsxs("group", { position, children: [
@@ -5000,9 +5254,9 @@ var Avl3DTransitionArc = ({
5000
5254
  const guardPt = curve.getPoint(0.3);
5001
5255
  const arrowPt = curve.getPoint(0.9);
5002
5256
  const arrowTangent = curve.getTangent(0.9);
5003
- const upVec = new THREE10.Vector3(0, 1, 0);
5004
- const tangentVec = new THREE10.Vector3(arrowTangent.x, arrowTangent.y, arrowTangent.z).normalize();
5005
- const quat = new THREE10.Quaternion().setFromUnitVectors(upVec, tangentVec);
5257
+ const upVec = new THREE5.Vector3(0, 1, 0);
5258
+ const tangentVec = new THREE5.Vector3(arrowTangent.x, arrowTangent.y, arrowTangent.z).normalize();
5259
+ const quat = new THREE5.Quaternion().setFromUnitVectors(upVec, tangentVec);
5006
5260
  const effectPositions2 = [];
5007
5261
  for (let ei = 0; ei < 4; ei++) {
5008
5262
  const t = 0.7 + ei * 0.05;
@@ -5226,14 +5480,14 @@ function operatorColor(label) {
5226
5480
  return "#4A90D9";
5227
5481
  }
5228
5482
  function edgeGeometry(parent, child) {
5229
- const p = new THREE10.Vector3(parent.x, parent.y, parent.z);
5230
- const c = new THREE10.Vector3(child.x, child.y, child.z);
5231
- const mid = new THREE10.Vector3().addVectors(p, c).multiplyScalar(0.5);
5232
- const dir = new THREE10.Vector3().subVectors(c, p);
5483
+ const p = new THREE5.Vector3(parent.x, parent.y, parent.z);
5484
+ const c = new THREE5.Vector3(child.x, child.y, child.z);
5485
+ const mid = new THREE5.Vector3().addVectors(p, c).multiplyScalar(0.5);
5486
+ const dir = new THREE5.Vector3().subVectors(c, p);
5233
5487
  const length = dir.length();
5234
- const yAxis = new THREE10.Vector3(0, 1, 0);
5488
+ const yAxis = new THREE5.Vector3(0, 1, 0);
5235
5489
  const angle = yAxis.angleTo(dir.normalize());
5236
- const axis = new THREE10.Vector3().crossVectors(yAxis, dir).normalize();
5490
+ const axis = new THREE5.Vector3().crossVectors(yAxis, dir).normalize();
5237
5491
  if (axis.length() < 1e-3) {
5238
5492
  return {
5239
5493
  position: [mid.x, mid.y, mid.z],
@@ -5609,12 +5863,12 @@ function useAvl3DConfig() {
5609
5863
  }
5610
5864
  function CameraController({ targetPosition, targetLookAt, animated }) {
5611
5865
  const { camera } = fiber.useThree();
5612
- const targetPosVec = React3.useRef(new THREE10__namespace.Vector3(...targetPosition));
5613
- const targetLookVec = React3.useRef(new THREE10__namespace.Vector3(...targetLookAt));
5866
+ const targetPosVec = React3.useRef(new THREE5__namespace.Vector3(...targetPosition));
5867
+ const targetLookVec = React3.useRef(new THREE5__namespace.Vector3(...targetLookAt));
5614
5868
  const isAnimating = React3.useRef(false);
5615
5869
  React3.useEffect(() => {
5616
- const newTarget = new THREE10__namespace.Vector3(...targetPosition);
5617
- const newLookAt = new THREE10__namespace.Vector3(...targetLookAt);
5870
+ const newTarget = new THREE5__namespace.Vector3(...targetPosition);
5871
+ const newLookAt = new THREE5__namespace.Vector3(...targetLookAt);
5618
5872
  if (!newTarget.equals(targetPosVec.current) || !newLookAt.equals(targetLookVec.current)) {
5619
5873
  targetPosVec.current.copy(newTarget);
5620
5874
  targetLookVec.current.copy(newLookAt);
@@ -5629,9 +5883,9 @@ function CameraController({ targetPosition, targetLookAt, animated }) {
5629
5883
  fiber.useFrame((_, delta) => {
5630
5884
  if (!isAnimating.current) return;
5631
5885
  const speed = 3;
5632
- camera.position.x = THREE10__namespace.MathUtils.damp(camera.position.x, targetPosVec.current.x, speed, delta);
5633
- camera.position.y = THREE10__namespace.MathUtils.damp(camera.position.y, targetPosVec.current.y, speed, delta);
5634
- camera.position.z = THREE10__namespace.MathUtils.damp(camera.position.z, targetPosVec.current.z, speed, delta);
5886
+ camera.position.x = THREE5__namespace.MathUtils.damp(camera.position.x, targetPosVec.current.x, speed, delta);
5887
+ camera.position.y = THREE5__namespace.MathUtils.damp(camera.position.y, targetPosVec.current.y, speed, delta);
5888
+ camera.position.z = THREE5__namespace.MathUtils.damp(camera.position.z, targetPosVec.current.z, speed, delta);
5635
5889
  camera.lookAt(targetLookVec.current);
5636
5890
  const dist = camera.position.distanceTo(targetPosVec.current);
5637
5891
  if (dist < 0.05) {
@@ -5646,7 +5900,7 @@ function SceneFade({ animating, children }) {
5646
5900
  fiber.useFrame((_, delta) => {
5647
5901
  if (!groupRef.current) return;
5648
5902
  const target = animating ? 0 : 1;
5649
- opacityRef.current = THREE10__namespace.MathUtils.damp(opacityRef.current, target, 5, delta);
5903
+ opacityRef.current = THREE5__namespace.MathUtils.damp(opacityRef.current, target, 5, delta);
5650
5904
  groupRef.current.visible = opacityRef.current > 0.05;
5651
5905
  const s = 0.9 + opacityRef.current * 0.1;
5652
5906
  groupRef.current.scale.setScalar(s);