Как вы получаете доступ к лицам модели в XNA? - PullRequest
1 голос
/ 07 апреля 2011

Я работаю над обнаружением столкновений для игры, написанной с использованием платформы Microsoft XNA Framework версии 4.0. При попытке получить доступ к самой модели, как только она была загружена платформой содержимого, я могу получить доступ к списку «ModelMesh», а для каждого - к списку MeshParts, но кажется, что детали имеют только диагностические данные, такие как количество вершин. , Я полностью озадачен тем, что случилось с фактическими данными лица для модели.

Я пытаюсь реализовать столкновение сферы-развертки / плоскости - то есть у меня движется шар, и я хотел бы проверить столкновение с многоугольником, когда шар движется. Мне нужен способ определения всех полигонов для тестирования, и для меня просто имеет смысл определить карту столкновений как упрощенную сетку, которую я проектирую параллельно с моим фактическим графическим объектом для использования при столкновении, но я полностью сбит с толку относительно того, как я должен получить доступ к этой информации, как только контентный конвейер XNA загрузит ее.

Возможно, здесь есть какое-то понимание? Я весь день прочесываю Google и не могу найти ничего, что могло бы помочь, хотя возможно, что я использую неправильные условия поиска ...

1 Ответ

3 голосов
/ 07 апреля 2011

Встроенный импортер содержимого XNA FBX / model и дескриптор процессора "обращены" так же, как это делает практически каждая программа моделирования - в виде списков вершин и индексов.(Как примечание, ваш графический процессор также изначально поддерживает эту схему, и современные игры полагаются на нее по соображениям производительности.)

Например, рассмотрим простой четырехугольник с четырьмя треугольниками.Вершины могут быть:

v0 (0,0,0)
v1 (1,0,0)
v2 (1,1,0)
v3 (0,1,0)

или

v0--v1
|  / |
| /  |
v3--v2

Чтобы представить это в форме «лица», вам потребуется список данных, эквивалентный

треугольник 1 (верхний левый): (0,0,0), (1,0,0), (0,1,0) = (v0, v1, v3)

треугольник 2 (нижнийсправа): (1,0,0), (1,1,0), (0,1,0) = (v1, v2, v3)

, что требует шести записей вершин.

Используя нативные структуры XNA, Vector3 имеет три элемента, каждый из которых является плавающей точкой одинарной точности (4 байта), так что каждый равен 3 * 4 = 12 байтов, и вам нужно шесть из них, так что72 байта.

Или вы можете использовать индексирование.В дополнение к четырем вершинам, вы храните список индексов:

f1: 0,1,3
f2: 1,2,3

Индексы могут быть сохранены с использованием шорт (16-битных целых).Итак, давайте рассмотрим разницу:

Нет индексов: две грани * 3 вершины * 3 компонента (xyz) * 4 байта каждая = 2 * 3 * 3 * 4 = 72 байта.

Индексируется:

вершин: 4 вершины * по 3 компонента * 4 байта на компонент = 48 байт,

индексы (3 шорта на треугольник): 6 индексов * 2 байта = 12 байт.

48 + 12 = 60, что немного меньше 72 байт для неиндексированной модели.

Эти 12 байтов могут показаться не слишком большими, пока вы не рассмотрите весь уровень с 100 000+ треугольников.В этот момент вы видите разницу в 1,2 МБ.Хотя ваша видеокарта может занимать около 2 ГБ памяти, перемещение этих данных назад и вперед между ОЗУ хоста и ОЗУ графического процессора стоит дорого.

Итак, как вы получаете эти данные?

Посмотрите наModel.Meshes[].MeshParts[].VertexBuffer.GetData() и Model.Meshes[].MeshParts[].IndexBuffer.GetData().Вы можете использовать эти методы для извлечения вершин и индексов, а затем перекрестные ссылки на них, чтобы получить список треугольников.

Вы не можете просто получить прямой доступ к элементам VertexBuffer и IndexBufferпоскольку они хранятся в ОЗУ графического процессора, разрешение случайного доступа к элементам может привести к снижению производительности почти до отрицательной скорости.

Также обратите внимание на метод GraphicsDevice.DrawIndexedPrimitives().

IПри необходимости можете опубликовать пример кода позже.

...