gePhysicsSystem

Description: Rigid body, constraint based physics system interface

Source file: …\genesis3d\OpenSource\Source\Physics\PhysicsSystem.h

Contents:

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)

Types:

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.

 Return to Contents

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.

Return to Contents

GENESISAPI geBoolean GENESISCC gePhysicsSystem_Destroy(gePhysicsSystem** ppSys);

Deletes the physics system.

Return to Contents

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

Return to Contents

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.

Return to Contents

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

Return to Contents

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.

Return to Contents

GENESISAPI gePhysicsObject** GENESISCC gePhysicsSystem_GetPhysobs(const gePhysicsSystem* pSys);

Will return an array of all the PhysicsObjects that have been added to the PhysicsSystem.

Return to Contents

GENESISAPI gePhysicsJoint** GENESISCC gePhysicsSystem_GetPhysjnts(const gePhysicsSystem* pSys);

Will return an array of all the PhysicsJoints that have been added to the PhysicsSystem.

Return to Contents

GENESISAPI int GENESISCC gePhysicsSystem_GetNumPhysobs(const gePhysicsSystem* pSys);

Will return then number of PhysicsObjects currently added to the PhysicsSystem.

Return to Contents

GENESISAPI int GENESISCC gePhysicsSystem_GetNumPhysjnts(const gePhysicsSystem* pSys);

Will return the number of PhysicsJoints currently added to the PhysicsSystem.

Return to Contents

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.

Return to Contents

Notes:

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

Return to Contents

Sample Code:

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;
	}
}

Return to Contents