如何在libGdx中获取点击的3D世界中的位置

3

我正在尝试创建一个类似于Minecraft的3D世界,玩家可以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);

谢谢你


1
好的,那么你实际上的问题是什么?你只是问一下然后准备好代码,这样并不会真正有所收获... - nanofarad
1
我该如何创建它的代码?我不是要求代码,因为那样并不能教会我,但我不知道如何编写它。因此,虽然代码能够起作用,但最好有一个指南/步骤说明。 - Soulless
1个回答

2
在一个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
    }
}

请注意,在Minecraft世界中有数千个这样的方块。采用这种简单的方法不会很快。您可能最终需要采用分层解决方案,首先检查大块(包含许多方块的边界框)是否可能被击中,然后开始检查单个方块。

你如何管理3D数组中每个块的boundingBox?而要获取X、Y、Z,我只需使用intersection.x、intersection.y、intersection.z,这样我就可以将这些坐标放入我的3D数组中了? 同时感谢您帮助我理解这个问题。 - Soulless
你在谈论哪个3D数组? - noone
我的地图存储在一个名为world的3D字符数组中。我的目标是使得当玩家右键点击时,他们可以破坏那个位置上的字符。因此,如果玩家挖掘一块泥土,它会将该地图位置从“d”切换到“”,但我需要访问人们点击的X、Y、Z坐标。 - Soulless
1
@Burf2000 你为什么认为我的解决方案行不通? - noone
抱歉,我只是在确认他是否解决了问题。我成功修复了我的问题,这里是链接:http://stackoverflow.com/questions/31805868/libgdx-detecting-where-a-ray-hits-a-3d-object?noredirect=1#comment51559869_31805868 - Burf2000

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接