莫道君行早、更有早行人

94 阅读1分钟

three.模型按预定轨迹移动

一. 自定义轨迹线

let peoplepoiArrs = [
    new THREE.Vector3(15, 22, 82),
    new THREE.Vector3(24, 22, 82),
    new THREE.Vector3(28, 22, 82),
    new THREE.Vector3(35, 22, 82),
    new THREE.Vector3(37, 22, 77),
];
const peoplepoiArr = new THREE.CatmullRomCurve3(peoplepoiArrs);
export { peoplepoiArr };

二. 轨迹移动函数

import * as THREE from 'three';

/* 轨迹跟随 */
let progress = 0; // 物体运动时在运动路径的初始位置,范围0~1
// const velocity = 0.008; // 速度

const moveCurveFn = (curve:object | any ,curveMod:object | any, velocity = 0.008) =>  {
    /* 轨迹与模型 */
    if (curve && curveMod) {
        
        if (progress <= 1 - velocity) {
            const point = curve.getPointAt(progress); //获取样条曲线指定点坐标
            const pointBox = curve.getPointAt(progress + velocity);
            if (point && pointBox) {
                curveMod.position.set(point.x, point.y, point.z);
                let targetPos = pointBox;
                let offsetAngle = -1*Math.PI;  // 可设置方向朝向 默认0
                let mtx = new THREE.Matrix4()  // 创建一个4维矩阵
                mtx.lookAt(curveMod.position, targetPos, curveMod.up) //设置朝向
                mtx.multiply(new THREE.Matrix4().makeRotationFromEuler(new THREE.Euler(0, offsetAngle, 0)))

                let toRot = new THREE.Quaternion().setFromRotationMatrix(mtx)  //计算出需要进行旋转的四元数值
                curveMod.quaternion.slerp(toRot, 0.2)
            }
            progress += velocity;
            requestAnimationFrame(()=>moveCurveFn(curve,curveMod,velocity)); // 动画自动结束
        } else {
            /* 可设置是否循环 如循环:progress = 0; requestAnimationFrame()拿到上级循环 */
            progress = 1;
            if (progress == 1) { progress = 0 }
        }
    }
}

export default moveCurveFn;

三. 引入使用函数

import moveCurveFn from '../hooks/curveMove';


let v3pos = [
    new THREE.Vector3(clickX, clickY, clickZ)
]
carArr.curveType = 'catmullrom'; //设置是否张力
carArr.closed = true; //设置是否闭环
carArr.tension = 0.5; //设置线的张力,0为无弧度折线

// 为曲线添加材质在场景中显示出来,方便看到轨迹线
const points = carArr.getPoints(50)
const geometry = new THREE.BufferGeometry().setFromPoints(points);
const material = new THREE.LineBasicMaterial({ color: 0x000000 });

moveCurveFn(firepoiArr,firecarmod,0.004)