├── AlteHaasGroteskBold.ttf ├── AlteHaasGroteskRegular.ttf ├── Maru ├── AudioController.js ├── AudioTexture.js ├── FurryGroup.js ├── FurryHead.js ├── FurryTail.js ├── GUI.js ├── GeosansLight.ttf ├── LoadedAudio.js ├── Loader.js ├── Looper.js ├── MaruBassKickLoop.mp3 ├── MaruBassModLoop.mp3 ├── MaruBellALoop.mp3 ├── MaruBellBLoop.mp3 ├── MaruBellBrightLoop.mp3 ├── MaruBellCLoop.mp3 ├── MaruClapLoop.mp3 ├── MaruHatsLoop.mp3 ├── MaruHiupLoop.mp3 ├── MaruIMPLoop.mp3 ├── MaruKickLoop.mp3 ├── MaruLogritLoop.mp3 ├── MaruLoops.zip ├── MaruLopanLoop.mp3 ├── MaruModALoop.mp3 ├── MaruModBLoop.mp3 ├── MaruRNLLoop.mp3 ├── MaruRollLoop.mp3 ├── MaruSnareLoop.mp3 ├── MaruUpmidLoop.mp3 ├── MaruVocLoop.mp3 ├── OBJLoader.js ├── ObjectControls.js ├── ParticleUtils.js ├── PhysicsRenderer.js ├── PosVelSimulation.js ├── ShaderLoader.js ├── Stream.js ├── TrackballControls.js ├── Tween.js ├── activate.wav ├── andaBit.wav ├── cab_sprite.png ├── dat.gui.min.js ├── deactivate.wav ├── goodJob.wav ├── hover.wav ├── icons │ ├── albumCover.png │ ├── cabbibo.png │ ├── cabbibo_1.png │ ├── connect_1.png │ ├── cursorWhite.png │ ├── download_1.png │ ├── facebook_1.png │ ├── info_1.png │ ├── loadGif.gif │ ├── normals │ │ ├── 08_normalmap.png │ │ ├── 10389-normal.jpg │ │ ├── 3989-normal.jpg │ │ ├── 4706-normal.jpg │ │ ├── 7723-normal.jpg │ │ ├── 7870-normal.jpg │ │ ├── 8158-normal.jpg │ │ ├── 940-normal.jpg │ │ ├── bumpmap_normalmap.jpg │ │ ├── carbonFiber.png │ │ ├── chesterfield.png │ │ ├── moss_normal_map.jpg │ │ ├── other.jpg │ │ ├── rock.jpg │ │ └── rock1.png │ ├── prism_1.png │ ├── rioux_1.png │ ├── sem_metal.jpg │ ├── soundcloud_1.png │ ├── sprite.png │ ├── starMap.png │ ├── thumb.jpg │ ├── thumb.png │ ├── twitter_1.png │ └── warp_1.png ├── index.html ├── initEasterEgg.js ├── initJelly.js ├── initPoly.js ├── initThree.js ├── jelly.wav ├── jquery.min.js ├── lvl4 │ ├── ambient.mp3 │ ├── ambient1.mp3 │ ├── death.mp3 │ ├── part1 │ │ ├── drums.mp3 │ │ ├── hats.mp3 │ │ ├── highSynth.mp3 │ │ ├── lowSynth.mp3 │ │ └── vox.mp3 │ └── part2 │ │ ├── drums.mp3 │ │ ├── hats.mp3 │ │ ├── highSynth.mp3 │ │ ├── lowSynth.mp3 │ │ └── vox.mp3 ├── main.css ├── polymer-sticker.png ├── shaders │ ├── curl.glsl │ ├── curlSim.glsl │ ├── deathSim.glsl │ ├── fs-accel.glsl │ ├── fs-clueLine.glsl │ ├── fs-deathParticles.glsl │ ├── fs-furryHead.glsl │ ├── fs-furryParticles.glsl │ ├── fs-furryTail.glsl │ ├── fs-mainTail.glsl │ ├── fs-poly.glsl │ ├── fs-polyOrg.glsl │ ├── fs-polyOutline.glsl │ ├── fs-render.glsl │ ├── fs-simPos.glsl │ ├── fs-simVel.glsl │ ├── fs-texturePass.glsl │ ├── fs-toFrom.glsl │ ├── gravitySimBug1.glsl │ ├── lightColors.glsl │ ├── room │ │ ├── fs-render.glsl │ │ ├── fs-simPos.glsl │ │ ├── fs-simVel.glsl │ │ └── vs-render.glsl │ ├── semLookup.glsl │ ├── simplex.glsl │ ├── sphereDisrupt.glsl │ ├── ss-furryHead.glsl │ ├── ss-furryTail.glsl │ ├── ss-mainTail.glsl │ ├── triplanarMap.glsl │ ├── vs-furryHead.glsl │ ├── vs-furryParticles.glsl │ ├── vs-furryTail.glsl │ ├── vs-mainTail.glsl │ ├── vs-pass.glsl │ ├── vs-planet.glsl │ ├── vs-planetDisplace.glsl │ ├── vs-poly.glsl │ ├── vs-polyOrg.glsl │ ├── vs-polyOutline.glsl │ └── vs-render.glsl ├── stats.min.js ├── three.js ├── three.min.js └── underscore.js ├── README.md ├── WARP303_Packshot_3000.jpg ├── WARP303_Packshot_3000T.png ├── alte haas grotesk licence.rtf ├── index.html ├── plaid.png ├── plaidlogo.png ├── poly.png ├── polyText.png └── polymer-cover-object-2.png /AlteHaasGroteskBold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/AlteHaasGroteskBold.ttf -------------------------------------------------------------------------------- /AlteHaasGroteskRegular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/AlteHaasGroteskRegular.ttf -------------------------------------------------------------------------------- /Maru/AudioController.js: -------------------------------------------------------------------------------- 1 | 2 | function AudioController(){ 3 | 4 | try { 5 | window.AudioContext = window.AudioContext||window.webkitAudioContext; 6 | }catch(e) { 7 | alert( 'WEB AUDIO API NOT SUPPORTED' ); 8 | } 9 | 10 | this.ctx = new AudioContext(); 11 | 12 | this.mute = this.ctx.createGain(); 13 | this.gain = this.ctx.createGain(); 14 | this.analyzer = this.ctx.createAnalyser(); 15 | 16 | this.analyzer.frequencyBinCount = 1024; 17 | this.analyzer.array = new Uint8Array( this.analyzer.frequencyBinCount ); 18 | 19 | this.texture = new AudioTexture( this.analyzer ); 20 | 21 | this.gain.connect( this.analyzer ); 22 | this.analyzer.connect( this.mute ); 23 | this.mute.connect( this.ctx.destination ); 24 | 25 | 26 | this.updateArray = []; 27 | this.notes = []; 28 | this.loops = []; 29 | 30 | 31 | this.noteInput = this.ctx.createGain(); 32 | this.loopInput = this.ctx.createGain(); 33 | 34 | this.noteInput.connect( this.gain ); 35 | this.loopInput.connect( this.gain ); 36 | 37 | } 38 | 39 | 40 | AudioController.prototype.update = function(){ 41 | 42 | this.analyzer.getByteFrequencyData( this.analyzer.array ); 43 | 44 | this.texture.update(); 45 | 46 | for( var i = 0; i < this.updateArray.length; i++ ){ 47 | 48 | this.updateArray[i](); 49 | 50 | } 51 | 52 | } 53 | 54 | 55 | AudioController.prototype.addToUpdateArray = function( callback ){ 56 | 57 | this.updateArray.push( callback ); 58 | 59 | } 60 | 61 | AudioController.prototype.removeFromUpdateArray = function( callback ){ 62 | 63 | for( var i = 0; i< this.updateArray.length; i++ ){ 64 | 65 | if( this.updateArray[i] === callback ){ 66 | 67 | this.updateArray.splice( i , 1 ); 68 | console.log( 'SPLICED' ); 69 | 70 | } 71 | 72 | } 73 | 74 | } 75 | 76 | 77 | -------------------------------------------------------------------------------- /Maru/AudioTexture.js: -------------------------------------------------------------------------------- 1 | function AudioTexture( analyzer ){ 2 | 3 | var analyzer = analyzer; 4 | 5 | var fbc = analyzer.frequencyBinCount; 6 | 7 | // TODO: why 2 * 4 instead of 4 ? 8 | // fudge factor is to make sure texture reachs from 0 -> 1 in vUv coords 9 | var pixels = fbc / 8; 10 | 11 | //creates a canvas element 12 | var canvas = document.createElement('canvas'); 13 | canvas.style.zIndex = 999; 14 | canvas.style.position = 'absolute'; 15 | canvas.style.top = '50px'; 16 | canvas.style.left = '100px'; 17 | canvas.style.border = '1px solid red'; 18 | 19 | // uncomment to see texture in upper left corner 20 | //document.body.appendChild( canvas ); 21 | 22 | 23 | canvas.width = pixels; 24 | canvas.height = 1; 25 | 26 | var c = canvas.getContext('2d'); 27 | 28 | var width = canvas.width; 29 | var height = canvas.height; 30 | 31 | var imageData = c.createImageData( width , height ); 32 | 33 | c.putImageData( imageData , 0 , 0 ); 34 | 35 | texture = new THREE.Texture( canvas ); 36 | texture.update = textureUpdate.bind( texture ) 37 | texture.analyzer = analyzer; 38 | texture.c = c; 39 | texture.pixels = pixels; 40 | texture.width = width; 41 | texture.height = height; 42 | 43 | // console.log( audio ); 44 | 45 | return texture; 46 | 47 | } 48 | 49 | textureUpdate = function(){ 50 | 51 | if( this.analyzer){ 52 | 53 | 54 | var imageData = this.c.createImageData( this.width , this.height ); 55 | 56 | //transfers audio data to rgb values 57 | for (var i = 0; i < this.pixels ; i++) { 58 | 59 | var x = i; 60 | var y = 0; 61 | var r = this.analyzer.array[i] | 0; 62 | var g = this.analyzer.array[i+1] | 0; 63 | var b = this.analyzer.array[i+2] | 0; 64 | var a = this.analyzer.array[i+3] | 0; 65 | setPixelData( imageData , x , y , r , g , b , a ); 66 | 67 | } 68 | 69 | 70 | this.c.putImageData( imageData , 0 , 0 ); 71 | 72 | //updates the texture 73 | this.needsUpdate = true; 74 | 75 | } 76 | 77 | //console.log('ss'); 78 | 79 | } 80 | 81 | //TODO: Move this to canvasFunctions 82 | 83 | setPixelData = function ( imageData, x, y, r, g, b, a) { 84 | 85 | //console.log( r + " : " + g + " : " + b + " : " + a); 86 | index = ( x + y * imageData.width ) * 4; 87 | imageData.data[index+0] = r; 88 | imageData.data[index+1] = g; 89 | imageData.data[index+2] = b; 90 | imageData.data[index+3] = a; 91 | 92 | } 93 | 94 | 95 | -------------------------------------------------------------------------------- /Maru/FurryHead.js: -------------------------------------------------------------------------------- 1 | 2 | var FURRY_HEAD_GEO , FURRY_HEAD_POS; 3 | function FurryHead( page , leader ){ 4 | 5 | 6 | this.page = page; 7 | this.size = 64; 8 | this.sim = shaders.ss.furryHead; 9 | this.leader = leader; 10 | 11 | this.physicsRenderer = new PhysicsRenderer( 12 | this.size, 13 | this.sim, 14 | renderer 15 | ); 16 | 17 | this.physicsRenderer.setUniform( 't_audio' ,G.uniforms.t_audio ); 18 | 19 | this.physicsRenderer.setUniform( 't_column' , { 20 | type:"t", 21 | value:null 22 | }); 23 | 24 | 25 | this.physicsRenderer.setUniform( 'leader' , { 26 | type:"v3" , 27 | value:this.leader.position 28 | }); 29 | 30 | this.physicsRenderer.setUniform( 'dT' , G.uniforms.dT ); 31 | 32 | this.physicsRenderer.setUniform( 'timer' , G.uniforms.time ); 33 | 34 | 35 | 36 | var t_normal = THREE.ImageUtils.loadTexture('icons/normals/moss_normal_map.jpg'); //MATS.textures.normals.moss; 37 | 38 | //console.log( t_normal ); 39 | 40 | var uniforms = { 41 | 42 | t_normal: { type:"t" , value: t_normal }, 43 | //t_audio: { type:"t" , value: audio.texture }, 44 | t_audio: G.uniforms.t_audio, 45 | t_pos: { type:"t" , value: null }, 46 | lightPos: { type:"v3" , value: this.page.position }, 47 | 48 | } 49 | 50 | var material = new THREE.ShaderMaterial({ 51 | 52 | uniforms: uniforms, 53 | vertexShader: shaders.vs.furryHead, 54 | fragmentShader: shaders.fs.furryHead, 55 | side: THREE.DoubleSide 56 | 57 | }); 58 | 59 | if( !FURRY_HEAD_GEO ){ 60 | this.geo = this.createGeo( this.size ); 61 | FURRY_HEAD_GEO = this.geo; 62 | }else{ 63 | this.geo = FURRY_HEAD_GEO; 64 | } 65 | 66 | var m = new THREE.MeshNormalMaterial(); 67 | this.mesh = new THREE.Mesh( this.geo , material ); 68 | 69 | this.mesh.frustumCulled = false; 70 | 71 | var pR = this.physicsRenderer; 72 | 73 | pR.addBoundTexture( this.mesh , 't_pos' , 'output' ); 74 | 75 | var mesh = new THREE.Mesh( new THREE.BoxGeometry( 5 , 5 , 5) ); 76 | var pTexture = this.createPosTexture( this.size ); 77 | 78 | this.pTexture; 79 | 80 | if( !FURRY_HEAD_POS ){ 81 | var mesh = new THREE.Mesh( new THREE.BoxGeometry( 5 , 5 , 5) ); 82 | this.pTexture = this.createPosTexture( this.size ); 83 | FURRY_HEAD_POS = this.pTexture; 84 | }else{ 85 | this.pTexture = FURRY_HEAD_POS;//this.createLineGeo(); 86 | } 87 | 88 | this.physicsRenderer.reset( this.pTexture ); 89 | 90 | //this.physicsRenderer.addDebugScene( scene ); 91 | 92 | } 93 | 94 | FurryHead.prototype.update = function(){ 95 | 96 | this.physicsRenderer.update(); 97 | } 98 | 99 | 100 | FurryHead.prototype.createGeo = function( size ){ 101 | 102 | var geo = new THREE.BufferGeometry(); 103 | 104 | var subSize = (size) * (size-1); 105 | 106 | var posA = new THREE.BufferAttribute( new Float32Array( subSize * 6 * 3 ), 3 ); 107 | var normA = new THREE.BufferAttribute( new Float32Array( subSize * 6 * 3 ), 3 ); 108 | 109 | geo.addAttribute( 'position', posA ); 110 | geo.addAttribute( 'normal', normA ); 111 | 112 | var positions = geo.getAttribute( 'position' ).array; 113 | var normals = geo.getAttribute( 'normal' ).array; 114 | 115 | var uvArray = []; 116 | for( var i = 0; i < size; i++ ){ 117 | for( var j = 0; j < size-1; j++ ){ 118 | 119 | if( i < size-1){ 120 | var x = (i+.5) / size; 121 | var y = (j+.5) / size; 122 | }else{ 123 | var x = 10000; //.5 / size; 124 | var y = (j+.5) / size; 125 | } 126 | 127 | uvArray.push( [ x , y ] ); 128 | } 129 | } 130 | 131 | for( var i=0; i < uvArray.length; i++ ){ 132 | 133 | var x = uvArray[i][0]; 134 | var y = uvArray[i][1]; 135 | 136 | 137 | // Tri 1 138 | 139 | var index = i * 6 * 3; 140 | // var i = //TODO: index 141 | // 142 | 143 | if( x != 10000 ){ 144 | 145 | positions[ index + 0 ] = x - (.5 / size); 146 | positions[ index + 1 ] = y + (.5 / size); 147 | positions[ index + 2 ] = 0; 148 | 149 | positions[ index + 3 ] = x - ( .5 / size ); 150 | positions[ index + 4 ] = y - ( .5 / size) ; 151 | positions[ index + 5 ] = 0; 152 | 153 | positions[ index + 6 ] = x + (.5 / size); 154 | positions[ index + 7 ] = y + (.5 / size); 155 | positions[ index + 8 ] = 0; 156 | 157 | positions[ index + 9 ] = x + (.5 / size); 158 | positions[ index + 10 ] = y + (.5 / size); 159 | positions[ index + 11 ] = 0; 160 | 161 | positions[ index + 12 ] = x - ( .5 / size ); 162 | positions[ index + 13 ] = y - ( .5 / size) ; 163 | positions[ index + 14 ] = 0; 164 | 165 | positions[ index + 15 ] = x + (.5 / size); 166 | positions[ index + 16 ] = y - (.5 / size); 167 | positions[ index + 17 ] = 0; 168 | 169 | 170 | normals[ index + 0 ] = x - (.5 / size); 171 | normals[ index + 1 ] = y + (.5 / size); 172 | normals[ index + 2 ] = 0; 173 | 174 | normals[ index + 3 ] = x - ( .5 / size ); 175 | normals[ index + 4 ] = y - ( .5 / size) ; 176 | normals[ index + 5 ] = 0; 177 | 178 | normals[ index + 6 ] = x + (.5 / size); 179 | normals[ index + 7 ] = y + (.5 / size); 180 | normals[ index + 8 ] = 0; 181 | 182 | normals[ index + 9 ] = x + (.5 / size); 183 | normals[ index + 10 ] = y + (.5 / size); 184 | normals[ index + 11 ] = 0; 185 | 186 | normals[ index + 12 ] = x - ( .5 / size ); 187 | normals[ index + 13 ] = y - ( .5 / size) ; 188 | normals[ index + 14 ] = 0; 189 | 190 | normals[ index + 15 ] = x + (.5 / size); 191 | normals[ index + 16 ] = y - (.5 / size); 192 | normals[ index + 17 ] = 0; 193 | 194 | }else{ 195 | 196 | positions[ index + 0 ] = 1 - (.5 / size); 197 | positions[ index + 1 ] = y + (.5 / size); 198 | positions[ index + 2 ] = 0; 199 | 200 | positions[ index + 3 ] = 1 - ( .5 / size ); 201 | positions[ index + 4 ] = y - ( .5 / size) ; 202 | positions[ index + 5 ] = 0; 203 | 204 | positions[ index + 6 ] = 0 + (.5 / size); 205 | positions[ index + 7 ] = y + (.5 / size); 206 | positions[ index + 8 ] = 0; 207 | 208 | positions[ index + 9 ] = 0 + (.5 / size); 209 | positions[ index + 10 ] = y + (.5 / size); 210 | positions[ index + 11 ] = 0; 211 | 212 | positions[ index + 12 ] = 1 - ( .5 / size ); 213 | positions[ index + 13 ] = y - ( .5 / size) ; 214 | positions[ index + 14 ] = 0; 215 | 216 | positions[ index + 15 ] = 0 + (.5 / size); 217 | positions[ index + 16 ] = y - (.5 / size); 218 | positions[ index + 17 ] = 0; 219 | 220 | 221 | normals[ index + 0 ] = 1 - (.5 / size); 222 | normals[ index + 1 ] = y + (.5 / size); 223 | normals[ index + 2 ] = 0; 224 | 225 | normals[ index + 3 ] = 1 - ( .5 / size ); 226 | normals[ index + 4 ] = y - ( .5 / size) ; 227 | normals[ index + 5 ] = 0; 228 | 229 | normals[ index + 6 ] = 0 + (.5 / size); 230 | normals[ index + 7 ] = y + (.5 / size); 231 | normals[ index + 8 ] = 0; 232 | 233 | normals[ index + 9 ] = 0 + (.5 / size); 234 | normals[ index + 10 ] = y + (.5 / size); 235 | normals[ index + 11 ] = 0; 236 | 237 | normals[ index + 12 ] = 1 - ( .5 / size ); 238 | normals[ index + 13 ] = y - ( .5 / size) ; 239 | normals[ index + 14 ] = 0; 240 | 241 | normals[ index + 15 ] = 0 + (.5 / size); 242 | normals[ index + 16 ] = y - (.5 / size); 243 | normals[ index + 17 ] = 0; 244 | 245 | 246 | 247 | } 248 | 249 | /* 250 | positions[ i + 3 ] = x + ( .5 / size ); 251 | positions[ i + 4 ] = y - ( .5 / size) ; 252 | positions[ i + 5 ] = 0; 253 | */ 254 | 255 | // Tri 2 256 | 257 | } 258 | 259 | return geo; 260 | 261 | 262 | }; 263 | 264 | 265 | FurryHead.prototype.createPosTexture = function( size ){ 266 | 267 | 268 | var data = new Float32Array( size * size * 4 ); 269 | 270 | for ( var i = 0, l = data.length; i < l; i += 4 ) { 271 | 272 | var y = Math.floor( (i/4) / size ); 273 | var x = (i/4) - (y * size); 274 | 275 | 276 | var theta = 2 * Math.PI * ( x / size ); 277 | 278 | var r =( .1 * Math.random() + .9) * 1; 279 | var posX = r * Math.cos( theta ); 280 | var posZ = r * Math.sin( theta ); 281 | 282 | /*var face = geometry.faces[ Math.floor( Math.random() * facesLength ) ]; 283 | 284 | var vertex1 = geometry.vertices[ face.a ]; 285 | var vertex2 = geometry.vertices[ Math.random() > 0.5 ? face.b : face.c ]; 286 | 287 | point.subVectors( vertex2, vertex1 ); 288 | point.multiplyScalar( Math.random() ); 289 | point.add( vertex1 );*/ 290 | 291 | data[ i ] = 1000 +posX; 292 | data[ i + 1 ] = 100 +posZ; 293 | data[ i + 2 ] = 100 + (1 - (y/size))*100; 294 | data[ i + 3 ] = 1; 295 | 296 | } 297 | 298 | var positionsTexture = new THREE.DataTexture( 299 | data, 300 | size, 301 | size, 302 | THREE.RGBAFormat, 303 | THREE.FloatType 304 | ); 305 | 306 | positionsTexture.minFilter = THREE.NearestFilter; 307 | positionsTexture.magFilter = THREE.NearestFilter; 308 | positionsTexture.generateMipmaps = false; 309 | positionsTexture.needsUpdate = true; 310 | 311 | return positionsTexture; 312 | 313 | }; 314 | -------------------------------------------------------------------------------- /Maru/GUI.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | function GUI( PARAMS , params ){ 4 | 5 | this.params = _.defaults( params || {} ,{ 6 | domElement: document.body, 7 | }); 8 | 9 | 10 | //console.log( this.params ); 11 | this.PARAMS = PARAMS; 12 | 13 | this.gui = new dat.GUI({autoPlace:false}); 14 | this.gui.close(); 15 | 16 | // TODO: make passable 17 | this.domElement = this.params.domElement; 18 | this.domElement.appendChild(this.gui.domElement); 19 | 20 | 21 | this.soul = this.gui.addFolder( 'Soul' ); 22 | this.body = this.gui.addFolder( 'Body' ); 23 | 24 | for( var propt in PARAMS.soul ){ 25 | 26 | var p = PARAMS.soul[propt]; 27 | 28 | if( p.type === "f" ){ 29 | 30 | if(p.constraints ){ 31 | this.addFloat( 'soul' , p , propt , p.constraints ); 32 | }else{ 33 | this.addFloat( 'soul' , p , propt ); 34 | } 35 | 36 | } 37 | } 38 | 39 | 40 | 41 | 42 | for( var propt in PARAMS.body ){ 43 | 44 | var p = PARAMS.body[propt]; 45 | 46 | if( p.type === "f" ){ 47 | 48 | if(p.constraints ){ 49 | this.addFloat( 'body' , p , propt , p.constraints ); 50 | }else{ 51 | this.addFloat( 'body' , p , propt ); 52 | } 53 | 54 | }else if( p.type === "color" ){ 55 | 56 | this.addColor( 'body' , p , propt ); 57 | 58 | } 59 | 60 | } 61 | 62 | } 63 | 64 | // Need to create an extra varible call tmp_color1 to be able to use 65 | GUI.prototype.addColor = function( folder , object , name ){ 66 | 67 | // console.log('ass'); 68 | var actualObject = name.split( 'tmp_' )[1]; 69 | // console.log( actualObject ); 70 | 71 | // console.log( object ); 72 | this[folder].addColor( object , 'value' ).name( actualObject ).onChange(function(v){ 73 | this.PARAMS[folder][actualObject].value.setHex( v ) 74 | 75 | }.bind( this ) ); 76 | 77 | 78 | } 79 | 80 | GUI.prototype.addFloat = function( folder , object , name , constraints ){ 81 | 82 | if( constraints ){ 83 | this[folder].add( object , 'value' , constraints[0] , constraints[1] ).name( name ); 84 | }else{ 85 | this[folder].add( object , 'value' ).name( name ); 86 | } 87 | 88 | } 89 | 90 | /* 91 | 92 | guiSim.add( PARAMS.simulation.repulsionPower , 'value' , -10 , 100).name( 'Repulsion Power' ); 93 | guiSim.add( PARAMS.simulation.repulsionRadius , 'value' , 10 , 1000).name( 'Repulsion Radius' ); 94 | guiSim.add( PARAMS.simulation.dampening , 'value' , .8 , .999 ).name( 'Dampenening' ); 95 | 96 | guiSim.add( PARAMS , 'toggle').name( 'toggleRepelers' ); 97 | 98 | 99 | 100 | guiSim.add( PARAMS, 'objectType' , [ 101 | 'cube', 102 | 'sphere' , 103 | //'hand' , 104 | //'skull' , 105 | //'logo' , 106 | //'bieb' , 107 | //'rickAndBarney', 108 | //'ring', 109 | 'torus' 110 | ] ).onChange( function(value){ 111 | 112 | recreateGeometry(value); 113 | console.log(value); 114 | 115 | }); 116 | 117 | 118 | guiRender.add( PARAMS.render.audioDisplacement , 'value' , -3 , 3).name( 'Audio Displacement' ); 119 | guiRender.add( PARAMS.render.custom1 , 'value' , 0 , 1).name( 'Custom1' ); 120 | guiRender.add( PARAMS.render.custom2 , 'value' , 0 , 1).name( 'Custom2' ); 121 | guiRender.add( PARAMS.render.custom3 , 'value' , 0 , 1).name( 'Custom3' ); 122 | 123 | guiRender.addColor( PARAMS.render , 'lambTemp' ).name( 'Lambert' ).onChange( function( value ){ 124 | 125 | PARAMS.render.c_lamb.value.r =value.r / 256; 126 | PARAMS.render.c_lamb.value.g =value.g / 256; 127 | PARAMS.render.c_lamb.value.b =value.b / 256; 128 | 129 | }).listen(); 130 | 131 | guiRender.addColor( PARAMS.render , 'specTemp' ).name( 'Specular' ).onChange( function( value ){ 132 | 133 | PARAMS.render.c_spec.value.r =value.r / 256; 134 | PARAMS.render.c_spec.value.g =value.g / 256; 135 | PARAMS.render.c_spec.value.b =value.b / 256; 136 | 137 | }).listen(); 138 | 139 | guiRender.addColor( PARAMS.render , 'audioTemp' ).name( 'Fresnel?' ).onChange( function( value ){ 140 | 141 | PARAMS.render.c_audio.value.r =value.r / 256; 142 | PARAMS.render.c_audio.value.g =value.g / 256; 143 | PARAMS.render.c_audio.value.b =value.b / 256; 144 | 145 | }).listen(); 146 | 147 | 148 | PARAMS.render.lambTemp.r = PARAMS.render.c_lamb.value.r * 256; 149 | PARAMS.render.lambTemp.g = PARAMS.render.c_lamb.value.g * 256; 150 | PARAMS.render.lambTemp.b = PARAMS.render.c_lamb.value.b * 256; 151 | 152 | PARAMS.render.specTemp.r = PARAMS.render.c_spec.value.r * 256; 153 | PARAMS.render.specTemp.g = PARAMS.render.c_spec.value.g * 256; 154 | PARAMS.render.specTemp.b = PARAMS.render.c_spec.value.b * 256; 155 | 156 | PARAMS.render.audioTemp.r = PARAMS.render.c_audio.value.r * 256; 157 | PARAMS.render.audioTemp.g = PARAMS.render.c_audio.value.g * 256; 158 | PARAMS.render.audioTemp.b = PARAMS.render.c_audio.value.b * 256; 159 | 160 | 161 | 162 | 163 | guiRender.add( PARAMS,'visualType' , [ 164 | 'plastic' , 165 | 'wireframe' , 166 | 'striped' , 167 | 'ambient', 168 | 'fractal' 169 | ]).onChange(function(value){ 170 | 171 | */ 172 | -------------------------------------------------------------------------------- /Maru/GeosansLight.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/GeosansLight.ttf -------------------------------------------------------------------------------- /Maru/LoadedAudio.js: -------------------------------------------------------------------------------- 1 | function LoadedAudio( controller , file , params ){ 2 | 3 | this.loader; 4 | this.params = _.defaults( params || {}, { 5 | 6 | looping: false, 7 | fbc: 128, 8 | fadeTime: 1, 9 | texture: true, 10 | 11 | }); 12 | 13 | this.controller = controller; 14 | 15 | this.file = file; 16 | 17 | this.playing = false; 18 | 19 | this.looping = this.params.looping; 20 | 21 | this.buffer; 22 | 23 | this.filterOn = false; 24 | this.filter = this.controller.ctx.createBiquadFilter(); 25 | this.analyser = this.controller.ctx.createAnalyser(); 26 | this.analyser.array = new Uint8Array( this.params.fbc ); 27 | this.gain = this.controller.ctx.createGain(); 28 | 29 | this.analyzer = this.analyser; //I hate spelling 30 | 31 | this.analyser.connect( this.gain ); 32 | 33 | if( this.looping ){ 34 | this.gain.connect( this.controller.loopInput ); 35 | }else{ 36 | this.gain.connect( this.controller.noteInput ); 37 | } 38 | 39 | 40 | 41 | this.time = 0; 42 | 43 | if( this.params.texture ){ 44 | 45 | this.texture = AudioTexture( this.analyser ); 46 | 47 | } 48 | 49 | this.loadFile(); 50 | 51 | } 52 | 53 | 54 | LoadedAudio.prototype._loadProgress = function(e){ 55 | 56 | this.loaded = e.loaded / e.total; 57 | 58 | this.loadProgress( e ); 59 | 60 | //tween.start(); 61 | } 62 | 63 | LoadedAudio.prototype.loadProgress = function(){ 64 | 65 | 66 | } 67 | 68 | 69 | LoadedAudio.prototype.loadFile = function(){ 70 | 71 | 72 | var request=new XMLHttpRequest(); 73 | request.open("GET",this.file,true); 74 | request.responseType="arraybuffer"; 75 | 76 | var self = this; 77 | request.onerror = function(){ 78 | alert( 'ERROR LOADING SONG' ); 79 | //self.womb.loader.addFailue( 'Capability to load song' , 'http://womble.com' 80 | } 81 | 82 | 83 | 84 | request.onprogress = this._loadProgress.bind( this ); 85 | 86 | var self = this; 87 | 88 | request.onload = function(){ 89 | 90 | self.controller.ctx.decodeAudioData(request.response,function(buffer){ 91 | 92 | if(!buffer){ 93 | alert('error decoding file data: '+url); 94 | return; 95 | } 96 | 97 | self.buffer = buffer; 98 | self.onDecode(); 99 | 100 | }) 101 | }, 102 | 103 | request.send(); 104 | 105 | } 106 | 107 | LoadedAudio.prototype.onDecode = function(){ 108 | 109 | //gets just the track name, removing the mp3 110 | this.trackID= this.file.split('.')[this.file.split('.').length-2]; 111 | 112 | this.createSource(); 113 | 114 | //var self = this; 115 | //if( this.params.onLoad ) this.params.onLoad( self ); 116 | 117 | this._onLoad(); 118 | 119 | } 120 | 121 | 122 | LoadedAudio.prototype.createSource = function() { 123 | 124 | this.source = this.controller.ctx.createBufferSource(); 125 | this.source.buffer = this.buffer; 126 | this.source.loop = false;//this.looping; 127 | 128 | this.source.connect( this.analyser ); 129 | 130 | if( !this.looping ){ 131 | 132 | //this.gain.gain.value = 1; 133 | 134 | } 135 | 136 | 137 | 138 | 139 | }; 140 | 141 | LoadedAudio.prototype.destroySource = function(){ 142 | 143 | this.source.disconnect(this.analyser); 144 | this.analyser.disconnect(this.gain); 145 | this.source = undefined; 146 | this.analyser = undefined; 147 | 148 | }; 149 | 150 | LoadedAudio.prototype.fadeOut = function( time ){ 151 | 152 | var t = this.controller.ctx.currentTime; 153 | if( !time ) time = this.params.fadeTime; 154 | this.gain.gain.linearRampToValueAtTime( this.gain.gain.value , t ); 155 | this.gain.gain.linearRampToValueAtTime( 0.0 , t + time ); 156 | 157 | } 158 | 159 | LoadedAudio.prototype.fadeIn = function( time , value ){ 160 | 161 | if( !time ) time = this.params.fadeTime; 162 | if( !value ) value = 1; 163 | 164 | var t = this.controller.ctx.currentTime; 165 | this.gain.gain.linearRampToValueAtTime( this.gain.gain.value , t ); 166 | this.gain.gain.linearRampToValueAtTime( 1.0 , t + time ); 167 | 168 | } 169 | 170 | LoadedAudio.prototype.turnOffFilter = function(){ 171 | this.filterOn = false; 172 | this.filter.disconnect(0); 173 | this.source.disconnect( 0 ); 174 | this.source.connect( this.gain ); 175 | } 176 | 177 | LoadedAudio.prototype.turnOnFilter = function(){ 178 | this.filterOn = true; 179 | this.source.disconnect( 0 ); 180 | this.source.connect( this.filter ); 181 | this.filter.connect( this.gain ); 182 | } 183 | 184 | 185 | 186 | LoadedAudio.prototype.stop = function(){ 187 | 188 | this.playing = false; 189 | 190 | if( this.source.noteOff ){ 191 | this.source.noteOff(0); 192 | }else{ 193 | this.source.stop(); 194 | } 195 | 196 | this.createSource(); 197 | 198 | }; 199 | 200 | LoadedAudio.prototype.play = function( vol ){ 201 | 202 | if( vol ){ this.gain.gain.value = vol } 203 | //this.startTime = this.controller.womb.time.value; 204 | 205 | this.playing = true; 206 | 207 | if( this.source.noteOn ){ 208 | this.source.noteOn(0); 209 | } 210 | 211 | 212 | this.source.start(); 213 | 214 | // Creates a new source for the audio right away 215 | // so we can play the next one with no delay 216 | // if(this.looping == false){ 217 | this.createSource(); 218 | // } 219 | // 220 | //this.controller.addToUpdateArray( this.update.bind( this ) ); 221 | 222 | }; 223 | 224 | LoadedAudio.prototype._onLoad = function(){ 225 | 226 | if( this.looping ){ 227 | 228 | 229 | looper.everyLoop( function(){ 230 | 231 | if( this.playing ){ 232 | this.play() 233 | } 234 | 235 | }.bind( this )); 236 | 237 | this.gain.gain.value = 0; 238 | 239 | } 240 | 241 | this.onLoad(); 242 | 243 | this.controller.addToUpdateArray( this.update.bind( this ) ); 244 | 245 | } 246 | LoadedAudio.prototype.onLoad = function(){} 247 | 248 | 249 | LoadedAudio.prototype.update = function(){ 250 | 251 | if( this.playing ){ 252 | 253 | //this.time = this.controller.womb.time.value - this.startTime; 254 | this.analyser.getByteFrequencyData( this.analyser.array ); 255 | this.averageVolume = this.getAverage( this.analyser.array ); 256 | 257 | //console.log( this.averageVolume ); 258 | if( this.texture ) 259 | this.texture.update(); 260 | 261 | } 262 | 263 | } 264 | 265 | LoadedAudio.prototype.getAverage = function( array ){ 266 | 267 | var ave = 0; 268 | var l = array.length; 269 | 270 | for( var i = 0; i< array.length; i++ ){ 271 | 272 | ave += array[i]; 273 | 274 | } 275 | 276 | ave /= l; 277 | 278 | return ave; 279 | 280 | } 281 | 282 | 283 | 284 | -------------------------------------------------------------------------------- /Maru/Looper.js: -------------------------------------------------------------------------------- 1 | 2 | function Looper( controller , timer , params ){ 3 | 4 | this.controller = controller; 5 | this.params = _.defaults( params || {}, { 6 | 7 | beatsPerMinute: 120, 8 | beatsPerMeasure: 4, 9 | beatType: 4, 10 | measuresPerLoop: 4, // number of measures in loop 11 | 12 | }); 13 | 14 | this.timer = timer; 15 | 16 | this.beatsPerMinute = this.params.beatsPerMinute; 17 | this.bpm = this.beatsPerMinute; 18 | 19 | this.beatsPerSecond = this.bpm / 60; 20 | this.bps = this.beatsPerSecond; 21 | 22 | this.secondsPerBeat = 1 / this.bps; 23 | this.spb = this.secondsPerBeat; 24 | 25 | this.beatsPerMeasure = this.params.beatsPerMeasure; 26 | 27 | this.measureLength = this.spb * this.beatsPerMeasure; 28 | 29 | this.measuresPerLoop = this.params.measuresPerLoop; 30 | this.mpl = this.measuresPerLoop; 31 | 32 | this.loopLength = this.measureLength * this.mpl; 33 | 34 | this.measure = 0; 35 | this.oMeasure = 0; 36 | 37 | this.timeInMeasure = 0; 38 | this.measureStartTime = 0; 39 | this.percentOfMeasure = 0; 40 | this.oPercentOfMeasure = 0; 41 | 42 | this.timeInLoop = 0; 43 | this.loopStartTime = 0; 44 | this.percentOfLoop = 0; 45 | this.oPercentOfLoop = 0; 46 | 47 | this.loop = -1; 48 | this.oLoop = -1; 49 | 50 | this.hits = []; 51 | 52 | this.onNextLoopArray = []; 53 | this.onNextMeasureArray = []; 54 | this.everyLoopArray = []; 55 | 56 | this.controller.addToUpdateArray( this._update.bind( this ) ); 57 | 58 | 59 | } 60 | 61 | Looper.prototype._update = function(){ 62 | 63 | this.updateTime(); 64 | this.checkHits(); 65 | 66 | this.update(); 67 | 68 | } 69 | 70 | Looper.prototype.start =function(){ 71 | 72 | this._onNewLoop(); 73 | this._onNewMeasure(); 74 | 75 | } 76 | 77 | Looper.prototype.update = function(){ 78 | 79 | 80 | }; 81 | 82 | 83 | Looper.prototype.tweenGain = function( gainNode , newValue ){ 84 | 85 | var percentTilEnd = 1 - this.percentOfLoop; 86 | var timeTilEnd = percentTilEnd * this.loopLength; 87 | 88 | var endValue = newValue * 1; 89 | var i = { gain: gainNode.gain.value } 90 | var t = { gain: endValue } 91 | 92 | var tween = new TWEEN.Tween( i ).to( t , timeTilEnd * 1000 ); 93 | 94 | tween.easing( TWEEN.Easing.Quartic.In ) 95 | tween.gainNode = gainNode; 96 | tween.newValue = newValue; 97 | tween.endValue = endValue 98 | 99 | tween.onUpdate(function( ){ 100 | 101 | this.gainNode.gain.value = i.gain; 102 | 103 | }.bind(tween)); 104 | 105 | tween.onComplete( function(){ 106 | this.gain.value = newValue; 107 | }.bind( gainNode )); 108 | 109 | tween.start(); 110 | 111 | } 112 | 113 | Looper.prototype.onNextMeasure = function( callback ){ 114 | 115 | this.onNextMeasureArray.push( callback ) 116 | 117 | } 118 | 119 | Looper.prototype.onNextLoop = function( callback ){ 120 | 121 | this.onNextLoopArray.push( callback ) 122 | 123 | } 124 | 125 | Looper.prototype.everyLoop = function( callback ){ 126 | 127 | this.everyLoopArray.push( callback ); 128 | 129 | } 130 | 131 | 132 | 133 | Looper.prototype.updateTime = function(){ 134 | 135 | this.newMeasure = false; 136 | 137 | this.oPercentOfMeasure = this.percentOfMeasure; 138 | 139 | this.timeInMeasure = this.timer.value - this.measureStartTime; 140 | this.percentOfMeasure = this.timeInMeasure / this.measureLength; 141 | 142 | 143 | this.timeInLoop = this.timer.value - this.loopStartTime; 144 | this.percentOfLoop = this.timeInLoop / this.loopLength; 145 | 146 | 147 | if( this.percentOfLoop >= 1.0 ){ 148 | this._onNewLoop(); 149 | } 150 | 151 | if( this.percentOfMeasure >= 1.0 ){ 152 | this._onNewMeasure(); 153 | } 154 | 155 | 156 | } 157 | 158 | Looper.prototype._onNewLoop = function(){ 159 | 160 | 161 | this.oLoop = this.loop; 162 | 163 | this.loopStartTime += this.loopLength * this.percentOfLoop; 164 | this.loop += 1; 165 | 166 | this.newLoop = true; 167 | 168 | for( var i = 0; i < this.onNextLoopArray.length; i++ ){ 169 | 170 | this.onNextLoopArray[i](); 171 | 172 | } 173 | 174 | for( var i = 0; i < this.everyLoopArray.length; i++ ){ 175 | 176 | this.everyLoopArray[i](); 177 | 178 | } 179 | this.onNextLoopArray = []; 180 | this.onNewLoop(); 181 | 182 | 183 | } 184 | 185 | Looper.prototype.onNewLoop = function(){} 186 | 187 | Looper.prototype._onNewMeasure = function(){ 188 | 189 | this.oMeasure = this.measure; 190 | this.measure +=1; 191 | this.measureStartTime = this.measure * this.measureLength; 192 | 193 | this.newMeasure = true; 194 | 195 | 196 | for( var i = 0; i < this.onNextMeasureArray.length; i++ ){ 197 | this.onNextMeasureArray[i](); 198 | } 199 | 200 | this.onNextMeasureArray = []; 201 | 202 | this.onNewMeasure(); 203 | 204 | 205 | //this.measureInLoop = 206 | 207 | } 208 | 209 | 210 | Looper.prototype.onNewMeasure = function(){} 211 | 212 | Looper.prototype.addHit = function( callback , params ){ 213 | 214 | var hit = _.defaults( params || {}, { 215 | 216 | callback: callback, 217 | 218 | percents: [ .0 , .25 , .50 , .75 ], 219 | measureFrequency: 1, 220 | measureOffset: 0, 221 | duration: [ 0 , 1000000000 ], 222 | 223 | }); 224 | 225 | 226 | this.hits.push( hit ); 227 | 228 | } 229 | 230 | Looper.prototype.addSequence = function( callback , sequenceLength , hitArray , duration ){ 231 | 232 | for( var i = 0; i < hitArray.length; i++ ){ 233 | 234 | if( !duration ) duration = [0 , 10000000000 ]; 235 | this.addHit( callback , { 236 | 237 | measureFrequency: sequenceLength, 238 | measureOffset: hitArray[i][0], 239 | percents: hitArray[i][1], 240 | duration: duration 241 | 242 | }); 243 | 244 | } 245 | 246 | 247 | 248 | } 249 | 250 | Looper.prototype.checkHits = function(){ 251 | 252 | for( var i = 0; i < this.hits.length; i++ ){ 253 | 254 | var hit = this.hits[i]; 255 | 256 | var t = this.audio.time; 257 | 258 | // only check if within the duration of hit 259 | if( t >= hit.duration[0] && t <= hit.duration[1] ){ 260 | 261 | // only check if on proper measure 262 | if( this.measure % hit.measureFrequency == hit.measureOffset ){ 263 | 264 | for( var j = 0; j < hit.percents.length; j ++ ){ 265 | 266 | var p = hit.percents[j]; 267 | 268 | if( 269 | this.percentOfMeasure >= p && 270 | this.oPercentOfMeasure < p 271 | ){ 272 | 273 | 274 | hit.callback(); 275 | 276 | // In this case the percentage is at 0 277 | }else if( p == 0 && this.newMeasure ){ 278 | 279 | hit.callback(); 280 | 281 | } 282 | 283 | } 284 | 285 | } 286 | 287 | } 288 | 289 | } 290 | 291 | 292 | }; 293 | 294 | -------------------------------------------------------------------------------- /Maru/MaruBassKickLoop.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/MaruBassKickLoop.mp3 -------------------------------------------------------------------------------- /Maru/MaruBassModLoop.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/MaruBassModLoop.mp3 -------------------------------------------------------------------------------- /Maru/MaruBellALoop.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/MaruBellALoop.mp3 -------------------------------------------------------------------------------- /Maru/MaruBellBLoop.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/MaruBellBLoop.mp3 -------------------------------------------------------------------------------- /Maru/MaruBellBrightLoop.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/MaruBellBrightLoop.mp3 -------------------------------------------------------------------------------- /Maru/MaruBellCLoop.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/MaruBellCLoop.mp3 -------------------------------------------------------------------------------- /Maru/MaruClapLoop.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/MaruClapLoop.mp3 -------------------------------------------------------------------------------- /Maru/MaruHatsLoop.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/MaruHatsLoop.mp3 -------------------------------------------------------------------------------- /Maru/MaruHiupLoop.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/MaruHiupLoop.mp3 -------------------------------------------------------------------------------- /Maru/MaruIMPLoop.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/MaruIMPLoop.mp3 -------------------------------------------------------------------------------- /Maru/MaruKickLoop.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/MaruKickLoop.mp3 -------------------------------------------------------------------------------- /Maru/MaruLogritLoop.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/MaruLogritLoop.mp3 -------------------------------------------------------------------------------- /Maru/MaruLoops.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/MaruLoops.zip -------------------------------------------------------------------------------- /Maru/MaruLopanLoop.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/MaruLopanLoop.mp3 -------------------------------------------------------------------------------- /Maru/MaruModALoop.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/MaruModALoop.mp3 -------------------------------------------------------------------------------- /Maru/MaruModBLoop.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/MaruModBLoop.mp3 -------------------------------------------------------------------------------- /Maru/MaruRNLLoop.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/MaruRNLLoop.mp3 -------------------------------------------------------------------------------- /Maru/MaruRollLoop.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/MaruRollLoop.mp3 -------------------------------------------------------------------------------- /Maru/MaruSnareLoop.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/MaruSnareLoop.mp3 -------------------------------------------------------------------------------- /Maru/MaruUpmidLoop.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/MaruUpmidLoop.mp3 -------------------------------------------------------------------------------- /Maru/MaruVocLoop.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/MaruVocLoop.mp3 -------------------------------------------------------------------------------- /Maru/OBJLoader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | */ 4 | 5 | THREE.OBJLoader = function ( manager ) { 6 | 7 | this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager; 8 | 9 | }; 10 | 11 | THREE.OBJLoader.prototype = { 12 | 13 | constructor: THREE.OBJLoader, 14 | 15 | load: function ( url, onLoad, onProgress, onError ) { 16 | 17 | var scope = this; 18 | 19 | var loader = new THREE.XHRLoader( scope.manager ); 20 | loader.setCrossOrigin( this.crossOrigin ); 21 | loader.load( url, function ( text ) { 22 | 23 | onLoad( scope.parse( text ) ); 24 | 25 | } ); 26 | 27 | }, 28 | 29 | parse: function ( text ) { 30 | 31 | function vector( x, y, z ) { 32 | 33 | return new THREE.Vector3( parseFloat( x ), parseFloat( y ), parseFloat( z ) ); 34 | 35 | } 36 | 37 | function uv( u, v ) { 38 | 39 | return new THREE.Vector2( parseFloat( u ), parseFloat( v ) ); 40 | 41 | } 42 | 43 | function face3( a, b, c, normals ) { 44 | 45 | return new THREE.Face3( a, b, c, normals ); 46 | 47 | } 48 | 49 | var object = new THREE.Object3D(); 50 | var geometry, material, mesh; 51 | 52 | function parseVertexIndex( index ) { 53 | 54 | index = parseInt( index ); 55 | 56 | return index >= 0 ? index - 1 : index + vertices.length; 57 | 58 | } 59 | 60 | function parseNormalIndex( index ) { 61 | 62 | index = parseInt( index ); 63 | 64 | return index >= 0 ? index - 1 : index + normals.length; 65 | 66 | } 67 | 68 | function parseUVIndex( index ) { 69 | 70 | index = parseInt( index ); 71 | 72 | return index >= 0 ? index - 1 : index + uvs.length; 73 | 74 | } 75 | 76 | function add_face( a, b, c, normals_inds ) { 77 | 78 | if ( normals_inds === undefined ) { 79 | 80 | geometry.faces.push( face3( 81 | vertices[ parseVertexIndex( a ) ] - 1, 82 | vertices[ parseVertexIndex( b ) ] - 1, 83 | vertices[ parseVertexIndex( c ) ] - 1 84 | ) ); 85 | 86 | } else { 87 | 88 | geometry.faces.push( face3( 89 | vertices[ parseVertexIndex( a ) ] - 1, 90 | vertices[ parseVertexIndex( b ) ] - 1, 91 | vertices[ parseVertexIndex( c ) ] - 1, 92 | [ 93 | normals[ parseNormalIndex( normals_inds[ 0 ] ) ].clone(), 94 | normals[ parseNormalIndex( normals_inds[ 1 ] ) ].clone(), 95 | normals[ parseNormalIndex( normals_inds[ 2 ] ) ].clone() 96 | ] 97 | ) ); 98 | 99 | } 100 | 101 | } 102 | 103 | function add_uvs( a, b, c ) { 104 | 105 | geometry.faceVertexUvs[ 0 ].push( [ 106 | uvs[ parseUVIndex( a ) ].clone(), 107 | uvs[ parseUVIndex( b ) ].clone(), 108 | uvs[ parseUVIndex( c ) ].clone() 109 | ] ); 110 | 111 | } 112 | 113 | function handle_face_line(faces, uvs, normals_inds) { 114 | 115 | if ( faces[ 3 ] === undefined ) { 116 | 117 | add_face( faces[ 0 ], faces[ 1 ], faces[ 2 ], normals_inds ); 118 | 119 | if ( uvs !== undefined && uvs.length > 0 ) { 120 | 121 | add_uvs( uvs[ 0 ], uvs[ 1 ], uvs[ 2 ] ); 122 | 123 | } 124 | 125 | } else { 126 | 127 | if ( normals_inds !== undefined && normals_inds.length > 0 ) { 128 | 129 | add_face( faces[ 0 ], faces[ 1 ], faces[ 3 ], [ normals_inds[ 0 ], normals_inds[ 1 ], normals_inds[ 3 ] ] ); 130 | add_face( faces[ 1 ], faces[ 2 ], faces[ 3 ], [ normals_inds[ 1 ], normals_inds[ 2 ], normals_inds[ 3 ] ] ); 131 | 132 | } else { 133 | 134 | add_face( faces[ 0 ], faces[ 1 ], faces[ 3 ] ); 135 | add_face( faces[ 1 ], faces[ 2 ], faces[ 3 ] ); 136 | 137 | } 138 | 139 | if ( uvs !== undefined && uvs.length > 0 ) { 140 | 141 | add_uvs( uvs[ 0 ], uvs[ 1 ], uvs[ 3 ] ); 142 | add_uvs( uvs[ 1 ], uvs[ 2 ], uvs[ 3 ] ); 143 | 144 | } 145 | 146 | } 147 | 148 | } 149 | 150 | // create mesh if no objects in text 151 | 152 | if ( /^o /gm.test( text ) === false ) { 153 | 154 | geometry = new THREE.Geometry(); 155 | material = new THREE.MeshLambertMaterial(); 156 | mesh = new THREE.Mesh( geometry, material ); 157 | object.add( mesh ); 158 | 159 | } 160 | 161 | var vertices = []; 162 | var normals = []; 163 | var uvs = []; 164 | 165 | // v float float float 166 | 167 | var vertex_pattern = /v( +[\d|\.|\+|\-|e]+)( +[\d|\.|\+|\-|e]+)( +[\d|\.|\+|\-|e]+)/; 168 | 169 | // vn float float float 170 | 171 | var normal_pattern = /vn( +[\d|\.|\+|\-|e]+)( +[\d|\.|\+|\-|e]+)( +[\d|\.|\+|\-|e]+)/; 172 | 173 | // vt float float 174 | 175 | var uv_pattern = /vt( +[\d|\.|\+|\-|e]+)( +[\d|\.|\+|\-|e]+)/; 176 | 177 | // f vertex vertex vertex ... 178 | 179 | var face_pattern1 = /f( +-?\d+)( +-?\d+)( +-?\d+)( +-?\d+)?/; 180 | 181 | // f vertex/uv vertex/uv vertex/uv ... 182 | 183 | var face_pattern2 = /f( +(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+))?/; 184 | 185 | // f vertex/uv/normal vertex/uv/normal vertex/uv/normal ... 186 | 187 | var face_pattern3 = /f( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))( +(-?\d+)\/(-?\d+)\/(-?\d+))?/; 188 | 189 | // f vertex//normal vertex//normal vertex//normal ... 190 | 191 | var face_pattern4 = /f( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))( +(-?\d+)\/\/(-?\d+))?/ 192 | 193 | // 194 | 195 | var lines = text.split( '\n' ); 196 | 197 | for ( var i = 0; i < lines.length; i ++ ) { 198 | 199 | var line = lines[ i ]; 200 | line = line.trim(); 201 | 202 | var result; 203 | 204 | if ( line.length === 0 || line.charAt( 0 ) === '#' ) { 205 | 206 | continue; 207 | 208 | } else if ( ( result = vertex_pattern.exec( line ) ) !== null ) { 209 | 210 | // ["v 1.0 2.0 3.0", "1.0", "2.0", "3.0"] 211 | 212 | vertices.push( 213 | geometry.vertices.push( 214 | vector( 215 | result[ 1 ], result[ 2 ], result[ 3 ] 216 | ) 217 | ) 218 | ); 219 | 220 | } else if ( ( result = normal_pattern.exec( line ) ) !== null ) { 221 | 222 | // ["vn 1.0 2.0 3.0", "1.0", "2.0", "3.0"] 223 | 224 | normals.push( 225 | vector( 226 | result[ 1 ], result[ 2 ], result[ 3 ] 227 | ) 228 | ); 229 | 230 | } else if ( ( result = uv_pattern.exec( line ) ) !== null ) { 231 | 232 | // ["vt 0.1 0.2", "0.1", "0.2"] 233 | 234 | uvs.push( 235 | uv( 236 | result[ 1 ], result[ 2 ] 237 | ) 238 | ); 239 | 240 | } else if ( ( result = face_pattern1.exec( line ) ) !== null ) { 241 | 242 | // ["f 1 2 3", "1", "2", "3", undefined] 243 | 244 | handle_face_line( 245 | [ result[ 1 ], result[ 2 ], result[ 3 ], result[ 4 ] ] 246 | ); 247 | 248 | } else if ( ( result = face_pattern2.exec( line ) ) !== null ) { 249 | 250 | // ["f 1/1 2/2 3/3", " 1/1", "1", "1", " 2/2", "2", "2", " 3/3", "3", "3", undefined, undefined, undefined] 251 | 252 | handle_face_line( 253 | [ result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ] ], //faces 254 | [ result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ] ] //uv 255 | ); 256 | 257 | } else if ( ( result = face_pattern3.exec( line ) ) !== null ) { 258 | 259 | // ["f 1/1/1 2/2/2 3/3/3", " 1/1/1", "1", "1", "1", " 2/2/2", "2", "2", "2", " 3/3/3", "3", "3", "3", undefined, undefined, undefined, undefined] 260 | 261 | handle_face_line( 262 | [ result[ 2 ], result[ 6 ], result[ 10 ], result[ 14 ] ], //faces 263 | [ result[ 3 ], result[ 7 ], result[ 11 ], result[ 15 ] ], //uv 264 | [ result[ 4 ], result[ 8 ], result[ 12 ], result[ 16 ] ] //normal 265 | ); 266 | 267 | } else if ( ( result = face_pattern4.exec( line ) ) !== null ) { 268 | 269 | // ["f 1//1 2//2 3//3", " 1//1", "1", "1", " 2//2", "2", "2", " 3//3", "3", "3", undefined, undefined, undefined] 270 | 271 | handle_face_line( 272 | [ result[ 2 ], result[ 5 ], result[ 8 ], result[ 11 ] ], //faces 273 | [ ], //uv 274 | [ result[ 3 ], result[ 6 ], result[ 9 ], result[ 12 ] ] //normal 275 | ); 276 | 277 | } else if ( /^o /.test( line ) ) { 278 | 279 | geometry = new THREE.Geometry(); 280 | material = new THREE.MeshLambertMaterial(); 281 | 282 | mesh = new THREE.Mesh( geometry, material ); 283 | mesh.name = line.substring( 2 ).trim(); 284 | object.add( mesh ); 285 | 286 | } else if ( /^g /.test( line ) ) { 287 | 288 | // group 289 | 290 | } else if ( /^usemtl /.test( line ) ) { 291 | 292 | // material 293 | 294 | material.name = line.substring( 7 ).trim(); 295 | 296 | } else if ( /^mtllib /.test( line ) ) { 297 | 298 | // mtl file 299 | 300 | } else if ( /^s /.test( line ) ) { 301 | 302 | // smooth shading 303 | 304 | } else { 305 | 306 | // console.log( "THREE.OBJLoader: Unhandled line " + line ); 307 | 308 | } 309 | 310 | } 311 | 312 | var children = object.children; 313 | 314 | for ( var i = 0, l = children.length; i < l; i ++ ) { 315 | 316 | var geometry = children[ i ].geometry; 317 | 318 | geometry.computeFaceNormals(); 319 | geometry.computeBoundingSphere(); 320 | 321 | } 322 | 323 | return object; 324 | 325 | } 326 | 327 | }; -------------------------------------------------------------------------------- /Maru/ObjectControls.js: -------------------------------------------------------------------------------- 1 | // TODO Make it so you can pass in renderer w / h 2 | function ObjectControls( eye , params ){ 3 | 4 | this.intersected; 5 | this.selected; 6 | 7 | this.eye = eye; 8 | 9 | this.mouse = new THREE.Vector3(); 10 | this.unprojectedMouse = new THREE.Vector3(); 11 | 12 | this.objects = []; 13 | 14 | var params = params || {}; 15 | var p = params; 16 | 17 | this.domElement = p.domElement || document; 18 | 19 | // Recursively check descendants of objects in this.objects for intersections. 20 | this.recursive = p.recursive || false; 21 | 22 | this.raycaster = new THREE.Raycaster(); 23 | 24 | this.raycaster.near = this.eye.near; 25 | this.raycaster.far = this.eye.far; 26 | 27 | 28 | var addListener = this.domElement.addEventListener; 29 | 30 | var cb1 = this.mouseDown.bind( this ); 31 | var cb2 = this.mouseUp.bind( this ); 32 | var cb3 = this.mouseMove.bind( this ); 33 | 34 | this.domElement.addEventListener( 'mousedown', cb1 , false ) 35 | this.domElement.addEventListener( 'mouseup' , cb2 , false ) 36 | this.domElement.addEventListener( 'mousemove', cb3 , false ) 37 | 38 | this.domElement.addEventListener( 'touchdown', cb1 , false ) 39 | this.domElement.addEventListener( 'touchup' , cb2 , false ) 40 | this.domElement.addEventListener( 'touchmove', cb3 , false ) 41 | 42 | this.unprojectMouse(); 43 | 44 | } 45 | 46 | 47 | 48 | 49 | /* 50 | 51 | EVENTS 52 | 53 | */ 54 | 55 | 56 | // You can think of _up and _down as mouseup and mouse down 57 | ObjectControls.prototype._down = function(){ 58 | 59 | this.down(); 60 | 61 | if( this.intersected ){ 62 | 63 | this._select( this.intersected ); 64 | 65 | } 66 | 67 | } 68 | 69 | ObjectControls.prototype.down = function(){} 70 | 71 | 72 | 73 | ObjectControls.prototype._up = function(){ 74 | 75 | this.up(); 76 | 77 | if( this.selected ){ 78 | 79 | this._deselect( this.selected ); 80 | 81 | } 82 | 83 | } 84 | 85 | ObjectControls.prototype.up = function(){} 86 | 87 | 88 | 89 | ObjectControls.prototype._hoverOut = function( object ){ 90 | 91 | this.hoverOut(); 92 | 93 | this.objectHovered = false; 94 | 95 | if( object.hoverOut ){ 96 | object.hoverOut( this ); 97 | } 98 | 99 | }; 100 | 101 | ObjectControls.prototype.hoverOut = function(){}; 102 | 103 | 104 | 105 | ObjectControls.prototype._hoverOver = function( object ){ 106 | 107 | this.hoverOver(); 108 | 109 | this.objectHovered = true; 110 | 111 | if( object.hoverOver ){ 112 | object.hoverOver( this ); 113 | } 114 | 115 | }; 116 | 117 | ObjectControls.prototype.hoverOver = function(){} 118 | 119 | 120 | 121 | ObjectControls.prototype._select = function( object ){ 122 | 123 | this.select(); 124 | 125 | var intersectionPoint = this.getIntersectionPoint( this.intersected ); 126 | 127 | this.selected = object; 128 | this.intersectionPoint = intersectionPoint; 129 | 130 | if( object.select ){ 131 | object.select( this ); 132 | } 133 | 134 | }; 135 | 136 | ObjectControls.prototype.select = function(){} 137 | 138 | 139 | 140 | ObjectControls.prototype._deselect = function( object ){ 141 | 142 | //console.log('DESELECT'); 143 | 144 | this.selected = undefined; 145 | this.intersectionPoint = undefined; 146 | 147 | if( object.deselect ){ 148 | object.deselect( this ); 149 | } 150 | 151 | this.deselect(); 152 | 153 | }; 154 | 155 | ObjectControls.prototype.deselect = function(){} 156 | 157 | 158 | 159 | 160 | /* 161 | 162 | Changing what objects we are controlling 163 | 164 | */ 165 | 166 | ObjectControls.prototype.add = function( object ){ 167 | 168 | this.objects.push( object ); 169 | 170 | }; 171 | 172 | ObjectControls.prototype.remove = function( object ){ 173 | 174 | for( var i = 0; i < this.objects.length; i++ ){ 175 | 176 | if( this.objects[i] == object ){ 177 | 178 | this.objects.splice( i , 1 ); 179 | 180 | } 181 | 182 | } 183 | 184 | }; 185 | 186 | 187 | 188 | 189 | /* 190 | 191 | Update Loop 192 | 193 | */ 194 | 195 | ObjectControls.prototype.update = function(){ 196 | 197 | this.setRaycaster( this.unprojectedMouse ); 198 | if( !this.selected ){ 199 | 200 | this.checkForIntersections( this.unprojectedMouse ); 201 | 202 | }else{ 203 | 204 | this._updateSelected( this.unprojectedMouse ); 205 | 206 | } 207 | 208 | }; 209 | 210 | ObjectControls.prototype._updateSelected = function(){ 211 | 212 | if( this.selected.update ){ 213 | 214 | this.selected.update( this ); 215 | 216 | } 217 | 218 | } 219 | 220 | ObjectControls.prototype.updateSelected = function(){}; 221 | 222 | 223 | 224 | 225 | ObjectControls.prototype.setRaycaster = function( position ){ 226 | 227 | var origin = position; 228 | var direction = origin.clone() 229 | 230 | direction.sub( this.eye.position ); 231 | direction.normalize(); 232 | 233 | this.raycaster.set( this.eye.position , direction ); 234 | 235 | } 236 | 237 | 238 | 239 | /* 240 | 241 | Checks 242 | 243 | */ 244 | 245 | ObjectControls.prototype.checkForIntersections = function( position ){ 246 | 247 | var intersected = this.raycaster.intersectObjects( this.objects, this.recursive ); 248 | 249 | 250 | if( intersected.length > 0 ){ 251 | 252 | for (var n = 0; n < intersected.length; n++ ) { 253 | 254 | if ( this.recursive ) { 255 | 256 | var topLevelObj = this._findTopLevelAncestor( intersected[n].object ); 257 | if ( topLevelObj ) { 258 | 259 | // Reset intersected.object, leave intersected.point etc. unchanged. 260 | // This works since in the two most common use cases the ancestor: 261 | // (1) contains the child object (and the intersection point) 262 | // (2) is not a THREE.Mesh and thus doesn't appear in the scene, 263 | // e.g. an Object3D used for grouping other related objects. 264 | intersected[n].object = topLevelObj; 265 | 266 | } 267 | 268 | } 269 | 270 | } 271 | 272 | this._objectIntersected( intersected ); 273 | 274 | }else{ 275 | 276 | this._noObjectIntersected(); 277 | 278 | } 279 | 280 | }; 281 | 282 | ObjectControls.prototype.checkForUpDown = function( hand , oHand ){ 283 | 284 | if( this.upDownEvent( this.selectionStrength , hand , oHand ) === true ){ 285 | 286 | this._down(); 287 | 288 | }else if( this.upDownEvent( this.selectionStrength , hand , oHand ) === false ){ 289 | 290 | this._up(); 291 | 292 | } 293 | 294 | }; 295 | 296 | 297 | 298 | 299 | ObjectControls.prototype.getIntersectionPoint = function( i ){ 300 | 301 | var intersected = this.raycaster.intersectObjects( this.objects, this.recursive ); 302 | 303 | return intersected[0].point.sub( i.position ); 304 | 305 | } 306 | 307 | ObjectControls.prototype._findTopLevelAncestor = function( object ){ 308 | 309 | // Traverse back up until we find the first ancestor that is a top-level 310 | // object then return it (or null), since only top-level objects (which 311 | // were passed to objectControls.add) handle events, even if their child 312 | // objects are the ones intersected. 313 | 314 | while ( this.objects.indexOf(object) === -1) { 315 | 316 | if ( !object.parent ) { 317 | 318 | return null; 319 | 320 | } 321 | 322 | object = object.parent; 323 | 324 | } 325 | 326 | return object; 327 | 328 | } 329 | 330 | 331 | 332 | /* 333 | 334 | Raycast Events 335 | 336 | */ 337 | 338 | ObjectControls.prototype._objectIntersected = function( intersected ){ 339 | 340 | // Assigning out first intersected object 341 | // so we don't get changes everytime we hit 342 | // a new face 343 | var firstIntersection = intersected[0].object; 344 | 345 | if( !this.intersected ){ 346 | 347 | this.intersected = firstIntersection; 348 | 349 | this._hoverOver( this.intersected ); 350 | 351 | 352 | }else{ 353 | 354 | if( this.intersected != firstIntersection ){ 355 | 356 | this._hoverOut( this.intersected ); 357 | 358 | this.intersected = firstIntersection; 359 | 360 | this._hoverOver( this.intersected ); 361 | 362 | } 363 | 364 | } 365 | 366 | this.objectIntersected(); 367 | 368 | }; 369 | 370 | ObjectControls.prototype.objectIntersected = function(){} 371 | 372 | ObjectControls.prototype._noObjectIntersected = function(){ 373 | 374 | if( this.intersected ){ 375 | 376 | this._hoverOut( this.intersected ); 377 | this.intersected = undefined; 378 | 379 | } 380 | 381 | this.noObjectIntersected(); 382 | 383 | }; 384 | 385 | ObjectControls.prototype.noObjectIntersected = function(){} 386 | 387 | 388 | ObjectControls.prototype.mouseMove = function(event){ 389 | 390 | this.mouseMoved = true; 391 | 392 | this.mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1; 393 | this.mouse.y = -( event.clientY / window.innerHeight ) * 2 + 1; 394 | this.mouse.z = 1; 395 | 396 | this.unprojectMouse(); 397 | 398 | } 399 | 400 | ObjectControls.prototype.unprojectMouse = function(){ 401 | 402 | this.unprojectedMouse.copy( this.mouse ); 403 | this.unprojectedMouse.unproject( this.eye ); 404 | 405 | } 406 | 407 | ObjectControls.prototype.mouseDown = function( event ){ 408 | this.mouseMove( event ); 409 | this._down(); 410 | } 411 | 412 | ObjectControls.prototype.mouseUp = function(){ 413 | this.mouseMove( event ); 414 | this._up(); 415 | } 416 | 417 | 418 | ObjectControls.prototype.touchStart = function(event){ 419 | this.touchMove( event ); 420 | this._down(); 421 | } 422 | 423 | ObjectControls.prototype.touchEnd = function(event){ 424 | this.touchMove( event ); 425 | this._up(); 426 | } 427 | 428 | ObjectControls.prototype.touchMove= function(event){ 429 | 430 | this.mouseMoved = true; 431 | 432 | this.mouse.x = ( event.touches[ 0 ].pageX / window.innerWidth ) * 2 - 1; 433 | this.mouse.y = -( event.touches[ 0 ].pageY / window.innerHeight ) * 2 + 1; 434 | this.mouse.z = 1; 435 | 436 | this.unprojectMouse(); 437 | 438 | } 439 | -------------------------------------------------------------------------------- /Maru/ParticleUtils.js: -------------------------------------------------------------------------------- 1 | var ParticleUtils = { 2 | 3 | 4 | /* From @mrdoob's Sporel Demo */ 5 | createPositionsTexture: function( size , mesh ){ 6 | 7 | var geometry = new THREE.Geometry(); 8 | 9 | geometry.merge( mesh.geometry , mesh.matrix ); 10 | 11 | var point = new THREE.Vector3(); 12 | var facesLength = geometry.faces.length; 13 | 14 | var data = new Float32Array( size * size * 4 ); 15 | 16 | for ( var i = 0, l = data.length; i < l; i += 4 ) { 17 | 18 | var face = geometry.faces[ Math.floor( Math.random() * facesLength ) ]; 19 | 20 | var vertex1 = geometry.vertices[ face.a ]; 21 | var vertex2 = geometry.vertices[ Math.random() > 0.5 ? face.b : face.c ]; 22 | 23 | point.subVectors( vertex2, vertex1 ); 24 | point.multiplyScalar( Math.random() ); 25 | point.add( vertex1 ); 26 | 27 | data[ i ] = point.x; 28 | data[ i + 1 ] = point.y; 29 | data[ i + 2 ] = point.z; 30 | data[ i + 3 ] = 1; 31 | 32 | } 33 | 34 | var positionsTexture = new THREE.DataTexture( 35 | data, 36 | size, 37 | size, 38 | THREE.RGBAFormat, 39 | THREE.FloatType 40 | ); 41 | 42 | positionsTexture.minFilter = THREE.NearestFilter; 43 | positionsTexture.magFilter = THREE.NearestFilter; 44 | positionsTexture.generateMipmaps = false; 45 | positionsTexture.needsUpdate = true; 46 | 47 | positionsTexture.mesh = mesh; 48 | 49 | return positionsTexture; 50 | 51 | }, 52 | 53 | 54 | createLookupGeometry: function( size ){ 55 | 56 | var geo = new THREE.BufferGeometry(); 57 | 58 | // geo.addAttribute( 'position', Float32Array , size * size , 3 ); 59 | 60 | var pos = new THREE.BufferAttribute( new Float32Array( size * size * 3 ) , 3 ); 61 | 62 | var positions = pos.array; 63 | 64 | for ( var i = 0, j = 0, l = positions.length / 3; i < l; i ++, j += 3 ) { 65 | 66 | positions[ j ] = ( i % size ) / size; 67 | positions[ j + 1 ] = Math.floor( i / size ) / size; 68 | //positions[ j + 2 ] = Math.sin( (i / size) * Math.PI ); 69 | 70 | } 71 | 72 | geo.addAttribute( 'position', pos ); 73 | 74 | 75 | return geo; 76 | 77 | }, 78 | 79 | 80 | 81 | createParticleLookupGeometry: function( size ){ 82 | 83 | 84 | 85 | var geo = new THREE.BufferGeometry(); 86 | 87 | //var posBuffer = new THREE.BufferAttribute( new Float32Array( 32 * 32 * 4 ) , 3 ); 88 | 89 | var positions = []; 90 | var uvs = []; 91 | var indices = []; 92 | 93 | 94 | for ( var i = 0; i < size * size; i++ ) { 95 | 96 | positions[ i * 4 * 3 + 0 ] = ( i % size ) / size; 97 | positions[ i * 4 * 3 + 1 ] = Math.floor( i / size ) / size; 98 | positions[ i * 4 * 3 + 2 ] = 0; 99 | 100 | positions[ i * 4 * 3 + 3 ] = ( i % size ) / size; 101 | positions[ i * 4 * 3 + 4 ] = Math.floor( i / size ) / size; 102 | positions[ i * 4 * 3 + 5 ] = 0; 103 | 104 | positions[ i * 4 * 3 + 6 ] = ( i % size ) / size; 105 | positions[ i * 4 * 3 + 7 ] = Math.floor( i / size ) / size; 106 | positions[ i * 4 * 3 + 8 ] = 0; 107 | 108 | positions[ i * 4 * 3 + 9 ] = ( i % size ) / size; 109 | positions[ i * 4 * 3 + 10 ] = Math.floor( i / size ) / size; 110 | positions[ i * 4 * 3 + 11 ] = 0; 111 | 112 | 113 | uvs[ i * 4 * 2 + 0 ] = 0; 114 | uvs[ i * 4 * 2 + 1 ] = 0; 115 | 116 | uvs[ i * 4 * 2 + 2 ] = 1; 117 | uvs[ i * 4 * 2 + 3 ] = 0; 118 | 119 | uvs[ i * 4 * 2 + 4 ] = 0; 120 | uvs[ i * 4 * 2 + 5 ] = 1; 121 | 122 | uvs[ i * 4 * 2 + 6 ] = 1; 123 | uvs[ i * 4 * 2 + 7 ] = 1; 124 | 125 | 126 | //uvs[ j + 2 ] = Math.sin( (i / size) * Math.PI ); 127 | 128 | } 129 | 130 | 131 | for( var i = 0; i < size*size; i++ ){ 132 | 133 | indices.push( i * 4 + 0 ); 134 | indices.push( i * 4 + 3 ); 135 | indices.push( i * 4 + 1 ); 136 | indices.push( i * 4 + 0 ); 137 | indices.push( i * 4 + 2 ); 138 | indices.push( i * 4 + 3 ); 139 | 140 | } 141 | 142 | 143 | geo.setIndex(indices); 144 | geo.addAttribute('position',new THREE.Float32BufferAttribute(positions,3)); 145 | geo.addAttribute('uv2',new THREE.Float32BufferAttribute(uvs,2)); 146 | 147 | 148 | return geo; 149 | 150 | } 151 | 152 | } 153 | -------------------------------------------------------------------------------- /Maru/PhysicsRenderer.js: -------------------------------------------------------------------------------- 1 | function PhysicsRenderer( size , shader , renderer ){ 2 | 3 | // First Make sure everything Works 4 | this.checkCompatibility( renderer ); 5 | this.renderer = renderer; 6 | 7 | this.size = size || 128; 8 | this.s2 = size * size; 9 | 10 | this.renderer = renderer; 11 | 12 | this.clock = new THREE.Clock(); 13 | 14 | 15 | // Sets up our render targets 16 | this.rt_1 = new THREE.WebGLRenderTarget( this.size, this.size, { 17 | minFilter: THREE.NearestFilter, 18 | magFilter: THREE.NearestFilter, 19 | format: THREE.RGBAFormat, 20 | type:THREE.FloatType, 21 | stencilBuffer: false 22 | }); 23 | 24 | this.rt_2 = this.rt_1.clone(); 25 | this.rt_3 = this.rt_1.clone(); 26 | 27 | this.counter = 0; 28 | 29 | this.debugScene = this.createDebugScene(); 30 | this.texturePassProgram = this.createTexturePassProgram(); 31 | 32 | // WHERE THE MAGIC HAPPENS 33 | this.simulation = this.createSimulationProgram( shader ); 34 | this.material = this.simulation; 35 | 36 | this.boundTextures = []; 37 | 38 | /* 39 | 40 | GPGPU Utilities 41 | From Sporel by Mr.Doob 42 | @author mrdoob / http://www.mrdoob.com 43 | 44 | */ 45 | 46 | this.camera = new THREE.OrthographicCamera( - 0.5, 0.5, 0.5, - 0.5, 0, 1 ); 47 | this.scene = new THREE.Scene(); 48 | this.mesh = new THREE.Mesh( new THREE.PlaneGeometry( 1, 1 ) ); 49 | this.scene.add( this.mesh ); 50 | 51 | } 52 | 53 | PhysicsRenderer.prototype.checkCompatibility = function( renderer ){ 54 | 55 | var gl = renderer.context; 56 | 57 | if ( gl.getExtension( "OES_texture_float" ) === null ) { 58 | this.onError( "No Float Textures"); 59 | return; 60 | } 61 | 62 | if ( gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ) === 0 ) { 63 | this.onError( "Vert Shader Textures don't work"); 64 | return; 65 | } 66 | 67 | } 68 | 69 | PhysicsRenderer.prototype.onError = function( e ){ 70 | console.log( e ); 71 | } 72 | 73 | PhysicsRenderer.prototype.createDebugScene= function(){ 74 | 75 | var debugScene = new THREE.Object3D(); 76 | debugScene.position.z = 0; 77 | 78 | var geo = new THREE.PlaneGeometry( 100 , 100 ); 79 | 80 | var debugMesh = new THREE.Mesh( geo , new THREE.MeshBasicMaterial({ 81 | map: this.rt_1 82 | })); 83 | debugMesh.position.set( -105 , 0 , 0 ); 84 | 85 | debugScene.add( debugMesh ); 86 | 87 | var debugMesh = new THREE.Mesh( geo , new THREE.MeshBasicMaterial({ 88 | map: this.rt_2 89 | })); 90 | debugMesh.position.set( 0 , 0 , 0 ); 91 | debugScene.add( debugMesh ); 92 | 93 | var debugMesh = new THREE.Mesh( geo , new THREE.MeshBasicMaterial({ 94 | map: this.rt_3 95 | })); 96 | debugMesh.position.set( 105, 0 , 0 ); 97 | debugScene.add( debugMesh ); 98 | 99 | return debugScene; 100 | 101 | } 102 | 103 | PhysicsRenderer.prototype.removeDebugScene = function( scene ){ 104 | scene.remove( this.debugScene ); 105 | } 106 | 107 | PhysicsRenderer.prototype.addDebugScene = function( scene ){ 108 | scene.add( this.debugScene ); 109 | } 110 | 111 | 112 | PhysicsRenderer.prototype.createTexturePassProgram = function(){ 113 | 114 | var uniforms = { 115 | texture:{ type:"t" , value:null }, 116 | } 117 | 118 | var texturePassShader = new THREE.ShaderMaterial({ 119 | uniforms:uniforms, 120 | vertexShader:this.VSPass, 121 | fragmentShader:this.FSPass, 122 | }); 123 | 124 | return texturePassShader; 125 | 126 | } 127 | 128 | PhysicsRenderer.prototype.createSimulationProgram = function(sim){ 129 | 130 | this.simulationUniforms = { 131 | t_oPos:{ type:"t" , value:null }, 132 | t_pos:{ type:"t" , value:null }, 133 | } 134 | 135 | 136 | var program = new THREE.ShaderMaterial({ 137 | 138 | uniforms:this.simulationUniforms, 139 | vertexShader:this.VSPass, 140 | fragmentShader:sim 141 | 142 | }); 143 | 144 | return program; 145 | 146 | } 147 | 148 | 149 | PhysicsRenderer.prototype.VSPass = [ 150 | "varying vec2 vUv;", 151 | "void main() {", 152 | " vUv = uv;", 153 | " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 154 | "}" 155 | ].join("\n"); 156 | 157 | PhysicsRenderer.prototype.FSPass = [ 158 | "uniform sampler2D texture;", 159 | "varying vec2 vUv;", 160 | "void main() {", 161 | " vec4 c = texture2D( texture , vUv );", 162 | " gl_FragColor = c ;", 163 | "}" 164 | ].join("\n"); 165 | 166 | 167 | PhysicsRenderer.prototype.update = function(){ 168 | 169 | var flipFlop = this.counter % 3; 170 | 171 | if( flipFlop == 0 ){ 172 | 173 | this.simulation.uniforms.t_oPos.value = this.rt_1; 174 | this.simulation.uniforms.t_pos.value = this.rt_2; 175 | 176 | this.pass( this.simulation, this.rt_3 ); 177 | 178 | this.ooOutput = this.rt_1; 179 | this.oOutput = this.rt_2; 180 | this.output = this.rt_3; 181 | 182 | }else if( flipFlop == 1 ){ 183 | 184 | this.simulation.uniforms.t_oPos.value = this.rt_2; 185 | this.simulation.uniforms.t_pos.value = this.rt_3; 186 | 187 | this.pass( this.simulation , this.rt_1 ); 188 | 189 | this.ooOutput = this.rt_2; 190 | this.oOutput = this.rt_3; 191 | this.output = this.rt_1; 192 | 193 | 194 | }else if( flipFlop == 2 ){ 195 | 196 | this.simulation.uniforms.t_oPos.value = this.rt_3; 197 | this.simulation.uniforms.t_pos.value = this.rt_1; 198 | 199 | this.pass( this.simulation , this.rt_2 ); 200 | 201 | this.ooOutput = this.rt_3; 202 | this.oOutput = this.rt_1; 203 | this.output = this.rt_2; 204 | 205 | } 206 | 207 | this.counter ++; 208 | 209 | this.bindTextures(); 210 | 211 | } 212 | 213 | // Some GPGPU Utilities author: @mrdoob 214 | PhysicsRenderer.prototype.render = function ( scene, camera, target ) { 215 | renderer.render( scene, camera, target, false ); 216 | }; 217 | 218 | PhysicsRenderer.prototype.pass = function ( shader , target ) { 219 | this.mesh.material = shader; 220 | this.renderer.render( this.scene, this.camera, target, false ); 221 | }; 222 | 223 | PhysicsRenderer.prototype.out = function ( shader ) { 224 | this.mesh.material = shader.material; 225 | this.renderer.render( this.scene, this.camera ); 226 | }; 227 | 228 | // Used if he have uniforms we want to update! 229 | PhysicsRenderer.prototype.setUniforms = function( uniforms ){ 230 | 231 | this.simulation.uniforms = uniforms || {}; 232 | 233 | // Have to make sure that these always remain! 234 | this.simulation.uniforms.t_pos = { value:"t" , value:null }; 235 | this.simulation.uniforms.t_oPos = { value:"t" , value:null }; 236 | 237 | console.log( this.simulation.uniforms ); 238 | 239 | } 240 | 241 | PhysicsRenderer.prototype.setUniform = function( name , u ){ 242 | this.simulation.uniforms[name] = u; 243 | } 244 | 245 | // resets the render targets to the from position 246 | PhysicsRenderer.prototype.reset = function( texture ){ 247 | 248 | this.texture = texture; 249 | this.texturePassProgram.uniforms.texture.value = texture; 250 | 251 | this.pass( this.texturePassProgram , this.rt_1 ); 252 | this.pass( this.texturePassProgram , this.rt_2 ); 253 | this.pass( this.texturePassProgram , this.rt_3 ); 254 | 255 | } 256 | 257 | PhysicsRenderer.prototype.addBoundTexture = function( system , uniform , value ){ 258 | this.boundTextures.push( [ system , uniform , value ] ); 259 | } 260 | 261 | PhysicsRenderer.prototype.bindTextures = function(){ 262 | 263 | for( var i = 0; i < this.boundTextures.length; i++ ){ 264 | 265 | var boundSystem = this.boundTextures[i][0]; 266 | var boundUniform = this.boundTextures[i][1]; 267 | var textureToBind = this.boundTextures[i][2]; 268 | 269 | if( !boundSystem.material ){ 270 | console.log( boundSystem ); 271 | console.log( boundUniform ); 272 | } 273 | 274 | var uniform = boundSystem.material.uniforms[ boundUniform ]; 275 | 276 | uniform.value = this[ textureToBind ]; 277 | 278 | 279 | } 280 | 281 | } 282 | 283 | -------------------------------------------------------------------------------- /Maru/PosVelSimulation.js: -------------------------------------------------------------------------------- 1 | function PosVelSimulation( size , posShader , velShader , renderer ){ 2 | 3 | // First Make sure everything Works 4 | this.checkCompatibility( renderer ); 5 | this.renderer = renderer; 6 | 7 | this.size = size || 128; 8 | this.s2 = size * size; 9 | 10 | this.renderer = renderer; 11 | 12 | this.clock = new THREE.Clock(); 13 | 14 | 15 | // Sets up our render targets 16 | this.rt_pos1 = new THREE.WebGLRenderTarget( this.size, this.size, { 17 | minFilter: THREE.NearestFilter, 18 | magFilter: THREE.NearestFilter, 19 | format: THREE.RGBAFormat, 20 | type:THREE.FloatType, 21 | stencilBuffer: false 22 | }); 23 | 24 | this.rt_pos2 = this.rt_pos1.clone(); 25 | this.rt_vel1 = this.rt_pos1.clone(); 26 | this.rt_vel2 = this.rt_pos1.clone(); 27 | 28 | this.counter = 0; 29 | 30 | this.debugScene = this.createDebugScene(); 31 | this.texturePassProgram = this.createTexturePassProgram(); 32 | 33 | // WHERE THE MAGIC HAPPENS 34 | this.posSimulation = this.createSimulationProgram( posShader ); 35 | this.velSimulation = this.createSimulationProgram( velShader ); 36 | 37 | this.boundTextures = []; 38 | 39 | /* 40 | 41 | GPGPU Utilities 42 | From Sporel by Mr.Doob 43 | @author mrdoob / http://www.mrdoob.com 44 | 45 | */ 46 | 47 | this.camera = new THREE.OrthographicCamera( - 0.5, 0.5, 0.5, - 0.5, 0, 1 ); 48 | this.scene = new THREE.Scene(); 49 | this.mesh = new THREE.Mesh( new THREE.PlaneGeometry( 1, 1 ) ); 50 | this.scene.add( this.mesh ); 51 | 52 | } 53 | 54 | PosVelSimulation.prototype.checkCompatibility = function( renderer ){ 55 | 56 | var gl = renderer.context; 57 | 58 | if ( gl.getExtension( "OES_texture_float" ) === null ) { 59 | this.onError( "No Float Textures"); 60 | return; 61 | } 62 | 63 | if ( gl.getParameter( gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ) === 0 ) { 64 | this.onError( "Vert Shader Textures don't work"); 65 | return; 66 | } 67 | 68 | } 69 | 70 | PosVelSimulation.prototype.onError = function( e ){ 71 | console.log( e ); 72 | } 73 | 74 | PosVelSimulation.prototype.createDebugScene= function(){ 75 | 76 | var debugScene = new THREE.Object3D(); 77 | debugScene.position.z = 0; 78 | 79 | var geo = new THREE.PlaneGeometry( 100 , 100 ); 80 | 81 | var debugMesh = new THREE.Mesh( geo , new THREE.MeshBasicMaterial({ 82 | map: this.rt_pos1 83 | })); 84 | debugMesh.position.set( -55 , 55 , 0 ); 85 | 86 | debugScene.add( debugMesh ); 87 | 88 | var debugMesh = new THREE.Mesh( geo , new THREE.MeshBasicMaterial({ 89 | map: this.rt_pos2 90 | })); 91 | debugMesh.position.set( 55 , 55 , 0 ); 92 | debugScene.add( debugMesh ); 93 | 94 | var debugMesh = new THREE.Mesh( geo , new THREE.MeshBasicMaterial({ 95 | map: this.rt_vel1 96 | })); 97 | debugMesh.position.set( -55, -55 , 0 ); 98 | debugScene.add( debugMesh ); 99 | 100 | var debugMesh = new THREE.Mesh( geo , new THREE.MeshBasicMaterial({ 101 | map: this.rt_vel2 102 | })); 103 | debugMesh.position.set( 55, -55 , 0 ); 104 | debugScene.add( debugMesh ); 105 | 106 | return debugScene; 107 | 108 | } 109 | 110 | PosVelSimulation.prototype.removeDebugScene = function( scene ){ 111 | scene.remove( this.debugScene ); 112 | } 113 | 114 | PosVelSimulation.prototype.addDebugScene = function( scene ){ 115 | scene.add( this.debugScene ); 116 | } 117 | 118 | 119 | PosVelSimulation.prototype.createTexturePassProgram = function(){ 120 | 121 | var uniforms = { 122 | texture:{ type:"t" , value:null }, 123 | } 124 | 125 | var texturePassShader = new THREE.ShaderMaterial({ 126 | uniforms:uniforms, 127 | vertexShader:this.VSPass, 128 | fragmentShader:this.FSPass, 129 | }); 130 | 131 | return texturePassShader; 132 | 133 | } 134 | 135 | PosVelSimulation.prototype.createSimulationProgram = function(sim){ 136 | 137 | var simulationUniforms = { 138 | t_pos:{ type:"t" , value:null }, 139 | t_vel:{ type:"t" , value:null }, 140 | delta:{ type:"f" , value:0 } 141 | } 142 | 143 | 144 | var program = new THREE.ShaderMaterial({ 145 | 146 | uniforms: simulationUniforms, 147 | vertexShader:this.VSPass, 148 | fragmentShader:sim 149 | 150 | }); 151 | 152 | return program; 153 | 154 | } 155 | 156 | 157 | PosVelSimulation.prototype.VSPass = [ 158 | "varying vec2 vUv;", 159 | "void main() {", 160 | " vUv = uv;", 161 | " gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 162 | "}" 163 | ].join("\n"); 164 | 165 | PosVelSimulation.prototype.FSPass = [ 166 | "uniform sampler2D texture;", 167 | "varying vec2 vUv;", 168 | "void main() {", 169 | " vec4 c = texture2D( texture , vUv );", 170 | " gl_FragColor = c ;", 171 | "}" 172 | ].join("\n"); 173 | 174 | 175 | PosVelSimulation.prototype.update = function(){ 176 | 177 | var flipFlop = this.counter % 2; 178 | var delta = this.clock.getDelta(); 179 | 180 | this.posSimulation.uniforms.delta.value = delta; 181 | this.velSimulation.uniforms.delta.value = delta; 182 | 183 | if( flipFlop == 0 ){ 184 | 185 | this.posSimulation.uniforms.t_pos.value = this.rt_pos2; 186 | this.velSimulation.uniforms.t_vel.value = this.rt_vel2; 187 | 188 | this.pass( this.velSimulation , this.rt_vel1 ); 189 | 190 | this.posSimulation.uniforms.t_pos.value = this.rt_pos2; 191 | this.posSimulation.uniforms.t_vel.value = this.rt_vel1; 192 | 193 | this.pass( this.posSimulation , this.rt_pos1 ); 194 | 195 | this.oOutputPos = this.rt_pos2; 196 | this.oOutputVel = this.rt_vel2; 197 | 198 | this.outputPos = this.rt_pos1; 199 | this.outputVel = this.rt_vel1; 200 | 201 | }else if( flipFlop == 1 ){ 202 | 203 | this.posSimulation.uniforms.t_pos.value = this.rt_pos1; 204 | this.velSimulation.uniforms.t_vel.value = this.rt_vel1; 205 | 206 | this.pass( this.velSimulation , this.rt_vel2 ); 207 | 208 | this.posSimulation.uniforms.t_pos.value = this.rt_pos1; 209 | this.posSimulation.uniforms.t_vel.value = this.rt_vel2; 210 | 211 | this.pass( this.posSimulation , this.rt_pos2 ); 212 | 213 | this.oOutputPos = this.rt_pos1; 214 | this.oOutputVel = this.rt_vel1; 215 | 216 | this.outputPos = this.rt_pos2; 217 | this.outputVel = this.rt_vel2; 218 | 219 | } 220 | 221 | this.counter ++; 222 | 223 | this.bindTextures(); 224 | 225 | } 226 | 227 | // Some GPGPU Utilities author: @mrdoob 228 | PosVelSimulation.prototype.render = function ( scene, camera, target ) { 229 | renderer.render( scene, camera, target, false ); 230 | }; 231 | 232 | PosVelSimulation.prototype.pass = function ( shader , target ) { 233 | this.mesh.material = shader; 234 | this.renderer.render( this.scene, this.camera, target, false ); 235 | }; 236 | 237 | PosVelSimulation.prototype.out = function ( shader ) { 238 | this.mesh.material = shader.material; 239 | this.renderer.render( this.scene, this.camera ); 240 | }; 241 | 242 | // Used if he have uniforms we want to update! 243 | PosVelSimulation.prototype.setUniforms = function( uniforms ){ 244 | 245 | this.simulation.uniforms = uniforms || {}; 246 | 247 | // Have to make sure that these always remain! 248 | this.simulation.uniforms.t_pos = { value:"t" , value:null }; 249 | this.simulation.uniforms.t_oPos = { value:"t" , value:null }; 250 | 251 | console.log( this.simulation.uniforms ); 252 | 253 | } 254 | 255 | PosVelSimulation.prototype.setPosUniform = function( name , u ){ 256 | this.posSimulation.uniforms[name] = u; 257 | } 258 | 259 | PosVelSimulation.prototype.setVelUniform = function( name , u ){ 260 | this.velSimulation.uniforms[name] = u; 261 | } 262 | 263 | 264 | // resets the render targets to the from position 265 | PosVelSimulation.prototype.reset = function( posTexture , velTexture ){ 266 | 267 | this.texturePassProgram.uniforms.texture.value = posTexture; 268 | 269 | this.pass( this.texturePassProgram , this.rt_pos1 ); 270 | this.pass( this.texturePassProgram , this.rt_pos2 ); 271 | 272 | this.texturePassProgram.uniforms.texture.value = velTexture; 273 | 274 | this.pass( this.texturePassProgram , this.rt_vel1 ); 275 | this.pass( this.texturePassProgram , this.rt_vel2 ); 276 | 277 | } 278 | 279 | PosVelSimulation.prototype.addBoundTexture = function( system , uniform , value ){ 280 | this.boundTextures.push( [ system , uniform , value ] ); 281 | } 282 | 283 | PosVelSimulation.prototype.bindTextures = function(){ 284 | 285 | for( var i = 0; i < this.boundTextures.length; i++ ){ 286 | 287 | var boundSystem = this.boundTextures[i][0]; 288 | var boundUniform = this.boundTextures[i][1]; 289 | var textureToBind = this.boundTextures[i][2]; 290 | 291 | var uniform = boundSystem.material.uniforms[ boundUniform ]; 292 | 293 | uniform.value = this[ textureToBind ]; 294 | 295 | 296 | } 297 | 298 | } 299 | 300 | -------------------------------------------------------------------------------- /Maru/ShaderLoader.js: -------------------------------------------------------------------------------- 1 | 2 | // Shader Loader will Load any shader you want, 3 | // And be able to add in large functions ( such as noise ) 4 | // with regex inside the shader 5 | function ShaderLoader( pathToShaders , pathToChunks ){ 6 | 7 | this.fragmentShaders = {}; 8 | this.vertexShaders = {}; 9 | this.simulationShaders = {}; 10 | 11 | this.vs = this.vertexShaders; 12 | this.fs = this.fragmentShaders; 13 | this.ss = this.simulationShaders; 14 | 15 | this.pathToShaders = pathToShaders || "/" ; 16 | this.pathToChunks = pathToChunks || pathToShaders; 17 | 18 | this.shaderChunks = {}; 19 | 20 | this.shadersLoaded = 0; 21 | this.shadersToLoad = 0; 22 | 23 | } 24 | 25 | 26 | 27 | /* 28 | 29 | Loads in a shader chunk when told to by 30 | onShaderLoaded. 31 | 32 | it is important to know that the title of the 33 | chunk needs to be the same as the reference in the shader 34 | 35 | AKA, if I use: 36 | 37 | $simplexNoise 38 | 39 | I will need to create a file in the pathToChunks directory 40 | called 41 | 42 | simplexNoise.js 43 | 44 | 45 | */ 46 | ShaderLoader.prototype.loadShaderChunk = function( type ){ 47 | 48 | var path = this.pathToChunks + "/" + type + ".glsl"; 49 | 50 | var self = this; 51 | $.ajax({ 52 | url:path, 53 | dataType:'text', 54 | context:{ 55 | title:type, 56 | path: path 57 | }, 58 | complete: function( r ){ 59 | self.onChunkLoaded( r.responseText , this.title ); 60 | }, 61 | error:function( r ){ 62 | console.log( 'ERROR: Unable to Load Shader' + this.path ); 63 | self.onChunkLoaded( " NO SHADER LOADED " , this.title ); 64 | } 65 | }); 66 | 67 | } 68 | 69 | ShaderLoader.prototype.onChunkLoaded = function( chunk , title ){ 70 | 71 | this.shaderChunks[title] = chunk; 72 | 73 | } 74 | 75 | /* 76 | 77 | This function Loads a shader with whatever title/ 78 | type we prefer. 79 | 80 | */ 81 | ShaderLoader.prototype.load = function( shader , title , type ){ 82 | 83 | var self = this; 84 | 85 | this._beginLoad( shader , title , type ); 86 | 87 | 88 | // request the file over AJAX 89 | $.ajax({ 90 | url: self.pathToShaders +"/" + shader + ".glsl" , 91 | dataType: 'text', 92 | context: { 93 | type: type 94 | }, 95 | complete: function(r){ 96 | self.onShaderLoaded( r.responseText , title , this.type ); 97 | } 98 | }); 99 | 100 | } 101 | 102 | /* 103 | 104 | Once a Shader is loaded, check to see if there are any extra chunks 105 | we need to find and pull in. 106 | 107 | Will recall itself, until the chunk has been loaded in 108 | 109 | */ 110 | ShaderLoader.prototype.onShaderLoaded = function( shaderText , title , type ){ 111 | 112 | var finalShader = shaderText; 113 | 114 | var readyToLoad = true; 115 | 116 | 117 | var array = finalShader.split( "$" ); 118 | 119 | for( var i = 1; i < array.length; i++ ){ 120 | 121 | var chunkName = array[i].split("\n")[0]; 122 | 123 | if( this.shaderChunks[chunkName] ){ 124 | 125 | var tmpShader = finalShader.split( "$" + chunkName ); 126 | 127 | finalShader = tmpShader.join( this.shaderChunks[chunkName] ); 128 | 129 | }else{ 130 | 131 | readyToLoad = false; 132 | this.loadShaderChunk( chunkName ); 133 | 134 | } 135 | 136 | } 137 | 138 | if( readyToLoad ){ 139 | 140 | if( type == 'vertex' ){ 141 | this.vertexShaders[ title ] = finalShader; 142 | }else if( type == 'fragment' ){ 143 | this.fragmentShaders[ title ] = finalShader; 144 | }else if( type == 'simulation' ){ 145 | this.simulationShaders[ title ] = finalShader; 146 | } 147 | 148 | this._endLoad( finalShader , title , type ); 149 | 150 | }else{ 151 | 152 | var self = this; 153 | setTimeout( function(){ 154 | self.onShaderLoaded( finalShader , title , type ) 155 | }, 300 ); 156 | 157 | } 158 | 159 | } 160 | 161 | 162 | // might add something later... 163 | ShaderLoader.prototype._beginLoad = function( shader , title , type ){ 164 | this.shadersToLoad ++; 165 | this.beginLoad( shader , title , type ); 166 | } 167 | 168 | ShaderLoader.prototype._endLoad = function( shaderText , title , type ){ 169 | this.shadersLoaded ++; 170 | 171 | if( this.shadersLoaded == this.shadersToLoad ){ 172 | this.shaderSetLoaded(); 173 | } 174 | 175 | this.endLoad( shaderText , title , type ); 176 | 177 | } 178 | 179 | 180 | ShaderLoader.prototype.setValue = function( shader , name , value ){ 181 | 182 | //console.log( name , value ); 183 | 184 | 185 | var a = '@'+name; 186 | // console.log( a ); 187 | 188 | var replaced = false; 189 | 190 | var newStr = shader.replace( a , function(token){replaced = true; return value;}); 191 | 192 | // console.log( 'replaced' , replaced ); 193 | return newStr; 194 | 195 | } 196 | 197 | ShaderLoader.prototype.shaderSetLoaded = function(){} 198 | ShaderLoader.prototype.endLoad = function(){} 199 | ShaderLoader.prototype.beginLoad = function(){} 200 | -------------------------------------------------------------------------------- /Maru/Stream.js: -------------------------------------------------------------------------------- 1 | 2 | STREAMS = []; 3 | 4 | var ULTIMATE_STREAM, ULTIMATE_SOURCE , ULTIMATE_GAIN , ULTIMATE_CONTROLLER ; 5 | 6 | function Stream( file , controller, looping ){ 7 | 8 | this.file = file; 9 | this.controller = controller; 10 | this.ctx = this.controller.ctx; 11 | 12 | if( !ULTIMATE_STREAM ){ 13 | 14 | ULTIMATE_STREAM = new Audio(); 15 | 16 | 17 | 18 | var ctx = controller.ctx; 19 | 20 | ULTIMATE_SOURCE = ctx.createMediaElementSource( ULTIMATE_STREAM ); 21 | ULTIMATE_GAIN = ctx.createGain(); 22 | 23 | ULTIMATE_SOURCE.connect( ULTIMATE_GAIN ); 24 | 25 | 26 | ULTIMATE_GAIN.connect( controller.gain ); 27 | //ULTIMATE_SOURCE.connect( controller.gain ); 28 | 29 | ULTIMATE_CONTROLLER = controller; 30 | 31 | } 32 | 33 | this.looping = looping; 34 | 35 | this.controller.notes.push( this ); 36 | 37 | STREAMS.push( this ); 38 | 39 | } 40 | 41 | 42 | Stream.prototype.play = function(){ 43 | 44 | this.playing = true; 45 | 46 | ULTIMATE_STREAM.src = this.file; 47 | ULTIMATE_STREAM.play(); 48 | //ULTIMATE_GAIN.gain.value = 0.5; 49 | var t = ULTIMATE_CONTROLLER.ctx.currentTime; 50 | ULTIMATE_GAIN.gain.linearRampToValueAtTime( 1 , ULTIMATE_CONTROLLER.ctx.currentTime + .1 ); 51 | 52 | } 53 | 54 | Stream.prototype.stop = function(){ 55 | 56 | this.playing = false; 57 | 58 | var t = ULTIMATE_CONTROLLER.ctx.currentTime; 59 | 60 | console.log('TIME' ); 61 | console.log( t ); 62 | ULTIMATE_GAIN.gain.linearRampToValueAtTime( ULTIMATE_GAIN.gain.value , t ); 63 | 64 | ULTIMATE_GAIN.gain.linearRampToValueAtTime( 0.0 , t + .1); 65 | 66 | setTimeout( function(){ 67 | ULTIMATE_STREAM.pause(); 68 | },99); 69 | 70 | } 71 | 72 | 73 | 74 | 75 | 76 | /*Stream.prototype.fadeOut = function( time , callback ){ 77 | 78 | var t = this.controller.ctx.currentTime; 79 | if( !time ) time = this.params.fadeTime; 80 | this.gain.gain.linearRampToValueAtTime( this.gain.gain.value , t ); 81 | this.gain.gain.linearRampToValueAtTime( 0.0 , t + time ); 82 | 83 | setTimeout( callback.bind( this ) , time * 1000 ); 84 | 85 | } 86 | 87 | ULTIMATE_GAIN.fadeIn = function( time , value ){ 88 | 89 | this.gain.gain.linearRampToValueAtTime( 1 , this.controller.ctx.currentTime + time ); 90 | 91 | }*/ 92 | 93 | /*Stream.prototype.play = function(){ 94 | 95 | var self = this; 96 | 97 | if(!this.source){ 98 | this.createSource(); 99 | } 100 | 101 | 102 | setTimeout(function(){ 103 | 104 | 105 | 106 | self.audio.play(); 107 | self.fadeIn( .5 , 1 ); 108 | self.playing = true; 109 | 110 | },10); 111 | 112 | 113 | } 114 | 115 | Stream.prototype.stop = function(){ 116 | 117 | this.fadeOut( .4 , function(){ 118 | 119 | this.audio.pause(); 120 | this.playing = false; 121 | 122 | this.audio.currentTime = 0; 123 | this.audio = undefined; 124 | //this.audio.currentTime = 0; 125 | //this.source.currentTime = 0; 126 | // this.gain.disconnect( this.source ); 127 | 128 | //this.gain.disconnect( this.source ); 129 | //this.source = undefined; 130 | 131 | }); 132 | 133 | }*/ 134 | 135 | 136 | Stream.prototype.update = function(){ 137 | 138 | //this.analyzer.getByteFrequencyData( this.analyzer.array ); 139 | 140 | } 141 | -------------------------------------------------------------------------------- /Maru/activate.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/activate.wav -------------------------------------------------------------------------------- /Maru/andaBit.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/andaBit.wav -------------------------------------------------------------------------------- /Maru/cab_sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/cab_sprite.png -------------------------------------------------------------------------------- /Maru/deactivate.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/deactivate.wav -------------------------------------------------------------------------------- /Maru/goodJob.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/goodJob.wav -------------------------------------------------------------------------------- /Maru/hover.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/hover.wav -------------------------------------------------------------------------------- /Maru/icons/albumCover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/albumCover.png -------------------------------------------------------------------------------- /Maru/icons/cabbibo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/cabbibo.png -------------------------------------------------------------------------------- /Maru/icons/cabbibo_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/cabbibo_1.png -------------------------------------------------------------------------------- /Maru/icons/connect_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/connect_1.png -------------------------------------------------------------------------------- /Maru/icons/cursorWhite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/cursorWhite.png -------------------------------------------------------------------------------- /Maru/icons/download_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/download_1.png -------------------------------------------------------------------------------- /Maru/icons/facebook_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/facebook_1.png -------------------------------------------------------------------------------- /Maru/icons/info_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/info_1.png -------------------------------------------------------------------------------- /Maru/icons/loadGif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/loadGif.gif -------------------------------------------------------------------------------- /Maru/icons/normals/08_normalmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/normals/08_normalmap.png -------------------------------------------------------------------------------- /Maru/icons/normals/10389-normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/normals/10389-normal.jpg -------------------------------------------------------------------------------- /Maru/icons/normals/3989-normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/normals/3989-normal.jpg -------------------------------------------------------------------------------- /Maru/icons/normals/4706-normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/normals/4706-normal.jpg -------------------------------------------------------------------------------- /Maru/icons/normals/7723-normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/normals/7723-normal.jpg -------------------------------------------------------------------------------- /Maru/icons/normals/7870-normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/normals/7870-normal.jpg -------------------------------------------------------------------------------- /Maru/icons/normals/8158-normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/normals/8158-normal.jpg -------------------------------------------------------------------------------- /Maru/icons/normals/940-normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/normals/940-normal.jpg -------------------------------------------------------------------------------- /Maru/icons/normals/bumpmap_normalmap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/normals/bumpmap_normalmap.jpg -------------------------------------------------------------------------------- /Maru/icons/normals/carbonFiber.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/normals/carbonFiber.png -------------------------------------------------------------------------------- /Maru/icons/normals/chesterfield.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/normals/chesterfield.png -------------------------------------------------------------------------------- /Maru/icons/normals/moss_normal_map.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/normals/moss_normal_map.jpg -------------------------------------------------------------------------------- /Maru/icons/normals/other.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/normals/other.jpg -------------------------------------------------------------------------------- /Maru/icons/normals/rock.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/normals/rock.jpg -------------------------------------------------------------------------------- /Maru/icons/normals/rock1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/normals/rock1.png -------------------------------------------------------------------------------- /Maru/icons/prism_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/prism_1.png -------------------------------------------------------------------------------- /Maru/icons/rioux_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/rioux_1.png -------------------------------------------------------------------------------- /Maru/icons/sem_metal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/sem_metal.jpg -------------------------------------------------------------------------------- /Maru/icons/soundcloud_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/soundcloud_1.png -------------------------------------------------------------------------------- /Maru/icons/sprite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/sprite.png -------------------------------------------------------------------------------- /Maru/icons/starMap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/starMap.png -------------------------------------------------------------------------------- /Maru/icons/thumb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/thumb.jpg -------------------------------------------------------------------------------- /Maru/icons/thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/thumb.png -------------------------------------------------------------------------------- /Maru/icons/twitter_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/twitter_1.png -------------------------------------------------------------------------------- /Maru/icons/warp_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cabbibo/PlaidPolymer/0fb2ef297d33b560f6fdefe223ba5a72d5e55f38/Maru/icons/warp_1.png -------------------------------------------------------------------------------- /Maru/initEasterEgg.js: -------------------------------------------------------------------------------- 1 | function initEasterEgg(){ 2 | 3 | 4 | 5 | var geo = new THREE.IcosahedronGeometry(10,1); 6 | var mat = new THREE.MeshNormalMaterial(); 7 | 8 | EasterEgg = new THREE.Mesh( geo , mat ); 9 | EasterEgg.scale.multiplyScalar( 100 ); 10 | 11 | EasterEgg.added = false; 12 | EasterEgg.textAdded = false; 13 | 14 | EasterEgg.addDistance = 3950; 15 | 16 | EasterEgg.gui = new dat.GUI({autoPlace:false}); 17 | 18 | 19 | var gHolder = document.createElement('div'); 20 | 21 | var tHolder = document.createElement('h1'); 22 | 23 | tHolder.innerHTML ='EasterEgg'; 24 | 25 | gHolder.appendChild( tHolder ); 26 | var guis = document.getElementById( 'GUI' ); 27 | 28 | guis.appendChild( gHolder ); 29 | gHolder.appendChild(EasterEgg.gui.domElement); 30 | 31 | 32 | EasterEgg.furryTails = []; 33 | 34 | var center = new THREE.Mesh( 35 | new THREE.IcosahedronGeometry( 1.1 , 1 ), 36 | new THREE.MeshNormalMaterial({side:THREE.DoubleSide}) 37 | ); 38 | 39 | //EasterEgg.gui.domElement = this.params.domElement; 40 | 41 | var bait = center.clone(); 42 | 43 | var c = [ 44 | new THREE.Color( '#ed0000' ), 45 | new THREE.Color( '#fff000' ), 46 | new THREE.Color( '#ff8700' ), 47 | new THREE.Color( '#e82626' ), 48 | ]; 49 | 50 | 51 | var col1 = new THREE.Vector3( c[0].r , c[0].g , c[0].b ); 52 | var col2 = new THREE.Vector3( c[1].r , c[1].g , c[1].b ); 53 | var col3 = new THREE.Vector3( c[2].r , c[2].g , c[2].b ); 54 | var col4 = new THREE.Vector3( c[3].r , c[3].g , c[3].b ); 55 | var friends = new FurryGroup( EasterEgg , 'friends' , audioController , 10 ,{ 56 | center: center, 57 | bait: bait, 58 | color1: col1, 59 | color2: col2, 60 | color3: col3, 61 | color4: col4 62 | 63 | }); 64 | 65 | 66 | /*var m = new THREE.Mesh( new THREE.IcosahedronGeometry( 1 , 0 ) , new THREE.MeshNormalMaterial() ); 67 | m.scale.multiplyScalar( .02 ); 68 | EasterEgg.add( m );*/ 69 | 70 | /* EasterEgg.text = new PhysicsText( 71 | [ 'You can live.', 72 | '','', 73 | 'Remember this miracle on your journey, and realize that no matter how far you go, already you have made it here.', 74 | '','', 75 | 'Find joy in the short existance you have, because even if you make it, it will not be enough' 76 | ].join("\n") 77 | );*/ 78 | EasterEgg.update = function(){ 79 | 80 | 81 | var p = camera.position.clone(); 82 | 83 | // console.log( this.added ); 84 | if( this.added == false ){ 85 | 86 | //console.log('YA'); 87 | this.added = true; 88 | scene.add( this ); 89 | 90 | //this.position.copy( p ); 91 | 92 | var f = new THREE.Vector3( 0 , 0 , -1 ); 93 | f.applyQuaternion( camera.quaternion ); 94 | f.multiplyScalar( this.addDistance / 2 ); 95 | //this.position.add( f ); 96 | 97 | for( var i = 0; i < this.furryTails.length; i++ ){ 98 | 99 | this.furryTails[i].activate(); 100 | this.furryTails[i].line.scale.multiplyScalar( .001 ); 101 | this.furryTails[i].physicsParticles.scale.multiplyScalar( .001 ); 102 | this.furryTails[i].head.mesh.scale.multiplyScalar( .001 ); 103 | this.furryTails[i].leader.scale.multiplyScalar( .001 ); 104 | //this.furryTails[i].bait 105 | 106 | var position = new THREE.Vector3( 107 | (Math.random() - .5 ) * 10, 108 | (Math.random() - .5 ) * 10, 109 | (Math.random() - .5 ) * 10 110 | ); 111 | 112 | this.furryTails[i].addCollisionForce( position , 10 ); 113 | this.furryTails[i].addDistanceForce( position , .00004 ); 114 | 115 | this.furryTails[i].velocity.set( 116 | (Math.random() - .5) * 300, 117 | (Math.random() - .5) * 300, 118 | (Math.random() - .5) * 300 119 | ); 120 | 121 | for( var j = 0; j < this.furryTails.length; j++ ){ 122 | 123 | if( j != i ){ 124 | 125 | 126 | var oP = this.furryTails[j].position; 127 | this.furryTails[i].addDistanceForce( oP , .000004 ); 128 | this.furryTails[i].addCollisionForce( oP , 10 ); 129 | 130 | //this.furryTails[i].addDistanceInverseSquaredForce( oP , -.000000001 ); 131 | 132 | } 133 | 134 | 135 | } 136 | //scene.add( this.furryTails[i].leader ); 137 | //this.furryTails[i].updatePhysics(); 138 | 139 | 140 | 141 | // this.startText. 142 | 143 | } 144 | } 145 | 146 | if( this.added == true ){ 147 | 148 | for( var i = 0; i < this.furryTails.length; i++ ){ 149 | 150 | this.furryTails[i].updateTail(); 151 | this.furryTails[i].updatePhysics(); 152 | 153 | } 154 | 155 | } 156 | 157 | 158 | } 159 | 160 | ////////////////// scene.add( EasterEgg ); 161 | 162 | } 163 | -------------------------------------------------------------------------------- /Maru/initPoly.js: -------------------------------------------------------------------------------- 1 | 2 | DLD = false; 3 | 4 | var raycaster = new THREE.Raycaster(); 5 | function initPoly(){ 6 | 7 | for( var i = 0; i < loopList.length; i++ ){ 8 | 9 | POLYS[loopList[i]] = new Poly( i, LOOPS[loopList[i]] , loopList[i]); 10 | 11 | console.log(POLYS[loopList[i]]); 12 | 13 | } 14 | 15 | 16 | } 17 | 18 | function Poly( id , note ,name){ 19 | 20 | this.note = note; 21 | this.note.gain.gain.value = 0; 22 | this.id = id; 23 | this.name = name; 24 | 25 | this.active = false; 26 | 27 | 28 | this.mesh = new THREE.Mesh( 29 | new THREE.IcosahedronGeometry( 40.1 , 2 ), 30 | new THREE.ShaderMaterial({ 31 | uniforms:{ 32 | t_audio:{type:"t",value:this.note.texture}, 33 | time:G.uniforms.time, 34 | jelly:{type:"v3",value:headMesh.position}, 35 | active:{type:"f",value:1} 36 | }, 37 | vertexShader: shaders.vs.poly, 38 | fragmentShader: shaders.fs.poly, 39 | flatShading:true 40 | }) 41 | ); 42 | 43 | this.bgMesh = new THREE.Mesh( 44 | new THREE.IcosahedronGeometry( 40.1 , 2 ), 45 | new THREE.ShaderMaterial({ 46 | uniforms:{ 47 | t_audio:{type:"t",value:this.note.texture}, 48 | time:G.uniforms.time, 49 | jelly:{type:"v3",value:headMesh.position}, 50 | color:{type:"v4", value:new THREE.Vector4(44/255,43/255,71/255,1)}//new THREE.Vector4(44/255,43/255,71/255,1); 51 | 52 | }, 53 | vertexShader: shaders.vs.polyOutline, 54 | fragmentShader: shaders.fs.polyOutline, 55 | flatShading:true 56 | }) 57 | ); 58 | 59 | this.organicMesh = new THREE.Mesh( 60 | new THREE.IcosahedronGeometry( 40.1 , 5 ), 61 | new THREE.ShaderMaterial({ 62 | uniforms:{ 63 | t_audio:{type:"t",value:this.note.texture}, 64 | time:G.uniforms.time, 65 | jelly:{type:"v3",value:headMesh.position}, 66 | active:{type:"f",value:1}, 67 | hovered:{type:"f",value:0}, 68 | }, 69 | vertexShader: shaders.vs.polyOrg, 70 | fragmentShader: shaders.fs.polyOrg, 71 | flatShading:true 72 | })); 73 | 74 | 75 | this.mesh.add(this.bgMesh); 76 | 77 | 78 | var row = Math.floor(id %4); 79 | row = (row+1)%2; 80 | 81 | 82 | var targetZ = 150; 83 | var distance = -1000; 84 | 85 | 86 | var vec = new THREE.Vector3(); // create once and reuse 87 | var pos = new THREE.Vector3(); // create once and reuse 88 | 89 | var topLeft = new THREE.Vector3(); 90 | var topRight = new THREE.Vector3(); 91 | var bottomLeft = new THREE.Vector3(); 92 | var bottomRight = new THREE.Vector3(); 93 | 94 | 95 | vec.set( -.8, 1, 0.5 ); 96 | raycaster.setFromCamera( vec, camera ); 97 | vec.copy(camera.position); 98 | vec.add( raycaster.ray.direction.clone().multiplyScalar(1300)); 99 | 100 | topLeft.copy( vec ); 101 | 102 | vec.set( .8, 1, 0.5 ); 103 | raycaster.setFromCamera( vec, camera ); 104 | vec.copy(camera.position); 105 | vec.add( raycaster.ray.direction.clone().multiplyScalar(1300)); 106 | 107 | topRight.copy( vec ); 108 | 109 | vec.set( -.8, -1, 0.5 ); 110 | raycaster.setFromCamera( vec, camera ); 111 | vec.copy(camera.position); 112 | vec.add( raycaster.ray.direction.clone().multiplyScalar(1300)); 113 | 114 | bottomLeft.copy( vec ); 115 | 116 | vec.set( .8, -1, 0.5 ); 117 | raycaster.setFromCamera( vec, camera ); 118 | vec.copy(camera.position); 119 | vec.add( raycaster.ray.direction.clone().multiplyScalar(1300)); 120 | 121 | bottomRight.copy( vec ); 122 | 123 | left = new THREE.Vector3().copy( topLeft ).sub( topRight ); 124 | up = new THREE.Vector3().copy( topLeft ).sub( bottomLeft ); 125 | 126 | 127 | var leftVal = ((id % 4)+.5)/4 128 | var upVal = (((Math.floor(id /4)+.25)+(row * .5))/5) 129 | 130 | this.mesh.position.copy(topLeft).add(left.multiplyScalar(-upVal)).add(up.multiplyScalar(-leftVal)); 131 | 132 | console.log( this.mesh.position ); 133 | 134 | 135 | /* this.mesh.position.y = 1.3*((((id % 4)+.5)/4)-.5) * window.innerHeight; 136 | 137 | this.mesh.position.x = (row-.5) * (.5 *window.innerWidth / 5) + 1*(((Math.floor(id /4)+.5)/5)-.5) * window.innerWidth; 138 | this.mesh.position.z = 0;//(Math.random()-.5) * 100; 139 | */ 140 | 141 | this.organicMesh.position.copy( this.mesh.position ); 142 | this.mesh.material.map = this.note.texture; 143 | 144 | this.mesh.hoverOver = function(){ 145 | this.hoverOver(); 146 | }.bind( this ); 147 | 148 | this.mesh.hoverOut = function(){ 149 | this.hoverOut(); 150 | }.bind( this ); 151 | 152 | this.mesh.select = function(){ 153 | this.select(); 154 | }.bind( this ); 155 | 156 | this.mesh.deselect = function(){ 157 | this.deselect(); 158 | }.bind( this ); 159 | 160 | objectControls.add( this.mesh ); 161 | 162 | this.deactivate 163 | 164 | } 165 | 166 | Poly.prototype = { 167 | 168 | update:function(){ 169 | 170 | //this.bgMesh.position.copy( this.mesh.position ); 171 | this.mesh.rotation.x += .01 * Math.sin(this.id * 10); 172 | this.mesh.rotation.y += .01 * Math.sin(this.id * 10+20); 173 | this.mesh.rotation.z += .01 * Math.sin(this.id * 10+40); 174 | 175 | 176 | 177 | //this.mesh.add(this.bgMesh); 178 | }, 179 | 180 | 181 | play:function(){ 182 | this.note.play(); 183 | scene.add( this.mesh ); 184 | }, 185 | 186 | activate:function(){ 187 | this.active = true; 188 | //this.mesh.material.uniforms.active.value = 1; 189 | this.organicMesh.material.uniforms.active.value = 1; 190 | 191 | scene.remove( this.mesh ); 192 | scene.add( this.organicMesh ); 193 | 194 | this.note.gain.gain.value = 1; 195 | 196 | 197 | 198 | var canDL = true; 199 | for( var i = 0; i < loopList.length; i++ ){ 200 | if( POLYS[loopList[i]].active == false ){ canDL = false; } 201 | } 202 | 203 | 204 | if( canDL && DLD == false ){ 205 | var url="MaruLoops.zip"; 206 | //window.open(url); 207 | 208 | 209 | /*var zip_file_path = url; //put inside "" your path with file.zip 210 | var zip_file_name = "Maru Loops" //put inside "" file name or something 211 | var a = document.createElement("a"); 212 | document.body.appendChild(a); 213 | a.style = "display: none"; 214 | a.href = zip_file_path; 215 | a.download = zip_file_name; 216 | a.click(); 217 | document.body.removeChild(a); 218 | DLD = true;*/ 219 | DLD = true; 220 | 221 | displaySignUp(); 222 | NOTES.goodJob.play(); 223 | 224 | }else{ 225 | NOTES.activate.play(); 226 | } 227 | }, 228 | 229 | deactivate: function(){ 230 | this.active = false; 231 | 232 | this.mesh.material.uniforms.active.value = 1; 233 | this.organicMesh.material.uniforms.active.value = 1; 234 | this.note.gain.gain.value = 0; 235 | 236 | scene.add( this.mesh ); 237 | scene.remove( this.organicMesh ); 238 | }, 239 | 240 | 241 | hoverOver: function(){ 242 | 243 | 244 | if( this.active == false ){ 245 | this.mesh.scale.x = 1.1; 246 | this.mesh.scale.y = 1.1; 247 | this.mesh.scale.z = 1.1; 248 | 249 | this.organicMesh.scale.x = 1.1; 250 | this.organicMesh.scale.y = 1.1; 251 | this.organicMesh.scale.z = 1.1; 252 | 253 | this.bgMesh.scale.x = 1; 254 | this.bgMesh.scale.y = 1; 255 | this.bgMesh.scale.z = 1; 256 | //vec3(44.,43.,71.)/255.; 257 | this.bgMesh.material.uniforms.color.value = new THREE.Vector4( 174/255, 197/255, 212/255,1);;//new THREE.Vector4(44/255,43/255,71/255,1); 258 | 259 | 260 | } 261 | NOTES.hover.play(); 262 | 263 | this.organicMesh.material.uniforms.hovered.value = 1; 264 | 265 | document.getElementById("TITLE").innerHTML="