04Collision Detection

advertisement
95.4501
Comp 4501
Wilf LaLonde ©2012
Definition
• Collision detection is the act of determining
what is being hit for the purposes of providing
suitable reaction behavior.
• To have objects (especially the player)
navigate the game world without going
through other objects; need instantaneous
feedback.
• To be able to perform visibility queries (is
sun visible for lens flare, is player visible to
an AI to cause attack, objects encountered
by bullet so a scorch mark can be made).
Comp 4501
Wilf LaLonde ©2012
Definition
• Physics simulation is the act of computing
the behavior that should result from a set of
properties that include the shape of an
object, its mass, it translational and
rotational velocities, and the other objects in
its neighborhood that can constrain the
movement of the object...
PhysX provides behavior simulation from
increasingly complex objects built out of sphere,
cube, and capsule shapes along with ray
sweeping and sphere sweeping queries...
Comp 4501
Wilf LaLonde ©2012
PhysX
• Free software that provides both capabilities.
• Requires the user to build collision detection
shapes for his world and to use a query API for
immediate control purposes and a simulation
engine for more autonomous behavior.
• The PhysX engine is a parallel multiprocessor
capable engine that requires the use of ONE
simple synchronization point to use effectively.
Comp 4501
Wilf LaLonde ©2012
Preliminaries
• Need to have access to online PhysX SDK
documentation (though we will review it here).
• Need access to specific source libraries,
DLLs, and LIBs.
• Provides a not-so-easy to figure out ALLENCOMPASING DEMO for perusal... (too
much intertwining of renderer code with
physics code)
• Begin perusal in file “PhysXSample.cpp”
Comp 4501
Wilf LaLonde ©2012
Generic Design
physics engine
scene
physics actors
collision shapes
geometric entities
PxPhysics* sdk;
transform
friction materials
mass
density
cooker
PxCooking* cooking;
PxScene* scene;
we call it physicsSystem
PxMaterial* material;
Comp 4501
Wilf LaLonde ©2012
Creating / Deleting Physics Engine
• Can peruse a subset of the sample code in
“PhysXSample::onInit ()” and
“PhysXSample::onShutdown ()” that
creates/deletes appropriate components.
• Important parts are the following:
• A 16-byte boundary space allocator
• An error callback object
• An extension library for mass and inertia and the
ability to obtain a cooker on demand
• A scene object with complicated components
associated with threads and CUDA.
We’ll provide a physics manager that sets all this up...
Comp 4501
Wilf LaLonde ©2012
Once you have a physics system
• You can make it perform simulations in
parallel with something that is not going to
change the state of your objects...
if (physicsManager->scene != NULL)
physicsManager->scene->simulate (DT);
game->draw ();
if (physicsManager->scene != NULL)
physicsManager->scene->fetchResults (true);
wait until simulation done
Comp 4501
Wilf LaLonde ©2012
Most Important Object: Actors
• Actors are the only objects that can be
associated with positional information
among other things.
Instead of transformations, physX uses
quaternions implemented in a class called
PxTransform... and calls them poses in the
demos.
We provide a handful of routines for converting back and
forth WITHOUT HAVING TO KNOW HOW THEY WORK...
Comp 4501
Wilf LaLonde ©2012
Conversion Routines
//Convenience conversion functions...
inline PxTransform asTransform (Transformation &transformation) {
return PxTransform (*((PxMat44 *) &transformation));}
inline Transformation asTransformation (PxTransform &transform) {
return *((Transformation *) &PxMat44 (transform));}
inline Point asPoint (PxVec3 &point) {
return Point (point.x, point.y, point.z);}
inline PxVec3 asVec3 (Point &point) {
return PxVec3 (point.x, point.y, point.z);}
inline PxTransform transformTranslatedTo (PxTransform &transform,
Point &point) {
return PxTransform (asVec3 (point), transform.q);}
Comp 4501
Wilf LaLonde ©2012
Game Objects
• Game objects, in general, need at least
A transformation to position it
A display shape for drawing it
A collision shape for moving it.
• PhysX by contrast deals with the collision
aspect from actors and also needs the
equivalent of a transformation to do this... It
does not support user objects directly.
• So the easiest way to deal with it is have the
game object access the transformation
information from the physics actor rather
than duplicate it...
Comp 4501
Wilf LaLonde ©2012
Actor Types Depend on their Collision Shapes
• Actor types
• Static (unmovable)
• Dynamic (movable)
• Static only collision shapes include
• infinite planes (demos only)
• terrain (needs a cooker to finalize it)
• triangle meshes (a polygon soup)
• Static or dynamic collision shapes include
• Spheres, boxes, capsules, and convex meshes
(but not encouraged to use latter)
Comp 4501
Wilf LaLonde ©2012
Shapes Need Friction Materials
• Since shapes dictate what rubs when movement
occurs, they also need information about
friction; i.e., friction materials...
• static friction (0 slippery, 1  sticky)
• dynamic friction (0  slippery, 1  sticky),
• coefficient of restitution (0  stick when hit,
1  bounce with no loss of energy).
PhysX calls physics materials “PxMaterial” which YOU
MUST NOT CONFUSE WITH DISPLAY MATERIALS.
Comp 4501
Wilf LaLonde ©2012
Sample Friction Coefficients
• The coefficient of static friction, denoted μs is
usually larger than the coefficient of dynamic
(or kinetic) friction, denoted μk.
Static friction,
Materials
Lubricated
Aluminium
Steel
0.61
Copper
Steel
0.53
Brass
Steel
0.51
Cast iron
Copper
1.05
Cast iron
Zinc
0.85
Concrete
(wet)
Rubber
0.30
Concrete
(dry)
Rubber
1.0
Concrete
Wood
0.62[10]
Copper
Glass
0.68
Glass
Glass
0.94
Metal
Wood
0.2–0.6[10]
0.2 (wet)[10]
Polyethene
Steel
0.2[11]
0.2[11]
Steel
Steel
0.80[11]
0.16[11]
Steel
PTFE
0.04[11]
0.04[11]
PTFE
PTFE
0.04[11]
0.04[11]
Wood
0.25–0.5[10]
0.2 (wet)[10]
Wood
Comp 4501
Dry and
clean
Sample values from
Wikipedia
PhysX demos often use
0.5 and 0.5
Wilf LaLonde ©2012
Shapes Need Geometric Information
• Shapes make use of a small geometric objects for
encoding simple information; e.g., each shape type
requires a specific geometry type; e.g.
terrain
triangle mesh
plane
sphere
box
capsule
 PxHeightFieldGeometry
 PxTriangleMeshGeometry
 PxPlaneGeometry
 PxSphereGeometry
 PxBoxGeometry
 PxCapsuleGeometry
Would have seemed simpler if it were private
information provided to the shape during its contruction
Comp 4501
Wilf LaLonde ©2012
Some Shapes Are Complex
• Complex shapes like triangle meshes or
convex meshes need extra initialization code
to be executed before they are built (they call
this cooking).
• There are tools for filing out cooked shapes
and filing them back in pre-cooked to speed
up their use (a more advanced topic)...
Comp 4501
Wilf LaLonde ©2012
Actor Construction
• Create the actor as either a static or dynamic type at its pose
(orientation and position) in the scene.
• Have the actor create the appropriate type of shape with material
and specific geometric; it adds the shape to itself...
• Set density (so far, I set everything to 1), mass, linear velocity, and
angular velocity (velocities 0 if not set; don’t now what [1,2,3]
means for angular velocity).
• Update the mass and inertia properties (via updateMassAndInertia)
• Add the Actor to the scene if you want to be able to hit it or if you
want the simulator to use it... (an example where you would not is if
you only want it for sphere sweeping queries)...
• Delete (via release) all intermediate objects you had to create
except for the actor and the shape...
Comp 4501
Wilf LaLonde ©2012
Sphere Actor Example
PxRigidDynamic* sphereActor =
thePhysics->createRigidDynamic (PxTransform (position));
PxMaterial* sphereMaterial = mSDK->createMaterial (0.5f, 0.5f, 0.1f);
PxShape* sphereShape =
sphereActor->createShape (PxSphereGeometry (radius), sphereMaterial);
PxReal sphereDensity = 1.0;
PxRigidBodyExt::updateMassAndInertia (*sphereActor, sphereDensity);
sphereActor->setLinearVelocity (velocity); //Do nothing if not moving.
scene->addActor (sphereActor);
sphereMaterial->release ()
I keep the scene in a physicsManager
who creates all the physics objects.
Spheres have a radius.
Comp 4501
The documentation sometimes uses thePhysics,
sample code uses mSDK, I use physicsSystem.
Wilf LaLonde ©2012
Shape ONLY Example for Capsule Actors
PxTransform pose;
pose.q = PxQuat (PxHalfPi, PxVec (0,0,1)); //90 degrees around z.
PxReal radius = 1.0; //Meter?
PxReal halfHeight = 5.0; //Meters?
PxShape* capsuleShape =
capsuleActor->createShape (
PxCapsuleGeometry (radius, halfHeight), aMaterial, pose);
Capsules have a height (half above, half below); x-axis oriented
Comp 4501
Wilf LaLonde ©2012
Shape ONLY Example for Box Actors
PxReal halfWidth 1.0; //Meter?
PxReal halfHeight = 5.0; //Meters?
PxReal halfDepth = 2.0; //Meters?
PxShape* boxShape =
` boxActor->createShape (PxBoxGeometry (
halfWidth, halfHeight, halfDepth ), boxMaterial);
Boxes are specified via half width, half height, half depth,
Comp 4501
Wilf LaLonde ©2012
TriangleMesh Actors (Use a TriangleMesh shape)
This is for
PxTriangleMeshDesc description;
STATIC geometry
description.points.count = “number of vertices”;
description.triangles.count = “number of triangles”;
description.points.stride = “size of a vertex”;
description.triangles.stride = “size of a triangle”;
description.points.data = vertices; //std::vector<PxVec3>
description.triangles.data = indices; //std::vector<PxU32>
PxCooking* cooker = PxCreateCooking (PX_PHYSICS_VERSION, thePhysics>getFoundation(), PxCookingParams ());
MemoryWriteBuffer buffer;
bool status = cooker->cookTriangleMesh (description, buffer);
PxTriangleMesh* triangleMesh =
thePhysics->createTriangleMesh (MemoryReadBuffer (buffer.data));
cooker->release ();
PxRigidStatic* triangleMeshActor = thePhysics->createRigidStatic(pose);
PxShape* triangleMeshShape =
aTriMeshActor->createShape (PxTriangleMeshGeometry (triangleMesh),
material);
Triangle meshes are collection of vertices and the triangle indices AND must be cooked.
Comp 4501
Wilf LaLonde ©2012
Shape ONLY Example for Convex Mesh Actors
const PxVec3 convexVertices [] = {
PxVec3 (0,1,0), PxVec3 (1,0,0), PxVec3 (-1,0,0), PxVec3 (0,0,1),
PxVec3 (0,0,-1)}; //5 vertices for a pyramid with base at 0 and peak at 1.
PxConvexMeshDesc convexDescription;
convexDescription.points.count = 5;
convexDescription.points.stride = sizeof (PxVec3);
convexDescription.points.data = convexVertices;
convexDescription.flags = PxConvexFlag::eCOMPUTE_CONVEX
There are NO indices; These are polygon soup vertices....
SO YOU CAN’T MAKE it NON-CONVEX...
Convex meshes are specified via vertices and
must be initialized (cooked) before creation...
Comp 4501
Wilf LaLonde ©2012
Initializing (Cooking) Convex Meshes before Creation
PxCooking* cooker = PxCreateCooking (PX_PHYSICS_VERSION,
thePhysics->getFoundation (), PxCookingParams ());
MemoryWriteBuffer buffer;
bool status = cooker->cookConvexMesh (convexDescription, buffer);
PxConvexMesh* convexMesh =
thePhysics->createConvexMesh (MemoryReadBuffer (buffer.data));
cooker->release ();
Don’t know whether a cooker can be reused...
Personally, I don’t know why this is NOT private to createConvexMesh?
Comp 4501
Wilf LaLonde ©2012
Shape ONLY Example for Plane Actors
//Planes placed into space with a pose.
PxRigidStatic* planeActor = thePhysics->createRigidStatic (pose);
PxShape* planeShape =
planeActor->createShape (PxPlaneGeometry (), material);
Planes are specified with their backs hittable and the default direction
pointing toward the positive x-direction (the identity pose)
Comp 4501
Wilf LaLonde ©2012
Game Engine Versus PhysX Terrain
Both can
cut quads
this way
Row based; texture Y goes up;
vertex z goes more negative
game engine
Comp 4501
Column based; texture Y goes
down; vertex z goes more positive
PhysX
Wilf LaLonde ©2012
PhysX Height Map
diagonal through quad origin
• By executing, physXVertex->setTessFlag on the topleft vertex. we mean split this vertex to get
material0
So every vertex will say this (it
must be irrelevant for the
rightmost column and the
bottommost row)
material1
• By executing, physXVertex->clearTessFlag on the
top-left vertex, we mean don’t split this vertex to get
material0
diagonal NOT through quad origin
0-based index
So every vertex will say this
material1
Comp 4501
Wilf LaLonde ©2012
Terrain (HeightField) Actors (Use a HeightField shape)
PxHeightFieldSample* samples = //Unclear if origin is top left or bottom left
new PxHeightFieldSample [rows * columns]; //PxHeightFieldDesc says it’s row based.
Loop over samples //More details later
sample.height = “a 16 bit integer (modified by scale below)”
sample. materialIndex0 = 0; //Upper triangle
sample. materialIndex1 = 0; //Lower triangle (NOT CLEAR)
//PxHeightFieldMaterial::eHOLE is special.
Sample. setTessFlag (); //Means plit this vertex so triangle diagonal is top-left to bottom-right.
Sample. clearTessFlag (); //Means don’t so triangle diagonal is bottom-left to top-right.
PxHeightFieldDesc description;
Actor deletes its shape but not
description.format = PxHeightFieldFormat::eS16_TM;
samples or height field or the
description.nbColumns = cols;
materials which can be deleted
immediately after creating the shape.
description.nbRows = rows;
description.samples.data = samples;
description.samples.stride = sizeof (PxHeightFieldSample);
PxHeightField* heightField = thePhysics->createHeightField (description);
PxRigidStatic* terrainActor = thePhysics- >createRigidStatic (pose);
PxShape* terrainShape = terrainActor->createShape (
PxHeightFieldGeometry (heightField, PxMeshGeometryFlags (),
yScale, xScale, zScale),
materialReference); //OR materialPointersArray, materialPointersArraySize);
TerraIns are HeightField actors with rectangular grids of height field samples.
Comp 4501
Wilf LaLonde ©2012
Dealing with The Game Engine VERSUS PhysX
PxRigidStatic *PhysicsManager::physicsTerrain (Terrain *terrain) {
float physXXScale, physXYScale, physXZScale; Point physXPosition;
terrain->physicsAttributes (physXXScale, physXYScale, physXZScale, physXPosition);
//Create points for the terrain (PhysX calls them samples). setTessFlag means triangle diagonal
//going from top left to bottom right (like backslash character), clearTessFlag means triangle
//diagonal from bottom left to top right (like divide character)...
PxHeightFieldSample* samplePoints = new
|
PxHeightFieldSample [terrain->heightMapWidth * terrain->heightMapHeight];
for (long y = 0; y < terrain->heightMapHeight; y++) {
for (long x = 0; x < terrain->heightMapWidth; x++) {
PxHeightFieldSample &toPoint = samplePoints [terrain->physicsCoordinateFor (x, y)];
toPoint.height = (PxI16) terrain->physicsHeightFor (x, y);
toPoint.clearTessFlag ();
toPoint.materialIndex0 = 0;
toPoint.materialIndex1 = 0;
}
}
We provide 2 routines for physics conversion
Comp 4501
Wilf LaLonde ©2012
Point/Sphere Sweeping
• Look up “raycastSingle” (for point sweeping) and
“sweepSingle” (for sphere sweeping) for details on
parameters that are needed or search the demo for
example uses...
• Need from point for point sweeping and transform for
sphere sweeping. Both need a distance and direction...
which can be computed from “from” and “to” points...
float toDistance;
Vector direction = to - from;
direction.normalize (toDistance);
Game has both a normalize and a normalized method
Comp 4501
Wilf LaLonde ©2012
Can Get Sphere Geometry of Existing Sphere Actor
PxShape* shapeBuffer [1]; PxU32 shapeBufferSize = 1;
physicsSphere->getShapes (shapeBuffer, shapeBufferSize);
PxSphereGeometry sphereGeometry;
shapeBuffer [0]->getSphereGeometry (sphereGeometry);
The sphere geometry is in the sphere shape
Comp 4501
Wilf LaLonde ©2012
Point/Sphere Sweeping
PxSweepHit hit; //Filled in by the query...
if (scene->raycastSingle (“from point”, “direction”, “distance”,
“flags”, hit) //true if blocked...
if (scene->sweepSingle (“sphereGeometry”, “from transform”,
“direction”, “distance”, “flags”, hit) //true if blocked..
where “flags” are
PxSceneQueryFlag::eBLOCKING_HIT |
PxSceneQueryFlag::eDISTANCE
If it was blocked, can find the intersection point easily
float hitDistance = hit.distance;
float t = hitDistance / toDistance;
Point intersectionPoint = from + (to - from) * t;
Comp 4501
Wilf LaLonde ©2012
Odds and Ends
• Kinematic actors (with property eKINEMATIC) are special
dynamic actors that are not influenced by forces (such as
gravity), and have no momentum. They are considered to have
infinite mass and can be moved around the world using the
moveKinematic() method.
They will push regular dynamic actors out of the way.
Kinematics will not collide with static or other kinematic
objects.
Kinematic actors are great for moving platforms or characters
where direct motion control is desired.
Comp 4501
Wilf LaLonde ©2012
Conclusion
• PhysX is more complex than it needs to be
but the complexity can be hidden away...
• I have seen demos with a huge number of
collapsing objects; e.g., from a castle built
out of cement blocks...
Where can I get an editor to do this or how
can I write a converter for the existing
castle?
Comp 4501
Wilf LaLonde ©2012
Download