1,介绍
该示例使用的是 r95版本Three.js库。
主要实现功能:创建一个管道(管道的作用主要是方便观察运动方向),镜头跟随物体移动效果,物体上下左右拐弯镜头跟随拐弯。
效果图如下:
2,实现思路
1,定义关键固定位置坐标,用固定坐标值生成一组曲线。
2,将曲线分割成多份获取分割后的一组顶点坐标
3,加载物体并设置初始位置,这里用的是个飞机模型
4,通过Threejs的帧动画实时修改物体坐标和物体朝向,达到运动效果
根据坐标生成曲线,并创建一个管道
// 通过类CatmullRomCurve3创建一个3D样条曲线
curve = new THREE.CatmullRomCurve3([
new THREE.Vector3(-1000, -5000, -5000),
new THREE.Vector3(1000, -5000, 0),
new THREE.Vector3(1800, 800, 1000),
new THREE.Vector3(800, 5000, 5000),
new THREE.Vector3(0, 0, 10000)
]);
// 样条曲线均匀分割100
var points = curve.getPoints(100);
var geometry = new THREE.Geometry();
// 把从曲线轨迹上获得的顶点坐标赋值给几何体
geometry.vertices = points
var material = new THREE.LineBasicMaterial({
color: "#4488ff"
});
var line = new THREE.Line(geometry, material);
scene.add(line);
//管道体
const tubeGeometry = new THREE.TubeGeometry(curve, 100, 500, 30); // 101取点数 3为r 30为三角切面数
const tubeMesh = new THREE.Mesh(tubeGeometry, new THREE.MeshBasicMaterial({
color: "#00aa00",
side: THREE.DoubleSide,
wireframe: true
}))
scene.add(tubeMesh)
加载物体模型,这里用的是个飞机模型glb格式
// 引用GLTFLoader.js文件,加载模型
var loader = new THREE.GLTFLoader();
loader.load('assets/models/feiji/feiji.glb', function(result) {
mesh = result.scene;
mesh.position.set(-1000, -5000, -5000);
scene.add(mesh);
});
实时修改物体坐标和物体朝向
function changeLookAt(t) {
// 当前点在线条上的位置
const position = curve.getPointAt(t);
var nPos = new THREE.Vector3(position.x, position.y - 100, position.z);
mesh.position.copy(nPos);
// 返回点t在曲线上位置切线向量
const tangent = curve.getTangentAt(t);
// 位置向量和切线向量相加即为所需朝向的点向量
const lookAtVec = tangent.add(nPos);
mesh.lookAt(lookAtVec);
if (t > 0.03) {
var pos = curve.getPointAt(t - 0.03);
camera.position.copy(pos);
camera.lookAt(position)
}
}
var clock = new THREE.Clock(); //声明一个时钟对象
const loopTime = 10 * 1000; // loopTime: 循环一圈的时间
let i = 0;
function renderScene() {
// 使用requestAnimationFrame函数进行渲染
requestAnimationFrame(renderScene);
renderer.render(scene, camera);
if (curve) {
let time = Date.now();
let t = (time % loopTime) / loopTime; // 计算当前时间进度百分比
setTimeout(function() {
changeLookAt(t);
}, 2000)
}
}
在线预览:左本的博客 (zuoben.top)