线性移动,包括直线移动和曲线移动,移动更流畅,执行结束有回调函数

import * as THREE from "three";
export function cureMoveFn(pointNumber: number, mesh: any, points: THREE.Vector3[], camera: THREE.Camera, renderer: THREE.WebGLRenderer, scene: THREE.Scene, isClear: any, fun: any) {
    //第一个参数曲线上的点,点越多,移动的越慢,mesh是小车的模型,points是车辆的参考路径,后面的就是老三样
    const curve = new THREE.CatmullRomCurve3(points);
    //更新下模型的方向矩阵吧,我是这么理解的
    mesh.updateMatrix();
    const localMatrix = mesh.matrix.clone();
    const forwardVector = new THREE.Vector3();

    // 获取模型的前方向
    forwardVector.setFromMatrixColumn(localMatrix, 2);

    // 单位化前方向
    forwardVector.normalize();
    //从第一个点出发
    let pathIndex = 1;
    let isAnimating = true; // 添加一个标志来控制动画是否继续
    function initAnimate() {
        if (pathIndex === pointNumber - 1) {
            //如果你要循环执行的话把return换成重新赋值,pathIndex=0
            fun();
            if (isClear == true) {
                scene.remove(mesh);
            }
            return

        }
        pathIndex += 1;
        //判断模型是否加载成功了
        if (mesh) {
            //这里其实就是获取两个相近的点,形成一个向量,近似于切线的单位向量
            // 样条曲线上某个点的比值(0-1)之间
            const sphereCurveIndex = pathIndex / pointNumber;
            // 样条曲线上某个点的比值(0-1)之间
            const sphereCurveIndex1 = (pathIndex - 1) / pointNumber;

            const positionVec = curve.getPointAt(sphereCurveIndex); //获取曲线上位置的点,传值为0-1的小数表示整个线段的位置
            const positionVec1 = curve.getPointAt(sphereCurveIndex1);
            let tangent = new THREE.Vector3(positionVec.x - positionVec1.x, positionVec.y - positionVec1.y, positionVec.z - positionVec1.z)
            tangent.normalize()
            //这一行是一点点移动车的位置
            mesh.position.set(positionVec.x, positionVec.y, positionVec.z);
            // 这三行是让小车朝向切线方向,用到了四元数,setFromUnitVectors
            const q = new THREE.Quaternion();
            q.setFromUnitVectors(forwardVector, tangent);
            // 把四元数赋值给模型的方向矩阵
            mesh.quaternion.copy(q);
            console.log(0);
            renderer.render(scene, camera);
        }
        if (isAnimating) {
            requestAnimationFrame(initAnimate);
        }

    }
    initAnimate()
}

export function carMove(pointNumber: number, mesh: any, points: any, camera: any, renderer: any, scene: any, isClear: any, fun: any) {
    let statement: any = true;
    document.addEventListener('keydown', function (event) {
        if (event.key === 'p') {
            statement = !statement;
        }
    });
    //第一个参数曲线上的点,点越多,移动的越慢,mesh是小车的模型,points是车辆的参考路径,后面的就是老三样
    // const curve = new THREE.CatmullRomCurve3(points);
    const CurvePath = new THREE.CurvePath();
    for (let i = 0; i < points.length - 1; i++) {
        const line = new THREE.LineCurve3(points[i], points[i + 1]);
        CurvePath.curves.push(line);
    }

    //更新下模型的方向矩阵吧,我是这么理解的 
    console.log(mesh.matrix);

    mesh.updateMatrix();
    console.log(mesh.matrix);

    const localMatrix = mesh.matrix.clone();
    const forwardVector = new THREE.Vector3();

    // 获取模型的前方向
    forwardVector.setFromMatrixColumn(localMatrix, 2);
    console.log(forwardVector);


    // 单位化前方向
    forwardVector.normalize();
    //从第一个点出发
    let pathIndex = 1;
    function initAnimate() {
        console.log('11111');

        if (pathIndex === pointNumber - 1) {
            //如果你要循环执行的话把return换成重新赋值,pathIndex=0
            fun();
            if (isClear == true) {
                scene.remove(mesh);
            }
            return
        }
        //判断模型是否加载成功了
        if (mesh && statement) {
            pathIndex += 1;
            //这里其实就是获取两个相近的点,形成一个向量,近似于切线的单位向量
            // 样条曲线上某个点的比值(0-1)之间
            const sphereCurveIndex = pathIndex / pointNumber;
            // 样条曲线上某个点的比值(0-1)之间
            const sphereCurveIndex1 = (pathIndex - 1) / pointNumber;

            const positionVec: any = CurvePath.getPointAt(sphereCurveIndex); //获取曲线上位置的点,传值为0-1的小数表示整个线段的位置
            const positionVec1: any = CurvePath.getPointAt(sphereCurveIndex1);
            let tangent = new THREE.Vector3(positionVec.x - positionVec1.x, positionVec.y - positionVec1.y, positionVec.z - positionVec1.z)
            tangent.normalize()
            //这一行是一点点移动车的位置
            mesh.position.set(positionVec.x, positionVec.y, positionVec.z);
            // 这三行是让小车朝向切线方向,用到了四元数,setFromUnitVectors
            const q = new THREE.Quaternion();
            q.setFromUnitVectors(forwardVector, tangent);
            // 把四元数赋值给模型的方向矩阵
            mesh.quaternion.copy(q);
        }
        requestAnimationFrame(initAnimate);
        renderer.render(scene, camera);
    }
    initAnimate()
}

// cureMoveFn(600, Carmodel, points, camera, renderer, scene);

isclear是true的话就会执行完给你模型移出场景,fun是执行完会触发的函数

举例:

let pointArray = [
     new THREE.Vector3(0.1, 25, -0.25),
     new THREE.Vector3(-13, 25, -0.5), 
     new THREE.Vector3(-13, 25, -1),]
let fun = () => {
//回调函数

    }
//第一个参数是生成多少个点,点越少越快,第二个是需要移动的模型,第三个是你绘制线路的点,至少两个,
//最后两个是执行完以后是否移出模型和回调函数吗
cureMoveFn(100, firemen, pointArray2, camera, renderer, scene, false, fun);

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值