在Libgdx 3d中的RayCasting

好吧所以我一直在尝试相当一段时间在libgdx中的Raycast基于我在寻找的3D碰撞检测..但我画了一个空白,似乎没有任何文档。 有人会善意地把我送到正确的方向吗?

使用libgdx来实现你想要做的事情实际上非常容易。 以下是我用于进行射线测试并找到我的射线所能击中的最近碰撞对象的内容。 我们假设它位于一个名为BulletUtil的类中。

 private static final Vector3 rayFrom = new Vector3(); private static final Vector3 rayTo = new Vector3(); private static final ClosestRayResultCallback callback = new ClosestRayResultCallback(rayFrom, rayTo); public static btCollisionObject rayTest(btCollisionWorld collisionWorld, Ray ray) { rayFrom.set(ray.origin); // 50 meters max from the origin rayTo.set(ray.direction).scl(50f).add(rayFrom); // we reuse the ClosestRayResultCallback, thus we need to reset its // values callback.setCollisionObject(null); callback.setClosestHitFraction(1f); callback.getRayFromWorld().setValue(rayFrom.x, rayFrom.y, rayFrom.z); callback.getRayToWorld().setValue(rayTo.x, rayTo.y, rayTo.z); collisionWorld.rayTest(rayFrom, rayTo, callback); if (callback.hasHit()) { return callback.getCollisionObject(); } return null; } 

现在你还需要一个对点击事件做出反应的InputProcessor

 public class BulletInputProcessor extends InputAdapter { private Viewport pickingViewport; private btCollisionWorld collisionWorld; // a constructor which takes a Viewport and the collision world and stores them public BulletInputProcessor(...) { ... } @Override public boolean touchUp(int screenX, int screenY, int pointer, int button) { if (button == Input.Buttons.LEFT) { Ray pickRay = pickingViewport.getPickRay(screenX, screenY); btCollisionObject body = BulletUtil.rayTest(collisionWorld, pickRay); if (body != null) { // do whatever you want with this body now return true; } } return false; } } 

Viewport负责创建拾取Ray 。 您应该在此处使用视口来管理用于渲染世界的PerspectiveCamera 。 不要忘记通过Gdx.input.setInputProcessor(new BulletInputProcessor(collisionWorld, viewport))注册输入处理器。

@noone在你的代码中,有两行对我来说不起作用。 可能会被弃用?

 callback.getRayFromWorld().setValue(rayFrom.x, rayFrom.y, rayFrom.z); callback.getRayToWorld().setValue(rayTo.x, rayTo.y, rayTo.z); 

我把它们改成了

  Vector3 rayFromWorld = new Vector3(); rayFromWorld.set(rayFrom.x, rayFrom.y, rayFrom.z); Vector3 rayToWorld = new Vector3(); rayToWorld.set(rayTo.x, rayTo.y, rayTo.z); 

这使整个function像魅力一样工作。

我发现的另一件事是,你必须激活身体(由这个函数返回)才能对它施加力。 大多数刚性身体在一段时间后设置为睡眠状态,并且ClosestRayResultCallback不会将其唤醒。

 btCollisionObject target = CollisionUtils.rayTest(dynamicsWorld, ray); //test for collisionflags and stuff here //and if your target is instance of btRigidBody btRigidBody body = (btRigidBody)target; body.activate(); body.applyCentralForce(ray.direction.scl(50000));