Game Development Community

Game Physics engine

by Albert Steckenborn · in Torque Game Engine Advanced · 09/18/2006 (5:13 am) · 8 replies

Hi,
i'm trying to implement the Game Physics engine (http://www.game-physics-engine.info/) into tse.
The first Tests are nearly successful. But i have one problem and may be someone of you can help me out.

Here is my PhysicBox::processTick() method

// Parent process tick
   Parent::processTick(move);
	
   // if body valid
   if(SimpleBody) {
	    // get current container
		Container * currentContainer;
		if(isClientObject()) // Client object. 
		{
		   currentContainer = &gClientContainer;
		}
		else // Server object. 
		{
		   currentContainer =  &gServerContainer;
		}

		// variables for collision detection
		RayInfo rInfo; // Will return info on what the castRay found including object information.
		Point3F start, end;
		
		// number of mass elements
		long temp1Long = SimpleBody->NumMassElements;
		long j;

		// for all mass elements
		for(j = 0; j < temp1Long; j++)
		{
			if(SimpleBody->MassElement[j].CollisionsArePossible == TRUE)
			{
				// calculate distance from terrain
				start.x = end.x = SimpleBody->MassElement[j].WorldSpacePos.x; 
				start.y = end.y = SimpleBody->MassElement[j].WorldSpacePos.z; 
				start.z = 2000; //SimpleBody->MassElement[j].WorldSpacePos.y;
				end.z = -2000; 

				if(currentContainer->castRay(start, end,  StaticObjectType | 
											   InteriorObjectType | WaterObjectType | 
											   ShapeBaseObjectType | StaticShapeObjectType | 
											   ItemObjectType | TerrainObjectType |
											   StaticTSObjectType , &rInfo))
				{
				//	Con::printf("Position distanz %f",SimpleBody->MassElement[j].WorldSpacePos.y -rInfo.point.z);

					// set terrain distance
					SimpleBody->MassElement_TerrainDistance[j] = SimpleBody->MassElement[j].WorldSpacePos.y-rInfo.point.z; 
					SimpleBody->MassElement_TerrainFrictionConstant[j] = 1.0f;
				}
			}
		}

		// start simulation
	    float g_NormalFrameTime=0.001f*32;
		PhysicalSimulationParameter->Calculate_TimeSteps(g_NormalFrameTime , 4);
		SimpleBody->Simulate_BehaviourApprox(PhysicalSimulationParameter, TRUE, FALSE, 0.75f);

		// get render Matrix
		MatrixF mat=mObjToWorld;

		// get rotation of simulation Object
		D3DXMATRIXA16 tempMatrix = g_identityMatrix;
		tempMatrix._11 = 2.0f;
		tempMatrix._22 = 2.0f;
		tempMatrix._33 = 2.0f;
		tempMatrix *= SimpleBody->RotationMatrix;
		
		// get position of simulation object
		Point3F pos;
		pos.x = SimpleBody->CenterOfMass_WorldSpace.x;
		pos.y = SimpleBody->CenterOfMass_WorldSpace.z;
		pos.z = SimpleBody->CenterOfMass_WorldSpace.y;

		//// Set new Rotation of render matrix
	                MatrixF xRot,zRot;
	                xRot.set(EulerF(tempMatrix._11, 0, 0));
	                zRot.set(EulerF(0, 0, tempMatrix._22));
		mat.mul(zRot, xRot);

		// Set new position of render matrix
		mat.setColumn(3,pos);

		// set matrix to object
		Parent::setTransform(mat);
		setMaskBits(PositionMask);

Here are my question:

1) I use the castRay function to dectect the distance of my point between the terrain. Is there a faster way to detect it ?

2) I get the rotation matrix with this funtion tempMatrix *= SimpleBody->RotationMatrix;
And i set the new rotation with these code:

MatrixF xRot,zRot;
xRot.set(EulerF(tempMatrix._11, 0, 0));
zRot.set(EulerF(0, 0, tempMatrix._22));
mat.mul(zRot, xRot);

Is there a better and faster way to set the new rotation ?


Thanks forward

#1
09/18/2006 (4:42 pm)
1. castRay is pretty fast... is it showing up a performance hit for you?

2. Yes - you should be able to specify all of the rotation at once... but even that shouldn't be super slow.

Are you finding performance bottlenecks in those issues? If they work I'd say let well enough alone and move on to other issues. ;)
#2
09/19/2006 (7:41 am)
Are you going to release a resource on how to do this? =)
#3
09/19/2006 (10:38 am)
@Ben:

We are in contact with the developer of these physic engine. I've seen some demos of him and the physic engine is pretty fast. We've implemented it into TSE and the result is pretty slow. I believe its not related to TSE rather on our implementation and we need some help to make it better:

1) We've tested to copy the both matrixes directly together but it don't work. I know the MatrixF is collum majored but this is the only solution it works:

// get rotation of simulation Object
		D3DXMATRIXA16 tempMatrix = g_identityMatrix;
		tempMatrix._11 = 2.0f;
		tempMatrix._22 = 2.0f;
		tempMatrix._33 = 2.0f;
		tempMatrix *= SimpleBody->RotationMatrix;
		
		// Set new Rotation of render matrix
	    MatrixF xRot, yRot, zRot, zxTemp;
	    xRot.set(EulerF(tempMatrix._11, 0, 0));
	    yRot.set(EulerF(0, tempMatrix._22, 0));
	    zRot.set(EulerF(0, 0, tempMatrix._33));
		zxTemp.mul(zRot, xRot);
		mat.mul(zxTemp, yRot);
		
		// get position of simulation object
		Point3F pos;
		pos.x = SimpleBody->CenterOfMass_WorldSpace.x;
		pos.y = SimpleBody->CenterOfMass_WorldSpace.z;
		pos.z = SimpleBody->CenterOfMass_WorldSpace.y;

		// Set new position of render matrix
		mat.setColumn(3,pos);
	               // set matrix to object
		Parent::setTransform(mat);

Can you tell me the way to copy direct the

D3DXMATRIXA16 tempMatrix; to the MatrixF mat; Matrix ?

2)
We need the fastest way to detect the distance between two objects (object1 and terrain or object1 to object2). Is CastRay the fastes way ? Or can you tell me a faste way.

Thanks forward for helping.

@Jonathon
I don't know yet. First we want to have it fully working. But if you have questions do not hesitate to contact me.

Greetings
#4
09/19/2006 (10:53 am)
Have you run it under the profiler to see where the time is going? The slowdown might be due to any number of things - a slow matrix copy is probably not the biggest issue you have facing you. ;)

If nothing else, it could be because the physics demos were running the most basic rendering & no other features - by the time you get all the other stuff in there for a full game, it might not be all that fast. Or it could be that you're calculating physics too often - they should only be calculated on ticks, not in between, so if you do pysics calcs more than 32 times a sec, something is wrong. :)

Anyway - my biggest piece of advice is to profile, profile, profile and find out _for sure_ where your time is going, before you start optimizing.
#5
09/30/2006 (7:20 am)
Hi,
i've fixed the problem with the physics engine. Now the boxes are falling correct.
Only one problem is left and i really need to have an answer.

I really need to know how to convert a D3DXMATRIXA16 transformation matrix (scaling, rotation and translation) to a MatrixF.

I'm using the following code for an airplane, but the plane matrix and the physic matrix are not the same, so my plane ist flying in the air like a helicopter by accelerating.

MatrixF mat=mObjToWorld;

			D3DXMATRIXA16 tempMatrix = g_identityMatrix;
			tempMatrix._11 = 1.0f;
			tempMatrix._22 = 1.0f;
			tempMatrix._33 = 1.0f;

			tempMatrix *= AirplaneBody->RotationMatrix;

			tempMatrix._41 = AirplaneBody->CenterOfMass_WorldSpace.x;
			tempMatrix._42 = AirplaneBody->CenterOfMass_WorldSpace.z;
			tempMatrix._43 = AirplaneBody->CenterOfMass_WorldSpace.y;

			mat.m[0]=tempMatrix._11;
			mat.m[4]=tempMatrix._12;
			mat.m[8]=tempMatrix._13;
			mat.m[12]=tempMatrix._14;
			mat.m[1]=tempMatrix._21;
			mat.m[5]=tempMatrix._22;
			mat.m[9]=tempMatrix._23;
			mat.m[13]=tempMatrix._24;
			mat.m[2]=tempMatrix._31;
			mat.m[6]=tempMatrix._32;
			mat.m[10]=tempMatrix._33;
			mat.m[14]=tempMatrix._34;
			mat.m[3]=tempMatrix._41;
			mat.m[7]=tempMatrix._42;
			mat.m[11]=tempMatrix._43;
			mat.m[15]=tempMatrix._44;

			Parent::setTransform(mat);

Thx for helping
#7
10/02/2006 (8:13 pm)
Sounds like you need to swap your matrix around a bit. Have you tried making sure that the two engines use the same X/Y/Z conventions? (Torque has Z+ up, Y+ right, X+ into the scene, IIRC - a bit different from many other engines). Reordering the matrix will fix this, but there'll be a bit of trial and error. Don't forget your linear algebra. :)
#8
10/07/2006 (9:09 am)
Puuuh. now its working very well :-D

i use the following code
MatrixF mat; //=mObjToWorld;

			D3DXMATRIXA16 tempMatrix = g_identityMatrix;
			tempMatrix._11 = 1.0f;
			tempMatrix._22 = 1.0f;
			tempMatrix._33 = 1.0f;

			tempMatrix *= AirplaneBody->RotationMatrix;

			mat.m[0]=tempMatrix._11;
			mat.m[4]=tempMatrix._13;
			mat.m[8]=tempMatrix._12;
			mat.m[12]=tempMatrix._14;
			
			mat.m[1]=tempMatrix._31;
			mat.m[5]=tempMatrix._33;
			mat.m[9]=tempMatrix._32;
			mat.m[13]=tempMatrix._34;

			mat.m[2]=tempMatrix._21;
			mat.m[6]=tempMatrix._23;
			mat.m[10]=tempMatrix._22;
			mat.m[14]=tempMatrix._24;

			mat.m[3]=AirplaneBody->CenterOfMass_WorldSpace.x;
			mat.m[7]=AirplaneBody->CenterOfMass_WorldSpace.z;
			mat.m[11]=AirplaneBody->CenterOfMass_WorldSpace.y;
			mat.m[15]=tempMatrix._44;
			  

			Parent::setTransform(mat);

Now i only have to found out how to make it networkable. I think i have to read some dokuments before i will start with it.

@Ben. Thx for helping out

Greetings