• Create Account

Calling all IT Pros from Canada and Australia.. we need your help! Support our site by taking a quick sponsored surveyand win a chance at a \$50 Amazon gift card. Click here to get started!

# chezmark

Member Since 04 Dec 2011
Offline Last Active Feb 14 2012 09:36 AM

### Problem transforming Jos Stam's 2D real-time fluid dynamics in 3D

11 February 2012 - 11:56 AM

Hi everyone, i was trying to implement jos stam paper for fluid dynamics from 2D in 3D but i think that along the way I have messed things up. Well when the simulation runs if you hit the 'v' (toggle density and velocity) on your keyboard you will see a cube (3D) instead of a rectangle (2D) but the problems that arise are :

1) It takes a long time to display densities and velocities since you pressed the 'v' keyboard button

2) The default size of rectangular matrix in jos stam paper was 64, in order for my simulation to run i have reduce it to 16, as soon as i try to increase to N = 64 (default in jos stam example) the simulation blows up.

If anyone has any idea as to what i am doing wrong please let me know.
If you can redirect me to the correct solution i would be more than appreciated.

I have attached Jos Stam code and also my modifications on Jos Stam's code. If you would like please take a look to have a concrete understanding on their differences.

### OpenGL and PhysiX library simulation problem

05 December 2011 - 04:20 AM

Hi everyone, i was wondering if you can help me out with a problem i am facing. Well i know that i am not good neither in opengl nor on physx, but i was eager to give it a try. What i was hoping to do is to make a simulation where there is a rectangular cuboid in the scene which has one side transparent(so we can see what's happening inside) and inside that rectangular there are two cubes and two spheres which are starting from an initial position and then forces are applied to those objects and they start collide with each other and the surrounding environment, in this case the rectangular cuboid. All i have done so far is take one sample of the physx sdk and add couple of lines to draw two cubes and two spheres. What i don't know is how to put those inside a rectangular cuboid and apply forces to them to make them collide. I have attached an image of what the simulation looks like now.
I could appreciate any kind of help at all. Thank you all and god bless you.

here is the code for the header files

Lesson101.h

```
#ifndef LESSON101_H
#define LESSON101_H

#include <GL/glut.h>

#include <stdio.h>

#include "NxPhysics.h"
#include "DrawObjects.h"
#include "HUD.h"

#include "DebugRenderer.h"
#include "CommonCode.h"

void PrintControls();
void ProcessCameraKeys();
void SetupCamera();
void DrawForce(NxActor* actor, NxVec3& forceVec, const NxVec3& color);

NxVec3 ApplyForceToActor(NxActor* actor, const NxVec3& forceDir, const NxReal forceStrength);
void ProcessForceKeys();
void ProcessInputs();
void SelectNextActor();
bool IsSelectable(NxActor* actor);

void RenderCallback();
void ReshapeCallback(int width, int height);
void IdleCallback();
void KeyboardCallback(unsigned char key, int x, int y);
void KeyboardUpCallback(unsigned char key, int x, int y);
void SpecialCallback(int key, int x, int y);
void MouseCallback(int button, int state, int x, int y);
void MotionCallback(int x, int y);
void ExitCallback();
void InitGlut(int argc, char** argv);

NxActor* CreateGroundPlane();
NxActor* CreateBox();
NxActor* CreateSphere();
NxActor* CreateCapsule();
NxActor* CreateBounds3();
NxActor* CreateSegment();
NxActor* CreateRay();

void InitializeHUD();

void InitNx();
void ReleaseNx();
void ResetNx();

void StartPhysics();
void GetPhysicsResults();

int main(int argc, char** argv);

#endif  // LESSON101_H

```

DrawObjects.h

```#ifndef DRAWOBJECTS_H
#define DRAWOBJECTS_H

class NxShape;
class NxActor;

void SetupGLMatrix(const NxVec3& pos, const NxMat33& orient);
void DrawLine(const NxVec3& p0, const NxVec3& p1, const NxVec3& color, float lineWidth=2.0f);
void DrawTriangle(const NxVec3& p0, const NxVec3& p1, const NxVec3& p2, const NxVec3& color);
void DrawCircle(NxU32 nbSegments, const NxMat34& matrix, const NxVec3& color, const NxF32 radius, const bool semicircle = false);
void DrawEllipse(NxU32 nbSegments, const NxMat34& matrix, const NxVec3& color, const NxF32 radius1, const NxF32 radius2, const bool semicircle = false);

void DrawWirePlane(NxShape* plane, const NxVec3& color);
void DrawPlane(NxShape* plane);

void DrawWireBox(NxShape* box, const NxVec3& color, float lineWidth=2.0f);
void DrawWireBox(const NxBox& obb, const NxVec3& color, float lineWidth=2.0f);
void DrawBox(NxShape* box);

void DrawWireSphere(NxShape* sphere, const NxVec3& color);
void DrawWireSphere(NxSphere* sphere, const NxVec3& color);
void DrawSphere(NxShape* sphere);

void DrawWireCapsule(NxShape* capsule, const NxVec3& color);
void DrawWireCapsule(const NxCapsule& capsule, const NxVec3& color);
void DrawCapsule(NxShape* capsule);
void DrawCapsule(const NxVec3& color, NxF32 r, NxF32 h);

void DrawWireConvex(NxShape* mesh, const NxVec3& color, bool useShapeUserData);
void DrawConvex(NxShape* mesh, bool useShapeUserData);

void DrawWireMesh(NxShape* mesh, const NxVec3& color, bool useShapeUserData);
void DrawMesh(NxShape* mesh, bool useShapeUserData);
void DrawWheelShape(NxShape* wheel);

void DrawArrow(const NxVec3& posA, const NxVec3& posB, const NxVec3& color);
void DrawContactPoint(const NxVec3& pos, const NxReal radius, const NxVec3& color);

void DrawWireShape(NxShape* shape, const NxVec3& color, bool useShapeUserData);
void DrawShape(NxShape* shape, bool useShapeUserData);
void DrawActor(NxActor* actor, NxActor* selectedActor, bool useShapeUserData);

void DrawActorShapeSelect(NxActor* actor, NxShape* shape, const bool shapeSelectMode, NxActor* selectedActor, bool useShapeUserData);

#endif  // DRAWOBJECTS_H

```

HUD.h

```#ifndef HUD_H
#define HUD_H

#include <GL/glut.h>
#include <stdio.h>

#include "NxPhysics.h"

class DisplayString
{
public:
char m_string[512];
NxReal m_xpos;
NxReal m_ypos;

DisplayString()
{
m_string[0]='\0';
m_ypos = m_xpos = 0;
}

void Set(char* s, NxReal x, NxReal y)
{
sprintf(m_string, s);
m_xpos = x;
m_ypos = y;
}
};

class HUD
{
public:
NxArray<DisplayString> m_DisplayString;

void AddDisplayString(char* s, NxReal x, NxReal y);
void SetDisplayString(NxU32 i, char* s, NxReal x, NxReal y);
void Clear();
void Render();
};
#endif  // HUD_H

```

here is the actual .cpp file Lesson101.cpp

```// ===============================================================================
//						  NVIDIA PHYSX SDK TRAINING PROGRAMS
//						     LESSON 101 : PRIMARY SHAPE
//
//						    Written by QA BJ, 6-2-2008
// ===============================================================================

#include "Lesson101.h"
#include "UpdateTime.h"

// Physics SDK globals
NxPhysicsSDK*     gPhysicsSDK = NULL;
NxScene*          gScene = NULL;
NxVec3            gDefaultGravity(0,-9.8,0);

// User report globals
DebugRenderer     gDebugRenderer;

// HUD globals
HUD hud;

// Display globals
int gMainHandle;
int mx = 0;
int my = 0;

// Camera globals
float	gCameraAspectRatio = 1.0f;
NxVec3	gCameraPos(0,5,-15);
NxVec3	gCameraForward(0,0,1);
NxVec3	gCameraRight(-1,0,0);
const NxReal gCameraSpeed = 10;

// Force globals
NxVec3	gForceVec(0,0,0);
NxReal	gForceStrength	= 20000;
bool	bForceMode		= true;

// Keyboard globals
#define MAX_KEYS 256
bool gKeys[MAX_KEYS];

// Simulation globals
NxReal	gDeltaTime			= 1.0/60.0;
bool	bHardwareScene		= false;
bool	bPause				= false;
bool	bDebugWireframeMode = false;

// Actor globals
NxActor* groundPlane = NULL;

// Focus actor
NxActor* gSelectedActor = NULL;

void PrintControls()
{
printf("\n Flight Controls:\n ----------------\n w = forward, s = back\n a = strafe left, d = strafe right\n q = up, z = down\n");
printf("\n Force Controls:\n ---------------\n i = +z, k = -z\n j = +x, l = -x\n u = +y, m = -y\n");
printf("\n Miscellaneous:\n --------------\n p   = Pause\n b   = Toggle Debug Wireframe Mode\n x   = Toggle Shadows\n r   = Select Actor\n F10 = Reset scene\n");
}

NxVec3 ApplyForceToActor(NxActor* actor, const NxVec3& forceDir, const NxReal forceStrength)
{
NxVec3 forceVec = forceStrength*forceDir*gDeltaTime;
return forceVec;
}

void ProcessCameraKeys()
{
NxReal deltaTime;

if (bPause)
{
deltaTime = 0.0005;
}
else
{
deltaTime = gDeltaTime;
}

// Process camera keys
for (int i = 0; i < MAX_KEYS; i++)
{
if (!gKeys[i])  { continue; }

switch (i)
{
// Camera controls
case 'w':{ gCameraPos += gCameraForward*gCameraSpeed*deltaTime; break; }
case 's':{ gCameraPos -= gCameraForward*gCameraSpeed*deltaTime; break; }
case 'a':{ gCameraPos -= gCameraRight*gCameraSpeed*deltaTime;	break; }
case 'd':{ gCameraPos += gCameraRight*gCameraSpeed*deltaTime;	break; }
case 'z':{ gCameraPos -= NxVec3(0,1,0)*gCameraSpeed*deltaTime;	break; }
case 'q':{ gCameraPos += NxVec3(0,1,0)*gCameraSpeed*deltaTime;	break; }
}
}
}

void SetupCamera()
{
gCameraAspectRatio = (float)glutGet(GLUT_WINDOW_WIDTH) / (float)glutGet(GLUT_WINDOW_HEIGHT);

// Setup camera
glMatrixMode(GL_PROJECTION);
gluPerspective(60.0f, gCameraAspectRatio, 1.0f, 10000.0f);
gluLookAt(gCameraPos.x,gCameraPos.y,gCameraPos.z,gCameraPos.x + gCameraForward.x, gCameraPos.y + gCameraForward.y, gCameraPos.z + gCameraForward.z, 0.0f, 1.0f, 0.0f);

glMatrixMode(GL_MODELVIEW);
}

{
// Render all the actors in the scene
NxU32 nbActors = gScene->getNbActors();
NxActor** actors = gScene->getActors();
while (nbActors--)
{
NxActor* actor = *actors++;
DrawActor(actor, gSelectedActor, false);

{
}
}
}

void DrawForce(NxActor* actor, NxVec3& forceVec, const NxVec3& color)
{
// Draw only if the force is large enough
NxReal force = forceVec.magnitude();
if (force < 0.1)  return;

forceVec = 3*forceVec/force;

NxVec3 pos = actor->getCMassGlobalPosition();
DrawArrow(pos, pos + forceVec, color);
}

bool IsSelectable(NxActor* actor)
{
NxShape*const* shapes = gSelectedActor->getShapes();
NxU32 nShapes = gSelectedActor->getNbShapes();
while (nShapes--)
{
if (shapes[nShapes]->getFlag(NX_TRIGGER_ENABLE))
{
return false;
}
}

if(!actor->isDynamic())
return false;

if (actor == groundPlane)
return false;

return true;
}

void SelectNextActor()
{
NxU32 nbActors = gScene->getNbActors();
NxActor** actors = gScene->getActors();
for(NxU32 i = 0; i < nbActors; i++)
{
if (actors[i] == gSelectedActor)
{
NxU32 j = 1;
gSelectedActor = actors[(i+j)%nbActors];
while (!IsSelectable(gSelectedActor))
{
j++;
gSelectedActor = actors[(i+j)%nbActors];
}
break;
}
}
}

void ProcessForceKeys()
{
// Process force keys
for (int i = 0; i < MAX_KEYS; i++)
{
if (!gKeys[i])  { continue; }

switch (i)
{
// Force controls
case 'i': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(0,0,1),gForceStrength);		break; }
case 'k': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(0,0,-1),gForceStrength);	break; }
case 'j': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(1,0,0),gForceStrength);		break; }
case 'l': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(-1,0,0),gForceStrength);	break; }
case 'u': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(0,1,0),gForceStrength);		break; }
case 'm': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(0,-1,0),gForceStrength);	break; }

// Return box to (0,5,0)
case 't':
{
if (gSelectedActor)
{
gSelectedActor->setGlobalPosition(NxVec3(0,5,0));
gScene->flushCaches();
}
break;
}
}
}
}

void ProcessInputs()
{
ProcessForceKeys();

// Show debug wireframes
if (bDebugWireframeMode)
{
if (gScene)  gDebugRenderer.renderData(*gScene->getDebugRenderable());
}
}

void RenderCallback()
{
// Clear buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

ProcessCameraKeys();
SetupCamera();

if (gScene && !bPause)
{
GetPhysicsResults();
ProcessInputs();
StartPhysics();
}

// Display scene

DrawForce(gSelectedActor, gForceVec, NxVec3(1,1,0));
gForceVec = NxVec3(0,0,0);

// Render the HUD
hud.Render();

glFlush();
glutSwapBuffers();
}

void ReshapeCallback(int width, int height)
{
glViewport(0, 0, width, height);
gCameraAspectRatio = float(width)/float(height);
}

void IdleCallback()
{
glutPostRedisplay();
}

void KeyboardCallback(unsigned char key, int x, int y)
{
gKeys[key] = true;

switch (key)
{
case 'r':	{ SelectNextActor(); break; }
default:	{ break; }
}
}

void KeyboardUpCallback(unsigned char key, int x, int y)
{
gKeys[key] = false;

switch (key)
{
case 'p':
{
bPause = !bPause;
if (bPause)
hud.SetDisplayString(0, "Paused - Hit \"p\" to Unpause", 0.3f, 0.55f);
else
hud.SetDisplayString(0, "", 0.0f, 0.0f);
UpdateTime();
break;
}
case 'b': { bDebugWireframeMode = !bDebugWireframeMode; break; }
case 27 : { exit(0); break; }
default : { break; }
}
}

void SpecialCallback(int key, int x, int y)
{
switch (key)
{
// Reset PhysX
case GLUT_KEY_F10: ResetNx(); return;
}
}

void MouseCallback(int button, int state, int x, int y)
{
mx = x;
my = y;
}

void MotionCallback(int x, int y)
{
int dx = mx - x;
int dy = my - y;

gCameraForward.normalize();
gCameraRight.cross(gCameraForward,NxVec3(0,1,0));

NxQuat qx(NxPiF32 * dx * 20 / 180.0f, NxVec3(0,1,0));
qx.rotate(gCameraForward);
NxQuat qy(NxPiF32 * dy * 20 / 180.0f, gCameraRight);
qy.rotate(gCameraForward);

mx = x;
my = y;
}

void ExitCallback()
{
ReleaseNx();
}

void InitGlut(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitWindowSize(900, 700);
glutInitWindowPosition(100,100);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
gMainHandle = glutCreateWindow("Primary Shape");
glutSetWindow(gMainHandle);
glutDisplayFunc(RenderCallback);
glutReshapeFunc(ReshapeCallback);
glutIdleFunc(IdleCallback);
glutKeyboardFunc(KeyboardCallback);
glutKeyboardUpFunc(KeyboardUpCallback);
glutSpecialFunc(SpecialCallback);
glutMouseFunc(MouseCallback);
glutMotionFunc(MotionCallback);
MotionCallback(0,0);
atexit(ExitCallback);

// Setup default render states
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_CULL_FACE);

// Setup lighting
glEnable(GL_LIGHTING);
float AmbientColor[]    = { 0.0f, 0.1f, 0.2f, 0.0f };         glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientColor);
float DiffuseColor[]    = { 0.2f, 0.2f, 0.2f, 0.0f };         glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseColor);
float SpecularColor[]   = { 0.5f, 0.5f, 0.5f, 0.0f };         glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularColor);
float Position[]        = { 100.0f, 100.0f, -400.0f, 1.0f };  glLightfv(GL_LIGHT0, GL_POSITION, Position);
glEnable(GL_LIGHT0);
}

NxActor* CreateGroundPlane()
{
// Create a plane with default descriptor
NxPlaneShapeDesc planeDesc;
NxActorDesc actorDesc;
actorDesc.shapes.pushBack(&planeDesc);
return gScene->createActor(actorDesc);
}

NxActor* CreateBox()
{
// Set the box starting height to 3.5m so box starts off falling onto the ground
NxReal boxStartHeight = 3.5;

// Add a single-shape actor to the scene
NxActorDesc actorDesc;
NxBodyDesc bodyDesc;

// The actor has one shape, a box, 1m on a side
NxBoxShapeDesc boxDesc;
boxDesc.dimensions.set(0.5,0.5,0.5);
boxDesc.localPose.t = NxVec3(0, 0, 0);
actorDesc.shapes.pushBack(&boxDesc);

actorDesc.body			= &bodyDesc;
actorDesc.density		= 10.0f;
actorDesc.globalPose.t	= NxVec3(0,boxStartHeight,0);
assert(actorDesc.isValid());
NxActor *pActor = gScene->createActor(actorDesc);
assert(pActor);

// //create actor with no shapes
//NxShape* const *shape = pActor->getShapes();
//NxBoxShape *boxShape = shape[0]->isBox();
//assert(boxShape);
//pActor->releaseShape(*boxShape);

//NxVec3 forceVec1 = gForceStrength*NxVec3(1,0,0)*gDeltaTime;
//NxVec3 forceVec2 = gForceStrength*NxVec3(-1,0,0)*gDeltaTime;
NxVec3 forceVec3 = gForceStrength*NxVec3(0,1,0)*gDeltaTime;
//NxVec3 forceVec4 = gForceStrength*NxVec3(0,-1,0)*gDeltaTime;
//NxVec3 forceVec5 = gForceStrength*NxVec3(0,0,1)*gDeltaTime;
//NxVec3 forceVec6 = gForceStrength*NxVec3(0,0,-1)*gDeltaTime;

/*NxVec3 ApplyForceToActor(NxActor* actor, const NxVec3& forceDir, const NxReal forceStrength)
{
NxVec3 forceVec = forceStrength*forceDir*gDeltaTime;
return forceVec;
}
gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(1,0,0),gForceStrength)*/

return pActor;
}

NxActor* CreateSphere()
{
// Set the sphere starting height to 3.5m so box starts off falling onto the ground
NxReal sphereStartHeight = 3.5;

// Add a single-shape actor to the scene
NxActorDesc actorDesc;
NxBodyDesc bodyDesc;

// The actor has one shape, a sphere, 1m on radius
NxSphereShapeDesc sphereDesc;
sphereDesc.localPose.t	= NxVec3(0, 0, 0);

actorDesc.shapes.pushBack(&sphereDesc);
actorDesc.body			= &bodyDesc;
actorDesc.density		= 10.0f;
actorDesc.globalPose.t	= NxVec3(3.0f,sphereStartHeight,0);
return gScene->createActor(actorDesc);
}

NxActor* CreateCapsule()
{
// Set the capsule starting height to 3.5m so box starts off falling onto the ground
NxReal capsuleStartHeight = 3.5;

// Add a single-shape actor to the scene
NxActorDesc actorDesc;
NxBodyDesc bodyDesc;

// The actor has one shape, a sphere, 1m on radius
NxCapsuleShapeDesc capsuleDesc;
capsuleDesc.height		= 0.75f;
capsuleDesc.localPose.t = NxVec3(0, 0, 0);

//Rotate capsule shape
NxQuat quat(45, NxVec3(0, 0, 1));
NxMat33 m33(quat);
capsuleDesc.localPose.M = m33;

actorDesc.shapes.pushBack(&capsuleDesc);
actorDesc.body			= &bodyDesc;
actorDesc.density		= 10.0f;
actorDesc.globalPose.t	= NxVec3(6.0f,capsuleStartHeight,0);

////Rotate actor
//NxQuat quat1(45, NxVec3(1, 0, 0));
//NxMat33 m331(quat1);
//actorDesc.globalPose.M = m331;

return gScene->createActor(actorDesc);
}

void InitializeHUD()
{
bHardwareScene = (gScene->getSimType() == NX_SIMULATION_HW);

hud.Clear();

//if (bHardwareScene)
//else

if (bPause)
hud.AddDisplayString("Paused - Hit \"p\" to Unpause", 0.3f, 0.55f);
else
}

void InitNx()
{
// Initialize camera parameters
gCameraAspectRatio	= 1.0f;
gCameraPos			= NxVec3(0,5,-15);
gCameraForward		= NxVec3(0,0,1);
gCameraRight		= NxVec3(-1,0,0);

// Create the physics SDK
gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION);
if (!gPhysicsSDK)  return;
else if(gPhysicsSDK != NULL)
gPhysicsSDK->getFoundationSDK().getRemoteDebugger()->connect("localhost", 5425);

// Set the physics parameters
gPhysicsSDK->setParameter(NX_SKIN_WIDTH, 0.01);

// Set the debug visualization parameters
gPhysicsSDK->setParameter(NX_VISUALIZATION_SCALE, 1);
gPhysicsSDK->setParameter(NX_VISUALIZE_COLLISION_SHAPES, 1);
gPhysicsSDK->setParameter(NX_VISUALIZE_ACTOR_AXES, 1);

// Create the scene
NxSceneDesc sceneDesc;
sceneDesc.simType				= NX_SIMULATION_SW;
sceneDesc.gravity               = gDefaultGravity;
gScene = gPhysicsSDK->createScene(sceneDesc);
if(!gScene)
{
sceneDesc.simType			= NX_SIMULATION_SW;
gScene = gPhysicsSDK->createScene(sceneDesc);
if(!gScene) return;
}

// Create the default material
NxMaterial* defaultMaterial = gScene->getMaterialFromIndex(0);
defaultMaterial->setRestitution(0.5);
defaultMaterial->setStaticFriction(0.5);
defaultMaterial->setDynamicFriction(0.5);

// Create the objects in the scene
groundPlane		= CreateGroundPlane();
gSelectedActor	= CreateBox();
CreateBox();
CreateSphere();
CreateSphere();
//	CreateCapsule();

// Initialize HUD
InitializeHUD();

// Get the current time
UpdateTime();

// Start the first frame of the simulation
if (gScene)  StartPhysics();
}

void ReleaseNx()
{
if (gScene)
{
GetPhysicsResults();  // Make sure to fetchResults() before shutting down
gPhysicsSDK->releaseScene(*gScene);
}
if (gPhysicsSDK)  gPhysicsSDK->release();
}

void ResetNx()
{
ReleaseNx();
InitNx();
}

void StartPhysics()
{
// Update the time step
gDeltaTime = UpdateTime();

// Start collision and dynamics for delta time since the last frame
gScene->simulate(gDeltaTime);
gScene->flushStream();
}

void GetPhysicsResults()
{
// Get results from gScene->simulate(gDeltaTime)
while (!gScene->fetchResults(NX_RIGID_BODY_FINISHED, false));
}

int main(int argc, char** argv)
{
PrintControls();
InitGlut(argc, argv);
InitNx();
glutMainLoop();
ReleaseNx();
return 0;
}

```

### OpenGL and PhysiX library simulation problem

05 December 2011 - 04:17 AM

Hi everyone, i was wondering if you can help me out with a problem i am facing. Well i know that i am not good neither in opengl nor on physx, but i was eager to give it a try. What i was hoping to do is to make a simulation where there is a rectangular cuboid in the scene which has one side transparent(so we can see what's happening inside) and inside that rectangular there are two cubes and two spheres which are starting from an initial position and then forces are applied to those objects and they start collide with each other and the surrounding environment, in this case the rectangular cuboid. All i have done so far is take one sample of the physx sdk and add couple of lines to draw two cubes and two spheres. What i don't know is how to put those inside a rectangular cuboid and apply forces to them to make them collide. I have attached an image of what the simulation looks like now.
I could appreciate any kind of help at all. Thank you all and god bless you.

here is the code for the header files

Lesson101.h

[cdoe]

#ifndef LESSON101_H
#define LESSON101_H

#include <GL/glut.h>

#include <stdio.h>

#include "NxPhysics.h"
#include "DrawObjects.h"
#include "HUD.h"

#include "DebugRenderer.h"
#include "CommonCode.h"

void PrintControls();
void ProcessCameraKeys();
void SetupCamera();
void DrawForce(NxActor* actor, NxVec3& forceVec, const NxVec3& color);

NxVec3 ApplyForceToActor(NxActor* actor, const NxVec3& forceDir, const NxReal forceStrength);
void ProcessForceKeys();
void ProcessInputs();
void SelectNextActor();
bool IsSelectable(NxActor* actor);

void RenderCallback();
void ReshapeCallback(int width, int height);
void IdleCallback();
void KeyboardCallback(unsigned char key, int x, int y);
void KeyboardUpCallback(unsigned char key, int x, int y);
void SpecialCallback(int key, int x, int y);
void MouseCallback(int button, int state, int x, int y);
void MotionCallback(int x, int y);
void ExitCallback();
void InitGlut(int argc, char** argv);

NxActor* CreateGroundPlane();
NxActor* CreateBox();
NxActor* CreateSphere();
NxActor* CreateCapsule();
NxActor* CreateBounds3();
NxActor* CreateSegment();
NxActor* CreateRay();

void InitializeHUD();

void InitNx();
void ReleaseNx();
void ResetNx();

void StartPhysics();
void GetPhysicsResults();

int main(int argc, char** argv);

#endif // LESSON101_H

[/code]

DrawObjects.h

```#ifndef DRAWOBJECTS_H
#define DRAWOBJECTS_H

class NxShape;
class NxActor;

void SetupGLMatrix(const NxVec3& pos, const NxMat33& orient);
void DrawLine(const NxVec3& p0, const NxVec3& p1, const NxVec3& color, float lineWidth=2.0f);
void DrawTriangle(const NxVec3& p0, const NxVec3& p1, const NxVec3& p2, const NxVec3& color);
void DrawCircle(NxU32 nbSegments, const NxMat34& matrix, const NxVec3& color, const NxF32 radius, const bool semicircle = false);
void DrawEllipse(NxU32 nbSegments, const NxMat34& matrix, const NxVec3& color, const NxF32 radius1, const NxF32 radius2, const bool semicircle = false);

void DrawWirePlane(NxShape* plane, const NxVec3& color);
void DrawPlane(NxShape* plane);

void DrawWireBox(NxShape* box, const NxVec3& color, float lineWidth=2.0f);
void DrawWireBox(const NxBox& obb, const NxVec3& color, float lineWidth=2.0f);
void DrawBox(NxShape* box);

void DrawWireSphere(NxShape* sphere, const NxVec3& color);
void DrawWireSphere(NxSphere* sphere, const NxVec3& color);
void DrawSphere(NxShape* sphere);

void DrawWireCapsule(NxShape* capsule, const NxVec3& color);
void DrawWireCapsule(const NxCapsule& capsule, const NxVec3& color);
void DrawCapsule(NxShape* capsule);
void DrawCapsule(const NxVec3& color, NxF32 r, NxF32 h);

void DrawWireConvex(NxShape* mesh, const NxVec3& color, bool useShapeUserData);
void DrawConvex(NxShape* mesh, bool useShapeUserData);

void DrawWireMesh(NxShape* mesh, const NxVec3& color, bool useShapeUserData);
void DrawMesh(NxShape* mesh, bool useShapeUserData);
void DrawWheelShape(NxShape* wheel);

void DrawArrow(const NxVec3& posA, const NxVec3& posB, const NxVec3& color);
void DrawContactPoint(const NxVec3& pos, const NxReal radius, const NxVec3& color);

void DrawWireShape(NxShape* shape, const NxVec3& color, bool useShapeUserData);
void DrawShape(NxShape* shape, bool useShapeUserData);
void DrawActor(NxActor* actor, NxActor* selectedActor, bool useShapeUserData);

void DrawActorShapeSelect(NxActor* actor, NxShape* shape, const bool shapeSelectMode, NxActor* selectedActor, bool useShapeUserData);

#endif  // DRAWOBJECTS_H

```

HUD.h

```#ifndef HUD_H
#define HUD_H

#include <GL/glut.h>
#include <stdio.h>

#include "NxPhysics.h"

class DisplayString
{
public:
char m_string[512];
NxReal m_xpos;
NxReal m_ypos;

DisplayString()
{
m_string[0]='\0';
m_ypos = m_xpos = 0;
}

void Set(char* s, NxReal x, NxReal y)
{
sprintf(m_string, s);
m_xpos = x;
m_ypos = y;
}
};

class HUD
{
public:
NxArray<DisplayString> m_DisplayString;

void AddDisplayString(char* s, NxReal x, NxReal y);
void SetDisplayString(NxU32 i, char* s, NxReal x, NxReal y);
void Clear();
void Render();
};
#endif  // HUD_H

```

here is the actual .cpp file Lesson101.cpp

```// ===============================================================================
//						  NVIDIA PHYSX SDK TRAINING PROGRAMS
//						     LESSON 101 : PRIMARY SHAPE
//
//						    Written by QA BJ, 6-2-2008
// ===============================================================================

#include "Lesson101.h"
#include "UpdateTime.h"

// Physics SDK globals
NxPhysicsSDK*     gPhysicsSDK = NULL;
NxScene*          gScene = NULL;
NxVec3            gDefaultGravity(0,-9.8,0);

// User report globals
DebugRenderer     gDebugRenderer;

// HUD globals
HUD hud;

// Display globals
int gMainHandle;
int mx = 0;
int my = 0;

// Camera globals
float	gCameraAspectRatio = 1.0f;
NxVec3	gCameraPos(0,5,-15);
NxVec3	gCameraForward(0,0,1);
NxVec3	gCameraRight(-1,0,0);
const NxReal gCameraSpeed = 10;

// Force globals
NxVec3	gForceVec(0,0,0);
NxReal	gForceStrength	= 20000;
bool	bForceMode		= true;

// Keyboard globals
#define MAX_KEYS 256
bool gKeys[MAX_KEYS];

// Simulation globals
NxReal	gDeltaTime			= 1.0/60.0;
bool	bHardwareScene		= false;
bool	bPause				= false;
bool	bDebugWireframeMode = false;

// Actor globals
NxActor* groundPlane = NULL;

// Focus actor
NxActor* gSelectedActor = NULL;

void PrintControls()
{
printf("\n Flight Controls:\n ----------------\n w = forward, s = back\n a = strafe left, d = strafe right\n q = up, z = down\n");
printf("\n Force Controls:\n ---------------\n i = +z, k = -z\n j = +x, l = -x\n u = +y, m = -y\n");
printf("\n Miscellaneous:\n --------------\n p   = Pause\n b   = Toggle Debug Wireframe Mode\n x   = Toggle Shadows\n r   = Select Actor\n F10 = Reset scene\n");
}

NxVec3 ApplyForceToActor(NxActor* actor, const NxVec3& forceDir, const NxReal forceStrength)
{
NxVec3 forceVec = forceStrength*forceDir*gDeltaTime;
return forceVec;
}

void ProcessCameraKeys()
{
NxReal deltaTime;

if (bPause)
{
deltaTime = 0.0005;
}
else
{
deltaTime = gDeltaTime;
}

// Process camera keys
for (int i = 0; i < MAX_KEYS; i++)
{
if (!gKeys[i])  { continue; }

switch (i)
{
// Camera controls
case 'w':{ gCameraPos += gCameraForward*gCameraSpeed*deltaTime; break; }
case 's':{ gCameraPos -= gCameraForward*gCameraSpeed*deltaTime; break; }
case 'a':{ gCameraPos -= gCameraRight*gCameraSpeed*deltaTime;	break; }
case 'd':{ gCameraPos += gCameraRight*gCameraSpeed*deltaTime;	break; }
case 'z':{ gCameraPos -= NxVec3(0,1,0)*gCameraSpeed*deltaTime;	break; }
case 'q':{ gCameraPos += NxVec3(0,1,0)*gCameraSpeed*deltaTime;	break; }
}
}
}

void SetupCamera()
{
gCameraAspectRatio = (float)glutGet(GLUT_WINDOW_WIDTH) / (float)glutGet(GLUT_WINDOW_HEIGHT);

// Setup camera
glMatrixMode(GL_PROJECTION);
gluPerspective(60.0f, gCameraAspectRatio, 1.0f, 10000.0f);
gluLookAt(gCameraPos.x,gCameraPos.y,gCameraPos.z,gCameraPos.x + gCameraForward.x, gCameraPos.y + gCameraForward.y, gCameraPos.z + gCameraForward.z, 0.0f, 1.0f, 0.0f);

glMatrixMode(GL_MODELVIEW);
}

{
// Render all the actors in the scene
NxU32 nbActors = gScene->getNbActors();
NxActor** actors = gScene->getActors();
while (nbActors--)
{
NxActor* actor = *actors++;
DrawActor(actor, gSelectedActor, false);

{
}
}
}

void DrawForce(NxActor* actor, NxVec3& forceVec, const NxVec3& color)
{
// Draw only if the force is large enough
NxReal force = forceVec.magnitude();
if (force < 0.1)  return;

forceVec = 3*forceVec/force;

NxVec3 pos = actor->getCMassGlobalPosition();
DrawArrow(pos, pos + forceVec, color);
}

bool IsSelectable(NxActor* actor)
{
NxShape*const* shapes = gSelectedActor->getShapes();
NxU32 nShapes = gSelectedActor->getNbShapes();
while (nShapes--)
{
if (shapes[nShapes]->getFlag(NX_TRIGGER_ENABLE))
{
return false;
}
}

if(!actor->isDynamic())
return false;

if (actor == groundPlane)
return false;

return true;
}

void SelectNextActor()
{
NxU32 nbActors = gScene->getNbActors();
NxActor** actors = gScene->getActors();
for(NxU32 i = 0; i < nbActors; i++)
{
if (actors[i] == gSelectedActor)
{
NxU32 j = 1;
gSelectedActor = actors[(i+j)%nbActors];
while (!IsSelectable(gSelectedActor))
{
j++;
gSelectedActor = actors[(i+j)%nbActors];
}
break;
}
}
}

void ProcessForceKeys()
{
// Process force keys
for (int i = 0; i < MAX_KEYS; i++)
{
if (!gKeys[i])  { continue; }

switch (i)
{
// Force controls
case 'i': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(0,0,1),gForceStrength);		break; }
case 'k': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(0,0,-1),gForceStrength);	break; }
case 'j': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(1,0,0),gForceStrength);		break; }
case 'l': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(-1,0,0),gForceStrength);	break; }
case 'u': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(0,1,0),gForceStrength);		break; }
case 'm': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(0,-1,0),gForceStrength);	break; }

// Return box to (0,5,0)
case 't':
{
if (gSelectedActor)
{
gSelectedActor->setGlobalPosition(NxVec3(0,5,0));
gScene->flushCaches();
}
break;
}
}
}
}

void ProcessInputs()
{
ProcessForceKeys();

// Show debug wireframes
if (bDebugWireframeMode)
{
if (gScene)  gDebugRenderer.renderData(*gScene->getDebugRenderable());
}
}

void RenderCallback()
{
// Clear buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

ProcessCameraKeys();
SetupCamera();

if (gScene && !bPause)
{
GetPhysicsResults();
ProcessInputs();
StartPhysics();
}

// Display scene

DrawForce(gSelectedActor, gForceVec, NxVec3(1,1,0));
gForceVec = NxVec3(0,0,0);

// Render the HUD
hud.Render();

glFlush();
glutSwapBuffers();
}

void ReshapeCallback(int width, int height)
{
glViewport(0, 0, width, height);
gCameraAspectRatio = float(width)/float(height);
}

void IdleCallback()
{
glutPostRedisplay();
}

void KeyboardCallback(unsigned char key, int x, int y)
{
gKeys[key] = true;

switch (key)
{
case 'r':	{ SelectNextActor(); break; }
default:	{ break; }
}
}

void KeyboardUpCallback(unsigned char key, int x, int y)
{
gKeys[key] = false;

switch (key)
{
case 'p':
{
bPause = !bPause;
if (bPause)
hud.SetDisplayString(0, "Paused - Hit \"p\" to Unpause", 0.3f, 0.55f);
else
hud.SetDisplayString(0, "", 0.0f, 0.0f);
UpdateTime();
break;
}
case 'b': { bDebugWireframeMode = !bDebugWireframeMode; break; }
case 27 : { exit(0); break; }
default : { break; }
}
}

void SpecialCallback(int key, int x, int y)
{
switch (key)
{
// Reset PhysX
case GLUT_KEY_F10: ResetNx(); return;
}
}

void MouseCallback(int button, int state, int x, int y)
{
mx = x;
my = y;
}

void MotionCallback(int x, int y)
{
int dx = mx - x;
int dy = my - y;

gCameraForward.normalize();
gCameraRight.cross(gCameraForward,NxVec3(0,1,0));

NxQuat qx(NxPiF32 * dx * 20 / 180.0f, NxVec3(0,1,0));
qx.rotate(gCameraForward);
NxQuat qy(NxPiF32 * dy * 20 / 180.0f, gCameraRight);
qy.rotate(gCameraForward);

mx = x;
my = y;
}

void ExitCallback()
{
ReleaseNx();
}

void InitGlut(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitWindowSize(900, 700);
glutInitWindowPosition(100,100);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
gMainHandle = glutCreateWindow("Primary Shape");
glutSetWindow(gMainHandle);
glutDisplayFunc(RenderCallback);
glutReshapeFunc(ReshapeCallback);
glutIdleFunc(IdleCallback);
glutKeyboardFunc(KeyboardCallback);
glutKeyboardUpFunc(KeyboardUpCallback);
glutSpecialFunc(SpecialCallback);
glutMouseFunc(MouseCallback);
glutMotionFunc(MotionCallback);
MotionCallback(0,0);
atexit(ExitCallback);

// Setup default render states
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_CULL_FACE);

// Setup lighting
glEnable(GL_LIGHTING);
float AmbientColor[]    = { 0.0f, 0.1f, 0.2f, 0.0f };         glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientColor);
float DiffuseColor[]    = { 0.2f, 0.2f, 0.2f, 0.0f };         glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseColor);
float SpecularColor[]   = { 0.5f, 0.5f, 0.5f, 0.0f };         glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularColor);
float Position[]        = { 100.0f, 100.0f, -400.0f, 1.0f };  glLightfv(GL_LIGHT0, GL_POSITION, Position);
glEnable(GL_LIGHT0);
}

NxActor* CreateGroundPlane()
{
// Create a plane with default descriptor
NxPlaneShapeDesc planeDesc;
NxActorDesc actorDesc;
actorDesc.shapes.pushBack(&planeDesc);
return gScene->createActor(actorDesc);
}

NxActor* CreateBox()
{
// Set the box starting height to 3.5m so box starts off falling onto the ground
NxReal boxStartHeight = 3.5;

// Add a single-shape actor to the scene
NxActorDesc actorDesc;
NxBodyDesc bodyDesc;

// The actor has one shape, a box, 1m on a side
NxBoxShapeDesc boxDesc;
boxDesc.dimensions.set(0.5,0.5,0.5);
boxDesc.localPose.t = NxVec3(0, 0, 0);
actorDesc.shapes.pushBack(&boxDesc);

actorDesc.body			= &bodyDesc;
actorDesc.density		= 10.0f;
actorDesc.globalPose.t	= NxVec3(0,boxStartHeight,0);
assert(actorDesc.isValid());
NxActor *pActor = gScene->createActor(actorDesc);
assert(pActor);

// //create actor with no shapes
//NxShape* const *shape = pActor->getShapes();
//NxBoxShape *boxShape = shape[0]->isBox();
//assert(boxShape);
//pActor->releaseShape(*boxShape);

//NxVec3 forceVec1 = gForceStrength*NxVec3(1,0,0)*gDeltaTime;
//NxVec3 forceVec2 = gForceStrength*NxVec3(-1,0,0)*gDeltaTime;
NxVec3 forceVec3 = gForceStrength*NxVec3(0,1,0)*gDeltaTime;
//NxVec3 forceVec4 = gForceStrength*NxVec3(0,-1,0)*gDeltaTime;
//NxVec3 forceVec5 = gForceStrength*NxVec3(0,0,1)*gDeltaTime;
//NxVec3 forceVec6 = gForceStrength*NxVec3(0,0,-1)*gDeltaTime;

/*NxVec3 ApplyForceToActor(NxActor* actor, const NxVec3& forceDir, const NxReal forceStrength)
{
NxVec3 forceVec = forceStrength*forceDir*gDeltaTime;
return forceVec;
}
gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(1,0,0),gForceStrength)*/

return pActor;
}

NxActor* CreateSphere()
{
// Set the sphere starting height to 3.5m so box starts off falling onto the ground
NxReal sphereStartHeight = 3.5;

// Add a single-shape actor to the scene
NxActorDesc actorDesc;
NxBodyDesc bodyDesc;

// The actor has one shape, a sphere, 1m on radius
NxSphereShapeDesc sphereDesc;
sphereDesc.localPose.t	= NxVec3(0, 0, 0);

actorDesc.shapes.pushBack(&sphereDesc);
actorDesc.body			= &bodyDesc;
actorDesc.density		= 10.0f;
actorDesc.globalPose.t	= NxVec3(3.0f,sphereStartHeight,0);
return gScene->createActor(actorDesc);
}

NxActor* CreateCapsule()
{
// Set the capsule starting height to 3.5m so box starts off falling onto the ground
NxReal capsuleStartHeight = 3.5;

// Add a single-shape actor to the scene
NxActorDesc actorDesc;
NxBodyDesc bodyDesc;

// The actor has one shape, a sphere, 1m on radius
NxCapsuleShapeDesc capsuleDesc;
capsuleDesc.height		= 0.75f;
capsuleDesc.localPose.t = NxVec3(0, 0, 0);

//Rotate capsule shape
NxQuat quat(45, NxVec3(0, 0, 1));
NxMat33 m33(quat);
capsuleDesc.localPose.M = m33;

actorDesc.shapes.pushBack(&capsuleDesc);
actorDesc.body			= &bodyDesc;
actorDesc.density		= 10.0f;
actorDesc.globalPose.t	= NxVec3(6.0f,capsuleStartHeight,0);

////Rotate actor
//NxQuat quat1(45, NxVec3(1, 0, 0));
//NxMat33 m331(quat1);
//actorDesc.globalPose.M = m331;

return gScene->createActor(actorDesc);
}

void InitializeHUD()
{
bHardwareScene = (gScene->getSimType() == NX_SIMULATION_HW);

hud.Clear();

//if (bHardwareScene)
//else

if (bPause)
hud.AddDisplayString("Paused - Hit \"p\" to Unpause", 0.3f, 0.55f);
else
}

void InitNx()
{
// Initialize camera parameters
gCameraAspectRatio	= 1.0f;
gCameraPos			= NxVec3(0,5,-15);
gCameraForward		= NxVec3(0,0,1);
gCameraRight		= NxVec3(-1,0,0);

// Create the physics SDK
gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION);
if (!gPhysicsSDK)  return;
else if(gPhysicsSDK != NULL)
gPhysicsSDK->getFoundationSDK().getRemoteDebugger()->connect("localhost", 5425);

// Set the physics parameters
gPhysicsSDK->setParameter(NX_SKIN_WIDTH, 0.01);

// Set the debug visualization parameters
gPhysicsSDK->setParameter(NX_VISUALIZATION_SCALE, 1);
gPhysicsSDK->setParameter(NX_VISUALIZE_COLLISION_SHAPES, 1);
gPhysicsSDK->setParameter(NX_VISUALIZE_ACTOR_AXES, 1);

// Create the scene
NxSceneDesc sceneDesc;
sceneDesc.simType				= NX_SIMULATION_SW;
sceneDesc.gravity               = gDefaultGravity;
gScene = gPhysicsSDK->createScene(sceneDesc);
if(!gScene)
{
sceneDesc.simType			= NX_SIMULATION_SW;
gScene = gPhysicsSDK->createScene(sceneDesc);
if(!gScene) return;
}

// Create the default material
NxMaterial* defaultMaterial = gScene->getMaterialFromIndex(0);
defaultMaterial->setRestitution(0.5);
defaultMaterial->setStaticFriction(0.5);
defaultMaterial->setDynamicFriction(0.5);

// Create the objects in the scene
groundPlane		= CreateGroundPlane();
gSelectedActor	= CreateBox();
CreateBox();
CreateSphere();
CreateSphere();
//	CreateCapsule();

// Initialize HUD
InitializeHUD();

// Get the current time
UpdateTime();

// Start the first frame of the simulation
if (gScene)  StartPhysics();
}

void ReleaseNx()
{
if (gScene)
{
GetPhysicsResults();  // Make sure to fetchResults() before shutting down
gPhysicsSDK->releaseScene(*gScene);
}
if (gPhysicsSDK)  gPhysicsSDK->release();
}

void ResetNx()
{
ReleaseNx();
InitNx();
}

void StartPhysics()
{
// Update the time step
gDeltaTime = UpdateTime();

// Start collision and dynamics for delta time since the last frame
gScene->simulate(gDeltaTime);
gScene->flushStream();
}

void GetPhysicsResults()
{
// Get results from gScene->simulate(gDeltaTime)
while (!gScene->fetchResults(NX_RIGID_BODY_FINISHED, false));
}

int main(int argc, char** argv)
{
PrintControls();
InitGlut(argc, argv);
InitNx();
glutMainLoop();
ReleaseNx();
return 0;
}

```

### OpenGL and PhysiX library simulation problem

04 December 2011 - 03:51 PM

Hi everyone, i was wondering if you can help me out with a problem i am facing. Well i know that i am not good neither in opengl nor on physx, but i was eager to give it a try. What i was hoping to do is to make a simulation where there is a rectangular cuboid in the scene which has one side transparent(so we can see what's happening inside) and inside that rectangular there are two cubes and two spheres which are starting from an initial position and then forces are applied to those objects and they start collide with each other and the surrounding environment, in this case the rectangular cuboid. All i have done so far is take one sample of the physx sdk and add couple of lines to draw two cubes and two spheres. What i don't know is how to put those inside a rectangular cuboid and apply forces to them to make them collide. I have attached an image of what the simulation looks like now.
I could appreciate any kind of help at all. Thank you all and god bless you.

here is the code for the header files

Lesson101.h

```
#ifndef LESSON101_H
#define LESSON101_H

#include <GL/glut.h>

#include <stdio.h>

#include "NxPhysics.h"
#include "DrawObjects.h"
#include "HUD.h"

#include "DebugRenderer.h"
#include "CommonCode.h"

void PrintControls();
void ProcessCameraKeys();
void SetupCamera();
void DrawForce(NxActor* actor, NxVec3& forceVec, const NxVec3& color);

NxVec3 ApplyForceToActor(NxActor* actor, const NxVec3& forceDir, const NxReal forceStrength);
void ProcessForceKeys();
void ProcessInputs();
void SelectNextActor();
bool IsSelectable(NxActor* actor);

void RenderCallback();
void ReshapeCallback(int width, int height);
void IdleCallback();
void KeyboardCallback(unsigned char key, int x, int y);
void KeyboardUpCallback(unsigned char key, int x, int y);
void SpecialCallback(int key, int x, int y);
void MouseCallback(int button, int state, int x, int y);
void MotionCallback(int x, int y);
void ExitCallback();
void InitGlut(int argc, char** argv);

NxActor* CreateGroundPlane();
NxActor* CreateBox();
NxActor* CreateSphere();
NxActor* CreateCapsule();
NxActor* CreateBounds3();
NxActor* CreateSegment();
NxActor* CreateRay();

void InitializeHUD();

void InitNx();
void ReleaseNx();
void ResetNx();

void StartPhysics();
void GetPhysicsResults();

int main(int argc, char** argv);

#endif  // LESSON101_H

```

DrawObjects.h

```#ifndef DRAWOBJECTS_H
#define DRAWOBJECTS_H

class NxShape;
class NxActor;

void SetupGLMatrix(const NxVec3& pos, const NxMat33& orient);
void DrawLine(const NxVec3& p0, const NxVec3& p1, const NxVec3& color, float lineWidth=2.0f);
void DrawTriangle(const NxVec3& p0, const NxVec3& p1, const NxVec3& p2, const NxVec3& color);
void DrawCircle(NxU32 nbSegments, const NxMat34& matrix, const NxVec3& color, const NxF32 radius, const bool semicircle = false);
void DrawEllipse(NxU32 nbSegments, const NxMat34& matrix, const NxVec3& color, const NxF32 radius1, const NxF32 radius2, const bool semicircle = false);

void DrawWirePlane(NxShape* plane, const NxVec3& color);
void DrawPlane(NxShape* plane);

void DrawWireBox(NxShape* box, const NxVec3& color, float lineWidth=2.0f);
void DrawWireBox(const NxBox& obb, const NxVec3& color, float lineWidth=2.0f);
void DrawBox(NxShape* box);

void DrawWireSphere(NxShape* sphere, const NxVec3& color);
void DrawWireSphere(NxSphere* sphere, const NxVec3& color);
void DrawSphere(NxShape* sphere);

void DrawWireCapsule(NxShape* capsule, const NxVec3& color);
void DrawWireCapsule(const NxCapsule& capsule, const NxVec3& color);
void DrawCapsule(NxShape* capsule);
void DrawCapsule(const NxVec3& color, NxF32 r, NxF32 h);

void DrawWireConvex(NxShape* mesh, const NxVec3& color, bool useShapeUserData);
void DrawConvex(NxShape* mesh, bool useShapeUserData);

void DrawWireMesh(NxShape* mesh, const NxVec3& color, bool useShapeUserData);
void DrawMesh(NxShape* mesh, bool useShapeUserData);
void DrawWheelShape(NxShape* wheel);

void DrawArrow(const NxVec3& posA, const NxVec3& posB, const NxVec3& color);
void DrawContactPoint(const NxVec3& pos, const NxReal radius, const NxVec3& color);

void DrawWireShape(NxShape* shape, const NxVec3& color, bool useShapeUserData);
void DrawShape(NxShape* shape, bool useShapeUserData);
void DrawActor(NxActor* actor, NxActor* selectedActor, bool useShapeUserData);

void DrawActorShapeSelect(NxActor* actor, NxShape* shape, const bool shapeSelectMode, NxActor* selectedActor, bool useShapeUserData);

#endif  // DRAWOBJECTS_H

```

HUD.h

```#ifndef HUD_H
#define HUD_H

#include <GL/glut.h>
#include <stdio.h>

#include "NxPhysics.h"

class DisplayString
{
public:
char m_string[512];
NxReal m_xpos;
NxReal m_ypos;

DisplayString()
{
m_string[0]='\0';
m_ypos = m_xpos = 0;
}

void Set(char* s, NxReal x, NxReal y)
{
sprintf(m_string, s);
m_xpos = x;
m_ypos = y;
}
};

class HUD
{
public:
NxArray<DisplayString> m_DisplayString;

void AddDisplayString(char* s, NxReal x, NxReal y);
void SetDisplayString(NxU32 i, char* s, NxReal x, NxReal y);
void Clear();
void Render();
};
#endif  // HUD_H

```

here is the actual .cpp file Lesson101.cpp

```// ===============================================================================
//						  NVIDIA PHYSX SDK TRAINING PROGRAMS
//						     LESSON 101 : PRIMARY SHAPE
//
//						    Written by QA BJ, 6-2-2008
// ===============================================================================

#include "Lesson101.h"
#include "UpdateTime.h"

// Physics SDK globals
NxPhysicsSDK*     gPhysicsSDK = NULL;
NxScene*          gScene = NULL;
NxVec3            gDefaultGravity(0,-9.8,0);

// User report globals
DebugRenderer     gDebugRenderer;

// HUD globals
HUD hud;

// Display globals
int gMainHandle;
int mx = 0;
int my = 0;

// Camera globals
float	gCameraAspectRatio = 1.0f;
NxVec3	gCameraPos(0,5,-15);
NxVec3	gCameraForward(0,0,1);
NxVec3	gCameraRight(-1,0,0);
const NxReal gCameraSpeed = 10;

// Force globals
NxVec3	gForceVec(0,0,0);
NxReal	gForceStrength	= 20000;
bool	bForceMode		= true;

// Keyboard globals
#define MAX_KEYS 256
bool gKeys[MAX_KEYS];

// Simulation globals
NxReal	gDeltaTime			= 1.0/60.0;
bool	bHardwareScene		= false;
bool	bPause				= false;
bool	bDebugWireframeMode = false;

// Actor globals
NxActor* groundPlane = NULL;

// Focus actor
NxActor* gSelectedActor = NULL;

void PrintControls()
{
printf("\n Flight Controls:\n ----------------\n w = forward, s = back\n a = strafe left, d = strafe right\n q = up, z = down\n");
printf("\n Force Controls:\n ---------------\n i = +z, k = -z\n j = +x, l = -x\n u = +y, m = -y\n");
printf("\n Miscellaneous:\n --------------\n p   = Pause\n b   = Toggle Debug Wireframe Mode\n x   = Toggle Shadows\n r   = Select Actor\n F10 = Reset scene\n");
}

NxVec3 ApplyForceToActor(NxActor* actor, const NxVec3& forceDir, const NxReal forceStrength)
{
NxVec3 forceVec = forceStrength*forceDir*gDeltaTime;
return forceVec;
}

void ProcessCameraKeys()
{
NxReal deltaTime;

if (bPause)
{
deltaTime = 0.0005;
}
else
{
deltaTime = gDeltaTime;
}

// Process camera keys
for (int i = 0; i < MAX_KEYS; i++)
{
if (!gKeys[i])  { continue; }

switch (i)
{
// Camera controls
case 'w':{ gCameraPos += gCameraForward*gCameraSpeed*deltaTime; break; }
case 's':{ gCameraPos -= gCameraForward*gCameraSpeed*deltaTime; break; }
case 'a':{ gCameraPos -= gCameraRight*gCameraSpeed*deltaTime;	break; }
case 'd':{ gCameraPos += gCameraRight*gCameraSpeed*deltaTime;	break; }
case 'z':{ gCameraPos -= NxVec3(0,1,0)*gCameraSpeed*deltaTime;	break; }
case 'q':{ gCameraPos += NxVec3(0,1,0)*gCameraSpeed*deltaTime;	break; }
}
}
}

void SetupCamera()
{
gCameraAspectRatio = (float)glutGet(GLUT_WINDOW_WIDTH) / (float)glutGet(GLUT_WINDOW_HEIGHT);

// Setup camera
glMatrixMode(GL_PROJECTION);
gluPerspective(60.0f, gCameraAspectRatio, 1.0f, 10000.0f);
gluLookAt(gCameraPos.x,gCameraPos.y,gCameraPos.z,gCameraPos.x + gCameraForward.x, gCameraPos.y + gCameraForward.y, gCameraPos.z + gCameraForward.z, 0.0f, 1.0f, 0.0f);

glMatrixMode(GL_MODELVIEW);
}

{
// Render all the actors in the scene
NxU32 nbActors = gScene->getNbActors();
NxActor** actors = gScene->getActors();
while (nbActors--)
{
NxActor* actor = *actors++;
DrawActor(actor, gSelectedActor, false);

{
}
}
}

void DrawForce(NxActor* actor, NxVec3& forceVec, const NxVec3& color)
{
// Draw only if the force is large enough
NxReal force = forceVec.magnitude();
if (force < 0.1)  return;

forceVec = 3*forceVec/force;

NxVec3 pos = actor->getCMassGlobalPosition();
DrawArrow(pos, pos + forceVec, color);
}

bool IsSelectable(NxActor* actor)
{
NxShape*const* shapes = gSelectedActor->getShapes();
NxU32 nShapes = gSelectedActor->getNbShapes();
while (nShapes--)
{
if (shapes[nShapes]->getFlag(NX_TRIGGER_ENABLE))
{
return false;
}
}

if(!actor->isDynamic())
return false;

if (actor == groundPlane)
return false;

return true;
}

void SelectNextActor()
{
NxU32 nbActors = gScene->getNbActors();
NxActor** actors = gScene->getActors();
for(NxU32 i = 0; i < nbActors; i++)
{
if (actors[i] == gSelectedActor)
{
NxU32 j = 1;
gSelectedActor = actors[(i+j)%nbActors];
while (!IsSelectable(gSelectedActor))
{
j++;
gSelectedActor = actors[(i+j)%nbActors];
}
break;
}
}
}

void ProcessForceKeys()
{
// Process force keys
for (int i = 0; i < MAX_KEYS; i++)
{
if (!gKeys[i])  { continue; }

switch (i)
{
// Force controls
case 'i': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(0,0,1),gForceStrength);		break; }
case 'k': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(0,0,-1),gForceStrength);	break; }
case 'j': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(1,0,0),gForceStrength);		break; }
case 'l': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(-1,0,0),gForceStrength);	break; }
case 'u': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(0,1,0),gForceStrength);		break; }
case 'm': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(0,-1,0),gForceStrength);	break; }

// Return box to (0,5,0)
case 't':
{
if (gSelectedActor)
{
gSelectedActor->setGlobalPosition(NxVec3(0,5,0));
gScene->flushCaches();
}
break;
}
}
}
}

void ProcessInputs()
{
ProcessForceKeys();

// Show debug wireframes
if (bDebugWireframeMode)
{
if (gScene)  gDebugRenderer.renderData(*gScene->getDebugRenderable());
}
}

void RenderCallback()
{
// Clear buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

ProcessCameraKeys();
SetupCamera();

if (gScene && !bPause)
{
GetPhysicsResults();
ProcessInputs();
StartPhysics();
}

// Display scene

DrawForce(gSelectedActor, gForceVec, NxVec3(1,1,0));
gForceVec = NxVec3(0,0,0);

// Render the HUD
hud.Render();

glFlush();
glutSwapBuffers();
}

void ReshapeCallback(int width, int height)
{
glViewport(0, 0, width, height);
gCameraAspectRatio = float(width)/float(height);
}

void IdleCallback()
{
glutPostRedisplay();
}

void KeyboardCallback(unsigned char key, int x, int y)
{
gKeys[key] = true;

switch (key)
{
case 'r':	{ SelectNextActor(); break; }
default:	{ break; }
}
}

void KeyboardUpCallback(unsigned char key, int x, int y)
{
gKeys[key] = false;

switch (key)
{
case 'p':
{
bPause = !bPause;
if (bPause)
hud.SetDisplayString(0, "Paused - Hit \"p\" to Unpause", 0.3f, 0.55f);
else
hud.SetDisplayString(0, "", 0.0f, 0.0f);
UpdateTime();
break;
}
case 'b': { bDebugWireframeMode = !bDebugWireframeMode; break; }
case 27 : { exit(0); break; }
default : { break; }
}
}

void SpecialCallback(int key, int x, int y)
{
switch (key)
{
// Reset PhysX
case GLUT_KEY_F10: ResetNx(); return;
}
}

void MouseCallback(int button, int state, int x, int y)
{
mx = x;
my = y;
}

void MotionCallback(int x, int y)
{
int dx = mx - x;
int dy = my - y;

gCameraForward.normalize();
gCameraRight.cross(gCameraForward,NxVec3(0,1,0));

NxQuat qx(NxPiF32 * dx * 20 / 180.0f, NxVec3(0,1,0));
qx.rotate(gCameraForward);
NxQuat qy(NxPiF32 * dy * 20 / 180.0f, gCameraRight);
qy.rotate(gCameraForward);

mx = x;
my = y;
}

void ExitCallback()
{
ReleaseNx();
}

void InitGlut(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitWindowSize(900, 700);
glutInitWindowPosition(100,100);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
gMainHandle = glutCreateWindow("Primary Shape");
glutSetWindow(gMainHandle);
glutDisplayFunc(RenderCallback);
glutReshapeFunc(ReshapeCallback);
glutIdleFunc(IdleCallback);
glutKeyboardFunc(KeyboardCallback);
glutKeyboardUpFunc(KeyboardUpCallback);
glutSpecialFunc(SpecialCallback);
glutMouseFunc(MouseCallback);
glutMotionFunc(MotionCallback);
MotionCallback(0,0);
atexit(ExitCallback);

// Setup default render states
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_CULL_FACE);

// Setup lighting
glEnable(GL_LIGHTING);
float AmbientColor[]    = { 0.0f, 0.1f, 0.2f, 0.0f };         glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientColor);
float DiffuseColor[]    = { 0.2f, 0.2f, 0.2f, 0.0f };         glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseColor);
float SpecularColor[]   = { 0.5f, 0.5f, 0.5f, 0.0f };         glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularColor);
float Position[]        = { 100.0f, 100.0f, -400.0f, 1.0f };  glLightfv(GL_LIGHT0, GL_POSITION, Position);
glEnable(GL_LIGHT0);
}

NxActor* CreateGroundPlane()
{
// Create a plane with default descriptor
NxPlaneShapeDesc planeDesc;
NxActorDesc actorDesc;
actorDesc.shapes.pushBack(&planeDesc);
return gScene->createActor(actorDesc);
}

NxActor* CreateBox()
{
// Set the box starting height to 3.5m so box starts off falling onto the ground
NxReal boxStartHeight = 3.5;

// Add a single-shape actor to the scene
NxActorDesc actorDesc;
NxBodyDesc bodyDesc;

// The actor has one shape, a box, 1m on a side
NxBoxShapeDesc boxDesc;
boxDesc.dimensions.set(0.5,0.5,0.5);
boxDesc.localPose.t = NxVec3(0, 0, 0);
actorDesc.shapes.pushBack(&boxDesc);

actorDesc.body			= &bodyDesc;
actorDesc.density		= 10.0f;
actorDesc.globalPose.t	= NxVec3(0,boxStartHeight,0);
assert(actorDesc.isValid());
NxActor *pActor = gScene->createActor(actorDesc);
assert(pActor);

// //create actor with no shapes
//NxShape* const *shape = pActor->getShapes();
//NxBoxShape *boxShape = shape[0]->isBox();
//assert(boxShape);
//pActor->releaseShape(*boxShape);

//NxVec3 forceVec1 = gForceStrength*NxVec3(1,0,0)*gDeltaTime;
//NxVec3 forceVec2 = gForceStrength*NxVec3(-1,0,0)*gDeltaTime;
NxVec3 forceVec3 = gForceStrength*NxVec3(0,1,0)*gDeltaTime;
//NxVec3 forceVec4 = gForceStrength*NxVec3(0,-1,0)*gDeltaTime;
//NxVec3 forceVec5 = gForceStrength*NxVec3(0,0,1)*gDeltaTime;
//NxVec3 forceVec6 = gForceStrength*NxVec3(0,0,-1)*gDeltaTime;

/*NxVec3 ApplyForceToActor(NxActor* actor, const NxVec3& forceDir, const NxReal forceStrength)
{
NxVec3 forceVec = forceStrength*forceDir*gDeltaTime;
return forceVec;
}
gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(1,0,0),gForceStrength)*/

return pActor;
}

NxActor* CreateSphere()
{
// Set the sphere starting height to 3.5m so box starts off falling onto the ground
NxReal sphereStartHeight = 3.5;

// Add a single-shape actor to the scene
NxActorDesc actorDesc;
NxBodyDesc bodyDesc;

// The actor has one shape, a sphere, 1m on radius
NxSphereShapeDesc sphereDesc;
sphereDesc.localPose.t	= NxVec3(0, 0, 0);

actorDesc.shapes.pushBack(&sphereDesc);
actorDesc.body			= &bodyDesc;
actorDesc.density		= 10.0f;
actorDesc.globalPose.t	= NxVec3(3.0f,sphereStartHeight,0);
return gScene->createActor(actorDesc);
}

NxActor* CreateCapsule()
{
// Set the capsule starting height to 3.5m so box starts off falling onto the ground
NxReal capsuleStartHeight = 3.5;

// Add a single-shape actor to the scene
NxActorDesc actorDesc;
NxBodyDesc bodyDesc;

// The actor has one shape, a sphere, 1m on radius
NxCapsuleShapeDesc capsuleDesc;
capsuleDesc.height		= 0.75f;
capsuleDesc.localPose.t = NxVec3(0, 0, 0);

//Rotate capsule shape
NxQuat quat(45, NxVec3(0, 0, 1));
NxMat33 m33(quat);
capsuleDesc.localPose.M = m33;

actorDesc.shapes.pushBack(&capsuleDesc);
actorDesc.body			= &bodyDesc;
actorDesc.density		= 10.0f;
actorDesc.globalPose.t	= NxVec3(6.0f,capsuleStartHeight,0);

////Rotate actor
//NxQuat quat1(45, NxVec3(1, 0, 0));
//NxMat33 m331(quat1);
//actorDesc.globalPose.M = m331;

return gScene->createActor(actorDesc);
}

void InitializeHUD()
{
bHardwareScene = (gScene->getSimType() == NX_SIMULATION_HW);

hud.Clear();

//if (bHardwareScene)
//else

if (bPause)
hud.AddDisplayString("Paused - Hit \"p\" to Unpause", 0.3f, 0.55f);
else
}

void InitNx()
{
// Initialize camera parameters
gCameraAspectRatio	= 1.0f;
gCameraPos			= NxVec3(0,5,-15);
gCameraForward		= NxVec3(0,0,1);
gCameraRight		= NxVec3(-1,0,0);

// Create the physics SDK
gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION);
if (!gPhysicsSDK)  return;
else if(gPhysicsSDK != NULL)
gPhysicsSDK->getFoundationSDK().getRemoteDebugger()->connect("localhost", 5425);

// Set the physics parameters
gPhysicsSDK->setParameter(NX_SKIN_WIDTH, 0.01);

// Set the debug visualization parameters
gPhysicsSDK->setParameter(NX_VISUALIZATION_SCALE, 1);
gPhysicsSDK->setParameter(NX_VISUALIZE_COLLISION_SHAPES, 1);
gPhysicsSDK->setParameter(NX_VISUALIZE_ACTOR_AXES, 1);

// Create the scene
NxSceneDesc sceneDesc;
sceneDesc.simType				= NX_SIMULATION_SW;
sceneDesc.gravity               = gDefaultGravity;
gScene = gPhysicsSDK->createScene(sceneDesc);
if(!gScene)
{
sceneDesc.simType			= NX_SIMULATION_SW;
gScene = gPhysicsSDK->createScene(sceneDesc);
if(!gScene) return;
}

// Create the default material
NxMaterial* defaultMaterial = gScene->getMaterialFromIndex(0);
defaultMaterial->setRestitution(0.5);
defaultMaterial->setStaticFriction(0.5);
defaultMaterial->setDynamicFriction(0.5);

// Create the objects in the scene
groundPlane		= CreateGroundPlane();
gSelectedActor	= CreateBox();
CreateBox();
CreateSphere();
CreateSphere();
//	CreateCapsule();

// Initialize HUD
InitializeHUD();

// Get the current time
UpdateTime();

// Start the first frame of the simulation
if (gScene)  StartPhysics();
}

void ReleaseNx()
{
if (gScene)
{
GetPhysicsResults();  // Make sure to fetchResults() before shutting down
gPhysicsSDK->releaseScene(*gScene);
}
if (gPhysicsSDK)  gPhysicsSDK->release();
}

void ResetNx()
{
ReleaseNx();
InitNx();
}

void StartPhysics()
{
// Update the time step
gDeltaTime = UpdateTime();

// Start collision and dynamics for delta time since the last frame
gScene->simulate(gDeltaTime);
gScene->flushStream();
}

void GetPhysicsResults()
{
// Get results from gScene->simulate(gDeltaTime)
while (!gScene->fetchResults(NX_RIGID_BODY_FINISHED, false));
}

int main(int argc, char** argv)
{
PrintControls();
InitGlut(argc, argv);
InitNx();
glutMainLoop();
ReleaseNx();
return 0;
}

```

### OpenGL and PhysiX library simulation problem

04 December 2011 - 03:48 PM

Hi everyone, i was wondering if you can help me out with a problem i am facing. Well i know that i am not good neither in opengl nor on physx, but i was eager to give it a try. What i was hoping to do is to make a simulation where there is a rectangular cuboid in the scene which has one side transparent(so we can see what's happening inside) and inside that rectangular there are two cubes and two spheres which are starting from an initial position and then forces are applied to those objects and they start collide with each other and the surrounding environment, in this case the rectangular cuboid. All i have done so far is take one sample of the physx sdk and add couple of lines to draw two cubes and two spheres. What i don't know is how to put those inside a rectangular cuboid and apply forces to them to make them collide. I have attached an image of what the simulation looks like now.
I could appreciate any kind of help at all. Thank you all and god bless you.

here is the code for the header files

Lesson101.h

```
#ifndef LESSON101_H
#define LESSON101_H

#include <GL/glut.h>

#include <stdio.h>

#include "NxPhysics.h"
#include "DrawObjects.h"
#include "HUD.h"

#include "DebugRenderer.h"
#include "CommonCode.h"

void PrintControls();
void ProcessCameraKeys();
void SetupCamera();
void DrawForce(NxActor* actor, NxVec3& forceVec, const NxVec3& color);

NxVec3 ApplyForceToActor(NxActor* actor, const NxVec3& forceDir, const NxReal forceStrength);
void ProcessForceKeys();
void ProcessInputs();
void SelectNextActor();
bool IsSelectable(NxActor* actor);

void RenderCallback();
void ReshapeCallback(int width, int height);
void IdleCallback();
void KeyboardCallback(unsigned char key, int x, int y);
void KeyboardUpCallback(unsigned char key, int x, int y);
void SpecialCallback(int key, int x, int y);
void MouseCallback(int button, int state, int x, int y);
void MotionCallback(int x, int y);
void ExitCallback();
void InitGlut(int argc, char** argv);

NxActor* CreateGroundPlane();
NxActor* CreateBox();
NxActor* CreateSphere();
NxActor* CreateCapsule();
NxActor* CreateBounds3();
NxActor* CreateSegment();
NxActor* CreateRay();

void InitializeHUD();

void InitNx();
void ReleaseNx();
void ResetNx();

void StartPhysics();
void GetPhysicsResults();

int main(int argc, char** argv);

#endif  // LESSON101_H

```

DrawObjects.h

```#ifndef DRAWOBJECTS_H
#define DRAWOBJECTS_H

class NxShape;
class NxActor;

void SetupGLMatrix(const NxVec3& pos, const NxMat33& orient);
void DrawLine(const NxVec3& p0, const NxVec3& p1, const NxVec3& color, float lineWidth=2.0f);
void DrawTriangle(const NxVec3& p0, const NxVec3& p1, const NxVec3& p2, const NxVec3& color);
void DrawCircle(NxU32 nbSegments, const NxMat34& matrix, const NxVec3& color, const NxF32 radius, const bool semicircle = false);
void DrawEllipse(NxU32 nbSegments, const NxMat34& matrix, const NxVec3& color, const NxF32 radius1, const NxF32 radius2, const bool semicircle = false);

void DrawWirePlane(NxShape* plane, const NxVec3& color);
void DrawPlane(NxShape* plane);

void DrawWireBox(NxShape* box, const NxVec3& color, float lineWidth=2.0f);
void DrawWireBox(const NxBox& obb, const NxVec3& color, float lineWidth=2.0f);
void DrawBox(NxShape* box);

void DrawWireSphere(NxShape* sphere, const NxVec3& color);
void DrawWireSphere(NxSphere* sphere, const NxVec3& color);
void DrawSphere(NxShape* sphere);

void DrawWireCapsule(NxShape* capsule, const NxVec3& color);
void DrawWireCapsule(const NxCapsule& capsule, const NxVec3& color);
void DrawCapsule(NxShape* capsule);
void DrawCapsule(const NxVec3& color, NxF32 r, NxF32 h);

void DrawWireConvex(NxShape* mesh, const NxVec3& color, bool useShapeUserData);
void DrawConvex(NxShape* mesh, bool useShapeUserData);

void DrawWireMesh(NxShape* mesh, const NxVec3& color, bool useShapeUserData);
void DrawMesh(NxShape* mesh, bool useShapeUserData);
void DrawWheelShape(NxShape* wheel);

void DrawArrow(const NxVec3& posA, const NxVec3& posB, const NxVec3& color);
void DrawContactPoint(const NxVec3& pos, const NxReal radius, const NxVec3& color);

void DrawWireShape(NxShape* shape, const NxVec3& color, bool useShapeUserData);
void DrawShape(NxShape* shape, bool useShapeUserData);
void DrawActor(NxActor* actor, NxActor* selectedActor, bool useShapeUserData);

void DrawActorShapeSelect(NxActor* actor, NxShape* shape, const bool shapeSelectMode, NxActor* selectedActor, bool useShapeUserData);

#endif  // DRAWOBJECTS_H

```

HUD.h

```#ifndef HUD_H
#define HUD_H

#include <GL/glut.h>
#include <stdio.h>

#include "NxPhysics.h"

class DisplayString
{
public:
char m_string[512];
NxReal m_xpos;
NxReal m_ypos;

DisplayString()
{
m_string[0]='\0';
m_ypos = m_xpos = 0;
}

void Set(char* s, NxReal x, NxReal y)
{
sprintf(m_string, s);
m_xpos = x;
m_ypos = y;
}
};

class HUD
{
public:
NxArray<DisplayString> m_DisplayString;

void AddDisplayString(char* s, NxReal x, NxReal y);
void SetDisplayString(NxU32 i, char* s, NxReal x, NxReal y);
void Clear();
void Render();
};
#endif  // HUD_H

```

here is the actual .cpp file Lesson101.cpp

```// ===============================================================================
//						  NVIDIA PHYSX SDK TRAINING PROGRAMS
//						     LESSON 101 : PRIMARY SHAPE
//
//						    Written by QA BJ, 6-2-2008
// ===============================================================================

#include "Lesson101.h"
#include "UpdateTime.h"

// Physics SDK globals
NxPhysicsSDK*     gPhysicsSDK = NULL;
NxScene*          gScene = NULL;
NxVec3            gDefaultGravity(0,-9.8,0);

// User report globals
DebugRenderer     gDebugRenderer;

// HUD globals
HUD hud;

// Display globals
int gMainHandle;
int mx = 0;
int my = 0;

// Camera globals
float	gCameraAspectRatio = 1.0f;
NxVec3	gCameraPos(0,5,-15);
NxVec3	gCameraForward(0,0,1);
NxVec3	gCameraRight(-1,0,0);
const NxReal gCameraSpeed = 10;

// Force globals
NxVec3	gForceVec(0,0,0);
NxReal	gForceStrength	= 20000;
bool	bForceMode		= true;

// Keyboard globals
#define MAX_KEYS 256
bool gKeys[MAX_KEYS];

// Simulation globals
NxReal	gDeltaTime			= 1.0/60.0;
bool	bHardwareScene		= false;
bool	bPause				= false;
bool	bDebugWireframeMode = false;

// Actor globals
NxActor* groundPlane = NULL;

// Focus actor
NxActor* gSelectedActor = NULL;

void PrintControls()
{
printf("\n Flight Controls:\n ----------------\n w = forward, s = back\n a = strafe left, d = strafe right\n q = up, z = down\n");
printf("\n Force Controls:\n ---------------\n i = +z, k = -z\n j = +x, l = -x\n u = +y, m = -y\n");
printf("\n Miscellaneous:\n --------------\n p   = Pause\n b   = Toggle Debug Wireframe Mode\n x   = Toggle Shadows\n r   = Select Actor\n F10 = Reset scene\n");
}

NxVec3 ApplyForceToActor(NxActor* actor, const NxVec3& forceDir, const NxReal forceStrength)
{
NxVec3 forceVec = forceStrength*forceDir*gDeltaTime;
return forceVec;
}

void ProcessCameraKeys()
{
NxReal deltaTime;

if (bPause)
{
deltaTime = 0.0005;
}
else
{
deltaTime = gDeltaTime;
}

// Process camera keys
for (int i = 0; i < MAX_KEYS; i++)
{
if (!gKeys[i])  { continue; }

switch (i)
{
// Camera controls
case 'w':{ gCameraPos += gCameraForward*gCameraSpeed*deltaTime; break; }
case 's':{ gCameraPos -= gCameraForward*gCameraSpeed*deltaTime; break; }
case 'a':{ gCameraPos -= gCameraRight*gCameraSpeed*deltaTime;	break; }
case 'd':{ gCameraPos += gCameraRight*gCameraSpeed*deltaTime;	break; }
case 'z':{ gCameraPos -= NxVec3(0,1,0)*gCameraSpeed*deltaTime;	break; }
case 'q':{ gCameraPos += NxVec3(0,1,0)*gCameraSpeed*deltaTime;	break; }
}
}
}

void SetupCamera()
{
gCameraAspectRatio = (float)glutGet(GLUT_WINDOW_WIDTH) / (float)glutGet(GLUT_WINDOW_HEIGHT);

// Setup camera
glMatrixMode(GL_PROJECTION);
gluPerspective(60.0f, gCameraAspectRatio, 1.0f, 10000.0f);
gluLookAt(gCameraPos.x,gCameraPos.y,gCameraPos.z,gCameraPos.x + gCameraForward.x, gCameraPos.y + gCameraForward.y, gCameraPos.z + gCameraForward.z, 0.0f, 1.0f, 0.0f);

glMatrixMode(GL_MODELVIEW);
}

{
// Render all the actors in the scene
NxU32 nbActors = gScene->getNbActors();
NxActor** actors = gScene->getActors();
while (nbActors--)
{
NxActor* actor = *actors++;
DrawActor(actor, gSelectedActor, false);

{
}
}
}

void DrawForce(NxActor* actor, NxVec3& forceVec, const NxVec3& color)
{
// Draw only if the force is large enough
NxReal force = forceVec.magnitude();
if (force < 0.1)  return;

forceVec = 3*forceVec/force;

NxVec3 pos = actor->getCMassGlobalPosition();
DrawArrow(pos, pos + forceVec, color);
}

bool IsSelectable(NxActor* actor)
{
NxShape*const* shapes = gSelectedActor->getShapes();
NxU32 nShapes = gSelectedActor->getNbShapes();
while (nShapes--)
{
if (shapes[nShapes]->getFlag(NX_TRIGGER_ENABLE))
{
return false;
}
}

if(!actor->isDynamic())
return false;

if (actor == groundPlane)
return false;

return true;
}

void SelectNextActor()
{
NxU32 nbActors = gScene->getNbActors();
NxActor** actors = gScene->getActors();
for(NxU32 i = 0; i < nbActors; i++)
{
if (actors[i] == gSelectedActor)
{
NxU32 j = 1;
gSelectedActor = actors[(i+j)%nbActors];
while (!IsSelectable(gSelectedActor))
{
j++;
gSelectedActor = actors[(i+j)%nbActors];
}
break;
}
}
}

void ProcessForceKeys()
{
// Process force keys
for (int i = 0; i < MAX_KEYS; i++)
{
if (!gKeys[i])  { continue; }

switch (i)
{
// Force controls
case 'i': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(0,0,1),gForceStrength);		break; }
case 'k': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(0,0,-1),gForceStrength);	break; }
case 'j': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(1,0,0),gForceStrength);		break; }
case 'l': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(-1,0,0),gForceStrength);	break; }
case 'u': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(0,1,0),gForceStrength);		break; }
case 'm': { gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(0,-1,0),gForceStrength);	break; }

// Return box to (0,5,0)
case 't':
{
if (gSelectedActor)
{
gSelectedActor->setGlobalPosition(NxVec3(0,5,0));
gScene->flushCaches();
}
break;
}
}
}
}

void ProcessInputs()
{
ProcessForceKeys();

// Show debug wireframes
if (bDebugWireframeMode)
{
if (gScene)  gDebugRenderer.renderData(*gScene->getDebugRenderable());
}
}

void RenderCallback()
{
// Clear buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

ProcessCameraKeys();
SetupCamera();

if (gScene && !bPause)
{
GetPhysicsResults();
ProcessInputs();
StartPhysics();
}

// Display scene

DrawForce(gSelectedActor, gForceVec, NxVec3(1,1,0));
gForceVec = NxVec3(0,0,0);

// Render the HUD
hud.Render();

glFlush();
glutSwapBuffers();
}

void ReshapeCallback(int width, int height)
{
glViewport(0, 0, width, height);
gCameraAspectRatio = float(width)/float(height);
}

void IdleCallback()
{
glutPostRedisplay();
}

void KeyboardCallback(unsigned char key, int x, int y)
{
gKeys[key] = true;

switch (key)
{
case 'r':	{ SelectNextActor(); break; }
default:	{ break; }
}
}

void KeyboardUpCallback(unsigned char key, int x, int y)
{
gKeys[key] = false;

switch (key)
{
case 'p':
{
bPause = !bPause;
if (bPause)
hud.SetDisplayString(0, "Paused - Hit \"p\" to Unpause", 0.3f, 0.55f);
else
hud.SetDisplayString(0, "", 0.0f, 0.0f);
UpdateTime();
break;
}
case 'b': { bDebugWireframeMode = !bDebugWireframeMode; break; }
case 27 : { exit(0); break; }
default : { break; }
}
}

void SpecialCallback(int key, int x, int y)
{
switch (key)
{
// Reset PhysX
case GLUT_KEY_F10: ResetNx(); return;
}
}

void MouseCallback(int button, int state, int x, int y)
{
mx = x;
my = y;
}

void MotionCallback(int x, int y)
{
int dx = mx - x;
int dy = my - y;

gCameraForward.normalize();
gCameraRight.cross(gCameraForward,NxVec3(0,1,0));

NxQuat qx(NxPiF32 * dx * 20 / 180.0f, NxVec3(0,1,0));
qx.rotate(gCameraForward);
NxQuat qy(NxPiF32 * dy * 20 / 180.0f, gCameraRight);
qy.rotate(gCameraForward);

mx = x;
my = y;
}

void ExitCallback()
{
ReleaseNx();
}

void InitGlut(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitWindowSize(900, 700);
glutInitWindowPosition(100,100);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
gMainHandle = glutCreateWindow("Primary Shape");
glutSetWindow(gMainHandle);
glutDisplayFunc(RenderCallback);
glutReshapeFunc(ReshapeCallback);
glutIdleFunc(IdleCallback);
glutKeyboardFunc(KeyboardCallback);
glutKeyboardUpFunc(KeyboardUpCallback);
glutSpecialFunc(SpecialCallback);
glutMouseFunc(MouseCallback);
glutMotionFunc(MotionCallback);
MotionCallback(0,0);
atexit(ExitCallback);

// Setup default render states
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_DEPTH_TEST);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_CULL_FACE);

// Setup lighting
glEnable(GL_LIGHTING);
float AmbientColor[]    = { 0.0f, 0.1f, 0.2f, 0.0f };         glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientColor);
float DiffuseColor[]    = { 0.2f, 0.2f, 0.2f, 0.0f };         glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseColor);
float SpecularColor[]   = { 0.5f, 0.5f, 0.5f, 0.0f };         glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularColor);
float Position[]        = { 100.0f, 100.0f, -400.0f, 1.0f };  glLightfv(GL_LIGHT0, GL_POSITION, Position);
glEnable(GL_LIGHT0);
}

NxActor* CreateGroundPlane()
{
// Create a plane with default descriptor
NxPlaneShapeDesc planeDesc;
NxActorDesc actorDesc;
actorDesc.shapes.pushBack(&planeDesc);
return gScene->createActor(actorDesc);
}

NxActor* CreateBox()
{
// Set the box starting height to 3.5m so box starts off falling onto the ground
NxReal boxStartHeight = 3.5;

// Add a single-shape actor to the scene
NxActorDesc actorDesc;
NxBodyDesc bodyDesc;

// The actor has one shape, a box, 1m on a side
NxBoxShapeDesc boxDesc;
boxDesc.dimensions.set(0.5,0.5,0.5);
boxDesc.localPose.t = NxVec3(0, 0, 0);
actorDesc.shapes.pushBack(&boxDesc);

actorDesc.body			= &bodyDesc;
actorDesc.density		= 10.0f;
actorDesc.globalPose.t	= NxVec3(0,boxStartHeight,0);
assert(actorDesc.isValid());
NxActor *pActor = gScene->createActor(actorDesc);
assert(pActor);

// //create actor with no shapes
//NxShape* const *shape = pActor->getShapes();
//NxBoxShape *boxShape = shape[0]->isBox();
//assert(boxShape);
//pActor->releaseShape(*boxShape);

//NxVec3 forceVec1 = gForceStrength*NxVec3(1,0,0)*gDeltaTime;
//NxVec3 forceVec2 = gForceStrength*NxVec3(-1,0,0)*gDeltaTime;
NxVec3 forceVec3 = gForceStrength*NxVec3(0,1,0)*gDeltaTime;
//NxVec3 forceVec4 = gForceStrength*NxVec3(0,-1,0)*gDeltaTime;
//NxVec3 forceVec5 = gForceStrength*NxVec3(0,0,1)*gDeltaTime;
//NxVec3 forceVec6 = gForceStrength*NxVec3(0,0,-1)*gDeltaTime;

/*NxVec3 ApplyForceToActor(NxActor* actor, const NxVec3& forceDir, const NxReal forceStrength)
{
NxVec3 forceVec = forceStrength*forceDir*gDeltaTime;
return forceVec;
}
gForceVec = ApplyForceToActor(gSelectedActor,NxVec3(1,0,0),gForceStrength)*/

return pActor;
}

NxActor* CreateSphere()
{
// Set the sphere starting height to 3.5m so box starts off falling onto the ground
NxReal sphereStartHeight = 3.5;

// Add a single-shape actor to the scene
NxActorDesc actorDesc;
NxBodyDesc bodyDesc;

// The actor has one shape, a sphere, 1m on radius
NxSphereShapeDesc sphereDesc;
sphereDesc.localPose.t	= NxVec3(0, 0, 0);

actorDesc.shapes.pushBack(&sphereDesc);
actorDesc.body			= &bodyDesc;
actorDesc.density		= 10.0f;
actorDesc.globalPose.t	= NxVec3(3.0f,sphereStartHeight,0);
return gScene->createActor(actorDesc);
}

NxActor* CreateCapsule()
{
// Set the capsule starting height to 3.5m so box starts off falling onto the ground
NxReal capsuleStartHeight = 3.5;

// Add a single-shape actor to the scene
NxActorDesc actorDesc;
NxBodyDesc bodyDesc;

// The actor has one shape, a sphere, 1m on radius
NxCapsuleShapeDesc capsuleDesc;
capsuleDesc.height		= 0.75f;
capsuleDesc.localPose.t = NxVec3(0, 0, 0);

//Rotate capsule shape
NxQuat quat(45, NxVec3(0, 0, 1));
NxMat33 m33(quat);
capsuleDesc.localPose.M = m33;

actorDesc.shapes.pushBack(&capsuleDesc);
actorDesc.body			= &bodyDesc;
actorDesc.density		= 10.0f;
actorDesc.globalPose.t	= NxVec3(6.0f,capsuleStartHeight,0);

////Rotate actor
//NxQuat quat1(45, NxVec3(1, 0, 0));
//NxMat33 m331(quat1);
//actorDesc.globalPose.M = m331;

return gScene->createActor(actorDesc);
}

void InitializeHUD()
{
bHardwareScene = (gScene->getSimType() == NX_SIMULATION_HW);

hud.Clear();

//if (bHardwareScene)
//else

if (bPause)
hud.AddDisplayString("Paused - Hit \"p\" to Unpause", 0.3f, 0.55f);
else
}

void InitNx()
{
// Initialize camera parameters
gCameraAspectRatio	= 1.0f;
gCameraPos			= NxVec3(0,5,-15);
gCameraForward		= NxVec3(0,0,1);
gCameraRight		= NxVec3(-1,0,0);

// Create the physics SDK
gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION);
if (!gPhysicsSDK)  return;
else if(gPhysicsSDK != NULL)
gPhysicsSDK->getFoundationSDK().getRemoteDebugger()->connect("localhost", 5425);

// Set the physics parameters
gPhysicsSDK->setParameter(NX_SKIN_WIDTH, 0.01);

// Set the debug visualization parameters
gPhysicsSDK->setParameter(NX_VISUALIZATION_SCALE, 1);
gPhysicsSDK->setParameter(NX_VISUALIZE_COLLISION_SHAPES, 1);
gPhysicsSDK->setParameter(NX_VISUALIZE_ACTOR_AXES, 1);

// Create the scene
NxSceneDesc sceneDesc;
sceneDesc.simType				= NX_SIMULATION_SW;
sceneDesc.gravity               = gDefaultGravity;
gScene = gPhysicsSDK->createScene(sceneDesc);
if(!gScene)
{
sceneDesc.simType			= NX_SIMULATION_SW;
gScene = gPhysicsSDK->createScene(sceneDesc);
if(!gScene) return;
}

// Create the default material
NxMaterial* defaultMaterial = gScene->getMaterialFromIndex(0);
defaultMaterial->setRestitution(0.5);
defaultMaterial->setStaticFriction(0.5);
defaultMaterial->setDynamicFriction(0.5);

// Create the objects in the scene
groundPlane		= CreateGroundPlane();
gSelectedActor	= CreateBox();
CreateBox();
CreateSphere();
CreateSphere();
//	CreateCapsule();

// Initialize HUD
InitializeHUD();

// Get the current time
UpdateTime();

// Start the first frame of the simulation
if (gScene)  StartPhysics();
}

void ReleaseNx()
{
if (gScene)
{
GetPhysicsResults();  // Make sure to fetchResults() before shutting down
gPhysicsSDK->releaseScene(*gScene);
}
if (gPhysicsSDK)  gPhysicsSDK->release();
}

void ResetNx()
{
ReleaseNx();
InitNx();
}

void StartPhysics()
{
// Update the time step
gDeltaTime = UpdateTime();

// Start collision and dynamics for delta time since the last frame
gScene->simulate(gDeltaTime);
gScene->flushStream();
}

void GetPhysicsResults()
{
// Get results from gScene->simulate(gDeltaTime)
while (!gScene->fetchResults(NX_RIGID_BODY_FINISHED, false));
}

int main(int argc, char** argv)
{
PrintControls();
InitGlut(argc, argv);
InitNx();
glutMainLoop();
ReleaseNx();
return 0;
}

```

PARTNERS