首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在正确的世界位置绘制相机对齐的四边形?

在正确的世界位置绘制相机对齐的四边形?
EN

Stack Overflow用户
提问于 2018-09-19 20:55:34
回答 1查看 108关注 0票数 0

我在绘制面对固定(但旋转)的正交相机的四边形时遇到了问题。正交相机在等轴测投影中显示3D世界。现在我需要在世界中放置异构精灵,以便这些四边形最终需要显示在正确的世界位置。但目前我正试着在世界的中心画一个。

代码语言:javascript
运行
复制
// FloorObject just holds the UV coordinates to be used.
public void addBillboard(FloorObject floorObject) {
    Vector3 direction =  new Vector3(1, 0, 0).nor();
    Vector3 cameraDirection = cam.direction;//cam.position.cpy().sub(new Vector3(0, 0, 0)).nor();

    Vector3 leftRight = direction;

    float dot = direction.cpy().dot(cameraDirection);

    cam.normalizeUp();
    Vector3 updown = cam.up;//new Vector3(0, 1, 0);

    if (Math.abs(dot) < 1f) {
        updown = direction.cpy().crs(cameraDirection);
    }
    updown.nor();

    Vector3 position = new Vector3(0, 0, 0);

    Vector3 bottomLeft = position.cpy().add(updown).sub(leftRight);
    Vector3 topLeft = position.cpy().sub(updown).sub(leftRight);
    Vector3 bottomRight = position.cpy().add(updown).add(leftRight);
    Vector3 topRight = position.cpy().sub(updown).add(leftRight);

    // Adding verts to the buffer.

    // Bottom left
    verts[vi++] = bottomLeft.x;
    verts[vi++] = bottomLeft.y;
    verts[vi++] = bottomLeft.z;
    verts[vi++] = floorObject.getU();
    verts[vi++] = floorObject.getV2();
    verts[vi++] = 1;

    // Bottom right
    verts[vi++] = bottomRight.x;
    verts[vi++] = bottomRight.y;
    verts[vi++] = bottomRight.z;
    verts[vi++] = floorObject.getU2();
    verts[vi++] = floorObject.getV2();
    verts[vi++] = 1;

    // Top left
    verts[vi++] = topLeft.x;
    verts[vi++] = topLeft.y;
    verts[vi++] = topLeft.z;
    verts[vi++] = floorObject.getU();
    verts[vi++] = floorObject.getV();
    verts[vi++] = 1;

    // Top right
    verts[vi++] = topRight.x;
    verts[vi++] = topRight.y;
    verts[vi++] = topRight.z;
    verts[vi++] = floorObject.getU2();
    verts[vi++] = floorObject.getV();
    verts[vi++] = 1;

}

使用我的等轴测投影,四边形旋转了大约27.5度。当使用透视相机时,它会到处旋转。我真的只关心使用等轴测相机在正确的世界位置显示等轴测纹理。

如果这很重要,我需要根据场景中的其他几何体以特定的顺序绘制这些精灵。因此,每当我需要绘制等轴测精灵时,我都会按顺序(从后到前)调用此方法,它会以正确的顺序添加到VertexBuffer中。

EN

回答 1

Stack Overflow用户

发布于 2018-09-20 15:32:32

我想出了一个非常简短的(用代码)解决方案。涉及到相机的视图矩阵,我对矩阵没有透彻的理解,但它们基本上包含了旋转,缩放和变换。因此,在我的上一个例子中,我创建了两个向量"leftRight“和"upDown”,并将它们重命名为" right“和" up”,表示相机在世界视图中的右方向和上方向,通常也称为模型视图。这就是我如何从相机的视图矩阵中获得正确的值。

代码语言:javascript
运行
复制
    right.x = modelview.val[0];
    right.y = modelview.val[4];
    right.z = modelview.val[8];

    up.x = modelview.val[1];
    up.y = modelview.val[5];
    up.z = modelview.val[9];

它只是查找数组中的值。我之前尝试过,但是使用了不正确的查找索引。有了这些,变换顶点的数学就非常简单了。

代码语言:javascript
运行
复制
    float size = 1.4142135624f;

    Vector3 bottomLeft = position.cpy().sub(right.cpy().scl(size * .5f));
    Vector3 bottomRight = position.cpy().add(right.cpy().scl(size * .5f));
    Vector3 topRight = position.cpy().add(right.cpy().scl(size * .5f)).add(up.cpy().scl(size * 2));
    Vector3 topLeft = position.cpy().sub(right.cpy().scl(size * .5f)).add(up.cpy().scl(size * 2));

由于我的地板四边形的大小是1x1,我需要做毕达哥拉斯1.414..,因为它需要填满一个完整的瓷砖。然后我计算每个顶点的位置,因为我需要将四边形的底部中心放置在一个精确的世界位置,我将大小乘以.5,我的广告牌需要高度的两倍,所以我将大小与向上向量乘以2。为了更快,为此创建了2个常量(宽度和高度),这样就不需要乘法了。然后,当这些计算出来后,我可以像往常一样批量处理我的顶点。

代码语言:javascript
运行
复制
    // Bottom left
    verts[vi++] = bottomLeft.x;
    verts[vi++] = bottomLeft.y;
    verts[vi++] = bottomLeft.z;
    verts[vi++] = floorObject.getU();
    verts[vi++] = floorObject.getV2();
    verts[vi++] = 1;

    // Bottom right halfway
    verts[vi++] = bottomRight.x;
    verts[vi++] = bottomRight.y;
    verts[vi++] = bottomRight.z;
    verts[vi++] = floorObject.getU2();
    verts[vi++] = floorObject.getV2();
    verts[vi++] = 1;

    // Top left
    verts[vi++] = topLeft.x;
    verts[vi++] = topLeft.y;
    verts[vi++] = topLeft.z;
    verts[vi++] = floorObject.getU();
    verts[vi++] = floorObject.getV();
    verts[vi++] = 1;

    // Top right halway
    verts[vi++] = topRight.x;
    verts[vi++] = topRight.y;
    verts[vi++] = topRight.z;
    verts[vi++] = floorObject.getU2();
    verts[vi++] = floorObject.getV();
    verts[vi++] = 1;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52406377

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档