# Companion

> An iPhone app that turns a photo of a real object into a textured 3D model to spin, keep, and arrange in a personal collection. A small API hands the photo to an image-to-3D model and converts the result for iOS.

- Author: Benjamin Zhuang
- Category: 3D collectibles app
- Context: Hackathon MVP · two-person team
- Years: 2026
- Stack: Swift, SwiftUI, WidgetKit, Node.js, Hono, Zod, Next.js, React Three Fiber, Meshy 6 via Wavespeed
- Source: https://github.com/Benjaminnnnnn/companion (private repository)
- Demo: https://companion-eight-zeta.vercel.app
- Web page: https://benjaminnnnnn.github.io/portfolio/companion/

**Photograph an object. Keep it as a 3D collectible.**

## Key figures

- 1 photo: in, one textured model out
- 30,000: triangle target per model
- USDZ: converted once, then cached

## A shelf for things you care about.

Companion was built in a week as a hackathon MVP. You photograph an object, wait while a model is generated, and get a 3D collectible that lives in a gallery and on home screen widgets.

## Submit, poll, convert once.

The API sends the photo to Meshy 6 through Wavespeed and returns a prediction ID, which the app polls. The first time a prediction completes, the server downloads the GLB, converts it to USDZ with a Python script, and caches the result so later polls and downloads reuse it.

Routes are described with Zod schemas that also generate the OpenAPI document. The model provider, converter, and cache sit behind small interfaces, so the generation flow reads top to bottom.

## What is real and what is a mock-up.

The 3D generation path is real. The web landing page is a marketing mock-up: its user counts, rating, and community screens are placeholder content, and its object pictures are image-model renders rather than app output.

I worked on the iOS interface, widgets, model rendering, the web app, and the API scaffold, with one teammate. The repository is private.
