Help me to extend my physics engine

Asif_Saadat
Asif_Saadat used Ask the Experts™
on
i am very bad at maths and physics stuff , although i had managed to develop a 3d engine on my own in opengl now i am trying to add some physics capabilities into my engine for this i have written a small rigid body class with some basic functionality because i want to understand before i implement ,i have read many books , physics for game programmers/developer etc and more, but due to my bad math background i cannot pick what they say and the sourcecode they provide its really big and tightly coupled with their own engine and it is hard for me to understand and pick code from there and add into my engine, after you see my rigidbody class i have impletemented integrator and how to applyforces, it simulate correctly , tell me how to add some collision detection and collission response thing with my own engine not some external examples i have seen all those and dont get them ,i know collision is hard but for simplicity all i want is for sphere and cube and a plane but if anybody wanna help me more they are welcome and thanks in advanced
typedef struct RB
{
	float Position[3],LinearVelocity[3],AngularVelocity[3],Force[3],Torque[3],Mass,Orientation[4];
	float MT[16];
    void Init(void)
	{
		VECTOR3_SetZero(Position);
		VECTOR3_SetZero(LinearVelocity);
		VECTOR3_SetZero(AngularVelocity);
		VECTOR3_SetZero(Force);
		VECTOR3_SetZero(Torque);
		Quaternion_Identity(Orientation);
		Mass=1.0f;
	}
	void Integrate(float dt) 
	{
		
		VECTOR3_Set(LinearVelocity,LinearVelocity[0]+Force[0]/Mass*dt,LinearVelocity[1]+Force[1]/Mass*dt,LinearVelocity[2]+Force[2]/Mass*dt);
		VECTOR3_SetZero(Force);
		VECTOR3_Set(AngularVelocity,AngularVelocity[0]+Torque[0]/Mass*dt,AngularVelocity[1]+Torque[1]/Mass*dt,AngularVelocity[2]+Torque[2]/Mass*dt);
		VECTOR3_SetZero(Torque);
		VECTOR3_Set(Position,Position[0]+LinearVelocity[0]*dt,Position[1]+LinearVelocity[1]*dt,Position[2]+LinearVelocity[2]*dt);

		float Q[4];
		Quaternion_Set(Q,AngularVelocity[0]*dt,AngularVelocity[1]*dt,AngularVelocity[2]*dt,0.0f);
		Quaternion::Concate(Q,Orientation);		
		Quaternion_Set(Orientation,Orientation[0]+Q[0],Orientation[1]+Q[1],Orientation[2]+Q[2],Orientation[3]+Q[3]);
		Quaternion::Normalize(Orientation);

		Quaternion::ToMatrix(Orientation,MT);	  
    }

	
	void ApplyForce(float *forcePosition, float *directionMagnitude) 
	{
    
	  float lengthSquared =VECTOR3_SQLength(directionMagnitude);
	  if (lengthSquared < 1e-8f) return; 

	  VECTOR3_Add(Force,directionMagnitude);	  
	  float distance[3];
	  VECTOR3_Subtract(distance,forcePosition,Position);
	  VECTOR3_CrossProduct(forcePosition,directionMagnitude,distance);
	  VECTOR3_Add(Torque,forcePosition);
	
		
    }

	void ApplyForce(float f_x,float f_y,float f_z, float d_x, float d_y, float d_z) 
	{
		float fv[3],dv[3];
		VECTOR3_Set(fv,f_x,f_y,f_z);
		VECTOR3_Set(dv,d_x,d_y,d_z);
		ApplyForce(fv,dv);

		
	}
	void Draw(void)
	{
		glPushMatrix();
		glTranslatef(Position[0],Position[1],Position[2]);
		glMultMatrixf(MT);
		glutWireSphere(1,12,12);
		glPopMatrix();
	}


}RB;

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
ozo
Most Valuable Expert 2014
Top Expert 2015

Commented:
I don't see where your code says anything about spheres, cubes or planes, so I don't know how collision detection would apply to your code,
but spheres collide when the distance between their centres is less than the sum of their radii,
a sphere collides with a plane when the distance between the centre and the plane is less than its radius.
If cubes are oriented the same way, then in a coordinate system aligned with the cubes,
they collide if the difference between each coordinate of their centres is less than half the sum of the sizes of the cubes.
If the cubes can have different orientations than it gets a little more tricky to explain, and I'd prefer to see how cubes are represented in your code before trying to describe it

Author

Commented:
the code say nothing about them yet , but rigidbodies will be of types (sphere,cubes,planes) before i add them to my class i want to understand how would be their collisions and collision response , i need a solution which could be added to my existing code perhaps it should start from a simple sphere collision reponse , i know how to check 2 sphere collision , maybe i am more intrested in collision reponse rather collission detection but i need to know that too for more complex objects like cubes,clinder, code etc.

Commented:
Asif,

You need to decide, fundamentally, what sort of volumes will collide.

For each type of fundamental object, you'll need to support a collision between it and all the other fundamental objects.

For instance, if you support SPHERE and PLANE as your fundamental types, then you need:

DetectCollisionBetweenSphereAndPlane
DetectCollisionBetweenSphereAndSphere
DetectCollisionBetweenPlaneAndPlane
DetectCollisionBetweenPlaneAndSphere

The more of these fundamental types you support, the more you'll need to implement...

These routines don't determine the collision response, usually... they are simply culling routines, used to identify which objects in the scene need to have collisions applied.

Once you have a list of objects that need collision response, then you need to "apply" the response.

Over time, I've found it's easier to understand this math if you simplify it to two dimensions, and then collide objects using simple 2D Vector math.

Each object has a current location, and a "desired location".  You'll need to maintain these as separate positions.

These locations are then the endpoints of a line segment.  This line segment has some magnitude, and a heading.   If we have an orientation and a length, you can treat it as a vector,  current->desired.

The "result" of the collision (CollisionResponse) is then the product of the two vectors, just like a high school physics text would teach.  The order of the objects that you're updating matters, so be sure to not set both objects to the same result (if both are moving).  You'll need to apply each separately.

You can then update the object's current location to the result you obtained; do this for every object in your list, and then re-render the scene.

This is the absolute simplest version of collision detection and response, but it might help to get you started.

You can get much fancier; you can do the math with 3D vectors, you can model objects with different masses and velocities, you can add the effects of friction or whatever you can think of.

But all of those fancy things have their roots in this sort of implementation.

Hope this helps,
-john

Author

Commented:
thanks John for giving me a respone on this, you have explained it well , but i have read so many theory upon this , i got so many sourcecode/examples on this too for 2D and 3D ,but i cannot integrate them in to my engine or maybe i am that bad in maths and stuff. what i want, let say there is a method in my RB class

void Collision(RB *other)
{
   CollisionContacts *ct
   if(other->type==SPHERE && type==SPHERE)
      if(CheckForSphereSphereCollision())
      {
          ResolveContacts(ct,other);
     
      }


  if(ct)
  {
     DoAllCollisionResponseThings(); // like change velocity and torque , mean ApplyForce to rigidbodies
  }
}


now i need some basic sourcecode for the functions i just called if somebody can help me and fill it for me by looking at my existing RB class whatever math is involved it should be in C++ code, right now i ask for sphere to sphere and plane to sphere collision reponse and detection code.

thanks everybody

Commented:
Asif,

The key to this exercise is to start simple, and then build upon and extend the model with more and more features, so that you can learn how all the parts come together.

So, keep your 3d renderer the way it is...

But keep in mind rendering is not the same as collision detection and response; the geometries used are often quite different.

I would advocate the following:

1) get it working, simply, in 2D.. allow a circle to collide with a circle... and then implement the response.
2) Once that works, add support for a circle to collide with a 2D line segment
3) Make certain that all the math is using vectors, even if it's only 2D math

This math is much simpler, and generally can be well understood and debugged without added complexity.  Keep in mind, collision detection is different from collision response, and to do collision detection well, you need to integrate over the object's movement.. this is generally not the way this sort of math is taught, so make sure you keep the math as simple as possible in your initial attempts until you're certain that the collision detection is working.

Collision response in 2d is not significantly different in 3D, so it's not a waste of time to do it this way.

After you get the basics working, you can add things like mass, gravity, friction, acceleration.. Each of these is much easier to add piece by piece rather than a BIG BANG sort of implementation.

Once you have those basic operations (circle to circle, circle to line) working, then you can extend the model to 3 dimensions, and it's much easier.

I found a nice blog with example code and some very well written articles in PDFs here.  They really are quite good.

http://chrishecker.com/Rigid_Body_Dynamics#Physics_Articles

Hope this helps,
-john


Author

Commented:
sorry for the late response i was out of town for the weekend.

John i appreciate your concern with my question , but i have already told you i have gone through all the theory process and have read so many tutorials/books etc including the link you gave me . but i found it difficult to implement those things in to my solutions. for some reason i only want to do this with 3d and i dont have much time to spend on 2d and learn from that and then goto 3d , maybe my math is too bad to do this ,if you can extend my class to support basic collision detection is response i would be glad for that. i am looking some more experts opinion on that.

i hope you understand what i clearly want.

thanks

Commented:
I do understand what you clearly want, but I don't want to write your code for you.

I'm happy to guide, to answer questions, and to point you at resources.

But it seems like you want me to write it.  I'd prefer you learned the math.

-john

Author

Commented:
i dont want you write my code ,what i want whatever you trying to explain me do it with example code not just with physics concepts and all theory crap ,if you redirect me to theory and other resources then why i came to expert exchange as i have mentioned that i have collected tons of engines , sourcecode , books , articles blah. and google is best for it and for sourcecode

http://en.pudn.com

what i want to speak with the person who wrote examples/sourcecode for this, then i can ask them couples questions to clear my mind and understand what is going on and how can i do it.
I've written a complete collision detection and response engine. You tube Ososky Games physics engine.

Detection is very complex but easy compared to response. I seriously had to read, reread several chapters on the subject from several different sources before I began to appreciate to complexity of it. Not only is responding to to initial contact complex, but for really good engines there are additional layers of algorithms required to account to penetration resolution.

My advice to you would be this, if you have a limited understanding of math and not willing to invest the time to learn in, abandon trying to write your own physics engine, it is harder than you think. You can utilized off the shelf physics engines and be much more productive.

If you are committed to doing it, I'll share a little bit of my magic code. The code implements and algebraic equation that you will find associated with collision response physics. If you learn what the code is doing, you may have a shot, if not, again, i would lean on somebody else implementation of a physics engine. It's what most commercial games do anyway.


#include "PhysicsFunctions.h"
using namespace GameEngine2;


DWORD PhysicsFunctions::PHYSICS_RESOLVE_COLLISION_ALPHA(KineticBody* k1, KineticBody* k2, FLOAT closing_speed, D3DXVECTOR3 collision_pt, D3DXVECTOR3 collision_normal)
{
	const float e = k1->g_CoefficientOfResitution;

	collision_normal = collision_normal;

	D3DXVECTOR3 R1 = collision_pt - k1->g_Position;
	D3DXVECTOR3 R2 = collision_pt - k2->g_Position;

	D3DXVECTOR3 cross1;
	D3DXVECTOR3 cross2;

	D3DXVec3Cross(&cross1,&R1,&collision_normal);
	D3DXVec3Cross(&cross2,&R2,&collision_normal);

	D3DXVec3TransformCoord(&cross1,&cross1,&k1->g_InertiaTensorInverse);
	D3DXVec3TransformCoord(&cross1,&cross1,&k2->g_InertiaTensorInverse);

	D3DXVECTOR3 crossA;
	D3DXVECTOR3 crossB;
	D3DXVec3Cross(&crossA,&cross1,&R1);
	D3DXVec3Cross(&crossB,&cross1,&R2);

	D3DXVECTOR3 sum = crossA + crossB; //cross sum...
	FLOAT sum_dot_normal = D3DXVec3Dot(&sum,&collision_normal);

	FLOAT one_over_mass =  (1.0f/k1->g_Mass + 1.0f/k2->g_Mass);

	//this depends only on e1 value, might change later
	float numerator = -(e + 1.0f) * closing_speed;
	float denominator = one_over_mass + sum_dot_normal;

	float j = numerator/denominator;
	D3DXVECTOR3 j_vector = collision_normal*j;

	D3DXVECTOR3 angular_add_1;
	D3DXVECTOR3 angular_add_2;

	D3DXVec3Cross(&angular_add_1,&R1,&j_vector);
	D3DXVec3TransformCoord(&angular_add_1,&angular_add_1,&k1->g_InertiaTensorInverse);

	D3DXVec3Cross(&angular_add_2,&R2,&j_vector);
	D3DXVec3TransformCoord(&angular_add_2,&angular_add_2,&k2->g_InertiaTensorInverse);

	D3DXVECTOR3 linear_add_1 = j_vector / k1->g_Mass;
	D3DXVECTOR3 linear_add_2 = j_vector / k2->g_Mass;

	k1->g_LinearVelocity += linear_add_1;
	k1->g_AngularVelocity += angular_add_1;

	k2->g_LinearVelocity -= linear_add_2;
	k2->g_AngularVelocity += angular_add_2;


	return 0;
}

Open in new window

Commented:
Honestly, I don't know what else to do.

You said yourself that you've got tons of examples...

When I'm faced with a similar set of circumstances, I generally decompose the hard problem to a set of simpler problems, and I keep doing it until I get to a point where I understand what's happening.

I've tried to guide you on how to break it down into simpiler problems, that you can then extend and make more robust for your needs, but you actively resist it.

I simply can't do what you're asking for.. I can't put knowledge into your head directly.  You need to work for it, there is no other way.

I'm happy to answer any questions you have along the way, and to guide you.

But you have an existing concept and framework in mind, then you'll need to be the one putting it in.

Hope this helps,
-john

Author

Commented:
thanks 'MatthewOsosky' it helped to understand collision response thing, what i want to ask , for every kind of collision this method will do , like all we need is to calculate collision points and collision normal , weather objects are sphere or cubes or whatever.

'John'

my way of learning things is weird different , i learn from code then figure out the math for that ,most ppl learn math and then they implement in code. this is may because of my bad base of mathematics , but all i  can do is good for me , all you were trying to guide me and teach me was the right way , this is how someone need to be guided , but i was asking a different way for me.

 'MatthewOsosky' could also explaine to me how to do collision for only sphere for your collision response function so that the cycle is complete?


thanks every body
It does not matter about that shaped of the objects you are colliding, that only matters in collision detection. Colliding to sphere's is obviously a very special case, the mathmatics of which are considerable simpler than the algorithm I've got above. But what I do have above will also work correctly for spheres. Different shapes can have drastic difference on the implementation of the collision detection, but after that the shape of the object does not matter. What does matter (most) is the objects mass, the the intertia tenson. The the direction of the contact (collision normal) and the other object's mass, you know what direction and the force of the direction to apply on an object. When you apply that force to the object, the interia tensor allows you to figure out how that force will effect the objects rotation. The inertia tensor for a sphere is easy to figure out...

http://en.wikipedia.org/wiki/List_of_moment_of_inertia_tensors

The inertia tensors for more complex objects are harder to calculate and are usually broken down to simpler shapes. (i.e. a space ship might be simplefied as a block).

The CoefficientOfResitution variable is basically described as how much energy is lost in the collision. Think, friction or material deformation..

The kinectic body above hold various variables, th most important for the calcualtion in question are the objects position, liner and rotational velocities (as Vector3), and the objects inverse (easier calcuation) inertia tensor. You should easily be able to provide these for your spheres. Plug the numbers in and it should change to satisfactory for the sphere's.

Commented:
Good luck, Asif.

I wish you well.

-john

Author

Commented:
sorry for late response there were some problems in my computer.
thanks john
thank MatthewOsosky

could to give me a sample code for collision detection and moment_of_inertia_tensors  it would be make understand it clear.

thanks
Sorry the code for collision detection is specific to what you are doing. All collision detection code should/is optimized for the situation if is trying to detect. Spheres is absolutly the easier situation to detect. If the distance between two spehere is less than the sum of both radii, it's in collsion. I already told you where you can get the formulas for intertia tensor.

Again, I got to say it doesnt not sound like your ready to write your own engine. It's probably one of the hardest disciplines in progamming. You're going to need to read alot more materrial than what you'll be provided on expert expert change to get any undertanding of the subject. I would look to the Morgan Kaufmann series on physics engine developement. It's probably one of the better ones and there and serveral texts that you will need to cover.

This is not something that you can put together in a day, or two, or ten. It will take several weeks to get a good feel for the code.

Author

Commented:
i understand how to collide 2 sphere but how to calculate collision normal and collision points just show me an example rest of the things i will do , pls belive me , i learn this way its stupid but it is right for me. :)
I don't think you are understanding what I'm saying, or believing me. These things are more complicated than you are supposing.

Commented:
Asif,

Again, you want us to do it for you, but we can't.

You'll need to learn the math; there is no other way.

-john

Author

Commented:
john i dont want you to write my code , i just want that you show me how you write yours and i will write mine by looking at it understanding it , if you are afraid that i will steal your snippet you can hide happily , i want to learn math but it will take too long. once i get the picture i will totally change it into my way ,into my engine.

you think MatthewOsosky gave me some 'collision response' code and now i am using his code?
his code in directx and i am using opengl , i just get the idea how to do it , i will do it in opengl whatever good for my engine.

if i had to learn math , why do i need expert expert, there are tons of books and resource you know, expert gives fast/simple solution that the person ask the question can understand and solive his/her problem ,thats what i think expert exchange is doing.
What I'm trying to tell you is you have to learn the math. Sorry, you can't build a physics engine without understanding it.

The way to do it without learning the math is to use an other the self physics engine library.

Author

Commented:
although it was not complete solution wat i asked, but it solved some of my problems thanks

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial