path3D可以实现需求

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 .
网友评论