@nice2dev/ui-3d 1.3.15 → 1.3.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cjs/collaborative/collaborativeScene.js +160 -206
  3. package/dist/cjs/core/editorAsk.js +51 -41
  4. package/dist/cjs/core/i18n.js +13 -14
  5. package/dist/cjs/core/threeCompat.js +29 -42
  6. package/dist/cjs/dance/DanceBridge.js +148 -177
  7. package/dist/cjs/dance/DanceScoreEngine.js +209 -221
  8. package/dist/cjs/dance/PoseDetector.js +302 -275
  9. package/dist/cjs/index.js +110 -113
  10. package/dist/cjs/material/MaterialEditor.module.css.js +242 -5
  11. package/dist/cjs/material/NiceMaterialEditor.js +1213 -757
  12. package/dist/cjs/material/materialEditorTypes.js +35 -49
  13. package/dist/cjs/material/materialEditorUtils.js +684 -747
  14. package/dist/cjs/material/materialNodeDefinitions.js +1411 -1459
  15. package/dist/cjs/model/ModelEditor.js +90 -40
  16. package/dist/cjs/model/ModelEditor.module.css.js +257 -5
  17. package/dist/cjs/model/ModelEditorLeftPanel.js +126 -47
  18. package/dist/cjs/model/ModelEditorMenuBar.js +359 -32
  19. package/dist/cjs/model/ModelEditorRightPanel.js +647 -131
  20. package/dist/cjs/model/ModelEditorSubComponents.js +277 -112
  21. package/dist/cjs/model/ModelEditorTimeline.js +232 -34
  22. package/dist/cjs/model/ModelEditorToolbar.js +170 -14
  23. package/dist/cjs/model/ModelEditorViewport.js +231 -39
  24. package/dist/cjs/model/ModelViewer.js +388 -63
  25. package/dist/cjs/model/ModelViewer.module.css.js +77 -5
  26. package/dist/cjs/model/NiceArmatureEditor.js +473 -274
  27. package/dist/cjs/model/NiceMorphTargetEditor.js +333 -227
  28. package/dist/cjs/model/NiceOctree.js +372 -320
  29. package/dist/cjs/model/NicePhysicsSimulation.js +528 -298
  30. package/dist/cjs/model/NiceProceduralGeometry.js +673 -300
  31. package/dist/cjs/model/NiceTerrainEditor.js +595 -385
  32. package/dist/cjs/model/NiceWeightPainter.js +384 -261
  33. package/dist/cjs/model/NiceXRPreview.js +385 -308
  34. package/dist/cjs/model/cadModeUtils.js +103 -106
  35. package/dist/cjs/model/editorShortcuts.js +171 -194
  36. package/dist/cjs/model/modelEditorTypes.js +100 -118
  37. package/dist/cjs/model/modelEditorUtils.js +1061 -1146
  38. package/dist/cjs/model/simsModeUtils.js +1023 -1053
  39. package/dist/cjs/model/useModelEditor.js +1977 -1933
  40. package/dist/cjs/model/useModelViewer.js +633 -665
  41. package/dist/cjs/nice2dev-ui-3d.css +1 -1
  42. package/dist/cjs/particle/NiceParticleEditor.js +1186 -571
  43. package/dist/cjs/particle/ParticleEditor.module.css.js +122 -5
  44. package/dist/cjs/particle/particleEditorTypes.js +62 -70
  45. package/dist/cjs/particle/particleEditorUtils.js +998 -1013
  46. package/dist/cjs/rendering/NiceCascadedShadows.js +381 -259
  47. package/dist/cjs/rendering/NiceRenderExport.js +424 -337
  48. package/dist/cjs/rendering/NiceSSAO.js +454 -337
  49. package/dist/cjs/rendering/NiceSSR.js +387 -261
  50. package/dist/cjs/rendering/NiceWebGPURenderer.js +359 -230
  51. package/dist/cjs/uv/NiceUVEditor.js +787 -550
  52. package/dist/cjs/uv/UVEditor.module.css.js +53 -5
  53. package/dist/cjs/uv/uvEditorTypes.js +59 -76
  54. package/dist/cjs/uv/uvEditorUtils.js +501 -575
  55. package/dist/esm/collaborative/collaborativeScene.js +163 -205
  56. package/dist/esm/core/editorAsk.js +53 -40
  57. package/dist/esm/core/i18n.js +15 -13
  58. package/dist/esm/core/threeCompat.js +18 -26
  59. package/dist/esm/dance/DanceBridge.js +151 -176
  60. package/dist/esm/dance/DanceScoreEngine.js +211 -220
  61. package/dist/esm/dance/PoseDetector.js +304 -274
  62. package/dist/esm/index.js +258 -36
  63. package/dist/esm/material/MaterialEditor.module.css.js +242 -3
  64. package/dist/esm/material/NiceMaterialEditor.js +1215 -756
  65. package/dist/esm/material/materialEditorTypes.js +45 -48
  66. package/dist/esm/material/materialEditorUtils.js +713 -746
  67. package/dist/esm/material/materialNodeDefinitions.js +1415 -1458
  68. package/dist/esm/model/ModelEditor.js +91 -39
  69. package/dist/esm/model/ModelEditor.module.css.js +257 -3
  70. package/dist/esm/model/ModelEditorLeftPanel.js +126 -45
  71. package/dist/esm/model/ModelEditorMenuBar.js +359 -30
  72. package/dist/esm/model/ModelEditorRightPanel.js +634 -114
  73. package/dist/esm/model/ModelEditorSubComponents.js +265 -94
  74. package/dist/esm/model/ModelEditorTimeline.js +232 -32
  75. package/dist/esm/model/ModelEditorToolbar.js +170 -12
  76. package/dist/esm/model/ModelEditorViewport.js +231 -37
  77. package/dist/esm/model/ModelViewer.js +389 -62
  78. package/dist/esm/model/ModelViewer.module.css.js +77 -3
  79. package/dist/esm/model/NiceArmatureEditor.js +462 -258
  80. package/dist/esm/model/NiceMorphTargetEditor.js +322 -211
  81. package/dist/esm/model/NiceOctree.js +361 -304
  82. package/dist/esm/model/NicePhysicsSimulation.js +517 -282
  83. package/dist/esm/model/NiceProceduralGeometry.js +667 -284
  84. package/dist/esm/model/NiceTerrainEditor.js +584 -369
  85. package/dist/esm/model/NiceWeightPainter.js +373 -245
  86. package/dist/esm/model/NiceXRPreview.js +374 -292
  87. package/dist/esm/model/cadModeUtils.js +95 -88
  88. package/dist/esm/model/editorShortcuts.js +172 -193
  89. package/dist/esm/model/modelEditorTypes.js +90 -100
  90. package/dist/esm/model/modelEditorUtils.js +1056 -1128
  91. package/dist/esm/model/simsModeUtils.js +1021 -1035
  92. package/dist/esm/model/useModelEditor.js +1946 -1920
  93. package/dist/esm/model/useModelViewer.js +619 -647
  94. package/dist/esm/nice2dev-ui-3d.css +1 -1
  95. package/dist/esm/particle/NiceParticleEditor.js +1188 -570
  96. package/dist/esm/particle/ParticleEditor.module.css.js +122 -3
  97. package/dist/esm/particle/particleEditorTypes.js +69 -69
  98. package/dist/esm/particle/particleEditorUtils.js +1027 -1012
  99. package/dist/esm/rendering/NiceCascadedShadows.js +370 -243
  100. package/dist/esm/rendering/NiceRenderExport.js +413 -321
  101. package/dist/esm/rendering/NiceSSAO.js +450 -328
  102. package/dist/esm/rendering/NiceSSR.js +383 -252
  103. package/dist/esm/rendering/NiceWebGPURenderer.js +326 -214
  104. package/dist/esm/uv/NiceUVEditor.js +788 -549
  105. package/dist/esm/uv/UVEditor.module.css.js +53 -3
  106. package/dist/esm/uv/uvEditorTypes.js +68 -75
  107. package/dist/esm/uv/uvEditorUtils.js +515 -557
  108. package/package.json +7 -12
@@ -1,192 +1,167 @@
1
- import { useRef, useState, useEffect, useCallback } from 'react';
2
- import { DanceScoreEngine } from './DanceScoreEngine.js';
3
-
4
- /**
5
- * DanceBridge — Connects choreography DSL (ui-graphics) ↔ pose detection (ui-3d) ↔ audio sync (ui-audio)
6
- *
7
- * Orchestrates a dance session: plays audio, runs reference choreography,
8
- * captures live poses, and scores accuracy — all in sync.
9
- */
10
- // ── Bridge engine (non-React) ───────────────────────────────────
1
+ import { useRef, useState, useEffect, useCallback } from "react";
2
+ import { DanceScoreEngine } from "./DanceScoreEngine.js";
11
3
  class DanceBridge {
12
- constructor(config, callbacks = {}) {
13
- this._state = 'idle';
14
- this.startTime = 0;
15
- this.pausedAt = 0;
16
- this.pauseAccum = 0;
17
- this.nextBeatIdx = 0;
18
- this.config = config;
19
- this.callbacks = callbacks;
20
- this.engine = new DanceScoreEngine(config.scoreConfig);
21
- this.engine.loadReference(config.reference);
22
- const frames = config.reference.frames;
23
- this.duration = frames.length > 0 ? frames[frames.length - 1].timestamp_sec : 0;
4
+ constructor(config, callbacks = {}) {
5
+ this._state = "idle";
6
+ this.startTime = 0;
7
+ this.pausedAt = 0;
8
+ this.pauseAccum = 0;
9
+ this.nextBeatIdx = 0;
10
+ this.config = config;
11
+ this.callbacks = callbacks;
12
+ this.engine = new DanceScoreEngine(config.scoreConfig);
13
+ this.engine.loadReference(config.reference);
14
+ const frames = config.reference.frames;
15
+ this.duration = frames.length > 0 ? frames[frames.length - 1].timestamp_sec : 0;
16
+ }
17
+ get state() {
18
+ return this._state;
19
+ }
20
+ get elapsed() {
21
+ if (this._state === "idle" || this._state === "countdown") {
22
+ return 0;
24
23
  }
25
- get state() {
26
- return this._state;
24
+ if (this._state === "paused") {
25
+ return (this.pausedAt - this.startTime - this.pauseAccum) / 1e3;
27
26
  }
28
- get elapsed() {
29
- if (this._state === 'idle' || this._state === 'countdown') {
30
- return 0;
31
- }
32
- if (this._state === 'paused') {
33
- return (this.pausedAt - this.startTime - this.pauseAccum) / 1000;
34
- }
35
- if (this._state === 'finished') {
36
- return this.duration;
37
- }
38
- return (performance.now() - this.startTime - this.pauseAccum) / 1000;
27
+ if (this._state === "finished") {
28
+ return this.duration;
39
29
  }
40
- get combo() {
41
- return this.engine.getResult().combo;
30
+ return (performance.now() - this.startTime - this.pauseAccum) / 1e3;
31
+ }
32
+ get combo() {
33
+ return this.engine.getResult().combo;
34
+ }
35
+ start() {
36
+ const countdownMs = (this.config.countdownSec ?? 3) * 1e3;
37
+ this.setState("countdown");
38
+ setTimeout(() => {
39
+ this.engine.reset();
40
+ this.startTime = performance.now();
41
+ this.pauseAccum = 0;
42
+ this.nextBeatIdx = 0;
43
+ this.setState("playing");
44
+ }, countdownMs);
45
+ }
46
+ pause() {
47
+ if (this._state !== "playing") {
48
+ return;
42
49
  }
43
- start() {
44
- var _a;
45
- const countdownMs = ((_a = this.config.countdownSec) !== null && _a !== void 0 ? _a : 3) * 1000;
46
- this.setState('countdown');
47
- setTimeout(() => {
48
- this.engine.reset();
49
- this.startTime = performance.now();
50
- this.pauseAccum = 0;
51
- this.nextBeatIdx = 0;
52
- this.setState('playing');
53
- }, countdownMs);
50
+ this.pausedAt = performance.now();
51
+ this.setState("paused");
52
+ }
53
+ resume() {
54
+ if (this._state !== "paused") {
55
+ return;
54
56
  }
55
- pause() {
56
- if (this._state !== 'playing') {
57
- return;
58
- }
59
- this.pausedAt = performance.now();
60
- this.setState('paused');
57
+ this.pauseAccum += performance.now() - this.pausedAt;
58
+ this.setState("playing");
59
+ }
60
+ stop() {
61
+ this.setState("finished");
62
+ const result = this.engine.getResult();
63
+ this.callbacks.onFinish?.(result);
64
+ return result;
65
+ }
66
+ feedFrame(frame) {
67
+ if (this._state !== "playing") {
68
+ return null;
61
69
  }
62
- resume() {
63
- if (this._state !== 'paused') {
64
- return;
65
- }
66
- this.pauseAccum += performance.now() - this.pausedAt;
67
- this.setState('playing');
68
- }
69
- stop() {
70
- var _a, _b;
71
- this.setState('finished');
72
- const result = this.engine.getResult();
73
- (_b = (_a = this.callbacks).onFinish) === null || _b === void 0 ? void 0 : _b.call(_a, result);
74
- return result;
70
+ const elapsed = this.elapsed;
71
+ const offset = this.config.beatSync?.offsetSec ?? 0;
72
+ const adjustedFrame = {
73
+ ...frame,
74
+ timestamp_sec: elapsed + offset
75
+ };
76
+ this.checkBeats(elapsed);
77
+ if (this.duration > 0) {
78
+ this.callbacks.onProgress?.(Math.min(elapsed / this.duration, 1));
75
79
  }
76
- feedFrame(frame) {
77
- var _a, _b, _c, _d, _e, _f;
78
- if (this._state !== 'playing') {
79
- return null;
80
- }
81
- const elapsed = this.elapsed;
82
- const offset = (_b = (_a = this.config.beatSync) === null || _a === void 0 ? void 0 : _a.offsetSec) !== null && _b !== void 0 ? _b : 0;
83
- const adjustedFrame = {
84
- ...frame,
85
- timestamp_sec: elapsed + offset,
86
- };
87
- // Check for beats
88
- this.checkBeats(elapsed);
89
- // Report progress
90
- if (this.duration > 0) {
91
- (_d = (_c = this.callbacks).onProgress) === null || _d === void 0 ? void 0 : _d.call(_c, Math.min(elapsed / this.duration, 1));
92
- }
93
- // Score
94
- const score = this.engine.scoreFrame(adjustedFrame);
95
- (_f = (_e = this.callbacks).onScore) === null || _f === void 0 ? void 0 : _f.call(_e, score);
96
- // Auto-finish at end of reference
97
- if (elapsed >= this.duration) {
98
- this.stop();
99
- }
100
- return score;
80
+ const score = this.engine.scoreFrame(adjustedFrame);
81
+ this.callbacks.onScore?.(score);
82
+ if (elapsed >= this.duration) {
83
+ this.stop();
101
84
  }
102
- checkBeats(elapsed) {
103
- var _a, _b, _c;
104
- const beats = (_a = this.config.beatSync) === null || _a === void 0 ? void 0 : _a.beats;
105
- if (!beats) {
106
- return;
107
- }
108
- while (this.nextBeatIdx < beats.length && beats[this.nextBeatIdx] <= elapsed) {
109
- (_c = (_b = this.callbacks).onBeat) === null || _c === void 0 ? void 0 : _c.call(_b, this.nextBeatIdx, beats[this.nextBeatIdx]);
110
- this.nextBeatIdx++;
111
- }
85
+ return score;
86
+ }
87
+ checkBeats(elapsed) {
88
+ const beats = this.config.beatSync?.beats;
89
+ if (!beats) {
90
+ return;
112
91
  }
113
- setState(state) {
114
- var _a, _b;
115
- this._state = state;
116
- (_b = (_a = this.callbacks).onStateChange) === null || _b === void 0 ? void 0 : _b.call(_a, state);
92
+ while (this.nextBeatIdx < beats.length && beats[this.nextBeatIdx] <= elapsed) {
93
+ this.callbacks.onBeat?.(this.nextBeatIdx, beats[this.nextBeatIdx]);
94
+ this.nextBeatIdx++;
117
95
  }
96
+ }
97
+ setState(state) {
98
+ this._state = state;
99
+ this.callbacks.onStateChange?.(state);
100
+ }
118
101
  }
119
- // ── React hook: useDanceBridge ──────────────────────────────────
120
102
  function useDanceBridge(config, callbacks) {
121
- const bridgeRef = useRef(null);
122
- const [state, setState] = useState('idle');
123
- const [lastScore, setLastScore] = useState(null);
124
- const [result, setResult] = useState(null);
125
- const [combo, setCombo] = useState(0);
126
- const [progress, setProgress] = useState(0);
127
- useEffect(() => {
128
- if (!config) {
129
- bridgeRef.current = null;
130
- return;
131
- }
132
- bridgeRef.current = new DanceBridge(config, {
133
- ...callbacks,
134
- onStateChange(s) {
135
- var _a;
136
- setState(s);
137
- (_a = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onStateChange) === null || _a === void 0 ? void 0 : _a.call(callbacks, s);
138
- },
139
- onScore(score) {
140
- var _a;
141
- setLastScore(score);
142
- (_a = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onScore) === null || _a === void 0 ? void 0 : _a.call(callbacks, score);
143
- },
144
- onFinish(r) {
145
- var _a;
146
- setResult(r);
147
- (_a = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onFinish) === null || _a === void 0 ? void 0 : _a.call(callbacks, r);
148
- },
149
- onProgress(p) {
150
- var _a;
151
- setProgress(p);
152
- (_a = callbacks === null || callbacks === void 0 ? void 0 : callbacks.onProgress) === null || _a === void 0 ? void 0 : _a.call(callbacks, p);
153
- },
154
- });
155
- return () => {
156
- bridgeRef.current = null;
157
- };
158
- // eslint-disable-next-line react-hooks/exhaustive-deps
159
- }, [config]);
160
- const start = useCallback(() => {
161
- var _a;
162
- (_a = bridgeRef.current) === null || _a === void 0 ? void 0 : _a.start();
163
- }, []);
164
- const pause = useCallback(() => {
165
- var _a;
166
- (_a = bridgeRef.current) === null || _a === void 0 ? void 0 : _a.pause();
167
- }, []);
168
- const resume = useCallback(() => {
169
- var _a;
170
- (_a = bridgeRef.current) === null || _a === void 0 ? void 0 : _a.resume();
171
- }, []);
172
- const stop = useCallback(() => { var _a, _b; return (_b = (_a = bridgeRef.current) === null || _a === void 0 ? void 0 : _a.stop()) !== null && _b !== void 0 ? _b : null; }, []);
173
- const feedFrame = useCallback((frame) => {
174
- var _a, _b;
175
- const score = (_b = (_a = bridgeRef.current) === null || _a === void 0 ? void 0 : _a.feedFrame(frame)) !== null && _b !== void 0 ? _b : null;
176
- if (bridgeRef.current) {
177
- setCombo(bridgeRef.current.combo);
178
- }
179
- return score;
180
- }, []);
181
- return { start, pause, resume, stop, feedFrame, state, lastScore, result, combo, progress };
103
+ const bridgeRef = useRef(null);
104
+ const [state, setState] = useState("idle");
105
+ const [lastScore, setLastScore] = useState(null);
106
+ const [result, setResult] = useState(null);
107
+ const [combo, setCombo] = useState(0);
108
+ const [progress, setProgress] = useState(0);
109
+ useEffect(() => {
110
+ if (!config) {
111
+ bridgeRef.current = null;
112
+ return;
113
+ }
114
+ bridgeRef.current = new DanceBridge(config, {
115
+ ...callbacks,
116
+ onStateChange(s) {
117
+ setState(s);
118
+ callbacks?.onStateChange?.(s);
119
+ },
120
+ onScore(score) {
121
+ setLastScore(score);
122
+ callbacks?.onScore?.(score);
123
+ },
124
+ onFinish(r) {
125
+ setResult(r);
126
+ callbacks?.onFinish?.(r);
127
+ },
128
+ onProgress(p) {
129
+ setProgress(p);
130
+ callbacks?.onProgress?.(p);
131
+ }
132
+ });
133
+ return () => {
134
+ bridgeRef.current = null;
135
+ };
136
+ }, [config]);
137
+ const start = useCallback(() => {
138
+ bridgeRef.current?.start();
139
+ }, []);
140
+ const pause = useCallback(() => {
141
+ bridgeRef.current?.pause();
142
+ }, []);
143
+ const resume = useCallback(() => {
144
+ bridgeRef.current?.resume();
145
+ }, []);
146
+ const stop = useCallback(() => bridgeRef.current?.stop() ?? null, []);
147
+ const feedFrame = useCallback((frame) => {
148
+ const score = bridgeRef.current?.feedFrame(frame) ?? null;
149
+ if (bridgeRef.current) {
150
+ setCombo(bridgeRef.current.combo);
151
+ }
152
+ return score;
153
+ }, []);
154
+ return { start, pause, resume, stop, feedFrame, state, lastScore, result, combo, progress };
182
155
  }
183
- // ── Utility: Convert @nice2dev/ui-audio RhythmResponse to BeatSync ──
184
156
  function rhythmToBeatSync(rhythm, offsetSec = 0) {
185
- return {
186
- bpm: rhythm.tempoBpm,
187
- beats: rhythm.beatsSeconds,
188
- offsetSec,
189
- };
157
+ return {
158
+ bpm: rhythm.tempoBpm,
159
+ beats: rhythm.beatsSeconds,
160
+ offsetSec
161
+ };
190
162
  }
191
-
192
- export { DanceBridge, rhythmToBeatSync, useDanceBridge };
163
+ export {
164
+ DanceBridge,
165
+ rhythmToBeatSync,
166
+ useDanceBridge
167
+ };