@nice2dev/ui-3d 1.0.2 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/cjs/core/i18n.js +3 -3
  2. package/dist/cjs/dance/DanceBridge.js +13 -13
  3. package/dist/cjs/dance/DanceScoreEngine.js +8 -8
  4. package/dist/cjs/dance/PoseDetector.js +20 -20
  5. package/dist/cjs/material/NiceMaterialEditor.js +19 -19
  6. package/dist/cjs/model/ModelEditorLeftPanel.js +3 -3
  7. package/dist/cjs/model/ModelEditorMenuBar.js +2 -2
  8. package/dist/cjs/model/ModelEditorRightPanel.js +2 -2
  9. package/dist/cjs/model/ModelEditorSubComponents.js +3 -3
  10. package/dist/cjs/model/ModelEditorTimeline.js +3 -3
  11. package/dist/cjs/model/ModelEditorToolbar.js +2 -2
  12. package/dist/cjs/model/ModelEditorViewport.js +2 -2
  13. package/dist/cjs/model/ModelViewer.js +8 -8
  14. package/dist/cjs/model/NiceArmatureEditor.js +18 -18
  15. package/dist/cjs/model/NiceMorphTargetEditor.js +18 -18
  16. package/dist/cjs/model/NiceOctree.js +16 -16
  17. package/dist/cjs/model/NicePhysicsSimulation.js +24 -24
  18. package/dist/cjs/model/NiceProceduralGeometry.js +8 -8
  19. package/dist/cjs/model/NiceTerrainEditor.js +19 -19
  20. package/dist/cjs/model/NiceWeightPainter.js +14 -14
  21. package/dist/cjs/model/NiceXRPreview.js +18 -18
  22. package/dist/cjs/model/useModelEditor.js +127 -127
  23. package/dist/cjs/model/useModelViewer.js +61 -61
  24. package/dist/cjs/particle/NiceParticleEditor.js +11 -11
  25. package/dist/cjs/rendering/NiceCascadedShadows.js +12 -12
  26. package/dist/cjs/rendering/NiceRenderExport.js +5 -5
  27. package/dist/cjs/rendering/NiceSSAO.js +18 -18
  28. package/dist/cjs/rendering/NiceSSR.js +14 -14
  29. package/dist/cjs/rendering/NiceWebGPURenderer.js +21 -21
  30. package/dist/cjs/ui/dist/index.js +26566 -19233
  31. package/dist/cjs/ui/dist/index.js.map +1 -1
  32. package/dist/cjs/uv/NiceUVEditor.js +24 -24
  33. package/dist/esm/model/ModelEditorLeftPanel.js +5 -5
  34. package/dist/esm/model/ModelEditorMenuBar.js +5 -5
  35. package/dist/esm/model/ModelEditorRightPanel.js +17 -17
  36. package/dist/esm/model/ModelEditorSubComponents.js +6 -6
  37. package/dist/esm/model/ModelEditorTimeline.js +5 -5
  38. package/dist/esm/model/ModelEditorToolbar.js +4 -4
  39. package/dist/esm/model/ModelEditorViewport.js +2 -2
  40. package/dist/esm/model/ModelViewer.js +5 -5
  41. package/dist/esm/ui/dist/index.js +25913 -18601
  42. package/dist/esm/ui/dist/index.js.map +1 -1
  43. package/package.json +2 -2
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var Ae = require('react');
3
+ var Ve = require('react');
4
4
  var THREE = require('three');
5
5
  var OrbitControls_js = require('three/examples/jsm/controls/OrbitControls.js');
6
6
  var TransformControls_js = require('three/examples/jsm/controls/TransformControls.js');
@@ -72,82 +72,82 @@ function findNodeById(nodes, id) {
72
72
  ═══════════════════════════════════════════ */
73
73
  function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
74
74
  /* ── refs ── */
75
- const mountRef = Ae.useRef(null);
76
- const rendererRef = Ae.useRef(null);
77
- const sceneRef = Ae.useRef(new THREE__namespace.Scene());
78
- const cameraRef = Ae.useRef(new THREE__namespace.PerspectiveCamera(50, 1, 0.01, 10000));
79
- const orbitRef = Ae.useRef(null);
80
- const transformRef = Ae.useRef(null);
81
- const clockRef = Ae.useRef(new THREE__namespace.Clock());
82
- const mixerRef = Ae.useRef(null);
83
- const rafRef = Ae.useRef(0);
84
- const fileInputRef = Ae.useRef(null);
85
- const mergeInputRef = Ae.useRef(null);
86
- const videoInputRef = Ae.useRef(null);
87
- const raycasterRef = Ae.useRef(new THREE__namespace.Raycaster());
88
- const skeletonHelperRef = Ae.useRef(null);
75
+ const mountRef = Ve.useRef(null);
76
+ const rendererRef = Ve.useRef(null);
77
+ const sceneRef = Ve.useRef(new THREE__namespace.Scene());
78
+ const cameraRef = Ve.useRef(new THREE__namespace.PerspectiveCamera(50, 1, 0.01, 10000));
79
+ const orbitRef = Ve.useRef(null);
80
+ const transformRef = Ve.useRef(null);
81
+ const clockRef = Ve.useRef(new THREE__namespace.Clock());
82
+ const mixerRef = Ve.useRef(null);
83
+ const rafRef = Ve.useRef(0);
84
+ const fileInputRef = Ve.useRef(null);
85
+ const mergeInputRef = Ve.useRef(null);
86
+ const videoInputRef = Ve.useRef(null);
87
+ const raycasterRef = Ve.useRef(new THREE__namespace.Raycaster());
88
+ const skeletonHelperRef = Ve.useRef(null);
89
89
  /* ── state ── */
90
- const [sceneTree, setSceneTree] = Ae.useState([]);
91
- const [selectedId, setSelectedId] = Ae.useState(null);
92
- const [transformMode, setTransformMode] = Ae.useState("translate");
93
- const [animations, setAnimations] = Ae.useState([]);
94
- const [activeAnimIdx, setActiveAnimIdx] = Ae.useState(-1);
95
- const [isPlaying, setIsPlaying] = Ae.useState(false);
96
- const [animTime, setAnimTime] = Ae.useState(0);
97
- const [animDuration, setAnimDuration] = Ae.useState(0);
98
- const [animSpeed, setAnimSpeed] = Ae.useState(1);
99
- const [loopAnim, setLoopAnim] = Ae.useState(true);
100
- const [bottomCollapsed, setBottomCollapsed] = Ae.useState(false);
101
- const [showGrid, setShowGrid] = Ae.useState(true);
102
- const [showAxes, setShowAxes] = Ae.useState(true);
103
- const [wireframe, setWireframe] = Ae.useState(false);
104
- const [bgColor, setBgColor] = Ae.useState("#111122");
105
- const [statusText, setStatusText] = Ae.useState("Ready");
106
- const [dragOver, setDragOver] = Ae.useState(false);
107
- const [polyCount, setPolyCount] = Ae.useState(0);
108
- const [meshCount, setMeshCount] = Ae.useState(0);
109
- const [boneCount, setBoneCount] = Ae.useState(0);
90
+ const [sceneTree, setSceneTree] = Ve.useState([]);
91
+ const [selectedId, setSelectedId] = Ve.useState(null);
92
+ const [transformMode, setTransformMode] = Ve.useState("translate");
93
+ const [animations, setAnimations] = Ve.useState([]);
94
+ const [activeAnimIdx, setActiveAnimIdx] = Ve.useState(-1);
95
+ const [isPlaying, setIsPlaying] = Ve.useState(false);
96
+ const [animTime, setAnimTime] = Ve.useState(0);
97
+ const [animDuration, setAnimDuration] = Ve.useState(0);
98
+ const [animSpeed, setAnimSpeed] = Ve.useState(1);
99
+ const [loopAnim, setLoopAnim] = Ve.useState(true);
100
+ const [bottomCollapsed, setBottomCollapsed] = Ve.useState(false);
101
+ const [showGrid, setShowGrid] = Ve.useState(true);
102
+ const [showAxes, setShowAxes] = Ve.useState(true);
103
+ const [wireframe, setWireframe] = Ve.useState(false);
104
+ const [bgColor, setBgColor] = Ve.useState("#111122");
105
+ const [statusText, setStatusText] = Ve.useState("Ready");
106
+ const [dragOver, setDragOver] = Ve.useState(false);
107
+ const [polyCount, setPolyCount] = Ve.useState(0);
108
+ const [meshCount, setMeshCount] = Ve.useState(0);
109
+ const [boneCount, setBoneCount] = Ve.useState(0);
110
110
  // Material editor
111
- const [selMaterialIdx, setSelMaterialIdx] = Ae.useState(0);
112
- const [matRefresh, setMatRefresh] = Ae.useState(0);
111
+ const [selMaterialIdx, setSelMaterialIdx] = Ve.useState(0);
112
+ const [matRefresh, setMatRefresh] = Ve.useState(0);
113
113
  // AI panel
114
- const [aiStatus, setAiStatus] = Ae.useState("");
115
- const [aiBusy, setAiBusy] = Ae.useState(false);
114
+ const [aiStatus, setAiStatus] = Ve.useState("");
115
+ const [aiBusy, setAiBusy] = Ve.useState(false);
116
116
  // Blender 2.0 — viewport & editor
117
- const [shadingMode, setShadingMode] = Ae.useState("solid");
118
- const [editorMode, setEditorMode] = Ae.useState("object");
119
- const [contextMenu, setContextMenu] = Ae.useState(null);
120
- const [outlinerSearch, setOutlinerSearch] = Ae.useState("");
121
- const [snapEnabled, setSnapEnabled] = Ae.useState(false);
122
- const [snapGrid, setSnapGrid] = Ae.useState(1);
123
- const [showSkeleton, setShowSkeleton] = Ae.useState(true);
124
- const [addMenuOpen, setAddMenuOpen] = Ae.useState(null);
125
- const [gizmoSpace, setGizmoSpace] = Ae.useState("world");
126
- const [propTab, setPropTab] = Ae.useState("object");
127
- const [fogEnabled, setFogEnabled] = Ae.useState(false);
128
- const [fogColor, setFogColor] = Ae.useState("#111122");
129
- const [fogNear, setFogNear] = Ae.useState(10);
130
- const [fogFar, setFogFar] = Ae.useState(100);
131
- const [showLightHelpers, setShowLightHelpers] = Ae.useState(true);
117
+ const [shadingMode, setShadingMode] = Ve.useState("solid");
118
+ const [editorMode, setEditorMode] = Ve.useState("object");
119
+ const [contextMenu, setContextMenu] = Ve.useState(null);
120
+ const [outlinerSearch, setOutlinerSearch] = Ve.useState("");
121
+ const [snapEnabled, setSnapEnabled] = Ve.useState(false);
122
+ const [snapGrid, setSnapGrid] = Ve.useState(1);
123
+ const [showSkeleton, setShowSkeleton] = Ve.useState(true);
124
+ const [addMenuOpen, setAddMenuOpen] = Ve.useState(null);
125
+ const [gizmoSpace, setGizmoSpace] = Ve.useState("world");
126
+ const [propTab, setPropTab] = Ve.useState("object");
127
+ const [fogEnabled, setFogEnabled] = Ve.useState(false);
128
+ const [fogColor, setFogColor] = Ve.useState("#111122");
129
+ const [fogNear, setFogNear] = Ve.useState(10);
130
+ const [fogFar, setFogFar] = Ve.useState(100);
131
+ const [showLightHelpers, setShowLightHelpers] = Ve.useState(true);
132
132
  // The root object that was loaded (mesh/character)
133
- const rootObjectRef = Ae.useRef(null);
133
+ const rootObjectRef = Ve.useRef(null);
134
134
  // Active animation action
135
- const activeActionRef = Ae.useRef(null);
135
+ const activeActionRef = Ve.useRef(null);
136
136
  // All loaded animation clips (for the current model)
137
- const allClipsRef = Ae.useRef([]);
137
+ const allClipsRef = Ve.useRef([]);
138
138
  /* keep refs current */
139
- const animTimeRef = Ae.useRef(animTime);
139
+ const animTimeRef = Ve.useRef(animTime);
140
140
  animTimeRef.current = animTime;
141
- const isPlayingRef = Ae.useRef(isPlaying);
141
+ const isPlayingRef = Ve.useRef(isPlaying);
142
142
  isPlayingRef.current = isPlaying;
143
- const animSpeedRef = Ae.useRef(animSpeed);
143
+ const animSpeedRef = Ve.useRef(animSpeed);
144
144
  animSpeedRef.current = animSpeed;
145
- const loopAnimRef = Ae.useRef(loopAnim);
145
+ const loopAnimRef = Ve.useRef(loopAnim);
146
146
  loopAnimRef.current = loopAnim;
147
147
  /* ─────────────────────────────────────────
148
148
  Scene setup
149
149
  ───────────────────────────────────────── */
150
- Ae.useEffect(() => {
150
+ Ve.useEffect(() => {
151
151
  const container = mountRef.current;
152
152
  if (!container)
153
153
  return;
@@ -280,7 +280,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
280
280
  /* ─────────────────────────────────────────
281
281
  Rebuild scene tree from Three.js scene
282
282
  ───────────────────────────────────────── */
283
- const rebuildTree = Ae.useCallback(() => {
283
+ const rebuildTree = Ve.useCallback(() => {
284
284
  const scene = sceneRef.current;
285
285
  let polys = 0;
286
286
  let meshes = 0;
@@ -347,9 +347,9 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
347
347
  /* ─────────────────────────────────────────
348
348
  File loading
349
349
  ───────────────────────────────────────── */
350
- const playClipRef = Ae.useRef(() => { });
351
- const focusOnObjectRef = Ae.useRef(() => { });
352
- const addObjectToScene = Ae.useCallback((obj, clips, filename) => {
350
+ const playClipRef = Ve.useRef(() => { });
351
+ const focusOnObjectRef = Ve.useRef(() => { });
352
+ const addObjectToScene = Ve.useCallback((obj, clips, filename) => {
353
353
  const scene = sceneRef.current;
354
354
  obj.traverse((child) => {
355
355
  if (child instanceof THREE__namespace.Mesh) {
@@ -396,7 +396,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
396
396
  rebuildTree();
397
397
  setStatusText(`Loaded: ${filename} (${clips.length} animation(s))`);
398
398
  }, [rebuildTree]);
399
- const loadFile = Ae.useCallback(async (file) => {
399
+ const loadFile = Ve.useCallback(async (file) => {
400
400
  var _a, _b, _c, _d, _e, _f;
401
401
  const name = file.name.toLowerCase();
402
402
  const ext = "." + name.split(".").pop();
@@ -515,7 +515,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
515
515
  URL.revokeObjectURL(url);
516
516
  }
517
517
  }, [addObjectToScene]);
518
- const mergeAnimationFBX = Ae.useCallback(async (file) => {
518
+ const mergeAnimationFBX = Ve.useCallback(async (file) => {
519
519
  var _a;
520
520
  const url = URL.createObjectURL(file);
521
521
  setStatusText(`Merging animations from ${file.name}...`);
@@ -556,7 +556,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
556
556
  /* ─────────────────────────────────────────
557
557
  Animation controls
558
558
  ───────────────────────────────────────── */
559
- const playClip = Ae.useCallback((index) => {
559
+ const playClip = Ve.useCallback((index) => {
560
560
  const mixer = mixerRef.current;
561
561
  if (!mixer || index < 0 || index >= allClipsRef.current.length)
562
562
  return;
@@ -576,7 +576,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
576
576
  setIsPlaying(true);
577
577
  }, []);
578
578
  playClipRef.current = playClip;
579
- const togglePlay = Ae.useCallback(() => {
579
+ const togglePlay = Ve.useCallback(() => {
580
580
  if (activeAnimIdx < 0 && allClipsRef.current.length > 0) {
581
581
  playClip(0);
582
582
  return;
@@ -593,7 +593,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
593
593
  setIsPlaying(true);
594
594
  }
595
595
  }, [activeAnimIdx, playClip]);
596
- const stopAnim = Ae.useCallback(() => {
596
+ const stopAnim = Ve.useCallback(() => {
597
597
  const action = activeActionRef.current;
598
598
  if (action) {
599
599
  action.stop();
@@ -602,7 +602,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
602
602
  setIsPlaying(false);
603
603
  setAnimTime(0);
604
604
  }, []);
605
- const seekAnim = Ae.useCallback((t) => {
605
+ const seekAnim = Ve.useCallback((t) => {
606
606
  var _a;
607
607
  const action = activeActionRef.current;
608
608
  if (!action)
@@ -616,7 +616,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
616
616
  /* ─────────────────────────────────────────
617
617
  Camera helpers
618
618
  ───────────────────────────────────────── */
619
- const focusOnObject = Ae.useCallback((obj) => {
619
+ const focusOnObject = Ve.useCallback((obj) => {
620
620
  const box = new THREE__namespace.Box3().setFromObject(obj);
621
621
  const center = box.getCenter(new THREE__namespace.Vector3());
622
622
  const size = box.getSize(new THREE__namespace.Vector3());
@@ -630,7 +630,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
630
630
  }
631
631
  }, []);
632
632
  focusOnObjectRef.current = focusOnObject;
633
- const setCameraPreset = Ae.useCallback((preset) => {
633
+ const setCameraPreset = Ve.useCallback((preset) => {
634
634
  const orbit = orbitRef.current;
635
635
  if (!orbit)
636
636
  return;
@@ -664,7 +664,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
664
664
  /* ─────────────────────────────────────────
665
665
  Selection & transform
666
666
  ───────────────────────────────────────── */
667
- const selectObject = Ae.useCallback((node) => {
667
+ const selectObject = Ve.useCallback((node) => {
668
668
  var _a;
669
669
  setSelectedId((_a = node === null || node === void 0 ? void 0 : node.id) !== null && _a !== void 0 ? _a : null);
670
670
  const tc = transformRef.current;
@@ -678,29 +678,29 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
678
678
  tc.detach();
679
679
  }
680
680
  }, [transformMode]);
681
- Ae.useEffect(() => {
681
+ Ve.useEffect(() => {
682
682
  var _a;
683
683
  (_a = transformRef.current) === null || _a === void 0 ? void 0 : _a.setMode(transformMode);
684
684
  }, [transformMode]);
685
685
  /* ─────────────────────────────────────────
686
686
  Toggle helpers
687
687
  ───────────────────────────────────────── */
688
- Ae.useEffect(() => {
688
+ Ve.useEffect(() => {
689
689
  const scene = sceneRef.current;
690
690
  const grid = scene.getObjectByName("__grid");
691
691
  if (grid)
692
692
  grid.visible = showGrid;
693
693
  }, [showGrid]);
694
- Ae.useEffect(() => {
694
+ Ve.useEffect(() => {
695
695
  const scene = sceneRef.current;
696
696
  const axes = scene.getObjectByName("__axes");
697
697
  if (axes)
698
698
  axes.visible = showAxes;
699
699
  }, [showAxes]);
700
- Ae.useEffect(() => {
700
+ Ve.useEffect(() => {
701
701
  sceneRef.current.background = new THREE__namespace.Color(bgColor);
702
702
  }, [bgColor]);
703
- Ae.useEffect(() => {
703
+ Ve.useEffect(() => {
704
704
  const root = rootObjectRef.current;
705
705
  if (!root)
706
706
  return;
@@ -719,7 +719,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
719
719
  /* ─────────────────────────────────────────
720
720
  Viewport shading mode
721
721
  ───────────────────────────────────────── */
722
- Ae.useEffect(() => {
722
+ Ve.useEffect(() => {
723
723
  const renderer = rendererRef.current;
724
724
  if (!renderer)
725
725
  return;
@@ -772,12 +772,12 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
772
772
  }
773
773
  }, [shadingMode]);
774
774
  /* Gizmo space */
775
- Ae.useEffect(() => {
775
+ Ve.useEffect(() => {
776
776
  var _a;
777
777
  (_a = transformRef.current) === null || _a === void 0 ? void 0 : _a.setSpace(gizmoSpace);
778
778
  }, [gizmoSpace]);
779
779
  /* Snap settings */
780
- Ae.useEffect(() => {
780
+ Ve.useEffect(() => {
781
781
  const tc = transformRef.current;
782
782
  if (!tc)
783
783
  return;
@@ -793,7 +793,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
793
793
  }
794
794
  }, [snapEnabled, snapGrid]);
795
795
  /* Skeleton helper */
796
- Ae.useEffect(() => {
796
+ Ve.useEffect(() => {
797
797
  const scene = sceneRef.current;
798
798
  if (skeletonHelperRef.current) {
799
799
  scene.remove(skeletonHelperRef.current);
@@ -814,7 +814,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
814
814
  }
815
815
  }, [showSkeleton, sceneTree]);
816
816
  /* Fog */
817
- Ae.useEffect(() => {
817
+ Ve.useEffect(() => {
818
818
  if (fogEnabled) {
819
819
  sceneRef.current.fog = new THREE__namespace.Fog(fogColor, fogNear, fogFar);
820
820
  }
@@ -823,7 +823,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
823
823
  }
824
824
  }, [fogEnabled, fogColor, fogNear, fogFar]);
825
825
  /* Light helpers visibility */
826
- Ae.useEffect(() => {
826
+ Ve.useEffect(() => {
827
827
  sceneRef.current.traverse((obj) => {
828
828
  if (obj.name.startsWith("__helper_")) {
829
829
  obj.visible = showLightHelpers;
@@ -833,16 +833,16 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
833
833
  /* ─────────────────────────────────────────
834
834
  Drag-and-drop
835
835
  ───────────────────────────────────────── */
836
- const handleDragOver = Ae.useCallback((e) => {
836
+ const handleDragOver = Ve.useCallback((e) => {
837
837
  e.preventDefault();
838
838
  e.stopPropagation();
839
839
  setDragOver(true);
840
840
  }, []);
841
- const handleDragLeave = Ae.useCallback((e) => {
841
+ const handleDragLeave = Ve.useCallback((e) => {
842
842
  e.preventDefault();
843
843
  setDragOver(false);
844
844
  }, []);
845
- const handleDrop = Ae.useCallback((e) => {
845
+ const handleDrop = Ve.useCallback((e) => {
846
846
  e.preventDefault();
847
847
  e.stopPropagation();
848
848
  setDragOver(false);
@@ -857,14 +857,14 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
857
857
  /* ─────────────────────────────────────────
858
858
  Helpers
859
859
  ───────────────────────────────────────── */
860
- const selectedNode = Ae.useMemo(() => (selectedId ? findNodeById(sceneTree, selectedId) : null), [selectedId, sceneTree]);
861
- const selectedMaterials = Ae.useMemo(() => {
860
+ const selectedNode = Ve.useMemo(() => (selectedId ? findNodeById(sceneTree, selectedId) : null), [selectedId, sceneTree]);
861
+ const selectedMaterials = Ve.useMemo(() => {
862
862
  if (!selectedNode || !(selectedNode.object instanceof THREE__namespace.Mesh))
863
863
  return [];
864
864
  const m = selectedNode.object.material;
865
865
  return Array.isArray(m) ? m : [m];
866
866
  }, [selectedNode, matRefresh]);
867
- const deleteSelected = Ae.useCallback(() => {
867
+ const deleteSelected = Ve.useCallback(() => {
868
868
  var _a;
869
869
  if (!selectedNode)
870
870
  return;
@@ -873,7 +873,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
873
873
  setSelectedId(null);
874
874
  rebuildTree();
875
875
  }, [selectedNode, rebuildTree]);
876
- const duplicateSelected = Ae.useCallback(() => {
876
+ const duplicateSelected = Ve.useCallback(() => {
877
877
  if (!selectedNode)
878
878
  return;
879
879
  const clone = selectedNode.object.clone(true);
@@ -886,7 +886,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
886
886
  /* ─────────────────────────────────────────
887
887
  Keyboard shortcuts
888
888
  ───────────────────────────────────────── */
889
- Ae.useEffect(() => {
889
+ Ve.useEffect(() => {
890
890
  const handleKey = (e) => {
891
891
  var _a, _b, _c;
892
892
  const tag = (_a = e.target) === null || _a === void 0 ? void 0 : _a.tagName;
@@ -994,14 +994,14 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
994
994
  /* ─────────────────────────────────────────
995
995
  File input handlers
996
996
  ───────────────────────────────────────── */
997
- const handleFileInput = Ae.useCallback((e) => {
997
+ const handleFileInput = Ve.useCallback((e) => {
998
998
  const files = e.target.files;
999
999
  if (!files)
1000
1000
  return;
1001
1001
  Array.from(files).forEach(loadFile);
1002
1002
  e.target.value = "";
1003
1003
  }, [loadFile]);
1004
- const handleMergeInput = Ae.useCallback((e) => {
1004
+ const handleMergeInput = Ve.useCallback((e) => {
1005
1005
  const files = e.target.files;
1006
1006
  if (!files)
1007
1007
  return;
@@ -1011,7 +1011,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1011
1011
  /* ─────────────────────────────────────────
1012
1012
  Export functions
1013
1013
  ───────────────────────────────────────── */
1014
- const exportGLTF = Ae.useCallback((binary) => {
1014
+ const exportGLTF = Ve.useCallback((binary) => {
1015
1015
  const root = rootObjectRef.current;
1016
1016
  if (!root) {
1017
1017
  setStatusText("Nothing to export");
@@ -1038,7 +1038,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1038
1038
  setStatusText(`Export error: ${String(err)}`);
1039
1039
  }, options);
1040
1040
  }, []);
1041
- const exportOBJ = Ae.useCallback(() => {
1041
+ const exportOBJ = Ve.useCallback(() => {
1042
1042
  const root = rootObjectRef.current;
1043
1043
  if (!root) {
1044
1044
  setStatusText("Nothing to export");
@@ -1054,7 +1054,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1054
1054
  URL.revokeObjectURL(a.href);
1055
1055
  setStatusText("Exported OBJ successfully");
1056
1056
  }, []);
1057
- const exportSTL = Ae.useCallback((binary) => {
1057
+ const exportSTL = Ve.useCallback((binary) => {
1058
1058
  const root = rootObjectRef.current;
1059
1059
  if (!root) {
1060
1060
  setStatusText("Nothing to export");
@@ -1076,7 +1076,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1076
1076
  URL.revokeObjectURL(a.href);
1077
1077
  setStatusText(`Exported STL${binary ? " (binary)" : ""} successfully`);
1078
1078
  }, []);
1079
- const exportPLY = Ae.useCallback((binary) => {
1079
+ const exportPLY = Ve.useCallback((binary) => {
1080
1080
  const root = rootObjectRef.current;
1081
1081
  if (!root) {
1082
1082
  setStatusText("Nothing to export");
@@ -1100,7 +1100,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1100
1100
  setStatusText(`Exported PLY${binary ? " (binary)" : ""} successfully`);
1101
1101
  }, { binary });
1102
1102
  }, []);
1103
- const exportUSDZ = Ae.useCallback(async () => {
1103
+ const exportUSDZ = Ve.useCallback(async () => {
1104
1104
  const root = rootObjectRef.current;
1105
1105
  if (!root) {
1106
1106
  setStatusText("Nothing to export");
@@ -1128,7 +1128,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1128
1128
  /* ─────────────────────────────────────────
1129
1129
  Dispose & clear
1130
1130
  ───────────────────────────────────────── */
1131
- const disposeObject = Ae.useCallback((obj) => {
1131
+ const disposeObject = Ve.useCallback((obj) => {
1132
1132
  obj.traverse((child) => {
1133
1133
  if (child.geometry) {
1134
1134
  child.geometry.dispose();
@@ -1148,7 +1148,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1148
1148
  }
1149
1149
  });
1150
1150
  }, []);
1151
- const clearScene = Ae.useCallback(() => {
1151
+ const clearScene = Ve.useCallback(() => {
1152
1152
  var _a;
1153
1153
  if (!window.confirm("Clear the entire scene? This cannot be undone."))
1154
1154
  return;
@@ -1186,7 +1186,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1186
1186
  /* ─────────────────────────────────────────
1187
1187
  Save to Library
1188
1188
  ───────────────────────────────────────── */
1189
- const saveToLibrary = Ae.useCallback(() => {
1189
+ const saveToLibrary = Ve.useCallback(() => {
1190
1190
  if (!onSaveToLibrary)
1191
1191
  return;
1192
1192
  const root = rootObjectRef.current;
@@ -1214,7 +1214,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1214
1214
  /* ─────────────────────────────────────────
1215
1215
  Add Mesh / Light / Camera / Empty
1216
1216
  ───────────────────────────────────────── */
1217
- const addPrimitive = Ae.useCallback((type) => {
1217
+ const addPrimitive = Ve.useCallback((type) => {
1218
1218
  let geo;
1219
1219
  switch (type) {
1220
1220
  case "cube":
@@ -1275,7 +1275,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1275
1275
  setStatusText(`Added ${mesh.name}`);
1276
1276
  setAddMenuOpen(null);
1277
1277
  }, [rebuildTree]);
1278
- const addSceneLight = Ae.useCallback((type) => {
1278
+ const addSceneLight = Ve.useCallback((type) => {
1279
1279
  let light;
1280
1280
  switch (type) {
1281
1281
  case "point": {
@@ -1328,7 +1328,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1328
1328
  setStatusText(`Added ${light.name}`);
1329
1329
  setAddMenuOpen(null);
1330
1330
  }, [rebuildTree]);
1331
- const addCameraObject = Ae.useCallback(() => {
1331
+ const addCameraObject = Ve.useCallback(() => {
1332
1332
  const cam = new THREE__namespace.PerspectiveCamera(50, 16 / 9, 0.1, 1000);
1333
1333
  cam.name = "Camera";
1334
1334
  cam.position.set(5, 3, 5);
@@ -1341,7 +1341,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1341
1341
  setStatusText("Added Camera");
1342
1342
  setAddMenuOpen(null);
1343
1343
  }, [rebuildTree]);
1344
- const addEmpty = Ae.useCallback((type) => {
1344
+ const addEmpty = Ve.useCallback((type) => {
1345
1345
  const obj = new THREE__namespace.Object3D();
1346
1346
  obj.name = type === "arrows" ? "Empty_Arrows" : type === "cube_empty" ? "Empty_Cube" : "Empty";
1347
1347
  sceneRef.current.add(obj);
@@ -1357,7 +1357,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1357
1357
  /* ─────────────────────────────────────────
1358
1358
  Raycaster click-to-select
1359
1359
  ───────────────────────────────────────── */
1360
- const handleViewportClick = Ae.useCallback((e) => {
1360
+ const handleViewportClick = Ve.useCallback((e) => {
1361
1361
  if (editorMode !== "object")
1362
1362
  return;
1363
1363
  if (!mountRef.current || !rendererRef.current || !cameraRef.current)
@@ -1393,12 +1393,12 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1393
1393
  /* ─────────────────────────────────────────
1394
1394
  Context menu
1395
1395
  ───────────────────────────────────────── */
1396
- const handleContextMenu = Ae.useCallback((e) => {
1396
+ const handleContextMenu = Ve.useCallback((e) => {
1397
1397
  e.preventDefault();
1398
1398
  setContextMenu({ x: e.clientX, y: e.clientY });
1399
1399
  }, []);
1400
- const closeContextMenu = Ae.useCallback(() => setContextMenu(null), []);
1401
- Ae.useEffect(() => {
1400
+ const closeContextMenu = Ve.useCallback(() => setContextMenu(null), []);
1401
+ Ve.useEffect(() => {
1402
1402
  if (!contextMenu)
1403
1403
  return;
1404
1404
  const close = () => setContextMenu(null);
@@ -1408,7 +1408,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1408
1408
  /* ─────────────────────────────────────────
1409
1409
  AI animation from video
1410
1410
  ───────────────────────────────────────── */
1411
- const handleAIVideo = Ae.useCallback(async (e) => {
1411
+ const handleAIVideo = Ve.useCallback(async (e) => {
1412
1412
  var _a;
1413
1413
  const file = (_a = e.target.files) === null || _a === void 0 ? void 0 : _a[0];
1414
1414
  if (!file)
@@ -1454,24 +1454,24 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1454
1454
  /* ─────────────────────────────────────────
1455
1455
  Node helpers
1456
1456
  ───────────────────────────────────────── */
1457
- const toggleNodeVisibility = Ae.useCallback((node) => {
1457
+ const toggleNodeVisibility = Ve.useCallback((node) => {
1458
1458
  node.object.visible = !node.object.visible;
1459
1459
  rebuildTree();
1460
1460
  }, [rebuildTree]);
1461
- const toggleNodeExpanded = Ae.useCallback((node) => {
1461
+ const toggleNodeExpanded = Ve.useCallback((node) => {
1462
1462
  node.expanded = !node.expanded;
1463
1463
  setSceneTree((prev) => [...prev]);
1464
1464
  }, []);
1465
1465
  /* ─────────────────────────────────────────
1466
1466
  Undo / Redo
1467
1467
  ───────────────────────────────────────── */
1468
- const undoRedoRef = Ae.useRef(new modelEditorUtils.UndoRedoStack());
1469
- const [undoRedoVer, setUndoRedoVer] = Ae.useState(0);
1470
- const pushUndo = Ae.useCallback((action) => {
1468
+ const undoRedoRef = Ve.useRef(new modelEditorUtils.UndoRedoStack());
1469
+ const [undoRedoVer, setUndoRedoVer] = Ve.useState(0);
1470
+ const pushUndo = Ve.useCallback((action) => {
1471
1471
  undoRedoRef.current.push(action);
1472
1472
  setUndoRedoVer((v) => v + 1);
1473
1473
  }, []);
1474
- const undo = Ae.useCallback(() => {
1474
+ const undo = Ve.useCallback(() => {
1475
1475
  const label = undoRedoRef.current.undo();
1476
1476
  if (label) {
1477
1477
  setStatusText(`Undo: ${label}`);
@@ -1479,7 +1479,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1479
1479
  }
1480
1480
  setUndoRedoVer((v) => v + 1);
1481
1481
  }, [rebuildTree]);
1482
- const redo = Ae.useCallback(() => {
1482
+ const redo = Ve.useCallback(() => {
1483
1483
  const label = undoRedoRef.current.redo();
1484
1484
  if (label) {
1485
1485
  setStatusText(`Redo: ${label}`);
@@ -1492,7 +1492,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1492
1492
  const undoLabel = undoRedoRef.current.undoLabel;
1493
1493
  const redoLabel = undoRedoRef.current.redoLabel;
1494
1494
  // Keyboard shortcuts for undo/redo
1495
- Ae.useEffect(() => {
1495
+ Ve.useEffect(() => {
1496
1496
  const handleKeyDown = (e) => {
1497
1497
  if ((e.ctrlKey || e.metaKey) && e.key === "z" && !e.shiftKey) {
1498
1498
  e.preventDefault();
@@ -1509,7 +1509,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1509
1509
  /* ─────────────────────────────────────────
1510
1510
  Batch Import
1511
1511
  ───────────────────────────────────────── */
1512
- const loadFiles = Ae.useCallback(async (files) => {
1512
+ const loadFiles = Ve.useCallback(async (files) => {
1513
1513
  const fileArray = Array.from(files).filter((f) => {
1514
1514
  const ext = f.name.substring(f.name.lastIndexOf(".")).toLowerCase();
1515
1515
  return modelEditorTypes.SUPPORTED_EXTENSIONS.includes(ext);
@@ -1535,7 +1535,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1535
1535
  /* ─────────────────────────────────────────
1536
1536
  PBR Presets
1537
1537
  ───────────────────────────────────────── */
1538
- const applyPreset = Ae.useCallback((preset) => {
1538
+ const applyPreset = Ve.useCallback((preset) => {
1539
1539
  const node = selectedNode;
1540
1540
  if (!node || !(node.object instanceof THREE__namespace.Mesh)) {
1541
1541
  setStatusText("Select a mesh to apply material preset");
@@ -1589,7 +1589,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1589
1589
  /* ─────────────────────────────────────────
1590
1590
  LOD Generation
1591
1591
  ───────────────────────────────────────── */
1592
- const generateSelectedLOD = Ae.useCallback(() => {
1592
+ const generateSelectedLOD = Ve.useCallback(() => {
1593
1593
  const node = selectedNode;
1594
1594
  if (!node || !(node.object instanceof THREE__namespace.Mesh)) {
1595
1595
  setStatusText("Select a mesh to generate LOD");
@@ -1611,7 +1611,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1611
1611
  /* ─────────────────────────────────────────
1612
1612
  Instancing
1613
1613
  ───────────────────────────────────────── */
1614
- const convertSelectedToInstanced = Ae.useCallback(() => {
1614
+ const convertSelectedToInstanced = Ve.useCallback(() => {
1615
1615
  const root = rootObjectRef.current || sceneRef.current;
1616
1616
  const result = modelEditorUtils.convertToInstanced(root);
1617
1617
  if (result.created === 0) {
@@ -1622,7 +1622,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1622
1622
  setStatusText(`Created ${result.created} instanced meshes, removed ${result.removed} duplicates`);
1623
1623
  }, [rebuildTree]);
1624
1624
  /* ── HDRI Environment ── */
1625
- const applyHDRI = Ae.useCallback((preset) => {
1625
+ const applyHDRI = Ve.useCallback((preset) => {
1626
1626
  const renderer = rendererRef.current;
1627
1627
  if (!renderer)
1628
1628
  return;
@@ -1640,7 +1640,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
1640
1640
  setStatusText(`Environment: ${preset.name}`);
1641
1641
  }, []);
1642
1642
  /* ── Snap ── */
1643
- const snapPoint = Ae.useCallback((point) => {
1643
+ const snapPoint = Ve.useCallback((point) => {
1644
1644
  const root = rootObjectRef.current || sceneRef.current;
1645
1645
  const modes = snapEnabled ? ["vertex", "edge", "grid"] : ["grid"];
1646
1646
  return modelEditorUtils.snapMulti(point, root, snapGrid, modes, 0.5);