├── .gitignore ├── SocialImage.jpg ├── postcss.config.js ├── tailwind.config.js ├── vite.config.js ├── public ├── decoder │ ├── draco_decoder.wasm │ └── draco_wasm_wrapper.js ├── resources │ ├── models │ │ └── Avatar.glb │ ├── textures │ │ └── env │ │ │ ├── back.jpeg │ │ │ ├── front.jpeg │ │ │ ├── left.jpeg │ │ │ ├── right.jpeg │ │ │ ├── top.jpeg │ │ │ └── bottom.jpeg │ └── animations │ │ └── Animations.glb └── RobeSantoro-ThreeJS-Avatar-Controller-CodeSee.svg ├── modules ├── State.js ├── CharacterControllerProxy.js ├── FiniteStateMachine.js ├── CharacterFSM.js ├── ThirdPersonCamera.js ├── CharacterControllerInput.js ├── CharacterController.js ├── World.js └── States.js ├── main.js ├── style.css ├── package.json ├── index.html ├── .github └── workflows │ └── codesee-arch-diagram.yml └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | *.local 6 | package-lock.json -------------------------------------------------------------------------------- /SocialImage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobeSantoro/ThreeJS-Avatar-Controller/HEAD/SocialImage.jpg -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | content: ["*"], 3 | theme: { 4 | extend: {}, 5 | }, 6 | plugins: [], 7 | } -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | assetsInclude: ['**/*.glb', '**/*.gltf', '**/*.wasm'], 3 | publicDir: ['public'], 4 | } -------------------------------------------------------------------------------- /public/decoder/draco_decoder.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobeSantoro/ThreeJS-Avatar-Controller/HEAD/public/decoder/draco_decoder.wasm -------------------------------------------------------------------------------- /public/resources/models/Avatar.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobeSantoro/ThreeJS-Avatar-Controller/HEAD/public/resources/models/Avatar.glb -------------------------------------------------------------------------------- /public/resources/textures/env/back.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobeSantoro/ThreeJS-Avatar-Controller/HEAD/public/resources/textures/env/back.jpeg -------------------------------------------------------------------------------- /public/resources/textures/env/front.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobeSantoro/ThreeJS-Avatar-Controller/HEAD/public/resources/textures/env/front.jpeg -------------------------------------------------------------------------------- /public/resources/textures/env/left.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobeSantoro/ThreeJS-Avatar-Controller/HEAD/public/resources/textures/env/left.jpeg -------------------------------------------------------------------------------- /public/resources/textures/env/right.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobeSantoro/ThreeJS-Avatar-Controller/HEAD/public/resources/textures/env/right.jpeg -------------------------------------------------------------------------------- /public/resources/textures/env/top.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobeSantoro/ThreeJS-Avatar-Controller/HEAD/public/resources/textures/env/top.jpeg -------------------------------------------------------------------------------- /public/resources/animations/Animations.glb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobeSantoro/ThreeJS-Avatar-Controller/HEAD/public/resources/animations/Animations.glb -------------------------------------------------------------------------------- /public/resources/textures/env/bottom.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobeSantoro/ThreeJS-Avatar-Controller/HEAD/public/resources/textures/env/bottom.jpeg -------------------------------------------------------------------------------- /modules/State.js: -------------------------------------------------------------------------------- 1 | export class State { 2 | constructor(parent) { 3 | this._parent = parent; 4 | } 5 | 6 | Enter() { } 7 | Exit() { } 8 | Update() { } 9 | } 10 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | 2 | import { World } from './modules/World'; 3 | 4 | let _APP = null; 5 | 6 | window.addEventListener('DOMContentLoaded', () => { 7 | _APP = new World(); 8 | console.log(_APP); 9 | }); 10 | -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | * { 6 | margin: 0; 7 | padding: 0; 8 | } 9 | 10 | html, body { 11 | background: transparent; 12 | overflow: hidden; 13 | } 14 | -------------------------------------------------------------------------------- /modules/CharacterControllerProxy.js: -------------------------------------------------------------------------------- 1 | export class CharacterControllerProxy { 2 | constructor(animations) { 3 | this._animations = animations; 4 | } 5 | 6 | get animations() { 7 | return this._animations; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "threejs-oop-vite", 3 | "version": "0.0.0", 4 | "scripts": { 5 | "dev": "vite", 6 | "build": "vite build", 7 | "preview": "vite preview" 8 | }, 9 | "devDependencies": { 10 | "autoprefixer": "^10.4.2", 11 | "postcss": "^8.4.6", 12 | "tailwindcss": "^3.0.19", 13 | "vite": "^2.7.2" 14 | }, 15 | "dependencies": { 16 | "three": "^0.137.5" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | ThreeJS Avatar Controller 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /.github/workflows/codesee-arch-diagram.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - main 5 | pull_request_target: 6 | types: [opened, synchronize, reopened] 7 | 8 | name: CodeSee 9 | 10 | permissions: read-all 11 | 12 | jobs: 13 | codesee: 14 | runs-on: ubuntu-latest 15 | continue-on-error: true 16 | name: Analyze the repo with CodeSee 17 | steps: 18 | - uses: Codesee-io/codesee-action@v2 19 | with: 20 | codesee-token: ${{ secrets.CODESEE_ARCH_DIAG_API_TOKEN }} 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ThreeJS-Avatar-Controller 2 | 3 | ThreeJS Character Controller - OOP Approach based on [SimonDev Tutorials](https://www.youtube.com/watch?v=EkPfhzIbp2g) 4 | 5 | RobeSantoro ThreeJS Avatar Controller CodeSee Pseudo Call Stack Map 6 | 7 | [Live Demo](https://three-js-avatar-controller.vercel.app/) 8 | 9 | ![ThreeJS Character Controller](https://repository-images.githubusercontent.com/454737605/b3e6e3c7-5ec6-4c83-93e9-109109579b9c) 10 | 11 | - git clone this repo 12 | 13 | - install dependencies 14 | 15 | ```bash 16 | npm install 17 | ``` 18 | 19 | - run development server 20 | 21 | ```bash 22 | npm run dev 23 | ``` 24 | -------------------------------------------------------------------------------- /modules/FiniteStateMachine.js: -------------------------------------------------------------------------------- 1 | export class FiniteStateMachine { 2 | constructor() { 3 | this._states = {}; 4 | this._currentState = null; 5 | } 6 | 7 | _AddState(name, type) { 8 | this._states[name] = type; 9 | } 10 | 11 | SetState(name) { 12 | const prevState = this._currentState; 13 | 14 | if (prevState) { 15 | if (prevState.Name == name) { 16 | return; 17 | } 18 | prevState.Exit(); 19 | } 20 | 21 | const state = new this._states[name](this); 22 | 23 | this._currentState = state; 24 | state.Enter(prevState); 25 | } 26 | 27 | Update(timeElapsed, input) { 28 | if (this._currentState) { 29 | this._currentState.Update(timeElapsed, input); 30 | //console.log(this._currentState.Name); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /modules/CharacterFSM.js: -------------------------------------------------------------------------------- 1 | import { FiniteStateMachine } from './FiniteStateMachine'; 2 | import * as STATE from './States'; 3 | 4 | export class CharacterFSM extends FiniteStateMachine { 5 | constructor(proxy) { 6 | super(); 7 | this._proxy = proxy; 8 | this._Init(); 9 | } 10 | 11 | _Init() { 12 | this._AddState('idle', STATE.IdleState); 13 | this._AddState('walk', STATE.WalkState); 14 | this._AddState('run', STATE.RunState); 15 | this._AddState('dance', STATE.DanceState); 16 | this._AddState('walkback', STATE.WalkBackState); 17 | this._AddState('jump', STATE.JumpState); 18 | this._AddState('jumprun', STATE.JumpRunState); 19 | //this._AddState('strafeLeft', STATE.StrafeLeftState); 20 | //this._AddState('strafeRight', STATE.StrafeRightState); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /modules/ThirdPersonCamera.js: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three'; 2 | 3 | export class ThirdPersonCamera { 4 | constructor(params) { 5 | 6 | this._CharacterCamera = params.camera; 7 | this._target = params.target; 8 | 9 | this._currentPosition = new THREE.Vector3(); 10 | this._currentLookat = new THREE.Vector3(); 11 | 12 | 13 | } 14 | 15 | _CalculateIdealOffset() { 16 | const idealOffset = new THREE.Vector3(-0.35, 2, -2); 17 | idealOffset.applyQuaternion(this._target.Rotation); 18 | idealOffset.add(this._target.Position); 19 | return idealOffset; 20 | } 21 | 22 | _CalculateIdealLookat() { 23 | const idealLookat = new THREE.Vector3(0, 0, 5); 24 | idealLookat.applyQuaternion(this._target.Rotation); 25 | idealLookat.add(this._target.Position); 26 | return idealLookat; 27 | } 28 | 29 | Update(timeElapsed) { 30 | const idealOffset = this._CalculateIdealOffset(); 31 | const idealLookat = this._CalculateIdealLookat(); 32 | 33 | const t = 1.0 - Math.pow(0.001, timeElapsed); 34 | 35 | this._currentPosition.lerp(idealOffset, t); 36 | this._currentLookat.lerp(idealLookat, t); 37 | 38 | this._CharacterCamera.position.copy(this._currentPosition); 39 | this._CharacterCamera.lookAt(this._currentLookat); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /modules/CharacterControllerInput.js: -------------------------------------------------------------------------------- 1 | export class CharacterControllerInput { 2 | constructor() { 3 | this._Init(); 4 | } 5 | 6 | _Init() { 7 | this._keys = { 8 | forward: false, 9 | backward: false, 10 | left: false, 11 | right: false, 12 | effe: false, 13 | shift: false, 14 | space: false, 15 | debug: false, 16 | }; 17 | 18 | this._mouse = { 19 | x: 0, 20 | y: 0 21 | } 22 | 23 | // Listen for key presses 24 | document.addEventListener('keydown', (e) => this._onKeyDown(e), false); 25 | document.addEventListener('keyup', (e) => this._onKeyUp(e), false); 26 | 27 | // Listen for mouse movement 28 | document.addEventListener('mousemove', (e) => this._onMouseMove(e), false); 29 | 30 | } 31 | 32 | _onMouseMove(event) { 33 | this._mouse.x = event.clientX; 34 | this._mouse.y = event.clientY; 35 | } 36 | 37 | _onKeyDown(event) { 38 | switch (event.keyCode) { 39 | case 87: // w 40 | case 38: // up 41 | this._keys.forward = true; 42 | break; 43 | case 65: // a 44 | case 37: // left 45 | this._keys.left = true; 46 | break; 47 | case 83: // s 48 | case 40: // down 49 | this._keys.backward = true; 50 | break; 51 | case 68: // d 52 | case 39: // right 53 | this._keys.right = true; 54 | break; 55 | case 70: // f 56 | this._keys.effe = true; 57 | break; 58 | case 16: // SHIFT 59 | this._keys.shift = true; 60 | break; 61 | case 32: // SPACE 62 | this._keys.space = true; 63 | break; 64 | case 86: // v 65 | if (this._keys.debug == true) { 66 | this._keys.debug = false; 67 | } else { 68 | this._keys.debug = true; 69 | } 70 | break; 71 | } 72 | } 73 | 74 | _onKeyUp(event) { 75 | switch (event.keyCode) { 76 | case 87: // w 77 | case 38: // up 78 | this._keys.forward = false; 79 | break; 80 | case 65: // a 81 | case 37: // left 82 | this._keys.left = false; 83 | break; 84 | case 83: // s 85 | case 40: // down 86 | this._keys.backward = false; 87 | break; 88 | case 68: // d 89 | case 39: // right 90 | this._keys.right = false; 91 | break; 92 | case 70: // f 93 | this._keys.effe = false; 94 | break; 95 | case 16: // SHIFT 96 | this._keys.shift = false; 97 | break; 98 | case 32: // SPACE 99 | this._keys.space = false; 100 | break; 101 | } 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /modules/CharacterController.js: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three'; 2 | import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; 3 | import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'; 4 | import { CharacterFSM } from './CharacterFSM'; 5 | import { CharacterControllerProxy } from './CharacterControllerProxy'; 6 | import { CharacterControllerInput } from './CharacterControllerInput'; 7 | 8 | // const AVATAR_PATH = 'https://d1a370nemizbjq.cloudfront.net/b45f2152-d224-4ffb-9ecc-662993cb9866.glb'; // RTFKT 9 | const AVATAR_PATH = 'https://api.readyplayer.me/v1/avatars/63b439b7f17e295642bdd67a.glb?quality=high&meshLod=0&textureSizeLimit=1024&textureAtlas=1024&morphTargets=none'; // Bianca 10 | // const AVATAR_PATH = './resources/models/Avatar.glb'; // LOCAL 11 | 12 | /* ANIMATIONS */ 13 | const ANIMATIONS_PATH = '/resources/animations/Animations.glb'; 14 | 15 | export class CharacterController { 16 | constructor(params) { 17 | this._Init(params); 18 | } 19 | 20 | _Init(params) { 21 | this._params = params; 22 | this._decceleration = new THREE.Vector3(-0.0005, -0.0001, -9.0); 23 | this._acceleration = new THREE.Vector3(1.0, 0.25, 20.0); 24 | this._velocity = new THREE.Vector3(0, 0, 0); 25 | this._position = new THREE.Vector3(); 26 | 27 | this._animations = {}; 28 | 29 | /////////////////////////////////////////////////////////////////////////////////////// 30 | 31 | if (true) { // Check if onMobile/TouchDevice or not 32 | this._input = new CharacterControllerInput(); 33 | } 34 | 35 | /////////////////////////////////////////////////////////////////////////////////////// 36 | 37 | this._stateMachine = new CharacterFSM(new CharacterControllerProxy(this._animations)); 38 | 39 | this._LoadModelandAnims(); 40 | } 41 | 42 | _LoadModelandAnims() { 43 | 44 | this.loaded = false; 45 | 46 | ///////////////////////////////////////////////////////////////////////// Load the glTF model from AVATAR_PATH 47 | const DRACO_LOADER = new DRACOLoader(); 48 | DRACO_LOADER.setDecoderPath('./decoder/'); 49 | 50 | const AvatarModelLoader = new GLTFLoader(); 51 | AvatarModelLoader.setDRACOLoader(DRACO_LOADER); 52 | 53 | AvatarModelLoader.load(AVATAR_PATH, (gltf) => { 54 | 55 | const AvatarModel = gltf.scene; 56 | 57 | // Traverse and Cast Shadow 58 | AvatarModel.traverse((child) => { 59 | if (child.isMesh) { 60 | child.castShadow = true; 61 | //child.receiveShadow = true; 62 | } 63 | }); 64 | 65 | this._target = AvatarModel; 66 | this._params.scene.add(this._target); 67 | 68 | ///////////////////////////////////////////////////////////// Load the animations form Animations.glb file 69 | const gltfLoader = new GLTFLoader(); 70 | gltfLoader.setDRACOLoader(DRACO_LOADER); 71 | 72 | gltfLoader.load(ANIMATIONS_PATH, (gltf) => { 73 | 74 | this._mixer = new THREE.AnimationMixer(this._target); 75 | 76 | const _OnLoad = (animName, anim) => { 77 | const clip = anim; 78 | const action = this._mixer.clipAction(clip); 79 | 80 | this._animations[animName] = { 81 | clip: clip, 82 | action: action, 83 | }; 84 | 85 | }; 86 | 87 | _OnLoad('idle', gltf.animations[0]); 88 | _OnLoad('walk', gltf.animations[1]); 89 | _OnLoad('run', gltf.animations[2]); 90 | _OnLoad('dance', gltf.animations[3]); 91 | _OnLoad('walkback', gltf.animations[4]); 92 | _OnLoad('jump', gltf.animations[5]); 93 | _OnLoad('jumprun', gltf.animations[6]); 94 | 95 | 96 | //console.log(this._target); 97 | //console.log(this._animations); 98 | //console.log(this._mixer); 99 | this.loaded = true; 100 | this._stateMachine.SetState('idle'); 101 | 102 | //this._mixer.action.play(); 103 | }); 104 | 105 | }); 106 | 107 | 108 | } 109 | 110 | get Position() { 111 | return this._position; 112 | } 113 | 114 | get Rotation() { 115 | if (!this._target) { 116 | return new THREE.Quaternion(); 117 | } 118 | return this._target.quaternion; 119 | } 120 | 121 | Update(timeInSeconds) { 122 | 123 | if (!this._target) { 124 | return; 125 | } 126 | 127 | // console.log(this._input._mouse); 128 | 129 | this._stateMachine.Update(timeInSeconds, this._input); 130 | 131 | const velocity = this._velocity; 132 | const frameDecceleration = new THREE.Vector3( 133 | velocity.x * this._decceleration.x, 134 | velocity.y * this._decceleration.y, 135 | velocity.z * this._decceleration.z 136 | ); 137 | frameDecceleration.multiplyScalar(timeInSeconds); 138 | frameDecceleration.z = Math.sign(frameDecceleration.z) * Math.min( 139 | Math.abs(frameDecceleration.z), Math.abs(velocity.z)); 140 | 141 | velocity.add(frameDecceleration); 142 | 143 | const controlObject = this._target; 144 | const _Q = new THREE.Quaternion(); 145 | const _A = new THREE.Vector3(); 146 | const _R = controlObject.quaternion.clone(); 147 | 148 | const acc = this._acceleration.clone(); 149 | if (this._input._keys.shift) { 150 | acc.multiplyScalar(3.0); 151 | } 152 | 153 | if (this.loaded == true) { 154 | if (this._stateMachine._currentState.Name == 'dance') { 155 | acc.multiplyScalar(0.0); 156 | } 157 | } 158 | 159 | if (this._input._keys.forward) { 160 | velocity.z += acc.z * timeInSeconds; 161 | } 162 | if (this._input._keys.backward) { 163 | velocity.z -= acc.z * timeInSeconds; 164 | } 165 | if (this._input._keys.left) { 166 | _A.set(0, 1, 0); 167 | _Q.setFromAxisAngle(_A, 4.0 * Math.PI * timeInSeconds * this._acceleration.y); 168 | _R.multiply(_Q); 169 | } 170 | if (this._input._keys.right) { 171 | _A.set(0, 1, 0); 172 | _Q.setFromAxisAngle(_A, 4.0 * -Math.PI * timeInSeconds * this._acceleration.y); 173 | _R.multiply(_Q); 174 | } 175 | 176 | controlObject.quaternion.copy(_R); 177 | 178 | const oldPosition = new THREE.Vector3(); 179 | oldPosition.copy(controlObject.position); 180 | 181 | const forward = new THREE.Vector3(0, 0, 1); 182 | forward.applyQuaternion(controlObject.quaternion); 183 | forward.normalize(); 184 | 185 | const sideways = new THREE.Vector3(1, 0, 0); 186 | sideways.applyQuaternion(controlObject.quaternion); 187 | sideways.normalize(); 188 | 189 | sideways.multiplyScalar(velocity.x * timeInSeconds); 190 | forward.multiplyScalar(velocity.z * timeInSeconds); 191 | 192 | controlObject.position.add(forward); 193 | controlObject.position.add(sideways); 194 | 195 | this._position.copy(controlObject.position); 196 | 197 | if (this._mixer) { 198 | this._mixer.update(timeInSeconds); 199 | } 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /modules/World.js: -------------------------------------------------------------------------------- 1 | import * as THREE from 'three'; 2 | import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; 3 | import { CharacterController } from './CharacterController'; 4 | import { ThirdPersonCamera } from './ThirdPersonCamera'; 5 | 6 | export class World { 7 | constructor() { 8 | this._Initialize(); 9 | } 10 | 11 | _Initialize() { 12 | /////////////////////////////////////////////////////////////////////////////////////// Set the WebGL Renderer 13 | this._threejs = new THREE.WebGLRenderer({ 14 | antialias: true, 15 | }); 16 | this._threejs.outputEncoding = THREE.sRGBEncoding; 17 | this._threejs.shadowMap.enabled = true; 18 | this._threejs.shadowMap.type = THREE.PCFSoftShadowMap; 19 | this._threejs.setPixelRatio(window.devicePixelRatio); 20 | this._threejs.setSize(window.innerWidth, window.innerHeight); 21 | 22 | this._canvas = this._threejs.domElement; 23 | document.body.appendChild(this._canvas); 24 | 25 | //Add the resize event listener 26 | window.addEventListener('resize', () => { 27 | this._OnWindowResize(); 28 | }, false); 29 | 30 | // Create the scene 31 | this._scene = new THREE.Scene(); 32 | 33 | /////////////////////////////////////////////// Add a directional light, Shadow Camera Helper and Ambient Light 34 | const dirLight = new THREE.DirectionalLight(0xffffff, 1.0); 35 | dirLight.position.set(-2, 4, 3); 36 | dirLight.castShadow = true; 37 | 38 | const shadowSize = 1.5; 39 | 40 | dirLight.shadow.mapsize = new THREE.Vector2(2048, 2048); 41 | dirLight.shadow.camera.near = 0.1; 42 | dirLight.shadow.camera.far = 100; 43 | dirLight.shadow.camera.left = -shadowSize; 44 | dirLight.shadow.camera.right = shadowSize; 45 | dirLight.shadow.camera.top = shadowSize; 46 | dirLight.shadow.camera.bottom = -shadowSize; 47 | dirLight.shadow.bias = 0.001; 48 | 49 | // Create a Group to hold the directional light 50 | this._dirLightGroup = new THREE.Group(); 51 | this._dirLightGroup.add(dirLight); 52 | this._dirLightGroup.add(dirLight.target); 53 | 54 | this._scene.add(this._dirLightGroup); 55 | 56 | // Add a shadow helper 57 | this.ShadowCameraHelper = new THREE.CameraHelper(dirLight.shadow.camera); 58 | this.ShadowCameraHelper.visible = false; 59 | this._scene.add(this.ShadowCameraHelper); 60 | 61 | // Add an ambient light 62 | const ambLight = new THREE.AmbientLight(0xffffff, 0.1); 63 | this._scene.add(ambLight); 64 | 65 | /////////////////////////////////////////////////////////////////////////////////////////////// Add the Cubemap 66 | const loader = new THREE.CubeTextureLoader(); 67 | const envTexture = loader.load([ 68 | './resources/textures/env/right.jpeg', 69 | './resources/textures/env/left.jpeg', 70 | './resources/textures/env/top.jpeg', 71 | './resources/textures/env/bottom.jpeg', 72 | './resources/textures/env/front.jpeg', 73 | './resources/textures/env/back.jpeg', // posz 74 | ]); 75 | envTexture.encoding = THREE.sRGBEncoding; 76 | this._scene.background = envTexture; 77 | 78 | /////////////////////////////////////////////////////////////////////////////////////////////// Add GroundPlane 79 | const plane = new THREE.Mesh( 80 | new THREE.PlaneGeometry(100, 100, 10, 10), 81 | new THREE.MeshStandardMaterial({ 82 | color: 0x485511, 83 | roughness: 0.8, 84 | metalness: 0.1, 85 | envMap: envTexture, 86 | envMapIntensity: 0.25 87 | })); 88 | 89 | plane.castShadow = false; 90 | plane.receiveShadow = true; 91 | plane.rotation.x = -Math.PI / 2; 92 | this._scene.add(plane); 93 | 94 | // Add grid 95 | const grid = new THREE.GridHelper(50, 100, 0xffffff, 0xffffff); 96 | this._scene.add(grid); 97 | 98 | ////////////////////////////////////////////////////////////////////////////////////////// Set the Debug Camera 99 | const fov = 60; 100 | const aspect = window.innerWidth / window.innerHeight; 101 | const near = 0.1; 102 | const far = 100.0; 103 | this.DebugCamera = new THREE.PerspectiveCamera(fov, aspect, near, far); 104 | this.DebugCamera.position.set(0, 3, 5); 105 | this.DebugCamera.lookAt(new THREE.Vector3(0, 0, 0)); 106 | 107 | // Set the Orbit Controls for the Debug Camera 108 | this.OrbitControls = new OrbitControls(this.DebugCamera, this._canvas); 109 | 110 | ////////////////////////////////////////////////////////////////////////////////////// Set the Character Camera 111 | this._CharacterCamera = new THREE.PerspectiveCamera(fov, aspect, near, far); 112 | 113 | // Add a Camera Helper to the Character Camera 114 | this.CameraHelper = new THREE.CameraHelper(this._CharacterCamera); 115 | this.CameraHelper.visible = false; 116 | 117 | this._scene.add(this.CameraHelper); 118 | 119 | //////////////////////////////////////////////////////////// Add the Character Controller and ThirdPersonCamera 120 | //this._mixers = []; 121 | this._previousRAF = null; 122 | 123 | // Create Params 124 | this._params = { 125 | camera: this._CharacterCamera, 126 | scene: this._scene, 127 | canvas: this._canvas 128 | }; 129 | 130 | // Create the Character Controller 131 | this._CharacterController = new CharacterController(this._params); 132 | 133 | // Add target to Params Object for the ThirdPersonCamera to follow 134 | this._params.target = this._CharacterController; 135 | 136 | // Create the ThirdPersonCamera 137 | this._thirdPersonCamera = new ThirdPersonCamera(this._params); 138 | 139 | /////////////////////////////////////////////////////////////////////////////////////// Request Animation Frame 140 | this._RAF(); 141 | } 142 | 143 | _OnWindowResize() { 144 | 145 | this._CharacterCamera.aspect = window.innerWidth / window.innerHeight; 146 | this._CharacterCamera.updateProjectionMatrix(); 147 | 148 | this.DebugCamera.aspect = window.innerWidth / window.innerHeight; 149 | this.DebugCamera.updateProjectionMatrix(); 150 | 151 | this._threejs.setSize(window.innerWidth, window.innerHeight); 152 | } 153 | 154 | _RAF() { 155 | requestAnimationFrame((t) => { 156 | //console.log(Math.floor(t / 1000)); 157 | if (this._previousRAF === null) { 158 | this._previousRAF = t; 159 | } 160 | 161 | this._RAF(); 162 | 163 | if (this._CharacterController._input._keys.debug === true) { // Render Debug Camera 164 | 165 | this._threejs.render(this._scene, this.DebugCamera); 166 | 167 | } else { // Render Character Camera 168 | 169 | this._threejs.render(this._scene, this._CharacterCamera); 170 | } 171 | 172 | this._Step(t - this._previousRAF); 173 | this._previousRAF = t; 174 | }); 175 | } 176 | 177 | _Step(timeElapsed) { 178 | 179 | const timeElapsedS = timeElapsed * 0.001; 180 | 181 | //if (this._mixers) { this._mixers.map(m => m.update(timeElapsedS)); } 182 | if (this._CharacterController) { this._CharacterController.Update(timeElapsedS); } 183 | 184 | if (this._thirdPersonCamera) { this._thirdPersonCamera.Update(timeElapsedS); } 185 | 186 | this._dirLightGroup.position 187 | .set(this._CharacterController._position.x, 188 | this._CharacterController._position.y, 189 | this._CharacterController._position.z); 190 | 191 | 192 | if (this._CharacterController._input._keys.debug === true) { // Activate Debug Helpers 193 | 194 | this.CameraHelper.visible = true; 195 | this.ShadowCameraHelper.visible = true; 196 | 197 | } else { 198 | 199 | this.CameraHelper.visible = false; 200 | this.ShadowCameraHelper.visible = false; 201 | } 202 | 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /modules/States.js: -------------------------------------------------------------------------------- 1 | 2 | import * as THREE from 'three'; 3 | import { State } from './State'; 4 | 5 | export class IdleState extends State { 6 | constructor(parent) { 7 | super(parent); 8 | } 9 | 10 | get Name() { 11 | return 'idle'; 12 | } 13 | 14 | Enter(prevState) { 15 | const idleAction = this._parent._proxy._animations['idle'].action; 16 | if (prevState) { 17 | const prevAction = this._parent._proxy._animations[prevState.Name].action; 18 | idleAction.time = 0.0; 19 | idleAction.enabled = true; 20 | idleAction.setEffectiveTimeScale(1.0); 21 | idleAction.setEffectiveWeight(1.0); 22 | idleAction.crossFadeFrom(prevAction, 0.2, true); 23 | idleAction.play(); 24 | } else { 25 | idleAction.play(); 26 | } 27 | } 28 | 29 | Exit() { 30 | } 31 | 32 | Update(_, input) { 33 | if (input._keys.forward) { 34 | this._parent.SetState('walk'); 35 | } else if (input._keys.backward) { 36 | this._parent.SetState('walkback'); 37 | } else if (input._keys.space) { 38 | this._parent.SetState('jump'); 39 | } else if (input._keys.effe) { 40 | this._parent.SetState('dance'); 41 | } 42 | } 43 | }; 44 | 45 | export class DanceState extends State { 46 | constructor(parent) { 47 | super(parent); 48 | 49 | this._FinishedCallback = () => { 50 | this._Finished(); 51 | } 52 | } 53 | 54 | get Name() { 55 | return 'dance'; 56 | } 57 | 58 | Enter(prevState) { 59 | const curAction = this._parent._proxy._animations['dance'].action; 60 | const mixer = curAction.getMixer(); 61 | mixer.addEventListener('finished', this._FinishedCallback); 62 | 63 | if (prevState) { 64 | const prevAction = this._parent._proxy._animations[prevState.Name].action; 65 | 66 | curAction.reset(); 67 | curAction.setLoop(THREE.LoopOnce, 1); 68 | curAction.clampWhenFinished = true; 69 | curAction.crossFadeFrom(prevAction, 0.2, true); 70 | curAction.play(); 71 | } else { 72 | curAction.play(); 73 | } 74 | } 75 | 76 | _Finished() { 77 | this._Cleanup(); 78 | this._parent.SetState('idle'); 79 | } 80 | 81 | _Cleanup() { 82 | const action = this._parent._proxy._animations['dance'].action; 83 | action.getMixer().removeEventListener('finished', this._CleanupCallback); 84 | } 85 | 86 | Exit() { 87 | this._Cleanup(); 88 | } 89 | 90 | Update(_) { 91 | } 92 | }; 93 | 94 | export class JumpState extends State { 95 | constructor(parent) { 96 | super(parent); 97 | 98 | this._FinishedCallback = () => { 99 | this._Finished(); 100 | } 101 | } 102 | 103 | get Name() { 104 | return 'jump'; 105 | } 106 | 107 | Enter(prevState) { 108 | const curAction = this._parent._proxy._animations['jump'].action; 109 | const mixer = curAction.getMixer(); 110 | mixer.addEventListener('finished', this._FinishedCallback); 111 | 112 | if (prevState) { 113 | const prevAction = this._parent._proxy._animations[prevState.Name].action; 114 | 115 | curAction.reset(); 116 | curAction.setLoop(THREE.LoopOnce, 1); 117 | curAction.clampWhenFinished = true; 118 | curAction.crossFadeFrom(prevAction, 0.1, true); 119 | curAction.play(); 120 | } else { 121 | curAction.play(); 122 | } 123 | } 124 | 125 | _Finished() { 126 | this._Cleanup(); 127 | this._parent.SetState('idle'); 128 | } 129 | 130 | _Cleanup() { 131 | const action = this._parent._proxy._animations['jump'].action; 132 | action.getMixer().removeEventListener('finished', this._CleanupCallback); 133 | } 134 | 135 | Exit() { 136 | this._Cleanup(); 137 | } 138 | 139 | Update(_) { 140 | } 141 | }; 142 | 143 | export class WalkState extends State { 144 | constructor(parent) { 145 | super(parent); 146 | } 147 | 148 | get Name() { 149 | return 'walk'; 150 | } 151 | 152 | Enter(prevState) { 153 | const curAction = this._parent._proxy._animations['walk'].action; 154 | if (prevState) { 155 | const prevAction = this._parent._proxy._animations[prevState.Name].action; 156 | 157 | curAction.enabled = true; 158 | 159 | if (prevState.Name == 'run') { 160 | const ratio = curAction.getClip().duration / prevAction.getClip().duration; 161 | curAction.time = prevAction.time * ratio; 162 | } else { 163 | curAction.time = 0.0; 164 | curAction.setEffectiveTimeScale(1.0); 165 | curAction.setEffectiveWeight(1.0); 166 | } 167 | 168 | curAction.crossFadeFrom(prevAction, 0.5, true); 169 | curAction.play(); 170 | } else { 171 | curAction.play(); 172 | } 173 | } 174 | 175 | Exit() { 176 | } 177 | 178 | Update(timeElapsed, input) { 179 | if (input._keys.forward) { 180 | if (input._keys.shift) { 181 | this._parent.SetState('run'); 182 | } 183 | return; 184 | } 185 | 186 | this._parent.SetState('idle'); 187 | } 188 | }; 189 | 190 | export class WalkBackState extends State { 191 | constructor(parent) { 192 | super(parent); 193 | } 194 | 195 | get Name() { 196 | return 'walkback'; 197 | } 198 | 199 | Enter(prevState) { 200 | const curAction = this._parent._proxy._animations['walkback'].action; 201 | if (prevState) { 202 | const prevAction = this._parent._proxy._animations[prevState.Name].action; 203 | 204 | curAction.enabled = true; 205 | 206 | if (prevState.Name == 'run') { 207 | const ratio = curAction.getClip().duration / prevAction.getClip().duration; 208 | curAction.time = prevAction.time * ratio; 209 | } else { 210 | curAction.time = 0.0; 211 | curAction.setEffectiveTimeScale(1.0); 212 | curAction.setEffectiveWeight(1.0); 213 | } 214 | 215 | curAction.crossFadeFrom(prevAction, 0.5, true); 216 | curAction.play(); 217 | } else { 218 | curAction.play(); 219 | } 220 | } 221 | 222 | Exit() { 223 | } 224 | 225 | Update(timeElapsed, input) { 226 | if (input._keys.backward) { 227 | if (input._keys.shift) { 228 | //this._parent.SetState('run'); 229 | } 230 | return; 231 | } 232 | 233 | this._parent.SetState('idle'); 234 | } 235 | }; 236 | 237 | export class RunState extends State { 238 | constructor(parent) { 239 | super(parent); 240 | } 241 | 242 | get Name() { 243 | return 'run'; 244 | } 245 | 246 | Enter(prevState) { 247 | const curAction = this._parent._proxy._animations['run'].action; 248 | 249 | if (prevState) { 250 | 251 | const prevAction = this._parent._proxy._animations[prevState.Name].action; 252 | curAction.enabled = true; 253 | 254 | if (prevState.Name == 'walk') { 255 | const ratio = curAction.getClip().duration / prevAction.getClip().duration; 256 | curAction.time = prevAction.time * ratio; 257 | 258 | } else if (prevState.Name == 'jumprun') { 259 | curAction.time = 0.0; 260 | curAction.setEffectiveTimeScale(1.0); 261 | curAction.setEffectiveWeight(1.0); 262 | curAction.crossFadeFrom(prevAction, 1, true); 263 | curAction.play(); 264 | 265 | } else { 266 | curAction.time = 0.0; 267 | curAction.setEffectiveTimeScale(1.0); 268 | curAction.setEffectiveWeight(1.0); 269 | 270 | } 271 | 272 | curAction.crossFadeFrom(prevAction, 0.1, true); 273 | curAction.play(); 274 | 275 | } else { 276 | curAction.play(); 277 | } 278 | } 279 | 280 | Exit() { 281 | } 282 | 283 | Update(timeElapsed, input) { 284 | if (input._keys.forward) { 285 | if (!input._keys.shift) { 286 | this._parent.SetState('walk'); 287 | } 288 | if (input._keys.space) { 289 | this._parent.SetState('jumprun'); 290 | } 291 | return; 292 | } 293 | 294 | this._parent.SetState('idle'); 295 | } 296 | }; 297 | 298 | export class JumpRunState extends State { 299 | constructor(parent) { 300 | super(parent); 301 | 302 | this._FinishedCallback = () => { 303 | this._Finished(); 304 | } 305 | } 306 | 307 | get Name() { 308 | return 'jumprun'; 309 | } 310 | 311 | Enter(prevState) { 312 | const curAction = this._parent._proxy._animations['jumprun'].action; 313 | const mixer = curAction.getMixer(); 314 | mixer.addEventListener('finished', this._FinishedCallback); 315 | 316 | if (prevState) { 317 | const prevAction = this._parent._proxy._animations[prevState.Name].action; 318 | 319 | curAction.reset(); 320 | curAction.setLoop(THREE.LoopOnce, 1); 321 | curAction.clampWhenFinished = true; 322 | curAction.crossFadeFrom(prevAction, 0.1, true); 323 | curAction.play(); 324 | } else { 325 | curAction.play(); 326 | } 327 | } 328 | 329 | _Finished() { 330 | this._Cleanup(); 331 | this._parent.SetState('run'); 332 | } 333 | 334 | _Cleanup() { 335 | const action = this._parent._proxy._animations['jumprun'].action; 336 | action.getMixer().removeEventListener('finished', this._CleanupCallback); 337 | } 338 | 339 | Exit() { 340 | this._Cleanup(); 341 | } 342 | 343 | Update(_) { 344 | } 345 | }; -------------------------------------------------------------------------------- /public/RobeSantoro-ThreeJS-Avatar-Controller-CodeSee.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 44 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 56 | 57 | 58 | modules/ 59 | 60 | 61 | 62 | 63 | 65 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 77 | 78 | 79 | public/ 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 96 | 97 | 98 | decoder/ 99 | 100 | 101 | 102 | 103 | 104 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 116 | 117 | 118 | resources/ 119 | 120 | 121 | 122 | 123 | 125 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 137 | 138 | 139 | models/ 140 | 141 | 142 | 143 | 144 | 146 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 158 | 159 | 160 | animations/ 161 | 162 | 163 | 164 | 165 | 167 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 179 | 180 | 181 | textures/ 182 | 183 | 184 | 185 | 186 | 188 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 200 | 201 | 202 | env/ 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 258 | 259 | 260 | ThirdPersonCamera.js 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 271 | 272 | 273 | CharacterControllerProxy.js 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 284 | 285 | 286 | CharacterControllerInput.js 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 297 | 298 | 299 | CharacterController.js 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 310 | 311 | 312 | CharacterFSM.js 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 323 | 324 | 325 | FiniteStateMachine.js 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 336 | 337 | 338 | States.js 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 349 | 350 | 351 | State.js 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 362 | 363 | 364 | index.html 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 375 | 376 | 377 | style.css 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 388 | 389 | 390 | World.js 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 401 | 402 | 403 | main.js 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 414 | 415 | 416 | README.md 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 427 | 428 | 429 | draco_decoder.js 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 440 | 441 | 442 | draco_decoder.wasm 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 453 | 454 | 455 | draco_wasm_wrapper.js 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 466 | 467 | Animations.glb 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 477 | 478 | Avatar.glb 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 488 | 489 | back.jpeg 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 499 | 500 | bottom.jpeg 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 510 | 511 | front.jpeg 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 521 | 522 | left.jpeg 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 532 | 533 | right.jpeg 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 543 | 544 | top.jpeg 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 554 | 555 | vite.config.js 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 565 | 566 | tailwind.config.js 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 576 | 577 | postcss.config.js 578 | 579 | 580 | 581 | 582 | 583 | 584 | -------------------------------------------------------------------------------- /public/decoder/draco_wasm_wrapper.js: -------------------------------------------------------------------------------- 1 | var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.arrayIteratorImpl=function(f){var m=0;return function(){return m=d);)++b;if(16k?d+=String.fromCharCode(k):(k-=65536,d+=String.fromCharCode(55296|k>>10,56320|k&1023))}}else d+=String.fromCharCode(k)}return d}function X(a,c){return a?h(ca,a,c):""}function e(a,c){0=d&&(d=65536+((d&1023)<<10)|a.charCodeAt(++b)&1023);127>=d?++c:c=2047>=d?c+2:65535>=d?c+3:c+4}c=Array(c+1);b=0;d=c.length;if(0=e){var f=a.charCodeAt(++k);e=65536+((e&1023)<<10)|f&1023}if(127>=e){if(b>=d)break;c[b++]=e}else{if(2047>=e){if(b+1>=d)break;c[b++]=192|e>>6}else{if(65535>=e){if(b+2>=d)break;c[b++]=224|e>>12}else{if(b+3>=d)break;c[b++]=240|e>>18;c[b++]=128|e>>12&63}c[b++]=128|e>>6&63}c[b++]=128| 18 | e&63}}c[b]=0}a=n.alloc(c,T);n.copy(c,T,a)}return a}function x(){throw"cannot construct a Status, no constructor in IDL";}function A(){this.ptr=Oa();u(A)[this.ptr]=this}function B(){this.ptr=Pa();u(B)[this.ptr]=this}function C(){this.ptr=Qa();u(C)[this.ptr]=this}function D(){this.ptr=Ra();u(D)[this.ptr]=this}function E(){this.ptr=Sa();u(E)[this.ptr]=this}function q(){this.ptr=Ta();u(q)[this.ptr]=this}function J(){this.ptr=Ua();u(J)[this.ptr]=this}function w(){this.ptr=Va();u(w)[this.ptr]=this}function F(){this.ptr= 19 | Wa();u(F)[this.ptr]=this}function r(){this.ptr=Xa();u(r)[this.ptr]=this}function G(){this.ptr=Ya();u(G)[this.ptr]=this}function H(){this.ptr=Za();u(H)[this.ptr]=this}function O(){this.ptr=$a();u(O)[this.ptr]=this}function K(){this.ptr=ab();u(K)[this.ptr]=this}function g(){this.ptr=bb();u(g)[this.ptr]=this}function y(){this.ptr=cb();u(y)[this.ptr]=this}function Q(){throw"cannot construct a VoidPtr, no constructor in IDL";}function I(){this.ptr=db();u(I)[this.ptr]=this}function L(){this.ptr=eb();u(L)[this.ptr]= 20 | this}m=m||{};var a="undefined"!==typeof m?m:{},Ga=!1,Ha=!1;a.onRuntimeInitialized=function(){Ga=!0;if(Ha&&"function"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};a.onModuleParsed=function(){Ha=!0;if(Ga&&"function"===typeof a.onModuleLoaded)a.onModuleLoaded(a)};a.isVersionSupported=function(a){if("string"!==typeof a)return!1;a=a.split(".");return 2>a.length||3=a[1]?!0:0!=a[0]||10>2]},getStr:function(){return X(R.get())}, 26 | get64:function(){var a=R.get();R.get();return a},getZero:function(){R.get()}},Ka={__cxa_allocate_exception:function(a){return ib(a)},__cxa_throw:function(a,c,b){"uncaught_exception"in ta?ta.uncaught_exceptions++:ta.uncaught_exceptions=1;throw a;},abort:function(){z()},emscripten_get_sbrk_ptr:function(){return 13664},emscripten_memcpy_big:function(a,c,b){ca.set(ca.subarray(c,c+b),a)},emscripten_resize_heap:function(a){if(2147418112= 27 | c?e(2*c,65536):Math.min(e((3*c+2147483648)/4,65536),2147418112);a:{try{ia.grow(c-ka.byteLength+65535>>16);l(ia.buffer);var b=1;break a}catch(d){}b=void 0}return b?!0:!1},environ_get:function(a,c){var b=0;ba().forEach(function(d,e){var f=c+b;e=P[a+4*e>>2]=f;for(f=0;f>0]=d.charCodeAt(f);T[e>>0]=0;b+=d.length+1});return 0},environ_sizes_get:function(a,c){var b=ba();P[a>>2]=b.length;var d=0;b.forEach(function(a){d+=a.length+1});P[c>>2]=d;return 0},fd_close:function(a){return 0},fd_seek:function(a, 28 | c,b,d,e){return 0},fd_write:function(a,c,b,d){try{for(var e=0,f=0;f>2],k=P[c+(8*f+4)>>2],h=0;h>2]=e;return 0}catch(ua){return"undefined"!==typeof FS&&ua instanceof FS.ErrnoError||z(ua),ua.errno}},memory:ia,setTempRet0:function(a){},table:gb},La=function(){function e(c,b){a.asm=c.exports;aa--;a.monitorRunDependencies&&a.monitorRunDependencies(aa);0==aa&&(null!==sa&&(clearInterval(sa),sa=null),ja&&(c=ja,ja=null,c()))}function c(a){e(a.instance)} 29 | function b(a){return Ma().then(function(a){return WebAssembly.instantiate(a,d)}).then(a,function(a){Y("failed to asynchronously prepare wasm: "+a);z(a)})}var d={env:Ka,wasi_unstable:Ka};aa++;a.monitorRunDependencies&&a.monitorRunDependencies(aa);if(a.instantiateWasm)try{return a.instantiateWasm(d,e)}catch(Na){return Y("Module.instantiateWasm callback failed with error: "+Na),!1}(function(){if(da||"function"!==typeof WebAssembly.instantiateStreaming||va(U)||"function"!==typeof fetch)return b(c);fetch(U, 30 | {credentials:"same-origin"}).then(function(a){return WebAssembly.instantiateStreaming(a,d).then(c,function(a){Y("wasm streaming compile failed: "+a);Y("falling back to ArrayBuffer instantiation");b(c)})})})();return{}}();a.asm=La;var hb=a.___wasm_call_ctors=function(){return a.asm.__wasm_call_ctors.apply(null,arguments)},jb=a._emscripten_bind_Status_code_0=function(){return a.asm.emscripten_bind_Status_code_0.apply(null,arguments)},kb=a._emscripten_bind_Status_ok_0=function(){return a.asm.emscripten_bind_Status_ok_0.apply(null, 31 | arguments)},lb=a._emscripten_bind_Status_error_msg_0=function(){return a.asm.emscripten_bind_Status_error_msg_0.apply(null,arguments)},mb=a._emscripten_bind_Status___destroy___0=function(){return a.asm.emscripten_bind_Status___destroy___0.apply(null,arguments)},Oa=a._emscripten_bind_DracoUInt16Array_DracoUInt16Array_0=function(){return a.asm.emscripten_bind_DracoUInt16Array_DracoUInt16Array_0.apply(null,arguments)},nb=a._emscripten_bind_DracoUInt16Array_GetValue_1=function(){return a.asm.emscripten_bind_DracoUInt16Array_GetValue_1.apply(null, 32 | arguments)},ob=a._emscripten_bind_DracoUInt16Array_size_0=function(){return a.asm.emscripten_bind_DracoUInt16Array_size_0.apply(null,arguments)},pb=a._emscripten_bind_DracoUInt16Array___destroy___0=function(){return a.asm.emscripten_bind_DracoUInt16Array___destroy___0.apply(null,arguments)},Pa=a._emscripten_bind_PointCloud_PointCloud_0=function(){return a.asm.emscripten_bind_PointCloud_PointCloud_0.apply(null,arguments)},qb=a._emscripten_bind_PointCloud_num_attributes_0=function(){return a.asm.emscripten_bind_PointCloud_num_attributes_0.apply(null, 33 | arguments)},rb=a._emscripten_bind_PointCloud_num_points_0=function(){return a.asm.emscripten_bind_PointCloud_num_points_0.apply(null,arguments)},sb=a._emscripten_bind_PointCloud___destroy___0=function(){return a.asm.emscripten_bind_PointCloud___destroy___0.apply(null,arguments)},Qa=a._emscripten_bind_DracoUInt8Array_DracoUInt8Array_0=function(){return a.asm.emscripten_bind_DracoUInt8Array_DracoUInt8Array_0.apply(null,arguments)},tb=a._emscripten_bind_DracoUInt8Array_GetValue_1=function(){return a.asm.emscripten_bind_DracoUInt8Array_GetValue_1.apply(null, 34 | arguments)},ub=a._emscripten_bind_DracoUInt8Array_size_0=function(){return a.asm.emscripten_bind_DracoUInt8Array_size_0.apply(null,arguments)},vb=a._emscripten_bind_DracoUInt8Array___destroy___0=function(){return a.asm.emscripten_bind_DracoUInt8Array___destroy___0.apply(null,arguments)},Ra=a._emscripten_bind_DracoUInt32Array_DracoUInt32Array_0=function(){return a.asm.emscripten_bind_DracoUInt32Array_DracoUInt32Array_0.apply(null,arguments)},wb=a._emscripten_bind_DracoUInt32Array_GetValue_1=function(){return a.asm.emscripten_bind_DracoUInt32Array_GetValue_1.apply(null, 35 | arguments)},xb=a._emscripten_bind_DracoUInt32Array_size_0=function(){return a.asm.emscripten_bind_DracoUInt32Array_size_0.apply(null,arguments)},yb=a._emscripten_bind_DracoUInt32Array___destroy___0=function(){return a.asm.emscripten_bind_DracoUInt32Array___destroy___0.apply(null,arguments)},Sa=a._emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0=function(){return a.asm.emscripten_bind_AttributeOctahedronTransform_AttributeOctahedronTransform_0.apply(null,arguments)},zb=a._emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1= 36 | function(){return a.asm.emscripten_bind_AttributeOctahedronTransform_InitFromAttribute_1.apply(null,arguments)},Ab=a._emscripten_bind_AttributeOctahedronTransform_quantization_bits_0=function(){return a.asm.emscripten_bind_AttributeOctahedronTransform_quantization_bits_0.apply(null,arguments)},Bb=a._emscripten_bind_AttributeOctahedronTransform___destroy___0=function(){return a.asm.emscripten_bind_AttributeOctahedronTransform___destroy___0.apply(null,arguments)},Ta=a._emscripten_bind_PointAttribute_PointAttribute_0= 37 | function(){return a.asm.emscripten_bind_PointAttribute_PointAttribute_0.apply(null,arguments)},Cb=a._emscripten_bind_PointAttribute_size_0=function(){return a.asm.emscripten_bind_PointAttribute_size_0.apply(null,arguments)},Db=a._emscripten_bind_PointAttribute_GetAttributeTransformData_0=function(){return a.asm.emscripten_bind_PointAttribute_GetAttributeTransformData_0.apply(null,arguments)},Eb=a._emscripten_bind_PointAttribute_attribute_type_0=function(){return a.asm.emscripten_bind_PointAttribute_attribute_type_0.apply(null, 38 | arguments)},Fb=a._emscripten_bind_PointAttribute_data_type_0=function(){return a.asm.emscripten_bind_PointAttribute_data_type_0.apply(null,arguments)},Gb=a._emscripten_bind_PointAttribute_num_components_0=function(){return a.asm.emscripten_bind_PointAttribute_num_components_0.apply(null,arguments)},Hb=a._emscripten_bind_PointAttribute_normalized_0=function(){return a.asm.emscripten_bind_PointAttribute_normalized_0.apply(null,arguments)},Ib=a._emscripten_bind_PointAttribute_byte_stride_0=function(){return a.asm.emscripten_bind_PointAttribute_byte_stride_0.apply(null, 39 | arguments)},Jb=a._emscripten_bind_PointAttribute_byte_offset_0=function(){return a.asm.emscripten_bind_PointAttribute_byte_offset_0.apply(null,arguments)},Kb=a._emscripten_bind_PointAttribute_unique_id_0=function(){return a.asm.emscripten_bind_PointAttribute_unique_id_0.apply(null,arguments)},Lb=a._emscripten_bind_PointAttribute___destroy___0=function(){return a.asm.emscripten_bind_PointAttribute___destroy___0.apply(null,arguments)},Ua=a._emscripten_bind_AttributeTransformData_AttributeTransformData_0= 40 | function(){return a.asm.emscripten_bind_AttributeTransformData_AttributeTransformData_0.apply(null,arguments)},Mb=a._emscripten_bind_AttributeTransformData_transform_type_0=function(){return a.asm.emscripten_bind_AttributeTransformData_transform_type_0.apply(null,arguments)},Nb=a._emscripten_bind_AttributeTransformData___destroy___0=function(){return a.asm.emscripten_bind_AttributeTransformData___destroy___0.apply(null,arguments)},Va=a._emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0= 41 | function(){return a.asm.emscripten_bind_AttributeQuantizationTransform_AttributeQuantizationTransform_0.apply(null,arguments)},Ob=a._emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1=function(){return a.asm.emscripten_bind_AttributeQuantizationTransform_InitFromAttribute_1.apply(null,arguments)},Pb=a._emscripten_bind_AttributeQuantizationTransform_quantization_bits_0=function(){return a.asm.emscripten_bind_AttributeQuantizationTransform_quantization_bits_0.apply(null,arguments)}, 42 | Qb=a._emscripten_bind_AttributeQuantizationTransform_min_value_1=function(){return a.asm.emscripten_bind_AttributeQuantizationTransform_min_value_1.apply(null,arguments)},Rb=a._emscripten_bind_AttributeQuantizationTransform_range_0=function(){return a.asm.emscripten_bind_AttributeQuantizationTransform_range_0.apply(null,arguments)},Sb=a._emscripten_bind_AttributeQuantizationTransform___destroy___0=function(){return a.asm.emscripten_bind_AttributeQuantizationTransform___destroy___0.apply(null,arguments)}, 43 | Wa=a._emscripten_bind_DracoInt8Array_DracoInt8Array_0=function(){return a.asm.emscripten_bind_DracoInt8Array_DracoInt8Array_0.apply(null,arguments)},Tb=a._emscripten_bind_DracoInt8Array_GetValue_1=function(){return a.asm.emscripten_bind_DracoInt8Array_GetValue_1.apply(null,arguments)},Ub=a._emscripten_bind_DracoInt8Array_size_0=function(){return a.asm.emscripten_bind_DracoInt8Array_size_0.apply(null,arguments)},Vb=a._emscripten_bind_DracoInt8Array___destroy___0=function(){return a.asm.emscripten_bind_DracoInt8Array___destroy___0.apply(null, 44 | arguments)},Xa=a._emscripten_bind_MetadataQuerier_MetadataQuerier_0=function(){return a.asm.emscripten_bind_MetadataQuerier_MetadataQuerier_0.apply(null,arguments)},Wb=a._emscripten_bind_MetadataQuerier_HasEntry_2=function(){return a.asm.emscripten_bind_MetadataQuerier_HasEntry_2.apply(null,arguments)},Xb=a._emscripten_bind_MetadataQuerier_GetIntEntry_2=function(){return a.asm.emscripten_bind_MetadataQuerier_GetIntEntry_2.apply(null,arguments)},Yb=a._emscripten_bind_MetadataQuerier_GetIntEntryArray_3= 45 | function(){return a.asm.emscripten_bind_MetadataQuerier_GetIntEntryArray_3.apply(null,arguments)},Zb=a._emscripten_bind_MetadataQuerier_GetDoubleEntry_2=function(){return a.asm.emscripten_bind_MetadataQuerier_GetDoubleEntry_2.apply(null,arguments)},$b=a._emscripten_bind_MetadataQuerier_GetStringEntry_2=function(){return a.asm.emscripten_bind_MetadataQuerier_GetStringEntry_2.apply(null,arguments)},ac=a._emscripten_bind_MetadataQuerier_NumEntries_1=function(){return a.asm.emscripten_bind_MetadataQuerier_NumEntries_1.apply(null, 46 | arguments)},bc=a._emscripten_bind_MetadataQuerier_GetEntryName_2=function(){return a.asm.emscripten_bind_MetadataQuerier_GetEntryName_2.apply(null,arguments)},cc=a._emscripten_bind_MetadataQuerier___destroy___0=function(){return a.asm.emscripten_bind_MetadataQuerier___destroy___0.apply(null,arguments)},Ya=a._emscripten_bind_DracoInt16Array_DracoInt16Array_0=function(){return a.asm.emscripten_bind_DracoInt16Array_DracoInt16Array_0.apply(null,arguments)},dc=a._emscripten_bind_DracoInt16Array_GetValue_1= 47 | function(){return a.asm.emscripten_bind_DracoInt16Array_GetValue_1.apply(null,arguments)},ec=a._emscripten_bind_DracoInt16Array_size_0=function(){return a.asm.emscripten_bind_DracoInt16Array_size_0.apply(null,arguments)},fc=a._emscripten_bind_DracoInt16Array___destroy___0=function(){return a.asm.emscripten_bind_DracoInt16Array___destroy___0.apply(null,arguments)},Za=a._emscripten_bind_DracoFloat32Array_DracoFloat32Array_0=function(){return a.asm.emscripten_bind_DracoFloat32Array_DracoFloat32Array_0.apply(null, 48 | arguments)},gc=a._emscripten_bind_DracoFloat32Array_GetValue_1=function(){return a.asm.emscripten_bind_DracoFloat32Array_GetValue_1.apply(null,arguments)},hc=a._emscripten_bind_DracoFloat32Array_size_0=function(){return a.asm.emscripten_bind_DracoFloat32Array_size_0.apply(null,arguments)},ic=a._emscripten_bind_DracoFloat32Array___destroy___0=function(){return a.asm.emscripten_bind_DracoFloat32Array___destroy___0.apply(null,arguments)},$a=a._emscripten_bind_GeometryAttribute_GeometryAttribute_0=function(){return a.asm.emscripten_bind_GeometryAttribute_GeometryAttribute_0.apply(null, 49 | arguments)},jc=a._emscripten_bind_GeometryAttribute___destroy___0=function(){return a.asm.emscripten_bind_GeometryAttribute___destroy___0.apply(null,arguments)},ab=a._emscripten_bind_DecoderBuffer_DecoderBuffer_0=function(){return a.asm.emscripten_bind_DecoderBuffer_DecoderBuffer_0.apply(null,arguments)},kc=a._emscripten_bind_DecoderBuffer_Init_2=function(){return a.asm.emscripten_bind_DecoderBuffer_Init_2.apply(null,arguments)},lc=a._emscripten_bind_DecoderBuffer___destroy___0=function(){return a.asm.emscripten_bind_DecoderBuffer___destroy___0.apply(null, 50 | arguments)},bb=a._emscripten_bind_Decoder_Decoder_0=function(){return a.asm.emscripten_bind_Decoder_Decoder_0.apply(null,arguments)},mc=a._emscripten_bind_Decoder_GetEncodedGeometryType_1=function(){return a.asm.emscripten_bind_Decoder_GetEncodedGeometryType_1.apply(null,arguments)},nc=a._emscripten_bind_Decoder_DecodeBufferToPointCloud_2=function(){return a.asm.emscripten_bind_Decoder_DecodeBufferToPointCloud_2.apply(null,arguments)},oc=a._emscripten_bind_Decoder_DecodeBufferToMesh_2=function(){return a.asm.emscripten_bind_Decoder_DecodeBufferToMesh_2.apply(null, 51 | arguments)},pc=a._emscripten_bind_Decoder_GetAttributeId_2=function(){return a.asm.emscripten_bind_Decoder_GetAttributeId_2.apply(null,arguments)},qc=a._emscripten_bind_Decoder_GetAttributeIdByName_2=function(){return a.asm.emscripten_bind_Decoder_GetAttributeIdByName_2.apply(null,arguments)},rc=a._emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3=function(){return a.asm.emscripten_bind_Decoder_GetAttributeIdByMetadataEntry_3.apply(null,arguments)},sc=a._emscripten_bind_Decoder_GetAttribute_2= 52 | function(){return a.asm.emscripten_bind_Decoder_GetAttribute_2.apply(null,arguments)},tc=a._emscripten_bind_Decoder_GetAttributeByUniqueId_2=function(){return a.asm.emscripten_bind_Decoder_GetAttributeByUniqueId_2.apply(null,arguments)},uc=a._emscripten_bind_Decoder_GetMetadata_1=function(){return a.asm.emscripten_bind_Decoder_GetMetadata_1.apply(null,arguments)},vc=a._emscripten_bind_Decoder_GetAttributeMetadata_2=function(){return a.asm.emscripten_bind_Decoder_GetAttributeMetadata_2.apply(null, 53 | arguments)},wc=a._emscripten_bind_Decoder_GetFaceFromMesh_3=function(){return a.asm.emscripten_bind_Decoder_GetFaceFromMesh_3.apply(null,arguments)},xc=a._emscripten_bind_Decoder_GetTriangleStripsFromMesh_2=function(){return a.asm.emscripten_bind_Decoder_GetTriangleStripsFromMesh_2.apply(null,arguments)},yc=a._emscripten_bind_Decoder_GetTrianglesUInt16Array_3=function(){return a.asm.emscripten_bind_Decoder_GetTrianglesUInt16Array_3.apply(null,arguments)},zc=a._emscripten_bind_Decoder_GetTrianglesUInt32Array_3= 54 | function(){return a.asm.emscripten_bind_Decoder_GetTrianglesUInt32Array_3.apply(null,arguments)},Ac=a._emscripten_bind_Decoder_GetAttributeFloat_3=function(){return a.asm.emscripten_bind_Decoder_GetAttributeFloat_3.apply(null,arguments)},Bc=a._emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3=function(){return a.asm.emscripten_bind_Decoder_GetAttributeFloatForAllPoints_3.apply(null,arguments)},Cc=a._emscripten_bind_Decoder_GetAttributeIntForAllPoints_3=function(){return a.asm.emscripten_bind_Decoder_GetAttributeIntForAllPoints_3.apply(null, 55 | arguments)},Dc=a._emscripten_bind_Decoder_GetAttributeInt8ForAllPoints_3=function(){return a.asm.emscripten_bind_Decoder_GetAttributeInt8ForAllPoints_3.apply(null,arguments)},Ec=a._emscripten_bind_Decoder_GetAttributeUInt8ForAllPoints_3=function(){return a.asm.emscripten_bind_Decoder_GetAttributeUInt8ForAllPoints_3.apply(null,arguments)},Fc=a._emscripten_bind_Decoder_GetAttributeInt16ForAllPoints_3=function(){return a.asm.emscripten_bind_Decoder_GetAttributeInt16ForAllPoints_3.apply(null,arguments)}, 56 | Gc=a._emscripten_bind_Decoder_GetAttributeUInt16ForAllPoints_3=function(){return a.asm.emscripten_bind_Decoder_GetAttributeUInt16ForAllPoints_3.apply(null,arguments)},Hc=a._emscripten_bind_Decoder_GetAttributeInt32ForAllPoints_3=function(){return a.asm.emscripten_bind_Decoder_GetAttributeInt32ForAllPoints_3.apply(null,arguments)},Ic=a._emscripten_bind_Decoder_GetAttributeUInt32ForAllPoints_3=function(){return a.asm.emscripten_bind_Decoder_GetAttributeUInt32ForAllPoints_3.apply(null,arguments)},Jc= 57 | a._emscripten_bind_Decoder_GetAttributeDataArrayForAllPoints_5=function(){return a.asm.emscripten_bind_Decoder_GetAttributeDataArrayForAllPoints_5.apply(null,arguments)},Kc=a._emscripten_bind_Decoder_SkipAttributeTransform_1=function(){return a.asm.emscripten_bind_Decoder_SkipAttributeTransform_1.apply(null,arguments)},Lc=a._emscripten_bind_Decoder___destroy___0=function(){return a.asm.emscripten_bind_Decoder___destroy___0.apply(null,arguments)},cb=a._emscripten_bind_Mesh_Mesh_0=function(){return a.asm.emscripten_bind_Mesh_Mesh_0.apply(null, 58 | arguments)},Mc=a._emscripten_bind_Mesh_num_faces_0=function(){return a.asm.emscripten_bind_Mesh_num_faces_0.apply(null,arguments)},Nc=a._emscripten_bind_Mesh_num_attributes_0=function(){return a.asm.emscripten_bind_Mesh_num_attributes_0.apply(null,arguments)},Oc=a._emscripten_bind_Mesh_num_points_0=function(){return a.asm.emscripten_bind_Mesh_num_points_0.apply(null,arguments)},Pc=a._emscripten_bind_Mesh___destroy___0=function(){return a.asm.emscripten_bind_Mesh___destroy___0.apply(null,arguments)}, 59 | Qc=a._emscripten_bind_VoidPtr___destroy___0=function(){return a.asm.emscripten_bind_VoidPtr___destroy___0.apply(null,arguments)},db=a._emscripten_bind_DracoInt32Array_DracoInt32Array_0=function(){return a.asm.emscripten_bind_DracoInt32Array_DracoInt32Array_0.apply(null,arguments)},Rc=a._emscripten_bind_DracoInt32Array_GetValue_1=function(){return a.asm.emscripten_bind_DracoInt32Array_GetValue_1.apply(null,arguments)},Sc=a._emscripten_bind_DracoInt32Array_size_0=function(){return a.asm.emscripten_bind_DracoInt32Array_size_0.apply(null, 60 | arguments)},Tc=a._emscripten_bind_DracoInt32Array___destroy___0=function(){return a.asm.emscripten_bind_DracoInt32Array___destroy___0.apply(null,arguments)},eb=a._emscripten_bind_Metadata_Metadata_0=function(){return a.asm.emscripten_bind_Metadata_Metadata_0.apply(null,arguments)},Uc=a._emscripten_bind_Metadata___destroy___0=function(){return a.asm.emscripten_bind_Metadata___destroy___0.apply(null,arguments)},Vc=a._emscripten_enum_draco_StatusCode_OK=function(){return a.asm.emscripten_enum_draco_StatusCode_OK.apply(null, 61 | arguments)},Wc=a._emscripten_enum_draco_StatusCode_DRACO_ERROR=function(){return a.asm.emscripten_enum_draco_StatusCode_DRACO_ERROR.apply(null,arguments)},Xc=a._emscripten_enum_draco_StatusCode_IO_ERROR=function(){return a.asm.emscripten_enum_draco_StatusCode_IO_ERROR.apply(null,arguments)},Yc=a._emscripten_enum_draco_StatusCode_INVALID_PARAMETER=function(){return a.asm.emscripten_enum_draco_StatusCode_INVALID_PARAMETER.apply(null,arguments)},Zc=a._emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION= 62 | function(){return a.asm.emscripten_enum_draco_StatusCode_UNSUPPORTED_VERSION.apply(null,arguments)},$c=a._emscripten_enum_draco_StatusCode_UNKNOWN_VERSION=function(){return a.asm.emscripten_enum_draco_StatusCode_UNKNOWN_VERSION.apply(null,arguments)},ad=a._emscripten_enum_draco_DataType_DT_INVALID=function(){return a.asm.emscripten_enum_draco_DataType_DT_INVALID.apply(null,arguments)},bd=a._emscripten_enum_draco_DataType_DT_INT8=function(){return a.asm.emscripten_enum_draco_DataType_DT_INT8.apply(null, 63 | arguments)},cd=a._emscripten_enum_draco_DataType_DT_UINT8=function(){return a.asm.emscripten_enum_draco_DataType_DT_UINT8.apply(null,arguments)},dd=a._emscripten_enum_draco_DataType_DT_INT16=function(){return a.asm.emscripten_enum_draco_DataType_DT_INT16.apply(null,arguments)},ed=a._emscripten_enum_draco_DataType_DT_UINT16=function(){return a.asm.emscripten_enum_draco_DataType_DT_UINT16.apply(null,arguments)},fd=a._emscripten_enum_draco_DataType_DT_INT32=function(){return a.asm.emscripten_enum_draco_DataType_DT_INT32.apply(null, 64 | arguments)},gd=a._emscripten_enum_draco_DataType_DT_UINT32=function(){return a.asm.emscripten_enum_draco_DataType_DT_UINT32.apply(null,arguments)},hd=a._emscripten_enum_draco_DataType_DT_INT64=function(){return a.asm.emscripten_enum_draco_DataType_DT_INT64.apply(null,arguments)},id=a._emscripten_enum_draco_DataType_DT_UINT64=function(){return a.asm.emscripten_enum_draco_DataType_DT_UINT64.apply(null,arguments)},jd=a._emscripten_enum_draco_DataType_DT_FLOAT32=function(){return a.asm.emscripten_enum_draco_DataType_DT_FLOAT32.apply(null, 65 | arguments)},kd=a._emscripten_enum_draco_DataType_DT_FLOAT64=function(){return a.asm.emscripten_enum_draco_DataType_DT_FLOAT64.apply(null,arguments)},ld=a._emscripten_enum_draco_DataType_DT_BOOL=function(){return a.asm.emscripten_enum_draco_DataType_DT_BOOL.apply(null,arguments)},md=a._emscripten_enum_draco_DataType_DT_TYPES_COUNT=function(){return a.asm.emscripten_enum_draco_DataType_DT_TYPES_COUNT.apply(null,arguments)},nd=a._emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE=function(){return a.asm.emscripten_enum_draco_EncodedGeometryType_INVALID_GEOMETRY_TYPE.apply(null, 66 | arguments)},od=a._emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD=function(){return a.asm.emscripten_enum_draco_EncodedGeometryType_POINT_CLOUD.apply(null,arguments)},pd=a._emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH=function(){return a.asm.emscripten_enum_draco_EncodedGeometryType_TRIANGULAR_MESH.apply(null,arguments)},qd=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM=function(){return a.asm.emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_INVALID_TRANSFORM.apply(null, 67 | arguments)},rd=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM=function(){return a.asm.emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_NO_TRANSFORM.apply(null,arguments)},sd=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM=function(){return a.asm.emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_QUANTIZATION_TRANSFORM.apply(null,arguments)},td=a._emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM=function(){return a.asm.emscripten_enum_draco_AttributeTransformType_ATTRIBUTE_OCTAHEDRON_TRANSFORM.apply(null, 68 | arguments)},ud=a._emscripten_enum_draco_GeometryAttribute_Type_INVALID=function(){return a.asm.emscripten_enum_draco_GeometryAttribute_Type_INVALID.apply(null,arguments)},vd=a._emscripten_enum_draco_GeometryAttribute_Type_POSITION=function(){return a.asm.emscripten_enum_draco_GeometryAttribute_Type_POSITION.apply(null,arguments)},wd=a._emscripten_enum_draco_GeometryAttribute_Type_NORMAL=function(){return a.asm.emscripten_enum_draco_GeometryAttribute_Type_NORMAL.apply(null,arguments)},xd=a._emscripten_enum_draco_GeometryAttribute_Type_COLOR= 69 | function(){return a.asm.emscripten_enum_draco_GeometryAttribute_Type_COLOR.apply(null,arguments)},yd=a._emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD=function(){return a.asm.emscripten_enum_draco_GeometryAttribute_Type_TEX_COORD.apply(null,arguments)},zd=a._emscripten_enum_draco_GeometryAttribute_Type_GENERIC=function(){return a.asm.emscripten_enum_draco_GeometryAttribute_Type_GENERIC.apply(null,arguments)};a._setThrew=function(){return a.asm.setThrew.apply(null,arguments)};var ta=a.__ZSt18uncaught_exceptionv= 70 | function(){return a.asm._ZSt18uncaught_exceptionv.apply(null,arguments)};a._free=function(){return a.asm.free.apply(null,arguments)};var ib=a._malloc=function(){return a.asm.malloc.apply(null,arguments)};a.stackSave=function(){return a.asm.stackSave.apply(null,arguments)};a.stackAlloc=function(){return a.asm.stackAlloc.apply(null,arguments)};a.stackRestore=function(){return a.asm.stackRestore.apply(null,arguments)};a.__growWasmMemory=function(){return a.asm.__growWasmMemory.apply(null,arguments)}; 71 | a.dynCall_ii=function(){return a.asm.dynCall_ii.apply(null,arguments)};a.dynCall_vi=function(){return a.asm.dynCall_vi.apply(null,arguments)};a.dynCall_iii=function(){return a.asm.dynCall_iii.apply(null,arguments)};a.dynCall_vii=function(){return a.asm.dynCall_vii.apply(null,arguments)};a.dynCall_iiii=function(){return a.asm.dynCall_iiii.apply(null,arguments)};a.dynCall_v=function(){return a.asm.dynCall_v.apply(null,arguments)};a.dynCall_viii=function(){return a.asm.dynCall_viii.apply(null,arguments)}; 72 | a.dynCall_viiii=function(){return a.asm.dynCall_viiii.apply(null,arguments)};a.dynCall_iiiiiii=function(){return a.asm.dynCall_iiiiiii.apply(null,arguments)};a.dynCall_iidiiii=function(){return a.asm.dynCall_iidiiii.apply(null,arguments)};a.dynCall_jiji=function(){return a.asm.dynCall_jiji.apply(null,arguments)};a.dynCall_viiiiii=function(){return a.asm.dynCall_viiiiii.apply(null,arguments)};a.dynCall_viiiii=function(){return a.asm.dynCall_viiiii.apply(null,arguments)};a.asm=La;var fa;a.then=function(e){if(fa)e(a); 73 | else{var c=a.onRuntimeInitialized;a.onRuntimeInitialized=function(){c&&c();e(a)}}return a};ja=function c(){fa||ma();fa||(ja=c)};a.run=ma;if(a.preInit)for("function"==typeof a.preInit&&(a.preInit=[a.preInit]);0=n.size?(t(0>=1;break;case 4:d>>=2;break;case 8:d>>=3}for(var c=0;c