当模型动起来时,如何切换到模型的视角呢?
导出的模型里面不仅有场景,还有相机等元素,因此我们只需把这个相机给到全局相机即可。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="http://www.yanhuangxueyuan.com/threejs/build/three.min.js"></script>
<script src="http://www.yanhuangxueyuan.com/threejs/examples/js/controls/OrbitControls.js"></script>
<script src="http://www.yanhuangxueyuan.com/threejs/examples/js/loaders/GLTFLoader.js"></script>
<script src="http://www.yanhuangxueyuan.com/threejs/examples/js/loaders/DRACOLoader.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.4/gsap.min.js"></script>
</head>
<body>
<div id="webgl"></div>
</body>
</html>
<script>
var camera, scene, renderer;
let redcar = null;//红色跑车
let curve = null;//运行轨迹
init();
function init() {
//场景
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 100);
scene.add(camera);//添加相机
//添加坐标轴
var axes = new THREE.AxesHelper(500);//500表示xyz轴的长度,红:x,绿:y,蓝:z
scene.add(axes);
addGlb('./model/city.glb');
render();
animate();
}
async function addGlb(filepath) {
const loader = new THREE.GLTFLoader();
const dracoloader = getDracoLoader();
loader.setDRACOLoader(dracoloader);//注入loader
const city = await loadGlb(filepath, loader);
scene.add(city.scene);
city.scene.traverse(child => {
if (child.name === 'redcar') {
redcar = child;//设定跑车
}
if (child.name === '汽车园区轨迹') {
//跑车轨迹
const line = child;
const points = [];
line.visible = false;
for (let i = line.geometry.attributes.position.count - 1; i >= 0; i--) {
points.push(new THREE.Vector3(
line.geometry.attributes.position.getX(i),
line.geometry.attributes.position.getY(i),
line.geometry.attributes.position.getZ(i)
))
}
curve = new THREE.CatmullRomCurve3(points, false);//创建曲线,不闭合
carAnimation();//运行动画
}
city.cameras.forEach(v => {
//切换相机到跑车视角
if (v.name === 'carcamera_Orientation') {
camera = v;
}
})
});
}
//动画
function carAnimation() {
let curveProgess = 0;
gsap.to(null, {
duration: 50,
repeat: -1,
onUpdate: () => {
if (curveProgess >= 1) {
curveProgess = 0;
}
let point = curve.getPoint(curveProgess)
// 让汽车运动
redcar.position.set(point.x, point.y, point.z)
curveProgess += 0.001;
// 朝向下一个点
point = curve.getPoint(curveProgess);
redcar.lookAt(point);
}
})
}
function getDracoLoader() {
//对模型解压
const dracoloader = new THREE.DRACOLoader();
dracoloader.setDecoderPath("./draco/");//把examples\jsm\libs\draco这个文件夹复制过来
dracoloader.setDecoderConfig({ type: "js" })
dracoloader.preload();
return dracoloader;
}
function loadGlb(filepath, loader) {
return new Promise((resolve, reject) => {
loader.setCrossOrigin('Anonymous');//跨域问题
loader.load(filepath, (gltf) => {
console.log('gltf>>>', gltf);
//处理材质丢失的情况
gltf.scene.traverse(child => {
if (child.isMesh) {
child.material.emissive = child.material.color;
child.material.emissiveMap = child.material.map;
}
});
resolve(gltf);
}, undefined, (error) => {
console.error(error);
reject(error);
});
});
}
function render() {
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});//画布
renderer.setSize(window.innerWidth, window.innerHeight);//设置渲染区域尺寸
renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
document.getElementById('webgl').appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
});
}
function animate() {
renderer.render(scene, camera);//开始渲染
requestAnimationFrame(animate);
}
</script>
GIF 2023-1-9 16-32-04.gif







网友评论