Fast Contact Reduction for Dynamics Simulation Ádám Moravánszky and Pierre Terdiman - NovodeX AG adam.moravanszky@novodex.com, pierre.terdiman@novodex.com Introduction A typical physics pipeline contains three distinct parts: 1. Collision detection detects collisions between the objects in a scene. 2. Contact generation creates contact points from the collision data. 3. Dynamics simulation enforces the non-penetration constraints represented by contacts and updates the objects’ poses. To simulate the interaction of bodies in contact, non-penetration constraints must be expressed in a compact manner that permits efficient simulation of the resulting dynamics. Contact points have been introduced and used for this purpose in robotics literature since [Lozano-Perez83] and later in computer graphics literature with [Hahn88] and others. Contact points represent the local non-penetration constraints between colliding shapes. The number of emitted contact points has a direct influence over the accuracy, stability and speed of the simulation. Creating a single contact point for each pair of colliding shapes is usually not enough to produce high quality simulations. On the other hand, too many contact points may lead to stability issues and / or poor performance, depending on how the dynamics part of the pipeline has been implemented. This Gem presents several contact reduction algorithms that diminish the number of emitted contacts and their associated workload: contact preprocessing, contact clustering and contact persistence. Contact Reduction Collision detection algorithms often work by decomposing meshes into triangles or volume elements. Contact points are then generated independently for each of these elements. In this way one quickly ends up with too many contact points when the results from the many intersecting elements are combined, especially if the resolution of the elements is high, and / or the interpenetration of the bodies is great. Even if the created contact points succeed in adequately representing the local geometries in contact, generating a large number of contact points has several disadvantages. First, dynamics algorithms that solve for the true contact forces can have difficulty with strongly overdetermined problems imposed by many contacts. These algorithms operate in at least quadratic time in the number of contact points [Baraff92, Anitescu99]. In this case having more contact points than absolutely necessary is clearly a bad idea. Furthermore, a matrix representing such an overdetermined system is ill-conditioned. Solvers that try to factor this matrix will have a hard time. Some iterative solvers may also take more iterations to converge than for a problem with the same number, but linearly independent constraints. Fortunately this is becoming less of a practical problem because many approximate algorithms used for interactive dynamics simulation scale linearly with the number of constraints [Jakobsen01]. These inexpensive algorithms on the other hand are often sensitive to the number of contact points used, because they typically apply some penalty force or impulse at each contact, whose effects can become erratic when the number of contacts varies. Solvers based on penalty methods are still commonly used in games. Some of them use various constants and thresholds fine-tuned for the single contact case, such as a sphere rolling on a plane. They work well in that ideal case. However, when the number of simultaneous contacts increases, the simulation becomes less and less stable as it moves away from the fine-tuned case. For example, imagine a torus resting on a plane. If one contact is created at each vertex position, not only will the generated forces be far from ideal, but they will also directly depend on tessellation. Reducing the number of contacts helps to solve the stability problem [Kim02]. For these reasons the number of contact points should be kept at a minimum without sacrificing the realism of the simulation. We tackle this problem in two steps: by preprocessing the colliding shapes and clustering contact points. Overview of Preprocessing There are at least two different kinds of contacts: Contacts that can be discarded, because they have no influence over the simulation. Contacts that can be merged into a single one, producing a possibly less accurate, yet still plausible simulation. Contact preprocessing takes care of the first kind of contact. The preprocessing step examines all potential contacts of a given shape. This is not always possible, depending on the shape at hand. However when it is, potential contacts that will not play a significant role in the simulation are marked and discarded in advance. This is a powerful approach since the best way to get rid of redundant contacts is not to generate them in the first place. Overview of Clustering Contact clustering takes care of the second kind of contact by reducing a certain set of contact points to a smaller set, which is only legitimate when it does not change the nature of the non-penetration constraints. In the simplest case, such as an object resting on a flat plane, all valid contact normals will be identical and equal to the plane normal, and all the contact points will be on or below the plane. The distance of a contact below a plane is the local penetration depth at that point. Disregarding penetrations, one can show that all contact configurations with the same convex hull in the plane are equivalent for the purpose of rigid body simulation. Indeed, only three kinds of motions are possible for the body resting on the plane: It may be receding from the plane, in which case the contact surface will vanish. It may press against the surface, and may eventually slide along it. It may ‘fall over’ by rolling around any of the edges of the convex hull. Thus, the contact behavior is only influenced by the common contact normal direction, and the edges of the convex hull of the contact points. All the contact points not on the convex hull may be discarded without changing the nature of the non-penetration constraints. It is often desirable to reduce the contact points on the hull even further, especially in cases such as between the cylinder and the floor (Figure 1). We have developed an algorithm that removes those hull vertices which cause a minimal decrease in hull area, because in turn this minimizes the probability that the cylinder will fall over when it should not. However, a straight implementation of this rigorous approach is too expensive. Instead, a refined algorithm approximates the convex hull using the axisaligned bounds of the contact points. This approximate version works fairly well in practice, on both single (Figure 1) or composite objects (Figure 4). Figure 1: A set of contacts before and after reduction. The cylinder and torus are handled as meshes, resting on a plane. Overview of Persistence After reducing the number of contacts, the algorithm makes them persistent. Contact points regenerated from scratch in every simulation frame tend to have strong temporal coherence, i.e. contact points generated in a sequence of frames will be quite similar. Explicitly tracking this similarity over time has several benefits. First, some iterative algorithms solving for the contact forces can be started from an arbitrary initial guess force: the closer it is to the solution, the faster the algorithm will converge. This process is called warm starting. We warm start the solver with the contact forces of the previous time step, hoping that the contact forces of the current frame will be similar to the forces of the last frame. But this is only possible if a correspondence can be found between the previous and current contact points. Another application of persistent contacts is to achieve the best possible simulation of static friction between two bodies that must not slide at all relative to each other. We can enforce this no-slip condition by making certain, in each time step, that the relative tangential velocity at the contact points between the bodies is zero. If error accumulates, the bodies slowly drift along the tangent plane of their contacts. The same problem happens when we simulate joints between bodies with Lagrange multiplier based techniques: pose space error will accumulate at the joint. To combat this error we must be able to measure it. For joints, it is easy to compute the error because we know where the joint is supposed to be attached in the local coordinate system of each body. For contacts, it is not possible to do this unless we know where the contact was located when it was created, or when static friction conditions have started to apply. Persistent contacts are a solution to this problem. Details on Preprocessing The most efficient way to reduce contact points is not to generate them in the first place. Putting this notion into practice depends on the exact type of collision detection algorithm used, so a single example will be presented: the box-mesh contact generation algorithm used to collide game objects against a mesh representing a static environment. It is a common desire to perform collision detection with the same data set used for graphics, and one of the most common graphics display formats is an indexed triangle list. The triangles are assumed to be oriented (one of their sides is declared as the front face—the one exposed to the world, while the other is the back face), but must satisfy no other requirement. The efficiency of the method will decrease if the mesh contains many non-manifold edges or t-intersections. Given that the collision detection system reports all triangles of the mesh intersecting the box, contact generation is performed between the box shape and each triangle separately. This includes the testing of each of the triangle edges and vertices against the shape. Such practice can lead to duplicate contacts along edges shared by two triangles that both intersect the colliding shape. The following types of mesh edges are not worth testing against at all, and can be marked as inactive during preprocessing: An interior edge is an edge between two triangles with identical normals. Such an edge only serves to tessellate a planar polygon into triangles, and is not a real geometrical feature, and can be safely ignored. A concave edge is an edge between two triangles that form a concave angle with their front faces. This edge cannot be touched by another object in a nondegenerate manner unless it also touches one of the two triangles, and thus also does not need be tested. This leaves us with two kinds of edges that the collision detection system must test: boundary edges (edges not shared by two triangles), and convex edges (non-boundary edges neither interior nor concave), see Figure 2. It is sufficient to test convex edges from only one of the triangles that contain them. Non-manifold edges are treated as convex, because it is assumed that they do not occur frequently enough to demand special attention. Some vertices can be ignored in a similar manner: Declare all vertices connected to a concave edge to be concave, and ignore them. This makes sense for the same reason that concave edges are ignored. Declare all vertices connected to only interior edges to be interior, and ignore them. Test against all other vertices in one of the potentially several triangles they are connected to. Making use of these rules can exempt a significant number of features from collision detection computations, and thus reduce computation times while lowering the number of emitted contact points. These rules are best implemented in a preprocessing step: first, allocate six bits of additional storage for each triangle. There is one bit for each of the triangle’s vertices and edges, and any vertex or edge will only be involved in contact computations when the corresponding bit is set. Initially, all six bits for all triangles are cleared. The mesh is traversed and a record is created for each triangle edge. Each edge record contains two vertex references and a triangle reference. The edges are then sorted so that two or more edges involving the same two vertices become adjacent in the list. The sorted list is then traversed. When the system encounters a run of edges between the same two vertices, only one of the edges is examined: if it is a convex or boundary edge, set the three bits corresponding to the edge and its two vertices in the edge’s triangle’s flag record. If the edge is concave, mark its record in the sorted edge list as such, but take no other action. Once all edges in the edge list are processed, perform a second pass: in this pass look for the concave edges that were marked, and unflag both of their vertices in all of the triangles they occur in. This procedure ensures that no vertex adjacent to a concave edge ever gets tested. Figure 2: Thick black edges are the only one tested for collision (game level courtesy of Arkane Studios). Details on Contact Clustering The first step in our contact-clustering algorithm is to group the contact points according to their contact normals. Some types of collision detection will generate all contact points with an identical normal direction. Two examples are collisions between any types of convex shapes (Figure 3), and between a plane and an arbitrary shape (Figure 1). In these cases the normal group generation step is trivial and can be skipped. Otherwise at least two approaches can be used: a cube map and a k-means based algorithm. The first is suitable for contact sets involving a few distinct normal directions; the second is better for smooth shapes where no two normals tend to be identical. Cube Map Clustering This algorithm starts from a given set of input contacts, and a discrete set of contact clusters. Each cluster represents a group of contacts with similar normals. A cube map lookup maps each contact normal to the corresponding cluster. This lookup is typically faster than normal vector quantization. The six faces of the unit cube are subdivided in a regular N*N grid, resulting in 6*N*N clusters. This mapping is similar to the one used for normal masks [Zhang-Hoff97]. (Listing_1.txt) Contact clusters are never explicitly allocated in order to save memory. Instead, we compute cluster indices on-the-fly and use them to sort recorded contacts by cluster. We then process each cluster in order, reducing them on the fly. Figure 3: Two convex shapes in collision generate contacts with similar normal orientation. K-means Clustering The above cube map based algorithm performs well if the normals are very tightly clustered. Otherwise a cluster of normals may fall into different cube map cells, and be split. This can come up during collision detection between round shapes such as spheres, and highly tessellated geometry. This case also leads to many contact points, and is an ideal candidate for reduction. The k-means clustering algorithm is a well-known tool for data analysis. Given a set of input vectors, and k, the number of clusters to be found, it quickly maps the input vectors to k clusters. The cluster centers are also determined. In our application the contact normals are the input vectors. It is difficult to know ahead of time how many ‘natural’ clusters are formed by the normals, if any. In the case of a sphere versus a high-resolution triangle mesh, three clusters give good results in practice. Asking for a larger number of clusters leads to natural clusters getting split, and increases the running time of the algorithm. Asking for a single cluster is the equivalent of simply averaging all the normals, but this can lead to opposing normals canceling out. In our experience, given input data in natural clusters, k-means converges in just three iterations using arbitrary initial cluster placement. After k-means has identified the three clusters, examine the resulting average normal of each cluster. If two of the three clusters normals are within an epsilon of each other, we conclude that there were less than three natural clusters and merge the clusters. Thus, there can be one, two, or three clusters (Listing_2.txt). Cluster reduction For each cluster, whether found using the cube map or k-means, compute a projection plane as the average of all contact planes in this cluster. Then compute two orthonormal vectors on the plane, forming a basis with the plane’s normal vector. Next, project all contacts in the cluster onto the plane using simple dot products (Listing_3.txt), and record extremal values along the two derived basis vectors. Also, record the contact with greatest penetration depth. You can actually work with contact indices to avoid manipulating the more expensive contact structures. After all contacts in the cluster have been processed, at most five contacts are left: 4 contacts located on the 2D AABB around contact projections in the plane. 1 contact with greatest penetration depth. It sometimes happens that the final list of five contacts actually contains the same contact multiple times. A small O(n2) loop eventually removes redundant contacts from the list. Remaining contacts are sent to the dynamics engine. Figure 4: Composite objects also benefit from contact reduction. Details on Persistence If a physics engine does not already support contact persistence, it can be implemented through hashing. During a simulation step, contacts are recorded in a double-buffered contact vector. Double buffering ensures contacts from the previous step are still available in the current step. The contact persistence code is then given the two lists of contacts, to find correspondences between them. Contact Identifier The contact structure originally contains the two bodies in contact (either using handles, or actual pointers). To implement contact persistence, a 64-bit contact ID is added to the structure (Listing_4.txt). Contact generation routines, i.e. portions of code responsible for filling the contact structure, are now also responsible for creating a unique identifier describing each contact. Typically this 64-bit ID is composed of two 32-bit parts, each of them encoding an object’s feature (vertex, edge, face) that was used to create the contact (Listing_5.txt). These identifiers only depend on the contact generation code that created them, and can be setup in any arbitrary way as long as they define a given contact in a non-ambiguous way. A feature can actually be more than standard vertices / edges / faces – for example a voxel index works as well. Hashing First create hash values for all contacts of the previous step, and store them in a hash table. Then loop through current contacts and hash them into the previous table, in search of a similar contact. The key to the algorithm is the use of object and contact identifiers in the hash value (Listing_6.txt). The advantages of this approach over one that actually keeps persistent data for each active pair (i.e. a pair of colliding objects) are numerous: It requires minimal modifications to integrate with an existing physics engine. The main hashing part is about a page of code only, plus a few extra lines in each contact routine to generate the IDs. It is fast (experiments show an O(n) behavior). It is robust since it does not examine positions or normals to match old contacts to current ones. It does not use complex memory management, contrary to a solution where each active pair actually maintains a persistent contact array. The primary disadvantage might be that if a vertex-face contact becomes and edge/edge contact, persistence is lost. Conclusion This Gem presented an approach to reduce contact points by grouping them according to normals before applying an approximate hull computation. Contact points are made persistent using a feature based identification system. In our own work, friction forces are computed once for each of the resulting reduced groups of contact points, instead of separately at each contact as we did previously. The application of this algorithm did not have a significant negative impact on performance, but managed to reduce contact points when working with high detail geometry, which in turn lead to improved performance and increased stability. The approximate nature of the aggressive contact removal did not lead to a visible drop in simulation accuracy, primarily because the contact points with the greatest penetration are never reduced. References [Anitescu99] Mihai Anitescu, F.A. Potra, D. Stewart. Time-Stepping for ThreeDimensional Rigid-Body Dynamics. Computer Methods in Applied Mechanics and Engineering, 177 pp. 183-197, 1999. [Baraff92] David Baraff. Dynamic Simulation of Non-Penetrating Rigid Bodies. Ph.D. thesis, Dept. of Computer Science, Cornell University, 1992. [Hahn88] J.K. Hahn. Realistic animation of rigid bodies. Computer Graphics (Proc.Siggraph), vol. 22, pp. 229-308, 1987 [Jakobsen01] Thomas Jakobsen. Advanced Character Physics. Proceedings, Game Developer's Conference 2001, San Jose, 2001. [Kim02] Young J. Kim, Miguel A. Otaduy, Ming C. Lin and Dinesh Manocha. Six Degree-of Freedom Haptic Display Using Localized Contact Computations.Tenth Symposium on Haptic Interfaces For Virtual Environment and Teleoperator Systems, March 24-25, 2002. [Lozano-Perez83] T Lozano-Perez. Spatial planning: a configuration space approach. IEEE Transaction on Computers, C-32(2):108--120, 1983. [Zhang-Hoff97] Hansong Zhang, Kenny Hoff. Fast Backface Culling Using Normal Masks. ACM Symposium on Interactive 3D Graphics, Providence, 1997