@nice2dev/ui-3d 1.1.9 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +76 -0
- package/README.md +11 -15
- package/dist/cjs/core/threeCompat.js +52 -0
- package/dist/cjs/dance/PoseDetector.js +112 -62
- package/dist/cjs/index.js +0 -3
- package/dist/cjs/model/ModelEditor.js +0 -3
- package/dist/cjs/model/ModelViewer.js +0 -3
- package/dist/cjs/model/NiceArmatureEditor.js +2 -2
- package/dist/cjs/model/NicePhysicsSimulation.js +1 -1
- package/dist/cjs/model/NiceTerrainEditor.js +2 -2
- package/dist/cjs/model/NiceWeightPainter.js +2 -2
- package/dist/cjs/model/NiceXRPreview.js +3 -3
- package/dist/cjs/model/useModelEditor.js +8 -3
- package/dist/cjs/model/useModelViewer.js +13 -9
- package/dist/cjs/rendering/NiceRenderExport.js +2 -2
- package/dist/cjs/rendering/NiceWebGPURenderer.js +3 -2
- package/dist/esm/core/threeCompat.js +30 -0
- package/dist/esm/dance/PoseDetector.js +114 -63
- package/dist/esm/index.js +3 -3
- package/dist/esm/model/ModelEditor.js +1 -3
- package/dist/esm/model/ModelViewer.js +1 -3
- package/dist/esm/model/NiceArmatureEditor.js +3 -3
- package/dist/esm/model/NicePhysicsSimulation.js +1 -1
- package/dist/esm/model/NiceTerrainEditor.js +2 -2
- package/dist/esm/model/NiceWeightPainter.js +2 -2
- package/dist/esm/model/NiceXRPreview.js +3 -3
- package/dist/esm/model/useModelEditor.js +8 -3
- package/dist/esm/model/useModelViewer.js +13 -9
- package/dist/esm/rendering/NiceRenderExport.js +2 -2
- package/dist/esm/rendering/NiceWebGPURenderer.js +3 -2
- package/dist/types/core/threeCompat.d.ts +14 -0
- package/dist/types/dance/PoseDetector.d.ts +14 -13
- package/dist/types/index.d.ts +4 -4
- package/dist/types/model/ModelEditor.d.ts +0 -4
- package/dist/types/model/ModelViewer.d.ts +0 -4
- package/package.json +3 -3
|
@@ -21,6 +21,7 @@ import { STLLoader } from 'three/examples/jsm/loaders/STLLoader.js';
|
|
|
21
21
|
import { SVGLoader } from 'three/examples/jsm/loaders/SVGLoader.js';
|
|
22
22
|
import { TDSLoader } from 'three/examples/jsm/loaders/TDSLoader.js';
|
|
23
23
|
import { VTKLoader } from 'three/examples/jsm/loaders/VTKLoader.js';
|
|
24
|
+
import { createFrameClock, SOFT_SHADOW_MAP } from '../core/threeCompat.js';
|
|
24
25
|
import { SUPPORTED_EXTENSIONS, pose3dToClip } from './modelEditorTypes.js';
|
|
25
26
|
import { UndoRedoStack, createMaterialFromPreset, generateLOD, convertToInstanced, applyHDRIPreset, snapMulti, HDRI_PRESETS, PBR_PRESETS } from './modelEditorUtils.js';
|
|
26
27
|
|
|
@@ -52,6 +53,7 @@ function findNodeById(nodes, id) {
|
|
|
52
53
|
Hook
|
|
53
54
|
═══════════════════════════════════════════ */
|
|
54
55
|
function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
|
|
56
|
+
var _a;
|
|
55
57
|
/* ── refs ── */
|
|
56
58
|
const mountRef = useRef(null);
|
|
57
59
|
const rendererRef = useRef(null);
|
|
@@ -59,7 +61,9 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
|
|
|
59
61
|
const cameraRef = useRef(new THREE.PerspectiveCamera(50, 1, 0.01, 10000));
|
|
60
62
|
const orbitRef = useRef(null);
|
|
61
63
|
const transformRef = useRef(null);
|
|
62
|
-
|
|
64
|
+
// Created once: useRef's argument runs on every render, and three r183 warns per Clock.
|
|
65
|
+
const clockRef = useRef(null);
|
|
66
|
+
(_a = clockRef.current) !== null && _a !== void 0 ? _a : (clockRef.current = createFrameClock());
|
|
63
67
|
const mixerRef = useRef(null);
|
|
64
68
|
const rafRef = useRef(0);
|
|
65
69
|
const fileInputRef = useRef(null);
|
|
@@ -139,7 +143,7 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
|
|
|
139
143
|
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: false });
|
|
140
144
|
renderer.setPixelRatio(window.devicePixelRatio);
|
|
141
145
|
renderer.shadowMap.enabled = true;
|
|
142
|
-
renderer.shadowMap.type =
|
|
146
|
+
renderer.shadowMap.type = SOFT_SHADOW_MAP;
|
|
143
147
|
renderer.toneMapping = THREE.ACESFilmicToneMapping;
|
|
144
148
|
renderer.toneMappingExposure = 1.2;
|
|
145
149
|
renderer.outputColorSpace = THREE.SRGBColorSpace;
|
|
@@ -222,8 +226,9 @@ function useModelEditor({ onSaveToLibrary, onAIPoseVideo, }) {
|
|
|
222
226
|
onResize();
|
|
223
227
|
// Animation loop
|
|
224
228
|
const animate = () => {
|
|
229
|
+
var _a, _b;
|
|
225
230
|
rafRef.current = requestAnimationFrame(animate);
|
|
226
|
-
const dt = clockRef.current.getDelta();
|
|
231
|
+
const dt = (_b = (_a = clockRef.current) === null || _a === void 0 ? void 0 : _a.getDelta()) !== null && _b !== void 0 ? _b : 0;
|
|
227
232
|
orbit.update();
|
|
228
233
|
// Update mixer
|
|
229
234
|
if (mixerRef.current && isPlayingRef.current) {
|
|
@@ -8,6 +8,7 @@ import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
|
|
|
8
8
|
import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader.js';
|
|
9
9
|
import { PLYLoader } from 'three/examples/jsm/loaders/PLYLoader.js';
|
|
10
10
|
import { STLLoader } from 'three/examples/jsm/loaders/STLLoader.js';
|
|
11
|
+
import { createFrameClock, SOFT_SHADOW_MAP } from '../core/threeCompat.js';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* useModelViewer — lightweight hook for the view-only 3D model viewer.
|
|
@@ -39,6 +40,7 @@ const TONE_MAP = {
|
|
|
39
40
|
Hook
|
|
40
41
|
═══════════════════════════════════════════ */
|
|
41
42
|
function useModelViewer(props = {}) {
|
|
43
|
+
var _a;
|
|
42
44
|
const { src, format, navigationMode: initNavMode = 'orbit', quality = 'high', autoRotateSpeed: initAutoRotate = 0, backgroundColor = 'var(--nice-bg, #1a1a2e)', showGrid: initShowGrid = true, shadows = true, gamepad = false, cameraPresets: _cameraPresets = [], annotations: _annotations = [], hotspots: _hotspots = [], floorPlans: _floorPlans = [], onHotspotClick: _onHotspotClick, onAnnotationClick: _onAnnotationClick, onLoadProgress, onLoad, onError, clippingPlanes = [], measureMode: initMeasureMode = false, measurements: _measurements = [], onMeasure: _onMeasure, minDistance = 0.1, maxDistance = 1000, fov = 50, vr: _vr = false, walkSpeed = 5, ambientIntensity = 0.5, directionalIntensity = 0.8, antiAlias = true, toneMapping = 'aces', exposure = 1, } = props;
|
|
43
45
|
/* ── refs ── */
|
|
44
46
|
const mountRef = useRef(null);
|
|
@@ -46,7 +48,9 @@ function useModelViewer(props = {}) {
|
|
|
46
48
|
const sceneRef = useRef(new THREE.Scene());
|
|
47
49
|
const cameraRef = useRef(new THREE.PerspectiveCamera(fov, 1, 0.01, 10000));
|
|
48
50
|
const orbitRef = useRef(null);
|
|
49
|
-
|
|
51
|
+
// Created once: useRef's argument runs on every render, and three r183 warns per Clock.
|
|
52
|
+
const clockRef = useRef(null);
|
|
53
|
+
(_a = clockRef.current) !== null && _a !== void 0 ? _a : (clockRef.current = createFrameClock());
|
|
50
54
|
const mixerRef = useRef(null);
|
|
51
55
|
const rafRef = useRef(0);
|
|
52
56
|
const rootRef = useRef(null);
|
|
@@ -102,7 +106,7 @@ function useModelViewer(props = {}) {
|
|
|
102
106
|
renderer.outputColorSpace = THREE.SRGBColorSpace;
|
|
103
107
|
if (shadows) {
|
|
104
108
|
renderer.shadowMap.enabled = true;
|
|
105
|
-
renderer.shadowMap.type =
|
|
109
|
+
renderer.shadowMap.type = SOFT_SHADOW_MAP;
|
|
106
110
|
}
|
|
107
111
|
mount.appendChild(renderer.domElement);
|
|
108
112
|
rendererRef.current = renderer;
|
|
@@ -156,20 +160,20 @@ function useModelViewer(props = {}) {
|
|
|
156
160
|
ro.observe(mount);
|
|
157
161
|
// Animation loop
|
|
158
162
|
const animate = () => {
|
|
159
|
-
var _a, _b, _c, _d, _e;
|
|
163
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
160
164
|
if (disposeRef.current) {
|
|
161
165
|
return;
|
|
162
166
|
}
|
|
163
167
|
rafRef.current = requestAnimationFrame(animate);
|
|
164
|
-
const dt = clockRef.current.getDelta();
|
|
168
|
+
const dt = (_b = (_a = clockRef.current) === null || _a === void 0 ? void 0 : _a.getDelta()) !== null && _b !== void 0 ? _b : 0;
|
|
165
169
|
// Gamepad FPS-style nav
|
|
166
170
|
if (gamepad && navMode === 'fps') {
|
|
167
|
-
const pads = (
|
|
168
|
-
const gp = (
|
|
171
|
+
const pads = (_c = navigator.getGamepads) === null || _c === void 0 ? void 0 : _c.call(navigator);
|
|
172
|
+
const gp = (_d = pads === null || pads === void 0 ? void 0 : pads[0]) !== null && _d !== void 0 ? _d : null;
|
|
169
173
|
if (gp) {
|
|
170
|
-
const lx = (
|
|
171
|
-
const ly = (
|
|
172
|
-
const rx = (
|
|
174
|
+
const lx = (_e = gp.axes[0]) !== null && _e !== void 0 ? _e : 0;
|
|
175
|
+
const ly = (_f = gp.axes[1]) !== null && _f !== void 0 ? _f : 0;
|
|
176
|
+
const rx = (_g = gp.axes[2]) !== null && _g !== void 0 ? _g : 0;
|
|
173
177
|
const fwd = new THREE.Vector3();
|
|
174
178
|
camera.getWorldDirection(fwd);
|
|
175
179
|
fwd.y = 0;
|
|
@@ -320,13 +320,13 @@ const NiceRenderExport = ({ renderer, scene, camera, className = '', }) => {
|
|
|
320
320
|
? 'var(--nice-color-accent, #6366f1)'
|
|
321
321
|
: 'transparent',
|
|
322
322
|
color: config.width === p.width && config.height === p.height
|
|
323
|
-
? 'var(--nice-
|
|
323
|
+
? 'var(--nice-color-white, #fff)'
|
|
324
324
|
: 'inherit',
|
|
325
325
|
}, children: p.label }, p.label))) }), jsxs("div", { style: { display: 'flex', gap: 4, alignItems: 'center' }, children: [jsx("input", { type: "number", value: config.width, min: 1, max: 8192, onChange: (e) => setConfig({ width: parseInt(e.target.value, 10) || 1 }), style: { width: 70, padding: '3px 6px' } }), jsx("span", { children: "\u00D7" }), jsx("input", { type: "number", value: config.height, min: 1, max: 8192, onChange: (e) => setConfig({ height: parseInt(e.target.value, 10) || 1 }), style: { width: 70, padding: '3px 6px' } })] }), jsxs("label", { children: ["Format:", jsxs("select", { value: config.format, onChange: (e) => setConfig({ format: e.target.value }), style: { width: '100%', marginTop: 2 }, children: [jsx("option", { value: "png", children: "PNG (lossless + alpha)" }), jsx("option", { value: "jpeg", children: "JPEG (lossy, no alpha)" }), jsx("option", { value: "exr", children: "EXR (HDR float)" })] })] }), jsxs("label", { children: ["Background:", jsxs("select", { value: config.backgroundMode, onChange: (e) => setConfig({ backgroundMode: e.target.value }), style: { width: '100%', marginTop: 2 }, children: [jsx("option", { value: "transparent", children: "Transparent" }), jsx("option", { value: "color", children: "Solid Color" }), jsx("option", { value: "scene", children: "Scene Background" })] })] }), config.backgroundMode === 'color' && (jsxs("label", { style: { display: 'flex', alignItems: 'center', gap: 6 }, children: ["Color:", jsx("input", { type: "color", value: config.backgroundColor, onChange: (e) => setConfig({ backgroundColor: e.target.value }) })] })), jsxs("label", { children: ["Supersampling: ", config.samples, "x", jsxs("select", { value: config.samples, onChange: (e) => setConfig({ samples: parseInt(e.target.value, 10) }), style: { width: '100%', marginTop: 2 }, children: [jsx("option", { value: 1, children: "1x (none)" }), jsx("option", { value: 2, children: "2x" }), jsx("option", { value: 4, children: "4x (best quality)" })] })] }), jsx("button", { type: "button", onClick: handleRender, disabled: isRendering, style: {
|
|
326
326
|
background: isRendering
|
|
327
327
|
? 'var(--nice-bg-tertiary, #94a3b8)'
|
|
328
328
|
: 'var(--nice-color-accent, #6366f1)',
|
|
329
|
-
color: 'var(--nice-
|
|
329
|
+
color: 'var(--nice-color-white, #fff)',
|
|
330
330
|
border: 'none',
|
|
331
331
|
borderRadius: 4,
|
|
332
332
|
padding: '8px 12px',
|
|
@@ -2,6 +2,7 @@ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
|
2
2
|
import { NiceIcon } from '@nice2dev/ui';
|
|
3
3
|
import { useState, useRef, useEffect, useCallback } from 'react';
|
|
4
4
|
import * as THREE from 'three';
|
|
5
|
+
import { SOFT_SHADOW_MAP } from '../core/threeCompat.js';
|
|
5
6
|
|
|
6
7
|
/* ── WebGPU detection ── */
|
|
7
8
|
async function detectWebGPU() {
|
|
@@ -116,7 +117,7 @@ function useWebGPURenderer(canvas, scene, camera, width = 800, height = 600, onR
|
|
|
116
117
|
r.toneMappingExposure = toneMappingExposure;
|
|
117
118
|
r.outputColorSpace = outputColorSpace;
|
|
118
119
|
r.shadowMap.enabled = true;
|
|
119
|
-
r.shadowMap.type =
|
|
120
|
+
r.shadowMap.type = SOFT_SHADOW_MAP;
|
|
120
121
|
rendererRef.current = r;
|
|
121
122
|
setRenderer(r);
|
|
122
123
|
setIsWebGPU(usingWebGPU);
|
|
@@ -214,7 +215,7 @@ const NiceWebGPURenderer = ({ canvas, scene, camera, width, height, onRendererRe
|
|
|
214
215
|
padding: '2px 6px',
|
|
215
216
|
borderRadius: 4,
|
|
216
217
|
background: isWebGPU ? 'var(--nice-success, #22c55e)' : 'var(--nice-warning, #f59e0b)',
|
|
217
|
-
color: 'var(--nice-
|
|
218
|
+
color: 'var(--nice-color-white, #fff)',
|
|
218
219
|
}, children: isWebGPU ? 'WebGPU' : 'WebGL' })] }), !isReady && jsx("div", { style: { opacity: 0.6, fontSize: 11 }, children: "Initializing\u2026" }), capabilities && (jsxs("div", { style: { fontSize: 10, opacity: 0.7, lineHeight: 1.5 }, children: ["GPU: ", capabilities.adapterName, jsx("br", {}), "Vendor: ", capabilities.vendor, jsx("br", {}), "Max Texture: ", capabilities.maxTextureDimension2D, "px", capabilities.features.length > 0 && (jsxs(Fragment, { children: [jsx("br", {}), "Features: ", capabilities.features.length] }))] })), jsxs("label", { children: ["Tone Mapping:", jsx("select", { value: toneMapping, onChange: (e) => setToneMapping(parseInt(e.target.value, 10)), style: { width: '100%', marginTop: 2 }, children: TONE_MAPPINGS.map((tm) => (jsx("option", { value: tm.value, children: tm.label }, tm.value))) })] }), jsxs("label", { children: ["Exposure: ", toneMappingExposure.toFixed(2), jsx("input", { type: "range", min: 0.1, max: 3, step: 0.05, value: toneMappingExposure, onChange: (e) => setToneMappingExposure(parseFloat(e.target.value)), style: { width: '100%' } })] }), jsxs("label", { children: ["Output Color Space:", jsxs("select", { value: outputColorSpace, onChange: (e) => setOutputColorSpace(e.target.value), style: { width: '100%', marginTop: 2 }, children: [jsx("option", { value: THREE.SRGBColorSpace, children: "sRGB" }), jsx("option", { value: THREE.LinearSRGBColorSpace, children: "Linear sRGB" })] })] }), jsxs("label", { children: ["Pixel Ratio: ", pixelRatio.toFixed(1), jsx("input", { type: "range", min: 0.5, max: 3, step: 0.5, value: pixelRatio, onChange: (e) => setPixelRatio(parseFloat(e.target.value)), style: { width: '100%' } })] })] }));
|
|
219
220
|
};
|
|
220
221
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* three.js r183 deprecated `Clock` (for `Timer`) and folds `PCFSoftShadowMap` into
|
|
3
|
+
* `PCFShadowMap`; both log a console warning there. The peer range starts at r150, which has
|
|
4
|
+
* neither `Timer` in its core nor the softer `PCFShadowMap`, so the choice follows the revision.
|
|
5
|
+
*/
|
|
6
|
+
import * as THREE from 'three';
|
|
7
|
+
/** Soft shadows without the r183 deprecation warning; older three keeps `PCFSoftShadowMap`. */
|
|
8
|
+
export declare const SOFT_SHADOW_MAP: THREE.ShadowMapType;
|
|
9
|
+
/** Seconds since the previous call — what an animation loop feeds its mixer. */
|
|
10
|
+
export interface FrameClock {
|
|
11
|
+
getDelta(): number;
|
|
12
|
+
}
|
|
13
|
+
/** `Timer` where three has deprecated `Clock`, `Clock` before. */
|
|
14
|
+
export declare function createFrameClock(): FrameClock;
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { Pose3DFrame } from '../model/modelEditorTypes';
|
|
2
|
+
import type { PosePerson3D, Pose3DFrame } from '../model/modelEditorTypes';
|
|
3
3
|
export type PoseBackend = 'mediapipe' | 'tfjs';
|
|
4
|
+
/**
|
|
5
|
+
* Finds the people in one video frame; the model is yours — TF.js pose-detection (MoveNet,
|
|
6
|
+
* BlazePose), MediaPipe Pose Landmarker… Return keypoints in video pixels, named as in COCO-17
|
|
7
|
+
* (`nose`, `left_shoulder`, `right_ankle`, …): the overlay connects them by name. It may be
|
|
8
|
+
* async; the next detection waits for it.
|
|
9
|
+
*/
|
|
10
|
+
export type NicePoseDetectorFn = (video: HTMLVideoElement, timestampMs: number) => PosePerson3D[] | Promise<PosePerson3D[]>;
|
|
4
11
|
export interface NicePoseDetectorConfig {
|
|
5
|
-
/**
|
|
12
|
+
/** Finds the poses in each frame. Without it the camera runs, but nothing is detected. */
|
|
13
|
+
detector?: NicePoseDetectorFn;
|
|
14
|
+
/** Which backend your `detector` uses — informational; the component loads no model. */
|
|
6
15
|
backend?: PoseBackend;
|
|
7
16
|
/** Maximum number of persons to track */
|
|
8
17
|
maxPersons?: number;
|
|
@@ -17,8 +26,6 @@ export interface NicePoseDetectorConfig {
|
|
|
17
26
|
/** Show confidence dots on keypoints */
|
|
18
27
|
showConfidence?: boolean;
|
|
19
28
|
}
|
|
20
|
-
/** @deprecated Use NicePoseDetectorConfig */
|
|
21
|
-
export type PoseDetectorConfig = NicePoseDetectorConfig;
|
|
22
29
|
export interface NicePoseDetectorHandle {
|
|
23
30
|
/** Start detection */
|
|
24
31
|
start(): void;
|
|
@@ -29,8 +36,6 @@ export interface NicePoseDetectorHandle {
|
|
|
29
36
|
/** Check if actively detecting */
|
|
30
37
|
readonly isDetecting: boolean;
|
|
31
38
|
}
|
|
32
|
-
/** @deprecated Use NicePoseDetectorHandle */
|
|
33
|
-
export type PoseDetectorHandle = NicePoseDetectorHandle;
|
|
34
39
|
export interface NicePoseDetectorProps extends NicePoseDetectorConfig {
|
|
35
40
|
/** Called each frame with detected poses */
|
|
36
41
|
onFrame?: (frame: Pose3DFrame) => void;
|
|
@@ -38,7 +43,7 @@ export interface NicePoseDetectorProps extends NicePoseDetectorConfig {
|
|
|
38
43
|
onStart?: () => void;
|
|
39
44
|
/** Called when detection stops */
|
|
40
45
|
onStop?: () => void;
|
|
41
|
-
/** Called
|
|
46
|
+
/** Called when the camera cannot start or the detector fails (detection then stops) */
|
|
42
47
|
onError?: (error: Error) => void;
|
|
43
48
|
/** CSS class for the container */
|
|
44
49
|
className?: string;
|
|
@@ -49,14 +54,10 @@ export interface NicePoseDetectorProps extends NicePoseDetectorConfig {
|
|
|
49
54
|
/** Height of the video feed */
|
|
50
55
|
height?: number;
|
|
51
56
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
export declare function usePoseDetection(config?: PoseDetectorConfig): {
|
|
55
|
-
start: (video: HTMLVideoElement, onFrame?: (frame: Pose3DFrame) => void) => Promise<void>;
|
|
57
|
+
export declare function usePoseDetection(config?: NicePoseDetectorConfig): {
|
|
58
|
+
start: (video: HTMLVideoElement, onFrame?: (frame: Pose3DFrame) => void, onError?: (error: Error) => void) => Promise<void>;
|
|
56
59
|
stop: () => void;
|
|
57
60
|
isDetecting: boolean;
|
|
58
61
|
getLatestFrame: () => Pose3DFrame | null;
|
|
59
62
|
};
|
|
60
63
|
export declare const NicePoseDetector: React.ForwardRefExoticComponent<NicePoseDetectorProps & React.RefAttributes<NicePoseDetectorHandle>>;
|
|
61
|
-
/** @deprecated Use NicePoseDetector */
|
|
62
|
-
export declare const PoseDetector: React.ForwardRefExoticComponent<NicePoseDetectorProps & React.RefAttributes<NicePoseDetectorHandle>>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
* @nice2dev/ui-3d — Public API
|
|
3
3
|
*
|
|
4
4
|
* Tree-shakeable exports. Import only what you need:
|
|
5
|
-
* import {
|
|
5
|
+
* import { NiceModelEditor } from '@nice2dev/ui-3d';
|
|
6
6
|
* import { NiceI18nProvider } from '@nice2dev/ui-3d';
|
|
7
7
|
*/
|
|
8
|
-
export { NiceModelEditor,
|
|
9
|
-
export { NiceModelViewer,
|
|
8
|
+
export { NiceModelEditor, type NiceModelEditorProps } from './model/ModelEditor';
|
|
9
|
+
export { NiceModelViewer, type NiceModelViewerProps } from './model/ModelViewer';
|
|
10
10
|
export { type CADTool, type CADSnapMode, type CADUnit, type CADGridConfig, type WallSegment, type WallOpening, type FloorPlan, type RoomDefinition, type RoomType, type StairConfig, type Annotation, type CADSettings, type DXFEntity, DEFAULT_CAD_SETTINGS, UNIT_SCALES, ROOM_COLORS, WALL_MATERIALS, FLOOR_MATERIALS, createCADGrid, snapToCADGrid, } from './model/cadModeUtils';
|
|
11
11
|
export { type FurnitureCategory, type FurnitureItem, type PlacedFurniture, type RoomLayout, type SimsTool, type SimsState, FURNITURE_CATALOG, FURNITURE_CATEGORIES, ROOM_PRESETS, createFurnitureMesh, placeFurnitureInScene, removeFurnitureFromScene, rotatePlacedItem, resizePlacedItem, createDragPreview, getFloorIntersection, checkFurnitureCollision, applyRoomLayout, calculateBudget, } from './model/simsModeUtils';
|
|
12
12
|
export { useModelEditor } from './model/useModelEditor';
|
|
@@ -15,7 +15,7 @@ export { NiceI18nProvider, useNiceTranslation, type NiceTranslateFn, type NiceI1
|
|
|
15
15
|
export { UndoRedoStack, type UndoAction, PBR_PRESETS, type PBRPreset, applyPBRPreset, createMaterialFromPreset, generateLOD, type LODLevel, convertToInstanced, countTriangles, computeSceneBounds, measureDistance, measureAngle, type Measurement, HDRI_PRESETS, type HDRIPreset, applyHDRIPreset, snapToGrid, snapToVertex, snapToEdge, snapMulti, type SnapTarget, type SnapResult, evaluateTrack, setKeyframe, removeKeyframe, toThreeKeyframeTrack, createAnimationClip, type Keyframe, type KeyframeTrack, downloadBlob, exportSceneGLTF, exportSceneUSDZ, type ExportOptions, crossfadeAnimations, makeAdditiveAction, blendAnimations, subclip, type AnimationBlendConfig, solveIKChain, type IKChain, createViewportCamera, renderMultiViewport, QUAD_VIEWPORT, type ViewportPreset, type ViewportConfig, } from './model/modelEditorUtils';
|
|
16
16
|
export { EditorShortcutManager, type EditorShortcut, type EditorShortcutBinding, type EditorShortcutConfig, } from './model/editorShortcuts';
|
|
17
17
|
export type { Pose3DSequenceResult, Pose3DFrame, PosePerson3D, PoseKeypoint3D, SceneNode, AnimClip, TransformMode, ShadingMode, EditorMode, } from './model/modelEditorTypes';
|
|
18
|
-
export { NicePoseDetector,
|
|
18
|
+
export { NicePoseDetector, usePoseDetection, type NicePoseDetectorProps, type NicePoseDetectorHandle, type NicePoseDetectorConfig, type NicePoseDetectorFn, type PoseBackend, } from './dance/PoseDetector';
|
|
19
19
|
export { DanceScoreEngine, useDanceScore, type DanceScoreConfig, type FrameScore, type DanceSessionResult, type HitRating, type KeypointScore, } from './dance/DanceScoreEngine';
|
|
20
20
|
export { DanceBridge, useDanceBridge, rhythmToBeatSync, type DanceBridgeConfig, type DanceBridgeCallbacks, type DanceBridgeHandle, type DanceSessionState, type BeatSync, } from './dance/DanceBridge';
|
|
21
21
|
export { NiceUVEditor, type NiceUVEditorProps } from './uv/NiceUVEditor';
|
|
@@ -13,9 +13,5 @@ export interface NiceModelEditorProps {
|
|
|
13
13
|
/** Optional AI pose-from-video callback. If omitted the AI video button is hidden. */
|
|
14
14
|
onAIPoseVideo?: (file: File) => Promise<import('./modelEditorTypes').Pose3DSequenceResult>;
|
|
15
15
|
}
|
|
16
|
-
/** @deprecated Use NiceModelEditorProps */
|
|
17
|
-
export type ModelEditorProps = NiceModelEditorProps;
|
|
18
16
|
export declare const NiceModelEditor: React.FC<NiceModelEditorProps>;
|
|
19
|
-
/** @deprecated Use NiceModelEditor */
|
|
20
|
-
export declare const ModelEditor: React.FC<NiceModelEditorProps>;
|
|
21
17
|
export default NiceModelEditor;
|
|
@@ -23,9 +23,5 @@ export interface NiceModelViewerProps extends UseModelViewerProps {
|
|
|
23
23
|
/** Render prop — exposes the full API. */
|
|
24
24
|
children?: (api: ModelViewerAPI) => React.ReactNode;
|
|
25
25
|
}
|
|
26
|
-
/** @deprecated Use NiceModelViewerProps */
|
|
27
|
-
export type ModelViewerProps = NiceModelViewerProps;
|
|
28
26
|
export declare const NiceModelViewer: React.FC<NiceModelViewerProps>;
|
|
29
|
-
/** @deprecated Use NiceModelViewer */
|
|
30
|
-
export declare const ModelViewer: React.FC<NiceModelViewerProps>;
|
|
31
27
|
export default NiceModelViewer;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nice2dev/ui-3d",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Nice2Dev 3D Editor
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Nice2Dev 3D Editor — Blender-style 3D model editor component for React, powered by Three.js",
|
|
5
5
|
"author": "NiceToDev <contact@nicetodev.com>",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
7
7
|
"homepage": "https://github.com/NiceToDev/NiceToDev.UI#readme",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"three": ">=0.150.0"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
|
-
"@nice2dev/ui": "^1.
|
|
68
|
+
"@nice2dev/ui": "^1.2.0",
|
|
69
69
|
"@rollup/plugin-commonjs": "^29.0.3",
|
|
70
70
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
71
71
|
"@rollup/plugin-typescript": "^12.3.0",
|