最成功的公共物理引擎对“模式”或“面向对象设计”并不十分重视.
这是一个支持我的,无可否认的大胆断言的纲要:
Chipmunk – 写在C,足够说.
Box2d – 用C语言编写,这里有一些多态性.有一些形状的层次结构(基类b2Shape)和一些虚函数.尽管如此,抽象漏洞就像一个筛子一样泄漏,你会在整个源代码中找到很多关于叶子类的强制转换.还有一个“联系人”的层次结构,这证明更成功,虽然使用单个虚函数,在没有多态的情况下重写它是很简单的(我相信,花栗鼠使用函数指针). b2Body是用于表示刚体的类,它是非虚拟的.
Bullet – 用C语言编写,用于大量游戏.大量的功能,大量的代码(相对于其他两个).实际上有一个基类,刚体和软体表示扩展,但只有一小部分代码可以使用它.大多数基类的虚函数与序列化(保存/加载引擎状态)有关,剩下的两个虚函数软体无法实现一个TODO通知我们需要清理一些hack.在物理引擎中并不完全是对多态性的认可.
这是很多的话,我甚至没有真正开始回答你的问题.我想要回家的是,多态性不是在现有物理引擎中有效应用的东西.这可能不是因为作者没有“得到”OO.
所以无论如何,我的建议是:你的实体类沟通多态.你不会最终得到100种不可能在以后重构的不同类型,你的物理引擎的形状数据将是相当同质的(凸多边形,盒子,球体等),你的实体数据很可能是甚至更均匀(可能只是开始的刚体).
我觉得你做的另一个错误只是支持一个Physics :: System.能够独立于彼此模拟身体(例如,对于双人游戏)具有实用性,并且最简单的方法是支持多个Physics :: Systems.
考虑到这一点,最简洁的“模式”将是工厂模式.当用户想要创建一个刚体时,他们需要告诉Physics :: System(充当工厂)为他们做这件事,所以在你的Physics :: System中:
// returning a smart pointer would not be unreasonable,but I'm returning a raw pointer for simplicity:
rigid_body_t* AddBody( body_params_t const& body_params );
并在客户端代码中:
circle_params_t circle(1.f /*radius*/);
body_params_t b( 1.f /*mass*/,&circle /*shape params*/,xform /*system transform*/ );
rigid_body_t* body = physics_system.AddBody( b );
Anyhoo,有种咆哮.希望这是有帮助的.至少我想指向Box2d.它是用一种非常简单的C语言编写的,其中应用的模式将与您的引擎相关,无论是3D还是2D.