已被阅读 2834 次 | 文章分类:javascript | 2022-05-29 20:42
threejs实现模型炸开的效果
1 效果如下
2 基本原理
首先加载一个obj模型;然后遍历obj模型的所有children mesh;按一定比例改变每个子mesh的中心点位置即可;
爆炸代码:
function modelExplode(num){
// 模型世界中心
var modelWorldCenter=new THREE.Vector3(0,0,0);//.addVectors(box.max,box.min).multiplyScalar(0.5);//模型中心坐标
// 定义盒子
var childBox=new THREE.Box3();
// 遍历场景所有元素
scene.traverse(function(child){
// 如果元素是mesh
if(child.isMesh){
childBox.setFromObject(child);
debugger;
var childCenter=new THREE.Vector3().addVectors(childBox.max,childBox.min).multiplyScalar(0.5);
if(isNaN(childCenter.x))return;
child.childCenter=new THREE.Vector3().subVectors(childCenter,modelWorldCenter).normalize();
if(!child.isMesh || !child.childCenter) return;
// 爆炸公式:更改mesh位置
child.position.copy(child.childCenter).multiplyScalar(num);
}
});
}
3 全部代码
import * as THREE from 'three'
import { OBJLoader, MTLLoader } from 'three-obj-mtl-loader'
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
let scene,camera,gridHelper,axes,renderer;
initScene();
function initScene(){
// ---------------------------------------------------------------------
// 场景和相机
// ---------------------------------------------------------------------
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 100000);
camera.position.set(1940, 650, 850 );
camera.lookAt(0,0,0);
// ---------------------------------------------------------------------
// 辅助网格
// ---------------------------------------------------------------------
gridHelper = new THREE.GridHelper(12000, 20, 0x888888, 0x444444 );
gridHelper.position.y = - 50;
gridHelper.name = "Grid";
scene.add(gridHelper);
// ---------------------------------------------------------------------
// 辅助坐标轴
// ---------------------------------------------------------------------
axes = new THREE.AxesHelper(50000);
axes.name = "AxesHelper";
scene.add(axes);
// 光源一定要添加,否则模型没有光 肯定是黑色
var light = new THREE.DirectionalLight(0xffffff);// 光源颜色
light.position.set(20, 10, 1305);// 光源位置
scene.add(light);// 光源添加到场景中
// ---------------------------------------------------------------------
// 渲染器
// ---------------------------------------------------------------------
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
let controls = new OrbitControls(camera,renderer.domElement);
animate();
function animate() {
requestAnimationFrame(animate);
controls.update();
renderer.render(scene, camera);
}
}
let path="./statics/models/obj/IronMan/";
let objName="IronMan.obj";
let mtlName="IronMan.mtl";
initModel();
// 初始化钢铁侠模型
function initModel() {
try{
// 1 定义材质加载器
var mtlLoader=new MTLLoader();
// 2 指定材质的资源路径
mtlLoader.resourcePath=path;
mtlLoader.path=path;
// 3 加载材质文件
mtlLoader.load(mtlName,function(materials){
// 材质预加载
materials.preload();
// 4 定义 obj加载器
var objLoader=new OBJLoader();
// 5 设置 材质
objLoader.setMaterials(materials);
// 6 设置 obj模型资源路径
objLoader.setPath(path);
// 7 加载 obj模型文件
objLoader.load(objName,function(obj){
console.log("obj.children",obj.children)
obj.position.y=10;
obj.scale.set(10, 10, 10);
scene.add(obj);
modelExplode(200)
})
})
}catch(e){
console.error('解析失败',e);
}
}
function modelExplode(num){
// 模型世界中心
var modelWorldCenter=new THREE.Vector3(0,0,0);//.addVectors(box.max,box.min).multiplyScalar(0.5);//模型中心坐标
// 定义盒子
var childBox=new THREE.Box3();
// 遍历场景所有元素
scene.traverse(function(child){
// 如果元素是mesh
if(child.isMesh){
childBox.setFromObject(child);
debugger;
var childCenter=new THREE.Vector3().addVectors(childBox.max,childBox.min).multiplyScalar(0.5);
if(isNaN(childCenter.x))return;
child.childCenter=new THREE.Vector3().subVectors(childCenter,modelWorldCenter).normalize();
if(!child.isMesh || !child.childCenter) return;
// 爆炸公式:更改mesh位置
child.position.copy(child.childCenter).multiplyScalar(num);
}
});
}
亦可以根据range滑动条交互的方式,改变爆炸的幅度
let scaleDom=document.getElementById('scale');
scaleDom.ondragend=function(num){
modelExplode(scaleDom.value)
}
QQ:3410192267 | 技术支持 微信:popstarqqsmall
Copyright ©2017 xiaobaigis.com . 版权所有 鲁ICP备17027716号