Как стать автором
Обновить

Комментарии 9

Спасибо за статью.

А ваша версия Combine() может полностью удалять лишнюю геометрию, например, когда объединяются 2 кубика?
image
даже макс и майя при комбайне таким не занимаются)
(странно прозвучало)
это не комбайн, это булеан
А ваша версия Combine() может полностью удалять лишнюю геометрию, например, когда объединяются 2 кубика?

Наш Combine() удаляет только те вершины, данные которых полностью совпадают, так что нет, внутренняя геометрия останется. Для достижения результата, приведенного Вами в примере, у нас есть отдельный алгоритм, который требует значительно больших вычислительных ресурсов. О варианте реализации в сцене можете почитать здесь. Также в дальнейшем мы собираемся опубликовать еще одну статью об этой задаче.
В начале мне не очень понравилось название статьи, так как это прежде всего описание реализаций функций редактора для меша. В то время как «процедурное редактирование» это как то больше смахивает на непосредственное применение функций в обход какого то вида GUI редактора.

Но вот в чем беда.
В CAD-средствах есть функция перерасчета нормалей, которую обычно вызывают уже после применения требуемых трансформаций. Существуют разные способы выполнения такого перерасчета. Наиболее распространенный вычисляет нормаль к плоскости каждого треугольника, а затем каждой вершине присваивает нормаль как среднее от нормалей треугольников, которым эта вершина принадлежит.

Такой алгоритм действительно имеет место быть частому применению, но чаще он встречается у велосипедистов самоучек (все этим страдают), а не в конкретных редакторах.

Например этот алгоритм некорректно считает нормали у того же куба если объединить все его вершины, сделав его как бы сглаженным. Так так в сложении нормалей трех плоскостей для отдельного угла куба участвует не по одной нормали, а по две. Это происходить из за того что в формировании грани куба участвуют два треугольника.

И такой изъян очень часто встречается при расчете тех же нормалей для самописного тирейна под OpeGL. Поэтому в редакторах используют не просто усредненную нормаль, а берут за основу веса, для складываемой нормали, угол треугольника, принадлежащий вершине для которой вычисляется нормаль. Вот такой алгоритм пожалуй более распространен в редакторах.

Благо в Unity есть уже реализованный вариант.
«процедурное редактирование» это как то больше смахивает на непосредственное применение функций в обход какого то вида GUI редактора

Описанные в статье методы в нашем случае предназначены именно для вызова в скриптах, например, при загрузке уровня, поэтому и назвали «процедурное редактирование».
Такой алгоритм действительно имеет место быть частому применению, но чаще он встречается у велосипедистов самоучек (все этим страдают), а не в конкретных редакторах

Мы написали, что существуют разные способы, и привели наиболее простой, чтобы его можно было быстро реализовать при надобности.
И спасибо за дополнение!
Вообще у Extrude, точнее у его отдельных алгоритмов, гораздо больше применения. Можно также при помощи его кода легко реализовать Bevel Profile или Loft. Да все эти завершенные операции пересекаются по своей базе и плюс в процедурном «редактировании» в том что эти базовые алгоритмы можно комбинировать, в отличии от редактора. Но опять же если позволяет API.
Описанные в статье методы в нашем случае предназначены именно для вызова в скриптах, например, при загрузке уровня, поэтому и назвали «процедурное редактирование».

Процедурный Extrude немного проще, на то он и процедурный что половину вычислений можно заменить простыми данными или константами для генерации конкретной модели. Это также повышает производительность для быстрой генерации объекта.

Но помимо этого даже для метода предназначенного для редактора в предложенном коде используются избыточные структуры, что дает лишнее использование и выделение памяти, а также лишние обращения. Например структура Vertex не нужна вовсе, каждый отдельный mesh можно и нужно обрабатывать как отдельный mesh, поэтому meshid лишний. Если посмотреть на конструкцию Unity mesh то там не требуется хранить то какому submesh принадлежит индекс или вершина. А при последовательной обработке мешей meshid будет являться глобальным значением.

Далее от этого следуют различные упрощения по поиску контура. Например Edge можно представить в виде одного числа которое не зависимо от направления будет одинаковым.

int64 Edge = Math.Max(id1,id2) + (Math.Min(id1,id2) << 32);
bool OrdInv = Math.Min(id1,id2) == id1;


Список ребер таким образом можно представить как HashSet, а направления записать отдельно.

Второй момент почему процедурный Exturude проще исходит из того что область выдавливания, в примере того же водоема, можно взять уже готовую без вычисления контура по треугольникам.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий