well part of the problem is trying to use a library as if it was a different library.
I do not know how those libraries do it, I only know how Newton does it.
in newton there is a class class dgCollisionInstance
which is the object that you get back whe you create a collision.
the object contain a reference to a unique collision shape that is managed by the world.
Take for example a box, there can be different boxes types based on the size but the are only one copy of each box of the same sizes. this is the code that makes a box
- Code: Select all
NewtonCollision* NewtonCreateBox(const NewtonWorld* const newtonWorld, dFloat dx, dFloat dy, dFloat dz, int shapeID, const dFloat* const offsetMatrix)
{
TRACE_FUNCTION(__FUNCTION__);
Newton* const world = (Newton *)newtonWorld;
dgMatrix matrix (dgGetIdentityMatrix());
if (offsetMatrix) {
matrix = dgMatrix (offsetMatrix);
}
return (NewtonCollision*) world->CreateBox (dx, dy, dz, shapeID, matrix);
}
and this is how the low lever object is created.
- Code: Select all
dgCollisionInstance* dgWorld::CreateBox(dgFloat32 dx, dgFloat32 dy, dgFloat32 dz, dgInt32 shapeID, const dgMatrix& offsetMatrix)
{
dgUnsigned32 crc = dgCollisionBox::CalculateSignature(dx, dy, dz);
dgBodyCollisionList::dgTreeNode* node = dgBodyCollisionList::Find (crc);
if (!node) {
dgCollision* const collision = new (m_allocator) dgCollisionBox (m_allocator, crc, dx, dy, dz);
node = dgBodyCollisionList::Insert (collision, crc);
}
return CreateInstance (node->GetInfo(), shapeID, offsetMatrix);
}
you can see that it tries to find a box that matches the size of the box, if it does not find it, it makes a unique collision Box and add it to the cache. if it find one is just uses the node.
then it creates a box using that pointer to the box in the cache.
It is the call to CreateInstance that add a reference to the unique collision shape.
when you create a body of any kind, this is the function call
- Code: Select all
void dgBody::AttachCollision (dgCollisionInstance* const collisionSrc)
{
dgCollisionInstance* const instance = new (m_world->GetAllocator()) dgCollisionInstance (*collisionSrc);
m_world->GetBroadPhase()->CollisionChange (this, instance);
if (m_collision) {
m_collision->Release();
}
m_collision = instance;
m_equilibrium = 0;
}
you see that it creates a new collision instance from the argument, then it releases the collision that is in the body and assigns this new one.
the reason is uses reference is because other data structures has references to some collisions shape.
in the pass in new 1.0 the collision instance was part of the collision base class, and the cache uses the extra data like scale to make the hash, but that was making the cash bigger dificult to maintain. so it was separated quite earlly by the late version of newtion 1.5
this is the same for all shapes including compound and scene with the exception of soft bodies collisions which each get a duplicate of the shape.
Coumpound are trees of CollsionInstances, so each child is the same as a collision Instance on a body.