在游戏中的图形和物理引擎之间共享数据?

Pol*_*hic 4 c++ graphics 3d-engine game-engine physics-engine

我正在编写一个由几个模块组成的游戏引擎。其中两个是图形引擎物理引擎

我想知道在它们之间共享数据是否是一个好的解决方案?

两种方式(共享或不共享)看起来像这样:

不共享数据

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

    //some only graphic data 
    //like textures and detailed model's vertices 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 information 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
Run Code Online (Sandbox Code Playgroud)

我看到两个主要问题:

  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->assignModel3D(&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)
Run Code Online (Sandbox Code Playgroud)

这里的问题:

  1. physicsEngine 无法创建新对象,只需从 engine3D 中“分配”现有对象(不知何故,它对我来说看起来更反独立)
  2. 在assignModel3D函数中投射数据
  3. physicsEngine并且graphicsEngine必须小心 - 他们不能在不需要数据时删除数据(因为第二个可能需要它)。但这是一种罕见的情况。此外,他们只能删除指针,而不是对象。或者我们可以假设graphicsEngine将删除对象,physicsEngine只是指向它们的指针。

哪种方式更好?

哪些会在未来产生更多的问题?

我更喜欢第二个解决方案,但我想知道为什么大多数图形和物理引擎更喜欢第一个(也许是因为它们通常只制作图形或只制作物理引擎和其他人在游戏中连接它们?)。

他们还有更多隐藏的优点和缺点吗?

Mil*_*Yip 5

现在越来越多的游戏引擎采用组件化设计(如Unity、Unreal)。在这种设计中,aGameObject由组件列表组成。在您的情况下,可以有 aMeshComponent和 a PhysicalComponent,两者都附加到单个游戏对象。

为简单起见,您可以将世界变换变量放入GameObject. 在更新短语期间,PhysicalComponent将世界变换输出到该变量。在渲染期间,MeshComponent读取该变量。

这种设计背后的基本原理是在组件之间解耦。既不认识MeshComponent也不PhysicalComponent认识。它们只依赖于一个通用接口。与使用单一继承层次结构相比,通过组合扩展系统更容易。

然而,在现实场景中,您可能需要在物理/图形同步之间进行更复杂的处理。例如,物理模拟可能需要以固定时间步长(例如 30Hz)运行,而渲染需要可变。并且您可能需要从物理引擎的输出中插入结果。不过,一些物理引擎(例如 Bullet)直接支持此问题。

Unity 为他们的Components提供了很好的参考,值得一看。