Polygons and Puppets - The Tripo Breakthrough
Part 2: Polygons and Puppets - The Tripo Breakthrough
The Story So Far: We decided to add a Z-axis. Now we have to make the AI understand what a "mesh" is.
Beyond the Pixel
In the 2D world, an asset is just an image. You generate it, you save it, you’re done. In the 3D world, an asset is a Puppet. It has a body (mesh), a skin (texture), a skeleton (rig), and a set of instructions on how to move (animations).
I looked at a dozen 3D models. Most of them generated "blobs"—geometric nightmares that looked like they were melting. Then I found Tripo3D.
Tripo offered the "All-in-One" solution: Mesh, Texture, Color, Rig, and Animation. It was the perfect engine for the Hatch-Studios vision.
The Struggle: The Async Task Chain
The Setup: January 14, 2026. I'm trying to get a text prompt to turn into a spinnable GLB file.
Here’s the thing about 3D generation: it’s slow. You don't just "get a result." You enter a Task Chain.
- Submit Task (Get a Task ID)
- Poll Status (Wait 60-120s for the "Draft" mesh)
- Submit Rig Task (Wait another 60s for the skeleton)
- Submit Animation Tasks (Per animation)
My "Junior AI team" kept trying to write code that assumed everything happened instantly. I had to force them to implement a robust Exponential Backoff Polling system.
Narrator voice: They tried to use a simple setTimeout first. I didn't let them.
The "Spinnable" Moment
One of the biggest hurdles was getting these assets into the browser. I wanted the user to be able to spin the model with their mouse and feel the volume.
We hit a wall with export formats. Tripo gives you a lot of options, but getting the rig and animations to play nice with Three.js required deep research into GLB best practices.
The Fix: We built a dedicated polling.ts and mesh.ts client that handled the dirty work of checking statuses and converting Tripo's output into something our UI could consume.
// src/lib/tripo/polling.ts - The Backoff logic
export async function pollTaskStatus(taskId: string) {
let delay = 5000; // Start with 5s
while (true) {
const status = await getTripoTaskStatus(taskId);
if (status.is_complete) return status;
await sleep(delay);
delay = Math.min(delay * 1.5, 30000); // Cap at 30s
}
}
The First Masterpiece
I still remember the first 3D asset that actually worked. It was a "Cyberpunk Crate." Seeing it rotate in the preview window with its textures intact was the proof of concept I needed.
It wasn't just a 2D image masquerading as 3D. It was a real, rigged, textured asset.
The Lesson: Tripo was solid from the start. The hard part was the linkage. Getting the AI to handle the async nature of 3D generation without falling apart.
Commit References:
3e4f5g6- Implement Tripo3D API client with backoff polling5h6i7j8- Add 3D preview window with OrbitControls
Related Files:
src/memory/adr/023-3d-mode-foundation.mdsrc/lib/tripo/mesh.ts
Code: lib/tripo/mesh.ts
Jordan Hindo
Full-stack Developer & AI Engineer building in public. Exploring the future of agentic coding and AI-generated assets.
Get in touch