Building my physics solution

This topic is 3251 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I am trying to build me physics portion of my engine and I am stuck at deciding how I should solve a problem. Basically, my physics manager will hold an array of physics nodes (CPhysicsBase, or CRigidBody), then check for collision and return either NO_COLISSION, COLLISION or RESTING_CONTACT. However, it is not necessary for plain physics node to deal with RESTING_CONTACT, just typically a RigidBody node for applying friction. My question is, what is the best way to deal with the RESTING_CONTACT state? I could make an enum for the CPhysicsBase and CRigidBody, then make sure it is a RigidBody then just type cast it like
	case RESTING_CONTACT:
/* Handle the resting contact */
if(vPhysicsNodes[0]->GetCollisionType == RIGID_BODY)
((CRigidBody *)vPhysicsNodes[0])->ApplyFriction(elapsedTime);

break;


However, that just seems like a poorly hacked version. Or should I just drop the regular CPhysicsBase and just always use a CRigidBody so I do not have to worry about this? Idealy, I would like to be able to use a CPhysicsBase because it would hold less variables, functions and sometimes I do not need a RigidBody solution for the physics nodes (such as a typically wall that does not move). Here is a code example of my setup
#include <d3dx9.h>
#include <vector>
using std::vector;

typedef enum COLLISION_STATE{ NO_COLLISION ,COLLISION, RESTING_CONTACT };

class CCollisionSphere;
class CCollisionPlane;

class CCollisionBase
{
public:
virtual COLLISION_STATE CheckCollision(CCollisionBase *pCollisionBase) = 0;
virtual COLLISION_STATE DoCheckCollision(CCollisionPlane *pPlane) = 0;
virtual COLLISION_STATE DoCheckCollision(CCollisionSphere *pSphere) = 0;
};

class CCollisionSphere : public CCollisionBase
{
public:
COLLISION_STATE CheckCollision(CCollisionBase *pCollisionBase) { return pCollisionBase->DoCheckCollision(this); }
COLLISION_STATE DoCheckCollision(CCollisionPlane *pPlane) { return NO_COLLISION; }
COLLISION_STATE DoCheckCollision(CCollisionSphere *pSphere) { return NO_COLLISION; }
};

class CCollisionPlane : public CCollisionBase
{
public:
COLLISION_STATE CheckCollision(CCollisionBase *pCollisionBase) { return pCollisionBase->DoCheckCollision(this); }
COLLISION_STATE DoCheckCollision(CCollisionPlane *pPlane) { return NO_COLLISION; }
COLLISION_STATE DoCheckCollision(CCollisionSphere *pSphere) { return NO_COLLISION; }
};

class CPhysicsBase
{
protected:
CCollisionBase *m_pCollisionBounds;
public:
CPhysicsBase(CCollisionBase *pCollisionBounds)
{
m_pCollisionBounds = pCollisionBounds;
}

CCollisionBase *GetCollisionBounds() { return m_pCollisionBounds; }
};

class CRigidBody : public CPhysicsBase
{
public:
CRigidBody(CCollisionBase *pCollisionBounds) : CPhysicsBase(pCollisionBounds) { }
};

int main()
{
vector<CPhysicsBase *> vPhysicsNodes;

CCollisionBase *pCollisionSphere = new CCollisionSphere();
CCollisionBase *pCollisionPlane = new CCollisionPlane();

CRigidBody *pRigidBodySphere = new CRigidBody(pCollisionSphere);
CRigidBody *pRigidBodyPlane = new CRigidBody(pCollisionPlane);

vPhysicsNodes.push_back(pRigidBodySphere);
vPhysicsNodes.push_back(pRigidBodyPlane);

COLLISION_STATE collisionReponse = vPhysicsNodes[0]->GetCollisionBounds()->CheckCollision(vPhysicsNodes[1]->GetCollisionBounds());

switch(check)
{
case NO_COLLISION:
/* Compute Linear Velocity for vPhysicsNodes[0]*/

break;

case COLLISION:
/* Handles the collision contact */

break;

case RESTING_CONTACT:
/* Handle the resting contact */

break;
}

return(0);
}



Share on other sites
Does anyone have any opinions?

Share on other sites
Quote:
 Original post by simotixDoes anyone have any opinions?
Any particular reason why you aren't reusing an existing physics solution?

Share on other sites
Quote:
Original post by swiftcoder
Quote:
 Original post by simotixDoes anyone have any opinions?
Any particular reason why you aren't reusing an existing physics solution?

I was hoping to implement it my self for the sake of learning.

Share on other sites
I would use the base, and only store the base in the list. Then, call the apply friction function for every base object who is set to resting. Then, dont set any walls to resting :)

void Physics::Update(float dt){  foreach (PhysBase p in objects)  {    switch (p->ContactState())    {      case Resting:        p->UpdatingRestingContactStuffSuch            AsApplyFrictionIfThatsTheSortOfThingYoureInto();      break;    }  }}

Incase a wall does get set to a resting state, the update resting function will not be derived for a static object and essentially a no op.

You may not be interested in all this virtual call overhead. You could store the objects in different lists by type, and then use a templated update function to update each type of object.

Note: I would have probably chose to put this switch statement inside the object itself, and let the derived type determine which cases are relevant and how to handle them.

My physics loops usually look like this:
void Physics::Update(float dt){  foreach (PhysBase p in objects)    p->PreStep();  foreach (PhysBase p in objects)    p->CollisionAndResolution();  foreach (PhysBase p in objects)    p->Integration();  foreach (PhysBase p in objects)    p->PostStep();}

Or something along those lines. I would do the resting contact stuff in PreStep of the RigidBody type, but PreStep for a StaticBody type may be blank, and entirely different for a ChacterBody or VehicleBody type.

Share on other sites
Quote:
 Original post by bzroomI would use the base, and only store the base in the list. Then, call the apply friction function for every base object who is set to resting. Then, dont set any walls to resting :)void Physics::Update(float dt){ foreach (PhysBase p in objects) { switch (p->ContactState()) { case Resting: p->UpdatingRestingContactStuffSuch AsApplyFrictionIfThatsTheSortOfThingYoureInto(); break; } }}

I really like this idea, sure there is a bit of virtual overhead though. I may also have to deal with a bit of double dispatching also. Do you happen to remember where you learned this idea?

Share on other sites
No where in particular. Just lots of experimentation.

1. 1
2. 2
Rutin
21
3. 3
4. 4
frob
13
5. 5

• 12
• 9
• 9
• 17
• 21
• Forum Statistics

• Total Topics
632601
• Total Posts
3007344

×