@nice2dev/ui-3d 1.1.0 → 1.1.1
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/collaborative/collaborativeScene.js +16 -8
- package/dist/cjs/collaborative/collaborativeScene.js.map +1 -1
- package/dist/cjs/core/i18n.js +3 -3
- package/dist/cjs/dance/DanceBridge.js +65 -30
- package/dist/cjs/dance/DanceBridge.js.map +1 -1
- package/dist/cjs/dance/DanceScoreEngine.js +37 -23
- package/dist/cjs/dance/DanceScoreEngine.js.map +1 -1
- package/dist/cjs/dance/PoseDetector.js +92 -49
- package/dist/cjs/dance/PoseDetector.js.map +1 -1
- package/dist/cjs/material/NiceMaterialEditor.js +134 -91
- package/dist/cjs/material/NiceMaterialEditor.js.map +1 -1
- package/dist/cjs/material/materialEditorUtils.js +86 -55
- package/dist/cjs/material/materialEditorUtils.js.map +1 -1
- package/dist/cjs/model/ModelEditor.js +16 -14
- package/dist/cjs/model/ModelEditor.js.map +1 -1
- package/dist/cjs/model/ModelEditorLeftPanel.js +21 -15
- package/dist/cjs/model/ModelEditorLeftPanel.js.map +1 -1
- package/dist/cjs/model/ModelEditorMenuBar.js +23 -10
- package/dist/cjs/model/ModelEditorMenuBar.js.map +1 -1
- package/dist/cjs/model/ModelEditorRightPanel.js +32 -27
- package/dist/cjs/model/ModelEditorRightPanel.js.map +1 -1
- package/dist/cjs/model/ModelEditorSubComponents.js +20 -20
- package/dist/cjs/model/ModelEditorSubComponents.js.map +1 -1
- package/dist/cjs/model/ModelEditorTimeline.js +12 -11
- package/dist/cjs/model/ModelEditorTimeline.js.map +1 -1
- package/dist/cjs/model/ModelEditorToolbar.js +5 -5
- package/dist/cjs/model/ModelEditorToolbar.js.map +1 -1
- package/dist/cjs/model/ModelEditorViewport.js +12 -8
- package/dist/cjs/model/ModelEditorViewport.js.map +1 -1
- package/dist/cjs/model/ModelViewer.js +16 -15
- package/dist/cjs/model/ModelViewer.js.map +1 -1
- package/dist/cjs/model/NiceArmatureEditor.js +53 -30
- package/dist/cjs/model/NiceArmatureEditor.js.map +1 -1
- package/dist/cjs/model/NiceMorphTargetEditor.js +51 -30
- package/dist/cjs/model/NiceMorphTargetEditor.js.map +1 -1
- package/dist/cjs/model/NiceOctree.js +62 -37
- package/dist/cjs/model/NiceOctree.js.map +1 -1
- package/dist/cjs/model/NicePhysicsSimulation.js +74 -36
- package/dist/cjs/model/NicePhysicsSimulation.js.map +1 -1
- package/dist/cjs/model/NiceProceduralGeometry.js +101 -31
- package/dist/cjs/model/NiceProceduralGeometry.js.map +1 -1
- package/dist/cjs/model/NiceTerrainEditor.js +88 -38
- package/dist/cjs/model/NiceTerrainEditor.js.map +1 -1
- package/dist/cjs/model/NiceWeightPainter.js +46 -24
- package/dist/cjs/model/NiceWeightPainter.js.map +1 -1
- package/dist/cjs/model/NiceXRPreview.js +89 -43
- package/dist/cjs/model/NiceXRPreview.js.map +1 -1
- package/dist/cjs/model/cadModeUtils.js +2 -2
- package/dist/cjs/model/cadModeUtils.js.map +1 -1
- package/dist/cjs/model/editorShortcuts.js +69 -35
- package/dist/cjs/model/editorShortcuts.js.map +1 -1
- package/dist/cjs/model/modelEditorTypes.js +56 -52
- package/dist/cjs/model/modelEditorTypes.js.map +1 -1
- package/dist/cjs/model/modelEditorUtils.js +356 -131
- package/dist/cjs/model/modelEditorUtils.js.map +1 -1
- package/dist/cjs/model/simsModeUtils.js +819 -74
- package/dist/cjs/model/simsModeUtils.js.map +1 -1
- package/dist/cjs/model/useModelEditor.js +501 -394
- package/dist/cjs/model/useModelEditor.js.map +1 -1
- package/dist/cjs/model/useModelViewer.js +117 -86
- package/dist/cjs/model/useModelViewer.js.map +1 -1
- package/dist/cjs/particle/NiceParticleEditor.js +126 -69
- package/dist/cjs/particle/NiceParticleEditor.js.map +1 -1
- package/dist/cjs/particle/particleEditorUtils.js +64 -27
- package/dist/cjs/particle/particleEditorUtils.js.map +1 -1
- package/dist/cjs/rendering/NiceCascadedShadows.js +35 -23
- package/dist/cjs/rendering/NiceCascadedShadows.js.map +1 -1
- package/dist/cjs/rendering/NiceRenderExport.js +26 -12
- package/dist/cjs/rendering/NiceRenderExport.js.map +1 -1
- package/dist/cjs/rendering/NiceSSAO.js +28 -23
- package/dist/cjs/rendering/NiceSSAO.js.map +1 -1
- package/dist/cjs/rendering/NiceSSR.js +22 -18
- package/dist/cjs/rendering/NiceSSR.js.map +1 -1
- package/dist/cjs/rendering/NiceWebGPURenderer.js +60 -37
- package/dist/cjs/rendering/NiceWebGPURenderer.js.map +1 -1
- package/dist/cjs/ui/dist/NiceErrorBoundary-D75yr_WE.js +572 -0
- package/dist/cjs/ui/dist/NiceErrorBoundary-D75yr_WE.js.map +1 -0
- package/dist/cjs/ui/dist/NiceForm-CKoJA6NG.js +4979 -0
- package/dist/cjs/ui/dist/NiceForm-CKoJA6NG.js.map +1 -0
- package/dist/cjs/ui/dist/NiceModal-1QX7NhyH.js +98 -0
- package/dist/cjs/ui/dist/NiceModal-1QX7NhyH.js.map +1 -0
- package/dist/cjs/ui/dist/NiceModuleLifecyclePanel-CMrPbSw9.js +5244 -0
- package/dist/cjs/ui/dist/NiceModuleLifecyclePanel-CMrPbSw9.js.map +1 -0
- package/dist/cjs/ui/dist/NicePagination-DbE-uOkl.js +174 -0
- package/dist/cjs/ui/dist/NicePagination-DbE-uOkl.js.map +1 -0
- package/dist/cjs/ui/dist/NicePinCodeInput-B8cI8zu8.js +10459 -0
- package/dist/cjs/ui/dist/NicePinCodeInput-B8cI8zu8.js.map +1 -0
- package/dist/cjs/ui/dist/NiceSavedQueryPanel-CZ5bYOe_.js +6313 -0
- package/dist/cjs/ui/dist/NiceSavedQueryPanel-CZ5bYOe_.js.map +1 -0
- package/dist/cjs/ui/dist/NiceTabs-DzLHzwuA.js +1639 -0
- package/dist/cjs/ui/dist/NiceTabs-DzLHzwuA.js.map +1 -0
- package/dist/cjs/ui/dist/NiceWindow-DeC83yfE.js +807 -0
- package/dist/cjs/ui/dist/NiceWindow-DeC83yfE.js.map +1 -0
- package/dist/cjs/ui/dist/charts-BAS21jkC.js +3833 -0
- package/dist/cjs/ui/dist/charts-BAS21jkC.js.map +1 -0
- package/dist/cjs/ui/dist/core-Da43q-pO.js +11683 -0
- package/dist/cjs/ui/dist/core-Da43q-pO.js.map +1 -0
- package/dist/cjs/ui/dist/index-pAuGTbuB.js +28876 -0
- package/dist/cjs/ui/dist/index-pAuGTbuB.js.map +1 -0
- package/dist/cjs/uv/NiceUVEditor.js +115 -86
- package/dist/cjs/uv/NiceUVEditor.js.map +1 -1
- package/dist/cjs/uv/uvEditorUtils.js +41 -23
- package/dist/cjs/uv/uvEditorUtils.js.map +1 -1
- package/dist/esm/collaborative/collaborativeScene.js +16 -8
- package/dist/esm/collaborative/collaborativeScene.js.map +1 -1
- package/dist/esm/dance/DanceBridge.js +55 -20
- package/dist/esm/dance/DanceBridge.js.map +1 -1
- package/dist/esm/dance/DanceScoreEngine.js +29 -15
- package/dist/esm/dance/DanceScoreEngine.js.map +1 -1
- package/dist/esm/dance/PoseDetector.js +73 -30
- package/dist/esm/dance/PoseDetector.js.map +1 -1
- package/dist/esm/material/NiceMaterialEditor.js +115 -72
- package/dist/esm/material/NiceMaterialEditor.js.map +1 -1
- package/dist/esm/material/materialEditorUtils.js +86 -55
- package/dist/esm/material/materialEditorUtils.js.map +1 -1
- package/dist/esm/model/ModelEditor.js +16 -14
- package/dist/esm/model/ModelEditor.js.map +1 -1
- package/dist/esm/model/ModelEditorLeftPanel.js +21 -15
- package/dist/esm/model/ModelEditorLeftPanel.js.map +1 -1
- package/dist/esm/model/ModelEditorMenuBar.js +23 -10
- package/dist/esm/model/ModelEditorMenuBar.js.map +1 -1
- package/dist/esm/model/ModelEditorRightPanel.js +32 -27
- package/dist/esm/model/ModelEditorRightPanel.js.map +1 -1
- package/dist/esm/model/ModelEditorSubComponents.js +17 -17
- package/dist/esm/model/ModelEditorSubComponents.js.map +1 -1
- package/dist/esm/model/ModelEditorTimeline.js +12 -11
- package/dist/esm/model/ModelEditorTimeline.js.map +1 -1
- package/dist/esm/model/ModelEditorToolbar.js +5 -5
- package/dist/esm/model/ModelEditorToolbar.js.map +1 -1
- package/dist/esm/model/ModelEditorViewport.js +12 -8
- package/dist/esm/model/ModelEditorViewport.js.map +1 -1
- package/dist/esm/model/ModelViewer.js +8 -7
- package/dist/esm/model/ModelViewer.js.map +1 -1
- package/dist/esm/model/NiceArmatureEditor.js +36 -13
- package/dist/esm/model/NiceArmatureEditor.js.map +1 -1
- package/dist/esm/model/NiceMorphTargetEditor.js +34 -13
- package/dist/esm/model/NiceMorphTargetEditor.js.map +1 -1
- package/dist/esm/model/NiceOctree.js +47 -22
- package/dist/esm/model/NiceOctree.js.map +1 -1
- package/dist/esm/model/NicePhysicsSimulation.js +51 -13
- package/dist/esm/model/NicePhysicsSimulation.js.map +1 -1
- package/dist/esm/model/NiceProceduralGeometry.js +94 -24
- package/dist/esm/model/NiceProceduralGeometry.js.map +1 -1
- package/dist/esm/model/NiceTerrainEditor.js +70 -20
- package/dist/esm/model/NiceTerrainEditor.js.map +1 -1
- package/dist/esm/model/NiceWeightPainter.js +33 -11
- package/dist/esm/model/NiceWeightPainter.js.map +1 -1
- package/dist/esm/model/NiceXRPreview.js +72 -26
- package/dist/esm/model/NiceXRPreview.js.map +1 -1
- package/dist/esm/model/cadModeUtils.js +2 -2
- package/dist/esm/model/cadModeUtils.js.map +1 -1
- package/dist/esm/model/editorShortcuts.js +69 -35
- package/dist/esm/model/editorShortcuts.js.map +1 -1
- package/dist/esm/model/modelEditorTypes.js +56 -52
- package/dist/esm/model/modelEditorTypes.js.map +1 -1
- package/dist/esm/model/modelEditorUtils.js +356 -131
- package/dist/esm/model/modelEditorUtils.js.map +1 -1
- package/dist/esm/model/simsModeUtils.js +819 -74
- package/dist/esm/model/simsModeUtils.js.map +1 -1
- package/dist/esm/model/useModelEditor.js +384 -277
- package/dist/esm/model/useModelEditor.js.map +1 -1
- package/dist/esm/model/useModelViewer.js +56 -25
- package/dist/esm/model/useModelViewer.js.map +1 -1
- package/dist/esm/particle/NiceParticleEditor.js +116 -59
- package/dist/esm/particle/NiceParticleEditor.js.map +1 -1
- package/dist/esm/particle/particleEditorUtils.js +64 -27
- package/dist/esm/particle/particleEditorUtils.js.map +1 -1
- package/dist/esm/rendering/NiceCascadedShadows.js +24 -12
- package/dist/esm/rendering/NiceCascadedShadows.js.map +1 -1
- package/dist/esm/rendering/NiceRenderExport.js +22 -8
- package/dist/esm/rendering/NiceRenderExport.js.map +1 -1
- package/dist/esm/rendering/NiceSSAO.js +11 -6
- package/dist/esm/rendering/NiceSSAO.js.map +1 -1
- package/dist/esm/rendering/NiceSSR.js +9 -5
- package/dist/esm/rendering/NiceSSR.js.map +1 -1
- package/dist/esm/rendering/NiceWebGPURenderer.js +40 -17
- package/dist/esm/rendering/NiceWebGPURenderer.js.map +1 -1
- package/dist/esm/ui/dist/NiceErrorBoundary-D75yr_WE.js +563 -0
- package/dist/esm/ui/dist/NiceErrorBoundary-D75yr_WE.js.map +1 -0
- package/dist/esm/ui/dist/NiceForm-CKoJA6NG.js +4960 -0
- package/dist/esm/ui/dist/NiceForm-CKoJA6NG.js.map +1 -0
- package/dist/esm/ui/dist/NiceModal-1QX7NhyH.js +96 -0
- package/dist/esm/ui/dist/NiceModal-1QX7NhyH.js.map +1 -0
- package/dist/esm/ui/dist/NiceModuleLifecyclePanel-CMrPbSw9.js +5201 -0
- package/dist/esm/ui/dist/NiceModuleLifecyclePanel-CMrPbSw9.js.map +1 -0
- package/dist/esm/ui/dist/NicePagination-DbE-uOkl.js +172 -0
- package/dist/esm/ui/dist/NicePagination-DbE-uOkl.js.map +1 -0
- package/dist/esm/ui/dist/NicePinCodeInput-B8cI8zu8.js +10408 -0
- package/dist/esm/ui/dist/NicePinCodeInput-B8cI8zu8.js.map +1 -0
- package/dist/esm/ui/dist/NiceSavedQueryPanel-CZ5bYOe_.js +6296 -0
- package/dist/esm/ui/dist/NiceSavedQueryPanel-CZ5bYOe_.js.map +1 -0
- package/dist/esm/ui/dist/NiceTabs-DzLHzwuA.js +1630 -0
- package/dist/esm/ui/dist/NiceTabs-DzLHzwuA.js.map +1 -0
- package/dist/esm/ui/dist/NiceWindow-DeC83yfE.js +796 -0
- package/dist/esm/ui/dist/NiceWindow-DeC83yfE.js.map +1 -0
- package/dist/esm/ui/dist/charts-BAS21jkC.js +3809 -0
- package/dist/esm/ui/dist/charts-BAS21jkC.js.map +1 -0
- package/dist/esm/ui/dist/core-Da43q-pO.js +11502 -0
- package/dist/esm/ui/dist/core-Da43q-pO.js.map +1 -0
- package/dist/esm/ui/dist/index-pAuGTbuB.js +28792 -0
- package/dist/esm/ui/dist/index-pAuGTbuB.js.map +1 -0
- package/dist/esm/uv/NiceUVEditor.js +91 -62
- package/dist/esm/uv/NiceUVEditor.js.map +1 -1
- package/dist/esm/uv/uvEditorUtils.js +41 -23
- package/dist/esm/uv/uvEditorUtils.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
-
var
|
|
4
|
+
var _e = require('react');
|
|
5
|
+
var ParticleEditor_module = require('./ParticleEditor.module.css.js');
|
|
5
6
|
var particleEditorTypes = require('./particleEditorTypes.js');
|
|
6
7
|
var particleEditorUtils = require('./particleEditorUtils.js');
|
|
7
|
-
var ParticleEditor_module = require('./ParticleEditor.module.css.js');
|
|
8
8
|
|
|
9
9
|
/* ═══════════════════════════════════════════════════════════════════════════
|
|
10
10
|
State Reducer
|
|
@@ -52,10 +52,11 @@ function particleEditorReducer(state, action) {
|
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
54
|
case 'REMOVE_SYSTEM': {
|
|
55
|
-
if (state.systems.length <= 1)
|
|
55
|
+
if (state.systems.length <= 1) {
|
|
56
56
|
return state;
|
|
57
|
+
}
|
|
57
58
|
const newState = pushToUndoStack(state);
|
|
58
|
-
const newSystems = newState.systems.filter(s => s.id !== action.systemId);
|
|
59
|
+
const newSystems = newState.systems.filter((s) => s.id !== action.systemId);
|
|
59
60
|
return {
|
|
60
61
|
...newState,
|
|
61
62
|
systems: newSystems,
|
|
@@ -68,13 +69,14 @@ function particleEditorReducer(state, action) {
|
|
|
68
69
|
const newState = pushToUndoStack(state);
|
|
69
70
|
return {
|
|
70
71
|
...newState,
|
|
71
|
-
systems: newState.systems.map(s => s.id === action.systemId ? { ...s, ...action.updates } : s),
|
|
72
|
+
systems: newState.systems.map((s) => s.id === action.systemId ? { ...s, ...action.updates } : s),
|
|
72
73
|
};
|
|
73
74
|
}
|
|
74
75
|
case 'DUPLICATE_SYSTEM': {
|
|
75
|
-
const system = state.systems.find(s => s.id === action.systemId);
|
|
76
|
-
if (!system)
|
|
76
|
+
const system = state.systems.find((s) => s.id === action.systemId);
|
|
77
|
+
if (!system) {
|
|
77
78
|
return state;
|
|
79
|
+
}
|
|
78
80
|
const cloned = particleEditorUtils.cloneSystem(system);
|
|
79
81
|
const newState = pushToUndoStack(state);
|
|
80
82
|
return {
|
|
@@ -91,7 +93,7 @@ function particleEditorReducer(state, action) {
|
|
|
91
93
|
return {
|
|
92
94
|
...state,
|
|
93
95
|
expandedModules: state.expandedModules.includes(action.module)
|
|
94
|
-
? state.expandedModules.filter(m => m !== action.module)
|
|
96
|
+
? state.expandedModules.filter((m) => m !== action.module)
|
|
95
97
|
: [...state.expandedModules, action.module],
|
|
96
98
|
};
|
|
97
99
|
case 'SET_TOOL':
|
|
@@ -123,8 +125,9 @@ function particleEditorReducer(state, action) {
|
|
|
123
125
|
case 'SET_PREVIEW_MODE':
|
|
124
126
|
return { ...state, previewMode: action.mode };
|
|
125
127
|
case 'UNDO': {
|
|
126
|
-
if (state.undoStack.length === 0)
|
|
128
|
+
if (state.undoStack.length === 0) {
|
|
127
129
|
return state;
|
|
130
|
+
}
|
|
128
131
|
const previous = state.undoStack[state.undoStack.length - 1];
|
|
129
132
|
return {
|
|
130
133
|
...state,
|
|
@@ -134,8 +137,9 @@ function particleEditorReducer(state, action) {
|
|
|
134
137
|
};
|
|
135
138
|
}
|
|
136
139
|
case 'REDO': {
|
|
137
|
-
if (state.redoStack.length === 0)
|
|
140
|
+
if (state.redoStack.length === 0) {
|
|
138
141
|
return state;
|
|
142
|
+
}
|
|
139
143
|
const next = state.redoStack[state.redoStack.length - 1];
|
|
140
144
|
return {
|
|
141
145
|
...state,
|
|
@@ -145,23 +149,27 @@ function particleEditorReducer(state, action) {
|
|
|
145
149
|
};
|
|
146
150
|
}
|
|
147
151
|
case 'COPY_SYSTEM': {
|
|
148
|
-
const system = state.systems.find(s => s.id === action.systemId);
|
|
149
|
-
if (!system)
|
|
152
|
+
const system = state.systems.find((s) => s.id === action.systemId);
|
|
153
|
+
if (!system) {
|
|
150
154
|
return state;
|
|
155
|
+
}
|
|
151
156
|
return { ...state, clipboard: { ...system } };
|
|
152
157
|
}
|
|
153
158
|
case 'COPY_MODULE': {
|
|
154
|
-
const system = state.systems.find(s => s.id === action.systemId);
|
|
155
|
-
if (!system)
|
|
159
|
+
const system = state.systems.find((s) => s.id === action.systemId);
|
|
160
|
+
if (!system) {
|
|
156
161
|
return state;
|
|
162
|
+
}
|
|
157
163
|
const moduleData = system[action.moduleKey];
|
|
158
|
-
if (!moduleData)
|
|
164
|
+
if (!moduleData) {
|
|
159
165
|
return state;
|
|
166
|
+
}
|
|
160
167
|
return { ...state, clipboard: { [action.moduleKey]: moduleData } };
|
|
161
168
|
}
|
|
162
169
|
case 'PASTE_SYSTEM': {
|
|
163
|
-
if (!state.clipboard || !state.clipboard.id)
|
|
170
|
+
if (!state.clipboard || !state.clipboard.id) {
|
|
164
171
|
return state;
|
|
172
|
+
}
|
|
165
173
|
const pasted = particleEditorUtils.cloneSystem(state.clipboard);
|
|
166
174
|
const newState = pushToUndoStack(state);
|
|
167
175
|
return {
|
|
@@ -171,19 +179,20 @@ function particleEditorReducer(state, action) {
|
|
|
171
179
|
};
|
|
172
180
|
}
|
|
173
181
|
case 'PASTE_MODULE': {
|
|
174
|
-
if (!state.clipboard || state.clipboard.id)
|
|
182
|
+
if (!state.clipboard || state.clipboard.id) {
|
|
175
183
|
return state;
|
|
184
|
+
}
|
|
176
185
|
const newState = pushToUndoStack(state);
|
|
177
186
|
return {
|
|
178
187
|
...newState,
|
|
179
|
-
systems: newState.systems.map(s => s.id === action.systemId ? { ...s, ...state.clipboard } : s),
|
|
188
|
+
systems: newState.systems.map((s) => s.id === action.systemId ? { ...s, ...state.clipboard } : s),
|
|
180
189
|
};
|
|
181
190
|
}
|
|
182
191
|
case 'ADD_FORCE': {
|
|
183
192
|
const newState = pushToUndoStack(state);
|
|
184
193
|
return {
|
|
185
194
|
...newState,
|
|
186
|
-
systems: newState.systems.map(s => s.id === action.systemId
|
|
195
|
+
systems: newState.systems.map((s) => s.id === action.systemId
|
|
187
196
|
? { ...s, externalForces: [...s.externalForces, action.force] }
|
|
188
197
|
: s),
|
|
189
198
|
};
|
|
@@ -192,8 +201,8 @@ function particleEditorReducer(state, action) {
|
|
|
192
201
|
const newState = pushToUndoStack(state);
|
|
193
202
|
return {
|
|
194
203
|
...newState,
|
|
195
|
-
systems: newState.systems.map(s => s.id === action.systemId
|
|
196
|
-
? { ...s, externalForces: s.externalForces.filter(f => f.id !== action.forceId) }
|
|
204
|
+
systems: newState.systems.map((s) => s.id === action.systemId
|
|
205
|
+
? { ...s, externalForces: s.externalForces.filter((f) => f.id !== action.forceId) }
|
|
197
206
|
: s),
|
|
198
207
|
};
|
|
199
208
|
}
|
|
@@ -201,10 +210,10 @@ function particleEditorReducer(state, action) {
|
|
|
201
210
|
const newState = pushToUndoStack(state);
|
|
202
211
|
return {
|
|
203
212
|
...newState,
|
|
204
|
-
systems: newState.systems.map(s => s.id === action.systemId
|
|
213
|
+
systems: newState.systems.map((s) => s.id === action.systemId
|
|
205
214
|
? {
|
|
206
215
|
...s,
|
|
207
|
-
externalForces: s.externalForces.map(f => f.id === action.forceId ? { ...f, ...action.updates } : f),
|
|
216
|
+
externalForces: s.externalForces.map((f) => f.id === action.forceId ? { ...f, ...action.updates } : f),
|
|
208
217
|
}
|
|
209
218
|
: s),
|
|
210
219
|
};
|
|
@@ -213,7 +222,7 @@ function particleEditorReducer(state, action) {
|
|
|
213
222
|
const newState = pushToUndoStack(state);
|
|
214
223
|
return {
|
|
215
224
|
...newState,
|
|
216
|
-
systems: newState.systems.map(s => s.id === action.systemId
|
|
225
|
+
systems: newState.systems.map((s) => s.id === action.systemId
|
|
217
226
|
? { ...s, subEmitters: [...s.subEmitters, action.subEmitter] }
|
|
218
227
|
: s),
|
|
219
228
|
};
|
|
@@ -222,8 +231,8 @@ function particleEditorReducer(state, action) {
|
|
|
222
231
|
const newState = pushToUndoStack(state);
|
|
223
232
|
return {
|
|
224
233
|
...newState,
|
|
225
|
-
systems: newState.systems.map(s => s.id === action.systemId
|
|
226
|
-
? { ...s, subEmitters: s.subEmitters.filter(se => se.id !== action.subEmitterId) }
|
|
234
|
+
systems: newState.systems.map((s) => s.id === action.systemId
|
|
235
|
+
? { ...s, subEmitters: s.subEmitters.filter((se) => se.id !== action.subEmitterId) }
|
|
227
236
|
: s),
|
|
228
237
|
};
|
|
229
238
|
}
|
|
@@ -231,7 +240,7 @@ function particleEditorReducer(state, action) {
|
|
|
231
240
|
const newState = pushToUndoStack(state);
|
|
232
241
|
return {
|
|
233
242
|
...newState,
|
|
234
|
-
systems: newState.systems.map(s => s.id === action.systemId
|
|
243
|
+
systems: newState.systems.map((s) => s.id === action.systemId
|
|
235
244
|
? { ...s, emission: { ...s.emission, bursts: [...s.emission.bursts, action.burst] } }
|
|
236
245
|
: s),
|
|
237
246
|
};
|
|
@@ -240,7 +249,7 @@ function particleEditorReducer(state, action) {
|
|
|
240
249
|
const newState = pushToUndoStack(state);
|
|
241
250
|
return {
|
|
242
251
|
...newState,
|
|
243
|
-
systems: newState.systems.map(s => s.id === action.systemId
|
|
252
|
+
systems: newState.systems.map((s) => s.id === action.systemId
|
|
244
253
|
? {
|
|
245
254
|
...s,
|
|
246
255
|
emission: {
|
|
@@ -268,13 +277,13 @@ function particleEditorReducer(state, action) {
|
|
|
268
277
|
Hook: useParticleEditor
|
|
269
278
|
═══════════════════════════════════════════════════════════════════════════ */
|
|
270
279
|
function useParticleEditor(initialSystems) {
|
|
271
|
-
const [state, dispatch] =
|
|
280
|
+
const [state, dispatch] = _e.useReducer(particleEditorReducer, initialSystems, createInitialState);
|
|
272
281
|
return { state, dispatch };
|
|
273
282
|
}
|
|
274
283
|
function SystemListPanel({ systems, selectedId, onSelect, onAdd, onRemove, onDuplicate, onRename, onAddPreset, }) {
|
|
275
|
-
const [editingId, setEditingId] =
|
|
276
|
-
const [editName, setEditName] =
|
|
277
|
-
const [showPresets, setShowPresets] =
|
|
284
|
+
const [editingId, setEditingId] = _e.useState(null);
|
|
285
|
+
const [editName, setEditName] = _e.useState('');
|
|
286
|
+
const [showPresets, setShowPresets] = _e.useState(false);
|
|
278
287
|
const handleStartRename = (system) => {
|
|
279
288
|
setEditingId(system.id);
|
|
280
289
|
setEditName(system.name);
|
|
@@ -285,10 +294,16 @@ function SystemListPanel({ systems, selectedId, onSelect, onAdd, onRemove, onDup
|
|
|
285
294
|
}
|
|
286
295
|
setEditingId(null);
|
|
287
296
|
};
|
|
288
|
-
return (jsxRuntime.jsxs("div", { className: ParticleEditor_module.systemList, children: [jsxRuntime.jsxs("div", { className: ParticleEditor_module.systemListHeader, children: [jsxRuntime.jsxs("span", { children: ["Systems (", systems.length, ")"] }), jsxRuntime.jsxs("div", { className: ParticleEditor_module.systemListActions, children: [jsxRuntime.jsx("button", { onClick: onAdd, title: "New System", children: "+" }), jsxRuntime.jsx("button", { onClick: () => setShowPresets(!showPresets), title: "Add Preset", children: "\uD83D\uDCCB" })] })] }), showPresets && (jsxRuntime.jsx("div", { className: ParticleEditor_module.presetMenu, children: Object.keys(particleEditorUtils.PARTICLE_PRESETS).map(preset => (jsxRuntime.jsx("button", { className: ParticleEditor_module.presetItem, onClick: () => {
|
|
297
|
+
return (jsxRuntime.jsxs("div", { className: ParticleEditor_module.systemList, children: [jsxRuntime.jsxs("div", { className: ParticleEditor_module.systemListHeader, children: [jsxRuntime.jsxs("span", { children: ["Systems (", systems.length, ")"] }), jsxRuntime.jsxs("div", { className: ParticleEditor_module.systemListActions, children: [jsxRuntime.jsx("button", { onClick: onAdd, title: "New System", children: "+" }), jsxRuntime.jsx("button", { onClick: () => setShowPresets(!showPresets), title: "Add Preset", children: "\uD83D\uDCCB" })] })] }), showPresets && (jsxRuntime.jsx("div", { className: ParticleEditor_module.presetMenu, children: Object.keys(particleEditorUtils.PARTICLE_PRESETS).map((preset) => (jsxRuntime.jsx("button", { className: ParticleEditor_module.presetItem, onClick: () => {
|
|
289
298
|
onAddPreset(preset);
|
|
290
299
|
setShowPresets(false);
|
|
291
|
-
}, children: preset.charAt(0).toUpperCase() + preset.slice(1) }, preset))) })), jsxRuntime.jsx("div", { className: ParticleEditor_module.systemItems, children: systems.map(system => (jsxRuntime.jsx("div", { className: `${ParticleEditor_module.systemItem} ${selectedId === system.id ? ParticleEditor_module.selected : ''}`, onClick: () => onSelect(system.id), children: editingId === system.id ? (jsxRuntime.jsx("input", { type: "text", value: editName, onChange: e => setEditName(e.target.value), onBlur: handleFinishRename, onKeyDown: e => e.key === 'Enter' && handleFinishRename(), autoFocus: true, className: ParticleEditor_module.renameInput })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: ParticleEditor_module.systemName, onDoubleClick: () => handleStartRename(system), children: system.name }), jsxRuntime.jsxs("div", { className: ParticleEditor_module.systemItemActions, children: [jsxRuntime.jsx("button", { onClick: e
|
|
300
|
+
}, children: preset.charAt(0).toUpperCase() + preset.slice(1) }, preset))) })), jsxRuntime.jsx("div", { className: ParticleEditor_module.systemItems, children: systems.map((system) => (jsxRuntime.jsx("div", { className: `${ParticleEditor_module.systemItem} ${selectedId === system.id ? ParticleEditor_module.selected : ''}`, onClick: () => onSelect(system.id), children: editingId === system.id ? (jsxRuntime.jsx("input", { type: "text", value: editName, onChange: (e) => setEditName(e.target.value), onBlur: handleFinishRename, onKeyDown: (e) => e.key === 'Enter' && handleFinishRename(), autoFocus: true, className: ParticleEditor_module.renameInput })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { className: ParticleEditor_module.systemName, onDoubleClick: () => handleStartRename(system), children: system.name }), jsxRuntime.jsxs("div", { className: ParticleEditor_module.systemItemActions, children: [jsxRuntime.jsx("button", { onClick: (e) => {
|
|
301
|
+
e.stopPropagation();
|
|
302
|
+
onDuplicate(system.id);
|
|
303
|
+
}, title: "Duplicate", children: "\uD83D\uDCCB" }), jsxRuntime.jsx("button", { onClick: (e) => {
|
|
304
|
+
e.stopPropagation();
|
|
305
|
+
onRemove(system.id);
|
|
306
|
+
}, title: "Remove", disabled: systems.length <= 1, children: "\uD83D\uDDD1\uFE0F" })] })] })) }, system.id))) })] }));
|
|
292
307
|
}
|
|
293
308
|
function InspectorPanel({ system, expandedModules, selectedModule, onToggleModule, onSelectModule, onUpdateSystem, }) {
|
|
294
309
|
if (!system) {
|
|
@@ -299,7 +314,11 @@ function InspectorPanel({ system, expandedModules, selectedModule, onToggleModul
|
|
|
299
314
|
{ key: 'emission', hasEnabled: true, enabled: system.emission.enabled },
|
|
300
315
|
{ key: 'shape', hasEnabled: false },
|
|
301
316
|
{ key: 'velocityOverLifetime', hasEnabled: true, enabled: system.velocityOverLifetime.enabled },
|
|
302
|
-
{
|
|
317
|
+
{
|
|
318
|
+
key: 'limitVelocityOverLifetime',
|
|
319
|
+
hasEnabled: true,
|
|
320
|
+
enabled: system.limitVelocityOverLifetime.enabled,
|
|
321
|
+
},
|
|
303
322
|
{ key: 'inheritVelocity', hasEnabled: true, enabled: system.inheritVelocity.enabled },
|
|
304
323
|
{ key: 'forceOverLifetime', hasEnabled: true, enabled: system.forceOverLifetime.enabled },
|
|
305
324
|
{ key: 'colorOverLifetime', hasEnabled: true, enabled: system.colorOverLifetime.enabled },
|
|
@@ -313,22 +332,27 @@ function InspectorPanel({ system, expandedModules, selectedModule, onToggleModul
|
|
|
313
332
|
{ key: 'collision', hasEnabled: true, enabled: system.collision.enabled },
|
|
314
333
|
{ key: 'triggers', hasEnabled: true, enabled: system.triggers.enabled },
|
|
315
334
|
{ key: 'subEmitters', hasEnabled: false },
|
|
316
|
-
{
|
|
335
|
+
{
|
|
336
|
+
key: 'textureSheetAnimation',
|
|
337
|
+
hasEnabled: true,
|
|
338
|
+
enabled: system.textureSheetAnimation.enabled,
|
|
339
|
+
},
|
|
317
340
|
{ key: 'lights', hasEnabled: true, enabled: system.lights.enabled },
|
|
318
341
|
{ key: 'trails', hasEnabled: false },
|
|
319
342
|
{ key: 'renderer', hasEnabled: false },
|
|
320
343
|
{ key: 'material', hasEnabled: false },
|
|
321
344
|
];
|
|
322
345
|
const handleModuleToggle = (key, enabled) => {
|
|
323
|
-
|
|
346
|
+
const current = system[key];
|
|
347
|
+
onUpdateSystem({ [key]: { ...current, enabled } });
|
|
324
348
|
};
|
|
325
|
-
return (jsxRuntime.jsxs("div", { className: ParticleEditor_module.inspector, children: [jsxRuntime.jsx("div", { className: ParticleEditor_module.inspectorHeader, children: jsxRuntime.jsx("span", { children: system.name }) }), jsxRuntime.jsx("div", { className: ParticleEditor_module.inspectorModules, children: modules.map(mod => (jsxRuntime.jsxs("div", { className: ParticleEditor_module.moduleSection, children: [jsxRuntime.jsxs("div", { className: `${ParticleEditor_module.moduleHeader} ${selectedModule === mod.key ? ParticleEditor_module.selected : ''}`, onClick: () => onToggleModule(mod.key), children: [jsxRuntime.jsx("span", { className: ParticleEditor_module.moduleIcon, children: expandedModules.includes(mod.key) ? '▼' : '►' }), mod.hasEnabled && (jsxRuntime.jsx("input", { type: "checkbox", checked: mod.enabled, onChange: e => {
|
|
349
|
+
return (jsxRuntime.jsxs("div", { className: ParticleEditor_module.inspector, children: [jsxRuntime.jsx("div", { className: ParticleEditor_module.inspectorHeader, children: jsxRuntime.jsx("span", { children: system.name }) }), jsxRuntime.jsx("div", { className: ParticleEditor_module.inspectorModules, children: modules.map((mod) => (jsxRuntime.jsxs("div", { className: ParticleEditor_module.moduleSection, children: [jsxRuntime.jsxs("div", { className: `${ParticleEditor_module.moduleHeader} ${selectedModule === mod.key ? ParticleEditor_module.selected : ''}`, onClick: () => onToggleModule(mod.key), children: [jsxRuntime.jsx("span", { className: ParticleEditor_module.moduleIcon, children: expandedModules.includes(mod.key) ? '▼' : '►' }), mod.hasEnabled && (jsxRuntime.jsx("input", { type: "checkbox", checked: mod.enabled, onChange: (e) => {
|
|
326
350
|
e.stopPropagation();
|
|
327
351
|
handleModuleToggle(mod.key, e.target.checked);
|
|
328
352
|
}, className: ParticleEditor_module.moduleCheckbox })), jsxRuntime.jsx("span", { className: ParticleEditor_module.moduleName, children: particleEditorTypes.MODULE_NAMES[mod.key] || mod.key })] }), expandedModules.includes(mod.key) && (jsxRuntime.jsx("div", { className: ParticleEditor_module.moduleContent, children: jsxRuntime.jsx(ModuleEditor, { system: system, moduleKey: mod.key, onUpdate: onUpdateSystem }) }))] }, mod.key))) })] }));
|
|
329
353
|
}
|
|
330
354
|
function ModuleEditor({ system, moduleKey, onUpdate }) {
|
|
331
|
-
const renderDistributionInput = (label, value, onChange) => (jsxRuntime.jsxs("div", { className: ParticleEditor_module.propertyRow, children: [jsxRuntime.jsx("label", { children: label }), jsxRuntime.jsxs("div", { className: ParticleEditor_module.distributionInput, children: [jsxRuntime.jsxs("select", { value: value.type, onChange: e => {
|
|
355
|
+
const renderDistributionInput = (label, value, onChange) => (jsxRuntime.jsxs("div", { className: ParticleEditor_module.propertyRow, children: [jsxRuntime.jsx("label", { children: label }), jsxRuntime.jsxs("div", { className: ParticleEditor_module.distributionInput, children: [jsxRuntime.jsxs("select", { value: value.type, onChange: (e) => {
|
|
332
356
|
const newType = e.target.value;
|
|
333
357
|
if (newType === 'constant') {
|
|
334
358
|
onChange({ type: 'constant', value: value.type === 'constant' ? value.value : 1 });
|
|
@@ -337,57 +361,85 @@ function ModuleEditor({ system, moduleKey, onUpdate }) {
|
|
|
337
361
|
onChange({ type: 'random', min: 0, max: 1 });
|
|
338
362
|
}
|
|
339
363
|
else if (newType === 'curve') {
|
|
340
|
-
onChange({
|
|
364
|
+
onChange({
|
|
365
|
+
type: 'curve',
|
|
366
|
+
curve: [
|
|
367
|
+
{ time: 0, value: 1 },
|
|
368
|
+
{ time: 1, value: 1 },
|
|
369
|
+
],
|
|
370
|
+
});
|
|
341
371
|
}
|
|
342
|
-
}, className: ParticleEditor_module.distributionType, children: [jsxRuntime.jsx("option", { value: "constant", children: "Constant" }), jsxRuntime.jsx("option", { value: "random", children: "Random" }), jsxRuntime.jsx("option", { value: "curve", children: "Curve" })] }), value.type === 'constant' && (jsxRuntime.jsx("input", { type: "number", value: value.value, onChange: e => onChange({ ...value, value: parseFloat(e.target.value) || 0 }), className: ParticleEditor_module.numberInput })), value.type === 'random' && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("input", { type: "number", value: value.min, onChange: e => onChange({ ...value, min: parseFloat(e.target.value) || 0 }), className: ParticleEditor_module.numberInput, placeholder: "Min" }), jsxRuntime.jsx("input", { type: "number", value: value.max, onChange: e => onChange({ ...value, max: parseFloat(e.target.value) || 0 }), className: ParticleEditor_module.numberInput, placeholder: "Max" })] }))] })] }));
|
|
343
|
-
const renderNumberInput = (label, value, onChange, props) => (jsxRuntime.jsxs("div", { className: ParticleEditor_module.propertyRow, children: [jsxRuntime.jsx("label", { children: label }), jsxRuntime.jsx("input", { type: "number", value: value, onChange: e => onChange(parseFloat(e.target.value) || 0), className: ParticleEditor_module.numberInput, ...props })] }));
|
|
344
|
-
const renderToggle = (label, value, onChange) => (jsxRuntime.jsxs("div", { className: ParticleEditor_module.propertyRow, children: [jsxRuntime.jsx("label", { children: label }), jsxRuntime.jsx("input", { type: "checkbox", checked: value, onChange: e => onChange(e.target.checked), className: ParticleEditor_module.toggleInput })] }));
|
|
345
|
-
const renderSelect = (label, value, options, onChange) => (jsxRuntime.jsxs("div", { className: ParticleEditor_module.propertyRow, children: [jsxRuntime.jsx("label", { children: label }), jsxRuntime.jsx("select", { value: value, onChange: e => onChange(e.target.value), className: ParticleEditor_module.selectInput, children: Object.entries(options).map(([key, name]) => (jsxRuntime.jsx("option", { value: key, children: name }, key))) })] }));
|
|
372
|
+
}, className: ParticleEditor_module.distributionType, children: [jsxRuntime.jsx("option", { value: "constant", children: "Constant" }), jsxRuntime.jsx("option", { value: "random", children: "Random" }), jsxRuntime.jsx("option", { value: "curve", children: "Curve" })] }), value.type === 'constant' && (jsxRuntime.jsx("input", { type: "number", value: value.value, onChange: (e) => onChange({ ...value, value: parseFloat(e.target.value) || 0 }), className: ParticleEditor_module.numberInput })), value.type === 'random' && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("input", { type: "number", value: value.min, onChange: (e) => onChange({ ...value, min: parseFloat(e.target.value) || 0 }), className: ParticleEditor_module.numberInput, placeholder: "Min" }), jsxRuntime.jsx("input", { type: "number", value: value.max, onChange: (e) => onChange({ ...value, max: parseFloat(e.target.value) || 0 }), className: ParticleEditor_module.numberInput, placeholder: "Max" })] }))] })] }));
|
|
373
|
+
const renderNumberInput = (label, value, onChange, props) => (jsxRuntime.jsxs("div", { className: ParticleEditor_module.propertyRow, children: [jsxRuntime.jsx("label", { children: label }), jsxRuntime.jsx("input", { type: "number", value: value, onChange: (e) => onChange(parseFloat(e.target.value) || 0), className: ParticleEditor_module.numberInput, ...props })] }));
|
|
374
|
+
const renderToggle = (label, value, onChange) => (jsxRuntime.jsxs("div", { className: ParticleEditor_module.propertyRow, children: [jsxRuntime.jsx("label", { children: label }), jsxRuntime.jsx("input", { type: "checkbox", checked: value, onChange: (e) => onChange(e.target.checked), className: ParticleEditor_module.toggleInput })] }));
|
|
375
|
+
const renderSelect = (label, value, options, onChange) => (jsxRuntime.jsxs("div", { className: ParticleEditor_module.propertyRow, children: [jsxRuntime.jsx("label", { children: label }), jsxRuntime.jsx("select", { value: value, onChange: (e) => onChange(e.target.value), className: ParticleEditor_module.selectInput, children: Object.entries(options).map(([key, name]) => (jsxRuntime.jsx("option", { value: key, children: name }, key))) })] }));
|
|
346
376
|
switch (moduleKey) {
|
|
347
377
|
case 'main':
|
|
348
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [renderNumberInput('Duration', system.duration,
|
|
378
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [renderNumberInput('Duration', system.duration, (v) => onUpdate({ duration: v }), {
|
|
379
|
+
min: 0,
|
|
380
|
+
step: 0.1,
|
|
381
|
+
}), renderToggle('Looping', system.looping, (v) => onUpdate({ looping: v })), renderToggle('Prewarm', system.prewarm, (v) => onUpdate({ prewarm: v })), renderDistributionInput('Start Delay', system.startDelay, (v) => onUpdate({ startDelay: v })), renderDistributionInput('Start Lifetime', system.startLifetime, (v) => onUpdate({ startLifetime: v })), renderDistributionInput('Start Speed', system.startSpeed, (v) => onUpdate({ startSpeed: v })), renderDistributionInput('Start Size', system.startSize, (v) => onUpdate({ startSize: v })), renderDistributionInput('Start Rotation', system.startRotation, (v) => onUpdate({ startRotation: v })), renderDistributionInput('Gravity Modifier', system.gravityModifier, (v) => onUpdate({ gravityModifier: v })), renderSelect('Simulation Space', system.simulationSpace, { local: 'Local', world: 'World', custom: 'Custom' }, (v) => onUpdate({ simulationSpace: v })), renderNumberInput('Simulation Speed', system.simulationSpeed, (v) => onUpdate({ simulationSpeed: v }), { min: 0, step: 0.1 }), renderNumberInput('Max Particles', system.maxParticles, (v) => onUpdate({ maxParticles: v }), { min: 1, step: 1 })] }));
|
|
349
382
|
case 'emission':
|
|
350
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [renderDistributionInput('Rate over Time', system.emission.rateOverTime, v => onUpdate({ emission: { ...system.emission, rateOverTime: v } })), renderDistributionInput('Rate over Distance', system.emission.rateOverDistance, v => onUpdate({ emission: { ...system.emission, rateOverDistance: v } })), jsxRuntime.jsxs("div", { className: ParticleEditor_module.propertyRow, children: [jsxRuntime.jsxs("label", { children: ["Bursts (", system.emission.bursts.length, ")"] }), jsxRuntime.jsx("button", { className: ParticleEditor_module.addButton, onClick: () => onUpdate({
|
|
383
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [renderDistributionInput('Rate over Time', system.emission.rateOverTime, (v) => onUpdate({ emission: { ...system.emission, rateOverTime: v } })), renderDistributionInput('Rate over Distance', system.emission.rateOverDistance, (v) => onUpdate({ emission: { ...system.emission, rateOverDistance: v } })), jsxRuntime.jsxs("div", { className: ParticleEditor_module.propertyRow, children: [jsxRuntime.jsxs("label", { children: ["Bursts (", system.emission.bursts.length, ")"] }), jsxRuntime.jsx("button", { className: ParticleEditor_module.addButton, onClick: () => onUpdate({
|
|
351
384
|
emission: {
|
|
352
385
|
...system.emission,
|
|
353
|
-
bursts: [
|
|
386
|
+
bursts: [
|
|
387
|
+
...system.emission.bursts,
|
|
388
|
+
{
|
|
354
389
|
time: 0,
|
|
355
390
|
count: { type: 'constant', value: 30 },
|
|
356
391
|
cycles: 1,
|
|
357
392
|
interval: 0.01,
|
|
358
393
|
probability: 1,
|
|
359
|
-
}
|
|
394
|
+
},
|
|
395
|
+
],
|
|
360
396
|
},
|
|
361
397
|
}), children: "Add Burst" })] })] }));
|
|
362
398
|
case 'shape':
|
|
363
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [renderSelect('Shape', system.shape.type, particleEditorTypes.EMITTER_SHAPE_NAMES,
|
|
364
|
-
|
|
399
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [renderSelect('Shape', system.shape.type, particleEditorTypes.EMITTER_SHAPE_NAMES, (v) =>
|
|
400
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- writing into discriminated-union variant; runtime narrowed by `type`
|
|
401
|
+
onUpdate({ shape: { ...system.shape, type: v } })), renderToggle('Emit from Shell', system.shape.emitFromShell, (v) => onUpdate({ shape: { ...system.shape, emitFromShell: v } })), renderToggle('Random Direction', system.shape.randomDirection, (v) => onUpdate({ shape: { ...system.shape, randomDirection: v } })), (system.shape.type === 'sphere' ||
|
|
402
|
+
system.shape.type === 'hemisphere' ||
|
|
403
|
+
system.shape.type === 'cone' ||
|
|
404
|
+
system.shape.type === 'circle') && (jsxRuntime.jsx(jsxRuntime.Fragment, { children: renderDistributionInput('Radius', system.shape.radius, (v) =>
|
|
405
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- writing into discriminated-union variant; runtime narrowed by `type`
|
|
406
|
+
onUpdate({ shape: { ...system.shape, radius: v } })) })), system.shape.type === 'cone' && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [renderNumberInput('Angle', system.shape.angle,
|
|
407
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- writing into discriminated-union variant; runtime narrowed by `type`
|
|
408
|
+
(v) => onUpdate({ shape: { ...system.shape, angle: v } }), { min: 0, max: 90 }), renderNumberInput('Length', system.shape.length,
|
|
409
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- writing into discriminated-union variant; runtime narrowed by `type`
|
|
410
|
+
(v) => onUpdate({ shape: { ...system.shape, length: v } }), { min: 0 })] }))] }));
|
|
365
411
|
case 'renderer':
|
|
366
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [renderSelect('Render Mode', system.renderer.type, particleEditorTypes.RENDER_MODE_NAMES,
|
|
412
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [renderSelect('Render Mode', system.renderer.type, particleEditorTypes.RENDER_MODE_NAMES, (v) =>
|
|
413
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- writing into discriminated-union variant; runtime narrowed by `type`
|
|
414
|
+
onUpdate({ renderer: { ...system.renderer, type: v } })), renderSelect('Sort Mode', system.renderer.sortMode, {
|
|
367
415
|
none: 'None',
|
|
368
416
|
by_distance: 'By Distance',
|
|
369
417
|
oldest_in_front: 'Oldest in Front',
|
|
370
418
|
youngest_in_front: 'Youngest in Front',
|
|
371
|
-
}, v => onUpdate({ renderer: { ...system.renderer, sortMode: v } }))] }));
|
|
419
|
+
}, (v) => onUpdate({ renderer: { ...system.renderer, sortMode: v } }))] }));
|
|
372
420
|
case 'material':
|
|
373
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [renderSelect('Shading', system.material.shading, { unlit: 'Unlit', lit: 'Lit' }, v => onUpdate({ material: { ...system.material, shading: v } })), renderSelect('Blend Mode', system.material.blendMode,
|
|
421
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [renderSelect('Shading', system.material.shading, { unlit: 'Unlit', lit: 'Lit' }, (v) => onUpdate({ material: { ...system.material, shading: v } })), renderSelect('Blend Mode', system.material.blendMode,
|
|
422
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- BLEND_MODE_NAMES is keyed by ParticleBlendMode but renderSelect is generic
|
|
423
|
+
particleEditorTypes.BLEND_MODE_NAMES, (v) => onUpdate({ material: { ...system.material, blendMode: v } }))] }));
|
|
374
424
|
default:
|
|
375
|
-
return
|
|
425
|
+
return jsxRuntime.jsx("div", { className: ParticleEditor_module.moduleNotImplemented, children: "Module editor not yet implemented" });
|
|
376
426
|
}
|
|
377
427
|
}
|
|
378
428
|
function Toolbar({ isPlaying, isPaused, playbackSpeed, currentTime, canUndo, canRedo, showGrid, showBounds, showEmitterShape, viewMode, onPlay, onPause, onStop, onRestart, onSpeedChange, onUndo, onRedo, onToggleGrid, onToggleBounds, onToggleEmitterShape, onViewModeChange, onNew, onExport, onImport, }) {
|
|
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))) })] }));
|
|
429
|
+
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
430
|
}
|
|
381
431
|
function PreviewPanel({ systems, isPlaying, isPaused, currentTime, showGrid, showEmitterShape, }) {
|
|
382
|
-
const canvasRef =
|
|
432
|
+
const canvasRef = _e.useRef(null);
|
|
383
433
|
// Simple preview rendering (placeholder - real implementation would use Three.js)
|
|
384
|
-
|
|
434
|
+
_e.useEffect(() => {
|
|
385
435
|
const canvas = canvasRef.current;
|
|
386
|
-
if (!canvas)
|
|
436
|
+
if (!canvas) {
|
|
387
437
|
return;
|
|
438
|
+
}
|
|
388
439
|
const ctx = canvas.getContext('2d');
|
|
389
|
-
if (!ctx)
|
|
440
|
+
if (!ctx) {
|
|
390
441
|
return;
|
|
442
|
+
}
|
|
391
443
|
const width = canvas.width;
|
|
392
444
|
const height = canvas.height;
|
|
393
445
|
const centerX = width / 2;
|
|
@@ -431,8 +483,8 @@ function PreviewPanel({ systems, isPlaying, isPaused, currentTime, showGrid, sho
|
|
|
431
483
|
const angle = seed * Math.PI * 2 + currentTime;
|
|
432
484
|
const distance = 30 + ((currentTime * 50 + i * 10) % 150);
|
|
433
485
|
const x = centerX + Math.cos(angle) * distance;
|
|
434
|
-
const y = centerY - Math.sin(angle) * distance * 0.5 - (currentTime * 30 + i * 3) % 150;
|
|
435
|
-
const alpha = 1 -
|
|
486
|
+
const y = centerY - Math.sin(angle) * distance * 0.5 - ((currentTime * 30 + i * 3) % 150);
|
|
487
|
+
const alpha = 1 - distance / 180;
|
|
436
488
|
const size = 3 + Math.sin(seed * 10 + currentTime) * 2;
|
|
437
489
|
ctx.beginPath();
|
|
438
490
|
ctx.arc(x, y, size, 0, Math.PI * 2);
|
|
@@ -448,19 +500,20 @@ function PreviewPanel({ systems, isPlaying, isPaused, currentTime, showGrid, sho
|
|
|
448
500
|
═══════════════════════════════════════════════════════════════════════════ */
|
|
449
501
|
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
502
|
const { state, dispatch } = useParticleEditor(initialSystems);
|
|
451
|
-
const animationFrameRef =
|
|
452
|
-
const selectedSystem =
|
|
503
|
+
const animationFrameRef = _e.useRef();
|
|
504
|
+
const selectedSystem = _e.useMemo(() => state.systems.find((s) => s.id === state.selectedSystemId) || null, [state.systems, state.selectedSystemId]);
|
|
453
505
|
// Notify parent of changes
|
|
454
|
-
|
|
506
|
+
_e.useEffect(() => {
|
|
455
507
|
onSystemsChange === null || onSystemsChange === void 0 ? void 0 : onSystemsChange(state.systems);
|
|
456
508
|
}, [state.systems, onSystemsChange]);
|
|
457
509
|
// Animation loop
|
|
458
|
-
|
|
459
|
-
if (!state.isPlaying || state.isPaused)
|
|
510
|
+
_e.useEffect(() => {
|
|
511
|
+
if (!state.isPlaying || state.isPaused) {
|
|
460
512
|
return;
|
|
513
|
+
}
|
|
461
514
|
let lastTime = performance.now();
|
|
462
515
|
const animate = (time) => {
|
|
463
|
-
const dt = (time - lastTime) / 1000 * state.playbackSpeed;
|
|
516
|
+
const dt = ((time - lastTime) / 1000) * state.playbackSpeed;
|
|
464
517
|
lastTime = time;
|
|
465
518
|
dispatch({ type: 'SET_CURRENT_TIME', time: state.currentTime + dt });
|
|
466
519
|
// Check if we need to loop
|
|
@@ -495,8 +548,9 @@ function NiceParticleEditor({ systems: initialSystems, onSystemsChange, onPlay,
|
|
|
495
548
|
input.onchange = async (e) => {
|
|
496
549
|
var _a;
|
|
497
550
|
const file = (_a = e.target.files) === null || _a === void 0 ? void 0 : _a[0];
|
|
498
|
-
if (!file)
|
|
551
|
+
if (!file) {
|
|
499
552
|
return;
|
|
553
|
+
}
|
|
500
554
|
const text = await file.text();
|
|
501
555
|
const systems = particleEditorUtils.importSystemsFromJSON(text);
|
|
502
556
|
if (systems) {
|
|
@@ -514,7 +568,10 @@ function NiceParticleEditor({ systems: initialSystems, onSystemsChange, onPlay,
|
|
|
514
568
|
}, onStop: () => {
|
|
515
569
|
dispatch({ type: 'STOP' });
|
|
516
570
|
onStop === null || onStop === void 0 ? void 0 : onStop();
|
|
517
|
-
}, onRestart: () => dispatch({ type: 'RESTART' }), onSpeedChange: speed => dispatch({ type: 'SET_PLAYBACK_SPEED', speed }), onUndo: () => dispatch({ type: 'UNDO' }), onRedo: () => dispatch({ type: 'REDO' }), onToggleGrid: () => dispatch({ type: 'TOGGLE_GRID' }), onToggleBounds: () => dispatch({ type: 'TOGGLE_BOUNDS' }), onToggleEmitterShape: () => dispatch({ type: 'TOGGLE_EMITTER_SHAPE' }), onViewModeChange: mode => dispatch({ type: 'SET_VIEW_MODE', mode }), onNew: () => dispatch({ type: 'NEW_PROJECT' }), onExport: handleExport, onImport: handleImport })), jsxRuntime.jsxs("div", { className: ParticleEditor_module.editorBody, children: [showSystemList && (jsxRuntime.jsx(SystemListPanel, { systems: state.systems, selectedId: state.selectedSystemId, onSelect: id => dispatch({ type: 'SELECT_SYSTEM', systemId: id }), onAdd: () => dispatch({ type: 'ADD_SYSTEM', system: particleEditorUtils.createDefaultSystem() }), onRemove: id => dispatch({ type: 'REMOVE_SYSTEM', systemId: id }), onDuplicate: id => dispatch({ type: 'DUPLICATE_SYSTEM', systemId: id }), onRename: (id, name) => dispatch({ type: 'UPDATE_SYSTEM', systemId: id, updates: { name } }), onAddPreset:
|
|
571
|
+
}, onRestart: () => dispatch({ type: 'RESTART' }), onSpeedChange: (speed) => dispatch({ type: 'SET_PLAYBACK_SPEED', speed }), onUndo: () => dispatch({ type: 'UNDO' }), onRedo: () => dispatch({ type: 'REDO' }), onToggleGrid: () => dispatch({ type: 'TOGGLE_GRID' }), onToggleBounds: () => dispatch({ type: 'TOGGLE_BOUNDS' }), onToggleEmitterShape: () => dispatch({ type: 'TOGGLE_EMITTER_SHAPE' }), onViewModeChange: (mode) => dispatch({ type: 'SET_VIEW_MODE', mode }), onNew: () => dispatch({ type: 'NEW_PROJECT' }), onExport: handleExport, onImport: handleImport })), jsxRuntime.jsxs("div", { className: ParticleEditor_module.editorBody, children: [showSystemList && (jsxRuntime.jsx(SystemListPanel, { systems: state.systems, selectedId: state.selectedSystemId, onSelect: (id) => dispatch({ type: 'SELECT_SYSTEM', systemId: id }), onAdd: () => dispatch({ type: 'ADD_SYSTEM', system: particleEditorUtils.createDefaultSystem() }), onRemove: (id) => dispatch({ type: 'REMOVE_SYSTEM', systemId: id }), onDuplicate: (id) => dispatch({ type: 'DUPLICATE_SYSTEM', systemId: id }), onRename: (id, name) => dispatch({ type: 'UPDATE_SYSTEM', systemId: id, updates: { name } }), onAddPreset: (preset) => dispatch({
|
|
572
|
+
type: 'ADD_SYSTEM',
|
|
573
|
+
system: particleEditorUtils.applyPreset(preset),
|
|
574
|
+
}) })), showPreview && (jsxRuntime.jsx(PreviewPanel, { systems: state.systems, isPlaying: state.isPlaying, isPaused: state.isPaused, currentTime: state.currentTime, showGrid: state.showGrid, showEmitterShape: state.showEmitterShape })), showInspector && (jsxRuntime.jsx(InspectorPanel, { system: selectedSystem, expandedModules: state.expandedModules, selectedModule: state.selectedModule, onToggleModule: (module) => dispatch({ type: 'TOGGLE_MODULE', module }), onSelectModule: (module) => dispatch({ type: 'SELECT_MODULE', module }), onUpdateSystem: (updates) => {
|
|
518
575
|
if (state.selectedSystemId) {
|
|
519
576
|
dispatch({ type: 'UPDATE_SYSTEM', systemId: state.selectedSystemId, updates });
|
|
520
577
|
}
|