I am writing a physics engine and having a hard time figuring out a good way to design my data storage.
The functionality that I want:
- Have a class that represents a PhysicsBody
- Have a class that represents a collision volume (Lets say a box)
- Each physics body can have one more collision volumes attached to it
- Possible to have physics body without a collision volume
- Optional: CollisionVolume without a physics body. (think Trigger Volumes)
Right now I have basically two loops. One that updates the physics bodies in the simulation. It updates their position/velocity/rotation. The second loop performs collision detection over all the collision volumes. Its just a nested for loop that checks for collisions between each pair of collision volumes. (I know it can be done better but that's a separate topic)
I know that the ideal way is to store objects in contiguous arrays.
std::vector<PhysicsBody> m_bodies;
std::vector<CollisionVolume> m_colliders;
Problems I found with this approach:
- Its hard to maintain PhysicsBody -> CollisionVolume relationship. For example, if I want to remove a CollisionVolume from my vector, I would swap it with the last one and pop back. Data gets moved and if I stored an index to a CollisionVolume in PhysicsBody, its no more valid.
- Anytime I destroy a PhysicsBody, the destructor will check if there was any collision volume attached to it and appropriately remove that from the Physics system as well. Problem is that a vector will make internal copies and destroy them and when that happens it will wreak havoc by removing collision volumes that weren't supposed to be removed.
- CollisionVolume is actually a base class(doesn't have to be) and other classes derive from it like boxes/spheres and what not. I could potentially not use inheritance and come up with some other complicated design, but this is something to keep in mind.
I tried hard to find a way around it but ended up storing pointers instead:
std::vector<PhysicsBody*> m_bodies;
std::vector<CollisionVolume*> m_colliders;
The best solution to minimizing cache misses that I came up with was overloading new/delete and storing these objects in a memory pool just for the physics system.
Are there any other better solutions to this? Obviously performance is key.