Physics Engines AGEIA PhysX SDK - UFPE
Transcript of Physics Engines AGEIA PhysX SDK - UFPE
25/3/2008
1
Virtual Reality
and Multimedia
Research Group
Tutorial
AGEIA PhysX
SVR2007
Thiago Souto MaiorDaliton Silva
Guilherme MouraMárcio Bueno
Veronica TeichriebJudith Kelner
{ mouse, ds2, gsm, masb, vt, jk } @cin.ufpe.br
Petrópolis, May 2007
Introduction
• What does physics give?
– Real world interaction metaphor
– Realistic simulation
• Who needs physics?
– Immersive games and applications
• How to use this?
– Through physics engines implemented in software or hardware
Physics Engines
• Simplified Newtonian models
• “High precision” versus “real time” simulations
• Commercial and open source engines
• What comes together in a physics engine?– Mandatory
• Tons of math calculations
• Collision detection
• Rigid body dynamics
– Optional• Fluid dynamics
• Cloth simulation
• Particle systems
• Deformable object dynamics
AGEIA PhysX SDK
• Based upon NovodeX API
• Middleware concept
• First asynchronous physics API
• Takes advantage of multiprocessing game systems
AGEIA PhysX SDK
• Supports game development life cycle
– 3DSMax and Maya plugins (PhysX Create)
– Properties tuning with PhysX Rocket
– Visual remote debugging with PhysX VRD
AGEIA PhysX SDK
• Integration with game engines
– Unreal Engine 3.0
– Emergent GameBryo
– Natural Motion Endorphin
• Runs in PC, Xbox 360 and PS3
25/3/2008
2
AGEIA PhysX SDK
• Supports
– Complex rigid body dynamics
– Collision detection
– Joints and springs
– Volumetric fluid simulation
– Particle systems
– Cloth simulation
– Soft body simulation
AGEIA PhysX Processor
• AGEIA PhysX PPU
• Powerful PPU + CPU + GPU
– Physics + Math + Fast Rendering
Other Physics Engines
• Open source
– Open Dynamics Engine (ODE)
– Bullet Physics Library
• Free
– TOKAMAK
– Newton
• Commercial
– Havok FX
Download
• Account registration required
• http://devsupport.ageia.com
• 1-3 business days
Download
• Download section
• SDK version selection
Download
• AGEIA Driver
• System Software
25/3/2008
3
License
• Free license
– Non-commercial use
– PS3 platform (through Sony pre-purchase)
– Through some middleware partnerships
• UE3, Gamebryo 2.2, etc
– PC platform (if makes use* of PhysX HW)
• $50k per platform
– All other uses
Installation
• System requirements
– Windows XP or Vista
• Most recent Service Pack
– 512MB of system memory
– At least 150MB of free HD space
– PCI expansion slot for PPU
– Additional 4-pin molex power connector
Installation
• PPU Driver and System Software
– Run samples
• PhysX SDK Core
– Header and lib files
– Documentation
Documentation
• Documents
– Windows help file containing PhysX API
• Samples
– Source codes and executables covering most of PhysX features
• Training Programs
– Documents,
overview and
source code
Architecture & Components
World (PhysX SDK)
Architecture: World
NxPhysicsSDK * myWorld =
NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION);
25/3/2008
4
Architecture: Scene
• Scene
– Collection of every interactive element
• Bodies
• Constraints
• Effectors
Architecture: Actor
• Actor
– Main simulation object
• Dynamic
• Static
NxPlaneShapeDesc planeDesc;
NxActorDesc actorDesc;
actorDesc.shapes.pushBack(&planeDesc);
NxActor *staticActor = gScene->createActor(actorDesc);
Architecture: Shapes
• Shapes
Architecture: Shapes
• Box Shape
NxBoxShapeDesc boxDesc;
boxDesc.dimensions.set(0.5f, 0.5f, 0.5f);
NxBoxShape *boxShape = actor->createShape(boxDesc)->isBox();
Architecture: Shapes
• Capsule Shape
– Defined by a radius and a height
NxCapsuleShapeDesc capsuleDesc;
capsuleDesc.height = 2.0f;
capsuleDesc.radius = 0.5f;
NxCapsuleShape
*capsuleShape=actor->createShape(capsuleDesc)->isCapsule();
Architecture: Shapes
• Convex Shape
– Shape defined by a set of vertices
25/3/2008
5
Architecture: Shapes
NxVec3 verts[8] = { NxVec3(-1,-1,-1),NxVec3(-1,-1,1),
NxVec3(-1,1,-1),NxVec3(-1,1,1),
NxVec3(1,-1,-1),NxVec3(1,-1,1),
NxVec3(1,1,-1),NxVec3(1,1,1) };
NxU32 vertCount = 8;
NxConvexMeshDesc convexDesc;
convexDesc.numVertices = vertCount;
convexDesc.pointStrideBytes = sizeof(NxVec3);
convexDesc.points = verts;
convexDesc.flags = NX_CF_COMPUTE_CONVEX;
MemoryWriteBuffer buf;
bool status = NxCookConvexMesh(convexDesc, buf);
NxConvexMesh *mesh = gPhysicsSDK->createConvexMesh(MemoryReadBuffer(buf.data));
NxConvexShapeDesc convexShapeDesc;
convexShapeDesc.meshData = mesh;
NxConvexShape *convexShape=actor->createShape(convexShapeDesc)->isConvex();
Architecture: Shapes
• Height Field Shape
– Height Field Map to generate a collision terrain
Architecture: ShapesNxHeightFieldDesc heightFieldDesc;
heightFieldDesc.nbColumns = nbColumns;
heightFieldDesc.nbRows = nbRows;
heightFieldDesc.verticalExtent = -1000;
heightFieldDesc.convexEdgeThreshold = 0;
heightFieldDesc.samples = new NxU32[nbColumns*nbRows];
heightFieldDesc.sampleStride = sizeof(NxU32);
NxU8* currentByte = (NxU8*)heightFieldDesc.samples;
for (NxU32 row = 0; row < nbRows; row++)
{
for (NxU32 column = 0; column < nbColumns; column++)
{
NxHeightFieldSample* currentSample = (NxHeightFieldSample*)currentByte;
currentSample->height = computeHeight(row,column);
currentSample->materialIndex0 = gMaterial0;
currentSample->materialIndex1 = gMaterial1;
currentSample->tessFlag = 0;
currentByte += heightFieldDesc.sampleStride;
}
}
NxHeightField* heightField = gScene->getPhysicsSDK().createHeightField(heightFieldDesc);
Architecture: Shapes
NxHeightFieldShapeDesc heightFieldShapeDesc;
heightFieldShapeDesc.heightField = heightField;
heightFieldShapeDesc.heightScale = gVerticalScale;
heightFieldShapeDesc.rowScale = gHorizontalScale;
heightFieldShapeDesc.columnScale = gHorizontalScale;
heightFieldShapeDesc.holeMaterial = 2;
NxHeightFieldShape
*heightFieldShape=
actor->createShape(heightFieldShapeDesc)->isHeightField();
Architecture: Shapes
• Plane Shape
– Default: y = 0
– Defined by a Normal and the distance from the origin
NxPlaneShapeDesc planeDesc;
planeDesc.normal = NxVec3(0.0f,1.0f,0.0f);
planeDesc.d = 10.0f;
NxPlaneShape
*planeShape=actor->createShape(planeDesc)->isPlane();
Architecture: Shapes
• Sphere Shape
– Defined by
a radius
NxSphereShapeDesc sphereDesc;
sphereDesc.radius = 1.0f;
NxSphereShape
*sphereShape=actor->createShape(sphereDesc)->isSphere();
25/3/2008
6
Architecture: Shapes
• Triangle Mesh Shape
NxTriangleMeshShapeDesc meshShapeDesc;
meshShapeDesc.meshData = triangleMesh;
NxTriangleMeshShape *triangleMeshShape=
actor->createShape(meshShapeDesc)->isTriangleMesh();
Architecture: Shapes
• Wheel Shape– Radius
– Suspension travel
– Motor torque
– Brake torque
– Steer angle
– Raycast from shape’s
origin along the axis• Hard contact
• Soft suspension
• No contact
Architecture: Joints
• Joints
– Connections between rigid bodies
Architecture: Materials
• Materials
– Shape surface properties
• Friction
• Restitution
Architecture: Materials
NxMaterialDesc material;
material.restitution = 0.0f;
material.staticFriction = 0.1f;
material.dynamicFriction = 0.1f;
material.dynamicFrictionV = 0.8f;
material.staticFrictionV = 1.0f;
material.dirOfAnisotropy.set(0,0,1);
material.flags = NX_MF_ANISOTROPIC;
NxMaterial *anisoMaterial =
gScene->createMaterial(material);
NxMaterial* defaultMaterial =
gScene->getMaterialFromIndex(0);
defaultMaterial->setRestitution(0.5);
defaultMaterial->setStaticFriction(0.5);
defaultMaterial->setDynamicFriction(0.5);
Anisotropicmaterial
Defaultmaterial
Mathematical Support
• Based on
– NxMath
– NxMat33
– NxMat34
– NxVec3
– NxQuat
• Storage format independent
– According to row or column major
25/3/2008
7
NxMath
• Container of static math operations
• Conversion between degrees and radians
• Functions
– min, max, floor, ceil, sqrt
– Logarithm functions in common bases
– Trigonometric functions
– Some constants like NxPi, NxHalfPi, NxTwoPi and NxInvPi
NxMat33
• Abstraction to 3x3 matrix
• Represent rotations or inertia tensors
• Implements operators
– Sum and subtraction (+/-)
– Matrix and scalar product (*)
• Other operations like inverting and transposing are also available
NxMat33
• Example
– Given a vector in world space, how to transform it into local space?
NxVec3 localVec, worldVec;
NxMat33 orient, invOrient;
worldVec = NxVec3(0,0,1);
orient = actor->getGlobalOrientation();
orient.getInverse(invOrient);
localVec = invOrient * worldVec;
NxMat34
• Wrapper class encapsulates
– NxMat33 (rotation)
– NxVec3 (translation)
• Public attributes: M and t
• Conversions to 4x4 rendering matrix formats
• Operator product (*)
NxMat34
• Example
– Given a position in the world space, how to transform it into the local space?
NxActor* actor;
...
NxVec3 localPos, worldPos;
NxMat34 mat, invMat;
worldPos = NxVec3(0,0,1);
mat = actor->getGlobalPose();
mat.getInverse(invMat);
localPos = invMat * worldPos;
NxVec3
• Can represent a point or a vector
• Attributes: x, y, z
• Direct or array-like access
• Implements vectors’ arithmetic, including cross product, dot product and others operations related to vectors
25/3/2008
8
NxQuat
• Quaternion representation• Hamiltonian Arithmetic• Attributes: x, y, z, w• Used to represent a rotation
– Axis and angle
• Concatenation through product (*), like matrixes• Rotations can be applied to points and vectors
– rot method
• Interpolation between two orientations– Slerp– Quaternion is used as keyframe
NxQuat
• Example
– How to transform a quaternion into its correspondent 3x3 matrix?
NxQuat q;
q.fromAngleAxis(90, NxVec3(0,1,0));
...
NxMat33 orient;
orient.fromQuat(q);
Scene
• Declaring variables
static NxPhysicsSDK* gPhysicsSDK = NULL;
static NxScene* gScene = NULL;
static NxVec3 gDefaultGravity(0.0f, -98.1f, 0.0f);
static ErrorStream gErrorStream;
Scene
• Initializing the World
gPhysicsSDK =
NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION, NULL, &gErrorStream);
Scene
• Setting DEBUG information
// setParameter(VISUALIZATION_TYPE, TRUE|FALSE);
gPhysicsSDK->setParameter(NX_VISUALIZE_COLLISION_SHAPES, 1);
Scene
• Creating the Scene
NxSceneDesc sceneDesc;
sceneDesc.gravity = gDefaultGravity;
sceneDesc.userTriggerReport = &gMySensorReport;
gScene = gPhysicsSDK->createScene(sceneDesc);
25/3/2008
9
Scene
• Defining a Material
NxMaterial * defaultMaterial =
gScene->getMaterialFromIndex(0);
defaultMaterial->setRestitution(0.0f);
defaultMaterial->setStaticFriction(0.0f);
defaultMaterial->setDynamicFriction(0.0f);
Scene
• Creating a floor
NxPlaneShapeDesc PlaneDesc;
NxActorDesc ActorDesc;
ActorDesc.shapes.pushBack(&PlaneDesc);
gScene->createActor(ActorDesc);
Scene
• Empty Scene
Actors
• Physical objects
• Static, dynamic or kinematic
Static versus Dynamic
• Static
– Take part of the landscape
– Non-moving characters, buildings...
– Provide only collision detection
• Dynamic
– Have mass, momentum and inertia
– Called “bodies”
– Movable objects
Creating Actors
• Create actor description
– Set density, global pose, optional body description
// Create a dynamic 'box' actor.
// A dynamic actor has a non NULL body.
NxActorDesc actorDesc;
NxBodyDesc bodyDesc;
actorDesc.setToDefault();//reset to default values.
actorDesc.body = &bodyDesc;
actorDesc.density = 10;
// set initial position.
actorDesc.globalPose.t = NxVec3(0.0f,10.0f,0.0f);
25/3/2008
10
Creating Actors
• Create the collision model
– Create shape descriptions
– Add to the shape repository
NxBoxShapeDesc boxDesc;
// The actor has one shape, a 1m cube.
boxDesc.dimensions.set(0.5f,0.5f,0.5f);
actorDesc.shapes.pushBack(&boxDesc);
Creating Actors
• Edit body description
– Set body flags
– Inertia tensor
– Mass
– Center of mass
– Force and torque
NxBodyDesc body;
body.setToDefault();
body.flags |= NX_BF_KINEMATIC;
NxActorDesc actDesc;
actDesc.body = &body;
Creating Actors
• Finally, create the Actor
NxActor *dynamicActor=gScene->createActor(actorDesc);
Creating Actors
//moves and/or rotates a kinematic actor
void moveGlobalPose (const NxMat34 &mat);
//moves a kinematic actor
void moveGlobalPosition (const NxVec3 &vec);
//rotates a kinematic actor using a rotation matrix
void moveGlobalOrientation (const NxMat33 &mat);
//rotates a kinematic actor using a quaternion
void moveGlobalOrientationQuat (const NxQuat &quat);
• Kinematic handling methods
Materials
• Realistic collision reaction
• Bonded to shapes
• Shapes always have an assigned material (default)
• Materials are global (use index as id)
• Material properties– Restitution [0,1]
– Static friction [0, +inf)
– Dynamic friction [0,1]
Creating Materials
NxMaterialDesc materialDesc;
materialDesc.restitution= 0.7f;
materialDesc.staticFriction= 0.5f;
materialDesc.dynamicFriction= 0.5f;
NxMaterial *newMaterial =
gScene->createMaterial(materialDesc);
NxActorDesc actorDesc;
NxBoxShapeDesc boxDesc;
boxDesc.dimensions.set(4,4,5);
boxDesc.materialIndex = newMaterial->getMaterialIndex();
actorDesc.shapes.pushBack(&boxDesc);
25/3/2008
11
Elements Interaction
• Interaction through force and torque application
– Force controls the acceleration and, indirectly, velocity and position
Force
Elements Interaction
• Interaction through force and torque application
– Torque controls the rotational acceleration
Torque
Elements Interaction
void addForce(const NxVec3 &, NxForceMode);
void addLocalForce(const NxVec3 &, NxForceMode);
void addTorque(const NxVec3 &, NxForceMode);
void addLocalTorque(const NxVec3 &, NxForceMode);
Elements Interaction
void addForceAtPos(const NxVec3 & force, const NxVec3 &
pos, NxForceMode);
void addForceAtLocalPos(const NxVec3 & force, const
NxVec3 & pos, NxForceMode);
void addLocalForceAtPos(const NxVec3 & force, const
NxVec3 & pos, NxForceMode);
void addLocalForceAtLocalPos(const NxVec3 & force,
const NxVec3 & pos, NxForceMode);
Elements Interaction
• Some force modes
– NX_FORCE
– NX_IMPULSE
– NX_ACCELERATION
Joints
• Represent connections between bodies– Different types improve
simulation realism
– Particular parameters can be modified
25/3/2008
12
Joints
• Different types
revolute
distance point in plane
point on line pulley
motorized
v3
Joints: Spherical
• Spherical
– Have three degrees of freedom
– Shoulder joints, ball-and-socket joints
Joints: SphericalNxSphericalJoint*
CreateSphericalJoint(NxActor* a0, NxActor* a1)
{
NxSphericalJointDesc sphericalDesc;
sphericalDesc.actor[0] = a0;
sphericalDesc.actor[1] = a1;
sphericalDesc.setGlobalAnchor(globalAnchor);
sphericalDesc.setGlobalAxis(globalAxis);
sphericalDesc.flags |= NX_SJF_SWING_LIMIT_ENABLED;
sphericalDesc.swingLimit.value = 0.3*NxPi;
sphericalDesc.flags |= NX_SJF_TWIST_LIMIT_ENABLED;
sphericalDesc.twistLimit.low.value = -0.05*NxPi;
sphericalDesc.twistLimit.high.value = 0.05*NxPi;
return
(NxSphericalJoint*)gScene->createJoint(sphericalDesc);
}
Joints: Revolute
• Revolute
–Called the “hinge” joint
–Represent the hinge on a door
Joints: Revolute
NxRevoluteJoint* CreateRevoluteJoint(NxActor* a0,
NxActor* a1, NxVec3 globalAnchor, NxVec3 globalAxis)
{
NxRevoluteJointDesc revDesc;
revDesc.actor[0] = a0;
revDesc.actor[1] = a1;
revDesc.setGlobalAnchor(globalAnchor);
revDesc.setGlobalAxis(globalAxis);
revDesc.jointFlags |= NX_JF_COLLISION_ENABLED;
return
(NxRevoluteJoint*)gScene->createJoint(revDesc);
}
Joints: Prismatic
• Prismatic
– The global anchor will be set on the top of the lower actor and two limit planes will be set at the boundaries of the upper actor
Slide 67
v3 completar ponto de interrogaçãoveronica; 7/11/2006
25/3/2008
13
Joints: Cylindrical
• Cylindrical
– Free to rotate around the primary axis like a revolute joint
– Setup is identical to the prismatic joint, as well as the creation function
Joints: Fixed
• Fixed
– Unite two actors, without any degree of freedom
– Implementation is identical to the other joints
v4
Joints: Distance
• Distance
– Connects two actors by a rod
– Each end of the rod is attached to an anchor point on each actor
– Has two anchor points
NxVec3 anchor1 = NxVec3(0,1,0);
Joints: PIP
• Point in plane
–Allows its actors to rotate about all axes with respect to each other and translate along two axes
Joints: PIP
NxPointInPlaneJoint* CreatePointInPlaneJoint(NxActor*
a0, NxActor* a1, NxVec3 globalAnchor, NxVec3
globalAxis)
{
NxPointInPlaneJointDesc pipDesc;
pipDesc.actor[0] = a0;
pipDesc.actor[1] = a1;
pipDesc.setGlobalAnchor(globalAnchor);
pipDesc.setGlobalAxis(globalAxis);
pipDesc.jointFlags |= NX_JF_COLLISION_ENABLED;
NxJoint* joint = gScene->createJoint(pipDesc);
return joint->isPointInPlaneJoint();
}
Joints: PIP
void InitNx()
{
NxJoint* jointPtr = &pipJoint->getJoint();
jointPtr->setLimitPoint(globalAnchor);
jointPtr->addLimitPlane(NxVec3(1,0,0), globalAnchor
– 5*NxVec3(1,0,0));
jointPtr->addLimitPlane(NxVec3(-1,0,0), globalAnchor
+ 5*NxVec3(1,0,0));
jointPtr->addLimitPlane(NxVec3(0,0,1), globalAnchor
– 5*NxVec3(0,0,1));
jointPtr->addLimitPlane(NxVec3(0,0,-1), globalAnchor
+ 5*NxVec3(0,0,1));
}
Slide 74
v4 não tem uma figurinha disso?veronica; 7/11/2006
25/3/2008
14
Joints: POL
• Point on line
–Analogous to PIP but with a line in place of the plane
Joints: POL
void InitNx()
{
NxJoint* jointPtr = &polJoint->getJoint();
jointPtr->setLimitPoint(globalAnchor);
// Add left-right limiting planes
jointPtr->addLimitPlane(-globalAxis, globalAnchor +
5*globalAxis);
jointPtr->addLimitPlane(globalAxis, globalAnchor -
5*globalAxis);
…
}
Joints: Pulley
• Pulley
– Can make a pulley system more complicated than just a wheel
Joints: PulleyNxPulleyJoint* CreatePulleyJoint(NxActor* a0, NxActor* a1, const
NxVec3& pulley0, const NxVec3& pulley1, const NxVec3& globalAxis,
NxReal distance, NxReal ratio)
{
NxPulleyJointDesc pulleyDesc;
pulleyDesc.actor[0] = a0;
pulleyDesc.actor[1] = a1;
pulleyDesc.localAnchor[0] = NxVec3(0,2,0);
pulleyDesc.localAnchor[1] = NxVec3(0,2,0);
pulleyDesc.setGlobalAxis(globalAxis);
pulleyDesc.pulley[0] = pulley0;
pulleyDesc.pulley[1] = pulley1;
pulleyDesc.distance = distance;
pulleyDesc.ratio = ratio;
pulleyDesc.flags = NX_PJF_IS_RIGID;
pulleyDesc.stiffness = 1;
pulleyDesc.jointFlags |= NX_JF_COLLISION_ENABLED;
return (NxPulleyJoint*)gScene->createJoint(pulleyDesc);
}
Joints: Parameters
• Parameters
– Joint Limits
– Breakable Joints
– Joint Motor
– Joint Spring
Joints: Parameters
• Parameters: Joint Limits
– Restricts the movement of the bodies united by the joint
NxRevoluteJointDesc revDesc;
// Enable and set up joint limits
revDesc.flags |= NX_RJF_LIMIT_ENABLED;
revDesc.limit.high.value = 0.25*NxPi;
revDesc.limit.high.restitution = 1;
revDesc.limit.low.value = 0;
revDesc.limit.low.restitution = 1;
25/3/2008
15
Joints: Parameters
• Parameters: Breakable Joints
– Define a maximum force and torque supported by joint
– Revolute or Spherical
– Support only fixed values (do not support intervals) �
{
NxRevoluteJointDesc revDesc;
...
NxJoint* joint = gScene->createJoint(revDesc);
NxReal maxForce = 2000;
NxReal maxTorque = 100;
joint->setBreakable(maxForce,maxTorque);
return (NxRevoluteJoint*)joint;
}
Joints: Parameters
• Parameters: Joint Motor
– Supplies a relative torque between two bodies
– Revolute or Spherical{
NxRevoluteJointDesc revDesc;
...
revDesc.flags |= NX_RJF_MOTOR_ENABLED;
NxMotorDesc motorDesc;
motorDesc.velTarget = 1000;
motorDesc.maxForce = 500;
motorDesc.freeSpin = true;
revDesc.motor = motorDesc;
return (NxRevoluteJoint*)gScene->createJoint(revDesc);
}
Joints: Parameters
• Parameters: Joint Spring
– Generates a similar effect to a real spring {
NxRevoluteJointDesc revDesc;
…
revDesc.flags |= NX_RJF_SPRING_ENABLED;
NxSpringDesc springDesc;
springDesc.spring = 5000;
springDesc.damper = 50;
springDesc.targetValue = 0.5*NxPi;
revDesc.spring = springDesc;
return (NxRevoluteJoint*)gScene->createJoint(revDesc);
}
Collision Detection
• Used to create Triggers
• Used to select or pick objects (Raycasting)
• May supply a contact report that contains details about the collisions occurred
– User may change the environment
• May work without programmer’s interaction
Raycasting
• Collision detection with rays
• Used for
– Mouse picking
– Line of sight
– Calculating distances
– Simulating shooting
• Executed by NxScene
Raycasting
• raycastAnyBounds, raycastAnyShape– Returns a boolean
• raycastClosestBounds, raycastClosestShape– Returns closest shape and distance
• raycastAllBounds, raycastAllShapes– Returns the number of shapes stabbed and enumerates using
an user raycast report
• Parameters– NxRay attributes
• orig and dir (normalized)
– Shape type• NX_STATIC_SHAPES, NX_DYNAMIC_SHAPES,
NX_ALL_SHAPES
25/3/2008
16
Raycasting
NxRay worldRay;
worldRay.dir = NxVec3(0.0f, 0.0f, 1.0f);
worldRay.orig = NxVec3(0.0f, 0.0f, 0.0f);
if(gScene->raycastAnyShapes(worldRay, NX_ALL_SHAPES))
{
//the ray hit something ...
}
NxRay worldRay;
worldRay.dir = NxVec3(0.0f, 0.0f, 1.0f);
worldRay.orig = NxVec3(0.0f, 0.0f, 0.0f);
NxRaycastHit hit;
gScene->raycastClosestShapes(worldRay, NX_ALL_SHAPES, hit);
NxActor &s = hit.shape->getActor();
//do something to the actor
Raycastingclass MyRaycastReport : public NxUserRaycastReport
{
virtual bool onHit(const NxRaycastHit& hit)
{
NxActor &hitActor = hit.shape->getActor();
//The ray hit an actor, do something...
return true;
}
}gMyReport;
...
NxRay worldRay;
worldRay.dir = NxVec3(0.0f, 0.0f, 1.0f);
worldRay.orig = NxVec3(0.0f, 0.0f, 0.0f);
gScene->raycastAllShapes(worldRay, gMyReport,
NX_ALL_SHAPES);
Raycasting
• NxRaycastHit
– Shape
– World impact point
– World impact normal
– Barycentric coordinates of the hit face
– Material index and distance to the ray origin
Triggers
• Detect shape’s presence in specific zones
• Simulate presence sensors, surveillance areas, automatic doors...
• Event handling using a report
• Implemented with special shapes
– Permit shapes to pass through it
– Generate events• NX_TRIGGER_ON_ENTER
• NX_TRIGGER_ON_LEAVE
• NX_TRIGGER_ON_STAY
Creating a Trigger
// This trigger is a cube
NxBoxShapeDesc boxDesc;
boxDesc.dimensions = NxVec3(10.0f, 10.0f, 10.0f);
boxDesc.shapeFlags |= NX_TRIGGER_ENABLE;
NxActorDesc actorDesc;
actorDesc.shapes.pushBack(&boxDesc);
NxActor * triggerActor = gScene->createActor(actorDesc);
Creating a Trigger Report
class SensorReport : public NxUserTriggerReport
{
virtual void onTrigger(NxShape& triggerShape,
NxShape& otherShape, NxTriggerFlag status) {
if(status & NX_TRIGGER_ON_ENTER)
{
NxActor& triggerActor = triggerShape.getActor();
NxActor& actor = otherShape.getActor();
}
if(status & NX_TRIGGER_ON_LEAVE)
{
NxActor& triggerActor = triggerShape.getActor();
NxActor& actor = otherShape.getActor();
}
}
} gMySensorReport;
25/3/2008
17
Setting the Trigger Report
• After creating a trigger report, the programmer has to tell the scene to use this report
gScene->setUserTriggerReport(&gMySensorReport);
Contact Report
• User defined reports called when a collision happens
• Handles generic collisions
– Adds sound
– Makes mesh deformation
• User must subclass NxUserContactReport
Contact Report
class MyContactReport : public NxUserContactReport {
void onContactNotify(NxContactPair& pair, NxU32 events) {
//... you can read the contact information out of
// the contact pair data here.
}
} myReport;
• NxUserContact implementation
Contact Report
• NxContactPair attributes
//the two actors that make up the pair
NxActor *actors[2];
//a stream that can be readed by an
NxContactStreamIterator.
NxConstContactStream stream;
//the total contact normal force that was applied for
//this pair, to maintain nonpenetration constraints
NxVec3 sumNormalForce;
//the total tangential force that was applied for this
pair
NxVec3 sumFrictionForce;
Contact Report
• To set the contact report
• Collision groups– Shape: 32
• Disabling collision groups
– Actor: 32767
scene->setUserContactReport(&myReport);
NxScene::setGroupCollisionFlag(CollisionGroup g1,
CollisionGroup g2, bool enable);
Contact Report//to set all flags in a single pair of actors
scene->setActorPairFlags(actor0, actor1,
NX_NOTIFY_ON_START_TOUCH
| NX_NOTIFY_ON_END_TOUCH
| NX_NOTIFY_ON_TOUCH);
//to set flags using groups you must set the actor's group
before
actor0.setGroup(1);
actor1.setGroup(1);
actor2.setGroup(23);
actor3.setGroup(7);
//now set the flags
scene->setActorGroupPairFlags(1,23, NX_NOTIFY_ON_START_TOUCH
| NX_NOTIFY_ON_END_TOUCH);
//to disable a specific pair use:
scene->setActorPairFlags(actor1, actor2, NX_IGNORE_PAIR);
25/3/2008
18
Wrappers
• NxOgre
– Bridges the gap between PhysX and OGRE 3D
– Does not slow down the simulation
– 30-40 FPS with an excessive number of bodies
http://www.nxogre.org
http://www.ogre3d.org
Final Considerations
• Developing Physics
– Compute-intensive algorithms
– Complex mathematical and logical calculations
• PhysX SDK
– Encapsulates all the hard calculations
– Accelerates the development