取消项目鼠标以获取3D世界坐标Libgdx

Bee*_*ake 3 java 3d libgdx

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

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

目前我只是简单地使用鼠标的x和y坐标移动模型,并添加乘数和摄像机位置等因子.这不是很好,因为它不跟随光标,如果我旋转相机,那么模型不会以正确的方向移动.

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

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

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

libgx鼠标

我知道我错了,我应该使用unproject方法.我试图使用unproject方法并没有取得什么成功,模型只是粘在相机的近窗格上.我希望我的对象在y轴上保持为0,所以我使用了这个:

cam.unproject(mousePos);
instances.get(modelIndex).transform.setToTranslation(mousePos.x, 0, mousePos.z);
Run Code Online (Sandbox Code Playgroud)

然后,这导致模型在正确的方向上移动得非常慢(不是用鼠标).此外,当我旋转或移动相机时,模型将被设置在距离的某处或者甚至在相机后面.

Xop*_*ppa 11

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

Ray ray = cam.getPickRay(screenX, screenY);
Run Code Online (Sandbox Code Playgroud)

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

ray.origin.y + ray.direction.y * distance = 0 <=>
ray.direction.y * distance = -ray.origin.y <=>
distance = -ray.origin.y / ray.direction.y
Run Code Online (Sandbox Code Playgroud)

导致:

float distance = -ray.origin.y / ray.direction.y;
Run Code Online (Sandbox Code Playgroud)

现在,要获得该距离的光线位置:

Vector3 tmpVector = new Vector3();
tmpVector.set(ray.direction).scl(distance).add(ray.origin);
Run Code Online (Sandbox Code Playgroud)

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

instance.transform.setTranslation(tmpVector);
Run Code Online (Sandbox Code Playgroud)

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

我建议您使用InputProcessor(请参阅http://code.google.com/p/libgdx/wiki/InputEvent),以便将它们放在一起:

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;
}
Run Code Online (Sandbox Code Playgroud)

请注意,您可能需要重写touchdown,并返回truetouchDragged被调用.