Game Development Community

dev|Pro Game Development Curriculum

PhysX in TGE Version 0.3 (Work-In-Progress)

by Shannon "ScarWars" Scarvaci · 07/03/2006 (11:35 am) · 269 comments

Outline
1. License
2. Get SDK from Ageia
3. Implementation
4. Scripts
5. Know Issues
6. Need your supports!

License:
The license of PhysX is following:
Free:
  * Commercial & non-commercial use on PC
       Must keep registration information currect
       Must agree to the EULA at the time of download (pops up, but is copied below)
       Available for Windows & Linux (soon)
       No PhysX HW support requirement
  * PS3 platform (through Sony pre-purchase)
  * All platforms through some of our middleware partnerships, such as UE3, Gamebryo 2.2,
     and others
k per platform:
  * Xbox 360
  * Fee may be waived at our discretion for multi-platform developers providing PC HW support
  * Fee may be waived at our discretion for some Tools & Middleware providers

Get SDK from Ageiq
You can obtain the SDK from www.ageia.com website, my currently version for this physics is 2.7.0.

If you are using Visual Studio then you need to add "include" and "library" in the project configuration.
(If you using linux or mac, then i don't know where to setup because I dont have linux or mac with me)
Directory for include files:
C:\Program Files\AGEIA PhysX SDK\v2.6.4\SDKs\Physics\include
C:\Program Files\AGEIA PhysX SDK\v2.6.4\SDKs\Foundation\include
C:\Program Files\AGEIA PhysX SDK\v2.6.4\SDKs\PhysXLoader\include
C:\Program Files\AGEIA PhysX SDK\v2.6.4\SDKs\Cooking\include
Directory for library files:
C:\Program Files\AGEIA PhysX SDK\v2.6.4\SDKs\lib\win32
Note: These files' path's are relative to my hard drive, your files may be in different directory depending on how you installed the PhysX SDK.

Please install AGEIA PhysX Runtime in your PC (prefered lastest version)
Also put two dll file (PhysXLoader.dll and NxCooking.dll from AGEIA PhysX SDK\v2.7.0\SDKs\Bin\win32) in the example folder.


Implementation
Copy the 17 files from "PhysX" folder into engine/PhysX and modify some TGE's source code files.

Player
in game/player.h in bold
//----------------------------------------------------------------------------

[b]struct sNxActor;[/b]
class Player: public ShapeBase
{
  typedef ShapeBase Parent;
  [b]sNxActor *mActor;[/b]
protected:
  /// Bit masks for different types of events
  enum MaskBits {

game/player.cc at the top in bold
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
[b]#include "physX/PhysX.h"
#include "physX/PhysXWorld.h"[/b]
#include "game/player.h"

game/player.cc in Player::Player() function
mMountPending = 0;

   [b]mActor = NULL;[/b]
}

game/player.cc in Player::onAdd() function
gCamFXMgr.clear();
        }

	 [b]PhysXWorld *PxWorld = PhysXWorld::getWorld(isServerObject());
	 if (PxWorld) {
		 mActor = PxWorld->AddShapeBase(this);
	 }[/b]

   return true;

game/player.cc in Player::setPosition(...)
else {
      mat.set(EulerF(0, 0, rot.z));
      mat.setColumn(3,pos);
   }
   [b]if (mActor) {
      QuatF q(mat);
      Point3F pos;
      mat.getColumn(3,&pos);
      NxQuat quat;
      quat.setXYZW(q.x,q.y,q.z,q.w);
      mActor->actor->setGlobalOrientationQuat(quat);
      mActor->actor->setGlobalPosition(NxVec3(pos.x,pos.y,pos.z));
   }[/b]
   Parent::setTransform(mat);
   mRot = rot;
}

Terrain
in terrain/terrData.cc
at the top of the file
#include "terrain/terrRender.h"
#include "terrain/blender.h"

[b]#include "physX/PhysXWorld.h"[/b]

extern bool gDGLRender;

terrain/terrData.cc in TerrainBlock::onAdd function near the end
if(!unpackEmptySquares())
                 return(false);

	[b]PhysXWorld *PxWorld = PhysXWorld::getWorld(isServerObject());
	if (PxWorld) {
		PxWorld->SetupTerrainCollision(); // old style
	}[/b]

   return true;
}

Interior
in interior/interior.h
class Interior
{
   ...
   friend class EditInteriorResource;
   [b]friend class PhysXInterior;[/b]

in interior/interiorInstance.h
class InteriorInstance : public SceneObject
{
   ...
   friend class FloorPlan;
   [b]friend class PhysXInterior;
   friend class PhysXWorld;[/b]

in interior/interiorInstance.cc
#include "platform/profiler.h"
[b]#include "physX/PhysXWorld.h"[/b]

...

bool InteriorInstance::onAdd()
{
   ...
   
   addToScene();

   [b]PhysXWorld *PxWorld = PhysXWorld::getWorld(isServerObject());
   if (PxWorld) {
      PxWorld->SetupInterior(*this);
   }[/b]
   return true;
}

TSStatic
in ts/tsShapeInstance.h
class TSShapeInstance
{
   ...
   friend class TSPartInstance;
   [b]friend class PhysXTSStatic;
   friend class PhysXActor;[/b]

in game/tsStatic.h
class TSStatic : public SceneObject
{
   ...
   friend class TSStaticConvex; 
   [b]friend class PhysXTSStatic;[/b]

in game/tsStatic.cc
#include "sim/netConnection.h"
[b]#include "physX/PhysXWorld.h"[/b]

...

bool TSStatic::onAdd()
{
   ...
   
   addToScene();

   [b]PhysXWorld *PxWorld = PhysXWorld::getWorld(isServerObject());
   if (PxWorld) {
      PxWorld->SetupTSStatic(*this);
   }[/b]
   return true;
}

ShapeBase
in game\shapeBase.h
class ShapeBase : public GameBase
{
   typedef GameBase Parent;
   friend class ShapeBaseConvex;
   friend class ShapeBaseImageData;
   [b]friend class PhysXWorld;[/b]

Material in GameBase
in game\gameBase.h
[b]struct PhysXMaterialData;[/b]
struct GameBaseData : public SimDataBlock {
   ...
   void unpackData(BitStream* stream);
   [b]// PhysX
   PhysXMaterialData* mMaterialBlock;[/b]
};
...
class GameBase : public SceneObject
{
   ...
   enum GameBaseMasks {
      InitialUpdateMask =     Parent::NextFreeMask,
      DataBlockMask =         InitialUpdateMask << 1,
      ExtendedInfoMask =      DataBlockMask << 1,
      ControlMask =           ExtendedInfoMask << 1,
      [b]//NextFreeMask =        ControlMask << 1
      // PhysX
      MaterialDataBlockMask = ControlMask << 1,
      NextFreeMask =          MaterialDataBlockMask << 1[/b]
   };
   ...

   [b]// PhysX
   bool setMaterialDataBlock(PhysXMaterialData* dptr);
   bool onNewMaterialDataBlock(PhysXMaterialData* dptr);[/b]

};
...
in game\gameBase.cc
[b]#include "physX/PhysX.h"
#include "physX/PhysXActor.h"[/b]
#include "platform/platform.h"
...
GameBaseData::GameBaseData()
{
   ...
   [b]mMaterialBlock = 0;[/b]
}
...
[b]IMPLEMENT_CONSOLETYPE(PhysXMaterialData)
IMPLEMENT_GETDATATYPE(PhysXMaterialData)
IMPLEMENT_SETDATATYPE(PhysXMaterialData)[/b]

void GameBaseData::initPersistFields()
{
   Parent::initPersistFields();
   ...
   [b]addField("materialBlock", TypePhysXMaterialDataPtr, Offset(mMaterialBlock, GameBaseData));[/b]
}
...
bool GameBase::onNewDataBlock(GameBaseData* dptr)
{
   ...
   [b]onNewMaterialDataBlock(mDataBlock->mMaterialBlock);[/b]

   setMaskBits(DataBlockMask);
   return true;
}
...
bool GameBase::setDataBlock(GameBaseData* dptr)
{
   ...
}

[b]bool GameBase::setMaterialDataBlock(PhysXMaterialData* dptr)
{
   if (isGhost() || isProperlyAdded()) {
      if (mDataBlock->mMaterialBlock != dptr)
         return onNewMaterialDataBlock(dptr);
   }
   else
      mDataBlock->mMaterialBlock = dptr;
   return true;
}

bool GameBase::onNewMaterialDataBlock(PhysXMaterialData* dptr)
{
   mDataBlock->mMaterialBlock = dptr;

   if (!mDataBlock->mMaterialBlock)
      return false;

   setMaskBits(MaterialDataBlockMask);
   return true;
}[/b]
...
U32 GameBase::packUpdate(NetConnection *, U32 mask, BitStream *stream)
{
   ...
   [b]if (stream->writeFlag((mask & MaterialDataBlockMask) && mDataBlock->mMaterialBlock != NULL)) {
      stream->writeRangedU32(mDataBlock->mMaterialBlock->getId(),
                             DataBlockObjectIdFirst,
                             DataBlockObjectIdLast);
   }[/b]

   // cafTODO: ControlMask
   return 0;
}

void GameBase::unpackUpdate(NetConnection *con, BitStream *stream)
{
   ...
   [b]if (stream->readFlag()) {
      PhysXMaterialData* dptrMD = 0;
      SimObjectId id = stream->readRangedU32(DataBlockObjectIdFirst, DataBlockObjectIdLast);

      if (!Sim::findObject(id,dptrMD) || !setMaterialDataBlock(dptrMD))
         con->setLastError("Invalid packet GameBase::unpackUpdate()");
   }[/b]
}

Scripts
Copy three script files (PhysX.cs, physXActorBox.cs and physXActorSphere.cs) in starter.fps/server/scripts and add three lines of code in starter.fps/server/scripts/games.cs

// PhysX
	 exec("./physX.cs");
	 exec("./physXActorBox.cs");
	 exec("./physXActorSphere.cs");
	 exec("./physXJoints.cs");

add one line of code in common/client/mission.cs
function clientCmdMissionStart(%seq)
{
   // The client recieves a mission start right before
   // being dropped into the game.
	[b]startPhysX();[/b]
}

and in every mission file need to add PhysXWorld as show in bold:
new SimGroup(MissionGroup) {

	 [b]new PhysXWorld() {
		errorReport = false; // set to true if you want error report from PhysX
	 };[/b]
	
	 new ScriptObject(MissionInfo) {
	 ...

If you want to testing around by droping the object in the free-look camera, then use default.bind.cs script
function addCrate(%val)
{
	if (%val)
		commandToServer('pxcrate');
}
function addBox(%val)
{
	if (%val)
		commandToServer('pxbox');
}
function addRock(%val)
{
	if (%val)
		commandToServer('pxsphere');
}

moveMap.bind( keyboard, "alt r", addCrate);
moveMap.bind( keyboard, "alt t", addBox);
moveMap.bind( keyboard, "alt y", addRock);

Know Issues
Terrain is the problem here because PhysX can accept 256x256 collision mesh in their engine which is mean squareSize equal to one! So the TGE's default squareSize is 8 and you see object will miss the collision in some area of the terrain. Possible solution is to create chunks, for example if you use squareSize of 8 then use 64 chunks of 256x256 collision mesh.

Loading the mesh of 256x256 collision will very slow but there possible solution is to write the mesh to file create by PhysX engine and read the file from PhysX will be lots faster, similar to lighting system which is used in TGE.

I've tried number of way to use Terrain collision in PhysX such as split in four section, NxHeightfield which make it very slow but I haven't tried this in PPU yet. So I have to stick with 256x256 collision mesh for a while.

Player/ShapeBase collision with PhysX's object is not complete.

Networking:
Loading objects from the begin in the remote client sometime not showing but if object appear during the gameplay will work ok. That something i need to be working on. (There may be some problem because of improved speed, but didn't test it yet)

Improved PhysX Speed
Big thank to decryptoid for helping us in PhysX, esp. for speed improvement.

Need your supports!
Now you can play with PhysX in your TGE game! If you find any improvement for this Physics in coding or script or anything please post here and I'll happy to update in here.
Also please use TDNfor any info to advise for our community

In the future:
- Run in PPU.
- Player collision.
- ShapeBase, (TSStatic and Interior - Completed) collision.
- Use advance physics such as joints, clothes and fluid. Done two type of joints

Enjoy your Physics!

Check out the video.
First Video
Second Video
Joints Video (4MB, prefer download before watch)

This is my first resource, please be kind to me :)

Due to file limit please download from here Updated 13th Apirl 2006

Here TGEA PhysX Resource here
#41
05/05/2006 (5:38 pm)
Shannon: It is from the SDK.

Well I got it all in and here's the message I get when I try to create a physxworld:

"Unable to find any athena hardware devices!"

I have the software drivers installed, but is there anything else I need to do to get this to run?
#42
05/06/2006 (12:15 am)
@John, did you download the update version? (update version is 20th Apirl)
if you have the update version then in the mission file set this errorReport = false to avoid message box.

@EntrOpy - this message ("Unable to find any athena hardware devices!") is normal because you dont have PPU card, in the release version you will not notice this message. You got it working with PhysX?
#43
05/06/2006 (6:04 am)
Nope. I get that message, then it just crashes. I added this to stock TGE 1.4 by the way.

#0 0x064d1a00 in ?? ()
No symbol table info available. <------ Nice huh?
#1 0x0045577a in SimObject::registerObject() (this=0x5491580)
at console/simManager.cc:426
ret = false

It is crashing at this line:
gScene = gPhysicsSDK->createScene(sceneDesc);

I am using GCC. Apparently it won't compile under gcc because there is a bit of MS assembly language in there. I guess I will have to wait until they release the linux version (before the end of the year they say). I refuse to sacrifice portability, and my servers are designed to run under linux.
#44
05/07/2006 (3:44 pm)
Keep this in mind when working on the networking(Ageia Support)

Avoid the use of setPosition whenever possible:

This hurts the performance of the engine, which is tuned for the case of temporal/spatial coherance. setPosition causes the object to be removed from the Broadphase and re-inserted as if it were a new object, which is much slower than the other means of update listed below. Only use setPosition if the actor is actually intended to "teleport" elsewhere, especially over a long distance.

It causes artifacts: If the actor is teleported into another actor, resolution of the penetration will cause one or both of the actors to fly off, and performance will be negatively affected due to the cost of penetration resolution.
Two alternatives to setPosition are:

Calculate impulses to apply to the actor to push it toward the desired position. This will allow the actor to affect other, client-side-only physics actors in a believable manner. If there are large or immobile actors in the way, however, you may have to switch to #2 to resolve.

Switch the actor's state to keyframed and execute a moveTo operation on it. This is friendly to the Broadphase and still allows interactions with other dynamic actors, but allows the actor to pass through other static or keyframed actors that would otherwise have block it.
Note that MMO developers we have talked to have reported that updating an object's angular velocity is more effective in maintaining synchronization than setting its linear velocity, rotation or position. So to reduce bandwidth, you should prioritize your updates in that order.
#45
05/10/2006 (5:58 pm)
Nevermind. Somehow I thought it was in the SDK. I didnt see the zip.
#46
05/10/2006 (6:16 pm)
@EntrOpy - linux version of PhysX will release soon, hopefully work well in TGE's linux version.

@Robert - Thanks for clear explain over PhysX, I'll try to resolve this in my spare time.

@Matt - all files in "physX" folder from zip into engine/physX, not from SDK.
#47
05/14/2006 (11:37 am)
Yay my PhysX card's being delivered tomorrow!!!!!!!!!
#48
05/18/2006 (6:13 am)
I got a PhysX card!
#49
05/18/2006 (7:56 am)
Hooty..Hoot...I got mine yesterday. Building up a new dev computer.

Asus A8N-SLI NVIDIA Socket 939 ATX Motherboard
AMD Athlon64 4400 X2
2 Gig Ram
120 Gig Serial ATA Drive
NVIDIA GeForce 7600 GT/SLI
Creative X-FI Audio
Creative GigaWorks G550W Speaker Systems
Dual 19 inch ViewSonic LCD Monitors
and of course the Ageia Physx card. Also signed up and got the SDK from Ageia.

Going to take a weeks vacation the end of the month so hopefully I can get allot done....after I get all my (Honey Do's done, of course......:))

Thanks Shannon for this GREAT resource!
#50
05/18/2006 (8:18 am)
thats almost exactly what I have but I've got:
Asus A8V Socket 939 ATX Motherboard
AMD Athlon64 4400 X2
1 Gig Ram
300 Gig Serial ATA Drive
NVIDIA GeForce 7800gs
Creative X-FI Audio
19 inch Lg LCD Monitors
and of course the Ageia Physx card. Also signed up and got the SDK from Ageia.
#51
05/18/2006 (11:04 am)
Way cool......Should definitely have enough muscle there. I got it all put together last night and going to try and get the operating system and all the tools installed tonight. One of my son's have a softball game tonight so I will not be able to get to it utill then though.
#52
05/19/2006 (2:55 pm)
Hey, I love your recource so far, are you going to go all the way and add support for fluids, cloth simulation & ragdolls aswell?
#53
05/19/2006 (6:24 pm)
@SphyxGames, Jackie - you are damn lucky, I'm in aussie and it will take a little longer :(

@John - that the plan, there still long way to do all those things because I doing this during my spare time.
#54
05/20/2006 (8:57 am)
@Shannon, I am new to Torque and would like to work toward implementing physics. Are there some preliminary resources that you would point to for students as stepping stones to successfully using PhysX?

Thanks,
n8
#55
05/22/2006 (12:01 am)
@n8man - Depend what compiler are you using? what platform? could you email me through my profile so I can help ya
#56
05/26/2006 (8:07 am)
I am recieve these I have no idea what cause them.

C:\PROGRAM FILES\AGEIA TECHNOLOGIES\AGEIA PHYSX SDK\V2.3.3\SDKS\PHYSICS\INCLUDE\NxIntersectionRayPlane.h(34) : error C2562: 'NxSegmentPlaneIntersect' : 'void' function returning a value
C:\PROGRAM FILES\AGEIA TECHNOLOGIES\AGEIA PHYSX SDK\V2.3.3\SDKS\PHYSICS\INCLUDE\NxIntersectionRayPlane.h(31) : see declaration of 'NxSegmentPlaneIntersect'
PhysXJoint.cpp
C:\PROGRAM FILES\AGEIA TECHNOLOGIES\AGEIA PHYSX SDK\V2.3.3\SDKS\PHYSICS\INCLUDE\NxIntersectionRayPlane.h(34) : error C2562: 'NxSegmentPlaneIntersect' : 'void' function returning a value
C:\PROGRAM FILES\AGEIA TECHNOLOGIES\AGEIA PHYSX SDK\V2.3.3\SDKS\PHYSICS\INCLUDE\NxIntersectionRayPlane.h(31) : see declaration of 'NxSegmentPlaneIntersect'
PhysXStream.cpp
C:\PROGRAM FILES\AGEIA TECHNOLOGIES\AGEIA PHYSX SDK\V2.3.3\SDKS\PHYSICS\INCLUDE\NxIntersectionRayPlane.h(34) : error C2562: 'NxSegmentPlaneIntersect' : 'void' function returning a value
C:\PROGRAM FILES\AGEIA TECHNOLOGIES\AGEIA PHYSX SDK\V2.3.3\SDKS\PHYSICS\INCLUDE\NxIntersectionRayPlane.h(31) : see declaration of 'NxSegmentPlaneIntersect'
PhysXTerrain.cpp
C:\PROGRAM FILES\AGEIA TECHNOLOGIES\AGEIA PHYSX SDK\V2.3.3\SDKS\PHYSICS\INCLUDE\NxIntersectionRayPlane.h(34) : error C2562: 'NxSegmentPlaneIntersect' : 'void' function returning a value
C:\PROGRAM FILES\AGEIA TECHNOLOGIES\AGEIA PHYSX SDK\V2.3.3\SDKS\PHYSICS\INCLUDE\NxIntersectionRayPlane.h(31) : see declaration of 'NxSegmentPlaneIntersect'
PhysXTerrData.cpp
C:\PROGRAM FILES\AGEIA TECHNOLOGIES\AGEIA PHYSX SDK\V2.3.3\SDKS\PHYSICS\INCLUDE\NxIntersectionRayPlane.h(34) : error C2562: 'NxSegmentPlaneIntersect' : 'void' function returning a value
C:\PROGRAM FILES\AGEIA TECHNOLOGIES\AGEIA PHYSX SDK\V2.3.3\SDKS\PHYSICS\INCLUDE\NxIntersectionRayPlane.h(31) : see declaration of 'NxSegmentPlaneIntersect'
PhysXWorld.cpp
C:\PROGRAM FILES\AGEIA TECHNOLOGIES\AGEIA PHYSX SDK\V2.3.3\SDKS\PHYSICS\INCLUDE\NxIntersectionRayPlane.h(34) : error C2562: 'NxSegmentPlaneIntersect' : 'void' function returning a value
C:\PROGRAM FILES\AGEIA TECHNOLOGIES\AGEIA PHYSX SDK\V2.3.3\SDKS\PHYSICS\INCLUDE\NxIntersectionRayPlane.h(31) : see declaration of 'NxSegmentPlaneIntersect'
Error executing cl.exe.
#57
05/26/2006 (4:02 pm)
Just thought i'd post this here

Quote:
Tom Lassanske:

It looks like we're finishing up the details of the licensing/sub-licensing deal with Garage Games. Once I have the full story, I will create an article in the Knowledge Base that addresses it (like I have for the Dark Basic Pro PhysX Expansion Pack). I expect the two deals to be pretty close in nature.

In the meantime, I believe the current Torque integration is using 2.3.2, so I'll make sure Torque licensees can have access to it, for the time being (the version of PhysX integrated into Torque may end up as part of their standard distribution).

If you belive you are already ready for a full development license, please read http://support.ageia.com/ics/support/default.asp?deptID=1949&task=knowledge&questionID=378 and follow the instructions there.

from a thread on the ageia support centre
#58
05/27/2006 (1:59 pm)
If anyone is having the problems Michael listed change the contents of NxIntersectionRayPlane.h to:
#ifndef NX_INTERSECTION_RAY_PLANE
#define NX_INTERSECTION_RAY_PLANE

#include "Nxp.h"
#include "PhysXLoader.h"
class NxRay;
class NxPlane;

	NX_INLINE	bool NX_CALL_CONV	NxRayPlaneIntersect(const NxRay& ray, const NxPlane& plane, 
		NxReal& dist, NxVec3& pointOnPlane)
		{
		return NxGetUtilLib()->NxRayPlaneIntersect(ray,plane,dist,pointOnPlane);
		}

#endif
#59
06/01/2006 (9:56 am)
You know aparently at IGC, garage games were speaking to ageia about their intentions to officially support physx in TSE. Theres a thread in the support forum which one of the employees said about it.
#60
06/01/2006 (10:04 am)
That can't really be done though due to the license agreement. Also, the integration is fairly easy and it works in TSE so there wouldn't be much point to it.