@nice2dev/ui-3d 1.0.4 → 1.0.5
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.
- package/dist/cjs/core/i18n.js +3 -3
- package/dist/cjs/dance/DanceBridge.js +13 -13
- package/dist/cjs/dance/DanceScoreEngine.js +8 -8
- package/dist/cjs/dance/PoseDetector.js +20 -20
- package/dist/cjs/material/NiceMaterialEditor.js +19 -19
- package/dist/cjs/model/ModelEditorLeftPanel.js +3 -3
- package/dist/cjs/model/ModelEditorMenuBar.js +2 -2
- package/dist/cjs/model/ModelEditorRightPanel.js +2 -2
- package/dist/cjs/model/ModelEditorSubComponents.js +3 -3
- package/dist/cjs/model/ModelEditorTimeline.js +3 -3
- package/dist/cjs/model/ModelEditorToolbar.js +2 -2
- package/dist/cjs/model/ModelEditorViewport.js +2 -2
- package/dist/cjs/model/ModelViewer.js +8 -8
- package/dist/cjs/model/NiceArmatureEditor.js +18 -18
- package/dist/cjs/model/NiceMorphTargetEditor.js +18 -18
- package/dist/cjs/model/NiceOctree.js +16 -16
- package/dist/cjs/model/NicePhysicsSimulation.js +24 -24
- package/dist/cjs/model/NiceProceduralGeometry.js +8 -8
- package/dist/cjs/model/NiceTerrainEditor.js +19 -19
- package/dist/cjs/model/NiceWeightPainter.js +14 -14
- package/dist/cjs/model/NiceXRPreview.js +18 -18
- package/dist/cjs/model/useModelEditor.js +127 -127
- package/dist/cjs/model/useModelViewer.js +61 -61
- package/dist/cjs/particle/NiceParticleEditor.js +11 -11
- package/dist/cjs/rendering/NiceCascadedShadows.js +12 -12
- package/dist/cjs/rendering/NiceRenderExport.js +5 -5
- package/dist/cjs/rendering/NiceSSAO.js +18 -18
- package/dist/cjs/rendering/NiceSSR.js +14 -14
- package/dist/cjs/rendering/NiceWebGPURenderer.js +21 -21
- package/dist/cjs/ui/dist/index.js +32608 -24033
- package/dist/cjs/ui/dist/index.js.map +1 -1
- package/dist/cjs/uv/NiceUVEditor.js +24 -24
- package/dist/esm/model/ModelEditorLeftPanel.js +5 -5
- package/dist/esm/model/ModelEditorMenuBar.js +5 -5
- package/dist/esm/model/ModelEditorRightPanel.js +17 -17
- package/dist/esm/model/ModelEditorSubComponents.js +6 -6
- package/dist/esm/model/ModelEditorTimeline.js +5 -5
- package/dist/esm/model/ModelEditorToolbar.js +4 -4
- package/dist/esm/model/ModelEditorViewport.js +2 -2
- package/dist/esm/model/ModelViewer.js +5 -5
- package/dist/esm/ui/dist/index.js +31739 -23166
- package/dist/esm/ui/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var Ue = require('react');
|
|
4
4
|
var THREE = require('three');
|
|
5
5
|
var OrbitControls_js = require('three/examples/jsm/controls/OrbitControls.js');
|
|
6
6
|
var FBXLoader_js = require('three/examples/jsm/loaders/FBXLoader.js');
|
|
@@ -61,48 +61,48 @@ const TONE_MAP = {
|
|
|
61
61
|
function useModelViewer(props = {}) {
|
|
62
62
|
const { src, format, navigationMode: initNavMode = 'orbit', quality = 'high', autoRotateSpeed: initAutoRotate = 0, backgroundColor = '#1a1a2e', showGrid: initShowGrid = true, shadows = true, gamepad = false, cameraPresets = [], annotations = [], hotspots = [], floorPlans = [], onHotspotClick, onAnnotationClick, onLoadProgress, onLoad, onError, clippingPlanes = [], measureMode: initMeasureMode = false, measurements = [], onMeasure, minDistance = 0.1, maxDistance = 1000, fov = 50, vr = false, walkSpeed = 5, ambientIntensity = 0.5, directionalIntensity = 0.8, antiAlias = true, toneMapping = 'aces', exposure = 1, } = props;
|
|
63
63
|
/* ── refs ── */
|
|
64
|
-
const mountRef =
|
|
65
|
-
const rendererRef =
|
|
66
|
-
const sceneRef =
|
|
67
|
-
const cameraRef =
|
|
68
|
-
const orbitRef =
|
|
69
|
-
const clockRef =
|
|
70
|
-
const mixerRef =
|
|
71
|
-
const rafRef =
|
|
72
|
-
const rootRef =
|
|
73
|
-
const gridRef =
|
|
74
|
-
const clipsRef =
|
|
75
|
-
const keysRef =
|
|
76
|
-
|
|
77
|
-
const disposeRef =
|
|
64
|
+
const mountRef = Ue.useRef(null);
|
|
65
|
+
const rendererRef = Ue.useRef(null);
|
|
66
|
+
const sceneRef = Ue.useRef(new THREE__namespace.Scene());
|
|
67
|
+
const cameraRef = Ue.useRef(new THREE__namespace.PerspectiveCamera(fov, 1, 0.01, 10000));
|
|
68
|
+
const orbitRef = Ue.useRef(null);
|
|
69
|
+
const clockRef = Ue.useRef(new THREE__namespace.Clock());
|
|
70
|
+
const mixerRef = Ue.useRef(null);
|
|
71
|
+
const rafRef = Ue.useRef(0);
|
|
72
|
+
const rootRef = Ue.useRef(null);
|
|
73
|
+
const gridRef = Ue.useRef(null);
|
|
74
|
+
const clipsRef = Ue.useRef([]);
|
|
75
|
+
const keysRef = Ue.useRef(new Set());
|
|
76
|
+
Ue.useRef(null);
|
|
77
|
+
const disposeRef = Ue.useRef(false);
|
|
78
78
|
/* ── state ── */
|
|
79
|
-
const [loading, setLoading] =
|
|
80
|
-
const [loadProgress, setLoadProgress] =
|
|
81
|
-
const [error, setError] =
|
|
82
|
-
const [navMode, setNavMode] =
|
|
83
|
-
const [projection, setProjection] =
|
|
84
|
-
const [wireframe, setWireframe] =
|
|
85
|
-
const [gridVisible, setGridVisible] =
|
|
86
|
-
const [autoRotate, setAutoRotate] =
|
|
87
|
-
const [polyCount, setPolyCount] =
|
|
88
|
-
const [meshCount, setMeshCount] =
|
|
89
|
-
const [animNames, setAnimNames] =
|
|
90
|
-
const [activeAnimIdx, setActiveAnimIdx] =
|
|
91
|
-
const [isPlaying, setIsPlaying] =
|
|
92
|
-
const [animTime, setAnimTime] =
|
|
93
|
-
const [animDuration, setAnimDuration] =
|
|
94
|
-
const [animSpeed, setAnimSpeed] =
|
|
95
|
-
const [isFullscreen, setIsFullscreen] =
|
|
96
|
-
const [activeFloorPlanId, setActiveFloorPlanId] =
|
|
97
|
-
const [annotationsVisible, setAnnotationsVisible] =
|
|
98
|
-
const [clippingEnabled, setClippingEnabled] =
|
|
99
|
-
const [clippingPosition, setClippingPosition] =
|
|
100
|
-
const [clippingAxis, setClippingAxis] =
|
|
101
|
-
const [measureModeActive, setMeasureModeActive] =
|
|
102
|
-
const [dimensions, setDimensions] =
|
|
103
|
-
const [statusText, setStatusText] =
|
|
79
|
+
const [loading, setLoading] = Ue.useState(false);
|
|
80
|
+
const [loadProgress, setLoadProgress] = Ue.useState(0);
|
|
81
|
+
const [error, setError] = Ue.useState(null);
|
|
82
|
+
const [navMode, setNavMode] = Ue.useState(initNavMode);
|
|
83
|
+
const [projection, setProjection] = Ue.useState('perspective');
|
|
84
|
+
const [wireframe, setWireframe] = Ue.useState(false);
|
|
85
|
+
const [gridVisible, setGridVisible] = Ue.useState(initShowGrid);
|
|
86
|
+
const [autoRotate, setAutoRotate] = Ue.useState(initAutoRotate);
|
|
87
|
+
const [polyCount, setPolyCount] = Ue.useState(0);
|
|
88
|
+
const [meshCount, setMeshCount] = Ue.useState(0);
|
|
89
|
+
const [animNames, setAnimNames] = Ue.useState([]);
|
|
90
|
+
const [activeAnimIdx, setActiveAnimIdx] = Ue.useState(-1);
|
|
91
|
+
const [isPlaying, setIsPlaying] = Ue.useState(false);
|
|
92
|
+
const [animTime, setAnimTime] = Ue.useState(0);
|
|
93
|
+
const [animDuration, setAnimDuration] = Ue.useState(0);
|
|
94
|
+
const [animSpeed, setAnimSpeed] = Ue.useState(1);
|
|
95
|
+
const [isFullscreen, setIsFullscreen] = Ue.useState(false);
|
|
96
|
+
const [activeFloorPlanId, setActiveFloorPlanId] = Ue.useState(null);
|
|
97
|
+
const [annotationsVisible, setAnnotationsVisible] = Ue.useState(true);
|
|
98
|
+
const [clippingEnabled, setClippingEnabled] = Ue.useState(clippingPlanes.length > 0);
|
|
99
|
+
const [clippingPosition, setClippingPosition] = Ue.useState(0);
|
|
100
|
+
const [clippingAxis, setClippingAxis] = Ue.useState('y');
|
|
101
|
+
const [measureModeActive, setMeasureModeActive] = Ue.useState(initMeasureMode);
|
|
102
|
+
const [dimensions, setDimensions] = Ue.useState(null);
|
|
103
|
+
const [statusText, setStatusText] = Ue.useState('Ready');
|
|
104
104
|
/* ── scene setup ── */
|
|
105
|
-
|
|
105
|
+
Ue.useEffect(() => {
|
|
106
106
|
var _a;
|
|
107
107
|
const mount = mountRef.current;
|
|
108
108
|
if (!mount)
|
|
@@ -261,19 +261,19 @@ function useModelViewer(props = {}) {
|
|
|
261
261
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
262
262
|
}, []);
|
|
263
263
|
/* ── update grid visibility ── */
|
|
264
|
-
|
|
264
|
+
Ue.useEffect(() => {
|
|
265
265
|
if (gridRef.current)
|
|
266
266
|
gridRef.current.visible = gridVisible;
|
|
267
267
|
}, [gridVisible]);
|
|
268
268
|
/* ── update auto-rotate ── */
|
|
269
|
-
|
|
269
|
+
Ue.useEffect(() => {
|
|
270
270
|
if (orbitRef.current) {
|
|
271
271
|
orbitRef.current.autoRotate = autoRotate > 0;
|
|
272
272
|
orbitRef.current.autoRotateSpeed = autoRotate;
|
|
273
273
|
}
|
|
274
274
|
}, [autoRotate]);
|
|
275
275
|
/* ── wireframe toggle ── */
|
|
276
|
-
|
|
276
|
+
Ue.useEffect(() => {
|
|
277
277
|
if (!rootRef.current)
|
|
278
278
|
return;
|
|
279
279
|
rootRef.current.traverse((c) => {
|
|
@@ -288,7 +288,7 @@ function useModelViewer(props = {}) {
|
|
|
288
288
|
});
|
|
289
289
|
}, [wireframe]);
|
|
290
290
|
/* ── clipping ── */
|
|
291
|
-
|
|
291
|
+
Ue.useEffect(() => {
|
|
292
292
|
const renderer = rendererRef.current;
|
|
293
293
|
if (!renderer)
|
|
294
294
|
return;
|
|
@@ -302,7 +302,7 @@ function useModelViewer(props = {}) {
|
|
|
302
302
|
}
|
|
303
303
|
}, [clippingEnabled, clippingPosition, clippingAxis]);
|
|
304
304
|
/* ── counting helpers ── */
|
|
305
|
-
const countScene =
|
|
305
|
+
const countScene = Ue.useCallback(() => {
|
|
306
306
|
let tris = 0;
|
|
307
307
|
let meshes = 0;
|
|
308
308
|
sceneRef.current.traverse((c) => {
|
|
@@ -319,7 +319,7 @@ function useModelViewer(props = {}) {
|
|
|
319
319
|
setMeshCount(meshes);
|
|
320
320
|
}, []);
|
|
321
321
|
/* ── detect format from URL ── */
|
|
322
|
-
const detectFormat =
|
|
322
|
+
const detectFormat = Ue.useCallback((url, hint) => {
|
|
323
323
|
var _a, _b, _c;
|
|
324
324
|
if (hint)
|
|
325
325
|
return hint;
|
|
@@ -327,7 +327,7 @@ function useModelViewer(props = {}) {
|
|
|
327
327
|
return ext;
|
|
328
328
|
}, []);
|
|
329
329
|
/* ── load model ── */
|
|
330
|
-
const loadModel =
|
|
330
|
+
const loadModel = Ue.useCallback(async (url, fmt) => {
|
|
331
331
|
var _a, _b, _c;
|
|
332
332
|
setLoading(true);
|
|
333
333
|
setLoadProgress(0);
|
|
@@ -445,12 +445,12 @@ function useModelViewer(props = {}) {
|
|
|
445
445
|
}
|
|
446
446
|
}, [countScene, detectFormat, onLoad, onError, onLoadProgress, polyCount, meshCount]);
|
|
447
447
|
/* ── auto-load from src ── */
|
|
448
|
-
|
|
448
|
+
Ue.useEffect(() => {
|
|
449
449
|
if (src)
|
|
450
450
|
loadModel(src, format);
|
|
451
451
|
}, [src, format, loadModel]);
|
|
452
452
|
/* ── loadFile from disk ── */
|
|
453
|
-
const loadFile =
|
|
453
|
+
const loadFile = Ue.useCallback(async (file) => {
|
|
454
454
|
var _a;
|
|
455
455
|
const url = URL.createObjectURL(file);
|
|
456
456
|
const ext = (_a = file.name.split('.').pop()) === null || _a === void 0 ? void 0 : _a.toLowerCase();
|
|
@@ -462,11 +462,11 @@ function useModelViewer(props = {}) {
|
|
|
462
462
|
}
|
|
463
463
|
}, [loadModel]);
|
|
464
464
|
/* ── loadUrl ── */
|
|
465
|
-
const loadUrl =
|
|
465
|
+
const loadUrl = Ue.useCallback(async (url, fmt) => {
|
|
466
466
|
await loadModel(url, fmt);
|
|
467
467
|
}, [loadModel]);
|
|
468
468
|
/* ── animation controls ── */
|
|
469
|
-
const playAnimation =
|
|
469
|
+
const playAnimation = Ue.useCallback((index) => {
|
|
470
470
|
if (!mixerRef.current || index < 0 || index >= clipsRef.current.length)
|
|
471
471
|
return;
|
|
472
472
|
mixerRef.current.stopAllAction();
|
|
@@ -477,7 +477,7 @@ function useModelViewer(props = {}) {
|
|
|
477
477
|
setIsPlaying(true);
|
|
478
478
|
setAnimDuration(clip.duration);
|
|
479
479
|
}, []);
|
|
480
|
-
const togglePlay =
|
|
480
|
+
const togglePlay = Ue.useCallback(() => {
|
|
481
481
|
if (!mixerRef.current)
|
|
482
482
|
return;
|
|
483
483
|
if (isPlaying) {
|
|
@@ -491,13 +491,13 @@ function useModelViewer(props = {}) {
|
|
|
491
491
|
playAnimation(0);
|
|
492
492
|
}
|
|
493
493
|
}, [isPlaying, animSpeed, activeAnimIdx, playAnimation]);
|
|
494
|
-
const seekAnim =
|
|
494
|
+
const seekAnim = Ue.useCallback((t) => {
|
|
495
495
|
if (mixerRef.current)
|
|
496
496
|
mixerRef.current.setTime(t);
|
|
497
497
|
setAnimTime(t);
|
|
498
498
|
}, []);
|
|
499
499
|
/* ── camera presets ── */
|
|
500
|
-
const goToPreset =
|
|
500
|
+
const goToPreset = Ue.useCallback((preset) => {
|
|
501
501
|
const cam = cameraRef.current;
|
|
502
502
|
const orbit = orbitRef.current;
|
|
503
503
|
if (!orbit)
|
|
@@ -509,7 +509,7 @@ function useModelViewer(props = {}) {
|
|
|
509
509
|
cam.updateProjectionMatrix();
|
|
510
510
|
orbit.update();
|
|
511
511
|
}, []);
|
|
512
|
-
const resetCamera =
|
|
512
|
+
const resetCamera = Ue.useCallback(() => {
|
|
513
513
|
const cam = cameraRef.current;
|
|
514
514
|
cam.position.set(5, 4, 8);
|
|
515
515
|
if (orbitRef.current) {
|
|
@@ -517,7 +517,7 @@ function useModelViewer(props = {}) {
|
|
|
517
517
|
orbitRef.current.update();
|
|
518
518
|
}
|
|
519
519
|
}, []);
|
|
520
|
-
const zoomToFit =
|
|
520
|
+
const zoomToFit = Ue.useCallback(() => {
|
|
521
521
|
if (!rootRef.current)
|
|
522
522
|
return;
|
|
523
523
|
const box = new THREE__namespace.Box3().setFromObject(rootRef.current);
|
|
@@ -533,7 +533,7 @@ function useModelViewer(props = {}) {
|
|
|
533
533
|
}
|
|
534
534
|
}, []);
|
|
535
535
|
/* ── screenshot ── */
|
|
536
|
-
const screenshot =
|
|
536
|
+
const screenshot = Ue.useCallback((width, height) => {
|
|
537
537
|
const renderer = rendererRef.current;
|
|
538
538
|
if (!renderer)
|
|
539
539
|
return '';
|
|
@@ -554,7 +554,7 @@ function useModelViewer(props = {}) {
|
|
|
554
554
|
return url;
|
|
555
555
|
}, []);
|
|
556
556
|
/* ── fullscreen ── */
|
|
557
|
-
const toggleFullscreen =
|
|
557
|
+
const toggleFullscreen = Ue.useCallback(() => {
|
|
558
558
|
if (!mountRef.current)
|
|
559
559
|
return;
|
|
560
560
|
if (document.fullscreenElement) {
|
|
@@ -565,14 +565,14 @@ function useModelViewer(props = {}) {
|
|
|
565
565
|
}
|
|
566
566
|
}, []);
|
|
567
567
|
/* ── dispose ── */
|
|
568
|
-
const dispose =
|
|
568
|
+
const dispose = Ue.useCallback(() => {
|
|
569
569
|
var _a;
|
|
570
570
|
disposeRef.current = true;
|
|
571
571
|
cancelAnimationFrame(rafRef.current);
|
|
572
572
|
(_a = rendererRef.current) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
573
573
|
}, []);
|
|
574
574
|
/* ── finalise status text ── */
|
|
575
|
-
|
|
575
|
+
Ue.useEffect(() => {
|
|
576
576
|
if (!loading && !error && polyCount > 0) {
|
|
577
577
|
setStatusText(`${polyCount.toLocaleString()} triangles · ${meshCount} meshes · ${animNames.length} animation(s)`);
|
|
578
578
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
-
var
|
|
4
|
+
var Ue = require('react');
|
|
5
5
|
var particleEditorTypes = require('./particleEditorTypes.js');
|
|
6
6
|
var particleEditorUtils = require('./particleEditorUtils.js');
|
|
7
7
|
var ParticleEditor_module = require('./ParticleEditor.module.css.js');
|
|
@@ -268,13 +268,13 @@ function particleEditorReducer(state, action) {
|
|
|
268
268
|
Hook: useParticleEditor
|
|
269
269
|
═══════════════════════════════════════════════════════════════════════════ */
|
|
270
270
|
function useParticleEditor(initialSystems) {
|
|
271
|
-
const [state, dispatch] =
|
|
271
|
+
const [state, dispatch] = Ue.useReducer(particleEditorReducer, initialSystems, createInitialState);
|
|
272
272
|
return { state, dispatch };
|
|
273
273
|
}
|
|
274
274
|
function SystemListPanel({ systems, selectedId, onSelect, onAdd, onRemove, onDuplicate, onRename, onAddPreset, }) {
|
|
275
|
-
const [editingId, setEditingId] =
|
|
276
|
-
const [editName, setEditName] =
|
|
277
|
-
const [showPresets, setShowPresets] =
|
|
275
|
+
const [editingId, setEditingId] = Ue.useState(null);
|
|
276
|
+
const [editName, setEditName] = Ue.useState('');
|
|
277
|
+
const [showPresets, setShowPresets] = Ue.useState(false);
|
|
278
278
|
const handleStartRename = (system) => {
|
|
279
279
|
setEditingId(system.id);
|
|
280
280
|
setEditName(system.name);
|
|
@@ -379,9 +379,9 @@ function Toolbar({ isPlaying, isPaused, playbackSpeed, currentTime, canUndo, can
|
|
|
379
379
|
return (jsxRuntime.jsxs("div", { className: ParticleEditor_module.toolbar, children: [jsxRuntime.jsxs("div", { className: ParticleEditor_module.toolbarGroup, children: [jsxRuntime.jsx("button", { onClick: onNew, title: "New Project", children: "\uD83D\uDCC4" }), jsxRuntime.jsx("button", { onClick: onImport, title: "Import", children: "\uD83D\uDCC2" }), jsxRuntime.jsx("button", { onClick: onExport, title: "Export", children: "\uD83D\uDCBE" })] }), jsxRuntime.jsx("div", { className: ParticleEditor_module.toolbarSeparator }), jsxRuntime.jsxs("div", { className: ParticleEditor_module.toolbarGroup, children: [jsxRuntime.jsx("button", { onClick: onUndo, disabled: !canUndo, title: "Undo", children: "\u21A9\uFE0F" }), jsxRuntime.jsx("button", { onClick: onRedo, disabled: !canRedo, title: "Redo", children: "\u21AA\uFE0F" })] }), jsxRuntime.jsx("div", { className: ParticleEditor_module.toolbarSeparator }), jsxRuntime.jsxs("div", { className: ParticleEditor_module.toolbarGroup, children: [isPlaying && !isPaused ? (jsxRuntime.jsx("button", { onClick: onPause, title: "Pause", children: "\u23F8\uFE0F" })) : (jsxRuntime.jsx("button", { onClick: onPlay, title: "Play", children: "\u25B6\uFE0F" })), jsxRuntime.jsx("button", { onClick: onStop, title: "Stop", children: "\u23F9\uFE0F" }), jsxRuntime.jsx("button", { onClick: onRestart, title: "Restart", children: "\uD83D\uDD04" }), jsxRuntime.jsxs("select", { value: playbackSpeed, onChange: e => onSpeedChange(parseFloat(e.target.value)), className: ParticleEditor_module.speedSelect, title: "Playback Speed", children: [jsxRuntime.jsx("option", { value: 0.25, children: "0.25x" }), jsxRuntime.jsx("option", { value: 0.5, children: "0.5x" }), jsxRuntime.jsx("option", { value: 1, children: "1x" }), jsxRuntime.jsx("option", { value: 2, children: "2x" }), jsxRuntime.jsx("option", { value: 4, children: "4x" })] }), jsxRuntime.jsxs("span", { className: ParticleEditor_module.timeDisplay, children: [currentTime.toFixed(2), "s"] })] }), jsxRuntime.jsx("div", { className: ParticleEditor_module.toolbarSeparator }), jsxRuntime.jsxs("div", { className: ParticleEditor_module.toolbarGroup, children: [jsxRuntime.jsx("button", { onClick: onToggleGrid, className: showGrid ? ParticleEditor_module.active : '', title: "Toggle Grid", children: "#" }), jsxRuntime.jsx("button", { onClick: onToggleBounds, className: showBounds ? ParticleEditor_module.active : '', title: "Toggle Bounds", children: "\u2B1C" }), jsxRuntime.jsx("button", { onClick: onToggleEmitterShape, className: showEmitterShape ? ParticleEditor_module.active : '', title: "Toggle Emitter Shape", children: "\uD83D\uDD36" })] }), jsxRuntime.jsx("div", { className: ParticleEditor_module.toolbarSeparator }), jsxRuntime.jsx("div", { className: ParticleEditor_module.toolbarGroup, children: ['3d', 'top', 'side', 'front'].map(mode => (jsxRuntime.jsx("button", { onClick: () => onViewModeChange(mode), className: viewMode === mode ? ParticleEditor_module.active : '', title: mode.toUpperCase(), children: mode === '3d' ? '🎥' : mode.charAt(0).toUpperCase() }, mode))) })] }));
|
|
380
380
|
}
|
|
381
381
|
function PreviewPanel({ systems, isPlaying, isPaused, currentTime, showGrid, showEmitterShape, }) {
|
|
382
|
-
const canvasRef =
|
|
382
|
+
const canvasRef = Ue.useRef(null);
|
|
383
383
|
// Simple preview rendering (placeholder - real implementation would use Three.js)
|
|
384
|
-
|
|
384
|
+
Ue.useEffect(() => {
|
|
385
385
|
const canvas = canvasRef.current;
|
|
386
386
|
if (!canvas)
|
|
387
387
|
return;
|
|
@@ -448,14 +448,14 @@ function PreviewPanel({ systems, isPlaying, isPaused, currentTime, showGrid, sho
|
|
|
448
448
|
═══════════════════════════════════════════════════════════════════════════ */
|
|
449
449
|
function NiceParticleEditor({ systems: initialSystems, onSystemsChange, onPlay, onPause, onStop, customTextures, customMeshes, width = '100%', height = '600px', readOnly = false, showToolbar = true, showSystemList = true, showInspector = true, showPreview = true, showTimeline = true, theme = 'dark', className, }) {
|
|
450
450
|
const { state, dispatch } = useParticleEditor(initialSystems);
|
|
451
|
-
const animationFrameRef =
|
|
452
|
-
const selectedSystem =
|
|
451
|
+
const animationFrameRef = Ue.useRef();
|
|
452
|
+
const selectedSystem = Ue.useMemo(() => state.systems.find(s => s.id === state.selectedSystemId) || null, [state.systems, state.selectedSystemId]);
|
|
453
453
|
// Notify parent of changes
|
|
454
|
-
|
|
454
|
+
Ue.useEffect(() => {
|
|
455
455
|
onSystemsChange === null || onSystemsChange === void 0 ? void 0 : onSystemsChange(state.systems);
|
|
456
456
|
}, [state.systems, onSystemsChange]);
|
|
457
457
|
// Animation loop
|
|
458
|
-
|
|
458
|
+
Ue.useEffect(() => {
|
|
459
459
|
if (!state.isPlaying || state.isPaused)
|
|
460
460
|
return;
|
|
461
461
|
let lastTime = performance.now();
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
4
|
var THREE = require('three');
|
|
5
|
-
var
|
|
5
|
+
var Ue = require('react');
|
|
6
6
|
|
|
7
7
|
function _interopNamespaceDefault(e) {
|
|
8
8
|
var n = Object.create(null);
|
|
@@ -85,16 +85,16 @@ const DEFAULT_CSM = {
|
|
|
85
85
|
cascadeOverrides: [],
|
|
86
86
|
};
|
|
87
87
|
function useCSM(scene, camera, configOverride) {
|
|
88
|
-
const [config, setConfigState] =
|
|
89
|
-
const [showDebug, setShowDebug] =
|
|
90
|
-
const [cascadeSplits, setCascadeSplits] =
|
|
91
|
-
const lightsRef =
|
|
92
|
-
const debugGroup =
|
|
93
|
-
const setConfig =
|
|
88
|
+
const [config, setConfigState] = Ue.useState({ ...DEFAULT_CSM, ...configOverride });
|
|
89
|
+
const [showDebug, setShowDebug] = Ue.useState(false);
|
|
90
|
+
const [cascadeSplits, setCascadeSplits] = Ue.useState([]);
|
|
91
|
+
const lightsRef = Ue.useRef([]);
|
|
92
|
+
const debugGroup = Ue.useRef(new THREE__namespace.Group());
|
|
93
|
+
const setConfig = Ue.useCallback((partial) => {
|
|
94
94
|
setConfigState((prev) => ({ ...prev, ...partial }));
|
|
95
95
|
}, []);
|
|
96
96
|
// Create/update cascade lights
|
|
97
|
-
|
|
97
|
+
Ue.useEffect(() => {
|
|
98
98
|
var _a, _b, _c, _d, _e;
|
|
99
99
|
if (!scene || !camera)
|
|
100
100
|
return;
|
|
@@ -161,7 +161,7 @@ function useCSM(scene, camera, configOverride) {
|
|
|
161
161
|
};
|
|
162
162
|
}, [scene, camera, config]);
|
|
163
163
|
// Debug visualization
|
|
164
|
-
|
|
164
|
+
Ue.useEffect(() => {
|
|
165
165
|
if (!scene)
|
|
166
166
|
return;
|
|
167
167
|
debugGroup.current.name = '__csm_debug__';
|
|
@@ -196,7 +196,7 @@ function useCSM(scene, camera, configOverride) {
|
|
|
196
196
|
}
|
|
197
197
|
return () => scene.remove(debugGroup.current);
|
|
198
198
|
}, [scene, camera, showDebug, cascadeSplits]);
|
|
199
|
-
const update =
|
|
199
|
+
const update = Ue.useCallback(() => {
|
|
200
200
|
var _a;
|
|
201
201
|
if (!camera || !scene)
|
|
202
202
|
return;
|
|
@@ -228,7 +228,7 @@ function useCSM(scene, camera, configOverride) {
|
|
|
228
228
|
prevSplit = cascadeFar;
|
|
229
229
|
}
|
|
230
230
|
}, [camera, scene, config]);
|
|
231
|
-
const dispose =
|
|
231
|
+
const dispose = Ue.useCallback(() => {
|
|
232
232
|
var _a;
|
|
233
233
|
if (!scene)
|
|
234
234
|
return;
|
|
@@ -254,7 +254,7 @@ function useCSM(scene, camera, configOverride) {
|
|
|
254
254
|
/* ── Component ── */
|
|
255
255
|
const NiceCascadedShadows = ({ scene, camera, config: configProp, showDebug: initialDebug, className = '', }) => {
|
|
256
256
|
const { config, setConfig, cascadeSplits, showDebug, setShowDebug } = useCSM(scene, camera, configProp);
|
|
257
|
-
|
|
257
|
+
Ue.useEffect(() => {
|
|
258
258
|
if (initialDebug !== undefined)
|
|
259
259
|
setShowDebug(initialDebug);
|
|
260
260
|
}, [initialDebug, setShowDebug]);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
4
|
var THREE = require('three');
|
|
5
|
-
var
|
|
5
|
+
var Ue = require('react');
|
|
6
6
|
|
|
7
7
|
function _interopNamespaceDefault(e) {
|
|
8
8
|
var n = Object.create(null);
|
|
@@ -205,12 +205,12 @@ const DEFAULT_CONFIG = {
|
|
|
205
205
|
includeAlpha: true,
|
|
206
206
|
};
|
|
207
207
|
function useRenderExport(renderer, scene, camera) {
|
|
208
|
-
const [config, setConfigState] =
|
|
209
|
-
const [isRendering, setIsRendering] =
|
|
210
|
-
const setConfig =
|
|
208
|
+
const [config, setConfigState] = Ue.useState(DEFAULT_CONFIG);
|
|
209
|
+
const [isRendering, setIsRendering] = Ue.useState(false);
|
|
210
|
+
const setConfig = Ue.useCallback((partial) => {
|
|
211
211
|
setConfigState((prev) => ({ ...prev, ...partial }));
|
|
212
212
|
}, []);
|
|
213
|
-
const render =
|
|
213
|
+
const render = Ue.useCallback(async () => {
|
|
214
214
|
if (!renderer || !scene || !camera)
|
|
215
215
|
return null;
|
|
216
216
|
setIsRendering(true);
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
4
|
var THREE = require('three');
|
|
5
|
-
var
|
|
5
|
+
var Ue = require('react');
|
|
6
6
|
|
|
7
7
|
function _interopNamespaceDefault(e) {
|
|
8
8
|
var n = Object.create(null);
|
|
@@ -203,22 +203,22 @@ const DEFAULT_SSAO = {
|
|
|
203
203
|
maxDistance: 10,
|
|
204
204
|
};
|
|
205
205
|
function useSSAO(renderer, scene, camera, configOverride) {
|
|
206
|
-
const [config, setConfigState] =
|
|
207
|
-
const [aoRenderTarget, setAoRenderTarget] =
|
|
208
|
-
const depthRT =
|
|
209
|
-
const blurRT =
|
|
210
|
-
const ssaoMaterial =
|
|
211
|
-
const blurMaterial =
|
|
212
|
-
const noiseTexture =
|
|
213
|
-
const kernel =
|
|
214
|
-
const orthoScene =
|
|
215
|
-
const orthoCamera =
|
|
216
|
-
const quadRef =
|
|
217
|
-
const setConfig =
|
|
206
|
+
const [config, setConfigState] = Ue.useState({ ...DEFAULT_SSAO, ...configOverride });
|
|
207
|
+
const [aoRenderTarget, setAoRenderTarget] = Ue.useState(null);
|
|
208
|
+
const depthRT = Ue.useRef(null);
|
|
209
|
+
const blurRT = Ue.useRef(null);
|
|
210
|
+
const ssaoMaterial = Ue.useRef(null);
|
|
211
|
+
const blurMaterial = Ue.useRef(null);
|
|
212
|
+
const noiseTexture = Ue.useRef(generateNoiseTexture());
|
|
213
|
+
const kernel = Ue.useRef(generateSSAOKernel(128));
|
|
214
|
+
const orthoScene = Ue.useRef(new THREE__namespace.Scene());
|
|
215
|
+
const orthoCamera = Ue.useRef(new THREE__namespace.OrthographicCamera(-1, 1, 1, -1, 0, 1));
|
|
216
|
+
const quadRef = Ue.useRef(null);
|
|
217
|
+
const setConfig = Ue.useCallback((partial) => {
|
|
218
218
|
setConfigState((prev) => ({ ...prev, ...partial }));
|
|
219
219
|
}, []);
|
|
220
220
|
// Setup
|
|
221
|
-
|
|
221
|
+
Ue.useEffect(() => {
|
|
222
222
|
if (!renderer || !camera)
|
|
223
223
|
return;
|
|
224
224
|
const width = Math.floor(renderer.domElement.width * config.resolution);
|
|
@@ -300,7 +300,7 @@ function useSSAO(renderer, scene, camera, configOverride) {
|
|
|
300
300
|
};
|
|
301
301
|
}, [renderer, camera, config.resolution]);
|
|
302
302
|
// Update uniforms
|
|
303
|
-
|
|
303
|
+
Ue.useEffect(() => {
|
|
304
304
|
if (!ssaoMaterial.current)
|
|
305
305
|
return;
|
|
306
306
|
const u = ssaoMaterial.current.uniforms;
|
|
@@ -311,12 +311,12 @@ function useSSAO(renderer, scene, camera, configOverride) {
|
|
|
311
311
|
u.minDistance.value = config.minDistance;
|
|
312
312
|
u.maxDistance.value = config.maxDistance;
|
|
313
313
|
}, [config]);
|
|
314
|
-
|
|
314
|
+
Ue.useEffect(() => {
|
|
315
315
|
if (!blurMaterial.current)
|
|
316
316
|
return;
|
|
317
317
|
blurMaterial.current.uniforms.blurSize.value = config.blurSize;
|
|
318
318
|
}, [config.blurSize]);
|
|
319
|
-
const update =
|
|
319
|
+
const update = Ue.useCallback(() => {
|
|
320
320
|
if (!renderer || !scene || !camera || !config.enabled)
|
|
321
321
|
return;
|
|
322
322
|
if (!depthRT.current || !aoRenderTarget || !quadRef.current)
|
|
@@ -337,7 +337,7 @@ function useSSAO(renderer, scene, camera, configOverride) {
|
|
|
337
337
|
}
|
|
338
338
|
renderer.setRenderTarget(null);
|
|
339
339
|
}, [renderer, scene, camera, config.enabled, config.blurEnabled, aoRenderTarget]);
|
|
340
|
-
const dispose =
|
|
340
|
+
const dispose = Ue.useCallback(() => {
|
|
341
341
|
var _a, _b, _c, _d, _e;
|
|
342
342
|
(_a = depthRT.current) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
343
343
|
aoRenderTarget === null || aoRenderTarget === void 0 ? void 0 : aoRenderTarget.dispose();
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
4
|
var THREE = require('three');
|
|
5
|
-
var
|
|
5
|
+
var Ue = require('react');
|
|
6
6
|
|
|
7
7
|
function _interopNamespaceDefault(e) {
|
|
8
8
|
var n = Object.create(null);
|
|
@@ -147,19 +147,19 @@ const DEFAULT_SSR = {
|
|
|
147
147
|
fresnelExponent: 3.0,
|
|
148
148
|
};
|
|
149
149
|
function useSSR(renderer, scene, camera, configOverride) {
|
|
150
|
-
const [config, setConfigState] =
|
|
151
|
-
const [renderTarget, setRenderTarget] =
|
|
152
|
-
const depthTarget =
|
|
153
|
-
const normalTarget =
|
|
154
|
-
const ssrMaterial =
|
|
155
|
-
const fullScreenQuad =
|
|
156
|
-
const orthoScene =
|
|
157
|
-
const orthoCamera =
|
|
158
|
-
const setConfig =
|
|
150
|
+
const [config, setConfigState] = Ue.useState({ ...DEFAULT_SSR, ...configOverride });
|
|
151
|
+
const [renderTarget, setRenderTarget] = Ue.useState(null);
|
|
152
|
+
const depthTarget = Ue.useRef(null);
|
|
153
|
+
const normalTarget = Ue.useRef(null);
|
|
154
|
+
const ssrMaterial = Ue.useRef(null);
|
|
155
|
+
const fullScreenQuad = Ue.useRef(null);
|
|
156
|
+
const orthoScene = Ue.useRef(new THREE__namespace.Scene());
|
|
157
|
+
const orthoCamera = Ue.useRef(new THREE__namespace.OrthographicCamera(-1, 1, 1, -1, 0, 1));
|
|
158
|
+
const setConfig = Ue.useCallback((partial) => {
|
|
159
159
|
setConfigState((prev) => ({ ...prev, ...partial }));
|
|
160
160
|
}, []);
|
|
161
161
|
// Setup render targets and shader
|
|
162
|
-
|
|
162
|
+
Ue.useEffect(() => {
|
|
163
163
|
if (!renderer || !camera)
|
|
164
164
|
return;
|
|
165
165
|
const width = Math.floor(renderer.domElement.width * config.resolution);
|
|
@@ -226,7 +226,7 @@ function useSSR(renderer, scene, camera, configOverride) {
|
|
|
226
226
|
};
|
|
227
227
|
}, [renderer, camera, config.resolution]);
|
|
228
228
|
// Update uniforms when config changes
|
|
229
|
-
|
|
229
|
+
Ue.useEffect(() => {
|
|
230
230
|
if (!ssrMaterial.current)
|
|
231
231
|
return;
|
|
232
232
|
const u = ssrMaterial.current.uniforms;
|
|
@@ -237,7 +237,7 @@ function useSSR(renderer, scene, camera, configOverride) {
|
|
|
237
237
|
u.intensity.value = config.intensity;
|
|
238
238
|
u.fresnelExponent.value = config.fresnelExponent;
|
|
239
239
|
}, [config]);
|
|
240
|
-
const update =
|
|
240
|
+
const update = Ue.useCallback(() => {
|
|
241
241
|
if (!renderer || !scene || !camera || !config.enabled)
|
|
242
242
|
return;
|
|
243
243
|
if (!renderTarget || !depthTarget.current)
|
|
@@ -257,7 +257,7 @@ function useSSR(renderer, scene, camera, configOverride) {
|
|
|
257
257
|
renderer.setRenderTarget(null);
|
|
258
258
|
renderer.render(orthoScene.current, orthoCamera.current);
|
|
259
259
|
}, [renderer, scene, camera, config.enabled, renderTarget]);
|
|
260
|
-
const dispose =
|
|
260
|
+
const dispose = Ue.useCallback(() => {
|
|
261
261
|
var _a, _b, _c;
|
|
262
262
|
renderTarget === null || renderTarget === void 0 ? void 0 : renderTarget.dispose();
|
|
263
263
|
(_a = depthTarget.current) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
4
|
var THREE = require('three');
|
|
5
|
-
var
|
|
5
|
+
var Ue = require('react');
|
|
6
6
|
|
|
7
7
|
function _interopNamespaceDefault(e) {
|
|
8
8
|
var n = Object.create(null);
|
|
@@ -54,17 +54,17 @@ async function detectWebGPU() {
|
|
|
54
54
|
}
|
|
55
55
|
/* ── Hook ── */
|
|
56
56
|
function useWebGPURenderer(canvas, scene, camera, width = 800, height = 600, onRendererReady) {
|
|
57
|
-
const [renderer, setRenderer] =
|
|
58
|
-
const [isWebGPU, setIsWebGPU] =
|
|
59
|
-
const [capabilities, setCapabilities] =
|
|
60
|
-
const [isReady, setIsReady] =
|
|
61
|
-
const [toneMapping, setToneMappingState] =
|
|
62
|
-
const [toneMappingExposure, setToneMappingExposureState] =
|
|
63
|
-
const [outputColorSpace, setOutputColorSpaceState] =
|
|
64
|
-
const [pixelRatio, setPixelRatioState] =
|
|
65
|
-
const rendererRef =
|
|
57
|
+
const [renderer, setRenderer] = Ue.useState(null);
|
|
58
|
+
const [isWebGPU, setIsWebGPU] = Ue.useState(false);
|
|
59
|
+
const [capabilities, setCapabilities] = Ue.useState(null);
|
|
60
|
+
const [isReady, setIsReady] = Ue.useState(false);
|
|
61
|
+
const [toneMapping, setToneMappingState] = Ue.useState(THREE__namespace.ACESFilmicToneMapping);
|
|
62
|
+
const [toneMappingExposure, setToneMappingExposureState] = Ue.useState(1.0);
|
|
63
|
+
const [outputColorSpace, setOutputColorSpaceState] = Ue.useState(THREE__namespace.SRGBColorSpace);
|
|
64
|
+
const [pixelRatio, setPixelRatioState] = Ue.useState(typeof window !== 'undefined' ? window.devicePixelRatio : 1);
|
|
65
|
+
const rendererRef = Ue.useRef(null);
|
|
66
66
|
// Initialize renderer
|
|
67
|
-
|
|
67
|
+
Ue.useEffect(() => {
|
|
68
68
|
if (!canvas)
|
|
69
69
|
return;
|
|
70
70
|
let disposed = false;
|
|
@@ -131,44 +131,44 @@ function useWebGPURenderer(canvas, scene, camera, width = 800, height = 600, onR
|
|
|
131
131
|
};
|
|
132
132
|
}, [canvas]);
|
|
133
133
|
// Update renderer settings reactively
|
|
134
|
-
|
|
134
|
+
Ue.useEffect(() => {
|
|
135
135
|
if (!rendererRef.current)
|
|
136
136
|
return;
|
|
137
137
|
rendererRef.current.toneMapping = toneMapping;
|
|
138
138
|
}, [toneMapping]);
|
|
139
|
-
|
|
139
|
+
Ue.useEffect(() => {
|
|
140
140
|
if (!rendererRef.current)
|
|
141
141
|
return;
|
|
142
142
|
rendererRef.current.toneMappingExposure = toneMappingExposure;
|
|
143
143
|
}, [toneMappingExposure]);
|
|
144
|
-
|
|
144
|
+
Ue.useEffect(() => {
|
|
145
145
|
if (!rendererRef.current)
|
|
146
146
|
return;
|
|
147
147
|
rendererRef.current.outputColorSpace = outputColorSpace;
|
|
148
148
|
}, [outputColorSpace]);
|
|
149
|
-
|
|
149
|
+
Ue.useEffect(() => {
|
|
150
150
|
if (!rendererRef.current)
|
|
151
151
|
return;
|
|
152
152
|
rendererRef.current.setPixelRatio(pixelRatio);
|
|
153
153
|
}, [pixelRatio]);
|
|
154
|
-
|
|
154
|
+
Ue.useEffect(() => {
|
|
155
155
|
if (!rendererRef.current)
|
|
156
156
|
return;
|
|
157
157
|
rendererRef.current.setSize(width, height);
|
|
158
158
|
}, [width, height]);
|
|
159
|
-
const setToneMapping =
|
|
159
|
+
const setToneMapping = Ue.useCallback((m) => {
|
|
160
160
|
setToneMappingState(m);
|
|
161
161
|
}, []);
|
|
162
|
-
const setToneMappingExposure =
|
|
162
|
+
const setToneMappingExposure = Ue.useCallback((e) => {
|
|
163
163
|
setToneMappingExposureState(e);
|
|
164
164
|
}, []);
|
|
165
|
-
const setOutputColorSpace =
|
|
165
|
+
const setOutputColorSpace = Ue.useCallback((s) => {
|
|
166
166
|
setOutputColorSpaceState(s);
|
|
167
167
|
}, []);
|
|
168
|
-
const setPixelRatio =
|
|
168
|
+
const setPixelRatio = Ue.useCallback((r) => {
|
|
169
169
|
setPixelRatioState(r);
|
|
170
170
|
}, []);
|
|
171
|
-
const dispose =
|
|
171
|
+
const dispose = Ue.useCallback(() => {
|
|
172
172
|
var _a;
|
|
173
173
|
(_a = rendererRef.current) === null || _a === void 0 ? void 0 : _a.dispose();
|
|
174
174
|
rendererRef.current = null;
|