下面的代码功能是控制一个三维模型沿着特定曲线轨迹运动。
曲线通过三维样条曲线曲线类THREE.CatmullRomCurve3
创建,然后从样条曲线通过曲线的方法.getPoints()
获取曲线上一系列的顶点坐标,得到顶点坐标就可以通过顶点坐标结合threejs帧动画来控制网格模型沿着曲线轨迹移动。
...
// 创建一个模型,用于沿着三维曲线运动
var box = new THREE.BoxGeometry(5, 5, 5);
var material = new THREE.MeshLambertMaterial({
color: 0x0000ff
}); //材质对象
var mesh = new THREE.Mesh(box, material);
scene.add(mesh);
mesh.position.set(-10, -50, -50)
...
// 通过类CatmullRomCurve3创建一个3D样条曲线
var curve = new THREE.CatmullRomCurve3([
new THREE.Vector3(-10, -50, -50),
new THREE.Vector3(10, 0, 0),
new THREE.Vector3(8, 50, 50),
new THREE.Vector3(-5, 0, 100)
]);
// 样条曲线均匀分割100分,返回51个顶点坐标
var points = curve.getPoints(100);
console.log('points', points);//控制台查看返回的顶点坐标
var geometry = new THREE.Geometry();
// 把从曲线轨迹上获得的顶点坐标赋值给几何体
geometry.vertices = points
var material = new THREE.LineBasicMaterial({
color: 0x4488ff
});
var line = new THREE.Line(geometry, material);
scene.add(line)
// 通过Threejs的帧动画相关API播放网格模型沿着曲线做动画运动
// 声明一个数组用于存储时间序列
let arr = []
for (let i = 0; i < 101; i++) {
arr.push(i)
}
// 生成一个时间序列
var times = new Float32Array(arr);
var posArr = []
points.forEach(elem => {
posArr.push(elem.x, elem.y, elem.z)
});
// 创建一个和时间序列相对应的位置坐标系列
var values = new Float32Array(posArr);
// 创建一个帧动画的关键帧数据,曲线上的位置序列对应一个时间序列
var posTrack = new THREE.KeyframeTrack('.position', times, values);
let duration = 101;
let clip = new THREE.AnimationClip("default", duration, [posTrack]);
var mixer = new THREE.AnimationMixer(mesh);
let AnimationAction = mixer.clipAction(clip);
AnimationAction.timeScale = 20;
AnimationAction.play();
...
var clock = new THREE.Clock();//声明一个时钟对象
function render() {
renderer.render(scene, camera);
requestAnimationFrame(render);
// 更新帧动画的时间
mixer.update(clock.getDelta());
}
render();