我知道我可以使用body.position.set(x,y,z)来瞬间移动一个物体,但是我怎样才能以动画的方式平滑地移动它,它的运动会粘附在物理上并与任何物体发生碰撞其他机构的旅程?使用body.velocity.set(x,y,z)将设置其速度,并使用body.linearDamping = v,将提供一些摩擦/阻力......但它仍然不够好,不能让我准确指出我想要的位置身体停止。
答案 0 :(得分:1)
听起来你正在寻找一个运动体。使用运动物体,您可以完全控制运动,并且它将推动其路径中的其他物体。然而,身体具有无限质量,并且不会受到与其碰撞的其他物体的影响。
从定义身体的起始和终止位置开始。
var startPosition = new CANNON.Vec3(5, 0, 2);
var endPosition = new CANNON.Vec3(-5, 0, 2);
var tweenTime = 3; // seconds
然后创建你的运动体。在这个例子中,我们将为它添加一个Box形状。
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 i开始位置,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);
}
请参阅下面的完整代码。您可以复制one of the cannon.js demos并粘贴此代码。
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();
答案 1 :(得分:-1)
您需要使用物理库,例如Physijs。它可以很容易地使用Three.js。谷歌搜索“Physijs Three.js”将提供示例。