Three.js加载OBJ模型实现爆炸/聚合效果的方向计算求助
解决Three.js OBJ模型爆炸/聚合效果的方案
嘿,作为Three.js新手,你已经能获取到模型部件并修改位置,这已经迈出了关键一步!你的核心问题是不知道部件该朝哪个方向运动,其实思路很简单:让每个部件沿着远离(爆炸)或靠近(聚合)模型中心的方向移动,下面我给你一步步拆解实现方法:
核心思路
OBJ加载后每个部件都是独立的Mesh,我们不需要操作顶点(那是单个几何体的爆炸方式),直接控制每个Mesh的位置即可:
- 先保存每个部件的初始位置,方便聚合时回到原位
- 确定一个爆炸中心点(比如模型的几何中心)
- 计算每个部件到爆炸中心的方向向量,爆炸时沿这个方向向外移动,聚合时反向移动
具体实现代码
第一步:加载模型后初始化数据
加载完OBJ模型后,先收集所有Mesh部件,保存它们的初始位置,并计算爆炸方向:
// 假设object是你加载的OBJ模型对象 const parts = []; // 遍历模型,收集所有Mesh部件(避免嵌套层级漏掉) object.traverse(child => { if (child.isMesh) { parts.push(child); // 保存部件的初始局部位置 child.userData.initialPosition = child.position.clone(); } }); // 计算模型的几何中心作为爆炸点(比固定(0,0,0)更自然) const boundingBox = new THREE.Box3().setFromObject(object); const explosionCenter = boundingBox.getCenter(new THREE.Vector3()); // 给每个部件计算爆炸方向 parts.forEach(part => { // 计算从爆炸中心指向部件初始位置的方向向量,归一化后确保移动速度一致 const direction = part.userData.initialPosition.clone().sub(explosionCenter).normalize(); part.userData.explodeDirection = direction; // 给每个部件加随机速度,避免所有部件移动节奏完全一致 part.userData.velocity = Math.random() * 0.5 + 0.2; });
第二步:在动画循环中实现爆炸/聚合动画
用一个进度变量控制爆炸的程度,0是初始状态,1是完全爆炸,通过切换进度的增减来实现爆炸和聚合的切换:
// 爆炸进度:0=初始状态,1=完全爆炸 let explodeProgress = 0; // 控制当前是爆炸还是聚合 let isExploding = true; // 最大爆炸距离,可根据你的模型大小调整 const maxExplodeDistance = 150; function animate() { requestAnimationFrame(animate); // 更新爆炸进度 if (isExploding) { // 爆炸:进度增加到1后停止 explodeProgress = Math.min(explodeProgress + 0.01, 1); } else { // 聚合:进度减少到0后停止 explodeProgress = Math.max(explodeProgress - 0.01, 0); } // 更新每个部件的位置 parts.forEach(part => { const initialPos = part.userData.initialPosition; const direction = part.userData.explodeDirection; const velocity = part.userData.velocity; // 计算当前进度下的位置偏移量 const offset = direction.multiplyScalar(explodeProgress * maxExplodeDistance * velocity); // 设置部件新位置:初始位置 + 偏移量 part.position.copy(initialPos).add(offset); }); renderer.render(scene, camera); } animate();
第三步:添加交互切换爆炸/聚合(可选)
你可以加个点击事件来切换爆炸和聚合状态,比如:
window.addEventListener('click', () => { isExploding = !isExploding; });
为什么和参考示例不同?
你找到的参考示例是对单个几何体的顶点做爆炸,而你的场景是多个独立的Mesh部件,所以不需要操作顶点数组,直接控制每个Mesh的position就可以,逻辑更简单。
内容的提问来源于stack exchange,提问作者Nguyễn Minh Vương
相关产品推荐
相关产品推荐

