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
Page «Previous 1 2 3 4 5 6 7 Last »
#1
04/15/2006 (3:42 am)
Thanks for this
#2
04/15/2006 (4:20 am)
Only problem I get is at mission load (with that physx world stuff, stronghold works fine):

Physx SDK Write Lock still aquired prodedure call skipped to avoid a deadlock

Click on ok, comes back (infinite loop?)
#3
04/15/2006 (4:53 am)
Edit: all fixed now
#4
04/15/2006 (5:43 am)
I have been following and waiting for your resource, Shannon.
I salute your stamina in this.

Very good job!
#5
04/15/2006 (5:55 am)
I agree - extremly fast well done!
#6
04/15/2006 (10:13 am)
So if our game can be played without the use of a PPU, we have to pay Ageia $50,000.

And if the game requires a PPU, you can use PhysX free.

Edit: Or if the game is greatly enhanced with the use of a PPU, I see.
#7
04/15/2006 (8:23 pm)
@James
thx for update, but className seem fine in my game, must be something else but anyway thanks!

@Stefan - Thanks!

@C2 - yeah, need PPU to get free PhysX :( but I'm not sure if can use both SW or PPU in one game? That something we need to find out.
#8
04/16/2006 (1:36 am)
Shannon - my game crashes on mission load with the error
Physx SDK Write Lock still aquired prodedure call skipped to avoid a deadlock
im assuming its a loop that keeps getting called, its strange it works on your pc

Edit: Im going to uninstall, reinstall the physx sdk (2.3.2) and reinstall tge then try the integration again

Edir #2: I just remembered I had to take out a function in NxIntersectionRayPlane.h - did you have to?
#9
04/16/2006 (2:20 am)
@James

I dont use NxIntersectionRayPlane.h, this must be the problem

Make sure any PhysX's header file in the physX/physX.h and all the other code call at the top of code files
#include "physX/physX.h"

Also don't forget to put PhysXLoader.dll and NxCooking.dll in the example folder.

Edit: I've keep playing around and finally got that error, must be somewhere to trigger this error. I'll find out in the Novedex forum for this error. Good things about this PhysX have given error message to ensure the physics working correctly. you can remove this error message if you want to. To remove error message modfiy the code from PhysXWorld.cpp in onAdd() function
//gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION, 0, &myOutputStream); 
// myOutputStream is for error message
gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION);
#10
04/16/2006 (11:20 am)
shannon i also get:
C:\SphyxGames\DawnOfMenPhysXEdition\engine\PhysX\PhysXActor.cpp(171) : error C2065: 'PhysXObjectType' : undeclared identifier

maybe that has something to do with it? - strange no-one else gets these problems though
#11
04/16/2006 (11:22 am)
Is PPU a PhysX Processor Unit? If so, this translates to facing the requirement of the user to get a PhysX card, which looks like it's still not to market. So, build in support for something that people can't buy yet? And how do you know if it's going to work until you can get your hands on one yourself?

http://www.gdhardware.com/interviews/agiea/001.htm

Looks like the good news is that it doesn't require huge frontside bus pipeline demands, 1x-4x PCI or PCI Express isn't tough to come by. What remains is how much this technology will cost when it gets to market.

I'm not paying 50K for physics support in an indie title. (As if I could!)
#12
04/16/2006 (11:40 am)
1) PPU is PhysX Processing Unit
2) The PhysX is only activated if the end-user has PhysX
3) Coming out in may at 217.37 pounds
4) Its free if you make significant use of the ppu

Edit:

5) Can buy them now
#13
04/16/2006 (4:31 pm)
@James - change to PlayerObjectType for now, but the zip file is updated so i guess you miss the update.
#14
04/17/2006 (1:57 am)
Shannon - Okay im down to one error and one warning now :)

Error:

If I comment out gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION, 0, &myOutputStream);
the engine crashes on mission load
but I dont get that message

Warning:

PhysXWorld.cpp
C:\SphyxGames\DawnOfMenPhysXEdition\engine\physX\PhysXWorld.cpp(37) : warning C4002: too many actual parameters for macro 'AssertFatal'

Edit:

Got it to work!
Just deleted , &myOutputStream
#15
04/17/2006 (2:42 am)
Looks like GG and Ageia have been talking.....
#16
04/18/2006 (12:15 pm)
Great job Shannon!
#17
04/18/2006 (6:19 pm)
Another question (maybe for the future): Are Novodex and the PPU interchangeable? I.E., if you build support in the game using Novodex can you assume that the PPU will use it seemlessly? I'm skeptical...
#18
04/19/2006 (6:49 am)
@n8man

Novodex is the library that is being used by the PPU. Right now everything is being run in software mode, when the hardware comes in then everything will be able to be run on the hardware. You can liken it to OpenGL or DirectX running in software or hardware acclerated mode.
#19
04/19/2006 (7:58 am)
@scott - If you go through the code there are a lot of refrences to hardware so I believe simple hardware support is in there :)
#20
04/19/2006 (11:10 am)
Well what I meant was that since I don't have the hardware yet its running in software mode and once I get the hardware it'll run in hardware mode.
Page «Previous 1 2 3 4 5 6 7 Last »