@d5techs/3dgs-lib 1.2.0 → 1.4.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/dist/3dgs-lib.cjs +430 -21
- package/dist/3dgs-lib.cjs.map +1 -1
- package/dist/3dgs-lib.js +430 -21
- package/dist/3dgs-lib.js.map +1 -1
- package/dist/App.d.ts +38 -4
- package/dist/core/gizmo/TransformGizmo.d.ts +2 -0
- package/dist/gs/PLYLoader.d.ts +7 -1
- package/dist/gs/PLYLoaderMobile.d.ts +8 -0
- package/dist/index.d.ts +3 -3
- package/dist/interaction/GizmoManager.d.ts +1 -0
- package/dist/interaction/HotspotManager.d.ts +57 -0
- package/package.json +1 -1
package/dist/App.d.ts
CHANGED
|
@@ -19,11 +19,12 @@ import { GSSplatRenderer } from "./gs/GSSplatRenderer";
|
|
|
19
19
|
import { GSSplatRendererMobile } from "./gs/GSSplatRendererMobile";
|
|
20
20
|
import type { BoundingBox, SimpleBoundingBox } from "./types";
|
|
21
21
|
import { HotspotManager } from "./interaction/HotspotManager";
|
|
22
|
-
import type { HotspotInfo } from "./interaction/HotspotManager";
|
|
22
|
+
import type { HotspotInfo, HotspotLabelPosition, HotspotLabelConfig } from "./interaction/HotspotManager";
|
|
23
23
|
import { SplatTransformProxy, MeshGroupProxy, SplatBoundingBoxProvider } from "./scene/proxies";
|
|
24
24
|
import { TransformableObject, GizmoMode } from "./core/gizmo/TransformGizmo";
|
|
25
25
|
import type { BoundingBoxProvider } from "./types";
|
|
26
26
|
import { SceneAidsRenderer } from "./core/SceneAidsRenderer";
|
|
27
|
+
import type { CoordinateSystem } from "./gs/PLYLoaderMobile";
|
|
27
28
|
/**
|
|
28
29
|
* 统一进度回调类型
|
|
29
30
|
* @param progress 进度值 0-100
|
|
@@ -64,16 +65,22 @@ export declare class App {
|
|
|
64
65
|
addOBJ(url: string): Promise<Mesh[]>;
|
|
65
66
|
/**
|
|
66
67
|
* 加载 PLY 文件 (3D Gaussian Splatting)
|
|
68
|
+
* @param urlOrBuffer PLY 文件 URL 或 ArrayBuffer
|
|
69
|
+
* @param onProgress 进度回调
|
|
70
|
+
* @param isLocalFile 是否为本地文件
|
|
71
|
+
* @param coordinateSystem 源数据坐标系,默认 'blender'(Z-up → Y-up 自动转换)
|
|
67
72
|
*/
|
|
68
|
-
addPLY(urlOrBuffer: string | ArrayBuffer, onProgress?: ProgressCallback, isLocalFile?: boolean): Promise<number>;
|
|
73
|
+
addPLY(urlOrBuffer: string | ArrayBuffer, onProgress?: ProgressCallback, isLocalFile?: boolean, coordinateSystem?: CoordinateSystem): Promise<number>;
|
|
69
74
|
/**
|
|
70
75
|
* 加载 Splat 文件
|
|
76
|
+
* @param coordinateSystem 源数据坐标系,默认 'blender'(Z-up → Y-up 自动转换)
|
|
71
77
|
*/
|
|
72
|
-
addSplat(urlOrBuffer: string | ArrayBuffer, onProgress?: ProgressCallback, isLocalFile?: boolean): Promise<number>;
|
|
78
|
+
addSplat(urlOrBuffer: string | ArrayBuffer, onProgress?: ProgressCallback, isLocalFile?: boolean, coordinateSystem?: CoordinateSystem): Promise<number>;
|
|
73
79
|
/**
|
|
74
80
|
* 加载 SOG 文件 (Spatially Ordered Gaussians)
|
|
81
|
+
* @param coordinateSystem 源数据坐标系,默认 'blender'(Z-up → Y-up 自动转换)
|
|
75
82
|
*/
|
|
76
|
-
addSOG(urlOrBuffer: string | ArrayBuffer, onProgress?: ProgressCallback, isLocalFile?: boolean): Promise<number>;
|
|
83
|
+
addSOG(urlOrBuffer: string | ArrayBuffer, onProgress?: ProgressCallback, isLocalFile?: boolean, coordinateSystem?: CoordinateSystem): Promise<number>;
|
|
77
84
|
/**
|
|
78
85
|
* 添加测试立方体
|
|
79
86
|
*/
|
|
@@ -123,6 +130,7 @@ export declare class App {
|
|
|
123
130
|
getViewportGizmo(): import(".").ViewportGizmo;
|
|
124
131
|
getBoundingBoxRenderer(): import(".").BoundingBoxRenderer;
|
|
125
132
|
setGizmoMode(mode: GizmoMode): void;
|
|
133
|
+
setUniformScaleOnly(enabled: boolean): void;
|
|
126
134
|
setGizmoTarget(object: TransformableObject | null): void;
|
|
127
135
|
setSelectionBoundingBox(box: SimpleBoundingBox | null): void;
|
|
128
136
|
setSelectionBoundingBoxProvider(provider: BoundingBoxProvider | null): void;
|
|
@@ -155,7 +163,33 @@ export declare class App {
|
|
|
155
163
|
getHotspotBillboard(hotspotIndex: number): boolean;
|
|
156
164
|
getHotspotCount(): number;
|
|
157
165
|
findHotspotIndexByMeshStart(overlayMeshStartIndex: number): number;
|
|
166
|
+
placeHotspotAt(objUrl: string, position: [number, number, number], normal: [number, number, number], visualDiameter?: number, normalOffset?: number, overrideScale?: number): Promise<HotspotInfo | null>;
|
|
158
167
|
getOverlayMeshByIndex(index: number): import("./mesh/Mesh").Mesh | null;
|
|
168
|
+
/**
|
|
169
|
+
* 检测给定屏幕坐标命中了哪个热点
|
|
170
|
+
* @returns 热点索引,-1 表示未命中
|
|
171
|
+
*/
|
|
172
|
+
hitTestHotspot(clientX: number, clientY: number): number;
|
|
173
|
+
/**
|
|
174
|
+
* 设置热点点击回调(非放置模式下生效)
|
|
175
|
+
*/
|
|
176
|
+
setOnHotspotClicked(cb: ((hotspotIndex: number, info: HotspotInfo) => void) | null): void;
|
|
177
|
+
/**
|
|
178
|
+
* 设置热点点击命中半径(NDC 空间,默认 0.05)
|
|
179
|
+
*/
|
|
180
|
+
setHotspotHitRadius(radius: number): void;
|
|
181
|
+
/**
|
|
182
|
+
* 设置热点文字标签
|
|
183
|
+
*/
|
|
184
|
+
setHotspotLabel(hotspotIndex: number, text: string, position?: HotspotLabelPosition, fontSize?: number, visible?: boolean): boolean;
|
|
185
|
+
/**
|
|
186
|
+
* 设置热点标签可见性
|
|
187
|
+
*/
|
|
188
|
+
setHotspotLabelVisible(hotspotIndex: number, visible: boolean): boolean;
|
|
189
|
+
/**
|
|
190
|
+
* 获取热点标签配置
|
|
191
|
+
*/
|
|
192
|
+
getHotspotLabel(hotspotIndex: number): HotspotLabelConfig | null;
|
|
159
193
|
private fetchWithProgress;
|
|
160
194
|
private parsePLYBuffer;
|
|
161
195
|
setGridVisible(visible: boolean): void;
|
package/dist/gs/PLYLoader.d.ts
CHANGED
|
@@ -14,9 +14,15 @@ export type SplatCPU = {
|
|
|
14
14
|
opacity: number;
|
|
15
15
|
shRest?: Float32Array;
|
|
16
16
|
};
|
|
17
|
+
import type { CoordinateSystem } from './PLYLoaderMobile';
|
|
18
|
+
export interface PLYLoadOptions {
|
|
19
|
+
/** 源数据坐标系,默认 'blender'(Z-up → Y-up 自动转换) */
|
|
20
|
+
coordinateSystem?: CoordinateSystem;
|
|
21
|
+
}
|
|
17
22
|
/**
|
|
18
23
|
* 加载并解析 PLY 文件
|
|
19
24
|
* @param url PLY 文件的 URL
|
|
25
|
+
* @param options 加载选项
|
|
20
26
|
* @returns SplatCPU 数组
|
|
21
27
|
*/
|
|
22
|
-
export declare function loadPLY(url: string): Promise<SplatCPU[]>;
|
|
28
|
+
export declare function loadPLY(url: string, options?: PLYLoadOptions): Promise<SplatCPU[]>;
|
|
@@ -9,6 +9,12 @@
|
|
|
9
9
|
* 5. 支持多种 PLY 数据类型
|
|
10
10
|
* 6. 确定性采样(基于文件内容的种子)
|
|
11
11
|
*/
|
|
12
|
+
/**
|
|
13
|
+
* 坐标系类型
|
|
14
|
+
* - 'blender': Blender 坐标系 (Z-up, 右手系),加载时自动将 Y/Z 对调转换为 WebGPU 的 Y-up 坐标系
|
|
15
|
+
* - 'webgpu': WebGPU 坐标系 (Y-up),数据已经是 Y-up 格式,不做转换
|
|
16
|
+
*/
|
|
17
|
+
export type CoordinateSystem = 'blender' | 'webgpu';
|
|
12
18
|
/**
|
|
13
19
|
* 移动端加载配置
|
|
14
20
|
*/
|
|
@@ -21,6 +27,8 @@ export interface MobileLoadOptions {
|
|
|
21
27
|
onProgress?: (loaded: number, total: number) => void;
|
|
22
28
|
/** 随机种子(用于确定性采样,默认使用文件大小作为种子) */
|
|
23
29
|
seed?: number;
|
|
30
|
+
/** 源数据坐标系,默认 'blender'(Z-up → Y-up 自动转换) */
|
|
31
|
+
coordinateSystem?: CoordinateSystem;
|
|
24
32
|
}
|
|
25
33
|
/**
|
|
26
34
|
* 紧凑 Splat 数据(用于移动端)
|
package/dist/index.d.ts
CHANGED
|
@@ -22,9 +22,9 @@ export { MTLParser } from './loaders/MTLParser';
|
|
|
22
22
|
export type { ParsedMaterial } from './loaders/MTLParser';
|
|
23
23
|
export type { IGSSplatRenderer, IGSSplatRendererWithCapabilities, } from './gs/IGSSplatRenderer';
|
|
24
24
|
export { loadPLY } from './gs/PLYLoader';
|
|
25
|
-
export type { SplatCPU } from './gs/PLYLoader';
|
|
25
|
+
export type { SplatCPU, PLYLoadOptions } from './gs/PLYLoader';
|
|
26
26
|
export { loadPLYMobile, parsePLYBuffer, compactDataToGPUBuffer } from './gs/PLYLoaderMobile';
|
|
27
|
-
export type { MobileLoadOptions, CompactSplatData } from './gs/PLYLoaderMobile';
|
|
27
|
+
export type { MobileLoadOptions, CompactSplatData, CoordinateSystem } from './gs/PLYLoaderMobile';
|
|
28
28
|
export { loadSplat, deserializeSplat } from './gs/SplatLoader';
|
|
29
29
|
export { loadSOG, deserializeSOG } from './gs/SOGLoader';
|
|
30
30
|
export type { SOGProgressCallback } from './gs/SOGLoader';
|
|
@@ -41,7 +41,7 @@ export type { SceneObjectType, SceneObjectInfo } from './scene/SceneManager';
|
|
|
41
41
|
export { SplatTransformProxy, MeshGroupProxy, SplatBoundingBoxProvider, } from './scene/proxies';
|
|
42
42
|
export { GizmoManager } from './interaction/GizmoManager';
|
|
43
43
|
export { HotspotManager } from './interaction/HotspotManager';
|
|
44
|
-
export type { HotspotInfo } from './interaction/HotspotManager';
|
|
44
|
+
export type { HotspotInfo, HotspotLabelConfig, HotspotLabelPosition } from './interaction/HotspotManager';
|
|
45
45
|
export type { TransformableObject } from './core/gizmo/TransformGizmo';
|
|
46
46
|
export { TransformGizmo, GizmoMode } from './core/gizmo/TransformGizmo';
|
|
47
47
|
export type { GizmoTheme, TransformGizmoConfig, GizmoSpace } from './core/gizmo/TransformGizmo';
|
|
@@ -10,6 +10,15 @@ import { OrbitControls } from "../core/OrbitControls";
|
|
|
10
10
|
import { MeshRenderer } from "../mesh/MeshRenderer";
|
|
11
11
|
import type { IGSSplatRenderer } from "../gs/IGSSplatRenderer";
|
|
12
12
|
import type { Vec3Tuple } from "../types";
|
|
13
|
+
/** 热点标签位置 */
|
|
14
|
+
export type HotspotLabelPosition = 'top' | 'left' | 'right';
|
|
15
|
+
/** 热点标签配置 */
|
|
16
|
+
export interface HotspotLabelConfig {
|
|
17
|
+
text: string;
|
|
18
|
+
position: HotspotLabelPosition;
|
|
19
|
+
fontSize: number;
|
|
20
|
+
visible: boolean;
|
|
21
|
+
}
|
|
13
22
|
/** 热点信息 */
|
|
14
23
|
export interface HotspotInfo {
|
|
15
24
|
position: Vec3Tuple;
|
|
@@ -24,6 +33,10 @@ export interface HotspotInfo {
|
|
|
24
33
|
placedNormalOffset: number;
|
|
25
34
|
/** 放置时的本地中心偏移 (本地空间) */
|
|
26
35
|
placedLocalCenter: Vec3Tuple;
|
|
36
|
+
/** 文字标签配置 */
|
|
37
|
+
label?: HotspotLabelConfig;
|
|
38
|
+
/** 标签 DOM 元素(内部使用) */
|
|
39
|
+
_labelElement?: HTMLDivElement;
|
|
27
40
|
}
|
|
28
41
|
/**
|
|
29
42
|
* HotspotManager
|
|
@@ -58,6 +71,9 @@ export declare class HotspotManager {
|
|
|
58
71
|
private lastNormal;
|
|
59
72
|
private indicatorBaseRadius;
|
|
60
73
|
private pickRadiusPx;
|
|
74
|
+
private labelContainer;
|
|
75
|
+
private onHotspotClicked;
|
|
76
|
+
private hotspotHitRadius;
|
|
61
77
|
private onHotspotPlaced;
|
|
62
78
|
private onModeChanged;
|
|
63
79
|
constructor(renderer: Renderer, camera: Camera, canvas: HTMLCanvasElement, controls: OrbitControls, meshRenderer: MeshRenderer);
|
|
@@ -69,6 +85,41 @@ export declare class HotspotManager {
|
|
|
69
85
|
getHotspots(): HotspotInfo[];
|
|
70
86
|
setOnHotspotPlaced(cb: ((info: HotspotInfo) => void) | null): void;
|
|
71
87
|
setOnModeChanged(cb: ((active: boolean) => void) | null): void;
|
|
88
|
+
private initLabelContainer;
|
|
89
|
+
/**
|
|
90
|
+
* 设置热点标签
|
|
91
|
+
*/
|
|
92
|
+
setHotspotLabel(hotspotIndex: number, text: string, position?: HotspotLabelPosition, fontSize?: number, visible?: boolean): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* 设置热点标签可见性
|
|
95
|
+
*/
|
|
96
|
+
setHotspotLabelVisible(hotspotIndex: number, visible: boolean): boolean;
|
|
97
|
+
/**
|
|
98
|
+
* 获取热点标签配置
|
|
99
|
+
*/
|
|
100
|
+
getHotspotLabel(hotspotIndex: number): HotspotLabelConfig | null;
|
|
101
|
+
private ensureLabelElement;
|
|
102
|
+
private applyLabelStyle;
|
|
103
|
+
/**
|
|
104
|
+
* 每帧更新所有标签的屏幕位置
|
|
105
|
+
*/
|
|
106
|
+
updateLabels(): void;
|
|
107
|
+
/**
|
|
108
|
+
* 设置热点点击回调
|
|
109
|
+
*/
|
|
110
|
+
setOnHotspotClicked(cb: ((hotspotIndex: number, info: HotspotInfo) => void) | null): void;
|
|
111
|
+
private _clickListenerBound;
|
|
112
|
+
private _boundOnCanvasClick;
|
|
113
|
+
private _onCanvasClick;
|
|
114
|
+
/**
|
|
115
|
+
* 检测给定屏幕坐标命中了哪个热点
|
|
116
|
+
* @returns 热点索引,-1 表示未命中
|
|
117
|
+
*/
|
|
118
|
+
hitTestHotspot(clientX: number, clientY: number): number;
|
|
119
|
+
/**
|
|
120
|
+
* 设置热点点击命中半径(NDC 空间,默认 0.05)
|
|
121
|
+
*/
|
|
122
|
+
setHotspotHitRadius(radius: number): void;
|
|
72
123
|
private pickPixelX;
|
|
73
124
|
private pickPixelY;
|
|
74
125
|
private lastClientX;
|
|
@@ -130,6 +181,12 @@ export declare class HotspotManager {
|
|
|
130
181
|
* 通过 overlay mesh 起始索引找到对应的热点索引
|
|
131
182
|
*/
|
|
132
183
|
findHotspotIndexByMeshStart(overlayMeshStartIndex: number): number;
|
|
184
|
+
/**
|
|
185
|
+
* 在指定位置和法线方向程序化放置一个热点(用于从保存数据恢复)。
|
|
186
|
+
* 逻辑与交互放置一致:加载 OBJ → 计算朝向矩阵 → addOverlayMesh → 注册到内部列表。
|
|
187
|
+
* @returns 放置后的 HotspotInfo,失败返回 null
|
|
188
|
+
*/
|
|
189
|
+
placeHotspotAt(objUrl: string, position: Vec3Tuple, normal: Vec3Tuple, visualDiameter?: number, normalOffset?: number, overrideScale?: number): Promise<HotspotInfo | null>;
|
|
133
190
|
/**
|
|
134
191
|
* 每帧调用:更新所有 billboard 热点朝向相机
|
|
135
192
|
*/
|