25/3/2008

SVR2007 Introduction Tutorial AGEIA PhysX • What does physics give? – Real world interaction metaphor – Realistic simulation Virtual Reality • Who needs physics? and Multimedia { mouse, ds2, gsm, masb, vt, jk } @cin.ufpe.br Research Group Thiago Souto Maior – Immersive games and applications Daliton Silva Guilherme Moura Márcio Bueno • How to use this? Veronica Teichrieb Judith Kelner – Through physics engines implemented in software or hardware

Petrópolis, May 2007

Physics Engines AGEIA PhysX SDK

• Simplified Newtonian models • Based upon NovodeX API • “High precision” versus “real time” simulations • Commercial and open engines • Middleware concept • What comes together in a physics engine? • First asynchronous physics API – Mandatory • Tons of math calculations • Takes advantage of multiprocessing game • Collision detection • Rigid body dynamics systems – Optional • Fluid dynamics • Cloth simulation • Particle systems • Deformable object dynamics

AGEIA PhysX SDK AGEIA PhysX SDK

• Supports game • Integration with game development life cycle engines – 3DSMax and Maya – 3.0 plugins (PhysX – Emergent Create) – Natural Motion – Properties tuning with Endorphin PhysX Rocket • Runs in PC, Xbox 360 – Visual remote and PS3 debugging with PhysX VRD

1 25/3/2008

AGEIA PhysX SDK AGEIA PhysX Processor

• Supports • AGEIA PhysX PPU – Complex rigid body dynamics • Powerful PPU + – Collision detection CPU + GPU – Joints and springs – Physics + Math + – Volumetric fluid simulation Fast Rendering – Particle systems – Cloth simulation – Soft body simulation

Other Physics Engines Download

• Open source • Account registration required – Open Dynamics Engine (ODE) • http://devsupport.ageia.com – Bullet Physics Library • 1-3 business days • Free – TOKAMAK – Newton • Commercial – FX

Download Download

• Download section • AGEIA Driver

• System Software • SDK version selection

2 25/3/2008

License Installation

• Free license • System requirements – Non-commercial use – Windows XP or Vista – PS3 platform (through Sony pre-purchase) • Most recent Service Pack – Through some middleware partnerships – 512MB of system memory • UE3, Gamebryo 2.2, etc – At least 150MB of free HD space – PC platform (if makes use* of PhysX HW) • $50k per platform – PCI expansion slot for PPU – All other uses – Additional 4-pin molex power connector

Installation Documentation

• PPU Driver and System Software • Documents – Run samples – Windows help file containing PhysX API • Samples – Source codes and executables covering most of • PhysX SDK Core PhysX features – Header and lib files • Training Programs – Documentation – Documents, overview and source code

Architecture & Components Architecture: World

NxPhysicsSDK * myWorld = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION);

World (PhysX SDK)

3 25/3/2008

Architecture: Scene Architecture: Actor

• Scene • Actor – Collection of every interactive element – Main simulation object • Bodies • Dynamic • Constraints • Static • Effectors NxPlaneShapeDesc planeDesc; NxActorDesc actorDesc; actorDesc.shapes.pushBack(&planeDesc); NxActor *staticActor = gScene->createActor(actorDesc);

Architecture: Shapes Architecture: Shapes

• Shapes • Box Shape

NxBoxShapeDesc boxDesc; boxDesc.dimensions.set(0.5f, 0.5f, 0.5f); NxBoxShape *boxShape = actor->createShape(boxDesc)->isBox();

Architecture: Shapes Architecture: Shapes

• Capsule Shape • Convex Shape – Defined by a radius – Shape defined by a set of vertices and a height

NxCapsuleShapeDesc capsuleDesc; capsuleDesc.height = 2.0f; capsuleDesc.radius = 0.5f;

NxCapsuleShape *capsuleShape=actor->createShape(capsuleDesc)->isCapsule();

4 25/3/2008

Architecture: Shapes 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), • Height Field Shape NxVec3(1,1,-1),NxVec3(1,1,1) }; – Height Field Map to generate a collision NxU32 vertCount = 8; terrain 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 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; NxHeightFieldShapeDesc heightFieldShapeDesc; for (NxU32 row = 0; row < nbRows; row++) { heightFieldShapeDesc.heightField = heightField; for (NxU32 column = 0; column < nbColumns; column++) { heightFieldShapeDesc.heightScale = gVerticalScale; NxHeightFieldSample* currentSample = (NxHeightFieldSample*)currentByte; heightFieldShapeDesc.rowScale = gHorizontalScale; currentSample->height = computeHeight(row,column); heightFieldShapeDesc.columnScale = gHorizontalScale; currentSample->materialIndex0 = gMaterial0; heightFieldShapeDesc.holeMaterial = 2; currentSample->materialIndex1 = gMaterial1;

currentSample->tessFlag = 0; NxHeightFieldShape currentByte += heightFieldDesc.sampleStride; *heightFieldShape= } } actor->createShape(heightFieldShapeDesc)->isHeightField();

NxHeightField* heightField = gScene->getPhysicsSDK().createHeightField(heightFieldDesc);

Architecture: Shapes Architecture: Shapes

• Plane Shape • Sphere Shape – Default: y = 0 – Defined by – Defined by a Normal a radius and the distance from the origin NxPlaneShapeDesc planeDesc; NxSphereShapeDesc sphereDesc; planeDesc.normal = NxVec3(0.0f,1.0f,0.0f); sphereDesc.radius = 1.0f; planeDesc.d = 10.0f; NxSphereShape NxPlaneShape *sphereShape=actor->createShape(sphereDesc)->isSphere(); *planeShape=actor->createShape(planeDesc)->isPlane();

5 25/3/2008

Architecture: Shapes Architecture: Shapes

• Triangle Mesh Shape • Wheel Shape – Radius – Suspension travel – Motor – Brake torque – Steer angle – Raycast from shape’s NxTriangleMeshShapeDesc meshShapeDesc; origin along the axis meshShapeDesc.meshData = triangleMesh; • Hard contact • Soft suspension NxTriangleMeshShape *triangleMeshShape= • No contact actor->createShape(meshShapeDesc)->isTriangleMesh();

Architecture: Joints Architecture: Materials

• Joints • Materials – Connections between rigid bodies – Shape surface properties • Friction • Restitution

Architecture: Materials Mathematical Support

Default NxMaterial* defaultMaterial = gScene->getMaterialFromIndex(0); material • Based on defaultMaterial->setRestitution(0.5); defaultMaterial->setStaticFriction(0.5); – NxMath defaultMaterial->setDynamicFriction(0.5); – NxMat33 NxMaterialDesc material; – NxMat34 material.restitution = 0.0f; material.staticFriction = 0.1f; – NxVec3 material.dynamicFriction = 0.1f; material.dynamicFrictionV = 0.8f; – NxQuat material.staticFrictionV = 1.0f; material.dirOfAnisotropy.set(0,0,1); • Storage format independent material.flags = NX_MF_ANISOTROPIC; – According to row or column major NxMaterial *anisoMaterial = Anisotropic gScene->createMaterial(material); material

6 25/3/2008

NxMath NxMat33

• Container of static math operations • Abstraction to 3x3 matrix • Conversion between degrees and radians • Represent rotations or inertia tensors • Functions • Implements operators – min, max, floor, ceil, sqrt – Sum and subtraction (+/-) – Logarithm functions in common bases – Matrix and scalar product (*) – Trigonometric functions • Other operations like inverting and – Some constants like NxPi, NxHalfPi, NxTwoPi transposing are also available and NxInvPi

NxMat33 NxMat34

• Example • Wrapper class encapsulates – Given a vector in world space, how to – NxMat33 (rotation) transform it into local space? – NxVec3 (translation)

NxVec3 localVec, worldVec; • Public attributes: M and t NxMat33 orient, invOrient; worldVec = NxVec3(0,0,1); • Conversions to 4x4 rendering matrix orient = actor->getGlobalOrientation(); formats orient.getInverse(invOrient); localVec = invOrient * worldVec; • Operator product (*)

NxMat34 NxVec3

• Example • Can represent a point or a vector – Given a position in the world space, how to • Attributes: x, y, z transform it into the local space? • Direct or array-like access NxActor* actor; ... • Implements vectors’ arithmetic, including NxVec3 localPos, worldPos; cross product, dot product and others NxMat34 mat, invMat; operations related to vectors worldPos = NxVec3(0,0,1); mat = actor->getGlobalPose(); mat.getInverse(invMat); localPos = invMat * worldPos;

7 25/3/2008

NxQuat NxQuat

• Quaternion representation • Example • Hamiltonian Arithmetic – How to transform a quaternion into its • Attributes: x, y, z, w correspondent 3x3 matrix? • Used to represent a rotation – Axis and angle NxQuat q; • Concatenation through product (*), like matrixes q.fromAngleAxis(90, NxVec3(0,1,0)); • Rotations can be applied to points and vectors – rot method ... NxMat33 orient; • Interpolation between two orientations orient.fromQuat(q); – Slerp – Quaternion is used as keyframe

Scene Scene

• Declaring variables • Initializing the World

static NxPhysicsSDK* gPhysicsSDK = NULL; gPhysicsSDK = static NxScene* gScene = NULL; NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION, NULL, &gErrorStream); static NxVec3 gDefaultGravity(0.0f, -98.1f, 0.0f); static ErrorStream gErrorStream;

Scene Scene

• Setting DEBUG information • Creating the Scene

// setParameter(VISUALIZATION_TYPE, TRUE|FALSE); NxSceneDesc sceneDesc; gPhysicsSDK->setParameter(NX_VISUALIZE_COLLISION_SHAPES, 1); sceneDesc.gravity = gDefaultGravity; sceneDesc.userTriggerReport = &gMySensorReport; gScene = gPhysicsSDK->createScene(sceneDesc);

8 25/3/2008

Scene Scene

• Defining a Material • Creating a floor

NxMaterial * defaultMaterial = NxPlaneShapeDesc PlaneDesc; gScene->getMaterialFromIndex(0); NxActorDesc ActorDesc; defaultMaterial->setRestitution(0.0f); ActorDesc.shapes.pushBack(&PlaneDesc); defaultMaterial->setStaticFriction(0.0f); gScene->createActor(ActorDesc); defaultMaterial->setDynamicFriction(0.0f);

Scene Actors

• Empty Scene • Physical objects • Static, dynamic or kinematic

Static versus Dynamic Creating Actors

• Static • Create actor description – Take part of the landscape – Set density, global pose, optional body – Non-moving characters, buildings... description – Provide only collision detection // Create a dynamic 'box' actor. // A dynamic actor has a non NULL body. • Dynamic NxActorDesc actorDesc; NxBodyDesc bodyDesc; – Have mass, momentum and inertia actorDesc.setToDefault(); //reset to default values. – Called “bodies” actorDesc.body = &bodyDesc; – Movable objects actorDesc.density = 10; // set initial position. actorDesc.globalPose.t = NxVec3(0.0f,10.0f,0.0f);

9 25/3/2008

Creating Actors Creating Actors

• Create the collision model • Edit body description – Create shape descriptions – Set body flags – Add to the shape repository – Inertia tensor – Mass NxBoxShapeDesc boxDesc; – Center of mass NxBodyDesc body; body.setToDefault(); // The actor has one shape, a 1m cube. – Force and torque body.flags |= NX_BF_KINEMATIC; boxDesc.dimensions.set(0.5f,0.5f,0.5f); actorDesc.shapes.pushBack(&boxDesc); NxActorDesc actDesc; actDesc.body = &body;

Creating Actors Creating Actors

• Finally, create the Actor • Kinematic handling methods

//moves and/or rotates a kinematic actor NxActor *dynamicActor=gScene->createActor(actorDesc); 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);

Materials Creating Materials

NxMaterialDesc materialDesc; • Realistic collision reaction materialDesc.restitution= 0.7f; • Bonded to shapes materialDesc.staticFriction= 0.5f; materialDesc.dynamicFriction= 0.5f; • Shapes always have an assigned material NxMaterial *newMaterial = (default) gScene->createMaterial(materialDesc); • Materials are global (use index as id) NxActorDesc actorDesc; NxBoxShapeDesc boxDesc; • Material properties boxDesc.dimensions.set(4,4,5); boxDesc.materialIndex = newMaterial->getMaterialIndex(); – Restitution [0,1] actorDesc.shapes.pushBack(&boxDesc); – Static friction [0, +inf) – Dynamic friction [0,1]

10 25/3/2008

Elements Interaction Elements Interaction

• Interaction through force and torque • Interaction through force and torque application application – Force controls the acceleration and, indirectly, – Torque controls the rotational acceleration velocity and position

Torque

Force

Elements Interaction Elements Interaction

void addForceAtPos( const NxVec3 & force, const NxVec3 & pos, NxForceMode); void addForce( const NxVec3 &, NxForceMode); void addLocalForce( const NxVec3 &, NxForceMode); void addForceAtLocalPos( const NxVec3 & force, const void addTorque( const NxVec3 &, NxForceMode); NxVec3 & pos, NxForceMode); void addLocalTorque( const NxVec3 &, NxForceMode); void addLocalForceAtPos( const NxVec3 & force, const NxVec3 & pos, NxForceMode);

void addLocalForceAtLocalPos( const NxVec3 & force, const NxVec3 & pos, NxForceMode);

Elements Interaction Joints

• Some force modes • Represent – NX_FORCE connections between bodies – NX_IMPULSE – Different types improve – NX_ACCELERATION simulation realism – Particular parameters can be modified

11 25/3/2008

v3 Joints Joints: Spherical

• Different types • Spherical – Have three degrees of freedom – Shoulder joints, ball-and-socket revolute point on line pulley joints

distance point in plane motorized

Joints: Spherical Joints: Revolute NxSphericalJoint* CreateSphericalJoint(NxActor* a0, NxActor* a1) { • Revolute NxSphericalJointDesc sphericalDesc; sphericalDesc.actor[0] = a0; – Called the “hinge” joint sphericalDesc.actor[1] = a1; sphericalDesc.setGlobalAnchor(globalAnchor); sphericalDesc.setGlobalAxis(globalAxis); – Represent the hinge on a door

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 Joints: Prismatic

NxRevoluteJoint* CreateRevoluteJoint(NxActor* a0, NxActor* a1, NxVec3 globalAnchor, NxVec3 globalAxis) • Prismatic { NxRevoluteJointDesc revDesc; – The global anchor will be set on the top of the lower actor and two limit planes will be set at revDesc.actor[0] = a0; the boundaries of the upper actor revDesc.actor[1] = a1; revDesc.setGlobalAnchor(globalAnchor); revDesc.setGlobalAxis(globalAxis);

revDesc.jointFlags |= NX_JF_COLLISION_ENABLED;

return (NxRevoluteJoint*)gScene->createJoint(revDesc); }

12 Slide 67 v3 completar ponto de interrogação veronica; 7/11/2006 25/3/2008

v4 Joints: Cylindrical Joints: Fixed

• Cylindrical • Fixed – Free to rotate around – Unite two actors, without any degree of the primary axis like a freedom revolute joint – Implementation is identical to the other joints – Setup is identical to the prismatic joint, as well as the creation function

Joints: Distance Joints: PIP

• Distance • Point in plane – Connects two – Allows its actors to rotate about all axes actors by a rod with respect to each other and translate – Each end of the rod along two axes is attached to an anchor point on each actor – Has two anchor points NxVec3 anchor1 = NxVec3(0,1,0);

Joints: PIP Joints: PIP

NxPointInPlaneJoint* CreatePointInPlaneJoint(NxActor* a0, NxActor* a1, NxVec3 globalAnchor, NxVec3 void InitNx() globalAxis) { { NxJoint* jointPtr = &pipJoint->getJoint(); NxPointInPlaneJointDesc pipDesc; jointPtr->setLimitPoint(globalAnchor); pipDesc.actor[0] = a0; jointPtr->addLimitPlane(NxVec3(1,0,0), globalAnchor pipDesc.actor[1] = a1; – 5*NxVec3(1,0,0)); pipDesc.setGlobalAnchor(globalAnchor); jointPtr->addLimitPlane(NxVec3(-1,0,0), globalAnchor pipDesc.setGlobalAxis(globalAxis); + 5*NxVec3(1,0,0)); pipDesc.jointFlags |= NX_JF_COLLISION_ENABLED; jointPtr->addLimitPlane(NxVec3(0,0,1), globalAnchor – 5*NxVec3(0,0,1)); NxJoint* joint = gScene->createJoint(pipDesc); jointPtr->addLimitPlane(NxVec3(0,0,-1), globalAnchor + 5*NxVec3(0,0,1)); return joint->isPointInPlaneJoint(); } }

13 Slide 74 v4 não tem uma figurinha disso? veronica; 7/11/2006 25/3/2008

Joints: POL Joints: POL

void InitNx() • Point on line { NxJoint* jointPtr = &polJoint->getJoint(); – Analogous to PIP but with a line in place jointPtr->setLimitPoint(globalAnchor); of the plane // Add left-right limiting planes jointPtr->addLimitPlane(-globalAxis, globalAnchor + 5*globalAxis); jointPtr->addLimitPlane(globalAxis, globalAnchor - 5*globalAxis); … }

Joints: Pulley Joints: Pulley NxPulleyJoint* CreatePulleyJoint(NxActor* a0, NxActor* a1, const NxVec3& pulley0, const NxVec3& pulley1, const NxVec3& globalAxis, • Pulley NxReal distance, NxReal ratio) { – Can make a pulley system NxPulleyJointDesc pulleyDesc; pulleyDesc.actor[0] = a0; more complicated than just a pulleyDesc.actor[1] = a1; wheel 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 Joints: Parameters

• Parameters • Parameters: Joint Limits – Joint Limits – Restricts the movement of the bodies united – Breakable Joints by the joint

– Joint Motor NxRevoluteJointDesc revDesc; – Joint Spring // 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;

14 25/3/2008

Joints: Parameters Joints: Parameters

• Parameters: Breakable Joints • Parameters: Joint Motor – Define a maximum force and torque supported by – Supplies a relative torque between two bodies joint – Revolute or Spherical – Revolute or Spherical – Support only fixed values (do not support intervals)  { NxRevoluteJointDesc revDesc; { ... NxRevoluteJointDesc revDesc; revDesc.flags |= NX_RJF_MOTOR_ENABLED; ... NxMotorDesc motorDesc; NxJoint* joint = gScene->createJoint(revDesc); motorDesc.velTarget = 1000; NxReal maxForce = 2000; motorDesc.maxForce = 500; NxReal maxTorque = 100; motorDesc.freeSpin = true ; joint->setBreakable(maxForce,maxTorque); revDesc.motor = motorDesc; return (NxRevoluteJoint*)joint; return (NxRevoluteJoint*)gScene->createJoint(revDesc); } }

Joints: Parameters Collision Detection

• Parameters: Joint Spring • Used to create Triggers – Generates a similar effect to a real spring • Used to select or pick objects (Raycasting) { NxRevoluteJointDesc revDesc; • May supply a contact report that contains … revDesc.flags |= NX_RJF_SPRING_ENABLED; details about the collisions occurred

NxSpringDesc springDesc; – User may change the environment springDesc.spring = 5000; springDesc.damper = 50; • May work without programmer’s springDesc.targetValue = 0.5*NxPi; interaction revDesc.spring = springDesc; return (NxRevoluteJoint*)gScene->createJoint(revDesc); }

Raycasting Raycasting

• Collision detection with rays • raycastAnyBounds, raycastAnyShape – Returns a boolean • Used for • raycastClosestBounds, raycastClosestShape – Mouse picking – Returns closest shape and distance • raycastAllBounds, raycastAllShapes – Line of sight – Returns the number of shapes stabbed and enumerates using – Calculating distances an user raycast report • Parameters – Simulating shooting – NxRay attributes • orig and dir (normalized) • Executed by NxScene – Shape type • NX_STATIC_SHAPES, NX_DYNAMIC_SHAPES, NX_ALL_SHAPES

15 25/3/2008

Raycasting Raycasting class MyRaycastReport : public NxUserRaycastReport NxRay worldRay; { worldRay.dir = NxVec3(0.0f, 0.0f, 1.0f); virtual bool onHit( const NxRaycastHit& hit) worldRay.orig = NxVec3(0.0f, 0.0f, 0.0f); { NxActor &hitActor = hit.shape->getActor(); if(gScene->raycastAnyShapes(worldRay, NX_ALL_SHAPES)) //The ray hit an actor, do something... { return true ; //the ray hit something ... } } }gMyReport;

NxRay worldRay; ... worldRay.dir = NxVec3(0.0f, 0.0f, 1.0f); worldRay.orig = NxVec3(0.0f, 0.0f, 0.0f); NxRay worldRay; NxRaycastHit hit; worldRay.dir = NxVec3(0.0f, 0.0f, 1.0f); gScene->raycastClosestShapes(worldRay, NX_ALL_SHAPES, hit); worldRay.orig = NxVec3(0.0f, 0.0f, 0.0f); NxActor &s = hit.shape->getActor(); //do something to the actor gScene->raycastAllShapes(worldRay, gMyReport, NX_ALL_SHAPES);

Raycasting Triggers

• NxRaycastHit • Detect shape’s presence in specific zones – Shape • Simulate presence sensors, surveillance areas, – World impact point automatic doors... – World impact normal • Event handling using a report – Barycentric coordinates of the hit face • Implemented with special shapes – Permit shapes to pass through it – Material index and distance to the ray origin – Generate events • NX_TRIGGER_ON_ENTER • NX_TRIGGER_ON_LEAVE • NX_TRIGGER_ON_STAY

Creating a Trigger Creating a Trigger Report

class SensorReport : public NxUserTriggerReport { virtual void onTrigger(NxShape& triggerShape, // This trigger is a cube NxShape& otherShape, NxTriggerFlag status) { NxBoxShapeDesc boxDesc; boxDesc.dimensions = NxVec3(10.0f, 10.0f, 10.0f); if (status & NX_TRIGGER_ON_ENTER) boxDesc.shapeFlags |= NX_TRIGGER_ENABLE; { NxActorDesc actorDesc; NxActor& triggerActor = triggerShape.getActor(); actorDesc.shapes.pushBack(&boxDesc); NxActor& actor = otherShape.getActor(); } NxActor * triggerActor = gScene->createActor(actorDesc); if (status & NX_TRIGGER_ON_LEAVE) { NxActor& triggerActor = triggerShape.getActor(); NxActor& actor = otherShape.getActor(); } } } gMySensorReport;

16 25/3/2008

Setting the Trigger Report Contact Report

• After creating a trigger report, the • User defined reports called when a programmer has to tell the scene to use collision happens this report • Handles generic collisions – Adds sound gScene->setUserTriggerReport(&gMySensorReport); – Makes mesh deformation • User must subclass NxUserContactReport

Contact Report Contact Report

• NxUserContact implementation • NxContactPair attributes //the two actors that make up the pair class MyContactReport : public NxUserContactReport { NxActor *actors[2]; void onContactNotify(NxContactPair& pair, NxU32 events) { //a stream that can be readed by an //... you can read the contact information out of NxContactStreamIterator. // the contact pair data here. NxConstContactStream stream; } //the total contact normal force that was applied for } myReport; //this pair, to maintain nonpenetration constraints NxVec3 sumNormalForce; //the total tangential force that was applied for this pair NxVec3 sumFrictionForce;

Contact Report Contact Report //to set all flags in a single pair of actors scene->setActorPairFlags(actor0, actor1, • To set the contact report NX_NOTIFY_ON_START_TOUCH | NX_NOTIFY_ON_END_TOUCH scene->setUserContactReport(&myReport); | NX_NOTIFY_ON_TOUCH); //to set flags using groups you must set the actor's group • Collision groups before – Shape: 32 actor0.setGroup(1); actor1.setGroup(1); • Disabling collision groups actor2.setGroup(23); actor3.setGroup(7); NxScene::setGroupCollisionFlag(CollisionGroup g1, CollisionGroup g2, bool enable); //now set the flags scene->setActorGroupPairFlags(1,23, NX_NOTIFY_ON_START_TOUCH | NX_NOTIFY_ON_END_TOUCH); – Actor: 32767 //to disable a specific pair use: scene->setActorPairFlags(actor1, actor2, NX_IGNORE_PAIR);

17 25/3/2008

Wrappers Final Considerations

• NxOgre • Developing Physics – Bridges the gap between PhysX and OGRE – Compute-intensive algorithms 3D – Complex mathematical and logical – Does not slow down the simulation calculations – 30-40 FPS with an excessive number of • PhysX SDK bodies – Encapsulates all the hard calculations – Accelerates the development http://www.nxogre.org http://www.ogre3d.org

18