bounding volume and collision design issues..

Started by
1 comment, last by Nanook 12 years, 6 months ago
I've had something thats been working for a while, but I'm in the process of splitting up my collision and physics code and I've run into some design issues.

Atm. PhysicsObjects got a pointer to a base BoundingVolume class. The BoundingVolume class has a function Collide() that takes another BoundingVolume instance. This function is then called for two PhysicsObjects inside a member function CheckCollision() on the PhysicsObject class. I then use the visitor pattern to implement this so it doesn't need to know the concrete class.. The visitor then sets up a Collider, eg ObbObbClass, instance which performs the collisioncheck.

In the case of the obb obb collision check I need position, velocity and angular velocity, but not for any of the other checks. In the current system I have been passing in a Contact class instance as a reference all the way from the CheckCollision() function. Before I pass in the contact instance I set the PhysicsObjects. Then if there is a contact the contact will be updated with contact points, normals and penetration depth. With this the obb obb collision check can get the data it needs from the PhysicsObject in the contact.

In my new code I don't want to have the Contact class in the collision code so I can't pass it in as I have been doing. I've created a new struct, ContactSet that only stores contact point, normal and penetration that I will be returned from the collider if there is a collision. But this means I can't get the position, velocity and angular velocity from the contact instance anymore.

My question is how I can implement this. I've been thinking of having a bounding volume manager that has a map of obb's, spheres and so on.. then store the bounding volume type and the key into that map in the PhysicObject and use that key to get the bounding volume and the type to set up the correct collider. Now with the position and all that I can just have it set up in the concrete collider constructor. This would work I guess, but I don't like the idea of having a manager for it and allso I wanted to post here to get sugestions on how to do it.
Advertisement
Without knowing what language is involved -

- If your language has Nullables, just add the data you might not need to the struct as nullables. That way, if you don't need them, they can be set to null and ignored. If you need them, they're there.

- If your language doesn't have Nullables, you can probably simulate them with something like "bool positionIsNull; Vector3 position;". You still have to pass in a position value even if you're not using it, but that can simply be "Vector3.Zero" and "positionIsNull = true;".
Yes I did think about that.. but with the visitor pattern that means passing in the pointers to alot of functions that doesnt realy need it.. I tried implementing it that way, but it got really messy..

I think I'm going to make a ColliderFactory class with a public create function that takes two boundingvol base class pointers and the position, velocity and angular velocity.. then have a getType function on the boundingvolumes and use this type to cast the bounding volumes to the concrete type.. then having overloaded private function for each of the cases that will create and return the appropriate collider..

It will use static_cast, but In a safe way and only on pointers.. I dont think it will be any slower than the visitor pattern either? And it will be relativly easy to maintain.. when adding new bounding volumes only the factory needs to be updated..



Something like this:
[source]

class ColliderFactory
{
public:
void CreateCollider(Collider& collider, const BoundingVol *bvol0, const BoundingVol *bvol1, Real dt,
const Math::Vector3D<Real> &pos0, const Math::Vector3D<Real> &pos1,
const Math::Vector3D<Real> &vel0, const Math::Vector3D<Real> &vel1,
const Math::Vector3D<Real> &angvel0, const Math::Vector3D<Real> &angvel1)
{
//Do static cast and call overloaded function
}
private:
void CreateCollider(Collider& collider, const Obb *obb0, const Obb *obb1, Real dt,
const Math::Vector3D<Real>& pos0, const Math::Vector3D<Real>& pos1,
const Math::Vector3D<Real>& vel0, const Math::Vector3D<Real>& vel1,
const Math::Vector3D<Real>& angvel0, const Math::Vector3D<Real>& angvel1);

void CreateCollider(Collider& collider, const Obb *obb, const Plane *plane, Real dt);

void CreateCollider(Collider& collider, const BSphere *bsphere, const Obb *obb, Real dt);

void CreateCollider(Collider& collider, const BSphere *bsphere, const Plane *plane, Real dt);

void CreateCollider(Collider& collider, const BSphere *bsphere0, const BSphere *bsphere1, Real dt);
};

[/source]

This topic is closed to new replies.

Advertisement