原理:通过修改模型材质的 x,y,z 轴坐标 positon.set( x,y,z) 来实现拆解,分解的效果。
注意:支持模型材质position 修改的材质类型为 type=“Mesh” ,其他类型的材质修改了position 可能没有实际效果
在上一篇 Three.js加载外部glb,fbx,gltf,obj 模型文件 的文章基础上新增一个 setModelMeshDecompose(模型拆解方法)
安装 tween.js (用于处理模型拆解的位置移动缓冲动画效果)
yarn add @tweenjs/tween.js
import TWEEN from "@tweenjs/tween.js";
setModelMeshDecompose 方法
// decompose 分解的大小距离
setModelMeshDecompose(decompose ) {
// 如果当前模型只有一个材质则不进行拆解
if (this.glowMaterialList.length <= 1) return false
// 修改材质位置移动
const modelDecomposeMove = (obj, position) => {
new TWEEN.Tween(obj.position)
.to(position, 500)
.onUpdate(function (val) {
obj.position.set(val.x || 0, val.y || 0, val.z || 0);
})
.start();
}
const length = this.glowMaterialList.length
const angleStep = (2 * Math.PI) / length;
// TODD glowMaterialList:当前模型的所有材质列表名称
this.glowMaterialList.forEach((name, i) => {
// 通过 getObjectByName 获取 要修改的材质
const mesh = this.model.getObjectByName(name)
// 如果 type 类型为Mesh 则修改材质的位置
if (mesh.type == 'Mesh') {
// 拆解位置移动的计算公式
const angle = i * angleStep;
const x = (decompose) * Math.cos(angle);
const y = (decompose) * Math.sin(angle);
const position = {
x, y, z: 0
}
// 执行拆解
modelDecomposeMove(mesh, position)
}
})
}
获取当前模型的所有材质名称的方法
getFlowMeaterList(){
const modelMaterialList= []
this.model.traverse((v) => {
if (v.isMesh && v.material) {
modelMaterialList.push(v)
}
})
this.glowMaterialList = modelMaterialList.map(v=>v.name)
}
在场景渲染动画帧方法中添加 TWEEN.update()
render(){
this.renderer.render(this.scene, this.camera)
TWEEN.update()
}
完整的代码可参考:https://gitee.com/ZHANG_6666/Three.js3D/blob/master/src/views/renderModel.js
界面效果对比