Физика: первые тесты
Чтож пока с рендером я решил завязать. На очереди – иерархия объектов.
class ageRenderObject
{
};
class agePhysicsObject
{
};
class ageSceneObject
{
class ageRenderObject;
class agePhysicsObject;
};
Вот, поднимаясь по иерархии вверх я создал класс ageSceneObject который включает в себя отрисовочный объект ageRenderObject (с которым я работал ранее) а также объект физического движка agePhysicsObject. В нём (ageSceneObject) происходит их синхронизация. Новонаписанный класс agePhysicsObject является просто обёрткой над классом физикса NxActor, и имеет специфический для моего движка функционал. Как например загрузка физической оболочки из файла.
Естественно вручную задавать оболочки это очень плохая идея. Поэтому я потратил пару дней на изучение плагинов и программ для их визуального создания и остановился бесплатном редакторе Scythe (http://www.physicseditor.com/)
Что я могу про него сказать? Хороший, интуитивно понятный редактор и прозрачный формат выходного файла. Конечно для загрузки оболочек можно использовать и их API, однако там очень много лишнего, поэтому я написал свой загрузчик их формата (благо его описание присутствует на их сайте в разделе downloads)
Вот видео того, что получилось:
И тоже самое но с отладочной информацией:
Иерархия игровых объектов
Работаю над иерархией и общей структурой объектов. Сначала в движке планировал разбить иерархию объектов на два класса – сцена и игровой уровень. Предполагалось, что в сцене мы храним сами пулы простых объектов, а в классе уровня – глобальные ссылки на них и пулы сложных объектов, собирающие несколько ссылок на простые объекты. Кроме того, логически, уровнь будет содержать классы конкретной игры, а сцена – более общие классы.
Вот такая была схема:
class Scene
{
Lights
Particles
Decals
SceneObjects
}
class GameObject
{
LightsID
ParticlesID
DecalsID
SceneObjectsID
}
class GameLevel
{
ParticlesType
DecalsType
ActorsType
StaticsType
DynamicsType
LightsID
ParticlesID
DecalsID
Actors:GameObject;
Static:GameObject;
Dynamic:GameObject;
}
Однако, при ближайшем рассмотрении всё пошло пи… короче такая схемка не покатит. И вот почему. Во-первых, отсечение по ок-трии в целях оптимизации надо будет делать в классе уровня, ибо отсечь один GameObject быстрее чем кучу SceneObjects, Particles и других его составляющих. Во-вторых, сомнительная радость размазывать хранение параметров для типов объекта по двум классам (например партиклы, декалы). В третьих же сериализация опять таки достаётся классу уровня.
Вот таким макаром класс Сцены становится всё худее и худее, а его значимость – всё меньше и меньше.
Вообщем волевым решением я всё перенёс в мега-класс GameScene:
class ageGameScene: public ageSingleton< ageGameScene>
{
ageResourseManager<ageTypeInfo> ActorsType;
ageResourseManager<ageTypeInfo> DynObjectsType;
ageResourseManager<ageTypeInfo> StatObjectsType;
ageResourseManager<ageTypeInfo> StatParticlesType;
ageResourseManager<ageTypeInfo> StatDecalsType;
ageCDynArray<ageSceneObject> SceneObjects;
ageCDynArray<ageCamera> Cameras;
ageCDynArray<ageLight> Lights;
ageCDynArray<ageDecal> Decals;
ageCDynArray<ageParticleEmitter> Particles;
ageCDynArray<ageActor> Actors;
ageCDynArray<ageDynObject> DynObjects;
ageCDynArray<ageStatObject> StatObjects;
ageSimpleArray<int> ActorsID;
ageSimpleArray<int> DynObjectsID;
ageSimpleArray<int> StatObjectsID;
ageSimpleArray<int> LightsID;
ageSimpleArray<int> ParticlesID;
ageSimpleArray<int> DecalsID;
int CameraID;
};
Вот такой жирдяй-класс. В нём же практически вся игра будет :-D
-----
К слову о проектировании. В голове эти все объекты у меня выглядят таким образом :-D
Lights & shadows test
Реализую классы сцены, по принципу, рассказанному в предыдущей серии :)
Не всё оказалось гладким. Точнее всё оказалось грубым и с зазубринами. Для начала неожиданно для себя узнал что стандартный вектор STL переалоцирует всю память, при резервировании. Далее оказалось что этот самый вектор требует ещё и конструктор копии для сложных агрегатных классов. В итоге – два дня на исправление моего ageDynArray (основанного на STL векторе) плюс нудное подписывание конструкторов копий для всех сложных агрегатных классов (коих у меня оказалось 12 штук). Раньше я ничего не замечал ибо клал в свой ageDynArray только относительно простые классы, для которых компилятор генерирует конструктор копии автоматически.
Напоследок была ещё одна весёлая штука – оказалось если и в базовом классе и в классе наследнике есть перегруженный оператор присваивания, то это отнюдь не означает что при его вызове из класса наследника, он вызовется автоматически и в базовом классе. Раньше я с такой ситуацией не сталкивался, поэтому по простоте душевной был уверен что он, как и конструктор, вызовется автоматически. Надо думаю ещё раз Страуструпа почитать на досуге :)
В итоге, класс сцены, хоть и со скрипом, но заработал. Добавил в него пока DynObjects, StatObjects и источники света. Для тестирования класса собрал небольшую демку, в которой можно добавлять бочки (DynObjects), которые падают на статический камень (StatObjects). Ну ещё источники света можно добавлять.
Вот: