@wangyoumo/gs3d-loader
v1.0.0
Published
A comprehensive library for loading, parsing and rendering Gaussian Splats 3D models
Maintainers
Readme
GS3D-Loader
一个用于加载、解析和渲染 Gaussian Splats 3D 模型的私有 JavaScript 库。支持多种格式(PLY、Splat、KSplat),提供框架无关的核心功能和 Vue 3 适配器。
特性
- 📄 多格式支持: PLY、Splat、KSplat 格式
- 🎯 框架无关: 核心库不依赖任何前端框架
- ⚡ Vue 3 优化: 提供完整的 Vue 3 Composition API 集成
- 🔄 实时变换: 支持模型变换(位置、旋转、缩放)
- 🎨 场景管理: 基于 Three.js 的完整 3D 场景管理
- 📤 导出功能: 支持导出为 KSplat 格式
- ⚙️ 配置管理: 灵活的配置和设置管理
- 📊 进度跟踪: 文件加载进度和状态监控
安装
npm install @your-scope/gs3d-loader快速开始
Vue 3 项目
<template>
<div>
<div ref="sceneContainer" class="scene-container"></div>
<div class="controls">
<input
type="file"
ref="fileInput"
@change="handleFileSelect"
multiple
accept=".ply,.splat,.ksplat"
/>
<div v-if="loading" class="loading">
{{ loadingMessage }} - {{ Math.round(loadingProgress) }}%
</div>
<div class="models">
<div
v-for="model in modelList"
:key="model.id"
class="model-item"
:class="{ selected: model.id === selectedModelId }"
@click="selectModel(model.id)"
>
{{ model.name }}
<button @click.stop="removeModel(model.id)">删除</button>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { useGaussianSplats } from '@your-scope/gs3d-loader/vue'
const sceneContainer = ref(null)
const fileInput = ref(null)
const {
loading,
loadingMessage,
loadingProgress,
modelList,
selectedModelId,
init,
importFiles,
selectModel,
removeModel,
} = useGaussianSplats()
onMounted(async () => {
await init(sceneContainer.value)
})
const handleFileSelect = async (event) => {
const files = Array.from(event.target.files)
if (files.length > 0) {
await importFiles(files)
event.target.value = '' // 清空文件输入
}
}
</script>
<style scoped>
.scene-container {
width: 100%;
height: 500px;
border: 1px solid #ccc;
}
.controls {
margin-top: 20px;
}
.model-item {
padding: 10px;
border: 1px solid #ddd;
margin: 5px 0;
cursor: pointer;
}
.model-item.selected {
background-color: #e3f2fd;
}
</style>纯 JavaScript 项目
import { createGS3DLoader } from '@your-scope/gs3d-loader'
const loader = createGS3DLoader({
config: {
scene: {
autoRotate: true,
backgroundColor: 0x000000
}
}
})
// 初始化场景
const container = document.getElementById('scene-container')
await loader.init(container)
// 监听事件
loader.on('model:imported', (data) => {
console.log('模型已加载:', data.fileName)
})
// 加载模型
const fileInput = document.getElementById('file-input')
fileInput.addEventListener('change', async (event) => {
const files = Array.from(event.target.files)
await loader.loadModels(files)
})
// 导出模型
await loader.exportModel('model-id', {
fileName: 'exported-model.ksplat',
applyTransform: true
})
// 清理资源
window.addEventListener('beforeunload', () => {
loader.dispose()
})API 文档
Vue Composable: useGaussianSplats
响应式状态
const {
// 加载状态
loading: Ref<boolean>,
loadingMessage: Ref<string>,
loadingProgress: Ref<number>,
progress: Ref<ProgressInfo[]>,
// 错误处理
errorMessage: Ref<string>,
lastFailedOperation: Ref<string | null>,
// 模型管理
models: Map<string, ModelData>,
modelList: ComputedRef<ModelData[]>,
modelCount: ComputedRef<number>,
hasModels: ComputedRef<boolean>,
selectedModelId: Ref<string | null>,
selectedModel: ComputedRef<ModelData | null>,
// 场景状态
sceneInitialized: Ref<boolean>,
gridVisible: Ref<boolean>,
// 设置
settings: {
dynamicScene: boolean,
autoRotate: boolean,
autoRotateSpeed: number,
backgroundColor: number
}
} = useGaussianSplats(options?)核心方法
// 场景初始化
await init(container: HTMLElement): Promise<void>
// 文件导入
await importFiles(files: File[], options?: ImportOptions): Promise<any>
await importFile(file: File, options?: ImportOptions): Promise<any>
// 模型管理
removeModel(modelId: string): void
clearAllModels(): void
selectModel(modelId: string): void
clearSelection(): void
// 模型操作
toggleModelVisibility(modelId: string, visible?: boolean): void
updateModelTransform(modelId: string, transform: Partial<Transform>): void
await exportModel(modelId: string, options?: ExportOptions): Promise<void>
// 场景控制
toggleGrid(): boolean
setGridVisible(visible: boolean): void
// 配置管理
updateSetting(key: string, value: any): void
toggleSetting(key: string): boolean
// 工具方法
openFileDialog(): void
isFileSupported(file: File | string): boolean
getSupportedFormats(): Record<string, any>
clearError(): void
// 事件系统
on(eventName: string, callback: (data: any) => void): () => void
once(eventName: string, callback: (data: any) => void): () => void
off(eventName: string, callback: (data: any) => void): void核心 API: createGS3DLoader
const loader = createGS3DLoader(options?: {
config?: Config
}): GS3DLoaderInstance
// 使用方法
await loader.init(container: HTMLElement)
await loader.loadModel(file: File, options?: ImportOptions)
await loader.loadModels(files: File[], options?: ImportOptions)
await loader.exportModel(modelId: string, options?: ExportOptions)
loader.removeModel(modelId: string)
loader.dispose()类型定义
interface Transform {
position?: [number, number, number]
rotation?: [number, number, number, number] // quaternion
scale?: [number, number, number]
}
interface ModelData {
id: string
name: string
type: 'gaussian' | 'box'
path?: string
originalFileName?: string
visible: boolean
fileSize?: number
format?: string
loadTime?: string
transform?: Transform
metadata?: Record<string, any>
}
interface ImportOptions {
position?: [number, number, number]
rotation?: [number, number, number, number]
scale?: [number, number, number]
dynamicScene?: boolean
splatAlphaRemovalThreshold?: number
sphericalHarmonicsDegree?: number
compressionLevel?: number
minimumAlpha?: number
antialiased?: boolean
}
interface ExportOptions {
fileName?: string
applyTransform?: boolean
}配置选项
const config = {
scene: {
dynamicScene: false,
autoRotate: false,
autoRotateSpeed: 0.5,
gridVisible: true,
backgroundColor: 0x000000
},
defaultTransform: {
position: [0, 0, 0],
rotation: [0, 0, 0, 1],
scale: [1, 1, 1]
},
import: {
autoApplyDefaultTransform: true,
dynamicSceneByDefault: false,
splatAlphaRemovalThreshold: 1,
sphericalHarmonicsDegree: 0,
compressionLevel: 0,
minimumAlpha: 1,
antialiased: false
}
}事件系统
库提供了完整的事件系统来监控操作状态:
// 模型相关事件
loader.on('model:imported', ({ modelId, fileName, format }) => {})
loader.on('model:exported', ({ modelId, fileName, format }) => {})
loader.on('model:removed', ({ modelId }) => {})
loader.on('model:visibility-changed', ({ modelId, visible }) => {})
loader.on('model:transform-changed', ({ modelId, transform }) => {})
// 文件操作事件
loader.on('files:import-start', ({ files, options }) => {})
loader.on('files:import-progress', ({ fileIndex, fileName, progress, modelId }) => {})
loader.on('files:import-complete', ({ results, successCount, errorCount }) => {})
loader.on('files:import-error', ({ fileName, error }) => {})
// 场景事件
loader.on('scene:ready', ({ container, renderer, scene, camera }) => {})
loader.on('scene:disposed', () => {})
// 高斯事件
loader.on('gaussian:loaded', ({ modelId, path, sceneIndex, transform, dynamicScene }) => {})
loader.on('gaussian:removed', ({ modelId }) => {})
// 导出事件
loader.on('export:request', ({ modelId, options }) => {})
loader.on('export:complete', ({ modelId, fileName }) => {})
loader.on('export:error', ({ modelId, error }) => {})
// 错误事件
loader.on('error', ({ type, message, error }) => {})开发与构建
# 安装依赖
npm install
# 开发模式
npm run dev
# 构建
npm run build
# TypeScript 检查
npm run type-check
# 清理
npm run clean支持的文件格式
| 格式 | 扩展名 | 导入 | 导出 | 描述 |
|------|--------|------|------|------|
| PLY | .ply | ✅ | ❌ | 标准点云格式 |
| Splat | .splat | ✅ | ❌ | Gaussian Splats 格式 |
| KSplat | .ksplat | ✅ | ✅ | 压缩的 Gaussian Splats 格式 |
依赖项
Peer Dependencies
three: ^0.160.0@mkkellogg/gaussian-splats-3d: ^0.4.7vue: ^3.0.0 (仅 Vue 适配器需要)
内部依赖
- TypeScript
- Rollup
- 各种构建工具
许可证
Private License - 仅供内部项目使用
更新日志
1.0.0
- 初始版本发布
- 支持 PLY、Splat、KSplat 格式
- Vue 3 Composition API 集成
- 完整的事件系统
- Three.js 场景管理
- 模型变换和导出功能
