【问题标题】:Converting quadriladerals in an OBJ file into triangles?将OBJ文件中的四边形转换为三角形?
【发布时间】:2014-07-06 14:26:12
【问题描述】:

起初,这似乎很明显......在找到 4 个索引的地方每个面制作 2 个三角形,对吗?
含义,如下:

v 1.000000 1.000000 0.000000
v -1.000000 1.000000 -0.000000
v 1.000000 -1.000000 0.000000
v -1.000000 -1.000000 -0.000000
f -4 -3 -2 -1

... 反过来,需要转换成类似的东西:

v 1.000000 1.000000 0.000000
v -1.000000 1.000000 -0.000000
v 1.000000 -1.000000 0.000000
v -1.000000 -1.000000 -0.000000
f -4 -3 -2
f -2 -3 -1

这个特定的例子当然可以正确渲染。
但是,并非所有情况都像将面分成两个面那样简单(其中第一个面包含原始面的前三个顶点,第二个面包含最后三个顶点,如上例所示)。以下面的立方体为例:

v 0.000000 1.000000 1.000000
v 0.000000 0.000000 1.000000
v 1.000000 0.000000 1.000000
v 1.000000 1.000000 1.000000
v 0.000000 1.000000 0.000000
v 0.000000 0.000000 0.000000
v 1.000000 0.000000 0.000000
v 1.000000 1.000000 0.000000
f 1 2 3 4
f 8 7 6 5
f 4 3 7 8
f 5 1 4 8
f 5 6 2 1
f 2 6 7 3

这些面不能在前面的例子中以同样的方式分割...所以,我需要一些方法来了解如何将一个四边形面分割成两个三角形面,同时使用 正确 索引第二张脸……

如何实现? 请注意,我没有使用固定功能管道,因此,使用 GL_QUADS 不是一个选项。我的渲染引擎几乎只使用 GL_TRIANGLES。

【问题讨论】:

  • 我理解这里的困惑,我花了最后两天试图弄清楚这一点。这些不是 QUAD 而是三角形条带,文档在这方面很差。

标签: java opengl graphics lwjgl wavefront


【解决方案1】:

如果您有 4 个索引,例如:

0 1 2 3

分成两个三角形将是一个具有前 3 个索引,一个具有第一个、第三个和第四个索引。在这个例子中:

0 1 2
0 2 3

让我们尝试一些 ASCII 艺术来说明这一点:

3-------2
|      /|
|    /  |
|  /    |
|/      |
0-------1

在这里,0 1 2 3 是四边形,0 1 2 是第一个三角形(右下),0 2 3 是第二个三角形(左上)。

更一般地,对于具有n 顶点的面,您会生成三角形:

0 (i) (i + 1)  [for i in 1..(n - 2)]

如果您不坚持使用单独的三角形,您也可以使用GL_TRIANGLE_FAN 基元,它们仍然在核心 OpenGL 中。这样,您可以使用原始索引序列绘制带有三角形扇形的任何凸多边形。因此,顶点序列0 1 2 3 的三角形扇形描述了这种情况下的四边形,并且它很容易泛化到具有超过 4 个顶点的面。

编辑:由于您似乎仍然有问题,让我们看看这如何适用于您帖子中的示例。我将列出每个面的四边形的原始索引序列,以及分割四边形后两个三角形的索引序列。

f 1 2 3 4 --> (1 2 3) (1 3 4)
f 8 7 6 5 --> (8 7 6) (8 6 5)
f 4 3 7 8 --> (4 3 7) (4 7 8)
f 5 1 4 8 --> (5 1 4) (5 4 8)
f 5 6 2 1 --> (5 6 2) (5 2 1)
f 2 6 7 3 --> (2 6 7) (2 7 3)

当我绘制立方体时,这对我来说是正确的。请记住从索引中减去 1 以供您使用,因为这些是从 1 开始的索引,您几乎肯定需要从 0 开始的索引。

【讨论】:

  • 您确定这对所有情况都正确吗?在我上面的最后一个“立方体”示例中,这将错误地渲染其中一个面,导致立方体一侧出现“切角”(即使使用 GL_TRIANGLE_FAN)。所以要么我的代码有问题,要么对象本身有问题,或者你的答案不能处理所有情况。
  • 你对哪张脸有问题?我画了它,当使用从 0 开始的索引时,一切看起来都很好。但是您发布的示例文件确实被破坏了,因为 OBJ 文件中的索引应该是基于 1 的。这是一个立方体示例:people.sc.fsu.edu/~jburkardt/data/obj/cube.obj。文件格式定义:fileformat.info/format/wavefrontobj/egff.htm.
  • 谢谢,我会看看,我会回复你
  • 好的,这样立方体就可以正确渲染了。但是列出的HEREHERE (两者都取自THIS 规范)似乎有缺失/畸形的三角形......在我们之前的主题仔细检查后发现HERE,我想也许是问题可能是从面部包含四边形的 OBJ 文件中产生的(因为它们没有被正确处理)。所以为了解决这个问题,我自己把四边形分成两个三角形,这导致我在上面的问题中遇到问题......
  • 我相信 -1 是指您在脸部之前阅读的最新顶点,-2 是指之前的那个,等等。这也是维基百科页面所说的:“-1 代表最新定义的顶点"。
【解决方案2】:

编写我自己的 obj loader 并仔细阅读规范,关于 'f' 参数的细节非常模糊,尤其是看到一些文件包含 'f' 行,其中有 > 4 个参数。

事实证明,这些实际上是一个奇数顺序的三角形条带。正确转换为三角形如下(伪代码):

n = 0;
triangles[n++] = [values[0], values[1], values[2]];
for(i = 3; i < count(values); ++i)
  triangles[n++] = [
    values[i - 3],
    values[i - 1],
    values[i]
  ];

例子:

f: A B C D E F G

将是以下 5 个三角形:

A B C
A C D
B D E
C E F
D F G

【讨论】:

  • 此答案中的信息有误,生成的三角形将是 ABC、ACD、ADE、AEF、AFG
  • 你是说顶点不对还是伪代码不对?
  • 我没看伪代码,但是顶点是错误的。它们没有形成三角形带。它们正在形成三角扇形。
  • 假设顶点A..G 是逆时针的(它们是根据f 格式的规范),你的三角形ABCBDE 重叠。我同意@Á.Márton 关于顶点应该是什么的观点。 ith 三角形应该由 v[0]、v[i]、v[i+1] 组成(如果 i 从 1 开始)
猜你喜欢
  • 2013-06-21
  • 2012-08-11
  • 2012-06-11
  • 1970-01-01
  • 2011-11-11
  • 2011-03-29
  • 2018-04-26
  • 2020-01-25
  • 2018-08-14
相关资源
最近更新 更多