diff --git a/.claude/agents/perf-review.md b/.claude/agents/perf-review.md new file mode 100644 index 0000000..b57134d --- /dev/null +++ b/.claude/agents/perf-review.md @@ -0,0 +1,36 @@ +--- +name: perf-review +description: Three.js / React Three Fiber performance auditor for the 3D portfolio room. Use PROACTIVELY after changes to the scene (RoomScene, Portfolio, assets) or when FPS, memory, or load time regress. Audits React re-renders, draw calls, shadows, textures, useFrame GC pressure, and asset sizes, then proposes or applies fixes that preserve visual quality. +--- + +You are a senior graphics engineer auditing a react-three-fiber portfolio room (Three.js, TypeScript, Next.js). +Maximize performance WITHOUT reducing visual quality. +A quality trade-off is a last resort and must be called out explicitly. + +## Targets +120 FPS on high-end desktops; 60+ FPS on mid-range GPUs (RTX 3060 class at 1440p); stable frame times; fast initial load; minimal memory; zero unnecessary React re-renders. + +## Budgets (warn when exceeded) +- Draw calls: <100 ideal, 200 max +- Triangles: <2M ideal, 5M max +- Texture memory: <500MB ideal, 1GB max +- Lights: ~1 key + 1 HDRI + 3-5 locals; shadows only on lights/objects that matter + +## Audit checklist (run on every change) +- **React**: unnecessary re-renders, missing memo/useMemo/useCallback, wrong effect deps, state updates in loops, objects recreated in render. +- **Three/R3F**: draw-call count, duplicate materials/geometries (share or instance them), light and shadow-caster count, texture memory, allocations inside useFrame (no `new Vector3`/`new Color` per frame — hoist and reuse), per-frame scene traversals or raycasts, work in useFrame that could run once. +- **Assets**: oversized or duplicate textures, uncompressed models (prefer meshopt/Draco, KTX2 textures), missing mipmaps, models loaded eagerly that could lazy-load. +- **Memory**: leaks, undisposed geometries/materials/textures/render targets, listeners not removed on unmount. +- **Animations/camera**: delta-time based, allocation-free, damped/eased, pause when tab hidden or object off-screen. + +## Prefer (in order) +Shared materials/geometries, instancing, merged meshes, static/baked shadow maps, LOD, asset compression, lazy loading — before ANY visible quality reduction. Reuse optimization patterns that already exist in this codebase before inventing new ones. + +## Report format +1. **Score /100** + top FPS risks in one line each. +2. **Findings** grouped Critical / Medium / Minor. Each: problem, why it hurts, `file:line`, fix (with code), estimated gain. +3. **Regressions**: treat every change as a PR review against the existing optimizations — never assume new code is optimal. + +## Project notes +- Perf knobs and budget decisions get logged as ADRs in `docs/decisions/` (see ADR-0011, ADR-0012). GUIDELINES.md sets the AAA-visuals bar — quality wins ties; perf work must not visibly degrade the room. +- The scene renders in the Claude Preview pane: verify with `preview_screenshot` before/after, and check the dev Stats meter (top-left) for FPS. diff --git a/.claude/launch.json b/.claude/launch.json index e8add2a..8edcbbc 100644 --- a/.claude/launch.json +++ b/.claude/launch.json @@ -5,7 +5,15 @@ "name": "portfolio-dev", "runtimeExecutable": "npm", "runtimeArgs": ["run", "dev"], - "port": 3000 + "port": 3000, + "autoPort": true + }, + { + "name": "portfolio-goodnight", + "runtimeExecutable": "npm", + "runtimeArgs": ["run", "dev:goodnight"], + "port": 3001, + "autoPort": true } ] } diff --git a/.gitignore b/.gitignore index 79673ae..951c28f 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ node_modules/ out/ build/ dist/ +*.tsbuildinfo # Environment variables — keep secrets out of git! .env @@ -42,3 +43,6 @@ headshot.* # Session handoff notes — local only, never published SESSION_TURNOVER.md + +# Project planning & workflow docs — kept on this computer only, not in the repo +docs/ diff --git a/CLAUDE.md b/CLAUDE.md index dedf75d..1413813 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,29 +2,51 @@ # Portfolio — Francisco Cardenas @AGENTS.md +@GUIDELINES.md ## Active phase -**Perspective-room redesign** (ADR-0002). **Phase 1: Room shell & camera — done** (signed off 2026-06-20; left-wall glitch fixed, global pull-back, left→right tour order — ADR-0006). Next: **Phase 2 — Hero objects: poster + flag** (planned, not started). +**PIVOT to real-time 3D — ADR-0010 (supersedes ADR-0002).** Francisco chose real 3D (Three.js / +react-three-fiber) over the CSS-3D room after seeing a real model in-page. **Phase 3 re-scoped:** rebuild +the room in 3D matching the current feel — room shell + warm light + scroll-wheel camera between the 6 +stops + the 5 placeholder markers + click-to-inspect (cards/résumé reused as HTML overlays from +`site.ts`), **minus the PC/desk and window** — then furnish with royalty-free `.glb` models. The CSS work +(Phases 1–3: room shell, camera, poster, desk/window) is being **replaced**; `site.ts` + inspect-card/résumé +UI carry over. **All work uncommitted** (Francisco gates the save). **First 3D step landed:** room shell + +warm lighting + scroll/keys/focus-rail camera between the 6 stops + 5 markers + click-to-inspect rebuilt in +react-three-fiber (CSS room/poster/desk/window removed). Next: real furniture (.glb) + live framing/lighting +tuning in a real browser (the headless preview can't hold a WebGL context — see Phase 3 log). ## Pointers - Plan: [docs/00_plan.md](docs/00_plan.md) - Decision log: [docs/decisions/](docs/decisions/) -- Current turnover: [docs/artifacts/handoffs/2026-06-20_phase1-closeout.md](docs/artifacts/handoffs/2026-06-20_phase1-closeout.md) +- Current turnover: [docs/artifacts/handoffs/2026-06-25_195918_phase-3_gaming-setup-and-peripherals.md](docs/artifacts/handoffs/2026-06-25_195918_phase-3_gaming-setup-and-peripherals.md) ## Phase index | # | Name | Status | Closeout date | Phase file | |---|------|--------|---------------|------------| | 1 | Room shell & camera | done | 2026-06-20 | [docs/01_room-shell-and-camera.md](docs/01_room-shell-and-camera.md) | -| 2 | Hero objects: poster + flag | planned | — | tracked in [docs/00_plan.md](docs/00_plan.md) | -| 3 | Furnish & populate sections | planned | — | tracked in [docs/00_plan.md](docs/00_plan.md) | +| 2 | Hero objects: poster + flag | done (uncommitted) | 2026-06-22 | [docs/02_hero-objects-poster-flag.md](docs/02_hero-objects-poster-flag.md) | +| 3 | Furnish & populate sections | in progress | — | [docs/03_furnish-sections.md](docs/03_furnish-sections.md) | | 4 | Lighting, polish, responsive, a11y | planned | — | tracked in [docs/00_plan.md](docs/00_plan.md) | | 5 | Content finalize & ship | planned | — | tracked in [docs/00_plan.md](docs/00_plan.md) | ## Standing rules +- **AAA-realism quality bar (GUIDELINES.md, added 2026-07-06 by Francisco):** realism/immersion over simplicity — PBR everywhere, 2K+ textures, cinematic lighting, high-poly assets, lived-in details, premium interactions. Where it conflicts with the older "calm WebGL budget" habits (ADR-0011's no-shadows/no-env-maps, "primitives keep the budget calm"), the guidelines set the new direction: pursue the quality, validate perf (60 FPS @1440p mid-range GPU), and log an ADR when a budget trade-off is decided. - **Full planning, hands-on execution (ADR-0003, supersedes ADR-0001):** locked plan + phases + decision log + handoffs, but build in the main session (no orchestration subagents) for the live-preview design loop. Commit per phase. -- Redesign = looks-3D perspective room assembled in the browser (CSS 3D), NOT real-time 3D (ADR-0002). +- Redesign = real-time 3D room (Three.js / react-three-fiber), rebuilt to match the CSS room's feel (ADR-0010, supersedes ADR-0002). - All paths use forward slashes. - Free-tier services only (Vercel hobby); CC0 assets only — no paid SaaS without an ADR. - Don't commit/push/deploy until Francisco says so. +- **Goodnight sandbox (added 2026-07-09, Francisco's ask):** overnight autonomous sessions ("run + goodnight have fun") must NOT touch this tree. They work in the `../Portfolio-goodnight` worktree + on the `goodnight` branch (first step: `git -C ../Portfolio-goodnight merge ` or + reset it to the session's start point), previewed via the `portfolio-goodnight` launch config → + localhost:3001. The regular room stays on localhost:3000 unchanged. In the morning Francisco + compares both hosts and says which goodnight changes merge into the working branch — nothing + merges without his pick. +- **Direct requests land on the MAIN tree (added 2026-07-09, Francisco's ask):** anything Francisco + asks for in a regular session is built on this tree / localhost:3000 — never on the goodnight + branch. Goodnight-branch content only moves here when Francisco names it (he drives the + migration, piece by piece). - Turbopack cache goes stale on CSS/font edits — stop server, `rm -rf .next`, restart. - `Private Random Stuff/` is git-ignored (résumés, references, raw textures) — never commit it. diff --git a/CREDITS.md b/CREDITS.md new file mode 100644 index 0000000..17451bf --- /dev/null +++ b/CREDITS.md @@ -0,0 +1,62 @@ +# Credits + +Third-party assets used in this site, with attribution as required by their licenses. + +## 3D models + +- **Messy bed 2.0 (with wall mounted backboard)** — `public/models/messy-bed/` + This work is based on ["Messy bed 2.0 (with wall mounted backboard)"](https://sketchfab.com/3d-models/messy-bed-20-with-wall-mounted-backboard-a2b2645701c94fa49e65661806219c6b) + by [thethieme](https://sketchfab.com/thethieme), licensed under [CC-BY-4.0](http://creativecommons.org/licenses/by/4.0/). + (Textures downscaled to 1K for web performance.) + +- **L-shaped desk table with wood tabletop** — `public/models/desk/` + This work is based on ["L-shaped desk table with wood tabletop"](https://sketchfab.com/3d-models/l-shaped-desk-table-with-wood-tabletop-087212b79e1142cfbd3babe862db7328) + by [Superenforcer_xp](https://sketchfab.com/Superenforcer_xp), licensed under [CC-BY-4.0](http://creativecommons.org/licenses/by/4.0/). + (Textures downscaled to 1K for web performance.) + +- **Gaming Computer** — `public/models/gaming-pc/` + ["Gaming Computer"](https://poly.pizza/m/5cN7W4ufoII) by Alex Safayan, + licensed under [CC-BY-3.0](https://creativecommons.org/licenses/by/3.0/), via [Poly Pizza](https://poly.pizza). + (`gaming-computer-opt.glb`: 175 fragment meshes joined with gltf-transform for draw-call performance; geometry unchanged.) + +- **RGB Keyboard and Mouse** — `public/models/rgb-keyboard-mouse/` + ["RGB Keyboard and Mouse"](https://sketchfab.com/3d-models/rgb-keyboard-and-mouse-df00ce3e66dc4b75a5f9b49c2e6b1406) by [Jamesley](https://sketchfab.com/jamesley55), + licensed under [CC-BY-4.0](http://creativecommons.org/licenses/by/4.0/), via [Sketchfab](https://sketchfab.com). + +- **Nightstand** — `public/models/nightstand/` + This work is based on ["nightstand"](https://sketchfab.com/3d-models/nightstand-415990b9b8d7434099682efbc9993132) + by [Fenik](https://sketchfab.com/fenik0), licensed under [CC-BY-4.0](http://creativecommons.org/licenses/by/4.0/). + (Textures compressed to 2K webp for web performance.) + +- **Gaming Chair** — `public/models/gaming-chair/` + ["Gaming Chair"](https://sketchfab.com/3d-models/gaming-chair-6ca81f60846648609b4208c9e7f31b14) by [9arts](https://sketchfab.com/9arts), + licensed under [CC-BY-4.0](http://creativecommons.org/licenses/by/4.0/), via [Sketchfab](https://sketchfab.com). + (`chair-opt.glb`: 67 fragment meshes joined into one .glb with gltf-transform for draw-call performance; geometry unchanged.) + +- **T-Rex (shelf figurine)** — `public/models/decor/trex.glb` + ["T-Rex"](https://poly.pizza/m/9GyZw9gGPMq) by Poly by Google, + licensed under [CC-BY-3.0](https://creativecommons.org/licenses/by/3.0/), via [Poly Pizza](https://poly.pizza). + +- **Diplodocus (shelf figurine)** — `public/models/decor/diplodocus.glb` + ["Diplodocus"](https://poly.pizza/m/12n6ICAVpYB) by Poly by Google, + licensed under [CC-BY-3.0](https://creativecommons.org/licenses/by/3.0/), via [Poly Pizza](https://poly.pizza). + +- **Simple soccer football** — `public/models/decor/soccer-ball.glb` + ["Simple soccer football"](https://poly.pizza/m/57u6P7Sr7K0) by Smirnoff Alexander, + licensed under [CC-BY-3.0](https://creativecommons.org/licenses/by/3.0/), via [Poly Pizza](https://poly.pizza). + +- **Headphones (CC0)** — `public/models/decor/headphones.glb` + ["Headphones"](https://poly.pizza/m/PSsWSIAYIL) by CreativeTrio, + Public Domain (CC0), via [Poly Pizza](https://poly.pizza). (Hung on the site's procedural desk stand.) + +- **Book Encyclopedia Set 01 (CC0)** — `public/models/polyhaven/book_encyclopedia_set_01/` + ["Book Encyclopedia Set 01"](https://polyhaven.com/a/book_encyclopedia_set_01) by John Malcolm, + [Poly Haven](https://polyhaven.com), CC0. (2K glTF export; 20 volumes used across the bookcase bays.) + +## Textures (CC0 — no attribution required, listed for provenance) + +- **Walls — painted plaster** (`public/textures/wall-*`): "PaintedPlaster017", [ambientCG](https://ambientcg.com), CC0. +- **Floor — wood** (`public/textures/floor-*`): "Wood Floor", [Poly Haven](https://polyhaven.com/a/wood_floor), CC0 (2K JPG set; replaced ambientCG "WoodFloor043"). +- **Ceiling — plaster** (`public/textures/ceiling-*`): "Plaster001", [ambientCG](https://ambientcg.com), CC0. +- **Window view — sky over leafy suburb** (`public/textures/window-view.jpg`): window-shaped crop from the tonemapped panorama of ["Kloofendal 48d Partly Cloudy"](https://polyhaven.com/a/kloofendal_48d_partly_cloudy) by Greg Zaal, [Poly Haven](https://polyhaven.com), CC0. (Cropped + downscaled to 1600px for web performance.) +- **Environment HDRI — reflections/image-based fill** (`public/textures/env-kloofendal-1k.hdr`): ["Kloofendal 48d Partly Cloudy"](https://polyhaven.com/a/kloofendal_48d_partly_cloudy) by Greg Zaal, [Poly Haven](https://polyhaven.com), CC0. (1k HDR; the same sky the window view is cropped from, so reflections match the outside.) diff --git a/GUIDELINES.md b/GUIDELINES.md new file mode 100644 index 0000000..c73e1a4 --- /dev/null +++ b/GUIDELINES.md @@ -0,0 +1,327 @@ +# Room Quality Guidelines + +## Overall Goal + +Build a modern, realistic, AAA-quality interactive room that showcases the portfolio. +Prioritize realism, immersion, and high visual fidelity over simplicity. + +## Visual Quality + +### Rendering + +- Always assume desktop-first. +- Use physically based rendering (PBR). +- Use realistic lighting and materials. +- Use HDRI environment maps whenever possible. +- Use ACES Filmic tone mapping. +- Enable color management. +- Use sRGB textures. +- Prefer soft realistic shadows. +- Never use flat colors if a realistic material exists. + +### Models + +- Prefer high-poly models. +- Preserve geometry detail. +- Avoid low-poly or stylized assets. +- Use bevels on hard edges. +- Add realistic imperfections. +- Never simplify geometry unless specifically asked. + +### Materials + +Every object should use realistic PBR materials. +Include: + +- Albedo +- Roughness +- Metalness +- Normal maps +- Ambient Occlusion +- Height/Displacement when appropriate + +Avoid placeholder materials. + +### Textures + +Use: + +- 2K minimum +- 4K for hero assets +- Tile seamlessly +- Maintain consistent texel density + +Avoid blurry textures. + +### Lighting + +Lighting should feel cinematic. +Use: + +- HDRI +- Directional sunlight +- Fill lighting +- Practical lights (lamps, LEDs, monitors) +- Contact shadows +- Ambient bounce + +Avoid: + +- Flat lighting +- Pure white lighting +- Overexposure + +### Realism + +Every object should have: + +- Proper scale +- Correct proportions +- Realistic spacing +- Accurate materials +- Small imperfections + +Examples: + +- Slight edge wear +- Fingerprints on glossy surfaces +- Small scratches +- Dust in corners +- Slight roughness variation + +Nothing should look computer-generated. + +## Scene Composition + +The room should feel lived in. +Include believable details like: + +- Books +- Plants +- Papers +- Keyboard +- Mouse +- Coffee mug +- Backpack +- Cables +- Monitor accessories + +Everything should have a purpose. + +## Animation + +Animations should be subtle. +Examples: + +- Floating dust particles +- Monitor glow +- Slight curtain movement +- Ceiling fan rotation +- Clock movement +- Screen reflections +- Mouse hover effects + +Avoid excessive animation. + +## Camera + +Use cinematic camera movement. +Requirements: + +- Smooth interpolation +- Slight inertia +- Gentle easing +- Comfortable FOV (45-60 degrees) +- No sudden movements + +## Performance + +Optimize intelligently. +Allowed: + +- Texture compression +- Instancing +- Frustum culling +- LOD for distant objects +- Lazy loading +- GLTF optimization + +Do NOT reduce visible quality. +Visual quality always takes priority. + +## Code Quality + +Code should be: + +- Modular +- Reusable +- TypeScript-first +- Well documented +- Easy to extend + +Organize by: + +``` +components/ +models/ +materials/ +lighting/ +animations/ +hooks/ +utils/ +config/ +``` + +Avoid large monolithic files. + +## React Three Fiber + +Use best practices. +Prefer: + +- Suspense +- Drei helpers +- useGLTF +- useTexture +- useAnimations +- Environment +- AccumulativeShadows +- ContactShadows + +Avoid unnecessary rerenders. + +## Asset Loading + +All assets should: + +- Load asynchronously +- Display loading states +- Cache properly +- Be compressed +- Use Draco or Meshopt when possible + +## Interactions + +Interactions should feel premium. +Examples: + +- Hover effects +- Cursor changes +- Smooth transitions +- Camera focus +- Interactive objects +- Portfolio screens +- Clickable devices + +No abrupt changes. + +## UI Design + +UI should be minimal. +Use: + +- Glassmorphism +- Soft blur +- Rounded corners +- Subtle shadows +- Elegant typography +- Smooth fades + +Avoid flashy colors. + +## Color Palette + +Use a cohesive palette. +Examples: + +- Warm wood +- Matte black +- Brushed aluminum +- White walls +- Soft ambient lighting +- Accent LEDs + +No oversaturated colors. + +## Audio + +Optional but encouraged. +Include subtle: + +- Room ambience +- Keyboard clicks +- Light hum +- Computer fan +- Rain outside +- Footsteps + +Keep volume low. + +## Portfolio Integration + +Projects should exist naturally inside the room. +Examples: + +- Monitor displaying project websites +- Whiteboard with project sketches +- Shelf containing awards +- Framed certificates +- Tablet showing UI work +- Books representing skills + +Avoid floating menus. + +## Responsiveness + +Support: + +- Desktop (highest quality) +- Laptop +- Tablet + +Mobile may reduce effects but preserve overall appearance. + +## Accessibility + +Include: + +- Keyboard navigation +- High contrast where needed +- Reduced motion option +- Focus indicators + +## Development Philosophy + +Before implementing any feature, ask: + +- Does this improve realism? +- Does this improve immersion? +- Would this exist in a real room? +- Does it feel premium? +- Is there a more polished implementation? + +If the answer is no, reconsider the approach. + +## General Rules + +- Never use placeholder assets in production. +- Never leave unfinished sections. +- Maintain a consistent level of detail across the scene. +- Favor realistic proportions and believable object placement. +- Prioritize quality over quantity. +- Every addition should contribute to the atmosphere or functionality of the room. +- Keep visual style consistent throughout the project. +- Use physically accurate lighting, materials, and shadows whenever possible. + +## Engineering Rules + +- Target performance: maintain 60+ FPS at 1440p on a mid-range GPU (e.g., RTX 3060/RX 6700 XT). + Profile before adding new effects. +- Post-processing: use effects sparingly (Bloom, SSAO, Depth of Field, Motion Blur) and only when they enhance realism. + Avoid over-processing the scene. +- Asset budget: optimize all imported models by removing hidden geometry, merging static meshes where appropriate, and using compressed textures and meshes. + High quality does not mean unnecessarily heavy assets. +- Lighting workflow: bake lighting where practical for static geometry, reserving real-time shadows and dynamic lights for interactive elements. +- Maintainability: expose tweakable values (lighting intensity, exposure, animation speeds, camera positions, colors) in configuration files rather than hardcoding them. +- Documentation: every significant component should include a brief comment explaining its purpose, dependencies, and any performance considerations. +- Consistency: before introducing a new model, material, or interaction, ensure it matches the existing artistic style, lighting model, and scale of the room. diff --git a/eslint.config.mjs b/eslint.config.mjs index 05e726d..553e3ee 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -12,6 +12,8 @@ const eslintConfig = defineConfig([ "out/**", "build/**", "next-env.d.ts", + // Git-ignored scratch space (saved reference pages carry their own vendor JS): + "Private Random Stuff/**", ]), ]); diff --git a/next.config.ts b/next.config.ts index e9ffa30..3d41d56 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,7 +1,10 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { - /* config options here */ + // R3F / WebGL: disable React StrictMode's dev-only double-mount. With it on, the + // creates then disposes a WebGL context at startup ("Context Lost" churn) + // which can tip a marginal GPU over. No effect in production. (ADR-0010 rebuild.) + reactStrictMode: false, }; export default nextConfig; diff --git a/package-lock.json b/package-lock.json index 390aa89..01e82bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,19 @@ { - "name": "pf-scaffold", + "name": "portfolio", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "pf-scaffold", + "name": "portfolio", "version": "0.1.0", "dependencies": { + "@react-three/drei": "^10.7.7", + "@react-three/fiber": "^9.6.1", "next": "16.2.9", "react": "19.2.4", - "react-dom": "19.2.4" + "react-dom": "19.2.4", + "three": "^0.184.0" }, "devDependencies": { "@tailwindcss/postcss": "^4", @@ -228,6 +231,15 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/runtime": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.7.tgz", + "integrity": "sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz", @@ -276,6 +288,12 @@ "node": ">=6.9.0" } }, + "node_modules/@dimforge/rapier3d-compat": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz", + "integrity": "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==", + "license": "Apache-2.0" + }, "node_modules/@emnapi/core": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", @@ -1083,6 +1101,24 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@mediapipe/tasks-vision": { + "version": "0.10.17", + "resolved": "https://registry.npmjs.org/@mediapipe/tasks-vision/-/tasks-vision-0.10.17.tgz", + "integrity": "sha512-CZWV/q6TTe8ta61cZXjfnnHsfWIdFhms03M9T7Cnd5y2mdpylJM0rF1qRq+wsQVRMLz1OYPVEBU9ph2Bx8cxrg==", + "license": "Apache-2.0" + }, + "node_modules/@monogrid/gainmap-js": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/@monogrid/gainmap-js/-/gainmap-js-3.4.0.tgz", + "integrity": "sha512-2Z0FATFHaoYJ8b+Y4y4Hgfn3FRFwuU5zRrk+9dFWp4uGAdHGqVEdP7HP+gLA3X469KXHmfupJaUbKo1b/aDKIg==", + "license": "MIT", + "dependencies": { + "promise-worker-transferable": "^1.0.4" + }, + "peerDependencies": { + "three": ">= 0.159.0" + } + }, "node_modules/@napi-rs/wasm-runtime": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.5.tgz", @@ -1306,6 +1342,94 @@ "node": ">=12.4.0" } }, + "node_modules/@react-three/drei": { + "version": "10.7.7", + "resolved": "https://registry.npmjs.org/@react-three/drei/-/drei-10.7.7.tgz", + "integrity": "sha512-ff+J5iloR0k4tC++QtD/j9u3w5fzfgFAWDtAGQah9pF2B1YgOq/5JxqY0/aVoQG5r3xSZz0cv5tk2YuBob4xEQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mediapipe/tasks-vision": "0.10.17", + "@monogrid/gainmap-js": "^3.0.6", + "@use-gesture/react": "^10.3.1", + "camera-controls": "^3.1.0", + "cross-env": "^7.0.3", + "detect-gpu": "^5.0.56", + "glsl-noise": "^0.0.0", + "hls.js": "^1.5.17", + "maath": "^0.10.8", + "meshline": "^3.3.1", + "stats-gl": "^2.2.8", + "stats.js": "^0.17.0", + "suspend-react": "^0.1.3", + "three-mesh-bvh": "^0.8.3", + "three-stdlib": "^2.35.6", + "troika-three-text": "^0.52.4", + "tunnel-rat": "^0.1.2", + "use-sync-external-store": "^1.4.0", + "utility-types": "^3.11.0", + "zustand": "^5.0.1" + }, + "peerDependencies": { + "@react-three/fiber": "^9.0.0", + "react": "^19", + "react-dom": "^19", + "three": ">=0.159" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, + "node_modules/@react-three/fiber": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-9.6.1.tgz", + "integrity": "sha512-zF0rsKcVYpcJwbFEnv2HkHX9cvOEgsfQo/X8lwmR2dn13S4qEQJXir9fxf5js2LQFoXqxOY7MDkOkYx2uZ4gSg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.17.8", + "@types/webxr": "*", + "base64-js": "^1.5.1", + "buffer": "^6.0.3", + "its-fine": "^2.0.0", + "react-use-measure": "^2.1.7", + "scheduler": "^0.27.0", + "suspend-react": "^0.1.3", + "use-sync-external-store": "^1.4.0", + "zustand": "^5.0.3" + }, + "peerDependencies": { + "expo": ">=43.0", + "expo-asset": ">=8.4", + "expo-file-system": ">=11.0", + "expo-gl": ">=11.0", + "react": ">=19 <19.3", + "react-dom": ">=19 <19.3", + "react-native": ">=0.78", + "three": ">=0.156" + }, + "peerDependenciesMeta": { + "expo": { + "optional": true + }, + "expo-asset": { + "optional": true + }, + "expo-file-system": { + "optional": true + }, + "expo-gl": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, "node_modules/@rtsao/scc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", @@ -1605,6 +1729,12 @@ "tailwindcss": "4.3.1" } }, + "node_modules/@tweenjs/tween.js": { + "version": "23.1.3", + "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz", + "integrity": "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==", + "license": "MIT" + }, "node_modules/@tybys/wasm-util": { "version": "0.10.2", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", @@ -1616,6 +1746,12 @@ "tslib": "^2.4.0" } }, + "node_modules/@types/draco3d": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/@types/draco3d/-/draco3d-1.4.10.tgz", + "integrity": "sha512-AX22jp8Y7wwaBgAixaSvkoG4M/+PlAcm3Qs4OW8yT9DM4xUpWKeFhLueTAyZF39pviAdcDdeJoACapiAceqNcw==", + "license": "MIT" + }, "node_modules/@types/estree": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", @@ -1647,11 +1783,16 @@ "undici-types": "~6.21.0" } }, + "node_modules/@types/offscreencanvas": { + "version": "2019.7.3", + "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.3.tgz", + "integrity": "sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==", + "license": "MIT" + }, "node_modules/@types/react": { "version": "19.2.17", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz", "integrity": "sha512-MXfmqaVPEVgkBT/aY0aGCkRWWtByiYQXo3xdQ8r5RzuFrPiRn8Gar2tQdXSUQ2GKV3bkXckek89V8wQBY2Q/Aw==", - "dev": true, "license": "MIT", "dependencies": { "csstype": "^3.2.2" @@ -1667,6 +1808,41 @@ "@types/react": "^19.2.0" } }, + "node_modules/@types/react-reconciler": { + "version": "0.28.9", + "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.9.tgz", + "integrity": "sha512-HHM3nxyUZ3zAylX8ZEyrDNd2XZOnQ0D5XfunJF5FLQnZbHHYq4UWvW1QfelQNXv1ICNkwYhfxjwfnqivYB6bFg==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/stats.js": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.4.tgz", + "integrity": "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==", + "license": "MIT" + }, + "node_modules/@types/three": { + "version": "0.184.1", + "resolved": "https://registry.npmjs.org/@types/three/-/three-0.184.1.tgz", + "integrity": "sha512-6q4VdiqVsrTRqmk62/BnlcAvIrnDM0zf2ZDVKI5kZiniWrSaOHaQzmbp+BNzoggc/8tgW412pL//wZIxu2PPTA==", + "license": "MIT", + "dependencies": { + "@dimforge/rapier3d-compat": "~0.12.0", + "@tweenjs/tween.js": "~23.1.3", + "@types/stats.js": "*", + "@types/webxr": ">=0.5.17", + "fflate": "~0.8.2", + "meshoptimizer": "~1.1.1" + } + }, + "node_modules/@types/webxr": { + "version": "0.5.24", + "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.24.tgz", + "integrity": "sha512-h8fgEd/DpoS9CBrjEQXR+dIDraopAEfu4wYVNY2tEPwk60stPWhvZMf4Foo5FakuQ7HFZoa8WceaWFervK2Ovg==", + "license": "MIT" + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.61.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.61.1.tgz", @@ -2316,6 +2492,24 @@ "win32" ] }, + "node_modules/@use-gesture/core": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/@use-gesture/core/-/core-10.3.1.tgz", + "integrity": "sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw==", + "license": "MIT" + }, + "node_modules/@use-gesture/react": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/@use-gesture/react/-/react-10.3.1.tgz", + "integrity": "sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g==", + "license": "MIT", + "dependencies": { + "@use-gesture/core": "10.3.1" + }, + "peerDependencies": { + "react": ">= 16.8.0" + } + }, "node_modules/acorn": { "version": "8.17.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", @@ -2609,6 +2803,26 @@ "dev": true, "license": "MIT" }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, "node_modules/baseline-browser-mapping": { "version": "2.10.37", "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.37.tgz", @@ -2621,6 +2835,15 @@ "node": ">=6.0.0" } }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, "node_modules/brace-expansion": { "version": "1.1.15", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", @@ -2679,6 +2902,30 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/call-bind": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", @@ -2739,6 +2986,19 @@ "node": ">=6" } }, + "node_modules/camera-controls": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/camera-controls/-/camera-controls-3.1.2.tgz", + "integrity": "sha512-xkxfpG2ECZ6Ww5/9+kf4mfg1VEYAoe9aDSY+IwF0UEs7qEzwy0aVRfs2grImIECs/PoBtWFrh7RXsQkwG922JA==", + "license": "MIT", + "engines": { + "node": ">=22.0.0", + "npm": ">=10.5.1" + }, + "peerDependencies": { + "three": ">=0.126.1" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001799", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001799.tgz", @@ -2816,11 +3076,28 @@ "dev": true, "license": "MIT" }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -2835,7 +3112,6 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "dev": true, "license": "MIT" }, "node_modules/damerau-levenshtein": { @@ -2960,6 +3236,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/detect-gpu": { + "version": "5.0.70", + "resolved": "https://registry.npmjs.org/detect-gpu/-/detect-gpu-5.0.70.tgz", + "integrity": "sha512-bqerEP1Ese6nt3rFkwPnGbsUF9a4q+gMmpTVVOEzoCyeCc+y7/RvJnQZJx1JwhgQI5Ntg0Kgat8Uu7XpBqnz1w==", + "license": "MIT", + "dependencies": { + "webgl-constants": "^1.1.1" + } + }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", @@ -2983,6 +3268,12 @@ "node": ">=0.10.0" } }, + "node_modules/draco3d": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.7.tgz", + "integrity": "sha512-m6WCKt/erDXcw+70IJXnG7M3awwQPAsZvJGX5zY7beBqpELw6RDGkYVU0W43AFxye4pDZ5i2Lbyc/NNGqwjUVQ==", + "license": "Apache-2.0" + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -3714,6 +4005,12 @@ "reusify": "^1.0.4" } }, + "node_modules/fflate": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.3.tgz", + "integrity": "sha512-tbZNuJrLwGUp3zshBtdy4W+ORxZuIh8a5ilyIEQDC5rY1f3U20JMry0Ll3WBzU58EZKsEuJFXhb5gwv8CsPvgA==", + "license": "MIT" + }, "node_modules/file-entry-cache": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", @@ -3971,6 +4268,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/glsl-noise": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/glsl-noise/-/glsl-noise-0.0.0.tgz", + "integrity": "sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w==", + "license": "MIT" + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -4102,6 +4405,32 @@ "hermes-estree": "0.25.1" } }, + "node_modules/hls.js": { + "version": "1.6.16", + "resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.6.16.tgz", + "integrity": "sha512-VSIRpLfRwlAAdGL4wiTucx2ScRipo0ed1FBatWkyt832jC4CReKstga6yIhYVwGu9LOBjuX9wzmRMeQdBJtzEA==", + "license": "Apache-2.0" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -4112,6 +4441,12 @@ "node": ">= 4" } }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "license": "MIT" + }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", @@ -4440,6 +4775,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "license": "MIT" + }, "node_modules/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", @@ -4596,7 +4937,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, "license": "ISC" }, "node_modules/iterator.prototype": { @@ -4617,6 +4957,18 @@ "node": ">= 0.4" } }, + "node_modules/its-fine": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/its-fine/-/its-fine-2.0.0.tgz", + "integrity": "sha512-KLViCmWx94zOvpLwSlsx6yOCeMhZYaxrJV87Po5k/FoZzcPSahvK5qJ7fYhS61sZi5ikmh2S3Hz55A2l3U69ng==", + "license": "MIT", + "dependencies": { + "@types/react-reconciler": "^0.28.9" + }, + "peerDependencies": { + "react": "^19.0.0" + } + }, "node_modules/jiti": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", @@ -4764,6 +5116,15 @@ "node": ">= 0.8.0" } }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, "node_modules/lightningcss": { "version": "1.32.0", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", @@ -5083,6 +5444,16 @@ "yallist": "^3.0.2" } }, + "node_modules/maath": { + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/maath/-/maath-0.10.8.tgz", + "integrity": "sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g==", + "license": "MIT", + "peerDependencies": { + "@types/three": ">=0.134.0", + "three": ">=0.134.0" + } + }, "node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", @@ -5113,6 +5484,21 @@ "node": ">= 8" } }, + "node_modules/meshline": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/meshline/-/meshline-3.3.1.tgz", + "integrity": "sha512-/TQj+JdZkeSUOl5Mk2J7eLcYTLiQm2IDzmlSvYm7ov15anEcDJ92GHqqazxTSreeNgfnYu24kiEvvv0WlbCdFQ==", + "license": "MIT", + "peerDependencies": { + "three": ">=0.137" + } + }, + "node_modules/meshoptimizer": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-1.1.1.tgz", + "integrity": "sha512-oRFNWJRDA/WTrVj7NWvqa5HqE1t9MYDj2VaWirQCzCCrAd2GHrqR/sQezCxiWATPNlKTcRaPRHPJwIRoPBAp5g==", + "license": "MIT" + }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -5526,7 +5912,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -5597,6 +5982,12 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/potpack": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz", + "integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==", + "license": "ISC" + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -5607,6 +5998,16 @@ "node": ">= 0.8.0" } }, + "node_modules/promise-worker-transferable": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/promise-worker-transferable/-/promise-worker-transferable-1.0.4.tgz", + "integrity": "sha512-bN+0ehEnrXfxV2ZQvU2PetO0n4gqBD4ulq3MI1WOPLgr7/Mg9yRQkX5+0v1vagr74ZTsl7XtzlaYDo2EuCeYJw==", + "license": "Apache-2.0", + "dependencies": { + "is-promise": "^2.1.0", + "lie": "^3.0.2" + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -5678,6 +6079,21 @@ "dev": true, "license": "MIT" }, + "node_modules/react-use-measure": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.7.tgz", + "integrity": "sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.13", + "react-dom": ">=16.13" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, "node_modules/reflect.getprototypeof": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", @@ -5722,6 +6138,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve": { "version": "2.0.0-next.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.7.tgz", @@ -5983,7 +6408,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -5996,7 +6420,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -6094,6 +6517,32 @@ "dev": true, "license": "MIT" }, + "node_modules/stats-gl": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/stats-gl/-/stats-gl-2.4.2.tgz", + "integrity": "sha512-g5O9B0hm9CvnM36+v7SFl39T7hmAlv541tU81ME8YeSb3i1CIP5/QdDeSB3A0la0bKNHpxpwxOVRo2wFTYEosQ==", + "license": "MIT", + "dependencies": { + "@types/three": "*", + "three": "^0.170.0" + }, + "peerDependencies": { + "@types/three": "*", + "three": "*" + } + }, + "node_modules/stats-gl/node_modules/three": { + "version": "0.170.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.170.0.tgz", + "integrity": "sha512-FQK+LEpYc0fBD+J8g6oSEyyNzjp+Q7Ks1C568WWaoMRLW+TkNNWmenWeGgJjV105Gd+p/2ql1ZcjYvNiPZBhuQ==", + "license": "MIT" + }, + "node_modules/stats.js": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/stats.js/-/stats.js-0.17.0.tgz", + "integrity": "sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==", + "license": "MIT" + }, "node_modules/stop-iteration-iterator": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz", @@ -6294,6 +6743,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/suspend-react": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/suspend-react/-/suspend-react-0.1.3.tgz", + "integrity": "sha512-aqldKgX9aZqpoDp3e8/BZ8Dm7x1pJl+qI3ZKxDN0i/IQTWUwBx/ManmlVJ3wowqbno6c2bmiIfs+Um6LbsjJyQ==", + "license": "MIT", + "peerDependencies": { + "react": ">=17.0" + } + }, "node_modules/tailwindcss": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.1.tgz", @@ -6315,6 +6773,44 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/three": { + "version": "0.184.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.184.0.tgz", + "integrity": "sha512-wtTRjG92pM5eUg/KuUnHsqSAlPM296brTOcLgMRqEeylYTh/CdtvKUvCyyCQTzFuStieWxvZb8mVTMvdPyUpxg==", + "license": "MIT" + }, + "node_modules/three-mesh-bvh": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/three-mesh-bvh/-/three-mesh-bvh-0.8.3.tgz", + "integrity": "sha512-4G5lBaF+g2auKX3P0yqx+MJC6oVt6sB5k+CchS6Ob0qvH0YIhuUk1eYr7ktsIpY+albCqE80/FVQGV190PmiAg==", + "license": "MIT", + "peerDependencies": { + "three": ">= 0.159.0" + } + }, + "node_modules/three-stdlib": { + "version": "2.36.1", + "resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.36.1.tgz", + "integrity": "sha512-XyGQrFmNQ5O/IoKm556ftwKsBg11TIb301MB5dWNicziQBEs2g3gtOYIf7pFiLa0zI2gUwhtCjv9fmjnxKZ1Cg==", + "license": "MIT", + "dependencies": { + "@types/draco3d": "^1.4.0", + "@types/offscreencanvas": "^2019.6.4", + "@types/webxr": "^0.5.2", + "draco3d": "^1.4.1", + "fflate": "^0.6.9", + "potpack": "^1.0.1" + }, + "peerDependencies": { + "three": ">=0.128.0" + } + }, + "node_modules/three-stdlib/node_modules/fflate": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz", + "integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==", + "license": "MIT" + }, "node_modules/tinyglobby": { "version": "0.2.17", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", @@ -6376,6 +6872,36 @@ "node": ">=8.0" } }, + "node_modules/troika-three-text": { + "version": "0.52.4", + "resolved": "https://registry.npmjs.org/troika-three-text/-/troika-three-text-0.52.4.tgz", + "integrity": "sha512-V50EwcYGruV5rUZ9F4aNsrytGdKcXKALjEtQXIOBfhVoZU9VAqZNIoGQ3TMiooVqFAbR1w15T+f+8gkzoFzawg==", + "license": "MIT", + "dependencies": { + "bidi-js": "^1.0.2", + "troika-three-utils": "^0.52.4", + "troika-worker-utils": "^0.52.0", + "webgl-sdf-generator": "1.1.1" + }, + "peerDependencies": { + "three": ">=0.125.0" + } + }, + "node_modules/troika-three-utils": { + "version": "0.52.4", + "resolved": "https://registry.npmjs.org/troika-three-utils/-/troika-three-utils-0.52.4.tgz", + "integrity": "sha512-NORAStSVa/BDiG52Mfudk4j1FG4jC4ILutB3foPnfGbOeIs9+G5vZLa0pnmnaftZUGm4UwSoqEpWdqvC7zms3A==", + "license": "MIT", + "peerDependencies": { + "three": ">=0.125.0" + } + }, + "node_modules/troika-worker-utils": { + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/troika-worker-utils/-/troika-worker-utils-0.52.0.tgz", + "integrity": "sha512-W1CpvTHykaPH5brv5VHLfQo9D1OYuo0cSBEUQFFT/nBUzM8iD6Lq2/tgG/f1OelbAS1WtaTPQzE5uM49egnngw==", + "license": "MIT" + }, "node_modules/ts-api-utils": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", @@ -6421,6 +6947,43 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/tunnel-rat": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/tunnel-rat/-/tunnel-rat-0.1.2.tgz", + "integrity": "sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ==", + "license": "MIT", + "dependencies": { + "zustand": "^4.3.2" + } + }, + "node_modules/tunnel-rat/node_modules/zustand": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz", + "integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==", + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.2.2" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -6655,11 +7218,39 @@ "punycode": "^2.1.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz", + "integrity": "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/utility-types": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", + "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/webgl-constants": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/webgl-constants/-/webgl-constants-1.1.1.tgz", + "integrity": "sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg==" + }, + "node_modules/webgl-sdf-generator": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/webgl-sdf-generator/-/webgl-sdf-generator-1.1.1.tgz", + "integrity": "sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA==", + "license": "MIT" + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -6812,6 +7403,35 @@ "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" } + }, + "node_modules/zustand": { + "version": "5.0.14", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.14.tgz", + "integrity": "sha512-/8tAspM5LMPr28b3fwLYrtdj77ECpfZviaP75CMTnwO8ISyaE4GDIG/9rDDYq/cH9D2Xw2A2RXglLInmVBQB/g==", + "license": "MIT", + "engines": { + "node": ">=12.20.0" + }, + "peerDependencies": { + "@types/react": ">=18.0.0", + "immer": ">=9.0.6", + "react": ">=18.0.0", + "use-sync-external-store": ">=1.2.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + }, + "use-sync-external-store": { + "optional": true + } + } } } } diff --git a/package.json b/package.json index 5683297..9e1c6dc 100644 --- a/package.json +++ b/package.json @@ -4,14 +4,18 @@ "private": true, "scripts": { "dev": "next dev", + "dev:goodnight": "cd ../Portfolio-goodnight && npm run dev -- -p 3001", "build": "next build", "start": "next start", "lint": "eslint" }, "dependencies": { + "@react-three/drei": "^10.7.7", + "@react-three/fiber": "^9.6.1", "next": "16.2.9", "react": "19.2.4", - "react-dom": "19.2.4" + "react-dom": "19.2.4", + "three": "^0.184.0" }, "devDependencies": { "@tailwindcss/postcss": "^4", diff --git a/public/fan-preview.html b/public/fan-preview.html new file mode 100644 index 0000000..679f93e --- /dev/null +++ b/public/fan-preview.html @@ -0,0 +1,382 @@ + + + + + +Galaxy Ceiling Fan — Preview (Hunter Discovery 52298) + + + + +
drag to orbit  •  scroll to zoom  •  space pause/spin
+ + + diff --git a/public/models/decor/diplodocus.glb b/public/models/decor/diplodocus.glb new file mode 100644 index 0000000..4750934 Binary files /dev/null and b/public/models/decor/diplodocus.glb differ diff --git a/public/models/decor/headphones.glb b/public/models/decor/headphones.glb new file mode 100644 index 0000000..ee822b1 Binary files /dev/null and b/public/models/decor/headphones.glb differ diff --git a/public/models/decor/soccer-ball.glb b/public/models/decor/soccer-ball.glb new file mode 100644 index 0000000..986c323 Binary files /dev/null and b/public/models/decor/soccer-ball.glb differ diff --git a/public/models/decor/trex.glb b/public/models/decor/trex.glb new file mode 100644 index 0000000..269fdf6 Binary files /dev/null and b/public/models/decor/trex.glb differ diff --git a/public/models/desk/scene.bin b/public/models/desk/scene.bin new file mode 100644 index 0000000..68bbda6 Binary files /dev/null and b/public/models/desk/scene.bin differ diff --git a/public/models/desk/scene.gltf b/public/models/desk/scene.gltf new file mode 100644 index 0000000..8c03022 --- /dev/null +++ b/public/models/desk/scene.gltf @@ -0,0 +1,375 @@ +{ + "accessors": [ + { + "bufferView": 2, + "componentType": 5126, + "count": 8186, + "max": [ + 0.6000000238418579, + 0.24868524074554443, + 0.7739999294281006 + ], + "min": [ + -0.6000000238418579, + -1.7513147592544556, + 0.0 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 98232, + "componentType": 5126, + "count": 8186, + "max": [ + 1.0, + 1.0, + 1.0 + ], + "min": [ + -1.0, + -1.0, + -1.0 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "componentType": 5126, + "count": 8186, + "max": [ + 0.9995238780975342, + 0.9780306220054626 + ], + "min": [ + 0.000476162473205477, + 0.000476170884212479 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "componentType": 5125, + "count": 21669, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 196464, + "componentType": 5126, + "count": 1014, + "max": [ + 0.6000000238418579, + 0.24868524074554443, + 0.8200001120567322 + ], + "min": [ + -0.6000000238418579, + -1.7513147592544556, + 0.7699998617172241 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 208632, + "componentType": 5126, + "count": 1014, + "max": [ + 1.0, + 1.0, + 1.0 + ], + "min": [ + -1.0, + -1.0, + -1.0 + ], + "type": "VEC3" + }, + { + "bufferView": 3, + "componentType": 5126, + "count": 1014, + "max": [ + 1.0, + 1.0, + 1.0, + 1.0 + ], + "min": [ + -1.0, + -1.0, + -1.0, + -1.0 + ], + "type": "VEC4" + }, + { + "bufferView": 1, + "byteOffset": 65488, + "componentType": 5126, + "count": 1014, + "max": [ + 0.8791875839233398, + 0.7600986361503601 + ], + "min": [ + 0.00047618531971238554, + 0.0004761569725815207 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 86676, + "componentType": 5125, + "count": 2811, + "type": "SCALAR" + } + ], + "asset": { + "extras": { + "author": "Superenforcer_xp (https://sketchfab.com/Superenforcer_xp)", + "license": "CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)", + "source": "https://sketchfab.com/3d-models/l-shaped-desk-table-with-wood-tabletop-087212b79e1142cfbd3babe862db7328", + "title": "L-shaped desk table with wood tabletop" + }, + "generator": "Sketchfab-15.53.0", + "version": "2.0" + }, + "bufferViews": [ + { + "buffer": 0, + "byteLength": 97920, + "name": "floatBufferViews", + "target": 34963 + }, + { + "buffer": 0, + "byteLength": 73600, + "byteOffset": 97920, + "byteStride": 8, + "name": "floatBufferViews", + "target": 34962 + }, + { + "buffer": 0, + "byteLength": 220800, + "byteOffset": 171520, + "byteStride": 12, + "name": "floatBufferViews", + "target": 34962 + }, + { + "buffer": 0, + "byteLength": 16224, + "byteOffset": 392320, + "byteStride": 16, + "name": "floatBufferViews", + "target": 34962 + } + ], + "buffers": [ + { + "byteLength": 408544, + "uri": "scene.bin" + } + ], + "images": [ + { + "uri": "textures/Rough_Dark-Blue_Texture_baseColor.jpeg" + }, + { + "uri": "textures/Rough_Dark-Blue_Texture_metallicRoughness.png" + }, + { + "uri": "textures/Rough_Dark-Blue_Texture_normal.png" + } + ], + "materials": [ + { + "doubleSided": true, + "name": "Rough_Light_Blue_Texture", + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.0, + 0.0, + 0.0, + 1.0 + ], + "metallicFactor": 0.0, + "roughnessFactor": 0.851812119808365 + } + }, + { + "doubleSided": true, + "name": "Rough_Dark-Blue_Texture", + "normalTexture": { + "index": 2 + }, + "pbrMetallicRoughness": { + "baseColorTexture": { + "index": 0 + }, + "metallicFactor": 0.0, + "metallicRoughnessTexture": { + "index": 1 + } + } + } + ], + "meshes": [ + { + "name": "L-Shaped Desk_Rough Light Blue Texture_0", + "primitives": [ + { + "attributes": { + "NORMAL": 1, + "POSITION": 0, + "TEXCOORD_0": 2 + }, + "indices": 3, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "L-Shaped Desk_Rough Dark-Blue Texture_0", + "primitives": [ + { + "attributes": { + "NORMAL": 5, + "POSITION": 4, + "TANGENT": 6, + "TEXCOORD_0": 7 + }, + "indices": 8, + "material": 1, + "mode": 4 + } + ] + } + ], + "nodes": [ + { + "children": [ + 1 + ], + "matrix": [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 2.220446049250313e-16, + -1.0, + 0.0, + 0.0, + 1.0, + 2.220446049250313e-16, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + "name": "Sketchfab_model" + }, + { + "children": [ + 2 + ], + "matrix": [ + 0.009999999776482582, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.009999999776482582, + 0.0, + 0.0, + -0.009999999776482582, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + "name": "9f68154daf694208b3ac1be7266ed604.fbx" + }, + { + "children": [ + 3 + ], + "name": "RootNode" + }, + { + "children": [ + 4, + 5 + ], + "matrix": [ + 100.0, + 0.0, + 0.0, + 0.0, + 0.0, + -1.629206793918314e-05, + -99.99999999999868, + 0.0, + 0.0, + 99.99999999999868, + -1.629206793918314e-05, + 0.0, + 30.000001907348633, + 0.0, + -75.13147735595703, + 1.0 + ], + "name": "L-Shaped Desk" + }, + { + "mesh": 0, + "name": "L-Shaped Desk_Rough Light Blue Texture_0" + }, + { + "mesh": 1, + "name": "L-Shaped Desk_Rough Dark-Blue Texture_0" + } + ], + "samplers": [ + { + "magFilter": 9729, + "minFilter": 9987, + "wrapS": 10497, + "wrapT": 10497 + } + ], + "scene": 0, + "scenes": [ + { + "name": "Sketchfab_Scene", + "nodes": [ + 0 + ] + } + ], + "textures": [ + { + "sampler": 0, + "source": 0 + }, + { + "sampler": 0, + "source": 1 + }, + { + "sampler": 0, + "source": 2 + } + ] +} diff --git a/public/models/desk/textures/Rough_Dark-Blue_Texture_baseColor.jpeg b/public/models/desk/textures/Rough_Dark-Blue_Texture_baseColor.jpeg new file mode 100644 index 0000000..d5f1303 Binary files /dev/null and b/public/models/desk/textures/Rough_Dark-Blue_Texture_baseColor.jpeg differ diff --git a/public/models/desk/textures/Rough_Dark-Blue_Texture_metallicRoughness.png b/public/models/desk/textures/Rough_Dark-Blue_Texture_metallicRoughness.png new file mode 100644 index 0000000..dbccee1 Binary files /dev/null and b/public/models/desk/textures/Rough_Dark-Blue_Texture_metallicRoughness.png differ diff --git a/public/models/desk/textures/Rough_Dark-Blue_Texture_normal.png b/public/models/desk/textures/Rough_Dark-Blue_Texture_normal.png new file mode 100644 index 0000000..74332ff Binary files /dev/null and b/public/models/desk/textures/Rough_Dark-Blue_Texture_normal.png differ diff --git a/public/models/gaming-chair/chair-opt.glb b/public/models/gaming-chair/chair-opt.glb new file mode 100644 index 0000000..dbacc04 Binary files /dev/null and b/public/models/gaming-chair/chair-opt.glb differ diff --git a/public/models/gaming-chair/scene.bin b/public/models/gaming-chair/scene.bin new file mode 100644 index 0000000..ed4af7c Binary files /dev/null and b/public/models/gaming-chair/scene.bin differ diff --git a/public/models/gaming-chair/scene.gltf b/public/models/gaming-chair/scene.gltf new file mode 100644 index 0000000..f60213f --- /dev/null +++ b/public/models/gaming-chair/scene.gltf @@ -0,0 +1,6851 @@ +{ + "accessors": [ + { + "bufferView": 2, + "componentType": 5126, + "count": 1928, + "max": [ + 12.589699745178223, + 5.958499908447266, + 11.219799995422363 + ], + "min": [ + -13.185500144958496, + 2.566190004348755, + -13.603599548339844 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 23136, + "componentType": 5126, + "count": 1928, + "max": [ + 0.9986859560012817, + 0.9998878836631775, + 0.9993431568145752 + ], + "min": [ + -0.9999209046363831, + -0.9999966025352478, + -0.999973714351654 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "componentType": 5126, + "count": 1928, + "max": [ + 13.94629955291748, + 14.12600040435791 + ], + "min": [ + -12.912599563598633, + -23.432899475097656 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "componentType": 5125, + "count": 4899, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 46272, + "componentType": 5126, + "count": 545, + "max": [ + 8.607720375061035, + 2.3179099559783936, + 10.218000411987305 + ], + "min": [ + 6.754310131072998, + -0.053801000118255615, + 7.842329978942871 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 52812, + "componentType": 5126, + "count": 545, + "max": [ + 0.9999122619628906, + 0.9999988675117493, + 0.9999136924743652 + ], + "min": [ + -0.9999116659164429, + -0.9999957084655762, + -0.9999964237213135 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 15424, + "componentType": 5126, + "count": 545, + "max": [ + 10.698699951171875, + -7.394889831542969 + ], + "min": [ + -9.698619842529297, + -26.05299949645996 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 19596, + "componentType": 5125, + "count": 924, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 59352, + "componentType": 5126, + "count": 40, + "max": [ + 8.674759864807129, + 2.248990058898926, + 10.142900466918945 + ], + "min": [ + 6.687280178070068, + 0.016442300751805305, + 7.910530090332031 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 59832, + "componentType": 5126, + "count": 40, + "max": [ + 0.9999110698699951, + 0.07545395195484161, + 0.05989193916320801 + ], + "min": [ + -0.9999111294746399, + -0.07046561688184738, + -0.08602523058652878 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 19784, + "componentType": 5126, + "count": 40, + "max": [ + 10.623499870300293, + -23.750099182128906 + ], + "min": [ + -9.623490333557129, + -25.98270034790039 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 23292, + "componentType": 5125, + "count": 96, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 60312, + "componentType": 5126, + "count": 528, + "max": [ + 8.468609809875488, + 2.6017398834228516, + 10.737500190734863 + ], + "min": [ + 6.905869960784912, + 0.8115220069885254, + 9.190150260925293 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 66648, + "componentType": 5126, + "count": 528, + "max": [ + 0.999911367893219, + 0.9999957084655762, + 0.9999116659164429 + ], + "min": [ + -0.9999123811721802, + -0.9999987483024597, + -0.9999127984046936 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 20104, + "componentType": 5126, + "count": 528, + "max": [ + 10.984600067138672, + -8.672410011291504 + ], + "min": [ + -9.9989595413208, + -25.187599182128906 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 23676, + "componentType": 5125, + "count": 1023, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 72984, + "componentType": 5126, + "count": 551, + "max": [ + -6.3929901123046875, + 2.3179099559783936, + 10.649200439453125 + ], + "min": [ + -8.246399879455566, + -0.053801100701093674, + 8.273520469665527 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 79596, + "componentType": 5126, + "count": 551, + "max": [ + 0.9999129772186279, + 0.9999988675117493, + 0.9999119639396667 + ], + "min": [ + -0.9999129772186279, + -0.9999957084655762, + -0.999996542930603 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 24328, + "componentType": 5126, + "count": 551, + "max": [ + 11.129799842834473, + -7.826010227203369 + ], + "min": [ + -10.129799842834473, + -26.05299949645996 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 27768, + "componentType": 5125, + "count": 924, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 86208, + "componentType": 5126, + "count": 37, + "max": [ + -6.3259501457214355, + 2.248990058898926, + 10.57409954071045 + ], + "min": [ + -8.313440322875977, + 0.016442300751805305, + 8.341710090637207 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 86652, + "componentType": 5126, + "count": 37, + "max": [ + 0.9999111294746399, + 0.0754551813006401, + 0.05989229679107666 + ], + "min": [ + -0.9999111294746399, + -0.0704750344157219, + -0.0860244408249855 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 28736, + "componentType": 5126, + "count": 37, + "max": [ + 11.054699897766113, + -23.750099182128906 + ], + "min": [ + -10.054699897766113, + -25.98270034790039 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 31464, + "componentType": 5125, + "count": 96, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 87096, + "componentType": 5126, + "count": 504, + "max": [ + -6.532100200653076, + 2.6017398834228516, + 11.168700218200684 + ], + "min": [ + -8.094840049743652, + 0.8115220069885254, + 9.621330261230469 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 93144, + "componentType": 5126, + "count": 504, + "max": [ + 0.999911904335022, + 0.9999958872795105, + 0.9999123215675354 + ], + "min": [ + -0.9999122619628906, + -0.9999987483024597, + -0.9999129772186279 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 29032, + "componentType": 5126, + "count": 504, + "max": [ + 11.41569995880127, + -9.10359001159668 + ], + "min": [ + -10.430100440979004, + -25.187599182128906 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 31848, + "componentType": 5125, + "count": 1020, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 99192, + "componentType": 5126, + "count": 560, + "max": [ + -11.467900276184082, + 2.3179099559783936, + -3.4248099327087402 + ], + "min": [ + -13.32129955291748, + -0.053798601031303406, + -5.800509929656982 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 105912, + "componentType": 5126, + "count": 560, + "max": [ + 0.9999129772186279, + 0.9999988675117493, + 0.9999130964279175 + ], + "min": [ + -0.9999129176139832, + -0.9999957084655762, + -0.9999951720237732 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 33064, + "componentType": 5126, + "count": 560, + "max": [ + 13.654199600219727, + 6.248040199279785 + ], + "min": [ + -12.614500045776367, + -26.05299949645996 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 35928, + "componentType": 5125, + "count": 924, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 112632, + "componentType": 5126, + "count": 37, + "max": [ + -11.400899887084961, + 2.249000072479248, + -3.4999499320983887 + ], + "min": [ + -13.388299942016602, + 0.016444699838757515, + -5.7323198318481445 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 113076, + "componentType": 5126, + "count": 37, + "max": [ + 0.9999112486839294, + 0.07539336383342743, + 0.05985753983259201 + ], + "min": [ + -0.9999112486839294, + -0.07043024897575378, + -0.08595345169305801 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 37544, + "componentType": 5126, + "count": 37, + "max": [ + 6.251719951629639, + -23.750099182128906 + ], + "min": [ + -5.251729965209961, + -25.98270034790039 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 39624, + "componentType": 5125, + "count": 96, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 113520, + "componentType": 5126, + "count": 499, + "max": [ + -11.607000350952148, + 2.6017398834228516, + -2.905319929122925 + ], + "min": [ + -13.169699668884277, + 0.811523973941803, + -4.452690124511719 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 119508, + "componentType": 5126, + "count": 499, + "max": [ + 0.9999113082885742, + 0.999995768070221, + 0.99991375207901 + ], + "min": [ + -0.9999128580093384, + -0.9999985098838806, + -0.99991375207901 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 37840, + "componentType": 5126, + "count": 499, + "max": [ + 13.500900268554688, + 4.970479965209961 + ], + "min": [ + -12.52079963684082, + -25.187599182128906 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 40008, + "componentType": 5125, + "count": 1026, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 125496, + "componentType": 5126, + "count": 512, + "max": [ + 0.32958701252937317, + 2.317919969558716, + -12.591400146484375 + ], + "min": [ + -1.5238300561904907, + -0.05379699915647507, + -14.967100143432617 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 131640, + "componentType": 5126, + "count": 512, + "max": [ + 0.9999117255210876, + 0.9999987483024597, + 0.9999119639396667 + ], + "min": [ + -0.9999122619628906, + -0.9999956488609314, + -0.999996542930603 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 41832, + "componentType": 5126, + "count": 512, + "max": [ + 15.481499671936035, + 15.414600372314453 + ], + "min": [ + -14.481499671936035, + -26.052900314331055 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 44112, + "componentType": 5125, + "count": 924, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 137784, + "componentType": 5126, + "count": 36, + "max": [ + 0.3966220021247864, + 2.249000072479248, + -12.666500091552734 + ], + "min": [ + -1.5908600091934204, + 0.016446299850940704, + -14.898900032043457 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 138216, + "componentType": 5126, + "count": 36, + "max": [ + 0.9999111294746399, + 0.0754554346203804, + 0.05988588556647301 + ], + "min": [ + -0.9999111294746399, + -0.07046734541654587, + -0.0860222801566124 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 45928, + "componentType": 5126, + "count": 36, + "max": [ + 15.418299674987793, + -23.750099182128906 + ], + "min": [ + -14.418299674987793, + -25.98270034790039 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 47808, + "componentType": 5125, + "count": 96, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 138648, + "componentType": 5126, + "count": 519, + "max": [ + 0.19047200679779053, + 2.601749897003174, + -12.071900367736816 + ], + "min": [ + -1.3722599744796753, + 0.8115260004997253, + -13.61929988861084 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 144876, + "componentType": 5126, + "count": 519, + "max": [ + 0.999911367893219, + 0.9999958872795105, + 0.99991375207901 + ], + "min": [ + -0.9999116659164429, + -0.9999986290931702, + -0.9999141693115234 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 46216, + "componentType": 5126, + "count": 519, + "max": [ + 13.903499603271484, + 14.137100219726563 + ], + "min": [ + -12.917799949645996, + -25.187599182128906 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 48192, + "componentType": 5125, + "count": 1020, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 151104, + "componentType": 5126, + "count": 556, + "max": [ + 12.801400184631348, + 2.3179099559783936, + -4.2435197830200195 + ], + "min": [ + 10.947999954223633, + -0.05379850044846535, + -6.619219779968262 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 157776, + "componentType": 5126, + "count": 556, + "max": [ + 0.9999129772186279, + 0.9999988675117493, + 0.9999131560325623 + ], + "min": [ + -0.9999104738235474, + -0.9999957084655762, + -0.9999964237213135 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 50368, + "componentType": 5126, + "count": 556, + "max": [ + 13.374500274658203, + 7.0666399002075195 + ], + "min": [ + -12.414199829101563, + -26.05299949645996 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 52272, + "componentType": 5125, + "count": 924, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 164448, + "componentType": 5126, + "count": 38, + "max": [ + 12.868399620056152, + 2.249000072479248, + -4.318659782409668 + ], + "min": [ + 10.880900382995605, + 0.016444899141788483, + -6.551030158996582 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 164904, + "componentType": 5126, + "count": 38, + "max": [ + 0.9999111294746399, + 0.07547995448112488, + 0.059945810586214066 + ], + "min": [ + -0.9999112486839294, + -0.07051774114370346, + -0.08604138344526291 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 54816, + "componentType": 5126, + "count": 38, + "max": [ + 7.070429801940918, + -23.750099182128906 + ], + "min": [ + -6.070429801940918, + -25.98270034790039 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 55968, + "componentType": 5125, + "count": 96, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 165360, + "componentType": 5126, + "count": 499, + "max": [ + 12.662300109863281, + 2.6017398834228516, + -3.724020004272461 + ], + "min": [ + 11.099499702453613, + 0.811523973941803, + -5.271399974822998 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 171348, + "componentType": 5126, + "count": 499, + "max": [ + 0.9999113082885742, + 0.9999956488609314, + 0.99991375207901 + ], + "min": [ + -0.9999114871025085, + -0.9999987483024597, + -0.9999133944511414 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 55120, + "componentType": 5126, + "count": 499, + "max": [ + 13.294599533081055, + 5.789140224456787 + ], + "min": [ + -12.272500038146973, + -25.187599182128906 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 56352, + "componentType": 5125, + "count": 1017, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 177336, + "componentType": 5126, + "count": 35, + "max": [ + 0.6411529779434204, + 14.105500221252441, + 0.5164690017700195 + ], + "min": [ + -0.8175910115242004, + 13.221799850463867, + -0.9422749876976013 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 177756, + "componentType": 5126, + "count": 35, + "max": [ + 1.0, + 0.0, + 1.0 + ], + "min": [ + -1.0, + 0.0, + -1.0 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 59112, + "componentType": 5126, + "count": 35, + "max": [ + 1.3639600276947021, + -11.893600463867188 + ], + "min": [ + -0.09699460119009018, + -12.777299880981445 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 60420, + "componentType": 5125, + "count": 72, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 178176, + "componentType": 5126, + "count": 1631, + "max": [ + 10.449907302856445, + 53.029876708984375, + 0.5647262930870056 + ], + "min": [ + -10.842674255371094, + 20.620914459228516, + -5.605391502380371 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 197748, + "componentType": 5126, + "count": 1631, + "max": [ + 0.9994155764579773, + 0.9888029098510742, + 0.9997713565826416 + ], + "min": [ + -0.9997677206993103, + -0.9985136389732361, + -0.9999961853027344 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 59392, + "componentType": 5126, + "count": 1631, + "max": [ + 11.221461296081543, + 27.02206802368164 + ], + "min": [ + -10.246200561523438, + -5.422380447387695 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 60708, + "componentType": 5125, + "count": 5592, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 217320, + "componentType": 5126, + "count": 361, + "max": [ + -9.81779956817627, + 26.817800521850586, + 11.105199813842773 + ], + "min": [ + -13.27239990234375, + 25.482799530029297, + 0.42243099212646484 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 221652, + "componentType": 5126, + "count": 361, + "max": [ + 0.9880953431129456, + 0.9999138712882996, + 0.9604894518852234 + ], + "min": [ + -0.9831284284591675, + -0.997830331325531, + -0.964025616645813 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 72440, + "componentType": 5126, + "count": 361, + "max": [ + 13.600500106811523, + 0.7645000219345093 + ], + "min": [ + -12.599499702453613, + -10.585800170898438 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 83076, + "componentType": 5125, + "count": 1218, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 225984, + "componentType": 5126, + "count": 338, + "max": [ + 13.108400344848633, + 26.677200317382813, + 11.286299705505371 + ], + "min": [ + 9.439229965209961, + 25.328899383544922, + 0.6974850296974182 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 230040, + "componentType": 5126, + "count": 338, + "max": [ + 0.9809219837188721, + 0.9997849464416504, + 0.9571409225463867 + ], + "min": [ + -0.9900985360145569, + -0.997505784034729, + -0.9766739010810852 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 75328, + "componentType": 5126, + "count": 338, + "max": [ + 13.712200164794922, + 0.6331120133399963 + ], + "min": [ + -12.71500015258789, + -10.766900062561035 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 87948, + "componentType": 5125, + "count": 1218, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 234096, + "componentType": 5126, + "count": 366, + "max": [ + 12.060600280761719, + 25.74720001220703, + 7.8253397941589355 + ], + "min": [ + 10.319499969482422, + 16.11319923400879, + 4.23006010055542 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 238488, + "componentType": 5126, + "count": 366, + "max": [ + 0.9992417693138123, + 0.4008449912071228, + 0.9902644753456116 + ], + "min": [ + -0.99992835521698, + -0.9587843418121338, + -0.9850390553474426 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 78032, + "componentType": 5126, + "count": 366, + "max": [ + 12.088500022888184, + -0.2519569993019104 + ], + "min": [ + -11.329000473022461, + -9.850959777832031 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 92820, + "componentType": 5125, + "count": 1044, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 242880, + "componentType": 5126, + "count": 131, + "max": [ + 12.642900466918945, + 24.903499603271484, + 6.9864301681518555 + ], + "min": [ + 11.736200332641602, + 24.44029998779297, + 5.275720119476318 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 244452, + "componentType": 5126, + "count": 131, + "max": [ + 0.9910816550254822, + 0.9973549842834473, + 0.994890034198761 + ], + "min": [ + -0.26483315229415894, + -0.9990840554237366, + -0.9948575496673584 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 80960, + "componentType": 5126, + "count": 131, + "max": [ + 13.265299797058105, + -1.1693300008773804 + ], + "min": [ + -12.262399673461914, + -6.4471001625061035 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 96996, + "componentType": 5125, + "count": 384, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 246024, + "componentType": 5126, + "count": 371, + "max": [ + -10.760299682617188, + 25.74720001220703, + 7.564819812774658 + ], + "min": [ + -12.322699546813965, + 16.252099990844727, + 4.036829948425293 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 250476, + "componentType": 5126, + "count": 371, + "max": [ + 0.9990538954734802, + 0.6312694549560547, + 0.9732287526130676 + ], + "min": [ + -0.9995086193084717, + -0.9599241018295288, + -0.9750258922576904 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 82008, + "componentType": 5126, + "count": 371, + "max": [ + 12.589200019836426, + -0.2519569993019104 + ], + "min": [ + -11.54520034790039, + -9.711030006408691 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 98532, + "componentType": 5125, + "count": 1044, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 254928, + "componentType": 5126, + "count": 116, + "max": [ + -12.051600456237793, + 25.032800674438477, + 6.648139953613281 + ], + "min": [ + -12.95829963684082, + 24.614500045776367, + 4.937419891357422 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 256320, + "componentType": 5126, + "count": 116, + "max": [ + 0.11833392083644867, + 0.9973792433738708, + 0.9947770237922668 + ], + "min": [ + -0.9974880218505859, + -0.9997971057891846, + -0.9948403835296631 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 84976, + "componentType": 5126, + "count": 116, + "max": [ + 13.297900199890137, + -1.0400899648666382 + ], + "min": [ + -12.300800323486328, + -6.108799934387207 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 102708, + "componentType": 5125, + "count": 384, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 257712, + "componentType": 5126, + "count": 689, + "max": [ + -8.789139747619629, + 21.98780059814453, + 0.8898890018463135 + ], + "min": [ + -11.04740047454834, + 16.687299728393555, + -6.509379863739014 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 265980, + "componentType": 5126, + "count": 689, + "max": [ + 0.9990226626396179, + 0.9999657273292542, + 0.994152843952179 + ], + "min": [ + -0.9997605681419373, + -0.9999668598175049, + -0.9972424507141113 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 85904, + "componentType": 5126, + "count": 689, + "max": [ + 11.139800071716309, + 6.941939830780029 + ], + "min": [ + -10.148599624633789, + -9.311779975891113 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 104244, + "componentType": 5125, + "count": 1914, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 274248, + "componentType": 5126, + "count": 192, + "max": [ + -9.542810440063477, + 20.156999588012695, + 0.1374180018901825 + ], + "min": [ + -10.646499633789063, + 19.171199798583984, + -4.219110012054443 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 276552, + "componentType": 5126, + "count": 192, + "max": [ + 0.9999997615814209, + 0.9991019368171692, + 0.9969956874847412 + ], + "min": [ + -0.9999997615814209, + -0.9991011619567871, + -0.9981634020805359 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 91416, + "componentType": 5126, + "count": 192, + "max": [ + 11.005999565124512, + 4.739590167999268 + ], + "min": [ + -10.006699562072754, + -6.827899932861328 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 111900, + "componentType": 5125, + "count": 363, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 278856, + "componentType": 5126, + "count": 262, + "max": [ + -10.269000053405762, + 20.475299835205078, + 2.8467800617218018 + ], + "min": [ + -10.70479965209961, + 19.21940040588379, + -0.07698550075292587 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 282000, + "componentType": 5126, + "count": 262, + "max": [ + 0.9971221089363098, + 0.8626528978347778, + 0.7816409468650818 + ], + "min": [ + -0.9974849820137024, + -0.8596093654632568, + -0.9010324478149414 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 92952, + "componentType": 5126, + "count": 262, + "max": [ + 11.038999557495117, + 0.5732020139694214 + ], + "min": [ + -9.891349792480469, + -6.756100177764893 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 113352, + "componentType": 5125, + "count": 684, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 285144, + "componentType": 5126, + "count": 1034, + "max": [ + 3.5263400077819824, + 16.75040054321289, + 6.539700031280518 + ], + "min": [ + -3.660830020904541, + 14.771300315856934, + -4.755259990692139 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 297552, + "componentType": 5126, + "count": 1034, + "max": [ + 0.999981164932251, + 0.9999445676803589, + 0.9968291521072388 + ], + "min": [ + -0.9996820688247681, + -0.9998546242713928, + -0.9999983310699463 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 95048, + "componentType": 5126, + "count": 1034, + "max": [ + 7.020289897918701, + 5.266170024871826 + ], + "min": [ + -5.806950092315674, + -11.227899551391602 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 116088, + "componentType": 5125, + "count": 2328, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 309960, + "componentType": 5126, + "count": 518, + "max": [ + -8.621199607849121, + 28.224899291992188, + -3.5379199981689453 + ], + "min": [ + -10.931500434875488, + 19.31529998779297, + -5.927450180053711 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 316176, + "componentType": 5126, + "count": 518, + "max": [ + 0.9999975562095642, + 0.988051176071167, + 0.9948973059654236 + ], + "min": [ + -0.9974724054336548, + -0.951111912727356, + -0.9950172901153564 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 103320, + "componentType": 5126, + "count": 518, + "max": [ + 11.291500091552734, + 6.188650131225586 + ], + "min": [ + -10.289799690246582, + -6.683780193328857 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 125400, + "componentType": 5125, + "count": 1164, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 322392, + "componentType": 5126, + "count": 208, + "max": [ + -8.818670272827148, + 21.790199279785156, + -2.8514199256896973 + ], + "min": [ + -9.596989631652832, + 18.315399169921875, + -6.326240062713623 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 324888, + "componentType": 5126, + "count": 208, + "max": [ + 1.0, + 0.9998997449874878, + 0.9998984336853027 + ], + "min": [ + -1.0, + -0.9998981952667236, + -0.9998987317085266 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 107464, + "componentType": 5126, + "count": 208, + "max": [ + 9.864700317382813, + 6.612880229949951 + ], + "min": [ + -8.864970207214355, + -7.677209854125977 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 130056, + "componentType": 5125, + "count": 354, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 327384, + "componentType": 5126, + "count": 574, + "max": [ + 9.648059844970703, + 21.486099243164063, + 1.1300400495529175 + ], + "min": [ + 8.569250106811523, + 16.756500244140625, + -6.122379779815674 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 334272, + "componentType": 5126, + "count": 574, + "max": [ + 0.9999189972877502, + 0.9426845908164978, + 0.9605727195739746 + ], + "min": [ + -0.9997721314430237, + -0.9666031002998352, + -0.9421501755714417 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 109128, + "componentType": 5126, + "count": 574, + "max": [ + 10.11989974975586, + 6.64178991317749 + ], + "min": [ + -9.078339576721191, + -9.242639541625977 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 131472, + "componentType": 5125, + "count": 1722, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 341160, + "componentType": 5126, + "count": 40, + "max": [ + 9.836179733276367, + 20.871299743652344, + -3.781860113143921 + ], + "min": [ + 9.467060089111328, + 19.881000518798828, + -4.723659992218018 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 341640, + "componentType": 5126, + "count": 40, + "max": [ + 1.6106506350865857e-08, + 0.9510193467140198, + 1.0 + ], + "min": [ + -4.0213853935711086e-07, + -0.9510219097137451, + -1.0 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 113720, + "componentType": 5126, + "count": 40, + "max": [ + 10.476099967956543, + 5.063199996948242 + ], + "min": [ + -9.476140022277832, + -6.023540019989014 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 138360, + "componentType": 5125, + "count": 60, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 342120, + "componentType": 5126, + "count": 247, + "max": [ + 9.216620445251465, + 21.527000427246094, + -2.380079984664917 + ], + "min": [ + 8.53831958770752, + 18.052200317382813, + -5.854899883270264 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 345084, + "componentType": 5126, + "count": 247, + "max": [ + 0.9524980187416077, + 0.99983149766922, + 0.9998356699943542 + ], + "min": [ + -1.0, + -0.9998372793197632, + -0.9998353123664856 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 114040, + "componentType": 5126, + "count": 247, + "max": [ + 9.798990249633789, + 6.1416401863098145 + ], + "min": [ + -8.798789978027344, + -7.940400123596191 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 138600, + "componentType": 5125, + "count": 426, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 348048, + "componentType": 5126, + "count": 293, + "max": [ + 9.883130073547363, + 28.43440055847168, + -3.3013100624084473 + ], + "min": [ + 8.504960060119629, + 19.559900283813477, + -5.831709861755371 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 351564, + "componentType": 5126, + "count": 293, + "max": [ + 0.9998965859413147, + 0.9985755085945129, + 0.999588131904602 + ], + "min": [ + -0.999975860118866, + -0.9980322122573853, + -0.9985442161560059 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 116016, + "componentType": 5126, + "count": 293, + "max": [ + 10.4822998046875, + 6.069530010223389 + ], + "min": [ + -9.483139991760254, + -6.443689823150635 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 140304, + "componentType": 5125, + "count": 828, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 355080, + "componentType": 5126, + "count": 8319, + "max": [ + 10.315244674682617, + 52.842193603515625, + 0.34574443101882935 + ], + "min": [ + -10.617766380310059, + 19.951356887817383, + -7.352994441986084 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 454908, + "componentType": 5126, + "count": 8319, + "max": [ + 0.999809205532074, + 0.9999480843544006, + 0.9999481439590454 + ], + "min": [ + -0.9992168545722961, + -0.9990300536155701, + -0.9999868869781494 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 118360, + "componentType": 5126, + "count": 8319, + "max": [ + 11.008601188659668, + 26.742794036865234 + ], + "min": [ + -9.896491050720215, + -6.054090976715088 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 143616, + "componentType": 5125, + "count": 30780, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 554736, + "componentType": 5126, + "count": 133, + "max": [ + 0.2022988349199295, + 37.72208023071289, + -3.3811450004577637 + ], + "min": [ + -0.5760210752487183, + 22.035903930664063, + -4.342788219451904 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 556332, + "componentType": 5126, + "count": 133, + "max": [ + 0.20273254811763763, + 0.23334021866321564, + 0.9997644424438477 + ], + "min": [ + -0.19796252250671387, + -0.2243260145187378, + 0.9713020920753479 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 184912, + "componentType": 5126, + "count": 133, + "max": [ + 4.117400646209717, + 12.000349044799805 + ], + "min": [ + -0.07060801982879639, + -4.164830207824707 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 266736, + "componentType": 5125, + "count": 456, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 557928, + "componentType": 5126, + "count": 36, + "max": [ + -0.06361159682273865, + 20.92569923400879, + 5.736179828643799 + ], + "min": [ + -0.5267019867897034, + 19.286500930786133, + -5.280479907989502 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 558360, + "componentType": 5126, + "count": 36, + "max": [ + 0.9999983310699463, + 0.9960940480232239, + 0.32518482208251953 + ], + "min": [ + -0.9999983310699463, + -3.6816345527768135e-08, + -0.32069578766822815 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 185976, + "componentType": 5126, + "count": 36, + "max": [ + 6.216780185699463, + 5.799890041351318 + ], + "min": [ + -5.216780185699463, + -6.71258020401001 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 268560, + "componentType": 5125, + "count": 96, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 558792, + "componentType": 5126, + "count": 3345, + "max": [ + 6.652601718902588, + 21.355899810791016, + 14.934748649597168 + ], + "min": [ + -7.724195957183838, + 16.415016174316406, + -6.061598777770996 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 598932, + "componentType": 5126, + "count": 3345, + "max": [ + 0.9998093247413635, + 0.99989914894104, + 0.9998950958251953 + ], + "min": [ + -0.9993561506271362, + -0.999970555305481, + -0.999787449836731 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 186264, + "componentType": 5126, + "count": 3345, + "max": [ + 15.058852195739746, + 6.450589656829834 + ], + "min": [ + -14.245553016662598, + -14.180802345275879 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 268944, + "componentType": 5125, + "count": 12144, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 639072, + "componentType": 5126, + "count": 1988, + "max": [ + 9.74225902557373, + 22.839797973632813, + 13.767963409423828 + ], + "min": [ + 4.801881790161133, + 16.253686904907227, + -6.0013532638549805 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 662928, + "componentType": 5126, + "count": 1988, + "max": [ + 0.9997119903564453, + 0.9936944842338562, + 0.9987823367118835 + ], + "min": [ + -0.9996871948242188, + -0.9999807476997375, + -0.9994590282440186 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 213024, + "componentType": 5126, + "count": 1988, + "max": [ + 14.087043762207031, + 6.448240756988525 + ], + "min": [ + -13.003767013549805, + -13.266502380371094 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 317520, + "componentType": 5125, + "count": 7272, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 686784, + "componentType": 5126, + "count": 503, + "max": [ + 9.552485466003418, + 22.93972396850586, + 13.864836692810059 + ], + "min": [ + 5.979055404663086, + 17.09111976623535, + -5.522336483001709 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 692820, + "componentType": 5126, + "count": 503, + "max": [ + 0.9985272884368896, + 0.993838369846344, + 0.9997978210449219 + ], + "min": [ + -0.972983717918396, + -0.9667470455169678, + -0.5007026791572571 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 228928, + "componentType": 5126, + "count": 503, + "max": [ + 14.315019607543945, + 6.045540809631348 + ], + "min": [ + -13.319467544555664, + -13.20920181274414 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 346608, + "componentType": 5125, + "count": 1764, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 698856, + "componentType": 5126, + "count": 1954, + "max": [ + -5.867087364196777, + 23.12464714050293, + 13.415387153625488 + ], + "min": [ + -10.490564346313477, + 16.343294143676758, + -6.194118499755859 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 722304, + "componentType": 5126, + "count": 1954, + "max": [ + 0.999640166759491, + 0.993601381778717, + 0.9989723563194275 + ], + "min": [ + -0.998388409614563, + -0.9994800090789795, + -0.9992150068283081 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 232952, + "componentType": 5126, + "count": 1954, + "max": [ + 13.688426971435547, + 6.375071048736572 + ], + "min": [ + -12.875102043151855, + -12.760417938232422 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 353664, + "componentType": 5125, + "count": 7296, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 745752, + "componentType": 5126, + "count": 431, + "max": [ + -7.151558876037598, + 23.339534759521484, + 13.46725082397461 + ], + "min": [ + -10.200096130371094, + 17.940006256103516, + -5.522336006164551 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 750924, + "componentType": 5126, + "count": 431, + "max": [ + 0.9882985353469849, + 0.9636896252632141, + 0.9687198400497437 + ], + "min": [ + -0.999670684337616, + -0.443317174911499, + -0.5186399817466736 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 248584, + "componentType": 5126, + "count": 431, + "max": [ + 13.927202224731445, + 6.04555082321167 + ], + "min": [ + -12.914301872253418, + -12.239602088928223 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 382848, + "componentType": 5125, + "count": 1536, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 756096, + "componentType": 5126, + "count": 65, + "max": [ + -4.090099811553955, + 16.82699966430664, + 6.815800189971924 + ], + "min": [ + -11.285300254821777, + 16.464500427246094, + 4.758880138397217 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 756876, + "componentType": 5126, + "count": 65, + "max": [ + 1.0, + 0.9999995827674866, + 1.0 + ], + "min": [ + -1.0, + -0.9999995827674866, + -1.0 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 252032, + "componentType": 5126, + "count": 65, + "max": [ + 11.595499992370605, + -4.2394700050354 + ], + "min": [ + -10.595499992370605, + -9.53462028503418 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 388992, + "componentType": 5125, + "count": 132, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 757656, + "componentType": 5126, + "count": 20, + "max": [ + 5.356790065765381, + 17.64299964904785, + 6.756499767303467 + ], + "min": [ + -6.362730026245117, + 16.806900024414063, + 4.654119968414307 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 757896, + "componentType": 5126, + "count": 20, + "max": [ + 0.0038789790123701096, + 0.0, + 0.9999924898147583 + ], + "min": [ + -0.00387983163818717, + -1.0, + -0.9999924898147583 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 252552, + "componentType": 5126, + "count": 20, + "max": [ + 6.7227702140808105, + -4.207409858703613 + ], + "min": [ + -5.7227702140808105, + -9.192239761352539 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 389520, + "componentType": 5125, + "count": 30, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 758136, + "componentType": 5126, + "count": 79, + "max": [ + 10.886199951171875, + 16.90329933166504, + 6.999060153961182 + ], + "min": [ + 3.501970052719116, + 16.40489959716797, + 4.760129928588867 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 759084, + "componentType": 5126, + "count": 79, + "max": [ + 1.0, + 0.9998087882995605, + 0.9996880292892456 + ], + "min": [ + -1.0, + -0.9998087882995605, + -0.9996880292892456 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 252712, + "componentType": 5126, + "count": 79, + "max": [ + 11.526200294494629, + -4.290550231933594 + ], + "min": [ + -10.476300239562988, + -9.594260215759277 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 389640, + "componentType": 5125, + "count": 132, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 760032, + "componentType": 5126, + "count": 992, + "max": [ + 6.230484962463379, + 28.78183364868164, + -0.10468804091215134 + ], + "min": [ + -5.759917259216309, + 22.31881332397461, + -3.473435878753662 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 771936, + "componentType": 5126, + "count": 992, + "max": [ + 0.9999403953552246, + 0.9972941279411316, + 0.9992316961288452 + ], + "min": [ + -0.9999404549598694, + -0.999939501285553, + -0.9999949932098389 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 253344, + "componentType": 5126, + "count": 992, + "max": [ + 6.643348693847656, + 3.929727554321289 + ], + "min": [ + -5.746428966522217, + -3.784820556640625 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 390168, + "componentType": 5125, + "count": 3576, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 783840, + "componentType": 5126, + "count": 316, + "max": [ + 6.230484962463379, + 28.467098236083984, + -0.3780006468296051 + ], + "min": [ + -5.759917259216309, + 22.31881332397461, + -2.629619836807251 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 787632, + "componentType": 5126, + "count": 316, + "max": [ + 0.9999403953552246, + 0.9480748772621155, + 0.9846060872077942 + ], + "min": [ + -0.9999404549598694, + -0.999939501285553, + -0.1722462773323059 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 261280, + "componentType": 5126, + "count": 316, + "max": [ + 6.635782241821289, + 3.302506446838379 + ], + "min": [ + -5.773978233337402, + -3.5214998722076416 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 404472, + "componentType": 5125, + "count": 1020, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 791424, + "componentType": 5126, + "count": 1217, + "max": [ + 5.233128547668457, + 49.520694732666016, + -1.7127660512924194 + ], + "min": [ + -5.74376916885376, + 43.34789276123047, + -5.132321357727051 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 806028, + "componentType": 5126, + "count": 1217, + "max": [ + 0.9582133293151855, + 0.9999101161956787, + 0.9990267753601074 + ], + "min": [ + -0.9582136869430542, + -0.9990953207015991, + -0.99931800365448 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 263808, + "componentType": 5126, + "count": 1217, + "max": [ + 6.25800895690918, + 23.698701858520508 + ], + "min": [ + -5.027287006378174, + 2.800680160522461 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 408552, + "componentType": 5125, + "count": 4194, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 820632, + "componentType": 5126, + "count": 536, + "max": [ + 5.285297393798828, + 49.520694732666016, + -2.049945831298828 + ], + "min": [ + -5.795937538146973, + 43.289669036865234, + -4.119852066040039 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 827064, + "componentType": 5126, + "count": 536, + "max": [ + 0.9840914011001587, + 0.99959796667099, + 0.9805044531822205 + ], + "min": [ + -0.984091579914093, + -0.9867823123931885, + -0.6895459890365601 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 273544, + "componentType": 5126, + "count": 536, + "max": [ + 6.077651023864746, + 23.6494197845459 + ], + "min": [ + -5.235660552978516, + 3.491528034210205 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 425328, + "componentType": 5125, + "count": 1848, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 833496, + "componentType": 5126, + "count": 688, + "max": [ + 6.1384100914001465, + 47.70159912109375, + -2.669100046157837 + ], + "min": [ + -6.414490222930908, + 19.805400848388672, + -7.522930145263672 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 841752, + "componentType": 5126, + "count": 688, + "max": [ + 0.9999973773956299, + 0.9992320537567139, + 0.9999760985374451 + ], + "min": [ + -0.9999974966049194, + -0.9994259476661682, + -0.9999762177467346 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 277832, + "componentType": 5126, + "count": 688, + "max": [ + 8.042340278625488, + 21.702499389648438 + ], + "min": [ + -7.04233980178833, + -6.193699836730957 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 432720, + "componentType": 5125, + "count": 1344, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 850008, + "componentType": 5126, + "count": 217, + "max": [ + 1.6017099618911743, + 16.063899993896484, + 3.7414300441741943 + ], + "min": [ + -1.626539945602417, + 13.921600341796875, + -1.7209099531173706 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 852612, + "componentType": 5126, + "count": 217, + "max": [ + 0.9997235536575317, + 0.9998959302902222, + 1.0 + ], + "min": [ + -1.0, + -0.9995847344398499, + -1.0 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 283336, + "componentType": 5126, + "count": 217, + "max": [ + 4.222020149230957, + 2.2403600215911865 + ], + "min": [ + -3.2221899032592773, + -12.044099807739258 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 438096, + "componentType": 5125, + "count": 702, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 855216, + "componentType": 5126, + "count": 201, + "max": [ + 1.1406300067901611, + 15.784899711608887, + 4.662909984588623 + ], + "min": [ + -1.0512299537658691, + 13.467399597167969, + 2.218909978866577 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 857628, + "componentType": 5126, + "count": 201, + "max": [ + 1.0, + 0.9815998673439026, + 0.9822879433631897 + ], + "min": [ + -1.0, + -0.9053981304168701, + -0.9815872311592102 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 285072, + "componentType": 5126, + "count": 201, + "max": [ + 5.000150203704834, + -1.7267600297927856 + ], + "min": [ + -4.000150203704834, + -12.445300102233887 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 440904, + "componentType": 5125, + "count": 360, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 860040, + "componentType": 5126, + "count": 358, + "max": [ + 1.2182899713516235, + 14.11870002746582, + 4.957180023193359 + ], + "min": [ + -1.0721100568771362, + 12.09749984741211, + 2.419019937515259 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 864336, + "componentType": 5126, + "count": 358, + "max": [ + 0.9886894822120667, + 0.9857144355773926, + 0.9949209094047546 + ], + "min": [ + -0.9956101775169373, + -0.99937504529953, + -0.9720757007598877 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 286680, + "componentType": 5126, + "count": 358, + "max": [ + 5.144979953765869, + -1.9297000169754028 + ], + "min": [ + -4.081719875335693, + -13.85569953918457 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 442344, + "componentType": 5125, + "count": 642, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 868632, + "componentType": 5126, + "count": 309, + "max": [ + -9.080060005187988, + 14.923700332641602, + -0.4677880108356476 + ], + "min": [ + -10.890800476074219, + 12.881799697875977, + -2.223989963531494 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 872340, + "componentType": 5126, + "count": 309, + "max": [ + 0.9921610355377197, + 0.9861531257629395, + 0.9847831726074219 + ], + "min": [ + -0.9722223877906799, + -0.9873268008232117, + -0.9954319596290588 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 289544, + "componentType": 5126, + "count": 309, + "max": [ + 11.226900100708008, + 2.715369939804077 + ], + "min": [ + -10.196599960327148, + -13.060600280761719 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 444912, + "componentType": 5125, + "count": 918, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 876048, + "componentType": 5126, + "count": 135, + "max": [ + -0.9686449766159058, + 15.589599609375, + -0.08142930269241333 + ], + "min": [ + -9.642569541931152, + 14.596599578857422, + -0.8879209756851196 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 877668, + "componentType": 5126, + "count": 135, + "max": [ + 0.8734265565872192, + 0.9717018604278564, + 0.9711471796035767 + ], + "min": [ + -0.8740649819374084, + -0.9715662002563477, + -0.9711549282073975 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 292016, + "componentType": 5126, + "count": 135, + "max": [ + 9.963800430297852, + 1.1751600503921509 + ], + "min": [ + -8.96776008605957, + -11.40250015258789 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 448584, + "componentType": 5125, + "count": 288, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 879288, + "componentType": 5126, + "count": 81, + "max": [ + 0.0518437996506691, + 37.12300109863281, + -2.878269910812378 + ], + "min": [ + -0.3799870014190674, + 20.26219940185547, + -4.9462199211120605 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 880260, + "componentType": 5126, + "count": 81, + "max": [ + 1.0, + 0.884248673915863, + 0.9186102747917175 + ], + "min": [ + -1.0, + -0.6725447773933411, + -0.006221320480108261 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 293096, + "componentType": 5126, + "count": 81, + "max": [ + 5.465630054473877, + 11.123900413513184 + ], + "min": [ + -4.465630054473877, + -5.721930027008057 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 449736, + "componentType": 5125, + "count": 156, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 881232, + "componentType": 5126, + "count": 249, + "max": [ + 1.7545499801635742, + 3.4516398906707764, + 1.7951500415802002 + ], + "min": [ + -2.133049964904785, + 2.7680599689483643, + -1.871150016784668 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 884220, + "componentType": 5126, + "count": 249, + "max": [ + 0.9530544281005859, + 0.30218008160591125, + 0.9124714136123657 + ], + "min": [ + -0.9530490040779114, + -1.0, + -0.9124711155891418 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 293744, + "componentType": 5126, + "count": 249, + "max": [ + 2.4930899143218994, + 2.3905599117279053 + ], + "min": [ + -1.39451003074646, + -23.23110008239746 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 450360, + "componentType": 5125, + "count": 510, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 887208, + "componentType": 5126, + "count": 151, + "max": [ + 0.04794130101799965, + 3.350330114364624, + -12.037400245666504 + ], + "min": [ + -1.204319953918457, + 2.5984599590301514, + -13.288900375366211 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 889020, + "componentType": 5126, + "count": 151, + "max": [ + 0.9999108910560608, + 0.0029033038299530745, + 0.9999136328697205 + ], + "min": [ + -0.9999111294746399, + -0.9999957084655762, + -0.9999122023582458 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 295736, + "componentType": 5126, + "count": 151, + "max": [ + 13.619400024414063, + 13.80739974975586 + ], + "min": [ + -12.630999565124512, + -23.378299713134766 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 452400, + "componentType": 5125, + "count": 288, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 890832, + "componentType": 5126, + "count": 148, + "max": [ + 12.638699531555176, + 3.350330114364624, + -3.918060064315796 + ], + "min": [ + 11.391799926757813, + 2.5984599590301514, + -5.164740085601807 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 892608, + "componentType": 5126, + "count": 148, + "max": [ + 0.9958008527755737, + 0.0029532192274928093, + 0.995804488658905 + ], + "min": [ + -0.995800793170929, + -0.9999957084655762, + -0.9958012104034424 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 296944, + "componentType": 5126, + "count": 148, + "max": [ + 13.055800437927246, + 5.6841301918029785 + ], + "min": [ + -12.277199745178223, + -23.378299713134766 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 453552, + "componentType": 5125, + "count": 288, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 894384, + "componentType": 5126, + "count": 152, + "max": [ + 8.36124038696289, + 3.350330114364624, + 10.654199600219727 + ], + "min": [ + 7.129740238189697, + 2.5984599590301514, + 9.421549797058105 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 896208, + "componentType": 5126, + "count": 152, + "max": [ + 0.9841083288192749, + 0.0029112224001437426, + 0.9841145277023315 + ], + "min": [ + -0.9841117262840271, + -0.9999956488609314, + -0.9841061234474182 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 298128, + "componentType": 5126, + "count": 152, + "max": [ + 10.876099586486816, + -8.902299880981445 + ], + "min": [ + -10.033100128173828, + -23.39859962463379 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 454704, + "componentType": 5125, + "count": 288, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 898032, + "componentType": 5126, + "count": 161, + "max": [ + -6.752649784088135, + 3.350330114364624, + 11.071399688720703 + ], + "min": [ + -7.995110034942627, + 2.5984599590301514, + 9.830880165100098 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 899964, + "componentType": 5126, + "count": 161, + "max": [ + 0.9918326735496521, + 0.0029041406232863665, + 0.9918432235717773 + ], + "min": [ + -0.9918283820152283, + -0.9999957084655762, + -0.9918335676193237 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 299344, + "componentType": 5126, + "count": 161, + "max": [ + 11.426600456237793, + -9.311389923095703 + ], + "min": [ + -10.314000129699707, + -23.397199630737305 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 455856, + "componentType": 5125, + "count": 288, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 901896, + "componentType": 5126, + "count": 152, + "max": [ + -11.793399810791016, + 3.350330114364624, + -3.0787899494171143 + ], + "min": [ + -13.039400100708008, + 2.5984599590301514, + -4.326260089874268 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 903720, + "componentType": 5126, + "count": 152, + "max": [ + 0.9958980083465576, + 0.002902404638007283, + 0.9958956241607666 + ], + "min": [ + -0.9958981275558472, + -0.9999957084655762, + -0.9958962202072144 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 300632, + "componentType": 5126, + "count": 152, + "max": [ + 13.399200439453125, + 4.8435797691345215 + ], + "min": [ + -12.177000045776367, + -23.39739990234375 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 457008, + "componentType": 5125, + "count": 288, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 905544, + "componentType": 5126, + "count": 232, + "max": [ + 1.3858799934387207, + 13.587499618530273, + 1.2596100568771362 + ], + "min": [ + -1.5443799495697021, + 5.477459907531738, + -1.5272300243377686 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 908328, + "componentType": 5126, + "count": 232, + "max": [ + 0.9999989867210388, + 0.995481550693512, + 0.9510557055473328 + ], + "min": [ + -0.9999989867210388, + -0.0014831169974058867, + -0.9510555267333984 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 301848, + "componentType": 5126, + "count": 232, + "max": [ + 2.0258400440216064, + 2.0466299057006836 + ], + "min": [ + -0.9044420123100281, + -20.521699905395508 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 458160, + "componentType": 5125, + "count": 420, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 911112, + "componentType": 5126, + "count": 153, + "max": [ + -11.812100410461426, + 3.350330114364624, + -3.0370800495147705 + ], + "min": [ + -13.064299583435059, + 2.5984599590301514, + -4.28863000869751 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 912948, + "componentType": 5126, + "count": 153, + "max": [ + 0.9999103546142578, + 0.002939017955213785, + 0.9999128580093384 + ], + "min": [ + -0.9999116063117981, + -0.9999956488609314, + -0.9999130964279175 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 303704, + "componentType": 5126, + "count": 153, + "max": [ + 13.424500465393066, + 4.806940078735352 + ], + "min": [ + -12.246999740600586, + -23.378299713134766 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 459840, + "componentType": 5125, + "count": 288, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 914784, + "componentType": 5126, + "count": 154, + "max": [ + -6.677430152893066, + 3.350330114364624, + 11.069000244140625 + ], + "min": [ + -7.929689884185791, + 2.5984599590301514, + 9.817480087280273 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 916632, + "componentType": 5126, + "count": 154, + "max": [ + 0.9999108910560608, + 0.002903757616877556, + 0.9999122619628906 + ], + "min": [ + -0.999910831451416, + -0.9999957084655762, + -0.9999131560325623 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 304928, + "componentType": 5126, + "count": 154, + "max": [ + 11.360799789428711, + -9.299079895019531 + ], + "min": [ + -10.372300148010254, + -23.378299713134766 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 460992, + "componentType": 5125, + "count": 288, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 918480, + "componentType": 5126, + "count": 162, + "max": [ + 8.315560340881348, + 3.350330114364624, + 10.589599609375 + ], + "min": [ + 7.063300132751465, + 2.5984599590301514, + 9.33804988861084 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 920424, + "componentType": 5126, + "count": 162, + "max": [ + 0.9999111294746399, + 0.0029274444095790386, + 0.9999149441719055 + ], + "min": [ + -0.9999111294746399, + -0.9999957084655762, + -0.9999129772186279 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 306160, + "componentType": 5126, + "count": 162, + "max": [ + 10.88129997253418, + -8.819930076599121 + ], + "min": [ + -9.892809867858887, + -23.378299713134766 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 462144, + "componentType": 5125, + "count": 288, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 922368, + "componentType": 5126, + "count": 155, + "max": [ + 12.618900299072266, + 3.350330114364624, + -3.8990299701690674 + ], + "min": [ + 11.366600036621094, + 2.5984599590301514, + -5.150579929351807 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 924228, + "componentType": 5126, + "count": 155, + "max": [ + 0.9999115467071533, + 0.002874793019145727, + 0.9999138116836548 + ], + "min": [ + -0.9999116659164429, + -0.9999957084655762, + -0.999913215637207 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 307456, + "componentType": 5126, + "count": 155, + "max": [ + 13.069899559020996, + 5.6689300537109375 + ], + "min": [ + -12.256999969482422, + -23.378299713134766 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 463296, + "componentType": 5125, + "count": 288, + "type": "SCALAR" + } + ], + "asset": { + "extras": { + "author": "9arts (https://sketchfab.com/9arts)", + "license": "CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)", + "source": "https://sketchfab.com/3d-models/gaming-chair-6ca81f60846648609b4208c9e7f31b14", + "title": "Gaming Chair" + }, + "generator": "Sketchfab-12.66.0", + "version": "2.0" + }, + "bufferViews": [ + { + "buffer": 0, + "byteLength": 464448, + "name": "floatBufferViews", + "target": 34963 + }, + { + "buffer": 0, + "byteLength": 308696, + "byteOffset": 464448, + "byteStride": 8, + "name": "floatBufferViews", + "target": 34962 + }, + { + "buffer": 0, + "byteLength": 926088, + "byteOffset": 773144, + "byteStride": 12, + "name": "floatBufferViews", + "target": 34962 + } + ], + "buffers": [ + { + "byteLength": 1699232, + "uri": "scene.bin" + } + ], + "materials": [ + { + "doubleSided": true, + "name": "auto", + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.00807476, + 0.00807476, + 0.00807476, + 1.0 + ], + "metallicFactor": 0.0, + "roughnessFactor": 0.9979413320596211 + } + }, + { + "doubleSided": true, + "name": "auto_1", + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.494196, + 0.00524818, + 0.0, + 1.0 + ], + "metallicFactor": 0.0, + "roughnessFactor": 0.97225634498168 + } + }, + { + "doubleSided": true, + "name": "auto_3", + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.023529, + 0.023529, + 0.023529, + 1.0 + ], + "metallicFactor": 0.0, + "roughnessFactor": 0.9947387556557408 + } + }, + { + "doubleSided": true, + "name": "auto_5.001", + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.69207, + 0.00628772, + 0.00628772, + 1.0 + ], + "metallicFactor": 0.0, + "roughnessFactor": 0.9612257725197265 + } + }, + { + "doubleSided": true, + "name": "Plastic_Black_Matte", + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.0139246, + 0.0139246, + 0.0139246, + 1.0 + ], + "metallicFactor": 0.0, + "roughnessFactor": 0.9963158971293951 + } + }, + { + "doubleSided": true, + "name": "auto_4", + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.00807476, + 0.00807476, + 0.00807476, + 1.0 + ], + "metallicFactor": 0.0, + "roughnessFactor": 0.9979413320596211 + } + }, + { + "doubleSided": true, + "name": "auto_6", + "pbrMetallicRoughness": { + "baseColorFactor": [ + 0.00807476, + 0.00807476, + 0.00807476, + 1.0 + ], + "metallicFactor": 0.0, + "roughnessFactor": 0.9979413320596211 + } + } + ], + "meshes": [ + { + "name": "Mesh1 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 1, + "POSITION": 0, + "TEXCOORD_0": 2 + }, + "indices": 3, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh2 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 5, + "POSITION": 4, + "TEXCOORD_0": 6 + }, + "indices": 7, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh2 skp7AF7_1 Model__auto_1_0", + "primitives": [ + { + "attributes": { + "NORMAL": 9, + "POSITION": 8, + "TEXCOORD_0": 10 + }, + "indices": 11, + "material": 1, + "mode": 4 + } + ] + }, + { + "name": "Mesh3 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 13, + "POSITION": 12, + "TEXCOORD_0": 14 + }, + "indices": 15, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh4 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 17, + "POSITION": 16, + "TEXCOORD_0": 18 + }, + "indices": 19, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh4 skp7AF7_1 Model__auto_1_0", + "primitives": [ + { + "attributes": { + "NORMAL": 21, + "POSITION": 20, + "TEXCOORD_0": 22 + }, + "indices": 23, + "material": 1, + "mode": 4 + } + ] + }, + { + "name": "Mesh5 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 25, + "POSITION": 24, + "TEXCOORD_0": 26 + }, + "indices": 27, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh6 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 29, + "POSITION": 28, + "TEXCOORD_0": 30 + }, + "indices": 31, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh6 skp7AF7_1 Model__auto_1_0", + "primitives": [ + { + "attributes": { + "NORMAL": 33, + "POSITION": 32, + "TEXCOORD_0": 34 + }, + "indices": 35, + "material": 1, + "mode": 4 + } + ] + }, + { + "name": "Mesh7 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 37, + "POSITION": 36, + "TEXCOORD_0": 38 + }, + "indices": 39, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh8 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 41, + "POSITION": 40, + "TEXCOORD_0": 42 + }, + "indices": 43, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh8 skp7AF7_1 Model__auto_1_0", + "primitives": [ + { + "attributes": { + "NORMAL": 45, + "POSITION": 44, + "TEXCOORD_0": 46 + }, + "indices": 47, + "material": 1, + "mode": 4 + } + ] + }, + { + "name": "Mesh9 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 49, + "POSITION": 48, + "TEXCOORD_0": 50 + }, + "indices": 51, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh10 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 53, + "POSITION": 52, + "TEXCOORD_0": 54 + }, + "indices": 55, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh10 skp7AF7_1 Model__auto_1_0", + "primitives": [ + { + "attributes": { + "NORMAL": 57, + "POSITION": 56, + "TEXCOORD_0": 58 + }, + "indices": 59, + "material": 1, + "mode": 4 + } + ] + }, + { + "name": "Mesh11 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 61, + "POSITION": 60, + "TEXCOORD_0": 62 + }, + "indices": 63, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh12 skp7AF7_1 Model__auto_3_0", + "primitives": [ + { + "attributes": { + "NORMAL": 65, + "POSITION": 64, + "TEXCOORD_0": 66 + }, + "indices": 67, + "material": 2, + "mode": 4 + } + ] + }, + { + "name": "Mesh13 skp7AF7_1 Model__auto_5.001_0", + "primitives": [ + { + "attributes": { + "NORMAL": 69, + "POSITION": 68, + "TEXCOORD_0": 70 + }, + "indices": 71, + "material": 3, + "mode": 4 + } + ] + }, + { + "name": "Mesh14 skp7AF7_1 Model_Plastic_Black_Matte_0", + "primitives": [ + { + "attributes": { + "NORMAL": 73, + "POSITION": 72, + "TEXCOORD_0": 74 + }, + "indices": 75, + "material": 4, + "mode": 4 + } + ] + }, + { + "name": "Mesh15 skp7AF7_1 Model_Plastic_Black_Matte_0", + "primitives": [ + { + "attributes": { + "NORMAL": 77, + "POSITION": 76, + "TEXCOORD_0": 78 + }, + "indices": 79, + "material": 4, + "mode": 4 + } + ] + }, + { + "name": "Mesh16 skp7AF7_1 Model_Plastic_Black_Matte_0", + "primitives": [ + { + "attributes": { + "NORMAL": 81, + "POSITION": 80, + "TEXCOORD_0": 82 + }, + "indices": 83, + "material": 4, + "mode": 4 + } + ] + }, + { + "name": "Mesh17 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 85, + "POSITION": 84, + "TEXCOORD_0": 86 + }, + "indices": 87, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh18 skp7AF7_1 Model_Plastic_Black_Matte_0", + "primitives": [ + { + "attributes": { + "NORMAL": 89, + "POSITION": 88, + "TEXCOORD_0": 90 + }, + "indices": 91, + "material": 4, + "mode": 4 + } + ] + }, + { + "name": "Mesh19 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 93, + "POSITION": 92, + "TEXCOORD_0": 94 + }, + "indices": 95, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh20 skp7AF7_1 Model_Plastic_Black_Matte_0", + "primitives": [ + { + "attributes": { + "NORMAL": 97, + "POSITION": 96, + "TEXCOORD_0": 98 + }, + "indices": 99, + "material": 4, + "mode": 4 + } + ] + }, + { + "name": "Mesh21 skp7AF7_1 Model_Plastic_Black_Matte_0", + "primitives": [ + { + "attributes": { + "NORMAL": 101, + "POSITION": 100, + "TEXCOORD_0": 102 + }, + "indices": 103, + "material": 4, + "mode": 4 + } + ] + }, + { + "name": "Mesh22 skp7AF7_1 Model_Plastic_Black_Matte_0", + "primitives": [ + { + "attributes": { + "NORMAL": 105, + "POSITION": 104, + "TEXCOORD_0": 106 + }, + "indices": 107, + "material": 4, + "mode": 4 + } + ] + }, + { + "name": "Mesh23 skp7AF7_1 Model_Plastic_Black_Matte_0", + "primitives": [ + { + "attributes": { + "NORMAL": 109, + "POSITION": 108, + "TEXCOORD_0": 110 + }, + "indices": 111, + "material": 4, + "mode": 4 + } + ] + }, + { + "name": "Mesh24 skp7AF7_1 Model_Plastic_Black_Matte_0", + "primitives": [ + { + "attributes": { + "NORMAL": 113, + "POSITION": 112, + "TEXCOORD_0": 114 + }, + "indices": 115, + "material": 4, + "mode": 4 + } + ] + }, + { + "name": "Mesh25 skp7AF7_1 Model__auto_3_0", + "primitives": [ + { + "attributes": { + "NORMAL": 117, + "POSITION": 116, + "TEXCOORD_0": 118 + }, + "indices": 119, + "material": 2, + "mode": 4 + } + ] + }, + { + "name": "Mesh26 skp7AF7_1 Model_Plastic_Black_Matte_0", + "primitives": [ + { + "attributes": { + "NORMAL": 121, + "POSITION": 120, + "TEXCOORD_0": 122 + }, + "indices": 123, + "material": 4, + "mode": 4 + } + ] + }, + { + "name": "Mesh27 skp7AF7_1 Model__auto_3_0", + "primitives": [ + { + "attributes": { + "NORMAL": 125, + "POSITION": 124, + "TEXCOORD_0": 126 + }, + "indices": 127, + "material": 2, + "mode": 4 + } + ] + }, + { + "name": "Mesh28 skp7AF7_1 Model_Plastic_Black_Matte_0", + "primitives": [ + { + "attributes": { + "NORMAL": 129, + "POSITION": 128, + "TEXCOORD_0": 130 + }, + "indices": 131, + "material": 4, + "mode": 4 + } + ] + }, + { + "name": "Mesh29 skp7AF7_1 Model_Plastic_Black_Matte_0", + "primitives": [ + { + "attributes": { + "NORMAL": 133, + "POSITION": 132, + "TEXCOORD_0": 134 + }, + "indices": 135, + "material": 4, + "mode": 4 + } + ] + }, + { + "name": "Mesh30 skp7AF7_1 Model__auto_4_0", + "primitives": [ + { + "attributes": { + "NORMAL": 137, + "POSITION": 136, + "TEXCOORD_0": 138 + }, + "indices": 139, + "material": 5, + "mode": 4 + } + ] + }, + { + "name": "Mesh30 skp7AF7_1 Model__auto_5.001_0", + "primitives": [ + { + "attributes": { + "NORMAL": 141, + "POSITION": 140, + "TEXCOORD_0": 142 + }, + "indices": 143, + "material": 3, + "mode": 4 + } + ] + }, + { + "name": "Mesh31 skp7AF7_1 Model__auto_5.001_0", + "primitives": [ + { + "attributes": { + "NORMAL": 145, + "POSITION": 144, + "TEXCOORD_0": 146 + }, + "indices": 147, + "material": 3, + "mode": 4 + } + ] + }, + { + "name": "Mesh32 skp7AF7_1 Model__auto_4_0", + "primitives": [ + { + "attributes": { + "NORMAL": 149, + "POSITION": 148, + "TEXCOORD_0": 150 + }, + "indices": 151, + "material": 5, + "mode": 4 + } + ] + }, + { + "name": "Mesh33 skp7AF7_1 Model__auto_4_0", + "primitives": [ + { + "attributes": { + "NORMAL": 153, + "POSITION": 152, + "TEXCOORD_0": 154 + }, + "indices": 155, + "material": 5, + "mode": 4 + } + ] + }, + { + "name": "Mesh34 skp7AF7_1 Model__auto_5.001_0", + "primitives": [ + { + "attributes": { + "NORMAL": 157, + "POSITION": 156, + "TEXCOORD_0": 158 + }, + "indices": 159, + "material": 3, + "mode": 4 + } + ] + }, + { + "name": "Mesh35 skp7AF7_1 Model__auto_4_0", + "primitives": [ + { + "attributes": { + "NORMAL": 161, + "POSITION": 160, + "TEXCOORD_0": 162 + }, + "indices": 163, + "material": 5, + "mode": 4 + } + ] + }, + { + "name": "Mesh36 skp7AF7_1 Model__auto_5.001_0", + "primitives": [ + { + "attributes": { + "NORMAL": 165, + "POSITION": 164, + "TEXCOORD_0": 166 + }, + "indices": 167, + "material": 3, + "mode": 4 + } + ] + }, + { + "name": "Mesh37 skp7AF7_1 Model_Plastic_Black_Matte_0", + "primitives": [ + { + "attributes": { + "NORMAL": 169, + "POSITION": 168, + "TEXCOORD_0": 170 + }, + "indices": 171, + "material": 4, + "mode": 4 + } + ] + }, + { + "name": "Mesh38 skp7AF7_1 Model__auto_3_0", + "primitives": [ + { + "attributes": { + "NORMAL": 173, + "POSITION": 172, + "TEXCOORD_0": 174 + }, + "indices": 175, + "material": 2, + "mode": 4 + } + ] + }, + { + "name": "Mesh39 skp7AF7_1 Model_Plastic_Black_Matte_0", + "primitives": [ + { + "attributes": { + "NORMAL": 177, + "POSITION": 176, + "TEXCOORD_0": 178 + }, + "indices": 179, + "material": 4, + "mode": 4 + } + ] + }, + { + "name": "Mesh40 skp7AF7_1 Model__auto_4_0", + "primitives": [ + { + "attributes": { + "NORMAL": 181, + "POSITION": 180, + "TEXCOORD_0": 182 + }, + "indices": 183, + "material": 5, + "mode": 4 + } + ] + }, + { + "name": "Mesh40 skp7AF7_1 Model__auto_5.001_0", + "primitives": [ + { + "attributes": { + "NORMAL": 185, + "POSITION": 184, + "TEXCOORD_0": 186 + }, + "indices": 187, + "material": 3, + "mode": 4 + } + ] + }, + { + "name": "Mesh41 skp7AF7_1 Model__auto_4_0", + "primitives": [ + { + "attributes": { + "NORMAL": 189, + "POSITION": 188, + "TEXCOORD_0": 190 + }, + "indices": 191, + "material": 5, + "mode": 4 + } + ] + }, + { + "name": "Mesh41 skp7AF7_1 Model__auto_5.001_0", + "primitives": [ + { + "attributes": { + "NORMAL": 193, + "POSITION": 192, + "TEXCOORD_0": 194 + }, + "indices": 195, + "material": 3, + "mode": 4 + } + ] + }, + { + "name": "Mesh42 skp7AF7_1 Model__auto_6_0", + "primitives": [ + { + "attributes": { + "NORMAL": 197, + "POSITION": 196, + "TEXCOORD_0": 198 + }, + "indices": 199, + "material": 6, + "mode": 4 + } + ] + }, + { + "name": "Mesh43 skp7AF7_1 Model_Plastic_Black_Matte_0", + "primitives": [ + { + "attributes": { + "NORMAL": 201, + "POSITION": 200, + "TEXCOORD_0": 202 + }, + "indices": 203, + "material": 4, + "mode": 4 + } + ] + }, + { + "name": "Mesh44 skp7AF7_1 Model_Plastic_Black_Matte_0", + "primitives": [ + { + "attributes": { + "NORMAL": 205, + "POSITION": 204, + "TEXCOORD_0": 206 + }, + "indices": 207, + "material": 4, + "mode": 4 + } + ] + }, + { + "name": "Mesh45 skp7AF7_1 Model_Plastic_Black_Matte_0", + "primitives": [ + { + "attributes": { + "NORMAL": 209, + "POSITION": 208, + "TEXCOORD_0": 210 + }, + "indices": 211, + "material": 4, + "mode": 4 + } + ] + }, + { + "name": "Mesh46 skp7AF7_1 Model_Plastic_Black_Matte_0", + "primitives": [ + { + "attributes": { + "NORMAL": 213, + "POSITION": 212, + "TEXCOORD_0": 214 + }, + "indices": 215, + "material": 4, + "mode": 4 + } + ] + }, + { + "name": "Mesh47 skp7AF7_1 Model_Plastic_Black_Matte_0", + "primitives": [ + { + "attributes": { + "NORMAL": 217, + "POSITION": 216, + "TEXCOORD_0": 218 + }, + "indices": 219, + "material": 4, + "mode": 4 + } + ] + }, + { + "name": "Mesh50 skp7AF7_1 Model__auto_5.001_0", + "primitives": [ + { + "attributes": { + "NORMAL": 221, + "POSITION": 220, + "TEXCOORD_0": 222 + }, + "indices": 223, + "material": 3, + "mode": 4 + } + ] + }, + { + "name": "Mesh51 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 225, + "POSITION": 224, + "TEXCOORD_0": 226 + }, + "indices": 227, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh52 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 229, + "POSITION": 228, + "TEXCOORD_0": 230 + }, + "indices": 231, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh53 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 233, + "POSITION": 232, + "TEXCOORD_0": 234 + }, + "indices": 235, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh54 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 237, + "POSITION": 236, + "TEXCOORD_0": 238 + }, + "indices": 239, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh55 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 241, + "POSITION": 240, + "TEXCOORD_0": 242 + }, + "indices": 243, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh56 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 245, + "POSITION": 244, + "TEXCOORD_0": 246 + }, + "indices": 247, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh57 skp7AF7_1 Model_Plastic_Black_Matte_0", + "primitives": [ + { + "attributes": { + "NORMAL": 249, + "POSITION": 248, + "TEXCOORD_0": 250 + }, + "indices": 251, + "material": 4, + "mode": 4 + } + ] + }, + { + "name": "Mesh58 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 253, + "POSITION": 252, + "TEXCOORD_0": 254 + }, + "indices": 255, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh59 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 257, + "POSITION": 256, + "TEXCOORD_0": 258 + }, + "indices": 259, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh60 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 261, + "POSITION": 260, + "TEXCOORD_0": 262 + }, + "indices": 263, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Mesh61 skp7AF7_1 Model__auto__0", + "primitives": [ + { + "attributes": { + "NORMAL": 265, + "POSITION": 264, + "TEXCOORD_0": 266 + }, + "indices": 267, + "material": 0, + "mode": 4 + } + ] + } + ], + "nodes": [ + { + "children": [ + 1 + ], + "matrix": [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 2.220446049250313e-16, + -1.0, + 0.0, + 0.0, + 1.0, + 2.220446049250313e-16, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + "name": "Sketchfab_model" + }, + { + "children": [ + 2 + ], + "matrix": [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + -1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + "name": "64f260fe569646809ee7d2053dba7710.fbx" + }, + { + "children": [ + 3, + 5, + 7, + 9, + 11, + 14, + 16, + 19, + 21, + 24, + 26, + 29, + 31, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + 66, + 68, + 70, + 72, + 75, + 77, + 79, + 81, + 83, + 85, + 87, + 89, + 91, + 93, + 96, + 99, + 101, + 103, + 105, + 107, + 109, + 111, + 113, + 115, + 117, + 119, + 121, + 123, + 125, + 127, + 129, + 131, + 133, + 135 + ], + "name": "RootNode" + }, + { + "children": [ + 4 + ], + "matrix": [ + -110.89090095143153, + -117.20639719396219, + -549.9807751646288, + 0.0, + -23.164857245787605, + 561.0487608076689, + -114.89443789211055, + 0.0, + 561.8535820226136, + -0.0009100197259324162, + -113.28458387385146, + 0.0, + 1877.5167236328125, + 4423.4072265625, + 8562.794921875, + 1.0 + ], + "name": "Camera.004" + }, + { + "name": "Object_4" + }, + { + "children": [ + 6 + ], + "matrix": [ + -2.977999697394616e-05, + -57.20887523164556, + -213.50640921337714, + 0.0, + -3.920611324747483e-06, + 213.5064092133792, + -57.20887523164556, + 0.0, + 221.03808593749795, + -3.920611054098301e-06, + -2.9779994918161705e-05, + 0.0, + 45.831722259521484, + 5015.84326171875, + 9400.2666015625, + 1.0 + ], + "name": "Camera.005" + }, + { + "name": "Object_6" + }, + { + "children": [ + 8 + ], + "matrix": [ + -2.1704325824473034e-05, + -496.53707885742057, + 2.959591267499861e-05, + 0.0, + -8.089615966398048e-05, + -2.9595909146890465e-05, + -496.5370788574144, + 0.0, + 496.5370178222586, + -2.1704327980126288e-05, + -8.089614839705078e-05, + 0.0, + -19.553686141967773, + 8847.44921875, + 69.95836639404297, + 1.0 + ], + "name": "Camera.006" + }, + { + "name": "Object_8" + }, + { + "children": [ + 10 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh1 skp7AF7_1 Model" + }, + { + "mesh": 0, + "name": "Mesh1 skp7AF7_1 Model__auto__0" + }, + { + "children": [ + 12, + 13 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh2 skp7AF7_1 Model" + }, + { + "mesh": 1, + "name": "Mesh2 skp7AF7_1 Model__auto__0" + }, + { + "mesh": 2, + "name": "Mesh2 skp7AF7_1 Model__auto_1_0" + }, + { + "children": [ + 15 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh3 skp7AF7_1 Model" + }, + { + "mesh": 3, + "name": "Mesh3 skp7AF7_1 Model__auto__0" + }, + { + "children": [ + 17, + 18 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh4 skp7AF7_1 Model" + }, + { + "mesh": 4, + "name": "Mesh4 skp7AF7_1 Model__auto__0" + }, + { + "mesh": 5, + "name": "Mesh4 skp7AF7_1 Model__auto_1_0" + }, + { + "children": [ + 20 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh5 skp7AF7_1 Model" + }, + { + "mesh": 6, + "name": "Mesh5 skp7AF7_1 Model__auto__0" + }, + { + "children": [ + 22, + 23 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh6 skp7AF7_1 Model" + }, + { + "mesh": 7, + "name": "Mesh6 skp7AF7_1 Model__auto__0" + }, + { + "mesh": 8, + "name": "Mesh6 skp7AF7_1 Model__auto_1_0" + }, + { + "children": [ + 25 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh7 skp7AF7_1 Model" + }, + { + "mesh": 9, + "name": "Mesh7 skp7AF7_1 Model__auto__0" + }, + { + "children": [ + 27, + 28 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh8 skp7AF7_1 Model" + }, + { + "mesh": 10, + "name": "Mesh8 skp7AF7_1 Model__auto__0" + }, + { + "mesh": 11, + "name": "Mesh8 skp7AF7_1 Model__auto_1_0" + }, + { + "children": [ + 30 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh9 skp7AF7_1 Model" + }, + { + "mesh": 12, + "name": "Mesh9 skp7AF7_1 Model__auto__0" + }, + { + "children": [ + 32, + 33 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh10 skp7AF7_1 Model" + }, + { + "mesh": 13, + "name": "Mesh10 skp7AF7_1 Model__auto__0" + }, + { + "mesh": 14, + "name": "Mesh10 skp7AF7_1 Model__auto_1_0" + }, + { + "children": [ + 35 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh11 skp7AF7_1 Model" + }, + { + "mesh": 15, + "name": "Mesh11 skp7AF7_1 Model__auto__0" + }, + { + "children": [ + 37 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh12 skp7AF7_1 Model" + }, + { + "mesh": 16, + "name": "Mesh12 skp7AF7_1 Model__auto_3_0" + }, + { + "children": [ + 39 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh13 skp7AF7_1 Model" + }, + { + "mesh": 17, + "name": "Mesh13 skp7AF7_1 Model__auto_5.001_0" + }, + { + "children": [ + 41 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh14 skp7AF7_1 Model" + }, + { + "mesh": 18, + "name": "Mesh14 skp7AF7_1 Model_Plastic_Black_Matte_0" + }, + { + "children": [ + 43 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh15 skp7AF7_1 Model" + }, + { + "mesh": 19, + "name": "Mesh15 skp7AF7_1 Model_Plastic_Black_Matte_0" + }, + { + "children": [ + 45 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh16 skp7AF7_1 Model" + }, + { + "mesh": 20, + "name": "Mesh16 skp7AF7_1 Model_Plastic_Black_Matte_0" + }, + { + "children": [ + 47 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh17 skp7AF7_1 Model" + }, + { + "mesh": 21, + "name": "Mesh17 skp7AF7_1 Model__auto__0" + }, + { + "children": [ + 49 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh18 skp7AF7_1 Model" + }, + { + "mesh": 22, + "name": "Mesh18 skp7AF7_1 Model_Plastic_Black_Matte_0" + }, + { + "children": [ + 51 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh19 skp7AF7_1 Model" + }, + { + "mesh": 23, + "name": "Mesh19 skp7AF7_1 Model__auto__0" + }, + { + "children": [ + 53 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh20 skp7AF7_1 Model" + }, + { + "mesh": 24, + "name": "Mesh20 skp7AF7_1 Model_Plastic_Black_Matte_0" + }, + { + "children": [ + 55 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh21 skp7AF7_1 Model" + }, + { + "mesh": 25, + "name": "Mesh21 skp7AF7_1 Model_Plastic_Black_Matte_0" + }, + { + "children": [ + 57 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh22 skp7AF7_1 Model" + }, + { + "mesh": 26, + "name": "Mesh22 skp7AF7_1 Model_Plastic_Black_Matte_0" + }, + { + "children": [ + 59 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh23 skp7AF7_1 Model" + }, + { + "mesh": 27, + "name": "Mesh23 skp7AF7_1 Model_Plastic_Black_Matte_0" + }, + { + "children": [ + 61 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh24 skp7AF7_1 Model" + }, + { + "mesh": 28, + "name": "Mesh24 skp7AF7_1 Model_Plastic_Black_Matte_0" + }, + { + "children": [ + 63 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh25 skp7AF7_1 Model" + }, + { + "mesh": 29, + "name": "Mesh25 skp7AF7_1 Model__auto_3_0" + }, + { + "children": [ + 65 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh26 skp7AF7_1 Model" + }, + { + "mesh": 30, + "name": "Mesh26 skp7AF7_1 Model_Plastic_Black_Matte_0" + }, + { + "children": [ + 67 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh27 skp7AF7_1 Model" + }, + { + "mesh": 31, + "name": "Mesh27 skp7AF7_1 Model__auto_3_0" + }, + { + "children": [ + 69 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh28 skp7AF7_1 Model" + }, + { + "mesh": 32, + "name": "Mesh28 skp7AF7_1 Model_Plastic_Black_Matte_0" + }, + { + "children": [ + 71 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh29 skp7AF7_1 Model" + }, + { + "mesh": 33, + "name": "Mesh29 skp7AF7_1 Model_Plastic_Black_Matte_0" + }, + { + "children": [ + 73, + 74 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + 1.5916157281026244e-10, + 0.0, + 0.0006516828434541821, + 1.0 + ], + "name": "Mesh30 skp7AF7_1 Model" + }, + { + "mesh": 34, + "name": "Mesh30 skp7AF7_1 Model__auto_4_0" + }, + { + "mesh": 35, + "name": "Mesh30 skp7AF7_1 Model__auto_5.001_0" + }, + { + "children": [ + 76 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh31 skp7AF7_1 Model" + }, + { + "mesh": 36, + "name": "Mesh31 skp7AF7_1 Model__auto_5.001_0" + }, + { + "children": [ + 78 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh32 skp7AF7_1 Model" + }, + { + "mesh": 37, + "name": "Mesh32 skp7AF7_1 Model__auto_4_0" + }, + { + "children": [ + 80 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh33 skp7AF7_1 Model" + }, + { + "mesh": 38, + "name": "Mesh33 skp7AF7_1 Model__auto_4_0" + }, + { + "children": [ + 82 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh34 skp7AF7_1 Model" + }, + { + "mesh": 39, + "name": "Mesh34 skp7AF7_1 Model__auto_5.001_0" + }, + { + "children": [ + 84 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh35 skp7AF7_1 Model" + }, + { + "mesh": 40, + "name": "Mesh35 skp7AF7_1 Model__auto_4_0" + }, + { + "children": [ + 86 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh36 skp7AF7_1 Model" + }, + { + "mesh": 41, + "name": "Mesh36 skp7AF7_1 Model__auto_5.001_0" + }, + { + "children": [ + 88 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh37 skp7AF7_1 Model" + }, + { + "mesh": 42, + "name": "Mesh37 skp7AF7_1 Model_Plastic_Black_Matte_0" + }, + { + "children": [ + 90 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh38 skp7AF7_1 Model" + }, + { + "mesh": 43, + "name": "Mesh38 skp7AF7_1 Model__auto_3_0" + }, + { + "children": [ + 92 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh39 skp7AF7_1 Model" + }, + { + "mesh": 44, + "name": "Mesh39 skp7AF7_1 Model_Plastic_Black_Matte_0" + }, + { + "children": [ + 94, + 95 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh40 skp7AF7_1 Model" + }, + { + "mesh": 45, + "name": "Mesh40 skp7AF7_1 Model__auto_4_0" + }, + { + "mesh": 46, + "name": "Mesh40 skp7AF7_1 Model__auto_5.001_0" + }, + { + "children": [ + 97, + 98 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh41 skp7AF7_1 Model" + }, + { + "mesh": 47, + "name": "Mesh41 skp7AF7_1 Model__auto_4_0" + }, + { + "mesh": 48, + "name": "Mesh41 skp7AF7_1 Model__auto_5.001_0" + }, + { + "children": [ + 100 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh42 skp7AF7_1 Model" + }, + { + "mesh": 49, + "name": "Mesh42 skp7AF7_1 Model__auto_6_0" + }, + { + "children": [ + 102 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh43 skp7AF7_1 Model" + }, + { + "mesh": 50, + "name": "Mesh43 skp7AF7_1 Model_Plastic_Black_Matte_0" + }, + { + "children": [ + 104 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh44 skp7AF7_1 Model" + }, + { + "mesh": 51, + "name": "Mesh44 skp7AF7_1 Model_Plastic_Black_Matte_0" + }, + { + "children": [ + 106 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh45 skp7AF7_1 Model" + }, + { + "mesh": 52, + "name": "Mesh45 skp7AF7_1 Model_Plastic_Black_Matte_0" + }, + { + "children": [ + 108 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh46 skp7AF7_1 Model" + }, + { + "mesh": 53, + "name": "Mesh46 skp7AF7_1 Model_Plastic_Black_Matte_0" + }, + { + "children": [ + 110 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh47 skp7AF7_1 Model" + }, + { + "mesh": 54, + "name": "Mesh47 skp7AF7_1 Model_Plastic_Black_Matte_0" + }, + { + "children": [ + 112 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh50 skp7AF7_1 Model" + }, + { + "mesh": 55, + "name": "Mesh50 skp7AF7_1 Model__auto_5.001_0" + }, + { + "children": [ + 114 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh51 skp7AF7_1 Model" + }, + { + "mesh": 56, + "name": "Mesh51 skp7AF7_1 Model__auto__0" + }, + { + "children": [ + 116 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh52 skp7AF7_1 Model" + }, + { + "mesh": 57, + "name": "Mesh52 skp7AF7_1 Model__auto__0" + }, + { + "children": [ + 118 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh53 skp7AF7_1 Model" + }, + { + "mesh": 58, + "name": "Mesh53 skp7AF7_1 Model__auto__0" + }, + { + "children": [ + 120 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh54 skp7AF7_1 Model" + }, + { + "mesh": 59, + "name": "Mesh54 skp7AF7_1 Model__auto__0" + }, + { + "children": [ + 122 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh55 skp7AF7_1 Model" + }, + { + "mesh": 60, + "name": "Mesh55 skp7AF7_1 Model__auto__0" + }, + { + "children": [ + 124 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh56 skp7AF7_1 Model" + }, + { + "mesh": 61, + "name": "Mesh56 skp7AF7_1 Model__auto__0" + }, + { + "children": [ + 126 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh57 skp7AF7_1 Model" + }, + { + "mesh": 62, + "name": "Mesh57 skp7AF7_1 Model_Plastic_Black_Matte_0" + }, + { + "children": [ + 128 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh58 skp7AF7_1 Model" + }, + { + "mesh": 63, + "name": "Mesh58 skp7AF7_1 Model__auto__0" + }, + { + "children": [ + 130 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh59 skp7AF7_1 Model" + }, + { + "mesh": 64, + "name": "Mesh59 skp7AF7_1 Model__auto__0" + }, + { + "children": [ + 132 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh60 skp7AF7_1 Model" + }, + { + "mesh": 65, + "name": "Mesh60 skp7AF7_1 Model__auto__0" + }, + { + "children": [ + 134 + ], + "matrix": [ + 99.99999999999847, + 1.8901470764646132e-19, + 1.748455531469508e-05, + 0.0, + -2.8485956683371794e-12, + 99.99999999999866, + 1.6292067073208867e-05, + 0.0, + -1.748455531469485e-05, + -1.6292067073209114e-05, + 99.99999999999714, + 0.0, + -1.3642420526593924e-10, + 0.0, + -4.547473508864641e-11, + 1.0 + ], + "name": "Mesh61 skp7AF7_1 Model" + }, + { + "mesh": 66, + "name": "Mesh61 skp7AF7_1 Model__auto__0" + }, + { + "children": [ + 136 + ], + "matrix": [ + 100.0, + 0.0, + 0.0, + 0.0, + 0.0, + 99.99999999999972, + -7.5497901264043296e-06, + 0.0, + 0.0, + 7.5497901264043296e-06, + 99.99999999999972, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + "name": "Sun" + }, + { + "children": [ + 137 + ], + "matrix": [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 2.220446049250313e-16, + 1.0, + 0.0, + 0.0, + -1.0, + 2.220446049250313e-16, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + "name": "Object_136" + }, + { + "name": "Object_137" + } + ], + "scene": 0, + "scenes": [ + { + "name": "Sketchfab_Scene", + "nodes": [ + 0 + ] + } + ] +} diff --git a/public/models/gaming-pc/gaming-computer-opt.glb b/public/models/gaming-pc/gaming-computer-opt.glb new file mode 100644 index 0000000..ea35e0c Binary files /dev/null and b/public/models/gaming-pc/gaming-computer-opt.glb differ diff --git a/public/models/gaming-pc/gaming-computer.glb b/public/models/gaming-pc/gaming-computer.glb new file mode 100644 index 0000000..e365275 Binary files /dev/null and b/public/models/gaming-pc/gaming-computer.glb differ diff --git a/public/models/kenney/cabinetTelevisionDoors.glb b/public/models/kenney/cabinetTelevisionDoors.glb new file mode 100644 index 0000000..6221e85 Binary files /dev/null and b/public/models/kenney/cabinetTelevisionDoors.glb differ diff --git a/public/models/kenney/lampSquareFloor.glb b/public/models/kenney/lampSquareFloor.glb new file mode 100644 index 0000000..844f5b0 Binary files /dev/null and b/public/models/kenney/lampSquareFloor.glb differ diff --git a/public/models/kenney/rugRectangle.glb b/public/models/kenney/rugRectangle.glb new file mode 100644 index 0000000..2ca3bb1 Binary files /dev/null and b/public/models/kenney/rugRectangle.glb differ diff --git a/public/models/kenney/sideTableDrawers.glb b/public/models/kenney/sideTableDrawers.glb new file mode 100644 index 0000000..a801b29 Binary files /dev/null and b/public/models/kenney/sideTableDrawers.glb differ diff --git a/public/models/messy-bed/scene.bin b/public/models/messy-bed/scene.bin new file mode 100644 index 0000000..a17ecc6 Binary files /dev/null and b/public/models/messy-bed/scene.bin differ diff --git a/public/models/messy-bed/scene.gltf b/public/models/messy-bed/scene.gltf new file mode 100644 index 0000000..6b9f297 --- /dev/null +++ b/public/models/messy-bed/scene.gltf @@ -0,0 +1,928 @@ +{ + "accessors": [ + { + "bufferView": 2, + "componentType": 5126, + "count": 2058, + "max": [ + 1.3084441423416138, + 1.0175703763961792, + 0.9245599508285522 + ], + "min": [ + -1.3084441423416138, + 0.7179964780807495, + 0.4124821126461029 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 24696, + "componentType": 5126, + "count": 2058, + "max": [ + 1.0, + 1.0, + 1.0 + ], + "min": [ + -1.0, + -1.0, + -1.0 + ], + "type": "VEC3" + }, + { + "bufferView": 3, + "componentType": 5126, + "count": 2058, + "max": [ + 1.0, + 1.0, + 1.0, + 1.0 + ], + "min": [ + -1.0, + -1.0, + -1.0, + -1.0 + ], + "type": "VEC4" + }, + { + "bufferView": 1, + "componentType": 5126, + "count": 2058, + "max": [ + 0.9700005650520325, + 0.22934934496879578 + ], + "min": [ + 0.006074755452573299, + 0.021558746695518494 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "componentType": 5125, + "count": 4896, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 49392, + "componentType": 5126, + "count": 994, + "max": [ + 0.8331380486488342, + 0.8255230188369751, + -0.5445850491523743 + ], + "min": [ + -0.6806660294532776, + 0.536014974117279, + -0.9984099864959717 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 61320, + "componentType": 5126, + "count": 994, + "max": [ + 0.9998172521591187, + 0.9994966983795166, + 0.9989262223243713 + ], + "min": [ + -0.9999222755432129, + -0.998486340045929, + -0.9989244341850281 + ], + "type": "VEC3" + }, + { + "bufferView": 3, + "byteOffset": 32928, + "componentType": 5126, + "count": 994, + "max": [ + 0.9642208814620972, + 0.9991565942764282, + 0.9980593323707581, + 1.0 + ], + "min": [ + -0.995429515838623, + -0.9993336200714111, + -0.9999181628227234, + -1.0 + ], + "type": "VEC4" + }, + { + "bufferView": 1, + "byteOffset": 16464, + "componentType": 5126, + "count": 994, + "max": [ + 0.7824514508247375, + 0.9281307458877563 + ], + "min": [ + 0.002940929727628827, + 0.0028301426209509373 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 19584, + "componentType": 5125, + "count": 5514, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 73248, + "componentType": 5126, + "count": 2476, + "max": [ + 0.9215628504753113, + 0.5641927719116211, + 0.9915558695793152 + ], + "min": [ + -0.9210963249206543, + 0.2993731200695038, + -0.9947721362113953 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 102960, + "componentType": 5126, + "count": 2476, + "max": [ + 0.9999920129776001, + 0.9999804496765137, + 0.998385488986969 + ], + "min": [ + -0.9998441934585571, + -1.0, + -0.9999992847442627 + ], + "type": "VEC3" + }, + { + "bufferView": 3, + "byteOffset": 48832, + "componentType": 5126, + "count": 2476, + "max": [ + 0.9999999403953552, + 0.9973680973052979, + 0.9996340870857239, + 1.0 + ], + "min": [ + -0.9999982118606567, + -0.9998458623886108, + -0.9999427199363708, + -1.0 + ], + "type": "VEC4" + }, + { + "bufferView": 1, + "byteOffset": 24416, + "componentType": 5126, + "count": 2476, + "max": [ + 0.9868587851524353, + 0.9863024353981018 + ], + "min": [ + 0.5089327692985535, + 0.5142819881439209 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 41640, + "componentType": 5125, + "count": 14412, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 132672, + "componentType": 5126, + "count": 2021, + "max": [ + 0.9966859817504883, + 0.6952620148658752, + 0.7799140214920044 + ], + "min": [ + -0.8106590509414673, + 0.37323200702667236, + -0.3986130356788635 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 156924, + "componentType": 5126, + "count": 2021, + "max": [ + 0.9958921074867249, + 0.9999978542327881, + 0.9982888698577881 + ], + "min": [ + -0.9986405968666077, + -0.9999134540557861, + -0.9969792366027832 + ], + "type": "VEC3" + }, + { + "bufferView": 3, + "byteOffset": 88448, + "componentType": 5126, + "count": 2021, + "max": [ + 0.989434003829956, + 0.9980007410049438, + 0.9994179010391235, + 1.0 + ], + "min": [ + -0.9602069854736328, + -0.9992778897285461, + -0.999977171421051, + 1.0 + ], + "type": "VEC4" + }, + { + "bufferView": 1, + "byteOffset": 44224, + "componentType": 5126, + "count": 2021, + "max": [ + 0.9725841283798218, + 0.5629931688308716 + ], + "min": [ + 0.5665116310119629, + 0.019163157790899277 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 99288, + "componentType": 5125, + "count": 11601, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 181176, + "componentType": 5126, + "count": 5353, + "max": [ + 1.1783572435379028, + 0.6789640784263611, + 1.3529304265975952 + ], + "min": [ + -1.0419435501098633, + -0.0009260898223146796, + -0.12823985517024994 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 245412, + "componentType": 5126, + "count": 5353, + "max": [ + 0.9997951984405518, + 0.9999994039535522, + 0.9999382495880127 + ], + "min": [ + -0.9993983507156372, + -1.0, + -0.9977296590805054 + ], + "type": "VEC3" + }, + { + "bufferView": 3, + "byteOffset": 120784, + "componentType": 5126, + "count": 5353, + "max": [ + 0.9999849796295166, + 0.9995407462120056, + 0.9999958872795105, + 1.0 + ], + "min": [ + -0.9998998045921326, + -0.9999901056289673, + -0.9998340606689453, + -1.0 + ], + "type": "VEC4" + }, + { + "bufferView": 1, + "byteOffset": 60392, + "componentType": 5126, + "count": 5353, + "max": [ + 0.5676594376564026, + 0.942223072052002 + ], + "min": [ + 0.002853017533197999, + 0.0028998733032494783 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 145692, + "componentType": 5125, + "count": 30870, + "type": "SCALAR" + }, + { + "bufferView": 2, + "byteOffset": 309648, + "componentType": 5126, + "count": 4455, + "max": [ + 1.3700000047683716, + 1.0377446413040161, + 1.131874918937683 + ], + "min": [ + -1.3700001239776611, + -1.0099999904632568, + -0.02499999850988388 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 363108, + "componentType": 5126, + "count": 4455, + "max": [ + 1.0, + 1.0, + 1.0 + ], + "min": [ + -1.0, + -1.0, + -1.0 + ], + "type": "VEC3" + }, + { + "bufferView": 3, + "byteOffset": 206432, + "componentType": 5126, + "count": 4455, + "max": [ + 1.0, + 1.0, + 1.0, + 1.0 + ], + "min": [ + -1.0, + -1.0, + -1.0, + -1.0 + ], + "type": "VEC4" + }, + { + "bufferView": 1, + "byteOffset": 103216, + "componentType": 5126, + "count": 4455, + "max": [ + 0.9922096133232117, + 0.9956596493721008 + ], + "min": [ + -6.861123256385326e-05, + 0.09022268652915955 + ], + "type": "VEC2" + }, + { + "bufferView": 0, + "byteOffset": 269172, + "componentType": 5125, + "count": 10026, + "type": "SCALAR" + } + ], + "asset": { + "extras": { + "author": "thethieme (https://sketchfab.com/thethieme)", + "license": "CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)", + "source": "https://sketchfab.com/3d-models/messy-bed-20-with-wall-mounted-backboard-a2b2645701c94fa49e65661806219c6b", + "title": "Messy bed 2.0 (with wall mounted backboard)" + }, + "generator": "Sketchfab-12.66.0", + "version": "2.0" + }, + "bufferViews": [ + { + "buffer": 0, + "byteLength": 309276, + "name": "floatBufferViews", + "target": 34963 + }, + { + "buffer": 0, + "byteLength": 138856, + "byteOffset": 309276, + "byteStride": 8, + "name": "floatBufferViews", + "target": 34962 + }, + { + "buffer": 0, + "byteLength": 416568, + "byteOffset": 448132, + "byteStride": 12, + "name": "floatBufferViews", + "target": 34962 + }, + { + "buffer": 0, + "byteLength": 277712, + "byteOffset": 864700, + "byteStride": 16, + "name": "floatBufferViews", + "target": 34962 + } + ], + "buffers": [ + { + "byteLength": 1142412, + "uri": "scene.bin" + } + ], + "images": [ + { + "uri": "textures/Nordli_Frame_baseColor.png" + }, + { + "uri": "textures/Nordli_Frame_metallicRoughness.png" + }, + { + "uri": "textures/Nordli_Frame_normal.png" + }, + { + "uri": "textures/Nordli_Fabrics_baseColor.png" + }, + { + "uri": "textures/Nordli_Fabrics_metallicRoughness.png" + }, + { + "uri": "textures/Nordli_Fabrics_normal.png" + } + ], + "materials": [ + { + "doubleSided": true, + "name": "Nordli_Frame", + "normalTexture": { + "index": 2 + }, + "occlusionTexture": { + "index": 1 + }, + "pbrMetallicRoughness": { + "baseColorTexture": { + "index": 0 + }, + "metallicFactor": 0.0, + "metallicRoughnessTexture": { + "index": 1 + } + } + }, + { + "doubleSided": true, + "name": "Nordli_Fabrics", + "normalTexture": { + "index": 5 + }, + "occlusionTexture": { + "index": 4 + }, + "pbrMetallicRoughness": { + "baseColorTexture": { + "index": 3 + }, + "metallicFactor": 0.0, + "metallicRoughnessTexture": { + "index": 4 + } + } + } + ], + "meshes": [ + { + "name": "Nordli_Shelves_Nordli_Frame_0", + "primitives": [ + { + "attributes": { + "NORMAL": 1, + "POSITION": 0, + "TANGENT": 2, + "TEXCOORD_0": 3 + }, + "indices": 4, + "material": 0, + "mode": 4 + } + ] + }, + { + "name": "Nordli_Pillows_Low_Nordli_Fabrics_0", + "primitives": [ + { + "attributes": { + "NORMAL": 6, + "POSITION": 5, + "TANGENT": 7, + "TEXCOORD_0": 8 + }, + "indices": 9, + "material": 1, + "mode": 4 + } + ] + }, + { + "name": "Nordli_Sheet_Low_Nordli_Fabrics_0", + "primitives": [ + { + "attributes": { + "NORMAL": 11, + "POSITION": 10, + "TANGENT": 12, + "TEXCOORD_0": 13 + }, + "indices": 14, + "material": 1, + "mode": 4 + } + ] + }, + { + "name": "Nordli_Comforter_Low_Nordli_Fabrics_0", + "primitives": [ + { + "attributes": { + "NORMAL": 16, + "POSITION": 15, + "TANGENT": 17, + "TEXCOORD_0": 18 + }, + "indices": 19, + "material": 1, + "mode": 4 + } + ] + }, + { + "name": "Nordli_Cover_Low_Nordli_Fabrics_0", + "primitives": [ + { + "attributes": { + "NORMAL": 21, + "POSITION": 20, + "TANGENT": 22, + "TEXCOORD_0": 23 + }, + "indices": 24, + "material": 1, + "mode": 4 + } + ] + }, + { + "name": "Nordli_Frame_Low_Nordli_Frame_0", + "primitives": [ + { + "attributes": { + "NORMAL": 26, + "POSITION": 25, + "TANGENT": 27, + "TEXCOORD_0": 28 + }, + "indices": 29, + "material": 0, + "mode": 4 + } + ] + } + ], + "nodes": [ + { + "children": [ + 1 + ], + "matrix": [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 2.220446049250313e-16, + -1.0, + 0.0, + 0.0, + 1.0, + 2.220446049250313e-16, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + "name": "Sketchfab_model" + }, + { + "children": [ + 2 + ], + "matrix": [ + 0.009999999776482582, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.009999999776482582, + 0.0, + 0.0, + -0.009999999776482582, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + "name": "3424d956a3904d468d1100f25915a64e.fbx" + }, + { + "children": [ + 3, + 5, + 7, + 9, + 11, + 13 + ], + "name": "RootNode" + }, + { + "children": [ + 4 + ], + "matrix": [ + 100.0, + 0.0, + 0.0, + 0.0, + 0.0, + -1.629206793918314e-05, + -99.99999999999868, + 0.0, + 0.0, + 99.99999999999868, + -1.629206793918314e-05, + 0.0, + 0.0, + 2.499999761581421, + 0.0, + 1.0 + ], + "name": "Nordli_Shelves" + }, + { + "mesh": 0, + "name": "Nordli_Shelves_Nordli_Frame_0" + }, + { + "children": [ + 6 + ], + "matrix": [ + 100.0, + 0.0, + 0.0, + 0.0, + 0.0, + 99.99999999999866, + 1.6292067073209114e-05, + 0.0, + 0.0, + -1.6292067073209114e-05, + 99.99999999999866, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + "name": "Nordli_Pillows_Low" + }, + { + "mesh": 1, + "name": "Nordli_Pillows_Low_Nordli_Fabrics_0" + }, + { + "children": [ + 8 + ], + "matrix": [ + 100.0, + 0.0, + 0.0, + 0.0, + 0.0, + 99.99999999999866, + 1.6292067073209114e-05, + 0.0, + 0.0, + -1.6292067073209114e-05, + 99.99999999999866, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + "name": "Nordli_Sheet_Low" + }, + { + "mesh": 2, + "name": "Nordli_Sheet_Low_Nordli_Fabrics_0" + }, + { + "children": [ + 10 + ], + "matrix": [ + 100.0, + 0.0, + 0.0, + 0.0, + 0.0, + 99.99999999999866, + 1.6292067073209114e-05, + 0.0, + 0.0, + -1.6292067073209114e-05, + 99.99999999999866, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + "name": "Nordli_Comforter_Low" + }, + { + "mesh": 3, + "name": "Nordli_Comforter_Low_Nordli_Fabrics_0" + }, + { + "children": [ + 12 + ], + "matrix": [ + 100.0, + 0.0, + 0.0, + 0.0, + 0.0, + 99.99999999999866, + 1.6292067073209114e-05, + 0.0, + 0.0, + -1.6292067073209114e-05, + 99.99999999999866, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ], + "name": "Nordli_Cover_Low" + }, + { + "mesh": 4, + "name": "Nordli_Cover_Low_Nordli_Fabrics_0" + }, + { + "children": [ + 14 + ], + "matrix": [ + 100.0, + 0.0, + 0.0, + 0.0, + 0.0, + -1.629206793918314e-05, + -99.99999999999868, + 0.0, + 0.0, + 99.99999999999868, + -1.629206793918314e-05, + 0.0, + 0.0, + 2.499999761581421, + 0.0, + 1.0 + ], + "name": "Nordli_Frame_Low" + }, + { + "mesh": 5, + "name": "Nordli_Frame_Low_Nordli_Frame_0" + } + ], + "samplers": [ + { + "magFilter": 9729, + "minFilter": 9987, + "wrapS": 10497, + "wrapT": 10497 + } + ], + "scene": 0, + "scenes": [ + { + "name": "Sketchfab_Scene", + "nodes": [ + 0 + ] + } + ], + "textures": [ + { + "sampler": 0, + "source": 0 + }, + { + "sampler": 0, + "source": 1 + }, + { + "sampler": 0, + "source": 2 + }, + { + "sampler": 0, + "source": 3 + }, + { + "sampler": 0, + "source": 4 + }, + { + "sampler": 0, + "source": 5 + } + ] +} diff --git a/public/models/messy-bed/textures/Nordli_Fabrics_baseColor.png b/public/models/messy-bed/textures/Nordli_Fabrics_baseColor.png new file mode 100644 index 0000000..d69db7f Binary files /dev/null and b/public/models/messy-bed/textures/Nordli_Fabrics_baseColor.png differ diff --git a/public/models/messy-bed/textures/Nordli_Fabrics_metallicRoughness.png b/public/models/messy-bed/textures/Nordli_Fabrics_metallicRoughness.png new file mode 100644 index 0000000..01e07ba Binary files /dev/null and b/public/models/messy-bed/textures/Nordli_Fabrics_metallicRoughness.png differ diff --git a/public/models/messy-bed/textures/Nordli_Fabrics_normal.png b/public/models/messy-bed/textures/Nordli_Fabrics_normal.png new file mode 100644 index 0000000..39896d0 Binary files /dev/null and b/public/models/messy-bed/textures/Nordli_Fabrics_normal.png differ diff --git a/public/models/messy-bed/textures/Nordli_Frame_baseColor.png b/public/models/messy-bed/textures/Nordli_Frame_baseColor.png new file mode 100644 index 0000000..00dd64f Binary files /dev/null and b/public/models/messy-bed/textures/Nordli_Frame_baseColor.png differ diff --git a/public/models/messy-bed/textures/Nordli_Frame_metallicRoughness.png b/public/models/messy-bed/textures/Nordli_Frame_metallicRoughness.png new file mode 100644 index 0000000..965c4b5 Binary files /dev/null and b/public/models/messy-bed/textures/Nordli_Frame_metallicRoughness.png differ diff --git a/public/models/messy-bed/textures/Nordli_Frame_normal.png b/public/models/messy-bed/textures/Nordli_Frame_normal.png new file mode 100644 index 0000000..b19997e Binary files /dev/null and b/public/models/messy-bed/textures/Nordli_Frame_normal.png differ diff --git a/public/models/nightstand/nightstand.glb b/public/models/nightstand/nightstand.glb new file mode 100644 index 0000000..5f88566 Binary files /dev/null and b/public/models/nightstand/nightstand.glb differ diff --git a/public/models/polyhaven/book_encyclopedia_set_01/book_encyclopedia_set_01.bin b/public/models/polyhaven/book_encyclopedia_set_01/book_encyclopedia_set_01.bin new file mode 100644 index 0000000..2320341 Binary files /dev/null and b/public/models/polyhaven/book_encyclopedia_set_01/book_encyclopedia_set_01.bin differ diff --git a/public/models/polyhaven/book_encyclopedia_set_01/book_encyclopedia_set_01.gltf b/public/models/polyhaven/book_encyclopedia_set_01/book_encyclopedia_set_01.gltf new file mode 100644 index 0000000..89a3e01 --- /dev/null +++ b/public/models/polyhaven/book_encyclopedia_set_01/book_encyclopedia_set_01.gltf @@ -0,0 +1,2945 @@ +{ + "asset": { + "generator": "Khronos glTF Blender I/O v1.6.16", + "version": "2.0" + }, + "scene": 0, + "scenes": [ + { + "name": "Scene", + "nodes": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19 + ] + } + ], + "nodes": [ + { + "mesh": 0, + "name": "book_encyclopedia_set_01_book01", + "translation": [ + 0, + 0, + 0.10099244862794876 + ] + }, + { + "mesh": 1, + "name": "book_encyclopedia_set_01_book02", + "translation": [ + 0.03461821377277374, + 0, + 0.10099244862794876 + ] + }, + { + "mesh": 2, + "name": "book_encyclopedia_set_01_book03", + "translation": [ + 0.06154705584049225, + 0, + 0.10099244117736816 + ] + }, + { + "mesh": 3, + "name": "book_encyclopedia_set_01_book04", + "translation": [ + 0.08769135177135468, + 0, + 0.10099244862794876 + ] + }, + { + "mesh": 4, + "name": "book_encyclopedia_set_01_book05", + "translation": [ + 0.11028188467025757, + 0, + 0.10099244862794876 + ] + }, + { + "mesh": 5, + "name": "book_encyclopedia_set_01_book06", + "translation": [ + 0.13115936517715454, + 0, + 0.10099244862794876 + ] + }, + { + "mesh": 6, + "name": "book_encyclopedia_set_01_book07", + "translation": [ + 0.15419802069664001, + 0, + 0.10099244862794876 + ] + }, + { + "mesh": 7, + "name": "book_encyclopedia_set_01_book08", + "translation": [ + 0.17794930934906006, + 0, + 0.10099244862794876 + ] + }, + { + "mesh": 8, + "name": "book_encyclopedia_set_01_book09", + "translation": [ + 0.2007046788930893, + 0, + 0.10099244862794876 + ] + }, + { + "mesh": 9, + "name": "book_encyclopedia_set_01_book10", + "translation": [ + 0.2235286831855774, + 0, + 0.10099244117736816 + ] + }, + { + "mesh": 10, + "name": "book_encyclopedia_set_01_book11", + "translation": [ + 0.2447497546672821, + 0, + 0.10099244117736816 + ] + }, + { + "mesh": 11, + "name": "book_encyclopedia_set_01_book12", + "translation": [ + 0.2677144706249237, + 0, + 0.10099244117736816 + ] + }, + { + "mesh": 12, + "name": "book_encyclopedia_set_01_book13", + "translation": [ + 0.3001822829246521, + 0, + 0.10099244117736816 + ] + }, + { + "mesh": 13, + "name": "book_encyclopedia_set_01_book14", + "translation": [ + 0.3387332856655121, + 0, + 0.10099243372678757 + ] + }, + { + "mesh": 14, + "name": "book_encyclopedia_set_01_book15", + "translation": [ + 0.3759635388851166, + 0, + 0.10099244117736816 + ] + }, + { + "mesh": 15, + "name": "book_encyclopedia_set_01_book16", + "translation": [ + 0.40813517570495605, + 0, + 0.10099244117736816 + ] + }, + { + "mesh": 16, + "name": "book_encyclopedia_set_01_book17", + "translation": [ + 0.44120898842811584, + 0, + 0.10099244117736816 + ] + }, + { + "mesh": 17, + "name": "book_encyclopedia_set_01_book18", + "translation": [ + 0.4741947054862976, + 0, + 0.10099243372678757 + ] + }, + { + "mesh": 18, + "name": "book_encyclopedia_set_01_book19", + "translation": [ + 0.49631625413894653, + 0, + 0.10099243372678757 + ] + }, + { + "mesh": 19, + "name": "book_encyclopedia_set_01_book20", + "translation": [ + 0.5200827121734619, + 0, + 0.10099243372678757 + ] + } + ], + "materials": [ + { + "doubleSided": true, + "name": "book_encyclopedia_set_01_cover", + "normalTexture": { + "index": 0 + }, + "pbrMetallicRoughness": { + "baseColorTexture": { + "index": 1 + }, + "metallicRoughnessTexture": { + "index": 2 + } + } + }, + { + "doubleSided": true, + "name": "book_encyclopedia_set_01_paper", + "normalTexture": { + "index": 3 + }, + "pbrMetallicRoughness": { + "baseColorTexture": { + "index": 4 + }, + "metallicFactor": 0, + "metallicRoughnessTexture": { + "index": 5 + } + } + } + ], + "meshes": [ + { + "name": "Cube.004", + "primitives": [ + { + "attributes": { + "POSITION": 0, + "NORMAL": 1, + "TEXCOORD_0": 2 + }, + "indices": 3, + "material": 0 + }, + { + "attributes": { + "POSITION": 4, + "NORMAL": 5, + "TEXCOORD_0": 6 + }, + "indices": 7, + "material": 1 + } + ] + }, + { + "name": "Cube.049", + "primitives": [ + { + "attributes": { + "POSITION": 8, + "NORMAL": 9, + "TEXCOORD_0": 10 + }, + "indices": 11, + "material": 0 + }, + { + "attributes": { + "POSITION": 12, + "NORMAL": 13, + "TEXCOORD_0": 14 + }, + "indices": 15, + "material": 1 + } + ] + }, + { + "name": "Cube.050", + "primitives": [ + { + "attributes": { + "POSITION": 16, + "NORMAL": 17, + "TEXCOORD_0": 18 + }, + "indices": 19, + "material": 0 + }, + { + "attributes": { + "POSITION": 20, + "NORMAL": 21, + "TEXCOORD_0": 22 + }, + "indices": 23, + "material": 1 + } + ] + }, + { + "name": "Cube.051", + "primitives": [ + { + "attributes": { + "POSITION": 24, + "NORMAL": 25, + "TEXCOORD_0": 26 + }, + "indices": 27, + "material": 0 + }, + { + "attributes": { + "POSITION": 28, + "NORMAL": 29, + "TEXCOORD_0": 30 + }, + "indices": 31, + "material": 1 + } + ] + }, + { + "name": "Cube.052", + "primitives": [ + { + "attributes": { + "POSITION": 32, + "NORMAL": 33, + "TEXCOORD_0": 34 + }, + "indices": 35, + "material": 0 + }, + { + "attributes": { + "POSITION": 36, + "NORMAL": 37, + "TEXCOORD_0": 38 + }, + "indices": 39, + "material": 1 + } + ] + }, + { + "name": "Cube.053", + "primitives": [ + { + "attributes": { + "POSITION": 40, + "NORMAL": 41, + "TEXCOORD_0": 42 + }, + "indices": 43, + "material": 0 + }, + { + "attributes": { + "POSITION": 44, + "NORMAL": 45, + "TEXCOORD_0": 46 + }, + "indices": 47, + "material": 1 + } + ] + }, + { + "name": "Cube.054", + "primitives": [ + { + "attributes": { + "POSITION": 48, + "NORMAL": 49, + "TEXCOORD_0": 50 + }, + "indices": 51, + "material": 0 + }, + { + "attributes": { + "POSITION": 52, + "NORMAL": 53, + "TEXCOORD_0": 54 + }, + "indices": 55, + "material": 1 + } + ] + }, + { + "name": "Cube.055", + "primitives": [ + { + "attributes": { + "POSITION": 56, + "NORMAL": 57, + "TEXCOORD_0": 58 + }, + "indices": 59, + "material": 0 + }, + { + "attributes": { + "POSITION": 60, + "NORMAL": 61, + "TEXCOORD_0": 62 + }, + "indices": 63, + "material": 1 + } + ] + }, + { + "name": "Cube.056", + "primitives": [ + { + "attributes": { + "POSITION": 64, + "NORMAL": 65, + "TEXCOORD_0": 66 + }, + "indices": 67, + "material": 0 + }, + { + "attributes": { + "POSITION": 68, + "NORMAL": 69, + "TEXCOORD_0": 70 + }, + "indices": 71, + "material": 1 + } + ] + }, + { + "name": "Cube.057", + "primitives": [ + { + "attributes": { + "POSITION": 72, + "NORMAL": 73, + "TEXCOORD_0": 74 + }, + "indices": 75, + "material": 0 + }, + { + "attributes": { + "POSITION": 76, + "NORMAL": 77, + "TEXCOORD_0": 78 + }, + "indices": 79, + "material": 1 + } + ] + }, + { + "name": "Cube.058", + "primitives": [ + { + "attributes": { + "POSITION": 80, + "NORMAL": 81, + "TEXCOORD_0": 82 + }, + "indices": 83, + "material": 0 + }, + { + "attributes": { + "POSITION": 84, + "NORMAL": 85, + "TEXCOORD_0": 86 + }, + "indices": 87, + "material": 1 + } + ] + }, + { + "name": "Cube.059", + "primitives": [ + { + "attributes": { + "POSITION": 88, + "NORMAL": 89, + "TEXCOORD_0": 90 + }, + "indices": 91, + "material": 0 + }, + { + "attributes": { + "POSITION": 92, + "NORMAL": 93, + "TEXCOORD_0": 94 + }, + "indices": 95, + "material": 1 + } + ] + }, + { + "name": "Cube.060", + "primitives": [ + { + "attributes": { + "POSITION": 96, + "NORMAL": 97, + "TEXCOORD_0": 98 + }, + "indices": 99, + "material": 0 + }, + { + "attributes": { + "POSITION": 100, + "NORMAL": 101, + "TEXCOORD_0": 102 + }, + "indices": 103, + "material": 1 + } + ] + }, + { + "name": "Cube.061", + "primitives": [ + { + "attributes": { + "POSITION": 104, + "NORMAL": 105, + "TEXCOORD_0": 106 + }, + "indices": 107, + "material": 0 + }, + { + "attributes": { + "POSITION": 108, + "NORMAL": 109, + "TEXCOORD_0": 110 + }, + "indices": 111, + "material": 1 + } + ] + }, + { + "name": "Cube.062", + "primitives": [ + { + "attributes": { + "POSITION": 112, + "NORMAL": 113, + "TEXCOORD_0": 114 + }, + "indices": 115, + "material": 0 + }, + { + "attributes": { + "POSITION": 116, + "NORMAL": 117, + "TEXCOORD_0": 118 + }, + "indices": 119, + "material": 1 + } + ] + }, + { + "name": "Cube.063", + "primitives": [ + { + "attributes": { + "POSITION": 120, + "NORMAL": 121, + "TEXCOORD_0": 122 + }, + "indices": 123, + "material": 0 + }, + { + "attributes": { + "POSITION": 124, + "NORMAL": 125, + "TEXCOORD_0": 126 + }, + "indices": 127, + "material": 1 + } + ] + }, + { + "name": "Cube.064", + "primitives": [ + { + "attributes": { + "POSITION": 128, + "NORMAL": 129, + "TEXCOORD_0": 130 + }, + "indices": 131, + "material": 0 + }, + { + "attributes": { + "POSITION": 132, + "NORMAL": 133, + "TEXCOORD_0": 134 + }, + "indices": 135, + "material": 1 + } + ] + }, + { + "name": "Cube.065", + "primitives": [ + { + "attributes": { + "POSITION": 136, + "NORMAL": 137, + "TEXCOORD_0": 138 + }, + "indices": 139, + "material": 0 + }, + { + "attributes": { + "POSITION": 140, + "NORMAL": 141, + "TEXCOORD_0": 142 + }, + "indices": 143, + "material": 1 + } + ] + }, + { + "name": "Cube.066", + "primitives": [ + { + "attributes": { + "POSITION": 144, + "NORMAL": 145, + "TEXCOORD_0": 146 + }, + "indices": 147, + "material": 0 + }, + { + "attributes": { + "POSITION": 148, + "NORMAL": 149, + "TEXCOORD_0": 150 + }, + "indices": 151, + "material": 1 + } + ] + }, + { + "name": "Cube.067", + "primitives": [ + { + "attributes": { + "POSITION": 152, + "NORMAL": 153, + "TEXCOORD_0": 154 + }, + "indices": 155, + "material": 0 + }, + { + "attributes": { + "POSITION": 156, + "NORMAL": 157, + "TEXCOORD_0": 158 + }, + "indices": 159, + "material": 1 + } + ] + } + ], + "textures": [ + { + "sampler": 0, + "source": 0 + }, + { + "sampler": 0, + "source": 1 + }, + { + "sampler": 0, + "source": 2 + }, + { + "sampler": 0, + "source": 3 + }, + { + "sampler": 0, + "source": 4 + }, + { + "sampler": 0, + "source": 5 + } + ], + "images": [ + { + "mimeType": "image/jpeg", + "name": "book_encyclopedia_set_01_cover_nor_gl", + "uri": "textures/book_encyclopedia_set_01_cover_nor_gl_2k.jpg" + }, + { + "mimeType": "image/jpeg", + "name": "book_encyclopedia_set_01_cover_diff", + "uri": "textures/book_encyclopedia_set_01_cover_diff_2k.jpg" + }, + { + "mimeType": "image/jpeg", + "name": "book_encyclopedia_set_01_cover_metallic-book_encyclopedia_set_01_cover_roughness", + "uri": "textures/book_encyclopedia_set_01_cover_arm_2k.jpg" + }, + { + "mimeType": "image/jpeg", + "name": "book_encyclopedia_set_01_paper_nor_gl", + "uri": "textures/book_encyclopedia_set_01_paper_nor_gl_2k.jpg" + }, + { + "mimeType": "image/jpeg", + "name": "book_encyclopedia_set_01_paper_diff", + "uri": "textures/book_encyclopedia_set_01_paper_diff_2k.jpg" + }, + { + "mimeType": "image/jpeg", + "name": "book_encyclopedia_set_01_paper_roughness", + "uri": "textures/book_encyclopedia_set_01_paper_roughness_2k.jpg" + } + ], + "accessors": [ + { + "bufferView": 0, + "componentType": 5126, + "count": 1368, + "max": [ + 0.01937238499522209, + 0.23741817474365234, + 0 + ], + "min": [ + -0.019316473975777626, + 0, + -0.16306231915950775 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "componentType": 5126, + "count": 1368, + "type": "VEC3" + }, + { + "bufferView": 2, + "componentType": 5126, + "count": 1368, + "type": "VEC2" + }, + { + "bufferView": 3, + "componentType": 5123, + "count": 6780, + "type": "SCALAR" + }, + { + "bufferView": 4, + "componentType": 5126, + "count": 2013, + "max": [ + 0.016494140028953552, + 0.23354820907115936, + -0.0009089797385968268 + ], + "min": [ + -0.016401464119553566, + 0.006047448143362999, + -0.15942445397377014 + ], + "type": "VEC3" + }, + { + "bufferView": 5, + "componentType": 5126, + "count": 2013, + "type": "VEC3" + }, + { + "bufferView": 6, + "componentType": 5126, + "count": 2013, + "type": "VEC2" + }, + { + "bufferView": 7, + "componentType": 5123, + "count": 3396, + "type": "SCALAR" + }, + { + "bufferView": 8, + "componentType": 5126, + "count": 1368, + "max": [ + 0.01416129618883133, + 0.23741817474365234, + 0 + ], + "min": [ + -0.01426942739635706, + 0, + -0.16306231915950775 + ], + "type": "VEC3" + }, + { + "bufferView": 9, + "componentType": 5126, + "count": 1368, + "type": "VEC3" + }, + { + "bufferView": 10, + "componentType": 5126, + "count": 1368, + "type": "VEC2" + }, + { + "bufferView": 11, + "componentType": 5123, + "count": 6780, + "type": "SCALAR" + }, + { + "bufferView": 12, + "componentType": 5126, + "count": 2055, + "max": [ + 0.011517160572111607, + 0.2335481494665146, + -0.0009090033709071577 + ], + "min": [ + -0.011835918761789799, + 0.006047489587217569, + -0.15942440927028656 + ], + "type": "VEC3" + }, + { + "bufferView": 13, + "componentType": 5126, + "count": 2055, + "type": "VEC3" + }, + { + "bufferView": 14, + "componentType": 5126, + "count": 2055, + "type": "VEC2" + }, + { + "bufferView": 15, + "componentType": 5123, + "count": 3312, + "type": "SCALAR" + }, + { + "bufferView": 16, + "componentType": 5126, + "count": 1372, + "max": [ + 0.011407114565372467, + 0.23741817474365234, + 0 + ], + "min": [ + -0.011390010826289654, + 0, + -0.16306231915950775 + ], + "type": "VEC3" + }, + { + "bufferView": 17, + "componentType": 5126, + "count": 1372, + "type": "VEC3" + }, + { + "bufferView": 18, + "componentType": 5126, + "count": 1372, + "type": "VEC2" + }, + { + "bufferView": 19, + "componentType": 5123, + "count": 6780, + "type": "SCALAR" + }, + { + "bufferView": 20, + "componentType": 5126, + "count": 2026, + "max": [ + 0.008541706018149853, + 0.2335481494665146, + -0.0009089915547519922 + ], + "min": [ + -0.0085503114387393, + 0.006047489587217569, + -0.15942440927028656 + ], + "type": "VEC3" + }, + { + "bufferView": 21, + "componentType": 5126, + "count": 2026, + "type": "VEC3" + }, + { + "bufferView": 22, + "componentType": 5126, + "count": 2026, + "type": "VEC2" + }, + { + "bufferView": 23, + "componentType": 5123, + "count": 3312, + "type": "SCALAR" + }, + { + "bufferView": 24, + "componentType": 5126, + "count": 1368, + "max": [ + 0.012318329885601997, + 0.23741817474365234, + 0 + ], + "min": [ + -0.012303679250180721, + 0, + -0.16306231915950775 + ], + "type": "VEC3" + }, + { + "bufferView": 25, + "componentType": 5126, + "count": 1368, + "type": "VEC3" + }, + { + "bufferView": 26, + "componentType": 5126, + "count": 1368, + "type": "VEC2" + }, + { + "bufferView": 27, + "componentType": 5123, + "count": 6780, + "type": "SCALAR" + }, + { + "bufferView": 28, + "componentType": 5126, + "count": 2032, + "max": [ + 0.00962780974805355, + 0.2335481494665146, + -0.0009090033709071577 + ], + "min": [ + -0.009627748280763626, + 0.006047489587217569, + -0.15942440927028656 + ], + "type": "VEC3" + }, + { + "bufferView": 29, + "componentType": 5126, + "count": 2032, + "type": "VEC3" + }, + { + "bufferView": 30, + "componentType": 5126, + "count": 2032, + "type": "VEC2" + }, + { + "bufferView": 31, + "componentType": 5123, + "count": 3312, + "type": "SCALAR" + }, + { + "bufferView": 32, + "componentType": 5126, + "count": 1368, + "max": [ + 0.009569397196173668, + 0.23741817474365234, + 0 + ], + "min": [ + -0.009583080187439919, + 0, + -0.16306231915950775 + ], + "type": "VEC3" + }, + { + "bufferView": 33, + "componentType": 5126, + "count": 1368, + "type": "VEC3" + }, + { + "bufferView": 34, + "componentType": 5126, + "count": 1368, + "type": "VEC2" + }, + { + "bufferView": 35, + "componentType": 5123, + "count": 6774, + "type": "SCALAR" + }, + { + "bufferView": 36, + "componentType": 5126, + "count": 2040, + "max": [ + 0.006689881905913353, + 0.2335481494665146, + -0.0009090033709071577 + ], + "min": [ + -0.0068577490746974945, + 0.006047489587217569, + -0.15942440927028656 + ], + "type": "VEC3" + }, + { + "bufferView": 37, + "componentType": 5126, + "count": 2040, + "type": "VEC3" + }, + { + "bufferView": 38, + "componentType": 5126, + "count": 2040, + "type": "VEC2" + }, + { + "bufferView": 39, + "componentType": 5123, + "count": 3312, + "type": "SCALAR" + }, + { + "bufferView": 40, + "componentType": 5126, + "count": 1368, + "max": [ + 0.009170538745820522, + 0.23741817474365234, + 0 + ], + "min": [ + -0.009224987588822842, + 0, + -0.16306231915950775 + ], + "type": "VEC3" + }, + { + "bufferView": 41, + "componentType": 5126, + "count": 1368, + "type": "VEC3" + }, + { + "bufferView": 42, + "componentType": 5126, + "count": 1368, + "type": "VEC2" + }, + { + "bufferView": 43, + "componentType": 5123, + "count": 6780, + "type": "SCALAR" + }, + { + "bufferView": 44, + "componentType": 5126, + "count": 1930, + "max": [ + 0.006322997156530619, + 0.2335481494665146, + -0.0009090033709071577 + ], + "min": [ + -0.0065722838044166565, + 0.006047477480024099, + -0.15942440927028656 + ], + "type": "VEC3" + }, + { + "bufferView": 45, + "componentType": 5126, + "count": 1930, + "type": "VEC3" + }, + { + "bufferView": 46, + "componentType": 5126, + "count": 1930, + "type": "VEC2" + }, + { + "bufferView": 47, + "componentType": 5123, + "count": 3312, + "type": "SCALAR" + }, + { + "bufferView": 48, + "componentType": 5126, + "count": 1368, + "max": [ + 0.012010203674435616, + 0.23741817474365234, + 0 + ], + "min": [ + -0.012027495540678501, + 0, + -0.16306231915950775 + ], + "type": "VEC3" + }, + { + "bufferView": 49, + "componentType": 5126, + "count": 1368, + "type": "VEC3" + }, + { + "bufferView": 50, + "componentType": 5126, + "count": 1368, + "type": "VEC2" + }, + { + "bufferView": 51, + "componentType": 5123, + "count": 6780, + "type": "SCALAR" + }, + { + "bufferView": 52, + "componentType": 5126, + "count": 1958, + "max": [ + 0.00925163459032774, + 0.2335481494665146, + -0.0009090033709071577 + ], + "min": [ + -0.00931568443775177, + 0.006047477480024099, + -0.15942440927028656 + ], + "type": "VEC3" + }, + { + "bufferView": 53, + "componentType": 5126, + "count": 1958, + "type": "VEC3" + }, + { + "bufferView": 54, + "componentType": 5126, + "count": 1958, + "type": "VEC2" + }, + { + "bufferView": 55, + "componentType": 5123, + "count": 3312, + "type": "SCALAR" + }, + { + "bufferView": 56, + "componentType": 5126, + "count": 1368, + "max": [ + 0.010798434726893902, + 0.23741817474365234, + 0 + ], + "min": [ + -0.010814642533659935, + 0, + -0.16306231915950775 + ], + "type": "VEC3" + }, + { + "bufferView": 57, + "componentType": 5126, + "count": 1368, + "type": "VEC3" + }, + { + "bufferView": 58, + "componentType": 5126, + "count": 1368, + "type": "VEC2" + }, + { + "bufferView": 59, + "componentType": 5123, + "count": 6780, + "type": "SCALAR" + }, + { + "bufferView": 60, + "componentType": 5126, + "count": 1951, + "max": [ + 0.008051929995417595, + 0.2335481494665146, + -0.0009090033709071577 + ], + "min": [ + -0.007959806360304356, + 0.006047477480024099, + -0.15942440927028656 + ], + "type": "VEC3" + }, + { + "bufferView": 61, + "componentType": 5126, + "count": 1951, + "type": "VEC3" + }, + { + "bufferView": 62, + "componentType": 5126, + "count": 1951, + "type": "VEC2" + }, + { + "bufferView": 63, + "componentType": 5123, + "count": 3312, + "type": "SCALAR" + }, + { + "bufferView": 64, + "componentType": 5126, + "count": 1368, + "max": [ + 0.01079279650002718, + 0.23741817474365234, + 0 + ], + "min": [ + -0.010820280760526657, + 0, + -0.16306231915950775 + ], + "type": "VEC3" + }, + { + "bufferView": 65, + "componentType": 5126, + "count": 1368, + "type": "VEC3" + }, + { + "bufferView": 66, + "componentType": 5126, + "count": 1368, + "type": "VEC2" + }, + { + "bufferView": 67, + "componentType": 5123, + "count": 6780, + "type": "SCALAR" + }, + { + "bufferView": 68, + "componentType": 5126, + "count": 1954, + "max": [ + 0.00803411565721035, + 0.2335481494665146, + -0.0009090033709071577 + ], + "min": [ + -0.00794385839253664, + 0.006047477480024099, + -0.15942440927028656 + ], + "type": "VEC3" + }, + { + "bufferView": 69, + "componentType": 5126, + "count": 1954, + "type": "VEC3" + }, + { + "bufferView": 70, + "componentType": 5126, + "count": 1954, + "type": "VEC2" + }, + { + "bufferView": 71, + "componentType": 5123, + "count": 3312, + "type": "SCALAR" + }, + { + "bufferView": 72, + "componentType": 5126, + "count": 1368, + "max": [ + 0.01078562531620264, + 0.23741817474365234, + 0 + ], + "min": [ + -0.010820280760526657, + 0, + -0.16306231915950775 + ], + "type": "VEC3" + }, + { + "bufferView": 73, + "componentType": 5126, + "count": 1368, + "type": "VEC3" + }, + { + "bufferView": 74, + "componentType": 5126, + "count": 1368, + "type": "VEC2" + }, + { + "bufferView": 75, + "componentType": 5123, + "count": 6780, + "type": "SCALAR" + }, + { + "bufferView": 76, + "componentType": 5126, + "count": 1929, + "max": [ + 0.007982125505805016, + 0.2335481494665146, + -0.0009089915547519922 + ], + "min": [ + -0.008167654275894165, + 0.006047477480024099, + -0.15942440927028656 + ], + "type": "VEC3" + }, + { + "bufferView": 77, + "componentType": 5126, + "count": 1929, + "type": "VEC3" + }, + { + "bufferView": 78, + "componentType": 5126, + "count": 1929, + "type": "VEC2" + }, + { + "bufferView": 79, + "componentType": 5123, + "count": 3312, + "type": "SCALAR" + }, + { + "bufferView": 80, + "componentType": 5126, + "count": 1368, + "max": [ + 0.008958311751484871, + 0.23741817474365234, + 0 + ], + "min": [ + -0.008976759389042854, + 0, + -0.16306231915950775 + ], + "type": "VEC3" + }, + { + "bufferView": 81, + "componentType": 5126, + "count": 1368, + "type": "VEC3" + }, + { + "bufferView": 82, + "componentType": 5126, + "count": 1368, + "type": "VEC2" + }, + { + "bufferView": 83, + "componentType": 5123, + "count": 6780, + "type": "SCALAR" + }, + { + "bufferView": 84, + "componentType": 5126, + "count": 1912, + "max": [ + 0.006090897601097822, + 0.2335481494665146, + -0.0009089915547519922 + ], + "min": [ + -0.006357812788337469, + 0.006047477480024099, + -0.15942440927028656 + ], + "type": "VEC3" + }, + { + "bufferView": 85, + "componentType": 5126, + "count": 1912, + "type": "VEC3" + }, + { + "bufferView": 86, + "componentType": 5126, + "count": 1912, + "type": "VEC2" + }, + { + "bufferView": 87, + "componentType": 5123, + "count": 3312, + "type": "SCALAR" + }, + { + "bufferView": 88, + "componentType": 5126, + "count": 1368, + "max": [ + 0.011360734701156616, + 0.23741817474365234, + 0 + ], + "min": [ + -0.01139145065099001, + 0, + -0.16306231915950775 + ], + "type": "VEC3" + }, + { + "bufferView": 89, + "componentType": 5126, + "count": 1368, + "type": "VEC3" + }, + { + "bufferView": 90, + "componentType": 5126, + "count": 1368, + "type": "VEC2" + }, + { + "bufferView": 91, + "componentType": 5123, + "count": 6780, + "type": "SCALAR" + }, + { + "bufferView": 92, + "componentType": 5126, + "count": 2058, + "max": [ + 0.008506884798407555, + 0.2335481494665146, + -0.0009089915547519922 + ], + "min": [ + -0.008802840486168861, + 0.006047489587217569, + -0.15942440927028656 + ], + "type": "VEC3" + }, + { + "bufferView": 93, + "componentType": 5126, + "count": 2058, + "type": "VEC3" + }, + { + "bufferView": 94, + "componentType": 5126, + "count": 2058, + "type": "VEC2" + }, + { + "bufferView": 95, + "componentType": 5123, + "count": 3312, + "type": "SCALAR" + }, + { + "bufferView": 96, + "componentType": 5126, + "count": 1368, + "max": [ + 0.018301209434866905, + 0.23741817474365234, + 0 + ], + "min": [ + -0.018250109627842903, + 0, + -0.16306231915950775 + ], + "type": "VEC3" + }, + { + "bufferView": 97, + "componentType": 5126, + "count": 1368, + "type": "VEC3" + }, + { + "bufferView": 98, + "componentType": 5126, + "count": 1368, + "type": "VEC2" + }, + { + "bufferView": 99, + "componentType": 5123, + "count": 6780, + "type": "SCALAR" + }, + { + "bufferView": 100, + "componentType": 5126, + "count": 2009, + "max": [ + 0.015585752204060555, + 0.2335481494665146, + -0.0009089915547519922 + ], + "min": [ + -0.015735484659671783, + 0.006047489587217569, + -0.15942440927028656 + ], + "type": "VEC3" + }, + { + "bufferView": 101, + "componentType": 5126, + "count": 2009, + "type": "VEC3" + }, + { + "bufferView": 102, + "componentType": 5126, + "count": 2009, + "type": "VEC2" + }, + { + "bufferView": 103, + "componentType": 5123, + "count": 3312, + "type": "SCALAR" + }, + { + "bufferView": 104, + "componentType": 5126, + "count": 1368, + "max": [ + 0.016351904720067978, + 0.23741817474365234, + 0 + ], + "min": [ + -0.01628226228058338, + 0, + -0.16306231915950775 + ], + "type": "VEC3" + }, + { + "bufferView": 105, + "componentType": 5126, + "count": 1368, + "type": "VEC3" + }, + { + "bufferView": 106, + "componentType": 5126, + "count": 1368, + "type": "VEC2" + }, + { + "bufferView": 107, + "componentType": 5123, + "count": 6780, + "type": "SCALAR" + }, + { + "bufferView": 108, + "componentType": 5126, + "count": 2020, + "max": [ + 0.013619603589177132, + 0.2335481494665146, + -0.0009090033709071577 + ], + "min": [ + -0.013788290321826935, + 0.006047489587217569, + -0.15942440927028656 + ], + "type": "VEC3" + }, + { + "bufferView": 109, + "componentType": 5126, + "count": 2020, + "type": "VEC3" + }, + { + "bufferView": 110, + "componentType": 5126, + "count": 2020, + "type": "VEC2" + }, + { + "bufferView": 111, + "componentType": 5123, + "count": 3312, + "type": "SCALAR" + }, + { + "bufferView": 112, + "componentType": 5126, + "count": 1368, + "max": [ + 0.01766282692551613, + 0.23741817474365234, + 0 + ], + "min": [ + -0.017644047737121582, + 0, + -0.16306231915950775 + ], + "type": "VEC3" + }, + { + "bufferView": 113, + "componentType": 5126, + "count": 1368, + "type": "VEC3" + }, + { + "bufferView": 114, + "componentType": 5126, + "count": 1368, + "type": "VEC2" + }, + { + "bufferView": 115, + "componentType": 5123, + "count": 6780, + "type": "SCALAR" + }, + { + "bufferView": 116, + "componentType": 5126, + "count": 2030, + "max": [ + 0.014881071634590626, + 0.2335481494665146, + -0.0009089915547519922 + ], + "min": [ + -0.015422468073666096, + 0.006047489587217569, + -0.15942440927028656 + ], + "type": "VEC3" + }, + { + "bufferView": 117, + "componentType": 5126, + "count": 2030, + "type": "VEC3" + }, + { + "bufferView": 118, + "componentType": 5126, + "count": 2030, + "type": "VEC2" + }, + { + "bufferView": 119, + "componentType": 5123, + "count": 3312, + "type": "SCALAR" + }, + { + "bufferView": 120, + "componentType": 5126, + "count": 1368, + "max": [ + 0.012361902743577957, + 0.23741814494132996, + 0 + ], + "min": [ + -0.01231264416128397, + -1.1795664001112982e-8, + -0.16306231915950775 + ], + "type": "VEC3" + }, + { + "bufferView": 121, + "componentType": 5126, + "count": 1368, + "type": "VEC3" + }, + { + "bufferView": 122, + "componentType": 5126, + "count": 1368, + "type": "VEC2" + }, + { + "bufferView": 123, + "componentType": 5123, + "count": 6780, + "type": "SCALAR" + }, + { + "bufferView": 124, + "componentType": 5126, + "count": 1959, + "max": [ + 0.009735752828419209, + 0.2335481494665146, + -0.0009089915547519922 + ], + "min": [ + -0.009593134745955467, + 0.006047477480024099, + -0.15942440927028656 + ], + "type": "VEC3" + }, + { + "bufferView": 125, + "componentType": 5126, + "count": 1959, + "type": "VEC3" + }, + { + "bufferView": 126, + "componentType": 5126, + "count": 1959, + "type": "VEC2" + }, + { + "bufferView": 127, + "componentType": 5123, + "count": 3312, + "type": "SCALAR" + }, + { + "bufferView": 128, + "componentType": 5126, + "count": 1368, + "max": [ + 0.017824852839112282, + 0.23741814494132996, + 0 + ], + "min": [ + -0.017821267247200012, + -1.1795664001112982e-8, + -0.16306231915950775 + ], + "type": "VEC3" + }, + { + "bufferView": 129, + "componentType": 5126, + "count": 1368, + "type": "VEC3" + }, + { + "bufferView": 130, + "componentType": 5126, + "count": 1368, + "type": "VEC2" + }, + { + "bufferView": 131, + "componentType": 5123, + "count": 6780, + "type": "SCALAR" + }, + { + "bufferView": 132, + "componentType": 5126, + "count": 1927, + "max": [ + 0.015137162059545517, + 0.2335481494665146, + -0.0009089915547519922 + ], + "min": [ + -0.015397505834698677, + 0.006047477480024099, + -0.15942440927028656 + ], + "type": "VEC3" + }, + { + "bufferView": 133, + "componentType": 5126, + "count": 1927, + "type": "VEC3" + }, + { + "bufferView": 134, + "componentType": 5126, + "count": 1927, + "type": "VEC2" + }, + { + "bufferView": 135, + "componentType": 5123, + "count": 3312, + "type": "SCALAR" + }, + { + "bufferView": 136, + "componentType": 5126, + "count": 1368, + "max": [ + 0.010910894721746445, + 0.23741814494132996, + 0 + ], + "min": [ + -0.01090452540665865, + -1.1795664001112982e-8, + -0.16306231915950775 + ], + "type": "VEC3" + }, + { + "bufferView": 137, + "componentType": 5126, + "count": 1368, + "type": "VEC3" + }, + { + "bufferView": 138, + "componentType": 5126, + "count": 1368, + "type": "VEC2" + }, + { + "bufferView": 139, + "componentType": 5123, + "count": 6780, + "type": "SCALAR" + }, + { + "bufferView": 140, + "componentType": 5126, + "count": 1949, + "max": [ + 0.008175608702003956, + 0.2335481494665146, + -0.0009090033709071577 + ], + "min": [ + -0.00838317722082138, + 0.006047477480024099, + -0.15942440927028656 + ], + "type": "VEC3" + }, + { + "bufferView": 141, + "componentType": 5126, + "count": 1949, + "type": "VEC3" + }, + { + "bufferView": 142, + "componentType": 5126, + "count": 1949, + "type": "VEC2" + }, + { + "bufferView": 143, + "componentType": 5123, + "count": 3312, + "type": "SCALAR" + }, + { + "bufferView": 144, + "componentType": 5126, + "count": 1368, + "max": [ + 0.0095955366268754, + 0.23741814494132996, + 0 + ], + "min": [ + -0.00960686057806015, + -1.1795664001112982e-8, + -0.16306231915950775 + ], + "type": "VEC3" + }, + { + "bufferView": 145, + "componentType": 5126, + "count": 1368, + "type": "VEC3" + }, + { + "bufferView": 146, + "componentType": 5126, + "count": 1368, + "type": "VEC2" + }, + { + "bufferView": 147, + "componentType": 5123, + "count": 6780, + "type": "SCALAR" + }, + { + "bufferView": 148, + "componentType": 5126, + "count": 1940, + "max": [ + 0.0067734322510659695, + 0.2335481494665146, + -0.0009090033709071577 + ], + "min": [ + -0.007032106630504131, + 0.006047477480024099, + -0.15942440927028656 + ], + "type": "VEC3" + }, + { + "bufferView": 149, + "componentType": 5126, + "count": 1940, + "type": "VEC3" + }, + { + "bufferView": 150, + "componentType": 5126, + "count": 1940, + "type": "VEC2" + }, + { + "bufferView": 151, + "componentType": 5123, + "count": 3312, + "type": "SCALAR" + }, + { + "bufferView": 152, + "componentType": 5126, + "count": 1368, + "max": [ + 0.011898239143192768, + 0.23741814494132996, + 0 + ], + "min": [ + -0.011888095177710056, + -1.1795664001112982e-8, + -0.16306231915950775 + ], + "type": "VEC3" + }, + { + "bufferView": 153, + "componentType": 5126, + "count": 1368, + "type": "VEC3" + }, + { + "bufferView": 154, + "componentType": 5126, + "count": 1368, + "type": "VEC2" + }, + { + "bufferView": 155, + "componentType": 5123, + "count": 6780, + "type": "SCALAR" + }, + { + "bufferView": 156, + "componentType": 5126, + "count": 1947, + "max": [ + 0.009206227958202362, + 0.2335481494665146, + -0.0009090033709071577 + ], + "min": [ + -0.009144631214439869, + 0.006047477480024099, + -0.15942440927028656 + ], + "type": "VEC3" + }, + { + "bufferView": 157, + "componentType": 5126, + "count": 1947, + "type": "VEC3" + }, + { + "bufferView": 158, + "componentType": 5126, + "count": 1947, + "type": "VEC2" + }, + { + "bufferView": 159, + "componentType": 5123, + "count": 3312, + "type": "SCALAR" + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 0 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 16416 + }, + { + "buffer": 0, + "byteLength": 10944, + "byteOffset": 32832 + }, + { + "buffer": 0, + "byteLength": 13560, + "byteOffset": 43776 + }, + { + "buffer": 0, + "byteLength": 24156, + "byteOffset": 57336 + }, + { + "buffer": 0, + "byteLength": 24156, + "byteOffset": 81492 + }, + { + "buffer": 0, + "byteLength": 16104, + "byteOffset": 105648 + }, + { + "buffer": 0, + "byteLength": 6792, + "byteOffset": 121752 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 128544 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 144960 + }, + { + "buffer": 0, + "byteLength": 10944, + "byteOffset": 161376 + }, + { + "buffer": 0, + "byteLength": 13560, + "byteOffset": 172320 + }, + { + "buffer": 0, + "byteLength": 24660, + "byteOffset": 185880 + }, + { + "buffer": 0, + "byteLength": 24660, + "byteOffset": 210540 + }, + { + "buffer": 0, + "byteLength": 16440, + "byteOffset": 235200 + }, + { + "buffer": 0, + "byteLength": 6624, + "byteOffset": 251640 + }, + { + "buffer": 0, + "byteLength": 16464, + "byteOffset": 258264 + }, + { + "buffer": 0, + "byteLength": 16464, + "byteOffset": 274728 + }, + { + "buffer": 0, + "byteLength": 10976, + "byteOffset": 291192 + }, + { + "buffer": 0, + "byteLength": 13560, + "byteOffset": 302168 + }, + { + "buffer": 0, + "byteLength": 24312, + "byteOffset": 315728 + }, + { + "buffer": 0, + "byteLength": 24312, + "byteOffset": 340040 + }, + { + "buffer": 0, + "byteLength": 16208, + "byteOffset": 364352 + }, + { + "buffer": 0, + "byteLength": 6624, + "byteOffset": 380560 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 387184 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 403600 + }, + { + "buffer": 0, + "byteLength": 10944, + "byteOffset": 420016 + }, + { + "buffer": 0, + "byteLength": 13560, + "byteOffset": 430960 + }, + { + "buffer": 0, + "byteLength": 24384, + "byteOffset": 444520 + }, + { + "buffer": 0, + "byteLength": 24384, + "byteOffset": 468904 + }, + { + "buffer": 0, + "byteLength": 16256, + "byteOffset": 493288 + }, + { + "buffer": 0, + "byteLength": 6624, + "byteOffset": 509544 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 516168 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 532584 + }, + { + "buffer": 0, + "byteLength": 10944, + "byteOffset": 549000 + }, + { + "buffer": 0, + "byteLength": 13548, + "byteOffset": 559944 + }, + { + "buffer": 0, + "byteLength": 24480, + "byteOffset": 573492 + }, + { + "buffer": 0, + "byteLength": 24480, + "byteOffset": 597972 + }, + { + "buffer": 0, + "byteLength": 16320, + "byteOffset": 622452 + }, + { + "buffer": 0, + "byteLength": 6624, + "byteOffset": 638772 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 645396 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 661812 + }, + { + "buffer": 0, + "byteLength": 10944, + "byteOffset": 678228 + }, + { + "buffer": 0, + "byteLength": 13560, + "byteOffset": 689172 + }, + { + "buffer": 0, + "byteLength": 23160, + "byteOffset": 702732 + }, + { + "buffer": 0, + "byteLength": 23160, + "byteOffset": 725892 + }, + { + "buffer": 0, + "byteLength": 15440, + "byteOffset": 749052 + }, + { + "buffer": 0, + "byteLength": 6624, + "byteOffset": 764492 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 771116 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 787532 + }, + { + "buffer": 0, + "byteLength": 10944, + "byteOffset": 803948 + }, + { + "buffer": 0, + "byteLength": 13560, + "byteOffset": 814892 + }, + { + "buffer": 0, + "byteLength": 23496, + "byteOffset": 828452 + }, + { + "buffer": 0, + "byteLength": 23496, + "byteOffset": 851948 + }, + { + "buffer": 0, + "byteLength": 15664, + "byteOffset": 875444 + }, + { + "buffer": 0, + "byteLength": 6624, + "byteOffset": 891108 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 897732 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 914148 + }, + { + "buffer": 0, + "byteLength": 10944, + "byteOffset": 930564 + }, + { + "buffer": 0, + "byteLength": 13560, + "byteOffset": 941508 + }, + { + "buffer": 0, + "byteLength": 23412, + "byteOffset": 955068 + }, + { + "buffer": 0, + "byteLength": 23412, + "byteOffset": 978480 + }, + { + "buffer": 0, + "byteLength": 15608, + "byteOffset": 1001892 + }, + { + "buffer": 0, + "byteLength": 6624, + "byteOffset": 1017500 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 1024124 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 1040540 + }, + { + "buffer": 0, + "byteLength": 10944, + "byteOffset": 1056956 + }, + { + "buffer": 0, + "byteLength": 13560, + "byteOffset": 1067900 + }, + { + "buffer": 0, + "byteLength": 23448, + "byteOffset": 1081460 + }, + { + "buffer": 0, + "byteLength": 23448, + "byteOffset": 1104908 + }, + { + "buffer": 0, + "byteLength": 15632, + "byteOffset": 1128356 + }, + { + "buffer": 0, + "byteLength": 6624, + "byteOffset": 1143988 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 1150612 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 1167028 + }, + { + "buffer": 0, + "byteLength": 10944, + "byteOffset": 1183444 + }, + { + "buffer": 0, + "byteLength": 13560, + "byteOffset": 1194388 + }, + { + "buffer": 0, + "byteLength": 23148, + "byteOffset": 1207948 + }, + { + "buffer": 0, + "byteLength": 23148, + "byteOffset": 1231096 + }, + { + "buffer": 0, + "byteLength": 15432, + "byteOffset": 1254244 + }, + { + "buffer": 0, + "byteLength": 6624, + "byteOffset": 1269676 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 1276300 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 1292716 + }, + { + "buffer": 0, + "byteLength": 10944, + "byteOffset": 1309132 + }, + { + "buffer": 0, + "byteLength": 13560, + "byteOffset": 1320076 + }, + { + "buffer": 0, + "byteLength": 22944, + "byteOffset": 1333636 + }, + { + "buffer": 0, + "byteLength": 22944, + "byteOffset": 1356580 + }, + { + "buffer": 0, + "byteLength": 15296, + "byteOffset": 1379524 + }, + { + "buffer": 0, + "byteLength": 6624, + "byteOffset": 1394820 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 1401444 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 1417860 + }, + { + "buffer": 0, + "byteLength": 10944, + "byteOffset": 1434276 + }, + { + "buffer": 0, + "byteLength": 13560, + "byteOffset": 1445220 + }, + { + "buffer": 0, + "byteLength": 24696, + "byteOffset": 1458780 + }, + { + "buffer": 0, + "byteLength": 24696, + "byteOffset": 1483476 + }, + { + "buffer": 0, + "byteLength": 16464, + "byteOffset": 1508172 + }, + { + "buffer": 0, + "byteLength": 6624, + "byteOffset": 1524636 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 1531260 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 1547676 + }, + { + "buffer": 0, + "byteLength": 10944, + "byteOffset": 1564092 + }, + { + "buffer": 0, + "byteLength": 13560, + "byteOffset": 1575036 + }, + { + "buffer": 0, + "byteLength": 24108, + "byteOffset": 1588596 + }, + { + "buffer": 0, + "byteLength": 24108, + "byteOffset": 1612704 + }, + { + "buffer": 0, + "byteLength": 16072, + "byteOffset": 1636812 + }, + { + "buffer": 0, + "byteLength": 6624, + "byteOffset": 1652884 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 1659508 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 1675924 + }, + { + "buffer": 0, + "byteLength": 10944, + "byteOffset": 1692340 + }, + { + "buffer": 0, + "byteLength": 13560, + "byteOffset": 1703284 + }, + { + "buffer": 0, + "byteLength": 24240, + "byteOffset": 1716844 + }, + { + "buffer": 0, + "byteLength": 24240, + "byteOffset": 1741084 + }, + { + "buffer": 0, + "byteLength": 16160, + "byteOffset": 1765324 + }, + { + "buffer": 0, + "byteLength": 6624, + "byteOffset": 1781484 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 1788108 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 1804524 + }, + { + "buffer": 0, + "byteLength": 10944, + "byteOffset": 1820940 + }, + { + "buffer": 0, + "byteLength": 13560, + "byteOffset": 1831884 + }, + { + "buffer": 0, + "byteLength": 24360, + "byteOffset": 1845444 + }, + { + "buffer": 0, + "byteLength": 24360, + "byteOffset": 1869804 + }, + { + "buffer": 0, + "byteLength": 16240, + "byteOffset": 1894164 + }, + { + "buffer": 0, + "byteLength": 6624, + "byteOffset": 1910404 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 1917028 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 1933444 + }, + { + "buffer": 0, + "byteLength": 10944, + "byteOffset": 1949860 + }, + { + "buffer": 0, + "byteLength": 13560, + "byteOffset": 1960804 + }, + { + "buffer": 0, + "byteLength": 23508, + "byteOffset": 1974364 + }, + { + "buffer": 0, + "byteLength": 23508, + "byteOffset": 1997872 + }, + { + "buffer": 0, + "byteLength": 15672, + "byteOffset": 2021380 + }, + { + "buffer": 0, + "byteLength": 6624, + "byteOffset": 2037052 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 2043676 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 2060092 + }, + { + "buffer": 0, + "byteLength": 10944, + "byteOffset": 2076508 + }, + { + "buffer": 0, + "byteLength": 13560, + "byteOffset": 2087452 + }, + { + "buffer": 0, + "byteLength": 23124, + "byteOffset": 2101012 + }, + { + "buffer": 0, + "byteLength": 23124, + "byteOffset": 2124136 + }, + { + "buffer": 0, + "byteLength": 15416, + "byteOffset": 2147260 + }, + { + "buffer": 0, + "byteLength": 6624, + "byteOffset": 2162676 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 2169300 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 2185716 + }, + { + "buffer": 0, + "byteLength": 10944, + "byteOffset": 2202132 + }, + { + "buffer": 0, + "byteLength": 13560, + "byteOffset": 2213076 + }, + { + "buffer": 0, + "byteLength": 23388, + "byteOffset": 2226636 + }, + { + "buffer": 0, + "byteLength": 23388, + "byteOffset": 2250024 + }, + { + "buffer": 0, + "byteLength": 15592, + "byteOffset": 2273412 + }, + { + "buffer": 0, + "byteLength": 6624, + "byteOffset": 2289004 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 2295628 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 2312044 + }, + { + "buffer": 0, + "byteLength": 10944, + "byteOffset": 2328460 + }, + { + "buffer": 0, + "byteLength": 13560, + "byteOffset": 2339404 + }, + { + "buffer": 0, + "byteLength": 23280, + "byteOffset": 2352964 + }, + { + "buffer": 0, + "byteLength": 23280, + "byteOffset": 2376244 + }, + { + "buffer": 0, + "byteLength": 15520, + "byteOffset": 2399524 + }, + { + "buffer": 0, + "byteLength": 6624, + "byteOffset": 2415044 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 2421668 + }, + { + "buffer": 0, + "byteLength": 16416, + "byteOffset": 2438084 + }, + { + "buffer": 0, + "byteLength": 10944, + "byteOffset": 2454500 + }, + { + "buffer": 0, + "byteLength": 13560, + "byteOffset": 2465444 + }, + { + "buffer": 0, + "byteLength": 23364, + "byteOffset": 2479004 + }, + { + "buffer": 0, + "byteLength": 23364, + "byteOffset": 2502368 + }, + { + "buffer": 0, + "byteLength": 15576, + "byteOffset": 2525732 + }, + { + "buffer": 0, + "byteLength": 6624, + "byteOffset": 2541308 + } + ], + "samplers": [ + { + "magFilter": 9729, + "minFilter": 9987 + } + ], + "buffers": [ + { + "byteLength": 2547932, + "uri": "book_encyclopedia_set_01.bin" + } + ] +} \ No newline at end of file diff --git a/public/models/polyhaven/book_encyclopedia_set_01/textures/book_encyclopedia_set_01_cover_arm_2k.jpg b/public/models/polyhaven/book_encyclopedia_set_01/textures/book_encyclopedia_set_01_cover_arm_2k.jpg new file mode 100644 index 0000000..f13d0ae Binary files /dev/null and b/public/models/polyhaven/book_encyclopedia_set_01/textures/book_encyclopedia_set_01_cover_arm_2k.jpg differ diff --git a/public/models/polyhaven/book_encyclopedia_set_01/textures/book_encyclopedia_set_01_cover_diff_2k.jpg b/public/models/polyhaven/book_encyclopedia_set_01/textures/book_encyclopedia_set_01_cover_diff_2k.jpg new file mode 100644 index 0000000..b1acd61 Binary files /dev/null and b/public/models/polyhaven/book_encyclopedia_set_01/textures/book_encyclopedia_set_01_cover_diff_2k.jpg differ diff --git a/public/models/polyhaven/book_encyclopedia_set_01/textures/book_encyclopedia_set_01_cover_nor_gl_2k.jpg b/public/models/polyhaven/book_encyclopedia_set_01/textures/book_encyclopedia_set_01_cover_nor_gl_2k.jpg new file mode 100644 index 0000000..b11f314 Binary files /dev/null and b/public/models/polyhaven/book_encyclopedia_set_01/textures/book_encyclopedia_set_01_cover_nor_gl_2k.jpg differ diff --git a/public/models/polyhaven/book_encyclopedia_set_01/textures/book_encyclopedia_set_01_paper_diff_2k.jpg b/public/models/polyhaven/book_encyclopedia_set_01/textures/book_encyclopedia_set_01_paper_diff_2k.jpg new file mode 100644 index 0000000..bf7038f Binary files /dev/null and b/public/models/polyhaven/book_encyclopedia_set_01/textures/book_encyclopedia_set_01_paper_diff_2k.jpg differ diff --git a/public/models/polyhaven/book_encyclopedia_set_01/textures/book_encyclopedia_set_01_paper_nor_gl_2k.jpg b/public/models/polyhaven/book_encyclopedia_set_01/textures/book_encyclopedia_set_01_paper_nor_gl_2k.jpg new file mode 100644 index 0000000..e6025e7 Binary files /dev/null and b/public/models/polyhaven/book_encyclopedia_set_01/textures/book_encyclopedia_set_01_paper_nor_gl_2k.jpg differ diff --git a/public/models/polyhaven/book_encyclopedia_set_01/textures/book_encyclopedia_set_01_paper_roughness_2k.jpg b/public/models/polyhaven/book_encyclopedia_set_01/textures/book_encyclopedia_set_01_paper_roughness_2k.jpg new file mode 100644 index 0000000..8fc9ad5 Binary files /dev/null and b/public/models/polyhaven/book_encyclopedia_set_01/textures/book_encyclopedia_set_01_paper_roughness_2k.jpg differ diff --git a/public/models/rgb-keyboard-mouse/scene-opt.glb b/public/models/rgb-keyboard-mouse/scene-opt.glb new file mode 100644 index 0000000..57baf3a Binary files /dev/null and b/public/models/rgb-keyboard-mouse/scene-opt.glb differ diff --git a/public/phantom-logo.webp b/public/phantom-logo.webp new file mode 100644 index 0000000..1f13a20 Binary files /dev/null and b/public/phantom-logo.webp differ diff --git a/public/poster-preview.html b/public/poster-preview.html new file mode 100644 index 0000000..530c416 --- /dev/null +++ b/public/poster-preview.html @@ -0,0 +1,149 @@ + + + + + +Poster — Francisco Cardenas + + + + + + +
+
+ + + + + +
Portfolio · The Room · 2026
+

+ Francisco + Cardenas +

+

+ Civil Engineering & Construction Management — building toward estimating & project controls. +

+
+ Expected May 2027 + Open to internships & co-ops +
+
+
+
Recovered original poster — open in any browser tab
+ + diff --git a/public/textures/ceiling-color.jpg b/public/textures/ceiling-color.jpg new file mode 100644 index 0000000..54b8d7b Binary files /dev/null and b/public/textures/ceiling-color.jpg differ diff --git a/public/textures/ceiling-normal.jpg b/public/textures/ceiling-normal.jpg new file mode 100644 index 0000000..f1baa32 Binary files /dev/null and b/public/textures/ceiling-normal.jpg differ diff --git a/public/textures/ceiling-roughness.jpg b/public/textures/ceiling-roughness.jpg new file mode 100644 index 0000000..fbcd590 Binary files /dev/null and b/public/textures/ceiling-roughness.jpg differ diff --git a/public/textures/env-kloofendal-1k.hdr b/public/textures/env-kloofendal-1k.hdr new file mode 100644 index 0000000..73133fa Binary files /dev/null and b/public/textures/env-kloofendal-1k.hdr differ diff --git a/public/textures/floor-color.jpg b/public/textures/floor-color.jpg new file mode 100644 index 0000000..31fe877 Binary files /dev/null and b/public/textures/floor-color.jpg differ diff --git a/public/textures/floor-normal.jpg b/public/textures/floor-normal.jpg new file mode 100644 index 0000000..295d656 Binary files /dev/null and b/public/textures/floor-normal.jpg differ diff --git a/public/textures/floor-roughness.jpg b/public/textures/floor-roughness.jpg new file mode 100644 index 0000000..7c94766 Binary files /dev/null and b/public/textures/floor-roughness.jpg differ diff --git a/public/textures/wall-color.jpg b/public/textures/wall-color.jpg new file mode 100644 index 0000000..3261b04 Binary files /dev/null and b/public/textures/wall-color.jpg differ diff --git a/public/textures/wall-normal.jpg b/public/textures/wall-normal.jpg new file mode 100644 index 0000000..6f8d3a6 Binary files /dev/null and b/public/textures/wall-normal.jpg differ diff --git a/public/textures/wall-roughness.jpg b/public/textures/wall-roughness.jpg new file mode 100644 index 0000000..cf8a880 Binary files /dev/null and b/public/textures/wall-roughness.jpg differ diff --git a/public/textures/window-view.jpg b/public/textures/window-view.jpg new file mode 100644 index 0000000..f14633d Binary files /dev/null and b/public/textures/window-view.jpg differ diff --git a/src/app/globals.css b/src/app/globals.css index ce1973b..f725105 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -2,11 +2,12 @@ /* ===================================================================== Francisco Cardenas — Portfolio - PHASE 1 — Perspective room shell & scroll-to-focus camera (ADR-0002). - One warm, cozy evening scheme (ADR-0004 — themes removed). The room is - a real CSS-3D corner: back wall + side walls + floor + ceiling assembled - under a shared perspective, lit warm. Scrolling glides a fixed camera - between placeholder focus anchors (real objects arrive in Phase 2/3). + The room is real-time 3D (Three.js / react-three-fiber, ADR-0010). This + stylesheet now covers only the HTML overlays that sit ON TOP of the WebGL + canvas — top bar, focus rail, scroll hint, the "read" affordance, the + click-to-read inspect card, and the one-page résumé — plus the one warm, + cozy evening scheme (ADR-0004). All CSS-3D room/wall/object styles were + removed in the pivot; the 3D scene replaces them. ===================================================================== */ :root { @@ -28,29 +29,6 @@ --accent: #e7912f; /* lamp amber — the one warm highlight */ --accent-2: #c9a36a; /* brass / aged-gold secondary */ --shadow: rgba(0, 0, 0, 0.5); - - /* room materials (CSS only — no photo textures, ADR-0004) */ - --wall: #c9b596; /* warm greige paint */ - --wall-lit: #dcc9a8; /* where the lamp hits */ - --wall-shade: #9c8a6e; /* walls in shadow */ - --floor: #6f4d30; /* warm wood */ - --floor-dark: #5d3f27; - --ceil: #564833; /* dim warm ceiling — present, not a void */ - - /* camera rig (driven by JS) */ - --cam-x: 0px; - --cam-y: 0px; - --cam-z: 0px; - --cam-ry: 0deg; - --cam-rx: 0deg; - /* global "dolly back" — one knob that steps EVERY view back for breathing - room (and space to furnish later). More negative = further back/smaller. */ - --pull: -250px; - - /* room dimensions — a larger, deeper room */ - --rw: 1620px; - --rh: 940px; - --rd: 1560px; } * { box-sizing: border-box; margin: 0; padding: 0; } @@ -72,6 +50,22 @@ a { color: inherit; } background-image: url("data:image/svg+xml;utf8,"); } +/* ============ Scene = the WebGL room canvas (full frame, behind the HUD) ============ */ +.scene { + position: fixed; inset: 0; z-index: 0; + background: radial-gradient(140% 120% at 38% 30%, #1c140d 0%, #0c0805 70%, #070402 100%); + opacity: 0; transform: scale(1.045); /* held slightly wide behind the curtain… */ + transition: opacity 1.1s var(--ease), transform 2s var(--ease); +} +body.lit .scene { opacity: 1; } /* fades in early, hidden behind the curtain */ +body.ready .scene { transform: none; } /* …then settles as the curtain lifts (cinematic push-in) */ +.scene canvas { display: block; touch-action: none; outline: none; } +/* evening vignette over the canvas → seats the room in darkness (non-interactive) */ +.scene::after { + content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none; + background: radial-gradient(125% 105% at 42% 38%, transparent 46%, rgba(8, 4, 2, 0.5) 84%, rgba(4, 2, 1, 0.78) 100%); +} + /* ============ Top bar ============ */ .topbar { position: fixed; top: 0; left: 0; right: 0; z-index: 50; @@ -100,155 +94,7 @@ a { color: inherit; } .btn-resume:hover { transform: translateY(-1px); filter: brightness(1.06); } .btn-resume:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; } -/* ============ Stage = the camera's perspective frame ============ */ -.stage { - position: fixed; inset: 0; overflow: hidden; - background: radial-gradient(140% 120% at 38% 30%, #1c140d 0%, #0c0805 70%, #070402 100%); - perspective: 1340px; - /* the eye's x slides per focus (JS drives --po-x) so grazing walls swing to - face us; y stays put. Default frames the back wall. */ - perspective-origin: var(--po-x, 43%) 37%; - cursor: grab; touch-action: none; -} -.stage.dragging { cursor: grabbing; } - -/* the moving camera rig — JS eases these vars between focus anchors */ -.camera { - position: absolute; inset: 0; - transform-style: preserve-3d; - transform: - translateZ(var(--pull, 0px)) /* global dolly-back */ - translate3d(var(--cam-x), var(--cam-y), var(--cam-z)) - rotateX(var(--cam-rx)) rotateY(var(--cam-ry)); - will-change: transform; -} - -/* the room box, centered in the camera frame. - A small base turn (yaw + a touch of pitch) gives a three-quarter "looking into - the corner" view instead of a head-on one-point shot. */ -.room { - position: absolute; left: 50%; top: 50%; - width: var(--rw); height: var(--rh); - transform-style: preserve-3d; - /* base three-quarter turn; JS drives --room-ry per focus so the room can swing - to bring a side wall forward (e.g. the left wall for the education stop). */ - transform: translate(-50%, -50%) rotateY(var(--room-ry, -14deg)) rotateX(4deg); -} - -/* ---- the six surfaces ---- */ -.face { position: absolute; top: 50%; left: 50%; } - -.face--back { - width: var(--rw); height: var(--rh); - margin-left: calc(var(--rw) / -2); margin-top: calc(var(--rh) / -2); - transform: translateZ(calc(var(--rd) / -2)); - background: - radial-gradient(64% 58% at 30% 24%, rgba(255, 196, 116, 0.26), transparent 62%), - linear-gradient(180deg, var(--wall-lit) 0%, var(--wall) 52%, var(--wall-shade) 100%); - box-shadow: inset 0 -70px 90px -36px rgba(0, 0, 0, 0.42); /* shadow pooling toward the floor */ -} - -.face--left { - width: var(--rd); height: var(--rh); - margin-left: calc(var(--rd) / -2); margin-top: calc(var(--rh) / -2); - transform: translateX(calc(var(--rw) / -2)) rotateY(90deg); - /* left(0%) edge = front/near camera, right(100%) edge = back corner → darken the corner */ - background: linear-gradient(90deg, #c5b18f 0%, #b39e7e 60%, var(--wall-shade) 100%); - box-shadow: inset 0 -70px 90px -36px rgba(0, 0, 0, 0.5); -} - -.face--right { - width: var(--rd); height: var(--rh); - margin-left: calc(var(--rd) / -2); margin-top: calc(var(--rh) / -2); - transform: translateX(calc(var(--rw) / 2)) rotateY(-90deg); - /* left(0%) edge = back corner, right(100%) edge = front catching lamp light */ - background: - radial-gradient(70% 80% at 88% 32%, rgba(255, 196, 116, 0.20), transparent 60%), - linear-gradient(90deg, var(--wall-shade) 0%, #bca988 50%, var(--wall-lit) 100%); - box-shadow: inset 0 -70px 90px -36px rgba(0, 0, 0, 0.46); -} - -.face--floor { - width: var(--rw); height: var(--rd); - margin-left: calc(var(--rw) / -2); margin-top: calc(var(--rd) / -2); - transform: translateY(calc(var(--rh) / 2)) rotateX(90deg); - /* top(0%) edge = front/near camera, bottom(100%) edge = far/back at the wall */ - background: - linear-gradient(180deg, transparent 48%, rgba(0, 0, 0, 0.14) 74%, rgba(0, 0, 0, 0.42) 100%), - radial-gradient(56% 46% at 50% 14%, rgba(255, 188, 108, 0.22), transparent 64%), - repeating-linear-gradient(90deg, - var(--floor) 0px, var(--floor) 70px, - var(--floor-dark) 70px, var(--floor-dark) 73px), - var(--floor); - box-shadow: inset 0 0 120px 30px rgba(0, 0, 0, 0.3); -} - -.face--ceil { - width: var(--rw); height: var(--rd); - margin-left: calc(var(--rw) / -2); margin-top: calc(var(--rd) / -2); - transform: translateY(calc(var(--rh) / -2)) rotateX(-90deg); - /* a dim but *present* warm ceiling: lamp light bounces up and pools toward the - lit side, the wall seam catches a faint cornice glow, corners fall into - evening shadow. Reads as a real ceiling instead of a black void. */ - background: - radial-gradient(74% 64% at 42% 60%, rgba(255, 193, 117, 0.15), transparent 66%), - linear-gradient(180deg, #5e5039 0%, var(--ceil) 56%, #4a3e2d 100%); - box-shadow: - inset 0 70px 84px -56px rgba(255, 214, 158, 0.12), /* faint cornice glow at the back-wall seam */ - inset 0 0 120px 30px rgba(0, 0, 0, 0.26); /* gentle corner seating — not black */ -} - -/* ---- placeholder focus anchors (Phase 1 stand-ins for future objects) ---- */ -.anchor { - position: absolute; transform: translate(-50%, -50%) scale(1); - width: 168px; min-height: 88px; padding: 13px 15px; - display: flex; flex-direction: column; gap: 7px; justify-content: center; - border: 1.5px solid var(--line-soft); border-radius: 4px; - background: rgba(18, 12, 8, 0.46); backdrop-filter: blur(1px); - color: var(--ink); text-align: left; - cursor: pointer; -webkit-tap-highlight-color: transparent; - transition: border-color 0.4s var(--ease), box-shadow 0.4s var(--ease), - background 0.4s var(--ease), transform 0.4s var(--ease); -} -.anchor .a-kick { - font-family: var(--r-mono); font-size: 9px; letter-spacing: 0.16em; text-transform: uppercase; - color: var(--muted); -} -.anchor .a-name { font-family: var(--r-display); font-weight: 600; font-size: 18px; line-height: 1.05; } -.anchor .a-tag { - font-family: var(--r-mono); font-size: 9px; letter-spacing: 0.1em; text-transform: uppercase; - color: var(--accent-2); opacity: 0.8; -} -.anchor::after { - content: ""; position: absolute; left: 18px; top: -9px; width: 9px; height: 9px; - border-radius: 50%; background: var(--accent); opacity: 0.42; - box-shadow: 0 0 0 4px rgba(231, 145, 47, 0.12); transition: opacity 0.4s var(--ease); -} -.anchor.is-focus { - border-color: var(--accent); - background: rgba(28, 18, 10, 0.62); - box-shadow: 0 0 0 1px var(--accent), 0 14px 40px -10px rgba(231, 145, 47, 0.45), - 0 0 60px -8px rgba(231, 145, 47, 0.4); - transform: translate(-50%, -50%) scale(1.06); -} -.anchor.is-focus::after { opacity: 1; } -/* floor markers lie on a plane that faces the ceiling → flip them upright for the camera */ -.anchor.on-floor { width: 184px; transform: translate(-50%, -50%) rotate(180deg); } -.anchor.on-floor.is-focus { transform: translate(-50%, -50%) rotate(180deg) scale(1.06); } - -/* warm motes / dust in the lamp light (ambient, very subtle) */ -.stage::before { - content: ""; position: absolute; inset: 0; z-index: 4; pointer-events: none; - background: radial-gradient(40% 36% at 33% 30%, rgba(255, 198, 122, 0.12), transparent 70%); - mix-blend-mode: screen; -} -/* camera vignette → seats the room in evening darkness */ -.stage::after { - content: ""; position: absolute; inset: 0; z-index: 5; pointer-events: none; - background: radial-gradient(125% 105% at 38% 34%, transparent 44%, rgba(8, 4, 2, 0.5) 82%, rgba(4, 2, 1, 0.78) 100%); -} - -/* ============ Focus rail (named anchors, right edge) ============ */ +/* ============ Focus rail (named stops, right edge) ============ */ .focusnav { position: fixed; right: 22px; top: 50%; transform: translateY(-50%); z-index: 46; display: flex; flex-direction: column; gap: 4px; pointer-events: none; @@ -279,8 +125,8 @@ a { color: inherit; } font-family: var(--r-mono); font-size: 10.5px; letter-spacing: 0.16em; text-transform: uppercase; color: var(--muted); display: flex; flex-direction: column; align-items: center; gap: 9px; opacity: 0; transition: opacity 0.6s; } -body.lit .hint { opacity: 1; } -.hint.gone { opacity: 0 !important; pointer-events: none; } +body.ready .hint { opacity: 1; transition-delay: 1s; } /* arrives after the curtain lifts */ +.hint.gone { opacity: 0 !important; pointer-events: none; transition-delay: 0s; } .hint .wheel { width: 22px; height: 34px; border: 1.5px solid var(--line-soft); border-radius: 12px; position: relative; } @@ -290,9 +136,18 @@ body.lit .hint { opacity: 1; } } @keyframes wheel { 0% { opacity: 0; transform: translate(-50%, 0); } 30% { opacity: 1; } 100% { opacity: 0; transform: translate(-50%, 12px); } } -/* intro: fade the whole room up once mounted */ -.camera { opacity: 0; transition: opacity 1.1s var(--ease); } -body.lit .camera { opacity: 1; } +/* ============ "Read" affordance — keyboard-friendly inspect trigger for the focused stop ============ */ +.read-cue { + position: fixed; left: 50%; bottom: 78px; transform: translateX(-50%); z-index: 45; + display: inline-flex; align-items: center; gap: 8px; + font-family: var(--r-mono); font-size: 10.5px; letter-spacing: 0.14em; text-transform: uppercase; + color: #1a120a; background: var(--accent); border: 0; padding: 9px 15px; border-radius: 3px; cursor: pointer; + box-shadow: 0 8px 22px -8px rgba(231, 145, 47, 0.6); + opacity: 0; pointer-events: none; transition: opacity 0.4s var(--ease), transform 0.25s var(--ease), filter 0.2s; +} +body.ready .read-cue { opacity: 0.95; pointer-events: auto; transition-delay: 1s, 0s, 0s; } +.read-cue:hover { transform: translateX(-50%) translateY(-1px); filter: brightness(1.05); } +.read-cue:focus-visible { outline: 2px solid var(--ink); outline-offset: 3px; } /* ============ Résumé / fast-lane view ============ */ .resume { position: fixed; inset: 0; z-index: 80; background: var(--bg); color: var(--ink); overflow-y: auto; opacity: 0; pointer-events: none; transition: opacity 0.45s var(--ease); } @@ -312,16 +167,449 @@ body.lit .camera { opacity: 1; } .resume .r-sec { grid-template-columns: 1fr; gap: 8px; } } +/* ============ Inspect overlay — the click-to-read card ============ + Clicking a focused marker dollies the 3D camera in and fades in this + readable, accessible card with the object's full content (a warm panel + matched to the room). Esc, the Back button, or clicking the dimmed room + closes it. Text lives here as real DOM (crisp + screen-reader friendly). */ +.inspect-layer { position: fixed; inset: 0; z-index: 70; } +.inspect-scrim { + position: absolute; inset: 0; cursor: pointer; + background: radial-gradient(120% 100% at 32% 38%, rgba(8, 4, 2, 0.28), rgba(6, 3, 1, 0.62) 86%); + animation: ins-fade 0.4s var(--ease); +} +.inspect-card { + position: absolute; top: 50%; right: clamp(20px, 5vw, 84px); transform: translateY(-50%); + width: min(440px, 92vw); max-height: 84vh; overflow-y: auto; + padding: 30px 30px 34px; + background: linear-gradient(180deg, #241b13, #1c150e); + border: 1.5px solid var(--line-soft); border-radius: 7px; + box-shadow: 0 30px 80px -20px rgba(0, 0, 0, 0.8), 0 0 0 1px rgba(231, 145, 47, 0.12), + 0 0 80px -20px rgba(231, 145, 47, 0.25); + animation: ins-card 0.45s var(--ease); +} +.inspect-card .inspect-close { + font-family: var(--r-mono); font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase; + border: 1.5px solid var(--line-soft); background: var(--bg-2); color: var(--ink); + padding: 9px 14px; border-radius: 3px; cursor: pointer; margin-bottom: 22px; + transition: border-color 0.2s, transform 0.2s var(--ease); +} +.inspect-card .inspect-close:hover { border-color: var(--accent); transform: translateX(-2px); } +.inspect-card .inspect-close:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } +.inspect-card .ic-kick { + font-family: var(--r-mono); font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; + color: var(--accent); margin-bottom: 10px; +} +.inspect-card .ic-title { + font-family: var(--r-display); font-weight: 700; font-size: 30px; line-height: 1.05; + letter-spacing: -0.01em; margin-bottom: 16px; +} +.inspect-card .ic-body { font-size: 15.5px; line-height: 1.68; color: var(--ink); } +.inspect-card .ic-facts { margin-top: 22px; border-top: 1.5px solid var(--line-soft); } +.inspect-card .ic-fact { + display: grid; grid-template-columns: 96px 1fr; gap: 8px 16px; + padding: 12px 0; border-bottom: 1px solid var(--hair); +} +.inspect-card .ic-fact dt { + font-family: var(--r-mono); font-size: 9.5px; letter-spacing: 0.12em; text-transform: uppercase; + color: var(--muted); padding-top: 2px; +} +.inspect-card .ic-fact dd { font-size: 14px; line-height: 1.5; color: var(--ink); } +/* roles (Experience) */ +.inspect-card .ic-roles { margin-top: 18px; display: flex; flex-direction: column; gap: 16px; } +.inspect-card .ic-role { border-left: 2px solid var(--line-soft); padding-left: 14px; } +.inspect-card .ic-role-head { font-size: 14.5px; line-height: 1.35; color: var(--ink); } +.inspect-card .ic-role-head b { font-family: var(--r-display); font-weight: 600; } +.inspect-card .ic-role-date { + font-family: var(--r-mono); font-size: 10px; letter-spacing: 0.08em; text-transform: uppercase; + color: var(--accent-2); margin-top: 3px; +} +.inspect-card .ic-role-note { font-size: 13px; line-height: 1.55; color: var(--muted); margin-top: 6px; } +/* software (Skills) */ +.inspect-card .ic-soft { margin-top: 18px; display: flex; flex-direction: column; gap: 9px; } +.inspect-card .ic-soft-row { display: grid; grid-template-columns: 116px 1fr; gap: 12px; align-items: baseline; } +.inspect-card .ic-soft-name { font-family: var(--r-display); font-weight: 600; font-size: 13.5px; color: var(--ink); } +.inspect-card .ic-soft-desc { font-size: 12.5px; line-height: 1.45; color: var(--muted); } +/* learning tags */ +.inspect-card .ic-tags { margin-top: 14px; display: flex; flex-wrap: wrap; gap: 7px; } +.inspect-card .ic-tag { + font-family: var(--r-mono); font-size: 10px; letter-spacing: 0.04em; + padding: 4px 9px; border: 1px solid var(--line-soft); border-radius: 3px; color: var(--muted); +} +/* contact links */ +.inspect-card .ic-links { margin-top: 20px; display: flex; flex-direction: column; gap: 9px; } +.inspect-card .ic-links a { + font-family: var(--r-mono); font-size: 12.5px; color: var(--accent); text-decoration: underline; width: max-content; +} +.inspect-card .ic-links a:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; } +.inspect-card .ic-link-note { font-family: var(--r-mono); font-size: 11.5px; color: var(--muted); } +@keyframes ins-fade { from { opacity: 0; } to { opacity: 1; } } +@keyframes ins-card { + from { opacity: 0; transform: translateY(-50%) translateX(18px); } + to { opacity: 1; transform: translateY(-50%) translateX(0); } +} +/* while inspecting, get the room HUD out of the way */ +body.inspecting .focusnav, body.inspecting .hint, body.inspecting .read-cue { opacity: 0 !important; pointer-events: none; } +/* mobile: the card becomes a bottom sheet */ +@media (max-width: 760px) { + .inspect-card { + top: auto; bottom: 14px; right: 14px; left: 14px; transform: none; + width: auto; max-height: 72vh; animation: ins-card-m 0.4s var(--ease); + } + @keyframes ins-card-m { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } } +} + /* ============ responsive (desktop-first per ADR-0004; keep mobile usable) ============ */ @media (max-width: 760px) { .brand .who { display: none; } - .stage { perspective: 940px; perspective-origin: var(--po-x, 46%) 39%; } - :root { --rw: 1180px; --rh: 780px; --rd: 1100px; } .focusnav { right: 12px; gap: 2px; } .focusnav button .fn-label { display: none; } + .read-cue { bottom: 70px; } } @media (prefers-reduced-motion: reduce) { * { animation-duration: 0.001s !important; } - .camera, .anchor, .btn-resume { transition-duration: 0.2s !important; } + .scene, .btn-resume { transition-duration: 0.2s !important; } +} + +/* ============ Loading curtain — the entry title screen (LoadingScreen.tsx) ============ + Hides ALL asset loading behind a warm near-black curtain in the room's own palette. + Sits above every overlay (z 95) incl. the grain (60), so it carries its own grain + + vignette for film continuity. Lift = opacity + soft blur; the scene scale-settles + underneath it (see .scene). */ +.loader { + position: fixed; inset: 0; z-index: 95; display: grid; place-items: center; + background: radial-gradient(120% 100% at 34% 26%, #241a10 0%, #140e08 52%, #0a0603 100%); + transition: opacity 1.15s var(--ease), filter 1.15s var(--ease); +} +.loader.lift { opacity: 0; filter: blur(6px); pointer-events: none; } +.loader::before { /* evening vignette — center glows, corners seat into darkness */ + content: ""; position: absolute; inset: 0; pointer-events: none; + background: radial-gradient(115% 95% at 50% 42%, transparent 40%, rgba(5, 3, 1, 0.55) 88%); +} +.loader::after { /* same film grain sheet as .grain */ + content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0.35; mix-blend-mode: overlay; + background-image: url("data:image/svg+xml;utf8,"); +} + +/* slow-breathing pool of lamplight behind the type — the fan light before the fan */ +.ld-glow { + position: absolute; left: 50%; top: 44%; width: min(72vw, 900px); aspect-ratio: 1.5; + transform: translate(-50%, -50%); filter: blur(30px); + background: radial-gradient(50% 50% at 50% 50%, rgba(231, 145, 47, 0.13), transparent 70%); + animation: ld-breathe 6.5s var(--ease) infinite alternate; +} +@keyframes ld-breathe { + from { opacity: 0.7; transform: translate(-50%, -50%) scale(0.96); } + to { opacity: 1; transform: translate(-50%, -50%) scale(1.05); } +} + +/* floating dust motes, like the room's air caught in the lamplight */ +.ld-dust { position: absolute; inset: 0; pointer-events: none; } /* out of flow — must not push the title stack */ +.ld-dust i { + position: absolute; width: 3px; height: 3px; border-radius: 50%; + background: radial-gradient(circle, rgba(242, 231, 214, 0.8), transparent 70%); + opacity: 0; animation: ld-float 9s linear infinite; +} +.ld-dust i:nth-child(1) { left: 24%; top: 62%; animation-delay: 0s; } +.ld-dust i:nth-child(2) { left: 38%; top: 30%; animation-delay: 1.6s; animation-duration: 11s; } +.ld-dust i:nth-child(3) { left: 52%; top: 72%; animation-delay: 3.1s; } +.ld-dust i:nth-child(4) { left: 64%; top: 26%; animation-delay: 0.9s; animation-duration: 12s; } +.ld-dust i:nth-child(5) { left: 74%; top: 58%; animation-delay: 4.2s; } +.ld-dust i:nth-child(6) { left: 31%; top: 44%; animation-delay: 5.4s; animation-duration: 10s; } +.ld-dust i:nth-child(7) { left: 82%; top: 40%; animation-delay: 2.3s; } +@keyframes ld-float { + 0% { opacity: 0; transform: translateY(12px); } + 12% { opacity: 0.5; } + 85% { opacity: 0.35; } + 100% { opacity: 0; transform: translateY(-46px); } +} + +/* the title stack — staged entrance, same hierarchy as the résumé head */ +.ld-center { + position: relative; display: grid; justify-items: center; text-align: center; padding: 0 24px; + transform: translateY(-4vh); /* optical center sits a touch above geometric center */ +} +.ld-kick { + font-family: var(--r-mono); font-size: 10.5px; letter-spacing: 0.34em; text-transform: uppercase; + color: var(--accent); animation: ld-rise 0.9s var(--ease) both 0.1s; +} +.ld-name { + font-family: var(--r-display); font-weight: 700; font-size: clamp(36px, 6.5vw, 66px); + letter-spacing: -0.03em; line-height: 1; margin-top: 16px; animation: ld-rise 0.9s var(--ease) both 0.22s; +} +.ld-sub { + font-family: var(--r-mono); font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase; + color: var(--muted); margin-top: 15px; animation: ld-rise 0.9s var(--ease) both 0.34s; +} + +/* progress = a hairline that fills with lamp amber; counter in the corner of the line */ +.ld-progress { width: min(420px, 64vw); margin-top: 46px; animation: ld-rise 0.9s var(--ease) both 0.5s; } +.ld-line { height: 1px; background: var(--hair); } +.ld-line span { + display: block; height: 100%; transform-origin: left; transform: scaleX(0); + background: linear-gradient(90deg, var(--accent-2), var(--accent)); + box-shadow: 0 0 12px rgba(231, 145, 47, 0.55); + transition: transform 0.55s var(--ease); +} +.ld-meta { + display: flex; justify-content: space-between; align-items: baseline; margin-top: 12px; + font-family: var(--r-mono); font-size: 10px; letter-spacing: 0.14em; text-transform: uppercase; + color: var(--muted); opacity: 0.85; /* one step quieter than the title stack */ +} +.ld-pct::after { content: "%"; opacity: 0.6; margin-left: 1px; } +@keyframes ld-rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } } + +@media (prefers-reduced-motion: reduce) { + .ld-glow, .ld-dust i { animation: none; } + .ld-dust i { opacity: 0.25; } + .ld-kick, .ld-name, .ld-sub, .ld-progress { animation-duration: 0.01s; } + .loader { transition-duration: 0.4s; } + .scene { transform: none; } +} + +/* ---- the 8-bit dino chase riding the progress line (PixelChase.tsx) ---- + Two-frame run gait: frame groups A/B alternate via opposite-phase keyframes; + a 2px bob on the whole dino sells the sprint. Positions come from the eased + loader progress every frame, so no left-transition is needed. */ +.ld-chase { position: relative; height: 36px; margin-bottom: 4px; } +.ld-dino { + position: absolute; bottom: -1px; /* feet touch the hairline ground */ + animation: ld-bob 0.36s steps(2, jump-none) infinite; +} +.ld-dino svg { display: block; } +.ld-fA { animation: ld-gait 0.36s linear infinite; } +.ld-fB { animation: ld-gait 0.36s linear infinite; animation-delay: -0.18s; } +@keyframes ld-gait { 0%, 49.9% { opacity: 1; } 50%, 100% { opacity: 0; } } +@keyframes ld-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-2px); } } +/* dinner is served — freeze the sprint on frame A */ +.ld-caught .ld-dino { animation: none; } +.ld-caught .ld-fA { animation: none; opacity: 1; } +.ld-caught .ld-fB { animation: none; opacity: 0; } +@media (prefers-reduced-motion: reduce) { + .ld-dino, .ld-fA, .ld-fB { animation: none; } + .ld-fB { opacity: 0; } +} + +/* ============ "Now playing" disc player (MusicPlayer.tsx) ============ + A miniature turntable in the room's palette, Persona-5 energy in the type + + muted deep red: plinth deck with a spinning Phantom-Thieves vinyl and a + tonearm that LIFTS off the record on pause, track block beside it, and a + full-width hover drawer (progress/time/transport). The sharp cut on the + bottom-right corner is the single P5 shape gesture — drop-shadow() (not + box-shadow) so the shadow follows the clipped silhouette. Sits top-LEFT + under the brand block; slides in once the curtain lifts (body.ready). */ +.mp { + /* the shell: fixed positioning, intro slide and the shared drop shadow — + the visible card is .mp-card inside (so the mini EQ chip can crossfade + with it), and the shell shrinks in .mini so its hover zone matches the + tiny chip instead of the ghost of the full card */ + position: fixed; top: 78px; left: 26px; z-index: 47; + width: 178px; + filter: drop-shadow(0 14px 22px rgba(0, 0, 0, 0.55)); + overflow: hidden; + opacity: 0; transform: translateX(-18px); pointer-events: none; + transition: opacity 0.7s var(--ease), transform 0.7s var(--ease), filter 0.3s var(--ease), + width 0.5s var(--ease), height 0.5s var(--ease); +} +body.ready .mp { opacity: 1; transform: none; pointer-events: auto; transition-delay: 1.35s, 1.35s, 0s, 0s, 0s; } +.mp:hover { filter: drop-shadow(0 18px 30px rgba(0, 0, 0, 0.7)); } +.mp-card { + display: grid; grid-template-columns: auto 1fr; align-items: center; column-gap: 10px; + width: 178px; padding: 8px 10px; + background: linear-gradient(135deg, rgba(31, 23, 16, 0.93), rgba(16, 11, 7, 0.95)); + border: 1px solid var(--line-soft); border-radius: 6px; + clip-path: polygon(0 0, 100% 0, 100% calc(100% - 14px), calc(100% - 14px) 100%, 0 100%); + backdrop-filter: blur(6px); + transform-origin: top left; + transition: opacity 0.3s var(--ease), transform 0.45s var(--ease); +} + +/* --- auto-tuck: a beat after sliding in (MusicPlayer.tsx drives .mini), the + card scales away into a tiny chip of bouncing EQ bars in the corner; + pointer-over or keyboard focus expands the full card again --- */ +.mp.mini { width: 76px; height: 28px; } /* fits the chip exactly (15 wave bars + padding + border) */ +.mp.mini .mp-card { opacity: 0; transform: scale(0.28); pointer-events: none; } +.mp.mini .mp-more { display: none; } /* no half-open drawer mid-collapse */ +.mp-chip { + /* a clean rounded pill (the P5 corner cut looked broken at 40px — its + clipped corner loses the border line) with a faint beat-pulsed glow */ + position: absolute; top: 0; left: 0; + display: flex; align-items: flex-end; + padding: 7px 8px; cursor: pointer; + background: linear-gradient(135deg, rgba(31, 23, 16, 0.94), rgba(16, 11, 7, 0.96)); + border: 1px solid var(--line-soft); border-radius: 8px; + opacity: 0; transform: translateY(-4px); pointer-events: none; + transition: opacity 0.3s var(--ease), transform 0.3s var(--ease); +} +.mp.mini .mp-chip { opacity: 1; transform: none; pointer-events: auto; transition-delay: 0.16s; } +.mp.mini.playing .mp-chip { animation: mp-chip-glow calc(var(--mp-beat) * 2) ease-in-out infinite; } +.mp-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; } +@keyframes mp-chip-glow { + 0%, 100% { box-shadow: 0 0 7px 0 rgba(201, 80, 63, 0.28); } + 25%, 75% { box-shadow: 0 0 0 0 rgba(201, 80, 63, 0); } + 50% { box-shadow: 0 0 6px 0 rgba(201, 80, 63, 0.2); } +} + +/* --- the chip's waveform: a dome of bars with a rolling crest ------------- + Eleven slim bars whose MAX heights follow a center-swelling envelope + (inline style from MusicPlayer.tsx), all running ONE shared swell + keyframe over exactly two beats — each bar starts a fraction of the + cycle later than its neighbor (inline negative delay), so a single + crest travels across the dome and the whole thing breathes "oo… oo…" + on the groove. --mp-beat is the tempo knob. */ +.mp { --mp-beat: 577ms; } /* ≈104 BPM — the Heartbreak groove */ +.mp-chip-eq { display: flex; align-items: flex-end; gap: 2px; height: 12px; } +.mp-chip-eq i { + width: 2px; border-radius: 1.5px; /* height + delay come inline per bar */ + transform: scaleY(0.22); transform-origin: bottom; + background: linear-gradient(to top, #8e2a20, #c9503f 70%, #e08a6a); + animation: mp-wave calc(var(--mp-beat) * 2) ease-in-out infinite; +} +/* dead waveform on pause: the envelope silhouette at stub height */ +.mp:not(.playing) .mp-chip-eq i { animation: none; } +@keyframes mp-wave { + 0%, 100% { transform: scaleY(0.22); } + 50% { transform: scaleY(1); } +} + +/* --- the deck: a brushed plinth carrying the platter + vinyl; grooves and the + Phantom Thieves label rotate, the specular sheen stays fixed (light + doesn't spin with the record), the tonearm rests on the groove --- */ +.mp-deck { + position: relative; width: 54px; height: 54px; flex: none; grid-row: 1; + border: 0; padding: 0; cursor: pointer; border-radius: 7px; + background: linear-gradient(145deg, #26272d, #121317); + box-shadow: inset 0 0 0 1px rgba(231, 214, 186, 0.07), inset 0 -6px 10px -8px #000, + 0 5px 12px -5px rgba(0, 0, 0, 0.85); +} +.mp-deck:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; } +.mp-screw { /* corner knob, like the reference deck */ + position: absolute; left: 4px; bottom: 4px; width: 5px; height: 5px; border-radius: 50%; + background: radial-gradient(circle at 38% 32%, #9aa0a8, #3c3f45 75%); +} +.mp-vinyl { + position: absolute; inset: 4px; border-radius: 50%; display: grid; place-items: center; + background: repeating-radial-gradient(circle at 50% 50%, #0b0b0d 0 1.3px, #17171b 1.3px 2.6px); + box-shadow: inset 0 0 0 1px rgba(231, 214, 186, 0.09), 0 3px 9px -3px rgba(0, 0, 0, 0.85); + animation: mp-spin 3.6s linear infinite; + animation-play-state: paused; +} +.mp.playing .mp-vinyl { animation-play-state: running; } +@keyframes mp-spin { to { transform: rotate(360deg); } } +.mp-label { + position: relative; width: 21px; height: 21px; border-radius: 50%; overflow: hidden; + display: grid; place-items: center; + background: radial-gradient(circle at 40% 32%, #b0362a, #8e2a20 72%); + box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.35); +} +.mp-logo { width: 16px; height: 16px; object-fit: contain; user-select: none; } +.mp-label::after { /* spindle */ + content: ""; position: absolute; width: 3px; height: 3px; border-radius: 50%; + background: #0b0b0d; box-shadow: 0 0 0 1px rgba(242, 231, 214, 0.25); +} +.mp.playing .mp-label { animation: mp-pulse 2.6s ease-in-out infinite; } +@keyframes mp-pulse { + 0%, 100% { box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.35), 0 0 0 0 rgba(201, 80, 63, 0); } + 50% { box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.35), 0 0 12px 1px rgba(201, 80, 63, 0.35); } +} +.mp-sheen { + position: absolute; inset: 4px; border-radius: 50%; pointer-events: none; + background: + radial-gradient(circle at 32% 26%, rgba(242, 231, 214, 0.15), transparent 42%), + conic-gradient(from 210deg, transparent 0 40%, rgba(242, 231, 214, 0.06) 47%, transparent 55%, transparent 78%, rgba(242, 231, 214, 0.05) 86%, transparent 92%); +} +/* tonearm: pivot pinned top-right of the plinth; the arm swings ONTO the + record while playing and lifts away on pause */ +.mp-arm { + position: absolute; top: 1px; right: 1px; width: 9px; height: 9px; border-radius: 50%; + background: radial-gradient(circle at 38% 32%, #565b63, #1a1b20 78%); + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.7); +} +.mp-arm i { + position: absolute; left: 50%; top: 50%; width: 2px; height: 26px; margin-left: -1px; + background: linear-gradient(#cfd3d9, #8d9097); + border-radius: 2px; transform-origin: top center; + transform: rotate(26deg); transition: transform 0.55s var(--ease); +} +.mp-arm i::after { /* headshell */ + content: ""; position: absolute; left: 50%; bottom: -1px; width: 5px; height: 7px; + transform: translateX(-50%); border-radius: 2px; + background: linear-gradient(#3b3e45, #16171b); +} +.mp:not(.playing) .mp-arm i { transform: rotate(-9deg); } /* lifted off the record */ + +/* --- track block --- */ +.mp-body { min-width: 0; grid-row: 1; } +.mp-kick { font-family: var(--r-mono); font-size: 7px; letter-spacing: 0.26em; text-transform: uppercase; color: var(--muted); opacity: 0.8; } +.mp-title { + font-family: var(--r-display); font-weight: 700; font-style: italic; /* the P5 lean */ + font-size: 13px; text-transform: uppercase; letter-spacing: 0.01em; line-height: 1.05; + color: var(--ink); margin-top: 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; +} +.mp-artist { + font-family: var(--r-mono); font-size: 7.5px; font-weight: 700; letter-spacing: 0.18em; + text-transform: uppercase; color: #c9503f; margin-top: 2px; +} + +/* --- equalizer: 14 bars on offset clocks; freezes with the disc --- */ +.mp-eq { display: flex; align-items: flex-end; gap: 2px; height: 8px; margin-top: 5px; } +.mp-eq i { + width: 2px; height: 100%; transform-origin: bottom; transform: scaleY(0.15); + background: linear-gradient(to top, #8e2a20, #c9503f); + animation: mp-eq 0.9s ease-in-out infinite alternate; animation-play-state: paused; +} +.mp.playing .mp-eq i { animation-play-state: running; } +@keyframes mp-eq { from { transform: scaleY(0.12); } to { transform: scaleY(1); } } +.mp-eq i:nth-child(1) { animation-duration: 0.74s; animation-delay: -0.31s; } +.mp-eq i:nth-child(2) { animation-duration: 0.92s; animation-delay: -0.75s; } +.mp-eq i:nth-child(3) { animation-duration: 0.68s; animation-delay: -0.12s; } +.mp-eq i:nth-child(4) { animation-duration: 1.04s; animation-delay: -0.56s; } +.mp-eq i:nth-child(5) { animation-duration: 0.81s; animation-delay: -0.92s; } +.mp-eq i:nth-child(6) { animation-duration: 0.95s; animation-delay: -0.24s; } +.mp-eq i:nth-child(7) { animation-duration: 0.71s; animation-delay: -0.63s; } +.mp-eq i:nth-child(8) { animation-duration: 1.08s; animation-delay: -0.42s; } +.mp-eq i:nth-child(9) { animation-duration: 0.77s; animation-delay: -0.85s; } +.mp-eq i:nth-child(10) { animation-duration: 0.9s; animation-delay: -0.18s; } +.mp-eq i:nth-child(11) { animation-duration: 0.66s; animation-delay: -0.51s; } +.mp-eq i:nth-child(12) { animation-duration: 1.02s; animation-delay: -0.98s; } +.mp-eq i:nth-child(13) { animation-duration: 0.84s; animation-delay: -0.35s; } +.mp-eq i:nth-child(14) { animation-duration: 0.73s; animation-delay: -0.7s; } + +/* --- hover / focus expanded drawer: spans the full card width --- */ +.mp-more { grid-column: 1 / -1; display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.45s var(--ease); } +.mp:hover .mp-more, .mp:focus-within .mp-more { grid-template-rows: 1fr; } +.mp-more-inner { overflow: hidden; min-height: 0; } +.mp-progress { height: 2px; background: var(--hair); margin-top: 9px; } +.mp-progress span { + display: block; height: 100%; background: linear-gradient(90deg, #8e2a20, #c9503f); + box-shadow: 0 0 8px rgba(201, 80, 63, 0.5); transition: width 0.3s linear; +} +.mp-row { display: flex; justify-content: space-between; align-items: center; margin-top: 7px; } +.mp-time { font-family: var(--r-mono); font-size: 8px; letter-spacing: 0.05em; color: var(--muted); white-space: nowrap; } +.mp-ctrl { display: flex; gap: 2px; } +.mp-ctrl button { + width: 18px; height: 18px; display: grid; place-items: center; background: none; border: 0; + color: var(--muted); cursor: pointer; border-radius: 3px; transition: color 0.2s, transform 0.2s; +} +.mp-ctrl button:hover { color: var(--ink); transform: translateY(-1px); } +.mp-ctrl button:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; } +.mp-ctrl button svg { width: 9px; height: 9px; } +.mp-ctrl .mp-play { color: #c9503f; } + +@media (max-width: 900px) { + .mp { width: 162px; top: 72px; left: 18px; } + .mp-card { width: 162px; column-gap: 8px; } + /* the chip slims down further on small screens (it read large on mobile) */ + .mp.mini { width: 74px; height: 24px; } + .mp-chip { padding: 6px 7px; } + .mp-chip-eq { height: 10px; } + .mp-deck { width: 48px; height: 48px; } + .mp-title { font-size: 12px; } +} +@media (prefers-reduced-motion: reduce) { + .mp-vinyl, .mp-label, .mp-eq i, .mp-chip-eq i, .mp-chip { animation: none !important; } + .mp-eq i { transform: scaleY(0.4); } + .mp-chip-eq i { transform: scaleY(0.45); } + .mp-arm i { transition: none; } } diff --git a/src/components/LoadingScreen.tsx b/src/components/LoadingScreen.tsx new file mode 100644 index 0000000..1657d4d --- /dev/null +++ b/src/components/LoadingScreen.tsx @@ -0,0 +1,103 @@ +"use client"; + +/* ===================================================================== + LoadingScreen.tsx — the entry curtain (title screen) over the 3D room. + --------------------------------------------------------------------- + A warm, near-black curtain in the site's own design language (same + tokens, type and grain as globals.css) that hides ALL asset loading: + the room loads, compiles its shaders and warms its shadow maps behind + it (RoomScene's LoadGate), so nothing ever pops in view. The progress + line + counter ease smoothly instead of jumping with the loader. + + Choreography: staged type entrance → line fills as assets arrive → + on `ready` the status flips to "Step inside." and the line completes → + a short beat → the curtain lifts (opacity + soft blur) and Portfolio + unmounts it after the transition (onExited). + ===================================================================== */ + +import { useEffect, useRef, useState } from "react"; +import { identity } from "@/content/site"; +import PixelChase from "./PixelChase"; + +export type LoadingScreenProps = { + progress: number; // raw loader progress 0–100 (jumps in chunks) + ready: boolean; // room fully loaded + compiled + warmed → begin the exit + onExited: () => void; // curtain finished fading — safe to unmount +}; + +export default function LoadingScreen({ progress, ready, onExited }: LoadingScreenProps) { + // "done" is just the `ready` prop; only the lift (a beat later) needs state + const [lifting, setLifting] = useState(false); + const [shown, setShown] = useState(0); // eased display value for the counter + + // ease the displayed percentage toward the real one (the loader jumps in + // chunks; a counted-up number reads as crafted, not mechanical) + useEffect(() => { + let raf = 0; + const tick = () => { + setShown((cur) => { + const target = ready ? 100 : progress; + const next = cur + (target - cur) * 0.12; + return target - next < 0.1 ? target : next; + }); + raf = requestAnimationFrame(tick); + }; + raf = requestAnimationFrame(tick); + return () => cancelAnimationFrame(raf); + }, [progress, ready]); + + // exit choreography: the line completes + "Step inside." lands the moment `ready` + // flips; one beat later the curtain lifts + useEffect(() => { + if (!ready) return; + const t = setTimeout(() => setLifting(true), 700); + return () => clearTimeout(t); + }, [ready]); + + const pct = Math.min(100, Math.round(shown)); + const lifted = useRef(false); + + return ( +
{ + if (lifting && e.target === e.currentTarget && !lifted.current) { + lifted.current = true; + onExited(); + } + }} + > + {/* slow-breathing warm glow + floating dust — the room's mood before the room */} + + ); +} diff --git a/src/components/MusicPlayer.tsx b/src/components/MusicPlayer.tsx new file mode 100644 index 0000000..3a9e77b --- /dev/null +++ b/src/components/MusicPlayer.tsx @@ -0,0 +1,196 @@ +"use client"; + +/* ===================================================================== + MusicPlayer.tsx — the "Now Playing" disc player (top-right HUD). + --------------------------------------------------------------------- + A Persona 5-inspired turntable card in the room's warm palette: a + spinning vinyl on the left (pure CSS — layered gradients for grooves, + a fixed specular sheen, a rotating label with a jagged red star; a + second WebGL context for a 90px HUD disc would be a perf smell), and + the track block on the right — bold condensed title, muted-red + accents, an animated equalizer, and a hover-expanded drawer with the + progress line, time and transport controls. + + No audio ships (the actual track is copyrighted — this is a visual + player): play/pause drives the disc spin, EQ and simulated progress. + Drop a file into AUDIO_SRC later and the same state wires up for real. + ===================================================================== */ + +import { useEffect, useRef, useState } from "react"; +import Image from "next/image"; + +const TRACK = { + title: "Heartbreak", + artist: "Persona 5", + length: 268, // 4:28, per the design reference +}; +const AUDIO_SRC = ""; // intentionally empty — see the header note + +const fmt = (s: number) => `${Math.floor(s / 60)}:${String(Math.floor(s % 60)).padStart(2, "0")}`; + +/* how long the full card stays up after sliding in, and after the pointer + leaves it, before tucking into the mini waveform chip */ +const COLLAPSE_AFTER_INTRO_MS = 3200; // ≈1.35s slide-in + ~1.8s on show +const COLLAPSE_AFTER_LEAVE_MS = 1400; + +/* the chip waveform's dome envelope: each bar's MAX height (%), swelling + through the middle and easing off at the ends — the crest that rolls + across them is globals.css's mp-wave keyframe. 15 bars × 2px = a longer, + thinner ribbon (the 11 × 3px version read chunky on mobile). */ +const WAVE_ENVELOPE = [30, 42, 55, 68, 80, 90, 97, 100, 97, 90, 80, 68, 55, 42, 30]; + +export default function MusicPlayer() { + const [playing, setPlaying] = useState(true); + const [t, setT] = useState(84); // start mid-song like a room you walked into + // mini = tucked into just the spinning disc; hover/focus expands it again + const [mini, setMini] = useState(false); + const hideTimer = useRef(null); + + const armCollapse = (ms: number) => { + if (hideTimer.current) window.clearTimeout(hideTimer.current); + hideTimer.current = window.setTimeout(() => setMini(true), ms); + }; + const cancelCollapse = () => { + if (hideTimer.current) window.clearTimeout(hideTimer.current); + hideTimer.current = null; + setMini(false); + }; + + // simulated playback clock (becomes the real audio clock if AUDIO_SRC is set) + useEffect(() => { + if (!playing) return; + const id = setInterval(() => setT((cur) => (cur + 0.25) % TRACK.length), 250); + return () => clearInterval(id); + }, [playing]); + + // the card slides in when the loading curtain lifts (body gains .ready); + // a beat later it tucks itself into the mini disc + useEffect(() => { + let mo: MutationObserver | null = null; + if (document.body.classList.contains("ready")) { + armCollapse(COLLAPSE_AFTER_INTRO_MS); + } else { + mo = new MutationObserver(() => { + if (document.body.classList.contains("ready")) { + armCollapse(COLLAPSE_AFTER_INTRO_MS); + mo?.disconnect(); + mo = null; + } + }); + mo.observe(document.body, { attributes: true, attributeFilter: ["class"] }); + } + return () => { + mo?.disconnect(); + if (hideTimer.current) window.clearTimeout(hideTimer.current); + }; + }, []); + + return ( + + ); +} diff --git a/src/components/PixelChase.tsx b/src/components/PixelChase.tsx new file mode 100644 index 0000000..d73e350 --- /dev/null +++ b/src/components/PixelChase.tsx @@ -0,0 +1,212 @@ +"use client"; + +/* ===================================================================== + PixelChase.tsx — the loading "bar": an 8-bit Spinosaurus chasing a + dodo along the progress hairline (LoadingScreen.tsx). + --------------------------------------------------------------------- + The Spino's position IS the loading progress; the dodo stays ahead on + a gap that shrinks as loading completes, so the catch lands exactly + at 100% ("Step inside." = dinner time). Sprites are hand-drawn pixel + maps rendered as SVG rects (crispEdges) — SSR-safe, no canvas — drawn + from the pixel-art references in Private Random Stuff/References + (Spinosaurus.png / Dodo.png), mirrored to face right. Two frames per + runner give the classic gait (CSS-toggled, no JS timer); positions + update from the loader's eased progress each frame, so no CSS + transition is needed. + ===================================================================== */ + +import { useMemo } from "react"; + +/* ---- sprite pixel maps ---- + One char per pixel; '.' = transparent, letters index into the sprite's + palette. Frame A/B = the two run poses (legs apart / legs passing). */ + +/* Spinosaurus (after References/Spinosaurus.png): olive body with a dark + green-grey back, rust sail with darker ribs, cream belly, long croc snout + with the jaw OPEN (it is chasing dinner), quadruped gait. 36×18. */ +const SPINO_A = [ + "............ssss....................", + "..........srssrssrs.................", + ".........ssrssrssrss................", + "........sssrssrssrsss......eeee.....", + ".......ssssrssrssrssss....eeoeeee...", + ".......sssssssssssssssseeeeeeeeeeeee", + "....eeeeeeeeeeeeeeeeeeeee.ctctctctct", + "...gggegggegggegggegggggggc.........", + ".ggggggggggggggggggggggg..tccc......", + "ggg.gggggggggcccccccccg.....cccc....", + ".....ggggggggccccccccg..............", + "........ggggggg....gggg.............", + "........gggggg.....ggg..............", + ".......ggg..........gg..............", + "......ggg...........ggg.............", + "......gg.............ggg............", + ".....ggg..............gg............", + ".....gggt.............ggt...........", +]; + +const SPINO_B = [ + "............ssss....................", + "..........srssrssrs.................", + ".........ssrssrssrss................", + "........sssrssrssrsss......eeee.....", + ".......ssssrssrssrssss....eeoeeee...", + ".......sssssssssssssssseeeeeeeeeeeee", + "....eeeeeeeeeeeeeeeeeeeee.ctctctctct", + "...gggegggegggegggegggggggc.........", + ".ggggggggggggggggggggggg..tccc......", + "ggg.gggggggggcccccccccg.....cccc....", + ".....ggggggggccccccccg..............", + "........ggggggg....gggg.............", + "........gggggg.....ggg..............", + "..........ggg......gg...............", + "...........ggg....gg................", + "............gg....g.................", + "............ggg..gg.................", + "............ggt..ggt................", +]; + +/* Dodo (after References/Dodo.png): plump slate-grey body with a darker + folded wing, tan neck/breast and tail plume, big dark hooked beak, wide + worried eye, orange legs — history's least escapable prey. 26×16. */ +const DODO_A = [ + "...............ccccc......", + "..............cccekddddd..", + "..............cccccdddddd.", + ".ccc..........cccc....ddd.", + "ccc.bbbbbbbbbbccc......dd.", + "ccccbbbbbbbbbbccc.........", + ".cccbbbbbbbbbbbbc.........", + "..bbbbnnnnnnnbccc.........", + "..bbccnnnnnnnbccc.........", + "..bbccnnnnnnnbbbc.........", + "...bbbnnnnnnbbbb..........", + "....bbbbbbbbbbb...........", + ".....bbbbbbbbb............", + "......oo...oo.............", + ".....oo.....oo............", + "....ook.....ook...........", +]; + +const DODO_B = [ + "...............ccccc......", + "..............cccekddddd..", + "..............cccccdddddd.", + ".ccc..........cccc....ddd.", + "ccc.bbbbbbbbbbccc......dd.", + "ccccbbbbbbbbbbccc.........", + ".cccbbbbbbbbbbbbc.........", + "..bbbbnnnnnnnbccc.........", + "..bbccnnnnnnnbccc.........", + "..bbccnnnnnnnbbbc.........", + "...bbbnnnnnnbbbb..........", + "....bbbbbbbbbbb...........", + ".....bbbbbbbbb............", + "........oo.oo.............", + "..........oo..............", + "..........ook.............", +]; + +/* palettes lifted from the reference art, warmed a touch for the curtain */ +const SPINO_COLORS: Record = { + g: "#7a8560", // olive body + e: "#454f3b", // dark green-grey back, head and snout top + s: "#9c5b30", // rust sail + r: "#66351c", // darker sail ribs + c: "#d8c193", // cream belly + lower jaw + t: "#efe6d1", // teeth and claws + o: "#e08a2d", // orange eye +}; +const DODO_COLORS: Record = { + b: "#707a89", // slate-grey body + n: "#575e6b", // darker folded wing + c: "#d3b98b", // tan head, neck, breast, plume + d: "#3a3d45", // dark hooked beak + e: "#f2efe6", // wide white eye + k: "#191a1e", // pupil + claws + o: "#cd8a3f", // orange legs +}; + +/* merge each row into horizontal runs so a sprite is ~50 rects, not ~400 */ +type Run = { x: number; y: number; w: number; fill: string }; +function spriteRuns(map: string[], palette: Record): Run[] { + const runs: Run[] = []; + map.forEach((row, y) => { + let x = 0; + while (x < row.length) { + const fill = palette[row[x]]; + if (!fill) { + x++; + continue; + } + let w = 1; + while (x + w < row.length && row[x + w] === row[x]) w++; + runs.push({ x, y, w, fill }); + x += w; + } + }); + return runs; +} + +function PixelSprite({ + frameA, + frameB, + palette, + scale, +}: { + frameA: string[]; + frameB: string[]; + palette: Record; + scale: number; +}) { + const a = useMemo(() => spriteRuns(frameA, palette), [frameA, palette]); + const b = useMemo(() => spriteRuns(frameB, palette), [frameB, palette]); + const cols = frameA[0].length; + const rows = frameA.length; + return ( + + ); +} + +export type PixelChaseProps = { + progress: number; // eased 0–100 from the loading screen + caught: boolean; // ready → the Spino has caught dinner; freeze the gait +}; + +export default function PixelChase({ progress, caught }: PixelChaseProps) { + const p = Math.min(100, Math.max(0, progress)); + // the chase math: Spino's nose = progress; the gap closes as loading completes, + // so at 100% the snout lands on the dodo's tail plume. Tuned for the 420px + // track (.ld-progress) against the 72px spino / 52px dodo sprites: the clear + // gap shrinks ~29px → −5px (snout into the plume) across the run. + const spinoLeft = p * 0.6; // % across the track + const gap = 24 - p * 0.08; // 24% head start → 16% (≈ 5px bite) + const dodoLeft = Math.min(spinoLeft + gap, 86); + return ( + + ); +} diff --git a/src/components/Portfolio.tsx b/src/components/Portfolio.tsx index e1f683f..584f60f 100644 --- a/src/components/Portfolio.tsx +++ b/src/components/Portfolio.tsx @@ -1,59 +1,37 @@ "use client"; /* ===================================================================== - Portfolio.tsx — PHASE 1: the perspective room shell + camera. + Portfolio.tsx — the page shell around the 3D room (ADR-0010). --------------------------------------------------------------------- - A real CSS-3D corner of a room (walls + floor + ceiling under one - shared perspective). A fixed camera glides between named focus - anchors as you scroll — these anchors are PLACEHOLDERS standing in - for the objects (poster, desk, shelf…) that get furnished in later - phases. Content/labels still come from src/content/site.ts. + Owns the React state + the imperative engine refs and all DOM input + (scroll wheel / keyboard / focus rail), then drives the WebGL room + (RoomScene, mounted client-only) through shared refs. Everything that + needs to be crisp, accessible, and SEO-readable stays as HTML overlays + here — the top bar, focus rail, the click-to-read "inspect" card, and + the one-page résumé — all sourced from src/content/site.ts. + + The CSS-3D room, poster, desk and window from Phases 1–3 were replaced + by the real-time 3D room; site.ts + the inspect card + résumé carried + over unchanged. ===================================================================== */ -import { useEffect, useRef, useState } from "react"; +import { useCallback, useEffect, useRef, useState } from "react"; +import dynamic from "next/dynamic"; import { identity, stations, resumeOrder } from "@/content/site"; +import { STOPS } from "./roomStops"; +import LoadingScreen from "./LoadingScreen"; +import MusicPlayer from "./MusicPlayer"; -/* ---- the placeholder focus anchors, pinned onto the room's surfaces ---- - `face` = which surface the marker lives on - `x`/`y` = its position on that surface (CSS %) - `cam` = where the camera glides to when this anchor is focused: - x/y/z — px translate of the room - ry/rx — small camera turn - rry — the ROOM's base turn (deg). The real lever for facing a - wall: turning the room brings a side wall forward so its - objects read square-on instead of edge-on. - pox — the perspective "eye" x-position (%), a finer framing nudge. - The six stops are arranged LEFT→RIGHT across the room so scrolling A→F - sweeps the camera smoothly across it with no backtracking: - about (A) → left wall - education/experience/skills (B,C,D) → back wall, left→right - involvement/contact (E,F) → right wall, back→front - rry — the ROOM's base turn. Back-wall and right-wall stops keep the resting - three-quarter turn (-14°); the left-wall stop (about) turns the room FURTHER - the same way (to -55°) so the left wall swings around to face us head-on. - Turning it the other way (toward +deg) instead shows the wall's BACK face — - mirrored and filling the screen (the original "glitch through the wall" bug). - All values glide smoothly between stops. */ -type Face = "back" | "left" | "right" | "floor"; -type Cam = { x: number; y: number; z: number; ry: number; rx: number; pox: number; rry: number }; -type Anchor = { id: string; face: Face; x: string; y: string; cam: Cam }; - -const ANCHORS: Anchor[] = [ - // left wall — the head-on stop the page lands on - { id: "about", face: "left", x: "44%", y: "44%", cam: { x: 420, y: 50, z: 240, ry: 0, rx: 0, pox: 43, rry: -55 } }, - // back wall, swept left → right - { id: "education", face: "back", x: "24%", y: "34%", cam: { x: 250, y: 55, z: 190, ry: 0, rx: 0, pox: 43, rry: -14 } }, - { id: "experience", face: "back", x: "55%", y: "34%", cam: { x: -30, y: 55, z: 195, ry: 0, rx: 0, pox: 43, rry: -14 } }, - { id: "skills", face: "back", x: "78%", y: "40%", cam: { x: -250, y: 35, z: 190, ry: 0, rx: 0, pox: 43, rry: -14 } }, - // right wall, back corner → front - { id: "involvement", face: "right", x: "38%", y: "40%", cam: { x: -90, y: 26, z: -110, ry: 54, rx: 0, pox: 43, rry: -14 } }, - { id: "contact", face: "right", x: "52%", y: "44%", cam: { x: -150, y: 28, z: -110, ry: 54, rx: 0, pox: 43, rry: -14 } }, -]; +// the WebGL canvas is client-only — keep it off the server (Next 16 lazy-load guide) +const RoomScene = dynamic(() => import("./RoomScene"), { ssr: false }); const stById = (id: string) => stations.find((s) => s.id === id); -const lerp = (a: number, b: number, t: number) => a + (b - a) * t; -/* ---------- the one-page résumé / fast-lane view ---------- */ +// one scroll = one stop; ignore further wheel events for this long (ms) so a fast +// scroll steps calmly one-by-one instead of flying through every stop +const STEP_COOLDOWN = 600; + +/* ---------- the one-page résumé / fast-lane view (carried over unchanged) ---------- */ function ResumeView({ onBack }: { onBack: () => void }) { return ( <> @@ -133,173 +111,198 @@ function ResumeView({ onBack }: { onBack: () => void }) { ); } -/* ---------- a single placeholder marker on a wall/floor ---------- */ -function AnchorMarker({ a, active, onClick }: { a: Anchor; active: boolean; onClick: () => void }) { - const st = stById(a.id); - return ( - - ); -} - export default function Portfolio() { const [resumeOpen, setResumeOpen] = useState(false); const [focus, setFocus] = useState(0); + const [inspect, setInspect] = useState(null); // stop index being inspected, or null - const stageRef = useRef(null); - const cameraRef = useRef(null); - const roomRef = useRef(null); - const hintRef = useRef(null); + /* ---- loading curtain (LoadingScreen) ---- + The room loads, compiles and warms up entirely behind an opaque curtain; input + stays gated until the scene is genuinely interaction-ready (RoomScene onReady), + so the first scroll feels identical to every scroll after it. */ + const [loadPct, setLoadPct] = useState(0); // loader progress for the curtain + const [roomReady, setRoomReady] = useState(false); // assets + shaders + warm frames done + const [curtain, setCurtain] = useState(true); // curtain stays mounted until its fade ends + const readyRef = useRef(false); // mirror for the input handlers + // DEV: visit /?loader to hold the curtain open for design review + const [holdCurtain] = useState( + () => typeof window !== "undefined" && window.location.search.includes("loader"), + ); + const handleReady = useCallback(() => { + if (!holdCurtain) setRoomReady(true); + }, [holdCurtain]); + // DEV: while /?loader holds the curtain, cycle a fake progress so the whole + // chase (start → gaining → caught) can be reviewed without reloading + useEffect(() => { + if (!holdCurtain) return; + let p = 0; + const id = setInterval(() => { + p = p >= 118 ? 0 : p + 1.2; + setLoadPct(Math.min(100, p)); + }, 50); + return () => clearInterval(id); + }, [holdCurtain]); + useEffect(() => { + if (!roomReady) return; + readyRef.current = true; + document.body.classList.add("ready"); // scene settle + hint/read-cue reveal (globals.css) + }, [roomReady]); - // imperative engine state the React tree shouldn't re-render on - const targetF = useRef(0); - const curF = useRef(0); + // imperative engine state the 3D rig reads each frame (no re-render per frame) + const targetFRef = useRef(0); + const curFRef = useRef(0); + const curZoomRef = useRef(0); + const inspectRef = useRef(null); const resumeRef = useRef(false); + const prevInspect = useRef(null); - // jump the camera to an anchor (used by the focus rail + marker clicks) - const goToRef = useRef<(i: number) => void>(() => {}); + const sceneRef = useRef(null); + const hintRef = useRef(null); + const cardRef = useRef(null); + const readBtnRef = useRef(null); + const hintGone = useRef(false); + + const N = STOPS.length; + const clampF = (v: number) => Math.max(0, Math.min(N - 1, v)); + const hideHint = () => { + if (hintGone.current) return; + hintGone.current = true; + hintRef.current?.classList.add("gone"); + }; + // keep engine mirrors + body flags in sync with React state useEffect(() => { resumeRef.current = resumeOpen; document.body.classList.toggle("resume-open", resumeOpen); }, [resumeOpen]); - /* intro reveal + escape-to-close */ useEffect(() => { - const raf = requestAnimationFrame(() => setTimeout(() => document.body.classList.add("lit"), 80)); + inspectRef.current = inspect; + document.body.classList.toggle("inspecting", inspect != null); + }, [inspect]); + + // a11y: move focus into the card on open, back to the "read" affordance on close + useEffect(() => { + if (inspect != null) { + const el = cardRef.current?.querySelector("[data-autofocus]") ?? cardRef.current; + el?.focus(); + } else if (prevInspect.current != null) { + readBtnRef.current?.focus(); + } + prevInspect.current = inspect; + }, [inspect]); + + // intro reveal + keyboard (Esc to close; arrows / page keys to step between stops) + useEffect(() => { + const lit = () => document.body.classList.add("lit"); + const raf = requestAnimationFrame(() => setTimeout(lit, 80)); + // reveal even if the tab loads in the background (rAF throttled) so it never sits blank + const litFallback = setTimeout(lit, 600); + const onKey = (e: KeyboardEvent) => { - if (e.key === "Escape") setResumeOpen(false); + if (!readyRef.current) return; // input stays gated until the curtain lifts + if (e.key === "Escape") { + if (inspectRef.current != null) setInspect(null); + else if (resumeRef.current) setResumeOpen(false); + return; + } + if (resumeRef.current || inspectRef.current != null) return; + const step = (n: number) => { + targetFRef.current = clampF(Math.round(targetFRef.current) + n); + hideHint(); + }; + if (["ArrowDown", "ArrowRight", "PageDown"].includes(e.key)) { + step(1); + e.preventDefault(); + } else if (["ArrowUp", "ArrowLeft", "PageUp"].includes(e.key)) { + step(-1); + e.preventDefault(); + } else if (e.key === "Home") { + targetFRef.current = 0; + hideHint(); + } else if (e.key === "End") { + targetFRef.current = N - 1; + hideHint(); + } }; window.addEventListener("keydown", onKey); return () => { + clearTimeout(litFallback); cancelAnimationFrame(raf); window.removeEventListener("keydown", onKey); }; + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - /* the scroll-to-focus camera engine (runs once) */ + // the "scroll to look around" hint counts its 7 seconds from when the room is + // actually explorable (curtain lifted), not from page mount useEffect(() => { - const stage = stageRef.current!; - const camera = cameraRef.current!; - const room = roomRef.current!; - const N = ANCHORS.length; - const reduce = matchMedia("(prefers-reduced-motion: reduce)").matches; - const clampF = (v: number) => Math.max(0, Math.min(N - 1, v)); - - const goTo = (i: number) => { - targetF.current = clampF(i); - hideHint(); - }; - goToRef.current = goTo; + if (!roomReady) return; + const t = setTimeout(hideHint, 7000); + return () => clearTimeout(t); + }, [roomReady]); - // wheel → glide between anchors + // scroll wheel over the canvas → step ONE stop per gesture (not continuous + // scrubbing). A cooldown swallows the rapid burst of events a fast scroll fires, + // so the camera advances one item at a time (with its fixed pan+zoom) instead of + // spazzing through all of them. The rig pans at a constant speed from there. + useEffect(() => { + const el = sceneRef.current; + if (!el) return; + let lastStep = 0; const onWheel = (e: WheelEvent) => { - if (resumeRef.current) return; + if (!readyRef.current) return; // gated until the curtain lifts + if (resumeRef.current || inspectRef.current != null) return; + e.preventDefault(); const d = Math.abs(e.deltaY) >= Math.abs(e.deltaX) ? e.deltaY : e.deltaX; - targetF.current = clampF(targetF.current + d * 0.0045); + if (Math.abs(d) < 2) return; + const now = e.timeStamp || performance.now(); + if (now - lastStep < STEP_COOLDOWN) return; + lastStep = now; + targetFRef.current = clampF(Math.round(targetFRef.current) + (d > 0 ? 1 : -1)); hideHint(); - e.preventDefault(); - }; - stage.addEventListener("wheel", onWheel, { passive: false }); - - // keys → step between anchors - const onKey = (e: KeyboardEvent) => { - if (resumeRef.current) return; - const step = (n: number) => { targetF.current = clampF(Math.round(targetF.current) + n); hideHint(); }; - if (["ArrowDown", "ArrowRight", "PageDown", " "].includes(e.key)) { step(1); e.preventDefault(); } - else if (["ArrowUp", "ArrowLeft", "PageUp"].includes(e.key)) { step(-1); e.preventDefault(); } - else if (e.key === "Home") { targetF.current = 0; } - else if (e.key === "End") { targetF.current = N - 1; } - }; - window.addEventListener("keydown", onKey); - - // drag (pointer / touch) → vertical drag scrubs focus - let dragging = false, startY = 0, startF = 0, moved = 0; - const onDown = (e: PointerEvent) => { - if (resumeRef.current) return; - if ((e.target as HTMLElement).closest(".anchor, .topbar, .focusnav")) return; - dragging = true; moved = 0; startY = e.clientY; startF = targetF.current; - stage.classList.add("dragging"); - stage.setPointerCapture(e.pointerId); - }; - const onMove = (e: PointerEvent) => { - if (!dragging) return; - moved += Math.abs(e.movementY || 0); - targetF.current = clampF(startF + (startY - e.clientY) * 0.006); - if (moved > 6) hideHint(); - }; - const endDrag = () => { dragging = false; stage.classList.remove("dragging"); }; - stage.addEventListener("pointerdown", onDown); - stage.addEventListener("pointermove", onMove); - stage.addEventListener("pointerup", endDrag); - stage.addEventListener("pointercancel", endDrag); - - // render loop - let lastNearest = -1; - let raf = 0; - const apply = () => { - if (reduce) curF.current = targetF.current; - else { - curF.current += (targetF.current - curF.current) * 0.09; - if (Math.abs(targetF.current - curF.current) < 0.001) curF.current = targetF.current; - } - const f = curF.current; - const i0 = Math.floor(f), i1 = Math.min(N - 1, i0 + 1), t = f - i0; - const a = ANCHORS[i0].cam, b = ANCHORS[i1].cam; - camera.style.setProperty("--cam-x", lerp(a.x, b.x, t).toFixed(2) + "px"); - camera.style.setProperty("--cam-y", lerp(a.y, b.y, t).toFixed(2) + "px"); - camera.style.setProperty("--cam-z", lerp(a.z, b.z, t).toFixed(2) + "px"); - camera.style.setProperty("--cam-ry", lerp(a.ry, b.ry, t).toFixed(3) + "deg"); - camera.style.setProperty("--cam-rx", lerp(a.rx, b.rx, t).toFixed(3) + "deg"); - stage.style.setProperty("--po-x", lerp(a.pox, b.pox, t).toFixed(2) + "%"); // glide the eye too - room.style.setProperty("--room-ry", lerp(a.rry, b.rry, t).toFixed(3) + "deg"); // turn the room to face the wall - - const nearest = Math.round(f); - if (nearest !== lastNearest) { lastNearest = nearest; setFocus(nearest); } - raf = requestAnimationFrame(apply); - }; - apply(); - - // auto-hide the scroll hint - let hintGone = false; - function hideHint() { - if (hintGone) return; - hintGone = true; - hintRef.current?.classList.add("gone"); - } - const hintTimer = setTimeout(hideHint, 7000); - - return () => { - cancelAnimationFrame(raf); - clearTimeout(hintTimer); - stage.removeEventListener("wheel", onWheel); - window.removeEventListener("keydown", onKey); - stage.removeEventListener("pointerdown", onDown); - stage.removeEventListener("pointermove", onMove); - stage.removeEventListener("pointerup", endDrag); - stage.removeEventListener("pointercancel", endDrag); }; + el.addEventListener("wheel", onWheel, { passive: false }); + return () => el.removeEventListener("wheel", onWheel); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - const anchorsOn = (face: Face) => ANCHORS.filter((a) => a.face === face); - const renderAnchors = (face: Face) => - anchorsOn(face).map((a) => { - const idx = ANCHORS.indexOf(a); - return ( - goToRef.current(idx)} /> - ); - }); + // glide the camera to a stop (focus rail + first marker click); open / close the close-up + const goTo = (i: number) => { + targetFRef.current = clampF(i); + hideHint(); + }; + const openInspect = (i: number) => { + targetFRef.current = clampF(i); + setInspect(i); + }; + const closeInspect = () => setInspect(null); + // a marker click: first focuses the stop, then (when already focused) opens its card + const onActivate = (i: number) => { + if (focus === i) openInspect(i); + else goTo(i); + }; - const init = ANCHORS[0].cam; + const focusStation = stById(STOPS[focus].id); + const inspectStation = inspect != null ? stById(STOPS[inspect].id) : null; + + // lightweight focus trap: keep Tab cycling inside the open card (a11y for the dialog) + const onCardKey = (e: React.KeyboardEvent) => { + if (e.key !== "Tab") return; + const card = cardRef.current; + if (!card) return; + const f = card.querySelectorAll('a[href], button:not([disabled]), [tabindex]:not([tabindex="-1"])'); + if (!f.length) return; + const first = f[0]; + const last = f[f.length - 1]; + if (e.shiftKey && document.activeElement === first) { + last.focus(); + e.preventDefault(); + } else if (!e.shiftKey && document.activeElement === last) { + first.focus(); + e.preventDefault(); + } + }; return ( <> @@ -321,51 +324,36 @@ export default function Portfolio() {
- {/* ===== the room ===== */} -
-
-
- -
-
+ {/* ===== the 3D room ===== */} +
+ +
+ + {/* ===== loading curtain — unmounts itself once its lift transition ends ===== */} + {curtain && ( + setCurtain(false)} /> + )} + + {/* ===== "now playing" disc player — slides in after the curtain lifts ===== */} + {/* ===== focus rail ===== */}