path3D

作者: skoll | 来源:发表于2022-09-26 23:41 被阅读0次

path3D可以实现需求

image.png

1 .path3d是从曲线上点的一系列位置向量创建的数学对象。一旦确定,path3d可以用于确定每个点的曲线的切线,发现和副法线相含量的三元组

创建

获取变量

API

properties

1 .path:Vector3数组,Path3D的曲线轴

methods

1 .getBinormalAt:返回沿此路径指定位置处的插值Path3D曲线点的副法线向量。与插值的Path3D曲线点对应的副法线向量,如果未插值,则从预计算副法线数组中获取副法线。
2 .getBinormals:返回在每个Path3D曲线点上填充有副法线向量的数组。
3 .getClosestPositionTo:将此路径上最近的虚拟点的位置返回到任意Vector3,从0.0到1.0
4 .getCurve:返回设计其曲线的连续Vector3的Path3D数组。
5 .getDistanceAt:返回沿此路径在指定位置处插值Path3D曲线点的距离(浮点).这个api有点垃圾好吧
6 .getDistances:返回用第i个点与第一个曲线点之间的距离(浮点)填充的数组。
7 .getNormalAt:返回沿此路径在指定位置处的插值Path3D曲线点的切线向量。
8 .getNormals
9 .getPointAt():返回沿此路径的插值点:0.1就是距离取0.1的在线上的点
10 .getPoints:返回设计其曲线的连续Vector3的Path3D数组。
11 .getPreviousPointIndexAt:返回沿此图形的插值点的上一个点的数组索引
12 .getSubPositionAt:返回插值点相对于其所在的两个路径点的位置,从0.0(点A)到1.0(点B)
13 .getTangentAt:返回沿此路径在指定位置处的插值Path3D曲线点的切线向量。
14 .getTangents:
15 .length:路径的计算长度(浮点)。
16 .slice():返回此路径的子路径(切片)
17 .update:强制Path3D切线、法线、副法线和距离重新计算。

path3d这个确实给力

1 .sin曲线,粒子沿着这个曲线运动

<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Babylon Template</title>

    <style>
        html,
        body {
            overflow: hidden;
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }

        #renderCanvas {
            width: 100%;
            height: 100%;
            touch-action: none;
        }
    </style>

    <script src="https://cdn.babylonjs.com/babylon.js"></script>
    <script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
    <script src="https://code.jquery.com/pep/0.4.3/pep.js"></script>
</head>

<body>
    <canvas id="renderCanvas" touch-action="none"></canvas>
    <script>
        const canvas = document.getElementById("renderCanvas");
        const engine = new BABYLON.Engine(canvas, true);

        function createParticle(scene) {
            var particleSystem = new BABYLON.ParticleSystem("particles", 500, scene);
            particleSystem.particleTexture = new BABYLON.Texture("http://127.0.0.1:8080/source/image/cloud.png", scene);
            // particleSystem.emitter = new BABYLON.Vector3(0, 10, 0); 
            particleSystem.minEmitBox = new BABYLON.Vector3(-1, 0, 0);
            particleSystem.maxEmitBox = new BABYLON.Vector3(1, 0, 0);
            particleSystem.color1 = new BABYLON.Color4(0.7, 0.8, 1.0, 1.0);
            particleSystem.color2 = new BABYLON.Color4(0.2, 0.5, 1.0, 1.0);
            particleSystem.colorDead = new BABYLON.Color4(0, 0, 0.2, 0.0);
            particleSystem.minSize = 0.1;
            particleSystem.maxSize = 0.5;
            particleSystem.minLifeTime = 2;
            particleSystem.maxLifeTime = 3.5;
            particleSystem.emitRate = 50;
            particleSystem.blendMode = BABYLON.ParticleSystem.BLENDMODE_ONEONE;
            particleSystem.gravity = new BABYLON.Vector3(0, -9.81, 0);
            particleSystem.direction1 = new BABYLON.Vector3(-2, 8, 2);
            particleSystem.direction2 = new BABYLON.Vector3(2, 8, -2);
            particleSystem.minAngularSpeed = 0;
            particleSystem.maxAngularSpeed = Math.PI;
            particleSystem.minEmitPower = 1;
            particleSystem.maxEmitPower = 3;
            particleSystem.updateSpeed = 0.005;
            particleSystem.start();
            return particleSystem
        }

        const createScene = function () {
            const scene = new BABYLON.Scene(engine);
            const camera = new BABYLON.ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 2.5, 15, new BABYLON.Vector3(0, 0, 0));
            camera.attachControl(canvas, true);
            const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0));

            const particleSystem = createParticle(scene)

            let points = []
            for (let i = 0; i < 50; i++) {
                points.push(
                    new BABYLON.Vector3(i - 25, 5 * Math.sin(i / 2), 0)
                    // new BABYLON.Vector3(i,0,0)
                )
            }

            let path3d = new BABYLON.Path3D(points)
            const curve = path3d.getCurve()
            // 获取到构成3d曲线的所有点,也就是points
            // 切线
            const tangents=path3d.getTangents()
            // 法线
            const normals=path3d.getNormals()
            // 副法线
            const binnormals=path3d.getBinormals()

            const distance=path3d.getDistances()
            // 所有点到原点的距离
            
            
            const pos=path3d.getPointAt(0.5)

            const li=BABYLON.Mesh.CreateLines('li',points,scene)

            let dis=0


            scene.onBeforeRenderObservable.add(() => {
                dis+=0.001
                let position=path3d.getPointAt(dis)
                particleSystem.emitter.x = position.x
                particleSystem.emitter.y=position.y
                particleSystem.emitter.z=position.z
                //这样是改变粒子发射的位置,如果是描边的话,基础版本就是一个点沿着某个路径转
                //movePOV    

                //进阶版就是一个一条线散发粒子,然后沿着某个路径移动,就越像火车一样    
            })
            return scene;
        };

        const scene = createScene();


        engine.runRenderLoop(function () {
            scene.render();
        });
        window.addEventListener("resize", function () {
            engine.resize();
        });
    </script>
</body>

</html>

2 .过山车曲线,三次贝塞尔构成的曲线,并且照相机沿着运动

1 .从这里面可以发现他的动画不是scene那一套,而是构建出动画帧,然后调用动画函数播放的,这样可能性能会比较高,不会掉帧
2 .或者说这样可以方便调整速率

emitter压根就没有position属性.所以动画上去没效果,还是需要在单独给emitter.x,y,z赋值.甚至尝试了transformNode都不行

<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Babylon Template</title>

    <style>
        html,
        body {
            overflow: hidden;
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }

        #renderCanvas {
            width: 100%;
            height: 100%;
            touch-action: none;
        }
    </style>

    <script src="https://cdn.babylonjs.com/babylon.js"></script>
    <script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
    <script src="https://code.jquery.com/pep/0.4.3/pep.js"></script>
</head>

<body>
    <canvas id="renderCanvas" touch-action="none"></canvas>
    <script>
        const canvas = document.getElementById("renderCanvas");
        const engine = new BABYLON.Engine(canvas, true);

        function createParticle(scene) {
            var particleSystem = new BABYLON.ParticleSystem("particles", 500, scene);
            particleSystem.particleTexture = new BABYLON.Texture("http://127.0.0.1:8080/source/image/cloud.png", scene);
            // particleSystem.emitter = new BABYLON.Vector3(0, 10, 0); 
            particleSystem.minEmitBox = new BABYLON.Vector3(-1, 0, 0);
            particleSystem.maxEmitBox = new BABYLON.Vector3(1, 0, 0);
            particleSystem.color1 = new BABYLON.Color4(0.7, 0.8, 1.0, 1.0);
            particleSystem.color2 = new BABYLON.Color4(0.2, 0.5, 1.0, 1.0);
            particleSystem.colorDead = new BABYLON.Color4(0, 0, 0.2, 0.0);
            particleSystem.minSize = 0.1;
            particleSystem.maxSize = 0.5;
            particleSystem.minLifeTime = 2;
            particleSystem.maxLifeTime = 3.5;
            particleSystem.emitRate = 50;
            particleSystem.blendMode = BABYLON.ParticleSystem.BLENDMODE_ONEONE;
            particleSystem.gravity = new BABYLON.Vector3(0, -9.81, 0);
            particleSystem.direction1 = new BABYLON.Vector3(-2, 8, 2);
            particleSystem.direction2 = new BABYLON.Vector3(2, 8, -2);
            particleSystem.minAngularSpeed = 0;
            particleSystem.maxAngularSpeed = Math.PI;
            particleSystem.minEmitPower = 1;
            particleSystem.maxEmitPower = 3;
            particleSystem.updateSpeed = 0.005;
            particleSystem.start();
            return particleSystem
        }

        const createScene = function () {
            const scene = new BABYLON.Scene(engine);
            const camera = new BABYLON.ArcRotateCamera("camera", -Math.PI / 2, Math.PI / 2.5, 15, new BABYLON.Vector3(0, 0, 0));
            camera.attachControl(canvas, true);
            const light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0));

            const particleSystem = createParticle(scene)

            let points = []
            let n = 100
            let railLength = 0.5
            for (let i = 0; i < n; i++) {
                points.push(new BABYLON.Vector3(
                    i * railLength, 0, 0
                ))
            }

            let path3d = new BABYLON.Path3D(points)
            const curve = path3d.getCurve()
            // 获取到构成3d曲线的所有点,也就是points
            // 切线
            const tangents=path3d.getTangents()
            // 法线
            const normals=path3d.getNormals()
            // 副法线
            const binnormals=path3d.getBinormals()

            const distance=path3d.getDistances()
            // 所有点到原点的距离
            
            let transformNode=new BABYLON.TransformNode('particle')
            particleSystem.emitter.parent=transformNode
                
            const pos=path3d.getPointAt(0.5)

            const li=BABYLON.Mesh.CreateLines('li',points,scene)

            const frame=60
            const posAnim=new BABYLON.Animation('particlePos','position',frame,BABYLON.Animation.ANIMATIONTYPE_VECTOR3)
            const posKeys=[]

            const precent=100
            // 这个表示要分的分数

            for(let i=0;i<precent;i++){
                let position=path3d.getPointAt(i/precent)
                posKeys.push({
                    frame:i*frame,
                    value:position
                })
            }
            posAnim.setKeys(posKeys)
            transformNode.animations.push(posAnim)
            console.log(particleSystem)

            scene.onBeforeRenderObservable.add(() => {
                // particleSystem.emitter.x = position.x
                // particleSystem.emitter.y=position.y
                // particleSystem.emitter.z=position.z
                //这样是改变粒子发射的位置,如果是描边的话,基础版本就是一个点沿着某个路径转
                //movePOV    

                //进阶版就是一个一条线散发粒子,然后沿着某个路径移动,就越像火车一样  
            })

            scene.beginAnimation(transformNode,0,1000,true)

            return scene;
        };

        const scene = createScene();


        engine.runRenderLoop(function () {
            scene.render();
        });
        window.addEventListener("resize", function () {
            engine.resize();
        });
    </script>
</body>
</html>

进阶版,火车版本尝试

1 .我们要做的是自定义发射器,每一秒都是要重新定义发射器发射粒子的位置
2 .一种就是每一帧用新算出来的粒子位置来重新生成粒子,一种就是每一帧只改位置。
3 .或者更无脑的就是多加几个粒子,都沿着那条线运动,只是我们要差时让他开始。这个想想感觉效果就不怎么样
4 .

相关文章

  • 通过点生成3D房间-圆墙壁

    // 墙的生成 let path: Path3D = new Path3D(); path.moveTo(-5, ...

  • path3D

    path3D可以实现需求 1 .path3d是从曲线上点的一系列位置向量创建的数学对象。一旦确定,path3d可以...

网友评论

      本文标题:path3D

      本文链接:https://www.haomeiwen.com/subject/rzygortx.html