Skip to content

Repository files navigation

3D Truck — Path Editor & Follow-Path Simulator

Editor path 3D berbasis three.js + React tempat truk kontainer low-poly dapat ditempatkan, diberi tujuan, dan berjalan mengikuti lintasan (garis + kurva Bezier) dengan artikulasi kingpin yang realistis — trailer menekuk pada sambungan fifth wheel saat menikung, digerakkan oleh library simulasi vehicle-path2.

Stack React TS

Menjalankan

Prasyarat: Node.js ≥ 20.19 (atau ≥ 22.12).

npm install
npm run dev      # buka http://localhost:5173

Cara pakai

Kontrol mouse: klik kiri = aksi editor (sesuai mode aktif) · drag kanan = orbit kamera · drag tengah = pan · scroll = zoom.

  1. Line (tab PATH): drag kiri di tanah untuk menggambar garis lintasan (min. 3 m).
  2. Curve: drag dari satu garis ke garis lain — kurva Bezier penghubung dihitung otomatis (tangent mode proportional-40 / magic-55 bisa diganti di panel). Kurva digambar putus-putus dengan warna yang sama seperti garis.
  3. Drag: geser endpoint/badan garis, titik attachment kurva, truk, atau marker tujuan.
  4. Start (tab VEHICLE): klik garis (panjang ≥ 12.3 m) untuk menempatkan truk.
  5. End: pilih truk, lalu klik garis tujuan — hijau = terjangkau, merah "no path" = tidak tersambung.
  6. ▶ Play: truk berangkat dengan kecepatan konstan (slider Speed), trailer berartikulasi pada kingpin, berhenti tepat di marker. ↺ Reset mengembalikan.

Panel punya dua tema — Paper (light, default) dan Slate (dark) — diganti lewat tombol ☀/☾ di kanan atas panel; pilihan tersimpan ke localStorage (key 3d-truck-theme-v1).

Panel juga menyediakan: daftar line (rename/edit koordinat/hapus), daftar curve (edit offset/hapus), Copy Snapshot (JSON ke clipboard), Import Snapshot, statistik scene, dan section Display:

  • Truck opacity (10–100%): menembus-pandangkan semua truk.
  • Cargo per-truk (kartu VEHICLE, saat truk dipilih): pilih mode muatan (Empty / 40ft / 2×20ft / 20ft Depan / 20ft Belakang) dan warna tiap kontainer. Mode 2×20ft punya dua warna terpisah (depan & belakang). Tersimpan per-truk ke localStorage; scene lama tanpa data cargo tampil sebagai 40ft putih.
  • Axle markers (ON/OFF): palang penanda posisi axle hasil hitungan library — selalu pekat, tidak ikut transparan. Penempatan benar bila: palang amber segaris poros roda depan, slate di tengah antara dua axle penggerak tractor (pusat fifth wheel), merah di poros roda tengah tri-axle trailer.

Scene tersimpan otomatis ke localStorage (key 3d-truck-scene-v1) dan pulih saat halaman dimuat ulang.

Arsitektur

Semua koordinat dalam meter (1 unit = 1 m). Library vehicle-path2 bekerja di 2D (x, y); dunia three.js memetakannya ke (x, 0, z) dengan y ≡ z.

src/
├── ContainerTruck.js          Aset truk low-poly (vanilla three.js, beku & teruji)
├── Container.js               Aset kontainer low-poly mandiri (box 40ft/20ft + warna)
├── App.tsx                    State scene + PathEngine + loop animasi (RAF)
├── types.ts                   Tipe editor + konstanta truk (axle [3.6, 8.7] m)
├── ids.ts                     Generator ID berurut (line-N / curve-N / vehicle-N)
├── persistence.ts             Autosave localStorage + import/export snapshot
└── components/
    ├── Canvas3D.tsx           Scene three.js + seluruh interaksi editor (raycast tanah)
    ├── Panel.tsx              Panel kontrol (mode, daftar, vehicle, display)
    └── three/
        ├── SceneSetup.ts      Renderer, kamera, lampu, ground, raycast helper
        ├── PathLayer.ts       Visual garis/kurva/marker/preview di tanah
        ├── TruckLayer.ts      Instance ContainerTruck per vehicle + opacity + marker axle
        └── pose.js            Pemetaan pose: 3 posisi axle 2D → posisi/yaw/hitchAngle

Bagaimana truk mengikuti path — setiap truk adalah vehicle 3 axle di library (axleSpacings = [3.6, 8.7]: axle depan → kingpin → pusat bogie trailer). Tiap frame PathEngine.moveVehicle menggeser ketiga axle sejauh speed × deltaTime di sepanjang path (kecepatan konstan, tanpa modul akselerasi); dari posisinya, pose.js menghitung:

posisi  = axle kingpin            (origin aset memang di kingpin)
yaw     = −heading_tractor
hitch   = wrapToPi(heading_tractor − heading_trailer)   → ContainerTruck.hitchAngle

Aset ContainerTruck (mandiri, bisa dicopy ke project lain)

import { ContainerTruck } from './ContainerTruck.js';

const truck = new ContainerTruck();        // opsional: { cabColor, boxColor }
scene.add(truck);                          // extends THREE.Group, 21 mesh
truck.hitchAngle = Math.PI / 6;            // artikulasi kingpin, clamp ±90°
truck.dispose();                           // lepas resource GPU (geometry roda dibagi antar instance)

Scripts

Perintah Fungsi
npm run dev Dev server Vite
npm run build Typecheck (tsc --noEmit) + build produksi
npm run preview Serve hasil build
npm run typecheck Pemeriksaan TypeScript saja
npm run smoke 18 asersi aset ContainerTruck termasuk cargo (Node murni, tanpa browser)
npm run check:pose 11 asersi pemetaan pose 2D→3D
npm run check:container 11 asersi aset Container (dims 40ft/20ft, warna, dispose)

Dokumentasi proses

Desain & rencana implementasi tiap fase tersimpan di repo:

  • docs/superpowers/specs/ — spec yang disetujui (aset truk, editor + follow-path, transparansi + marker axle)
  • docs/superpowers/plans/ — implementation plan per fase

Referensi visual aset: Screenshot 2026-06-10 133628.png (truk kontainer 4 arah).

Kredit

  • Simulasi gerak multi-axle: vehicle-path2 (pola pemakaian mengikuti demo resminya).
  • Dibangun dengan three.js, React 19, TypeScript, dan Vite.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages