Преобразование квадриладералов из файла OBJ в треугольники?

Сначала это казалось очевидным ... Делайте по 2 треугольника на каждую грань, где бы ни было найдено 4 индекса, не так ли?
Имеется в виду следующее:

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

Этот конкретный пример, конечно, будет отображен правильно.
Однако не все случаи так просты, как разделение грани на две грани (где первая грань содержит первые три вершины исходной грани, а вторая грань содержит последние 3 вершины, как в примере выше). Возьмем, к примеру, следующий куб:

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.


person RectangleEquals    schedule 18.05.2014    source источник
comment
Я понимаю, в чем тут путаница, последние два дня я трачу на то, чтобы понять это. Это не квадроциклы, а треугольные полоски, документация по этому очень скудная.   -  person Geoffrey    schedule 15.04.2017


Ответы (2)


Если у вас 4 индекса, например:

0 1 2 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.

person Reto Koradi    schedule 18.05.2014
comment
Вы уверены, что это верно для всех случаев? В моем последнем примере куба, приведенном выше, это привело бы к неправильной визуализации одной из граней, что привело бы к срезанному углу на одной стороне куба (даже с GL_TRIANGLE_FAN). Значит, либо что-то еще не так с моим кодом, или сам объект, либо ваш ответ не обрабатывает все случаи. - person RectangleEquals; 18.05.2014
comment
С каким лицом у вас проблемы? Я набросал его, и все выглядит нормально при использовании индексов с отсчетом от 0. Но опубликованный вами пример файла действительно поврежден, потому что индексы в файлах OBJ должны быть основаны на 1. Вот пример куба: people.sc.fsu.edu/~jburkardt /data/obj/cube.obj. Определение формата файла: fileformat.info/format/wavefrontobj/egff.htm. - person Reto Koradi; 19.05.2014
comment
Спасибо, я посмотрю на это и вернусь к вам - person RectangleEquals; 19.05.2014
comment
Итак, куб отрисовывается правильно. Но перечисленные здесь ЗДЕСЬ и ЗДЕСЬ (оба взяты из ЭТОЙ спецификации) отсутствуют / искаженные треугольники ... и после более тщательного изучения нашей предыдущей темы, обнаруженной ЗДЕСЬ, я подумал, что, возможно, проблема могла быть в были созданы из файлов OBJ, где лица содержат квадраты (поскольку они не обрабатывались должным образом). Итак, чтобы исправить это, я взял на себя задачу разделить квадраты на два треугольника, что привело меня к проблеме в моем вопросе выше ... - person RectangleEquals; 19.05.2014
comment
Я также пробовал сетки , экспортированные в формат OBJ из 3DS Max, а также ЭТО, найденный на случайном веб-сайте ... и кажется, что пока лица представляют собой прямые треугольники, а не четырехугольники (плоская сетка для пример), тогда он будет отображаться нормально. Но по какой-то причине четырехугольники всегда кажутся ошибочными, и я переписывал свой код около дюжины раз, пытаясь понять, почему, и единственное, что я могу придумать, - это преобразовать все четырехугольники в треугольники. - person RectangleEquals; 19.05.2014
comment
Частично проблема может заключаться в том, что некоторые из этих файлов используют индексы на основе 0 (что я считаю неправильным). Кроме того, трудно сказать, почему это не работает для вас. - person Reto Koradi; 19.05.2014
comment
Да, на самом деле это были опечатки, когда я их отлаживал. Я пробовал каждый файл как на основе 0, так и на основе 1, и единственное существенное отличие, которое он дает, - это превращение плоскостей (для 0) в один треугольник (для 1) ... Большинство кубов все еще рендерит неправильно, независимо от базы индекса, и я почти уверен, что это как-то связано с лицами, содержащими более 3 индексов в строке. Я все еще бьюсь головой об этом ... - person RectangleEquals; 19.05.2014
comment
В приведенном вами примере я добавил к ответу результат применения предложенного подразделения. - person Reto Koradi; 19.05.2014
comment
Хорошо, я думаю, что начинаю разбираться в этом, и у меня есть только один последний вопрос ... Для лиц, содержащих отрицательные индексы (также известные как вкрапленные ссылки), то есть: f -3 -2 -1 < / b> ... В каком направлении они ссылаются на вершины? Будет ли -3 означать Вернуться на три вершины от самой последней, или Перейти к третьей вершине с момента последнего выражения лица, или что-то совсем другое ? Ни одна из спецификаций OBJ, похоже, не содержит подробностей об этом, и я вижу их примерно в половине этих файлов сетки, что наводит меня на мысль, что я тоже делаю что-то не так. - person RectangleEquals; 19.05.2014
comment
Я считаю, что -1 относится к последней вершине, которую вы читали перед лицом, -2 - к предыдущей и т. Д. Это то, что также говорится на странице Википедии: -1 представляет собой последнюю определенную вершину. - person Reto Koradi; 19.05.2014
comment
Теперь это (в основном) решено, и я могу без проблем рендерить большинство мешей. Оказывается, настоящая проблема заключалась в том, что я заставлял начинать с нуля индекс для всех индексов лиц, не проверяя сначала, были ли они на самом деле ссылочными (отрицательными) индексами ... Конечным результатом было то, что не- ссылочные индексы отсчитывались от нуля, а ссылочные индексы основывались на факте -1 ... Также было несколько других ошибок. Но по большей части, похоже, сейчас это работает, и я чувствую, что, хотя ваши ответы не касались реальных проблем, вы заслуживаете очков за то, что остались и помогли. Спасибо! - person RectangleEquals; 19.05.2014
comment
Этот ответ мне очень помог; Это было крошечное указание на то, что лица основаны на 1, а не на 0, что полностью устранило мои проблемы с отрисовкой. СПАСИБО! - person Cyberfox; 08.07.2017
comment
Сработало отлично. - person Pixel; 20.01.2019

Написав свой собственный загрузчик obj и очень внимательно прочитав спецификацию, подробности о параметре '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
person Geoffrey    schedule 15.04.2017
comment
Информация в этом ответе неверна, в результате получатся треугольники ABC, ACD, ADE, AEF, AFG. - person Á. Márton; 26.04.2020
comment
Вы говорите, что вершины неправильные или неправильный псевдокод? - person Geoffrey; 27.04.2020
comment
Я не смотрел на псевдокод, но вершины неправильные. Они не образуют треугольную полосу. Они образуют веер треугольника. - person Á. Márton; 01.05.2020
comment
Предполагая, что вершины A..G повернуты против часовой стрелки (что соответствует спецификации формата f), ваши треугольники ABC и BDE перекрываются. Я согласен с @A.Márton относительно того, какими должны быть вершины. iй треугольник должен состоять из v [0], v [i], v [i + 1] (если i начинается с 1) - person Calvin Godfrey; 23.06.2020