Наиболее успешные общедоступные физические движки не очень сильно относятся к «шаблонам» или «объектно-ориентированному дизайну».
Вот краткое изложение, подтверждающее мое, по общему мнению, смелое утверждение:
Бурундук - написано на С, достаточно сказано.
Box2d - Написано на C ++, и здесь есть некоторый полиморфизм. есть иерархия фигур (базовый класс b2Shape) с несколькими виртуальными функциями. Однако эта абстракция протекает как сито, и вы найдете множество приведения к листовым классам по всему исходному коду. Существует также иерархия «контактов», которая оказывается более успешной, хотя с одной виртуальной функцией было бы тривиально переписать это без полиморфизма (я думаю, что chipmunk использует указатель на функцию). b2Body - это класс, используемый для представления твердых тел, и он не является виртуальным.
Bullet - Написан на C ++, используется во многих играх. Тонны функций, тонны кода (относительно двух других). На самом деле существует базовый класс, который расширяет представления твердого тела и мягкого тела, но только небольшая часть кода может его использовать. Большинство виртуальных функций базового класса относятся к сериализации (сохранение / загрузка состояния механизма), из двух оставшихся виртуальных функций мягкое тело не может реализовать одну из них с TODO, информирующим нас о том, что некоторый хак необходимо очистить. Не совсем убедительное подтверждение полиморфизма в физических движках.
Это много слов, и я даже не начал отвечать на ваш вопрос. Все, что я хочу сказать, - это то, что полиморфизм - это не то, что эффективно применяется в существующих физических движках. И это, вероятно, не потому, что авторы не «получили» ОО.
Так что в любом случае мой совет: канавный полиморфизм для вашего класса сущностей. У вас не будет 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.