Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Three.js 将物体移动到特定位置_Three.js_Cannon.js - Fatal编程技术网

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”将

我知道我可以使用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();