@chocozhang/three-model-render 1.0.1
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/LICENSE +21 -0
- package/README.md +609 -0
- package/dist/camera/index.d.ts +133 -0
- package/dist/camera/index.js +291 -0
- package/dist/camera/index.js.map +1 -0
- package/dist/camera/index.mjs +265 -0
- package/dist/camera/index.mjs.map +1 -0
- package/dist/core/index.d.ts +102 -0
- package/dist/core/index.js +455 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/index.mjs +432 -0
- package/dist/core/index.mjs.map +1 -0
- package/dist/effect/index.d.ts +214 -0
- package/dist/effect/index.js +749 -0
- package/dist/effect/index.js.map +1 -0
- package/dist/effect/index.mjs +728 -0
- package/dist/effect/index.mjs.map +1 -0
- package/dist/index.d.ts +852 -0
- package/dist/index.js +3268 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3223 -0
- package/dist/index.mjs.map +1 -0
- package/dist/interaction/index.d.ts +160 -0
- package/dist/interaction/index.js +661 -0
- package/dist/interaction/index.js.map +1 -0
- package/dist/interaction/index.mjs +637 -0
- package/dist/interaction/index.mjs.map +1 -0
- package/dist/loader/index.d.ts +175 -0
- package/dist/loader/index.js +786 -0
- package/dist/loader/index.js.map +1 -0
- package/dist/loader/index.mjs +758 -0
- package/dist/loader/index.mjs.map +1 -0
- package/dist/setup/index.d.ts +47 -0
- package/dist/setup/index.js +199 -0
- package/dist/setup/index.js.map +1 -0
- package/dist/setup/index.mjs +178 -0
- package/dist/setup/index.mjs.map +1 -0
- package/dist/ui/index.d.ts +36 -0
- package/dist/ui/index.js +292 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/index.mjs +271 -0
- package/dist/ui/index.mjs.map +1 -0
- package/package.json +98 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/interaction/clickHandler.ts","../../src/interaction/arrowGuide.ts","../../src/interaction/liquidFiller.ts"],"sourcesContent":[null,null,null],"names":["THREE","BufferGeometryUtils"],"mappings":"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"}
|
|
@@ -0,0 +1,637 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
import * as BufferGeometryUtils from 'three/examples/jsm/utils/BufferGeometryUtils.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 创建模型点击高亮工具(OutlinePass 版)- 优化版
|
|
6
|
+
*
|
|
7
|
+
* ✨ 功能增强:
|
|
8
|
+
* - 使用 AbortController 统一管理事件生命周期
|
|
9
|
+
* - 支持防抖处理避免频繁触发
|
|
10
|
+
* - 可自定义 Raycaster 参数
|
|
11
|
+
* - 根据相机距离动态调整描边厚度
|
|
12
|
+
*
|
|
13
|
+
* @param camera 相机
|
|
14
|
+
* @param scene 场景
|
|
15
|
+
* @param renderer 渲染器
|
|
16
|
+
* @param outlinePass 已初始化的 OutlinePass
|
|
17
|
+
* @param onClick 点击回调
|
|
18
|
+
* @param options 可选配置
|
|
19
|
+
* @returns dispose 函数,用于清理事件和资源
|
|
20
|
+
*/
|
|
21
|
+
function createModelClickHandler(camera, scene, renderer, outlinePass, onClick, options = {}) {
|
|
22
|
+
// 配置项
|
|
23
|
+
const { clickThreshold = 3, debounceDelay = 0, raycasterParams = {}, enableDynamicThickness = true, minThickness = 1, maxThickness = 10 } = options;
|
|
24
|
+
const raycaster = new THREE.Raycaster();
|
|
25
|
+
const mouse = new THREE.Vector2();
|
|
26
|
+
// 应用 raycaster 自定义参数
|
|
27
|
+
if (raycasterParams.near !== undefined)
|
|
28
|
+
raycaster.near = raycasterParams.near;
|
|
29
|
+
if (raycasterParams.far !== undefined)
|
|
30
|
+
raycaster.far = raycasterParams.far;
|
|
31
|
+
if (raycasterParams.pointsPrecision !== undefined) {
|
|
32
|
+
if (!raycaster.params.Points) {
|
|
33
|
+
raycaster.params.Points = { threshold: raycasterParams.pointsPrecision };
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
raycaster.params.Points.threshold = raycasterParams.pointsPrecision;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
let startX = 0;
|
|
40
|
+
let startY = 0;
|
|
41
|
+
let selectedObject = null;
|
|
42
|
+
let debounceTimer = null;
|
|
43
|
+
// 使用 AbortController 统一管理事件
|
|
44
|
+
const abortController = new AbortController();
|
|
45
|
+
const signal = abortController.signal;
|
|
46
|
+
/** 恢复对象高亮(清空 OutlinePass.selectedObjects) */
|
|
47
|
+
function restoreObject() {
|
|
48
|
+
outlinePass.selectedObjects = [];
|
|
49
|
+
}
|
|
50
|
+
/** 鼠标按下记录位置 */
|
|
51
|
+
function handleMouseDown(event) {
|
|
52
|
+
startX = event.clientX;
|
|
53
|
+
startY = event.clientY;
|
|
54
|
+
}
|
|
55
|
+
/** 鼠标抬起判定点击或拖动(带防抖) */
|
|
56
|
+
function handleMouseUp(event) {
|
|
57
|
+
const dx = Math.abs(event.clientX - startX);
|
|
58
|
+
const dy = Math.abs(event.clientY - startY);
|
|
59
|
+
if (dx > clickThreshold || dy > clickThreshold)
|
|
60
|
+
return; // 拖动不触发点击
|
|
61
|
+
// 防抖处理
|
|
62
|
+
if (debounceDelay > 0) {
|
|
63
|
+
if (debounceTimer !== null) {
|
|
64
|
+
clearTimeout(debounceTimer);
|
|
65
|
+
}
|
|
66
|
+
debounceTimer = window.setTimeout(() => {
|
|
67
|
+
processClick(event);
|
|
68
|
+
debounceTimer = null;
|
|
69
|
+
}, debounceDelay);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
processClick(event);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/** 实际的点击处理逻辑 */
|
|
76
|
+
function processClick(event) {
|
|
77
|
+
const rect = renderer.domElement.getBoundingClientRect();
|
|
78
|
+
mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1;
|
|
79
|
+
mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1;
|
|
80
|
+
raycaster.setFromCamera(mouse, camera);
|
|
81
|
+
const intersects = raycaster.intersectObjects(scene.children, true);
|
|
82
|
+
if (intersects.length > 0) {
|
|
83
|
+
let object = intersects[0].object;
|
|
84
|
+
// 点击不同模型,先清除之前高亮
|
|
85
|
+
if (selectedObject && selectedObject !== object)
|
|
86
|
+
restoreObject();
|
|
87
|
+
selectedObject = object;
|
|
88
|
+
// highlightObject(selectedObject); // 可选:是否自动高亮
|
|
89
|
+
onClick(selectedObject, {
|
|
90
|
+
name: selectedObject.name || '未命名模型',
|
|
91
|
+
position: selectedObject.getWorldPosition(new THREE.Vector3()),
|
|
92
|
+
uuid: selectedObject.uuid
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
// 点击空白 → 清除高亮
|
|
97
|
+
if (selectedObject)
|
|
98
|
+
restoreObject();
|
|
99
|
+
selectedObject = null;
|
|
100
|
+
onClick(null);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// 使用 AbortController 的 signal 注册事件
|
|
104
|
+
renderer.domElement.addEventListener('mousedown', handleMouseDown, { signal });
|
|
105
|
+
renderer.domElement.addEventListener('mouseup', handleMouseUp, { signal });
|
|
106
|
+
/** 销毁函数:解绑事件并清除高亮 */
|
|
107
|
+
return () => {
|
|
108
|
+
// 清理防抖定时器
|
|
109
|
+
if (debounceTimer !== null) {
|
|
110
|
+
clearTimeout(debounceTimer);
|
|
111
|
+
debounceTimer = null;
|
|
112
|
+
}
|
|
113
|
+
// 一次性解绑所有事件
|
|
114
|
+
abortController.abort();
|
|
115
|
+
// 清除高亮
|
|
116
|
+
restoreObject();
|
|
117
|
+
// 清空引用
|
|
118
|
+
selectedObject = null;
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// src/utils/ArrowGuide.ts
|
|
123
|
+
/**
|
|
124
|
+
* ArrowGuide - 优化版
|
|
125
|
+
* 箭头引导效果工具,支持高亮模型并淡化其他对象
|
|
126
|
+
*
|
|
127
|
+
* ✨ 优化内容:
|
|
128
|
+
* - 使用 WeakMap 自动回收材质,避免内存泄漏
|
|
129
|
+
* - 使用 AbortController 管理事件生命周期
|
|
130
|
+
* - 添加材质复用机制,减少重复创建
|
|
131
|
+
* - 改进 dispose 逻辑,确保完全释放资源
|
|
132
|
+
* - 添加错误处理和边界检查
|
|
133
|
+
*/
|
|
134
|
+
class ArrowGuide {
|
|
135
|
+
constructor(renderer, camera, scene, options) {
|
|
136
|
+
var _a, _b, _c;
|
|
137
|
+
this.renderer = renderer;
|
|
138
|
+
this.camera = camera;
|
|
139
|
+
this.scene = scene;
|
|
140
|
+
this.lxMesh = null;
|
|
141
|
+
this.flowActive = false;
|
|
142
|
+
this.modelBrightArr = [];
|
|
143
|
+
this.pointerDownPos = new THREE.Vector2();
|
|
144
|
+
this.clickThreshold = 10;
|
|
145
|
+
this.raycaster = new THREE.Raycaster();
|
|
146
|
+
this.mouse = new THREE.Vector2();
|
|
147
|
+
// ✨ 使用 WeakMap 自动回收材质(GC 友好)
|
|
148
|
+
this.originalMaterials = new WeakMap();
|
|
149
|
+
this.fadedMaterials = new WeakMap();
|
|
150
|
+
// ✨ AbortController 用于事件管理
|
|
151
|
+
this.abortController = null;
|
|
152
|
+
// 配置:非高亮透明度和亮度
|
|
153
|
+
this.fadeOpacity = 0.5;
|
|
154
|
+
this.fadeBrightness = 0.1;
|
|
155
|
+
this.clickThreshold = (_a = options === null || options === void 0 ? void 0 : options.clickThreshold) !== null && _a !== void 0 ? _a : 10;
|
|
156
|
+
this.ignoreRaycastNames = new Set((options === null || options === void 0 ? void 0 : options.ignoreRaycastNames) || []);
|
|
157
|
+
this.fadeOpacity = (_b = options === null || options === void 0 ? void 0 : options.fadeOpacity) !== null && _b !== void 0 ? _b : 0.5;
|
|
158
|
+
this.fadeBrightness = (_c = options === null || options === void 0 ? void 0 : options.fadeBrightness) !== null && _c !== void 0 ? _c : 0.1;
|
|
159
|
+
this.abortController = new AbortController();
|
|
160
|
+
this.initEvents();
|
|
161
|
+
}
|
|
162
|
+
// —— 工具:缓存原材质(仅首次)
|
|
163
|
+
cacheOriginalMaterial(mesh) {
|
|
164
|
+
if (!this.originalMaterials.has(mesh)) {
|
|
165
|
+
this.originalMaterials.set(mesh, mesh.material);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// —— 工具:为某个材质克隆一个"半透明版本",保留所有贴图与参数
|
|
169
|
+
makeFadedClone(mat) {
|
|
170
|
+
const clone = mat.clone();
|
|
171
|
+
const c = clone;
|
|
172
|
+
// 只改透明相关参数,不改 map / normalMap / roughnessMap 等细节
|
|
173
|
+
c.transparent = true;
|
|
174
|
+
if (typeof c.opacity === 'number')
|
|
175
|
+
c.opacity = this.fadeOpacity;
|
|
176
|
+
if (c.color && c.color.isColor) {
|
|
177
|
+
c.color.multiplyScalar(this.fadeBrightness); // 颜色整体变暗
|
|
178
|
+
}
|
|
179
|
+
// 为了让箭头在透明建筑后也能顺畅显示,常用策略:不写深度,仅测试深度
|
|
180
|
+
clone.depthWrite = false;
|
|
181
|
+
clone.depthTest = true;
|
|
182
|
+
clone.needsUpdate = true;
|
|
183
|
+
return clone;
|
|
184
|
+
}
|
|
185
|
+
// —— 工具:为 mesh.material(可能是数组)批量克隆"半透明版本"
|
|
186
|
+
createFadedMaterialFrom(mesh) {
|
|
187
|
+
const orig = mesh.material;
|
|
188
|
+
if (Array.isArray(orig)) {
|
|
189
|
+
return orig.map(m => this.makeFadedClone(m));
|
|
190
|
+
}
|
|
191
|
+
return this.makeFadedClone(orig);
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* 设置箭头 Mesh
|
|
195
|
+
*/
|
|
196
|
+
setArrowMesh(mesh) {
|
|
197
|
+
this.lxMesh = mesh;
|
|
198
|
+
this.cacheOriginalMaterial(mesh);
|
|
199
|
+
try {
|
|
200
|
+
const mat = mesh.material;
|
|
201
|
+
if (mat && mat.map) {
|
|
202
|
+
const map = mat.map;
|
|
203
|
+
map.wrapS = THREE.RepeatWrapping;
|
|
204
|
+
map.wrapT = THREE.RepeatWrapping;
|
|
205
|
+
map.needsUpdate = true;
|
|
206
|
+
}
|
|
207
|
+
mesh.visible = false;
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
console.error('ArrowGuide: 设置箭头材质失败', error);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* 高亮指定模型
|
|
215
|
+
*/
|
|
216
|
+
highlight(models) {
|
|
217
|
+
if (!models || models.length === 0) {
|
|
218
|
+
console.warn('ArrowGuide: 高亮模型列表为空');
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
this.modelBrightArr = models;
|
|
222
|
+
this.flowActive = true;
|
|
223
|
+
if (this.lxMesh)
|
|
224
|
+
this.lxMesh.visible = true;
|
|
225
|
+
this.applyHighlight();
|
|
226
|
+
}
|
|
227
|
+
// ✅ 应用高亮效果:非高亮模型保留细节 → 使用"克隆后的半透明材质"
|
|
228
|
+
applyHighlight() {
|
|
229
|
+
// ✨ 使用 Set 提升查找性能
|
|
230
|
+
const keepMeshes = new Set();
|
|
231
|
+
this.modelBrightArr.forEach(obj => {
|
|
232
|
+
obj.traverse(child => {
|
|
233
|
+
if (child.isMesh)
|
|
234
|
+
keepMeshes.add(child);
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
try {
|
|
238
|
+
this.scene.traverse(obj => {
|
|
239
|
+
if (obj.isMesh) {
|
|
240
|
+
const mesh = obj;
|
|
241
|
+
// 缓存原材质(用于恢复)
|
|
242
|
+
this.cacheOriginalMaterial(mesh);
|
|
243
|
+
if (!keepMeshes.has(mesh)) {
|
|
244
|
+
// 非高亮:如果还没给它生成过"半透明克隆材质",就创建一次
|
|
245
|
+
if (!this.fadedMaterials.has(mesh)) {
|
|
246
|
+
const faded = this.createFadedMaterialFrom(mesh);
|
|
247
|
+
this.fadedMaterials.set(mesh, faded);
|
|
248
|
+
}
|
|
249
|
+
// 替换为克隆材质(保留所有贴图/法线等细节)
|
|
250
|
+
const fadedMat = this.fadedMaterials.get(mesh);
|
|
251
|
+
if (fadedMat)
|
|
252
|
+
mesh.material = fadedMat;
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
// 高亮对象:确保回到原材质(避免上一次高亮后遗留)
|
|
256
|
+
const orig = this.originalMaterials.get(mesh);
|
|
257
|
+
if (orig && mesh.material !== orig) {
|
|
258
|
+
mesh.material = orig;
|
|
259
|
+
mesh.material.needsUpdate = true;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
catch (error) {
|
|
266
|
+
console.error('ArrowGuide: 应用高亮失败', error);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
// ✅ 恢复为原材质 & 释放克隆材质
|
|
270
|
+
restore() {
|
|
271
|
+
this.flowActive = false;
|
|
272
|
+
if (this.lxMesh)
|
|
273
|
+
this.lxMesh.visible = false;
|
|
274
|
+
try {
|
|
275
|
+
// ✨ 收集所有需要释放的材质
|
|
276
|
+
const materialsToDispose = [];
|
|
277
|
+
this.scene.traverse(obj => {
|
|
278
|
+
if (obj.isMesh) {
|
|
279
|
+
const mesh = obj;
|
|
280
|
+
const orig = this.originalMaterials.get(mesh);
|
|
281
|
+
if (orig) {
|
|
282
|
+
mesh.material = orig;
|
|
283
|
+
mesh.material.needsUpdate = true;
|
|
284
|
+
}
|
|
285
|
+
// ✨ 收集待释放的淡化材质
|
|
286
|
+
const faded = this.fadedMaterials.get(mesh);
|
|
287
|
+
if (faded) {
|
|
288
|
+
if (Array.isArray(faded)) {
|
|
289
|
+
materialsToDispose.push(...faded);
|
|
290
|
+
}
|
|
291
|
+
else {
|
|
292
|
+
materialsToDispose.push(faded);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
// ✨ 批量释放材质(不触碰贴图资源)
|
|
298
|
+
materialsToDispose.forEach(mat => {
|
|
299
|
+
try {
|
|
300
|
+
mat.dispose();
|
|
301
|
+
}
|
|
302
|
+
catch (error) {
|
|
303
|
+
console.error('ArrowGuide: 释放材质失败', error);
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
// ✨ 创建新的 WeakMap(相当于清空)
|
|
307
|
+
this.fadedMaterials = new WeakMap();
|
|
308
|
+
}
|
|
309
|
+
catch (error) {
|
|
310
|
+
console.error('ArrowGuide: 恢复材质失败', error);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* 动画更新(每帧调用)
|
|
315
|
+
*/
|
|
316
|
+
animate() {
|
|
317
|
+
if (!this.flowActive || !this.lxMesh)
|
|
318
|
+
return;
|
|
319
|
+
try {
|
|
320
|
+
const mat = this.lxMesh.material;
|
|
321
|
+
if (mat && mat.map) {
|
|
322
|
+
const map = mat.map;
|
|
323
|
+
map.offset.y -= 0.01;
|
|
324
|
+
map.needsUpdate = true;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
catch (error) {
|
|
328
|
+
console.error('ArrowGuide: 动画更新失败', error);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* 初始化事件监听器
|
|
333
|
+
*/
|
|
334
|
+
initEvents() {
|
|
335
|
+
const dom = this.renderer.domElement;
|
|
336
|
+
const signal = this.abortController.signal;
|
|
337
|
+
// ✨ 使用 AbortController signal 自动管理事件生命周期
|
|
338
|
+
dom.addEventListener('pointerdown', (e) => {
|
|
339
|
+
this.pointerDownPos.set(e.clientX, e.clientY);
|
|
340
|
+
}, { signal });
|
|
341
|
+
dom.addEventListener('pointerup', (e) => {
|
|
342
|
+
const dx = Math.abs(e.clientX - this.pointerDownPos.x);
|
|
343
|
+
const dy = Math.abs(e.clientY - this.pointerDownPos.y);
|
|
344
|
+
if (dx > this.clickThreshold || dy > this.clickThreshold)
|
|
345
|
+
return; // 拖拽
|
|
346
|
+
const rect = dom.getBoundingClientRect();
|
|
347
|
+
this.mouse.x = ((e.clientX - rect.left) / rect.width) * 2 - 1;
|
|
348
|
+
this.mouse.y = -((e.clientY - rect.top) / rect.height) * 2 + 1;
|
|
349
|
+
this.raycaster.setFromCamera(this.mouse, this.camera);
|
|
350
|
+
const intersects = this.raycaster.intersectObjects(this.scene.children, true);
|
|
351
|
+
const filtered = intersects.filter(i => {
|
|
352
|
+
if (!i.object)
|
|
353
|
+
return false;
|
|
354
|
+
if (this.ignoreRaycastNames.has(i.object.name))
|
|
355
|
+
return false;
|
|
356
|
+
return true;
|
|
357
|
+
});
|
|
358
|
+
if (filtered.length === 0)
|
|
359
|
+
this.restore(); // 点击空白恢复
|
|
360
|
+
}, { signal });
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* 释放所有资源
|
|
364
|
+
*/
|
|
365
|
+
dispose() {
|
|
366
|
+
// ✨ 先恢复材质
|
|
367
|
+
this.restore();
|
|
368
|
+
// ✨ 使用 AbortController 一次性解绑所有事件
|
|
369
|
+
if (this.abortController) {
|
|
370
|
+
this.abortController.abort();
|
|
371
|
+
this.abortController = null;
|
|
372
|
+
}
|
|
373
|
+
// ✨ 清空引用
|
|
374
|
+
this.modelBrightArr = [];
|
|
375
|
+
this.lxMesh = null;
|
|
376
|
+
this.fadedMaterials = new WeakMap();
|
|
377
|
+
this.originalMaterials = new WeakMap();
|
|
378
|
+
this.ignoreRaycastNames.clear();
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
// utils/LiquidFillerGroup.ts
|
|
383
|
+
/**
|
|
384
|
+
* LiquidFillerGroup - 优化版
|
|
385
|
+
* 支持单模型或多模型液位动画、独立颜色控制
|
|
386
|
+
*
|
|
387
|
+
* ✨ 优化内容:
|
|
388
|
+
* - 使用 renderer.domElement 替代 window 事件
|
|
389
|
+
* - 使用 AbortController 管理事件生命周期
|
|
390
|
+
* - 添加错误处理和边界检查
|
|
391
|
+
* - 优化动画管理,避免内存泄漏
|
|
392
|
+
* - 完善资源释放逻辑
|
|
393
|
+
*/
|
|
394
|
+
class LiquidFillerGroup {
|
|
395
|
+
/**
|
|
396
|
+
* 构造函数
|
|
397
|
+
* @param models 单个或多个 THREE.Object3D
|
|
398
|
+
* @param scene 场景
|
|
399
|
+
* @param camera 相机
|
|
400
|
+
* @param renderer 渲染器
|
|
401
|
+
* @param defaultOptions 默认液体选项
|
|
402
|
+
* @param clickThreshold 点击阈值,单位像素
|
|
403
|
+
*/
|
|
404
|
+
constructor(models, scene, camera, renderer, defaultOptions, clickThreshold = 10) {
|
|
405
|
+
this.items = [];
|
|
406
|
+
this.raycaster = new THREE.Raycaster();
|
|
407
|
+
this.pointerDownPos = new THREE.Vector2();
|
|
408
|
+
this.clickThreshold = 10;
|
|
409
|
+
this.abortController = null; // ✨ 事件管理器
|
|
410
|
+
/** pointerdown 记录位置 */
|
|
411
|
+
this.handlePointerDown = (event) => {
|
|
412
|
+
this.pointerDownPos.set(event.clientX, event.clientY);
|
|
413
|
+
};
|
|
414
|
+
/** pointerup 判断点击空白,恢复原始材质 */
|
|
415
|
+
this.handlePointerUp = (event) => {
|
|
416
|
+
const dx = event.clientX - this.pointerDownPos.x;
|
|
417
|
+
const dy = event.clientY - this.pointerDownPos.y;
|
|
418
|
+
const distance = Math.sqrt(dx * dx + dy * dy);
|
|
419
|
+
if (distance > this.clickThreshold)
|
|
420
|
+
return; // 拖拽不触发
|
|
421
|
+
// ✨ 使用 renderer.domElement 的实际尺寸
|
|
422
|
+
const rect = this.renderer.domElement.getBoundingClientRect();
|
|
423
|
+
const pointerNDC = new THREE.Vector2(((event.clientX - rect.left) / rect.width) * 2 - 1, -((event.clientY - rect.top) / rect.height) * 2 + 1);
|
|
424
|
+
this.raycaster.setFromCamera(pointerNDC, this.camera);
|
|
425
|
+
// 点击空白 -> 所有模型恢复
|
|
426
|
+
const intersectsAny = this.items.some(item => this.raycaster.intersectObject(item.model, true).length > 0);
|
|
427
|
+
if (!intersectsAny) {
|
|
428
|
+
this.restoreAll();
|
|
429
|
+
}
|
|
430
|
+
};
|
|
431
|
+
this.scene = scene;
|
|
432
|
+
this.camera = camera;
|
|
433
|
+
this.renderer = renderer;
|
|
434
|
+
this.clickThreshold = clickThreshold;
|
|
435
|
+
// ✨ 创建 AbortController 用于事件管理
|
|
436
|
+
this.abortController = new AbortController();
|
|
437
|
+
const modelArray = Array.isArray(models) ? models : [models];
|
|
438
|
+
modelArray.forEach(model => {
|
|
439
|
+
var _a, _b, _c;
|
|
440
|
+
try {
|
|
441
|
+
const options = {
|
|
442
|
+
color: (_a = defaultOptions === null || defaultOptions === void 0 ? void 0 : defaultOptions.color) !== null && _a !== void 0 ? _a : 0x00ff00,
|
|
443
|
+
opacity: (_b = defaultOptions === null || defaultOptions === void 0 ? void 0 : defaultOptions.opacity) !== null && _b !== void 0 ? _b : 0.6,
|
|
444
|
+
speed: (_c = defaultOptions === null || defaultOptions === void 0 ? void 0 : defaultOptions.speed) !== null && _c !== void 0 ? _c : 0.05,
|
|
445
|
+
};
|
|
446
|
+
// 保存原始材质
|
|
447
|
+
const originalMaterials = new Map();
|
|
448
|
+
model.traverse(obj => {
|
|
449
|
+
if (obj.isMesh) {
|
|
450
|
+
const mesh = obj;
|
|
451
|
+
originalMaterials.set(mesh, mesh.material);
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
// ✨ 边界检查:确保有材质可以保存
|
|
455
|
+
if (originalMaterials.size === 0) {
|
|
456
|
+
console.warn('LiquidFillerGroup: 模型没有 Mesh 对象', model);
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
// 应用淡线框材质
|
|
460
|
+
model.traverse(obj => {
|
|
461
|
+
if (obj.isMesh) {
|
|
462
|
+
const mesh = obj;
|
|
463
|
+
mesh.material = new THREE.MeshBasicMaterial({
|
|
464
|
+
color: 0xffffff,
|
|
465
|
+
wireframe: true,
|
|
466
|
+
transparent: true,
|
|
467
|
+
opacity: 0.2,
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
});
|
|
471
|
+
// 创建液体 Mesh
|
|
472
|
+
const geometries = [];
|
|
473
|
+
model.traverse(obj => {
|
|
474
|
+
if (obj.isMesh) {
|
|
475
|
+
const mesh = obj;
|
|
476
|
+
const geom = mesh.geometry.clone();
|
|
477
|
+
geom.applyMatrix4(mesh.matrixWorld);
|
|
478
|
+
geometries.push(geom);
|
|
479
|
+
}
|
|
480
|
+
});
|
|
481
|
+
if (geometries.length === 0) {
|
|
482
|
+
console.warn('LiquidFillerGroup: 模型没有几何体', model);
|
|
483
|
+
return;
|
|
484
|
+
}
|
|
485
|
+
const mergedGeometry = BufferGeometryUtils.mergeGeometries(geometries, false);
|
|
486
|
+
if (!mergedGeometry) {
|
|
487
|
+
console.error('LiquidFillerGroup: 几何体合并失败', model);
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
const material = new THREE.MeshPhongMaterial({
|
|
491
|
+
color: options.color,
|
|
492
|
+
transparent: true,
|
|
493
|
+
opacity: options.opacity,
|
|
494
|
+
side: THREE.DoubleSide,
|
|
495
|
+
});
|
|
496
|
+
const liquidMesh = new THREE.Mesh(mergedGeometry, material);
|
|
497
|
+
this.scene.add(liquidMesh);
|
|
498
|
+
// 设置 clippingPlane
|
|
499
|
+
const clipPlane = new THREE.Plane(new THREE.Vector3(0, -1, 0), 0);
|
|
500
|
+
const mat = liquidMesh.material;
|
|
501
|
+
mat.clippingPlanes = [clipPlane];
|
|
502
|
+
this.renderer.localClippingEnabled = true;
|
|
503
|
+
this.items.push({
|
|
504
|
+
model,
|
|
505
|
+
liquidMesh,
|
|
506
|
+
clipPlane,
|
|
507
|
+
originalMaterials,
|
|
508
|
+
options,
|
|
509
|
+
animationId: null // ✨ 初始化动画 ID
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
catch (error) {
|
|
513
|
+
console.error('LiquidFillerGroup: 初始化模型失败', model, error);
|
|
514
|
+
}
|
|
515
|
+
});
|
|
516
|
+
// ✨ 使用 renderer.domElement 替代 window,使用 AbortController signal
|
|
517
|
+
const signal = this.abortController.signal;
|
|
518
|
+
this.renderer.domElement.addEventListener('pointerdown', this.handlePointerDown, { signal });
|
|
519
|
+
this.renderer.domElement.addEventListener('pointerup', this.handlePointerUp, { signal });
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* 设置液位
|
|
523
|
+
* @param models 单个模型或模型数组
|
|
524
|
+
* @param percent 液位百分比 0~1
|
|
525
|
+
*/
|
|
526
|
+
fillTo(models, percent) {
|
|
527
|
+
// ✨ 边界检查
|
|
528
|
+
if (percent < 0 || percent > 1) {
|
|
529
|
+
console.warn('LiquidFillerGroup: percent 必须在 0~1 之间', percent);
|
|
530
|
+
percent = Math.max(0, Math.min(1, percent));
|
|
531
|
+
}
|
|
532
|
+
const modelArray = Array.isArray(models) ? models : [models];
|
|
533
|
+
modelArray.forEach(model => {
|
|
534
|
+
const item = this.items.find(i => i.model === model);
|
|
535
|
+
if (!item) {
|
|
536
|
+
console.warn('LiquidFillerGroup: 未找到模型', model);
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
if (!item.liquidMesh) {
|
|
540
|
+
console.warn('LiquidFillerGroup: liquidMesh 已被释放', model);
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
// ✨ 取消之前的动画
|
|
544
|
+
if (item.animationId !== null) {
|
|
545
|
+
cancelAnimationFrame(item.animationId);
|
|
546
|
+
item.animationId = null;
|
|
547
|
+
}
|
|
548
|
+
try {
|
|
549
|
+
const box = new THREE.Box3().setFromObject(item.liquidMesh);
|
|
550
|
+
const min = box.min.y;
|
|
551
|
+
const max = box.max.y;
|
|
552
|
+
const targetHeight = min + (max - min) * percent;
|
|
553
|
+
const animate = () => {
|
|
554
|
+
if (!item.liquidMesh) {
|
|
555
|
+
item.animationId = null;
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
const diff = targetHeight - item.clipPlane.constant;
|
|
559
|
+
if (Math.abs(diff) > 0.01) {
|
|
560
|
+
item.clipPlane.constant += diff * item.options.speed;
|
|
561
|
+
item.animationId = requestAnimationFrame(animate);
|
|
562
|
+
}
|
|
563
|
+
else {
|
|
564
|
+
item.clipPlane.constant = targetHeight;
|
|
565
|
+
item.animationId = null;
|
|
566
|
+
}
|
|
567
|
+
};
|
|
568
|
+
animate();
|
|
569
|
+
}
|
|
570
|
+
catch (error) {
|
|
571
|
+
console.error('LiquidFillerGroup: fillTo 执行失败', model, error);
|
|
572
|
+
}
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
/** 设置多个模型液位,percentList 与 items 顺序对应 */
|
|
576
|
+
fillToAll(percentList) {
|
|
577
|
+
if (percentList.length !== this.items.length) {
|
|
578
|
+
console.warn(`LiquidFillerGroup: percentList 长度 (${percentList.length}) 与 items 长度 (${this.items.length}) 不匹配`);
|
|
579
|
+
}
|
|
580
|
+
percentList.forEach((p, idx) => {
|
|
581
|
+
if (idx < this.items.length) {
|
|
582
|
+
this.fillTo(this.items[idx].model, p);
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
/** 恢复单个模型原始材质并移除液体 */
|
|
587
|
+
restore(model) {
|
|
588
|
+
const item = this.items.find(i => i.model === model);
|
|
589
|
+
if (!item)
|
|
590
|
+
return;
|
|
591
|
+
// ✨ 取消动画
|
|
592
|
+
if (item.animationId !== null) {
|
|
593
|
+
cancelAnimationFrame(item.animationId);
|
|
594
|
+
item.animationId = null;
|
|
595
|
+
}
|
|
596
|
+
// 恢复原始材质
|
|
597
|
+
item.model.traverse(obj => {
|
|
598
|
+
if (obj.isMesh) {
|
|
599
|
+
const mesh = obj;
|
|
600
|
+
const original = item.originalMaterials.get(mesh);
|
|
601
|
+
if (original)
|
|
602
|
+
mesh.material = original;
|
|
603
|
+
}
|
|
604
|
+
});
|
|
605
|
+
// 释放液体 Mesh
|
|
606
|
+
if (item.liquidMesh) {
|
|
607
|
+
this.scene.remove(item.liquidMesh);
|
|
608
|
+
item.liquidMesh.geometry.dispose();
|
|
609
|
+
if (Array.isArray(item.liquidMesh.material)) {
|
|
610
|
+
item.liquidMesh.material.forEach(m => m.dispose());
|
|
611
|
+
}
|
|
612
|
+
else {
|
|
613
|
+
item.liquidMesh.material.dispose();
|
|
614
|
+
}
|
|
615
|
+
item.liquidMesh = null;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
/** 恢复所有模型 */
|
|
619
|
+
restoreAll() {
|
|
620
|
+
this.items.forEach(item => this.restore(item.model));
|
|
621
|
+
}
|
|
622
|
+
/** 销毁方法,释放事件和资源 */
|
|
623
|
+
dispose() {
|
|
624
|
+
// ✨ 先恢复所有模型
|
|
625
|
+
this.restoreAll();
|
|
626
|
+
// ✨ 使用 AbortController 一次性解绑所有事件
|
|
627
|
+
if (this.abortController) {
|
|
628
|
+
this.abortController.abort();
|
|
629
|
+
this.abortController = null;
|
|
630
|
+
}
|
|
631
|
+
// ✨ 清空 items
|
|
632
|
+
this.items.length = 0;
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
export { ArrowGuide, LiquidFillerGroup, createModelClickHandler };
|
|
637
|
+
//# sourceMappingURL=index.mjs.map
|