135 lines
4.5 KiB
Markdown
135 lines
4.5 KiB
Markdown
# upload-GLTF
|
|
|
|
A secure web interface for uploading 3D assets (GLTF/GLB + textures) with automatic Draco compression and GitHub push. Built for La Fabrik Durable.
|
|
|
|
## Stack
|
|
|
|
- **Next.js 16** (App Router) + React 19 + TypeScript
|
|
- **Three.js** (@react-three/fiber + @react-three/drei) for 3D preview
|
|
- **Tailwind CSS** for styling
|
|
- **Octokit** for pushing via the GitHub API
|
|
- **Blender** (headless) for Draco mesh compression
|
|
- **Coolify** (Docker) for hosting
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
git clone https://github.com/La-Fabrik-Durable/upload-GLTF.git
|
|
cd upload-GLTF
|
|
npm install
|
|
```
|
|
|
|
## Configuration
|
|
|
|
Copy `.env.example` to `.env.local` and fill in the values:
|
|
|
|
```env
|
|
UPLOAD_SECRET_KEY=your-secret-key-here
|
|
GITHUB_TOKEN=ghp_your-github-personal-access-token
|
|
GIT_BRANCH=main
|
|
GIT_REPO_URL=https://github.com/your-org/your-repo.git
|
|
BLENDER_PATH=/Applications/Blender.app/Contents/MacOS/Blender
|
|
```
|
|
|
|
| Variable | Description | Required |
|
|
|----------|-------------|----------|
|
|
| `UPLOAD_SECRET_KEY` | Secret key for upload authentication | Yes |
|
|
| `GITHUB_TOKEN` | GitHub Personal Access Token (fine-grained, `Contents: Read and write`) | Yes |
|
|
| `GIT_BRANCH` | Target branch (default: main) | No |
|
|
| `GIT_REPO_URL` | Target GitHub repository URL | Yes |
|
|
| `BLENDER_PATH` | Path to Blender binary (default: `blender`) | No |
|
|
|
|
> To create a token: GitHub > Settings > Developer settings > Fine-grained personal access tokens > select the target repo > Permissions > Contents: Read and write.
|
|
|
|
## Usage
|
|
|
|
### Development
|
|
|
|
```bash
|
|
npm run dev
|
|
```
|
|
|
|
Access the app at `http://localhost:3000`
|
|
|
|
> **Note:** Draco compression requires Blender installed locally. On macOS, Blender is typically at `/Applications/Blender.app/Contents/MacOS/Blender`. Set `BLENDER_PATH` in `.env.local` accordingly. If Blender is not available, models are pushed to GitHub without compression.
|
|
|
|
### Production (Coolify / Docker)
|
|
|
|
```bash
|
|
docker build -t upload-gltf .
|
|
docker run -p 3000:3000 \
|
|
-e UPLOAD_SECRET_KEY=your-key \
|
|
-e GITHUB_TOKEN=ghp_xxx \
|
|
-e GIT_REPO_URL=https://github.com/org/repo.git \
|
|
upload-gltf
|
|
```
|
|
|
|
The Dockerfile includes Blender headless for automatic Draco compression.
|
|
|
|
## How it works
|
|
|
|
1. The user enters their access key
|
|
2. They pick a **destination** (`farm`, `map`, `powergrid`, `workshop`, `general`, `environment`)
|
|
3. They select a folder containing:
|
|
- `model.glb` or `model.gltf` (required)
|
|
- Textures: `roughness`, `normal`, `metalness`, `color`, `displace` (`.png/.jpg/.webp`, optional)
|
|
4. The model is displayed in a 3D preview
|
|
5. On clicking "Envoyer sur GitHub":
|
|
- The app checks if the folder already exists on the remote repo
|
|
- If it exists, a confirmation dialog is shown listing the existing files that will be replaced
|
|
- On confirmation (or if the folder is new), all files are sent to the `/api/upload` endpoint
|
|
6. For models: the file is written to `/tmp`, compressed with Blender Draco, then the compressed version is pushed
|
|
7. For textures: pushed directly without compression
|
|
8. All files are pushed in a **single commit** with a formatted message:
|
|
```
|
|
update: upload-gltf add a new model -> farm/my-model
|
|
|
|
📦 Model
|
|
✅ model.gltf (compressed)
|
|
🎨 Textures
|
|
✅ color.jpg
|
|
❌ metalness (manquant)
|
|
```
|
|
9. If the folder already existed, orphan files (present in the old version but not in the new upload) are deleted in the same commit
|
|
10. If Blender is unavailable, the original model is pushed as-is (graceful fallback)
|
|
|
|
## Destinations
|
|
|
|
Uploaded models are pushed to `public/models/<destination>/<folderName>/` in the target repo:
|
|
|
|
| Destination | Path |
|
|
|-------------|------|
|
|
| Farm | `public/models/farm/` |
|
|
| Map | `public/models/map/` |
|
|
| Powergrid | `public/models/powergrid/` |
|
|
| Workshop | `public/models/workshop/` |
|
|
| General | `public/models/general/` |
|
|
| Environment | `public/models/environment/` |
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
app/
|
|
├── api/upload/route.ts # API: GET (check existence) + POST (compress + push)
|
|
├── globals.css # Tailwind + Google Fonts
|
|
├── layout.tsx # Root layout
|
|
└── page.tsx # Home page
|
|
components/
|
|
├── UploadZone.tsx # UI: key input, destination picker, folder picker, validation, overwrite confirmation, upload
|
|
├── ModelViewer.tsx # Lazy wrapper for the 3D viewer
|
|
└── SceneViewer.tsx # Three.js Canvas
|
|
scripts/
|
|
└── compress.py # Blender Draco compression script
|
|
```
|
|
|
|
## Supported Formats
|
|
|
|
| Type | Extensions |
|
|
|------|------------|
|
|
| 3D Models | `.glb`, `.gltf` |
|
|
| Textures | `.png`, `.jpg`, `.jpeg`, `.webp` |
|
|
|
|
## License
|
|
|
|
MIT
|