Three.js 将物体移动到特定位置
我知道我可以使用body.position.set(x,y,z)来瞬间移动一个物体,但是我如何才能以动画的方式平稳地移动它,使它的运动与物理规律相一致,并在移动过程中与任何其他物体发生碰撞?使用body.velocity.set(x,y,z)将设置其速度,使用body.linearDamping=v将提供一些摩擦/阻力。。。但它仍然不够好,无法让我精确地指定身体停止的位置 为此,您需要使用物理库,例如Physijs。它可以轻松地使用Three.js。谷歌搜索“Physijs Three.js”将提供一些例子。听起来你在寻找一个运动学体。使用运动学实体,您可以完全控制运动,并且它将推开其路径中的其他实体。但是,物体具有无限质量,不受其他物体碰撞的影响 从定义身体的起始和结束位置开始Three.js 将物体移动到特定位置,three.js,cannon.js,Three.js,Cannon.js,我知道我可以使用body.position.set(x,y,z)来瞬间移动一个物体,但是我如何才能以动画的方式平稳地移动它,使它的运动与物理规律相一致,并在移动过程中与任何其他物体发生碰撞?使用body.velocity.set(x,y,z)将设置其速度,使用body.linearDamping=v将提供一些摩擦/阻力。。。但它仍然不够好,无法让我精确地指定身体停止的位置 为此,您需要使用物理库,例如Physijs。它可以轻松地使用Three.js。谷歌搜索“Physijs Three.js”将
var startPosition = new CANNON.Vec3(5, 0, 2);
var endPosition = new CANNON.Vec3(-5, 0, 2);
var tweenTime = 3; // seconds
然后创建你的运动学身体。在本例中,我们将向其添加一个长方体形状
var body = new CANNON.Body({
mass: 0,
type: CANNON.Body.KINEMATIC,
position: startPosition
});
body.addShape(new CANNON.Box(new CANNON.Vec3(1,1,1)));
world.add(body);
计算方向向量,得到两条路径的总长度
var direction = new CANNON.Vec3();
endPosition.vsub(startPosition, direction);
var totalLength = direction.length();
direction.normalize();
可使用公式v=s/t计算速度和速度
var speed = totalLength / tweenTime;
direction.scale(speed, body.velocity);
对于每次更新,计算两次进度:一个介于0和1之间的数字,其中0表示开始位置,1表示结束位置。使用此数字可以计算当前身体位置
var progress = (world.time - startTime) / tweenTime;
if(progress < 1){
// Calculate current position
direction.scale(progress * totalLength, offset);
startPosition.vadd(offset, body.position);
} else {
// We passed the end position! Stop.
body.velocity.set(0,0,0);
body.position.copy(endPosition);
}
var progress=(world.time-startTime)/twentime;
如果(进度<1){
//计算当前位置
方向、比例(进度*总长度、偏移);
起始位置vadd(偏移,主体位置);
}否则{
//我们通过了终点位置!停下。
体速度设置(0,0,0);
正文.位置.副本(结束位置);
}
请参阅下面的完整代码。您可以复制并粘贴此代码
var demo = new CANNON.Demo();
var postStepHandler;
demo.addScene("Tween box",function(){
var world = demo.getWorld();
// Inputs
var startPosition = new CANNON.Vec3(5, 0, 2);
var endPosition = new CANNON.Vec3(-5, 0, 2);
var tweenTime = 3; // seconds
var body = new CANNON.Body({
mass: 0,
type: CANNON.Body.KINEMATIC,
position: startPosition
});
body.addShape(new CANNON.Box(new CANNON.Vec3(1,1,1)));
world.add(body);
demo.addVisual(body);
if(postStepHandler){
world.removeEventListener('postStep', postStepHandler);
}
// Compute direction vector and get total length of the path
var direction = new CANNON.Vec3();
endPosition.vsub(startPosition, direction);
var totalLength = direction.length();
direction.normalize();
var speed = totalLength / tweenTime;
direction.scale(speed, body.velocity);
// Save the start time
var startTime = world.time;
var offset = new CANNON.Vec3();
postStepHandler = function(){
// Progress is a number where 0 is at start position and 1 is at end position
var progress = (world.time - startTime) / tweenTime;
if(progress < 1){
direction.scale(progress * totalLength, offset);
startPosition.vadd(offset, body.position);
} else {
body.velocity.set(0,0,0);
body.position.copy(endPosition);
world.removeEventListener('postStep', postStepHandler);
postStepHandler = null;
}
}
world.addEventListener('postStep', postStepHandler);
});
demo.start();
var demo=new CANNON.demo();
var postStepHandler;
addScene(“Tween-box”,function()){
var-world=demo.getWorld();
//投入
var startPosition=新加农炮.Vec3(5,0,2);
var endPosition=新加农炮.Vec3(-5,0,2);
var twentime=3;//秒
var body=新加农炮。body({
质量:0,
类型:加农炮、车身、运动学、,
位置:开始位置
});
车身.addShape(新加农炮.Box(新加农炮.Vec3(1,1,1));
添加(正文);
demo.addVisual(body);
如果(斯特凡德勒){
world.removeEventListener('postStep',postStepHandler);
}
//计算方向向量并得到路径的总长度
var direction=new CANNON.Vec3();
vsub(起始位置,方向);
var totalLength=方向.长度();
方向。规范化();
var速度=总长度/二十分钟;
方向.刻度(速度,身体.速度);
//保存开始时间
var startTime=world.time;
var offset=new CANNON.Vec3();
postStepHandler=函数(){
//进度是一个数字,其中0位于开始位置,1位于结束位置
var progress=(world.time-startTime)/twentime;
如果(进度<1){
方向、比例(进度*总长度、偏移);
起始位置vadd(偏移,主体位置);
}否则{
体速度设置(0,0,0);
正文.位置.副本(结束位置);
world.removeEventListener('postStep',postStepHandler);
postStepHandler=null;
}
}
world.addEventListener(“postStep”,postStepHandler);
});
demo.start();