threedviewer 2.0.1 → 2.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/README.md +25 -4
- package/dist/SimpleViewerWrapper.d.ts +24 -0
- package/dist/core/ViewerCore.d.ts +114 -0
- package/dist/core/entities/ViewerState.d.ts +44 -0
- package/dist/core/events/ViewerEvents.d.ts +49 -0
- package/dist/core/interfaces/ICamera.d.ts +27 -0
- package/dist/core/interfaces/IControls.d.ts +38 -0
- package/dist/core/interfaces/IModelLoader.d.ts +46 -0
- package/dist/core/interfaces/IObject3D.d.ts +36 -0
- package/dist/core/interfaces/IRenderer.d.ts +44 -0
- package/dist/core/interfaces/IRendererExtension.d.ts +15 -0
- package/dist/core/interfaces/IScene.d.ts +36 -0
- package/dist/core/interfaces/index.d.ts +7 -0
- package/dist/core/services/IEnvironmentService.d.ts +34 -0
- package/dist/core/services/IFloorAlignmentService.d.ts +11 -0
- package/dist/core/services/IPathTracingService.d.ts +81 -0
- package/dist/core/services/ISceneSetupService.d.ts +79 -0
- package/dist/core/utils/MemoryMonitor.d.ts +31 -0
- package/dist/core/utils/RenderLoopManager.d.ts +65 -0
- package/dist/core/utils/SceneSerializer.d.ts +41 -0
- package/dist/defaultOptions.d.ts +4 -1
- package/dist/errors/ErrorCode.d.ts +9 -0
- package/dist/errors/ThreeViewerError.d.ts +1 -1
- package/dist/events/EventEmitter.d.ts +9 -1
- package/dist/events/ViewerEvents.d.ts +11 -4
- package/dist/index.d.ts +1 -1
- package/dist/infrastructure/converters/RendererOptionsConverter.d.ts +6 -0
- package/dist/infrastructure/factories/ViewerFactory.d.ts +20 -0
- package/dist/{ThreeSceneSetup/HexGrid → infrastructure/three}/HexTile.d.ts +1 -1
- package/dist/infrastructure/three/HexTileConfig.d.ts +41 -0
- package/dist/infrastructure/three/ThreeCamera.d.ts +57 -0
- package/dist/infrastructure/three/ThreeControls.d.ts +75 -0
- package/dist/infrastructure/three/ThreeEnvironmentService.d.ts +17 -0
- package/dist/infrastructure/three/ThreeFloorAlignmentService.d.ts +6 -0
- package/dist/infrastructure/three/ThreeModelLoader.d.ts +20 -0
- package/dist/infrastructure/three/ThreeObject3D.d.ts +29 -0
- package/dist/infrastructure/three/ThreePathTracingService.d.ts +68 -0
- package/dist/infrastructure/three/ThreeRenderer.d.ts +29 -0
- package/dist/infrastructure/three/ThreeScene.d.ts +30 -0
- package/dist/infrastructure/three/ThreeSceneSetupService.d.ts +13 -0
- package/dist/infrastructure/three/ThreeVector3.d.ts +24 -0
- package/dist/infrastructure/three/index.d.ts +11 -0
- package/dist/infrastructure/three/types/PathTracerTypes.d.ts +42 -0
- package/dist/infrastructure/types/ExtendedTypes.d.ts +77 -0
- package/dist/presentation/adapters/EventAdapter.d.ts +41 -0
- package/dist/presentation/components/PerformanceMonitor.d.ts +5 -0
- package/dist/presentation/components/SimpleViewer.d.ts +7 -0
- package/dist/presentation/components/ViewerCanvas.d.ts +4 -0
- package/dist/presentation/components/ViewerContext.d.ts +20 -0
- package/dist/presentation/components/ViewerErrorBoundary.d.ts +19 -0
- package/dist/presentation/components/ViewerGizmo.d.ts +12 -0
- package/dist/presentation/hooks/index.d.ts +5 -0
- package/dist/presentation/hooks/useDebounce.d.ts +7 -0
- package/dist/presentation/hooks/useStableOptions.d.ts +6 -0
- package/dist/presentation/hooks/useViewerCore.d.ts +11 -0
- package/dist/presentation/hooks/useViewerEvents.d.ts +12 -0
- package/dist/presentation/hooks/useViewerState.d.ts +18 -0
- package/dist/simple-viewer.es.js +14248 -15250
- package/dist/simple-viewer.umd.js +135 -178
- package/dist/testUtils/testDefaultOptions.d.ts +7 -0
- package/dist/types/CommonTypes.d.ts +59 -0
- package/dist/types/SimpleViewerOptions.d.ts +2 -36
- package/dist/types/options/HelperOptions.d.ts +0 -5
- package/dist/types/options/RenderingOptions.d.ts +25 -0
- package/dist/types/options/index.d.ts +1 -0
- package/dist/types.d.ts +6 -120
- package/dist/validation/OptionsValidator.d.ts +2 -2
- package/package.json +9 -2
- package/dist/Resizer.d.ts +0 -5
- package/dist/SimpleViewer.d.ts +0 -20
- package/dist/ThreeSceneSetup/SceneInitializer.d.ts +0 -18
- package/dist/ThreeSceneSetup/addHelpers.d.ts +0 -3
- package/dist/ThreeSceneSetup/addLighting.d.ts +0 -3
- package/dist/ThreeSceneSetup/cleanupScene.d.ts +0 -3
- package/dist/ThreeSceneSetup/constants.d.ts +0 -1
- package/dist/ThreeSceneSetup/createGradientBackground.d.ts +0 -2
- package/dist/ThreeSceneSetup/fitCameraToObject.d.ts +0 -2
- package/dist/ThreeSceneSetup/get2DContext.d.ts +0 -1
- package/dist/ThreeSceneSetup/importRaytracer.d.ts +0 -7
- package/dist/ThreeSceneSetup/initializeScene.d.ts +0 -3
- package/dist/ThreeSceneSetup/setupScene/AnimationManager.d.ts +0 -24
- package/dist/ThreeSceneSetup/setupScene/CameraManager.d.ts +0 -9
- package/dist/ThreeSceneSetup/setupScene/ControlsManager.d.ts +0 -14
- package/dist/ThreeSceneSetup/setupScene/EnvironmentMapManager.d.ts +0 -32
- package/dist/ThreeSceneSetup/setupScene/PathTracingManager.d.ts +0 -25
- package/dist/ThreeSceneSetup/setupScene/RendererManager.d.ts +0 -11
- package/dist/ThreeSceneSetup/setupScene/SceneManager.d.ts +0 -28
- package/dist/ThreeSceneSetup/setupScene/initializeCamera.d.ts +0 -3
- package/dist/ThreeSceneSetup/setupScene/initializeRenderer.d.ts +0 -3
- package/dist/ThreeSceneSetup/types.d.ts +0 -8
- package/dist/ThreeSceneSetup/updateSize.d.ts +0 -3
- package/dist/loadModel.d.ts +0 -3
- package/dist/utils/deprecation.d.ts +0 -15
- package/dist/utils/optionsMapper.d.ts +0 -11
- package/dist/utils.d.ts +0 -1
- /package/dist/{FloorAligner.d.ts → infrastructure/three/FloorAligner.d.ts} +0 -0
- /package/dist/{ThreeSceneSetup/HexGrid → infrastructure/three}/HexGrid.d.ts +0 -0
package/README.md
CHANGED
|
@@ -132,7 +132,7 @@ function App() {
|
|
|
132
132
|
...defaultOptions.helpers,
|
|
133
133
|
grid: true,
|
|
134
134
|
axes: true,
|
|
135
|
-
|
|
135
|
+
gizmo: true, // Enable viewport gizmo
|
|
136
136
|
},
|
|
137
137
|
threeBaseRefs: {
|
|
138
138
|
scene: sceneRef,
|
|
@@ -285,10 +285,8 @@ const defaultOptions: SimpleViewerOptions = {
|
|
|
285
285
|
},
|
|
286
286
|
helpers: {
|
|
287
287
|
grid: true,
|
|
288
|
-
gridColor: '#333333',
|
|
289
288
|
axes: false,
|
|
290
|
-
|
|
291
|
-
addGizmo: false, // new Gizmo control is disabled by default
|
|
289
|
+
gizmo: false, // Viewport gizmo is disabled by default
|
|
292
290
|
},
|
|
293
291
|
threeBaseRefs: {
|
|
294
292
|
mountPoint: {current: null},
|
|
@@ -316,6 +314,29 @@ const defaultOptions: SimpleViewerOptions = {
|
|
|
316
314
|
};
|
|
317
315
|
```
|
|
318
316
|
|
|
317
|
+
### Viewport Gizmo
|
|
318
|
+
|
|
319
|
+
ThreeDViewer includes an optional viewport gizmo for easy camera orientation control:
|
|
320
|
+
|
|
321
|
+
```javascript
|
|
322
|
+
const options = {
|
|
323
|
+
helpers: {
|
|
324
|
+
gizmo: true, // Enable with default settings
|
|
325
|
+
// Or configure with options:
|
|
326
|
+
gizmo: {
|
|
327
|
+
placement: 'top-right', // 'top-left', 'top-right', 'bottom-left', 'bottom-right'
|
|
328
|
+
size: 128 // Size in pixels
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
};
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
The gizmo provides:
|
|
335
|
+
- Interactive 3D orientation indicator
|
|
336
|
+
- Click to snap camera to axis views
|
|
337
|
+
- Visual feedback for current camera orientation
|
|
338
|
+
- Synchronized with main viewport controls
|
|
339
|
+
|
|
319
340
|
### Path Tracing
|
|
320
341
|
|
|
321
342
|
ThreeDViewer now supports path tracing for high-quality rendering with customizable settings:
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { SimpleViewerProps } from './types';
|
|
3
|
+
import { ControlsInstance } from './types/CommonTypes';
|
|
4
|
+
import { TypedEventEmitter } from './events/EventEmitter';
|
|
5
|
+
import { ViewerEventMap } from './events/ViewerEvents';
|
|
6
|
+
import * as THREE from 'three';
|
|
7
|
+
export interface SimpleViewerHandle {
|
|
8
|
+
scene: THREE.Scene | null;
|
|
9
|
+
camera: THREE.Camera | null;
|
|
10
|
+
renderer: THREE.WebGLRenderer | null;
|
|
11
|
+
controls: ControlsInstance | null;
|
|
12
|
+
events: TypedEventEmitter<ViewerEventMap>;
|
|
13
|
+
loadModel?: (url: string) => Promise<void>;
|
|
14
|
+
startRendering?: () => void;
|
|
15
|
+
stopRendering?: () => void;
|
|
16
|
+
captureScreenshot?: () => Promise<string>;
|
|
17
|
+
dispose?: () => void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* SimpleViewer component using clean architecture
|
|
21
|
+
* This is now the main export replacing the legacy implementation
|
|
22
|
+
*/
|
|
23
|
+
declare const SimpleViewerWrapper: React.ForwardRefExoticComponent<SimpleViewerProps & React.RefAttributes<SimpleViewerHandle>>;
|
|
24
|
+
export default SimpleViewerWrapper;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { IRenderer, IRendererOptions, IScene, IModelLoader, ICamera, IControls, IObject3D, Result } from './interfaces';
|
|
2
|
+
import { ViewerState } from './entities/ViewerState';
|
|
3
|
+
import { TypedEventEmitter } from '../events/EventEmitter';
|
|
4
|
+
import { ViewerEventMap } from './events/ViewerEvents';
|
|
5
|
+
import { SimpleViewerOptions } from '../types/SimpleViewerOptions';
|
|
6
|
+
import { IPathTracingService } from './services/IPathTracingService';
|
|
7
|
+
import { IEnvironmentService } from './services/IEnvironmentService';
|
|
8
|
+
import { ISceneSetupService } from './services/ISceneSetupService';
|
|
9
|
+
import { IFloorAlignmentService } from './services/IFloorAlignmentService';
|
|
10
|
+
export interface ViewerDependencies {
|
|
11
|
+
renderer: IRenderer;
|
|
12
|
+
scene: IScene;
|
|
13
|
+
camera: ICamera;
|
|
14
|
+
controls: IControls;
|
|
15
|
+
modelLoader: IModelLoader;
|
|
16
|
+
options: SimpleViewerOptions;
|
|
17
|
+
rendererOptions?: IRendererOptions;
|
|
18
|
+
pathTracingService?: IPathTracingService;
|
|
19
|
+
environmentService?: IEnvironmentService;
|
|
20
|
+
sceneSetupService?: ISceneSetupService;
|
|
21
|
+
floorAlignmentService?: IFloorAlignmentService;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Core business logic for the 3D viewer
|
|
25
|
+
* Independent of UI framework and rendering engine
|
|
26
|
+
*/
|
|
27
|
+
export declare class ViewerCore {
|
|
28
|
+
private state;
|
|
29
|
+
private readonly events;
|
|
30
|
+
private readonly renderLoopManager;
|
|
31
|
+
private lastFrameTime;
|
|
32
|
+
private frameCount;
|
|
33
|
+
private stateChangeCallback?;
|
|
34
|
+
private pathTracingStartTime?;
|
|
35
|
+
private screenshotElement;
|
|
36
|
+
private isShowingScreenshot;
|
|
37
|
+
private screenshotResizeHandler?;
|
|
38
|
+
private serializedSceneState?;
|
|
39
|
+
private lastModelUrl?;
|
|
40
|
+
private pathTracingCompleteHandled;
|
|
41
|
+
private disposed;
|
|
42
|
+
private readonly renderer;
|
|
43
|
+
private readonly scene;
|
|
44
|
+
private readonly camera;
|
|
45
|
+
private readonly controls;
|
|
46
|
+
private readonly modelLoader;
|
|
47
|
+
private readonly options;
|
|
48
|
+
private readonly rendererOptions?;
|
|
49
|
+
private readonly sceneSetupService?;
|
|
50
|
+
private environmentService?;
|
|
51
|
+
private pathTracingService?;
|
|
52
|
+
private readonly floorAlignmentService?;
|
|
53
|
+
constructor(dependencies: ViewerDependencies);
|
|
54
|
+
/**
|
|
55
|
+
* Initialize the viewer
|
|
56
|
+
*/
|
|
57
|
+
initialize(): Promise<Result<void>>;
|
|
58
|
+
/**
|
|
59
|
+
* Load a 3D model
|
|
60
|
+
*/
|
|
61
|
+
loadModel(source: string | IObject3D): Promise<Result<void>>;
|
|
62
|
+
/**
|
|
63
|
+
* Start the render loop
|
|
64
|
+
*/
|
|
65
|
+
private startRenderLoop;
|
|
66
|
+
/**
|
|
67
|
+
* Stop the render loop
|
|
68
|
+
*/
|
|
69
|
+
private stopRenderLoop;
|
|
70
|
+
/**
|
|
71
|
+
* Render a single frame
|
|
72
|
+
*/
|
|
73
|
+
private renderFrame;
|
|
74
|
+
/**
|
|
75
|
+
* Resize the renderer
|
|
76
|
+
*/
|
|
77
|
+
resize(width: number, height: number): void;
|
|
78
|
+
/**
|
|
79
|
+
* Get current state
|
|
80
|
+
*/
|
|
81
|
+
getState(): ViewerState;
|
|
82
|
+
/**
|
|
83
|
+
* Subscribe to state changes
|
|
84
|
+
*/
|
|
85
|
+
onStateChange(callback: (state: ViewerState) => void): () => void;
|
|
86
|
+
/**
|
|
87
|
+
* Get event emitter
|
|
88
|
+
*/
|
|
89
|
+
getEvents(): TypedEventEmitter<ViewerEventMap>;
|
|
90
|
+
/**
|
|
91
|
+
* Get renderer DOM element
|
|
92
|
+
*/
|
|
93
|
+
getDomElement(): HTMLCanvasElement;
|
|
94
|
+
/**
|
|
95
|
+
* Replace the 3D scene with a screenshot
|
|
96
|
+
*/
|
|
97
|
+
private replaceWithScreenshot;
|
|
98
|
+
/**
|
|
99
|
+
* Restore the 3D scene from screenshot
|
|
100
|
+
*/
|
|
101
|
+
private restoreFromScreenshot;
|
|
102
|
+
/**
|
|
103
|
+
* Dispose scene resources while keeping the screenshot
|
|
104
|
+
*/
|
|
105
|
+
private disposeSceneResources;
|
|
106
|
+
/**
|
|
107
|
+
* Recursively dispose of an object and its children
|
|
108
|
+
*/
|
|
109
|
+
private disposeObject;
|
|
110
|
+
/**
|
|
111
|
+
* Dispose of all resources
|
|
112
|
+
*/
|
|
113
|
+
dispose(): void;
|
|
114
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { IObject3D } from '../interfaces/IObject3D';
|
|
2
|
+
import { ThreeViewerError } from '../../errors/ThreeViewerError';
|
|
3
|
+
export type ViewerStatus = 'idle' | 'loading' | 'loaded' | 'error' | 'rendering' | 'disposed';
|
|
4
|
+
export interface ViewerStateData {
|
|
5
|
+
status: ViewerStatus;
|
|
6
|
+
currentModel: IObject3D | null;
|
|
7
|
+
error: ThreeViewerError | null;
|
|
8
|
+
isInitialized: boolean;
|
|
9
|
+
loadProgress: number;
|
|
10
|
+
renderInfo: RenderInfo;
|
|
11
|
+
}
|
|
12
|
+
export interface RenderInfo {
|
|
13
|
+
frameCount: number;
|
|
14
|
+
fps: number;
|
|
15
|
+
lastRenderTime: number;
|
|
16
|
+
averageRenderTime: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Immutable state class for the viewer
|
|
20
|
+
* Implements state machine pattern for viewer states
|
|
21
|
+
*/
|
|
22
|
+
export declare class ViewerState {
|
|
23
|
+
private readonly data;
|
|
24
|
+
constructor(data?: Partial<ViewerStateData>);
|
|
25
|
+
get status(): ViewerStatus;
|
|
26
|
+
get currentModel(): IObject3D | null;
|
|
27
|
+
get error(): ThreeViewerError | null;
|
|
28
|
+
get isInitialized(): boolean;
|
|
29
|
+
get loadProgress(): number;
|
|
30
|
+
get renderInfo(): RenderInfo;
|
|
31
|
+
setInitialized(): ViewerState;
|
|
32
|
+
startLoading(): ViewerState;
|
|
33
|
+
updateLoadProgress(progress: number): ViewerState;
|
|
34
|
+
setLoaded(model: IObject3D): ViewerState;
|
|
35
|
+
setError(error: ThreeViewerError): ViewerState;
|
|
36
|
+
startRendering(): ViewerState;
|
|
37
|
+
updateRenderInfo(info: Partial<RenderInfo>): ViewerState;
|
|
38
|
+
dispose(): ViewerState;
|
|
39
|
+
canLoad(): boolean;
|
|
40
|
+
canRender(): boolean;
|
|
41
|
+
isLoading(): boolean;
|
|
42
|
+
hasError(): boolean;
|
|
43
|
+
toJSON(): ViewerStateData;
|
|
44
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ThreeViewerError } from '../../errors';
|
|
2
|
+
import { IObject3D } from '../interfaces/IObject3D';
|
|
3
|
+
import { ICamera } from '../interfaces/ICamera';
|
|
4
|
+
import { IControls } from '../interfaces/IControls';
|
|
5
|
+
export interface ViewerEventMap {
|
|
6
|
+
'initialized': {
|
|
7
|
+
viewer: unknown;
|
|
8
|
+
};
|
|
9
|
+
'disposed': {
|
|
10
|
+
viewer: unknown;
|
|
11
|
+
};
|
|
12
|
+
'model:loading': {
|
|
13
|
+
url: string;
|
|
14
|
+
};
|
|
15
|
+
'model:loaded': {
|
|
16
|
+
model: IObject3D;
|
|
17
|
+
loadTime: number;
|
|
18
|
+
};
|
|
19
|
+
'model:error': {
|
|
20
|
+
error: ThreeViewerError;
|
|
21
|
+
url?: string;
|
|
22
|
+
};
|
|
23
|
+
'render:start': {
|
|
24
|
+
frame: number;
|
|
25
|
+
};
|
|
26
|
+
'render:complete': {
|
|
27
|
+
frame: number;
|
|
28
|
+
renderTime: number;
|
|
29
|
+
samples?: number;
|
|
30
|
+
};
|
|
31
|
+
'pathtracing:complete': {
|
|
32
|
+
samples: number;
|
|
33
|
+
totalTime: number;
|
|
34
|
+
};
|
|
35
|
+
'screenshot:captured': {
|
|
36
|
+
dataUrl: string;
|
|
37
|
+
};
|
|
38
|
+
'controls:change': {
|
|
39
|
+
type?: string;
|
|
40
|
+
camera?: ICamera;
|
|
41
|
+
controls?: IControls;
|
|
42
|
+
};
|
|
43
|
+
'object:selected': {
|
|
44
|
+
object: IObject3D;
|
|
45
|
+
};
|
|
46
|
+
'error': {
|
|
47
|
+
error: ThreeViewerError;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { IObject3D, IVector3 } from './IObject3D';
|
|
2
|
+
import { IRendererExtension } from './IRendererExtension';
|
|
3
|
+
/**
|
|
4
|
+
* Core interface for cameras, independent of rendering engine
|
|
5
|
+
*/
|
|
6
|
+
export interface ICamera extends IObject3D, IRendererExtension {
|
|
7
|
+
type: 'perspective' | 'orthographic';
|
|
8
|
+
near: number;
|
|
9
|
+
far: number;
|
|
10
|
+
lookAt(target: IVector3): void;
|
|
11
|
+
updateProjectionMatrix(): void;
|
|
12
|
+
getWorldDirection(target: IVector3): void;
|
|
13
|
+
}
|
|
14
|
+
export interface IPerspectiveCamera extends ICamera {
|
|
15
|
+
type: 'perspective';
|
|
16
|
+
fov: number;
|
|
17
|
+
aspect: number;
|
|
18
|
+
}
|
|
19
|
+
export interface IOrthographicCamera extends ICamera {
|
|
20
|
+
type: 'orthographic';
|
|
21
|
+
left: number;
|
|
22
|
+
right: number;
|
|
23
|
+
top: number;
|
|
24
|
+
bottom: number;
|
|
25
|
+
zoom: number;
|
|
26
|
+
}
|
|
27
|
+
export type CameraType = IPerspectiveCamera | IOrthographicCamera;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { IVector3 } from './IObject3D';
|
|
2
|
+
/**
|
|
3
|
+
* Core interface for camera controls, independent of implementation
|
|
4
|
+
*/
|
|
5
|
+
export interface IControls {
|
|
6
|
+
enabled: boolean;
|
|
7
|
+
enableDamping: boolean;
|
|
8
|
+
dampingFactor: number;
|
|
9
|
+
enableZoom: boolean;
|
|
10
|
+
enableRotate: boolean;
|
|
11
|
+
enablePan: boolean;
|
|
12
|
+
zoomSpeed: number;
|
|
13
|
+
minDistance: number;
|
|
14
|
+
maxDistance: number;
|
|
15
|
+
rotateSpeed: number;
|
|
16
|
+
minPolarAngle: number;
|
|
17
|
+
maxPolarAngle: number;
|
|
18
|
+
minAzimuthAngle: number;
|
|
19
|
+
maxAzimuthAngle: number;
|
|
20
|
+
panSpeed: number;
|
|
21
|
+
screenSpacePanning: boolean;
|
|
22
|
+
target: IVector3;
|
|
23
|
+
update(): boolean;
|
|
24
|
+
reset(): void;
|
|
25
|
+
dispose(): void;
|
|
26
|
+
connect(domElement: HTMLElement): void;
|
|
27
|
+
disconnect(): void;
|
|
28
|
+
}
|
|
29
|
+
export interface IOrbitControls extends IControls {
|
|
30
|
+
type: 'orbit';
|
|
31
|
+
autoRotate: boolean;
|
|
32
|
+
autoRotateSpeed: number;
|
|
33
|
+
}
|
|
34
|
+
export interface IMapControls extends IControls {
|
|
35
|
+
type: 'map';
|
|
36
|
+
screenSpacePanning: true;
|
|
37
|
+
}
|
|
38
|
+
export type ControlsType = IOrbitControls | IMapControls;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Result } from '../../utils/Result';
|
|
2
|
+
import { IObject3D } from './IObject3D';
|
|
3
|
+
/**
|
|
4
|
+
* Core interface for model loaders, independent of file format
|
|
5
|
+
*/
|
|
6
|
+
export interface IModelLoader {
|
|
7
|
+
/**
|
|
8
|
+
* Load a 3D model from a URL
|
|
9
|
+
*/
|
|
10
|
+
load(url: string): Promise<Result<IModel>>;
|
|
11
|
+
/**
|
|
12
|
+
* Check if this loader supports the given URL/file type
|
|
13
|
+
*/
|
|
14
|
+
supports(url: string): boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface IModel {
|
|
17
|
+
scene: IObject3D;
|
|
18
|
+
animations?: IAnimation[];
|
|
19
|
+
cameras?: IModelCamera[];
|
|
20
|
+
userData?: Record<string, unknown>;
|
|
21
|
+
}
|
|
22
|
+
export interface IAnimation {
|
|
23
|
+
name: string;
|
|
24
|
+
duration: number;
|
|
25
|
+
tracks: IAnimationTrack[];
|
|
26
|
+
}
|
|
27
|
+
export interface IAnimationTrack {
|
|
28
|
+
name: string;
|
|
29
|
+
type: 'vector' | 'quaternion' | 'number' | 'boolean';
|
|
30
|
+
times: Float32Array;
|
|
31
|
+
values: Float32Array;
|
|
32
|
+
}
|
|
33
|
+
export interface ILoadingManager {
|
|
34
|
+
onStart?: (url: string, itemsLoaded: number, itemsTotal: number) => void;
|
|
35
|
+
onProgress?: (url: string, itemsLoaded: number, itemsTotal: number) => void;
|
|
36
|
+
onLoad?: () => void;
|
|
37
|
+
onError?: (url: string) => void;
|
|
38
|
+
}
|
|
39
|
+
export interface IModelCamera {
|
|
40
|
+
name: string;
|
|
41
|
+
type: string;
|
|
42
|
+
fov?: number;
|
|
43
|
+
aspect?: number;
|
|
44
|
+
near: number;
|
|
45
|
+
far: number;
|
|
46
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Result } from '../../utils/Result';
|
|
2
|
+
/**
|
|
3
|
+
* Core interface for 3D objects, independent of Three.js
|
|
4
|
+
*/
|
|
5
|
+
export interface IObject3D {
|
|
6
|
+
id: string;
|
|
7
|
+
name: string;
|
|
8
|
+
visible: boolean;
|
|
9
|
+
position: IVector3;
|
|
10
|
+
rotation: IVector3;
|
|
11
|
+
scale: IVector3;
|
|
12
|
+
add(child: IObject3D): Result<void>;
|
|
13
|
+
remove(child: IObject3D): Result<void>;
|
|
14
|
+
traverse(callback: (object: IObject3D) => void): void;
|
|
15
|
+
clone(): IObject3D;
|
|
16
|
+
dispose(): void;
|
|
17
|
+
}
|
|
18
|
+
export interface IVector3 {
|
|
19
|
+
x: number;
|
|
20
|
+
y: number;
|
|
21
|
+
z: number;
|
|
22
|
+
set(x: number, y: number, z: number): void;
|
|
23
|
+
copy(v: IVector3): void;
|
|
24
|
+
add(v: IVector3): void;
|
|
25
|
+
multiply(v: IVector3): void;
|
|
26
|
+
normalize(): void;
|
|
27
|
+
length(): number;
|
|
28
|
+
}
|
|
29
|
+
export interface IBoundingBox {
|
|
30
|
+
min: IVector3;
|
|
31
|
+
max: IVector3;
|
|
32
|
+
setFromObject(object: IObject3D): void;
|
|
33
|
+
getCenter(target: IVector3): void;
|
|
34
|
+
getSize(target: IVector3): void;
|
|
35
|
+
isEmpty(): boolean;
|
|
36
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Result } from '../../utils/Result';
|
|
2
|
+
import { IScene } from './IScene';
|
|
3
|
+
import { ICamera } from './ICamera';
|
|
4
|
+
import { IRendererExtension } from './IRendererExtension';
|
|
5
|
+
/**
|
|
6
|
+
* Core interface for renderers, independent of rendering engine
|
|
7
|
+
* Extends IRendererExtension to allow controlled access to internal implementation
|
|
8
|
+
*/
|
|
9
|
+
export interface IRenderer extends IRendererExtension {
|
|
10
|
+
id: string;
|
|
11
|
+
initialize(options: IRendererOptions): Result<void>;
|
|
12
|
+
render(scene: IScene, camera: ICamera): Result<void>;
|
|
13
|
+
setSize(width: number, height: number): void;
|
|
14
|
+
setPixelRatio(ratio: number): void;
|
|
15
|
+
getDomElement(): HTMLCanvasElement;
|
|
16
|
+
getContext(): WebGLRenderingContext | WebGL2RenderingContext | null;
|
|
17
|
+
dispose(): void;
|
|
18
|
+
capabilities: IRendererCapabilities;
|
|
19
|
+
}
|
|
20
|
+
export interface IRendererOptions {
|
|
21
|
+
antialias?: boolean;
|
|
22
|
+
alpha?: boolean;
|
|
23
|
+
premultipliedAlpha?: boolean;
|
|
24
|
+
preserveDrawingBuffer?: boolean;
|
|
25
|
+
powerPreference?: 'high-performance' | 'low-power' | 'default';
|
|
26
|
+
pixelRatio?: number;
|
|
27
|
+
shadowMap?: {
|
|
28
|
+
enabled: boolean;
|
|
29
|
+
type?: 'basic' | 'pcf' | 'pcfsoft' | 'vsm';
|
|
30
|
+
};
|
|
31
|
+
toneMapping?: {
|
|
32
|
+
type: 'none' | 'linear' | 'reinhard' | 'cineon' | 'aces';
|
|
33
|
+
exposure: number;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export interface IRendererCapabilities {
|
|
37
|
+
maxTextureSize: number;
|
|
38
|
+
maxCubemapSize: number;
|
|
39
|
+
maxAttributes: number;
|
|
40
|
+
maxVertexUniforms: number;
|
|
41
|
+
maxFragmentUniforms: number;
|
|
42
|
+
maxSamples: number;
|
|
43
|
+
isWebGL2: boolean;
|
|
44
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Interface for renderer extensions that need access to the underlying renderer
|
|
3
|
+
* This allows features like path tracing while maintaining clean architecture
|
|
4
|
+
*/
|
|
5
|
+
export interface IRendererExtension<T = unknown> {
|
|
6
|
+
/**
|
|
7
|
+
* Get the internal renderer implementation
|
|
8
|
+
* Returns null if not available or not of expected type
|
|
9
|
+
*/
|
|
10
|
+
getInternalRenderer(): T | null;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Type guard for checking if an object implements IRendererExtension
|
|
14
|
+
*/
|
|
15
|
+
export declare function hasInternalRenderer<T>(obj: unknown): obj is IRendererExtension<T>;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Result } from '../../utils/Result';
|
|
2
|
+
import { IObject3D } from './IObject3D';
|
|
3
|
+
import { IRendererExtension } from './IRendererExtension';
|
|
4
|
+
/**
|
|
5
|
+
* Core interface for 3D scenes, independent of rendering engine
|
|
6
|
+
*/
|
|
7
|
+
export interface IScene extends IRendererExtension {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
add(object: IObject3D): Result<void>;
|
|
11
|
+
remove(object: IObject3D): Result<void>;
|
|
12
|
+
clear(): void;
|
|
13
|
+
traverse(callback: (object: IObject3D) => void): void;
|
|
14
|
+
background: IColor | ITexture | null;
|
|
15
|
+
fog: IFog | null;
|
|
16
|
+
environment: ITexture | null;
|
|
17
|
+
}
|
|
18
|
+
export interface IColor {
|
|
19
|
+
r: number;
|
|
20
|
+
g: number;
|
|
21
|
+
b: number;
|
|
22
|
+
setHex(hex: number): void;
|
|
23
|
+
setRGB(r: number, g: number, b: number): void;
|
|
24
|
+
getHex(): number;
|
|
25
|
+
}
|
|
26
|
+
export interface ITexture {
|
|
27
|
+
id: string;
|
|
28
|
+
image: HTMLImageElement | ImageData | HTMLCanvasElement | HTMLVideoElement | null;
|
|
29
|
+
needsUpdate: boolean;
|
|
30
|
+
dispose(): void;
|
|
31
|
+
}
|
|
32
|
+
export interface IFog {
|
|
33
|
+
color: IColor;
|
|
34
|
+
near: number;
|
|
35
|
+
far: number;
|
|
36
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Result } from '../../utils/Result';
|
|
2
|
+
import { IScene, ITexture } from '../interfaces/IScene';
|
|
3
|
+
import { IRenderer } from '../interfaces/IRenderer';
|
|
4
|
+
export interface IEnvironmentService {
|
|
5
|
+
/**
|
|
6
|
+
* Initialize the environment service
|
|
7
|
+
*/
|
|
8
|
+
initialize(options: IEnvironmentOptions): Promise<Result<void>>;
|
|
9
|
+
/**
|
|
10
|
+
* Load environment map from URL
|
|
11
|
+
*/
|
|
12
|
+
loadEnvironmentMap(url: string): Promise<Result<ITexture>>;
|
|
13
|
+
/**
|
|
14
|
+
* Apply environment to scene
|
|
15
|
+
*/
|
|
16
|
+
applyToScene(scene: IScene, texture: ITexture): Result<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Create studio environment
|
|
19
|
+
*/
|
|
20
|
+
createStudioEnvironment(options?: IStudioEnvironmentOptions): Result<ITexture>;
|
|
21
|
+
/**
|
|
22
|
+
* Dispose of resources
|
|
23
|
+
*/
|
|
24
|
+
dispose(): void;
|
|
25
|
+
}
|
|
26
|
+
export interface IEnvironmentOptions {
|
|
27
|
+
renderer: IRenderer;
|
|
28
|
+
autoDispose?: boolean;
|
|
29
|
+
}
|
|
30
|
+
export interface IStudioEnvironmentOptions {
|
|
31
|
+
intensity?: number;
|
|
32
|
+
groundColor?: string;
|
|
33
|
+
skyColor?: string;
|
|
34
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IObject3D } from '../interfaces/IObject3D';
|
|
2
|
+
import { Result } from '../../utils/Result';
|
|
3
|
+
/**
|
|
4
|
+
* Service interface for aligning objects to floor
|
|
5
|
+
*/
|
|
6
|
+
export interface IFloorAlignmentService {
|
|
7
|
+
/**
|
|
8
|
+
* Align an object to the floor (y=0)
|
|
9
|
+
*/
|
|
10
|
+
alignToFloor(object: IObject3D): Result<void>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Result } from '../../utils/Result';
|
|
2
|
+
import { IRenderer } from '../interfaces/IRenderer';
|
|
3
|
+
import { IScene } from '../interfaces/IScene';
|
|
4
|
+
import { ICamera } from '../interfaces/ICamera';
|
|
5
|
+
import { TypedEventEmitter } from '../../events/EventEmitter';
|
|
6
|
+
export interface IPathTracingService {
|
|
7
|
+
/**
|
|
8
|
+
* Event emitter for path tracing events
|
|
9
|
+
*/
|
|
10
|
+
readonly events: TypedEventEmitter<{
|
|
11
|
+
'pathtracing:paused': {
|
|
12
|
+
samples: number;
|
|
13
|
+
};
|
|
14
|
+
}>;
|
|
15
|
+
/**
|
|
16
|
+
* Initialize path tracing with given options
|
|
17
|
+
*/
|
|
18
|
+
initialize(options: IPathTracingOptions): Promise<Result<void>>;
|
|
19
|
+
/**
|
|
20
|
+
* Enable or disable path tracing
|
|
21
|
+
*/
|
|
22
|
+
setEnabled(enabled: boolean): void;
|
|
23
|
+
/**
|
|
24
|
+
* Update path tracing settings
|
|
25
|
+
*/
|
|
26
|
+
updateSettings(settings: Partial<IPathTracingSettings>): void;
|
|
27
|
+
/**
|
|
28
|
+
* Render a frame with path tracing
|
|
29
|
+
*/
|
|
30
|
+
render(scene: IScene, camera: ICamera): Promise<Result<void>>;
|
|
31
|
+
/**
|
|
32
|
+
* Get current sample count
|
|
33
|
+
*/
|
|
34
|
+
getSampleCount(): number;
|
|
35
|
+
/**
|
|
36
|
+
* Check if path tracing is currently enabled
|
|
37
|
+
*/
|
|
38
|
+
isEnabled(): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Check if path tracer has been disposed
|
|
41
|
+
*/
|
|
42
|
+
isPathTracerDisposed(): boolean;
|
|
43
|
+
/**
|
|
44
|
+
* Reset accumulation
|
|
45
|
+
*/
|
|
46
|
+
reset(): void;
|
|
47
|
+
/**
|
|
48
|
+
* Dispose of resources
|
|
49
|
+
*/
|
|
50
|
+
dispose(): void;
|
|
51
|
+
/**
|
|
52
|
+
* Check if path tracing is supported
|
|
53
|
+
*/
|
|
54
|
+
isSupported(): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Get the base64 image generated when pausing at the final sample
|
|
57
|
+
* @returns The base64 encoded PNG image or null if not available
|
|
58
|
+
*/
|
|
59
|
+
getPausedFrameBase64(): string | null;
|
|
60
|
+
/**
|
|
61
|
+
* Check if an image overlay is currently displayed
|
|
62
|
+
*/
|
|
63
|
+
hasImageOverlay(): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Remove the image overlay without disposing other resources
|
|
66
|
+
*/
|
|
67
|
+
removeImageOverlay(): void;
|
|
68
|
+
}
|
|
69
|
+
export interface IPathTracingOptions {
|
|
70
|
+
enabled: boolean;
|
|
71
|
+
renderer: IRenderer;
|
|
72
|
+
}
|
|
73
|
+
export interface IPathTracingSettings {
|
|
74
|
+
samples: number;
|
|
75
|
+
bounces: number;
|
|
76
|
+
transmissiveBounces?: number;
|
|
77
|
+
renderScale: number;
|
|
78
|
+
lowResScale: number;
|
|
79
|
+
dynamicLowRes: boolean;
|
|
80
|
+
enablePathTracing: boolean;
|
|
81
|
+
}
|