【问题标题】:RayCasting in Libgdx 3dLibgdx 3d 中的光线投射
【发布时间】:2014-07-28 05:23:48
【问题描述】:

好吧,所以我已经尝试了很长一段时间了,因为我在 libgdx 中使用 Raycast 根据我正在寻找的位置进行 3D 碰撞检测。但我画了一个空白,似乎在任何地方都没有任何文档。有人会好心把我送到正确的方向吗?

【问题讨论】:

  • 你使用子弹物理吗?
  • 是的对不起,我完全没有想到要提到这一点

标签: java libgdx collision-detection raycasting


【解决方案1】:

使用 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))注册输入处理器。

【讨论】:

  • 好的,我想我明白你的意思了,但我要去睡觉了,所以要到明天才能测试它顺便感谢您的快速响应!
  • 好吧,看来我在 0.0 的某个地方严重失败了无论我做什么,它都不会记录它与任何其他碰撞对象的碰撞
  • 目前有这个问题(几小时前刚刚发布 [stackoverflow.com/questions/27790457/…)。如何找到 ModelInstance 指向的“射线”?
【解决方案2】:

@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);

这让整个功能发挥得淋漓尽致。

我发现的另一件事是,您必须激活主体(由此函数返回)才能对其施加力。大多数刚体会在一定时间间隔后进入睡眠状态,并且 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));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-07
    • 1970-01-01
    相关资源
    最近更新 更多