跪拜 Guibai
← All articles
Frontend · AIGC

A Hospital 3D Twin Built With Codex: Where AI Fails on 'Does It Look Right'

By 夏天要喝冰可乐 ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

LLM-assisted 3D work becomes reliable only when tasks with verifiable outputs are handed to the AI and everything requiring a reference photo or design judgment stays with a human. That split is the difference between a twin that feels real and one that is merely pretty from two angles.

Summary

The build uses React 19, TypeScript, Vite, and Three.js 0.186, with modeling in Blender via MCP and the heavy lifting delegated to Codex. The work is split into six stages, each with a checkable deliverable, and the scope is deliberately tight: only outpatient and emergency get full business logic; the rest are spatial guides. The result is an 800-line React app with an 180k-triangle, 112-mesh model that rotates, clicks, enters a building, and keeps its numbers adding up.

The traps all sit in the gap between 'looks plausible' and 'actually works': the entrance arc was built backward until the author supplied the exact quadratic curve; picking needs explicit visibility checks because Raycaster ignores `visible`; camera framing uses a bounding-box projection and a 1000×540 logical safe area instead of hand-tuned positions; floor expansion computes the bounding box at the exploded final state; and even the fake dashboard data must reconcile totals with sub-items or viewers sense the screen is fake.

Codex handles batch Blender operations, boilerplate, and validation scripts well, but cannot judge 'does it look like a hospital' or keep three files consistent in one pass. The author also explains why native Three.js beat react-three-fiber: the scene is almost entirely imperative and stateful, so a React wrapper adds a reconciler without removing the `ref` and `useFrame` indirection.

Takeaways
— The six-stage workflow - research lock, full-screen plan, representative zone, sample validation, zone-by-zone development, acceptance - gives Codex one checkable deliverable per stage.
— Scope was cut upfront: only outpatient and emergency get business logic; the other buildings stay purely navigational.
— The entrance arc was built backwards because the AI invented a plausible curve; the real curve is y = -27 - 16*(x/60)^2, with a 16-meter mid-segment setback.
— Embedding identity in the model via `userData` and anchor objects, with a hard `throw` on missing anchors, turns silent failures into early ones.
— Raycaster does not respect `visible`, so recursive visibility checks are required; clicks are filtered on `pointerup` by a 6-pixel movement threshold.
— Camera framing computes from the bounding box projected onto screen axes, using a 1000×540 logical safe area and a 0.92 whitespace factor.
— Floor expansion computes the bounding box at the exploded final state, and the explosion offsets live in manifest.json as model properties, not page code.
— Fake data still must add up: `total.waiting` is derived from outpatient plus emergency; inconsistent totals read as 'this screen is fake'.
— Night mode switches materials by naming convention (TJ_glass, TJ_warmGlass) against a day/night palette in Blender.
— Scale adaptation uses a 1920×1080 logical canvas with `transform: scale()`, requiring `getBoundingClientRect()` for picking, care with stacking contexts, and reserved margins.
— Headless Chrome screenshots show a black scene if `--disable-gpu` is present; removing that argument fixes WebGL context creation.
— Codex excels at batch Blender operations, boilerplate, and validation scripts; it fails at 'does this look right', cross-file consistency, and inventing acceptance criteria.
— The author avoided react-three-fiber because the scene is almost entirely imperative; native Three.js in one `useEffect` exposes only `home / focus / zoom` to React.
Conclusions

AI's spatial errors are not geometry bugs but missing referents: an LLM has no photo of the real entrance, so it substitutes a visually plausible arc; the fix is a human supplying the exact quadratic and enforcing it in the model.

The claim that credibility is calculated, not modeled, is the sharpest point: viewers trust a dashboard when the numbers add up, even if every number is fabricated, so data integrity becomes a hard requirement for demos.

The project shifts the developer's bottleneck from writing code to specifying acceptance criteria: every successful instruction is a transformation of 'make it good' into a verifiable statement like 'the arc mid-segment retreats 16 meters' or 'hide these five object IDs when mode is floor and zone is set'.

Concepts & terms
Blender MCP
A Model Context Protocol connection that lets an LLM such as Codex issue commands to Blender, including batch material changes, renaming, splitting, and GLB export, typically by generating `bpy` scripts.
userData
Three.js's free-form data slot attached to any Object3D; here it carries region, building, and floor identity so picking logic can tie model nodes to UI data without guessing from screen coordinates.
Safe area
The 1000×540 logical pixel region of a 1920×1080 canvas not covered by UI panels; camera framing targets this region rather than the whole browser viewport.
manifest.json
A data file holding model-level properties like floor explosion offsets, treated as part of the model rather than the page, so changing them does not require touching React code.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗