Virtual Reality and Multimedia Research Group
Tutorial
AGEIA PhysX
SBGames 2006Thiago Souto Maior Daliton Silva Guilherme Moura Márcio Bueno Veronica Teichrieb Judith Kelner
{ mouse, ds2, gsm, masb, vt, jk } @cin.ufpe.br
Recife, November 2006
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
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
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 RC-1
• 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 =
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
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: Shapes
NxHeightFieldDesc 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. = 0; 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();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 contactArchitecture: 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); Anisotropic material Default materialMathematical Support
• Based on
– NxMath
– NxMat33
– NxMat34
– NxVec3
– NxQuat
• Storage format independent
– According to row or column major
NxMath
• Container with 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
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);
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.
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 (constNxMat33 &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 = gPhysicsSDK->createMaterial(materialDesc); NxActorDesc actorDesc; NxBoxShapeDesc boxDesc; boxDesc.dimensions.set(4,4,5); boxDesc.materialIndex = newMaterial->getMaterialIndex(); actorDesc.shapes.pushBack(&boxDesc);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(constNxVec3 &, NxForceMode); void addTorque(constNxVec3 &, NxForceMode); void addLocalTorque(const NxVec3 &, NxForceMode);
Elements Interaction
voidaddForceAtPos(const NxVec3 & force, const NxVec3 &pos, NxForceMode);
voidaddForceAtLocalPos(constNxVec3 & force, const NxrVec3 & pos, NxForceMode); voidaddLocalForceAtPos(constNxVec3 & force, const
NxVec3 & pos, NxForceMode); voidaddLocalForceAtLocalPos(constNxVec3 & 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
Joints
• Different types
revolute
distance point in plane
point on line pulley
motorized
Joints: Spherical
• Spherical
– Have three
degrees of freedom
– Shoulder joints,
ball-and-socket
joints
Joints: Spherical
NxSphericalJoint*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 and the top of
the lower actor and two limit planes will be set
at the boundaries of the upper actor
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
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); returnjoint->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)); }
Joints: POL
• Point on line
– Analogous to PIP but with a line in place
of the plane
Joints: POL
voidInitNx(){
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: Pulley
NxPulleyJoint* CreatePulleyJoint(NxActor* a0, NxActor* a1, const
NxVec3& pulley0, constNxVec3& pulley1, constNxVec3& 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;
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
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
Raycasting
classMyRaycastReport : publicNxUserRaycastReport {virtual boolonHit(constNxRaycastHit& 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 : publicNxUserTriggerReport{
virtual voidonTrigger(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(); }
}
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 : publicNxUserContactReport {
voidonContactNotify(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, boolenable);
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: