LibGDX:如何使用正交相机定位3D模型实例?

4

我有一个使用正交相机的Screen类,并希望在其上放置一个3D模型。

@Override
    public void show() {

    ....
    mCamera = new OrthographicCamera();
    mCamera.setToOrtho(false, width * sclWidth, height * sclWidth);
    ....

    //3d instance initialization
        modelBatch = new ModelBatch();
        ModelBuilder modelBuilder = new ModelBuilder();
        model = modelBuilder.createBox(0.5f,0.5f,0.5f, new Material(ColorAttribute.createDiffuse(Color.GREEN)), VertexAttributes.Usage.Position| VertexAttributes.Usage.Normal);

  modelInstance = new ModelInstance(model, 128,128,128);
  modelInstance.transform.set(mCamera.invProjectionView);
}



@Override
    public void render(float delta) {
        Gdx.gl.glClearColor(63 / 255f, 128 / 255f, 70 / 255f, 1);
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);

        //mCamera.rotateAround(Vector3.Zero, new Vector3(0,1,0),1f);
        mCamera.update();
    mBatch.setProjectionMatrix(mCamera.combined);

    mBatch.begin();
    mBatch.draw(img, 128*10, 0);

    mBatch.end();

    modelBatch.begin(mCamera);

    modelBatch.render(modelInstance);

    modelBatch.end();

}

当前是2D视图,可以根据屏幕的宽度和高度放置任何2D精灵到屏幕上的x和y位置。

但是,在进行3D模型时,情况完全不同。

3D模型会根据相机屏幕拉伸并在屏幕中心渲染。我找不到3D模型设置X或Y / SetZ函数的方法。

应该如何定位3D模型以及使用哪些函数?任何建议或指向教程的方向都将不胜感激。

更新: 相机位置:(768.0,192.0,0.0) 相机投影:[0.0012019231 | 0.0 | 0.0 | -0.0] [0.0 | 0.0021378205 | 0.0 | -0.0] [0.0 | 0.0 | -0.02 | -1.0] [0.0 | 0.0 | 0.0 | 1.0]


所有的内容都在文档中有详细解释。https://github.com/libgdx/libgdx/wiki/Quick-start - Tenfour04
是的,我看了大部分内容,但仍然无法理解。我以为当我们将正交相机设置为屏幕宽度和高度时,它会映射到屏幕的每个像素。但是当放置3D盒子时,使用0.5f,0.5f,0.5f,它显示出一个大约300像素宽的拉伸盒子。我无法弄清楚为什么。 - tipsywacky
1个回答

6
首先,您在坐标点128, 128, 128处实例化了模型。我不确定您的相机位置在哪里,但如果您想要一个居中的对象,则模型实例的X和Y应与相机位置相匹配。
此外,如果您希望整个模型可见,则需要将其沿Z轴方向移动。相机朝向-Z轴,因此模型实例的位置的Z必须小于相机的Z位置才能可见。
您的主要问题是应该删除以下行:
modelInstance.transform.set(mCamera.invProjectionView);

您绝对不想应用相机的投影矩阵并将其用作模型的变换矩阵。
通常,顶点位置(如ModelBatch的默认着色器中)通过将其位置乘以一系列矩阵从世界坐标映射到屏幕坐标。 变换矩阵描述了ModelInstance的位置、旋转和缩放,因此它将原始模型的顶点位置转换为世界空间。然后,视图矩阵将顶点平移到其相对于相机的位置(相机空间,也称为视图空间)。最后,投影矩阵将顶点平移到屏幕空间(将其投影到矩形屏幕上)。由于视图矩阵和投影矩阵都由相机定义,因此可以预先乘以它们并一次性传递给批处理程序(camera.combined)。
在着色器中,每个顶点位置都乘以矩阵以将其转换为屏幕空间。
因此,要在世界中移动模型实例,您需要对其变换矩阵执行操作,例如modelInstance.transform.translate(x,y,z)。通常情况下,您不需要调用set。行modelBatch.begin(mCamera);在幕后为您处理camera.combined矩阵。
在使用2D的SpriteBatch时,您直接将精灵放置在世界空间中,因为没有定义顶点位置的源模型。这就是为什么在使用SpriteBatch时通常不需要使用变换矩阵的原因(尽管可以将其用于将整个精灵平面移动到3D世界空间中的某个位置)。

哇,非常感谢。我发现不使用modelInstance.transform.set(mCamera.invProjectionView)也可以解决问题。设置相机的x和y值给了我很大的提示。再次感谢! - tipsywacky
顺便问一句,你知道这段代码的作用是什么吗?我正在试图找出为什么圆圈不会停止。http://gamedev.stackexchange.com/questions/118804/libgdx-and-gdx-ai-how-to-implement-wander-behavior - tipsywacky
很抱歉,我没有使用过gdx.ai。 - Tenfour04

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