Skip to content

Commit 19489e4

Browse files
committed
fix: format code with Biome
- Apply Biome formatting to all GLTF implementation files - Fix formatting issues in tests and core implementation - Ensure consistency with project style guidelines
1 parent 1ca10da commit 19489e4

21 files changed

Lines changed: 7440 additions & 501 deletions

.envrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
use flake

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,7 @@ reference-repos
3737
bun.lock
3838
relevant-repos
3939
.vercel
40+
41+
# Development files
42+
CLADE.md
43+
.direnv/

CLAUDE.md

Lines changed: 177 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,188 @@
11
---
2-
description: Use Bun instead of Node.js, npm, pnpm, or vite.
2+
description: GLTF Support Implementation for circuit-json-to-gltf
33
globs: "*.ts, *.tsx, *.html, *.css, *.js, *.jsx, package.json"
44
alwaysApply: false
55
---
66

7-
Default to using Bun instead of Node.js.
7+
# GLTF Support Implementation Guide
8+
9+
## Project Context
10+
Implementing tscircuit #758: Add cadModel.gltfUrl support to circuit-json-to-gltf.
11+
This completes the missing piece of the GLTF pipeline - 5 of 6 tasks already done.
12+
13+
## Architecture Overview
14+
15+
### Current State (83% Complete)
16+
- ✅ tscircuit/props - cadModel interface exists
17+
- ✅ tscircuit/circuit-json - `model_gltf_url` field defined
18+
- ✅ tscircuit/core - Component processing complete
19+
- ✅ tscircuit/3d-viewer - GLTF loader working (Models.stories.tsx)
20+
- ✅ tscircuit/cli - 3D viewer integration complete
21+
- ❌ circuit-json-to-gltf - **THIS IMPLEMENTATION**
22+
23+
### Data Flow
24+
```
25+
cadModel.gltfUrl (props) → model_gltf_url (circuit-json) → loadGLTF() → Triangle[] → GLTF Export
26+
```
27+
28+
## Implementation Strategy
29+
30+
### Custom GLTF Parser Approach
31+
Following project philosophy: "Pure GLTF 2.0 implementation without external 3D library dependencies"
32+
33+
**Rationale**: Project already has custom STL/OBJ parsers, maintaining consistency and avoiding dependencies.
34+
35+
### Integration Pattern
36+
Follow exact same pattern as existing STL/OBJ loaders:
37+
1. Loader function in `/lib/loaders/`
38+
2. Mesh interface in `/lib/types.ts`
39+
3. Geometry conversion in `/lib/gltf/geometry.ts`
40+
4. Pipeline integration in `/lib/converters/circuit-to-3d.ts`
41+
42+
## Files to Implement
43+
44+
### 1. NEW: `/lib/loaders/gltf.ts`
45+
```typescript
46+
export async function loadGLTF(url: string, transform?: CoordinateTransformConfig): Promise<GLTFMesh>
47+
function parseGLTF(gltfJson: any, baseUrl: string): GLTFMesh
48+
function extractMeshData(mesh: any, gltfJson: any, buffers: ArrayBuffer[]): Triangle[]
49+
```
50+
51+
**MVP Features**:
52+
- JSON GLTF format (.gltf files)
53+
- Embedded base64 buffers
54+
- TRIANGLES primitive mode
55+
- POSITION attributes (required)
56+
- NORMAL attributes (generate if missing)
57+
58+
**GLTF Parsing Algorithm**:
59+
1. Load GLTF JSON + resolve embedded buffers
60+
2. For each mesh.primitive: Extract POSITION/NORMAL via accessorbufferViewbuffer
61+
3. Convert to Triangle[] format matching STL/OBJ
62+
4. Apply coordinate transformation (Z_UP_TO_Y_UP)
63+
64+
### 2. MODIFY: `/lib/types.ts`
65+
```typescript
66+
export interface GLTFMesh extends STLMesh {
67+
// Same structure as STLMesh/OBJMesh
68+
}
69+
70+
export interface Box3D {
71+
meshType?: "stl" | "obj" | "gltf" // ADD "gltf"
72+
}
73+
```
74+
75+
### 3. MODIFY: `/lib/converters/circuit-to-3d.ts`
76+
**Integration Point**: Lines 97-148
77+
78+
**Current**:
79+
```typescript
80+
const { model_stl_url, model_obj_url } = cad
81+
if (!model_stl_url && !model_obj_url) continue
82+
```
83+
84+
**Updated**:
85+
```typescript
86+
const { model_stl_url, model_obj_url, model_gltf_url } = cad
87+
if (!model_stl_url && !model_obj_url && !model_gltf_url) continue
88+
89+
// Add GLTF loading:
90+
} else if (model_gltf_url) {
91+
box.mesh = await loadGLTF(model_gltf_url, defaultTransform)
92+
}
93+
```
894

9-
- Use `bun <file>` instead of `node <file>` or `ts-node <file>`
10-
- Use `bun test` instead of `jest` or `vitest`
11-
- Use `bun build <file.html|file.ts|file.css>` instead of `webpack` or `esbuild`
12-
- Use `bun install` instead of `npm install` or `yarn install` or `pnpm install`
13-
- Use `bun run <script>` for running scripts
14-
- Bun automatically loads .env, so don't use dotenv.
95+
### 4. MODIFY: `/lib/gltf/geometry.ts`
96+
```typescript
97+
export function createMeshFromGLTF(gltfMesh: GLTFMesh): MeshData {
98+
// Same pattern as createMeshFromSTL/createMeshFromOBJ
99+
}
100+
```
15101

16-
## Testing
102+
### 5. MODIFY: `/lib/index.ts`
103+
```typescript
104+
export { loadGLTF, clearGLTFCache } from "./loaders/gltf"
105+
```
17106

18-
Use `bun test` to run tests.
107+
## GLTF Technical Details
19108

20-
```ts#index.test.ts
21-
import { test, expect } from "bun:test";
109+
### GLTF Structure
110+
- **JSON Root**: scenes, nodes, meshes, accessors, bufferViews, buffers
111+
- **Buffers**: Raw binary data (embedded base64 or external)
112+
- **Accessors**: Typed views into buffers (vertices, normals, indices)
113+
- **Primitives**: Triangle lists with material references
22114

23-
test("hello world", () => {
24-
expect(1).toBe(1);
25-
});
115+
### Coordinate System
116+
- GLTF: Y-up right-handed
117+
- Apply: `COORDINATE_TRANSFORMS.Z_UP_TO_Y_UP` (existing pattern)
118+
119+
### Buffer Data Extraction
120+
```typescript
121+
// Extract accessor data from binary buffers
122+
function extractAccessorData(accessorIndex: number, gltfJson: any, buffers: ArrayBuffer[]) {
123+
const accessor = gltfJson.accessors[accessorIndex]
124+
const bufferView = gltfJson.bufferViews[accessor.bufferView]
125+
const buffer = buffers[bufferView.buffer]
126+
127+
// Handle componentType (FLOAT, UNSIGNED_SHORT, etc.)
128+
// Apply offset/stride from accessor/bufferView
129+
// Return typed array of position/normal/index data
130+
}
26131
```
132+
133+
## Testing Strategy
134+
135+
### Unit Tests (`/tests/unit/gltf-loader.test.ts`)
136+
- Parse simple GLTF files
137+
- Handle embedded buffers
138+
- Coordinate transformation
139+
- Error handling
140+
141+
### Integration Tests
142+
- circuit-json with model_gltf_url
143+
- End-to-end GLTFTriangle[] conversion
144+
- Performance vs STL/OBJ
145+
146+
### Test GLTF Files
147+
Use existing working models from 3d-viewer:
148+
- `./stories/assets/myGltf.gltf`
149+
- Simple geometric shapes for validation
150+
151+
## Development Workflow
152+
153+
### Day 1: Core Parser
154+
1. Implement basic GLTF parser (JSON format only)
155+
2. Add GLTFMesh interface
156+
3. Unit test with simple files
157+
158+
### Day 2: Integration
159+
1. Integrate into circuit-to-3d pipeline
160+
2. Add createMeshFromGLTF function
161+
3. Test end-to-end workflow
162+
163+
### Day 3: Polish & Demo
164+
1. Error handling and edge cases
165+
2. Performance optimization
166+
3. Demo video showing GLTF models in exported scenes
167+
168+
## Success Criteria
169+
- GLTF models load and render correctly in exported scenes
170+
- Performance comparable to STL/OBJ loading
171+
- Clean integration following existing patterns
172+
- Demo video showing end-to-end functionality
173+
- All tests pass
174+
175+
## Error Handling
176+
- Graceful degradation (log errors, continue processing)
177+
- Fallback to generic component box if GLTF loading fails
178+
- Validate GLTF structure and required fields
179+
180+
## Performance Considerations
181+
- Implement caching like STL/OBJ loaders
182+
- Memory-efficient buffer processing
183+
- Stream large GLTF files if needed
184+
185+
Default to using Bun instead of Node.js.
186+
- Use `bun test` to run tests
187+
- Use `bun run <script>` for scripts
188+
- Use `bun install` for dependencies

0 commit comments

Comments
 (0)