From Voxels to Lin Yue Developer Zyvop documented experiments rebuilding the rigged female mannequin used for the character Lin Yue in the game The Jade Crypt by scanning it into voxels at 2 cm, 1 cm and 5 mm resolutions, then comparing smoothing-and-decimation against wrapping to produce a usable surface. The 2 cm scan sampled the mannequin in its rest pose, recorded occupied cells as ASCII slices and estimated bone influences to build a simplified rig, but the developer states it was a geometric approximation that did not recover the original mesh topology, blended skin weights or detailed finger rig. Halving voxel size can increase cell count eightfold in the same volume, making finer scans increasingly expensive in memory and processing, and the work remains in progress. Last time, I wrote about reverse engineering my own game https://zyvop.com/reverse-engineering-my-own-game-or0pd . This time I had another question: what about reverse engineering a model? Not an LLM model. A GLB model In The Jade Crypt https://zyvop.com/building-the-jade-crypt-t44hy , Lin Yue started out using a free female mannequin from Quaternius’s Universal Animation Library 2 https://quaternius.com/packs/universalanimationlibrary2.html . It gave me a character and a set of movements to work with while I built the game. But looking at her one day, I wondered: what if I could make my own? The third-party female mannequin from the animation library, shown with its rig. This was the starting point for the scan experiments. That question sent me down a rabbit hole of voxels, scans, wrapping, smoothing, bad proportions, and eventually signed distance fields. The work is still in progress, but it has already changed how I think about making a character. The early voxel lead was a separate character experiment, before the mannequin-scanning work. An early generated voxel lead, from the project’s original preview. First, understand the mannequin A GLB can contain more than a visible mesh: there can be a skeleton, skin weights, materials and animation as well. My first experiment focused on the shape. Could I sample the mannequin and rebuild something that looked like it from small blocks? I started with 2 cm voxels . Think of a voxel as a little cube in 3D space. The scanner sampled the mannequin in its rest pose, recorded occupied cells as ASCII slices, and reconstructed an approximate blocky representation. For the rigged experiment, I also estimated bone influences from the source surface and built a simplified rig. This was a geometric approximation, not a recovery of the original mesh topology or skin weights. The coarse posed mannequin scan: the silhouette is there, but the blocks leave little room for fine detail. This screenshot shows the diagnostic scan, which is separate from the rest-pose rigged scan. The separate STL scanner shows the idea in code. For each cell center it counts surface crossings along a scanline, then fills points between pairs of crossings: js var inside := false for n in range 0, hits.size - 1, 2 : if hits n <= y and y < hits n + 1 : inside = true break row += "x" if inside else "." The resulting x and . characters become a slice of the volume. The STL scanner uses this approach; open or intersecting shells can leave ambiguous scanlines. Seeing a familiar silhouette emerge from rows of text was satisfying. It also showed the limitations quickly: fingers, curves and small features do not have many cells to work with at that scale. The scan approximated the dominant bone influence; it did not recover the mannequin's original blended weights or detailed finger rig. A separate STL scan captured a pose but carried no skin weights or materials at all. Smaller voxels, smoother surfaces The obvious next step was to go smaller. I explored 1 cm grids and even a 5 mm mannequin scan. Smaller cells captured more of the shape, but they also meant a much larger mesh. A smoother-looking character made of tiny cubes is still made of tiny cubes Halving the voxel size can increase the number of cells in the same 3D volume by a factor of eight. That made finer scans increasingly expensive in memory and processing, even before considering the resulting mesh complexity. The 5 mm rigged mannequin scan captures a much finer silhouette. The blue lines show the approximate rig; the surface is still built from voxels. So I compared two ways to turn that blocky result into a usable surface: - Smoothing and decimation: smooth the voxel meshes and reduce their triangles. Separate body parts remain separate, so seams and deformation need attention. - Wrapping: remesh the voxel surface into a continuous skin and transfer approximate weights onto it. This produced the greatest triangle reduction in my experiments, and the surface looked much less blocky. Wrapping didn't restore the original mannequin's topology. It generated new geometry around the scanned volume, trading the blocky appearance for a smoother, more continuous surface. The challenge then shifted from reconstruction to preserving shape and deformation quality. I also adjusted the mannequin-derived scan into a Lin Yue body silhouette. These two screenshots show that same experimental route before and after wrapping: The scan-derived Lin Yue body as fine voxels: much more detail than the coarse scan, but still visibly stepped. The scan-derived body after wrapping: a continuous, smoother surface, with an approximate rig. It is still derived from the mannequin. In the wrapping script, Blender's voxel remesh creates the new surface and a smooth modifier relaxes it: remesh = wrapped.modifiers.new 'Wrap volume', 'REMESH' remesh.mode = 'VOXEL' remesh.voxel size = size remesh.use remove disconnected = False bpy.ops.object.modifier apply modifier=remesh.name smooth = wrapped.modifiers.new 'Relax surface', 'SMOOTH' smooth.factor = 0.6 smooth.iterations = 4 bpy.ops.object.modifier apply modifier=smooth.name The script then transfers skin weights from a preserved reference mesh and relaxes them. The triangle reduction was an observation from this experiment, not a general benchmark; the repository doesn't record comparable triangle counts for every version. Wrapping was the exciting discovery, though it wasn't magic. Thin features can disappear, nearby parts can fuse, and transferred weights are not the original weights. A nice-looking still pose doesn't guarantee good movement. The independently authored 2 cm body also showed visible steps after wrapping; its 1 cm version gave the surface more to work with. But is it really mine? By this point, I could scan, reshape and wrap a mannequin-derived body. But another question kept nagging me: what if I stopped reconstructing an existing model and built the character entirely from scratch? After all, human anatomy isn't a secret. We know what a head, torso, arms and legs look like. The interesting challenge was whether I could describe those forms mathematically, generate the geometry myself, and turn them into a character with her own proportions and visual identity. The scan-based experiments had taught me a lot about geometry and reconstruction. Now I wanted to apply those lessons to something independently generated, with complete control over the shapes, proportions and design. My first attempt at an original body I wrote an independent generator using hand-chosen elliptical profiles: tapered legs, a torso, outstretched arms and an oval head. It read neither the mannequin nor its scan maps. I could generate slices, build the voxels, and wrap them into a surface. The independently authored voxel body after wrapping, rendered from its GLB. This is a body study, without hair or clothing. And honestly? My first attempt sucked big time. With that stiff T-pose and lumpy surface, she looked more like a zombie than the wuxia heroine I had in mind A body is much more than a stack of ellipses. Getting the silhouette to read from the front is one thing; making the side profile, shoulders, hips, hands and joints look convincing is another. I iterated on a second version, adjusting the proportions and adding joint spheres, but each improvement revealed another awkward transition. The exercise was valuable precisely because it exposed what I hadn't yet learned about the shape I was trying to create. Enter signed distance fields The next experiment used signed distance fields , or SDFs. Instead of placing a cube wherever I wanted solid material, I described shapes using a field: values on one side of a surface are inside, values on the other side are outside, and the zero boundary describes the surface. In this implementation, negative values represent the interior, positive values the exterior, and zero marks the surface. That gave me a different set of building blocks. I could describe limbs with tapered shapes, the head and body with rounded profiles, and joints with spheres. Smooth unions blended neighboring forms together. Marching cubes then extracted a triangle mesh from the field for Blender to work with. Here is the smooth-minimum function from the SDF generator. It blends two field values across a configurable distance k : python def smin a, b, k : h = np.clip 0.5 + 0.5 b - a / k, 0.0, 1.0 return b 1.0 - h + a h - k h 1.0 - h Once the field is sampled, the generator extracts the zero surface and writes the result as an OBJ mesh: field, origin = build field h verts, faces, , = measure.marching cubes field, level=0.0, spacing= h, h, h verts = verts + origin verts, faces = weld verts, faces write obj out, verts, faces The first SDF builder used its own geometric parameters and did not read the mannequin or scan data. It was not an instant character artist: I still had to adjust the proportions, profiles and transitions repeatedly. But now I could change the design in code, regenerate it, inspect it, and try again. From body to moving character Generating the surface was only half the problem. A static model can look convincing in Blender, but Lin Yue needs to run, climb, swim and fight in The Jade Crypt. That meant the next challenge was no longer just geometry: it was building a skeleton, assigning skin weights and making sure the character could survive movement without falling apart. The work grew into a character builder that generates the body, skins it to a 51-bone rig, builds animation clips and exports a GLB for review in Blender. The current experiments include jade-colored articulated joints, with repeated adjustments to the shoulder, hip, knee and other connections. The builder has clips for walking, running, sneaking, swimming, jumping, climbing, pushing, pulling and sword movements, along with idle and T-pose. Some are procedural; others use hand-tuned poses and timing. It also checks joint angles and excessive skin-edge stretching across frames. Those checks help catch problems such as a badly stretched neck, but they do not detect every collision or ugly crease, so visual review still matters. Here is the current result in Blender, with front and back views of Lin Yue in a T-pose: The current character study, with her face, hair and jade-colored articulated joints. She is still a work in progress. Here is an earlier render of the generated body from the builder's GLB in a walking pose: An earlier builder output in a walking pose, before the face and hair shown above. The push animation also revealed another problem: The push pose exposes a gap at the waist: the torso tilts away from the jade connector. The joint design and weights need more work as the body bends. A connected skeleton doesn't automatically mean the visible surfaces will stay connected. The current waist uses rigidly weighted pieces and a short connector, so a strong bend can expose the join. A rounded, overlapping joint or a deformable transition are possible directions to explore; neither has been validated as the fix yet. There is still integration work ahead. The builder's rig shares bone names and directions with the game model, but many local bone axes differ. Matching bone names does not guarantee animation compatibility; animation retargeting or local-basis correction may still be required. Attachments such as the sword and game-specific finger poses need testing and alignment before I can claim this is a drop-in replacement for the mannequin. Summary of experiments | Approach | What worked | Main limitation | |---|---|---| | 2 cm voxel scan | Fast silhouette approximation | Blocky, poor fine detail | | 5 mm voxel scan | Better geometric fidelity | More cells and mesh complexity | | Voxel wrapping | Smoother, continuous surface | Thin features and weight transfer | | Independent voxel body | Geometry authored from scratch | Awkward anatomy and transitions | | SDF procedural body | Parametric shapes and smooth blending | Requires careful design and tuning | | Rigged character builder | Generated animations and GLB | Joint gaps and game integration | What I learned The experiment began as a question about reverse engineering a GLB. It ended up being a lesson in making choices about what I wanted to own and understand. Voxel scans helped me explore representation and reconstruction; wrapping showed how much a surface can change; my awkward independent bodies showed how hard character design really is; and SDFs gave me a way to keep shaping an original procedural body. Lin Yue is still evolving. For now, I'm excited that the project has gone from “what if I could make my own?” to a character I can generate, rig, animate and keep improving. The next milestone isn't another polished render. It's getting this version of Lin Yue into The Jade Crypt, moving through the same traps, climbs and sword fights as the original mannequin—without her joints coming apart.