Upload
melina-freeman
View
220
Download
0
Embed Size (px)
DESCRIPTION
3 Key Topics Bounding Volumes –Axially-Aligned Bounding Boxes (AABBs) Interactions –Object – Object –Object – Bullet –Object – Terrain –Other Implementation –handleInteractions() –enforcePositions()
Citation preview
1
Sage Demo 4Collisions
SAGE Lecture NotesIan Parberry
University of North Texas
2
SAGE Demo 4• The goal of this demo will be to be able to
determine if an interaction/collisions has occurred between two objects
3
Key Topics• Bounding Volumes
– Axially-Aligned Bounding Boxes (AABBs)• Interactions
– Object – Object– Object – Bullet– Object – Terrain– Other
• Implementation– handleInteractions()– enforcePositions()
4
Bounding Volumes• A bounding volume has the following
properties.– It should contain the entire object
• There are exceptions to this rule as we will see shortly
– It should be as small as possible, while still enclosing the entire object
5
Bounding Volumes Cont.• Exceptions
– You may have extraneous extrusions that don’t need to be considered in collision detection
• Ex: A ship with an antennae
– You can use multiple bounding boxes to contain an object
• Ex: Another ship with an antennae– Except you want this antennae to be considered
6
Bounding Volumes Cont.• Bounding come in a variety of shapes and
sizes, as well as orientations. These are two of the most commonly used bounding volumes– Axially-Aligned Bounding Boxes– Bounding Spheres
7
Axially-Aligned Bounding Box(AABB)
• An AABB is defined using two vectors that point from the origin to the bottom left corner, and the top right corner of the box, thus defining both its size and position– This is the bounding volume for the objects in the SAGE demos.
8
AABB Cont.• An AABB is a box containing the object that is
restricted to a certain orientation (it can’t rotate)– This restriction is that it is aligned with the world
space axis (x, y, z)• An axially-aligned bounding box (AABB)
accelerates the computation of collision detection– It replaces the complex geometry of a typical game
object with a simpler shape– Each object in the demo has an AABB associated
with it
9
AABB
10
AABB Limitations• Bounding Box must be recalculated every
time the orientation of an object changes
– The bounding box will have to increase in size to be able to encompass the rotated object
11
Bounding Spheres• Bounding spheres are an extremely easy way to
calculate collisions– If an object is closer then the radius of the center
point, then there is an intersection• Less accurate for most models
12
Interactions• There are a number of different types of
interactions that are handled by the SAGE engine through the AABB3 class– Object - Object – Object - Bullet– Object - Terrain– Other
13
Object - Object• An interaction between two objects in the
game is an interaction between two bounding boxes
• There are two methods in the AABB3 class that can be used to test for an object - object interaction– intersectMoving() – One moving object, one
stationary– intersectMoving() – Two moving objects
14
intersectMoving() with only one moving object
• Used to check if the plane’s bounding box intersects any of the stationary objects in the scene (Silos and the Windmill)
• The first two parameters are the stationary and moving objects’ AABBs respectively
• The vector d is the movement vector for the moving object’s bounding box
float AABB3::intersectMoving( const AABB3 &stationaryBox, const AABB3 &movingBox, const Vector3 &d);
15
Stationary Box
Moving Box
d
16
intersectMoving() Cont.
• Each axis is checked individually• First, we check for an empty or infinite
time interval, and if there is such, we only need to check for an existing overlap
if (d.x == 0.0f) { // Empty or infinite inverval on x if ((stationaryBox.min.x >= movingBox.max.x) || (stationaryBox.max.x <= movingBox.min.x)) { // Empty time interval, so no intersection return kNoIntersection; } // Infinite time interval - no update necessary }}
17
intersectMoving() Cont.• If there is movement on a particular axis, we check for an
overlap over the interval [0-1] along the vector d
• We make this check on each axis, and update the parametric return value of the intersection accordingly (tEnter)
// Divide oncefloat oneOverD = 1.0f / d.x;// Compute time value when they begin and end overlappingfloat xEnter = (stationaryBox.min.x - movingBox.max.x) * oneOverD;float xLeave = (stationaryBox.max.x - movingBox.min.x) * oneOverD;// Check for interval out of orderif (xEnter > xLeave) { std::swap<float>(xEnter, xLeave);}
// Update intervalif (xEnter > tEnter) tEnter = xEnter;if (xLeave < tLeave) tLeave = xLeave;// Check if this resulted in empty intervalif (tEnter > tLeave) { return kNoIntersection;}
18
intersectMoving() with two moving objects
• We can view this situation as a special case of the previous situation where we had only one moving object by treating one object as stationary
• This test is performed in the demo when we want to test for a collision between the plane and the crows
float AABB3::intersectMoving( const AABB3 &box1, const AABB3 &box2, const Vector3 &d1, const Vector3 &d2){ return intersectMoving(box1, box2, d1 - d2);}
19
Object - Bullet• In the case of Object – Bullet interactions,
we now longer have to bounding volumes to check for an overlap, since the bullets in the demo are rays, and have no specific geometry
• So an object - bullet interaction is an example of a AABB - ray interaction and is handled with the rayIntersect() AABB3 function float AABB3::rayIntersect(
const Vector3 &rayOrg, // orgin of the ray const Vector3 &rayDelta, // length and direction of the ray Vector3 *returnNormal // optionally, the normal is returned) const;
20
rayIntersect() Cont.
• The first two parameters define the ray• The last parameter is optional and returns
the ray normal to the surface the bounding box if the ray intersected it
• The method returns the parametric value on the interval [0, 1] where the intersection occurred, if there was indeed an intersection float AABB3::rayIntersect(
const Vector3 &rayOrg, // orgin of the ray const Vector3 &rayDelta, // length and direction of the ray Vector3 *returnNormal // optionally, the normal is returned) const;
21
rayIntersect() Cont.• First, the function checks if the ray originates from within
the box, resulting in a trivial intersection, or pointing in the wrong direction entirely
bool inside = true;float xt, xn;if (rayOrg.x < min.x) { xt = min.x - rayOrg.x; if (xt > rayDelta.x) return kNoIntersection; xt /= rayDelta.x; inside = false; xn = -1.0f;} else if (rayOrg.x > max.x) { xt = max.x - rayOrg.x; if (xt < rayDelta.x) return kNoIntersection; xt /= rayDelta.x; inside = false; xn = 1.0f;} else { xt = -1.0f;}
22
rayIntersect() Cont.
• Next, we determine in which plane the intersection may occur
• Then we check whether an intersection did occur on that plane
int which = 0;float t = xt;if (yt > t) { which = 1; t = yt;}if (zt > t) { which = 2; t = zt;}
case 0: // intersect with yz plane{ float y = rayOrg.y + rayDelta.y*t; if (y < min.y || y > max.y) return kNoIntersection; float z = rayOrg.z + rayDelta.z*t; if (z < min.z || z > max.z) return kNoIntersection; if (returnNormal != NULL) { returnNormal->x = xn; returnNormal->y = 0.0f; returnNormal->z = 0.0f; }} break;
23
Object - Terrain
• This type of intersection is used to determine if the plane or a crow has come in contact with the ground
• First we determine the position on the terrain based on the x and z position of the object
• Then we check to see if the bottom of the AABB is lower then the terrain
24
Object - TerrainTerrain *terr = terrain.getTerrain();if(terr == NULL) return false;//test for plane collision with terrainVector3 planePos = plane.getPosition(); float planeBottom = plane.getBoundingBox().min.y;float terrainHeight = terr->getHeight(planePos.x,planePos.z);if(plane.isPlaneAlive() && planeBottom < terrainHeight); //collision
25
Other
• There are a couple of interactions that the AABB3 class can handle that aren’t used in Ned3D game– AABB - Sphere intersections
• intersectSphere()– AABB - Plane intersections
• intersectPlane()
26
intersectSphere()
• The two parameters define the sphere• The given sphere is compared to the
AABB3 whose function was called by determining if the closest point to the center of the sphere is closer than the sphere’s radius
// Find the closest point on box to the pointVector3 closestPoint = closestPointTo(center);// Check if it's within rangereturn Vector3::distanceSquared(center, closestPoint) < radius*radius;
27
intersectSphere() Cont.
28
intersectPlane()
• The first two parameters define the plane by the equation planeNormal = planeD
• The last parameter specifies the directions the AABB is traveling
• First, we make sure the AABB is traveling in the direction of the plane
float AABB3::intersectPlane( const Vector3 &n, float planeD, const Vector3 &dir) const;
float dot = n * dir;if (dot >= 0.0f) { return kNoIntersection;}
29
intersectPlane() Cont.• Next, we determine what the minimum and
maximum d values for which an intersection could occur with the current AABB
• If the maximum d value is greater than or equal to the planes d value, then there is no intersection; otherwise, there is an intersection and we return the parametric value on the interval [0, 1] where the intersection would occur
30
intersectPlane() Cont.float minD, maxD;if (n.x > 0.0f) { minD = n.x*min.x; maxD = n.x*max.x;} else { minD = n.x*max.x; maxD = n.x*min.x;}if (n.y > 0.0f) { minD += n.y*min.y; maxD += n.y*max.y;} else { minD += n.y*max.y; maxD += n.y*min.y;}if (n.z > 0.0f) { minD += n.z*min.z; maxD += n.z*max.z;} else { minD += n.z*max.z; maxD += n.z*min.z;}if (maxD <= planeD) { return kNoIntersection;}
31
intersectPlane() Cont.
• The return value is determined using a standard ray trace equation
float t = (planeD - minD) / dot;// Were we already penetrating?if (t < 0.0f) { return 0.0f;}// Return it. If > l, then we didn't hit in time. That's// the condition that the caller should be checking for.return t;
32
Implementation
• Demo 4 implements the previous interactions in the Ned3DObjectManager class using the method handleInteractions()
• The handleInteractions() method uses the following functions to test for collisionsbool interactPlaneCrow(PlaneObject &plane, CrowObject &crow);bool interactPlaneTerrain(PlaneObject &plane, TerrainObject &terrain);bool interactPlaneWater(PlaneObject &plane, WaterObject &water); bool interactPlaneFurniture(PlaneObject &plane, GameObject &furniture);bool interactCrowCrow(CrowObject &crow1, CrowObject &crow2);bool interactCrowTerrain(CrowObject &crow, TerrainObject &terrain);bool interactCrowBullet(CrowObject &crow, BulletObject &bullet);
33
handleInteractions()• The functions used by handleInteractions() check for
interactions between the moving objects and anything they can interact with using the AABB3 functions– interactPlaneCrow – Object - Object (Both Moving)– interactPlaneTerrain – Object - Terrain– interactPlaneWater – Object - Terrain– interactPlaneFurniture – Object - Object (One moving)– interactCrowCrow – Object - Object (Both Moving)– interactCrowTerrain – Object - Terrain– interactCrowBullet – Bullet - Object
34
enforcePositions()
• The enforcePositions method in the Ned3DObjectManager class checks two AABBs to see if the overlap
• If they overlap, it forces them apart using a Kluge, which forces them apart on the smallest dimension of overlap
35
enforcePositions() Cont.Vector3 delta = intersectBox.size();Vector3 obj1Pos = obj1.getPosition(), obj2Pos = obj2.getPosition();if (delta.x <= delta.y) if(delta.x <= delta.z) { // Push back on x float dx = (box1.min.x < box2.min.x) ? -delta.x : delta.x; obj1Pos.x += dx; obj2Pos.x -= dx; } else { // Push back on z float dz = (box1.min.z < box2.min.z) ? -delta.z : delta.z; obj1Pos.z += dz; obj2Pos.z -= dz; }else if(delta.y <= delta.z){ // Push back on y float dy = (box1.min.y < box2.min.y) ? -delta.y : delta.y; obj1Pos.y += dy; obj2Pos.y -= dy;}else{ // Push back on z float dz = (box1.min.z < box2.min.z) ? -delta.z : delta.z; obj1Pos.z += dz; obj2Pos.z -= dz;}