Options for modelling collisions
Collisions are a really important part of modelling components, as they specify how they behave in a physics world. In Simumatik, we have “two worlds” coexisting at the same time, a visual world and a physics world.
The visual world represents what we see as users, such as geometries, colors and textures for example. The physics world represents what the physics engine sees, such as collision shapes, mass and inertia.
When modeling components, we can decide if they are just visual elements or if they need physics properties. For example, a box interacting with other elements will need some physics, but an element just used for background decoration will not.
In emulation we split these worlds to achieve a perfect balance between performance and accuracy. Physics is costly to calculate, mainly due to object collisions and the need to keep track of thousands of triangles (fig.1) moving in an environment with plenty of objects.
To optimize this, we can use different geometries for the visual and the collision. That’s why in some video games, objects that didn’t collide visually, collided in the physics world, like a bullet going above your shoulder (fig.2).
fig.1 a mesh asset.
fig.2 mesh with a cube collision.
fig.3 mesh with convex hull collision.
fig.4 a collision mesh.
In order to create more realistic representations, a complex collision can be really simplified by using a convex-hull, which is the minimum geometry that surrounds the object (fig.3). This option is the most used as it provides a good balance.
On some occasions, more detailed geometries may be needed to allow for specific collisions to happen (fig.4). An example being hollow items, such as containers, that can have items inside. In this instance, the final collision can be recreated by using multiple simple geometries.
Simumatik gives the user total control with how to represent each component’s collision. You can easily create several collisions with different geometries, placed at different locations, thanks to the help of the Component Editor.
The simplest way to define collisions is by using one of several basic geometries, such as cubes, spheres, cylinders or planes. Let’s take a conveyor as an example (fig.5).
If we don’t need any kind of details, we could directly use a box to cover the entire object (fig.6). However, if anything tries to go below the conveyor, it won’t be able to.
An alternative would be to create several collisions, one for the surface and five to cover the skeleton (fig.7). That way, the collisions will approximately match the visuals, and objects will be able to go below the conveyor.
It all depends on your desired use. So for example, if you just plan on having objects over the conveyor, then it’s not worth defining that many collisions. The easiest way would be to just add one box for the surface! (fig.8)
fig.5 conveyor mesh.
fig.6 conveyor mesh with cube collision.
fig.7 with simple geometric collisions.
fig.8 with a cube collision on its surface.
Moreover, take a look at this curve conveyor (fig.9).
The collisions are rotated and placed over the conveyor’s rollers, making it more realistic. As you can see, you have the flexibility of choosing the best option for you.
fig.9 Conveyor mesh with collisions on each roller.
Sometimes simple geometries are not enough to build your collision shape, and therefore you can also use GLB files for collisions. To decrease the performance impact, Simumatik will try to create a convex hull for every part found in the mesh and reduce the amount of triangles.
If the mesh only has one part, a convex hull for the entire body will be created. This is the easiest option, but we lose a lot of accuracy (fig.10).
If the mesh is split in several pieces, each will have its own convex hull, allowing more details to be maintained, as you can see in the white object below (fig.11). For example, a really small item would fall down the conveyor due to the space between the rollers.
In case you don’t need these details, you can still tell Simumatik to create just one convex hull for the entire object, instead of one per piece. For that, add the element “as_convex_hull” inside Collision > Mesh and enable it to simplify the model.
It is also possible to use a mesh without creating a convex_hull if the object is static (mass 0), as it’s cheaper to calculate (fig.12). Add the element “as_triangle_mesh” inside Collision -> Mesh and enable it to use the mesh’s wireframe as a collision. This would be the most accurate option.
fig.10 convex hull collision.
fig.11 collision made from several convex hull parts (white).
fig.12 using a trimesh collision.
Some meshes are composed of just one piece (fig.13), like a concave cylinder (white) for example. If the component is dynamic (it has mass) we can’t enable “as_triangle_mesh”, so a convex_hull will be generated. The issue is that the object won’t be hollow anymore (blue).
fig.13 Cylinder mesh (white)
& its convex hull (blue)
fig.14 Cylinder mesh in multiple pieces (white) & concave cylinder made from several convex_hulls (blue)
fig.15 Cylinder mesh (white) &
concave cylinder generated with VHACD (blue)
In order to fix this problem (fig.14), the easiest way would be to cut the geometry into smaller pieces (white), so the convex hull is calculated for each small part (blue).
Some algorithms can perform this split operation automatically, such as VHACD. You can find open-source libraries or blender plugins for that, like for example github.com/kmammou/v-hacd. Above you can see the original one-piece cylinder and the generated several-pieces output (fig.15).
When working with meshes, independently of the method used, it’s really important to maintain the mesh’s triangle count as low as possible. This is the reason why using simple geometries is always the recommended way performance wise. You can check out our separate blog
By default, the physics engine is configured to work with relatively big objects. For performance and stability, a collision margin is automatically set, which means that your collision shapes will be thicker than the defined ones (1cm approx).
This is not an issue with components around 0.2m or bigger, but it may be for smaller ones, with a size around just a few centimeters. For instance, even though the following cylinder (fig.16) visually fits within the walls, the perpendicular yellow lines show it is colliding with the walls.
To fix this issue, we can individually change every collision’s margin by adding the margin element inside each collision element. There is no perfect value, so some testing needs to be performed in order to find the right one for you.
fig.16 Instability generated by collisions margins
fig.17 Stable collisions after tweaking collisions margins
For this case, static (green) collisions’s margins were set to 0, and dynamic (red) collisions’ margins to 0.001 (1mm). Be careful to never set dynamic collision’s margin to 0. As you can see (fig.17), most of the lines disappeared and the object is now properly touching the floor.
So to summarize, there is not a perfect way for when building virtual models, as it depends on the end-users goal. Simumatik’s goal is to provide them all the necessary tools to build models easily, while supporting every use-case by giving you as much flexibility as possible.
Emulating doesn’t need to be computationally expensive, it’s a matter of reaching the right balance. Some projects may want to prioritize the visual aspects while others may want extra accuracy. It’s up to you!