class: center, middle # Creación de Videojuegos ### Collision Detection --- # Collision Detection * Last week we talked about how forces and masses make objects move * Today we will be talking about how to detect if two objects bump into each other * As with movement, for many games an approximation is good enough * Remember that we discretized our physics simulation --- # A priori vs. a posteriori collision detection Since our objects move in discrete steps, we have to detect collisions "along the way". Two options: - A priori collision detection: Every simulation step we predict any collisions that will happen before the objects move, and take those collisions into account when moving them - A posteriori collision detection: Every simulation step, *after* objects move, we detect any intersections A posteriori collision detection is much simpler, and typically used in games. --- # Collisions * Now we only need to detect when two objects intersect * An intersection occurs if any point of one object is inside the other (we count the surface as "inside") * This problem is easier for some combinations of objects than for others * We will now look at several object combinations --- # Sphere-Sphere Collisions * A sphere has a center c and a radius r * Two sphere intersect, if they are closer together than the sum of their radii
$$ ||c_1 - c_2|| < r_1 + r_2\\\\ ||c_1 - c_2||^2 < (r_1 + r_2)^2 $$ --- # Sphere-Sphere Collisions Remember from last week: To determine the resulting forces, we also need the normal of the impact site
In the case of two spheres, the normal is the vector from one center to the other. --- # Sphere-Ray Collisions * Sometimes (for bullets, vision, path planning) all we want is to determine what is in a straight line from a certain point * In Unity this is done by ray casts * A ray has a starting point and a direction * The ray case returns the first object hit * To determine that, we need to calculate if a ray intersects an object --- # Your Best Friend: The Dot Product $$ \vec{A} \cdot \vec{B} = ||\vec{A}|| \cdot ||\vec{B}|| \cdot \cos{\theta} $$ If B is a unit vector: $$ \vec{A} \cdot \vec{B} = ||\vec{A}|| \cdot \cos{\theta} $$ This is the length of the projection of A onto the ray B.
image/svg+xml
--- # Sphere-Ray Collisions Let's take our ray y, with origin o and (unit) direction d: $$ \vec{y}(t) = \vec{o} + t \cdot \vec{d} $$ We can calculate the projection of the sphere center c onto the ray: $$ t_p = (\vec{c} - \vec{o}) \cdot \vec{d} $$ If t is less than 0, the sphere is behind the origin, otherwise we calculate $$ p = \vec{o} + t_p \cdot \vec{d} $$ --- class: small # Sphere-Ray Collisions We just calculated p, which is the distance of the sphere from the ray. If this distance is less than the radius, the ray is inside the sphere. To determine the actual intersection point we observe that the projection point, the center and the intersection point form a right triangle, with the longest side being the radius, and p as one of the legs. We can then subtract the length of the other leg from `\(t_p\)`
--- class: small # For Example Let's say we have a sphere with radius 3 at (2,1,8). Where does the ray starting at (0,0,0), in direction (0,0,1) intersect that sphere? -- $$ t_p = (\vec{c} - \vec{o}) \cdot \vec{d} = ((2,1,8) - (0,0,0)) \cdot (0,0,1) = 8 $$ $$ p = ||(\vec{o} + t_p \cdot \vec{d} - \vec{c})|| = ||(0,0,0) + 8 \cdot (0,0,1) - (2,1,8)|| \\\\= ||(-2,-1,0)|| = \sqrt{4+1} \approx 2.23 \le 3 $$ $$ t_i = t_p - \sqrt{r^2 - p^2} = 8 - \sqrt{9 - 5} = 8 - 2 = 6\\\\ i = \vec{o} + t_i \cdot \vec{d} = (0,0,0) + 6 \cdot (0,0,1) = (0,0,6) $$ --- class: small # Planes and points * Now let us consider objects with planar surfaces * One fundamental question we will have is: Which side of a plane is a point on? * Let's assume our plane is given as a point p and a normal n. (If we have a triangle, we can pick any of its vertices and calculate the normal) * A point x is in front of the plane (in the direction the normal points), if the vector from p to x points "in the same direction" as the normal * We can (again) use the dot product for this $$ (\vec{x} - \vec{p}) \cdot \vec{n} > 0 $$ --- # Question Given a plane going through the point (1,2,3) with normal (0.71,0,-0.71), for each of these three points determine if it lies in front, behind or on the plane. P1 = (3,4,5) P2 = (5,4,3) P3 = (0,0,0) --- # Polyhedron-Point Collisions * Now let's say we have a polyhedron * How can we determine if a point is inside or outside the polyhedron? * Two methods: - For each of the sides (planes) determine if the point is on the outside - Shoot a ray from the point and count how often it intersects the polyhedron * The first method only works on convex shapes --- # Question Given a tetrahedron with points $$a = (1, 1, 1)\\\\ b = (−1, −1, 1)\\\\ c = (−1, 1, −1)\\\\ d = (1, −1, −1) $$ How would we test if the point `\(p = (0.71,0.71,0)\)` is inside that tetrahedron? --- # Plane-Ray Collisions We want to determine if (and where) a ray y hits a plane $$ \vec{y}(t) = \vec{o} + t \cdot \vec{d} $$ Note that a point x *on* the plane has $$ (\vec{x} - \vec{p}) \cdot \vec{n} = 0 $$ So we are looking for a t such that $$ (\vec{o} + t \cdot \vec{d} - \vec{p}) \cdot \vec{n} = 0\\\\ t \cdot \vec{d} \cdot \vec{n} + (\vec{o} - \vec{p}) \cdot \vec{n} = 0\\\\ t = \frac{(\vec{p} - \vec{o}) \cdot \vec{n}}{\vec{d} \cdot \vec{n}} $$ --- # Example Where does the ray starting at (1,2,3), with the direction (0.71,0,-0.71) intersect the xy plane? -- $$ t = \frac{((0,0,0) - (1,2,3)) \cdot (0,0,1)}{(0.71,0,-0.71) \cdot (0,0,1)} = \frac{-3}{-0.71}\\\\ x = (1,2,3) + \frac{3}{0.71} \cdot (0.71,0,-0.71) \\\\ = (1,2,3) + (3,0,-3) = (4,2,0) $$ --- class: small # Triangle-Ray Collision * Usually we care if a ray hits a certain part of a plane, like a triangle * Idea: Calculate the Plane-Ray intersection, then check if the intersection point is inside the triangle * Many different ways to do this: - Calculate barycentric coordinates for the point, if all of the values are greater than 0, the point is inside the triangle - Check if the angles from the point to the vertices sum to 360 degrees - Check if the point is on the correct side of each edge of the triangle $$ ((\vec{v_2} - \vec{v_1}) \times (\vec{x} - \vec{v_1})) \cdot ((\vec{v_2} - \vec{v_1}) \times (\vec{v_3} - \vec{v_1})) > 0 $$ --- # Polyhedra * A Polyhedron is a solid object with polygons as faces * For example, a cube has squares as surfaces * As we discussed during our class on 3D graphics, triangles are commonly used as faces --- # Polyhedron-Sphere Collisions * We can now use what we have to detect collisions! * How do we determine if a sphere is colliding with a polyhedron? * If the center (point) of the sphere is inside the polyhedron, they collide * Otherwise, shoot a ray towards the polyhedron: If the intersection distance is less than the radius, they also collide --- # The Separating Planes Theorem For convex shapes
--- # (Convex) Polyhedron-Polyhedron Collisions * Any of the surface planes of the polyhedron can be used as a separating plane! * To check for intersections, find a surface such that all points of the other polyhedron are on the outside * If there is no such surface, the polyhedra intersect --- # Non-convex shapes * But this only works for convex polyhedra! * What do we do if we have a non-convex polyhedron? * Two options: - Approximate with a convex polyhedron - Decompose into convex components --- # Convex Hull Given a set of points, the convex hull is the smallest convex polyhedron that contains all the points.
--- # Convex Decomposition Split shape at every reflex vertex by inserting an edge to the/an opposite point.
--- class: center, middle # Bounding Volumes --- class: small # Bounding Volumes * Computing intersections between all pairs of arbitrary objects is expensive * Idea: Put a bigger object around each object for which intersections are easy to compute * Different bounding volumes: - Spheres: Easy to compute intersections, but may be too big - Boxes: Harder to compute intersections, but can be fitted pretty well - Axis-Aligned Boxes: Easy to compute intersections, better fit than spheres --- # Axis-Aligned Bounding Boxes
To test intersections: Check if x-projections *and* y-projections (and z-projections, in 3D) overlap. Sort-And-Sweep Algorithm: Sort start- and end-values of each interval, and iterate over them in sorted order. If there are two or more consecutive starts of intervals, the projections overlap. --- class: small # Hierarchical Representations * The idea of using larger bounding volumes to quickly eliminate unnecessary tests can be extended * For example, objects in one room will never collide with objects in a completely different room * Idea: Put multiple objects into a single bounding volume. If two such bounding volumes don't intersect, no object from one of them intersects with any object in the other. * Start with two objects, and put them into a combined bounding volume, then combine this larger bounding volume with another, etc. * We get a tree hierarchy of bounding volumes --- # Bounding Volume Tree
--- # Quadtrees/Octrees * Another idea is to split the space into fixed size parts, say cut each axis in half * This gives us 4 (in 2D), or 8 (in 3D) total parts * For any part in which there are objects, we can repeat this process * When any box only contains one object (and is sufficiently small), we can stop splitting * We can now test if something may intersect any object by checking the cell in which it falls in the tree --- # Octree
--- class: small # References * [Video Game Physics](https://www.toptal.com/game/video-game-physics-part-ii-collision-detection-for-solid-objects) * [Ray-Sphere Intersection](http://www.lighthouse3d.com/tutorials/maths/ray-sphere-intersection/) * [Ray-Plane Intersection](https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-plane-and-ray-disk-intersection) * [Ray-Intersections](http://www.realtimerendering.com/intersections.html)