@almadar/ui 5.140.0 → 5.142.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,9 +4,11 @@ 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 THREE9 = require('three');
7
+ var THREE10 = require('three');
8
+ var RoomEnvironment_js = require('three/examples/jsm/environments/RoomEnvironment.js');
8
9
  var drei = require('@react-three/drei');
9
10
  var jsxRuntime = require('react/jsx-runtime');
11
+ var postprocessing = require('@react-three/postprocessing');
10
12
  var GLTFLoader = require('three/examples/jsm/loaders/GLTFLoader');
11
13
  var SkeletonUtils = require('three/examples/jsm/utils/SkeletonUtils');
12
14
  var clsx = require('clsx');
@@ -14,7 +16,6 @@ var tailwindMerge = require('tailwind-merge');
14
16
  var OrbitControls_js = require('three/examples/jsm/controls/OrbitControls.js');
15
17
  var GLTFLoader_js = require('three/examples/jsm/loaders/GLTFLoader.js');
16
18
  var OBJLoader_js = require('three/examples/jsm/loaders/OBJLoader.js');
17
- var postprocessing = require('@react-three/postprocessing');
18
19
  var hooks = require('@almadar/ui/hooks');
19
20
 
20
21
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
@@ -38,7 +39,7 @@ function _interopNamespace(e) {
38
39
  }
39
40
 
40
41
  var React3__default = /*#__PURE__*/_interopDefault(React3);
41
- var THREE9__namespace = /*#__PURE__*/_interopNamespace(THREE9);
42
+ var THREE10__namespace = /*#__PURE__*/_interopNamespace(THREE10);
42
43
 
43
44
  var __defProp = Object.defineProperty;
44
45
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -189,6 +190,7 @@ function collectDrawnItems(nodes) {
189
190
  case "draw-shape":
190
191
  case "draw-text":
191
192
  case "draw-group":
193
+ case "draw-mesh":
192
194
  if (isValidScenePos(n.position)) out.push({ pos: n.position, id: n.id });
193
195
  break;
194
196
  case "draw-sprite-layer":
@@ -473,6 +475,10 @@ function Lighting3D({
473
475
  directionalIntensity = 0.8,
474
476
  directionalColor = "#ffffff",
475
477
  directionalPosition = [10, 20, 10],
478
+ hemisphereIntensity = 0.3,
479
+ hemisphereColor = "#87ceeb",
480
+ hemisphereGroundColor = "#362d1d",
481
+ points,
476
482
  shadows = true,
477
483
  shadowMapSize = 2048,
478
484
  shadowCameraSize = 20,
@@ -505,22 +511,63 @@ function Lighting3D({
505
511
  /* @__PURE__ */ jsxRuntime.jsx(
506
512
  "hemisphereLight",
507
513
  {
508
- intensity: 0.3,
509
- color: "#87ceeb",
510
- groundColor: "#362d1d"
514
+ intensity: hemisphereIntensity,
515
+ color: hemisphereColor,
516
+ groundColor: hemisphereGroundColor
511
517
  }
512
518
  ),
519
+ points?.map((p, i) => /* @__PURE__ */ jsxRuntime.jsx(
520
+ "pointLight",
521
+ {
522
+ position: p.position,
523
+ intensity: p.intensity,
524
+ color: p.color,
525
+ distance: p.distance,
526
+ decay: p.decay
527
+ },
528
+ i
529
+ )),
513
530
  showHelpers && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(
514
531
  "directionalLightHelper",
515
532
  {
516
533
  args: [
517
- new THREE9__namespace.DirectionalLight(directionalColor, directionalIntensity),
534
+ new THREE10__namespace.DirectionalLight(directionalColor, directionalIntensity),
518
535
  5
519
536
  ]
520
537
  }
521
538
  ) })
522
539
  ] });
523
540
  }
541
+ function Effects3D({ post }) {
542
+ if (!post || !post.bloom && !post.vignette) return null;
543
+ const passes = [];
544
+ if (post.bloom) {
545
+ passes.push(
546
+ /* @__PURE__ */ jsxRuntime.jsx(
547
+ postprocessing.Bloom,
548
+ {
549
+ intensity: post.bloom.intensity ?? 1,
550
+ luminanceThreshold: post.bloom.threshold ?? 0.9,
551
+ luminanceSmoothing: post.bloom.smoothing ?? 0.3
552
+ },
553
+ "bloom"
554
+ )
555
+ );
556
+ }
557
+ if (post.vignette) {
558
+ passes.push(
559
+ /* @__PURE__ */ jsxRuntime.jsx(
560
+ postprocessing.Vignette,
561
+ {
562
+ offset: post.vignette.offset ?? 0.3,
563
+ darkness: post.vignette.darkness ?? 0.6
564
+ },
565
+ "vignette"
566
+ )
567
+ );
568
+ }
569
+ return /* @__PURE__ */ jsxRuntime.jsx(postprocessing.EffectComposer, { children: passes });
570
+ }
524
571
  function CameraController3D({
525
572
  onCameraChange
526
573
  }) {
@@ -541,8 +588,8 @@ function FollowCamera3D({
541
588
  offset
542
589
  }) {
543
590
  const { camera } = fiber.useThree();
544
- const look = React3.useRef(new THREE9__namespace.Vector3(target[0], target[1], target[2]));
545
- const goal = React3.useRef(new THREE9__namespace.Vector3());
591
+ const look = React3.useRef(new THREE10__namespace.Vector3(target[0], target[1], target[2]));
592
+ const goal = React3.useRef(new THREE10__namespace.Vector3());
546
593
  fiber.useFrame((_, delta) => {
547
594
  const t = Math.min(1, delta * 5);
548
595
  goal.current.set(target[0] + offset[0], target[1] + offset[1], target[2] + offset[2]);
@@ -553,6 +600,88 @@ function FollowCamera3D({
553
600
  return null;
554
601
  }
555
602
 
603
+ // lib/drawable/projector3d.ts
604
+ function create3DProjector(opts = {}) {
605
+ const cellSize = opts.cellSize ?? 1;
606
+ const offsetX = opts.offsetX ?? 0;
607
+ const offsetZ = opts.offsetZ ?? 0;
608
+ return {
609
+ cellSize,
610
+ toWorld: (pos) => [pos.x * cellSize + offsetX, pos.z ?? 0, pos.y * cellSize + offsetZ]
611
+ };
612
+ }
613
+ var NUMERIC_TRACKS = [
614
+ "offsetX",
615
+ "offsetY",
616
+ "rotate",
617
+ "opacity",
618
+ "radiusX",
619
+ "radiusY",
620
+ "width",
621
+ "height",
622
+ "strokeWidth",
623
+ "strokeDashOffset",
624
+ "blur"
625
+ ];
626
+ function isAnimatedShape(node) {
627
+ return Boolean(node.animation && node.animation.durationMs > 0 && node.animation.keyframes.length > 0);
628
+ }
629
+ var lerp = (a, b, k) => a + (b - a) * k;
630
+ function applyShapeAnimation(node, timeMs) {
631
+ const anim = node.animation;
632
+ if (!anim || !(anim.durationMs > 0) || anim.keyframes.length === 0) return node;
633
+ const frames = [...anim.keyframes].sort((a, b) => a.at - b.at);
634
+ const cycle = timeMs / anim.durationMs;
635
+ const t = anim.loop === false ? Math.min(cycle, 1) : cycle - Math.floor(cycle);
636
+ const out = { ...node };
637
+ const trackValue = (key) => {
638
+ const defined = frames.filter((f) => f[key] !== void 0);
639
+ if (defined.length === 0) return void 0;
640
+ let prev;
641
+ let next;
642
+ for (const f of defined) {
643
+ if (f.at <= t) prev = f;
644
+ else if (!next) next = f;
645
+ }
646
+ if (!prev) return defined[0][key];
647
+ if (!next) return prev[key];
648
+ const span = next.at - prev.at;
649
+ const k = span > 0 ? (t - prev.at) / span : 1;
650
+ const a = prev[key];
651
+ const b = next[key];
652
+ if (typeof a === "number" && typeof b === "number") return lerp(a, b, k);
653
+ return a;
654
+ };
655
+ for (const key of NUMERIC_TRACKS) {
656
+ const v = trackValue(key);
657
+ if (v !== void 0) out[key] = v;
658
+ }
659
+ const fill = trackValue("fill");
660
+ if (fill !== void 0) out.fill = fill;
661
+ const stroke = trackValue("stroke");
662
+ if (stroke !== void 0) out.stroke = stroke;
663
+ const shadowFrames = frames.filter((f) => f.shadow !== void 0);
664
+ if (shadowFrames.length > 0) {
665
+ const sh = trackValue("shadow");
666
+ if (sh !== void 0) {
667
+ let prevSh;
668
+ let nextSh;
669
+ for (const f of shadowFrames) {
670
+ if (f.at <= t) prevSh = f;
671
+ else if (!nextSh) nextSh = f;
672
+ }
673
+ if (prevSh?.shadow && nextSh?.shadow) {
674
+ const span = nextSh.at - prevSh.at;
675
+ 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) };
677
+ } else {
678
+ out.shadow = sh;
679
+ }
680
+ }
681
+ }
682
+ return out;
683
+ }
684
+
556
685
  // lib/atlasSlice.ts
557
686
  var atlasCache = /* @__PURE__ */ new Map();
558
687
  function isTilesheet(a) {
@@ -687,12 +816,12 @@ function ModelLoader({
687
816
  if (!loadedModel) return null;
688
817
  const cloned = SkeletonUtils.clone(loadedModel);
689
818
  cloned.updateMatrixWorld(true);
690
- const tintColor = tint ? new THREE9__namespace.Color(tint) : null;
819
+ const tintColor = tint ? new THREE10__namespace.Color(tint) : null;
691
820
  cloned.traverse((child) => {
692
- if (child instanceof THREE9__namespace.Mesh) {
821
+ if (child instanceof THREE10__namespace.Mesh) {
693
822
  child.castShadow = castShadow;
694
823
  child.receiveShadow = receiveShadow;
695
- if (tintColor && child.material instanceof THREE9__namespace.MeshStandardMaterial) {
824
+ if (tintColor && child.material instanceof THREE10__namespace.MeshStandardMaterial) {
696
825
  const mat = child.material.clone();
697
826
  mat.color.multiply(tintColor);
698
827
  child.material = mat;
@@ -701,7 +830,7 @@ function ModelLoader({
701
830
  });
702
831
  return cloned;
703
832
  }, [loadedModel, castShadow, receiveShadow, tint]);
704
- const mixer = React3.useMemo(() => model ? new THREE9__namespace.AnimationMixer(model) : null, [model]);
833
+ const mixer = React3.useMemo(() => model ? new THREE10__namespace.AnimationMixer(model) : null, [model]);
705
834
  React3.useEffect(() => {
706
835
  if (!mixer || !animation || clips.length === 0) return;
707
836
  const wanted = animation.toLowerCase();
@@ -718,8 +847,8 @@ function ModelLoader({
718
847
  });
719
848
  const normFactor = React3.useMemo(() => {
720
849
  if (!model) return 1;
721
- const box = new THREE9__namespace.Box3().setFromObject(model);
722
- const size = new THREE9__namespace.Vector3();
850
+ const box = new THREE10__namespace.Box3().setFromObject(model);
851
+ const size = new THREE10__namespace.Vector3();
723
852
  box.getSize(size);
724
853
  const maxDim = Math.max(size.x, size.y, size.z);
725
854
  if (!Number.isFinite(maxDim) || maxDim < 0.05) return 1;
@@ -809,7 +938,7 @@ var warnUnsupported3d = (kind) => {
809
938
  warnedUnsupported.add(kind);
810
939
  mesh3dLog.warn("unsupported drawable kind on the 3D backend \u2014 skipped", { kind });
811
940
  };
812
- var CrossOriginTextureLoader = class extends THREE9__namespace.TextureLoader {
941
+ var CrossOriginTextureLoader = class extends THREE10__namespace.TextureLoader {
813
942
  constructor() {
814
943
  super();
815
944
  this.crossOrigin = "anonymous";
@@ -827,7 +956,7 @@ function useBillboardTexture(url) {
827
956
  url,
828
957
  (texture) => {
829
958
  if (!active) return;
830
- texture.colorSpace = THREE9__namespace.SRGBColorSpace;
959
+ texture.colorSpace = THREE10__namespace.SRGBColorSpace;
831
960
  setState({ texture, error: false });
832
961
  },
833
962
  void 0,
@@ -859,7 +988,7 @@ function useAtlasFrame(asset) {
859
988
  return { frame: { x: r.sx, y: r.sy, w: r.sw, h: r.sh }, ready: true };
860
989
  }, [asset, tick]);
861
990
  }
862
- function SpriteBillboard({ node, world, cellSize = 1 }) {
991
+ function SpriteBillboard({ node, world, cellSize = 1, groupOpacity = 1 }) {
863
992
  const { texture, error: textureError } = useBillboardTexture(node.asset.url);
864
993
  const { frame: atlasFrame, ready: atlasReady } = useAtlasFrame(node.asset);
865
994
  const frame = node.frame ?? atlasFrame;
@@ -880,7 +1009,7 @@ function SpriteBillboard({ node, world, cellSize = 1 }) {
880
1009
  }, [texture, frame, node.height, node.width, anchor, cellSize]);
881
1010
  const groundGeometry = React3__default.default.useMemo(() => {
882
1011
  if (anchor !== "top-left" || !texture || !atlasReady) return null;
883
- const g = new THREE9__namespace.PlaneGeometry(size.width, size.height);
1012
+ const g = new THREE10__namespace.PlaneGeometry(size.width, size.height);
884
1013
  g.rotateX(-Math.PI / 2);
885
1014
  return g;
886
1015
  }, [anchor, texture, atlasReady, size.width, size.height]);
@@ -888,15 +1017,15 @@ function SpriteBillboard({ node, world, cellSize = 1 }) {
888
1017
  if (anchor === "top-left") {
889
1018
  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: [
890
1019
  /* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [size.width, size.height] }),
891
- /* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: textureError ? 16729156 : 8947848, transparent: true, opacity: 0.6, side: THREE9__namespace.DoubleSide })
1020
+ /* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: textureError ? 16729156 : 8947848, transparent: true, opacity: 0.6, side: THREE10__namespace.DoubleSide })
892
1021
  ] }) });
893
1022
  }
894
1023
  return /* @__PURE__ */ jsxRuntime.jsx("group", { position: [world[0], world[1] + size.height / 2, world[2]], children: /* @__PURE__ */ jsxRuntime.jsxs("mesh", { children: [
895
1024
  /* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [size.width, size.height] }),
896
- /* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: textureError ? 16729156 : 8947848, transparent: true, opacity: 0.6, side: THREE9__namespace.DoubleSide })
1025
+ /* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color: textureError ? 16729156 : 8947848, transparent: true, opacity: 0.6, side: THREE10__namespace.DoubleSide })
897
1026
  ] }) });
898
1027
  }
899
- texture.magFilter = texture.minFilter = THREE9__namespace.NearestFilter;
1028
+ texture.magFilter = texture.minFilter = THREE10__namespace.NearestFilter;
900
1029
  texture.needsUpdate = true;
901
1030
  if (frame) {
902
1031
  texture.repeat.set(frame.w / size.imgW, frame.h / size.imgH);
@@ -909,8 +1038,8 @@ function SpriteBillboard({ node, world, cellSize = 1 }) {
909
1038
  map: texture,
910
1039
  transparent: true,
911
1040
  alphaTest: 0.1,
912
- side: THREE9__namespace.DoubleSide,
913
- opacity: node.opacity ?? 1
1041
+ side: THREE10__namespace.DoubleSide,
1042
+ opacity: (node.opacity ?? 1) * groupOpacity
914
1043
  }
915
1044
  ) }) });
916
1045
  }
@@ -922,13 +1051,13 @@ function SpriteBillboard({ node, world, cellSize = 1 }) {
922
1051
  map: texture,
923
1052
  transparent: true,
924
1053
  alphaTest: 0.1,
925
- side: THREE9__namespace.DoubleSide,
1054
+ side: THREE10__namespace.DoubleSide,
926
1055
  opacity: node.opacity ?? 1
927
1056
  }
928
1057
  )
929
1058
  ] }) });
930
1059
  }
931
- function Sprite3D({ node, projector }) {
1060
+ function Sprite3D({ node, projector, groupOpacity = 1 }) {
932
1061
  const asset = node.asset;
933
1062
  if (!asset?.url || !isValidScenePos(node.position)) return null;
934
1063
  if (asset.dimension === "3d") {
@@ -942,7 +1071,7 @@ function Sprite3D({ node, projector }) {
942
1071
  {
943
1072
  url: asset.url,
944
1073
  scale,
945
- rotation: [0, node.rotation ?? 0, 0],
1074
+ rotation: [0, (node.rotation ?? 0) * 180 / Math.PI, 0],
946
1075
  animation: node.animation,
947
1076
  fallbackGeometry: "box",
948
1077
  castShadow: true,
@@ -950,11 +1079,30 @@ function Sprite3D({ node, projector }) {
950
1079
  }
951
1080
  ) });
952
1081
  }
953
- return /* @__PURE__ */ jsxRuntime.jsx(SpriteBillboard, { node, world: projector.toWorld(node.position), cellSize: projector.cellSize });
1082
+ return /* @__PURE__ */ jsxRuntime.jsx(SpriteBillboard, { node, world: projector.toWorld(node.position), cellSize: projector.cellSize, groupOpacity });
954
1083
  }
955
- function Shape3D({ node, projector }) {
956
- if (!isValidScenePos(node.position)) return null;
957
- const world = projector.toWorld(node.position);
1084
+ function Shape3D({ node, projector, groupOpacity = 1 }) {
1085
+ const groupRef = React3__default.default.useRef(null);
1086
+ const materialRef = React3__default.default.useRef(null);
1087
+ const animated = isAnimatedShape(node);
1088
+ const validPos = isValidScenePos(node.position);
1089
+ const world = validPos ? projector.toWorld(node.position) : [0, 0, 0];
1090
+ fiber.useFrame(({ clock }) => {
1091
+ if (!animated || !groupRef.current) return;
1092
+ const view = applyShapeAnimation(node, clock.elapsedTime * 1e3);
1093
+ groupRef.current.position.set(
1094
+ world[0] + (view.offsetX ?? 0) * projector.cellSize,
1095
+ world[1] + 0.02,
1096
+ world[2] + (view.offsetY ?? 0) * projector.cellSize
1097
+ );
1098
+ groupRef.current.rotation.y = -(view.rotate ?? 0);
1099
+ const mat = materialRef.current;
1100
+ if (mat) {
1101
+ mat.opacity = (view.opacity ?? node.opacity ?? 1) * groupOpacity;
1102
+ if (view.fill) mat.color.set(view.fill);
1103
+ }
1104
+ });
1105
+ if (!validPos) return null;
958
1106
  const color = node.fill ?? node.stroke ?? "#ffffff";
959
1107
  let geometry;
960
1108
  switch (node.shape) {
@@ -972,7 +1120,7 @@ function Shape3D({ node, projector }) {
972
1120
  }
973
1121
  case "poly": {
974
1122
  if (!node.points || node.points.length === 0) return null;
975
- const s = new THREE9__namespace.Shape();
1123
+ const s = new THREE10__namespace.Shape();
976
1124
  node.points.forEach((p, i) => {
977
1125
  if (i === 0) s.moveTo(p.x, p.y);
978
1126
  else s.lineTo(p.x, p.y);
@@ -988,12 +1136,12 @@ function Shape3D({ node, projector }) {
988
1136
  default:
989
1137
  return null;
990
1138
  }
991
- return /* @__PURE__ */ jsxRuntime.jsxs("mesh", { rotation: [-Math.PI / 2, 0, 0], position: [world[0], world[1] + 0.02, world[2]], children: [
1139
+ 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: [
992
1140
  geometry,
993
- /* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { color, transparent: true, opacity: node.opacity ?? 1, side: THREE9__namespace.DoubleSide })
994
- ] });
1141
+ /* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { ref: materialRef, color, transparent: true, opacity: (node.opacity ?? 1) * groupOpacity, side: THREE10__namespace.DoubleSide })
1142
+ ] }) });
995
1143
  }
996
- function Text3D({ node, projector }) {
1144
+ function Text3D({ node, projector, groupOpacity = 1 }) {
997
1145
  if (!isValidScenePos(node.position)) return null;
998
1146
  const world = projector.toWorld(node.position);
999
1147
  return /* @__PURE__ */ jsxRuntime.jsx(drei.Billboard, { position: [world[0], world[1] + 1.2, world[2]], children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -1005,41 +1153,252 @@ function Text3D({ node, projector }) {
1005
1153
  anchorY: "middle",
1006
1154
  outlineWidth: 0.02,
1007
1155
  outlineColor: "#000000",
1156
+ fillOpacity: groupOpacity,
1157
+ outlineOpacity: groupOpacity,
1008
1158
  children: node.text
1009
1159
  }
1010
1160
  ) });
1011
1161
  }
1012
- function Drawable3D({ node, projector }) {
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)));
1166
+ }
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;
1196
+ }
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;
1210
+ }
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
+ };
1220
+ }
1221
+ function meshGeometry(node, cellSize) {
1222
+ const seg = clampSegments(node.segments);
1223
+ const r = (node.radius ?? 0.4) * cellSize;
1224
+ const w = (node.width ?? 1) * cellSize;
1225
+ const h = (node.height ?? 1) * cellSize;
1226
+ const d = (node.depth ?? node.width ?? 1) * cellSize;
1227
+ switch (node.shape) {
1228
+ case "box":
1229
+ return { element: /* @__PURE__ */ jsxRuntime.jsx("boxGeometry", { args: [w, h, d] }), lift: h / 2, size: Math.max(w, h, d) };
1230
+ case "sphere":
1231
+ return { element: /* @__PURE__ */ jsxRuntime.jsx("sphereGeometry", { args: [r, seg, seg] }), lift: r, size: r * 2 };
1232
+ case "capsule":
1233
+ return { element: /* @__PURE__ */ jsxRuntime.jsx("capsuleGeometry", { args: [r, h, Math.max(2, Math.round(seg / 2)), seg] }), lift: h / 2 + r, size: h + r * 2 };
1234
+ case "cylinder":
1235
+ return {
1236
+ element: /* @__PURE__ */ jsxRuntime.jsx("cylinderGeometry", { args: [(node.radiusTop ?? node.radius ?? 0.4) * cellSize, (node.radiusBottom ?? node.radius ?? 0.4) * cellSize, h, seg] }),
1237
+ lift: h / 2,
1238
+ size: Math.max(h, r * 2)
1239
+ };
1240
+ case "cone":
1241
+ return { element: /* @__PURE__ */ jsxRuntime.jsx("coneGeometry", { args: [r, h, seg] }), lift: h / 2, size: Math.max(h, r * 2) };
1242
+ case "torus": {
1243
+ const tube = (node.tube ?? (node.radius ?? 0.4) / 3) * cellSize;
1244
+ 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
+ }
1246
+ case "plane":
1247
+ return { element: /* @__PURE__ */ jsxRuntime.jsx("planeGeometry", { args: [w, d] }), lift: 0, size: Math.max(w, d) };
1248
+ case "circle":
1249
+ return { element: /* @__PURE__ */ jsxRuntime.jsx("circleGeometry", { args: [r, seg] }), lift: 0, size: r * 2 };
1250
+ default:
1251
+ return null;
1252
+ }
1253
+ }
1254
+ var SIDE_MAP = {
1255
+ front: THREE10__namespace.FrontSide,
1256
+ back: THREE10__namespace.BackSide,
1257
+ double: THREE10__namespace.DoubleSide
1258
+ };
1259
+ function meshMaterial(mat, opacity, ref) {
1260
+ const m = mat ?? {};
1261
+ const common = {
1262
+ ref,
1263
+ color: m.color ?? "#ffffff",
1264
+ transparent: opacity < 1,
1265
+ opacity,
1266
+ side: SIDE_MAP[m.side ?? "front"]
1267
+ };
1268
+ const emissive = m.emissive ? { emissive: m.emissive, emissiveIntensity: m.emissiveIntensity ?? 1 } : {};
1269
+ switch (m.kind ?? "standard") {
1270
+ case "basic":
1271
+ return /* @__PURE__ */ jsxRuntime.jsx("meshBasicMaterial", { ...common });
1272
+ case "toon":
1273
+ return /* @__PURE__ */ jsxRuntime.jsx("meshToonMaterial", { ...common, ...emissive });
1274
+ case "physical":
1275
+ return /* @__PURE__ */ jsxRuntime.jsx(
1276
+ "meshPhysicalMaterial",
1277
+ {
1278
+ ...common,
1279
+ ...emissive,
1280
+ metalness: m.metalness ?? 0,
1281
+ roughness: m.roughness ?? 0.5,
1282
+ transmission: m.transmission ?? 0,
1283
+ ior: m.ior ?? 1.5,
1284
+ flatShading: m.flatShading ?? false
1285
+ }
1286
+ );
1287
+ case "standard":
1288
+ default:
1289
+ return /* @__PURE__ */ jsxRuntime.jsx(
1290
+ "meshStandardMaterial",
1291
+ {
1292
+ ...common,
1293
+ ...emissive,
1294
+ metalness: m.metalness ?? 0,
1295
+ roughness: m.roughness ?? 0.5,
1296
+ flatShading: m.flatShading ?? false
1297
+ }
1298
+ );
1299
+ }
1300
+ }
1301
+ function Mesh3D({
1302
+ node,
1303
+ projector,
1304
+ groupOpacity = 1
1305
+ }) {
1306
+ const groupRef = React3.useRef(null);
1307
+ const meshRef = React3.useRef(null);
1308
+ const materialRef = React3.useRef(null);
1309
+ const animated = isAnimatedMesh(node);
1310
+ const validPos = isValidScenePos(node.position);
1311
+ const baseWorld = validPos ? projector.toWorld(node.position) : [0, 0, 0];
1312
+ const geo = React3.useMemo(() => meshGeometry(node, projector.cellSize), [node, projector.cellSize]);
1313
+ fiber.useFrame(({ clock }) => {
1314
+ if (!animated || !groupRef.current) return;
1315
+ const state = applyMeshAnimation(node, clock.elapsedTime * 1e3);
1316
+ if (!state) return;
1317
+ const [wx, wy, wz] = baseWorld;
1318
+ groupRef.current.position.set(
1319
+ wx + state.offset[0] * projector.cellSize,
1320
+ wy + state.offset[2] * projector.cellSize,
1321
+ wz + state.offset[1] * projector.cellSize
1322
+ );
1323
+ groupRef.current.scale.setScalar(state.scale);
1324
+ if (meshRef.current) {
1325
+ 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]);
1327
+ }
1328
+ const mat = materialRef.current;
1329
+ if (mat) {
1330
+ const effective = (state.opacity ?? node.opacity ?? 1) * (node.material?.opacity ?? 1) * groupOpacity;
1331
+ mat.opacity = effective;
1332
+ mat.transparent = effective < 1;
1333
+ if (state.color && mat.color) mat.color.set(state.color);
1334
+ if (state.emissive && mat.emissive) mat.emissive.set(state.emissive);
1335
+ if (state.emissiveIntensity !== void 0 && mat.emissiveIntensity !== void 0) {
1336
+ mat.emissiveIntensity = state.emissiveIntensity;
1337
+ }
1338
+ }
1339
+ });
1340
+ if (!validPos || !geo) return null;
1341
+ const lift = (node.pivot ?? "bottom") === "bottom" ? geo.lift : 0;
1342
+ const opacity = (node.opacity ?? 1) * (node.material?.opacity ?? 1) * groupOpacity;
1343
+ const rotation = node.rotation ?? [0, 0, 0];
1344
+ const outlineScale = geo.size > 0 ? 1 + (node.outline?.width ?? 0.05) * projector.cellSize / geo.size : 1;
1345
+ return /* @__PURE__ */ jsxRuntime.jsxs("group", { ref: groupRef, position: baseWorld, children: [
1346
+ /* @__PURE__ */ jsxRuntime.jsxs(
1347
+ "mesh",
1348
+ {
1349
+ ref: meshRef,
1350
+ position: [0, lift, 0],
1351
+ rotation,
1352
+ castShadow: node.castShadow ?? true,
1353
+ receiveShadow: node.receiveShadow ?? true,
1354
+ children: [
1355
+ geo.element,
1356
+ meshMaterial(node.material, opacity, materialRef)
1357
+ ]
1358
+ }
1359
+ ),
1360
+ node.outline && /* @__PURE__ */ jsxRuntime.jsxs("mesh", { position: [0, lift, 0], rotation, scale: outlineScale, children: [
1361
+ geo.element,
1362
+ /* @__PURE__ */ jsxRuntime.jsx(
1363
+ "meshBasicMaterial",
1364
+ {
1365
+ color: node.outline.color ?? "#101014",
1366
+ side: THREE10__namespace.BackSide,
1367
+ transparent: opacity < 1,
1368
+ opacity
1369
+ }
1370
+ )
1371
+ ] })
1372
+ ] });
1373
+ }
1374
+ function Drawable3D({ node, projector, groupOpacity = 1 }) {
1013
1375
  switch (node.type) {
1014
1376
  case "draw-sprite":
1015
- return /* @__PURE__ */ jsxRuntime.jsx(Sprite3D, { node, projector });
1377
+ return /* @__PURE__ */ jsxRuntime.jsx(Sprite3D, { node, projector, groupOpacity });
1016
1378
  case "draw-shape":
1017
- return /* @__PURE__ */ jsxRuntime.jsx(Shape3D, { node, projector });
1379
+ return /* @__PURE__ */ jsxRuntime.jsx(Shape3D, { node, projector, groupOpacity });
1018
1380
  case "draw-text":
1019
- return /* @__PURE__ */ jsxRuntime.jsx(Text3D, { node, projector });
1381
+ return /* @__PURE__ */ jsxRuntime.jsx(Text3D, { node, projector, groupOpacity });
1382
+ case "draw-mesh":
1383
+ return /* @__PURE__ */ jsxRuntime.jsx(Mesh3D, { node, projector, groupOpacity });
1020
1384
  case "draw-sprite-layer":
1021
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Sprite3D, { node: item, projector }, i)) });
1385
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Sprite3D, { node: item, projector, groupOpacity }, i)) });
1022
1386
  case "draw-shape-layer":
1023
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Shape3D, { node: item, projector }, i)) });
1387
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Shape3D, { node: item, projector, groupOpacity }, i)) });
1024
1388
  case "draw-text-layer":
1025
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Text3D, { node: item, projector }, i)) });
1026
- case "draw-group":
1027
- warnUnsupported3d("draw-group");
1028
- return null;
1389
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: node.items.map((item, i) => /* @__PURE__ */ jsxRuntime.jsx(Text3D, { node: item, projector, groupOpacity }, i)) });
1390
+ case "draw-group": {
1391
+ if (!isValidScenePos(node.position) || !Array.isArray(node.items)) return null;
1392
+ 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)) });
1398
+ }
1029
1399
  }
1030
1400
  }
1031
1401
 
1032
- // lib/drawable/projector3d.ts
1033
- function create3DProjector(opts = {}) {
1034
- const cellSize = opts.cellSize ?? 1;
1035
- const offsetX = opts.offsetX ?? 0;
1036
- const offsetZ = opts.offsetZ ?? 0;
1037
- return {
1038
- cellSize,
1039
- toWorld: (pos) => [pos.x * cellSize + offsetX, pos.z ?? 0, pos.y * cellSize + offsetZ]
1040
- };
1041
- }
1042
-
1043
1402
  // lib/drawable/three/game3dTheme.ts
1044
1403
  var GRID_COLORS_3D = {
1045
1404
  cell: "#444444",
@@ -1051,6 +1410,20 @@ function cn(...inputs) {
1051
1410
  }
1052
1411
  var DEFAULT_GRID_CONFIG = {
1053
1412
  cellSize: 1};
1413
+ function RoomEnvironment3D() {
1414
+ const { gl, scene } = fiber.useThree(({ gl: gl2, scene: scene2 }) => ({ gl: gl2, scene: scene2 }));
1415
+ React3.useEffect(() => {
1416
+ const pmremGenerator = new THREE10__namespace.PMREMGenerator(gl);
1417
+ const envTexture = pmremGenerator.fromScene(new RoomEnvironment_js.RoomEnvironment(), 0.04).texture;
1418
+ scene.environment = envTexture;
1419
+ return () => {
1420
+ scene.environment = null;
1421
+ envTexture.dispose();
1422
+ pmremGenerator.dispose();
1423
+ };
1424
+ }, [gl, scene]);
1425
+ return null;
1426
+ }
1054
1427
  var Canvas3DHost = React3.forwardRef(
1055
1428
  ({
1056
1429
  cameraMode = "isometric",
@@ -1075,6 +1448,9 @@ var Canvas3DHost = React3.forwardRef(
1075
1448
  keyMap,
1076
1449
  keyUpMap,
1077
1450
  pixelsPerUnit,
1451
+ fov,
1452
+ lighting,
1453
+ post,
1078
1454
  children,
1079
1455
  drawables
1080
1456
  }, ref) => {
@@ -1083,6 +1459,7 @@ var Canvas3DHost = React3.forwardRef(
1083
1459
  const [internalError, setInternalError] = React3.useState(null);
1084
1460
  const eventBus = useEventBus();
1085
1461
  const keysRef = React3.useRef(/* @__PURE__ */ new Set());
1462
+ const allDrawables = React3.useMemo(() => drawables ?? [], [drawables]);
1086
1463
  React3.useEffect(() => {
1087
1464
  if (!keyMap && !keyUpMap) return;
1088
1465
  const down = (e) => {
@@ -1116,7 +1493,7 @@ var Canvas3DHost = React3.forwardRef(
1116
1493
  unitAnimationEvent,
1117
1494
  cameraChangeEvent
1118
1495
  });
1119
- const drawnItems = React3.useMemo(() => collectDrawnItems(drawables ?? []), [drawables]);
1496
+ const drawnItems = React3.useMemo(() => collectDrawnItems(allDrawables), [allDrawables]);
1120
1497
  const scenePositions = React3.useMemo(() => drawnItems.map((i) => i.pos), [drawnItems]);
1121
1498
  const hitIndex = React3.useMemo(() => buildHitIndex(drawnItems), [drawnItems]);
1122
1499
  const gridBounds = React3.useMemo(() => {
@@ -1164,7 +1541,7 @@ var Canvas3DHost = React3.forwardRef(
1164
1541
  getCameraPosition: () => {
1165
1542
  if (controlsRef.current) {
1166
1543
  const pos = controlsRef.current.object.position;
1167
- return new THREE9__namespace.Vector3(pos.x, pos.y, pos.z);
1544
+ return new THREE10__namespace.Vector3(pos.x, pos.y, pos.z);
1168
1545
  }
1169
1546
  return null;
1170
1547
  },
@@ -1203,18 +1580,19 @@ var Canvas3DHost = React3.forwardRef(
1203
1580
  const cx = cameraTarget[0];
1204
1581
  const cz = cameraTarget[2];
1205
1582
  const d = size * 1;
1583
+ const fovDeg = fov ?? 45;
1206
1584
  switch (cameraMode) {
1207
1585
  case "isometric":
1208
- return { position: [cx + d, d * 0.8, cz + d], fov: 45 };
1586
+ return { position: [cx + d, d * 0.8, cz + d], fov: fovDeg };
1209
1587
  case "top-down":
1210
- return { position: [cx, d * 2, cz + d * 0.35], fov: 45 };
1588
+ return { position: [cx, d * 2, cz + d * 0.35], fov: fovDeg };
1211
1589
  case "follow":
1212
- return { position: [cx, d * 0.5, cz + d], fov: 45 };
1590
+ return { position: [cx, d * 0.5, cz + d], fov: fovDeg };
1213
1591
  case "perspective":
1214
1592
  default:
1215
- return { position: [cx + d, d, cz + d], fov: 45 };
1593
+ return { position: [cx + d, d, cz + d], fov: fovDeg };
1216
1594
  }
1217
- }, [cameraMode, gridBounds, cellSize, cameraTarget]);
1595
+ }, [cameraMode, gridBounds, cellSize, cameraTarget, fov]);
1218
1596
  const followWorld = React3.useMemo(() => {
1219
1597
  if (followTarget) return drawableProjector.toWorld(followTarget);
1220
1598
  return cameraTarget;
@@ -1297,9 +1675,19 @@ var Canvas3DHost = React3.forwardRef(
1297
1675
  shadowNormalBias: 0.04,
1298
1676
  shadowCameraSize: 5,
1299
1677
  shadowCameraNear: 0.5,
1300
- shadowCameraFar: 500
1678
+ shadowCameraFar: 500,
1679
+ ambientIntensity: lighting?.ambient?.intensity,
1680
+ ambientColor: lighting?.ambient?.color,
1681
+ directionalIntensity: lighting?.directional?.intensity,
1682
+ directionalColor: lighting?.directional?.color,
1683
+ directionalPosition: lighting?.directional?.position,
1684
+ hemisphereIntensity: lighting?.hemisphere?.intensity,
1685
+ hemisphereColor: lighting?.hemisphere?.color,
1686
+ hemisphereGroundColor: lighting?.hemisphere?.groundColor,
1687
+ points: lighting?.points
1301
1688
  }
1302
1689
  ),
1690
+ lighting?.environment === "room" && /* @__PURE__ */ jsxRuntime.jsx(RoomEnvironment3D, {}),
1303
1691
  showGrid && /* @__PURE__ */ jsxRuntime.jsx(
1304
1692
  drei.Grid,
1305
1693
  {
@@ -1322,7 +1710,7 @@ var Canvas3DHost = React3.forwardRef(
1322
1710
  fadeStrength: 1
1323
1711
  }
1324
1712
  ),
1325
- drawables && drawables.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("group", { children: drawables.map((node, i) => /* @__PURE__ */ jsxRuntime.jsx(Drawable3D, { node, projector: drawableProjector }, i)) }),
1713
+ allDrawables.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("group", { children: allDrawables.map((node, i) => /* @__PURE__ */ jsxRuntime.jsx(Drawable3D, { node, projector: drawableProjector }, i)) }),
1326
1714
  (tileClickEvent || unitClickEvent) && /* @__PURE__ */ jsxRuntime.jsxs(
1327
1715
  "mesh",
1328
1716
  {
@@ -1347,7 +1735,7 @@ var Canvas3DHost = React3.forwardRef(
1347
1735
  ]
1348
1736
  }
1349
1737
  ),
1350
- children,
1738
+ post && (post.bloom || post.vignette) ? /* @__PURE__ */ jsxRuntime.jsx(Effects3D, { post }) : null,
1351
1739
  /* @__PURE__ */ jsxRuntime.jsx(
1352
1740
  drei.OrbitControls,
1353
1741
  {
@@ -1358,7 +1746,7 @@ var Canvas3DHost = React3.forwardRef(
1358
1746
  dampingFactor: 0.05,
1359
1747
  enableZoom: true,
1360
1748
  enablePan: true,
1361
- touches: { ONE: THREE9__namespace.TOUCH.ROTATE, TWO: THREE9__namespace.TOUCH.DOLLY_PAN },
1749
+ touches: { ONE: THREE10__namespace.TOUCH.ROTATE, TWO: THREE10__namespace.TOUCH.DOLLY_PAN },
1362
1750
  minDistance: 2,
1363
1751
  maxDistance: 100,
1364
1752
  maxPolarAngle: Math.PI / 2 - 0.1
@@ -1381,15 +1769,15 @@ function Scene3D({ background = "#1a1a2e", fog, children }) {
1381
1769
  if (initializedRef.current) return;
1382
1770
  initializedRef.current = true;
1383
1771
  if (background.startsWith("#") || background.startsWith("rgb")) {
1384
- scene.background = new THREE9__namespace.Color(background);
1772
+ scene.background = new THREE10__namespace.Color(background);
1385
1773
  } else {
1386
- const loader = new THREE9__namespace.TextureLoader();
1774
+ const loader = new THREE10__namespace.TextureLoader();
1387
1775
  loader.load(background, (texture) => {
1388
1776
  scene.background = texture;
1389
1777
  });
1390
1778
  }
1391
1779
  if (fog) {
1392
- scene.fog = new THREE9__namespace.Fog(fog.color, fog.near, fog.far);
1780
+ scene.fog = new THREE10__namespace.Fog(fog.color, fog.near, fog.far);
1393
1781
  }
1394
1782
  return () => {
1395
1783
  scene.background = null;
@@ -1412,14 +1800,14 @@ var Camera3D = React3.forwardRef(
1412
1800
  }, ref) => {
1413
1801
  const { camera, set, viewport } = fiber.useThree();
1414
1802
  const controlsRef = React3.useRef(null);
1415
- const initialPosition = React3.useRef(new THREE9__namespace.Vector3(...position));
1416
- const initialTarget = React3.useRef(new THREE9__namespace.Vector3(...target));
1803
+ const initialPosition = React3.useRef(new THREE10__namespace.Vector3(...position));
1804
+ const initialTarget = React3.useRef(new THREE10__namespace.Vector3(...target));
1417
1805
  React3.useEffect(() => {
1418
1806
  let newCamera;
1419
1807
  if (mode === "isometric") {
1420
1808
  const aspect = viewport.aspect;
1421
1809
  const size = 10 / zoom;
1422
- newCamera = new THREE9__namespace.OrthographicCamera(
1810
+ newCamera = new THREE10__namespace.OrthographicCamera(
1423
1811
  -size * aspect,
1424
1812
  size * aspect,
1425
1813
  size,
@@ -1428,7 +1816,7 @@ var Camera3D = React3.forwardRef(
1428
1816
  1e3
1429
1817
  );
1430
1818
  } else {
1431
- newCamera = new THREE9__namespace.PerspectiveCamera(fov, viewport.aspect, 0.1, 1e3);
1819
+ newCamera = new THREE10__namespace.PerspectiveCamera(fov, viewport.aspect, 0.1, 1e3);
1432
1820
  }
1433
1821
  newCamera.position.copy(initialPosition.current);
1434
1822
  newCamera.lookAt(initialTarget.current.x, initialTarget.current.y, initialTarget.current.z);
@@ -1469,8 +1857,8 @@ var Camera3D = React3.forwardRef(
1469
1857
  }
1470
1858
  },
1471
1859
  getViewBounds: () => {
1472
- const min = new THREE9__namespace.Vector3(-10, -10, -10);
1473
- const max = new THREE9__namespace.Vector3(10, 10, 10);
1860
+ const min = new THREE10__namespace.Vector3(-10, -10, -10);
1861
+ const max = new THREE10__namespace.Vector3(10, 10, 10);
1474
1862
  return { min, max };
1475
1863
  }
1476
1864
  }));
@@ -1512,7 +1900,7 @@ var AssetLoader = class {
1512
1900
  __publicField(this, "textureCache");
1513
1901
  __publicField(this, "loadingPromises");
1514
1902
  this.objLoader = new OBJLoader_js.OBJLoader();
1515
- this.textureLoader = new THREE9__namespace.TextureLoader();
1903
+ this.textureLoader = new THREE10__namespace.TextureLoader();
1516
1904
  this.modelCache = /* @__PURE__ */ new Map();
1517
1905
  this.textureCache = /* @__PURE__ */ new Map();
1518
1906
  this.loadingPromises = /* @__PURE__ */ new Map();
@@ -1586,7 +1974,7 @@ var AssetLoader = class {
1586
1974
  return this.loadingPromises.get(`texture:${url}`);
1587
1975
  }
1588
1976
  const loadPromise = this.textureLoader.loadAsync(url).then((texture) => {
1589
- texture.colorSpace = THREE9__namespace.SRGBColorSpace;
1977
+ texture.colorSpace = THREE10__namespace.SRGBColorSpace;
1590
1978
  this.textureCache.set(url, texture);
1591
1979
  this.loadingPromises.delete(`texture:${url}`);
1592
1980
  return texture;
@@ -1660,7 +2048,7 @@ var AssetLoader = class {
1660
2048
  });
1661
2049
  this.modelCache.forEach((model) => {
1662
2050
  model.scene.traverse((child) => {
1663
- if (child instanceof THREE9__namespace.Mesh) {
2051
+ if (child instanceof THREE10__namespace.Mesh) {
1664
2052
  child.geometry.dispose();
1665
2053
  if (Array.isArray(child.material)) {
1666
2054
  child.material.forEach((m) => m.dispose());
@@ -1697,7 +2085,7 @@ var DEFAULT_OPTIONS = {
1697
2085
  gridSize: 20,
1698
2086
  assetLoader: new AssetLoader()
1699
2087
  };
1700
- function useThree4(options = {}) {
2088
+ function useThree5(options = {}) {
1701
2089
  const opts = { ...DEFAULT_OPTIONS, ...options };
1702
2090
  const containerRef = React3.useRef(null);
1703
2091
  const canvasRef = React3.useRef(null);
@@ -1710,21 +2098,21 @@ function useThree4(options = {}) {
1710
2098
  const [isReady, setIsReady] = React3.useState(false);
1711
2099
  const [dimensions, setDimensions] = React3.useState({ width: 0, height: 0 });
1712
2100
  const initialCameraPosition = React3.useMemo(
1713
- () => new THREE9__namespace.Vector3(...opts.cameraPosition),
2101
+ () => new THREE10__namespace.Vector3(...opts.cameraPosition),
1714
2102
  []
1715
2103
  );
1716
2104
  React3.useEffect(() => {
1717
2105
  if (!containerRef.current) return;
1718
2106
  const container = containerRef.current;
1719
2107
  const { clientWidth, clientHeight } = container;
1720
- const scene = new THREE9__namespace.Scene();
1721
- scene.background = new THREE9__namespace.Color(opts.backgroundColor);
2108
+ const scene = new THREE10__namespace.Scene();
2109
+ scene.background = new THREE10__namespace.Color(opts.backgroundColor);
1722
2110
  sceneRef.current = scene;
1723
2111
  let camera;
1724
2112
  const aspect = clientWidth / clientHeight;
1725
2113
  if (opts.cameraMode === "isometric") {
1726
2114
  const size = 10;
1727
- camera = new THREE9__namespace.OrthographicCamera(
2115
+ camera = new THREE10__namespace.OrthographicCamera(
1728
2116
  -size * aspect,
1729
2117
  size * aspect,
1730
2118
  size,
@@ -1733,11 +2121,11 @@ function useThree4(options = {}) {
1733
2121
  1e3
1734
2122
  );
1735
2123
  } else {
1736
- camera = new THREE9__namespace.PerspectiveCamera(45, aspect, 0.1, 1e3);
2124
+ camera = new THREE10__namespace.PerspectiveCamera(45, aspect, 0.1, 1e3);
1737
2125
  }
1738
2126
  camera.position.copy(initialCameraPosition);
1739
2127
  cameraRef.current = camera;
1740
- const renderer = new THREE9__namespace.WebGLRenderer({
2128
+ const renderer = new THREE10__namespace.WebGLRenderer({
1741
2129
  antialias: true,
1742
2130
  alpha: true,
1743
2131
  canvas: canvasRef.current || void 0
@@ -1745,7 +2133,7 @@ function useThree4(options = {}) {
1745
2133
  renderer.setSize(clientWidth, clientHeight);
1746
2134
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
1747
2135
  renderer.shadowMap.enabled = opts.shadows;
1748
- renderer.shadowMap.type = THREE9__namespace.PCFSoftShadowMap;
2136
+ renderer.shadowMap.type = THREE10__namespace.PCFSoftShadowMap;
1749
2137
  rendererRef.current = renderer;
1750
2138
  const controls = new OrbitControls_js.OrbitControls(camera, renderer.domElement);
1751
2139
  controls.enableDamping = true;
@@ -1754,16 +2142,16 @@ function useThree4(options = {}) {
1754
2142
  controls.maxDistance = 100;
1755
2143
  controls.maxPolarAngle = Math.PI / 2 - 0.1;
1756
2144
  controlsRef.current = controls;
1757
- const ambientLight = new THREE9__namespace.AmbientLight(16777215, 0.6);
2145
+ const ambientLight = new THREE10__namespace.AmbientLight(16777215, 0.6);
1758
2146
  scene.add(ambientLight);
1759
- const directionalLight = new THREE9__namespace.DirectionalLight(16777215, 0.8);
2147
+ const directionalLight = new THREE10__namespace.DirectionalLight(16777215, 0.8);
1760
2148
  directionalLight.position.set(10, 20, 10);
1761
2149
  directionalLight.castShadow = opts.shadows;
1762
2150
  directionalLight.shadow.mapSize.width = 2048;
1763
2151
  directionalLight.shadow.mapSize.height = 2048;
1764
2152
  scene.add(directionalLight);
1765
2153
  if (opts.showGrid) {
1766
- const gridHelper = new THREE9__namespace.GridHelper(
2154
+ const gridHelper = new THREE10__namespace.GridHelper(
1767
2155
  opts.gridSize,
1768
2156
  opts.gridSize,
1769
2157
  4473924,
@@ -1781,10 +2169,10 @@ function useThree4(options = {}) {
1781
2169
  const handleResize = () => {
1782
2170
  const { clientWidth: width, clientHeight: height } = container;
1783
2171
  setDimensions({ width, height });
1784
- if (camera instanceof THREE9__namespace.PerspectiveCamera) {
2172
+ if (camera instanceof THREE10__namespace.PerspectiveCamera) {
1785
2173
  camera.aspect = width / height;
1786
2174
  camera.updateProjectionMatrix();
1787
- } else if (camera instanceof THREE9__namespace.OrthographicCamera) {
2175
+ } else if (camera instanceof THREE10__namespace.OrthographicCamera) {
1788
2176
  const aspect2 = width / height;
1789
2177
  const size = 10;
1790
2178
  camera.left = -size * aspect2;
@@ -1815,7 +2203,7 @@ function useThree4(options = {}) {
1815
2203
  let newCamera;
1816
2204
  if (opts.cameraMode === "isometric") {
1817
2205
  const size = 10;
1818
- newCamera = new THREE9__namespace.OrthographicCamera(
2206
+ newCamera = new THREE10__namespace.OrthographicCamera(
1819
2207
  -size * aspect,
1820
2208
  size * aspect,
1821
2209
  size,
@@ -1824,7 +2212,7 @@ function useThree4(options = {}) {
1824
2212
  1e3
1825
2213
  );
1826
2214
  } else {
1827
- newCamera = new THREE9__namespace.PerspectiveCamera(45, aspect, 0.1, 1e3);
2215
+ newCamera = new THREE10__namespace.PerspectiveCamera(45, aspect, 0.1, 1e3);
1828
2216
  }
1829
2217
  newCamera.position.copy(currentPos);
1830
2218
  cameraRef.current = newCamera;
@@ -2154,8 +2542,8 @@ function useSceneGraph() {
2154
2542
  }
2155
2543
  function useRaycaster(options) {
2156
2544
  const { camera, canvas, cellSize = 1, offsetX = 0, offsetZ = 0 } = options;
2157
- const raycaster = React3.useRef(new THREE9__namespace.Raycaster());
2158
- const mouse = React3.useRef(new THREE9__namespace.Vector2());
2545
+ const raycaster = React3.useRef(new THREE10__namespace.Raycaster());
2546
+ const mouse = React3.useRef(new THREE10__namespace.Vector2());
2159
2547
  const clientToNDC = React3.useCallback(
2160
2548
  (clientX, clientY) => {
2161
2549
  if (!canvas) {
@@ -2225,8 +2613,8 @@ function useRaycaster(options) {
2225
2613
  const ndc = clientToNDC(clientX, clientY);
2226
2614
  mouse.current.set(ndc.x, ndc.y);
2227
2615
  raycaster.current.setFromCamera(mouse.current, camera);
2228
- const plane = new THREE9__namespace.Plane(new THREE9__namespace.Vector3(0, 1, 0), 0);
2229
- const target = new THREE9__namespace.Vector3();
2616
+ const plane = new THREE10__namespace.Plane(new THREE10__namespace.Vector3(0, 1, 0), 0);
2617
+ const target = new THREE10__namespace.Vector3();
2230
2618
  const intersection = raycaster.current.ray.intersectPlane(plane, target);
2231
2619
  if (intersection) {
2232
2620
  const gridX = Math.round((target.x - offsetX) / cellSize);
@@ -2264,7 +2652,7 @@ function useRaycaster(options) {
2264
2652
  return {
2265
2653
  gridX: gridCoords.x,
2266
2654
  gridZ: gridCoords.z,
2267
- worldPosition: new THREE9__namespace.Vector3(
2655
+ worldPosition: new THREE10__namespace.Vector3(
2268
2656
  gridCoords.x * cellSize + offsetX,
2269
2657
  0,
2270
2658
  gridCoords.z * cellSize + offsetZ
@@ -2294,7 +2682,7 @@ var DEFAULT_CONFIG = {
2294
2682
  };
2295
2683
  function gridToWorld(gridX, gridZ, config = DEFAULT_CONFIG) {
2296
2684
  const opts = { ...DEFAULT_CONFIG, ...config };
2297
- return new THREE9__namespace.Vector3(
2685
+ return new THREE10__namespace.Vector3(
2298
2686
  gridX * opts.cellSize + opts.offsetX,
2299
2687
  opts.elevation,
2300
2688
  gridZ * opts.cellSize + opts.offsetZ
@@ -2308,17 +2696,17 @@ function worldToGrid(worldX, worldZ, config = DEFAULT_CONFIG) {
2308
2696
  };
2309
2697
  }
2310
2698
  function raycastToPlane(camera, mouseX, mouseY, planeY = 0) {
2311
- const raycaster = new THREE9__namespace.Raycaster();
2312
- const mouse = new THREE9__namespace.Vector2(mouseX, mouseY);
2699
+ const raycaster = new THREE10__namespace.Raycaster();
2700
+ const mouse = new THREE10__namespace.Vector2(mouseX, mouseY);
2313
2701
  raycaster.setFromCamera(mouse, camera);
2314
- const plane = new THREE9__namespace.Plane(new THREE9__namespace.Vector3(0, 1, 0), -planeY);
2315
- const target = new THREE9__namespace.Vector3();
2702
+ const plane = new THREE10__namespace.Plane(new THREE10__namespace.Vector3(0, 1, 0), -planeY);
2703
+ const target = new THREE10__namespace.Vector3();
2316
2704
  const intersection = raycaster.ray.intersectPlane(plane, target);
2317
2705
  return intersection ? target : null;
2318
2706
  }
2319
2707
  function raycastToObjects(camera, mouseX, mouseY, objects) {
2320
- const raycaster = new THREE9__namespace.Raycaster();
2321
- const mouse = new THREE9__namespace.Vector2(mouseX, mouseY);
2708
+ const raycaster = new THREE10__namespace.Raycaster();
2709
+ const mouse = new THREE10__namespace.Vector2(mouseX, mouseY);
2322
2710
  raycaster.setFromCamera(mouse, camera);
2323
2711
  const intersects = raycaster.intersectObjects(objects, true);
2324
2712
  return intersects.length > 0 ? intersects[0] : null;
@@ -2370,14 +2758,14 @@ function getCellsInRadius(centerX, centerZ, radius) {
2370
2758
  return cells;
2371
2759
  }
2372
2760
  function createGridHighlight(color = 16776960, opacity = 0.3) {
2373
- const geometry = new THREE9__namespace.PlaneGeometry(0.95, 0.95);
2374
- const material = new THREE9__namespace.MeshBasicMaterial({
2761
+ const geometry = new THREE10__namespace.PlaneGeometry(0.95, 0.95);
2762
+ const material = new THREE10__namespace.MeshBasicMaterial({
2375
2763
  color,
2376
2764
  transparent: true,
2377
2765
  opacity,
2378
- side: THREE9__namespace.DoubleSide
2766
+ side: THREE10__namespace.DoubleSide
2379
2767
  });
2380
- const mesh = new THREE9__namespace.Mesh(geometry, material);
2768
+ const mesh = new THREE10__namespace.Mesh(geometry, material);
2381
2769
  mesh.rotation.x = -Math.PI / 2;
2382
2770
  mesh.position.y = 0.01;
2383
2771
  return mesh;
@@ -2390,31 +2778,31 @@ function normalizeMouseCoordinates(clientX, clientY, element) {
2390
2778
  };
2391
2779
  }
2392
2780
  function isInFrustum(position, camera, padding = 0) {
2393
- const frustum = new THREE9__namespace.Frustum();
2394
- const projScreenMatrix = new THREE9__namespace.Matrix4();
2781
+ const frustum = new THREE10__namespace.Frustum();
2782
+ const projScreenMatrix = new THREE10__namespace.Matrix4();
2395
2783
  projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
2396
2784
  frustum.setFromProjectionMatrix(projScreenMatrix);
2397
- const sphere = new THREE9__namespace.Sphere(position, padding);
2785
+ const sphere = new THREE10__namespace.Sphere(position, padding);
2398
2786
  return frustum.intersectsSphere(sphere);
2399
2787
  }
2400
2788
  function filterByFrustum(positions, camera, padding = 0) {
2401
- const frustum = new THREE9__namespace.Frustum();
2402
- const projScreenMatrix = new THREE9__namespace.Matrix4();
2789
+ const frustum = new THREE10__namespace.Frustum();
2790
+ const projScreenMatrix = new THREE10__namespace.Matrix4();
2403
2791
  projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
2404
2792
  frustum.setFromProjectionMatrix(projScreenMatrix);
2405
2793
  return positions.filter((position) => {
2406
- const sphere = new THREE9__namespace.Sphere(position, padding);
2794
+ const sphere = new THREE10__namespace.Sphere(position, padding);
2407
2795
  return frustum.intersectsSphere(sphere);
2408
2796
  });
2409
2797
  }
2410
2798
  function getVisibleIndices(positions, camera, padding = 0) {
2411
- const frustum = new THREE9__namespace.Frustum();
2412
- const projScreenMatrix = new THREE9__namespace.Matrix4();
2799
+ const frustum = new THREE10__namespace.Frustum();
2800
+ const projScreenMatrix = new THREE10__namespace.Matrix4();
2413
2801
  const visible = /* @__PURE__ */ new Set();
2414
2802
  projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
2415
2803
  frustum.setFromProjectionMatrix(projScreenMatrix);
2416
2804
  positions.forEach((position, index) => {
2417
- const sphere = new THREE9__namespace.Sphere(position, padding);
2805
+ const sphere = new THREE10__namespace.Sphere(position, padding);
2418
2806
  if (frustum.intersectsSphere(sphere)) {
2419
2807
  visible.add(index);
2420
2808
  }
@@ -2438,7 +2826,7 @@ function updateInstanceLOD(instancedMesh, positions, camera, lodDistances) {
2438
2826
  return lodIndices;
2439
2827
  }
2440
2828
  function cullInstancedMesh(instancedMesh, positions, visibleIndices) {
2441
- const dummy = new THREE9__namespace.Object3D();
2829
+ const dummy = new THREE10__namespace.Object3D();
2442
2830
  let visibleCount = 0;
2443
2831
  positions.forEach((position, index) => {
2444
2832
  if (visibleIndices.has(index)) {
@@ -3605,25 +3993,25 @@ function orbitRingPositions(count, radius, tilt) {
3605
3993
  return positions;
3606
3994
  }
3607
3995
  function arcCurve3D(from, to, offset) {
3608
- const start = new THREE9.Vector3(...from);
3609
- const end = new THREE9.Vector3(...to);
3610
- const mid = new THREE9.Vector3().addVectors(start, end).multiplyScalar(0.5);
3611
- const dir = new THREE9.Vector3().subVectors(end, start).normalize();
3612
- const up = new THREE9.Vector3(0, 1, 0);
3613
- const perp = new THREE9.Vector3().crossVectors(dir, up).normalize();
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();
3614
4002
  if (perp.length() < 1e-3) {
3615
- perp.crossVectors(dir, new THREE9.Vector3(1, 0, 0)).normalize();
4003
+ perp.crossVectors(dir, new THREE10.Vector3(1, 0, 0)).normalize();
3616
4004
  }
3617
4005
  const control = mid.clone().add(perp.multiplyScalar(offset));
3618
4006
  control.y += Math.abs(offset) * 0.3;
3619
- return new THREE9.QuadraticBezierCurve3(start, control, end);
4007
+ return new THREE10.QuadraticBezierCurve3(start, control, end);
3620
4008
  }
3621
4009
  function selfLoopCurve3D(position, loopRadius) {
3622
- const base = new THREE9.Vector3(...position);
3623
- const start = base.clone().add(new THREE9.Vector3(-loopRadius * 0.3, 0, 0));
3624
- const end = base.clone().add(new THREE9.Vector3(loopRadius * 0.3, 0, 0));
3625
- const control = base.clone().add(new THREE9.Vector3(0, loopRadius, 0));
3626
- return new THREE9.QuadraticBezierCurve3(start, control, end);
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);
3627
4015
  }
3628
4016
  function treeLayout3D(node, origin, horizontalSpacing, verticalSpacing = 2) {
3629
4017
  const results = [];
@@ -3790,7 +4178,7 @@ var Avl3DOrbitalNode = ({
3790
4178
  if (!groupRef.current) return;
3791
4179
  groupRef.current.rotation.y += delta * (hovered ? 0.4 : 0.2);
3792
4180
  groupRef.current.rotation.x += delta * 0.05;
3793
- currentScale.current = THREE9.MathUtils.damp(currentScale.current, targetScale, 6, delta);
4181
+ currentScale.current = THREE10.MathUtils.damp(currentScale.current, targetScale, 6, delta);
3794
4182
  });
3795
4183
  const baseBrightness = 0.3 + Math.min(pageCount, 5) * 0.05;
3796
4184
  const emissiveIntensity = hovered ? 0.8 : baseBrightness;
@@ -4432,7 +4820,7 @@ var Avl3DStateNode = ({
4432
4820
  const targetScale = hovered ? 1.08 : 1;
4433
4821
  const currentScale = React3.useRef(1);
4434
4822
  fiber.useFrame((_, delta) => {
4435
- currentScale.current = THREE9.MathUtils.damp(currentScale.current, targetScale, 6, delta);
4823
+ currentScale.current = THREE10.MathUtils.damp(currentScale.current, targetScale, 6, delta);
4436
4824
  });
4437
4825
  const scale = currentScale.current;
4438
4826
  return /* @__PURE__ */ jsxRuntime.jsxs("group", { position, children: [
@@ -4612,9 +5000,9 @@ var Avl3DTransitionArc = ({
4612
5000
  const guardPt = curve.getPoint(0.3);
4613
5001
  const arrowPt = curve.getPoint(0.9);
4614
5002
  const arrowTangent = curve.getTangent(0.9);
4615
- const upVec = new THREE9.Vector3(0, 1, 0);
4616
- const tangentVec = new THREE9.Vector3(arrowTangent.x, arrowTangent.y, arrowTangent.z).normalize();
4617
- const quat = new THREE9.Quaternion().setFromUnitVectors(upVec, tangentVec);
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);
4618
5006
  const effectPositions2 = [];
4619
5007
  for (let ei = 0; ei < 4; ei++) {
4620
5008
  const t = 0.7 + ei * 0.05;
@@ -4838,14 +5226,14 @@ function operatorColor(label) {
4838
5226
  return "#4A90D9";
4839
5227
  }
4840
5228
  function edgeGeometry(parent, child) {
4841
- const p = new THREE9.Vector3(parent.x, parent.y, parent.z);
4842
- const c = new THREE9.Vector3(child.x, child.y, child.z);
4843
- const mid = new THREE9.Vector3().addVectors(p, c).multiplyScalar(0.5);
4844
- const dir = new THREE9.Vector3().subVectors(c, p);
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);
4845
5233
  const length = dir.length();
4846
- const yAxis = new THREE9.Vector3(0, 1, 0);
5234
+ const yAxis = new THREE10.Vector3(0, 1, 0);
4847
5235
  const angle = yAxis.angleTo(dir.normalize());
4848
- const axis = new THREE9.Vector3().crossVectors(yAxis, dir).normalize();
5236
+ const axis = new THREE10.Vector3().crossVectors(yAxis, dir).normalize();
4849
5237
  if (axis.length() < 1e-3) {
4850
5238
  return {
4851
5239
  position: [mid.x, mid.y, mid.z],
@@ -5221,12 +5609,12 @@ function useAvl3DConfig() {
5221
5609
  }
5222
5610
  function CameraController({ targetPosition, targetLookAt, animated }) {
5223
5611
  const { camera } = fiber.useThree();
5224
- const targetPosVec = React3.useRef(new THREE9__namespace.Vector3(...targetPosition));
5225
- const targetLookVec = React3.useRef(new THREE9__namespace.Vector3(...targetLookAt));
5612
+ const targetPosVec = React3.useRef(new THREE10__namespace.Vector3(...targetPosition));
5613
+ const targetLookVec = React3.useRef(new THREE10__namespace.Vector3(...targetLookAt));
5226
5614
  const isAnimating = React3.useRef(false);
5227
5615
  React3.useEffect(() => {
5228
- const newTarget = new THREE9__namespace.Vector3(...targetPosition);
5229
- const newLookAt = new THREE9__namespace.Vector3(...targetLookAt);
5616
+ const newTarget = new THREE10__namespace.Vector3(...targetPosition);
5617
+ const newLookAt = new THREE10__namespace.Vector3(...targetLookAt);
5230
5618
  if (!newTarget.equals(targetPosVec.current) || !newLookAt.equals(targetLookVec.current)) {
5231
5619
  targetPosVec.current.copy(newTarget);
5232
5620
  targetLookVec.current.copy(newLookAt);
@@ -5241,9 +5629,9 @@ function CameraController({ targetPosition, targetLookAt, animated }) {
5241
5629
  fiber.useFrame((_, delta) => {
5242
5630
  if (!isAnimating.current) return;
5243
5631
  const speed = 3;
5244
- camera.position.x = THREE9__namespace.MathUtils.damp(camera.position.x, targetPosVec.current.x, speed, delta);
5245
- camera.position.y = THREE9__namespace.MathUtils.damp(camera.position.y, targetPosVec.current.y, speed, delta);
5246
- camera.position.z = THREE9__namespace.MathUtils.damp(camera.position.z, targetPosVec.current.z, speed, delta);
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);
5247
5635
  camera.lookAt(targetLookVec.current);
5248
5636
  const dist = camera.position.distanceTo(targetPosVec.current);
5249
5637
  if (dist < 0.05) {
@@ -5258,7 +5646,7 @@ function SceneFade({ animating, children }) {
5258
5646
  fiber.useFrame((_, delta) => {
5259
5647
  if (!groupRef.current) return;
5260
5648
  const target = animating ? 0 : 1;
5261
- opacityRef.current = THREE9__namespace.MathUtils.damp(opacityRef.current, target, 5, delta);
5649
+ opacityRef.current = THREE10__namespace.MathUtils.damp(opacityRef.current, target, 5, delta);
5262
5650
  groupRef.current.visible = opacityRef.current > 0.05;
5263
5651
  const s = 0.9 + opacityRef.current * 0.1;
5264
5652
  groupRef.current.scale.setScalar(s);
@@ -5558,5 +5946,5 @@ exports.useAvl3DConfig = useAvl3DConfig;
5558
5946
  exports.useGameCanvas3DEvents = useGameCanvas3DEvents;
5559
5947
  exports.useRaycaster = useRaycaster;
5560
5948
  exports.useSceneGraph = useSceneGraph;
5561
- exports.useThree = useThree4;
5949
+ exports.useThree = useThree5;
5562
5950
  exports.worldToGrid = worldToGrid;