Должен ли я делиться данными между графикой и физическим движком в игре?

9

Я пишу игровой движок, который состоит из нескольких модулей. Два из них - графический движок и физический движок .

Интересно, это хорошее решение для обмена данными между ними?

Два способа (делиться или нет) выглядит так:

Без обмена данными

GraphicsModel{
    //some common for graphics and physics data like position

    //some only graphic data 
    //like textures and detailed model's verticles that physics doesn't need
};

PhysicsModel{
    //some common for graphics and physics data like position

    //some only physics data 
    //usually my physics data contains A LOT more informations than graphics data
}

engine3D->createModel3D(...);
physicsEngine->createModel3D(...);

//connect graphics and physics data 
//e.g. update graphics model's position when physics model's position will change

Я вижу две основные проблемы:

  1. Много избыточных данных (например, две позиции для физических и графических данных)
  2. Проблема с обновлением данных (мне приходится вручную обновлять графические данные при изменении физических данных)

С обменом данными

Model{
     //some common for graphics and physics data like position
};

GraphicModel : public Model{
    //some only graphics data 
    //like textures and detailed model's verticles that physics doesn't need
};

PhysicsModel : public Model{
     //some only physics data 
    //usually my physics data contains A LOT more informations than graphics data
}

model = engine3D->createModel3D(...);
physicsEngine->assingModel3D(&model); //will cast to 
//PhysicsModel for it's purposes??

//when physics changes anything (like position) in model 
//(which it treats like PhysicsModel), the position for graphics data 
//will change as well (because it's the same model)

Проблемы здесь:

  1. PhysicsEngine не может создавать новые объекты, просто «вытаскивая» существующие из engine3D (для меня это выглядит более анти-независимым)
  2. Приведение данных в функцию assingModel3D
  3. physicsEngine и graphicsEngine должны быть осторожны - они не могут удалять данные, когда они им не нужны (потому что второй может понадобиться). Но это редкая ситуация. Более того, они могут просто удалить указатель, а не объект. Или мы можем предположить, что graphicsEngine будет удалять объекты, физика Engine просто указывает на них.

Какой способ лучше?

Что создаст больше проблем в будущем?

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

Есть ли у них какие-то скрытые плюсы и минусы?

PolGraphic
источник
Точно мой вопрос тоже.
Данияр

Ответы:

9

В настоящее время все больше игровых движков используют дизайн компонентов (например, Unity, Unreal). В этом виде конструкции, а GameObjectсостоит из списка компонентов. В вашей ситуации могут быть a MeshComponentи a PhysicalComponent, оба прикрепленные к одному игровому объекту.

Для простоты вы можете поместить переменную преобразования мира в GameObject. Во время обновления фразы PhysicalComponentвыходные данные преобразуются в эту переменную. Во время рендеринга MeshComponentчитает эту переменную.

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

В реалистическом сценарии, однако, вам может потребоваться более сложная обработка между синхронизацией физики / графики. Например, физическое моделирование может потребоваться с фиксированным временным шагом (например, 30 Гц), в то время как рендеринг должен быть переменным. И вам может потребоваться интерполировать результаты с выхода физического движка. Некоторые физические движки (например, Bullet) имеют прямую поддержку этой проблемы.

Единство обеспечивает хорошую ссылку их компонентов , который стоит посмотреть.

Мило Йип
источник
Это совсем не отвечает на вопрос, поскольку наличие двух компонентов ничего не говорит о том, используют ли они данные сетки или нет.
Maik Semder
2
На самом деле, он предлагает лучший дизайн, который является абсолютно законным.
Jcora
7

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

Качество, потому что физический движок не заботится о текстурных координатах, нормальных группах и всяких причудливых вещах, например. Каждый из них ожидает, что данные в очень специфической структуре сводятся к проблемам выравнивания, упаковки, чередования данных и т. Д.

Количество, потому что физическая сетка обычно имеет меньше треугольников, это упрощенная версия сетки рендеринга с высоким разрешением.

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

Майк Земдер
источник
0

Помимо отличного ответа @Millo Yip, я хотел бы просто напомнить вам, что вам нужно будет делить одни и те же данные с модулем Controls и модулем AI, и если я не ошибаюсь, большинство аудио-библиотек имеют представление о положении излучателя звука. так что вам нужно будет поделиться данными с этим модулем тоже.

ManicQin
источник
0

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

Как данные попадают из физики в рендеринг, зависит только от вас.

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

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

Naros
источник