├── .gitignore ├── README.md ├── app ├── Main.js ├── app.js ├── utils │ ├── VRControls.js │ └── VREffect.js └── view │ ├── PhysicsManager.js │ ├── World3D.js │ ├── confettis │ ├── Confettis.js │ ├── fs-confettis.glsl │ └── vs-confettis.glsl │ ├── cube │ └── Cube.js │ ├── explosion │ ├── Explosion.js │ ├── fs-explosion.glsl │ └── vs-explosion.glsl │ ├── floor │ └── Floor.js │ ├── gamepads │ ├── GamePads.js │ └── MousePad.js │ ├── letter │ ├── Letter.js │ ├── fs-letter.glsl │ └── vs-letter.glsl │ ├── shape │ ├── Shape.js │ ├── fs-shape.glsl │ └── vs-shape.glsl │ ├── sound │ ├── AssetsSound.js │ └── SoundManager.js │ └── utils.js ├── gifs └── celebrate.gif ├── package.json ├── public ├── assets │ ├── hand │ │ └── hand.json │ ├── letters │ │ ├── 0.json │ │ ├── 1.json │ │ ├── 2.json │ │ ├── 3.json │ │ ├── 4.json │ │ ├── 5.json │ │ ├── 6.json │ │ ├── 7.json │ │ ├── 8.json │ │ ├── 9.json │ │ ├── A.json │ │ ├── B.json │ │ ├── C.json │ │ ├── D.json │ │ ├── E.json │ │ ├── F.json │ │ ├── G.json │ │ ├── H.json │ │ ├── I.json │ │ ├── J.json │ │ ├── K.json │ │ ├── L.json │ │ ├── M.json │ │ ├── N.json │ │ ├── O.json │ │ ├── P.json │ │ ├── Q.json │ │ ├── R.json │ │ ├── S.json │ │ ├── T.json │ │ ├── U.json │ │ ├── V.json │ │ ├── W.json │ │ ├── X.json │ │ ├── Y.json │ │ └── Z.json │ ├── sounds │ │ ├── background-success.wav │ │ ├── background.wav │ │ ├── balloon1.wav │ │ ├── balloon2.wav │ │ ├── balloon3.wav │ │ └── balloon4.wav │ └── textures │ │ ├── breel.png │ │ ├── confettis.png │ │ ├── floor.png │ │ ├── gold.jpg │ │ ├── hand_occlusion.jpg │ │ └── silver.jpg ├── css │ └── main.css ├── index.html └── js │ └── vendor │ ├── cannon.min.js │ ├── webvr-manager.js │ └── webvr-polyfill.js └── watcher.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea 3 | bundle.js 4 | bundle.js.map 5 | *.swp 6 | *~ 7 | *.log 8 | .DS_Store 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # VR Made by Makers - a B-Reel experiment 2 | 3 | celebrate 4 | 5 | 6 | #### Interactive WebVR experience ([demo](https://b-reel.github.io/vr-madebymakers/)). 7 | 8 | --- 9 | 10 | ## Usage 11 | 12 | ```sh 13 | $ npm install 14 | $ npm start 15 | ``` 16 | 17 | # Custom text 18 | 19 | The text and the colors are passed as a hash. 20 | 21 | ``` 22 | /#text=Hello&colors=GSGSGS 23 | ``` 24 | 25 | Where: 26 | 27 | - `text` is the text to be displayed. 28 | - `colors` are the colors, one per letter (Gold, Silver, Gold, Silver, Gold, Silver in the above example). 29 | 30 | ## Linebreak 31 | 32 | To break a line, add `\n` in the text. 33 | 34 | ``` 35 | /#text=Hello\nWorld 36 | ``` 37 | 38 | ## Available colors 39 | 40 | * Silver, abbrev `S` 41 | * Gold, abbrev `G` 42 | 43 | ## Available Characters 44 | 45 | - `A`, `B`, `C`, `D`, `E`, `F`, `G`, `H`, `I`, `J`, `K`, `L`, `M`, `N`, `O`, `P`, `Q`, `R`, `S`, `T`, `U`, `V`, `W`, `X`, `Y`, `Z` 46 | - `0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9` 47 | 48 | ## Notes 49 | 50 | - If `colors` is missing, they will be random. 51 | - Don't forget to add spaces for both spaces and line breaks in `colors` (e.g: for `Hello World\nAgain`, `GGGG SSSSS GGGG`). 52 | - This isn't case sensitive, so `HELLO`, `hello` or `HeLlO` are the same. 53 | 54 | ## Cheats 55 | 56 | - Pressing `Q` will attract all the letters, and thus complete the game. 57 | - `Space` will release all the letters. 58 | -------------------------------------------------------------------------------- /app/Main.js: -------------------------------------------------------------------------------- 1 | var World3D = require('./view/World3D'); 2 | 3 | var Main = function(){ 4 | this.world3D = null; 5 | }; 6 | 7 | Main.prototype.init = function() { 8 | var container = document.getElementById('container'); 9 | this.world3D = new World3D(container); 10 | 11 | this.addEvents(); 12 | this.onResize(null); 13 | }; 14 | 15 | Main.prototype.addEvents = function() { 16 | window.addEventListener('resize', this.onResize.bind(this)); 17 | window.addEventListener('vrdisplaypresentchange', this.onResize.bind(this), true); 18 | }; 19 | 20 | Main.prototype.onResize = function() { 21 | var w = window.innerWidth; 22 | var h = window.innerHeight; 23 | 24 | this.world3D.onResize(w, h); 25 | }; 26 | 27 | module.exports = Main; 28 | -------------------------------------------------------------------------------- /app/app.js: -------------------------------------------------------------------------------- 1 | var Main = require('./Main.js'); 2 | require('es6-promise').polyfill(); 3 | 4 | window.app = new Main(); -------------------------------------------------------------------------------- /app/utils/VRControls.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author dmarcos / https://github.com/dmarcos 3 | * @author mrdoob / http://mrdoob.com 4 | */ 5 | 6 | var THREE = require('three'); 7 | 8 | var VRControls = function ( object, onError ) { 9 | 10 | var scope = this; 11 | 12 | var vrInput; 13 | 14 | var standingMatrix = new THREE.Matrix4(); 15 | 16 | function gotVRDevices( devices ) { 17 | 18 | for ( var i = 0; i < devices.length; i ++ ) { 19 | 20 | if ( ( 'VRDisplay' in window && devices[ i ] instanceof VRDisplay ) || 21 | ( 'PositionSensorVRDevice' in window && devices[ i ] instanceof PositionSensorVRDevice ) ) { 22 | 23 | vrInput = devices[ i ]; 24 | break; // We keep the first we encounter 25 | 26 | } 27 | 28 | } 29 | 30 | if ( !vrInput ) { 31 | 32 | if ( onError ) onError( 'VR input not available.' ); 33 | 34 | } 35 | 36 | } 37 | 38 | if ( navigator.getVRDisplays ) { 39 | 40 | navigator.getVRDisplays().then( gotVRDevices ); 41 | 42 | } else if ( navigator.getVRDevices ) { 43 | 44 | // Deprecated API. 45 | navigator.getVRDevices().then( gotVRDevices ); 46 | 47 | } 48 | 49 | // the Rift SDK returns the position in meters 50 | // this scale factor allows the user to define how meters 51 | // are converted to scene units. 52 | 53 | this.scale = 1; 54 | 55 | // If true will use "standing space" coordinate system where y=0 is the 56 | // floor and x=0, z=0 is the center of the room. 57 | this.standing = false; 58 | 59 | // Distance from the users eyes to the floor in meters. Used when 60 | // standing=true but the VRDisplay doesn't provide stageParameters. 61 | this.userHeight = 1.6; 62 | 63 | this.update = function () { 64 | 65 | if ( vrInput ) { 66 | 67 | if ( vrInput.getPose ) { 68 | 69 | var pose = vrInput.getPose(); 70 | 71 | if ( pose.orientation !== null ) { 72 | 73 | object.quaternion.fromArray( pose.orientation ); 74 | 75 | } 76 | 77 | if ( pose.position !== null ) { 78 | 79 | object.position.fromArray( pose.position ); 80 | 81 | } else { 82 | 83 | object.position.set( 0, 0, 0 ); 84 | 85 | } 86 | 87 | } else { 88 | 89 | // Deprecated API. 90 | var state = vrInput.getState(); 91 | 92 | if ( state.orientation !== null ) { 93 | 94 | object.quaternion.copy( state.orientation ); 95 | 96 | } 97 | 98 | if ( state.position !== null ) { 99 | 100 | object.position.copy( state.position ); 101 | 102 | } else { 103 | 104 | object.position.set( 0, 0, 0 ); 105 | 106 | } 107 | 108 | } 109 | 110 | if ( this.standing ) { 111 | 112 | if ( vrInput.stageParameters ) { 113 | 114 | object.updateMatrix(); 115 | 116 | standingMatrix.fromArray(vrInput.stageParameters.sittingToStandingTransform); 117 | object.applyMatrix( standingMatrix ); 118 | 119 | } else { 120 | 121 | object.position.setY( object.position.y + this.userHeight ); 122 | 123 | } 124 | 125 | } 126 | 127 | object.position.multiplyScalar( scope.scale ); 128 | 129 | } 130 | 131 | }; 132 | 133 | this.resetPose = function () { 134 | 135 | if ( vrInput ) { 136 | 137 | if ( vrInput.resetPose !== undefined ) { 138 | 139 | vrInput.resetPose(); 140 | 141 | } else if ( vrInput.resetSensor !== undefined ) { 142 | 143 | // Deprecated API. 144 | vrInput.resetSensor(); 145 | 146 | } else if ( vrInput.zeroSensor !== undefined ) { 147 | 148 | // Really deprecated API. 149 | vrInput.zeroSensor(); 150 | 151 | } 152 | 153 | } 154 | 155 | }; 156 | 157 | this.resetSensor = function () { 158 | 159 | console.warn( 'THREE.VRControls: .resetSensor() is now .resetPose().' ); 160 | this.resetPose(); 161 | 162 | }; 163 | 164 | this.zeroSensor = function () { 165 | 166 | console.warn( 'THREE.VRControls: .zeroSensor() is now .resetPose().' ); 167 | this.resetPose(); 168 | 169 | }; 170 | 171 | this.dispose = function () { 172 | 173 | vrInput = null; 174 | 175 | }; 176 | 177 | }; 178 | 179 | module.exports = VRControls; -------------------------------------------------------------------------------- /app/utils/VREffect.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author dmarcos / https://github.com/dmarcos 3 | * @author mrdoob / http://mrdoob.com 4 | * 5 | * WebVR Spec: http://mozvr.github.io/webvr-spec/webvr.html 6 | * 7 | * Firefox: http://mozvr.com/downloads/ 8 | * Chromium: https://drive.google.com/folderview?id=0BzudLt22BqGRbW9WTHMtOWMzNjQ&usp=sharing#list 9 | * 10 | */ 11 | 12 | var THREE = require('three'); 13 | 14 | var VREffect = function ( renderer, onError, onReady, onRenderLeftEye, onRenderRightEye ) { 15 | 16 | onReady = onReady || function() {}; 17 | 18 | this.onRenderLeftEye = onRenderLeftEye || function() {}; 19 | this.onRenderRightEye = onRenderRightEye || function() {}; 20 | 21 | var vrHMD; 22 | var isDeprecatedAPI = false; 23 | var eyeTranslationL = new THREE.Vector3(); 24 | var eyeTranslationR = new THREE.Vector3(); 25 | var renderRectL, renderRectR; 26 | var eyeFOVL, eyeFOVR; 27 | 28 | this.getHMD = function() { 29 | return vrHMD; 30 | } 31 | 32 | function gotVRDevices( devices ) { 33 | 34 | for ( var i = 0; i < devices.length; i ++ ) { 35 | 36 | if ( 'VRDisplay' in window && devices[ i ] instanceof VRDisplay ) { 37 | 38 | vrHMD = devices[ i ]; 39 | isDeprecatedAPI = false; 40 | break; // We keep the first we encounter 41 | 42 | } else if ( 'HMDVRDevice' in window && devices[ i ] instanceof HMDVRDevice ) { 43 | 44 | vrHMD = devices[ i ]; 45 | isDeprecatedAPI = true; 46 | break; // We keep the first we encounter 47 | 48 | } 49 | 50 | } 51 | 52 | if ( vrHMD === undefined ) { 53 | 54 | if ( onError ) onError( 'HMD not available' ); 55 | 56 | } 57 | 58 | } 59 | 60 | if ( navigator.getVRDisplays ) { 61 | 62 | navigator.getVRDisplays().then( gotVRDevices ); 63 | 64 | } else if ( navigator.getVRDevices ) { 65 | 66 | // Deprecated API. 67 | navigator.getVRDevices().then( gotVRDevices ); 68 | 69 | } 70 | 71 | // 72 | 73 | this.scale = 1; 74 | 75 | var isPresenting = false; 76 | 77 | var rendererSize = renderer.getSize(); 78 | var rendererPixelRatio = renderer.getPixelRatio(); 79 | 80 | this.setSize = function ( width, height ) { 81 | 82 | rendererSize = { width: width, height: height }; 83 | 84 | if ( isPresenting ) { 85 | 86 | var eyeParamsL = vrHMD.getEyeParameters( 'left' ); 87 | renderer.setPixelRatio( 1 ); 88 | 89 | if ( isDeprecatedAPI ) { 90 | 91 | renderer.setSize( eyeParamsL.renderRect.width * 2, eyeParamsL.renderRect.height, false ); 92 | 93 | } else { 94 | 95 | renderer.setSize( eyeParamsL.renderWidth * 2, eyeParamsL.renderHeight, false ); 96 | 97 | } 98 | 99 | 100 | } else { 101 | 102 | renderer.setPixelRatio( rendererPixelRatio ); 103 | renderer.setSize( width, height ); 104 | 105 | } 106 | 107 | }; 108 | 109 | // fullscreen 110 | 111 | var canvas = renderer.domElement; 112 | var fullscreenchange = canvas.mozRequestFullScreen ? 'mozfullscreenchange' : 'webkitfullscreenchange'; 113 | 114 | document.addEventListener( fullscreenchange, function () { 115 | 116 | isPresenting = isDeprecatedAPI && vrHMD && ( document.mozFullScreenElement || document.webkitFullscreenElement ) !== undefined; 117 | isPresenting = true 118 | 119 | if ( isPresenting ) { 120 | 121 | rendererPixelRatio = renderer.getPixelRatio(); 122 | rendererSize = renderer.getSize(); 123 | 124 | var eyeParamsL = vrHMD.getEyeParameters( 'left' ); 125 | renderer.setPixelRatio( 1 ); 126 | renderer.setSize( eyeParamsL.renderRect.width * 2, eyeParamsL.renderRect.height, false ); 127 | 128 | } else { 129 | 130 | renderer.setPixelRatio( rendererPixelRatio ); 131 | renderer.setSize( rendererSize.width, rendererSize.height ); 132 | 133 | } 134 | 135 | }, false ); 136 | 137 | window.addEventListener( 'vrdisplaypresentchange', function () { 138 | 139 | isPresenting = vrHMD && vrHMD.isPresenting; 140 | isPresenting = true 141 | 142 | if ( isPresenting ) { 143 | 144 | rendererPixelRatio = renderer.getPixelRatio(); 145 | rendererSize = renderer.getSize(); 146 | 147 | var eyeParamsL = vrHMD.getEyeParameters( 'left' ); 148 | renderer.setPixelRatio( 1 ); 149 | renderer.setSize( eyeParamsL.renderWidth * 2, eyeParamsL.renderHeight, false ); 150 | 151 | } else { 152 | 153 | renderer.setPixelRatio( rendererPixelRatio ); 154 | renderer.setSize( rendererSize.width, rendererSize.height ); 155 | 156 | } 157 | 158 | }, false ); 159 | 160 | this.setFullScreen = function ( boolean ) { 161 | 162 | return new Promise( function ( resolve, reject ) { 163 | 164 | if ( vrHMD === undefined ) { 165 | 166 | reject( new Error( 'No VR hardware found.' ) ); 167 | return; 168 | 169 | } 170 | if ( isPresenting === boolean ) { 171 | 172 | resolve(); 173 | return; 174 | 175 | } 176 | 177 | if ( ! isDeprecatedAPI ) { 178 | 179 | if ( boolean ) { 180 | 181 | resolve( vrHMD.requestPresent( [ { source: canvas } ] ) ); 182 | 183 | } else { 184 | 185 | resolve( vrHMD.exitPresent() ); 186 | 187 | } 188 | 189 | } else { 190 | 191 | if ( canvas.mozRequestFullScreen ) { 192 | 193 | canvas.mozRequestFullScreen( { vrDisplay: vrHMD } ); 194 | resolve(); 195 | 196 | } else if ( canvas.webkitRequestFullscreen ) { 197 | 198 | canvas.webkitRequestFullscreen( { vrDisplay: vrHMD } ); 199 | resolve(); 200 | 201 | } else { 202 | 203 | console.error( 'No compatible requestFullscreen method found.' ); 204 | reject( new Error( 'No compatible requestFullscreen method found.' ) ); 205 | 206 | } 207 | 208 | } 209 | 210 | } ); 211 | 212 | }; 213 | 214 | this.requestPresent = function () { 215 | 216 | return this.setFullScreen( true ); 217 | 218 | }; 219 | 220 | this.exitPresent = function () { 221 | 222 | return this.setFullScreen( false ); 223 | 224 | }; 225 | 226 | // render 227 | 228 | var cameraL = new THREE.PerspectiveCamera(); 229 | cameraL.layers.enable( 1 ); 230 | 231 | var cameraR = new THREE.PerspectiveCamera(); 232 | cameraR.layers.enable( 2 ); 233 | 234 | this.render = function ( scene, camera ) { 235 | 236 | if ( vrHMD && isPresenting ) { 237 | 238 | var autoUpdate = scene.autoUpdate; 239 | 240 | if ( autoUpdate ) { 241 | 242 | scene.updateMatrixWorld(); 243 | scene.autoUpdate = false; 244 | 245 | } 246 | 247 | var eyeParamsL = vrHMD.getEyeParameters( 'left' ); 248 | var eyeParamsR = vrHMD.getEyeParameters( 'right' ); 249 | 250 | if ( ! isDeprecatedAPI ) { 251 | 252 | eyeTranslationL.fromArray( eyeParamsL.offset ); 253 | eyeTranslationR.fromArray( eyeParamsR.offset ); 254 | eyeFOVL = eyeParamsL.fieldOfView; 255 | eyeFOVR = eyeParamsR.fieldOfView; 256 | 257 | } else { 258 | 259 | eyeTranslationL.copy( eyeParamsL.eyeTranslation ); 260 | eyeTranslationR.copy( eyeParamsR.eyeTranslation ); 261 | eyeFOVL = eyeParamsL.recommendedFieldOfView; 262 | eyeFOVR = eyeParamsR.recommendedFieldOfView; 263 | 264 | } 265 | 266 | if ( Array.isArray( scene ) ) { 267 | 268 | console.warn( 'THREE.VREffect.render() no longer supports arrays. Use object.layers instead.' ); 269 | scene = scene[ 0 ]; 270 | 271 | } 272 | 273 | // When rendering we don't care what the recommended size is, only what the actual size 274 | // of the backbuffer is. 275 | var size = renderer.getSize(); 276 | renderRectL = { x: 0, y: 0, width: size.width / 2, height: size.height }; 277 | renderRectR = { x: size.width / 2, y: 0, width: size.width / 2, height: size.height }; 278 | 279 | renderer.setScissorTest( true ); 280 | renderer.clear(); 281 | 282 | if ( camera.parent === null ) camera.updateMatrixWorld(); 283 | 284 | cameraL.projectionMatrix = fovToProjection( eyeFOVL, true, camera.near, camera.far ); 285 | cameraR.projectionMatrix = fovToProjection( eyeFOVR, true, camera.near, camera.far ); 286 | 287 | camera.matrixWorld.decompose( cameraL.position, cameraL.quaternion, cameraL.scale ); 288 | camera.matrixWorld.decompose( cameraR.position, cameraR.quaternion, cameraR.scale ); 289 | 290 | var scale = this.scale; 291 | cameraL.translateOnAxis( eyeTranslationL, scale ); 292 | cameraR.translateOnAxis( eyeTranslationR, scale ); 293 | 294 | 295 | // render left eye 296 | renderer.setViewport( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height ); 297 | renderer.setScissor( renderRectL.x, renderRectL.y, renderRectL.width, renderRectL.height ); 298 | renderer.render( scene, cameraL ); 299 | this.onRenderLeftEye.call(); 300 | 301 | // render right eye 302 | renderer.setViewport( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height ); 303 | renderer.setScissor( renderRectR.x, renderRectR.y, renderRectR.width, renderRectR.height ); 304 | renderer.render( scene, cameraR ); 305 | this.onRenderRightEye.call(); 306 | 307 | renderer.setScissorTest( false ); 308 | 309 | if ( autoUpdate ) { 310 | 311 | scene.autoUpdate = true; 312 | 313 | } 314 | 315 | if ( ! isDeprecatedAPI ) { 316 | 317 | vrHMD.submitFrame(); 318 | 319 | } 320 | 321 | return; 322 | 323 | } 324 | 325 | // Regular render mode if not HMD 326 | 327 | renderer.render( scene, camera ); 328 | 329 | }; 330 | 331 | // 332 | 333 | function fovToNDCScaleOffset( fov ) { 334 | 335 | var pxscale = 2.0 / ( fov.leftTan + fov.rightTan ); 336 | var pxoffset = ( fov.leftTan - fov.rightTan ) * pxscale * 0.5; 337 | var pyscale = 2.0 / ( fov.upTan + fov.downTan ); 338 | var pyoffset = ( fov.upTan - fov.downTan ) * pyscale * 0.5; 339 | return { scale: [ pxscale, pyscale ], offset: [ pxoffset, pyoffset ] }; 340 | 341 | } 342 | 343 | function fovPortToProjection( fov, rightHanded, zNear, zFar ) { 344 | 345 | rightHanded = rightHanded === undefined ? true : rightHanded; 346 | zNear = zNear === undefined ? 0.01 : zNear; 347 | zFar = zFar === undefined ? 10000.0 : zFar; 348 | 349 | var handednessScale = rightHanded ? - 1.0 : 1.0; 350 | 351 | // start with an identity matrix 352 | var mobj = new THREE.Matrix4(); 353 | var m = mobj.elements; 354 | 355 | // and with scale/offset info for normalized device coords 356 | var scaleAndOffset = fovToNDCScaleOffset( fov ); 357 | 358 | // X result, map clip edges to [-w,+w] 359 | m[ 0 * 4 + 0 ] = scaleAndOffset.scale[ 0 ]; 360 | m[ 0 * 4 + 1 ] = 0.0; 361 | m[ 0 * 4 + 2 ] = scaleAndOffset.offset[ 0 ] * handednessScale; 362 | m[ 0 * 4 + 3 ] = 0.0; 363 | 364 | // Y result, map clip edges to [-w,+w] 365 | // Y offset is negated because this proj matrix transforms from world coords with Y=up, 366 | // but the NDC scaling has Y=down (thanks D3D?) 367 | m[ 1 * 4 + 0 ] = 0.0; 368 | m[ 1 * 4 + 1 ] = scaleAndOffset.scale[ 1 ]; 369 | m[ 1 * 4 + 2 ] = - scaleAndOffset.offset[ 1 ] * handednessScale; 370 | m[ 1 * 4 + 3 ] = 0.0; 371 | 372 | // Z result (up to the app) 373 | m[ 2 * 4 + 0 ] = 0.0; 374 | m[ 2 * 4 + 1 ] = 0.0; 375 | m[ 2 * 4 + 2 ] = zFar / ( zNear - zFar ) * - handednessScale; 376 | m[ 2 * 4 + 3 ] = ( zFar * zNear ) / ( zNear - zFar ); 377 | 378 | // W result (= Z in) 379 | m[ 3 * 4 + 0 ] = 0.0; 380 | m[ 3 * 4 + 1 ] = 0.0; 381 | m[ 3 * 4 + 2 ] = handednessScale; 382 | m[ 3 * 4 + 3 ] = 0.0; 383 | 384 | mobj.transpose(); 385 | 386 | return mobj; 387 | 388 | } 389 | 390 | function fovToProjection( fov, rightHanded, zNear, zFar ) { 391 | 392 | var DEG2RAD = Math.PI / 180.0; 393 | 394 | var fovPort = { 395 | upTan: Math.tan( fov.upDegrees * DEG2RAD ), 396 | downTan: Math.tan( fov.downDegrees * DEG2RAD ), 397 | leftTan: Math.tan( fov.leftDegrees * DEG2RAD ), 398 | rightTan: Math.tan( fov.rightDegrees * DEG2RAD ) 399 | }; 400 | 401 | return fovPortToProjection( fovPort, rightHanded, zNear, zFar ); 402 | 403 | } 404 | 405 | }; 406 | 407 | module.exports = VREffect; -------------------------------------------------------------------------------- /app/view/PhysicsManager.js: -------------------------------------------------------------------------------- 1 | var THREE = require("three"); 2 | var TWEEN = require("tween.js"); 3 | var KeyCodes = require('./utils').KeyCodes; 4 | 5 | var that; 6 | 7 | /** 8 | * @param {THREE.Camera} dcamera 9 | * @param {THREE.Camera} camera 10 | */ 11 | var PhysicsManager = function(dcamera, camera) { 12 | that = this; 13 | 14 | THREE.EventDispatcher.call(this); 15 | 16 | this.world = new CANNON.World(); 17 | this.world.gravity.set(0, 0, 0); // m/s² 18 | 19 | this.dcamera = dcamera; 20 | this.camera = camera; 21 | this.mode = -1; 22 | 23 | this.threeCannon = []; 24 | 25 | // Sphere for the dummyCamera 26 | var radius = 0.25; 27 | 28 | this.camBody = new CANNON.Body({ 29 | mass: 0, 30 | shape: new CANNON.Sphere(radius) 31 | }); 32 | 33 | this.world.addBody(this.camBody); 34 | 35 | // Floor plane 36 | var groundBody = new CANNON.Body({ 37 | mass: 0 38 | }); 39 | 40 | var groundShape = new CANNON.Plane(); 41 | 42 | groundBody.addShape(groundShape); 43 | 44 | this.world.addBody(groundBody); 45 | 46 | this.fixedTimeStep = 1.0 / 60.0; 47 | this.maxSubSteps = 3; 48 | this.lastTime = 0; 49 | this.damping = 0.5; 50 | this.f = 10; //force 51 | 52 | this.bodyText = []; 53 | this.springElements = []; 54 | 55 | this.startPh = false; 56 | this.startSpring = {}; 57 | this.lettersLength = 0; 58 | 59 | window.addEventListener('click', this.onClick.bind(this)); 60 | window.addEventListener('keydown', this.onCursor, true); 61 | }; 62 | 63 | PhysicsManager.prototype = Object.create(THREE.EventDispatcher.prototype); 64 | 65 | PhysicsManager.prototype.onClick = function() { 66 | this.attractBodiesToPlayer(); 67 | }; 68 | 69 | /** 70 | * Attract shapes and letters to the player. 71 | */ 72 | PhysicsManager.prototype.attractBodiesToPlayer = function() { 73 | var vx, vy, vz; 74 | 75 | for(i = 0; i < this.threeCannon.length; i++) { 76 | if(this.mode === 3) { 77 | vx = this.camera.position.x - this.threeCannon[i].t.position.x; 78 | vy = this.camera.position.y - this.threeCannon[i].t.position.y; 79 | vz = this.camera.position.z - this.threeCannon[i].t.position.z; 80 | } else { 81 | vx = this.dcamera.position.x - this.threeCannon[i].t.position.x; 82 | vy = this.dcamera.position.y - this.threeCannon[i].t.position.y; 83 | vz = this.dcamera.position.z - this.threeCannon[i].t.position.z; 84 | } 85 | 86 | var v = new CANNON.Vec3(vx, vz, vy); 87 | 88 | v.normalize(); 89 | 90 | if(!this.threeCannon[i].c.isSpringing) { 91 | this.threeCannon[i].c.applyLocalImpulse( 92 | v.scale(this.f / 30), 93 | this.threeCannon[i].c.position 94 | ); 95 | 96 | if(this.threeCannon[i].c.springable) { 97 | v = v.scale(this.f / 2); 98 | } else { 99 | v = v.scale(this.f / 500); 100 | } 101 | 102 | this.threeCannon[i].c.applyImpulse(v, this.threeCannon[i].c.position); 103 | } 104 | } 105 | }; 106 | 107 | /** 108 | * Send all letters to their final position. 109 | */ 110 | PhysicsManager.prototype.showMessage = function() { 111 | for(var i = 0; i < that.threeCannon.length; i++) { 112 | var body = that.threeCannon[i].c; 113 | 114 | if(!body.isSpringing && body.springable && !body.isStarter) { 115 | that.addToSpring(that.bodyText[body.springIndex], body); 116 | } 117 | } 118 | }; 119 | 120 | /** 121 | * @param {Event} e - KeyEvent or Controller event 122 | */ 123 | PhysicsManager.prototype.onCursor = function(e) { 124 | if(that.startPh) { 125 | if(e.keyCode === KeyCodes.Q) { 126 | that.showMessage(); 127 | } 128 | 129 | if(e.keyCode === KeyCodes.SPACE || e === -1) { 130 | if (that.springElements.length >= that.lettersLength) { 131 | that.dispatchEvent({ 132 | type: 'messageUnlocked' 133 | }); 134 | } 135 | 136 | for(var i = 0; i < that.springElements.length; i++) { 137 | that.springElements[i].bodyB.isSpringing = false; 138 | } 139 | 140 | that.springElements = []; 141 | } 142 | } 143 | }; 144 | 145 | /** 146 | * Update all the CANNON.Body and apply changes to attached THREE.Mesh. 147 | * 148 | * @param {float} timestamp 149 | */ 150 | PhysicsManager.prototype.update = function(timestamp) { 151 | // Note: CANNON and THREE have the XY coordinates flipped 152 | 153 | if(this.lastTime !== void 0) { 154 | var dt = (timestamp - this.lastTime) / 1000; 155 | this.world.step(this.fixedTimeStep, dt, this.maxSubSteps); 156 | } 157 | 158 | if(this.mode === 3) { 159 | this.camBody.position.x = this.camera.position.x; 160 | this.camBody.position.y = this.camera.position.z; 161 | this.camBody.position.z = this.camera.position.y; 162 | } else { 163 | this.camBody.position.x = this.dcamera.position.x; 164 | this.camBody.position.y = this.dcamera.position.z; 165 | this.camBody.position.z = this.dcamera.position.y; 166 | } 167 | 168 | for(var i = 0; i < this.threeCannon.length; i++) { 169 | if(!this.threeCannon[i].c.isActuator) { 170 | this.threeCannon[i].t.position.x = this.threeCannon[i].c.position.x; 171 | this.threeCannon[i].t.position.y = this.threeCannon[i].c.position.z; 172 | this.threeCannon[i].t.position.z = this.threeCannon[i].c.position.y; 173 | 174 | if(!this.threeCannon[i].c.isSpringing) { 175 | this.threeCannon[i].t.quaternion.x = this.threeCannon[i].c.quaternion.x; 176 | this.threeCannon[i].t.quaternion.y = this.threeCannon[i].c.quaternion.z; 177 | this.threeCannon[i].t.quaternion.z = this.threeCannon[i].c.quaternion.y; 178 | this.threeCannon[i].t.quaternion.w = this.threeCannon[i].c.quaternion.w; 179 | } else { 180 | if(this.threeCannon[i].c.waitsAnimation) { 181 | this.threeCannon[i].c.waitsAnimation = false; 182 | this.animateQuaternion(this.threeCannon[i], 2000); 183 | } 184 | 185 | this.threeCannon[i].c.quaternion.x = this.threeCannon[i].t.quaternion.x; 186 | this.threeCannon[i].c.quaternion.y = this.threeCannon[i].t.quaternion.z; 187 | this.threeCannon[i].c.quaternion.z = this.threeCannon[i].t.quaternion.y; 188 | this.threeCannon[i].c.quaternion.w = this.threeCannon[i].t.quaternion.w; 189 | } 190 | } else { 191 | this.threeCannon[i].c.position.x = this.threeCannon[i].t.position.x; 192 | this.threeCannon[i].c.position.y = this.threeCannon[i].t.position.z; 193 | this.threeCannon[i].c.position.z = this.threeCannon[i].t.position.y; 194 | this.threeCannon[i].c.quaternion.x = this.threeCannon[i].t.quaternion.x; 195 | this.threeCannon[i].c.quaternion.y = this.threeCannon[i].t.quaternion.z; 196 | this.threeCannon[i].c.quaternion.z = this.threeCannon[i].t.quaternion.y; 197 | this.threeCannon[i].c.quaternion.w = this.threeCannon[i].t.quaternion.w; 198 | } 199 | } 200 | 201 | if(this.springElements.length > 0 && this.startPh) { 202 | for(i = 0; i < this.springElements.length; i++) { 203 | this.springElements[i].applyForce(); 204 | } 205 | } 206 | 207 | if(this.startSpring !== void 0) { 208 | this.startSpring.applyForce(); 209 | } 210 | 211 | this.lastTime = timestamp; 212 | }; 213 | 214 | /** 215 | * Add the starting cube. 216 | * 217 | * @param {THREE.Mesh} obj 218 | * @param {string} type 219 | */ 220 | PhysicsManager.prototype.addStarterObject = function(obj, type) { 221 | // Note: CANNON and THREE have the XY coordinates flipped 222 | 223 | var mass = 5; 224 | 225 | if(type === 'cube') { 226 | var bbox = new THREE.Box3().setFromObject(obj); 227 | 228 | var widthX = bbox.max.x - bbox.min.x; 229 | var widthY = bbox.max.y - bbox.min.y; 230 | var widthZ = bbox.max.z - bbox.min.z; 231 | 232 | 233 | var boxShape = new CANNON.Box(new CANNON.Vec3(widthX / 2, widthZ / 2, widthY / 2)); 234 | 235 | var boxBody = new CANNON.Body({ 236 | mass: mass, 237 | angularDamping: 0.3 238 | }); 239 | 240 | boxBody.springable = true; 241 | boxBody.isStarter = true; 242 | boxBody.addShape(boxShape); 243 | 244 | boxBody.position.set(obj.position.x, obj.position.z, obj.position.y); 245 | 246 | this.world.addBody(boxBody); 247 | 248 | var radius = 0.1; 249 | 250 | var body = new CANNON.Body({ 251 | mass: 0, 252 | position: new CANNON.Vec3(0, 0, 1.5), 253 | shape: new CANNON.Sphere(radius) 254 | }); 255 | 256 | this.startSpring = new CANNON.Spring(body, boxBody, { 257 | localAnchorA: new CANNON.Vec3(0, 0, -0.4), 258 | localAnchorB: new CANNON.Vec3(0, 0, 0), 259 | restLength: 0, 260 | stiffness: 50, 261 | damping: 40 262 | }); 263 | 264 | this.threeCannon.push({ 265 | 't': obj, 266 | 'c': boxBody 267 | }); 268 | } 269 | }; 270 | 271 | /** 272 | * Fade the opacity of the starting cube, then remove it. 273 | */ 274 | PhysicsManager.prototype.deleteStarterObject = function() { 275 | var cbody = that.startSpring.bodyB; 276 | var mesh = that.getThreeMeshFromCannonBody(this.startSpring.bodyB); 277 | mesh.material.transparent = true; 278 | 279 | new TWEEN.Tween({ 280 | opacity: mesh.material.opacity 281 | }).to({ 282 | opacity: 0 283 | }, 1000) 284 | .onUpdate(function() { 285 | mesh.material.opacity = this.opacity; 286 | }) 287 | .onComplete(function() { 288 | mesh.visible = false; 289 | cbody.sleep(); 290 | }) 291 | .start(); 292 | 293 | this.startSpring = undefined; 294 | }; 295 | 296 | /** 297 | * Add a new CANNON.Body to a THREE.Mesh. 298 | * 299 | * @param {THREE.Mesh} obj 300 | * @param {string} type 301 | * @param {boolean} actuator - aka object used for interaction. 302 | * @param {boolean} springable 303 | * @param {Object} options 304 | */ 305 | PhysicsManager.prototype.add3DObject = function(obj, type, actuator, springable, options) { 306 | // Note: CANNON and THREE have the XY coordinates flipped 307 | 308 | var mass, bbox, widthX, widthY, widthZ, boxShape, boxBody; 309 | 310 | if(actuator) { 311 | mass = 0; 312 | } else { 313 | mass = 5; 314 | } 315 | 316 | switch(type) { 317 | case 'cube': 318 | bbox = new THREE.Box3().setFromObject(obj); 319 | 320 | widthX = bbox.max.x - bbox.min.x; 321 | widthY = bbox.max.y - bbox.min.y; 322 | widthZ = bbox.max.z - bbox.min.z; 323 | 324 | boxShape = new CANNON.Box(new CANNON.Vec3(widthX / 2, widthZ / 2, widthY / 2)); 325 | 326 | if(options) { 327 | boxBody = new CANNON.Body(options); 328 | } else { 329 | boxBody = new CANNON.Body({ 330 | mass: mass, 331 | angularDamping: 0.3 332 | }); 333 | } 334 | 335 | boxBody.addShape(boxShape); 336 | 337 | boxBody.position.set(obj.position.x, obj.position.z, obj.position.y); 338 | this.world.addBody(boxBody); 339 | boxBody.springable = springable; 340 | boxBody.isActuator = actuator; 341 | boxBody.isSpringing = false; 342 | boxBody.springIndex = obj.springIndex; 343 | 344 | if(actuator) { 345 | boxBody.addEventListener('collide', function(e) { 346 | if(!that.startPh && e.body.isStarter && that.lastTime > 1000) { 347 | that.dispatchEvent({ 348 | type: 'starts', 349 | gamepadIndex: obj.gamepadIndex 350 | }); 351 | 352 | that.startPh = true; 353 | that.deleteStarterObject(); 354 | } 355 | if(e.body.springable && !e.body.isSpringing && that.startPh) { 356 | if(e.body.springIndex !== void 0) { 357 | that.addToSpring(that.bodyText[e.body.springIndex], e.body); 358 | that.dispatchEvent({ 359 | type: 'letterHit', 360 | mesh: that.getThreeMeshFromCannonBody(e.body), 361 | gamepadIndex: obj.gamepadIndex 362 | }); 363 | } 364 | } 365 | }); 366 | } 367 | 368 | this.threeCannon.push({ 369 | 't': obj, 370 | 'c': boxBody 371 | }); 372 | 373 | break; 374 | 375 | case 'sphere': 376 | bbox = new THREE.Box3().setFromObject(obj); 377 | 378 | var radius = bbox.max.x - bbox.min.x; 379 | boxShape = new CANNON.Sphere(radius / 2); 380 | 381 | if(options) { 382 | boxBody = new CANNON.Body(options); 383 | } else { 384 | boxBody = new CANNON.Body({ 385 | mass: mass, 386 | angularDamping: 0.3 387 | }); 388 | } 389 | 390 | boxBody.addShape(boxShape); 391 | boxBody.position.set(obj.position.x, obj.position.z, obj.position.y); 392 | this.world.addBody(boxBody); 393 | boxBody.springable = springable; 394 | boxBody.isActuator = actuator; 395 | boxBody.springIndex = obj.springIndex; 396 | 397 | // if (actuator) { 398 | // boxBody.addEventListener("collide", function(e) {}); 399 | // } 400 | 401 | this.threeCannon.push({ 402 | 't': obj, 403 | 'c': boxBody 404 | }); 405 | 406 | break; 407 | 408 | case 'convex': 409 | bbox = new THREE.Box3().setFromObject(obj); 410 | 411 | widthX = bbox.max.x - bbox.min.x; 412 | widthY = bbox.max.y - bbox.min.y; 413 | widthZ = bbox.max.z - bbox.min.z; 414 | 415 | var verts = []; 416 | 417 | for(var i = 0; i < obj.geometry.vertices.length; i++) { 418 | verts.push(new CANNON.Vec3(obj.geometry.vertices[i].x, obj.geometry.vertices[i].z, obj.geometry.vertices[i].y)); 419 | } 420 | 421 | var faces = []; 422 | 423 | for(var i = 0; i < obj.geometry.faces.length; i++) { 424 | faces.push([obj.geometry.faces[i].a, obj.geometry.faces[i].b, obj.geometry.faces[i].c]); 425 | } 426 | 427 | boxShape = new CANNON.Trimesh(verts, faces); 428 | 429 | if(options) { 430 | boxBody = new CANNON.Body(options); 431 | } else { 432 | boxBody = new CANNON.Body({ 433 | mass: mass, 434 | angularDamping: 0.3 435 | }); 436 | } 437 | 438 | boxBody.addShape(boxShape); 439 | boxBody.position.set(obj.position.x, obj.position.z, obj.position.y); 440 | this.world.addBody(boxBody); 441 | boxBody.springable = springable; 442 | boxBody.isActuator = actuator; 443 | boxBody.isSpringing = false; 444 | boxBody.springIndex = obj.springIndex; 445 | 446 | if(actuator) { 447 | boxBody.addEventListener('collide', function(e) { 448 | if(e.body.springable && !e.body.isSpringing) { 449 | if(e.body.springIndex !== void 0) { 450 | that.addToSpring(that.bodyText[e.body.springIndex], e.body); 451 | that.dispatchEvent({ 452 | type: 'letterHit', 453 | mesh: that.getThreeMeshFromCannonBody(e.body) 454 | }); 455 | } 456 | } 457 | }); 458 | } 459 | 460 | this.threeCannon.push({ 461 | 't': obj, 462 | 'c': boxBody 463 | }); 464 | 465 | break; 466 | 467 | default: 468 | break; 469 | } 470 | }; 471 | 472 | /** 473 | * Returns the THREE.Mesh attached to a CANNON.Body. 474 | * 475 | * @param {CANNON.Body} body 476 | * @returns {THREE.Mesh} 477 | */ 478 | PhysicsManager.prototype.getThreeMeshFromCannonBody = function(body) { 479 | for(var i = 0; i < this.threeCannon.length; i++) { 480 | if(body.id === this.threeCannon[i].c.id) { 481 | return this.threeCannon[i].t; 482 | } 483 | } 484 | 485 | return {}; 486 | }; 487 | 488 | /** 489 | * Generates a bounding box made of CANNON.Plane. 490 | * 491 | * @param {float} x 492 | * @param {float} y 493 | * @param {float} z 494 | */ 495 | PhysicsManager.prototype.setClosedArea = function(x, y, z) { 496 | var widthX = x; 497 | var widthY = y; 498 | var widthZ = z; 499 | 500 | // Left 501 | var groundBody = new CANNON.Body({ mass: 0 }); 502 | var groundShape = new CANNON.Plane(widthZ, widthY); 503 | groundBody.addShape(groundShape); 504 | var rot = new CANNON.Vec3(0, 1, 0); 505 | groundBody.quaternion.setFromAxisAngle(rot, (Math.PI / 2)); 506 | groundBody.position.set(-widthX / 2, 0, widthY / 2); 507 | this.world.addBody(groundBody); 508 | 509 | // Right 510 | groundBody = new CANNON.Body({ mass: 0 }); 511 | groundShape = new CANNON.Plane(widthZ, widthY); 512 | groundBody.addShape(groundShape); 513 | rot = new CANNON.Vec3(0, 1, 0); 514 | groundBody.quaternion.setFromAxisAngle(rot, -(Math.PI / 2)); 515 | groundBody.position.set(widthX / 2, 0, widthY / 2); 516 | this.world.addBody(groundBody); 517 | 518 | // Front 519 | groundBody = new CANNON.Body({ mass: 0 }); 520 | groundShape = new CANNON.Plane(widthX, widthY); 521 | groundBody.addShape(groundShape); 522 | rot = new CANNON.Vec3(1, 0, 0); 523 | groundBody.quaternion.setFromAxisAngle(rot, -(Math.PI / 2)); 524 | groundBody.position.set(0, -widthZ / 2, widthY / 2); 525 | this.world.addBody(groundBody); 526 | 527 | // Back 528 | groundBody = new CANNON.Body({ mass: 0 }); 529 | groundShape = new CANNON.Plane(widthX, widthY); 530 | groundBody.addShape(groundShape); 531 | rot = new CANNON.Vec3(1, 0, 0); 532 | groundBody.quaternion.setFromAxisAngle(rot, (Math.PI / 2)); 533 | groundBody.position.set(0, widthZ / 2, widthY / 2); 534 | this.world.addBody(groundBody); 535 | 536 | // Top 537 | groundBody = new CANNON.Body({ mass: 0 }); 538 | groundShape = new CANNON.Plane(widthX, widthZ); 539 | groundBody.addShape(groundShape); 540 | rot = new CANNON.Vec3(0, 1, 0); 541 | groundBody.quaternion.setFromAxisAngle(rot, (Math.PI)); 542 | groundBody.position.set(0, 0, widthY); 543 | this.world.addBody(groundBody); 544 | }; 545 | 546 | /** 547 | * Create CANNON.Spring between the two CANNON.Body. 548 | * 549 | * @param {CANNON.Body} bodyA 550 | * @param {CANNON.Body} bodyB 551 | */ 552 | PhysicsManager.prototype.addToSpring = function(bodyA, bodyB) { 553 | // Distance between the bodies 554 | var dx = bodyA.position.x - bodyB.position.x; 555 | var dy = bodyA.position.y - bodyB.position.y; 556 | var dz = bodyA.position.z - bodyB.position.z; 557 | var dist = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2) + Math.pow(dz, 2)); 558 | 559 | bodyB.isSpringing = true; 560 | bodyB.waitsAnimation = true; 561 | 562 | var spring = new CANNON.Spring(bodyA, bodyB, { 563 | localAnchorA: new CANNON.Vec3(0, 0, -0.4), 564 | localAnchorB: new CANNON.Vec3(0, 0, 0), 565 | restLength: dist, 566 | stiffness: 50, 567 | damping: 40 568 | }); 569 | 570 | that.springElements.push(spring); 571 | 572 | if(that.springElements.length >= that.lettersLength) { 573 | that.dispatchEvent({ 574 | type: 'messageDone' 575 | }); 576 | } 577 | 578 | // Shrink the spring resting lenght to 0 579 | new TWEEN.Tween({ 580 | length: spring.restLength 581 | }).to({ 582 | length: 0 583 | }, 2000) 584 | .easing(TWEEN.Easing.Exponential.InOut) 585 | .onUpdate(function() { 586 | spring.restLength = this.length; 587 | }) 588 | .start(); 589 | }; 590 | 591 | /** 592 | * Setting up the VR Mode. 593 | * 594 | * @param {int} mode 595 | */ 596 | PhysicsManager.prototype.setMode = function(mode) { 597 | this.mode = mode; 598 | }; 599 | 600 | /** 601 | * Add a CANNON.Body for each letter, and returns an array of the CANNON.Spring indices. 602 | * 603 | * @param {string} text 604 | * @returns {Array} 605 | */ 606 | PhysicsManager.prototype.setBodyText = function(text) { 607 | var boundingSphere = new CANNON.Sphere(0.1); 608 | 609 | var letterWidth = 1.3; 610 | var letterHeight = 2; 611 | 612 | // with CANNON, y and z axis are swapped 613 | var x = 0; 614 | var y = 5; 615 | var z = -9; 616 | 617 | var indices = []; 618 | 619 | var lines = text.split('\\N'); 620 | 621 | var offsetY = (lines.length * letterHeight) / 2; 622 | 623 | for(var i = 0; i < lines.length; ++i) { 624 | var line = lines[i]; 625 | 626 | var offsetX = (line.length * letterWidth) / 2; 627 | 628 | for(var j = 0; j < line.length; ++j) { 629 | var letter = line[j]; 630 | 631 | if(letter !== ' ') { 632 | this.bodyText.push(new CANNON.Body({ 633 | mass: 0, 634 | position: new CANNON.Vec3(x - offsetX, z, y + offsetY), 635 | shape: boundingSphere 636 | })); 637 | 638 | indices.push(this.bodyText.length - 1); 639 | } 640 | 641 | x += letterWidth; 642 | } 643 | 644 | x = 0; 645 | y -= letterHeight; 646 | } 647 | 648 | return indices; 649 | }; 650 | 651 | /** 652 | * Animate a quaternion to his resting position. 653 | * 654 | * @param {any} obj 655 | * @param {float} duration 656 | */ 657 | PhysicsManager.prototype.animateQuaternion = function(obj, duration) { 658 | var startQuaternion = new THREE.Quaternion().copy(obj.t.quaternion).normalize(); 659 | var endQuaternion = new THREE.Quaternion().set(0, 0, 0, 1).normalize(); 660 | 661 | new TWEEN.Tween({ 662 | progress: 0 663 | }).to({ 664 | progress: 1 665 | }, duration).onUpdate(function() { 666 | THREE.Quaternion.slerp( 667 | startQuaternion, 668 | endQuaternion, 669 | obj.t.quaternion, 670 | this.progress 671 | ); 672 | }).start(); 673 | }; 674 | 675 | /** 676 | * Setting up the length of the message. 677 | * This will allow us to know when all the letters have been hit. 678 | * 679 | * @param {int} duration 680 | */ 681 | PhysicsManager.prototype.setLettersLength = function(value) { 682 | this.lettersLength = value; 683 | }; 684 | 685 | module.exports = PhysicsManager; 686 | -------------------------------------------------------------------------------- /app/view/World3D.js: -------------------------------------------------------------------------------- 1 | var THREE = require('three'); 2 | var TWEEN = require('tween.js'); 3 | 4 | var VRControls = require('./../utils/VRControls'); 5 | var VREffect = require('./../utils/VREffect'); 6 | 7 | var GamePads = require('./gamepads/GamePads'); 8 | var MousePad = require('./gamepads/MousePad'); 9 | 10 | var PhysicsManager = require('./PhysicsManager'); 11 | 12 | var SoundManager = require('./sound/SoundManager'); 13 | var AssetsSound = require('./sound/AssetsSound'); 14 | 15 | var Floor = require('./floor/Floor'); 16 | var Cube = require('./cube/Cube'); 17 | var Explosion = require('./explosion/Explosion'); 18 | var Confettis = require('./confettis/Confettis'); 19 | var Letter = require('./letter/Letter'); 20 | var Shape = require('./shape/Shape'); 21 | 22 | var random = require('./utils').random; 23 | var getTextAndColorsFromHash = require('./utils').getTextAndColorsFromHash; 24 | var sendTextToAnalytics = require('./utils').sendTextToAnalytics; 25 | 26 | /** 27 | * @interface ILetterInfos { 28 | * char letter; 29 | * string color; 30 | * } 31 | * 32 | * @interface ICollisionEvent { 33 | * string type; 34 | * THREE.Mesh? mesh; 35 | * int gamepadIndex; 36 | * } 37 | */ 38 | 39 | /** 40 | * @param {HTMLElement} container 41 | */ 42 | var World3D = function(container) { 43 | this.boxSize = 20; 44 | 45 | this.container = container; 46 | 47 | this.camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 10000); 48 | this.camera.layers.enable(1); 49 | this.dummyCamera = new THREE.Object3D(); 50 | this.dummyCamera.add(this.camera); 51 | 52 | this.scene = new THREE.Scene(); 53 | this.renderer = new THREE.WebGLRenderer({ antialias: true }); 54 | 55 | this.physicsManager = new PhysicsManager(this.dummyCamera,this.camera); 56 | this.physicsManager.setClosedArea(this.boxSize, this.boxSize, this.boxSize); 57 | 58 | this.controls = new VRControls(this.camera); 59 | this.controls.standing = true; 60 | 61 | this.effect = new VREffect( 62 | this.renderer, 63 | null, 64 | null, 65 | this.onRenderLeft.bind(this), 66 | this.onRenderRight.bind(this) 67 | ); 68 | 69 | this.manager = new WebVRManager(this.renderer, this.effect, { 70 | hideButton: false, 71 | isUndistorted: false 72 | }); 73 | 74 | this.addEvents(); 75 | 76 | // plane to raycast 77 | this.planeCalc = new THREE.Mesh( 78 | new THREE.PlaneBufferGeometry(100, 100, 2, 2), 79 | new THREE.MeshNormalMaterial({ 80 | transparent: true, 81 | opacity: 0 82 | }) 83 | ); 84 | 85 | this.scene.add(this.dummyCamera); 86 | 87 | // elements 88 | this.floor = null; 89 | this.introCube = null; 90 | this.confettis = null; 91 | this.letters = []; 92 | this.shapes = []; 93 | 94 | this.createFloor(); 95 | this.createIntroCube(); 96 | this.createConfettis(); 97 | this.createLetters(); 98 | this.createShapes(); 99 | 100 | this.soundManager = new SoundManager(); 101 | this.soundManager.addSoundsFromConfig(AssetsSound.Sounds); 102 | this.balloonSoundIndex = 0; 103 | this.isSuccessSoundPlaying = false; 104 | 105 | this.renderBound = this.render.bind(this); 106 | }; 107 | 108 | World3D.prototype.setup = function() { 109 | this.renderer.setClearColor('#1a1f27', 1); 110 | this.container.appendChild(this.renderer.domElement); 111 | 112 | this.positionTouch1 = new THREE.Vector3(0, 100, 0); 113 | this.positionTouch2 = new THREE.Vector3(0, 100, 0); 114 | 115 | this.render(0); 116 | }; 117 | 118 | /** 119 | * @param {int} mode 120 | */ 121 | World3D.prototype.onModeChange = function(mode) { 122 | this.physicsManager.setMode(mode); 123 | 124 | if(mode === 3) { 125 | console.log('Passing to VR mode'); 126 | } 127 | }; 128 | 129 | World3D.prototype.addEvents = function() { 130 | this.manager.on('initialized', this.onInitializeManager.bind(this)); 131 | this.manager.on('modechange', this.onModeChange.bind(this)); 132 | 133 | this.physicsManager.addEventListener('starts', this.onStart.bind(this)); 134 | this.physicsManager.addEventListener('letterHit', this.onLetterHit.bind(this)); 135 | this.physicsManager.addEventListener('messageDone', this.onMessageComplete.bind(this)); 136 | this.physicsManager.addEventListener('messageUnlocked', this.onMessageRelease.bind(this)); 137 | }; 138 | 139 | /** 140 | * @param {ICollisionEvent} e 141 | */ 142 | World3D.prototype.onStart = function(e) { 143 | var gamepadIndex = e.gamepadIndex; 144 | 145 | this.soundManager.play(AssetsSound.BACKGROUND_NORMAL); 146 | 147 | for(var i = 0; i < this.shapes.length; ++i) { 148 | this.shapes[i].fadeIn(); 149 | } 150 | 151 | for(var i = 0; i < this.letters.length; ++i) { 152 | this.letters[i].fadeIn(); 153 | } 154 | 155 | this.physicsManager.attractBodiesToPlayer(); 156 | 157 | if(gamepadIndex !== void 0 && this.gamePads.vibrate) { 158 | this.gamePads.vibrate(gamepadIndex); 159 | } 160 | }; 161 | 162 | World3D.prototype.onMessageComplete = function() { 163 | this.soundManager.fadeOut(AssetsSound.BACKGROUND_NORMAL); 164 | 165 | if(this.isSuccessSoundPlaying) { 166 | this.soundManager.fadeIn(AssetsSound.BACKGROUND_SUCCESS); 167 | } 168 | else { 169 | this.soundManager.play(AssetsSound.BACKGROUND_SUCCESS); 170 | this.isSuccessSoundPlaying = true; 171 | } 172 | 173 | if(!this.confettis.el.parent) { 174 | this.scene.add(this.confettis.el); 175 | } 176 | 177 | this.confettis.start(); 178 | 179 | for(var i = 0; i < this.shapes.length; ++i) { 180 | this.shapes[i].startTripping(); 181 | } 182 | 183 | for(var j = 0; j < this.letters.length; ++j) { 184 | this.letters[j].startInflateLoop(random(1000, 5000)); 185 | } 186 | }; 187 | 188 | World3D.prototype.onMessageRelease = function() { 189 | this.soundManager.fadeIn(AssetsSound.BACKGROUND_NORMAL); 190 | this.soundManager.fadeOut(AssetsSound.BACKGROUND_SUCCESS); 191 | 192 | for(var i = 0; i < this.shapes.length; ++i) { 193 | this.shapes[i].stopTripping(); 194 | } 195 | 196 | for(var j = 0; j < this.letters.length; ++j) { 197 | this.letters[j].stopInflateLoop(); 198 | } 199 | }; 200 | 201 | /** 202 | * @param {ICollisionEvent} e 203 | */ 204 | World3D.prototype.onLetterHit = function(e) { 205 | var gamepadIndex = e.gamepadIndex; // left: 0, right: 1 206 | var mesh = e.mesh; 207 | var letter = mesh.letter; 208 | 209 | var explosion = Explosion.pool.length 210 | ? Explosion.pool.pop() 211 | : new Explosion(); 212 | 213 | explosion.setParent(this.scene); 214 | explosion.el.position.copy(mesh.position); 215 | 216 | new TWEEN.Tween({ progress: 0 }) 217 | .to({ progress: 1 }, 400) 218 | .onUpdate(function() { 219 | explosion.setProgress(this.progress); 220 | }) 221 | .onComplete(function() { 222 | Explosion.pool.push(explosion); 223 | explosion.setParent(null); 224 | }) 225 | .start(); 226 | 227 | letter.inflate(); 228 | 229 | // sound 230 | this.balloonSoundIndex++; 231 | 232 | if(this.balloonSoundIndex >= 4) { 233 | this.balloonSoundIndex = 0; 234 | } 235 | 236 | this.soundManager.play(AssetsSound['BALLOON_' + (this.balloonSoundIndex + 1)]); 237 | 238 | if(gamepadIndex !== void 0 && this.gamePads.vibrate) { 239 | this.gamePads.vibrate(gamepadIndex); 240 | } 241 | }; 242 | 243 | World3D.prototype.onInitializeManager = function(n, o) { 244 | if(!this.manager.isVRCompatible || typeof window.orientation !== 'undefined') { 245 | this.gamePads = new MousePad(this.scene, this.camera, this.effect, this.physicsManager); 246 | this.dummyCamera.position.z = 5; 247 | this.dummyCamera.position.y = 0.5; 248 | } else { 249 | this.gamePads = new GamePads(this.scene, this.camera, this.effect, this.physicsManager); 250 | } 251 | 252 | if(this.gamePads.h2 !== void 0) { 253 | this.physicsManager.add3DObject(this.gamePads.h2, 'cube', true, false); 254 | } 255 | 256 | this.setup(); 257 | }; 258 | 259 | /** 260 | * @returns {{x:float, y:float, z:float}} 261 | */ 262 | World3D.prototype.getRandomCoordinatesInBox = function() { 263 | var x = random(-this.boxSize / 2, this.boxSize / 2); 264 | var y = random(-this.boxSize / 2, this.boxSize / 2); 265 | var z = random(-this.boxSize / 2, this.boxSize / 2); 266 | 267 | return { 268 | x: x, 269 | y: y, 270 | z: z 271 | } 272 | }; 273 | 274 | World3D.prototype.createFloor = function() { 275 | this.floor = new Floor(); 276 | this.scene.add(this.floor.el); 277 | }; 278 | 279 | World3D.prototype.createIntroCube = function() { 280 | this.introCube = new Cube(1); 281 | this.introCube.el.position.y = 0.5; 282 | this.scene.add(this.introCube.el); 283 | this.physicsManager.addStarterObject(this.introCube.el,"cube"); 284 | }; 285 | 286 | World3D.prototype.createConfettis = function() { 287 | this.confettis = new Confettis(new THREE.Vector3(10, 10, 10), 1200, false); 288 | this.confettis.el.position.y += 5; 289 | }; 290 | 291 | World3D.prototype.createShapes = function() { 292 | for(var i = 0; i < 100; ++i) { 293 | var shape = new Shape(); 294 | 295 | var coordinates = this.getRandomCoordinatesInBox(); 296 | shape.el.position.set(coordinates.x, coordinates.y, coordinates.z); 297 | 298 | this.shapes.push(shape); 299 | this.scene.add(shape.el); 300 | this.physicsManager.add3DObject(shape.el, 'sphere', false, false); 301 | } 302 | }; 303 | 304 | /** 305 | * @param {string} text 306 | * @param {colors} colors 307 | * @param {{[key:string]:string}} colorsTable 308 | * @returns {Array} 309 | */ 310 | World3D.prototype.getLettersInfos = function(text, colors, colorsTable) { 311 | var letters = text.replace(/\\N/g, ' ').split(''); 312 | 313 | var lettersInfos = []; 314 | 315 | for(var i = 0; i < letters.length; ++i) { 316 | var letter = letters[i]; 317 | 318 | if(letter === ' ') { 319 | continue; 320 | } 321 | 322 | var letterInfos = { 323 | letter: letter, 324 | color: colorsTable[colors[i]] 325 | } 326 | 327 | lettersInfos.push(letterInfos); 328 | } 329 | 330 | return lettersInfos; 331 | }; 332 | 333 | World3D.prototype.createLetters = function() { 334 | var textInfos = getTextAndColorsFromHash(); 335 | 336 | sendTextToAnalytics(textInfos.text.replace(/\\N/g, ' ')); 337 | 338 | var lettersInfos = this.getLettersInfos( 339 | textInfos.text, 340 | textInfos.colors, 341 | { 342 | S: 'silver', 343 | G: 'gold' 344 | } 345 | ); 346 | 347 | this.physicsManager.setLettersLength(lettersInfos.length); 348 | var indices = this.physicsManager.setBodyText(textInfos.text); 349 | 350 | for(var i = 0; i < lettersInfos.length; i++ ){ 351 | var letterInfos = lettersInfos[i]; 352 | 353 | var letter = new Letter(letterInfos.letter, letterInfos.color); 354 | 355 | // attach letter to el 356 | // that way we can access back the Letter onLetterHit 357 | letter.el.letter = letter; 358 | 359 | var coordinates = this.getRandomCoordinatesInBox(); 360 | letter.el.position.set(coordinates.x, coordinates.y, coordinates.z); 361 | 362 | letter.el.springIndex = indices[i]; 363 | 364 | this.letters.push(letter); 365 | this.scene.add(letter.el); 366 | 367 | var addToPhysicSimulation = (function(letter) { 368 | this.physicsManager.add3DObject(letter.el, 'cube', false, true); 369 | letter.removeEventListener(addToPhysicSimulation); 370 | }).bind(this, letter); 371 | 372 | if(letter.isReady) { 373 | addToPhysicSimulation(); 374 | } 375 | else { 376 | letter.addEventListener('ready', addToPhysicSimulation); 377 | } 378 | } 379 | }; 380 | 381 | World3D.prototype.onRenderLeft = function() {}; 382 | 383 | World3D.prototype.onRenderRight = function() {}; 384 | 385 | /** 386 | * @param {float} timestamp 387 | */ 388 | World3D.prototype.render = function(timestamp) { 389 | window.requestAnimationFrame(this.renderBound); 390 | 391 | TWEEN.update(); 392 | 393 | for(var i = 0; i < this.shapes.length; ++i) { 394 | this.shapes[i].update(); 395 | } 396 | 397 | this.confettis.update(); 398 | 399 | this.planeCalc.lookAt(this.dummyCamera.position); 400 | this.gamePads.update(timestamp, [this.planeCalc]); 401 | 402 | this.physicsManager.update(timestamp); 403 | 404 | this.controls.update(); 405 | 406 | this.manager.render(this.scene, this.camera, timestamp); 407 | }; 408 | 409 | /** 410 | * @param {float} w 411 | * @param {float} h 412 | */ 413 | World3D.prototype.onResize = function(w, h) { 414 | this.renderer.setPixelRatio(window.devicePixelRatio); 415 | this.effect.setSize(w, h); 416 | this.camera.aspect = w / h; 417 | this.camera.updateProjectionMatrix(); 418 | }; 419 | 420 | module.exports = World3D; 421 | -------------------------------------------------------------------------------- /app/view/confettis/Confettis.js: -------------------------------------------------------------------------------- 1 | var THREE = require('three'); 2 | var random = require('../utils').random; 3 | var textureLoader = require('../utils').textureLoader; 4 | 5 | var vertexShader = require('./vs-confettis.glsl'); 6 | var fragmentShader = require('./fs-confettis.glsl'); 7 | 8 | /** 9 | * @interface IBoundaries { 10 | * float top; 11 | * float bottom; 12 | * float left; 13 | * float right; 14 | * float front; 15 | * float back; 16 | * } 17 | */ 18 | 19 | /** 20 | * @param {THREE.Vector3} size 21 | * @param {int} [count=200] 22 | */ 23 | function Confettis(size, count) { 24 | this._size = size; 25 | this._count = count || 200; 26 | 27 | this._isActive = false; 28 | 29 | this._boundaries = null; 30 | this._computeBoundaries(); 31 | 32 | this._geometry = null; 33 | this._createGeometry(); 34 | 35 | this._points = new THREE.Points(this._geometry, Confettis._material); 36 | this._points.frustumCulled = false; 37 | 38 | this.el = new THREE.Object3D(); 39 | this.el.add(this._points); 40 | }; 41 | 42 | Confettis._typesCount = 6; 43 | 44 | Confettis._material = new THREE.RawShaderMaterial({ 45 | uniforms: { 46 | size: { type: 'f', value: 40 }, 47 | map: { type: 't', value: textureLoader.load('assets/textures/confettis.png') }, 48 | repeat: { type: 'v2', value: new THREE.Vector2(1 / Confettis._typesCount, 1) } 49 | }, 50 | vertexShader: vertexShader, 51 | fragmentShader: fragmentShader, 52 | transparent: true, 53 | depthWrite: false 54 | }); 55 | 56 | Confettis.prototype._createGeometry = function() { 57 | this._geometry = new THREE.BufferGeometry(); 58 | 59 | var positions = new Float32Array(3 * this._count); 60 | var colors = new Float32Array(3 * this._count); 61 | var scales = new Float32Array(this._count); 62 | var offsets = new Float32Array(2 * this._count); 63 | 64 | this._velocities = new Float32Array(3 * this._count); 65 | 66 | for(var i = 0, j = 0, k = 0; i < this._count; ++i, j += 3, k += 2) { 67 | positions[j] = random(this._boundaries.left, this._boundaries.right); 68 | positions[j + 1] = random(this._boundaries.top, this._boundaries.top + this._size.y / 10); 69 | positions[j + 2] = random(this._boundaries.front, this._boundaries.back); 70 | 71 | colors[j] = Math.random(); 72 | colors[j + 1] = Math.random(); 73 | colors[j + 2] = Math.random(); 74 | 75 | scales[i] = random(1, 2); 76 | 77 | offsets[k] = random(0, Confettis._typesCount - 1, true) * (1 / Confettis._typesCount); 78 | offsets[k + 1] = 0; 79 | 80 | this._velocities[j] = random(-0.01, 0.01); 81 | this._velocities[j + 1] = random(-0.03, 0); 82 | this._velocities[j + 2] = 0; 83 | } 84 | 85 | this._geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3)); 86 | this._geometry.addAttribute('color', new THREE.BufferAttribute(colors, 3)); 87 | this._geometry.addAttribute('scale', new THREE.BufferAttribute(scales, 1)); 88 | this._geometry.addAttribute('offset', new THREE.BufferAttribute(offsets, 2)); 89 | }; 90 | 91 | Confettis.prototype._computeBoundaries = function() { 92 | var halfX = this._size.x / 2; 93 | var halfY = this._size.y / 2; 94 | var halfZ = this._size.z / 2; 95 | 96 | this._boundaries = { 97 | left: -halfX, 98 | right: halfX, 99 | top: halfY, 100 | bottom: -halfY, 101 | front: halfZ, 102 | back: -halfZ 103 | } 104 | }; 105 | 106 | Confettis.prototype.update = function() { 107 | if(!this._isActive) { 108 | return; 109 | } 110 | 111 | var positions = this._geometry.attributes.position.array; 112 | var velocities = this._velocities; 113 | 114 | for(var i = 0; i < positions.length; i += 3) { 115 | if(positions[i + 1] < this._boundaries.bottom) { 116 | positions[i + 1] = this._boundaries.top; 117 | 118 | if(positions[i] < this._boundaries.left) { 119 | positions[i] = this._boundaries.right; 120 | } 121 | else if(positions[i] > this._boundaries.right) { 122 | positions[i] = this._boundaries.left; 123 | } 124 | 125 | if(positions[i + 2] > this._boundaries.front) { 126 | positions[i + 2] = this._boundaries.back; 127 | } 128 | else if(positions[i + 2] < this._boundaries.back) { 129 | positions[i + 2] = this._boundaries.front; 130 | } 131 | } 132 | 133 | positions[i] += velocities[i]; 134 | positions[i + 1] += velocities[i + 1]; 135 | positions[i + 2] += velocities[i + 2]; 136 | } 137 | 138 | this._geometry.attributes.position.needsUpdate = true; 139 | }; 140 | 141 | Confettis.prototype.start = function() { 142 | this._isActive = true; 143 | }; 144 | 145 | Confettis.prototype.stop = function() { 146 | this._isActive = false; 147 | }; 148 | 149 | Confettis.prototype.dispose = function() { 150 | if(this.el.parent) { 151 | this.el.parent.remove(this.el); 152 | } 153 | }; 154 | 155 | module.exports = Confettis; 156 | -------------------------------------------------------------------------------- /app/view/confettis/fs-confettis.glsl: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | uniform sampler2D map; 4 | uniform vec2 repeat; 5 | 6 | varying vec3 vColor; 7 | varying vec2 vOffset; 8 | 9 | void main(void) { 10 | vec2 uv = vec2(gl_PointCoord.x, 1.0 - gl_PointCoord.y); 11 | vec2 offsetedUv = uv * repeat + vOffset; 12 | 13 | vec4 textureColor = texture2D(map, offsetedUv); 14 | textureColor.rgb *= vColor; 15 | 16 | gl_FragColor = textureColor; 17 | } 18 | -------------------------------------------------------------------------------- /app/view/confettis/vs-confettis.glsl: -------------------------------------------------------------------------------- 1 | uniform mat4 modelViewMatrix; 2 | uniform mat4 projectionMatrix; 3 | uniform float size; 4 | 5 | attribute vec3 position; 6 | attribute float scale; 7 | attribute vec2 offset; 8 | attribute vec3 color; 9 | 10 | varying vec3 vColor; 11 | varying vec2 vOffset; 12 | 13 | void main(void) { 14 | vColor = color; 15 | vOffset = offset; 16 | 17 | vec4 mvPosition = modelViewMatrix * vec4(position, 1.0); 18 | 19 | gl_PointSize = size * (scale / -mvPosition.z); 20 | gl_Position = projectionMatrix * mvPosition; 21 | } 22 | -------------------------------------------------------------------------------- /app/view/cube/Cube.js: -------------------------------------------------------------------------------- 1 | var THREE = require('three'); 2 | var textureLoader = require('../utils').textureLoader; 3 | 4 | /** 5 | * @param {float} [size=1] 6 | */ 7 | function Cube(size) { 8 | size = size || 1; 9 | 10 | var geometry = new THREE.BoxBufferGeometry(size, size, size); 11 | 12 | var material = new THREE.MeshBasicMaterial({ 13 | map: textureLoader.load('assets/textures/breel.png') 14 | }); 15 | 16 | this.el = new THREE.Mesh(geometry, material); 17 | }; 18 | 19 | Cube.prototype.dispose = function() { 20 | if(this.el.parent) { 21 | this.el.remove(this.el); 22 | } 23 | }; 24 | 25 | module.exports = Cube; 26 | -------------------------------------------------------------------------------- /app/view/explosion/Explosion.js: -------------------------------------------------------------------------------- 1 | var THREE = require('three'); 2 | 3 | var vertexShader = require('./vs-explosion.glsl'); 4 | var fragmentShader = require('./fs-explosion.glsl'); 5 | 6 | /** 7 | * @param {float} radius 8 | * @param {int} divisions 9 | */ 10 | function Explosion(radius, divisions) { 11 | this._radius = radius = 1; 12 | this._divisions = divisions || 12; 13 | 14 | this.el = new THREE.Object3D(); 15 | 16 | this._material = Explosion._material.clone(); 17 | 18 | this._createLines(); 19 | }; 20 | 21 | Explosion._material = new THREE.RawShaderMaterial({ 22 | uniforms: { 23 | progress: { type: 'f', value: 0 } 24 | }, 25 | vertexShader: vertexShader, 26 | fragmentShader: fragmentShader, 27 | transparent: true, 28 | depthWrite: false, 29 | linewidth: 2 30 | }); 31 | 32 | Explosion.pool = []; 33 | 34 | Explosion.prototype._createLines = function() { 35 | var sphereGeometry = new THREE.SphereGeometry( 36 | this._radius, 37 | this._divisions, 38 | this._divisions 39 | ); 40 | 41 | for(var i = 0; i < sphereGeometry.vertices.length; ++i) { 42 | var vertice = sphereGeometry.vertices[i]; 43 | 44 | var endOffset = Math.random() * 2; 45 | 46 | var endX = vertice.x * endOffset; 47 | var endY = vertice.y * endOffset; 48 | var endZ = vertice.z * endOffset; 49 | 50 | var startOffset = Math.random() * 0.5 + 2; 51 | 52 | var startX = endX * startOffset; 53 | var startY = endY * startOffset; 54 | var startZ = endZ * startOffset; 55 | 56 | var positions = new Float32Array([ 57 | startX, startY, startZ, 58 | endX, endY, endZ 59 | ]); 60 | 61 | var influences = new Float32Array([ 62 | 1, 63 | 0 64 | ]); 65 | 66 | var tints = new Float32Array([ 67 | Math.random(), Math.random(), Math.random(), 68 | Math.random(), Math.random(), Math.random() 69 | ]); 70 | 71 | var geometry = new THREE.BufferGeometry(); 72 | geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3)); 73 | geometry.addAttribute('influence', new THREE.BufferAttribute(influences, 1)); 74 | geometry.addAttribute('tint', new THREE.BufferAttribute(tints, 3)); 75 | 76 | var line = new THREE.Line(geometry, this._material); 77 | this.el.add(line); 78 | } 79 | }; 80 | 81 | /** 82 | * @param {THREE.Object3D} parent 83 | */ 84 | Explosion.prototype.setParent = function(parent) { 85 | if(this.el.parent) { 86 | this.el.parent.remove(this.el); 87 | } 88 | 89 | if(parent) { 90 | parent.add(this.el); 91 | } 92 | }; 93 | 94 | /** 95 | * @param {float} value from 0 to 1 96 | */ 97 | Explosion.prototype.setProgress = function(value) { 98 | this._material.uniforms.progress.value = value; 99 | }; 100 | 101 | Explosion.prototype.dispose = function() { 102 | if(this.el.parent) { 103 | this.el.parent.remove(this.el); 104 | } 105 | }; 106 | 107 | module.exports = Explosion; 108 | -------------------------------------------------------------------------------- /app/view/explosion/fs-explosion.glsl: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | varying float vInfluence; 4 | varying vec3 vTint; 5 | varying float vProgress; 6 | 7 | float map(const in float value, const in float inMin, const in float inMax, const in float outMin, const in float outMax) { 8 | if(value < inMin) { 9 | return outMin; 10 | } 11 | 12 | if(value > inMax) { 13 | return outMax; 14 | } 15 | 16 | return (value - inMin) / (inMax - inMin) * (outMax - outMin) + outMin; 17 | } 18 | 19 | void main() { 20 | float alpha = map(vProgress, 0.5, 1.0, 1.0, 0.0); 21 | 22 | gl_FragColor = vec4(vTint, vInfluence); 23 | gl_FragColor.a *= alpha; 24 | } 25 | -------------------------------------------------------------------------------- /app/view/explosion/vs-explosion.glsl: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | attribute float influence; 4 | attribute vec3 position; 5 | attribute vec3 tint; 6 | 7 | uniform mat4 projectionMatrix; 8 | uniform mat4 modelViewMatrix; 9 | uniform float progress; 10 | 11 | varying float vInfluence; 12 | varying vec3 vTint; 13 | varying float vProgress; 14 | 15 | float map(const in float value, const in float inMin, const in float inMax, const in float outMin, const in float outMax) { 16 | if(value < inMin) { 17 | return outMin; 18 | } 19 | 20 | if(value > inMax) { 21 | return outMax; 22 | } 23 | 24 | return (value - inMin) / (inMax - inMin) * (outMax - outMin) + outMin; 25 | } 26 | 27 | void main() { 28 | vInfluence = influence; 29 | vTint = tint; 30 | vProgress = progress; 31 | 32 | vec3 finalPosition = position; 33 | finalPosition *= map(progress, 0.0, 1.0, 0.0, 1.0); 34 | 35 | gl_Position = projectionMatrix * modelViewMatrix * vec4(finalPosition, 1.0); 36 | } 37 | -------------------------------------------------------------------------------- /app/view/floor/Floor.js: -------------------------------------------------------------------------------- 1 | var THREE = require('three'); 2 | var textureLoader = require('../utils').textureLoader; 3 | 4 | function Floor() { 5 | this.el = new THREE.Object3D(); 6 | this.el.rotation.x = -Math.PI / 2; 7 | 8 | var floor = new THREE.Mesh( 9 | new THREE.PlaneBufferGeometry(100, 100), 10 | new THREE.MeshBasicMaterial({ color: '#1a1f27' }) 11 | ); 12 | 13 | this.el.add(floor); 14 | 15 | var center = new THREE.Mesh( 16 | new THREE.PlaneBufferGeometry(6, 6), 17 | new THREE.MeshBasicMaterial({ 18 | map: textureLoader.load('assets/textures/floor.png'), 19 | transparent: true 20 | }) 21 | ); 22 | 23 | center.position.z = 0.01; 24 | 25 | this.el.add(center); 26 | }; 27 | 28 | Floor.prototype.dispose = function() { 29 | if(this.el.parent) { 30 | this.el.parent.remove(this.el); 31 | } 32 | }; 33 | 34 | module.exports = Floor; 35 | -------------------------------------------------------------------------------- /app/view/gamepads/GamePads.js: -------------------------------------------------------------------------------- 1 | var THREE = require('three'); 2 | var textureLoader = require('../utils').textureLoader; 3 | var jsonLoader = require('../utils').jsonLoader; 4 | 5 | /** 6 | * @param {THREE.Scene} scene 7 | * @param {THREE.Camera} camera 8 | * @param {VREffect} effect 9 | * @param {PhysicsManager} physics 10 | */ 11 | var GamePads = function(scene, camera, effect , physics) { 12 | window.gamePads = this; 13 | 14 | this.scene = scene; 15 | this.camera = camera; 16 | this.effect = effect; 17 | this.phManager = physics; 18 | 19 | this.intersectPoint = new THREE.Vector3(); 20 | this.intersectPoint2 = new THREE.Vector3(); 21 | this.sTSMat = new THREE.Matrix4(); 22 | 23 | var tempHand = new THREE.Mesh( 24 | new THREE.BoxBufferGeometry(0.1, 0.1, 0.1, 1, 1, 1), 25 | new THREE.MeshNormalMaterial() 26 | ); 27 | 28 | this.h1 = tempHand; 29 | this.h2 = tempHand; 30 | this.handlers = [this.h1, this.h2]; 31 | 32 | this.cursorlocked = []; 33 | this.cursorlocked[0] = false; 34 | this.cursorlocked[1] = false; 35 | this.triggerlocked = []; 36 | this.triggerlocked[0] = false; 37 | this.triggerlocked[1] = false; 38 | 39 | this._loadModel(); 40 | }; 41 | 42 | GamePads.prototype._loadModel = function() { 43 | jsonLoader.load('assets/hand/hand.json', (function (geometry) { 44 | geometry.scale(0.01, 0.01, 0.01); 45 | geometry.rotateY(Math.PI); 46 | geometry.computeBoundingBox(); 47 | 48 | var texture = textureLoader.load('assets/textures/hand_occlusion.jpg'); 49 | 50 | texture.generateMipmaps = false; 51 | texture.minFilter = THREE.LinearFilter; 52 | texture.magFilter = THREE.LinearFilter; 53 | 54 | var material = new THREE.MeshBasicMaterial({ 55 | map: texture, 56 | side: THREE.DoubleSide 57 | }); 58 | 59 | var hand = new THREE.Mesh(geometry, material); 60 | var hand2 = new THREE.Mesh(hand.geometry.clone(), hand.material.clone()); 61 | hand2.geometry.scale(-1, 1, 1); 62 | 63 | this.h1 = hand; 64 | this.h2 = hand2; 65 | this.h1.gamepadIndex = 0; 66 | this.h2.gamepadIndex = 1; 67 | 68 | this.h1.matrixAutoUpdate = false; 69 | this.h2.matrixAutoUpdate = false; 70 | 71 | this.handlers[0] = this.h1; 72 | this.handlers[1] = this.h2; 73 | 74 | this.scene.add(this.h1); 75 | this.scene.add(this.h2); 76 | this.phManager.add3DObject(this.h1, 'cube', true, false); 77 | this.phManager.add3DObject(this.h2, 'cube', true, false); 78 | }).bind(this)); 79 | }; 80 | 81 | /** 82 | * @param {float} time 83 | */ 84 | GamePads.prototype.update = function(time) { 85 | // Loop over every gamepad and if we find any that has a pose use it. 86 | var vrGamepads = []; 87 | var gamepads = navigator.getGamepads(); 88 | 89 | if(this.effect.getHMD()) { 90 | if(this.effect.getHMD().stageParameters) { 91 | this.sTSMat.fromArray(this.effect.getHMD().stageParameters.sittingToStandingTransform); 92 | } 93 | } 94 | 95 | for(var i = 0; i < gamepads.length; ++i) { 96 | var gamepad = gamepads[i]; 97 | 98 | // The array may contain undefined gamepads, so check for that as 99 | // well as a non-null pose. 100 | if(gamepad && gamepad.pose) { 101 | vrGamepads.push(gamepad); 102 | 103 | this.handlers[i].position.fromArray(gamepad.pose.position); 104 | 105 | this.handlers[i].quaternion.fromArray(gamepad.pose.orientation); 106 | this.handlers[i].updateMatrix(); 107 | this.handlers[i].applyMatrix(this.sTSMat); 108 | 109 | this.intersectPoint.copy(this.handlers[0].position); 110 | this.intersectPoint2.copy(this.handlers[1].position); 111 | 112 | if(gamepad.buttons[0].pressed) { 113 | if(this.cursorlocked[i] === false){ 114 | this.cursorlocked[i] = true; 115 | this.phManager.onCursor(-1); 116 | 117 | console.log('cursor locked'); 118 | } 119 | } 120 | else{ 121 | if(this.cursorlocked[i] === true){ 122 | this.cursorlocked[i] = false; 123 | 124 | console.log('cursor unlocked'); 125 | } 126 | } 127 | //Trigger 128 | if(gamepad.buttons[1].pressed) { 129 | if(this.triggerlocked[i] === false){ 130 | this.triggerlocked[i] = true; 131 | this.phManager.onClick(); 132 | 133 | console.log('trigger locked'); 134 | } 135 | } 136 | else{ 137 | if(this.triggerlocked[i] === true){ 138 | this.triggerlocked[i] = false; 139 | 140 | console.log('trigger unlocked'); 141 | } 142 | } 143 | } 144 | } 145 | }; 146 | 147 | /** 148 | * @param {int} gamepadIndex 149 | */ 150 | GamePads.prototype.vibrate = function(gamepadIndex) { 151 | var gamepads = navigator.getGamepads(); 152 | 153 | if(!gamepads || !gamepads.length) { 154 | return; 155 | } 156 | 157 | if(gamepads && gamepads.length && gamepads.length > gamepadIndex) { 158 | var gamepad = gamepads[gamepadIndex]; 159 | 160 | if(gamepad && 'haptics' in gamepad && gamepad.haptics.length > 0) { 161 | gamepad.haptics[0].vibrate(1, 200); 162 | } 163 | } 164 | }; 165 | 166 | module.exports = GamePads; 167 | -------------------------------------------------------------------------------- /app/view/gamepads/MousePad.js: -------------------------------------------------------------------------------- 1 | var THREE = require('three'); 2 | var textureLoader = require('../utils').textureLoader; 3 | var jsonLoader = require('../utils').jsonLoader; 4 | 5 | /** 6 | * @param {THREE.Scene} scene 7 | * @param {THREE.Camera} camera 8 | * @param {VREffect} effect 9 | * @param {PhysicsManager} physics 10 | */ 11 | var MousePad = function(scene, camera, effect, physics) { 12 | this.raycaster = new THREE.Raycaster(); 13 | this.screenVector = new THREE.Vector2(0, 0); 14 | 15 | this.scene = scene; 16 | this.camera = camera; 17 | 18 | this.phManager = physics; 19 | 20 | this.intersectPoint = new THREE.Vector3(); 21 | this.intersectPoint2 = new THREE.Vector3(); 22 | 23 | var tempHand = new THREE.Mesh( 24 | new THREE.BoxBufferGeometry(0.1, 0.1, 0.1, 1, 1, 1), 25 | new THREE.MeshNormalMaterial() 26 | ); 27 | 28 | this.h1 = tempHand; 29 | 30 | this._loadModel((function() { 31 | this._bindMethods(); 32 | this._addListeners(); 33 | }).bind(this)); 34 | }; 35 | 36 | /** 37 | * @param {() => void} callback 38 | */ 39 | MousePad.prototype._loadModel = function(callback) { 40 | jsonLoader.load('assets/hand/hand.json', (function (geometry) { 41 | geometry.scale(0.02, 0.02, 0.02); 42 | geometry.computeBoundingBox(); 43 | 44 | var texture = textureLoader.load('assets/textures/hand_occlusion.jpg'); 45 | texture.generateMipmaps = false; 46 | texture.minFilter = THREE.LinearFilter; 47 | texture.magFilter = THREE.LinearFilter; 48 | 49 | var material = new THREE.MeshBasicMaterial({ 50 | map: texture, 51 | side: THREE.DoubleSide 52 | }); 53 | 54 | var hand = new THREE.Mesh(geometry, material); 55 | hand.rotation.y += Math.PI; 56 | 57 | this.h1 = hand; 58 | 59 | this.scene.add(this.h1); 60 | this.phManager.add3DObject(this.h1, 'cube', true, false); 61 | 62 | if(callback) { 63 | callback(); 64 | } 65 | }).bind(this)); 66 | }; 67 | 68 | MousePad.prototype._bindMethods = function() { 69 | this._handleMouseMoveBound = this._handleMouseMove.bind(this); 70 | this._handleTouchEndBound = this._handleTouchEnd.bind(this); 71 | }; 72 | 73 | MousePad.prototype._addListeners = function() { 74 | window.addEventListener('mousemove', this._handleMouseMoveBound); 75 | window.addEventListener('touchend', this._handleTouchEndBound); 76 | }; 77 | 78 | MousePad.prototype._removeListeners = function() { 79 | window.addEventListener('mousemove', this._handleMouseMoveBound); 80 | window.addEventListener('touchend', this._handleTouchEndBound); 81 | }; 82 | 83 | MousePad.prototype._handleMouseMove = function( e ){ 84 | this.screenVector.x = (e.clientX / window.innerWidth) * 2 - 1; 85 | this.screenVector.y = (1 - (e.clientY / window.innerHeight)) * 2 - 1; 86 | }; 87 | 88 | MousePad.prototype._handleTouchEnd = function( e ){ 89 | this.screenVector.x = 0; 90 | this.screenVector.y = 0; 91 | }; 92 | 93 | /** 94 | * @param {float} time 95 | * @param {Array} objs 96 | */ 97 | MousePad.prototype.update = function(time, objs) { 98 | this.raycaster.setFromCamera(this.screenVector, this.camera); 99 | 100 | var intersects = this.raycaster.intersectObjects(objs); 101 | 102 | if(intersects.length > 0) { 103 | this.intersectPoint.copy(intersects[0].point); 104 | this.intersectPoint2.copy(intersects[0].point); 105 | this.h1.position.copy(intersects[0].point); 106 | } 107 | }; 108 | 109 | MousePad.prototype.dispose = function() { 110 | this._removeListeners(); 111 | }; 112 | 113 | module.exports = MousePad; 114 | -------------------------------------------------------------------------------- /app/view/letter/Letter.js: -------------------------------------------------------------------------------- 1 | var THREE = require('three'); 2 | var TWEEN = require('tween.js'); 3 | var Rebound = require('rebound'); 4 | var random = require('../utils').random; 5 | var textureLoader = require('../utils').textureLoader; 6 | var jsonLoader = require('../utils').jsonLoader; 7 | 8 | /** 9 | * @param {char} letter 10 | * @param {string} [color='silver'] gold or silver 11 | */ 12 | function Letter(letter, color) { 13 | this.el = new THREE.Mesh(); 14 | this.el.visible = false; 15 | 16 | this._material = Letter._material.clone(); 17 | this.el.material = this._material; 18 | 19 | this._isMatCapReady = false; 20 | this._isGeometryReady = false; 21 | this.isReady = this.isMatCapReady && this.isGeometryReady; 22 | 23 | Letter._loadMatCap(color || 'silver', (function(texture) { 24 | this._material.uniforms.normalMap.value = texture; 25 | this._material.uniforms.textureMap.value = texture; 26 | this._material.needsUpdate = true; 27 | 28 | this._isMatCapReady = true; 29 | this._checkIfReady(); 30 | }).bind(this)); 31 | 32 | Letter._loadModel(letter, (function(geometry) { 33 | this.el.geometry = geometry; 34 | 35 | this._isGeometryReady = true; 36 | this._checkIfReady(); 37 | }).bind(this)); 38 | 39 | this._inflateSpring = Letter._springSystem.createSpring(40, 3); 40 | this._inflateSpring.setEndValue(1).setAtRest(); 41 | 42 | this._inflateTimeoutId = null; 43 | this._inflateLoopIntervalId = null; 44 | 45 | this._addListeners(); 46 | }; 47 | 48 | Letter._material = new THREE.RawShaderMaterial({ 49 | uniforms: { 50 | normalMap: { type: 't', value: null }, 51 | textureMap: { type: 't', value: null }, 52 | inflation: { type: 'f', value: 0 }, 53 | opacity: { type: 'f', value: 0 } 54 | }, 55 | vertexShader: require('./vs-letter.glsl'), 56 | fragmentShader: require('./fs-letter.glsl'), 57 | transparent: true 58 | }); 59 | 60 | Letter._springSystem = new Rebound.SpringSystem(); 61 | 62 | Letter._matCaps = {}; 63 | 64 | Letter._models = {}; 65 | 66 | Letter.prototype = Object.create(THREE.EventDispatcher.prototype); 67 | 68 | Letter.prototype._checkIfReady = function() { 69 | if(this.isReady) { 70 | return; 71 | } 72 | 73 | this.isReady = this._isMatCapReady && this._isGeometryReady; 74 | 75 | if(this.isReady) { 76 | this.dispatchEvent({ type: 'ready' }); 77 | } 78 | }; 79 | 80 | Letter.prototype._addListeners = function() { 81 | this._inflateSpring.addListener({ 82 | onSpringUpdate: this._onInflateSpringUpdate.bind(this) 83 | }) 84 | }; 85 | 86 | Letter.prototype._removeListeners = function() { 87 | this._inflateSpring.removeAllListeners(); 88 | }; 89 | 90 | /** 91 | * @param {Rebound.Spring} spring 92 | */ 93 | Letter.prototype._onInflateSpringUpdate = function(spring) { 94 | this._material.uniforms.inflation.value = spring.getCurrentValue(); 95 | }; 96 | 97 | /** 98 | * @param {char} name 99 | * @param {(THREE.Geometry) => void} callback 100 | */ 101 | Letter._loadModel = function(name, callback) { 102 | var cache = Letter._models[name]; 103 | 104 | if(cache === void 0) { 105 | cache = { 106 | state: 'loading', 107 | waiters: [callback], 108 | model: null 109 | } 110 | 111 | Letter._models[name] = cache; 112 | 113 | var url = 'assets/letters/' + name + '.json'; 114 | 115 | jsonLoader.load(url, function(geometry, materials) { 116 | geometry.computeFaceNormals(); 117 | geometry.computeVertexNormals(); 118 | 119 | cache.state = 'loaded'; 120 | cache.model = geometry; 121 | 122 | for(var i = 0; i < cache.waiters.length; ++i) { 123 | cache.waiters[i](geometry); 124 | } 125 | 126 | cache.waiters.length = 0; 127 | }); 128 | } 129 | else if(cache.state === 'loading') { 130 | cache.waiters.push(callback); 131 | } 132 | else if(cache.state === 'loaded') { 133 | callback(cache.model); 134 | } 135 | }; 136 | 137 | /** 138 | * @param {string} name 139 | * @param {(THREE.Texture) => void} callback 140 | */ 141 | Letter._loadMatCap = function(name, callback) { 142 | if(Letter._matCaps[name] === void 0) { 143 | var url = 'assets/textures/' + name + '.jpg'; 144 | 145 | Letter._matCaps[name] = textureLoader.load(url); 146 | } 147 | 148 | callback(Letter._matCaps[name]); 149 | }; 150 | 151 | Letter.prototype.fadeIn = function() { 152 | var material = this._material; 153 | 154 | new TWEEN.Tween({ opacity: 0 }) 155 | .to({ opacity: 1 }) 156 | .delay(random(1000, 3000)) 157 | .onStart((function() { 158 | this.el.visible = true; 159 | }).bind(this)) 160 | .onUpdate(function() { 161 | material.uniforms.opacity.value = this.opacity; 162 | }) 163 | .start(); 164 | }; 165 | 166 | Letter.prototype.inflate = function() { 167 | if(this._inflateTimeoutId) { 168 | window.clearTimeout(this._inflateTimeoutId); 169 | this._inflateTimeoutId = null; 170 | } 171 | 172 | this._inflateSpring.setEndValue(0.09); 173 | 174 | this._inflateTimeoutId = window.setTimeout((function() { 175 | this._inflateSpring.setEndValue(0); 176 | }).bind(this), 300); 177 | }; 178 | 179 | /** 180 | * @param {float} [interval=2000] 181 | */ 182 | Letter.prototype.startInflateLoop = function(interval) { 183 | this._inflateLoopIntervalId = window.setInterval((function() { 184 | this.inflate(); 185 | }).bind(this), interval); 186 | }; 187 | 188 | Letter.prototype.stopInflateLoop = function() { 189 | if(this._inflateLoopIntervalId === null) { 190 | return; 191 | } 192 | 193 | window.clearInterval(this._inflateLoopIntervalId); 194 | 195 | this._inflateLoopIntervalId = null; 196 | }; 197 | 198 | Letter.prototype.dispose = function() { 199 | this._removeListeners(); 200 | 201 | if(this.el.parent) { 202 | this.el.parent.remove(this.el); 203 | } 204 | }; 205 | 206 | module.exports = Letter; 207 | -------------------------------------------------------------------------------- /app/view/letter/fs-letter.glsl: -------------------------------------------------------------------------------- 1 | #extension GL_OES_standard_derivatives : enable 2 | 3 | precision highp float; 4 | precision highp sampler2D; 5 | 6 | uniform sampler2D textureMap; 7 | uniform sampler2D normalMap; 8 | uniform float opacity; 9 | 10 | varying vec4 vPos; 11 | 12 | varying mat3 vNormalMatrix; 13 | varying vec4 vOPosition; 14 | varying vec3 vU; 15 | varying vec3 vSmoothNormal; 16 | 17 | float random(vec3 scale,float seed){return fract(sin(dot(gl_FragCoord.xyz+seed,scale))*43758.5453+seed);} 18 | 19 | void main() { 20 | vec3 fdx = dFdx( vPos.xyz ); 21 | vec3 fdy = dFdy( vPos.xyz ); 22 | vec3 n = normalize(cross(fdx, fdy)); 23 | n = vSmoothNormal; 24 | 25 | vec3 vNormal = vNormalMatrix * n; 26 | vec3 vONormal = n; 27 | 28 | vec3 c1 = vec3(1.0, 1.0, 1.0); 29 | 30 | vec3 color = vec3( .0, .0, .0 ); 31 | vec2 texScale = vec2(1.0); 32 | float normalScale = 0.0; 33 | float useSSS = 1.0; 34 | float useScreen = 2.0; 35 | 36 | // vec3 n = normalize( vONormal.xyz ); 37 | vec3 blend_weights = abs( n ); 38 | blend_weights = ( blend_weights - 0.2 ) * 7.; 39 | blend_weights = max( blend_weights, 0. ); 40 | blend_weights /= ( blend_weights.x + blend_weights.y + blend_weights.z ); 41 | 42 | vec2 coord1 = vPos.yz * texScale; 43 | vec2 coord2 = vPos.zx * texScale; 44 | vec2 coord3 = vPos.xy * texScale; 45 | 46 | vec3 bump1 = texture2D( normalMap, coord1 ).rgb; 47 | vec3 bump2 = texture2D( normalMap, coord2 ).rgb; 48 | vec3 bump3 = texture2D( normalMap, coord3 ).rgb; 49 | 50 | vec3 blended_bump = bump1 * blend_weights.xxx + bump2 * blend_weights.yyy + bump3 * blend_weights.zzz; 51 | 52 | vec3 tanX = vec3( vNormal.x, -vNormal.z, vNormal.y); 53 | vec3 tanY = vec3( vNormal.z, vNormal.y, -vNormal.x); 54 | vec3 tanZ = vec3(-vNormal.y, vNormal.x, vNormal.z); 55 | vec3 blended_tangent = tanX * blend_weights.xxx + tanY * blend_weights.yyy + tanZ * blend_weights.zzz; 56 | 57 | vec3 normalTex = blended_bump * 2.0 - 1.0; 58 | normalTex.xy *= normalScale; 59 | normalTex.y *= -1.; 60 | normalTex = normalize( normalTex ); 61 | mat3 tsb = mat3( normalize( blended_tangent ), normalize( cross( vNormal, blended_tangent ) ), normalize( vNormal ) ); 62 | vec3 finalNormal = tsb * normalTex; 63 | 64 | vec3 r = reflect( normalize( vU ), normalize( finalNormal ) ); 65 | float m = 2.0 * sqrt( r.x * r.x + r.y * r.y + ( r.z + 1.0 ) * ( r.z + 1.0 ) ); 66 | vec2 calculatedNormal = vec2( r.x / m + 0.5, r.y / m + 0.5 ); 67 | 68 | vec3 base = texture2D( textureMap, calculatedNormal ).rgb; 69 | 70 | float rim = 1.75 * max( 0., abs( dot( normalize( vNormal ), normalize( -vOPosition.xyz ) ) ) ); 71 | base += useSSS * color * ( 1. - .75 * rim ); 72 | base += ( 1. - useSSS ) * 10. * base * color * clamp( 1. - rim, 0., .15 ); 73 | 74 | if( useScreen == 1. ) { 75 | base = vec3( 1. ) - ( vec3( 1. ) - base ) * ( vec3( 1. ) - base ); 76 | } 77 | 78 | float nn = .05 * random( vec3( 1. ), length( gl_FragCoord ) ); 79 | base += vec3( nn ); 80 | 81 | gl_FragColor = vec4(base.rgb, opacity); 82 | } 83 | -------------------------------------------------------------------------------- /app/view/letter/vs-letter.glsl: -------------------------------------------------------------------------------- 1 | #extension GL_OES_standard_derivatives : enable 2 | 3 | precision highp float; 4 | 5 | attribute vec3 position; 6 | attribute vec3 normal; 7 | attribute vec2 aV2I; 8 | attribute vec2 uv; 9 | 10 | uniform mat4 modelViewMatrix; 11 | uniform mat4 projectionMatrix; 12 | uniform mat3 normalMatrix; 13 | uniform mat4 modelMatrix; 14 | uniform mat4 viewMatrix; 15 | uniform float inflation; 16 | 17 | varying vec4 vPos; 18 | varying vec2 vUv; 19 | 20 | varying mat3 vNormalMatrix; 21 | varying vec4 vOPosition; 22 | varying vec3 vU; 23 | varying vec3 vSmoothNormal; 24 | 25 | void main() { 26 | vec3 pos = position; 27 | 28 | vPos = vec4(pos, 1.0); 29 | vOPosition = modelViewMatrix * vPos; 30 | vU = normalize( vec3( modelViewMatrix * vPos ) ); 31 | vNormalMatrix = normalMatrix; 32 | 33 | vSmoothNormal = normal; 34 | gl_Position = projectionMatrix * modelViewMatrix * vec4(pos + normal * inflation, 1.0); 35 | } 36 | -------------------------------------------------------------------------------- /app/view/shape/Shape.js: -------------------------------------------------------------------------------- 1 | var THREE = require('three'); 2 | var TWEEN = require('tween.js'); 3 | var random = require('../utils').random; 4 | 5 | function Shape() { 6 | this._material = Shape._material.clone(); 7 | this._material.uniforms.time.value = 0; 8 | this._material.uniforms.timeOffset.value = random(0, 1); 9 | 10 | this.el = new THREE.Mesh(Shape._geometry, this._material); 11 | this.el.visible = false; 12 | 13 | var scale = random(0.05, 1); 14 | 15 | this.el.scale.set(scale, scale, scale); 16 | }; 17 | 18 | Shape._geometry = new THREE.IcosahedronGeometry(0.2, 2); 19 | 20 | Shape._material = new THREE.RawShaderMaterial({ 21 | uniforms: { 22 | time: { type: 'f', value: 0 }, 23 | timeOffset: { type: 'f', value: 0 }, 24 | speed: { type: 'f', value: 1 }, 25 | growFromTo: { type: 'v2', value: new THREE.Vector2(1, 1) } 26 | }, 27 | vertexShader: require('./vs-shape.glsl'), 28 | fragmentShader: require('./fs-shape.glsl') 29 | }); 30 | 31 | Shape.prototype.fadeIn = function() { 32 | var targetScale = this.el.scale.x; 33 | 34 | var mesh = this.el; 35 | 36 | new TWEEN.Tween({ scale: 0 }) 37 | .to({ scale: targetScale }, 1000) 38 | .easing(TWEEN.Easing.Elastic.Out) 39 | .delay(random(0, 2000)) 40 | .onStart(function() { 41 | mesh.visible = true; 42 | }) 43 | .onUpdate(function() { 44 | mesh.scale.set(this.scale, this.scale, this.scale); 45 | }) 46 | .start(); 47 | }; 48 | 49 | Shape.prototype.update = function() { 50 | this._material.uniforms.time.value += 0.01; 51 | }; 52 | 53 | Shape.prototype.startTripping = function() { 54 | this._material.uniforms.speed.value = 25; 55 | this._material.uniforms.growFromTo.value.set(0.5, 2); 56 | }; 57 | 58 | Shape.prototype.stopTripping = function() { 59 | this._material.uniforms.speed.value = 1; 60 | this._material.uniforms.growFromTo.value.set(1, 1); 61 | }; 62 | 63 | Shape.prototype.dispose = function() { 64 | if(this.el.parent) { 65 | this.el.parent(this.el); 66 | } 67 | }; 68 | 69 | module.exports = Shape; 70 | -------------------------------------------------------------------------------- /app/view/shape/fs-shape.glsl: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | precision highp sampler2D; 3 | 4 | varying vec2 vUv; 5 | varying vec4 vPos; 6 | varying float vTime; 7 | varying float vTimeOffset; 8 | varying float vSpeed; 9 | 10 | float random(const in vec3 scale, const in float seed) { 11 | return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) *43758.5453 + seed); 12 | } 13 | 14 | void main() { 15 | float time = vTime * vSpeed; 16 | 17 | float sin1 = (sin(time * vTimeOffset) + 1.0) / 2.0; 18 | float sin2 = (sin(time - vTimeOffset) + 1.0) / 2.0; 19 | float cos1 = (cos(time + vTimeOffset) + 1.0) / 2.0; 20 | 21 | float r = sin1; 22 | float g = cos1; 23 | float b = sin2; 24 | 25 | gl_FragColor = vec4(r, g, b, 1.0); 26 | 27 | float noise = 0.05 * random(vec3(1.0), length(gl_FragCoord)); 28 | gl_FragColor.rgb += vec3(noise); 29 | } 30 | -------------------------------------------------------------------------------- /app/view/shape/vs-shape.glsl: -------------------------------------------------------------------------------- 1 | precision highp float; 2 | 3 | attribute vec3 position; 4 | attribute vec3 normal; 5 | attribute vec2 uv; 6 | 7 | uniform mat4 modelViewMatrix; 8 | uniform mat4 projectionMatrix; 9 | uniform mat3 normalMatrix; 10 | uniform mat4 modelMatrix; 11 | uniform mat4 viewMatrix; 12 | 13 | uniform float time; 14 | uniform float timeOffset; 15 | uniform float speed; 16 | uniform vec2 growFromTo; 17 | 18 | varying vec4 vPos; 19 | varying vec2 vUv; 20 | varying float vTime; 21 | varying float vTimeOffset; 22 | varying float vSpeed; 23 | 24 | float map(const in float value, const in float inMin, const in float inMax, const in float outMin, const in float outMax) { 25 | if(value < inMin) { 26 | return outMin; 27 | } 28 | 29 | if(value > inMax) { 30 | return outMax; 31 | } 32 | 33 | return (value - inMin) / (inMax - inMin) * (outMax - outMin) + outMin; 34 | } 35 | 36 | void main() { 37 | vPos = vec4(position, 1.0); 38 | vUv = uv; 39 | vTime = time; 40 | vTimeOffset = timeOffset; 41 | vSpeed = speed; 42 | 43 | vec4 finalPosition = vec4(position * map(sin(time * timeOffset * speed), -1.0, 1.0, growFromTo.x, growFromTo.y), 1.0); 44 | 45 | gl_Position = projectionMatrix * modelViewMatrix * finalPosition; 46 | } 47 | -------------------------------------------------------------------------------- /app/view/sound/AssetsSound.js: -------------------------------------------------------------------------------- 1 | var BALLOON_1 = 0; 2 | var BALLOON_2 = 1; 3 | var BALLOON_3 = 2; 4 | var BALLOON_4 = 3; 5 | var BACKGROUND_NORMAL = 4; 6 | var BACKGROUND_SUCCESS = 5; 7 | 8 | var Sounds = {}; 9 | 10 | Sounds[BALLOON_1] = { 11 | src: 'assets/sounds/balloon1.wav', 12 | loop: false, 13 | volume: 1 14 | }; 15 | 16 | Sounds[BALLOON_2] = { 17 | src: 'assets/sounds/balloon2.wav', 18 | loop: false, 19 | volume: 1 20 | }; 21 | 22 | Sounds[BALLOON_3] = { 23 | src: 'assets/sounds/balloon3.wav', 24 | loop: false, 25 | volume: 1 26 | }; 27 | 28 | Sounds[BALLOON_4] = { 29 | src: 'assets/sounds/balloon4.wav', 30 | loop: false, 31 | volume: 1 32 | }; 33 | 34 | Sounds[BACKGROUND_NORMAL] = { 35 | src: 'assets/sounds/background.wav', 36 | loop: true, 37 | volume: 1 38 | }; 39 | 40 | Sounds[BACKGROUND_SUCCESS] = { 41 | src: 'assets/sounds/background-success.wav', 42 | loop: true, 43 | volume: 1 44 | }; 45 | 46 | module.exports = { 47 | BALLOON_1: BALLOON_1, 48 | BALLOON_2: BALLOON_2, 49 | BALLOON_3: BALLOON_3, 50 | BALLOON_4: BALLOON_4, 51 | BACKGROUND_NORMAL: BACKGROUND_NORMAL, 52 | BACKGROUND_SUCCESS: BACKGROUND_SUCCESS, 53 | 54 | Sounds: Sounds 55 | }; 56 | -------------------------------------------------------------------------------- /app/view/sound/SoundManager.js: -------------------------------------------------------------------------------- 1 | var Howler = require('howler'); 2 | 3 | /** 4 | * @interface ISound { 5 | * string|Array src; 6 | * boolean loop; 7 | * float volume; 8 | * } 9 | */ 10 | 11 | function SoundManager() { 12 | this._sounds = {}; 13 | }; 14 | 15 | /** 16 | * @param {string} name 17 | * @param {string|Array} srcs 18 | * @param {boolean} [loop=false] 19 | * @param {float} [volume=1] 20 | */ 21 | SoundManager.prototype.addSound = function(name, srcs, loop, volume) { 22 | if(!Array.isArray(srcs)) { 23 | srcs = [srcs]; 24 | } 25 | 26 | if(loop === void 0) { 27 | loop = false; 28 | } 29 | 30 | if(volume === void 0) { 31 | volume = 1; 32 | } 33 | 34 | var sound = new Howler.Howl({ 35 | src: srcs, 36 | loop: loop, 37 | volume: volume 38 | }); 39 | 40 | this._sounds[name] = sound; 41 | }; 42 | 43 | /** 44 | * @param {Array} sounds 45 | */ 46 | SoundManager.prototype.addSoundsFromConfig = function(sounds) { 47 | for(var name in sounds) { 48 | if(!sounds.hasOwnProperty(name)) { 49 | continue; 50 | } 51 | 52 | var sound = sounds[name]; 53 | 54 | this.addSound(name, sound.src, sound.loop, sound.volume); 55 | } 56 | }; 57 | 58 | /** 59 | * @param {string} sound 60 | * @returns {int} 61 | */ 62 | SoundManager.prototype.play = function(name) { 63 | var sound = this._sounds[name]; 64 | 65 | if(!sound || sound.state() === 'loading') { 66 | return; 67 | } 68 | 69 | return sound.play(); 70 | }; 71 | 72 | /** 73 | * @param {string} sound 74 | * @param {(int) => void} callback 75 | */ 76 | SoundManager.prototype.playWhenReady = function(name, callback) { 77 | var sound = this._sounds[name]; 78 | 79 | if(!sound) { 80 | return; 81 | } 82 | 83 | sound.once('load', (function() { 84 | var id = this.play(name); 85 | 86 | if(callback) { 87 | callback(id); 88 | } 89 | }).bind(this)); 90 | }; 91 | 92 | /** 93 | * @param {string} name 94 | * @param {float} duration 95 | * @param {int} id 96 | */ 97 | SoundManager.prototype.fadeOut = function(name, duration, id) { 98 | var sound = this._sounds[name]; 99 | 100 | if(!sound) { 101 | return; 102 | } 103 | 104 | sound.fade(sound.volume(), 0, duration || 1500, id); 105 | }; 106 | 107 | /** 108 | * @param {string} name 109 | * @param {float} duration 110 | * @param {int} id 111 | */ 112 | SoundManager.prototype.fadeIn = function(name, duration, id) { 113 | var sound = this._sounds[name]; 114 | 115 | if(!sound) { 116 | return; 117 | } 118 | 119 | sound.fade(sound.volume(), 1, duration || 1500, id); 120 | }; 121 | 122 | module.exports = SoundManager; 123 | 124 | -------------------------------------------------------------------------------- /app/view/utils.js: -------------------------------------------------------------------------------- 1 | var THREE = require('three'); 2 | 3 | /** 4 | * @param {float} min 5 | * @param {float} max 6 | * @param {boolean} round 7 | */ 8 | function random(min, max, round) { 9 | var value = Math.random() * (max - min) + min; 10 | return round ? Math.round(value) : value; 11 | }; 12 | 13 | /** 14 | * @returns {{[name:string]:string}} 15 | */ 16 | function getTextAndColorsFromHash() { 17 | var hash = window.location.hash; 18 | 19 | var text = null; 20 | var colors = null; 21 | 22 | hash.substr(1).split('&').forEach(function(part) { 23 | var subpart = part.split('='); 24 | 25 | if(subpart.length) { 26 | if(subpart[0] === 'text') { 27 | text = subpart[1].toUpperCase(); 28 | } else if(subpart[0] === 'colors') { 29 | colors = subpart[1].toUpperCase(); 30 | } 31 | } 32 | }); 33 | 34 | if(text === null) { 35 | text = 'HELLO WORLD'; 36 | } 37 | 38 | if(colors === null) { 39 | if(text !== null) { 40 | colors = Array.prototype.map.call(text, function() { 41 | return Math.random() < 0.5 ? 'S' : 'G'; 42 | }).join(''); 43 | } else { 44 | colors = 'SSSSS GGGGG'; 45 | } 46 | } 47 | 48 | return { 49 | text: text, 50 | colors: colors 51 | } 52 | }; 53 | 54 | var KeyCodes = { 55 | Q: 81, 56 | SPACE: 32 57 | }; 58 | 59 | function sendTextToAnalytics(text) { 60 | if(!ga) { 61 | return; 62 | } 63 | 64 | ga('set', 'dimension1', text); 65 | ga('send', 'pageview'); 66 | } 67 | 68 | module.exports = { 69 | random: random, 70 | textureLoader: new THREE.TextureLoader(), 71 | jsonLoader: new THREE.JSONLoader(), 72 | getTextAndColorsFromHash: getTextAndColorsFromHash, 73 | KeyCodes: KeyCodes, 74 | sendTextToAnalytics: sendTextToAnalytics 75 | }; 76 | -------------------------------------------------------------------------------- /gifs/celebrate.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/B-Reel/vr-madebymakers/3cf655a4ec4cc2316f40df28cbd6be32f4cf8b51/gifs/celebrate.gif -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vr-madebymakers", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "start": "npm run watcher & npm run server", 7 | "watcher": "node watcher.js -loglevel silent", 8 | "server": "./node_modules/node-static/bin/cli.js -a 0.0.0.0 -p 9000 public/" 9 | }, 10 | "dependencies": { 11 | "howler": "^2.0.0", 12 | "rebound": "0.0.13", 13 | "tween.js": "^16.3.4" 14 | }, 15 | "devDependencies": { 16 | "serve-favicon": "~2.1.3", 17 | "morgan": "~1.3.0", 18 | "path": "^0.4.9", 19 | "body-parser": "~1.8.1", 20 | "cookie-parser": "~1.3.3", 21 | "debug": "~2.0.0", 22 | "fs-extra": "^0.11.1", 23 | "browserify": "^10.2.4", 24 | "del": "^0.1.3", 25 | "es6-promise": "^3.2.1", 26 | "fs.extra": "^1.2.1", 27 | "glob": "^4.0.6", 28 | "gsap": "^1.16.1", 29 | "gulp": "^3.8.8", 30 | "gulp-browserify": "^0.5.1", 31 | "gulp-sourcemaps": "^1.5.0", 32 | "gulp-uglify": "^1.2.0", 33 | "gulp-util": "^3.0.4", 34 | "jquery": "~1.11.0", 35 | "jshint-stylish": "^0.4.0", 36 | "lodash": "^3.3.1", 37 | "lodash.assign": "^3.2.0", 38 | "node-static": "^0.7.6", 39 | "stringify": "^3.1.0", 40 | "three": ">=0.76.0", 41 | "vinyl-buffer": "^1.0.0", 42 | "vinyl-source-stream": "^1.0.0", 43 | "watchify": "^3.2.2" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /public/assets/letters/1.json: -------------------------------------------------------------------------------- 1 | { 2 | "faces":[33,0,4,5,1,0,1,2,3,33,1,5,128,127,3,2,4,5,33,4,130,129,5,1,6,7,2,33,5,129,210,128,2,7,8,4,33,0,1,6,2,0,3,9,10,33,2,6,137,136,10,9,11,12,33,1,127,126,6,3,5,13,9,33,6,126,212,137,9,13,14,11,33,0,2,7,3,0,10,15,16,33,3,7,134,133,16,15,17,18,33,2,136,135,7,10,12,19,15,33,7,135,213,134,15,19,20,17,33,0,3,8,4,0,16,21,1,33,4,8,131,130,1,21,22,6,33,3,133,132,8,16,18,23,21,33,8,132,211,131,21,23,24,22,33,9,13,14,10,25,26,27,28,33,10,14,143,142,28,27,29,30,33,13,133,134,14,26,18,17,27,33,14,134,213,143,27,17,20,29,33,9,10,15,11,25,28,31,32,33,11,15,140,139,32,31,33,34,33,10,142,141,15,28,30,35,31,33,15,141,215,140,31,35,36,33,33,9,11,16,12,25,32,37,38,33,12,16,146,145,38,37,39,40,33,11,139,138,16,32,34,41,37,33,16,138,214,146,37,41,42,39,33,9,12,17,13,25,38,43,26,33,13,17,132,133,26,43,23,18,33,12,145,144,17,38,40,44,43,33,17,144,211,132,43,44,24,23,33,18,22,23,19,45,46,47,48,33,19,23,152,151,48,47,49,50,33,22,145,146,23,46,40,39,47,33,23,146,214,152,47,39,42,49,33,18,19,24,20,45,48,51,52,33,20,24,149,148,52,51,53,54,33,19,151,150,24,48,50,55,51,33,24,150,217,149,51,55,56,53,33,18,20,25,21,45,52,57,58,33,21,25,155,154,58,57,59,60,33,20,148,147,25,52,54,61,57,33,25,147,216,155,57,61,62,59,33,18,21,26,22,45,58,63,46,33,22,26,144,145,46,63,44,40,33,21,154,153,26,58,60,64,63,33,26,153,211,144,63,64,24,44,33,27,31,32,28,65,66,67,68,33,28,32,159,160,68,67,69,70,33,31,157,158,32,66,71,72,67,33,32,158,219,159,67,72,73,69,33,27,28,33,29,65,68,74,75,33,29,33,162,163,75,74,76,77,33,28,160,161,33,68,70,78,74,33,33,161,220,162,74,78,79,76,33,27,29,34,30,65,75,80,81,33,30,34,165,166,81,80,82,83,33,29,163,164,34,75,77,84,80,33,34,164,221,165,80,84,85,82,33,27,30,35,31,65,81,86,66,33,31,35,156,157,66,86,87,71,33,30,166,167,35,81,83,88,86,33,35,167,218,156,86,88,89,87,33,36,40,41,37,90,91,92,93,33,37,41,164,163,93,92,84,77,33,40,172,173,41,91,94,95,92,33,41,173,221,164,92,95,85,84,33,36,37,42,38,90,93,96,97,33,38,42,174,175,97,96,98,99,33,37,163,162,42,93,77,76,96,33,42,162,220,174,96,76,79,98,33,36,38,43,39,90,97,100,101,33,39,43,168,169,101,100,102,103,33,38,175,176,43,97,99,104,100,33,43,176,222,168,100,104,105,102,33,36,39,44,40,90,101,106,91,33,40,44,171,172,91,106,107,94,33,39,169,170,44,101,103,108,106,33,44,170,223,171,106,108,109,107,33,45,49,50,46,110,111,112,113,33,46,50,176,175,113,112,104,99,33,49,181,182,50,111,114,115,112,33,50,182,222,176,112,115,105,104,33,45,46,51,47,110,113,116,117,33,47,51,183,184,117,116,118,119,33,46,175,174,51,113,99,98,116,33,51,174,220,183,116,98,79,118,33,45,47,52,48,110,117,120,121,33,48,52,177,178,121,120,122,123,33,47,184,185,52,117,119,124,120,33,52,185,224,177,120,124,125,122,33,45,48,53,49,110,121,126,111,33,49,53,180,181,111,126,127,114,33,48,178,179,53,121,123,128,126,33,53,179,225,180,126,128,129,127,33,54,58,59,55,130,131,132,133,33,55,59,126,127,133,132,13,5,33,58,190,191,59,131,134,135,132,33,59,191,212,126,132,135,14,13,33,54,55,60,56,130,133,136,137,33,56,60,186,187,137,136,138,139,33,55,127,128,60,133,5,4,136,33,60,128,210,186,136,4,8,138,33,54,56,61,57,130,137,140,141,33,57,61,158,157,141,140,72,71,33,56,187,188,61,137,139,142,140,33,61,188,219,158,140,142,73,72,33,54,57,62,58,130,141,143,131,33,58,62,189,190,131,143,144,134,33,57,157,156,62,141,71,87,143,33,62,156,218,189,143,87,89,144,33,63,67,68,64,145,146,147,148,33,64,68,153,154,148,147,64,60,33,67,196,197,68,146,149,150,147,33,68,197,211,153,147,150,24,64,33,63,64,69,65,145,148,151,152,33,65,69,192,193,152,151,153,154,33,64,154,155,69,148,60,59,151,33,69,155,216,192,151,59,62,153,33,63,65,70,66,145,152,155,156,33,66,70,185,184,156,155,124,119,33,65,193,194,70,152,154,157,155,33,70,194,224,185,155,157,125,124,33,63,66,71,67,145,156,158,146,33,67,71,195,196,146,158,159,149,33,66,184,183,71,156,119,118,158,33,71,183,220,195,158,118,79,159,33,72,76,77,73,160,161,162,163,33,73,77,147,148,163,162,61,54,33,76,193,192,77,161,154,153,162,33,77,192,216,147,162,153,62,61,33,72,73,78,74,160,163,164,165,33,74,78,198,199,165,164,166,167,33,73,148,149,78,163,54,53,164,33,78,149,217,198,164,53,56,166,33,72,74,79,75,160,165,168,169,33,75,79,179,178,169,168,128,123,33,74,199,200,79,165,167,170,168,33,79,200,225,179,168,170,129,128,33,72,75,80,76,160,169,171,161,33,76,80,194,193,161,171,157,154,33,75,178,177,80,169,123,122,171,33,80,177,224,194,171,122,125,157,33,81,85,86,82,172,173,174,175,33,82,86,141,142,175,174,35,30,33,85,205,206,86,173,176,177,174,33,86,206,215,141,174,177,36,35,33,81,82,87,83,172,175,178,179,33,83,87,201,202,179,178,180,181,33,82,142,143,87,175,30,29,178,33,87,143,213,201,178,29,20,180,33,81,83,88,84,172,179,182,183,33,84,88,173,172,183,182,95,94,33,83,202,203,88,179,181,184,182,33,88,203,221,173,182,184,85,95,33,81,84,89,85,172,183,185,173,33,85,89,204,205,173,185,186,176,33,84,172,171,89,183,94,107,185,33,89,171,223,204,185,107,109,186,33,90,94,95,91,187,188,189,190,33,91,95,135,136,190,189,19,12,33,94,202,201,95,188,181,180,189,33,95,201,213,135,189,180,20,19,33,90,91,96,92,187,190,191,192,33,92,96,191,190,192,191,135,134,33,91,136,137,96,190,12,11,191,33,96,137,212,191,191,11,14,135,33,90,92,97,93,187,192,193,194,33,93,97,167,166,194,193,88,83,33,92,190,189,97,192,134,144,193,33,97,189,218,167,193,144,89,88,33,90,93,98,94,187,194,195,188,33,94,98,203,202,188,195,184,181,33,93,166,165,98,194,83,82,195,33,98,165,221,203,195,82,85,184,33,99,103,104,100,196,197,198,199,33,100,104,129,130,199,198,7,6,33,103,187,186,104,197,139,138,198,33,104,186,210,129,198,138,8,7,33,99,100,105,101,196,199,200,201,33,101,105,197,196,201,200,150,149,33,100,130,131,105,199,6,22,200,33,105,131,211,197,200,22,24,150,33,99,101,106,102,196,201,202,203,33,102,106,161,160,203,202,78,70,33,101,196,195,106,201,149,159,202,33,106,195,220,161,202,159,79,78,33,99,102,107,103,196,203,204,197,33,103,107,188,187,197,204,142,139,33,102,160,159,107,203,70,69,204,33,107,159,219,188,204,69,73,142,33,108,112,113,109,205,206,207,208,33,109,113,150,151,208,207,55,50,33,112,199,198,113,206,167,166,207,33,113,198,217,150,207,166,56,55,33,108,109,114,110,205,208,209,210,33,110,114,207,208,210,209,211,212,33,109,151,152,114,208,50,49,209,33,114,152,214,207,209,49,42,211,33,108,110,115,111,205,210,213,214,33,111,115,182,181,214,213,115,114,33,110,208,209,115,210,212,215,213,33,115,209,222,182,213,215,105,115,33,108,111,116,112,205,214,216,206,33,112,116,200,199,206,216,170,167,33,111,181,180,116,214,114,127,216,33,116,180,225,200,216,127,129,170,33,117,121,122,118,217,218,219,220,33,118,122,138,139,220,219,41,34,33,121,208,207,122,218,212,211,219,33,122,207,214,138,219,211,42,41,33,117,118,123,119,217,220,221,222,33,119,123,206,205,222,221,177,176,33,118,139,140,123,220,34,33,221,33,123,140,215,206,221,33,36,177,33,117,119,124,120,217,222,223,224,33,120,124,170,169,224,223,108,103,33,119,205,204,124,222,176,186,223,33,124,204,223,170,223,186,109,108,33,117,120,125,121,217,224,225,218,33,121,125,209,208,218,225,215,212,33,120,169,168,125,224,103,102,225,33,125,168,222,209,225,102,105,215], 3 | "normals":[-0.332591,-0.942473,-0.033357,-0.226753,-0.916807,0.328623,-0.360851,-0.833644,0.418104,-0.527268,-0.847377,0.062502,-0.59035,-0.63097,0.503311,-0.764061,-0.622425,0.169561,-0.124943,-0.691244,0.711722,-0.148198,-0.638173,0.755486,-0.340556,-0.561327,0.754234,-0.631764,-0.736503,-0.241676,-0.442671,-0.826624,-0.347392,-0.696646,-0.533097,-0.480056,-0.52971,-0.580615,-0.618244,-0.825983,-0.54799,-0.131932,-0.81991,-0.462478,-0.337352,-0.289743,-0.856563,-0.426984,-0.201972,-0.973022,-0.11124,-0.171087,-0.85989,-0.480941,-0.109928,-0.979369,-0.169408,-0.374554,-0.593524,-0.712333,-0.235908,-0.590808,-0.771508,-0.201636,-0.958403,0.20191,-0.33726,-0.776513,0.532212,-0.161901,-0.983978,0.074374,-0.497391,-0.837031,0.227912,0.212683,-0.952422,-0.218238,0.008606,-0.979095,-0.20307,-0.030274,-0.859859,-0.509598,0.180151,-0.836207,-0.51793,-0.07651,-0.58742,-0.805628,0.138462,-0.569079,-0.810511,0.457076,-0.739036,-0.494827,0.50087,-0.838008,-0.216376,0.721519,-0.521897,-0.454939,0.788507,-0.580309,-0.20365,0.399121,-0.508927,-0.762658,0.6086,-0.418867,-0.673879,0.507279,-0.85992,-0.055879,0.20716,-0.977233,-0.045106,0.487838,-0.87286,0.008515,0.16654,-0.985748,0.023164,0.801294,-0.595172,-0.060274,0.791314,-0.611347,-0.006104,-0.027192,-0.999573,-0.007782,-0.147252,-0.987213,0.060976,0.072481,-0.99118,0.110843,0.114353,-0.991699,0.058382,0.45204,-0.890713,0.047365,0.417737,-0.902158,0.107578,0.768883,-0.638661,0.029603,0.739097,-0.667135,0.092776,0.40257,-0.892117,0.204962,0.048524,-0.976074,0.211951,0.435316,-0.817713,0.376568,0.033753,-0.900143,0.434217,0.704306,-0.684683,0.187414,0.668447,-0.685537,0.288461,-0.336192,-0.923521,0.184454,-0.312784,-0.944456,0.100558,-0.697226,-0.703604,0.137059,-0.718467,-0.692618,0.063448,-0.396649,-0.844508,0.359752,-0.668203,-0.704886,0.237953,-0.256813,-0.964049,0.068026,-0.714194,-0.69747,0.058565,-0.332591,0.942473,-0.033357,-0.527268,0.847377,0.062502,-0.360851,0.833644,0.418104,-0.226753,0.916807,0.328623,-0.148198,0.638173,0.755486,-0.124943,0.691244,0.711722,-0.764061,0.622425,0.169561,-0.59035,0.63097,0.503311,-0.340556,0.561327,0.754234,-0.201636,0.958403,0.20191,-0.201972,0.973022,-0.11124,-0.161901,0.983978,0.074374,-0.109928,0.979369,-0.169408,-0.33726,0.776513,0.532212,-0.497391,0.837031,0.227912,-0.289743,0.856563,-0.426984,-0.442671,0.826624,-0.347392,-0.374554,0.593524,-0.712333,-0.52971,0.580615,-0.618244,-0.171087,0.85989,-0.480941,-0.235908,0.590808,-0.771508,-0.631764,0.736503,-0.241676,-0.825983,0.54799,-0.131932,-0.696646,0.533097,-0.480056,-0.81991,0.462478,-0.337352,0.212683,0.952422,-0.218238,0.180151,0.836207,-0.51793,-0.030274,0.859859,-0.509598,0.008606,0.979095,-0.20307,0.138462,0.569079,-0.810511,-0.07651,0.58742,-0.805628,-0.027192,0.999573,-0.007782,0.20716,0.977233,-0.045106,-0.147252,0.987213,0.060976,0.16654,0.985748,0.023164,0.507279,0.85992,-0.055879,0.50087,0.838008,-0.216376,0.801294,0.595172,-0.060274,0.788507,0.580309,-0.20365,0.487838,0.87286,0.008515,0.791314,0.611347,-0.006104,0.457076,0.739036,-0.494827,0.399121,0.508927,-0.762658,0.721519,0.521897,-0.454939,0.6086,0.418867,-0.673879,0.072481,0.99118,0.110843,0.417737,0.902158,0.107578,0.45204,0.890713,0.047365,0.114353,0.991699,0.058382,0.739097,0.667135,0.092776,0.768883,0.638661,0.029603,-0.256813,0.964049,0.068026,-0.312784,0.944456,0.100558,-0.714194,0.69747,0.058565,-0.718467,0.692618,0.063448,-0.336192,0.923521,0.184454,0.048524,0.976074,0.211921,-0.396649,0.844508,0.359752,0.033753,0.900143,0.434217,-0.697226,0.703604,0.137059,-0.668203,0.704886,0.237953,0.40257,0.892117,0.204962,0.704306,0.684683,0.187414,0.435316,0.817713,0.376568,0.668447,0.685537,0.288461,-0.964721,0,0.263161,-0.998657,0,-0.051607,-0.956908,-0.282296,-0.06766,-0.921171,-0.305734,0.240669,-0.924131,0,-0.382061,-0.890255,-0.26841,-0.367931,-0.754112,-0.323344,0.571581,-0.79812,0,0.602496,-0.346507,-0.330973,0.877682,-0.350383,0,0.936583,-0.754112,0.323344,0.571581,-0.921171,0.305734,0.240699,-0.346507,0.330973,0.877682,-0.956908,0.282296,-0.06766,-0.890255,0.26841,-0.367931,-0.999969,0,-0.006653,-0.999969,0,-0.002228,-0.958037,-0.285989,0.018006,-0.947295,-0.320017,0.014008,-0.972106,0,0.234504,-0.910825,-0.319987,0.260659,-0.92346,-0.370281,0.100314,-0.995697,0,0.09238,-0.828974,-0.461074,0.316446,-0.923734,0,0.383007,-0.92346,0.370281,0.100314,-0.947295,0.320017,0.014008,-0.828974,0.461074,0.316446,-0.958037,0.285989,0.018006,-0.910825,0.319987,0.260659,0.010315,0,0.999939,-0.609516,0,0.792749,-0.526627,-0.57738,0.62392,0.019501,-0.625629,0.779839,0.534074,-0.558885,0.634327,0.599292,0,0.800501,0.807794,-0.45085,0.379681,0.89169,0,0.452589,0.534074,0.558885,0.634327,0.019501,0.625629,0.779839,0.807794,0.45085,0.379681,-0.526627,0.57738,0.62392,0.112674,0,-0.993622,0.382122,0,-0.9241,0.38197,-0.245796,-0.890866,0.117618,-0.263466,-0.957457,0.677145,0,-0.735832,0.656148,-0.234626,-0.717185,-0.094882,-0.271432,-0.957762,-0.097446,0,-0.995239,-0.263161,-0.275124,-0.92468,-0.268075,0,-0.963378,-0.094882,0.271432,-0.957762,0.117618,0.263466,-0.957457,-0.263161,0.275124,-0.92468,0.38197,0.245796,-0.890866,0.656148,0.234626,-0.717185,-0.574694,0,-0.818354,-0.419263,0,-0.907834,-0.411939,-0.277413,-0.867946,-0.567644,-0.276925,-0.775262,-0.737693,-0.270394,-0.61858,-0.753441,0,-0.657491,-0.737693,0.270394,-0.61858,-0.567644,0.276925,-0.775262,-0.411939,0.277413,-0.867946,0.008209,0,0.999939,0.080691,0,0.996734,0.024262,-0.326365,0.944914,-0.029878,-0.335521,0.941527,-0.515732,-0.389966,0.76281,-0.595355,0,0.80343,-0.515732,0.389996,0.76281,-0.029878,0.335521,0.941527,0.024262,0.326365,0.944914,0.997803,0,0.066103,0.98175,0,0.190069,0.909268,-0.373516,0.183447,0.940214,-0.332377,0.074099,0.952635,-0.303873,0.011597,0.999969,0,0.004639,0.958647,-0.283944,-0.019196,0.999695,0,-0.024232,0.952635,0.303873,0.011597,0.940214,0.332377,0.074099,0.958647,0.283944,-0.019196,0.909268,0.373516,0.183447,0.982727,0,-0.184973,0.997864,0,-0.065065,0.960112,-0.272286,-0.063417,0.9447,-0.267129,-0.1901,0.861721,-0.252388,-0.440107,0.898221,0,-0.439528,0.861721,0.252388,-0.440107,0.9447,0.267129,-0.1901,0.960112,0.272286,-0.063417], 4 | "name":"Plane.026Geometry", 5 | "vertices":[-0.184861,0.327931,-0.176862,-0.236625,0.294126,-0.153874,-0.192474,0.38761,-0.161143,-0.123083,0.360743,-0.189772,-0.175997,0.26693,-0.169948,-0.223649,0.244178,-0.146502,-0.24312,0.348828,-0.14134,-0.128216,0.42466,-0.170827,-0.119427,0.286783,-0.186595,0.078259,0.414087,-0.18781,0.075762,0.478819,-0.164826,0.13426,0.417475,-0.166246,0.078279,0.320632,-0.197633,0.013236,0.404999,-0.196055,0.012288,0.471996,-0.172781,0.127303,0.476987,-0.146304,0.137257,0.325947,-0.175603,0.011813,0.313391,-0.202923,0.059814,-0.165091,-0.179095,0.125357,-0.157541,-0.163689,0.050183,-0.335851,-0.155261,-0.006213,-0.166694,-0.171592,0.068639,0.020223,-0.192574,0.133223,0.025516,-0.174226,0.111866,-0.320918,-0.142963,-0.010109,-0.328123,-0.147593,0.000733,0.016061,-0.18839,-0.184861,0.327931,0.176862,-0.175997,0.26693,0.169948,-0.123083,0.360743,0.189772,-0.192474,0.38761,0.161143,-0.236625,0.294126,0.153874,-0.223649,0.244178,0.146502,-0.119427,0.286783,0.186595,-0.128216,0.42466,0.170827,-0.24312,0.348828,0.14134,0.078259,0.414087,0.18781,0.013236,0.404999,0.196055,0.078279,0.320632,0.197633,0.13426,0.417475,0.166246,0.075762,0.478819,0.164826,0.012288,0.471996,0.172781,0.011813,0.313391,0.202923,0.137257,0.325947,0.175603,0.127303,0.476987,0.146304,0.059814,-0.165091,0.179095,0.068639,0.020223,0.192574,-0.006213,-0.166694,0.171592,0.050183,-0.335851,0.155261,0.125357,-0.157541,0.163689,0.133223,0.025516,0.174226,0.000733,0.016061,0.18839,-0.010109,-0.328123,0.147593,0.111866,-0.320918,0.142963,-0.306994,0.242504,-0,-0.299123,0.248278,-0.062924,-0.28434,0.191887,-0,-0.299123,0.248278,0.062924,-0.313907,0.304668,-0,-0.304925,0.306173,-0.05824,-0.278508,0.201251,-0.059828,-0.278508,0.201251,0.059828,-0.304925,0.306173,0.05824,-0.106316,-0.182902,0,-0.095037,-0.177042,-0.076317,-0.105448,-0.343887,0,-0.095037,-0.177042,0.076317,-0.100477,-0.018041,0,-0.089929,-0.007872,-0.086469,-0.093534,-0.33228,-0.06497,-0.093534,-0.33228,0.06497,-0.089929,-0.007872,0.086469,0.035083,-0.581883,0,0.036772,-0.554366,-0.063125,0.107461,-0.552565,0,0.036772,-0.554366,0.063125,-0.033916,-0.556167,0,-0.026771,-0.530408,-0.059996,0.103494,-0.526528,-0.058572,0.103494,-0.526528,0.058572,-0.026771,-0.530408,0.059996,0.073412,0.554214,-0,0.07295,0.545872,-0.067631,0.009086,0.554033,-0,0.07295,0.545872,0.067631,0.126912,0.541606,-0,0.124064,0.534568,-0.060536,0.009442,0.544918,-0.070652,0.009442,0.544918,0.070652,0.124064,0.534568,0.060535,-0.206748,0.47392,-0,-0.204319,0.464823,-0.067053,-0.263173,0.425578,-0,-0.204319,0.464823,0.067053,-0.137025,0.513004,-0,-0.136046,0.503188,-0.070411,-0.257573,0.419021,-0.059426,-0.257573,0.419021,0.059426,-0.136046,0.503188,0.070411,-0.167891,0.170704,-0,-0.16743,0.182225,-0.075859,-0.128811,0.163532,-0,-0.16743,0.182225,0.075859,-0.210077,0.162674,-0,-0.209196,0.173986,-0.064588,-0.124711,0.178288,-0.086179,-0.124711,0.178288,0.086179,-0.209196,0.173986,0.064588,0.223406,-0.153327,0,0.212491,-0.151223,-0.068414,0.227607,0.034304,-0,0.212491,-0.151223,0.068414,0.205814,-0.327814,0,0.195291,-0.316761,-0.060341,0.21712,0.033328,-0.072306,0.21712,0.033328,0.072305,0.195291,-0.316761,0.060341,0.211341,0.421223,-0,0.202811,0.420153,-0.069011,0.195051,0.479525,-0,0.202811,0.420153,0.069011,0.220108,0.332476,-0,0.210902,0.331751,-0.072602,0.18766,0.476626,-0.06125,0.18766,0.476626,0.06125,0.210902,0.331751,0.072602,-0.280492,0.318341,-0.108135,-0.275629,0.265513,-0.117123,-0.258961,0.221346,-0.11141,-0.211928,0.202845,-0.11736,-0.169111,0.214922,-0.137311,-0.119289,0.220169,-0.154373,-0.056102,0.302637,-0.197301,-0.05561,0.387965,-0.195278,-0.057559,0.454586,-0.173629,-0.13311,0.47374,-0.130721,-0.198929,0.436422,-0.124102,-0.24836,0.394916,-0.109618,0.183286,0.329574,-0.134653,0.177143,0.418412,-0.127826,0.16518,0.473817,-0.113138,0.122025,0.513135,-0.112245,0.073191,0.520767,-0.125746,0.010509,0.517572,-0.13151,0.007738,0.187102,-0.198622,0.07526,0.191621,-0.19799,0.136758,0.197072,-0.177292,-0.01546,-0.454077,-0.111894,0.041814,-0.47222,-0.117722,0.101621,-0.449089,-0.108956,0.163911,-0.306747,-0.111167,0.179792,-0.150699,-0.126439,0.185659,0.030398,-0.133938,-0.056716,0.008279,-0.155184,-0.061553,-0.168595,-0.138294,-0.060764,-0.319633,-0.118111,-0.280492,0.318341,0.108135,-0.275629,0.265513,0.117123,-0.258961,0.221346,0.11141,-0.211928,0.202845,0.11736,-0.169111,0.214922,0.13731,-0.119289,0.220169,0.154373,-0.056102,0.302637,0.197301,-0.05561,0.387965,0.195278,-0.057559,0.454586,0.173629,-0.13311,0.47374,0.130721,-0.198929,0.436422,0.124102,-0.24836,0.394916,0.109618,0.183286,0.329574,0.134653,0.177143,0.418412,0.127826,0.16518,0.473817,0.113138,0.122025,0.513135,0.112245,0.073191,0.520767,0.125745,0.010509,0.517572,0.13151,0.007738,0.187102,0.198622,0.07526,0.191621,0.19799,0.136758,0.197072,0.177292,-0.01546,-0.454077,0.111894,0.041814,-0.47222,0.117722,0.101621,-0.449089,0.108956,0.163911,-0.306747,0.111167,0.179792,-0.150699,0.126439,0.185659,0.030398,0.133938,-0.056716,0.008279,0.155184,-0.061553,-0.168595,0.138294,-0.060764,-0.319633,0.118111,-0.247168,0.173638,-0.057525,-0.250513,0.162162,-0,-0.247168,0.173638,0.057525,-0.292284,0.366049,0.054249,-0.300745,0.368865,-0,-0.292284,0.366049,-0.054249,-0.074439,-0.455948,-0.057755,-0.085455,-0.476481,0,-0.074439,-0.455948,0.057755,-0.094417,0.126736,0.091175,-0.102964,0.110752,-0,-0.094417,0.126736,-0.091175,0.160599,-0.447218,-0.054817,0.169082,-0.46796,0,0.160599,-0.447218,0.054817,-0.061783,0.530944,-0.071084,-0.062311,0.540489,-0,-0.061783,0.530944,0.071084,0.162421,0.511366,0.056147,0.167991,0.516584,-0,0.162421,0.511366,-0.056147,0.214738,0.204962,-0.07328,0.224485,0.205948,-0,0.214738,0.204962,0.07328,-0.240097,0.196878,-0.09714,-0.062936,0.186631,-0.174262,-0.275436,0.360356,-0.092111,-0.060199,0.50231,-0.132262,0.185495,0.202003,-0.135923,0.151053,0.500566,-0.095337,-0.052471,-0.414202,-0.097609,0.143764,-0.405334,-0.093098,-0.275436,0.360356,0.092111,-0.240097,0.196878,0.09714,-0.062936,0.186631,0.174262,-0.060199,0.50231,0.132262,0.185495,0.202003,0.135923,0.151053,0.500566,0.095337,-0.052471,-0.414202,0.097609,0.143764,-0.405334,0.093098], 6 | "metadata":{ 7 | "faces":224, 8 | "normals":226, 9 | "version":3, 10 | "vertices":226, 11 | "uvs":0, 12 | "generator":"io_three", 13 | "type":"Geometry" 14 | }, 15 | "uvs":[] 16 | } -------------------------------------------------------------------------------- /public/assets/letters/I.json: -------------------------------------------------------------------------------- 1 | { 2 | "faces":[33,0,4,5,1,0,1,2,3,33,1,5,56,55,3,2,4,5,33,4,58,57,5,1,6,7,2,33,5,57,90,56,2,7,8,4,33,0,1,6,2,0,3,9,10,33,2,6,65,64,10,9,11,12,33,1,55,54,6,3,5,13,9,33,6,54,92,65,9,13,14,11,33,0,2,7,3,0,10,15,16,33,3,7,62,61,16,15,17,18,33,2,64,63,7,10,12,19,15,33,7,63,93,62,15,19,20,17,33,0,3,8,4,0,16,21,1,33,4,8,59,58,1,21,22,6,33,3,61,60,8,16,18,23,21,33,8,60,91,59,21,23,24,22,33,9,13,14,10,25,26,27,28,33,10,14,69,70,28,27,29,30,33,13,67,68,14,26,31,32,27,33,14,68,95,69,27,32,33,29,33,9,10,15,11,25,28,34,35,33,11,15,72,73,35,34,36,37,33,10,70,71,15,28,30,38,34,33,15,71,96,72,34,38,39,36,33,9,11,16,12,25,35,40,41,33,12,16,75,76,41,40,42,43,33,11,73,74,16,35,37,44,40,33,16,74,97,75,40,44,45,42,33,9,12,17,13,25,41,46,26,33,13,17,66,67,26,46,47,31,33,12,76,77,17,41,43,48,46,33,17,77,94,66,46,48,49,47,33,18,22,23,19,50,51,52,53,33,19,23,60,61,53,52,23,18,33,22,82,83,23,51,54,55,52,33,23,83,91,60,52,55,24,23,33,18,19,24,20,50,53,56,57,33,20,24,78,79,57,56,58,59,33,19,61,62,24,53,18,17,56,33,24,62,93,78,56,17,20,58,33,18,20,25,21,50,57,60,61,33,21,25,74,73,61,60,44,37,33,20,79,80,25,57,59,62,60,33,25,80,97,74,60,62,45,44,33,18,21,26,22,50,61,63,51,33,22,26,81,82,51,63,64,54,33,21,73,72,26,61,37,36,63,33,26,72,96,81,63,36,39,64,33,27,31,32,28,65,66,67,68,33,28,32,54,55,68,67,13,5,33,31,88,89,32,66,69,70,67,33,32,89,92,54,67,70,14,13,33,27,28,33,29,65,68,71,72,33,29,33,84,85,72,71,73,74,33,28,55,56,33,68,5,4,71,33,33,56,90,84,71,4,8,73,33,27,29,34,30,65,72,75,76,33,30,34,68,67,76,75,32,31,33,29,85,86,34,72,74,77,75,33,34,86,95,68,75,77,33,32,33,27,30,35,31,65,76,78,66,33,31,35,87,88,66,78,79,69,33,30,67,66,35,76,31,47,78,33,35,66,94,87,78,47,49,79,33,36,40,41,37,80,81,82,83,33,37,41,63,64,83,82,19,12,33,40,79,78,41,81,59,58,82,33,41,78,93,63,82,58,20,19,33,36,37,42,38,80,83,84,85,33,38,42,89,88,85,84,70,69,33,37,64,65,42,83,12,11,84,33,42,65,92,89,84,11,14,70,33,36,38,43,39,80,85,86,87,33,39,43,77,76,87,86,48,43,33,38,88,87,43,85,69,79,86,33,43,87,94,77,86,79,49,48,33,36,39,44,40,80,87,88,81,33,40,44,80,79,81,88,62,59,33,39,76,75,44,87,43,42,88,33,44,75,97,80,88,42,45,62,33,45,49,50,46,89,90,91,92,33,46,50,57,58,92,91,7,6,33,49,85,84,50,90,74,73,91,33,50,84,90,57,91,73,8,7,33,45,46,51,47,89,92,93,94,33,47,51,83,82,94,93,55,54,33,46,58,59,51,92,6,22,93,33,51,59,91,83,93,22,24,55,33,45,47,52,48,89,94,95,96,33,48,52,71,70,96,95,38,30,33,47,82,81,52,94,54,64,95,33,52,81,96,71,95,64,39,38,33,45,48,53,49,89,96,97,90,33,49,53,86,85,90,97,77,74,33,48,70,69,53,96,30,29,97,33,53,69,95,86,97,29,33,77], 3 | "normals":[0,-0.999969,-0,0,-0.986908,0.161229,-0.356548,-0.921812,0.151952,-0.340953,-0.940062,-0,-0.684164,-0.714713,0.145146,-0.692007,-0.721885,-0,0,-0.907895,0.419141,-0.421949,-0.833766,0.356029,-0.665517,-0.697348,0.265938,-0.356548,-0.921812,-0.151952,0,-0.986908,-0.161229,-0.421949,-0.833766,-0.356029,0,-0.907895,-0.419141,-0.684164,-0.714713,-0.145146,-0.665517,-0.697348,-0.265938,0.356548,-0.921812,-0.151952,0.340953,-0.940062,-0,0.684164,-0.714713,-0.145146,0.692007,-0.721885,-0,0.421949,-0.833766,-0.356029,0.665517,-0.697348,-0.265938,0.356548,-0.921812,0.151952,0.421949,-0.833766,0.356029,0.684164,-0.714713,0.145146,0.665517,-0.697348,0.265938,0,1,-0,-0.340953,0.940062,-0,-0.356548,0.921812,0.151952,0,0.986908,0.161229,-0.421949,0.833766,0.356029,0,0.907895,0.419141,-0.692007,0.721885,-0,-0.684164,0.714713,0.145146,-0.665517,0.697348,0.265938,0.356548,0.921812,0.151952,0.340953,0.940062,-0,0.684164,0.714713,0.145146,0.692007,0.721885,-0,0.421949,0.833766,0.356029,0.665517,0.697348,0.265938,0.356548,0.921812,-0.151952,0,0.986908,-0.161229,0.421949,0.833766,-0.356029,0,0.907895,-0.419141,0.684164,0.714713,-0.145146,0.665517,0.697348,-0.265938,-0.356548,0.921812,-0.151952,-0.684164,0.714713,-0.145146,-0.421949,0.833766,-0.356029,-0.665517,0.697348,-0.265938,1,0,-0,0.985595,0,0.169103,0.909726,-0.384442,0.156682,0.929624,-0.36848,-0,0.900204,0,0.435438,0.81576,-0.44966,0.36375,0.909726,-0.384442,-0.156682,0.985595,0,-0.169103,0.81576,-0.44966,-0.36375,0.900204,0,-0.435438,0.909726,0.384442,-0.156682,0.929624,0.36848,-0,0.81576,0.44966,-0.36375,0.909726,0.384442,0.156682,0.81576,0.44966,0.36375,-1,0,-0,-0.985595,0,-0.169103,-0.909726,-0.384442,-0.156682,-0.929624,-0.36848,-0,-0.900204,0,-0.435438,-0.81576,-0.44966,-0.36375,-0.909726,-0.384442,0.156682,-0.985595,0,0.169103,-0.81576,-0.44966,0.36375,-0.900204,0,0.435438,-0.909726,0.384442,0.156682,-0.929624,0.36848,-0,-0.81576,0.44966,0.36375,-0.909726,0.384442,-0.156682,-0.81576,0.44966,-0.36375,0,0,-1,0.607929,0,-0.79397,0.538774,-0.560625,-0.628773,0,-0.623341,-0.781915,-0.538774,-0.560625,-0.628773,-0.607929,0,-0.79397,-0.538774,0.560625,-0.628773,0,0.623341,-0.781915,0.538774,0.560625,-0.628773,0,0,1,-0.607929,0,0.79397,-0.538774,-0.560625,0.628773,0,-0.623341,0.781915,0.538774,-0.560625,0.628773,0.607929,0,0.79397,0.538774,0.560625,0.628773,0,0.623341,0.781915,-0.538774,0.560625,0.628773], 4 | "name":"Plane.005Geometry", 5 | "vertices":[0,0,-0.257125,-0.107767,0,-0.239848,0,0.258616,-0.239848,0.107767,0,-0.239848,0,-0.258616,-0.239848,-0.100298,-0.240692,-0.223587,-0.100298,0.240692,-0.223587,0.100298,0.240692,-0.223587,0.100298,-0.240692,-0.223587,0,0,0.257125,0,-0.258616,0.239848,0.107767,0,0.239848,0,0.258616,0.239848,-0.107767,0,0.239848,-0.100298,-0.240692,0.223587,0.100298,-0.240692,0.223587,0.100298,0.240692,0.223587,-0.100298,0.240692,0.223587,0.26995,0,-0,0.251811,0,-0.102647,0.251811,0.258616,-0,0.251811,0,0.102647,0.251811,-0.258616,-0,0.234739,-0.240692,-0.095533,0.234739,0.240692,-0.095533,0.234739,0.240692,0.095533,0.234739,-0.240692,0.095533,-0.26995,0,-0,-0.251811,0,-0.102647,-0.251811,-0.258616,0,-0.251811,0,0.102647,-0.251811,0.258616,-0,-0.234739,0.240692,-0.095533,-0.234739,-0.240692,-0.095533,-0.234739,-0.240692,0.095533,-0.234739,0.240692,0.095533,0,0.647819,-0,0,0.60429,-0.102647,-0.107767,0.60429,-0,0,0.60429,0.102647,0.107767,0.60429,-0,0.100298,0.563321,-0.095533,-0.100298,0.563321,-0.095533,-0.100298,0.563321,0.095533,0.100298,0.563321,0.095533,0,-0.647819,0,0,-0.60429,-0.102647,0.107767,-0.60429,0,0,-0.60429,0.102647,-0.107767,-0.60429,0,-0.100298,-0.563321,-0.095533,0.100298,-0.563321,-0.095533,0.100298,-0.563321,0.095533,-0.100298,-0.563321,0.095533,-0.184057,0.222768,-0.175313,-0.197661,0,-0.188271,-0.184057,-0.222768,-0.175313,-0.092829,-0.441695,-0.175313,0,-0.474342,-0.188271,0.092829,-0.441695,-0.175313,0.184057,-0.222768,-0.175313,0.197661,0,-0.188271,0.184057,0.222768,-0.175313,0.092829,0.441695,-0.175313,0,0.474342,-0.188271,-0.092829,0.441695,-0.175313,-0.184057,0.222768,0.175313,-0.197661,0,0.188271,-0.184057,-0.222768,0.175313,-0.092829,-0.441695,0.175313,0,-0.474342,0.188271,0.092829,-0.441695,0.175313,0.184057,-0.222768,0.175313,0.197661,0,0.188271,0.184057,0.222768,0.175313,0.092829,0.441695,0.175313,0,0.474342,0.188271,-0.092829,0.441695,0.175313,0.184057,0.441695,-0.088419,0.197661,0.474342,-0,0.184057,0.441695,0.088419,0.184057,-0.441695,0.088419,0.197661,-0.474342,0,0.184057,-0.441695,-0.088419,-0.184057,-0.441695,-0.088419,-0.197661,-0.474342,0,-0.184057,-0.441695,0.088419,-0.184057,0.441695,0.088419,-0.197661,0.474342,-0,-0.184057,0.441695,-0.088419,-0.156493,-0.375547,-0.149058,0.156493,-0.375547,-0.149058,-0.156493,0.375547,-0.149058,0.156493,0.375547,-0.149058,-0.156493,0.375547,0.149058,-0.156493,-0.375547,0.149058,0.156493,-0.375547,0.149058,0.156493,0.375547,0.149058], 6 | "metadata":{ 7 | "faces":96, 8 | "normals":98, 9 | "version":3, 10 | "vertices":98, 11 | "uvs":0, 12 | "generator":"io_three", 13 | "type":"Geometry" 14 | }, 15 | "uvs":[] 16 | } -------------------------------------------------------------------------------- /public/assets/letters/J.json: -------------------------------------------------------------------------------- 1 | { 2 | "faces":[33,0,4,5,1,0,1,2,3,33,1,5,200,199,3,2,4,5,33,4,202,201,5,1,6,7,2,33,5,201,330,200,2,7,8,4,33,0,1,6,2,0,3,9,10,33,2,6,209,208,10,9,11,12,33,1,199,198,6,3,5,13,9,33,6,198,332,209,9,13,14,11,33,0,2,7,3,0,10,15,16,33,3,7,206,205,16,15,17,18,33,2,208,207,7,10,12,19,15,33,7,207,333,206,15,19,20,17,33,0,3,8,4,0,16,21,1,33,4,8,203,202,1,21,22,6,33,3,205,204,8,16,18,23,21,33,8,204,331,203,21,23,24,22,33,9,13,14,10,25,26,27,28,33,10,14,230,229,28,27,29,30,33,13,235,236,14,26,31,32,27,33,14,236,338,230,27,32,33,29,33,9,10,15,11,25,28,34,35,33,11,15,212,211,35,34,36,37,33,10,229,228,15,28,30,38,34,33,15,228,335,212,34,38,39,36,33,9,11,16,12,25,35,40,41,33,12,16,218,217,41,40,42,43,33,11,211,210,16,35,37,44,40,33,16,210,334,218,40,44,45,42,33,9,12,17,13,25,41,46,26,33,13,17,234,235,26,46,47,31,33,12,217,216,17,41,43,48,46,33,17,216,339,234,46,48,49,47,33,18,22,23,19,50,51,52,53,33,19,23,239,238,53,52,54,55,33,22,244,245,23,51,56,57,52,33,23,245,340,239,52,57,58,54,33,18,19,24,20,50,53,59,60,33,20,24,221,220,60,59,61,62,33,19,238,237,24,53,55,63,59,33,24,237,337,221,59,63,64,61,33,18,20,25,21,50,60,65,66,33,21,25,227,226,66,65,67,68,33,20,220,219,25,60,62,69,65,33,25,219,336,227,65,69,70,67,33,18,21,26,22,50,66,71,51,33,22,26,243,244,51,71,72,56,33,21,226,225,26,66,68,73,71,33,26,225,341,243,71,73,74,72,33,27,31,32,28,75,76,77,78,33,28,32,215,214,78,77,79,80,33,31,202,203,32,76,6,22,77,33,32,203,331,215,77,22,24,79,33,27,28,33,29,75,78,81,82,33,29,33,236,235,82,81,32,31,33,28,214,213,33,78,80,83,81,33,33,213,338,236,81,83,33,32,33,27,29,34,30,75,82,84,85,33,30,34,233,232,85,84,86,87,33,29,235,234,34,82,31,47,84,33,34,234,339,233,84,47,49,86,33,27,30,35,31,75,85,88,76,33,31,35,201,202,76,88,7,6,33,30,232,231,35,85,87,89,88,33,35,231,330,201,88,89,8,7,33,36,40,41,37,90,91,92,93,33,37,41,224,223,93,92,94,95,33,40,211,212,41,91,37,36,92,33,41,212,335,224,92,36,39,94,33,36,37,42,38,90,93,96,97,33,38,42,245,244,97,96,57,56,33,37,223,222,42,93,95,98,96,33,42,222,340,245,96,98,58,57,33,36,38,43,39,90,97,99,100,33,39,43,242,241,100,99,101,102,33,38,244,243,43,97,56,72,99,33,43,243,341,242,99,72,74,101,33,36,39,44,40,90,100,103,91,33,40,44,210,211,91,103,44,37,33,39,241,240,44,100,102,104,103,33,44,240,334,210,103,104,45,44,33,45,49,50,46,105,106,107,108,33,46,50,249,250,108,107,109,110,33,49,247,248,50,106,111,112,107,33,50,248,343,249,107,112,113,109,33,45,46,51,47,105,108,114,115,33,47,51,252,253,115,114,116,117,33,46,250,251,51,108,110,118,114,33,51,251,344,252,114,118,119,116,33,45,47,52,48,105,115,120,121,33,48,52,255,256,121,120,122,123,33,47,253,254,52,115,117,124,120,33,52,254,345,255,120,124,125,122,33,45,48,53,49,105,121,126,106,33,49,53,246,247,106,126,127,111,33,48,256,257,53,121,123,128,126,33,53,257,342,246,126,128,129,127,33,54,58,59,55,130,131,132,133,33,55,59,284,283,133,132,134,135,33,58,277,278,59,131,136,137,132,33,59,278,348,284,132,137,138,134,33,54,55,60,56,130,133,139,140,33,56,60,264,265,140,139,141,142,33,55,283,282,60,133,135,143,139,33,60,282,349,264,139,143,144,141,33,54,56,61,57,130,140,145,146,33,57,61,258,259,146,145,147,148,33,56,265,266,61,140,142,149,145,33,61,266,346,258,145,149,150,147,33,54,57,62,58,130,146,151,131,33,58,62,276,277,131,151,152,136,33,57,259,260,62,146,148,153,151,33,62,260,347,276,151,153,154,152,33,63,67,68,64,155,156,157,158,33,64,68,293,292,158,157,159,160,33,67,286,287,68,156,161,162,157,33,68,287,352,293,157,162,163,159,33,63,64,69,65,155,158,164,165,33,65,69,273,274,165,164,166,167,33,64,292,291,69,158,160,168,164,33,69,291,353,273,164,168,169,166,33,63,65,70,66,155,165,170,171,33,66,70,267,268,171,170,172,173,33,65,274,275,70,165,167,174,170,33,70,275,350,267,170,174,175,172,33,63,66,71,67,155,171,176,156,33,67,71,285,286,156,176,177,161,33,66,268,269,71,171,173,178,176,33,71,269,351,285,176,178,179,177,33,72,76,77,73,180,181,182,183,33,73,77,251,250,183,182,118,110,33,76,262,263,77,181,184,185,182,33,77,263,344,251,182,185,119,118,33,72,73,78,74,180,183,186,187,33,74,78,279,280,187,186,188,189,33,73,250,249,78,183,110,109,186,33,78,249,343,279,186,109,113,188,33,72,74,79,75,180,187,190,191,33,75,79,282,283,191,190,143,135,33,74,280,281,79,187,189,192,190,33,79,281,349,282,190,192,144,143,33,72,75,80,76,180,191,193,181,33,76,80,261,262,181,193,194,184,33,75,283,284,80,191,135,134,193,33,80,284,348,261,193,134,138,194,33,81,85,86,82,195,196,197,198,33,82,86,260,259,198,197,153,148,33,85,271,272,86,196,199,200,197,33,86,272,347,260,197,200,154,153,33,81,82,87,83,195,198,201,202,33,83,87,288,289,202,201,203,204,33,82,259,258,87,198,148,147,201,33,87,258,346,288,201,147,150,203,33,81,83,88,84,195,202,205,206,33,84,88,291,292,206,205,168,160,33,83,289,290,88,202,204,207,205,33,88,290,353,291,205,207,169,168,33,81,84,89,85,195,206,208,196,33,85,89,270,271,196,208,209,199,33,84,292,293,89,206,160,159,208,33,89,293,352,270,208,159,163,209,33,90,94,95,91,210,211,212,213,33,91,95,198,199,213,212,13,5,33,94,298,299,95,211,214,215,212,33,95,299,332,198,212,215,14,13,33,90,91,96,92,210,213,216,217,33,92,96,294,295,217,216,218,219,33,91,199,200,96,213,5,4,216,33,96,200,330,294,216,4,8,218,33,90,92,97,93,210,217,220,221,33,93,97,248,247,221,220,112,111,33,92,295,296,97,217,219,222,220,33,97,296,343,248,220,222,113,112,33,90,93,98,94,210,221,223,211,33,94,98,297,298,211,223,224,214,33,93,247,246,98,221,111,127,223,33,98,246,342,297,223,127,129,224,33,99,103,104,100,225,226,227,228,33,100,104,219,220,228,227,69,62,33,103,304,305,104,226,229,230,227,33,104,305,336,219,227,230,70,69,33,99,100,105,101,225,228,231,232,33,101,105,300,301,232,231,233,234,33,100,220,221,105,228,62,61,231,33,105,221,337,300,231,61,64,233,33,99,101,106,102,225,232,235,236,33,102,106,269,268,236,235,178,173,33,101,301,302,106,232,234,237,235,33,106,302,351,269,235,237,179,178,33,99,102,107,103,225,236,238,226,33,103,107,303,304,226,238,239,229,33,102,268,267,107,236,173,172,238,33,107,267,350,303,238,172,175,239,33,108,112,113,109,240,241,242,243,33,109,113,240,241,243,242,104,102,33,112,310,311,113,241,244,245,242,33,113,311,334,240,242,245,45,104,33,108,109,114,110,240,243,246,247,33,110,114,306,307,247,246,248,249,33,109,241,242,114,243,102,101,246,33,114,242,341,306,246,101,74,248,33,108,110,115,111,240,247,250,251,33,111,115,290,289,251,250,207,204,33,110,307,308,115,247,249,252,250,33,115,308,353,290,250,252,169,207,33,108,111,116,112,240,251,253,241,33,112,116,309,310,241,253,254,244,33,111,289,288,116,251,204,203,253,33,116,288,346,309,253,203,150,254,33,117,121,122,118,255,256,257,258,33,118,122,231,232,258,257,89,87,33,121,295,294,122,256,219,218,257,33,122,294,330,231,257,218,8,89,33,117,118,123,119,255,258,259,260,33,119,123,312,313,260,259,261,262,33,118,232,233,123,258,87,86,259,33,123,233,339,312,259,86,49,261,33,117,119,124,120,255,260,263,264,33,120,124,281,280,264,263,192,189,33,119,313,314,124,260,262,265,263,33,124,314,349,281,263,265,144,192,33,117,120,125,121,255,264,266,256,33,121,125,296,295,256,266,222,219,33,120,280,279,125,264,189,188,266,33,125,279,343,296,266,188,113,222,33,126,130,131,127,267,268,269,270,33,127,131,222,223,270,269,98,95,33,130,319,320,131,268,271,272,269,33,131,320,340,222,269,272,58,98,33,126,127,132,128,267,270,273,274,33,128,132,315,316,274,273,275,276,33,127,223,224,132,270,95,94,273,33,132,224,335,315,273,94,39,275,33,126,128,133,129,267,274,277,278,33,129,133,272,271,278,277,200,199,33,128,316,317,133,274,276,279,277,33,133,317,347,272,277,279,154,200,33,126,129,134,130,267,278,280,268,33,130,134,318,319,268,280,281,271,33,129,271,270,134,278,199,209,280,33,134,270,352,318,280,209,163,281,33,135,139,140,136,282,283,284,285,33,136,140,213,214,285,284,83,80,33,139,325,326,140,283,286,287,284,33,140,326,338,213,284,287,33,83,33,135,136,141,137,282,285,288,289,33,137,141,321,322,289,288,290,291,33,136,214,215,141,285,80,79,288,33,141,215,331,321,288,79,24,290,33,135,137,142,138,282,289,292,293,33,138,142,263,262,293,292,185,184,33,137,322,323,142,289,291,294,292,33,142,323,344,263,292,294,119,185,33,135,138,143,139,282,293,295,283,33,139,143,324,325,283,295,296,286,33,138,262,261,143,293,184,194,295,33,143,261,348,324,295,194,138,296,33,144,148,149,145,297,298,299,300,33,145,149,204,205,300,299,23,18,33,148,322,321,149,298,291,290,299,33,149,321,331,204,299,290,24,23,33,144,145,150,146,297,300,301,302,33,146,150,327,328,302,301,303,304,33,145,205,206,150,300,18,17,301,33,150,206,333,327,301,17,20,303,33,144,146,151,147,297,302,305,306,33,147,151,254,253,306,305,124,117,33,146,328,329,151,302,304,307,305,33,151,329,345,254,305,307,125,124,33,144,147,152,148,297,306,308,298,33,148,152,323,322,298,308,294,291,33,147,253,252,152,306,117,116,308,33,152,252,344,323,308,116,119,294,33,153,157,158,154,309,310,311,312,33,154,158,225,226,312,311,73,68,33,157,307,306,158,310,249,248,311,33,158,306,341,225,311,248,74,73,33,153,154,159,155,309,312,313,314,33,155,159,305,304,314,313,230,229,33,154,226,227,159,312,68,67,313,33,159,227,336,305,313,67,70,230,33,153,155,160,156,309,314,315,316,33,156,160,275,274,316,315,174,167,33,155,304,303,160,314,229,239,315,33,160,303,350,275,315,239,175,174,33,153,156,161,157,309,316,317,310,33,157,161,308,307,310,317,252,249,33,156,274,273,161,316,167,166,317,33,161,273,353,308,317,166,169,252,33,162,166,167,163,318,319,320,321,33,163,167,216,217,321,320,48,43,33,166,313,312,167,319,262,261,320,33,167,312,339,216,320,261,49,48,33,162,163,168,164,318,321,322,323,33,164,168,311,310,323,322,245,244,33,163,217,218,168,321,43,42,322,33,168,218,334,311,322,42,45,245,33,162,164,169,165,318,323,324,325,33,165,169,266,265,325,324,149,142,33,164,310,309,169,323,244,254,324,33,169,309,346,266,324,254,150,149,33,162,165,170,166,318,325,326,319,33,166,170,314,313,319,326,265,262,33,165,265,264,170,325,142,141,326,33,170,264,349,314,326,141,144,265,33,171,175,176,172,327,328,329,330,33,172,176,237,238,330,329,63,55,33,175,301,300,176,328,234,233,329,33,176,300,337,237,329,233,64,63,33,171,172,177,173,327,330,331,332,33,173,177,320,319,332,331,272,271,33,172,238,239,177,330,55,54,331,33,177,239,340,320,331,54,58,272,33,171,173,178,174,327,332,333,334,33,174,178,287,286,334,333,162,161,33,173,319,318,178,332,271,281,333,33,178,318,352,287,333,281,163,162,33,171,174,179,175,327,334,335,328,33,175,179,302,301,328,335,237,234,33,174,286,285,179,334,161,177,335,33,179,285,351,302,335,177,179,237,33,180,184,185,181,336,337,338,339,33,181,185,207,208,339,338,19,12,33,184,328,327,185,337,304,303,338,33,185,327,333,207,338,303,20,19,33,180,181,186,182,336,339,340,341,33,182,186,299,298,341,340,215,214,33,181,208,209,186,339,12,11,340,33,186,209,332,299,340,11,14,215,33,180,182,187,183,336,341,342,343,33,183,187,257,256,343,342,128,123,33,182,298,297,187,341,214,224,342,33,187,297,342,257,342,224,129,128,33,180,183,188,184,336,343,344,337,33,184,188,329,328,337,344,307,304,33,183,256,255,188,343,123,122,344,33,188,255,345,329,344,122,125,307,33,189,193,194,190,345,346,347,348,33,190,194,228,229,348,347,38,30,33,193,316,315,194,346,276,275,347,33,194,315,335,228,347,275,39,38,33,189,190,195,191,345,348,349,350,33,191,195,326,325,350,349,287,286,33,190,229,230,195,348,30,29,349,33,195,230,338,326,349,29,33,287,33,189,191,196,192,345,350,351,352,33,192,196,278,277,352,351,137,136,33,191,325,324,196,350,286,296,351,33,196,324,348,278,351,296,138,137,33,189,192,197,193,345,352,353,346,33,193,197,317,316,346,353,279,276,33,192,277,276,197,352,136,152,353,33,197,276,347,317,353,152,154,279], 3 | "normals":[0.008545,-0.994873,-0.100742,0.010804,-0.998901,-0.045442,-0.322092,-0.945463,-0.048311,-0.32606,-0.939482,-0.104831,-0.687094,-0.724906,-0.048555,-0.681661,-0.723472,-0.109073,0.015503,-0.999512,-0.026429,-0.321482,-0.946379,-0.031007,-0.690878,-0.722373,-0.028352,-0.341838,-0.915647,-0.211493,0.007752,-0.976196,-0.216651,-0.398175,-0.820643,-0.409833,0.007752,-0.88525,-0.46498,-0.668813,-0.713309,-0.209296,-0.645711,-0.692648,-0.32136,0.353557,-0.911618,-0.209601,0.339,-0.93527,-0.101657,0.673116,-0.710074,-0.20661,0.685659,-0.720389,-0.10419,0.409162,-0.817011,-0.406262,0.650502,-0.689383,-0.318735,0.337992,-0.940184,-0.042116,0.34376,-0.938871,-0.017335,0.690725,-0.722037,-0.038942,0.694784,-0.719169,-0.00647,0.092349,-0.988128,-0.122654,-0.083102,-0.989929,0.114444,0.258187,-0.945189,0.199774,0.283212,-0.942564,0.176977,0.617084,-0.69274,0.373211,0.560137,-0.688894,0.460005,-0.045564,-0.989654,0.135868,0.312601,-0.93408,0.172491,0.658406,-0.697806,0.28193,0.233131,-0.936827,0.260689,-0.01059,-0.999878,-0.010865,0.143101,-0.940092,0.309336,-0.129307,-0.988159,0.082308,0.484298,-0.686666,0.542131,0.386395,-0.685263,0.617298,-0.225867,-0.942808,-0.245064,-0.04944,-0.926145,-0.373821,-0.48912,-0.700217,-0.520005,-0.33314,-0.701804,-0.629627,-0.366863,-0.92645,-0.084017,-0.610889,-0.695914,-0.377453,-0.381359,-0.920286,0.087069,-0.390515,-0.912839,0.119022,-0.752251,-0.657186,0.046876,-0.748344,-0.651662,0.12363,-0.295724,-0.95526,0.002106,-0.13538,-0.990448,0.025636,-0.156377,-0.917997,0.364391,-0.330302,-0.884518,0.329325,-0.174169,-0.688192,0.704276,-0.362499,-0.665883,0.652028,-0.067507,-0.996857,0.040895,-0.064089,-0.921354,0.383374,-0.055483,-0.688528,0.723075,-0.574175,-0.775414,0.262734,-0.548967,-0.834986,-0.037416,-0.81576,-0.54796,0.184973,-0.813746,-0.574572,-0.087252,-0.597247,-0.594104,0.538774,-0.778588,-0.487655,0.39494,-0.510483,-0.786126,-0.348399,-0.260964,-0.902524,-0.342479,-0.464431,-0.60155,-0.649892,-0.207587,-0.682394,-0.700858,-0.759392,-0.543901,-0.357006,-0.677511,-0.478561,-0.558458,-0.098422,-0.938108,-0.332011,-0.048311,-0.944273,-0.32548,-0.029633,-0.703269,-0.710257,0.013703,-0.701407,-0.712577,0.031678,-0.99939,-0.013215,0.022919,-0.999481,-0.021546,0.352458,-0.935789,-0.000122,0.360332,-0.932218,0.032991,0.699515,-0.714103,0.02591,0.700247,-0.708487,0.087436,0.361309,-0.928495,0.085482,0.039918,-0.999176,-0.000549,0.687796,-0.702872,0.181249,-0.310739,-0.948454,-0.06183,-0.317698,-0.947295,-0.04059,-0.701743,-0.708823,-0.071291,-0.700339,-0.712821,-0.036714,-0.320231,-0.946776,-0.032624,-0.695242,-0.718192,-0.027924,0.126774,-0.991638,-0.023316,0.119846,-0.990478,-0.067537,0.155095,-0.943388,0.29313,0.107944,-0.930448,0.350078,0.272561,-0.684866,0.675741,0.156316,-0.685049,0.711509,0.001221,-0.920072,0.391705,-0.038331,-0.997955,0.050783,0.045381,-0.686331,0.725822,-0.055483,-0.945738,-0.320078,0.150884,-0.911954,-0.381451,-0.022034,-0.698569,-0.715171,0.185095,-0.64568,-0.740806,0.127171,-0.918332,-0.374767,0.108066,-0.655599,-0.747307,0.008545,0.994873,-0.100742,-0.32606,0.939482,-0.104831,-0.322092,0.945463,-0.048311,0.010804,0.998901,-0.045442,-0.321482,0.946379,-0.031007,0.015503,0.999512,-0.026429,-0.681661,0.723472,-0.109073,-0.687094,0.724906,-0.048555,-0.690878,0.722373,-0.028352,0.337992,0.940184,-0.042116,0.339,0.93527,-0.101657,0.690725,0.722037,-0.038942,0.685659,0.720389,-0.10419,0.34376,0.938871,-0.017335,0.694784,0.719169,-0.00647,0.353557,0.911618,-0.209601,0.007752,0.976196,-0.216651,0.409162,0.817011,-0.406262,0.007752,0.88525,-0.46498,0.673116,0.710074,-0.20661,0.650502,0.689383,-0.318735,-0.341838,0.915647,-0.211493,-0.668813,0.713309,-0.209296,-0.398175,0.820643,-0.409833,-0.645711,0.692648,-0.32136,0.092349,0.988128,-0.122654,0.283212,0.942564,0.176977,0.258187,0.945189,0.199774,-0.083102,0.989929,0.114444,0.312601,0.93408,0.172491,-0.045564,0.989654,0.135868,0.560137,0.688894,0.460005,0.617084,0.69274,0.373211,0.658406,0.697806,0.28193,-0.381359,0.920286,0.087069,-0.04944,0.926145,-0.373821,-0.752251,0.657186,0.046876,-0.33314,0.701804,-0.629627,-0.390515,0.912839,0.119022,-0.748344,0.651662,0.12363,-0.225867,0.942808,-0.245064,-0.01059,0.999878,-0.010865,-0.366863,0.92645,-0.084017,-0.129307,0.988159,0.082308,-0.48912,0.700217,-0.520005,-0.610889,0.695914,-0.377453,0.233131,0.936827,0.260689,0.484298,0.686666,0.542131,0.143101,0.940092,0.309336,0.386395,0.685263,0.617298,-0.295724,0.95526,0.002106,-0.330302,0.884518,0.329325,-0.156377,0.917997,0.364391,-0.13538,0.990448,0.025636,-0.064089,0.921354,0.383374,-0.067507,0.996857,0.040895,-0.362499,0.665883,0.652028,-0.174169,0.688192,0.704276,-0.055483,0.688528,0.723075,-0.098422,0.938108,-0.332011,-0.260964,0.902524,-0.342479,-0.029633,0.703269,-0.710257,-0.207587,0.682394,-0.700858,-0.048311,0.944273,-0.32548,0.013703,0.701407,-0.712577,-0.510483,0.786126,-0.348399,-0.548967,0.834986,-0.037416,-0.759392,0.543901,-0.357006,-0.813746,0.574572,-0.087252,-0.464431,0.60155,-0.649892,-0.677511,0.478561,-0.558458,-0.574175,0.775414,0.262734,-0.597247,0.594104,0.538774,-0.81576,0.54796,0.184973,-0.778588,0.487655,0.39494,0.031678,0.99939,-0.013215,0.360332,0.932218,0.032991,0.352458,0.935789,-0.000122,0.022919,0.999481,-0.021546,0.700247,0.708487,0.087436,0.699515,0.714103,0.02591,-0.320231,0.946776,-0.032624,-0.317698,0.947295,-0.04059,-0.695242,0.718192,-0.027924,-0.700339,0.712821,-0.036714,-0.310739,0.948454,-0.06183,0.039918,0.999176,-0.000549,-0.701743,0.708823,-0.071291,0.361309,0.928495,0.085482,0.687796,0.702872,0.181249,0.126774,0.991638,-0.023316,0.107944,0.930448,0.350078,0.155095,0.943388,0.29313,0.119846,0.990478,-0.067537,0.156316,0.685049,0.711509,0.272561,0.684866,0.675741,0.127171,0.918332,-0.374767,0.150884,0.911954,-0.381451,0.108066,0.655599,-0.747307,0.185095,0.64568,-0.740806,-0.055483,0.945738,-0.320078,-0.038331,0.997955,0.050783,-0.022034,0.698569,-0.715171,0.001221,0.920072,0.391705,0.045381,0.686331,0.725822,-0.994568,0,-0.104068,-0.973327,0,-0.229286,-0.896512,-0.38496,-0.219092,-0.923917,-0.367351,-0.106571,-0.872005,0,-0.489486,-0.792444,-0.441054,-0.421277,-0.9317,-0.360424,-0.044496,-0.999084,0,-0.042238,-0.934263,-0.355907,-0.020722,-0.999847,0,-0.017121,-0.9317,0.360424,-0.044496,-0.923917,0.367351,-0.106571,-0.934263,0.355907,-0.020722,-0.896512,0.38496,-0.219092,-0.792444,0.441054,-0.421277,-0.990997,0,-0.133793,-0.924253,0,-0.381756,-0.891629,-0.257088,-0.3726,-0.957213,-0.262246,-0.122135,-0.740989,0,-0.671499,-0.722343,-0.271859,-0.635823,-0.952757,-0.267922,0.142888,-0.990936,0,0.134281,-0.848415,-0.281533,0.448195,-0.880856,0,0.473373,-0.952757,0.267922,0.142888,-0.957213,0.262246,-0.122135,-0.848415,0.281533,0.448195,-0.891629,0.257088,-0.3726,-0.722343,0.271859,-0.635823,0.307932,0,-0.951384,0.184698,0,-0.982788,0.147679,-0.284219,-0.947295,0.265023,-0.279641,-0.922788,-0.76928,0,-0.638874,-0.741295,-0.331675,-0.583453,0.041597,-0.322733,-0.945555,0.070437,0,-0.997497,0.083499,-0.328776,-0.940703,0.109592,0,-0.993957,0.041597,0.322733,-0.945555,0.265023,0.279641,-0.922788,0.083499,0.328776,-0.940703,0.147679,0.284219,-0.947295,-0.741295,0.331675,-0.583453,-0.999969,0,0.001953,-0.999969,0,-0.006592,-0.936705,-0.349773,-0.01352,-0.939848,-0.34138,-0.011292,-0.942534,-0.33256,-0.031922,-0.999969,0,-0.007782,-0.938047,-0.283975,0.198401,-0.969451,0,0.245155,-0.942534,0.33256,-0.031922,-0.939848,0.34138,-0.011292,-0.938047,0.283975,0.198401,-0.936705,0.349773,-0.01352,0.225654,0,0.974181,0.083651,0,0.99649,0.074953,-0.338816,0.937834,0.210364,-0.338847,0.91699,-0.044649,0,0.998993,-0.047609,-0.339549,0.93936,0.354534,-0.339732,0.87112,0.377606,0,0.925962,0.499466,-0.34077,0.796472,0.531419,0,0.847102,0.354534,0.339732,0.87112,0.210364,0.338847,0.91699,0.499466,0.34077,0.796472,0.074953,0.338816,0.937834,-0.047609,0.339549,0.93936,0.990631,0,0.136479,0.964354,0,0.264595,0.903104,-0.352092,0.245766,0.926389,-0.355052,0.125278,0.916349,0,0.400311,0.85934,-0.348918,0.373852,0.932646,-0.357982,0.044618,0.998718,0,0.050264,0.932615,-0.36082,0.00174,0.999969,0,0.004334,0.932646,0.357982,0.044618,0.926389,0.355052,0.125278,0.932615,0.36082,0.00174,0.903104,0.352092,0.245766,0.85934,0.348918,0.373852,0.994873,0,-0.101047,0.99942,0,-0.033906,0.93112,-0.362896,-0.03534,0.924192,-0.367809,-0.102634,0.897244,-0.384136,-0.217505,0.97351,0,-0.228553,0.795099,-0.439344,-0.418012,0.873897,0,-0.486068,0.897244,0.384136,-0.217505,0.924192,0.367809,-0.102634,0.795099,0.439344,-0.418012,0.93112,0.362896,-0.03534,-0.119297,0,-0.992828,0.064089,0,-0.997925,0.039338,-0.33668,-0.940764,-0.145695,-0.338267,-0.929685,-0.432081,-0.310739,-0.846583,-0.423414,0,-0.905911,-0.432081,0.310739,-0.846583,-0.145695,0.338267,-0.929685,0.039338,0.33668,-0.940764,-0.634693,0,-0.772729,-0.988769,0,0.149297,-0.954741,-0.280038,0.099948,-0.562151,-0.340342,-0.753716,-0.657582,-0.32606,-0.679128,-0.701315,0,-0.712821,-0.657582,0.32606,-0.679128,-0.562151,0.340342,-0.753716,-0.954741,0.280038,0.099948,-0.375317,0,0.926878,-0.634358,0,0.773003,-0.622028,-0.310495,0.718741,-0.374859,-0.333659,0.864925,-0.181738,-0.33961,0.922819,-0.182623,0,0.983154,-0.181738,0.33961,0.922819,-0.374859,0.333659,0.864925,-0.622028,0.310495,0.718741,0.007416,0,-0.999969,0.572008,0,-0.820215,0.511704,-0.534837,-0.672353,0.007599,-0.588763,-0.808222,-0.501724,-0.536943,-0.678152,-0.562731,0,-0.826594,-0.501724,0.536943,-0.678152,0.007599,0.588763,-0.808222,0.511704,0.534837,-0.672353,0.771294,0,0.636433,0.666219,0,0.74572,0.626057,-0.341838,0.700827,0.724723,-0.343211,0.59743,0.800928,-0.345653,0.488845,0.852992,0,0.521897,0.800928,0.345653,0.488845,0.724723,0.343211,0.59743,0.626057,0.341838,0.700827], 4 | "name":"Plane.021Geometry", 5 | "vertices":[0.07891,0.285308,-0.162823,0.009488,0.284966,-0.152367,0.078637,0.425673,-0.143778,0.148348,0.280956,-0.151615,0.078849,0.135149,-0.172239,0.005877,0.138861,-0.161359,0.017092,0.417428,-0.134526,0.140244,0.415141,-0.134049,0.15182,0.131437,-0.160153,0.026631,-0.313779,-0.167182,0.079563,-0.357142,-0.165928,0.002573,-0.337372,-0.18144,-0.025487,-0.270623,-0.159041,0.045107,-0.284865,-0.167089,0.104311,-0.32059,-0.166082,0.049735,-0.388945,-0.165844,-0.044589,-0.285799,-0.172845,-0.012994,-0.249502,-0.158824,-0.273694,-0.369821,-0.163605,-0.276404,-0.435207,-0.151529,-0.318398,-0.360974,-0.144244,-0.269537,-0.304751,-0.153925,-0.223077,-0.37819,-0.173306,-0.222655,-0.446551,-0.160083,-0.320513,-0.419524,-0.133915,-0.310496,-0.303684,-0.135572,-0.2235,-0.309828,-0.163422,0.073386,-0.167343,-0.180136,0.145588,-0.18327,-0.166276,0.067397,-0.215229,-0.180851,0.001185,-0.151415,-0.169979,0.076678,-0.098791,-0.178675,0.150255,-0.109437,-0.165401,0.137026,-0.237394,-0.166448,-0.002232,-0.193065,-0.17114,0.0031,-0.088146,-0.168126,-0.08856,-0.380718,-0.18103,-0.06681,-0.4467,-0.165944,-0.127827,-0.384793,-0.179807,-0.11031,-0.314737,-0.171979,-0.053323,-0.373146,-0.167218,-0.023631,-0.434145,-0.166035,-0.114356,-0.452822,-0.165191,-0.141298,-0.316763,-0.170448,-0.08263,-0.313262,-0.159127,0.07891,0.285308,0.162823,0.078849,0.135149,0.172239,0.148348,0.280956,0.151615,0.078637,0.425673,0.143778,0.009488,0.284966,0.152367,0.005877,0.138861,0.161359,0.15182,0.131437,0.160153,0.140244,0.415141,0.134049,0.017092,0.417428,0.134526,0.026631,-0.313779,0.167182,0.045107,-0.284865,0.167089,-0.025487,-0.270623,0.159041,0.002573,-0.337372,0.18144,0.079563,-0.357142,0.165928,0.104311,-0.32059,0.166082,-0.012994,-0.249502,0.158824,-0.044589,-0.285799,0.172845,0.049735,-0.388944,0.165844,-0.273694,-0.369821,0.163606,-0.223077,-0.37819,0.173306,-0.269537,-0.304751,0.153925,-0.318398,-0.360974,0.144245,-0.276404,-0.435207,0.151529,-0.222655,-0.446551,0.160083,-0.2235,-0.309828,0.163422,-0.310496,-0.303684,0.135572,-0.320513,-0.419524,0.133916,0.073386,-0.167343,0.180136,0.076678,-0.098791,0.178675,0.001185,-0.151415,0.169979,0.067397,-0.215229,0.180851,0.145588,-0.18327,0.166276,0.150255,-0.109437,0.165401,0.0031,-0.088146,0.168126,-0.002232,-0.193065,0.17114,0.137026,-0.237394,0.166448,-0.08856,-0.380718,0.181031,-0.053323,-0.373146,0.167218,-0.11031,-0.314737,0.171979,-0.127827,-0.384793,0.179807,-0.06681,-0.4467,0.165944,-0.023631,-0.434145,0.166035,-0.08263,-0.313262,0.159127,-0.141298,-0.316763,0.170448,-0.114356,-0.452822,0.165191,-0.09458,0.290244,-0,-0.083029,0.287589,-0.06554,-0.10358,0.144429,0,-0.083029,0.287589,0.06554,-0.074961,0.428223,-0,-0.064782,0.418747,-0.057892,-0.091418,0.14381,-0.069499,-0.091418,0.14381,0.069499,-0.064782,0.418747,0.057892,-0.381226,-0.347299,0,-0.374199,-0.348828,-0.060027,-0.382459,-0.409186,0,-0.374199,-0.348828,0.060027,-0.36594,-0.28847,0,-0.360265,-0.293854,-0.056395,-0.374907,-0.406681,-0.055886,-0.374907,-0.406681,0.055886,-0.360265,-0.293854,0.056395,-0.142935,-0.215764,0,-0.13931,-0.226761,-0.07543,-0.161504,-0.21472,0,-0.13931,-0.226761,0.07543,-0.126102,-0.228752,0,-0.120883,-0.238381,-0.071391,-0.159259,-0.226058,-0.074551,-0.159259,-0.226058,0.074551,-0.120883,-0.238381,0.071391,-0.107116,-0.127524,-0,-0.095083,-0.130179,-0.073906,-0.106676,-0.159818,-0,-0.095083,-0.130179,0.073906,-0.107266,-0.072178,0,-0.095003,-0.073952,-0.072833,-0.095071,-0.163512,-0.074686,-0.095071,-0.163512,0.074686,-0.095003,-0.073952,0.072833,-0.034185,-0.545673,0,-0.03781,-0.534676,-0.069395,0.022094,-0.528041,0,-0.03781,-0.534676,0.069395,-0.09415,-0.554866,0,-0.096395,-0.543527,-0.069294,0.017013,-0.517609,-0.069266,0.017013,-0.517609,0.069266,-0.096395,-0.543527,0.069294,0.253889,-0.207161,0,0.241856,-0.204507,-0.070203,0.260622,-0.125405,0,0.241856,-0.204507,0.070203,0.241469,-0.270641,0,0.229865,-0.266947,-0.069995,0.248359,-0.123631,-0.070108,0.248359,-0.123631,0.070108,0.229865,-0.266947,0.069995,0.252401,0.280372,-0,0.240865,0.278333,-0.064789,0.232236,0.423123,-0,0.240865,0.278333,0.064789,0.261278,0.125869,-0,0.249116,0.126488,-0.068292,0.222118,0.413822,-0.057414,0.222118,0.413822,0.057414,0.249116,0.126488,0.068292,-0.264747,-0.206826,0,-0.264717,-0.21783,-0.066683,-0.304421,-0.216472,0,-0.264717,-0.21783,0.066684,-0.224133,-0.207285,0,-0.224063,-0.218679,-0.070992,-0.302848,-0.226656,-0.0587,-0.302848,-0.226656,0.0587,-0.224063,-0.218679,0.070992,-0.097177,-0.206182,0,-0.089124,-0.213969,-0.07114,-0.115332,-0.20844,0,-0.089124,-0.213969,0.07114,-0.09438,-0.196364,0,-0.085138,-0.202832,-0.071211,-0.107471,-0.217035,-0.076076,-0.107471,-0.217035,0.076076,-0.085138,-0.202832,0.071211,-0.282642,-0.532817,0,-0.281225,-0.522128,-0.064288,-0.222021,-0.549094,0,-0.281225,-0.522128,0.064288,-0.332375,-0.505476,0,-0.328162,-0.496552,-0.057043,-0.222092,-0.5377,-0.067653,-0.222092,-0.5377,0.067653,-0.328162,-0.496552,0.057043,0.077974,0.629546,-0,0.078048,0.606744,-0.05996,0.013933,0.607316,-0,0.078048,0.606744,0.05996,0.142163,0.606173,-0,0.13805,0.584668,-0.055983,0.018186,0.585899,-0.05613,0.018186,0.585899,0.05613,0.13805,0.584668,0.055983,0.161161,-0.423709,0,0.152094,-0.416313,-0.069178,0.195316,-0.375699,0,0.152094,-0.416313,0.069178,0.120477,-0.466304,0,0.112617,-0.457708,-0.069076,0.185204,-0.369576,-0.069381,0.185204,-0.369576,0.069381,0.112617,-0.457708,0.069076,-0.034134,0.40894,-0.105997,-0.048349,0.284277,-0.120017,-0.054932,0.141954,-0.127213,0.004376,0.005646,-0.165335,0.078192,-0.000864,-0.176149,0.152007,-0.007374,-0.163476,0.21263,0.128344,-0.125403,0.2062,0.27695,-0.11889,0.191531,0.404851,-0.10528,0.134485,0.520782,-0.103491,0.07827,0.538675,-0.110894,0.022166,0.522365,-0.103795,-0.061232,-0.303312,-0.159179,-0.023133,-0.358742,-0.16722,0.015209,-0.414959,-0.165867,0.19505,-0.255864,-0.129105,0.205755,-0.196543,-0.129322,0.21157,-0.118308,-0.128985,-0.058177,-0.220992,-0.127845,-0.065619,-0.23578,-0.127797,-0.08389,-0.242822,-0.138307,-0.342148,-0.301696,-0.104387,-0.353222,-0.353394,-0.111094,-0.353756,-0.407387,-0.103336,-0.10313,-0.509513,-0.127915,-0.048685,-0.501685,-0.128229,0.001772,-0.48631,-0.128092,-0.223852,-0.25286,-0.129595,-0.265892,-0.250564,-0.121836,-0.303186,-0.256097,-0.107268,0.089036,-0.431922,-0.127806,0.124895,-0.394124,-0.127955,0.154869,-0.351206,-0.128247,-0.058214,-0.079275,-0.133072,-0.058982,-0.138142,-0.134877,-0.060256,-0.174594,-0.136142,-0.008016,-0.221996,-0.171854,0.057788,-0.251162,-0.181137,0.123593,-0.280327,-0.166267,-0.322036,-0.46837,-0.104783,-0.278603,-0.489708,-0.118242,-0.222303,-0.503519,-0.124587,-0.106126,-0.266465,-0.128186,-0.128435,-0.259752,-0.137282,-0.152524,-0.260072,-0.135801,-0.178661,-0.315103,-0.167712,-0.172478,-0.383905,-0.177366,-0.166296,-0.452706,-0.163372,-0.034134,0.40894,0.105997,-0.048349,0.284277,0.120017,-0.054932,0.141954,0.127213,0.004376,0.005646,0.165335,0.078192,-0.000864,0.176149,0.152007,-0.007374,0.163476,0.21263,0.128344,0.125403,0.2062,0.27695,0.11889,0.191531,0.404851,0.10528,0.134485,0.520782,0.103491,0.07827,0.538675,0.110894,0.022166,0.522365,0.103795,-0.061232,-0.303312,0.159179,-0.023133,-0.358742,0.16722,0.015209,-0.414959,0.165867,0.19505,-0.255864,0.129105,0.205755,-0.196543,0.129322,0.21157,-0.118308,0.128985,-0.058177,-0.220992,0.127845,-0.065619,-0.23578,0.127797,-0.08389,-0.242822,0.138307,-0.342148,-0.301696,0.104387,-0.353222,-0.353394,0.111094,-0.353756,-0.407387,0.103336,-0.10313,-0.509513,0.127915,-0.048685,-0.501685,0.128229,0.001772,-0.48631,0.128092,-0.223852,-0.25286,0.129595,-0.265892,-0.250564,0.121836,-0.303186,-0.256097,0.107268,0.089036,-0.431922,0.127806,0.124895,-0.394124,0.127955,0.154869,-0.351206,0.128247,-0.058214,-0.079275,0.133072,-0.058982,-0.138142,0.134877,-0.060256,-0.174594,0.136142,-0.008016,-0.221996,0.171854,0.057788,-0.251162,0.181137,0.123593,-0.280327,0.166267,-0.322036,-0.46837,0.104783,-0.278603,-0.489708,0.118242,-0.222303,-0.503519,0.124587,-0.106126,-0.266465,0.128186,-0.128435,-0.259752,0.137282,-0.152524,-0.260072,0.135801,-0.178661,-0.315103,0.167712,-0.172478,-0.383905,0.177366,-0.166295,-0.452706,0.163372,-0.094044,0.014326,-0.071389,-0.106347,0.015411,0,-0.094044,0.014326,0.071389,-0.032452,0.522959,0.052705,-0.040274,0.540027,-0,-0.032452,0.522959,-0.052705,-0.360267,-0.458795,-0.052161,-0.367041,-0.464967,0,-0.360267,-0.458795,0.052161,-0.335637,-0.250287,0.053213,-0.339403,-0.241821,0,-0.335637,-0.250287,-0.053213,-0.186904,-0.223367,-0.073117,-0.187935,-0.2119,0,-0.186904,-0.223367,0.073117,-0.110863,-0.235041,0.071309,-0.117536,-0.226304,0,-0.110863,-0.235041,-0.071309,-0.095755,-0.183108,-0.075248,-0.106722,-0.178247,-0,-0.095755,-0.183108,0.075248,0.067386,-0.492046,-0.069097,0.073908,-0.501682,0,0.067386,-0.492046,0.069097,-0.158052,-0.544442,0.068776,-0.157022,-0.555909,0,-0.158052,-0.544442,-0.068776,0.250428,-0.016054,-0.06953,0.26273,-0.017139,0,0.250428,-0.016054,0.06953,0.211332,-0.319215,0.069661,0.222299,-0.324076,0,0.211332,-0.319215,-0.069661,0.189103,0.520189,-0.052402,0.196813,0.537323,-0,0.189103,0.520189,0.052402,-0.057136,0.011071,-0.13057,0.21352,-0.012799,-0.127782,-0.016464,0.488331,-0.089048,0.17334,0.485517,-0.088583,-0.091897,-0.260461,-0.128054,0.047819,-0.463138,-0.127838,-0.327808,-0.26757,-0.089867,-0.34674,-0.446161,-0.088253,0.17843,-0.304632,-0.128643,-0.062853,-0.197691,-0.137024,-0.161143,-0.510041,-0.126813,-0.183813,-0.257768,-0.133324,-0.016464,0.488331,0.089048,-0.057136,0.011071,0.13057,0.21352,-0.012799,0.127782,0.17334,0.485517,0.088583,-0.091897,-0.260461,0.128054,0.047819,-0.463138,0.127838,0.17843,-0.304632,0.128643,-0.062853,-0.197691,0.137024,-0.327808,-0.26757,0.089867,-0.34674,-0.446161,0.088253,-0.161143,-0.510041,0.126813,-0.183813,-0.257768,0.133324], 6 | "metadata":{ 7 | "faces":352, 8 | "normals":354, 9 | "version":3, 10 | "vertices":354, 11 | "uvs":0, 12 | "generator":"io_three", 13 | "type":"Geometry" 14 | }, 15 | "uvs":[] 16 | } -------------------------------------------------------------------------------- /public/assets/letters/V.json: -------------------------------------------------------------------------------- 1 | { 2 | "faces":[33,0,4,5,1,0,1,2,3,33,1,5,214,213,3,2,4,5,33,4,219,220,5,1,6,7,2,33,5,220,315,214,2,7,8,4,33,0,1,6,2,0,3,9,10,33,2,6,196,195,10,9,11,12,33,1,213,212,6,3,5,13,9,33,6,212,310,196,9,13,14,11,33,0,2,7,3,0,10,15,16,33,3,7,193,192,16,15,17,18,33,2,195,194,7,10,12,19,15,33,7,194,311,193,15,19,20,17,33,0,3,8,4,0,16,21,1,33,4,8,218,219,1,21,22,6,33,3,192,191,8,16,18,23,21,33,8,191,316,218,21,23,24,22,33,9,12,13,10,25,26,27,28,33,10,13,208,207,28,27,29,30,33,12,189,190,13,26,31,32,27,33,13,190,309,208,27,32,33,29,33,9,10,14,11,25,28,34,35,33,11,14,199,198,35,34,36,37,33,10,207,206,14,28,30,38,34,33,14,206,312,199,34,38,39,36,33,9,11,15,12,25,35,40,26,33,12,15,188,189,26,40,41,31,33,11,198,197,15,35,37,42,40,33,15,197,308,188,40,42,43,41,33,16,20,21,17,44,45,46,47,33,17,21,226,225,47,46,48,49,33,20,228,229,21,45,50,51,46,33,21,229,318,226,46,51,52,48,33,16,17,22,18,44,47,53,54,33,18,22,202,201,54,53,55,56,33,17,225,224,22,47,49,57,53,33,22,224,314,202,53,57,58,55,33,16,18,23,19,44,54,59,60,33,19,23,205,204,60,59,61,62,33,18,201,200,23,54,56,63,59,33,23,200,313,205,59,63,64,61,33,16,19,24,20,44,60,65,45,33,20,24,227,228,45,65,66,50,33,19,204,203,24,60,62,67,65,33,24,203,317,227,65,67,68,66,33,25,29,30,26,69,70,71,72,33,26,30,187,186,72,71,73,74,33,29,189,188,30,70,31,41,71,33,30,188,308,187,71,41,43,73,33,25,26,31,27,69,72,75,76,33,27,31,220,219,76,75,7,6,33,26,186,185,31,72,74,77,75,33,31,185,315,220,75,77,8,7,33,25,27,32,28,69,76,78,79,33,28,32,217,216,79,78,80,81,33,27,219,218,32,76,6,22,78,33,32,218,316,217,78,22,24,80,33,25,28,33,29,69,79,82,70,33,29,33,190,189,70,82,32,31,33,28,216,215,33,79,81,83,82,33,33,215,309,190,82,83,33,32,33,34,38,39,35,84,85,86,87,33,35,39,211,210,87,86,88,89,33,38,207,208,39,85,30,29,86,33,39,208,309,211,86,29,33,88,33,34,35,40,36,84,87,90,91,33,36,40,229,228,91,90,51,50,33,35,210,209,40,87,89,92,90,33,40,209,318,229,90,92,52,51,33,34,36,41,37,84,91,93,94,33,37,41,223,222,94,93,95,96,33,36,228,227,41,91,50,66,93,33,41,227,317,223,93,66,68,95,33,34,37,42,38,84,94,97,85,33,38,42,206,207,85,97,38,30,33,37,222,221,42,94,96,98,97,33,42,221,312,206,97,98,39,38,33,43,47,48,44,99,100,101,102,33,44,48,265,264,102,101,103,104,33,47,258,259,48,100,105,106,101,33,48,259,319,265,101,106,107,103,33,43,44,49,45,99,102,108,109,33,45,49,236,237,109,108,110,111,33,44,264,263,49,102,104,112,108,33,49,263,322,236,108,112,113,110,33,43,45,50,46,99,109,114,115,33,46,50,239,240,115,114,116,117,33,45,237,238,50,109,111,118,114,33,50,238,323,239,114,118,119,116,33,43,46,51,47,99,115,120,100,33,47,51,257,258,100,120,121,105,33,46,240,241,51,115,117,122,120,33,51,241,324,257,120,122,123,121,33,52,55,56,53,124,125,126,127,33,53,56,235,234,127,126,128,129,33,55,252,253,56,125,130,131,126,33,56,253,321,235,126,131,132,128,33,52,53,57,54,124,127,133,134,33,54,57,242,243,134,133,135,136,33,53,234,233,57,127,129,137,133,33,57,233,320,242,133,137,138,135,33,52,54,58,55,124,134,139,125,33,55,58,251,252,125,139,140,130,33,54,243,244,58,134,136,141,139,33,58,244,325,251,139,141,142,140,33,59,63,64,60,143,144,145,146,33,60,64,274,273,146,145,147,148,33,63,270,271,64,144,149,150,145,33,64,271,329,274,145,150,151,147,33,59,60,65,61,143,146,152,153,33,61,65,248,249,153,152,154,155,33,60,273,272,65,146,148,156,152,33,65,272,328,248,152,156,157,154,33,59,61,66,62,143,153,158,159,33,62,66,245,246,159,158,160,161,33,61,249,250,66,153,155,162,158,33,66,250,326,245,158,162,163,160,33,59,62,67,63,143,159,164,144,33,63,67,269,270,144,164,165,149,33,62,246,247,67,159,161,166,164,33,67,247,327,269,164,166,167,165,33,68,72,73,69,168,169,170,171,33,69,73,233,234,171,170,137,129,33,72,231,232,73,169,172,173,170,33,73,232,320,233,170,173,138,137,33,68,69,74,70,168,171,174,175,33,70,74,260,261,175,174,176,177,33,69,234,235,74,171,129,128,174,33,74,235,321,260,174,128,132,176,33,68,70,75,71,168,175,178,179,33,71,75,263,264,179,178,112,104,33,70,261,262,75,175,177,180,178,33,75,262,322,263,178,180,113,112,33,68,71,76,72,168,179,181,169,33,72,76,230,231,169,181,182,172,33,71,264,265,76,179,104,103,181,33,76,265,319,230,181,103,107,182,33,77,81,82,78,183,184,185,186,33,78,82,253,252,186,185,131,130,33,81,255,256,82,184,187,188,185,33,82,256,321,253,185,188,132,131,33,77,78,83,79,183,186,189,190,33,79,83,266,267,190,189,191,192,33,78,252,251,83,186,130,140,189,33,83,251,325,266,189,140,142,191,33,77,79,84,80,183,190,193,194,33,80,84,272,273,194,193,156,148,33,79,267,268,84,190,192,195,193,33,84,268,328,272,193,195,157,156,33,77,80,85,81,183,194,196,184,33,81,85,254,255,184,196,197,187,33,80,273,274,85,194,148,147,196,33,85,274,329,254,196,147,151,197,33,86,90,91,87,198,199,200,201,33,87,91,185,186,201,200,77,74,33,90,279,280,91,199,202,203,200,33,91,280,315,185,200,203,8,77,33,86,87,92,88,198,201,204,205,33,88,92,275,276,205,204,206,207,33,87,186,187,92,201,74,73,204,33,92,187,308,275,204,73,43,206,33,86,88,93,89,198,205,208,209,33,89,93,232,231,209,208,173,172,33,88,276,277,93,205,207,210,208,33,93,277,320,232,208,210,138,173,33,86,89,94,90,198,209,211,199,33,90,94,278,279,199,211,212,202,33,89,231,230,94,209,172,182,211,33,94,230,319,278,211,182,107,212,33,95,99,100,96,213,214,215,216,33,96,100,197,198,216,215,42,37,33,99,276,275,100,214,207,206,215,33,100,275,308,197,215,206,43,42,33,95,96,101,97,213,216,217,218,33,97,101,281,282,218,217,219,220,33,96,198,199,101,216,37,36,217,33,101,199,312,281,217,36,39,219,33,95,97,102,98,213,218,221,222,33,98,102,244,243,222,221,141,136,33,97,282,283,102,218,220,223,221,33,102,283,325,244,221,223,142,141,33,95,98,103,99,213,222,224,214,33,99,103,277,276,214,224,210,207,33,98,243,242,103,222,136,135,224,33,103,242,320,277,224,135,138,210,33,104,108,109,105,225,226,227,228,33,105,109,209,210,228,227,92,89,33,108,288,289,109,226,229,230,227,33,109,289,318,209,227,230,52,92,33,104,105,110,106,225,228,231,232,33,106,110,284,285,232,231,233,234,33,105,210,211,110,228,89,88,231,33,110,211,309,284,231,88,33,233,33,104,106,111,107,225,232,235,236,33,107,111,256,255,236,235,188,187,33,106,285,286,111,232,234,237,235,33,111,286,321,256,235,237,132,188,33,104,107,112,108,225,236,238,226,33,108,112,287,288,226,238,239,229,33,107,255,254,112,236,187,197,238,33,112,254,329,287,238,197,151,239,33,113,117,118,114,240,241,242,243,33,114,118,200,201,243,242,63,56,33,117,294,295,118,241,244,245,242,33,118,295,313,200,242,245,64,63,33,113,114,119,115,240,243,246,247,33,115,119,290,291,247,246,248,249,33,114,201,202,119,243,56,55,246,33,119,202,314,290,246,55,58,248,33,113,115,120,116,240,247,250,251,33,116,120,247,246,251,250,166,161,33,115,291,292,120,247,249,252,250,33,120,292,327,247,250,252,167,166,33,113,116,121,117,240,251,253,241,33,117,121,293,294,241,253,254,244,33,116,246,245,121,251,161,160,253,33,121,245,326,293,253,160,163,254,33,122,126,127,123,255,256,257,258,33,123,127,221,222,258,257,98,96,33,126,282,281,127,256,220,219,257,33,127,281,312,221,257,219,39,98,33,122,123,128,124,255,258,259,260,33,124,128,296,297,260,259,261,262,33,123,222,223,128,258,96,95,259,33,128,223,317,296,259,95,68,261,33,122,124,129,125,255,260,263,264,33,125,129,268,267,264,263,195,192,33,124,297,298,129,260,262,265,263,33,129,298,328,268,263,265,157,195,33,122,125,130,126,255,264,266,256,33,126,130,283,282,256,266,223,220,33,125,267,266,130,264,192,191,266,33,130,266,325,283,266,191,142,223,33,131,135,136,132,267,268,269,270,33,132,136,191,192,270,269,23,18,33,135,303,304,136,268,271,272,269,33,136,304,316,191,269,272,24,23,33,131,132,137,133,267,270,273,274,33,133,137,299,300,274,273,275,276,33,132,192,193,137,270,18,17,273,33,137,193,311,299,273,17,20,275,33,131,133,138,134,267,274,277,278,33,134,138,238,237,278,277,118,111,33,133,300,301,138,274,276,279,277,33,138,301,323,238,277,279,119,118,33,131,134,139,135,267,278,280,268,33,135,139,302,303,268,280,281,271,33,134,237,236,139,278,111,110,280,33,139,236,322,302,280,110,113,281,33,140,144,145,141,282,283,284,285,33,141,145,212,213,285,284,13,5,33,144,306,307,145,283,286,287,284,33,145,307,310,212,284,287,14,13,33,140,141,146,142,282,285,288,289,33,142,146,280,279,289,288,203,202,33,141,213,214,146,285,5,4,288,33,146,214,315,280,288,4,8,203,33,140,142,147,143,282,289,290,291,33,143,147,259,258,291,290,106,105,33,142,279,278,147,289,202,212,290,33,147,278,319,259,290,212,107,106,33,140,143,148,144,282,291,292,283,33,144,148,305,306,283,292,293,286,33,143,258,257,148,291,105,121,292,33,148,257,324,305,292,121,123,293,33,149,153,154,150,294,295,296,297,33,150,154,203,204,297,296,67,62,33,153,297,296,154,295,262,261,296,33,154,296,317,203,296,261,68,67,33,149,150,155,151,294,297,298,299,33,151,155,295,294,299,298,245,244,33,150,204,205,155,297,62,61,298,33,155,205,313,295,298,61,64,245,33,149,151,156,152,294,299,300,301,33,152,156,250,249,301,300,162,155,33,151,294,293,156,299,244,254,300,33,156,293,326,250,300,254,163,162,33,149,152,157,153,294,301,302,295,33,153,157,298,297,295,302,265,262,33,152,249,248,157,301,155,154,302,33,157,248,328,298,302,154,157,265,33,158,162,163,159,303,304,305,306,33,159,163,224,225,306,305,57,49,33,162,291,290,163,304,249,248,305,33,163,290,314,224,305,248,58,57,33,158,159,164,160,303,306,307,308,33,160,164,289,288,308,307,230,229,33,159,225,226,164,306,49,48,307,33,164,226,318,289,307,48,52,230,33,158,160,165,161,303,308,309,310,33,161,165,271,270,310,309,150,149,33,160,288,287,165,308,229,239,309,33,165,287,329,271,309,239,151,150,33,158,161,166,162,303,310,311,304,33,162,166,292,291,304,311,252,249,33,161,270,269,166,310,149,165,311,33,166,269,327,292,311,165,167,252,33,167,171,172,168,312,313,314,315,33,168,172,194,195,315,314,19,12,33,171,300,299,172,313,276,275,314,33,172,299,311,194,314,275,20,19,33,167,168,173,169,312,315,316,317,33,169,173,307,306,317,316,287,286,33,168,195,196,173,315,12,11,316,33,173,196,310,307,316,11,14,287,33,167,169,174,170,312,317,318,319,33,170,174,241,240,319,318,122,117,33,169,306,305,174,317,286,293,318,33,174,305,324,241,318,293,123,122,33,167,170,175,171,312,319,320,313,33,171,175,301,300,313,320,279,276,33,170,240,239,175,319,117,116,320,33,175,239,323,301,320,116,119,279,33,176,180,181,177,321,322,323,324,33,177,181,215,216,324,323,83,81,33,180,285,284,181,322,234,233,323,33,181,284,309,215,323,233,33,83,33,176,177,182,178,321,324,325,326,33,178,182,304,303,326,325,272,271,33,177,216,217,182,324,81,80,325,33,182,217,316,304,325,80,24,272,33,176,178,183,179,321,326,327,328,33,179,183,262,261,328,327,180,177,33,178,303,302,183,326,271,281,327,33,183,302,322,262,327,281,113,180,33,176,179,184,180,321,328,329,322,33,180,184,286,285,322,329,237,234,33,179,261,260,184,328,177,176,329,33,184,260,321,286,329,176,132,237], 3 | "normals":[-0.038942,-0.98413,-0.17304,-0.025971,-0.997955,-0.058016,-0.339183,-0.940123,0.033418,-0.348735,-0.933103,-0.087649,-0.675924,-0.72396,0.1377,-0.685507,-0.728019,0.00473,-0.030854,-0.999298,-0.020264,-0.353099,-0.932401,0.076754,-0.682455,-0.706992,0.185369,-0.371075,-0.864528,-0.338878,-0.071352,-0.902402,-0.424879,-0.391156,-0.653645,-0.647816,-0.10715,-0.663076,-0.740806,-0.677236,-0.689779,-0.255867,-0.608966,-0.595386,-0.524064,0.221168,-0.838008,-0.498795,0.271249,-0.92645,-0.260903,0.503708,-0.647359,-0.571947,0.607959,-0.713675,-0.34785,0.16895,-0.611133,-0.773247,0.371288,-0.532273,-0.760765,0.297189,-0.944487,-0.140019,0.312326,-0.944334,-0.103183,0.656667,-0.723106,-0.214209,0.685018,-0.708701,-0.168645,-0.00177,-0.958953,0.283486,-0.170598,-0.968108,0.183447,-0.000549,-0.999786,0.019135,0.167455,-0.967681,0.188421,-0.016053,-0.996765,-0.078738,0.206763,-0.973937,0.093204,-0.20838,-0.974181,0.086764,0.016144,-0.996796,-0.078066,0.002258,-0.957549,-0.288156,0.392956,-0.802026,0.449782,-0.003906,-0.800287,0.599567,0.526017,-0.503586,0.685324,-0.006165,-0.509293,0.86053,0.495987,-0.820887,0.283029,0.70922,-0.536424,0.457381,-0.400128,-0.804224,0.439436,-0.500595,-0.823084,0.268105,-0.537736,-0.507035,0.673574,-0.718711,-0.540086,0.437849,0.041688,-0.984771,-0.168676,0.027253,-0.998016,-0.056337,-0.296457,-0.943388,-0.148595,-0.269173,-0.925596,-0.265999,-0.65389,-0.719535,-0.233772,-0.603748,-0.710105,-0.362194,0.031526,-0.999298,-0.019135,-0.312052,-0.943297,-0.113102,-0.68273,-0.705405,-0.190283,-0.217597,-0.839534,-0.497787,0.076968,-0.906339,-0.415448,-0.16419,-0.616627,-0.769921,0.116916,-0.671987,-0.731254,-0.49913,-0.645741,-0.577776,-0.368358,-0.534257,-0.760826,0.379315,-0.868343,-0.319468,0.352275,-0.932981,-0.073519,0.686026,-0.691488,-0.226264,0.687307,-0.725761,0.028871,0.406446,-0.663289,-0.628346,0.626362,-0.602863,-0.494125,0.340739,-0.939085,0.044801,0.35374,-0.931181,0.087954,0.674886,-0.720664,0.158513,0.680166,-0.703543,0.205817,-0.096988,-0.995239,0.009156,-0.158483,-0.986633,0.037202,-0.476699,-0.860408,0.179998,-0.429395,-0.89346,0.131596,-0.741081,-0.593005,0.314737,-0.724479,-0.641591,0.25193,-0.385479,-0.917234,0.100314,-0.053133,-0.998535,-0.006561,-0.701895,-0.679617,0.21305,0.316141,-0.943297,-0.101108,0.291147,-0.950133,-0.111576,0.70629,-0.687124,-0.170171,0.70922,-0.673879,-0.206915,0.17893,-0.97702,-0.115635,0.612018,-0.729026,-0.306406,0.097018,-0.995178,0.012146,0.157903,-0.986541,0.042116,-0.178167,-0.97644,-0.121494,-0.290414,-0.949187,-0.121036,-0.606342,-0.725852,-0.324717,-0.705191,-0.670919,-0.229255,-0.315744,-0.942259,-0.111362,0.053499,-0.998535,-0.004913,-0.703513,-0.684011,-0.192694,0.385357,-0.91586,0.11243,0.428327,-0.891903,0.144993,0.698508,-0.676199,0.234107,0.719657,-0.638142,0.273507,0.474227,-0.858577,0.194739,0.734336,-0.589526,0.336375,-0.038942,0.98413,-0.17304,-0.348735,0.933103,-0.087649,-0.339183,0.940123,0.033418,-0.025971,0.997955,-0.058016,-0.353099,0.932401,0.076754,-0.030854,0.999298,-0.020264,-0.685507,0.728019,0.00473,-0.675924,0.72396,0.1377,-0.682455,0.706992,0.185369,0.297189,0.944487,-0.140019,0.271249,0.92645,-0.260903,0.656667,0.723106,-0.214209,0.607959,0.713675,-0.34785,0.312326,0.944334,-0.103183,0.685018,0.708701,-0.168645,0.221168,0.838008,-0.498795,-0.071352,0.902402,-0.424879,0.16895,0.611133,-0.773247,-0.10715,0.663076,-0.740806,0.503708,0.647359,-0.571947,0.371288,0.532273,-0.760765,-0.371075,0.864528,-0.338878,-0.677236,0.689779,-0.255867,-0.391156,0.653645,-0.647816,-0.608966,0.595386,-0.524064,-0.00177,0.958953,0.283486,0.167455,0.967681,0.188421,-0.000549,0.999786,0.019135,-0.170598,0.968108,0.183447,0.016144,0.996796,-0.078066,-0.20838,0.974181,0.086764,0.206763,0.973937,0.093204,-0.016053,0.996765,-0.078738,0.002258,0.957549,-0.288156,-0.400128,0.804224,0.439436,-0.003906,0.800287,0.599567,-0.537736,0.507035,0.673574,-0.006165,0.509293,0.86053,-0.500595,0.823084,0.268105,-0.718711,0.540086,0.437849,0.392956,0.802026,0.449782,0.495987,0.820887,0.283029,0.526017,0.503586,0.685324,0.70922,0.536424,0.457381,0.041688,0.984771,-0.168676,-0.269173,0.925596,-0.265999,-0.296487,0.943388,-0.148595,0.027253,0.998016,-0.056337,-0.312052,0.943297,-0.113102,0.031526,0.999298,-0.019135,-0.603748,0.710105,-0.362194,-0.65389,0.719535,-0.233772,-0.68273,0.705405,-0.190283,0.340739,0.939085,0.044801,0.352275,0.932981,-0.073519,0.674886,0.720664,0.158513,0.687307,0.725761,0.028871,0.35374,0.931181,0.087954,0.680166,0.703543,0.205817,0.379315,0.868343,-0.319468,0.076968,0.906339,-0.415448,0.406446,0.663289,-0.628346,0.116916,0.671987,-0.731254,0.686026,0.691488,-0.226264,0.626362,0.602863,-0.494125,-0.217597,0.839534,-0.497787,-0.49913,0.645741,-0.577776,-0.16419,0.616627,-0.769921,-0.368358,0.534257,-0.760826,-0.096988,0.995239,0.009156,-0.429395,0.89346,0.131596,-0.476699,0.860408,0.179998,-0.158483,0.986633,0.037202,-0.724479,0.641591,0.25193,-0.741081,0.593005,0.314737,0.17893,0.97702,-0.115635,0.291147,0.950133,-0.111576,0.612018,0.729026,-0.306406,0.70922,0.673879,-0.206915,0.316141,0.943297,-0.101108,-0.053133,0.998535,-0.006561,0.70629,0.687124,-0.170171,-0.385479,0.917234,0.100314,-0.701895,0.679617,0.21305,0.097018,0.995178,0.012146,-0.290414,0.949187,-0.121036,-0.178167,0.97644,-0.121494,0.157903,0.986541,0.042116,-0.705191,0.670919,-0.229255,-0.606342,0.725852,-0.324717,0.474227,0.858577,0.194739,0.428327,0.891903,0.144993,0.734336,0.589526,0.336375,0.719657,0.638142,0.273507,0.385357,0.91586,0.11243,0.053499,0.998535,-0.004913,0.698508,0.676199,0.234107,-0.315744,0.942259,-0.111362,-0.703513,0.684011,-0.192694,-0.937315,0,0.34846,-0.95114,0,0.308756,-0.898007,-0.333079,0.287362,-0.893277,-0.308237,0.327128,-0.959197,0,0.282662,-0.898953,-0.352062,0.260598,-0.87579,-0.27842,0.394238,-0.909055,0,0.416639,-0.809992,-0.248238,0.531236,-0.830164,0,0.557451,-0.87579,0.27842,0.394238,-0.893277,0.308237,0.327128,-0.809992,0.248238,0.531236,-0.898007,0.333079,0.287362,-0.898953,0.352062,0.260598,-0.006897,0,0.999969,-0.582904,0,0.812494,-0.577166,-0.22956,0.783654,-0.006806,-0.229102,0.973357,0.563005,-0.227454,0.794519,0.568133,0,0.822901,0.797052,-0.245827,0.551592,0.816187,0,0.577776,0.563005,0.227454,0.794519,-0.006806,0.229102,0.973357,0.797052,0.245827,0.551592,-0.577166,0.22956,0.783654,-0.966521,0,-0.256569,-0.975707,0,-0.219062,-0.924741,-0.311258,-0.218909,-0.922758,-0.285134,-0.259163,-0.973724,0,-0.227699,-0.914335,-0.337687,-0.223395,-0.857997,-0.30549,-0.412854,-0.908719,0,-0.417341,0.008759,-0.59508,-0.803583,0.012177,0,-0.999908,-0.857997,0.30549,-0.412854,-0.922758,0.285134,-0.259163,0.008759,0.59508,-0.803583,-0.924741,0.311258,-0.218909,-0.914335,0.337687,-0.223395,0.134251,0,-0.990936,0.453322,0,-0.891324,0.436201,-0.350902,-0.828578,0.13303,-0.333384,-0.933317,0.79754,0,-0.603229,0.740013,-0.362285,-0.566637,-0.150731,-0.309488,-0.938871,-0.153111,0,-0.988189,-0.430219,-0.305673,-0.849361,-0.458693,0,-0.888577,-0.150731,0.309488,-0.938871,0.13303,0.333384,-0.933317,-0.430219,0.305673,-0.849361,0.436201,0.350902,-0.828578,0.740013,0.362285,-0.566637,0.927091,0,0.374767,0.897275,0,0.44142,0.865261,-0.275887,0.418561,0.884487,-0.30549,0.35258,0.890469,-0.330119,0.31315,0.941984,0,0.335643,0.892331,-0.348918,0.286294,0.950835,0,0.30961,0.890469,0.330119,0.31315,0.884487,0.30549,0.35258,0.892331,0.348918,0.286294,0.865261,0.275887,0.418561,0.913327,0,-0.407178,0.965941,0,-0.258736,0.898892,-0.358562,-0.251717,0.84344,-0.362651,-0.396283,0.980407,0,-0.196905,0.919828,-0.340617,-0.194525,0.695547,-0.338755,-0.633564,0.75338,0,-0.657552,0.434248,-0.304849,-0.847621,0.463424,0,-0.886105,0.695547,0.338755,-0.633564,0.84344,0.362651,-0.396283,0.434248,0.304849,-0.847621,0.898892,0.358562,-0.251717,0.919828,0.340617,-0.194525,-0.994781,0,0.101993,-0.977325,0,-0.211707,-0.901395,-0.375347,-0.215735,-0.923185,-0.376385,0.077425,-0.773644,0,-0.633595,-0.718345,-0.3567,-0.597217,-0.906064,-0.365337,0.213385,-0.971679,0,0.236274,-0.906064,0.365337,0.213385,-0.923185,0.376385,0.077425,-0.901395,0.375347,-0.215735,-0.718345,0.3567,-0.597217,0.990936,0,0.13422,0.964476,0,0.264077,0.900723,-0.362133,0.239814,0.921171,-0.373821,0.107944,0.909177,-0.375896,-0.179022,0.984954,0,-0.172735,0.909177,0.375896,-0.179022,0.921171,0.373821,0.107944,0.900723,0.362133,0.239814,-0.903256,0,-0.42909,-0.744316,0,-0.667806,-0.687979,-0.336467,-0.642994,-0.8352,-0.358989,-0.416517,-0.892392,-0.355174,-0.278329,-0.957823,0,-0.287271,-0.892392,0.355174,-0.278329,-0.8352,0.358989,-0.416517,-0.687979,0.336467,-0.642994,-0.121342,0,-0.992584,0.158544,0,-0.987335,0.156133,-0.305277,-0.93936,-0.12067,-0.326029,-0.93759,-0.415235,-0.342631,-0.842677,-0.429945,0,-0.902829,-0.415235,0.342631,-0.842677,-0.12067,0.326029,-0.93759,0.156133,0.305277,-0.93936,0.97412,0,-0.22602,0.920316,0,-0.391125,0.868557,-0.308267,-0.387982,0.929746,-0.287362,-0.230079,0.930387,-0.313791,-0.189428,0.982177,0,-0.187872,0.930387,0.313791,-0.189428,0.929746,0.287362,-0.230079,0.868557,0.308267,-0.387982], 4 | "name":"Plane.011Geometry", 5 | "vertices":[-0.308158,0.374693,-0.13747,-0.367417,0.36275,-0.127945,-0.323207,0.433014,-0.121405,-0.248491,0.385071,-0.128698,-0.286556,0.290116,-0.145707,-0.346917,0.27522,-0.135322,-0.376025,0.421484,-0.113155,-0.268758,0.43828,-0.113599,-0.226195,0.305012,-0.136664,-0.00923,-0.531646,-0.154598,0.024378,-0.502501,-0.160062,-0.009924,-0.575714,-0.139448,-0.041917,-0.502147,-0.160025,-0.007877,-0.44642,-0.16572,0.043001,-0.545388,-0.140546,-0.061913,-0.544823,-0.140493,0.318491,0.373043,-0.1375,0.259645,0.384302,-0.128752,0.335586,0.432312,-0.121438,0.376872,0.360183,-0.127947,0.294021,0.287609,-0.145735,0.234633,0.303522,-0.136708,0.281735,0.438245,-0.113652,0.387578,0.419978,-0.113163,0.353409,0.271697,-0.135331,-0.177889,-0.132811,-0.156744,-0.223221,-0.165123,-0.142248,-0.220618,0.028159,-0.153532,-0.131582,-0.099298,-0.150987,-0.131824,-0.287216,-0.159377,-0.169372,-0.325908,-0.14267,-0.27289,0.002401,-0.140862,-0.168345,0.053917,-0.145731,-0.090376,-0.243718,-0.157424,0.171834,-0.135199,-0.156811,0.126863,-0.100919,-0.151032,0.219622,0.025253,-0.15358,0.21587,-0.168268,-0.142328,0.120957,-0.288871,-0.159456,0.081056,-0.244792,-0.157471,0.168543,0.051953,-0.145768,0.270701,-0.001447,-0.140915,0.157114,-0.328107,-0.142766,-0.308158,0.374693,0.13747,-0.286556,0.290116,0.145707,-0.248491,0.385071,0.128698,-0.323207,0.433014,0.121405,-0.367417,0.36275,0.127945,-0.346917,0.27522,0.135322,-0.226195,0.305012,0.136664,-0.268758,0.43828,0.113599,-0.376025,0.421484,0.113155,-0.00923,-0.531647,0.154598,-0.041917,-0.502147,0.160025,-0.009924,-0.575714,0.139448,0.024378,-0.502501,0.160062,-0.007877,-0.44642,0.16572,-0.061913,-0.544823,0.140493,0.043001,-0.545388,0.140546,0.318491,0.373043,0.1375,0.294021,0.287609,0.145735,0.376872,0.360183,0.127947,0.335586,0.432312,0.121438,0.259645,0.384302,0.128752,0.234633,0.303522,0.136708,0.353409,0.271697,0.135331,0.387578,0.419978,0.113163,0.281735,0.438245,0.113652,-0.177889,-0.132811,0.156744,-0.131824,-0.287216,0.159377,-0.131582,-0.099298,0.150987,-0.220618,0.028159,0.153532,-0.223221,-0.165123,0.142248,-0.169372,-0.325908,0.14267,-0.090376,-0.243718,0.157424,-0.168345,0.053917,0.145731,-0.27289,0.002401,0.140862,0.171834,-0.135199,0.156811,0.120957,-0.288871,0.159456,0.21587,-0.168268,0.142328,0.219622,0.025253,0.15358,0.126863,-0.100919,0.151032,0.081056,-0.244792,0.157471,0.157114,-0.328107,0.142766,0.270701,-0.001447,0.140915,0.168543,0.051953,0.145768,-0.290488,-0.212689,0,-0.283014,-0.207404,-0.058814,-0.222772,-0.380341,0,-0.283014,-0.207404,0.058814,-0.351299,-0.036236,0,-0.342587,-0.031943,-0.058979,-0.216838,-0.374293,-0.058316,-0.216838,-0.374293,0.058316,-0.342587,-0.031943,0.058979,-0.010737,-0.626971,0,-0.010647,-0.621276,-0.056714,0.060713,-0.599823,0,-0.010647,-0.621276,0.056714,-0.081374,-0.599049,0,-0.079212,-0.593024,-0.057021,0.058745,-0.593775,-0.057051,0.058745,-0.593775,0.057051,-0.079212,-0.593024,0.057021,0.061299,-0.043148,0,0.068007,-0.050777,-0.067561,0.028778,-0.153272,0,0.068007,-0.050777,0.067561,0.091925,0.092002,-0,0.100438,0.087552,-0.063858,0.03228,-0.168279,-0.073074,0.03228,-0.168279,0.073074,0.100438,0.087552,0.063858,0.355762,0.501823,-0,0.353506,0.494048,-0.050731,0.297296,0.501175,-0,0.353506,0.494048,0.050731,0.409715,0.486922,-0,0.403778,0.479757,-0.047339,0.298985,0.493706,-0.04749,0.298985,0.493706,0.04749,0.403778,0.479757,0.047339,0.281221,-0.216964,0,0.27396,-0.211554,-0.058857,0.347319,-0.041497,0,0.27396,-0.211554,0.058857,0.208542,-0.383328,0,0.202828,-0.377192,-0.058369,0.338806,-0.037047,-0.059006,0.338806,-0.037047,0.059006,0.202828,-0.377192,0.058369,-0.159449,0.402314,-0,-0.169172,0.399764,-0.055389,-0.188921,0.452881,-0,-0.169172,0.399764,0.055389,-0.135655,0.327356,-0,-0.145715,0.324874,-0.058954,-0.197112,0.448726,-0.048883,-0.197112,0.448726,0.048883,-0.145715,0.324874,0.058954,-0.456867,0.347073,-0,-0.446735,0.348057,-0.054636,-0.437457,0.252876,-0,-0.446735,0.348057,0.054636,-0.457494,0.413147,-0,-0.447671,0.411038,-0.048439,-0.427397,0.255359,-0.057612,-0.427397,0.255359,0.057612,-0.447671,0.411038,0.048439,0.465086,0.343197,-0,0.455064,0.344305,-0.054622,0.468134,0.410691,-0,0.455064,0.344305,0.054622,0.442492,0.247828,-0,0.432594,0.250481,-0.057605,0.458303,0.408608,-0.048429,0.458303,0.408608,0.048429,0.432594,0.250481,0.057605,0.171897,0.402889,-0,0.181453,0.40018,-0.055427,0.145551,0.32739,-0,0.181453,0.40018,0.055427,0.203037,0.453934,-0,0.211009,0.449615,-0.048918,0.155449,0.324738,-0.058983,0.155449,0.324738,0.058983,0.211009,0.449615,0.048918,-0.340926,0.501026,-0,-0.338945,0.49342,-0.050713,-0.39582,0.486895,-0,-0.338945,0.49342,0.050713,-0.28207,0.499944,-0,-0.284051,0.492651,-0.047467,-0.390108,0.47987,-0.04733,-0.390108,0.47987,0.04733,-0.284051,0.492651,0.047467,-0.063804,-0.042658,0,-0.070799,-0.050166,-0.067552,-0.089937,0.092554,-0,-0.070799,-0.050166,0.067552,-0.034932,-0.15299,0,-0.038948,-0.167933,-0.07307,-0.098649,0.088261,-0.063847,-0.098649,0.088261,0.063847,-0.038948,-0.167933,0.07307,-0.31645,-0.019064,-0.108939,-0.260591,-0.191548,-0.109079,-0.199039,-0.356149,-0.108562,-0.114539,-0.459345,-0.142095,-0.08548,-0.41651,-0.160712,-0.048037,-0.364405,-0.163011,-0.175895,0.317426,-0.107858,-0.198725,0.393542,-0.101411,-0.223214,0.441959,-0.089503,-0.282209,0.471765,-0.087733,-0.333029,0.470712,-0.093742,-0.380876,0.458248,-0.087452,-0.072725,-0.574949,-0.1064,-0.010376,-0.60419,-0.105754,0.052841,-0.57563,-0.10645,0.393792,0.457647,-0.087465,0.346769,0.47084,-0.093774,0.296361,0.472372,-0.087776,0.4029,0.258437,-0.105839,0.425494,0.349383,-0.100264,0.430791,0.409367,-0.088826,0.098226,-0.460601,-0.142186,0.0706,-0.41742,-0.160783,0.034887,-0.364886,-0.163047,0.125977,0.074202,-0.116265,0.089429,-0.07094,-0.122209,0.047976,-0.202414,-0.130711,-0.419937,0.411541,-0.088838,-0.416774,0.352713,-0.100281,-0.397217,0.262807,-0.105845,-0.05582,-0.201821,-0.130693,-0.09299,-0.069958,-0.122187,-0.124785,0.075382,-0.116241,-0.200078,0.195496,-0.141131,-0.257633,0.175774,-0.149825,-0.315187,0.156052,-0.138543,0.185685,-0.358785,-0.108653,0.252176,-0.195322,-0.109154,0.313266,-0.023697,-0.108986,0.236663,0.442453,-0.089561,0.210558,0.393501,-0.101472,0.185143,0.316782,-0.107905,0.317812,0.151995,-0.138569,0.261343,0.172763,-0.149857,0.204874,0.19353,-0.141164,-0.31645,-0.019064,0.108939,-0.260591,-0.191548,0.109079,-0.199039,-0.356149,0.108562,-0.114539,-0.459345,0.142095,-0.08548,-0.41651,0.160712,-0.048037,-0.364405,0.163011,-0.175895,0.317426,0.107858,-0.198725,0.393542,0.101411,-0.223214,0.441959,0.089503,-0.282209,0.471765,0.087733,-0.333029,0.470712,0.093742,-0.380876,0.458248,0.087451,-0.072725,-0.574949,0.1064,-0.010376,-0.60419,0.105754,0.052841,-0.57563,0.10645,0.393792,0.457647,0.087465,0.346769,0.47084,0.093774,0.296361,0.472372,0.087776,0.4029,0.258437,0.105839,0.425494,0.349383,0.100264,0.430791,0.409367,0.088826,0.098226,-0.460601,0.142186,0.0706,-0.41742,0.160784,0.034887,-0.364886,0.163047,0.125977,0.074202,0.116265,0.089429,-0.07094,0.122209,0.047976,-0.202414,0.130711,-0.419937,0.411541,0.088838,-0.416774,0.352713,0.100281,-0.397217,0.262807,0.105845,-0.05582,-0.201821,0.130693,-0.09299,-0.069958,0.122187,-0.124785,0.075382,0.116241,-0.200078,0.195496,0.141131,-0.257633,0.175774,0.149825,-0.315187,0.156052,0.138543,0.185685,-0.358785,0.108653,0.252176,-0.195322,0.109154,0.313266,-0.023697,0.108986,0.236663,0.442453,0.089561,0.210558,0.393501,0.101472,0.185143,0.316782,0.107905,0.317812,0.151995,0.138569,0.261343,0.172763,0.149857,0.204874,0.19353,0.141164,-0.147694,-0.510278,-0.05766,-0.151838,-0.516644,0,-0.147694,-0.510278,0.05766,-0.391925,0.129755,0.058636,-0.401518,0.126468,-0,-0.391925,0.129755,-0.058636,0.129669,-0.51194,-0.057711,0.133599,-0.518358,0,0.129669,-0.51194,0.057711,-0.004215,-0.221737,-0.076282,-0.003884,-0.202007,0,-0.004215,-0.221737,0.076283,0.129582,0.22122,0.061241,0.12017,0.224681,-0,0.129582,0.22122,-0.061241,0.248669,0.478854,-0.044568,0.24337,0.485154,-0,0.248669,0.478854,0.044568,0.441484,0.451166,0.044257,0.450168,0.456527,-0,0.441484,0.451166,-0.044257,0.393104,0.124306,-0.058645,0.402515,0.120845,0,0.393104,0.124306,0.058645,-0.233936,0.477705,-0.04454,-0.228363,0.483834,-0,-0.233936,0.477705,0.04454,-0.12334,0.221793,0.061224,-0.113747,0.22508,-0,-0.12334,0.221793,-0.061224,-0.429148,0.452308,0.044259,-0.437694,0.457589,-0,-0.429149,0.452308,-0.044259,-0.135261,-0.491178,-0.107599,-0.005442,-0.295732,-0.144723,-0.411782,0.441778,-0.074808,-0.24528,0.465118,-0.07524,0.117878,-0.492688,-0.107685,0.423845,0.440487,-0.074807,0.259449,0.465905,-0.075284,-0.363148,0.139616,-0.107931,-0.152117,0.211932,-0.111813,0.364869,0.134689,-0.107948,0.157816,0.210836,-0.111842,-0.363148,0.139616,0.107931,-0.135261,-0.491178,0.107599,-0.005442,-0.295732,0.144723,-0.152117,0.211932,0.111813,-0.24528,0.465118,0.07524,-0.411782,0.441778,0.074808,0.117878,-0.492688,0.107685,0.423845,0.440487,0.074807,0.259449,0.465905,0.075284,0.364869,0.134689,0.107948,0.157816,0.210836,0.111842], 6 | "metadata":{ 7 | "faces":328, 8 | "normals":330, 9 | "version":3, 10 | "vertices":330, 11 | "uvs":0, 12 | "generator":"io_three", 13 | "type":"Geometry" 14 | }, 15 | "uvs":[] 16 | } -------------------------------------------------------------------------------- /public/assets/sounds/background-success.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/B-Reel/vr-madebymakers/3cf655a4ec4cc2316f40df28cbd6be32f4cf8b51/public/assets/sounds/background-success.wav -------------------------------------------------------------------------------- /public/assets/sounds/background.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/B-Reel/vr-madebymakers/3cf655a4ec4cc2316f40df28cbd6be32f4cf8b51/public/assets/sounds/background.wav -------------------------------------------------------------------------------- /public/assets/sounds/balloon1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/B-Reel/vr-madebymakers/3cf655a4ec4cc2316f40df28cbd6be32f4cf8b51/public/assets/sounds/balloon1.wav -------------------------------------------------------------------------------- /public/assets/sounds/balloon2.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/B-Reel/vr-madebymakers/3cf655a4ec4cc2316f40df28cbd6be32f4cf8b51/public/assets/sounds/balloon2.wav -------------------------------------------------------------------------------- /public/assets/sounds/balloon3.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/B-Reel/vr-madebymakers/3cf655a4ec4cc2316f40df28cbd6be32f4cf8b51/public/assets/sounds/balloon3.wav -------------------------------------------------------------------------------- /public/assets/sounds/balloon4.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/B-Reel/vr-madebymakers/3cf655a4ec4cc2316f40df28cbd6be32f4cf8b51/public/assets/sounds/balloon4.wav -------------------------------------------------------------------------------- /public/assets/textures/breel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/B-Reel/vr-madebymakers/3cf655a4ec4cc2316f40df28cbd6be32f4cf8b51/public/assets/textures/breel.png -------------------------------------------------------------------------------- /public/assets/textures/confettis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/B-Reel/vr-madebymakers/3cf655a4ec4cc2316f40df28cbd6be32f4cf8b51/public/assets/textures/confettis.png -------------------------------------------------------------------------------- /public/assets/textures/floor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/B-Reel/vr-madebymakers/3cf655a4ec4cc2316f40df28cbd6be32f4cf8b51/public/assets/textures/floor.png -------------------------------------------------------------------------------- /public/assets/textures/gold.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/B-Reel/vr-madebymakers/3cf655a4ec4cc2316f40df28cbd6be32f4cf8b51/public/assets/textures/gold.jpg -------------------------------------------------------------------------------- /public/assets/textures/hand_occlusion.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/B-Reel/vr-madebymakers/3cf655a4ec4cc2316f40df28cbd6be32f4cf8b51/public/assets/textures/hand_occlusion.jpg -------------------------------------------------------------------------------- /public/assets/textures/silver.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/B-Reel/vr-madebymakers/3cf655a4ec4cc2316f40df28cbd6be32f4cf8b51/public/assets/textures/silver.jpg -------------------------------------------------------------------------------- /public/css/main.css: -------------------------------------------------------------------------------- 1 | body{ 2 | position: absolute; 3 | top:0; 4 | left:0; 5 | margin: 0; 6 | padding: 0; 7 | width: 100%; 8 | height: 101%; 9 | overflow: hidden; 10 | } 11 | 12 | html { 13 | overflow: hidden; 14 | width: 100%; 15 | height: 100%; 16 | } 17 | 18 | #container{ 19 | position: absolute; 20 | width: 100%; 21 | height: 100%; 22 | overflow: hidden; 23 | } -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Made by Makers VR 7 | 8 | 9 | 10 |
11 | 12 | 21 | 22 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /public/js/vendor/webvr-manager.js: -------------------------------------------------------------------------------- 1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o %s', this.mode, mode); 501 | this.mode = mode; 502 | this.button.setMode(mode, this.isVRCompatible); 503 | 504 | // Emit an event indicating the mode changed. 505 | this.emit('modechange', mode, oldMode); 506 | }; 507 | 508 | /** 509 | * Main button was clicked. 510 | */ 511 | WebVRManager.prototype.onFSClick_ = function() { 512 | switch (this.mode) { 513 | case Modes.NORMAL: 514 | // TODO: Remove this hack if/when iOS gets real fullscreen mode. 515 | // If this is an iframe on iOS, break out and open in no_fullscreen mode. 516 | if (Util.isIOS() && Util.isIFrame()) { 517 | var url = window.location.href; 518 | url = Util.appendQueryParameter(url, 'no_fullscreen', 'true'); 519 | url = Util.appendQueryParameter(url, 'start_mode', Modes.MAGIC_WINDOW); 520 | top.location.href = url; 521 | return; 522 | } 523 | this.setMode_(Modes.MAGIC_WINDOW); 524 | this.requestFullscreen_(); 525 | break; 526 | case Modes.MAGIC_WINDOW: 527 | if (this.isFullscreenDisabled) { 528 | window.history.back(); 529 | return; 530 | } 531 | this.setMode_(Modes.NORMAL); 532 | this.exitFullscreen_(); 533 | break; 534 | } 535 | }; 536 | 537 | /** 538 | * The VR button was clicked. 539 | */ 540 | WebVRManager.prototype.onVRClick_ = function() { 541 | // TODO: Remove this hack when iOS has fullscreen mode. 542 | // If this is an iframe on iOS, break out and open in no_fullscreen mode. 543 | if (this.mode == Modes.NORMAL && Util.isIOS() && Util.isIFrame()) { 544 | var url = window.location.href; 545 | url = Util.appendQueryParameter(url, 'no_fullscreen', 'true'); 546 | url = Util.appendQueryParameter(url, 'start_mode', Modes.VR); 547 | top.location.href = url; 548 | return; 549 | } 550 | this.enterVRMode_(); 551 | }; 552 | 553 | WebVRManager.prototype.requestFullscreen_ = function() { 554 | var canvas = document.body; 555 | //var canvas = this.renderer.domElement; 556 | if (canvas.requestFullscreen) { 557 | canvas.requestFullscreen(); 558 | } else if (canvas.mozRequestFullScreen) { 559 | canvas.mozRequestFullScreen(); 560 | } else if (canvas.webkitRequestFullscreen) { 561 | canvas.webkitRequestFullscreen(); 562 | } else if (canvas.msRequestFullscreen) { 563 | canvas.msRequestFullscreen(); 564 | } 565 | }; 566 | 567 | WebVRManager.prototype.exitFullscreen_ = function() { 568 | if (document.exitFullscreen) { 569 | document.exitFullscreen(); 570 | } else if (document.mozCancelFullScreen) { 571 | document.mozCancelFullScreen(); 572 | } else if (document.webkitExitFullscreen) { 573 | document.webkitExitFullscreen(); 574 | } else if (document.msExitFullscreen) { 575 | document.msExitFullscreen(); 576 | } 577 | }; 578 | 579 | WebVRManager.prototype.onVRDisplayPresentChange_ = function(e) { 580 | console.log('onVRDisplayPresentChange_', e); 581 | if (this.hmd.isPresenting) { 582 | this.setMode_(Modes.VR); 583 | } else { 584 | this.setMode_(Modes.NORMAL); 585 | } 586 | }; 587 | 588 | WebVRManager.prototype.onVRDisplayDeviceParamsChange_ = function(e) { 589 | console.log('onVRDisplayDeviceParamsChange_', e); 590 | }; 591 | 592 | WebVRManager.prototype.onFullscreenChange_ = function(e) { 593 | // If we leave full-screen, go back to normal mode. 594 | if (document.webkitFullscreenElement === null || 595 | document.mozFullScreenElement === null) { 596 | this.setMode_(Modes.NORMAL); 597 | } 598 | }; 599 | 600 | module.exports = WebVRManager; 601 | 602 | },{"./button-manager.js":1,"./emitter.js":2,"./modes.js":4,"./util.js":5}]},{},[3]); -------------------------------------------------------------------------------- /watcher.js: -------------------------------------------------------------------------------- 1 | var watchify = require('watchify'); 2 | var browserify = require('browserify'); 3 | var stringify = require('stringify'); 4 | var gulp = require('gulp'); 5 | var source = require('vinyl-source-stream'); 6 | var buffer = require('vinyl-buffer'); 7 | var gutil = require('gulp-util'); 8 | var sourcemaps = require('gulp-sourcemaps'); 9 | var uglify = require('gulp-uglify'); 10 | 11 | var b = browserify('./app/app.js', { 12 | debug: true, 13 | cache: {}, 14 | packageCache: {} 15 | }) 16 | .transform(stringify(['.glsl'])); 17 | 18 | var w = watchify(b); 19 | 20 | w.on('update', bundle); 21 | 22 | function bundle(e) { 23 | if(e) { 24 | for(var i = 0; i < e.length; i++) { 25 | console.log('File changed', e[i]); 26 | } 27 | 28 | console.log(e.length, 'Files Built into /public/js/bundle.js'); 29 | console.log('Watching for changes....'); 30 | } 31 | 32 | return b.bundle() 33 | .on('error', gutil.log.bind(gutil, 'Browserify Error')) 34 | .pipe(source('bundle.js')) 35 | .pipe(buffer()) 36 | .pipe(sourcemaps.init({ loadMaps: true })) 37 | .pipe(sourcemaps.write('./')) 38 | .pipe(gulp.dest('./public/js')); 39 | }; 40 | 41 | bundle(); 42 | 43 | console.log('Watching for changes....'); 44 | --------------------------------------------------------------------------------