将身体移动到特定位置

时间:2014-12-17 19:27:52

标签: three.js cannon.js

我知道我可以使用body.position.set(x,y,z)来瞬间移动一个物体,但是我怎样才能以动画的方式平滑地移动它,它的运动会粘附在物理上并与任何物体发生碰撞其他机构的旅程?使用body.velocity.set(x,y,z)将设置其速度,并使用body.linearDamping = v,将提供一些摩擦/阻力......但它仍然不够好,不能让我准确指出我想要的位置身体停止。

2 个答案:

答案 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”将提供示例。