简体   繁体   English

如果发生碰撞,如何使用光线投射使“变形控制”不移动对象?

[英]How do I keep Transform Control from moving your object if there is a collision, using raycasting?

So I'm using Three.js and I have some cubes inside of a box. 因此,我正在使用Three.js,并且在框内有一些多维数据集。 I'm using the Transform Control to move the cubes around inside of the box with my mouse. 我正在使用“变换控件”用鼠标在盒子内部移动多维数据集。 I'd like to use raycasting in order to check for collisions. 我想使用光线投射来检查碰撞。 The question is how to I prevent the transform controller from moving the object if there is a collision? 问题是如果发生冲突,如何防止变换控制器移动对象? I'd like to stop it if it hits the wall. 如果它撞到墙上,我想阻止它。 By the way, I'm on version r81 for Three.js. 顺便说一下,我正在使用Three.js的r81版本。

UPDATE: I've used the size of the room to constrain the cubes from moving outside of the room. 更新:我已经使用了房间的大小来限制多维数据集从房间外移动。 This seems to work well. 这似乎运作良好。 Is there a way to use the cannon.js just for collisions? 有没有一种方法可以仅将cannon.js用于碰撞? I don't want the momentum or gravity or any other feature. 我不需要动量或重力或任何其他功能。 JUST the collision check and to stop it dead in its tracks when there is a collision. 只需进行碰撞检查,并在发生碰撞时将其停止在轨道上即可。

You could create helper raycaster and place all colliders in separate container. 您可以创建辅助光线投射器并将所有对撞机放置在单独的容器中。 After movement is applied to object move raycaster to its position and test if ray intersects any of other objects in container. 将运动应用于对象后,将射线投射器移至其位置并测试射线是否与容器中的任何其他对象相交。 If yes: reset previous position for that object. 如果是:重置该对象的先前位置。 In case of cube colliders you could want to raycast from cube center in multiple directions with half of side length as ray length. 如果是立方体碰撞器,则可能需要从立方体中心向多个方向进行射线投射,且边长的一半为射线长度。

I know this post is from a long time ago, but hopefully a googler finds this helpful. 我知道这篇文章是很久以前的,但希望Google员工能找到帮助。 I wasn't able to stop the user from moving my object, but I was able to move it back to its proper position immediately afterward by adding some logic to the render method. 我无法阻止用户移动我的对象,但是之后我可以通过向render方法添加一些逻辑,将其立即移动回其适当的位置。

For the original poster's problem with collisions, you could attach an event listener to the transform controls and request the object to be repositioned if it is in an illegal state. 对于原始发布者的碰撞问题,可以将事件侦听器附加到变换控件,并在对象处于非法状态时请求将其重新放置。

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

and then in your render function 然后在您的渲染功能中

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

If this feels a little hacky, that's because it is. 如果这有点怪异,那是因为。 But for those of us who don't have the time or skill to read and modify TransformControls.js, I think it may prove helpful. 但是对于那些没有时间或技能来阅读和修改TransformControls.js的人,我认为这可能会有所帮助。

Ben S does have the best and most painless way to implement collision detection with transform controls. Ben S确实是使用变换控件实现碰撞检测的最佳,最轻松的方法。 Within a event listener. 在事件监听器中。

But I don't know if the time of writing his answer he knew about or if there even was a function called "requestAnimationFrame". 但是我不知道写他的答案的时间他是否知道,或者甚至没有一个叫做“ requestAnimationFrame”的函数。 All you would have to do for collision detection instead of simply resetting the models position is to set up your render call within a loop (60 fps) by adding "requestAnimationFrame" to your render (I call it animate since that is more descriptive) function. 对于碰撞检测,您要做的不仅仅是简单地重置模型位置,而是通过在渲染器中添加“ requestAnimationFrame”来设置您的渲染调用(60 fps)(我称其为animate,因为它更具描述性) 。

Since it is in a loop and is called when the every frame the scene is drawn it will just not allow the object to move past the point of collision. 因为它是循环的,并且在绘制场景的每一帧时都会调用它,所以它只会不允许对象移过碰撞点。

function animate() {

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

            renderer.render(scene, camera);

}

And your event listener would just look like this. 您的事件侦听器将如下所示。

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

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

});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM