Collision The Game Loop Game Logic Update + Render May want to run game logic at a different frame rate from rendering (multiplayer) Where does physics and collision fit in? while( running ) { delta_time = current_time – last_time; while( last_time < current_time ) { move game objects by velocities for this delta_time; if( objects are interpenetrating ) { // subdivide delta_time and try again -- e.g.: delta_time *= 0.5f; } else { if( objects are touching ) { resolve collisions (by applying impulses); } last_time += delta_time; delta_time = current_time – last_time; } } Render(); } Distinction between collision detection and collision response Collision Detection Basically a geometric problem "Levels" of collision accuracy: (a) detecting interpenetration/contact, (b) determining point of contact, (c) determining POC and normal for modeling a response Difficult because of large number of cases to consider, and the need for efficiency Usually detect collisions between relatively simple geometric primitives Lots of primitives we can use: o Sphere o AABB o OBB o Polytopes (!) o Convex Hulls o Arbitrary triangle "soup" o Frustum (for visibility culling) Therefore lots and lots of cases to consider (pair-wise collisions): o Sphere vs. Sphere o Line/Ray/Line Segment vs. Plane o Line/Ray/Line Segment vs. Triangle o Sphere vs. Plane o Sphere vs. Triangle o AABB vs. AABB o Triangle vs. Triangle o etc. Sphere vs. Sphere Find delta vector between centers d = (C1 – C2) Find squared magnitude d2 = d d Compare to squared sum of radii d2 ≤ (r1 + r2)2 Line/Ray/Line Seg. vs. Plane Plane is described by ax + by + cz + d = 0 This is same as normal-distance form <n, d>, and gives point P0 = –dn (i.e., d = –n Pi) Line is described parametrically by arbitrary starting point L0 and a direction vector v L(t) = L0 + tv Distance from any point Q to the plane is just h = n (Q – P0) Therefore h = n Q + d Intersection occurs when h = 0, so solve n Q + d = 0 and substitute L(t) for Q n (L0 + tcv) + d = 0 – we want to find the t for contact, tc tc = (n L0 + d) / n v For ray, set L0 to be the starting point, and allow any tc ≥ 0 For line segment, set L0 to be the start, L1 = L0 + v to be the end; allow any tc [0, 1] Line vs. Triangle Determine point of intersection of line with the plane of the triangle, C = L0 + tcv To find plane of triangle, generate normal via cross product, d = –n Pi Check if point of contact falls inside triangle… Flatten triangle onto one of xy, yz or zx planes by setting one coord to 0 for each vertex Find an edge vector e01 = V1 – V0 Also find the vector between V0 and the point of contact C: w = C – V0 Rotate vector e01 by 90 degrees in either direction to find its perpendicular counterpart e01 Because the V2 is "inside" edge 01, e01 V2 gives the sign for dot products of any point inside that edge Therefore, C is inside edge 01 iff (e01 V2)(e01 C) ≥ 0 Repeat for all three edges – if it's inside all three, the point C is inside the triangle Moving Sphere vs. Plane Same as line vs. plane, but the trick is to realize that the sphere will contact the plane when its center is a radial distance r from the plane in a direction perpendicular to it Therefore, we can shift the plane by rn and find the point at which the line traced out by the sphere's center contacts the plane: tc = (n L0 + (d – r)) / n v Once we have a contact point Ccenter = L0 + tcv for the sphere's center, we can find the point of contact of the surface of the sphere by subtracting rn So, Csurface = (L0 + tcv) – rn = (L0 + [(n L0 + (d – r)) / n v]v) – rn Moving Sphere vs. Triangle We would think we can just find the point of contact of the sphere's surface with the plane of the triangle, then proceed with point-in-triangle test to see if that point lies inside triangle However this does not work because sphere might graze the edge of the triangle Exercise for the reader! Research it and see if you can figure it out! (Answer will be provided later) AABB vs. AABB Collect and sort open and close boundary points along each axis Intersecting clusters are found from nested opens (1D case) For 2D and 3D, find clusters along one axis; then for each cluster, repeat for the other two axes; continue doing this until the group no longer gets subdivided, and all dimensions have been analyzed Frustum Culling: A Special Case of Collision Detection Do in view space to make the problem much easier Transform bounding sphere center into view space Simple z compare for near and far planes For edge planes, we note that either nx = 0 or ny = 0 since they're perfectly horizontal or vertical, and also d = 0 since they pass thru the view-space origin (def'n of view space!) So, distance of (x,y,z) from vertical frustum plane is h = xnx + znz Distance from horizontal frustum plane is h = yny + znz If the distance is greater than bounding sphere radius r, then sphere is outside that plane (this assumes that we use outward-pointing frustum plane normals) Collision Detection Strategies Broad phase vs. Narrow phase Sphere hierarchies AABB hierarchies Spatial partitioning (BSP, quad-/oct-tree, simple grid, etc.) Collision "islands" Collision Response (if we have time) Simple response: destroy the objects! Bounce response: See Chris Hecker's paper for details Basically, use point of collision and normal to calculate an impulse (instantaneous change in velocity) Resources http://www.d6.com/users/checker/ http://www.d6.com/users/checker/pdfs/gdmphys3.pdf Mark DeLoura (ed.). Game Programming Gems. §4.4, 4.5, 4.6, 4.8, 4.10, 4.11. Charles River Media, 2000. Mark DeLoura (ed.). Game Programming Gems 2. §2.3, 2.7, 4.3, 4.4. Charles River Media, 2001.