| Author |
I Need A Physics
Engine Tutorial |
Webbird Dedicated
Joined: Mar 05,
2001 Posts:
31 |
Posted: 2001-08-13
02:19
Hi, freaks, I
need again some help. I am trying to implement the physics engine in
my code, but I don't have any sort of documentation on it. Neither
the html-doc nor the Genesis 3D - Books nor any tutorial on the
different websites does explain this topic (at least I found no
explanation). It would be a great help if some of you could tell
me at least, what I have to do to get the engine caring for the
physics. Maybe it would even help, if you could tell me, what the
PhysicsSystem-, PhysicsObject-, PhysicsJointclasses are for. What do
I have to create? Or does somebody know the adress of a
tutorial? I already found one (I think it was at WOG), but it only
explained how to set some entities in the editor for gtest.
Thanx in advance, Webbird
|
jasun220 Genesis God
Joined: Nov 19,
2000 Posts:
462 From:
Midland, TX, USA
|
Posted: 2001-08-13
06:58
Their are
millions of post about the physics system, and one how to use it.
Search the board for it. _________________ - A man learns from his own mistakes
- Jason Masoner -
Current Project: RC Challenge
-
E-Mail: jmasoner@mail.com
|
jwvanderbeck Administrator
Joined: Dec 18,
2000 Posts:
2213 From: Palm
Bay, FL, USA
|
Posted: 2001-08-13
10:20
Actually, there
is no good information on the Physics library. Very few people fully
understand it and those that do I guess haven't made any good
tutorials.
Lightning and I have fought with it for quite
some time. I'm actually slowly building a framework for testing it
and eventually as a tutorial on it, but that is moving along VERY
slowly as it is a very low priority. _________________ - John
Vanderbeck - Producer, Dark
Relic "Better leave the lights on"
- Novus Delta "Change is
coming..."
|
ZaG Godling
Joined: Mar 29,
2000 Posts:
312 From:
Ohio
|
Posted: 2001-08-13
10:55
Yeah, there are
some posts that describe how to set up the different parts of the
physics engine but they are pretty much overview from what I recall.
I think it is flexible enough that there are a lot of
different ways you can use it and people just plow their way through
to get what they need and move on. I'm not sure you'll find a guru
in our midst.
I created G3DCObjects that mimic the physics
entities that are in gtest but it took some time and patience to get
everything to work right.
ZaG
|
Webbird Dedicated
Joined: Mar 05,
2001 Posts:
31 |
Posted: 2001-08-13
11:00
Hi, again.
Does really nobody know even what these 3 classes stand for?
I would probably be able to understand it by reading the sourcecodes
of the engine and the gtest, but to do that I would need to know at
least, what these classes represent. Does every actor (I mean
Player, AIEnemy) need a PhysicsObject? Or a PhysicsSystem? And who
has to possess and care for the PhysicsJoints? I searched the
forum but I didn't find any interesting post. Only explanations on
how to create the classes in gtest...
Thanx,
Webbird
|
sirkorgan Moderator
Joined: May 11,
2001 Posts:
1133 From:
Ottawa, ON, Canada
|
Posted: 2001-08-13
11:21
They're not
classes, they're structs
A
PhysicsObject is affected by the physics calculations applied by the
PhysicsSystem. The PhysicsJoint connects PhysicsObjects. That
pendulum effect in GTest uses a combination of joints and objects.
Currently, I have no idea how to implement the physics system, but
I'm going to start playing with it soon. _________________ sirkorgan :: SMACKINZ! Wherever you go, &this
|
jwvanderbeck Administrator
Joined: Dec 18,
2000 Posts:
2213 From: Palm
Bay, FL, USA
|
Posted: 2001-08-13
11:22
Its hard to
understand unless you know physics to begin with
PhysicsSystem
is the overall system. You should really only need one of these per
game unless you gte creative.
PhysicsObject is the actual
object in the system. A player, a grenade, a spaceship...
PhysicsJoint from what I understand allows you to build
complex objects with joints in them, and each joint will be effected
seperatly while still being "connected" to the parent object. Like
sections of a rope. I think. I'm not 100% certain about the joints.
_________________ - John Vanderbeck - Producer, Dark
Relic "Better leave the lights on"
- Novus Delta "Change is
coming..."
|
Jeff Genesis God
Joined: Dec 06,
1998 Posts:
946 From:
Oxnard, CA, USA
|
Posted: 2001-08-13
15:14
Here is a fast
function reference for the gePhysicsSystem and gePhysicsObject. I
didn't spend a lot of time on this and I just did most of it from
memory. There are probably a lot of errors, so feel free to correct
them. This is a start now maybe others can fill in the rest.
gePhysicsSystem_Create()
Creates a physics
system, this is needed to hold all the physics objects and joint
together and allows them to interact in a simulated physics world.
gePhysicsSystem_Destroy()
Deletes the
physics system.
gePhysicsSystem_Iterate()
Updates the physics system, the time is a number between
0.0f and 1.0f and will control the speed of the physics system. Must
be called every time you want the physics simulation to be updated.
gePhysicsSystem_AddJoint()
Add a
PhysicsJoint to the physics system. If you want the joints to
interact in the physics simulation then you must add them to the
physics system.
gePhysicsSystem_AddObject()
Add a PhysicsObject to the physics system. If you want the
objects to interact in the physics simulation then you must add them
to the physics system.
PhysicsSystem_GetSourceConfigIndex()
I'm not
sure but I think this returns a unique number that can be used with
the objects and joints to identify that they belong to this specific
PhysicsSystem.
gePhysicsSystem_GetPhysobs()
Will return an array of all the PhysicsObjects that have
been added to the PhysicsSystem.
gePhysicsSystem_GetPhysjnts()
Will return an
array of all the PhysicsJoints that have been added to the
PhysicsSystem.
gePhysicsSystem_GetNumPhysobs()
Will return then number of PhysicsObjects currently added to
the PhysicsSystem.
gePhysicsSystem_GetNumPhysjnts()
Will return the number of PhysicsJoints currently added to
the PhysicsSystem.
gePhysicsSystem_GetSumOfConstraintDimensions()
Not sure what this does.
gePhysicsObject_Create()
Creates a
PhysicsObject. Use the Xform from this object to move your cameras,
actors, particles, ...
StartLocation, the position of the
object
mass, the mass of the object
AffectedByGravity, True is you want the object to be
affected by gravity, False if you don't
RespondsToForces,
True if you want the object to be affected by forces, False if you
don't
linearDamping, I think equations that deal with
movement can't go below this number. It's used to prevent floating
point errors.
angularDamping, I think equations that deal
with rotation can't go below this number. It's used to prevent
floating point errors.
Mins, Mimumum coordinates for
bounding box.
Maxs, Maxumum coordinates for bounding box
physicsScale, Scales all forces and values that affect this
object. use the GetXFormInEditorSpace() and
GetLocationInEditorSpace() to see the affects of the scaling.
gePhysicsObject_Destroy()
Destroys the
physics object
gePhysicsObject_ApplyGlobalFrameForce()
I'm
not sure but I think this applies a constant force to the object.
gePhysicsObject_ApplyGlobalFrameImpulse()
I'm not sure but I think this applies a constant impulse to
the object
gePhysicsObject_ComputeForces()
I
think this will compute and combine all the forces that are applied
to the object.
gePhysicsObject_Integrate()
I
think this is the update time for the object. I used it and the
lower the time is the slower the object moves in relationship to the
entire physics system. A number between 0.0f and 1.0f.
gePhysicsObject_GetMass()
Returns the mass
of the object
gePhysicsObject_SetMass()
Sets
the mass of the object
gePhysicsObject_GetOneOverMass()
Returns
1/mass
gePhysicsObject_GetXForm()
Returns
the Xform of the object
gePhysicsObject_SetXForm()
Sets the Xform of the object
gePhysicsObject_GetXFormInEditorSpace()
Returns a scaled Xform of the object, It's scale is
determined by the physicsScale value in the gePhysicsObject_Create()
function or the SetPhysicsScale() function.
gePhysicsObject_GetOriginalLocation()
Not
sure what it returns but if I had to guess, I would think you must
first set the location using the function below and it will return
those parameter. Useful for collision detection?
gePhysicsObject_SetOriginalLocation()
Refer
to the function above.
gePhysicsObject_GetLocation()
Returns the location of the object.
gePhysicsObject_GetLocationInEditorSpace()
Returns the scaled location of the object. It's scale is
determined by the physicsScale value in the gePhysicsObject_Create()
function or the SetPhysicsScale() function.
gePhysicsObject_GetLinearVelocity()
Returns
the linear velocity of the object.
gePhysicsObject_SetLinearVelocity()
Sets the
linear velocity of the object.
gePhysicsObject_GetAngularVelocity()
Return
the angular velocity of the object. Basically the speed at which the
object is rotating.
gePhysicsObject_SetAngularVelocity()
Sets
the angular velocity of the object. Basically the speed at which the
object is rotating.
gePhysicsObject_GetForce()
Returns the force on the object.
gePhysicsObject_SetForce()
Sets the force
applied to the object.
gePhysicsObject_GetTorque()
Return the torque applied to the object. Basically the force
that causes the object to spin.
gePhysicsObject_SetTorque()
Sets the torque
applied to the object. Basically the force that causes the object to
spin.
gePhysicsObject_GetAppliedForce()
Returns the force that is applied to an object that collides
with this object.
gePhysicsObject_SetAppliedForce()
Sets the force that is applied to an object that collides
with this object.
gePhysicsObject_GetAppliedTorque()
Returns the torque that is applied to an object that
collides with this object.
gePhysicsObject_SetAppliedTorque()
Sets the
torque that is applied to an object that collides with this object.
gePhysicsObject_ClearForce()
Removes the
force from an object.
gePhysicsObject_ClearTorque()
Removes the torque from an object.
gePhysicsObject_ClearAppliedForce()
Remove
the applied force from the object.
gePhysicsObject_ClearAppliedTorque()
Removes
the applied torque from the object.
gePhysicsObject_IncForce()
Adds the given
force to the current force.
gePhysicsObject_IncTorque()
Adds the given
torque to the current torque.
gePhysicsObject_IncAppliedForce()
Adds the
given force to the current applied force.
gePhysicsObject_IncAppliedTorque()
Adds the
given torque to the current applied torque.
gePhysicsObject_GetOrientation()
Returns the
orientation of the object in quaternion form.
gePhysicsObject_SetOrientation()
Sets the
orientation of the object in quaternion form.
gePhysicsObject_GetInertiaTensor()
Don't
know what a inertia tensor is.
gePhysicsObject_GetInertiaTensorInverse()
Don't know what a inertia tensor is.
gePhysicsObject_GetInertiaTensorInPhysicsSpace()
Don't know what a inertia tensor is.
gePhysicsObject_GetInertiaTensorInverseInPhysicsSpace()
Don't know what a inertia tensor is.
gePhysicsObject_IsAffectedByGravity()
Returns true if the object is affected by gravity, false if
it is not.
gePhysicsObject_SetIsAffectedByGravity()
True if the object should be affected by gravity, false if
it should not.
gePhysicsObject_RespondsToForces()
Returns true if the object is affected by forces, false if
it is not.
gePhysicsObject_SetRespondsToForces()
True if the object should be affected by forces, false if it
should not.
gePhysicsObject_GetLinearDamping()
Returns the linear damping
gePhysicsObject_SetLinearDamping()
Sets the
linear damping
gePhysicsObject_GetAngularDamping()
Returns the angular damping
gePhysicsObject_SetAngularDamping()
Sets the
angular damping
gePhysicsObject_SetActiveConfig()
Objects can have more than one config this will set which
one it is using.
gePhysicsObject_GetActiveConfig()
Objects can have more than one config this will return which
one it is using.
gePhysicsObject_SetPhysicsScale()
Scales all forces and values that affect this object. use
the GetXFormInEditorSpace() and GetLocationInEditorSpace() to see
the affects of the scaling.
gePhysicsObject_GetPhysicsScale()
Returns
the scale of the object.
[ This Message
was edited by: Jeff on 2001-08-13 15:35 ]
|
jwvanderbeck Administrator
Joined: Dec 18,
2000 Posts:
2213 From: Palm
Bay, FL, USA
|
Posted: 2001-08-13
15:19
Very nice of you
to take the time to type that up Jeff. _________________ -
John Vanderbeck - Producer, Dark
Relic "Better leave the lights on"
- Novus Delta "Change is
coming..."
|
Webbird Dedicated
Joined: Mar 05,
2001 Posts:
31 |
Posted: 2001-08-14
02:41
Hey, Jeff,
you helped me a lot. I'm now able to write my code.
Thanx, Sebi
|
Webbird Dedicated
Joined: Mar 05,
2001 Posts:
31 |
Posted: 2001-08-15
10:20
Ok, Guys, I
implemented it in my code. Two boxes fly towards each other and ...
One box flies through the other! What error did I do? They got their
velocity from gePhysicsObject_SetAppliedForce(). Both have the mass
100, gravity is off, respondstoforces is on, Mins and Maxs are each
+/- 50, every time to render the PhysicsSystem_Integrate() is called
(each time PhysicsObject_Integrate() and
PhysicsObject_ComputeForces() are called, too). Did I forget to set
any value? Or do I have to check for collisions? If yes, how can
I calculate the force, that is applied to the other object? Why did
the gePhysicsObject_Create() need my Mins and Maxs, when it doesn't
check for collision?
Any help would be great... Ciao,
Webbird
|
Defender Genesis God
Joined: Sep 13,
1999 Posts:
743 From: Pa.,
USA
|
Posted: 2001-08-15
11:40
Personally, I'd
advise you to code your own physics. While the physics displayed on
the "Physics Mania" level of GTest WAS quite groovy and impressive
and stuff, I just feel that it's always best to do it yourself,
unless the system is specifcally a physics library. If it's not a
physics library, then you'll probably (eventually) run into some
kind of implementation issue. Like, for example, a client-side
framerate dependency that alters the outcome of physics events.
In my shell, for example, movies and MP3s are played through
DirectX (using tommorris' code). Sound and image rendering are
handled with the engine. Since the engine loads the level maps, it
also handles gross collisions and physics (like the big, clumsy box
that surrounds people when they walk), but the more precise phyisics
(triangle-triangle collisions for realistic sword-fighting) are
handled through an imported library, ColDet (which is a simple
implementation of Tomas Moller's tri-tri algorithm, you can get it
from jwvanderbeck's site), because the engine doesn't handle this
well. And, although the engine does do the raw COLLISION code for
large, oriented-bounding-box (OBB) collisions, the RESULTS of those
collisions, like things sliding along walls, stepping up stairs,
pushing each other, setting off land mines, bouncing, etc. are
handled by my game module's own physics code (thus making physics
alterable for later mods without changing the shell). This way, the
engine handles only the things that are either NEEDED to be handled
by the engine (like world collisions and rendering) or that the
engine is well-suited for (like sound effects), and everything else
is "outsourced" at either the shell or game module level.
|
ZaG Godling
Joined: Mar 29,
2000 Posts:
312 From:
Ohio
|
Posted: 2001-08-15
14:05
You need to
detect collisions between any thing in your world (actor, model,
whatever) that is represented by a PhysicsObject and anything else.
When a collision occurs you can then use the
gePhysicsObject_ApplyGlobalFrameForce api to apply the force from
the impact to the object.
ZaG
|
Jeff Genesis God
Joined: Dec 06,
1998 Posts:
946 From:
Oxnard, CA, USA
|
Posted: 2001-08-15
15:29
Webbird, your
question made me do something that I never really thought about
doing, LOOK AT THE SOURCE CODE. I was pleasantly surprised to find
that this part of the source code has some comments. So needless to
say a lot of the assumptions that I made in the above post are
incorrect.
For example look at the
gePhysiscsSystem__Iterate() function:
Code:
|
GENESISAPI geBoolean GENESISCC gePhysicsSystem_Iterate(gePhysicsSystem* psPtr, float Time)
{
int i;
int numIntegrationSteps;
float minAssemblyRate, subStepSize;
float amountIntegrated = 0.f;
assert( psPtr != NULL );
////////////////////////////////////////////////////////////////////////////////////////////////////
// integrate numIntegrationSteps times during the frame
// this is done to ensure smoother motion and enforce constraint stability
minAssemblyRate = FLT_MAX;
if (psPtr->PhysicsJointCount == 0)
{
numIntegrationSteps = 1;
}
else
numIntegrationSteps = 5;
if (Time > 0.03f) Time = 0.03f;
subStepSize = Time / numIntegrationSteps;
for ( amountIntegrated = 0.f;
amountIntegrated < Time;
amountIntegrated += subStepSize)
{
for (i = 0; i < psPtr->PhysicsObjectCount; i++)
{
if (!gePhysicsObject_ComputeForces(psPtr->Objects[i], psPtr->sourceConfigIndex))
return GE_FALSE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
// enforce constraints
if (psPtr->sumOfConstraintDimensions > 0)
{
if (!gePhysicsSystem_EnforceConstraints(psPtr, subStepSize))
return GE_FALSE;
}
for (i = 0; i < psPtr->PhysicsObjectCount; i++)
{
if (!gePhysicsObject_Integrate(psPtr->Objects[i], subStepSize, psPtr->sourceConfigIndex))
return GE_FALSE;
}
psPtr->sourceConfigIndex = (psPtr->sourceConfigIndex == 0 ? 1 : 0);
psPtr->targetConfigIndex = (psPtr->targetConfigIndex == 0 ? 1 : 0);
// let physical object's control fns update themselves
}
for (i = 0; i < psPtr->PhysicsObjectCount; i++)
{
gePhysicsObject* pod;
pod = psPtr->Objects[i];
gePhysicsObject_ClearAppliedForce(pod, psPtr->sourceConfigIndex);
gePhysicsObject_ClearAppliedTorque(pod, psPtr->sourceConfigIndex);
gePhysicsObject_SetActiveConfig(psPtr->Objects[i], psPtr->sourceConfigIndex);
}
return GE_TRUE;
}
|
|
The
first thing that struck me about this code was the line that reads:
if (Time > 0.03f) Time = 0.03f;
This means that
the Time value for this function is from 0.0f to 0.03f. This leads
me to believe that the physics code should be separated from all the
other code and updated constantly, maybe even use a separate thread.
This is also probably the reason most people say the physics system
run slow, because their not updating it constantly to get real time
physics. This was probably programmed like this so the user can do
collision checking because the physics code doesn't handle it.
Also, the gePhysicsObject_Integrate() function is actually
the function that updates the PhysicsObject. The
gePhysicsSystem_Iterate() function just loops through all the
objects and calls gePhysicsObject_Integrate(). It also cleans up all
the odds and ends. Which indicates to me that I shouldn't be calling
gePhysicsObject_Integrate() and should just use the
gePhysicsSystem_Iterate() function and update it constantly.
I would highly suggest you look at the source code. It's
shed a whole new light on the physics code and it has shown me the
proper way to use it.
Note: Disregard my previous post
most of the assumption that I made are wrong.
|
jwvanderbeck Administrator
Joined: Dec 18,
2000 Posts:
2213 From: Palm
Bay, FL, USA
|
Posted: 2001-08-15
15:52
I'm actually
confused now. If the gePhysics system does NOT do collision, then I
am unsure how to use it.
If I have to detecte the collisions
myself, then it seems like I would have to do all the math myself to
be able to tell it the proper direction and angles of any collision.
No?
I mean, if I have 2 objects that collide, and the
physics lib doesn't do the collision, then how does it know the
correct angle and trajectory, and velocity of the 2 objects after
collision?
Am I missing something?
_________________ - John Vanderbeck - Producer, Dark
Relic "Better leave the lights on"
- Novus Delta "Change is
coming..."
|
ZaG Godling
Joined: Mar 29,
2000 Posts:
312 From:
Ohio
|
Posted: 2001-08-15
16:27
You haven't
missed anything John. You have detect the collision and tell the
physics system the angle of collision and force. The physics system
will handle incorporating that force along with any other existing
forces that are acting on the object and produce XForms for you each
frame that you can use to position the model or actor. The physics
system will also take into account the mass of the objects and such
and reduce the effect on the object each frame so that it is
affected by the collision in a realistic way.
ZaG
|
Jeff Genesis God
Joined: Dec 06,
1998 Posts:
946 From:
Oxnard, CA, USA
|
Posted: 2001-08-15
17:18
After the
collision is detected do something like this:
// Get force
and torque from object #1
gePhysicsObject_GetForce(po1,force1,0);
gePhysicsObject_GetTorque(po1,torque1,0);
// Get force
and torque from object #2
gePhysicsObject_GetForce(po2,force2,0);
gePhysicsObject_GetTorque(po2,torque2,0);
// Set applied
force and torque for object #1
gePhysicsObject_SetAppidedForce(po1,&force2,0);
gePhysicsObject_SetAppidedTorque(po1,&torque2,0);
//
Set applied force and torque for object #2
gePhysicsObject_SetAppidedForce(po2,force1,0);
gePhysicsObject_SetAppidedTorque(po2,torque1,0);
//
Compute forces for both objects
gePhysicsObject_ComputeForces(po1,0);
gePhysicsObject_ComputeForces(po2,0);
When the
gePhysicsObject_ComputeForces() function is called it will add the
object's applied force and torque to the object's force and torque
causing the object to change direction.
There's probably
more to it but you probably get the idea.
|
Webbird Dedicated
Joined: Mar 05,
2001 Posts:
31 |
Posted: 2001-08-16
02:35
Hi,
that
will help me pretty much. But I've some more questions. What Force
and Torque should I use when a collision with the world geometry
occured? By now the program crashes if a physicsobject wants to go
through the geometry. Is there any collision detection already
implemented? Or made I an error in my code? Before physics was
implemented, I could go through walls without causing the program to
crash.
Ciao, Webbird
|
Webbird Dedicated
Joined: Mar 05,
2001 Posts:
31 |
Posted: 2001-08-18
02:12
WAAAASSSSSUUUUPPPP???????
I repaired the code, it
doesn't crash now. And I made this kind of a collision handler, that
Jeff explain (you know, exchanging the forces and appliedforces).
Now I've a function that is called on collision. But it doesn't
work. I debugged it and found out, that the force/torque are 0/0/0.
The only property, that still holds a value is the
LinearVelocity/AngularVelocity.
|
BigBadCodar Genesis God
Joined: Nov 01,
2000 Posts:
418 From:
UK
|
Posted: 2001-08-18
02:57
*Shudders at
hearing wassup*
Is physics the most complicated G3D topic
then? Cause I think that that is the thing that most G3D people get
stuck on, and I havent learned it properly yet!
_________________ GameSmith Studios - Website Coming Soon!
Current Project:
Wouldn't you like to know... ;)
|
MiniMe2 Godling
Joined: Jan 15,
2001 Posts:
343 |
Posted: 2001-08-18
03:08
Physics is hard
but it isn't impossible ofcourse
(along as you are really
good at maths and physics. Unlike me who only got a 'E' in AS Level
Maths last week). _________________ David Mower, Founder,
http://www.mower3d.co.uk/,
| |