Я пишу игровой движок, который состоит из нескольких модулей. Два из них - графический движок и физический движок .
Интересно, это хорошее решение для обмена данными между ними?
Два способа (делиться или нет) выглядит так:
Без обмена данными
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
Я вижу две основные проблемы:
- Много избыточных данных (например, две позиции для физических и графических данных)
- Проблема с обновлением данных (мне приходится вручную обновлять графические данные при изменении физических данных)
С обменом данными
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)
Проблемы здесь:
- PhysicsEngine не может создавать новые объекты, просто «вытаскивая» существующие из engine3D (для меня это выглядит более анти-независимым)
- Приведение данных в функцию assingModel3D
- physicsEngine и graphicsEngine должны быть осторожны - они не могут удалять данные, когда они им не нужны (потому что второй может понадобиться). Но это редкая ситуация. Более того, они могут просто удалить указатель, а не объект. Или мы можем предположить, что graphicsEngine будет удалять объекты, физика Engine просто указывает на них.
Какой способ лучше?
Что создаст больше проблем в будущем?
Мне больше нравится второе решение, но мне интересно, почему большинство графических и физических движков предпочитают первое (может быть, потому, что они обычно делают только графический или только физический движок, и кто-то еще подключает их в игре?).
Есть ли у них какие-то скрытые плюсы и минусы?
physics
architecture
graphics
PolGraphic
источник
источник
Ответы:
В настоящее время все больше игровых движков используют дизайн компонентов (например, Unity, Unreal). В этом виде конструкции, а
GameObject
состоит из списка компонентов. В вашей ситуации могут быть aMeshComponent
и aPhysicalComponent
, оба прикрепленные к одному игровому объекту.Для простоты вы можете поместить переменную преобразования мира в
GameObject
. Во время обновления фразыPhysicalComponent
выходные данные преобразуются в эту переменную. Во время рендерингаMeshComponent
читает эту переменную.Обоснование этого дизайна заключается в разделении между компонентами. Ни то,
MeshComponent
ни другое неPhysicalComponent
знают. Они просто зависят от общего интерфейса. И это может быть проще расширить систему по составу, чем с помощью единой иерархии наследования.В реалистическом сценарии, однако, вам может потребоваться более сложная обработка между синхронизацией физики / графики. Например, физическое моделирование может потребоваться с фиксированным временным шагом (например, 30 Гц), в то время как рендеринг должен быть переменным. И вам может потребоваться интерполировать результаты с выхода физического движка. Некоторые физические движки (например, Bullet) имеют прямую поддержку этой проблемы.
Единство обеспечивает хорошую ссылку их компонентов , который стоит посмотреть.
источник
Двигатели обычно выбирают первый вариант (собственная физическая сетка и собственная сетка рендеринга), потому что им нужны очень разные данные, как по качеству, так и по количеству.
Качество, потому что физический движок не заботится о текстурных координатах, нормальных группах и всяких причудливых вещах, например. Каждый из них ожидает, что данные в очень специфической структуре сводятся к проблемам выравнивания, упаковки, чередования данных и т. Д.
Количество, потому что физическая сетка обычно имеет меньше треугольников, это упрощенная версия сетки рендеринга с высоким разрешением.
Разъединяя оба, мы гарантируем, что мы можем настроить один, включая изменение его структуры данных для лучшей производительности, не повреждая другой. Это гораздо более масштабируемо.
источник
Помимо отличного ответа @Millo Yip, я хотел бы просто напомнить вам, что вам нужно будет делить одни и те же данные с модулем Controls и модулем AI, и если я не ошибаюсь, большинство аудио-библиотек имеют представление о положении излучателя звука. так что вам нужно будет поделиться данными с этим модулем тоже.
источник
Как уже говорили другие, это довольно распространенное место, когда физика имеет внутреннее состояние данных, управляемое отдельно от внутреннего состояния данных механизма рендеринга. Часто можно увидеть, что даже данные преобразования (положение / ориентация / масштаб) хранятся отдельно от физики и визуализируемых объектов, поскольку возможно, что существует игровой объект, который не навязан физикой и не отрисован, но требует положения в мире для другой механики.
Как данные попадают из физики в рендеринг, зависит только от вас.
Вы можете сделать это через какой-то межсистемный процесс отправки, используя события / сообщения. Вы можете сделать это, выставив открытый интерфейс подсистемы рендеринга в подсистему физики, чтобы физика могла просто установить позицию особенно визуализируемого объекта. Другой вариант заключается в том, что визуализируемая подсистема запрашивает у объекта преобразование во время его обновления и выполняет обновление позиции визуализируемого компонента, после чего следует рисование.
Естественно, в зависимости от вашей игры некоторые из этих средств будут более дружественными к кешу и будут иметь лучшую производительность, чем другие. Я бы не стал слишком увлекаться определенным образом на этом этапе, выбрал бы шаблон общения и попробовал бы его. Вы можете легко переделать эту часть позже, чтобы протестировать различные средства для оптимизации.
источник