取消投影鼠标以获取 3D 世界坐标 Libgdx [英] Unproject mouse to get 3D world coordinates Libgdx

查看:21
本文介绍了取消投影鼠标以获取 3D 世界坐标 Libgdx的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题:如何让 3D 模型随着鼠标光标的移动而保持模型的 y 位置为 0.(使用 Libgdx)

My Question: How does one get a 3D model to move with the mouse cursor keeping the y location of the model at 0. (Using Libgdx)

我尝试过的:我正在尝试让我的 3D 模型跟随我的光标.

What I have tried: I'm trying to get my 3D models to follow my cursor.

目前,我只是通过添加乘数和相机位置等因素使模型随鼠标的 x 和 y 坐标移动.这不是很好,因为它不跟随光标,如果我旋转相机,则模型不会向正确的方向移动.

At the moment I have simply made the models move with the x and y coordinates of my mouse with adding factors like a multiplier and camera location. This is not very good because it doesn't follow the cursor and if I rotate the camera then the model doesn't move in the correct direction.

这是我为移动模型而创建的代码:

This is the code I created for moving the model :

instances.get(modelIndex).transform.setToTranslation(((Gdx.input.getX()-650)/10) + cam.position.x,0,((Gdx.input.getY()-400)/10)+ cam.position.z);

这是问题图片的链接(绿色圆圈是鼠标所在的位置).

Here's a link to an image of the problem (The green circle is where the mouse is).

我知道我这样做是错误的,我应该使用 unproject 方法.我曾尝试使用 unproject 方法,但收效甚微,模型只是粘在相机的近窗格中.我希望我的对象在 y 轴上保持为 0,所以我使用了这个:

I know that I'm going about this wrong and that I should be using the unproject method. I have tried to use the unproject method and did have little success, the model was just stuck to the near pane of the camera. I want my object to stay at 0 on the y axes so I used this:

cam.unproject(mousePos);
instances.get(modelIndex).transform.setToTranslation(mousePos.x, 0, mousePos.z);

这导致模型在正确的方向上移动得很慢(不是用鼠标).同样,当我旋转或移动相机时,模型会被设置在远处甚至相机后面的某个地方.

This then resulted in the model moving quite slowly(not with the mouse), in the right direction. Also when I rotated or moved the camera the model would be set somewhere in the distance or even behind the camera.

推荐答案

您不能简单地使用 camera.unproject,因为单个 2D 坐标可以表示 3D 空间中的多个坐标.相反,您可以使用 camera.getPickRay 来获取 Ray,它由原点(相机近平面上的位置)以及进入 3D 空间的方向定义.因此,您将在 3D 空间中获得表示 2D 坐标的线:

You cannot simply use camera.unproject, because a single 2D coordinate can represent multiple coordinates in 3D space. Instead you can use camera.getPickRay to get the Ray, which is defined by the origin (the location on the camera's near plane) along with a direction into 3D space. So, you'll get the line in 3D space that represents the 2D coordinate:

Ray ray = cam.getPickRay(screenX, screenY);

现在您想要该线(射线)上的点(距原点的距离),其中 y=0:

Now you want the point (distance from origin) on that line (ray) where y=0:

ray.origin.y + ray.direction.y * distance = 0 <=>
ray.direction.y * distance = -ray.origin.y <=>
distance = -ray.origin.y / ray.direction.y

导致:

float distance = -ray.origin.y / ray.direction.y;

现在要在该距离处获取射线上的位置:

Now to get the position on the ray at that distance:

Vector3 tmpVector = new Vector3();
tmpVector.set(ray.direction).scl(distance).add(ray.origin);

要将模型实例转换设置为该值,您可以使用:

To set the model instance translation to that value you can use:

instance.transform.setTranslation(tmpVector);

这里的 instance 指的是你的 instances.get(modelIndex).

Here instance is referring to your instances.get(modelIndex).

我鼓励您使用 InputProcessor(请参阅 http://code.google.com/p/libgdx/wiki/InputEvent),所以把它们放在一起:

I would encourage you to use InputProcessor (see http://code.google.com/p/libgdx/wiki/InputEvent), so to put it all together:

Vector3 tmpVector = new Vector3();
@Override
public boolean touchDragged (int screenX, int screenY, int pointer) {
    Ray ray = cam.getPickRay(screenX, screenY);
    final float distance = -ray.origin.y / ray.direction.y;
    tmpVector.set(ray.direction).scl(distance).add(ray.origin);
    instance.transform.setTranslation(tmpVector);
    return true;
}

请注意,您可能需要覆盖 touchdown 并返回 true 才能调用 touchDragged.

Note that you might need to override touchdown and return true for touchDragged to be called.

这篇关于取消投影鼠标以获取 3D 世界坐标 Libgdx的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆