@ridp/threejs 1.4.6 → 1.5.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 +425 -52
- package/dist/{PredictiveLoader-ClWlas7_.js → PredictiveLoader-C9zJlZEQ.js} +884 -810
- package/dist/PredictiveLoader-Xy5S4HBr.cjs +2 -0
- package/dist/assets/{gltfParserOptimized.worker-yo8WMPFM.js → gltfParserOptimized.worker-BHgPWvd-.js} +1 -1
- package/dist/hooks.cjs +1 -1
- package/dist/hooks.js +2 -2
- package/dist/{ImageLoader-B706H7-_.js → objectQuery-BfHUGPET.js} +418 -409
- package/dist/objectQuery-DNtwsgY8.cjs +24 -0
- package/dist/threejs.cjs +2 -2
- package/dist/threejs.js +33 -31
- package/dist/{useBatchGLTFLoader-B9kI2LGP.js → useBatchGLTFLoader-C1C8R5Ss.js} +1 -1
- package/dist/{useBatchGLTFLoader-C9v4CYix.cjs → useBatchGLTFLoader-DHJyQcpJ.cjs} +1 -1
- package/dist/utils.cjs +1 -1
- package/dist/utils.js +18 -16
- package/package.json +1 -1
- package/dist/ImageLoader-Bx97EjI3.cjs +0 -24
- package/dist/PredictiveLoader-wSx-b7OS.cjs +0 -2
package/README.md
CHANGED
|
@@ -61,6 +61,24 @@ yarn add @ridp/threejs dexie@^4 vue@^3 three@^0.178
|
|
|
61
61
|
pnpm add @ridp/threejs dexie@^4 vue@^3 three@^0.178
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
+
### vite.config.js 配置
|
|
65
|
+
因为涉及 worker,需要添加以下配置项:
|
|
66
|
+
```javascript
|
|
67
|
+
import { defineConfig } from 'vite';
|
|
68
|
+
|
|
69
|
+
export default defineConfig(() => {
|
|
70
|
+
return {
|
|
71
|
+
// plugins,
|
|
72
|
+
// build: { ... }
|
|
73
|
+
optimizeDeps: {
|
|
74
|
+
// ...
|
|
75
|
+
exclude: ['@ridp/threejs']
|
|
76
|
+
},
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
|
|
64
82
|
## 快速开始
|
|
65
83
|
|
|
66
84
|
### 基础场景初始化
|
|
@@ -162,18 +180,20 @@ new ThreeIns(selector: string, options: ThreeInsOptions)
|
|
|
162
180
|
|
|
163
181
|
##### setView()
|
|
164
182
|
|
|
165
|
-
|
|
183
|
+
设置模型视角 - 通过移动相机位置来实现视角切换。
|
|
166
184
|
|
|
167
185
|
```javascript
|
|
168
186
|
threeJsIns.setView(
|
|
169
187
|
model: Object3D,
|
|
170
188
|
viewType: ViewType,
|
|
171
189
|
options?: {
|
|
172
|
-
scale?: number, // 缩放比例,1=占满画布,0.5=50%,2=
|
|
190
|
+
scale?: number, // 缩放比例,1=占满画布,0.5=50%,2.0=200%(默认: 0.8)
|
|
191
|
+
position?: string | Vector3, // 模型在画布中的位置
|
|
173
192
|
showBox?: boolean, // 是否显示包围盒(默认: false)
|
|
174
|
-
animate?: boolean, // 是否启用动画(默认:
|
|
193
|
+
animate?: boolean, // 是否启用动画(默认: true)
|
|
175
194
|
duration?: number, // 动画时长(毫秒,默认: 1000)
|
|
176
|
-
offset?: Vector3
|
|
195
|
+
offset?: Vector3, // 额外的手动偏移量
|
|
196
|
+
boxColor?: number // 包围盒颜色(默认: 0xffff00)
|
|
177
197
|
}
|
|
178
198
|
): void
|
|
179
199
|
```
|
|
@@ -184,9 +204,13 @@ threeJsIns.setView(
|
|
|
184
204
|
- `ViewType.LEFT` - 左侧视(从左往右)
|
|
185
205
|
- `ViewType.ISO` - 等轴测视角(对角线上方俯视)
|
|
186
206
|
|
|
207
|
+
**position 参数选项:**
|
|
208
|
+
- 字符串选项:`'center'`(居中)、`'top-left'`(左上)、`'top-right'`(右上)、`'bottom-left'`(左下)、`'bottom-right'`(右下)
|
|
209
|
+
- Vector3:自定义偏移向量
|
|
210
|
+
|
|
187
211
|
**示例:**
|
|
188
212
|
```javascript
|
|
189
|
-
// 设置等轴测视角,模型占满画布
|
|
213
|
+
// 基础用法 - 设置等轴测视角,模型占满画布
|
|
190
214
|
threeJsIns.setView(model, ViewType.ISO, {
|
|
191
215
|
scale: 1.0,
|
|
192
216
|
showBox: true,
|
|
@@ -199,8 +223,73 @@ threeJsIns.setView(model, ViewType.TOP, {
|
|
|
199
223
|
scale: 0.5,
|
|
200
224
|
animate: true
|
|
201
225
|
});
|
|
226
|
+
|
|
227
|
+
// 使用位置控制 - 左上角显示
|
|
228
|
+
threeJsIns.setView(model, ViewType.ISO, {
|
|
229
|
+
position: 'top-left',
|
|
230
|
+
scale: 0.8
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// 组合使用 position 和 offset
|
|
234
|
+
threeJsIns.setView(model, ViewType.TOP, {
|
|
235
|
+
position: 'top-left', // 先自动定位到左上
|
|
236
|
+
offset: new THREE.Vector3(50, 0, 0), // 再额外向右偏移 50
|
|
237
|
+
scale: 0.8
|
|
238
|
+
});
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
##### setViewByRotation()
|
|
242
|
+
|
|
243
|
+
通过旋转物体切换视角 - 保持相机固定,通过旋转物体来实现视角切换。
|
|
244
|
+
|
|
245
|
+
```javascript
|
|
246
|
+
threeJsIns.setViewByRotation(
|
|
247
|
+
model: Object3D,
|
|
248
|
+
viewType: ViewType,
|
|
249
|
+
options?: {
|
|
250
|
+
animate?: boolean, // 是否启用动画(默认: true)
|
|
251
|
+
duration?: number, // 动画时长(毫秒,默认: 1000)
|
|
252
|
+
resetRotation?: boolean // 旋转前是否重置物体旋转(默认: true)
|
|
253
|
+
}
|
|
254
|
+
): { rotation: object, viewType: string, degrees: object }
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**旋转角度配置:**
|
|
258
|
+
- `ViewType.LEFT` - 物体绕 X 轴旋转 45°,Y 轴旋转 45°
|
|
259
|
+
- `ViewType.RIGHT` - 物体绕 Y 轴旋转 90°
|
|
260
|
+
- `ViewType.TOP` - 物体绕 X 轴旋转 90°
|
|
261
|
+
- `ViewType.ISO` - 物体绕 X 轴旋转 45°,Y 轴旋转 45°
|
|
262
|
+
|
|
263
|
+
**示例:**
|
|
264
|
+
```javascript
|
|
265
|
+
// 左侧视:物体绕 X 轴 45°,Y 轴 45°
|
|
266
|
+
const result = threeJsIns.setViewByRotation(model, ViewType.LEFT);
|
|
267
|
+
|
|
268
|
+
// 俯视:物体绕 X 轴 90°,无动画
|
|
269
|
+
threeJsIns.setViewByRotation(model, ViewType.TOP, {
|
|
270
|
+
animate: false
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
// 自定义动画时间
|
|
274
|
+
threeJsIns.setViewByRotation(model, ViewType.ISO, {
|
|
275
|
+
duration: 1500
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
// 不重置旋转,在当前基础上累加
|
|
279
|
+
threeJsIns.setViewByRotation(model, ViewType.LEFT, {
|
|
280
|
+
resetRotation: false
|
|
281
|
+
});
|
|
202
282
|
```
|
|
203
283
|
|
|
284
|
+
**两种视角切换方式对比:**
|
|
285
|
+
|
|
286
|
+
| 特性 | setView() | setViewByRotation() |
|
|
287
|
+
|------|-----------|---------------------|
|
|
288
|
+
| 实现方式 | 移动相机位置 | 旋转物体 |
|
|
289
|
+
| 相机位置 | 改变 | 固定 |
|
|
290
|
+
| 物体姿态 | 保持不变 | 改变 |
|
|
291
|
+
| 适用场景 | 通用视角切换 | 特殊视觉效果 |
|
|
292
|
+
|
|
204
293
|
##### frameArea()
|
|
205
294
|
|
|
206
295
|
> **⚠️ 已弃用** - 此方法仅为兼容旧版本保留,请使用 `setView()` 方法代替。
|
|
@@ -244,8 +333,8 @@ threeJsIns.setView(model, ViewType.ISO, {
|
|
|
244
333
|
```
|
|
245
334
|
|
|
246
335
|
**迁移指南:**
|
|
247
|
-
| 旧用法 (frameArea)
|
|
248
|
-
|
|
336
|
+
| 旧用法 (frameArea) | 新用法 (setView) |
|
|
337
|
+
| ----------------------- | ---------------------------------------------- |
|
|
249
338
|
| `frameArea(model, 1.0)` | `setView(model, ViewType.ISO, { scale: 1.0 })` |
|
|
250
339
|
| `frameArea(model, 0.5)` | `setView(model, ViewType.ISO, { scale: 0.5 })` |
|
|
251
340
|
| `frameArea(model, 2.0)` | `setView(model, ViewType.ISO, { scale: 2.0 })` |
|
|
@@ -338,15 +427,15 @@ threeJsIns.setView(model, ViewType.ISO, { scale: 1.0, animate: true });
|
|
|
338
427
|
|
|
339
428
|
**迁移对照表:**
|
|
340
429
|
|
|
341
|
-
| 功能
|
|
342
|
-
|
|
343
|
-
| 初始化场景
|
|
344
|
-
| 访问 scene
|
|
345
|
-
| 访问 camera | `const { camera } = useThreeJs(...)` | `threeJsIns.camera`
|
|
346
|
-
| 添加动画
|
|
347
|
-
| 视角切换
|
|
348
|
-
| 资源清理
|
|
349
|
-
| 适用范围
|
|
430
|
+
| 功能 | useThreeJs (已弃用) | ThreeIns 类 (推荐) |
|
|
431
|
+
| ----------- | ------------------------------------ | -------------------------------- |
|
|
432
|
+
| 初始化场景 | `useThreeJs('#el', opts)` | `new ThreeIns('#el', opts)` |
|
|
433
|
+
| 访问 scene | `const { scene } = useThreeJs(...)` | `threeJsIns.scene` |
|
|
434
|
+
| 访问 camera | `const { camera } = useThreeJs(...)` | `threeJsIns.camera` |
|
|
435
|
+
| 添加动画 | `addAnimate(fn)` | `threeJsIns.addAnimate(fn)` |
|
|
436
|
+
| 视角切换 | ❌ 不支持 | ✅ `setView(model, ViewType.ISO)` |
|
|
437
|
+
| 资源清理 | `dispose()` | ✅ `threeJsIns.dispose()` |
|
|
438
|
+
| 适用范围 | 仅 Vue 3 | 所有 JS/TS 项目 |
|
|
350
439
|
|
|
351
440
|
---
|
|
352
441
|
|
|
@@ -383,6 +472,10 @@ const {
|
|
|
383
472
|
getMemoryCacheInfo, // 获取内存缓存统计
|
|
384
473
|
deleteMemoryCache, // 删除指定模型的内存缓存
|
|
385
474
|
|
|
475
|
+
// 缓存迁移和验证 (v1.5.0+)
|
|
476
|
+
cleanLegacyCache, // 清理旧版本格式的缓存数据
|
|
477
|
+
validateCache, // 验证并修复缓存
|
|
478
|
+
|
|
386
479
|
// 性能监控
|
|
387
480
|
cacheMonitor // 缓存监控器实例
|
|
388
481
|
} = loader;
|
|
@@ -613,6 +706,92 @@ const model3 = await loader.asyncFetch('/models/car.glb', '1.0.0');
|
|
|
613
706
|
// [ asyncFetch ] ====> IndexedDB 缓存命中
|
|
614
707
|
```
|
|
615
708
|
|
|
709
|
+
##### 缓存迁移和验证 API (v1.5.0+)
|
|
710
|
+
|
|
711
|
+
**cleanLegacyCache()**
|
|
712
|
+
|
|
713
|
+
清理旧版本格式的缓存数据,手动触发清理不需要等待数据库版本升级。
|
|
714
|
+
|
|
715
|
+
```javascript
|
|
716
|
+
const result = await loader.cleanLegacyCache();
|
|
717
|
+
|
|
718
|
+
// 返回值:
|
|
719
|
+
{
|
|
720
|
+
total: 10, // 总记录数
|
|
721
|
+
deleted: 3, // 删除的记录数
|
|
722
|
+
kept: 7, // 保留的记录数
|
|
723
|
+
deletedPaths: [ // 被删除的路径列表
|
|
724
|
+
'/models/old1.glb',
|
|
725
|
+
'/models/old2.glb',
|
|
726
|
+
'/models/old3.glb'
|
|
727
|
+
]
|
|
728
|
+
}
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
**validateCache()**
|
|
732
|
+
|
|
733
|
+
验证并修复缓存完整性。
|
|
734
|
+
|
|
735
|
+
```javascript
|
|
736
|
+
const result = await loader.validateCache();
|
|
737
|
+
|
|
738
|
+
// 返回值:
|
|
739
|
+
{
|
|
740
|
+
total: 10, // 总记录数
|
|
741
|
+
valid: 8, // 有效记录数
|
|
742
|
+
invalid: 2, // 无效记录数
|
|
743
|
+
repairs: 1 // 修复的操作数
|
|
744
|
+
}
|
|
745
|
+
```
|
|
746
|
+
|
|
747
|
+
**使用场景:**
|
|
748
|
+
|
|
749
|
+
```javascript
|
|
750
|
+
// 场景 1: 应用启动时验证缓存
|
|
751
|
+
async function initApp() {
|
|
752
|
+
const { validateCache, asyncFetch } = useGLTFLoader();
|
|
753
|
+
|
|
754
|
+
// 验证并修复缓存
|
|
755
|
+
const result = await validateCache();
|
|
756
|
+
if (result.invalid > 0) {
|
|
757
|
+
console.warn(`发现 ${result.invalid} 条无效缓存,已自动清理`);
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
// 继续加载模型
|
|
761
|
+
const model = await asyncFetch('/models/car.glb', '1.0.0');
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
// 场景 2: 手动清理旧版本格式
|
|
765
|
+
async function cleanupOldCache() {
|
|
766
|
+
const { cleanLegacyCache } = useGLTFLoader();
|
|
767
|
+
|
|
768
|
+
const result = await cleanLegacyCache();
|
|
769
|
+
console.log(`清理完成: 删除 ${result.deleted} 条,保留 ${result.kept} 条`);
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
// 场景 3: 用户遇到缓存问题时一键修复
|
|
773
|
+
async function repairCache() {
|
|
774
|
+
const { validateCache, cleanLegacyCache } = useGLTFLoader();
|
|
775
|
+
|
|
776
|
+
// 先验证
|
|
777
|
+
const validation = await validateCache();
|
|
778
|
+
console.log('验证结果:', validation);
|
|
779
|
+
|
|
780
|
+
// 如果仍有问题,强制清理旧版本
|
|
781
|
+
if (validation.invalid > 0) {
|
|
782
|
+
const cleaned = await cleanLegacyCache();
|
|
783
|
+
console.log('清理结果:', cleaned);
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
```
|
|
787
|
+
|
|
788
|
+
**缓存版本说明:**
|
|
789
|
+
|
|
790
|
+
- **v1-v3 (旧版本)**: 使用序列化对象格式 (`object3DToData`)
|
|
791
|
+
- **v4+ (新版本)**: 直接存储 ArrayBuffer 原始数据
|
|
792
|
+
- **自动迁移**: 数据库会自动从旧版本升级,清理旧格式数据
|
|
793
|
+
- **手动清理**: 可使用 `cleanLegacyCache()` 手动清理
|
|
794
|
+
|
|
616
795
|
### useRaycaster()
|
|
617
796
|
|
|
618
797
|
射线拾取工具,用于鼠标交互和物体选择。
|
|
@@ -725,8 +904,7 @@ import {
|
|
|
725
904
|
createRaycaster, // 创建射线投射器
|
|
726
905
|
createAxesHelper, // 创建坐标轴辅助器
|
|
727
906
|
createArrowHelper, // 创建箭头辅助器
|
|
728
|
-
createStats
|
|
729
|
-
createTransformControls // 创建变换控制器
|
|
907
|
+
createStats // 创建性能监控器
|
|
730
908
|
} from '@ridp/threejs';
|
|
731
909
|
|
|
732
910
|
// 示例
|
|
@@ -737,6 +915,20 @@ const stats = createStats();
|
|
|
737
915
|
document.body.appendChild(stats.dom);
|
|
738
916
|
```
|
|
739
917
|
|
|
918
|
+
**功能说明:**
|
|
919
|
+
- `createCameraHelper(camera)` - 创建相机辅助线,显示相机视锥体
|
|
920
|
+
- `createGridHelper(size, divisions, color1, color2)` - 创建网格辅助线
|
|
921
|
+
- `size`: 网格大小,默认 150
|
|
922
|
+
- `divisions`: 分段数
|
|
923
|
+
- `color1/color2`: 中心线和其他线的颜色
|
|
924
|
+
- `createBox3Helper(model)` - 创建包围盒辅助线
|
|
925
|
+
- `createOrbitControl(camera, dom)` - 创建轨道控制器
|
|
926
|
+
- `createMapControls(camera, dom)` - 创建地图控制器
|
|
927
|
+
- `createRaycaster()` - 创建射线投射器,用于鼠标拾取
|
|
928
|
+
- `createAxesHelper(size)` - 创建坐标轴辅助线,默认大小 10
|
|
929
|
+
- `createArrowHelper(dir, origin, length, color)` - 创建箭头辅助线
|
|
930
|
+
- `createStats()` - 创建性能监控器(基于 stats.js)
|
|
931
|
+
|
|
740
932
|
### initEnvImage()
|
|
741
933
|
|
|
742
934
|
初始化场景环境贴图。
|
|
@@ -754,6 +946,30 @@ await initEnvImage(scene, '/hdr/outdoor.hdr');
|
|
|
754
946
|
await initEnvImage(scene, '/textures/env.jpg');
|
|
755
947
|
```
|
|
756
948
|
|
|
949
|
+
### getCommonParent()
|
|
950
|
+
|
|
951
|
+
查找多个网格对象的公共父节点。
|
|
952
|
+
|
|
953
|
+
```javascript
|
|
954
|
+
import { getCommonParent } from '@ridp/threejs';
|
|
955
|
+
|
|
956
|
+
// 查找多个选中对象的公共父节点
|
|
957
|
+
const meshes = [mesh1, mesh2, mesh3];
|
|
958
|
+
const commonParent = getCommonParent(meshes, scene);
|
|
959
|
+
|
|
960
|
+
console.log('公共父节点:', commonParent);
|
|
961
|
+
```
|
|
962
|
+
|
|
963
|
+
**功能说明:**
|
|
964
|
+
- 遍历每个网格的所有父节点,统计出现频率最高的父节点
|
|
965
|
+
- 返回的公共父节点可作为分组、操作的目标对象
|
|
966
|
+
- 常用于批量操作、场景组织等场景
|
|
967
|
+
|
|
968
|
+
**使用场景:**
|
|
969
|
+
- 批量选择对象时查找共同的容器
|
|
970
|
+
- 场景层级分析
|
|
971
|
+
- 分组操作前的父节点确定
|
|
972
|
+
|
|
757
973
|
### modelOptimizer
|
|
758
974
|
|
|
759
975
|
模型优化工具,用于减少多边形数量和优化材质。
|
|
@@ -779,26 +995,28 @@ const optimized = modelOptimizer.simplifyModel(model, {
|
|
|
779
995
|
modelOptimizer.optimizeMaterials(model);
|
|
780
996
|
```
|
|
781
997
|
|
|
782
|
-
###
|
|
998
|
+
### disposeThreeObject()
|
|
783
999
|
|
|
784
1000
|
深度释放 3D 对象及其子对象的资源。
|
|
785
1001
|
|
|
786
1002
|
```javascript
|
|
787
|
-
import {
|
|
1003
|
+
import { disposeThreeObject } from '@ridp/threejs';
|
|
788
1004
|
|
|
789
1005
|
// 释放模型资源
|
|
790
|
-
|
|
1006
|
+
disposeThreeObject(model);
|
|
791
1007
|
|
|
792
1008
|
// 释放整个场景
|
|
793
|
-
|
|
1009
|
+
disposeThreeObject(scene);
|
|
794
1010
|
```
|
|
795
1011
|
|
|
796
1012
|
**清理内容:**
|
|
797
|
-
- 几何体 (geometry)
|
|
798
|
-
- 材质 (material)
|
|
799
|
-
-
|
|
1013
|
+
- 几何体 (geometry.dispose())
|
|
1014
|
+
- 材质 (material.dispose())
|
|
1015
|
+
- 材质中的所有纹理 (texture.dispose())
|
|
800
1016
|
- 子对象递归清理
|
|
801
1017
|
|
|
1018
|
+
**注意:** 此函数会递归遍历对象的所有子对象,确保所有资源都被正确释放,避免内存泄漏。
|
|
1019
|
+
|
|
802
1020
|
### sceneRebuilder
|
|
803
1021
|
|
|
804
1022
|
渐进式场景重建工具,用于大型模型的分批渲染。
|
|
@@ -817,45 +1035,93 @@ const builder = new ProgressiveSceneBuilder(scene, camera, {
|
|
|
817
1035
|
await builder.build(model);
|
|
818
1036
|
```
|
|
819
1037
|
|
|
820
|
-
###
|
|
1038
|
+
### 模型序列化工具
|
|
821
1039
|
|
|
822
|
-
3D
|
|
1040
|
+
用于 Three.js 对象的序列化和反序列化,支持将 3D 对象转换为可存储的数据格式。
|
|
823
1041
|
|
|
824
1042
|
```javascript
|
|
825
|
-
import {
|
|
1043
|
+
import {
|
|
1044
|
+
object3DToData,
|
|
1045
|
+
object3DToDataSync,
|
|
1046
|
+
dataToObject3D,
|
|
1047
|
+
dataToObject3DSync
|
|
1048
|
+
} from '@ridp/threejs';
|
|
826
1049
|
|
|
827
|
-
//
|
|
828
|
-
const
|
|
1050
|
+
// 异步序列化(推荐,避免阻塞主线程)
|
|
1051
|
+
const data = await object3DToData(model, 50);
|
|
829
1052
|
|
|
830
|
-
//
|
|
831
|
-
const
|
|
1053
|
+
// 同步序列化
|
|
1054
|
+
const data = object3DToDataSync(model);
|
|
832
1055
|
|
|
833
|
-
//
|
|
834
|
-
const
|
|
1056
|
+
// 异步反序列化(推荐,避免阻塞主线程)
|
|
1057
|
+
const restoredModel = await dataToObject3D(data, 50);
|
|
835
1058
|
|
|
836
|
-
//
|
|
837
|
-
const
|
|
838
|
-
return obj.scale.x > 10;
|
|
839
|
-
});
|
|
1059
|
+
// 同步反序列化
|
|
1060
|
+
const restoredModel = dataToObject3DSync(data);
|
|
840
1061
|
```
|
|
841
1062
|
|
|
1063
|
+
**功能说明:**
|
|
1064
|
+
- `object3DToData(object, chunkSize)` - 异步序列化对象,使用分块处理避免阻塞
|
|
1065
|
+
- `chunkSize`: 每帧处理的对象数量,默认 50
|
|
1066
|
+
- `object3DToDataSync(object)` - 同步序列化对象
|
|
1067
|
+
- `dataToObject3D(data, chunkSize)` - 异步反序列化数据为 3D 对象
|
|
1068
|
+
- `dataToObject3DSync(data)` - 同步反序列化数据为 3D 对象
|
|
1069
|
+
|
|
1070
|
+
**序列化内容:**
|
|
1071
|
+
- 对象类型、名称、位置、旋转、缩放
|
|
1072
|
+
- 几何体数据(顶点、索引、UV 等)
|
|
1073
|
+
- 材质数据(颜色、纹理、属性等)
|
|
1074
|
+
- userData 自定义数据
|
|
1075
|
+
- 子对象层级关系
|
|
1076
|
+
|
|
1077
|
+
**使用场景:**
|
|
1078
|
+
- 场景状态保存和恢复
|
|
1079
|
+
- 模型数据的本地存储
|
|
1080
|
+
- 跨页面/跨会话的模型传输
|
|
1081
|
+
|
|
1082
|
+
### 对象查询工具
|
|
1083
|
+
|
|
1084
|
+
基于 userData 的对象查找工具。
|
|
1085
|
+
|
|
1086
|
+
```javascript
|
|
1087
|
+
import { getObjectByUserData, getRootObj } from '@ridp/threejs';
|
|
1088
|
+
|
|
1089
|
+
// 向下遍历查找首个匹配 userData 的对象
|
|
1090
|
+
const target = getObjectByUserData(mesh, 'type', 'wheel');
|
|
1091
|
+
|
|
1092
|
+
// 向上查找根节点(根据 userData 判定)
|
|
1093
|
+
const root = getRootObj(mesh, 'isRoot', true);
|
|
1094
|
+
```
|
|
1095
|
+
|
|
1096
|
+
**功能说明:**
|
|
1097
|
+
- `getObjectByUserData(obj, key, value)` - 从指定对象开始向下遍历,查找首个 userData[key]=value 的对象(包括自身)
|
|
1098
|
+
- `getRootObj(obj, rootKey, value)` - 从指定对象开始向上查找父级,直到找到 userData[rootKey]=value 的根对象
|
|
1099
|
+
|
|
842
1100
|
### CSS3D 辅助工具
|
|
843
1101
|
|
|
844
1102
|
```javascript
|
|
845
|
-
import {
|
|
1103
|
+
import { createInfoPlane, createTagPlane } from '@ridp/threejs';
|
|
846
1104
|
|
|
847
|
-
// 创建 CSS3D
|
|
848
|
-
const
|
|
849
|
-
|
|
850
|
-
scene.add(
|
|
1105
|
+
// 从 DOM ID 创建 CSS3D 信息面板
|
|
1106
|
+
const infoPlane = createInfoPlane('my-info-panel', [0.3, 0.3, 0.3]);
|
|
1107
|
+
infoPlane.position.set(0, 10, 0);
|
|
1108
|
+
scene.add(infoPlane);
|
|
851
1109
|
|
|
852
|
-
// 创建 CSS3D
|
|
853
|
-
const
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
scene.add(sprite);
|
|
1110
|
+
// 创建 CSS3D 标签面板
|
|
1111
|
+
const tagPlane = createTagPlane('设备名称', 0.01);
|
|
1112
|
+
tagPlane.position.set(5, 5, 5);
|
|
1113
|
+
scene.add(tagPlane);
|
|
857
1114
|
```
|
|
858
1115
|
|
|
1116
|
+
**功能说明:**
|
|
1117
|
+
- `createInfoPlane(id, scale)` - 从页面中已存在的 DOM 元素创建 CSS3D 精灵
|
|
1118
|
+
- `id`: DOM 元素的 ID
|
|
1119
|
+
- `scale`: 缩放比例数组 `[x, y, z]`,默认 `[0.3, 0.3, 0.3]`
|
|
1120
|
+
- ⚠️ 注意: HTML 元素不能设置为绝对定位
|
|
1121
|
+
- `createTagPlane(text, scale)` - 创建带文本的 CSS3D 标签
|
|
1122
|
+
- `text`: 标签文本内容
|
|
1123
|
+
- `scale`: 统一缩放比例(三个维度相同)
|
|
1124
|
+
|
|
859
1125
|
### CacheMonitor
|
|
860
1126
|
|
|
861
1127
|
缓存性能监控工具。
|
|
@@ -1227,9 +1493,8 @@ otherObjects.castShadow = false;
|
|
|
1227
1493
|
A: 使用 `asyncFetch` 的重试机制:
|
|
1228
1494
|
|
|
1229
1495
|
```javascript
|
|
1230
|
-
const [err, model] = await asyncFetch(url, version, {
|
|
1231
|
-
|
|
1232
|
-
timeout: 60000
|
|
1496
|
+
const [err, model] = await asyncFetch(url, version, null, {
|
|
1497
|
+
maxRetries: 5
|
|
1233
1498
|
});
|
|
1234
1499
|
|
|
1235
1500
|
if (err || !model) {
|
|
@@ -1238,7 +1503,50 @@ if (err || !model) {
|
|
|
1238
1503
|
}
|
|
1239
1504
|
```
|
|
1240
1505
|
|
|
1241
|
-
### Q:
|
|
1506
|
+
### Q: 如何清理旧版本缓存数据?
|
|
1507
|
+
|
|
1508
|
+
A: 使用 `cleanLegacyCache` 方法手动清理旧版本格式:
|
|
1509
|
+
|
|
1510
|
+
```javascript
|
|
1511
|
+
import { useGLTFLoader } from '@ridp/threejs';
|
|
1512
|
+
|
|
1513
|
+
const { cleanLegacyCache } = useGLTFLoader();
|
|
1514
|
+
|
|
1515
|
+
// 清理旧版本序列化格式
|
|
1516
|
+
const result = await cleanLegacyCache();
|
|
1517
|
+
console.log('清理结果:', result);
|
|
1518
|
+
// 输出: { total: 10, deleted: 3, kept: 7, deletedPaths: [...] }
|
|
1519
|
+
```
|
|
1520
|
+
|
|
1521
|
+
**自动迁移**: 当用户首次使用新版本时,数据库会自动从 v4 升级到 v5,自动清理旧版本格式数据。
|
|
1522
|
+
|
|
1523
|
+
### Q: 如何验证缓存完整性?
|
|
1524
|
+
|
|
1525
|
+
A: 使用 `validateCache` 方法:
|
|
1526
|
+
|
|
1527
|
+
```javascript
|
|
1528
|
+
import { useGLTFLoader } from '@ridp/threejs';
|
|
1529
|
+
|
|
1530
|
+
const { validateCache } = useGLTFLoader();
|
|
1531
|
+
|
|
1532
|
+
// 验证并修复缓存
|
|
1533
|
+
const result = await validateCache();
|
|
1534
|
+
console.log('验证结果:', result);
|
|
1535
|
+
// 输出: { total: 10, valid: 8, invalid: 2, repairs: 1 }
|
|
1536
|
+
|
|
1537
|
+
if (result.invalid > 0) {
|
|
1538
|
+
console.warn(`发现 ${result.invalid} 条无效缓存,已自动清理`);
|
|
1539
|
+
}
|
|
1540
|
+
```
|
|
1541
|
+
|
|
1542
|
+
### Q: 升级后原有缓存会被删除吗?
|
|
1543
|
+
|
|
1544
|
+
A: 只有旧版本序列化格式的数据会被删除。ArrayBuffer 格式的数据会被保留。自动迁移过程会:
|
|
1545
|
+
- ✅ 保留所有 ArrayBuffer 格式的数据
|
|
1546
|
+
- ❌ 删除所有旧版本序列化格式的数据
|
|
1547
|
+
- 📊 在控制台输出迁移日志
|
|
1548
|
+
|
|
1549
|
+
### Q: 如何清空所有缓存?
|
|
1242
1550
|
|
|
1243
1551
|
A: 使用 `clearCache` 方法:
|
|
1244
1552
|
|
|
@@ -1300,6 +1608,71 @@ function captureScreenshot() {
|
|
|
1300
1608
|
|
|
1301
1609
|
## 更新日志
|
|
1302
1610
|
|
|
1611
|
+
### v1.5.0 (2026-01-12)
|
|
1612
|
+
|
|
1613
|
+
**🎉 重大更新:**
|
|
1614
|
+
|
|
1615
|
+
- ✨ **新增 setViewByRotation() 方法**: 通过旋转物体切换视角
|
|
1616
|
+
- 提供另一种视角切换方式(与 setView 互补)
|
|
1617
|
+
- 左视图:物体绕 X 轴 45°,Y 轴旋转 45°
|
|
1618
|
+
- 支持动画过渡和旋转重置选项
|
|
1619
|
+
- 适用于特殊视觉效果需求
|
|
1620
|
+
|
|
1621
|
+
- ✨ **新增 setView() position 参数**: 控制模型在画布中的位置
|
|
1622
|
+
- 支持 5 种预设位置:`center`、`top-left`、`top-right`、`bottom-left`、`bottom-right`
|
|
1623
|
+
- 支持自定义 Vector3 偏移
|
|
1624
|
+
- 可与 offset 参数组合使用
|
|
1625
|
+
|
|
1626
|
+
- ✨ **新增缓存迁移和验证工具**:
|
|
1627
|
+
- 数据库版本升级:v4 → v5
|
|
1628
|
+
- 自动清理旧版本序列化格式数据
|
|
1629
|
+
- 新增 `cleanLegacyCache()` - 手动清理旧版本缓存
|
|
1630
|
+
- 新增 `validateCache()` - 验证并修复缓存完整性
|
|
1631
|
+
- 新增 `cleanLegacyFormats()` - IDBCache 实例方法
|
|
1632
|
+
- 新增 `validateAndRepair()` - IDBCache 实例方法
|
|
1633
|
+
|
|
1634
|
+
- 🔧 **增强 setView() 方法**:
|
|
1635
|
+
- 新增 `position` 参数控制模型在画布中的位置
|
|
1636
|
+
- 新增 `boxColor` 参数自定义包围盒颜色
|
|
1637
|
+
- 优化视角偏移计算逻辑
|
|
1638
|
+
- 完善文档和 JSDoc 注释
|
|
1639
|
+
|
|
1640
|
+
- 🐛 **修复缓存版本兼容性问题**:
|
|
1641
|
+
- 旧版本(v1-v3)使用序列化对象格式
|
|
1642
|
+
- 新版本(v4+)使用 ArrayBuffer 格式
|
|
1643
|
+
- 自动识别并删除旧格式数据
|
|
1644
|
+
- 添加完整的格式验证逻辑
|
|
1645
|
+
|
|
1646
|
+
**API 变更:**
|
|
1647
|
+
|
|
1648
|
+
```javascript
|
|
1649
|
+
// 新增 setViewByRotation
|
|
1650
|
+
threeJsIns.setViewByRotation(model, ViewType.LEFT, {
|
|
1651
|
+
animate: true,
|
|
1652
|
+
duration: 1000,
|
|
1653
|
+
resetRotation: true
|
|
1654
|
+
});
|
|
1655
|
+
|
|
1656
|
+
// setView 新增 position 参数
|
|
1657
|
+
threeJsIns.setView(model, ViewType.ISO, {
|
|
1658
|
+
position: 'top-left', // 新增:位置控制
|
|
1659
|
+
scale: 0.8,
|
|
1660
|
+
offset: new THREE.Vector3(50, 0, 0)
|
|
1661
|
+
});
|
|
1662
|
+
|
|
1663
|
+
// 缓存迁移和验证
|
|
1664
|
+
const { cleanLegacyCache, validateCache } = useGLTFLoader();
|
|
1665
|
+
await cleanLegacyCache(); // 清理旧版本缓存
|
|
1666
|
+
await validateCache(); // 验证和修复缓存
|
|
1667
|
+
```
|
|
1668
|
+
|
|
1669
|
+
**迁移说明:**
|
|
1670
|
+
|
|
1671
|
+
- 数据库会自动从 v4 升级到 v5
|
|
1672
|
+
- 旧版本序列化格式数据会被自动删除
|
|
1673
|
+
- ArrayBuffer 格式数据会被保留
|
|
1674
|
+
- 提供手动清理工具供用户使用
|
|
1675
|
+
|
|
1303
1676
|
### v1.4.2 (2026-01-07)
|
|
1304
1677
|
|
|
1305
1678
|
**🎉 重大更新:**
|