@d5techs/3dgs-lib 1.0.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 +236 -0
- package/dist/3dgs-lib.cjs +12012 -0
- package/dist/3dgs-lib.cjs.map +1 -0
- package/dist/3dgs-lib.js +12012 -0
- package/dist/3dgs-lib.js.map +1 -0
- package/dist/App.d.ts +142 -0
- package/dist/core/BoundingBoxRenderer.d.ts +70 -0
- package/dist/core/Camera.d.ts +38 -0
- package/dist/core/OrbitControls.d.ts +101 -0
- package/dist/core/Renderer.d.ts +69 -0
- package/dist/core/ViewportGizmo.d.ts +83 -0
- package/dist/core/gizmo/ArcShape.d.ts +90 -0
- package/dist/core/gizmo/ArrowShape.d.ts +51 -0
- package/dist/core/gizmo/BoxLineShape.d.ts +47 -0
- package/dist/core/gizmo/PlaneShape.d.ts +48 -0
- package/dist/core/gizmo/Shape.d.ts +117 -0
- package/dist/core/gizmo/SphereShape.d.ts +29 -0
- package/dist/core/gizmo/TransformGizmoV2.d.ts +203 -0
- package/dist/core/gizmo/index.d.ts +14 -0
- package/dist/core/math/Mat4.d.ts +38 -0
- package/dist/core/math/Quat.d.ts +52 -0
- package/dist/core/math/Ray.d.ts +65 -0
- package/dist/core/math/Vec3.d.ts +39 -0
- package/dist/gs/GSSplatRenderer.d.ts +217 -0
- package/dist/gs/GSSplatRendererMobile.d.ts +147 -0
- package/dist/gs/GSSplatSorter.d.ts +105 -0
- package/dist/gs/GSSplatSorterMobile.d.ts +86 -0
- package/dist/gs/IGSSplatRenderer.d.ts +123 -0
- package/dist/gs/PLYLoader.d.ts +22 -0
- package/dist/gs/PLYLoaderMobile.d.ts +62 -0
- package/dist/gs/SplatLoader.d.ts +25 -0
- package/dist/gs/TextureCompressor.d.ts +57 -0
- package/dist/index.d.ts +44 -0
- package/dist/interaction/GizmoManager.d.ts +132 -0
- package/dist/loaders/GLBLoader.d.ts +67 -0
- package/dist/loaders/MTLParser.d.ts +65 -0
- package/dist/loaders/OBJLoader.d.ts +68 -0
- package/dist/loaders/OBJParser.d.ts +115 -0
- package/dist/mesh/Mesh.d.ts +52 -0
- package/dist/mesh/MeshRenderer.d.ts +74 -0
- package/dist/scene/SceneManager.d.ts +136 -0
- package/package.json +62 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PLYLoaderMobile - 移动端优化的 PLY 加载器
|
|
3
|
+
*
|
|
4
|
+
* 优化点:
|
|
5
|
+
* 1. 直接输出 GPU buffer 格式,避免中间对象
|
|
6
|
+
* 2. 流式降采样,减少内存峰值
|
|
7
|
+
* 3. 可选跳过 SH 系数(移动端 L0 模式)
|
|
8
|
+
* 4. 使用 TypedArray 而非对象数组
|
|
9
|
+
* 5. 支持多种 PLY 数据类型
|
|
10
|
+
* 6. 确定性采样(基于文件内容的种子)
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* 移动端加载配置
|
|
14
|
+
*/
|
|
15
|
+
export interface MobileLoadOptions {
|
|
16
|
+
/** 最大 splat 数量,超过则降采样 */
|
|
17
|
+
maxSplats?: number;
|
|
18
|
+
/** 是否加载 SH 系数(false 时只加载 DC 颜色) */
|
|
19
|
+
loadSH?: boolean;
|
|
20
|
+
/** 进度回调 */
|
|
21
|
+
onProgress?: (loaded: number, total: number) => void;
|
|
22
|
+
/** 随机种子(用于确定性采样,默认使用文件大小作为种子) */
|
|
23
|
+
seed?: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 紧凑 Splat 数据(用于移动端)
|
|
27
|
+
* 直接返回 Float32Array,而非对象数组
|
|
28
|
+
*/
|
|
29
|
+
export interface CompactSplatData {
|
|
30
|
+
/** splat 数量 */
|
|
31
|
+
count: number;
|
|
32
|
+
/** 位置数据 Float32Array [x,y,z, x,y,z, ...] */
|
|
33
|
+
positions: Float32Array;
|
|
34
|
+
/** 缩放数据 Float32Array [sx,sy,sz, sx,sy,sz, ...] */
|
|
35
|
+
scales: Float32Array;
|
|
36
|
+
/** 旋转四元数 Float32Array [w,x,y,z, w,x,y,z, ...] */
|
|
37
|
+
rotations: Float32Array;
|
|
38
|
+
/** DC 颜色 Float32Array [r,g,b, r,g,b, ...] */
|
|
39
|
+
colors: Float32Array;
|
|
40
|
+
/** 不透明度 Float32Array [a, a, ...] */
|
|
41
|
+
opacities: Float32Array;
|
|
42
|
+
/** SH 系数(可选)Float32Array,每个 splat 45 个系数 */
|
|
43
|
+
shCoeffs?: Float32Array;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* 移动端优化的 PLY 加载器
|
|
47
|
+
* 直接输出紧凑格式,避免创建大量中间对象
|
|
48
|
+
*/
|
|
49
|
+
export declare function loadPLYMobile(url: string, options?: MobileLoadOptions): Promise<CompactSplatData>;
|
|
50
|
+
/**
|
|
51
|
+
* 解析 PLY ArrayBuffer
|
|
52
|
+
* 可以直接传入 ArrayBuffer 进行解析,用于本地文件加载
|
|
53
|
+
*/
|
|
54
|
+
export declare function parsePLYBuffer(buffer: ArrayBuffer, options?: MobileLoadOptions): Promise<CompactSplatData>;
|
|
55
|
+
/**
|
|
56
|
+
* 将 CompactSplatData 转换为 GPU buffer 格式
|
|
57
|
+
* 直接输出可以上传到 GPU 的 Float32Array
|
|
58
|
+
*
|
|
59
|
+
* @param data 紧凑 splat 数据
|
|
60
|
+
* @param includeFullSH 是否包含完整 SH 系数(256 字节/splat),否则只包含基本数据(64 字节/splat)
|
|
61
|
+
*/
|
|
62
|
+
export declare function compactDataToGPUBuffer(data: CompactSplatData, includeFullSH?: boolean): Float32Array;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SplatLoader - 加载 .splat 格式的 3D Gaussian Splatting 文件
|
|
3
|
+
*
|
|
4
|
+
* .splat 格式是一种紧凑的 3DGS 数据格式:
|
|
5
|
+
* - 每个 splat 固定 32 字节,无文件头
|
|
6
|
+
* - 数据布局: position(12) + scale(12) + color(3) + opacity(1) + rotation(4)
|
|
7
|
+
* - 不包含高阶球谐系数,仅 DC 颜色
|
|
8
|
+
*
|
|
9
|
+
* 四元数顺序: [w, x, y, z](与 PLYLoader 保持一致)
|
|
10
|
+
*
|
|
11
|
+
* 参考: supersplat/src/loaders/splat.ts
|
|
12
|
+
*/
|
|
13
|
+
import { SplatCPU } from "./PLYLoader";
|
|
14
|
+
/**
|
|
15
|
+
* 加载并解析 .splat 文件
|
|
16
|
+
* @param url .splat 文件的 URL
|
|
17
|
+
* @returns SplatCPU 数组
|
|
18
|
+
*/
|
|
19
|
+
export declare function loadSplat(url: string): Promise<SplatCPU[]>;
|
|
20
|
+
/**
|
|
21
|
+
* 从 ArrayBuffer 解析 splat 数据
|
|
22
|
+
* @param data 文件的 ArrayBuffer
|
|
23
|
+
* @returns SplatCPU 数组
|
|
24
|
+
*/
|
|
25
|
+
export declare function deserializeSplat(data: ArrayBufferLike): SplatCPU[];
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TextureCompressor - 移动端纹理压缩工具
|
|
3
|
+
* 将 splat 数据压缩为纹理格式,大幅减少 GPU 内存占用
|
|
4
|
+
*
|
|
5
|
+
* 内存对比:
|
|
6
|
+
* - 原始 Storage Buffer: 256 bytes/splat
|
|
7
|
+
* - 纹理压缩: ~52 bytes/splat (约 5x 压缩)
|
|
8
|
+
*
|
|
9
|
+
* 数据布局(保证精度):
|
|
10
|
+
* - positionTexture (RGBA32Float): x, y, z, unused - 16 bytes
|
|
11
|
+
* - scaleRotTexture1 (RGBA32Float): scale_x, scale_y, scale_z, rot_w - 16 bytes
|
|
12
|
+
* - scaleRotTexture2 (RGBA32Float): rot_x, rot_y, rot_z, unused - 16 bytes
|
|
13
|
+
* - colorTexture (RGBA8Unorm): r, g, b, opacity - 4 bytes
|
|
14
|
+
* 总计: 52 bytes/splat
|
|
15
|
+
*
|
|
16
|
+
* 注意:使用 RGBA32Float 替代 RGBA16Float 以保证 scale 和 rotation 的精度,
|
|
17
|
+
* 避免平面等细节渲染出现块状伪影。
|
|
18
|
+
*/
|
|
19
|
+
import { CompactSplatData } from "./PLYLoaderMobile";
|
|
20
|
+
/**
|
|
21
|
+
* 压缩后的纹理数据
|
|
22
|
+
*/
|
|
23
|
+
export interface CompressedSplatTextures {
|
|
24
|
+
width: number;
|
|
25
|
+
height: number;
|
|
26
|
+
count: number;
|
|
27
|
+
positionTexture: GPUTexture;
|
|
28
|
+
scaleRotTexture1: GPUTexture;
|
|
29
|
+
scaleRotTexture2: GPUTexture;
|
|
30
|
+
colorTexture: GPUTexture;
|
|
31
|
+
boundingBox: {
|
|
32
|
+
min: [number, number, number];
|
|
33
|
+
max: [number, number, number];
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* 计算纹理尺寸
|
|
38
|
+
* 将 splat 数量映射到 2D 纹理尺寸
|
|
39
|
+
* @param count splat 数量
|
|
40
|
+
* @returns 纹理宽度和高度(向上取整到 4 的倍数)
|
|
41
|
+
*/
|
|
42
|
+
export declare function calculateTextureDimensions(count: number): {
|
|
43
|
+
width: number;
|
|
44
|
+
height: number;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* 将 splat 数据压缩为纹理格式
|
|
48
|
+
* @param device GPU 设备
|
|
49
|
+
* @param data 紧凑格式的 splat 数据
|
|
50
|
+
* @returns 压缩后的纹理数据
|
|
51
|
+
*/
|
|
52
|
+
export declare function compressSplatsToTextures(device: GPUDevice, data: CompactSplatData): CompressedSplatTextures;
|
|
53
|
+
/**
|
|
54
|
+
* 销毁压缩纹理资源
|
|
55
|
+
* @param textures 压缩纹理数据
|
|
56
|
+
*/
|
|
57
|
+
export declare function destroyCompressedTextures(textures: CompressedSplatTextures): void;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebGPU 3D 渲染引擎
|
|
3
|
+
* 库入口文件 - 导出所有公共 API
|
|
4
|
+
*/
|
|
5
|
+
export { Renderer } from './core/Renderer';
|
|
6
|
+
export { Camera } from './core/Camera';
|
|
7
|
+
export { OrbitControls } from './core/OrbitControls';
|
|
8
|
+
export { ViewportGizmo } from './core/ViewportGizmo';
|
|
9
|
+
export { BoundingBoxRenderer } from './core/BoundingBoxRenderer';
|
|
10
|
+
export type { BoundingBox as SelectionBoundingBox, BoundingBoxProvider } from './core/BoundingBoxRenderer';
|
|
11
|
+
export { Mesh } from './mesh/Mesh';
|
|
12
|
+
export type { MeshBoundingBox } from './mesh/Mesh';
|
|
13
|
+
export { MeshRenderer } from './mesh/MeshRenderer';
|
|
14
|
+
export { GLBLoader } from './loaders/GLBLoader';
|
|
15
|
+
export type { MaterialData, LoadedMesh } from './loaders/GLBLoader';
|
|
16
|
+
export { OBJLoader } from './loaders/OBJLoader';
|
|
17
|
+
export { OBJParser } from './loaders/OBJParser';
|
|
18
|
+
export type { ParsedOBJData, ParsedObject } from './loaders/OBJParser';
|
|
19
|
+
export { MTLParser } from './loaders/MTLParser';
|
|
20
|
+
export type { ParsedMaterial } from './loaders/MTLParser';
|
|
21
|
+
export type { IGSSplatRenderer, IGSSplatRendererWithCapabilities, RendererCapabilities, BoundingBox, SHMode } from './gs/IGSSplatRenderer';
|
|
22
|
+
export { loadPLY } from './gs/PLYLoader';
|
|
23
|
+
export type { SplatCPU } from './gs/PLYLoader';
|
|
24
|
+
export { loadPLYMobile, parsePLYBuffer, compactDataToGPUBuffer } from './gs/PLYLoaderMobile';
|
|
25
|
+
export type { MobileLoadOptions, CompactSplatData } from './gs/PLYLoaderMobile';
|
|
26
|
+
export { loadSplat, deserializeSplat } from './gs/SplatLoader';
|
|
27
|
+
export { GSSplatRenderer, PerformanceTier } from './gs/GSSplatRenderer';
|
|
28
|
+
export { SHMode as GSSHMode } from './gs/GSSplatRenderer';
|
|
29
|
+
export type { MobileOptimizationConfig } from './gs/GSSplatRenderer';
|
|
30
|
+
export { GSSplatSorter } from './gs/GSSplatSorter';
|
|
31
|
+
export type { SorterOptions, CullingOptions, ScreenInfo } from './gs/GSSplatSorter';
|
|
32
|
+
export { GSSplatRendererMobile } from './gs/GSSplatRendererMobile';
|
|
33
|
+
export { GSSplatSorterMobile } from './gs/GSSplatSorterMobile';
|
|
34
|
+
export type { SorterOptions as MobileSorterOptions, CullingOptions as MobileCullingOptions } from './gs/GSSplatSorterMobile';
|
|
35
|
+
export { compressSplatsToTextures, destroyCompressedTextures, calculateTextureDimensions } from './gs/TextureCompressor';
|
|
36
|
+
export type { CompressedSplatTextures } from './gs/TextureCompressor';
|
|
37
|
+
export { SceneManager } from './scene/SceneManager';
|
|
38
|
+
export type { SceneObjectType, SceneObjectInfo } from './scene/SceneManager';
|
|
39
|
+
export { GizmoManager, SplatTransformProxy as GizmoSplatTransformProxy, MeshGroupProxy as GizmoMeshGroupProxy, SplatBoundingBoxProvider as GizmoSplatBoundingBoxProvider } from './interaction/GizmoManager';
|
|
40
|
+
export { App, SplatTransformProxy, MeshGroupProxy, SplatBoundingBoxProvider } from './App';
|
|
41
|
+
export type { ProgressCallback } from './App';
|
|
42
|
+
export type { TransformableObject } from './core/gizmo/TransformGizmoV2';
|
|
43
|
+
export { TransformGizmoV2, GizmoMode } from './core/gizmo/TransformGizmoV2';
|
|
44
|
+
export type { GizmoTheme, TransformGizmoConfig, GizmoSpace } from './core/gizmo/TransformGizmoV2';
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GizmoManager - Gizmo 交互管理器
|
|
3
|
+
*
|
|
4
|
+
* 负责管理所有 Gizmo 相关的交互:
|
|
5
|
+
* - TransformGizmo(变换控制)
|
|
6
|
+
* - ViewportGizmo(视口坐标轴)
|
|
7
|
+
* - BoundingBoxRenderer(选中对象包围盒)
|
|
8
|
+
*/
|
|
9
|
+
import { Renderer } from "../core/Renderer";
|
|
10
|
+
import { Camera } from "../core/Camera";
|
|
11
|
+
import { OrbitControls } from "../core/OrbitControls";
|
|
12
|
+
import { ViewportGizmo } from "../core/ViewportGizmo";
|
|
13
|
+
import { TransformGizmoV2, TransformableObject, GizmoMode } from "../core/gizmo/TransformGizmoV2";
|
|
14
|
+
import { BoundingBoxRenderer, BoundingBox as RendererBoundingBox, BoundingBoxProvider } from "../core/BoundingBoxRenderer";
|
|
15
|
+
import { IGSSplatRenderer } from "../gs/IGSSplatRenderer";
|
|
16
|
+
import { Mesh } from "../mesh/Mesh";
|
|
17
|
+
/**
|
|
18
|
+
* SplatTransformProxy - PLY/Splat 变换代理对象
|
|
19
|
+
* 实现类似 Mesh 的接口,让 TransformGizmo 可以操作 PLY 模型
|
|
20
|
+
*/
|
|
21
|
+
export declare class SplatTransformProxy implements TransformableObject {
|
|
22
|
+
position: [number, number, number];
|
|
23
|
+
rotation: [number, number, number];
|
|
24
|
+
scale: [number, number, number];
|
|
25
|
+
private renderer;
|
|
26
|
+
private center;
|
|
27
|
+
constructor(renderer: IGSSplatRenderer, center: [number, number, number]);
|
|
28
|
+
setPosition(x: number, y: number, z: number): void;
|
|
29
|
+
setRotation(x: number, y: number, z: number): void;
|
|
30
|
+
setScale(x: number, y: number, z: number): void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* MeshGroupProxy - 多 Mesh 组变换代理对象
|
|
34
|
+
* 让 TransformGizmo 可以同时操作多个 Mesh
|
|
35
|
+
*/
|
|
36
|
+
export declare class MeshGroupProxy implements TransformableObject {
|
|
37
|
+
position: [number, number, number];
|
|
38
|
+
rotation: [number, number, number];
|
|
39
|
+
scale: [number, number, number];
|
|
40
|
+
private meshes;
|
|
41
|
+
constructor(meshes: Mesh[]);
|
|
42
|
+
setPosition(x: number, y: number, z: number): void;
|
|
43
|
+
setRotation(x: number, y: number, z: number): void;
|
|
44
|
+
setScale(x: number, y: number, z: number): void;
|
|
45
|
+
getBoundingBox(): RendererBoundingBox | null;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* SplatBoundingBoxProvider - PLY/Splat 包围盒提供者
|
|
49
|
+
* 动态获取 PLY 的包围盒(考虑变换)
|
|
50
|
+
*/
|
|
51
|
+
export declare class SplatBoundingBoxProvider implements BoundingBoxProvider {
|
|
52
|
+
private renderer;
|
|
53
|
+
constructor(renderer: IGSSplatRenderer);
|
|
54
|
+
getBoundingBox(): RendererBoundingBox | null;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* GizmoManager - Gizmo 交互管理器
|
|
58
|
+
*/
|
|
59
|
+
export declare class GizmoManager {
|
|
60
|
+
private renderer;
|
|
61
|
+
private camera;
|
|
62
|
+
private canvas;
|
|
63
|
+
private controls;
|
|
64
|
+
private viewportGizmo;
|
|
65
|
+
private transformGizmo;
|
|
66
|
+
private boundingBoxRenderer;
|
|
67
|
+
private boundOnClick;
|
|
68
|
+
private boundOnPointerMove;
|
|
69
|
+
private boundOnPointerDown;
|
|
70
|
+
private boundOnPointerUp;
|
|
71
|
+
constructor(renderer: Renderer, camera: Camera, canvas: HTMLCanvasElement, controls: OrbitControls);
|
|
72
|
+
/**
|
|
73
|
+
* 设置事件监听器
|
|
74
|
+
*/
|
|
75
|
+
private setupEventListeners;
|
|
76
|
+
private onCanvasClick;
|
|
77
|
+
private onPointerMove;
|
|
78
|
+
private onPointerDown;
|
|
79
|
+
private onPointerUp;
|
|
80
|
+
/**
|
|
81
|
+
* 渲染所有 Gizmo
|
|
82
|
+
*/
|
|
83
|
+
render(pass: GPURenderPassEncoder): void;
|
|
84
|
+
/**
|
|
85
|
+
* 获取变换 Gizmo
|
|
86
|
+
*/
|
|
87
|
+
getTransformGizmo(): TransformGizmoV2;
|
|
88
|
+
/**
|
|
89
|
+
* 设置 Gizmo 模式
|
|
90
|
+
*/
|
|
91
|
+
setGizmoMode(mode: GizmoMode): void;
|
|
92
|
+
/**
|
|
93
|
+
* 设置 Gizmo 目标对象
|
|
94
|
+
*/
|
|
95
|
+
setGizmoTarget(object: TransformableObject | null): void;
|
|
96
|
+
/**
|
|
97
|
+
* 获取视口 Gizmo
|
|
98
|
+
*/
|
|
99
|
+
getViewportGizmo(): ViewportGizmo;
|
|
100
|
+
/**
|
|
101
|
+
* 获取包围盒渲染器
|
|
102
|
+
*/
|
|
103
|
+
getBoundingBoxRenderer(): BoundingBoxRenderer;
|
|
104
|
+
/**
|
|
105
|
+
* 设置选中对象的包围盒(静态模式)
|
|
106
|
+
*/
|
|
107
|
+
setSelectionBoundingBox(box: RendererBoundingBox | null): void;
|
|
108
|
+
/**
|
|
109
|
+
* 设置选中对象的包围盒提供者(动态模式)
|
|
110
|
+
*/
|
|
111
|
+
setSelectionBoundingBoxProvider(provider: BoundingBoxProvider | null): void;
|
|
112
|
+
/**
|
|
113
|
+
* 清除选中对象的包围盒
|
|
114
|
+
*/
|
|
115
|
+
clearSelectionBoundingBox(): void;
|
|
116
|
+
/**
|
|
117
|
+
* 创建 Splat 变换代理
|
|
118
|
+
*/
|
|
119
|
+
createSplatTransformProxy(renderer: IGSSplatRenderer): SplatTransformProxy | null;
|
|
120
|
+
/**
|
|
121
|
+
* 创建 Mesh 组变换代理
|
|
122
|
+
*/
|
|
123
|
+
createMeshGroupProxy(meshes: Mesh[]): MeshGroupProxy | null;
|
|
124
|
+
/**
|
|
125
|
+
* 创建 Splat 包围盒提供者
|
|
126
|
+
*/
|
|
127
|
+
createSplatBoundingBoxProvider(renderer: IGSSplatRenderer): SplatBoundingBoxProvider;
|
|
128
|
+
/**
|
|
129
|
+
* 销毁
|
|
130
|
+
*/
|
|
131
|
+
destroy(): void;
|
|
132
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Mesh } from '../mesh/Mesh';
|
|
2
|
+
/**
|
|
3
|
+
* 材质数据
|
|
4
|
+
*/
|
|
5
|
+
export interface MaterialData {
|
|
6
|
+
baseColorFactor: [number, number, number, number];
|
|
7
|
+
baseColorTexture: GPUTexture | null;
|
|
8
|
+
metallicFactor: number;
|
|
9
|
+
roughnessFactor: number;
|
|
10
|
+
doubleSided: boolean;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* 加载后的 Mesh 数据(包含材质)
|
|
14
|
+
*/
|
|
15
|
+
export interface LoadedMesh {
|
|
16
|
+
mesh: Mesh;
|
|
17
|
+
material: MaterialData;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* GLBLoader - GLB 文件加载器
|
|
21
|
+
* 解析 GLB 文件并生成 Mesh[],支持贴图
|
|
22
|
+
*/
|
|
23
|
+
export declare class GLBLoader {
|
|
24
|
+
private device;
|
|
25
|
+
private textureCache;
|
|
26
|
+
constructor(device: GPUDevice);
|
|
27
|
+
/**
|
|
28
|
+
* 加载 GLB 文件
|
|
29
|
+
*/
|
|
30
|
+
load(url: string): Promise<LoadedMesh[]>;
|
|
31
|
+
/**
|
|
32
|
+
* 解析 GLB 二进制数据
|
|
33
|
+
*/
|
|
34
|
+
private parse;
|
|
35
|
+
/**
|
|
36
|
+
* 解析所有网格
|
|
37
|
+
*/
|
|
38
|
+
private parseMeshes;
|
|
39
|
+
/**
|
|
40
|
+
* 解析单个图元
|
|
41
|
+
*/
|
|
42
|
+
private parsePrimitive;
|
|
43
|
+
/**
|
|
44
|
+
* 解析材质
|
|
45
|
+
*/
|
|
46
|
+
private parseMaterial;
|
|
47
|
+
/**
|
|
48
|
+
* 加载纹理
|
|
49
|
+
*/
|
|
50
|
+
private loadTexture;
|
|
51
|
+
/**
|
|
52
|
+
* 计算顶点数据的 bounding box
|
|
53
|
+
*/
|
|
54
|
+
private computeBoundingBox;
|
|
55
|
+
/**
|
|
56
|
+
* 获取访问器数据 - 修复字节对齐问题
|
|
57
|
+
*/
|
|
58
|
+
private getAccessorData;
|
|
59
|
+
/**
|
|
60
|
+
* 创建测试立方体(用于调试)
|
|
61
|
+
*/
|
|
62
|
+
createTestCube(): LoadedMesh;
|
|
63
|
+
/**
|
|
64
|
+
* 创建测试球体
|
|
65
|
+
*/
|
|
66
|
+
createTestSphere(radius?: number, segments?: number, rings?: number): LoadedMesh;
|
|
67
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MTLParser - MTL 材质文件解析器
|
|
3
|
+
* 解析 MTL 文件文本内容,提取材质数据
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* 解析后的材质数据
|
|
7
|
+
*/
|
|
8
|
+
export interface ParsedMaterial {
|
|
9
|
+
name: string;
|
|
10
|
+
diffuseColor: [number, number, number];
|
|
11
|
+
diffuseTexture: string | null;
|
|
12
|
+
opacity: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* MTL 文本解析器
|
|
16
|
+
*/
|
|
17
|
+
export declare class MTLParser {
|
|
18
|
+
private currentMaterial;
|
|
19
|
+
private materials;
|
|
20
|
+
/**
|
|
21
|
+
* 解析 MTL 文本内容
|
|
22
|
+
* @param text MTL 文件文本
|
|
23
|
+
* @returns 材质名称到材质数据的映射
|
|
24
|
+
*/
|
|
25
|
+
parse(text: string): Map<string, ParsedMaterial>;
|
|
26
|
+
/**
|
|
27
|
+
* 重置解析器状态
|
|
28
|
+
*/
|
|
29
|
+
private reset;
|
|
30
|
+
/**
|
|
31
|
+
* 解析单行
|
|
32
|
+
*/
|
|
33
|
+
private parseLine;
|
|
34
|
+
/**
|
|
35
|
+
* 解析新材质定义 (newmtl name)
|
|
36
|
+
*/
|
|
37
|
+
private parseNewMaterial;
|
|
38
|
+
/**
|
|
39
|
+
* 解析漫反射颜色 (Kd r g b)
|
|
40
|
+
*/
|
|
41
|
+
private parseDiffuseColor;
|
|
42
|
+
/**
|
|
43
|
+
* 解析漫反射纹理路径 (map_Kd path)
|
|
44
|
+
*/
|
|
45
|
+
private parseDiffuseTexture;
|
|
46
|
+
/**
|
|
47
|
+
* 解析透明度 (d factor)
|
|
48
|
+
* d = 1.0 表示完全不透明,d = 0.0 表示完全透明
|
|
49
|
+
*/
|
|
50
|
+
private parseOpacity;
|
|
51
|
+
/**
|
|
52
|
+
* 解析透明度 (Tr factor)
|
|
53
|
+
* Tr = 0.0 表示完全不透明,Tr = 1.0 表示完全透明
|
|
54
|
+
* 与 d 相反,所以 opacity = 1 - Tr
|
|
55
|
+
*/
|
|
56
|
+
private parseTransparency;
|
|
57
|
+
/**
|
|
58
|
+
* 创建默认材质
|
|
59
|
+
*/
|
|
60
|
+
private createDefaultMaterial;
|
|
61
|
+
/**
|
|
62
|
+
* 完成当前材质并添加到映射
|
|
63
|
+
*/
|
|
64
|
+
private finalizeCurrentMaterial;
|
|
65
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OBJLoader - OBJ 文件加载器
|
|
3
|
+
* 解析 OBJ 文件并生成 Mesh[],支持 MTL 材质
|
|
4
|
+
*/
|
|
5
|
+
import { LoadedMesh } from './GLBLoader';
|
|
6
|
+
/**
|
|
7
|
+
* OBJLoader - OBJ 文件加载器
|
|
8
|
+
* 解析 OBJ 文件并生成 LoadedMesh[]
|
|
9
|
+
*/
|
|
10
|
+
export declare class OBJLoader {
|
|
11
|
+
private device;
|
|
12
|
+
private textureCache;
|
|
13
|
+
constructor(device: GPUDevice);
|
|
14
|
+
/**
|
|
15
|
+
* 加载 OBJ 文件
|
|
16
|
+
* @param url OBJ 文件 URL
|
|
17
|
+
* @returns 加载后的网格数组
|
|
18
|
+
*
|
|
19
|
+
* Requirements: 2.1, 2.2, 2.3
|
|
20
|
+
*/
|
|
21
|
+
load(url: string): Promise<LoadedMesh[]>;
|
|
22
|
+
/**
|
|
23
|
+
* 从文本解析 OBJ(用于直接传入内容)
|
|
24
|
+
* @param text OBJ 文本内容
|
|
25
|
+
* @param baseUrl 基础 URL(用于加载 MTL 和纹理)
|
|
26
|
+
* @returns 加载后的网格数组
|
|
27
|
+
*
|
|
28
|
+
* Requirements: 2.1, 2.3
|
|
29
|
+
*/
|
|
30
|
+
parseFromText(text: string, baseUrl?: string): Promise<LoadedMesh[]>;
|
|
31
|
+
/**
|
|
32
|
+
* 提取 MTL 文件引用
|
|
33
|
+
*/
|
|
34
|
+
private extractMTLReference;
|
|
35
|
+
/**
|
|
36
|
+
* 加载 MTL 材质文件
|
|
37
|
+
* Requirement 4.1, 4.4: 加载 MTL 文件,失败时使用默认材质
|
|
38
|
+
*/
|
|
39
|
+
private loadMTL;
|
|
40
|
+
/**
|
|
41
|
+
* 创建 LoadedMesh 数组
|
|
42
|
+
*/
|
|
43
|
+
private createMeshes;
|
|
44
|
+
/**
|
|
45
|
+
* 创建单个 Mesh
|
|
46
|
+
*/
|
|
47
|
+
private createMesh;
|
|
48
|
+
/**
|
|
49
|
+
* 生成平面法线(当 OBJ 缺少法线数据时)
|
|
50
|
+
* Requirement 3.2: 从面几何计算平面法线
|
|
51
|
+
*/
|
|
52
|
+
private generateFlatNormals;
|
|
53
|
+
/**
|
|
54
|
+
* 计算顶点数据的 bounding box
|
|
55
|
+
* Requirement 3.5: 计算并存储 bounding box 信息
|
|
56
|
+
*/
|
|
57
|
+
private computeBoundingBox;
|
|
58
|
+
/**
|
|
59
|
+
* 创建材质数据
|
|
60
|
+
* Requirement 4.3: 将材质关联到网格
|
|
61
|
+
*/
|
|
62
|
+
private createMaterial;
|
|
63
|
+
/**
|
|
64
|
+
* 加载纹理
|
|
65
|
+
* Requirement 4.5, 6.3: 加载纹理,失败时使用 null
|
|
66
|
+
*/
|
|
67
|
+
private loadTexture;
|
|
68
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OBJParser - OBJ 文件文本解析器
|
|
3
|
+
* 解析 OBJ 文件文本内容,提取几何数据
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* 解析后的 OBJ 数据结构
|
|
7
|
+
*/
|
|
8
|
+
export interface ParsedOBJData {
|
|
9
|
+
objects: ParsedObject[];
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* 单个对象/组的数据
|
|
13
|
+
*/
|
|
14
|
+
export interface ParsedObject {
|
|
15
|
+
name: string;
|
|
16
|
+
positions: number[];
|
|
17
|
+
normals: number[];
|
|
18
|
+
uvs: number[];
|
|
19
|
+
indices: number[];
|
|
20
|
+
materialName: string | null;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* OBJ 文本解析器
|
|
24
|
+
*/
|
|
25
|
+
export declare class OBJParser {
|
|
26
|
+
private positions;
|
|
27
|
+
private uvs;
|
|
28
|
+
private normals;
|
|
29
|
+
private currentObject;
|
|
30
|
+
private objects;
|
|
31
|
+
private currentMaterial;
|
|
32
|
+
private vertexMap;
|
|
33
|
+
private vertexCount;
|
|
34
|
+
private warnedDirectives;
|
|
35
|
+
/**
|
|
36
|
+
* 解析 OBJ 文本内容
|
|
37
|
+
* @param text OBJ 文件文本
|
|
38
|
+
* @returns 解析后的数据结构
|
|
39
|
+
*/
|
|
40
|
+
parse(text: string): ParsedOBJData;
|
|
41
|
+
/**
|
|
42
|
+
* 重置解析器状态
|
|
43
|
+
*/
|
|
44
|
+
private reset;
|
|
45
|
+
/**
|
|
46
|
+
* 警告不支持的指令(仅首次出现时警告)
|
|
47
|
+
* @param directive 指令名称
|
|
48
|
+
* @param lineNum 行号
|
|
49
|
+
*/
|
|
50
|
+
private warnUnsupportedDirective;
|
|
51
|
+
/**
|
|
52
|
+
* 解析单行
|
|
53
|
+
*/
|
|
54
|
+
private parseLine;
|
|
55
|
+
/**
|
|
56
|
+
* 解析顶点位置 (v x y z [w])
|
|
57
|
+
*/
|
|
58
|
+
private parseVertex;
|
|
59
|
+
/**
|
|
60
|
+
* 解析纹理坐标 (vt u [v] [w])
|
|
61
|
+
*/
|
|
62
|
+
private parseTextureCoord;
|
|
63
|
+
/**
|
|
64
|
+
* 解析法线 (vn x y z)
|
|
65
|
+
*/
|
|
66
|
+
private parseNormal;
|
|
67
|
+
/**
|
|
68
|
+
* 解析面 (f v1 v2 v3 ...)
|
|
69
|
+
* 支持四种格式:
|
|
70
|
+
* - f v v v (仅顶点)
|
|
71
|
+
* - f v/vt v/vt v/vt (顶点/纹理)
|
|
72
|
+
* - f v/vt/vn v/vt/vn v/vt/vn (顶点/纹理/法线)
|
|
73
|
+
* - f v//vn v//vn v//vn (顶点//法线)
|
|
74
|
+
*/
|
|
75
|
+
private parseFace;
|
|
76
|
+
/**
|
|
77
|
+
* 解析面顶点索引
|
|
78
|
+
* 支持格式: v, v/vt, v/vt/vn, v//vn
|
|
79
|
+
*/
|
|
80
|
+
private parseFaceVertex;
|
|
81
|
+
/**
|
|
82
|
+
* 解析索引,支持负索引
|
|
83
|
+
* 负索引表示相对于当前顶点数的偏移(-1 表示最后一个顶点)
|
|
84
|
+
*/
|
|
85
|
+
private resolveIndex;
|
|
86
|
+
/**
|
|
87
|
+
* 添加三角形到当前对象
|
|
88
|
+
*/
|
|
89
|
+
private addTriangle;
|
|
90
|
+
/**
|
|
91
|
+
* 添加顶点到当前对象,返回索引
|
|
92
|
+
* 使用顶点去重,相同的顶点组合只添加一次
|
|
93
|
+
*/
|
|
94
|
+
private addVertex;
|
|
95
|
+
/**
|
|
96
|
+
* 解析对象或组 (o name / g name)
|
|
97
|
+
*/
|
|
98
|
+
private parseObjectOrGroup;
|
|
99
|
+
/**
|
|
100
|
+
* 解析材质引用 (usemtl name)
|
|
101
|
+
*/
|
|
102
|
+
private parseUseMaterial;
|
|
103
|
+
/**
|
|
104
|
+
* 确保存在当前对象
|
|
105
|
+
*/
|
|
106
|
+
private ensureCurrentObject;
|
|
107
|
+
/**
|
|
108
|
+
* 创建新对象
|
|
109
|
+
*/
|
|
110
|
+
private createNewObject;
|
|
111
|
+
/**
|
|
112
|
+
* 完成当前对象并添加到列表
|
|
113
|
+
*/
|
|
114
|
+
private finalizeCurrentObject;
|
|
115
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bounding Box 结构(与 GSSplatRenderer 共享接口)
|
|
3
|
+
*/
|
|
4
|
+
export interface MeshBoundingBox {
|
|
5
|
+
min: [number, number, number];
|
|
6
|
+
max: [number, number, number];
|
|
7
|
+
center: [number, number, number];
|
|
8
|
+
radius: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Mesh - 网格数据结构
|
|
12
|
+
* 存储 GPUBuffer + 变换属性
|
|
13
|
+
*/
|
|
14
|
+
export declare class Mesh {
|
|
15
|
+
vertexBuffer: GPUBuffer;
|
|
16
|
+
indexBuffer: GPUBuffer | null;
|
|
17
|
+
vertexCount: number;
|
|
18
|
+
indexCount: number;
|
|
19
|
+
modelMatrix: Float32Array;
|
|
20
|
+
hasUV: boolean;
|
|
21
|
+
indexFormat: 'uint16' | 'uint32';
|
|
22
|
+
position: Float32Array;
|
|
23
|
+
rotation: Float32Array;
|
|
24
|
+
scale: Float32Array;
|
|
25
|
+
private localBoundingBox;
|
|
26
|
+
constructor(vertexBuffer: GPUBuffer, vertexCount: number, indexBuffer?: GPUBuffer | null, indexCount?: number, boundingBox?: MeshBoundingBox);
|
|
27
|
+
/**
|
|
28
|
+
* 获取顶点 stride(字节数)
|
|
29
|
+
*/
|
|
30
|
+
getVertexStride(): number;
|
|
31
|
+
/**
|
|
32
|
+
* 设置本地 bounding box
|
|
33
|
+
*/
|
|
34
|
+
setBoundingBox(bbox: MeshBoundingBox): void;
|
|
35
|
+
/**
|
|
36
|
+
* 获取本地 bounding box
|
|
37
|
+
*/
|
|
38
|
+
getLocalBoundingBox(): MeshBoundingBox | null;
|
|
39
|
+
/**
|
|
40
|
+
* 获取世界空间的 bounding box(考虑完整变换:缩放、旋转、平移)
|
|
41
|
+
*/
|
|
42
|
+
getWorldBoundingBox(): MeshBoundingBox | null;
|
|
43
|
+
setPosition(x: number, y: number, z: number): void;
|
|
44
|
+
getPosition(): [number, number, number];
|
|
45
|
+
setRotation(rx: number, ry: number, rz: number): void;
|
|
46
|
+
getRotation(): [number, number, number];
|
|
47
|
+
setScale(sx: number, sy: number, sz: number): void;
|
|
48
|
+
getScale(): [number, number, number];
|
|
49
|
+
updateModelMatrix(): void;
|
|
50
|
+
resetTransform(): void;
|
|
51
|
+
destroy(): void;
|
|
52
|
+
}
|