анализ формата файла 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. Кто-нибудь делал это раньше и может порекомендовать более простой способ добиться того, что я пытаюсь сделать?


person fishfood    schedule 04.01.2013    source источник
comment
Если вы можете что-то хешировать, почему бы просто не использовать unordered_map? В противном случае ваш метод кажется прекрасным и не слишком сложным.   -  person pmr    schedule 04.01.2013
comment
Создавая хэш строки v / vn / vt, я создаю уникальное числовое значение, соответствующее этой строке, которое, как я надеюсь, будет быстрее искать / сравнивать на карте, чем эквивалентный текст.   -  person fishfood    schedule 04.01.2013
comment
@lapin: Это называется преждевременной оптимизацией. Просто сравните индексы (как числа, а не текст). Если ваше профилирование показывает, что это происходит медленно, тогда разрешите это.   -  person Nicol Bolas    schedule 04.01.2013
comment
Учитывая, что данные изначально находятся в строковом формате и необходимо сравнить все 3 индекса, я не совсем уверен, что использование строки в качестве ключа карты - это плохая идея. Хотя, если вы действительно хотите создать целочисленный хеш, я бы создал этот из индексов, а не из строки. Я согласен с приведенным выше комментарием, что вы должны начать с любой наивной версии, которая работает, и при необходимости оптимизировать.   -  person JasonD    schedule 04.01.2013


Ответы (2)


Можете ли вы обнаружить какие-либо потенциальные проблемы?

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

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

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

person Nicol Bolas    schedule 04.01.2013

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

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

person user1118710    schedule 17.04.2014