For nearly two weeks now I’ve been working on a voxelizer, to convert a 3D model into an image that can be displayed by LitSpin. The goal of voxelization is simple: we need to display an image on a grid of leds, which means that the input image needs to be divided into voxels (3D pixels), each voxel representing a led.
Our grid looks like this:
The number of voxels corresponds to our desired resolution (20 circles, 128 angles and 32 leds from top to bottom).
The voxelization algorithm consists in tracing rays across the model to detect intersections with the triangles of the model. When the ray crosses one triangle, it means that it is entering the volume of the model, when it crosses a second triangle, it means that it exited the model. So if the ray crossed an even number of triangles, it is inside the volume, else it is outside. Then we just need to select the voxels located where the ray is inside the volume. Since a drawing is worth a thousand words, here is an illustration in 2D:
Here I trace one vertical ray for each voxel located on the upper circle of the cylinder as shown on the simplified drawing below:
Together, the rays will cross every voxel of the grid. The algorithm used to compute the intersection point between a ray and a triangle is called the Möller–Trumbore algorithm. More about this algorithm here.
The voxelizer takes in input two files: an obj file describing the basic geometry of the models, and its associated mtl file describing its textures. It outputs a ppm file which is then easy to convert to a png file which can be used as input for Romain’s LitSimulate to display what the model should look like on LitSpin.
Here are some examples, with the original 3D models, the png file returned by the voxelizer, and the model displayed by the simulation:
As you can see, it works pretty well with the Charmander, however it does not detect the vertical faces of the cube. This is due to the fact that the rays used to voxelized are all vertical, therefore won’t really cross the vertical faces. I am planning on tracing horizontal rays as well to solve the issue, so stay tuned!