├── jumbo.jpg ├── public ├── shoe-draco.glb ├── royal_esplanade_1k.hdr └── index.html ├── resources ├── shoe.blend └── gltf │ ├── shoe.bin │ ├── normal.jpg │ ├── occlusionRougnessMetalness.jpg │ └── shoe.gltf ├── src ├── index.js ├── styles.css └── App.js ├── .prettierrc ├── package.json ├── readme.md └── .gitignore /jumbo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drcmda/floating-shoe/HEAD/jumbo.jpg -------------------------------------------------------------------------------- /public/shoe-draco.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drcmda/floating-shoe/HEAD/public/shoe-draco.glb -------------------------------------------------------------------------------- /resources/shoe.blend: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drcmda/floating-shoe/HEAD/resources/shoe.blend -------------------------------------------------------------------------------- /resources/gltf/shoe.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drcmda/floating-shoe/HEAD/resources/gltf/shoe.bin -------------------------------------------------------------------------------- /resources/gltf/normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drcmda/floating-shoe/HEAD/resources/gltf/normal.jpg -------------------------------------------------------------------------------- /public/royal_esplanade_1k.hdr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drcmda/floating-shoe/HEAD/public/royal_esplanade_1k.hdr -------------------------------------------------------------------------------- /resources/gltf/occlusionRougnessMetalness.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drcmda/floating-shoe/HEAD/resources/gltf/occlusionRougnessMetalness.jpg -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import ReactDOM from "react-dom" 3 | import "./styles.css" 4 | import "react-colorful/dist/index.css" 5 | import App from "./App" 6 | 7 | ReactDOM.render(, document.getElementById("root")) 8 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 140, 3 | "tabWidth": 2, 4 | "useTabs": false, 5 | "semi": false, 6 | "singleQuote": false, 7 | "trailingComma": "all", 8 | "bracketSpacing": true, 9 | "jsxBracketSameLine": true, 10 | "fluid": false 11 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "floating-shoe", 3 | "version": "1.0.0", 4 | "description": "", 5 | "keywords": [], 6 | "main": "src/index.js", 7 | "dependencies": { 8 | "drei": "2.2.12", 9 | "react": "17.0.1", 10 | "react-colorful": "4.4.4", 11 | "react-dom": "17.0.1", 12 | "react-scripts": "4.0.1", 13 | "react-three-fiber": "5.3.10", 14 | "three": "0.123.0", 15 | "valtio": "0.4.8" 16 | }, 17 | "devDependencies": { 18 | "typescript": "4.1.3" 19 | }, 20 | "scripts": { 21 | "start": "react-scripts start", 22 | "build": "react-scripts build", 23 | "test": "react-scripts test --env=jsdom", 24 | "eject": "react-scripts eject" 25 | }, 26 | "browserslist": [ 27 | ">0.2%", 28 | "not dead", 29 | "not ie <= 11", 30 | "not op_mini all" 31 | ] 32 | } -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ![](jumbo.jpg) 2 | 3 | npm install 4 | npm start 5 | 6 | This is a small primer on how to use GLTF models on the web, specifically how to use them as dynamic assets. 7 | 8 | Tutorial: https://www.youtube.com/watch?v=xy_tbV4pC54 9 | 10 | Live demo: https://codesandbox.io/s/floating-shoe-forked-qxjoj 11 | 12 | ### How to compress assets and turn them into JSX components 13 | 14 | 1. `npx gltf-pipeline -i model.gltf -o model.glb --draco.compressionLevel=7` 15 | 1. `npx gltfjsx model.glb` 16 | 17 | ### How to include them in your project 18 | 19 | 1. Set up [react-three-fiber](https://github.com/pmndrs/react-three-fiber) 20 | 1. Put `model.glb` into `/public` 21 | 1. Put `Model.js` (the output of [gltfjsx](https://github.com/pmndrs/react-three-fiber)) anywhere inside `/src` 22 | -------------------------------------------------------------------------------- /src/styles.css: -------------------------------------------------------------------------------- 1 | @import url("https://rsms.me/inter/inter.css"); 2 | 3 | html, 4 | body, 5 | #root { 6 | position: relative; 7 | margin: 0; 8 | padding: 0; 9 | overflow: hidden; 10 | outline: none; 11 | width: 100vw; 12 | height: 100vh; 13 | } 14 | 15 | body { 16 | background: white; 17 | font-family: "Inter var", sans-serif; 18 | display: flex; 19 | justify-content: center; 20 | } 21 | 22 | #root { 23 | width: 76ch; 24 | } 25 | 26 | h1 { 27 | position: absolute; 28 | top: 43px; 29 | left: 140px; 30 | padding: 0; 31 | margin: 40px; 32 | font-size: 5em; 33 | line-height: 0.7em; 34 | letter-spacing: -6px; 35 | color: #272730; 36 | } 37 | 38 | .picker { 39 | position: absolute !important; 40 | top: 74px; 41 | left: 70px; 42 | width: 90px !important; 43 | height: 90px !important; 44 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # misc 2 | .DS_Store 3 | .env.local 4 | .env.development.local 5 | .env.test.local 6 | .env.production.local 7 | 8 | # Logs 9 | logs 10 | *.log 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | 15 | # Directory for instrumented libs generated by jscoverage/JSCover 16 | lib-cov 17 | 18 | # Coverage directory used by tools like istanbul 19 | coverage 20 | *.lcov 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Compiled binary addons (https://nodejs.org/api/addons.html) 26 | build/ 27 | 28 | # Dependency directories 29 | node_modules/ 30 | jspm_packages/ 31 | 32 | # TypeScript cache 33 | *.tsbuildinfo 34 | 35 | # Optional eslint cache 36 | .eslintcache 37 | 38 | # Output of 'npm pack' 39 | *.tgz 40 | 41 | # Yarn Integrity file 42 | .yarn-integrity 43 | 44 | # pnpm lock 45 | 46 | pnpm-lock.yaml 47 | 48 | dist 49 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 22 | React App 23 | 24 | 25 | 26 | 29 |
30 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Suspense, useRef, useState, useEffect } from "react" 2 | import { Canvas, useFrame } from "react-three-fiber" 3 | import { ContactShadows, Environment, useGLTF, OrbitControls } from "drei" 4 | import { HexColorPicker } from "react-colorful" 5 | import { proxy, useProxy } from "valtio" 6 | 7 | // Using a Valtio state model to bridge reactivity between 8 | // the canvas and the dom, both can write to it and/or react to it. 9 | const state = proxy({ 10 | current: null, 11 | items: { 12 | laces: "#ffffff", 13 | mesh: "#ffffff", 14 | caps: "#ffffff", 15 | inner: "#ffffff", 16 | sole: "#ffffff", 17 | stripes: "#ffffff", 18 | band: "#ffffff", 19 | patch: "#ffffff", 20 | }, 21 | }) 22 | 23 | function Shoe() { 24 | const ref = useRef() 25 | const snap = useProxy(state) 26 | // Drei's useGLTF hook sets up draco automatically, that's how it differs from useLoader(GLTFLoader, url) 27 | // { nodes, materials } are extras that come from useLoader, these do not exist in threejs/GLTFLoader 28 | // nodes is a named collection of meshes, materials a named collection of materials 29 | const { nodes, materials } = useGLTF("shoe-draco.glb") 30 | 31 | // Animate model 32 | useFrame((state) => { 33 | const t = state.clock.getElapsedTime() 34 | ref.current.rotation.z = -0.2 - (1 + Math.sin(t / 1.5)) / 20 35 | ref.current.rotation.x = Math.cos(t / 4) / 8 36 | ref.current.rotation.y = Math.sin(t / 4) / 8 37 | ref.current.position.y = (1 + Math.sin(t / 1.5)) / 10 38 | }) 39 | 40 | // Cursor showing current color 41 | const [hovered, set] = useState(null) 42 | useEffect(() => { 43 | const cursor = `${hovered}` 44 | const auto = `` 45 | document.body.style.cursor = `url('data:image/svg+xml;base64,${btoa(hovered ? cursor : auto)}'), auto` 46 | }, [hovered]) 47 | 48 | // Using the GLTFJSX output here to wire in app-state and hook up events 49 | return ( 50 | (e.stopPropagation(), set(e.object.material.name))} 54 | onPointerOut={(e) => e.intersections.length === 0 && set(null)} 55 | onPointerMissed={() => (state.current = null)} 56 | onPointerDown={(e) => (e.stopPropagation(), (state.current = e.object.material.name))}> 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | ) 67 | } 68 | 69 | function Picker() { 70 | const snap = useProxy(state) 71 | return ( 72 |
73 | (state.items[snap.current] = color)} /> 74 |

{snap.current}

75 |
76 | ) 77 | } 78 | 79 | export default function App() { 80 | return ( 81 | <> 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | ) 95 | } 96 | -------------------------------------------------------------------------------- /resources/gltf/shoe.gltf: -------------------------------------------------------------------------------- 1 | { 2 | "asset" : { 3 | "generator" : "Khronos glTF Blender I/O v1.3.48", 4 | "version" : "2.0" 5 | }, 6 | "scene" : 0, 7 | "scenes" : [ 8 | { 9 | "name" : "Scene", 10 | "nodes" : [ 11 | 0, 12 | 1, 13 | 2 14 | ] 15 | } 16 | ], 17 | "nodes" : [ 18 | { 19 | "mesh" : 0, 20 | "name" : "Shoe" 21 | }, 22 | { 23 | "name" : "Light", 24 | "rotation" : [ 25 | 0.16907575726509094, 26 | 0.7558803558349609, 27 | -0.27217137813568115, 28 | 0.570947527885437 29 | ], 30 | "translation" : [ 31 | 4.076245307922363, 32 | 5.903861999511719, 33 | -1.0054539442062378 34 | ] 35 | }, 36 | { 37 | "name" : "Camera", 38 | "rotation" : [ 39 | 0.483536034822464, 40 | 0.33687159419059753, 41 | -0.20870360732078552, 42 | 0.7804827094078064 43 | ], 44 | "translation" : [ 45 | 7.358891487121582, 46 | 4.958309173583984, 47 | 6.925790786743164 48 | ] 49 | } 50 | ], 51 | "materials" : [ 52 | { 53 | "doubleSided" : true, 54 | "emissiveFactor" : [ 55 | 0, 56 | 0, 57 | 0 58 | ], 59 | "name" : "laces", 60 | "normalTexture" : { 61 | "index" : 0, 62 | "texCoord" : 0 63 | }, 64 | "occlusionTexture" : { 65 | "index" : 1, 66 | "texCoord" : 0 67 | }, 68 | "pbrMetallicRoughness" : { 69 | "baseColorFactor" : [ 70 | 1, 71 | 1, 72 | 1, 73 | 1 74 | ], 75 | "metallicRoughnessTexture" : { 76 | "index" : 1, 77 | "texCoord" : 0 78 | } 79 | } 80 | }, 81 | { 82 | "emissiveFactor" : [ 83 | 0, 84 | 0, 85 | 0 86 | ], 87 | "name" : "mesh", 88 | "normalTexture" : { 89 | "index" : 2, 90 | "texCoord" : 0 91 | }, 92 | "occlusionTexture" : { 93 | "index" : 3, 94 | "texCoord" : 0 95 | }, 96 | "pbrMetallicRoughness" : { 97 | "baseColorFactor" : [ 98 | 1, 99 | 1, 100 | 1, 101 | 1 102 | ], 103 | "metallicRoughnessTexture" : { 104 | "index" : 3, 105 | "texCoord" : 0 106 | } 107 | } 108 | }, 109 | { 110 | "doubleSided" : true, 111 | "emissiveFactor" : [ 112 | 0, 113 | 0, 114 | 0 115 | ], 116 | "name" : "caps", 117 | "pbrMetallicRoughness" : { 118 | "baseColorFactor" : [ 119 | 1, 120 | 1, 121 | 1, 122 | 1 123 | ], 124 | "metallicFactor" : 0.5, 125 | "roughnessFactor" : 0.5 126 | } 127 | }, 128 | { 129 | "doubleSided" : true, 130 | "emissiveFactor" : [ 131 | 0, 132 | 0, 133 | 0 134 | ], 135 | "name" : "inner", 136 | "normalTexture" : { 137 | "index" : 4, 138 | "texCoord" : 0 139 | }, 140 | "occlusionTexture" : { 141 | "index" : 5, 142 | "texCoord" : 0 143 | }, 144 | "pbrMetallicRoughness" : { 145 | "baseColorFactor" : [ 146 | 1, 147 | 1, 148 | 1, 149 | 1 150 | ], 151 | "metallicRoughnessTexture" : { 152 | "index" : 5, 153 | "texCoord" : 0 154 | } 155 | } 156 | }, 157 | { 158 | "doubleSided" : true, 159 | "emissiveFactor" : [ 160 | 0, 161 | 0, 162 | 0 163 | ], 164 | "name" : "sole", 165 | "normalTexture" : { 166 | "index" : 6, 167 | "texCoord" : 0 168 | }, 169 | "occlusionTexture" : { 170 | "index" : 7, 171 | "texCoord" : 0 172 | }, 173 | "pbrMetallicRoughness" : { 174 | "baseColorFactor" : [ 175 | 1, 176 | 1, 177 | 1, 178 | 1 179 | ], 180 | "metallicRoughnessTexture" : { 181 | "index" : 7, 182 | "texCoord" : 0 183 | } 184 | } 185 | }, 186 | { 187 | "doubleSided" : true, 188 | "emissiveFactor" : [ 189 | 0, 190 | 0, 191 | 0 192 | ], 193 | "name" : "stripes", 194 | "normalTexture" : { 195 | "index" : 8, 196 | "texCoord" : 0 197 | }, 198 | "occlusionTexture" : { 199 | "index" : 9, 200 | "texCoord" : 0 201 | }, 202 | "pbrMetallicRoughness" : { 203 | "baseColorFactor" : [ 204 | 1, 205 | 1, 206 | 1, 207 | 1 208 | ], 209 | "metallicRoughnessTexture" : { 210 | "index" : 9, 211 | "texCoord" : 0 212 | } 213 | } 214 | }, 215 | { 216 | "doubleSided" : true, 217 | "emissiveFactor" : [ 218 | 0, 219 | 0, 220 | 0 221 | ], 222 | "name" : "band", 223 | "normalTexture" : { 224 | "index" : 10, 225 | "texCoord" : 0 226 | }, 227 | "occlusionTexture" : { 228 | "index" : 11, 229 | "texCoord" : 0 230 | }, 231 | "pbrMetallicRoughness" : { 232 | "baseColorFactor" : [ 233 | 1, 234 | 1, 235 | 1, 236 | 1 237 | ], 238 | "metallicRoughnessTexture" : { 239 | "index" : 11, 240 | "texCoord" : 0 241 | } 242 | } 243 | }, 244 | { 245 | "doubleSided" : true, 246 | "emissiveFactor" : [ 247 | 0, 248 | 0, 249 | 0 250 | ], 251 | "name" : "patch", 252 | "normalTexture" : { 253 | "index" : 12, 254 | "texCoord" : 0 255 | }, 256 | "occlusionTexture" : { 257 | "index" : 13, 258 | "texCoord" : 0 259 | }, 260 | "pbrMetallicRoughness" : { 261 | "baseColorFactor" : [ 262 | 1, 263 | 1, 264 | 1, 265 | 1 266 | ], 267 | "metallicRoughnessTexture" : { 268 | "index" : 13, 269 | "texCoord" : 0 270 | } 271 | } 272 | } 273 | ], 274 | "meshes" : [ 275 | { 276 | "name" : "shoe", 277 | "primitives" : [ 278 | { 279 | "attributes" : { 280 | "POSITION" : 0, 281 | "NORMAL" : 1, 282 | "TEXCOORD_0" : 2 283 | }, 284 | "indices" : 3, 285 | "material" : 0 286 | }, 287 | { 288 | "attributes" : { 289 | "POSITION" : 4, 290 | "NORMAL" : 5, 291 | "TEXCOORD_0" : 6 292 | }, 293 | "indices" : 7, 294 | "material" : 1 295 | }, 296 | { 297 | "attributes" : { 298 | "POSITION" : 8, 299 | "NORMAL" : 9, 300 | "TEXCOORD_0" : 10 301 | }, 302 | "indices" : 11, 303 | "material" : 2 304 | }, 305 | { 306 | "attributes" : { 307 | "POSITION" : 12, 308 | "NORMAL" : 13, 309 | "TEXCOORD_0" : 14 310 | }, 311 | "indices" : 15, 312 | "material" : 3 313 | }, 314 | { 315 | "attributes" : { 316 | "POSITION" : 16, 317 | "NORMAL" : 17, 318 | "TEXCOORD_0" : 18 319 | }, 320 | "indices" : 19, 321 | "material" : 4 322 | }, 323 | { 324 | "attributes" : { 325 | "POSITION" : 20, 326 | "NORMAL" : 21, 327 | "TEXCOORD_0" : 22 328 | }, 329 | "indices" : 23, 330 | "material" : 5 331 | }, 332 | { 333 | "attributes" : { 334 | "POSITION" : 24, 335 | "NORMAL" : 25, 336 | "TEXCOORD_0" : 26 337 | }, 338 | "indices" : 27, 339 | "material" : 6 340 | }, 341 | { 342 | "attributes" : { 343 | "POSITION" : 28, 344 | "NORMAL" : 29, 345 | "TEXCOORD_0" : 30 346 | }, 347 | "indices" : 31, 348 | "material" : 7 349 | } 350 | ] 351 | } 352 | ], 353 | "textures" : [ 354 | { 355 | "source" : 0 356 | }, 357 | { 358 | "source" : 1 359 | }, 360 | { 361 | "source" : 0 362 | }, 363 | { 364 | "source" : 1 365 | }, 366 | { 367 | "source" : 0 368 | }, 369 | { 370 | "source" : 1 371 | }, 372 | { 373 | "source" : 0 374 | }, 375 | { 376 | "source" : 1 377 | }, 378 | { 379 | "source" : 0 380 | }, 381 | { 382 | "source" : 1 383 | }, 384 | { 385 | "source" : 0 386 | }, 387 | { 388 | "source" : 1 389 | }, 390 | { 391 | "source" : 0 392 | }, 393 | { 394 | "source" : 1 395 | } 396 | ], 397 | "images" : [ 398 | { 399 | "mimeType" : "image/jpeg", 400 | "name" : "normal", 401 | "uri" : "normal.jpg" 402 | }, 403 | { 404 | "mimeType" : "image/jpeg", 405 | "name" : "occlusionRougnessMetalness", 406 | "uri" : "occlusionRougnessMetalness.jpg" 407 | } 408 | ], 409 | "accessors" : [ 410 | { 411 | "bufferView" : 0, 412 | "componentType" : 5126, 413 | "count" : 1552, 414 | "max" : [ 415 | 0.31010252237319946, 416 | 0.23435352742671967, 417 | 0.19393111765384674 418 | ], 419 | "min" : [ 420 | -0.21236468851566315, 421 | -0.11542611569166183, 422 | -0.27246636152267456 423 | ], 424 | "type" : "VEC3" 425 | }, 426 | { 427 | "bufferView" : 1, 428 | "componentType" : 5126, 429 | "count" : 1552, 430 | "type" : "VEC3" 431 | }, 432 | { 433 | "bufferView" : 2, 434 | "componentType" : 5126, 435 | "count" : 1552, 436 | "type" : "VEC2" 437 | }, 438 | { 439 | "bufferView" : 3, 440 | "componentType" : 5123, 441 | "count" : 7227, 442 | "type" : "SCALAR" 443 | }, 444 | { 445 | "bufferView" : 4, 446 | "componentType" : 5126, 447 | "count" : 5199, 448 | "max" : [ 449 | 0.9846919178962708, 450 | 0.3809230625629425, 451 | 0.3442471921443939 452 | ], 453 | "min" : [ 454 | -0.9474887251853943, 455 | -0.3825278878211975, 456 | -0.35044431686401367 457 | ], 458 | "type" : "VEC3" 459 | }, 460 | { 461 | "bufferView" : 5, 462 | "componentType" : 5126, 463 | "count" : 5199, 464 | "type" : "VEC3" 465 | }, 466 | { 467 | "bufferView" : 6, 468 | "componentType" : 5126, 469 | "count" : 5199, 470 | "type" : "VEC2" 471 | }, 472 | { 473 | "bufferView" : 7, 474 | "componentType" : 5123, 475 | "count" : 21165, 476 | "type" : "SCALAR" 477 | }, 478 | { 479 | "bufferView" : 8, 480 | "componentType" : 5126, 481 | "count" : 1374, 482 | "max" : [ 483 | 0.2774718105792999, 484 | 0.16645346581935883, 485 | 0.19632135331630707 486 | ], 487 | "min" : [ 488 | -0.2291366010904312, 489 | -0.13262774050235748, 490 | -0.2687131464481354 491 | ], 492 | "type" : "VEC3" 493 | }, 494 | { 495 | "bufferView" : 9, 496 | "componentType" : 5126, 497 | "count" : 1374, 498 | "type" : "VEC3" 499 | }, 500 | { 501 | "bufferView" : 10, 502 | "componentType" : 5126, 503 | "count" : 1374, 504 | "type" : "VEC2" 505 | }, 506 | { 507 | "bufferView" : 11, 508 | "componentType" : 5123, 509 | "count" : 6210, 510 | "type" : "SCALAR" 511 | }, 512 | { 513 | "bufferView" : 12, 514 | "componentType" : 5126, 515 | "count" : 2166, 516 | "max" : [ 517 | 0.9421579241752625, 518 | 0.40126022696495056, 519 | 0.2965231239795685 520 | ], 521 | "min" : [ 522 | -0.8118161559104919, 523 | -0.38051360845565796, 524 | -0.3006590008735657 525 | ], 526 | "type" : "VEC3" 527 | }, 528 | { 529 | "bufferView" : 13, 530 | "componentType" : 5126, 531 | "count" : 2166, 532 | "type" : "VEC3" 533 | }, 534 | { 535 | "bufferView" : 14, 536 | "componentType" : 5126, 537 | "count" : 2166, 538 | "type" : "VEC2" 539 | }, 540 | { 541 | "bufferView" : 15, 542 | "componentType" : 5123, 543 | "count" : 11025, 544 | "type" : "SCALAR" 545 | }, 546 | { 547 | "bufferView" : 16, 548 | "componentType" : 5126, 549 | "count" : 1317, 550 | "max" : [ 551 | 1.0000001192092896, 552 | -0.220381498336792, 553 | 0.38874176144599915 554 | ], 555 | "min" : [ 556 | -1, 557 | -0.5139704942703247, 558 | -0.38874176144599915 559 | ], 560 | "type" : "VEC3" 561 | }, 562 | { 563 | "bufferView" : 17, 564 | "componentType" : 5126, 565 | "count" : 1317, 566 | "type" : "VEC3" 567 | }, 568 | { 569 | "bufferView" : 18, 570 | "componentType" : 5126, 571 | "count" : 1317, 572 | "type" : "VEC2" 573 | }, 574 | { 575 | "bufferView" : 19, 576 | "componentType" : 5123, 577 | "count" : 6315, 578 | "type" : "SCALAR" 579 | }, 580 | { 581 | "bufferView" : 20, 582 | "componentType" : 5126, 583 | "count" : 1570, 584 | "max" : [ 585 | 0.20826250314712524, 586 | 0.004239952191710472, 587 | 0.32903969287872314 588 | ], 589 | "min" : [ 590 | -0.2780020833015442, 591 | -0.3307887613773346, 592 | -0.3230103552341461 593 | ], 594 | "type" : "VEC3" 595 | }, 596 | { 597 | "bufferView" : 21, 598 | "componentType" : 5126, 599 | "count" : 1570, 600 | "type" : "VEC3" 601 | }, 602 | { 603 | "bufferView" : 22, 604 | "componentType" : 5126, 605 | "count" : 1570, 606 | "type" : "VEC2" 607 | }, 608 | { 609 | "bufferView" : 23, 610 | "componentType" : 5123, 611 | "count" : 7350, 612 | "type" : "SCALAR" 613 | }, 614 | { 615 | "bufferView" : 24, 616 | "componentType" : 5126, 617 | "count" : 1705, 618 | "max" : [ 619 | 0.34729886054992676, 620 | 0.5139704942703247, 621 | 0.0058010234497487545 622 | ], 623 | "min" : [ 624 | -0.8557736277580261, 625 | -0.08276855945587158, 626 | -0.09417246282100677 627 | ], 628 | "type" : "VEC3" 629 | }, 630 | { 631 | "bufferView" : 25, 632 | "componentType" : 5126, 633 | "count" : 1705, 634 | "type" : "VEC3" 635 | }, 636 | { 637 | "bufferView" : 26, 638 | "componentType" : 5126, 639 | "count" : 1705, 640 | "type" : "VEC2" 641 | }, 642 | { 643 | "bufferView" : 27, 644 | "componentType" : 5123, 645 | "count" : 7860, 646 | "type" : "SCALAR" 647 | }, 648 | { 649 | "bufferView" : 28, 650 | "componentType" : 5126, 651 | "count" : 219, 652 | "max" : [ 653 | -0.7029263377189636, 654 | 0.17990857362747192, 655 | 0.1358068436384201 656 | ], 657 | "min" : [ 658 | -0.9019400477409363, 659 | -0.021011920645833015, 660 | -0.22399701178073883 661 | ], 662 | "type" : "VEC3" 663 | }, 664 | { 665 | "bufferView" : 29, 666 | "componentType" : 5126, 667 | "count" : 219, 668 | "type" : "VEC3" 669 | }, 670 | { 671 | "bufferView" : 30, 672 | "componentType" : 5126, 673 | "count" : 219, 674 | "type" : "VEC2" 675 | }, 676 | { 677 | "bufferView" : 31, 678 | "componentType" : 5123, 679 | "count" : 948, 680 | "type" : "SCALAR" 681 | } 682 | ], 683 | "bufferViews" : [ 684 | { 685 | "buffer" : 0, 686 | "byteLength" : 18624, 687 | "byteOffset" : 0 688 | }, 689 | { 690 | "buffer" : 0, 691 | "byteLength" : 18624, 692 | "byteOffset" : 18624 693 | }, 694 | { 695 | "buffer" : 0, 696 | "byteLength" : 12416, 697 | "byteOffset" : 37248 698 | }, 699 | { 700 | "buffer" : 0, 701 | "byteLength" : 14454, 702 | "byteOffset" : 49664 703 | }, 704 | { 705 | "buffer" : 0, 706 | "byteLength" : 62388, 707 | "byteOffset" : 64120 708 | }, 709 | { 710 | "buffer" : 0, 711 | "byteLength" : 62388, 712 | "byteOffset" : 126508 713 | }, 714 | { 715 | "buffer" : 0, 716 | "byteLength" : 41592, 717 | "byteOffset" : 188896 718 | }, 719 | { 720 | "buffer" : 0, 721 | "byteLength" : 42330, 722 | "byteOffset" : 230488 723 | }, 724 | { 725 | "buffer" : 0, 726 | "byteLength" : 16488, 727 | "byteOffset" : 272820 728 | }, 729 | { 730 | "buffer" : 0, 731 | "byteLength" : 16488, 732 | "byteOffset" : 289308 733 | }, 734 | { 735 | "buffer" : 0, 736 | "byteLength" : 10992, 737 | "byteOffset" : 305796 738 | }, 739 | { 740 | "buffer" : 0, 741 | "byteLength" : 12420, 742 | "byteOffset" : 316788 743 | }, 744 | { 745 | "buffer" : 0, 746 | "byteLength" : 25992, 747 | "byteOffset" : 329208 748 | }, 749 | { 750 | "buffer" : 0, 751 | "byteLength" : 25992, 752 | "byteOffset" : 355200 753 | }, 754 | { 755 | "buffer" : 0, 756 | "byteLength" : 17328, 757 | "byteOffset" : 381192 758 | }, 759 | { 760 | "buffer" : 0, 761 | "byteLength" : 22050, 762 | "byteOffset" : 398520 763 | }, 764 | { 765 | "buffer" : 0, 766 | "byteLength" : 15804, 767 | "byteOffset" : 420572 768 | }, 769 | { 770 | "buffer" : 0, 771 | "byteLength" : 15804, 772 | "byteOffset" : 436376 773 | }, 774 | { 775 | "buffer" : 0, 776 | "byteLength" : 10536, 777 | "byteOffset" : 452180 778 | }, 779 | { 780 | "buffer" : 0, 781 | "byteLength" : 12630, 782 | "byteOffset" : 462716 783 | }, 784 | { 785 | "buffer" : 0, 786 | "byteLength" : 18840, 787 | "byteOffset" : 475348 788 | }, 789 | { 790 | "buffer" : 0, 791 | "byteLength" : 18840, 792 | "byteOffset" : 494188 793 | }, 794 | { 795 | "buffer" : 0, 796 | "byteLength" : 12560, 797 | "byteOffset" : 513028 798 | }, 799 | { 800 | "buffer" : 0, 801 | "byteLength" : 14700, 802 | "byteOffset" : 525588 803 | }, 804 | { 805 | "buffer" : 0, 806 | "byteLength" : 20460, 807 | "byteOffset" : 540288 808 | }, 809 | { 810 | "buffer" : 0, 811 | "byteLength" : 20460, 812 | "byteOffset" : 560748 813 | }, 814 | { 815 | "buffer" : 0, 816 | "byteLength" : 13640, 817 | "byteOffset" : 581208 818 | }, 819 | { 820 | "buffer" : 0, 821 | "byteLength" : 15720, 822 | "byteOffset" : 594848 823 | }, 824 | { 825 | "buffer" : 0, 826 | "byteLength" : 2628, 827 | "byteOffset" : 610568 828 | }, 829 | { 830 | "buffer" : 0, 831 | "byteLength" : 2628, 832 | "byteOffset" : 613196 833 | }, 834 | { 835 | "buffer" : 0, 836 | "byteLength" : 1752, 837 | "byteOffset" : 615824 838 | }, 839 | { 840 | "buffer" : 0, 841 | "byteLength" : 1896, 842 | "byteOffset" : 617576 843 | } 844 | ], 845 | "buffers" : [ 846 | { 847 | "byteLength" : 619472, 848 | "uri" : "shoe.bin" 849 | } 850 | ] 851 | } 852 | --------------------------------------------------------------------------------