Уголок tool-программистов
GameDev.ru / Сообщества / Уголок tool-программ / Форум / Универсальный способ сборки VertexBuffer'а при экспорте без дублирования вершин (комментарии)

Универсальный способ сборки VertexBuffer'а при экспорте без дублирования вершин (комментарии)

Страницы: 1 2 Следующая »
FrankinshteinПостоялецwww14 фев. 20070:46#0
Универсальный способ сборки VertexBuffer'а при экспорте без дублирования вершин (комментарии)

Это сообщение сгенерировано автоматически.

timurrrrНовичокwww14 фев. 20070:46#1
А так не работает?

struct vertex
{
  float px, py, pz;//позиции
  float nx, ny, nz;//нормали
  float s, t;//текст. координаты

  bool operator < (const vertex &r) const
  {
    const char *p1 = (const char*)(void*)this,
                    *p2 = (const char*)(void*)&r;
    for (int i=0; i < sizeof(vertex); ++i)
    {
      if (p1!=p2)
        return p1
< p2;     
    }
    return false;
  }
};

FrankinshteinПостоялецwww14 фев. 20076:16#2
Timurrrr
Можно и так, хотя я не пробывал.
CoriolisПостоялецwww14 фев. 200722:31#3
Глупый вопрос.
В псевдокоде: почему сразу нельзя накапливать индексы в myIB? Зачем делать два цикла?

Правка:
И в догонку, почему тогда ннельзя было сделать так, чтобы метод PushVertex возвращал бы индекс, под которым легла вершина в вектор? Тогда можно было бы сразу этот индекс писать в VB. И метод GetIndex тогда был бы ненужен.

Могет я не понимаю чего-то?

FrankinshteinПостоялецwww15 фев. 200715:59#4
Coriolis
Ты прав, можно сразу строить индексы, чето я не догадался. Поправлю щас.
CoriolisПостоялецwww15 фев. 200719:05#5
Пример поправил, да, но по прежнему нет смысла в методе GetIndex.
Я же писал, можно сделать чтобы PushVertex сразу возвращал индекс - мы же в этом методе знаем под каким элементом лежит запрошенная вершина. Я не силён в STL(да и в сях тоже), но вроде можно вообще юзать просто vector, при помещении вершины запоминать индекс (если поиск дал результат - то результат поиска, если нет - то индекс под которым добавили) - тогда сразу будем получать и индекс и вектор с нормалями.
FrankinshteinПостоялецwww15 фев. 200719:22#6
Coriolis
Так сразу и возвращает) внимательно посмотри,
а вектор я пробывал, map на high poly работает намноооого быстрее, у меня разница по скорости раза в 3-4 была.
CoriolisПостоялецwww15 фев. 200719:54#7
А, да, проглядел :)
И всё-таки, зачем GetIndex? :) Он у тебя теперь даже не юзается нигде :)
FrankinshteinПостоялецwww15 фев. 200720:06#8
Coriolis
пусть будет, вдруг пригодится)
SelenПостоялецwww29 мар. 200723:08#9
Frankinshtein
Спасибо и большой респект за статью, очень хорошая и полезная.
XProgerПостоялецwww30 мар. 20076:28#10
    local face = #()
    local vert = #()

    for i = 1 to mesh.numFaces do
    (
      texface = (GetTVFace Mesh i)
      append face (GetFace Mesh i)
      for j = 1 to 3 do
      (
        v = sVertex()
        v.c = (GetVert Mesh face[i][j])
        v.tc = (GetTVert Mesh texface[j])        
        v.sg = (getFaceSmoothGroup Mesh i)
        idx = 1
        for p in vert do
        (
          if (p.c == v.c) and (p.tc == v.tc) and ( ((bit.and p.sg v.sg) > 0) or (p.sg == v.sg) ) then
            exit
          idx += 1
        )
        if (vert.count < idx) then
          append vert v
        face[i][j] = idx - 1
      )
    )
Текстурные координаты и группы сглаживания. Существует более шустрый, а не универсальный алгоритм? )
KlounПостоялецwww2 дек. 200923:16#11
Я конечно понимаю, что прошло два года, но всеравно спрошу:
почему в структуре vertex вместо индексов вершнин\нормалей\текстурных вершин используются их значения? гороздо быстрее стравить один int чем три float? я не прав?
FrankinshteinПостоялецwww3 дек. 200910:00#12
Kloun
вопрос в том, как этот int сгенерить
KlounПостоялецwww3 дек. 200913:43#13
Frankinshtein
> вопрос в том, как этот int сгенерить
если для экспорта из макса - то ничего генерить не надо. макс сам выдает индексы )
GestaltПостоялецwww19 июля 201322:53#14
Предложу некоторые изменения.

Первое

С позиции именно объекта operator <, определённый для структуры VERTEX, не имеет реального смысла и используется только для корректной вставки в map. Для того, чтобы не нагружать структуру VERTEX лишним оператором и не вводить пользователя класса в заблуждене, можно задать свою собственную внешнюю функцию сравнения объектов. Сделать это можно ещё двумя способами. По умолчанию, сравнение объектов выполняет стркуктура less (третий аргумент в объявлении шаблона контейнера map):

// TEMPLATE CLASS map /* Dinkumware STL */
template<class _Kty,
  class _Ty,
  class _Pr = less<_Kty>,
  class _Alloc = allocator<pair<const _Kty, _Ty> > >
  class map { /* ... */ };

Поэтому:

Способ 1. В объявлении переменной map-контейнера укажем свою структуру:

// file : indexator.h
struct tVertexCompare
{
  bool operator() (const VERTEX& v1, const VERTEX& v2) const
  {
    return v1 < v2; // псевдокод
  }
};// end of indexator.h

// ...
// пример использования:
typedef std::map<VERTEX, unsigned int, tVertexCompare> VertSet; // указываем структуру сравнения 3-им аргументом

Способ 2. В пространстве имён std создать свой шаблон структуры less с указанием типа VERTEX:

// file : indexator.h
namespace std
{
  template<>
  struct less<VERTEX> : binary_function <VERTEX, VERTEX, bool>
  {
    bool operator() (const VERTEX& v1, const VERTEX& v2) const
    {
      return v1 < v2; // псевдокод
    }
  };
}; // end of indexator.h

// ...
// пример использования:
typedef std::map<VERTEX, unsigned int> VertSet; // структура сравнения уже в std, указывать её 3-им аргументом не нужно

Второе

Нет необходимости соритовать добавляемые вершины в map, что делается автоматически. Можно воспользоваться ассоциативным контейнером unordered_map, например из библиотеки boost на основе хэш-таблиц. Необходимо задать функцию хеширования и функцию сравнения ключей (вертексов):

#include <boost/unordered_map.hpp>

// структура сравнения:
struct tIequalTo : std::binary_function<VERTEX, VERTEX, bool>
{
  bool operator()(const VERTEX & v1, const VERTEX & v2) const
  {
    if ( v1 == v2 ) // псевдокод
      return true;
    return false;
  }
};

// структура вычисления хэша:
struct tHash : std::unary_function<VERTEX, std::size_t>
{
  std::size_t operator()(VERTEX const& v) const
  {
    return ((size_t)( v.x*738 + v.y*193 + v.z*834 ));
  }
};

// ...
// Пример использования:
typedef boost::unordered_map<VERTEX, unsigned int, tHash, tIequalTo > tVertexBoostUMap;
typedef tVertexBoostUMap::const_iterator tVertexBoostUMapIt;

Плюс ко всему, более логично не сравнивать элементы вертекса в порядке следования (как в map), а именно сравнивать их на совпадение (как в unordered_map). Прирост скорости полной сборки уникального вертексного буфера с использованием boost/unordered_map примерно в 1.6 .. 1.8 раза. Функция вычисления хэша может подлежать оптимизации, но это уже другой вопрос.

Страницы: 1 2 Следующая »

/ Форум / Уголок tool-программистов

Тема в архиве.

2001—2018 © GameDev.ru — Разработка игр