![]()
gePhysicsSystem
Description: Rigid body, constraint based physics system interface
Source file: \genesis3d\OpenSource\Source\Physics\PhysicsSystem.h
Functions: Create, Destroy, Iterate, AddJoint, AddObject, GetSourceConfigIndex, GetPhysobs, GetPhysjnts, GetNumPhysobs, GetNumPhysjnts, GetSumOfConstraintDimensions
Types: gePhysicsSystem
Notes: view
Sample Code: view
Changes for Genesis3D v1.6: Only one minor changes to _Iterate (float changed to geFloat)
typedef struct gePhysicsSystem gePhysicsSystem;
NOTE: The contents of this structure have been intentionally left out of the interface, by the designers of this module. Think of this as a handle only.
![]()
Functions:
![]()
GENESISAPI gePhysicsSystem* GENESISCC gePhysicsSystem_Create(void);
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.
![]()
GENESISAPI geBoolean GENESISCC gePhysicsSystem_Destroy(gePhysicsSystem** ppSys);
Deletes the physics system.
![]()
GENESISAPI geBoolean GENESISCC gePhysicsSystem_Iterate(gePhysicsSystem* psPtr, float Time);
Updates the physics system, the time is a number between 0.0f and 1.0f [actually should be 0.03f] and will control the speed of the physics system. Must be called every time you want the physics simulation to be updated.
Additional Note: [This function contains a] 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.
(KT Note:) This is the primary function that should be called to "run" the physics system each update cycle.
Note: in Genesis3D v1.6 Time is of type geFloat
![]()
GENESISAPI geBoolean GENESISCC gePhysicsSystem_AddJoint(gePhysicsSystem* psPtr, gePhysicsJoint* Joint);
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.
(KT Note): Joint should be created with gePhysicsJoint_Create.
![]()
GENESISAPI geBoolean GENESISCC gePhysicsSystem_AddObject(gePhysicsSystem* psPtr, gePhysicsObject* Object);
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.
(KT Note): Object should be created with gePhysicsObject_Create
![]()
GENESISAPI int GENESISCC gePhysicsSystem_GetSourceConfigIndex(const gePhysicsSystem* pSys);
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.
(KT Note): ConfigIndex should be 0 or 1. I don't think this value is used for identity.
![]()
GENESISAPI gePhysicsObject** GENESISCC gePhysicsSystem_GetPhysobs(const gePhysicsSystem* pSys);
Will return an array of all the PhysicsObjects that have been added to the PhysicsSystem.
![]()
GENESISAPI gePhysicsJoint** GENESISCC gePhysicsSystem_GetPhysjnts(const gePhysicsSystem* pSys);
Will return an array of all the PhysicsJoints that have been added to the PhysicsSystem.
![]()
GENESISAPI int GENESISCC gePhysicsSystem_GetNumPhysobs(const gePhysicsSystem* pSys);
Will return then number of PhysicsObjects currently added to the PhysicsSystem.
![]()
GENESISAPI int GENESISCC gePhysicsSystem_GetNumPhysjnts(const gePhysicsSystem* pSys);
Will return the number of PhysicsJoints currently added to the PhysicsSystem.
![]()
GENESISAPI int GENESISCC gePhysicsSystem_GetSumOfConstraintDimensions(const gePhysicsSystem* pSys);
Not sure what this does.
(KT Note:) SumOfConstraintDimensions = 3 * number of Joints (World and Spherical) added to the system.
![]()
The comments of these API functions were made by Jeff on the Genesis3D forum. His original post is here. Kdtop has made additional notes (indicated by "KT Note")
To see definations of terms (such as "applied torque"), click here
![]()
This code was supplied Jeff on the Genesis3D forum. His original post is here. Kdtop has made some formating changes and added some comments.
Here is some sample code on how to implement a
very simple physics system. It only has one physics object, and
no forces are applied. The only thing that will move the object
is gravity.
I wrote this code fast, and cut a lot of it out from another
program. This is not a full program, it's only intended to give
you an idea of how to implement physics using G3D. Also, there
are probably typos and error.
If you need any further explanation, post you questions, and I'll
try to answer them.
gePhysicsSystem* PS;
gePhysicsObject* PO;
geXForm3d Xform;
geExtBox ExtBox;
geActor* Actor;
BOOL Running = TRUE;
DWORD Timer1 = timeGetTime();
DWORD Timer2 = Timer1;
geVec3d OldVec,NewVec;
GE_Collision Col;
// Load an actor
LoadActor(Actor,"Dema.act");
geXForm3d_SetIdentity(&Xform);
geActor_GetDynamicExtBox(Actor,&ExtBox);
// Create physics system
PS = gePhysicsSystem_Create();
// Create physics object
PO = gePhysicsObject_Create(&Xform.Translation,//the start location
1.0f, //object mass
GE_TRUE, //IsAffectedByGravity
GE_TRUE, //RespondsToForces
0.00005f, //LinearDamping value
0.00005f, //AngularDamping value
&ExtBox.Min, //Minimum coordinates for bounding box.
&ExtBox.Max, //Max coordinates for bounding box.
1.0f //Scale of 1 makes PhysicsSpace to be the same as WorldSpace
);
// Add physics object to physics system
gePhysicsSystem_AddObject(PS,PO);
// Set physics object XForm
gePhysicsObject_SetXForm(PO, &Xform, 0);
// physics and rendering loop
while(Running) {
// This is used to limit the number of times the physics are updated
// The time used will entierly depend on your program
// Basiclly this make the physics independent of rendering
if ((timeGetTime()-Timer1) > 2) {
// reset the timer
Timer1 = timeGetTime();
// Save the xform's position before updating
OldVec = Xform.Translation;
// Update the physics system, the largest number is 0.03f and
// it only makes a differance if physics joints are added to the physics system.
// This function will call gePhysicsObject_ComputeForces() and
// gePhysicsObject_Integrate() for every physics object in the physics system.
gePhysicsSystem_Iterate(PS,0.03f);
// Get the updated XForm
gePhysicsObject_GetXFormInEditorSpace(PO, &Xform, 0);
// save the xform's position after updating
NewVec = Xform.Translation;
// test if there was a collision
if (geWorld_Collision(World,
&ExtBox.Min,
&ExtBox.Max,
&OldVec,
&NewVec,
GE_CONTENTS_SOLID_CLIP,
GE_COLLIDE_ALL,
0xffffffff,
NULL,
NULL,
&Col
) ) {
// Collision found do something
Xform.Translation = Col.Impact;
gePhysicsObject_SetXForm(PO, &Xform, 0);
}
// Set actors xform
geActor_ClearPose(Actor, &Xform);
}
// Limit rendering to 30 FPS
// This is needed because physics are slow and when
// trying to render every frame the physics slows to a crawl
if ((timeGetTime()-Timer2)>34) {
Timer2=timeGetTime();
if (!geEngine_BeginFrame(Engine, Camera, GE_TRUE))
Running = 0;
if (!geEngine_RenderWorld(Engine, World, Camera, 0.0f))
Running = 0;
if (!geEngine_EndFrame(Engine))
Running = 0;
}
}
![]()