我在绘制面对固定(但旋转)的正交相机的四边形时遇到了问题。正交相机在等轴测投影中显示3D世界。现在我需要在世界中放置异构精灵,以便这些四边形最终需要显示在正确的世界位置。但目前我正试着在世界的中心画一个。
// 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中。
发布于 2018-09-20 15:32:32
我想出了一个非常简短的(用代码)解决方案。涉及到相机的视图矩阵,我对矩阵没有透彻的理解,但它们基本上包含了旋转,缩放和变换。因此,在我的上一个例子中,我创建了两个向量"leftRight“和"upDown”,并将它们重命名为" right“和" up”,表示相机在世界视图中的右方向和上方向,通常也称为模型视图。这就是我如何从相机的视图矩阵中获得正确的值。
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];
它只是查找数组中的值。我之前尝试过,但是使用了不正确的查找索引。有了这些,变换顶点的数学就非常简单了。
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个常量(宽度和高度),这样就不需要乘法了。然后,当这些计算出来后,我可以像往常一样批量处理我的顶点。
// 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;
https://stackoverflow.com/questions/52406377
复制相似问题