Java 如何获取在libGdx中单击了三维世界中的哪个点

Java 如何获取在libGdx中单击了三维世界中的哪个点,java,3d,libgdx,Java,3d,Libgdx,我正在尝试创建一个3d世界,其行为类似于minecraft,玩家可以360度观看,如果他尝试单击某个点(3d世界中的X、Y、Z坐标),在那里绘制的模型将被删除。我对在LibGdx中编程3D世界非常陌生,所以任何帮助都是有用的。我使用以下方法进行相机旋转: float deltaX = -Gdx.input.getDeltaX() * player.degreesPerPixel; float deltaY = -Gdx.input.getDeltaY() * player.degreesPerP

我正在尝试创建一个3d世界,其行为类似于minecraft,玩家可以360度观看,如果他尝试单击某个点(3d世界中的X、Y、Z坐标),在那里绘制的模型将被删除。我对在LibGdx中编程3D世界非常陌生,所以任何帮助都是有用的。我使用以下方法进行相机旋转:

float deltaX = -Gdx.input.getDeltaX() * player.degreesPerPixel;
float deltaY = -Gdx.input.getDeltaY() * player.degreesPerPixel;
    if(deltaX>0)
        player.camera.rotate(Vector3.Z, (float)1.5);
    else if(deltaX<0)
        player.camera.rotate(Vector3.Z, (float)-1.5);
player.tmp.set(player.camera.direction).crs(player.camera.up).nor();
player.camera.direction.rotate(player.tmp, deltaY);
player.setDir(player.camera.direction.x, player.camera.direction.y);
float deltaX=-Gdx.input.getDeltaX()*player.degreesPerPixel;
float deltaY=-Gdx.input.getDeltaY()*player.degreesPerPixel;
如果(deltaX>0)
播放器。摄像机。旋转(矢量3.Z,(浮动)1.5);

否则,如果(deltaX在2D环境中,您通常只需使用
Camera.unproject(…)
,它会获取一些屏幕空间点并将其转换回游戏世界坐标

在3D中,这并不是那么容易,因为额外的维度会给你的世界增加一些深度。这就是为什么在2D平面(你的屏幕)上单击可以击中3D世界中基本上无限多个点的原因。在libgdx中,这条可能单击点的光线称为拾取光线

如果您希望交点位于某个平面上,则代码可能类似于:

public void hitSomething(Vector2 screenCoords) {
    // If you are only using a camera
    Ray pickRay = camera.getPickRay(screenCoords.x, screenCoords.y);
    // If your camera is managed by a viewport
    Ray pickRay = viewport.getPickRay(screenCoords.x, screenCoords.y);

    // we want to check a collision only on a certain plane, in this case the X/Z plane
    Plane plane = new Plane(new Vector3(0, 1, 0), Vector3.Zero);
    Vector3 intersection = new Vector3();
    if (Intersector.intersectRayPlane(pickRay, plane, intersection)) {
        // The ray has hit the plane, intersection is the point it hit
    } else {
        // Not hit
    }
}
在您的情况下,当您有一个类似于minecraft的世界时,您的代码可能如下所示:

public void hitSomething(Vector2 screenCoords) {
    Ray pickRay = ...;

    // A bounding box for each of your minecraft blocks
    BoundingBox boundingBox = new BoundingBox();
    Vector3 intersection = tmp;
    if (Intersector.intersectRayBounds(pickRay, boundingBox, intersection)) {
        // The ray has hit the box, intersection is the point it hit
    } else {
        // Not hit
    }
}

请注意,在雷霆战机的世界里,这样的区块实际上有数千个。采用这种简单的方法不会很快。你可能会得到一个分层解决方案,首先检查大块(包括许多区块的边界框)查看可能的命中率,然后开始检查各个块。

好的,那么你的问题是什么?如果你只是询问并准备好代码,肯定不会得到足够的回报……我该如何着手为它创建代码。我不是在询问代码,因为这并不能教会我,但我不知道如何进行编码它。因此,虽然代码可以工作,但向导/走查会更好。你如何管理3d数组中每个块的边界框?为了得到X,Y,Z,我可以做交叉点。X,交叉点。Y,交叉点。Z,这样我就可以把这些坐标放进我的3d数组中。也感谢你帮助我理解这一点。你说的是哪个3d数组ng about?我的地图存储在一个名为world的3D字符数组中。我的目标是使它在玩家右键单击时销毁那里的字符。因此,如果玩家挖掘一块泥土,它会将地图位置从“d”切换到“a”,但我需要访问用户单击的X、Y、Z坐标。@Burf2000为什么你认为我的gi维恩的解决方案不起作用?对不起,我只是检查了一下,他让它起作用了,我设法在这里修复了我的