javascript 如果发生碰撞,如何使用光线投射来防止变换控制移动对象?

lndjwyie  于 2023-02-15  发布在  Java
关注(0)|答案(4)|浏览(147)

我使用Three.js,我在一个盒子里有一些立方体。我使用变换控制器用我的鼠标在盒子里移动立方体。我想使用光线投射来检查碰撞。问题是如果有碰撞,我如何防止变换控制器移动物体?我想在它撞到墙上时停止它。顺便说一句,我在版本r81的Three.js.
更新:我已经使用了房间的大小来限制立方体移动到房间之外。这似乎工作得很好。有没有办法使用cannon.js只用于碰撞?我不需要动量或重力或任何其他功能。只是碰撞检查,并在发生碰撞时停止它的轨迹。

yebdmbv4

yebdmbv41#

我知道这篇文章是很久以前的,但希望google的人能发现这篇文章对我有帮助,我不能阻止用户移动我的对象,但我可以通过在render方法中添加一些逻辑,立即将它移回正确的位置。
对于原始发布者的碰撞问题,可以将事件侦听器附加到变换控件,并在对象处于非法状态时请求重新定位对象。

transformControls.addEventListener('objectChange', (e) => {
  if (illegalPosition(this.obj.position)) {
    needsReset = true;
  }
  lastPosition = attachedObject.position.clone();
});

然后在渲染函数中

if (needsReset) {
  attachedObject.position.set(lastPosition.x, lastPosition.y, lastPosition.z);
}

如果这让人觉得有点乏味,那是因为它确实如此,但是对于我们这些没有时间或技能来阅读和修改TransformControls.js的人来说,我认为它可能会很有帮助。

kupeojn6

kupeojn62#

你可以创建辅助光线投射器并将所有的碰撞器放置在单独的容器中。在移动应用于对象后,将光线投射器移动到它的位置,并测试光线是否与容器中的任何其他对象相交。如果是:重新设置那个物体的先前位置。2在立方体碰撞器中,你可以从立方体中心向多个方向投射光线,光线长度为边长的一半。

bn31dyow

bn31dyow3#

Ben S确实有最好的和最无痛的方法来实现碰撞检测与变换控件。在一个事件侦听器。
但我不知道他是否知道写答案的时间,或者是否有一个函数叫做“requestAnimationFrame”。你所要做的碰撞检测,而不是简单地重置模型的位置,是通过添加“requestAnimationFrame”到你的render(我称之为animate,因为这更具有描述性)函数,在一个循环(60 fps)内设置你的render调用。
由于它是在一个循环中,并且在绘制场景的每一帧时都被调用,因此它将不允许对象移动经过碰撞点。

function animate() {

            // Called to draw onto screen every frame (60fps).
            requestAnimationFrame(animate);

            renderer.render(scene, camera);

}

你的事件监听器看起来就像这样。

control.addEventListener('objectChange', (e) => {

        // Collision detection code here. Set colliding model position here.
        // No need to set it in render

});
pengsaosao

pengsaosao4#

老帖子,我知道。但这里有一个方法,仍然相当简单,但不 Flink 或使用光线投射。这里最大的问题是,你有一点反弹,如果你移动变换控制真的很快。但除此之外,它似乎工作得相当不错。你可以控制碰撞的精度调整步长值。

let transStart = null;

  //capture objects position on start
  control.addEventListener('mouseDown', function(){
    transStart = control.object.position.clone();
  })

  //you'll have to provide your own collision function
  control.addEventListener('objectChange', function(e){
    if(collision(sphere, cube)){ stopControls() };
  });

  function stopControls(){
    if(control.dragging && stopAt){
      //calculate direction object was moving at time of collision
      const s = transStart; 
      const e = control.object.position.clone();
      const n = e.clone().sub(s).negate().normalize();
      
      //janky hack nonsense that stops the transform control from 
      //continuing without making the camera controller go nuts.
      control.pointerUp({button:0});
      control.dragging = true;

      //translate back the direction it came by the step amount and do not 
      //stop until the objects are no longer colliding.
      //Increase the step size if you do not need super precise collision 
      //detection. It will save calculations.
      let step = 0.00005;
      while(colliding(sphere, cube)){
        sphere.translateOnAxis( n, step ) ;
        sphere.updateMatrix();
      }
    }
  }

相关问题