синтаксический анализ формата файла wavefront obj

Я хотел бы импортировать модели obj в мою программу opengl. У меня есть класс / формат данных, который я использую для передачи данных атрибутов в шейдеры:

class CustomVertex : public IVtxFmt
{
public:
float m_Position[3];      // x, y, z      offset 0, size = 3*sizeof(float)
float m_Normal[3];        // nx, ny, nz;  offset 3
float m_TexCoords[2];     // u, v         offset 6
float m_Colour[4];        // r, g, b, a   offset 8
float m_Tangent[3];       // r, g, b      offset 12
float m_Bitangent[3];     // r, g, b      offset 15
};

Поэтому я работаю с моделью бревенчатой ​​хижины, которую я скачал из Интернета.

В бревенчатой ​​хижине есть несколько определений вершин, нормалей и координат текстур, за которыми следует список определений граней.

Так что мой первый инстинкт был разобрать файл obj и в итоге

vector<vertex>
vector<Normal>
vector<TexCoord>

Это не просто перевести в мой формат CustomVertex, поскольку в файле может быть 210 вершин, 100 текстовых координат и 80 нормалей.

После списка ~ 390 лиц в этом формате:

f 83/42/1 67/46/1 210/42/1

Я сталкиваюсь со следующим в файле:

#
# object tile00
#

с последующим определением вершин.

Итак, из этого я сделал вывод, что модель может состоять из нескольких подобъектов, каждый из которых определяется числом граней; каждая грань определяется 3-мя значениями вершин / нормалей / текстовых координат.

Поэтому, чтобы получить вектор CustomVertex, я думаю, что мне нужно сделать следующее:

создать и заполнить:

vector <vertex>
vector <normal>
vector <texcoord>

vector <indices>

Мне нужно создать CustomVertex для каждой уникальной тройки v / vn / vt в определениях лица.

Итак, я подумал о создании карты:

std::vector<CustomVertex> and
std::map< nHashId, CustomVertex_index >

Таким образом, моя идея состоит в том, что для каждого v / vn / vt, с которым я сталкиваюсь, я создаю хеш этой строки, например. nHashId = hash («80/50/1») * и найдите на карте хэш. Если ничего не существует, я создаю CustomVertex и добавляю его в вектор, затем добавляю вновь созданный хэш и CustomVertex_index в карту.

*: Создавая хэш строки v / vn / vt, я создаю уникальное числовое значение, соответствующее этой строке, которое, я надеюсь, быстрее будет искать / сравнивать на карте, чем эквивалентный текст.

Если я сталкиваюсь с соответствием хешу, я считаю, что customvertex уже существует, и вместо создания нового CustomVertex я просто добавляю запись CustomVertex_index в вектор индексов и продолжаю.

Поскольку это кажется вычислительно дорогим упражнением, я предполагаю, что буду выгружать свои массивы CustomVertex (и соответствующие массивы индексов) на диск для последующего извлечения, а не анализировать каждый раз файл obj.

Прежде чем задавать свои вопросы, могу ли я указать, что из-за нехватки времени и отсутствия необходимости перепроектировать мой класс Vbo (нетривиальная задача) я застрял в формате CustomVertex — я знаю, что можно предоставлять атрибуты в отдельные массивы для моих шейдеров, но я читал, что чередование данных, как у меня с CustomVertex, может повысить производительность.

Итак, на мои вопросы:
1. Мой метод кажется здоровым или сумасшедшим? Если сумасшедший, пожалуйста, укажите, где я иду не так.

  1. Можете ли вы определить возможные проблемы?

  2. Кто-нибудь делал это раньше и может порекомендовать более простой способ добиться того, что я пытаюсь сделать?

3

Решение

Можете ли вы определить возможные проблемы?

Ты имеешь ввиду помимо хеш-коллизий? Потому что я не вижу той части вашего алгоритма, которая это обрабатывает.

Кто-нибудь делал это раньше и может порекомендовать более простой способ добиться того, что я пытаюсь сделать?

Есть гораздо более простой способ: просто сравнивайте индексы и не используйте хэши.

0

Другие решения

Вместо создания строкового хеша «v / vn / vt», идея состоит в том, чтобы хешировать только v как целое число. После этого вы получаете корзину, которая содержит все комбинации «v / vn / vt», которые имеют один и тот же индекс v.

Если произойдет коллизия хеша (то же самое, что и с v), вы бы сравнили коллизионную комбинацию с комбинацией в корзине, чтобы увидеть, действительно ли она дублирована. Если нет, не забудьте добавить столкновенную комбинацию в ведро.

0

По вопросам рекламы [email protected]