└── r48 ├── js ├── AudioObject.js ├── Car.js ├── DAT.GUI.min.js ├── Detector.js ├── ImprovedNoise.js ├── MD2Character.js ├── PRNG.js ├── RenderManager.js ├── ShaderExtras.js ├── ShaderSkin.js ├── ShaderTerrain.js ├── SimplexNoise.js ├── Sparks.js ├── Stats.js ├── Three.full.js ├── Three.js ├── Three2.js ├── Three3.js ├── Tween.js ├── ctm │ ├── CTMLoader.js │ ├── CTMWorker.js │ ├── ctm.js │ ├── license │ │ ├── OpenCTM.txt │ │ ├── js-lzma.txt │ │ └── js-openctm.txt │ └── lzma.js ├── extras │ ├── Shaders.js │ └── Utils.js └── postprocessing │ ├── BloomPass.js │ ├── DotScreenPass.js │ ├── EffectComposer.js │ ├── FilmPass.js │ ├── MaskPass.js │ ├── RenderPass.js │ ├── SavePass.js │ ├── ShaderPass.js │ └── TexturePass.js ├── tron ├── glow256.png ├── pixel.png ├── seq │ ├── glowseq_0.png │ ├── glowseq_1.png │ ├── glowseq_10.png │ ├── glowseq_11.png │ ├── glowseq_12.png │ ├── glowseq_13.png │ ├── glowseq_14.png │ ├── glowseq_15.png │ ├── glowseq_16.png │ ├── glowseq_17.png │ ├── glowseq_18.png │ ├── glowseq_19.png │ ├── glowseq_2.png │ ├── glowseq_3.png │ ├── glowseq_4.png │ ├── glowseq_5.png │ ├── glowseq_6.png │ ├── glowseq_7.png │ ├── glowseq_8.png │ └── glowseq_9.png ├── trondisk.js ├── trondisk_diffuse.jpg └── trondisk_glow.png ├── webgl_tron.html ├── webgl_tron_glow.html ├── webgl_tron_glow_animated.html ├── webgl_tron_glow_particles.html └── webgl_tron_godrays.html /r48/js/AudioObject.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | * AudioObject 5 | * 6 | * - 3d spatialized sound with Doppler-shift effect 7 | * 8 | * - uses Audio API (currently supported in WebKit-based browsers) 9 | * https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html 10 | * 11 | * - based on Doppler effect demo from Chromium 12 | * http://chromium.googlecode.com/svn/trunk/samples/audio/doppler.html 13 | * 14 | * - parameters 15 | * 16 | * - listener 17 | * dopplerFactor // A constant used to determine the amount of pitch shift to use when rendering a doppler effect. 18 | * speedOfSound // The speed of sound used for calculating doppler shift. The default value is 343.3 meters / second. 19 | * 20 | * - panner 21 | * refDistance // A reference distance for reducing volume as source move further from the listener. 22 | * maxDistance // The maximum distance between source and listener, after which the volume will not be reduced any further. 23 | * rolloffFactor // Describes how quickly the volume is reduced as source moves away from listener. 24 | * coneInnerAngle // An angle inside of which there will be no volume reduction. 25 | * coneOuterAngle // An angle outside of which the volume will be reduced to a constant value of coneOuterGain. 26 | * coneOuterGain // Amount of volume reduction outside of the coneOuterAngle. 27 | */ 28 | 29 | THREE.AudioObject = function ( url, volume, playbackRate, loop ) { 30 | 31 | THREE.Object3D.call( this ); 32 | 33 | if ( playbackRate === undefined ) playbackRate = 1; 34 | if ( volume === undefined ) volume = 1; 35 | if ( loop === undefined ) loop = true; 36 | 37 | if ( ! this.context ) { 38 | 39 | try { 40 | 41 | this.context = new webkitAudioContext(); 42 | 43 | } catch( error ) { 44 | 45 | console.warn( "THREE.AudioObject: webkitAudioContext not found" ); 46 | return this; 47 | 48 | } 49 | 50 | } 51 | 52 | this.directionalSource = false; 53 | 54 | this.listener = this.context.listener; 55 | this.panner = this.context.createPanner(); 56 | this.source = this.context.createBufferSource(); 57 | 58 | this.masterGainNode = this.context.createGainNode(); 59 | this.dryGainNode = this.context.createGainNode(); 60 | 61 | // Setup initial gains 62 | 63 | this.masterGainNode.gain.value = volume; 64 | this.dryGainNode.gain.value = 3.0; 65 | 66 | // Connect dry mix 67 | 68 | this.source.connect( this.panner ); 69 | this.panner.connect( this.dryGainNode ); 70 | this.dryGainNode.connect( this.masterGainNode ); 71 | 72 | // Connect master gain 73 | 74 | this.masterGainNode.connect( this.context.destination ); 75 | 76 | // Set source parameters and load sound 77 | 78 | this.source.playbackRate.value = playbackRate; 79 | this.source.loop = loop; 80 | 81 | loadBufferAndPlay( url ); 82 | 83 | // private properties 84 | 85 | var soundPosition = new THREE.Vector3(), 86 | cameraPosition = new THREE.Vector3(), 87 | oldSoundPosition = new THREE.Vector3(), 88 | oldCameraPosition = new THREE.Vector3(), 89 | 90 | soundDelta = new THREE.Vector3(), 91 | cameraDelta = new THREE.Vector3(), 92 | 93 | soundFront = new THREE.Vector3(), 94 | cameraFront = new THREE.Vector3(), 95 | soundUp = new THREE.Vector3(), 96 | cameraUp = new THREE.Vector3(); 97 | 98 | var _this = this; 99 | 100 | // API 101 | 102 | this.setVolume = function ( volume ) { 103 | 104 | this.masterGainNode.gain.value = volume; 105 | 106 | }; 107 | 108 | this.update = function ( camera ) { 109 | 110 | oldSoundPosition.copy( soundPosition ); 111 | oldCameraPosition.copy( cameraPosition ); 112 | 113 | soundPosition.copy( this.matrixWorld.getPosition() ); 114 | cameraPosition.copy( camera.matrixWorld.getPosition() ); 115 | 116 | soundDelta.sub( soundPosition, oldSoundPosition ); 117 | cameraDelta.sub( cameraPosition, oldCameraPosition ); 118 | 119 | cameraUp.copy( camera.up ); 120 | 121 | cameraFront.set( 0, 0, -1 ); 122 | camera.matrixWorld.rotateAxis( cameraFront ); 123 | cameraFront.normalize(); 124 | 125 | this.listener.setPosition( cameraPosition.x, cameraPosition.y, cameraPosition.z ); 126 | this.listener.setVelocity( cameraDelta.x, cameraDelta.y, cameraDelta.z ); 127 | this.listener.setOrientation( cameraFront.x, cameraFront.y, cameraFront.z, cameraUp.x, cameraUp.y, cameraUp.z ); 128 | 129 | this.panner.setPosition( soundPosition.x, soundPosition.y, soundPosition.z ); 130 | this.panner.setVelocity( soundDelta.x, soundDelta.y, soundDelta.z ); 131 | 132 | if ( this.directionalSource ) { 133 | 134 | soundFront.set( 0, 0, -1 ); 135 | this.matrixWorld.rotateAxis( soundFront ); 136 | soundFront.normalize(); 137 | 138 | soundUp.copy( this.up ); 139 | this.panner.setOrientation( soundFront.x, soundFront.y, soundFront.z, soundUp.x, soundUp.y, soundUp.z ); 140 | 141 | } 142 | 143 | 144 | }; 145 | 146 | function loadBufferAndPlay( url ) { 147 | 148 | // Load asynchronously 149 | 150 | var request = new XMLHttpRequest(); 151 | request.open( "GET", url, true ); 152 | request.responseType = "arraybuffer"; 153 | 154 | request.onload = function() { 155 | 156 | _this.source.buffer = _this.context.createBuffer( request.response, true ); 157 | _this.source.noteOn( 0 ); 158 | 159 | } 160 | 161 | request.send(); 162 | 163 | } 164 | 165 | }; 166 | 167 | THREE.AudioObject.prototype = new THREE.Object3D(); 168 | THREE.AudioObject.prototype.constructor = THREE.AudioObject; 169 | 170 | THREE.AudioObject.prototype.context = null; 171 | THREE.AudioObject.prototype.type = null; 172 | 173 | -------------------------------------------------------------------------------- /r48/js/Car.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.Car = function () { 6 | 7 | var scope = this; 8 | 9 | // car geometry manual parameters 10 | 11 | this.modelScale = 1; 12 | 13 | this.backWheelOffset = 2; 14 | 15 | this.autoWheelGeometry = true; 16 | 17 | // car geometry parameters automatically set from wheel mesh 18 | // - assumes wheel mesh is front left wheel in proper global 19 | // position with respect to body mesh 20 | // - other wheels are mirrored against car root 21 | // - if necessary back wheels can be offset manually 22 | 23 | this.wheelOffset = new THREE.Vector3(); 24 | 25 | this.wheelDiameter = 1; 26 | 27 | // car "feel" parameters 28 | 29 | this.MAX_SPEED = 2200; 30 | this.MAX_REVERSE_SPEED = -1500; 31 | 32 | this.MAX_WHEEL_ROTATION = 0.6; 33 | 34 | this.FRONT_ACCELERATION = 1250; 35 | this.BACK_ACCELERATION = 1500; 36 | 37 | this.WHEEL_ANGULAR_ACCELERATION = 1.5; 38 | 39 | this.FRONT_DECCELERATION = 750; 40 | this.WHEEL_ANGULAR_DECCELERATION = 1.0; 41 | 42 | this.STEERING_RADIUS_RATIO = 0.0023; 43 | 44 | this.MAX_TILT_SIDES = 0.05; 45 | this.MAX_TILT_FRONTBACK = 0.015; 46 | 47 | // internal control variables 48 | 49 | this.speed = 0; 50 | this.acceleration = 0; 51 | 52 | this.wheelOrientation = 0; 53 | this.carOrientation = 0; 54 | 55 | // car rigging 56 | 57 | this.root = new THREE.Object3D(); 58 | 59 | this.frontLeftWheelRoot = new THREE.Object3D(); 60 | this.frontRightWheelRoot = new THREE.Object3D(); 61 | 62 | this.bodyMesh = null; 63 | 64 | this.frontLeftWheelMesh = null; 65 | this.frontRightWheelMesh = null; 66 | 67 | this.backLeftWheelMesh = null; 68 | this.backRightWheelMesh = null; 69 | 70 | this.bodyGeometry = null; 71 | this.wheelGeometry = null; 72 | 73 | // internal helper variables 74 | 75 | this.loaded = false; 76 | 77 | this.meshes = []; 78 | 79 | // API 80 | 81 | this.enableShadows = function ( enable ) { 82 | 83 | for ( var i = 0; i < this.meshes.length; i ++ ) { 84 | 85 | this.meshes[ i ].castShadow = enable; 86 | this.meshes[ i ].receiveShadow = enable; 87 | 88 | } 89 | 90 | }; 91 | 92 | this.setVisible = function ( enable ) { 93 | 94 | for ( var i = 0; i < this.meshes.length; i ++ ) { 95 | 96 | this.meshes[ i ].visible = enable; 97 | this.meshes[ i ].visible = enable; 98 | 99 | } 100 | 101 | }; 102 | 103 | this.loadPartsJSON = function ( bodyURL, wheelURL ) { 104 | 105 | var loader = new THREE.JSONLoader(); 106 | 107 | loader.load( bodyURL, function( geometry ) { createBody( geometry ) } ); 108 | loader.load( wheelURL, function( geometry ) { createWheels( geometry ) } ); 109 | 110 | }; 111 | 112 | this.loadPartsBinary = function ( bodyURL, wheelURL ) { 113 | 114 | var loader = new THREE.BinaryLoader(); 115 | 116 | loader.load( bodyURL, function( geometry ) { createBody( geometry ) } ); 117 | loader.load( wheelURL, function( geometry ) { createWheels( geometry ) } ); 118 | 119 | }; 120 | 121 | this.updateCarModel = function ( delta, controls ) { 122 | 123 | // speed and wheels based on controls 124 | 125 | if ( controls.moveForward ) { 126 | 127 | this.speed = THREE.Math.clamp( this.speed + delta * this.FRONT_ACCELERATION, this.MAX_REVERSE_SPEED, this.MAX_SPEED ); 128 | this.acceleration = THREE.Math.clamp( this.acceleration + delta, -1, 1 ); 129 | 130 | } 131 | 132 | if ( controls.moveBackward ) { 133 | 134 | 135 | this.speed = THREE.Math.clamp( this.speed - delta * this.BACK_ACCELERATION, this.MAX_REVERSE_SPEED, this.MAX_SPEED ); 136 | this.acceleration = THREE.Math.clamp( this.acceleration - delta, -1, 1 ); 137 | 138 | } 139 | 140 | if ( controls.moveLeft ) { 141 | 142 | this.wheelOrientation = THREE.Math.clamp( this.wheelOrientation + delta * this.WHEEL_ANGULAR_ACCELERATION, - this.MAX_WHEEL_ROTATION, this.MAX_WHEEL_ROTATION ); 143 | 144 | } 145 | 146 | if ( controls.moveRight ) { 147 | 148 | this.wheelOrientation = THREE.Math.clamp( this.wheelOrientation - delta * this.WHEEL_ANGULAR_ACCELERATION, - this.MAX_WHEEL_ROTATION, this.MAX_WHEEL_ROTATION ); 149 | 150 | } 151 | 152 | // speed decay 153 | 154 | if ( ! ( controls.moveForward || controls.moveBackward ) ) { 155 | 156 | if ( this.speed > 0 ) { 157 | 158 | var k = exponentialEaseOut( this.speed / this.MAX_SPEED ); 159 | 160 | this.speed = THREE.Math.clamp( this.speed - k * delta * this.FRONT_DECCELERATION, 0, this.MAX_SPEED ); 161 | this.acceleration = THREE.Math.clamp( this.acceleration - k * delta, 0, 1 ); 162 | 163 | } else { 164 | 165 | var k = exponentialEaseOut( this.speed / this.MAX_REVERSE_SPEED ); 166 | 167 | this.speed = THREE.Math.clamp( this.speed + k * delta * this.BACK_ACCELERATION, this.MAX_REVERSE_SPEED, 0 ); 168 | this.acceleration = THREE.Math.clamp( this.acceleration + k * delta, -1, 0 ); 169 | 170 | } 171 | 172 | 173 | } 174 | 175 | // steering decay 176 | 177 | if ( ! ( controls.moveLeft || controls.moveRight ) ) { 178 | 179 | if ( this.wheelOrientation > 0 ) { 180 | 181 | this.wheelOrientation = THREE.Math.clamp( this.wheelOrientation - delta * this.WHEEL_ANGULAR_DECCELERATION, 0, this.MAX_WHEEL_ROTATION ); 182 | 183 | } else { 184 | 185 | this.wheelOrientation = THREE.Math.clamp( this.wheelOrientation + delta * this.WHEEL_ANGULAR_DECCELERATION, - this.MAX_WHEEL_ROTATION, 0 ); 186 | 187 | } 188 | 189 | } 190 | 191 | // car update 192 | 193 | var forwardDelta = this.speed * delta; 194 | 195 | this.carOrientation += ( forwardDelta * this.STEERING_RADIUS_RATIO )* this.wheelOrientation; 196 | 197 | // displacement 198 | 199 | this.root.position.x += Math.sin( this.carOrientation ) * forwardDelta; 200 | this.root.position.z += Math.cos( this.carOrientation ) * forwardDelta; 201 | 202 | // steering 203 | 204 | this.root.rotation.y = this.carOrientation; 205 | 206 | // tilt 207 | 208 | if ( this.loaded ) { 209 | 210 | this.bodyMesh.rotation.z = this.MAX_TILT_SIDES * this.wheelOrientation * ( this.speed / this.MAX_SPEED ); 211 | this.bodyMesh.rotation.x = - this.MAX_TILT_FRONTBACK * this.acceleration; 212 | 213 | } 214 | 215 | // wheels rolling 216 | 217 | var angularSpeedRatio = 1 / ( this.modelScale * ( this.wheelDiameter / 2 ) ); 218 | 219 | var wheelDelta = forwardDelta * angularSpeedRatio; 220 | 221 | if ( this.loaded ) { 222 | 223 | this.frontLeftWheelMesh.rotation.x += wheelDelta; 224 | this.frontRightWheelMesh.rotation.x += wheelDelta; 225 | this.backLeftWheelMesh.rotation.x += wheelDelta; 226 | this.backRightWheelMesh.rotation.x += wheelDelta; 227 | 228 | } 229 | 230 | // front wheels steering 231 | 232 | this.frontLeftWheelRoot.rotation.y = this.wheelOrientation; 233 | this.frontRightWheelRoot.rotation.y = this.wheelOrientation; 234 | 235 | }; 236 | 237 | // internal helper methods 238 | 239 | function createBody ( geometry ) { 240 | 241 | scope.bodyGeometry = geometry; 242 | 243 | createCar(); 244 | 245 | }; 246 | 247 | function createWheels ( geometry ) { 248 | 249 | scope.wheelGeometry = geometry; 250 | 251 | createCar(); 252 | 253 | }; 254 | 255 | function createCar () { 256 | 257 | if ( scope.bodyGeometry && scope.wheelGeometry ) { 258 | 259 | // compute wheel geometry parameters 260 | 261 | if ( scope.autoWheelGeometry ) { 262 | 263 | scope.wheelGeometry.computeBoundingBox(); 264 | 265 | var bb = scope.wheelGeometry.boundingBox; 266 | 267 | scope.wheelOffset.add( bb.min, bb.max ); 268 | scope.wheelOffset.multiplyScalar( 0.5 ); 269 | 270 | scope.wheelDiameter = bb.max.y - bb.min.y; 271 | 272 | THREE.GeometryUtils.center( scope.wheelGeometry ); 273 | 274 | } 275 | 276 | // rig the car 277 | 278 | var s = scope.modelScale, 279 | delta = new THREE.Vector3(), 280 | faceMaterial = new THREE.MeshFaceMaterial(); 281 | 282 | // body 283 | 284 | scope.bodyMesh = new THREE.Mesh( scope.bodyGeometry, faceMaterial ); 285 | scope.bodyMesh.scale.set( s, s, s ); 286 | 287 | scope.root.add( scope.bodyMesh ); 288 | 289 | // front left wheel 290 | 291 | delta.multiply( scope.wheelOffset, new THREE.Vector3( s, s, s ) ); 292 | 293 | scope.frontLeftWheelRoot.position.addSelf( delta ); 294 | 295 | scope.frontLeftWheelMesh = new THREE.Mesh( scope.wheelGeometry, faceMaterial ); 296 | scope.frontLeftWheelMesh.scale.set( s, s, s ); 297 | 298 | scope.frontLeftWheelRoot.add( scope.frontLeftWheelMesh ); 299 | scope.root.add( scope.frontLeftWheelRoot ); 300 | 301 | // front right wheel 302 | 303 | delta.multiply( scope.wheelOffset, new THREE.Vector3( -s, s, s ) ); 304 | 305 | scope.frontRightWheelRoot.position.addSelf( delta ); 306 | 307 | scope.frontRightWheelMesh = new THREE.Mesh( scope.wheelGeometry, faceMaterial ); 308 | 309 | scope.frontRightWheelMesh.scale.set( s, s, s ); 310 | scope.frontRightWheelMesh.rotation.z = Math.PI; 311 | 312 | scope.frontRightWheelRoot.add( scope.frontRightWheelMesh ); 313 | scope.root.add( scope.frontRightWheelRoot ); 314 | 315 | // back left wheel 316 | 317 | delta.multiply( scope.wheelOffset, new THREE.Vector3( s, s, -s ) ); 318 | delta.z -= scope.backWheelOffset; 319 | 320 | scope.backLeftWheelMesh = new THREE.Mesh( scope.wheelGeometry, faceMaterial ); 321 | 322 | scope.backLeftWheelMesh.position.addSelf( delta ); 323 | scope.backLeftWheelMesh.scale.set( s, s, s ); 324 | 325 | scope.root.add( scope.backLeftWheelMesh ); 326 | 327 | // back right wheel 328 | 329 | delta.multiply( scope.wheelOffset, new THREE.Vector3( -s, s, -s ) ); 330 | delta.z -= scope.backWheelOffset; 331 | 332 | scope.backRightWheelMesh = new THREE.Mesh( scope.wheelGeometry, faceMaterial ); 333 | 334 | scope.backRightWheelMesh.position.addSelf( delta ); 335 | scope.backRightWheelMesh.scale.set( s, s, s ); 336 | scope.backRightWheelMesh.rotation.z = Math.PI; 337 | 338 | scope.root.add( scope.backRightWheelMesh ); 339 | 340 | // cache meshes 341 | 342 | scope.meshes = [ scope.bodyMesh, scope.frontLeftWheelMesh, scope.frontRightWheelMesh, scope.backLeftWheelMesh, scope.backRightWheelMesh ]; 343 | 344 | // callback 345 | 346 | scope.loaded = true; 347 | 348 | if ( scope.callback ) { 349 | 350 | scope.callback( scope ); 351 | 352 | } 353 | 354 | } 355 | 356 | }; 357 | 358 | function quadraticEaseOut( k ) { return - k * ( k - 2 ); } 359 | function cubicEaseOut( k ) { return --k * k * k + 1; } 360 | function circularEaseOut( k ) { return Math.sqrt( 1 - --k * k ); } 361 | function sinusoidalEaseOut( k ) { return Math.sin( k * Math.PI / 2 ); } 362 | function exponentialEaseOut( k ) { return k === 1 ? 1 : - Math.pow( 2, - 10 * k ) + 1; } 363 | 364 | }; 365 | -------------------------------------------------------------------------------- /r48/js/DAT.GUI.min.js: -------------------------------------------------------------------------------- 1 | /** 2 | * dat.gui Javascript Controller Library 3 | * http://dataarts.github.com/dat.gui 4 | * 5 | * Copyright 2011 Data Arts Team, Google Creative Lab 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | */ 13 | var DAT=DAT||{}; 14 | DAT.GUI=function(a){a==void 0&&(a={});var b=!1;a.height==void 0?a.height=300:b=!0;var d=[],c=[],i=!0,f,h,j=this,g=!0,e=280;if(a.width!=void 0)e=a.width;var q=!1,k,p,n=0,r;this.domElement=document.createElement("div");this.domElement.setAttribute("class","guidat");this.domElement.style.width=e+"px";var l=a.height,m=document.createElement("div");m.setAttribute("class","guidat-controllers");m.style.height=l+"px";m.addEventListener("DOMMouseScroll",function(a){var b=this.scrollTop;a.wheelDelta?b+=a.wheelDelta: 15 | a.detail&&(b+=a.detail);a.preventDefault&&a.preventDefault();a.returnValue=!1;m.scrollTop=b},!1);var o=document.createElement("a");o.setAttribute("class","guidat-toggle");o.setAttribute("href","#");o.innerHTML=g?"Close Controls":"Open Controls";var t=!1,C=0,x=0,u=!1,v,y,w,z,D=function(a){y=v;z=w;v=a.pageY;w=a.pageX;a=v-y;if(!g)if(a>0)g=!0,l=k=1,o.innerHTML=p||"Close Controls";else return;var b=z-w;if(a>0&&l>h){var d=DAT.GUI.map(l,h,h+100,1,0);a*=d}t=!0;C+=a;k+=a;l+=a;m.style.height=k+"px";x+=b;e+= 16 | b;e=DAT.GUI.constrain(e,240,500);j.domElement.style.width=e+"px";A()};o.addEventListener("mousedown",function(a){y=v=a.pageY;z=w=a.pageX;u=!0;a.preventDefault();C=x=0;document.addEventListener("mousemove",D,!1);return!1},!1);o.addEventListener("click",function(a){a.preventDefault();return!1},!1);document.addEventListener("mouseup",function(a){u&&!t&&j.toggle();if(u&&t)if(x==0&&B(),k>h)clearTimeout(r),k=n=h,s();else if(m.children.length>=1){var b=m.children[0].offsetHeight;clearTimeout(r);n=Math.round(l/ 17 | b)*b-1;n<=0?(j.close(),k=b*2):(k=n,s())}document.removeEventListener("mousemove",D,!1);a.preventDefault();return u=t=!1},!1);this.domElement.appendChild(m);this.domElement.appendChild(o);if(a.domElement)a.domElement.appendChild(this.domElement);else if(DAT.GUI.autoPlace){if(DAT.GUI.autoPlaceContainer==null)DAT.GUI.autoPlaceContainer=document.createElement("div"),DAT.GUI.autoPlaceContainer.setAttribute("id","guidat"),document.body.appendChild(DAT.GUI.autoPlaceContainer);DAT.GUI.autoPlaceContainer.appendChild(this.domElement)}this.autoListenIntervalTime= 18 | 1E3/60;var E=function(){f=setInterval(function(){j.listen()},this.autoListenIntervalTime)};this.__defineSetter__("autoListen",function(a){(i=a)?c.length>0&&E():clearInterval(f)});this.__defineGetter__("autoListen",function(){return i});this.listenTo=function(a){c.length==0&&E();c.push(a)};this.unlistenTo=function(a){for(var b=0;bk?"auto":"hidden"},G={number:DAT.GUI.ControllerNumber,string:DAT.GUI.ControllerString,"boolean":DAT.GUI.ControllerBoolean,"function":DAT.GUI.ControllerFunction};this.reset=function(){for(var a=0,b=DAT.GUI.allControllers.length;a-1)document.body.scrollTop=DAT.GUI.scrollTop;n=k;this.open()}DAT.GUI.guiIndex++}DAT.GUI.allGuis.push(this);if(DAT.GUI.allGuis.length==1&&(window.addEventListener("keyup",function(a){!DAT.GUI.supressHotKeys&&a.keyCode==72&&DAT.GUI.toggleHide()},!1), 24 | DAT.GUI.inlineCSS))a=document.createElement("style"),a.setAttribute("type","text/css"),a.innerHTML=DAT.GUI.inlineCSS,document.head.insertBefore(a,document.head.firstChild)};DAT.GUI.hidden=!1;DAT.GUI.autoPlace=!0;DAT.GUI.autoPlaceContainer=null;DAT.GUI.allControllers=[];DAT.GUI.allGuis=[];DAT.GUI.supressHotKeys=!1;DAT.GUI.toggleHide=function(){DAT.GUI.hidden?DAT.GUI.open():DAT.GUI.close()}; 25 | DAT.GUI.open=function(){DAT.GUI.hidden=!1;for(var a in DAT.GUI.allGuis)DAT.GUI.allGuis[a].domElement.style.display="block"};DAT.GUI.close=function(){DAT.GUI.hidden=!0;for(var a in DAT.GUI.allGuis)DAT.GUI.allGuis[a].domElement.style.display="none"};DAT.GUI.saveURL=function(){var a=DAT.GUI.replaceGetVar("saveString",DAT.GUI.getSaveString());window.location=a};DAT.GUI.scrollTop=-1; 26 | DAT.GUI.load=function(a){var a=a.split(","),b=parseInt(a[0]);DAT.GUI.scrollTop=parseInt(a[1]);for(var d=0;dd&&(a=d);return a};DAT.GUI.error=function(a){typeof console.error=="function"&&console.error("[DAT.GUI ERROR] "+a)};DAT.GUI.roundToDecimal=function(a,b){var d=Math.pow(10,b);return Math.round(a*d)/d};DAT.GUI.extendController=function(a){a.prototype=new DAT.GUI.Controller;a.prototype.constructor=a};DAT.GUI.addClass=function(a,b){DAT.GUI.hasClass(a,b)||(a.className+=" "+b)}; 32 | DAT.GUI.hasClass=function(a,b){return a.className.indexOf(b)!=-1};DAT.GUI.removeClass=function(a,b){a.className=a.className.replace(RegExp(" "+b,"g"),"")};DAT.GUI.getVarFromURL("saveString")!=null&&DAT.GUI.load(DAT.GUI.getVarFromURL("saveString")); 33 | DAT.GUI.Controller=function(){this.parent=arguments[0];this.object=arguments[1];this.propertyName=arguments[2];if(arguments.length>0)this.initialValue=this.object[this.propertyName];this.domElement=document.createElement("div");this.domElement.setAttribute("class","guidat-controller "+this.type);this.propertyNameElement=document.createElement("span");this.propertyNameElement.setAttribute("class","guidat-propertyname");this.name(this.propertyName);this.domElement.appendChild(this.propertyNameElement); 34 | DAT.GUI.makeUnselectable(this.domElement)};DAT.GUI.Controller.prototype.changeFunction=null;DAT.GUI.Controller.prototype.finishChangeFunction=null;DAT.GUI.Controller.prototype.name=function(a){this.propertyNameElement.innerHTML=a;return this};DAT.GUI.Controller.prototype.reset=function(){this.setValue(this.initialValue);return this};DAT.GUI.Controller.prototype.listen=function(){this.parent.listenTo(this);return this};DAT.GUI.Controller.prototype.unlisten=function(){this.parent.unlistenTo(this);return this}; 35 | DAT.GUI.Controller.prototype.setValue=function(a){if(this.object[this.propertyName]!=void 0)this.object[this.propertyName]=a;else{var b={};b[this.propertyName]=a;this.object.set(b)}this.changeFunction!=null&&this.changeFunction.call(this,a);this.updateDisplay();return this};DAT.GUI.Controller.prototype.getValue=function(){var a=this.object[this.propertyName];a==void 0&&(a=this.object.get(this.propertyName));return a};DAT.GUI.Controller.prototype.updateDisplay=function(){}; 36 | DAT.GUI.Controller.prototype.onChange=function(a){this.changeFunction=a;return this};DAT.GUI.Controller.prototype.onFinishChange=function(a){this.finishChangeFunction=a;return this}; 37 | DAT.GUI.Controller.prototype.options=function(){var a=this,b=document.createElement("select");if(arguments.length==1){var d=arguments[0],c;for(c in d){var i=document.createElement("option");i.innerHTML=c;i.setAttribute("value",d[c]);if(arguments[c]==this.getValue())i.selected=!0;b.appendChild(i)}}else for(c=0;c=h&&(a=h);return DAT.GUI.Controller.prototype.setValue.call(this, 47 | a)};this.updateDisplay=function(){g.value=DAT.GUI.roundToDecimal(a.getValue(),4);if(e)e.value=a.getValue()}};DAT.GUI.extendController(DAT.GUI.ControllerNumber); 48 | DAT.GUI.ControllerNumberSlider=function(a,b,d,c,i){var f=!1,h=this;this.domElement=document.createElement("div");this.domElement.setAttribute("class","guidat-slider-bg");this.fg=document.createElement("div");this.fg.setAttribute("class","guidat-slider-fg");this.domElement.appendChild(this.fg);var j=function(b){if(f){var c;c=h.domElement;var d=0,g=0;if(c.offsetParent){do d+=c.offsetLeft,g+=c.offsetTop;while(c=c.offsetParent);c=[d,g]}else c=void 0;b=DAT.GUI.map(b.pageX,c[0],c[0]+h.domElement.offsetWidth, 49 | a.getMin(),a.getMax());b=Math.round(b/a.getStep())*a.getStep();a.setValue(b)}};this.domElement.addEventListener("mousedown",function(b){f=!0;DAT.GUI.addClass(a.domElement,"active");j(b);document.addEventListener("mouseup",g,!1)},!1);var g=function(){DAT.GUI.removeClass(a.domElement,"active");f=!1;a.finishChangeFunction!=null&&a.finishChangeFunction.call(this,a.getValue());document.removeEventListener("mouseup",g,!1)};this.__defineSetter__("value",function(b){this.fg.style.width=DAT.GUI.map(b,a.getMin(), 50 | a.getMax(),0,100)+"%"});document.addEventListener("mousemove",j,!1);this.value=i}; 51 | DAT.GUI.ControllerString=function(){this.type="string";var a=this;DAT.GUI.Controller.apply(this,arguments);var b=document.createElement("input"),d=this.getValue();b.setAttribute("value",d);b.setAttribute("spellcheck","false");this.domElement.addEventListener("mouseup",function(){b.focus();b.select()},!1);b.addEventListener("keyup",function(c){c.keyCode==13&&a.finishChangeFunction!=null&&(a.finishChangeFunction.call(this,a.getValue()),b.blur());a.setValue(b.value)},!1);b.addEventListener("mousedown", 52 | function(){DAT.GUI.makeSelectable(b)},!1);b.addEventListener("blur",function(){DAT.GUI.supressHotKeys=!1;a.finishChangeFunction!=null&&a.finishChangeFunction.call(this,a.getValue())},!1);b.addEventListener("focus",function(){DAT.GUI.supressHotKeys=!0},!1);this.updateDisplay=function(){b.value=a.getValue()};this.options=function(){a.domElement.removeChild(b);return DAT.GUI.Controller.prototype.options.apply(this,arguments)};this.domElement.appendChild(b)};DAT.GUI.extendController(DAT.GUI.ControllerString); 53 | DAT.GUI.inlineCSS="#guidat { position: fixed; top: 0; right: 0; width: auto; z-index: 1001; text-align: right; } .guidat { color: #fff; opacity: 0.97; text-align: left; float: right; margin-right: 20px; margin-bottom: 20px; background-color: #fff; } .guidat, .guidat input { font: 9.5px Lucida Grande, sans-serif; } .guidat-controllers { height: 300px; overflow-y: auto; overflow-x: hidden; background-color: rgba(0, 0, 0, 0.1); } a.guidat-toggle:link, a.guidat-toggle:visited, a.guidat-toggle:active { text-decoration: none; cursor: pointer; color: #fff; background-color: #222; text-align: center; display: block; padding: 5px; } a.guidat-toggle:hover { background-color: #000; } .guidat-controller { padding: 3px; height: 25px; clear: left; border-bottom: 1px solid #222; background-color: #111; } .guidat-controller, .guidat-controller input, .guidat-slider-bg, .guidat-slider-fg { -moz-transition: background-color 0.15s linear; -webkit-transition: background-color 0.15s linear; transition: background-color 0.15s linear; } .guidat-controller.boolean:hover, .guidat-controller.function:hover { background-color: #000; } .guidat-controller input { float: right; outline: none; border: 0; padding: 4px; margin-top: 2px; background-color: #222; } .guidat-controller select { margin-top: 4px; float: right; } .guidat-controller input:hover { background-color: #444; } .guidat-controller input:focus, .guidat-controller.active input { background-color: #555; color: #fff; } .guidat-controller.number { border-left: 5px solid #00aeff; } .guidat-controller.string { border-left: 5px solid #1ed36f; } .guidat-controller.string input { border: 0; color: #1ed36f; margin-right: 2px; width: 148px; } .guidat-controller.boolean { border-left: 5px solid #54396e; } .guidat-controller.function { border-left: 5px solid #e61d5f; } .guidat-controller.number input[type=text] { width: 35px; margin-left: 5px; margin-right: 2px; color: #00aeff; } .guidat .guidat-controller.boolean input { margin-top: 6px; margin-right: 2px; font-size: 20px; } .guidat-controller:last-child { border-bottom: none; -webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.5); -moz-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.5); box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.5); } .guidat-propertyname { padding: 5px; padding-top: 7px; cursor: default; display: inline-block; } .guidat-controller .guidat-slider-bg:hover, .guidat-controller.active .guidat-slider-bg { background-color: #444; } .guidat-controller .guidat-slider-bg .guidat-slider-fg:hover, .guidat-controller.active .guidat-slider-bg .guidat-slider-fg { background-color: #52c8ff; } .guidat-slider-bg { background-color: #222; cursor: ew-resize; width: 40%; margin-top: 2px; float: right; height: 21px; } .guidat-slider-fg { cursor: ew-resize; background-color: #00aeff; height: 21px; } "; 54 | -------------------------------------------------------------------------------- /r48/js/Detector.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * @author mr.doob / http://mrdoob.com/ 4 | */ 5 | 6 | Detector = { 7 | 8 | canvas: !! window.CanvasRenderingContext2D, 9 | webgl: ( function () { try { return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' ); } catch( e ) { return false; } } )(), 10 | workers: !! window.Worker, 11 | fileapi: window.File && window.FileReader && window.FileList && window.Blob, 12 | 13 | getWebGLErrorMessage: function () { 14 | 15 | var element = document.createElement( 'div' ); 16 | element.id = 'webgl-error-message'; 17 | element.style.fontFamily = 'monospace'; 18 | element.style.fontSize = '13px'; 19 | element.style.fontWeight = 'normal'; 20 | element.style.textAlign = 'center'; 21 | element.style.background = '#fff'; 22 | element.style.color = '#000'; 23 | element.style.padding = '1.5em'; 24 | element.style.width = '400px'; 25 | element.style.margin = '5em auto 0'; 26 | 27 | if ( ! this.webgl ) { 28 | 29 | element.innerHTML = window.WebGLRenderingContext ? [ 30 | 'Your graphics card does not seem to support WebGL.
', 31 | 'Find out how to get it here.' 32 | ].join( '\n' ) : [ 33 | 'Your browser does not seem to support WebGL.
', 34 | 'Find out how to get it here.' 35 | ].join( '\n' ); 36 | 37 | } 38 | 39 | return element; 40 | 41 | }, 42 | 43 | addGetWebGLMessage: function ( parameters ) { 44 | 45 | var parent, id, element; 46 | 47 | parameters = parameters || {}; 48 | 49 | parent = parameters.parent !== undefined ? parameters.parent : document.body; 50 | id = parameters.id !== undefined ? parameters.id : 'oldie'; 51 | 52 | element = Detector.getWebGLErrorMessage(); 53 | element.id = id; 54 | 55 | parent.appendChild( element ); 56 | 57 | } 58 | 59 | }; 60 | -------------------------------------------------------------------------------- /r48/js/ImprovedNoise.js: -------------------------------------------------------------------------------- 1 | // http://mrl.nyu.edu/~perlin/noise/ 2 | 3 | var ImprovedNoise = function () { 4 | 5 | var p = [151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10, 6 | 23,190,6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,88,237,149,56,87, 7 | 174,20,125,136,171,168,68,175,74,165,71,134,139,48,27,166,77,146,158,231,83,111,229,122,60,211, 8 | 133,230,220,105,92,41,55,46,245,40,244,102,143,54,65,25,63,161,1,216,80,73,209,76,132,187,208, 9 | 89,18,169,200,196,135,130,116,188,159,86,164,100,109,198,173,186,3,64,52,217,226,250,124,123,5, 10 | 202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,223,183,170,213,119, 11 | 248,152,2,44,154,163,70,221,153,101,155,167,43,172,9,129,22,39,253,19,98,108,110,79,113,224,232, 12 | 178,185,112,104,218,246,97,228,251,34,242,193,238,210,144,12,191,179,162,241,81,51,145,235,249, 13 | 14,239,107,49,192,214,31,181,199,106,157,184,84,204,176,115,121,50,45,127,4,150,254,138,236,205, 14 | 93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180]; 15 | 16 | for (var i=0; i < 256 ; i++) { 17 | 18 | p[256+i] = p[i]; 19 | 20 | } 21 | 22 | function fade(t) { 23 | 24 | return t * t * t * (t * (t * 6 - 15) + 10); 25 | 26 | } 27 | 28 | function lerp(t, a, b) { 29 | 30 | return a + t * (b - a); 31 | 32 | } 33 | 34 | function grad(hash, x, y, z) { 35 | 36 | var h = hash & 15; 37 | var u = h < 8 ? x : y, v = h < 4 ? y : h == 12 || h == 14 ? x : z; 38 | return ((h&1) == 0 ? u : -u) + ((h&2) == 0 ? v : -v); 39 | 40 | } 41 | 42 | return { 43 | 44 | noise: function (x, y, z) { 45 | 46 | var floorX = ~~x, floorY = ~~y, floorZ = ~~z; 47 | 48 | var X = floorX & 255, Y = floorY & 255, Z = floorZ & 255; 49 | 50 | x -= floorX; 51 | y -= floorY; 52 | z -= floorZ; 53 | 54 | var xMinus1 = x -1, yMinus1 = y - 1, zMinus1 = z - 1; 55 | 56 | var u = fade(x), v = fade(y), w = fade(z); 57 | 58 | var A = p[X]+Y, AA = p[A]+Z, AB = p[A+1]+Z, B = p[X+1]+Y, BA = p[B]+Z, BB = p[B+1]+Z; 59 | 60 | return lerp(w, lerp(v, lerp(u, grad(p[AA], x, y, z), 61 | grad(p[BA], xMinus1, y, z)), 62 | lerp(u, grad(p[AB], x, yMinus1, z), 63 | grad(p[BB], xMinus1, yMinus1, z))), 64 | lerp(v, lerp(u, grad(p[AA+1], x, y, zMinus1), 65 | grad(p[BA+1], xMinus1, y, z-1)), 66 | lerp(u, grad(p[AB+1], x, yMinus1, zMinus1), 67 | grad(p[BB+1], xMinus1, yMinus1, zMinus1)))); 68 | 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /r48/js/MD2Character.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.MD2Character = function () { 6 | 7 | var scope = this; 8 | 9 | this.scale = 1; 10 | this.animationFPS = 6; 11 | 12 | this.root = new THREE.Object3D(); 13 | 14 | this.meshBody = null; 15 | this.meshWeapon = null; 16 | 17 | this.skinsBody = []; 18 | this.skinsWeapon = []; 19 | 20 | this.weapons = []; 21 | 22 | this.activeAnimation = null; 23 | 24 | this.onLoadComplete = function () {}; 25 | 26 | this.loadCounter = 0; 27 | 28 | this.loadParts = function ( config ) { 29 | 30 | this.loadCounter = config.weapons.length * 2 + config.skins.length + 1; 31 | 32 | var weaponsTextures = [] 33 | for ( var i = 0; i < config.weapons.length; i ++ ) weaponsTextures[ i ] = config.weapons[ i ][ 1 ]; 34 | 35 | // SKINS 36 | 37 | this.skinsBody = loadTextures( config.baseUrl + "skins/", config.skins ); 38 | this.skinsWeapon = loadTextures( config.baseUrl + "skins/", weaponsTextures ); 39 | 40 | // BODY 41 | 42 | var loader = new THREE.JSONLoader(); 43 | 44 | loader.load( config.baseUrl + config.body, function( geo ) { 45 | 46 | geo.computeBoundingBox(); 47 | scope.root.position.y = - scope.scale * geo.boundingBox.min.y; 48 | 49 | var mesh = createPart( geo, scope.skinsBody[ 0 ] ); 50 | mesh.scale.set( scope.scale, scope.scale, scope.scale ); 51 | 52 | scope.root.add( mesh ); 53 | 54 | scope.meshBody = mesh; 55 | scope.activeAnimation = geo.firstAnimation; 56 | 57 | checkLoadingComplete(); 58 | 59 | } ); 60 | 61 | // WEAPONS 62 | 63 | var generateCallback = function ( index, name ) { 64 | 65 | return function( geo ) { 66 | 67 | var mesh = createPart( geo, scope.skinsWeapon[ index ] ); 68 | mesh.scale.set( scope.scale, scope.scale, scope.scale ); 69 | mesh.visible = false; 70 | 71 | mesh.name = name; 72 | 73 | scope.root.add( mesh ); 74 | 75 | scope.weapons[ index ] = mesh; 76 | scope.meshWeapon = mesh; 77 | 78 | checkLoadingComplete(); 79 | 80 | } 81 | 82 | } 83 | 84 | for ( var i = 0; i < config.weapons.length; i ++ ) { 85 | 86 | loader.load( config.baseUrl + config.weapons[ i ][ 0 ], generateCallback( i, config.weapons[ i ][ 0 ] ) ); 87 | 88 | } 89 | 90 | }; 91 | 92 | this.setPlaybackRate = function ( rate ) { 93 | 94 | if ( this.meshBody ) this.meshBody.duration = this.meshBody.baseDuration / rate; 95 | if ( this.meshWeapon ) this.meshWeapon.duration = this.meshWeapon.baseDuration / rate; 96 | 97 | }; 98 | 99 | this.setWireframe = function ( wireframeEnabled ) { 100 | 101 | if ( wireframeEnabled ) { 102 | 103 | if ( this.meshBody ) this.meshBody.material = this.meshBody.materialWireframe; 104 | if ( this.meshWeapon ) this.meshWeapon.material = this.meshWeapon.materialWireframe; 105 | 106 | } else { 107 | 108 | if ( this.meshBody ) this.meshBody.material = this.meshBody.materialTexture; 109 | if ( this.meshWeapon ) this.meshWeapon.material = this.meshWeapon.materialTexture; 110 | 111 | } 112 | 113 | }; 114 | 115 | this.setSkin = function( index ) { 116 | 117 | if ( this.meshBody && this.meshBody.material.wireframe === false ) { 118 | 119 | this.meshBody.material.map = this.skinsBody[ index ]; 120 | 121 | } 122 | 123 | }; 124 | 125 | this.setWeapon = function ( index ) { 126 | 127 | for ( var i = 0; i < this.weapons.length; i ++ ) this.weapons[ i ].visible = false; 128 | 129 | var activeWeapon = this.weapons[ index ]; 130 | 131 | if ( activeWeapon ) { 132 | 133 | activeWeapon.visible = true; 134 | this.meshWeapon = activeWeapon; 135 | 136 | activeWeapon.playAnimation( this.activeAnimation, this.animationFPS ); 137 | 138 | this.meshWeapon.baseDuration = this.meshWeapon.duration; 139 | 140 | this.meshWeapon.time = this.meshBody.time; 141 | this.meshWeapon.duration = this.meshBody.duration; 142 | 143 | } 144 | 145 | }; 146 | 147 | this.setAnimation = function ( animationName ) { 148 | 149 | if ( this.meshBody ) { 150 | 151 | this.meshBody.playAnimation( animationName, this.animationFPS ); 152 | this.meshBody.baseDuration = this.meshBody.duration; 153 | 154 | } 155 | 156 | if ( this.meshWeapon ) { 157 | 158 | this.meshWeapon.playAnimation( animationName, this.animationFPS ); 159 | this.meshWeapon.baseDuration = this.meshWeapon.duration; 160 | this.meshWeapon.time = this.meshBody.time; 161 | 162 | } 163 | 164 | this.activeAnimation = animationName; 165 | 166 | }; 167 | 168 | this.update = function ( delta ) { 169 | 170 | if ( this.meshBody ) { 171 | 172 | this.meshBody.updateAnimation( 1000 * delta ); 173 | 174 | } 175 | 176 | if ( this.meshWeapon ) { 177 | 178 | this.meshWeapon.updateAnimation( 1000 * delta ); 179 | 180 | } 181 | 182 | }; 183 | 184 | function loadTextures( baseUrl, textureUrls ) { 185 | 186 | var mapping = new THREE.UVMapping(); 187 | var textures = []; 188 | 189 | for ( var i = 0; i < textureUrls.length; i ++ ) { 190 | 191 | textures[ i ] = THREE.ImageUtils.loadTexture( baseUrl + textureUrls[ i ], mapping, checkLoadingComplete ); 192 | textures[ i ].name = textureUrls[ i ]; 193 | 194 | } 195 | 196 | return textures; 197 | 198 | }; 199 | 200 | function createPart( geometry, skinMap ) { 201 | 202 | geometry.computeMorphNormals(); 203 | 204 | var whiteMap = THREE.ImageUtils.generateDataTexture( 1, 1, new THREE.Color( 0xffffff ) ); 205 | var materialWireframe = new THREE.MeshPhongMaterial( { color: 0xffaa00, specular: 0x111111, shininess: 50, wireframe: true, shading: THREE.SmoothShading, map: whiteMap, morphTargets: true, morphNormals: true, perPixel: true, metal: false } ); 206 | 207 | var materialTexture = new THREE.MeshPhongMaterial( { color: 0xffffff, specular: 0x111111, shininess: 50, wireframe: false, shading: THREE.SmoothShading, map: skinMap, morphTargets: true, morphNormals: true, perPixel: true, metal: false } ); 208 | materialTexture.wrapAround = true; 209 | 210 | // 211 | 212 | var mesh = new THREE.MorphAnimMesh( geometry, materialTexture ); 213 | mesh.rotation.y = -Math.PI/2; 214 | 215 | mesh.castShadow = true; 216 | mesh.receiveShadow = true; 217 | 218 | // 219 | 220 | mesh.materialTexture = materialTexture; 221 | mesh.materialWireframe = materialWireframe; 222 | 223 | // 224 | 225 | mesh.parseAnimations(); 226 | 227 | mesh.playAnimation( geometry.firstAnimation, scope.animationFPS ); 228 | mesh.baseDuration = mesh.duration; 229 | 230 | return mesh; 231 | 232 | }; 233 | 234 | function checkLoadingComplete() { 235 | 236 | scope.loadCounter -= 1; 237 | 238 | if ( scope.loadCounter === 0 ) scope.onLoadComplete(); 239 | 240 | }; 241 | 242 | }; 243 | -------------------------------------------------------------------------------- /r48/js/PRNG.js: -------------------------------------------------------------------------------- 1 | // Park-Miller-Carta Pseudo-Random Number Generator 2 | // https://github.com/pnitsch/BitmapData.js/blob/master/js/BitmapData.js 3 | 4 | var PRNG = function () { 5 | 6 | this.seed = 1; 7 | this.next = function() { return (this.gen() / 2147483647); }; 8 | this.nextRange = function(min, max) { return min + ((max - min) * this.next()) }; 9 | this.gen = function() { return this.seed = (this.seed * 16807) % 2147483647; }; 10 | 11 | }; 12 | -------------------------------------------------------------------------------- /r48/js/RenderManager.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * THREE.Extras.RenderManager helps handling multiple scenes, cameras and render loops. 3 | * 4 | * @author Thibaut 'BKcore' Despoulain 5 | * 6 | * Initialize the a RenderManager by passing a Renderer object: 7 | * var renderManager = new THREE.Extras.RenderManager(new THREE.WebGLRenderer()); 8 | * 9 | * A render setup structure : 10 | * { 11 | * id : render setup ID, 12 | * scene : main scene, 13 | * camera : main camera, 14 | * render : render loop called when render setup is active (current), 15 | * objects : object references accessible in the render loop via this.objects 16 | * } 17 | * 18 | * The render method's context will be the render setup's object, so in your render loop: 19 | * function(delta, renderer) 20 | * { 21 | * this.scene; 22 | * this.camera; 23 | * this.id; 24 | * this.objects; 25 | * renderer.render(...); 26 | * } 27 | * 28 | * Use the "objects" attribute to store useful references and variables like time, geometries, materials, etc. 29 | * Example: 30 | * renderManager.add('mySetup', scene, camera, function(delta, renderer) 31 | * { 32 | * this.objects.timer += delta; 33 | * this.objects.torus.rotation.z = Math.PI * Math.cos(this.objects.timer); 34 | * renderer.render(this.scene, this.camera); 35 | * }, 36 | * { 37 | * timer: 0, 38 | * torus: torusMesh 39 | * }); 40 | */ 41 | 42 | THREE = THREE || {}; 43 | THREE.Extras = THREE.Extras || {}; 44 | 45 | THREE.Extras.RenderManager = function(renderer) 46 | { 47 | this.renderer = renderer; 48 | this.time = Date.now()/1000; 49 | 50 | this.renders = {}; 51 | this.current = {}; 52 | this.size = 0; 53 | 54 | this.defaultRenderMethod = function(delta, renderer) 55 | { 56 | renderer.render(this.scene, this.camera); 57 | }; 58 | }; 59 | 60 | THREE.Extras.RenderManager.prototype.add = function(id, scene, camera, render, objects) 61 | { 62 | render = render || this.defaultRenderMethod; 63 | objects = objects || {}; 64 | 65 | this.renders[id] = { 66 | id: id, 67 | scene: scene, 68 | camera: camera, 69 | render: render, 70 | objects: objects 71 | }; 72 | 73 | if(this.size == 0) this.current = this.renders[id]; 74 | 75 | this.size++; 76 | }; 77 | 78 | THREE.Extras.RenderManager.prototype.get = function(id) 79 | { 80 | return this.renders[id]; 81 | }; 82 | 83 | THREE.Extras.RenderManager.prototype.remove = function(id) 84 | { 85 | if(id in this.renders) 86 | { 87 | delete this.renders[id]; 88 | this.size--; 89 | } 90 | }; 91 | 92 | THREE.Extras.RenderManager.prototype.renderCurrent = function() 93 | { 94 | if(this.current && this.current.render) 95 | { 96 | var now = Date.now()/1000; 97 | var delta = now - this.time; 98 | this.time = now; 99 | 100 | this.current.render.call(this.current, delta, this.renderer); 101 | } 102 | else console.warn('RenderManager: No current render defined.'); 103 | }; 104 | 105 | THREE.Extras.RenderManager.prototype.setCurrent = function(id) 106 | { 107 | if(id in this.renders) 108 | { 109 | this.current = this.renders[id]; 110 | } 111 | else console.warn('RenderManager: Render "'+id+'" not found.'); 112 | }; -------------------------------------------------------------------------------- /r48/js/ShaderSkin.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/js/ShaderSkin.js -------------------------------------------------------------------------------- /r48/js/ShaderTerrain.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * 4 | */ 5 | 6 | THREE.ShaderTerrain = { 7 | 8 | /* ------------------------------------------------------------------------- 9 | // Dynamic terrain shader 10 | // - Blinn-Phong 11 | // - height + normal + diffuse1 + diffuse2 + specular + detail maps 12 | // - point and directional lights (use with "lights: true" material option) 13 | ------------------------------------------------------------------------- */ 14 | 15 | 'terrain' : { 16 | 17 | uniforms: THREE.UniformsUtils.merge( [ 18 | 19 | THREE.UniformsLib[ "fog" ], 20 | THREE.UniformsLib[ "lights" ], 21 | 22 | { 23 | 24 | "enableDiffuse1" : { type: "i", value: 0 }, 25 | "enableDiffuse2" : { type: "i", value: 0 }, 26 | "enableSpecular" : { type: "i", value: 0 }, 27 | "enableReflection": { type: "i", value: 0 }, 28 | 29 | "tDiffuse1" : { type: "t", value: 0, texture: null }, 30 | "tDiffuse2" : { type: "t", value: 1, texture: null }, 31 | "tDetail" : { type: "t", value: 2, texture: null }, 32 | "tNormal" : { type: "t", value: 3, texture: null }, 33 | "tSpecular" : { type: "t", value: 4, texture: null }, 34 | "tDisplacement": { type: "t", value: 5, texture: null }, 35 | 36 | "uNormalScale": { type: "f", value: 1.0 }, 37 | 38 | "uDisplacementBias": { type: "f", value: 0.0 }, 39 | "uDisplacementScale": { type: "f", value: 1.0 }, 40 | 41 | "uDiffuseColor": { type: "c", value: new THREE.Color( 0xeeeeee ) }, 42 | "uSpecularColor": { type: "c", value: new THREE.Color( 0x111111 ) }, 43 | "uAmbientColor": { type: "c", value: new THREE.Color( 0x050505 ) }, 44 | "uShininess": { type: "f", value: 30 }, 45 | "uOpacity": { type: "f", value: 1 }, 46 | 47 | "uRepeatBase" : { type: "v2", value: new THREE.Vector2( 1, 1 ) }, 48 | "uRepeatOverlay" : { type: "v2", value: new THREE.Vector2( 1, 1 ) }, 49 | 50 | "uOffset" : { type: "v2", value: new THREE.Vector2( 0, 0 ) } 51 | 52 | } 53 | 54 | ] ), 55 | 56 | fragmentShader: [ 57 | 58 | "uniform vec3 uAmbientColor;", 59 | "uniform vec3 uDiffuseColor;", 60 | "uniform vec3 uSpecularColor;", 61 | "uniform float uShininess;", 62 | "uniform float uOpacity;", 63 | 64 | "uniform bool enableDiffuse1;", 65 | "uniform bool enableDiffuse2;", 66 | "uniform bool enableSpecular;", 67 | 68 | "uniform sampler2D tDiffuse1;", 69 | "uniform sampler2D tDiffuse2;", 70 | "uniform sampler2D tDetail;", 71 | "uniform sampler2D tNormal;", 72 | "uniform sampler2D tSpecular;", 73 | "uniform sampler2D tDisplacement;", 74 | 75 | "uniform float uNormalScale;", 76 | 77 | "uniform vec2 uRepeatOverlay;", 78 | "uniform vec2 uRepeatBase;", 79 | 80 | "uniform vec2 uOffset;", 81 | 82 | "varying vec3 vTangent;", 83 | "varying vec3 vBinormal;", 84 | "varying vec3 vNormal;", 85 | "varying vec2 vUv;", 86 | 87 | "uniform vec3 ambientLightColor;", 88 | 89 | "#if MAX_DIR_LIGHTS > 0", 90 | "uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];", 91 | "uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];", 92 | "#endif", 93 | 94 | "#if MAX_POINT_LIGHTS > 0", 95 | "uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];", 96 | "uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];", 97 | "uniform float pointLightDistance[ MAX_POINT_LIGHTS ];", 98 | "#endif", 99 | 100 | "varying vec3 vViewPosition;", 101 | 102 | THREE.ShaderChunk[ "fog_pars_fragment" ], 103 | 104 | "void main() {", 105 | 106 | "gl_FragColor = vec4( vec3( 1.0 ), uOpacity );", 107 | 108 | "vec3 specularTex = vec3( 1.0 );", 109 | 110 | "vec2 uvOverlay = uRepeatOverlay * vUv + uOffset;", 111 | "vec2 uvBase = uRepeatBase * vUv;", 112 | 113 | "vec3 normalTex = texture2D( tDetail, uvOverlay ).xyz * 2.0 - 1.0;", 114 | "normalTex.xy *= uNormalScale;", 115 | "normalTex = normalize( normalTex );", 116 | 117 | "if( enableDiffuse1 && enableDiffuse2 ) {", 118 | 119 | "vec4 colDiffuse1 = texture2D( tDiffuse1, uvOverlay );", 120 | "vec4 colDiffuse2 = texture2D( tDiffuse2, uvOverlay );", 121 | 122 | "#ifdef GAMMA_INPUT", 123 | 124 | "colDiffuse1.xyz *= colDiffuse1.xyz;", 125 | "colDiffuse2.xyz *= colDiffuse2.xyz;", 126 | 127 | "#endif", 128 | 129 | "gl_FragColor = gl_FragColor * mix ( colDiffuse1, colDiffuse2, 1.0 - texture2D( tDisplacement, uvBase ) );", 130 | 131 | " } else if( enableDiffuse1 ) {", 132 | 133 | "gl_FragColor = gl_FragColor * texture2D( tDiffuse1, uvOverlay );", 134 | 135 | "} else if( enableDiffuse2 ) {", 136 | 137 | "gl_FragColor = gl_FragColor * texture2D( tDiffuse2, uvOverlay );", 138 | 139 | "}", 140 | 141 | "if( enableSpecular )", 142 | "specularTex = texture2D( tSpecular, uvOverlay ).xyz;", 143 | 144 | "mat3 tsb = mat3( vTangent, vBinormal, vNormal );", 145 | "vec3 finalNormal = tsb * normalTex;", 146 | 147 | "vec3 normal = normalize( finalNormal );", 148 | "vec3 viewPosition = normalize( vViewPosition );", 149 | 150 | // point lights 151 | 152 | "#if MAX_POINT_LIGHTS > 0", 153 | 154 | "vec3 pointDiffuse = vec3( 0.0 );", 155 | "vec3 pointSpecular = vec3( 0.0 );", 156 | 157 | "for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {", 158 | 159 | "vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );", 160 | "vec3 lVector = lPosition.xyz + vViewPosition.xyz;", 161 | 162 | "float lDistance = 1.0;", 163 | "if ( pointLightDistance[ i ] > 0.0 )", 164 | "lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );", 165 | 166 | "lVector = normalize( lVector );", 167 | 168 | "vec3 pointHalfVector = normalize( lVector + viewPosition );", 169 | "float pointDistance = lDistance;", 170 | 171 | "float pointDotNormalHalf = max( dot( normal, pointHalfVector ), 0.0 );", 172 | "float pointDiffuseWeight = max( dot( normal, lVector ), 0.0 );", 173 | 174 | "float pointSpecularWeight = specularTex.r * max( pow( pointDotNormalHalf, uShininess ), 0.0 );", 175 | 176 | "pointDiffuse += pointDistance * pointLightColor[ i ] * uDiffuseColor * pointDiffuseWeight;", 177 | "pointSpecular += pointDistance * pointLightColor[ i ] * uSpecularColor * pointSpecularWeight * pointDiffuseWeight;", 178 | 179 | "}", 180 | 181 | "#endif", 182 | 183 | // directional lights 184 | 185 | "#if MAX_DIR_LIGHTS > 0", 186 | 187 | "vec3 dirDiffuse = vec3( 0.0 );", 188 | "vec3 dirSpecular = vec3( 0.0 );", 189 | 190 | "for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {", 191 | 192 | "vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );", 193 | 194 | "vec3 dirVector = normalize( lDirection.xyz );", 195 | "vec3 dirHalfVector = normalize( dirVector + viewPosition );", 196 | 197 | "float dirDotNormalHalf = max( dot( normal, dirHalfVector ), 0.0 );", 198 | "float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );", 199 | 200 | "float dirSpecularWeight = specularTex.r * max( pow( dirDotNormalHalf, uShininess ), 0.0 );", 201 | 202 | "dirDiffuse += directionalLightColor[ i ] * uDiffuseColor * dirDiffuseWeight;", 203 | "dirSpecular += directionalLightColor[ i ] * uSpecularColor * dirSpecularWeight * dirDiffuseWeight;", 204 | 205 | "}", 206 | 207 | "#endif", 208 | 209 | // all lights contribution summation 210 | 211 | "vec3 totalDiffuse = vec3( 0.0 );", 212 | "vec3 totalSpecular = vec3( 0.0 );", 213 | 214 | "#if MAX_DIR_LIGHTS > 0", 215 | 216 | "totalDiffuse += dirDiffuse;", 217 | "totalSpecular += dirSpecular;", 218 | 219 | "#endif", 220 | 221 | "#if MAX_POINT_LIGHTS > 0", 222 | 223 | "totalDiffuse += pointDiffuse;", 224 | "totalSpecular += pointSpecular;", 225 | 226 | "#endif", 227 | 228 | //"gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor) + totalSpecular;", 229 | "gl_FragColor.xyz = gl_FragColor.xyz * ( totalDiffuse + ambientLightColor * uAmbientColor + totalSpecular );", 230 | 231 | THREE.ShaderChunk[ "linear_to_gamma_fragment" ], 232 | THREE.ShaderChunk[ "fog_fragment" ], 233 | 234 | "}" 235 | 236 | ].join("\n"), 237 | 238 | vertexShader: [ 239 | 240 | "attribute vec4 tangent;", 241 | 242 | "uniform vec2 uRepeatBase;", 243 | 244 | "uniform sampler2D tNormal;", 245 | 246 | "#ifdef VERTEX_TEXTURES", 247 | 248 | "uniform sampler2D tDisplacement;", 249 | "uniform float uDisplacementScale;", 250 | "uniform float uDisplacementBias;", 251 | 252 | "#endif", 253 | 254 | "varying vec3 vTangent;", 255 | "varying vec3 vBinormal;", 256 | "varying vec3 vNormal;", 257 | "varying vec2 vUv;", 258 | 259 | "varying vec3 vViewPosition;", 260 | 261 | "void main() {", 262 | 263 | "vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );", 264 | 265 | "vViewPosition = -mvPosition.xyz;", 266 | 267 | "vNormal = normalize( normalMatrix * normal );", 268 | 269 | // tangent and binormal vectors 270 | 271 | "vTangent = normalize( normalMatrix * tangent.xyz );", 272 | 273 | "vBinormal = cross( vNormal, vTangent ) * tangent.w;", 274 | "vBinormal = normalize( vBinormal );", 275 | 276 | // texture coordinates 277 | 278 | "vUv = uv;", 279 | 280 | "vec2 uvBase = uv * uRepeatBase;", 281 | 282 | // displacement mapping 283 | 284 | "#ifdef VERTEX_TEXTURES", 285 | 286 | "vec3 dv = texture2D( tDisplacement, uvBase ).xyz;", 287 | "float df = uDisplacementScale * dv.x + uDisplacementBias;", 288 | "vec4 displacedPosition = vec4( vNormal.xyz * df, 0.0 ) + mvPosition;", 289 | "gl_Position = projectionMatrix * displacedPosition;", 290 | 291 | "#else", 292 | 293 | "gl_Position = projectionMatrix * mvPosition;", 294 | 295 | "#endif", 296 | 297 | "vec3 normalTex = texture2D( tNormal, uvBase ).xyz * 2.0 - 1.0;", 298 | "vNormal = normalMatrix * normalTex;", 299 | 300 | "}" 301 | 302 | ].join("\n") 303 | 304 | } 305 | 306 | }; 307 | -------------------------------------------------------------------------------- /r48/js/SimplexNoise.js: -------------------------------------------------------------------------------- 1 | // Ported from Stefan Gustavson's java implementation 2 | // http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf 3 | // Read Stefan's excellent paper for details on how this code works. 4 | // 5 | // Sean McCullough banksean@gmail.com 6 | // 7 | // Added 4D noise 8 | // Joshua Koo zz85nus@gmail.com 9 | 10 | /** 11 | * You can pass in a random number generator object if you like. 12 | * It is assumed to have a random() method. 13 | */ 14 | var SimplexNoise = function(r) { 15 | if (r == undefined) r = Math; 16 | this.grad3 = [[1,1,0],[-1,1,0],[1,-1,0],[-1,-1,0], 17 | [1,0,1],[-1,0,1],[1,0,-1],[-1,0,-1], 18 | [0,1,1],[0,-1,1],[0,1,-1],[0,-1,-1]]; 19 | 20 | this.grad4 = [[0,1,1,1], [0,1,1,-1], [0,1,-1,1], [0,1,-1,-1], 21 | [0,-1,1,1], [0,-1,1,-1], [0,-1,-1,1], [0,-1,-1,-1], 22 | [1,0,1,1], [1,0,1,-1], [1,0,-1,1], [1,0,-1,-1], 23 | [-1,0,1,1], [-1,0,1,-1], [-1,0,-1,1], [-1,0,-1,-1], 24 | [1,1,0,1], [1,1,0,-1], [1,-1,0,1], [1,-1,0,-1], 25 | [-1,1,0,1], [-1,1,0,-1], [-1,-1,0,1], [-1,-1,0,-1], 26 | [1,1,1,0], [1,1,-1,0], [1,-1,1,0], [1,-1,-1,0], 27 | [-1,1,1,0], [-1,1,-1,0], [-1,-1,1,0], [-1,-1,-1,0]]; 28 | 29 | this.p = []; 30 | for (var i=0; i<256; i++) { 31 | this.p[i] = Math.floor(r.random()*256); 32 | } 33 | // To remove the need for index wrapping, double the permutation table length 34 | this.perm = []; 35 | for(var i=0; i<512; i++) { 36 | this.perm[i]=this.p[i & 255]; 37 | } 38 | 39 | // A lookup table to traverse the simplex around a given point in 4D. 40 | // Details can be found where this table is used, in the 4D noise method. 41 | this.simplex = [ 42 | [0,1,2,3],[0,1,3,2],[0,0,0,0],[0,2,3,1],[0,0,0,0],[0,0,0,0],[0,0,0,0],[1,2,3,0], 43 | [0,2,1,3],[0,0,0,0],[0,3,1,2],[0,3,2,1],[0,0,0,0],[0,0,0,0],[0,0,0,0],[1,3,2,0], 44 | [0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0], 45 | [1,2,0,3],[0,0,0,0],[1,3,0,2],[0,0,0,0],[0,0,0,0],[0,0,0,0],[2,3,0,1],[2,3,1,0], 46 | [1,0,2,3],[1,0,3,2],[0,0,0,0],[0,0,0,0],[0,0,0,0],[2,0,3,1],[0,0,0,0],[2,1,3,0], 47 | [0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0], 48 | [2,0,1,3],[0,0,0,0],[0,0,0,0],[0,0,0,0],[3,0,1,2],[3,0,2,1],[0,0,0,0],[3,1,2,0], 49 | [2,1,0,3],[0,0,0,0],[0,0,0,0],[0,0,0,0],[3,1,0,2],[0,0,0,0],[3,2,0,1],[3,2,1,0]]; 50 | }; 51 | 52 | SimplexNoise.prototype.dot = function(g, x, y) { 53 | return g[0]*x + g[1]*y; 54 | }; 55 | 56 | SimplexNoise.prototype.noise = function(xin, yin) { 57 | var n0, n1, n2; // Noise contributions from the three corners 58 | // Skew the input space to determine which simplex cell we're in 59 | var F2 = 0.5*(Math.sqrt(3.0)-1.0); 60 | var s = (xin+yin)*F2; // Hairy factor for 2D 61 | var i = Math.floor(xin+s); 62 | var j = Math.floor(yin+s); 63 | var G2 = (3.0-Math.sqrt(3.0))/6.0; 64 | var t = (i+j)*G2; 65 | var X0 = i-t; // Unskew the cell origin back to (x,y) space 66 | var Y0 = j-t; 67 | var x0 = xin-X0; // The x,y distances from the cell origin 68 | var y0 = yin-Y0; 69 | // For the 2D case, the simplex shape is an equilateral triangle. 70 | // Determine which simplex we are in. 71 | var i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords 72 | if(x0>y0) {i1=1; j1=0;} // lower triangle, XY order: (0,0)->(1,0)->(1,1) 73 | else {i1=0; j1=1;} // upper triangle, YX order: (0,0)->(0,1)->(1,1) 74 | // A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and 75 | // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where 76 | // c = (3-sqrt(3))/6 77 | var x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords 78 | var y1 = y0 - j1 + G2; 79 | var x2 = x0 - 1.0 + 2.0 * G2; // Offsets for last corner in (x,y) unskewed coords 80 | var y2 = y0 - 1.0 + 2.0 * G2; 81 | // Work out the hashed gradient indices of the three simplex corners 82 | var ii = i & 255; 83 | var jj = j & 255; 84 | var gi0 = this.perm[ii+this.perm[jj]] % 12; 85 | var gi1 = this.perm[ii+i1+this.perm[jj+j1]] % 12; 86 | var gi2 = this.perm[ii+1+this.perm[jj+1]] % 12; 87 | // Calculate the contribution from the three corners 88 | var t0 = 0.5 - x0*x0-y0*y0; 89 | if(t0<0) n0 = 0.0; 90 | else { 91 | t0 *= t0; 92 | n0 = t0 * t0 * this.dot(this.grad3[gi0], x0, y0); // (x,y) of grad3 used for 2D gradient 93 | } 94 | var t1 = 0.5 - x1*x1-y1*y1; 95 | if(t1<0) n1 = 0.0; 96 | else { 97 | t1 *= t1; 98 | n1 = t1 * t1 * this.dot(this.grad3[gi1], x1, y1); 99 | } 100 | var t2 = 0.5 - x2*x2-y2*y2; 101 | if(t2<0) n2 = 0.0; 102 | else { 103 | t2 *= t2; 104 | n2 = t2 * t2 * this.dot(this.grad3[gi2], x2, y2); 105 | } 106 | // Add contributions from each corner to get the final noise value. 107 | // The result is scaled to return values in the interval [-1,1]. 108 | return 70.0 * (n0 + n1 + n2); 109 | }; 110 | 111 | // 3D simplex noise 112 | SimplexNoise.prototype.noise3d = function(xin, yin, zin) { 113 | var n0, n1, n2, n3; // Noise contributions from the four corners 114 | // Skew the input space to determine which simplex cell we're in 115 | var F3 = 1.0/3.0; 116 | var s = (xin+yin+zin)*F3; // Very nice and simple skew factor for 3D 117 | var i = Math.floor(xin+s); 118 | var j = Math.floor(yin+s); 119 | var k = Math.floor(zin+s); 120 | var G3 = 1.0/6.0; // Very nice and simple unskew factor, too 121 | var t = (i+j+k)*G3; 122 | var X0 = i-t; // Unskew the cell origin back to (x,y,z) space 123 | var Y0 = j-t; 124 | var Z0 = k-t; 125 | var x0 = xin-X0; // The x,y,z distances from the cell origin 126 | var y0 = yin-Y0; 127 | var z0 = zin-Z0; 128 | // For the 3D case, the simplex shape is a slightly irregular tetrahedron. 129 | // Determine which simplex we are in. 130 | var i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords 131 | var i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords 132 | if(x0>=y0) { 133 | if(y0>=z0) 134 | { i1=1; j1=0; k1=0; i2=1; j2=1; k2=0; } // X Y Z order 135 | else if(x0>=z0) { i1=1; j1=0; k1=0; i2=1; j2=0; k2=1; } // X Z Y order 136 | else { i1=0; j1=0; k1=1; i2=1; j2=0; k2=1; } // Z X Y order 137 | } 138 | else { // x0 y0) ? 32 : 0; 230 | var c2 = (x0 > z0) ? 16 : 0; 231 | var c3 = (y0 > z0) ? 8 : 0; 232 | var c4 = (x0 > w0) ? 4 : 0; 233 | var c5 = (y0 > w0) ? 2 : 0; 234 | var c6 = (z0 > w0) ? 1 : 0; 235 | var c = c1 + c2 + c3 + c4 + c5 + c6; 236 | var i1, j1, k1, l1; // The integer offsets for the second simplex corner 237 | var i2, j2, k2, l2; // The integer offsets for the third simplex corner 238 | var i3, j3, k3, l3; // The integer offsets for the fourth simplex corner 239 | // simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order. 240 | // Many values of c will never occur, since e.g. x>y>z>w makes x=3 ? 1 : 0; 245 | j1 = simplex[c][1]>=3 ? 1 : 0; 246 | k1 = simplex[c][2]>=3 ? 1 : 0; 247 | l1 = simplex[c][3]>=3 ? 1 : 0; 248 | // The number 2 in the "simplex" array is at the second largest coordinate. 249 | i2 = simplex[c][0]>=2 ? 1 : 0; 250 | j2 = simplex[c][1]>=2 ? 1 : 0; k2 = simplex[c][2]>=2 ? 1 : 0; 251 | l2 = simplex[c][3]>=2 ? 1 : 0; 252 | // The number 1 in the "simplex" array is at the second smallest coordinate. 253 | i3 = simplex[c][0]>=1 ? 1 : 0; 254 | j3 = simplex[c][1]>=1 ? 1 : 0; 255 | k3 = simplex[c][2]>=1 ? 1 : 0; 256 | l3 = simplex[c][3]>=1 ? 1 : 0; 257 | // The fifth corner has all coordinate offsets = 1, so no need to look that up. 258 | var x1 = x0 - i1 + G4; // Offsets for second corner in (x,y,z,w) coords 259 | var y1 = y0 - j1 + G4; 260 | var z1 = z0 - k1 + G4; 261 | var w1 = w0 - l1 + G4; 262 | var x2 = x0 - i2 + 2.0*G4; // Offsets for third corner in (x,y,z,w) coords 263 | var y2 = y0 - j2 + 2.0*G4; 264 | var z2 = z0 - k2 + 2.0*G4; 265 | var w2 = w0 - l2 + 2.0*G4; 266 | var x3 = x0 - i3 + 3.0*G4; // Offsets for fourth corner in (x,y,z,w) coords 267 | var y3 = y0 - j3 + 3.0*G4; 268 | var z3 = z0 - k3 + 3.0*G4; 269 | var w3 = w0 - l3 + 3.0*G4; 270 | var x4 = x0 - 1.0 + 4.0*G4; // Offsets for last corner in (x,y,z,w) coords 271 | var y4 = y0 - 1.0 + 4.0*G4; 272 | var z4 = z0 - 1.0 + 4.0*G4; 273 | var w4 = w0 - 1.0 + 4.0*G4; 274 | // Work out the hashed gradient indices of the five simplex corners 275 | var ii = i & 255; 276 | var jj = j & 255; 277 | var kk = k & 255; 278 | var ll = l & 255; 279 | var gi0 = perm[ii+perm[jj+perm[kk+perm[ll]]]] % 32; 280 | var gi1 = perm[ii+i1+perm[jj+j1+perm[kk+k1+perm[ll+l1]]]] % 32; 281 | var gi2 = perm[ii+i2+perm[jj+j2+perm[kk+k2+perm[ll+l2]]]] % 32; 282 | var gi3 = perm[ii+i3+perm[jj+j3+perm[kk+k3+perm[ll+l3]]]] % 32; 283 | var gi4 = perm[ii+1+perm[jj+1+perm[kk+1+perm[ll+1]]]] % 32; 284 | // Calculate the contribution from the five corners 285 | var t0 = 0.6 - x0*x0 - y0*y0 - z0*z0 - w0*w0; 286 | if(t0<0) n0 = 0.0; 287 | else { 288 | t0 *= t0; 289 | n0 = t0 * t0 * this.dot(grad4[gi0], x0, y0, z0, w0); 290 | } 291 | var t1 = 0.6 - x1*x1 - y1*y1 - z1*z1 - w1*w1; 292 | if(t1<0) n1 = 0.0; 293 | else { 294 | t1 *= t1; 295 | n1 = t1 * t1 * this.dot(grad4[gi1], x1, y1, z1, w1); 296 | } 297 | var t2 = 0.6 - x2*x2 - y2*y2 - z2*z2 - w2*w2; 298 | if(t2<0) n2 = 0.0; 299 | else { 300 | t2 *= t2; 301 | n2 = t2 * t2 * this.dot(grad4[gi2], x2, y2, z2, w2); 302 | } var t3 = 0.6 - x3*x3 - y3*y3 - z3*z3 - w3*w3; 303 | if(t3<0) n3 = 0.0; 304 | else { 305 | t3 *= t3; 306 | n3 = t3 * t3 * this.dot(grad4[gi3], x3, y3, z3, w3); 307 | } 308 | var t4 = 0.6 - x4*x4 - y4*y4 - z4*z4 - w4*w4; 309 | if(t4<0) n4 = 0.0; 310 | else { 311 | t4 *= t4; 312 | n4 = t4 * t4 * this.dot(grad4[gi4], x4, y4, z4, w4); 313 | } 314 | // Sum up and scale the result to cover the range [-1,1] 315 | return 27.0 * (n0 + n1 + n2 + n3 + n4); 316 | }; 317 | -------------------------------------------------------------------------------- /r48/js/Stats.js: -------------------------------------------------------------------------------- 1 | // stats.js r8 - http://github.com/mrdoob/stats.js 2 | var Stats=function(){var h,a,n=0,o=0,i=Date.now(),u=i,p=i,l=0,q=1E3,r=0,e,j,f,b=[[16,16,48],[0,255,255]],m=0,s=1E3,t=0,d,k,g,c=[[16,48,16],[0,255,0]];h=document.createElement("div");h.style.cursor="pointer";h.style.width="80px";h.style.opacity="0.9";h.style.zIndex="10001";h.addEventListener("mousedown",function(a){a.preventDefault();n=(n+1)%2;n==0?(e.style.display="block",d.style.display="none"):(e.style.display="none",d.style.display="block")},!1);e=document.createElement("div");e.style.textAlign= 3 | "left";e.style.lineHeight="1.2em";e.style.backgroundColor="rgb("+Math.floor(b[0][0]/2)+","+Math.floor(b[0][1]/2)+","+Math.floor(b[0][2]/2)+")";e.style.padding="0 0 3px 3px";h.appendChild(e);j=document.createElement("div");j.style.fontFamily="Helvetica, Arial, sans-serif";j.style.fontSize="9px";j.style.color="rgb("+b[1][0]+","+b[1][1]+","+b[1][2]+")";j.style.fontWeight="bold";j.innerHTML="FPS";e.appendChild(j);f=document.createElement("div");f.style.position="relative";f.style.width="74px";f.style.height= 4 | "30px";f.style.backgroundColor="rgb("+b[1][0]+","+b[1][1]+","+b[1][2]+")";for(e.appendChild(f);f.children.length<74;)a=document.createElement("span"),a.style.width="1px",a.style.height="30px",a.style.cssFloat="left",a.style.backgroundColor="rgb("+b[0][0]+","+b[0][1]+","+b[0][2]+")",f.appendChild(a);d=document.createElement("div");d.style.textAlign="left";d.style.lineHeight="1.2em";d.style.backgroundColor="rgb("+Math.floor(c[0][0]/2)+","+Math.floor(c[0][1]/2)+","+Math.floor(c[0][2]/2)+")";d.style.padding= 5 | "0 0 3px 3px";d.style.display="none";h.appendChild(d);k=document.createElement("div");k.style.fontFamily="Helvetica, Arial, sans-serif";k.style.fontSize="9px";k.style.color="rgb("+c[1][0]+","+c[1][1]+","+c[1][2]+")";k.style.fontWeight="bold";k.innerHTML="MS";d.appendChild(k);g=document.createElement("div");g.style.position="relative";g.style.width="74px";g.style.height="30px";g.style.backgroundColor="rgb("+c[1][0]+","+c[1][1]+","+c[1][2]+")";for(d.appendChild(g);g.children.length<74;)a=document.createElement("span"), 6 | a.style.width="1px",a.style.height=Math.random()*30+"px",a.style.cssFloat="left",a.style.backgroundColor="rgb("+c[0][0]+","+c[0][1]+","+c[0][2]+")",g.appendChild(a);return{domElement:h,update:function(){i=Date.now();m=i-u;s=Math.min(s,m);t=Math.max(t,m);k.textContent=m+" MS ("+s+"-"+t+")";var a=Math.min(30,30-m/200*30);g.appendChild(g.firstChild).style.height=a+"px";u=i;o++;if(i>p+1E3)l=Math.round(o*1E3/(i-p)),q=Math.min(q,l),r=Math.max(r,l),j.textContent=l+" FPS ("+q+"-"+r+")",a=Math.min(30,30-l/ 7 | 100*30),f.appendChild(f.firstChild).style.height=a+"px",p=i,o=0}}}; 8 | 9 | -------------------------------------------------------------------------------- /r48/js/Tween.js: -------------------------------------------------------------------------------- 1 | // tween.js r5 - http://github.com/sole/tween.js 2 | var TWEEN=TWEEN||function(){var a,e,c=60,b=false,h=[];return{setFPS:function(f){c=f||60},start:function(f){arguments.length!=0&&this.setFPS(f);e=setInterval(this.update,1E3/c)},stop:function(){clearInterval(e)},setAutostart:function(f){(b=f)&&!e&&this.start()},add:function(f){h.push(f);b&&!e&&this.start()},getAll:function(){return h},removeAll:function(){h=[]},remove:function(f){a=h.indexOf(f);a!==-1&&h.splice(a,1)},update:function(f){a=0;num_tweens=h.length;for(f=f||Date.now();a1?1:d;i=n(d);for(g in c)a[g]=e[g]+c[g]*i;l!==null&&l.call(a,i);if(d==1){m!==null&&m.call(a);k!==null&&k.start();return false}return true}};TWEEN.Easing={Linear:{},Quadratic:{},Cubic:{},Quartic:{},Quintic:{},Sinusoidal:{},Exponential:{},Circular:{},Elastic:{},Back:{},Bounce:{}};TWEEN.Easing.Linear.EaseNone=function(a){return a}; 6 | TWEEN.Easing.Quadratic.EaseIn=function(a){return a*a};TWEEN.Easing.Quadratic.EaseOut=function(a){return-a*(a-2)};TWEEN.Easing.Quadratic.EaseInOut=function(a){if((a*=2)<1)return 0.5*a*a;return-0.5*(--a*(a-2)-1)};TWEEN.Easing.Cubic.EaseIn=function(a){return a*a*a};TWEEN.Easing.Cubic.EaseOut=function(a){return--a*a*a+1};TWEEN.Easing.Cubic.EaseInOut=function(a){if((a*=2)<1)return 0.5*a*a*a;return 0.5*((a-=2)*a*a+2)};TWEEN.Easing.Quartic.EaseIn=function(a){return a*a*a*a}; 7 | TWEEN.Easing.Quartic.EaseOut=function(a){return-(--a*a*a*a-1)};TWEEN.Easing.Quartic.EaseInOut=function(a){if((a*=2)<1)return 0.5*a*a*a*a;return-0.5*((a-=2)*a*a*a-2)};TWEEN.Easing.Quintic.EaseIn=function(a){return a*a*a*a*a};TWEEN.Easing.Quintic.EaseOut=function(a){return(a-=1)*a*a*a*a+1};TWEEN.Easing.Quintic.EaseInOut=function(a){if((a*=2)<1)return 0.5*a*a*a*a*a;return 0.5*((a-=2)*a*a*a*a+2)};TWEEN.Easing.Sinusoidal.EaseIn=function(a){return-Math.cos(a*Math.PI/2)+1}; 8 | TWEEN.Easing.Sinusoidal.EaseOut=function(a){return Math.sin(a*Math.PI/2)};TWEEN.Easing.Sinusoidal.EaseInOut=function(a){return-0.5*(Math.cos(Math.PI*a)-1)};TWEEN.Easing.Exponential.EaseIn=function(a){return a==0?0:Math.pow(2,10*(a-1))};TWEEN.Easing.Exponential.EaseOut=function(a){return a==1?1:-Math.pow(2,-10*a)+1};TWEEN.Easing.Exponential.EaseInOut=function(a){if(a==0)return 0;if(a==1)return 1;if((a*=2)<1)return 0.5*Math.pow(2,10*(a-1));return 0.5*(-Math.pow(2,-10*(a-1))+2)}; 9 | TWEEN.Easing.Circular.EaseIn=function(a){return-(Math.sqrt(1-a*a)-1)};TWEEN.Easing.Circular.EaseOut=function(a){return Math.sqrt(1- --a*a)};TWEEN.Easing.Circular.EaseInOut=function(a){if((a/=0.5)<1)return-0.5*(Math.sqrt(1-a*a)-1);return 0.5*(Math.sqrt(1-(a-=2)*a)+1)};TWEEN.Easing.Elastic.EaseIn=function(a){var e,c=0.1,b=0.4;if(a==0)return 0;if(a==1)return 1;b||(b=0.3);if(!c||c<1){c=1;e=b/4}else e=b/(2*Math.PI)*Math.asin(1/c);return-(c*Math.pow(2,10*(a-=1))*Math.sin((a-e)*2*Math.PI/b))}; 10 | TWEEN.Easing.Elastic.EaseOut=function(a){var e,c=0.1,b=0.4;if(a==0)return 0;if(a==1)return 1;b||(b=0.3);if(!c||c<1){c=1;e=b/4}else e=b/(2*Math.PI)*Math.asin(1/c);return c*Math.pow(2,-10*a)*Math.sin((a-e)*2*Math.PI/b)+1}; 11 | TWEEN.Easing.Elastic.EaseInOut=function(a){var e,c=0.1,b=0.4;if(a==0)return 0;if(a==1)return 1;b||(b=0.3);if(!c||c<1){c=1;e=b/4}else e=b/(2*Math.PI)*Math.asin(1/c);if((a*=2)<1)return-0.5*c*Math.pow(2,10*(a-=1))*Math.sin((a-e)*2*Math.PI/b);return c*Math.pow(2,-10*(a-=1))*Math.sin((a-e)*2*Math.PI/b)*0.5+1};TWEEN.Easing.Back.EaseIn=function(a){return a*a*(2.70158*a-1.70158)};TWEEN.Easing.Back.EaseOut=function(a){return(a-=1)*a*(2.70158*a+1.70158)+1}; 12 | TWEEN.Easing.Back.EaseInOut=function(a){if((a*=2)<1)return 0.5*a*a*(3.5949095*a-2.5949095);return 0.5*((a-=2)*a*(3.5949095*a+2.5949095)+2)};TWEEN.Easing.Bounce.EaseIn=function(a){return 1-TWEEN.Easing.Bounce.EaseOut(1-a)};TWEEN.Easing.Bounce.EaseOut=function(a){return(a/=1)<1/2.75?7.5625*a*a:a<2/2.75?7.5625*(a-=1.5/2.75)*a+0.75:a<2.5/2.75?7.5625*(a-=2.25/2.75)*a+0.9375:7.5625*(a-=2.625/2.75)*a+0.984375}; 13 | TWEEN.Easing.Bounce.EaseInOut=function(a){if(a<0.5)return TWEEN.Easing.Bounce.EaseIn(a*2)*0.5;return TWEEN.Easing.Bounce.EaseOut(a*2-1)*0.5+0.5}; -------------------------------------------------------------------------------- /r48/js/ctm/CTMLoader.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Loader for CTM encoded models generated by OpenCTM tools: 3 | * http://openctm.sourceforge.net/ 4 | * 5 | * Uses js-openctm library by Juan Mellado 6 | * http://code.google.com/p/js-openctm/ 7 | * 8 | * @author alteredq / http://alteredqualia.com/ 9 | */ 10 | 11 | THREE.CTMLoader = function ( context, showStatus ) { 12 | 13 | this.context = context; 14 | 15 | THREE.Loader.call( this, showStatus ); 16 | 17 | }; 18 | 19 | THREE.CTMLoader.prototype = new THREE.Loader(); 20 | THREE.CTMLoader.prototype.constructor = THREE.CTMLoader; 21 | 22 | 23 | // Load multiple CTM parts defined in JSON 24 | 25 | THREE.CTMLoader.prototype.loadParts = function( url, callback, useWorker, useBuffers, basePath ) { 26 | 27 | var scope = this; 28 | 29 | var xhr = new XMLHttpRequest(); 30 | 31 | basePath = basePath ? basePath : this.extractUrlbase( url ); 32 | 33 | xhr.onreadystatechange = function() { 34 | 35 | if ( xhr.readyState == 4 ) { 36 | 37 | if ( xhr.status == 200 || xhr.status == 0 ) { 38 | 39 | var jsonObject = JSON.parse( xhr.responseText ); 40 | 41 | var materials = [], geometries = [], counter = 0; 42 | 43 | function callbackFinal( geometry ) { 44 | 45 | counter += 1; 46 | 47 | geometries.push( geometry ); 48 | 49 | if ( counter === jsonObject.offsets.length ) { 50 | 51 | callback( geometries, materials ); 52 | 53 | } 54 | 55 | } 56 | 57 | 58 | // init materials 59 | 60 | for ( var i = 0; i < jsonObject.materials.length; i ++ ) { 61 | 62 | materials[ i ] = THREE.Loader.prototype.createMaterial( jsonObject.materials[ i ], basePath ); 63 | 64 | } 65 | 66 | // load joined CTM file 67 | 68 | var partUrl = basePath + jsonObject.data; 69 | scope.load( partUrl, callbackFinal, useWorker, useBuffers, jsonObject.offsets ); 70 | 71 | } 72 | 73 | } 74 | 75 | } 76 | 77 | xhr.open( "GET", url, true ); 78 | if ( xhr.overrideMimeType ) xhr.overrideMimeType( "text/plain; charset=x-user-defined" ); 79 | xhr.setRequestHeader( "Content-Type", "text/plain" ); 80 | xhr.send( null ); 81 | 82 | }; 83 | 84 | // Load CTMLoader compressed models 85 | // - parameters 86 | // - url (required) 87 | // - callback (required) 88 | 89 | THREE.CTMLoader.prototype.load = function( url, callback, useWorker, useBuffers, offsets ) { 90 | 91 | var scope = this; 92 | 93 | offsets = offsets !== undefined ? offsets : [ 0 ]; 94 | 95 | var xhr = new XMLHttpRequest(), 96 | callbackProgress = null; 97 | 98 | var length = 0; 99 | 100 | xhr.onreadystatechange = function() { 101 | 102 | if ( xhr.readyState == 4 ) { 103 | 104 | if ( xhr.status == 200 || xhr.status == 0 ) { 105 | 106 | var binaryData = xhr.responseText; 107 | 108 | //var s = Date.now(); 109 | 110 | if ( useWorker ) { 111 | 112 | var worker = new Worker( "js/ctm/CTMWorker.js" ); 113 | 114 | worker.onmessage = function( event ) { 115 | 116 | var files = event.data; 117 | 118 | for ( var i = 0; i < files.length; i ++ ) { 119 | 120 | var ctmFile = files[ i ]; 121 | 122 | if ( useBuffers ) { 123 | 124 | scope.createModelBuffers( ctmFile, callback ); 125 | 126 | } else { 127 | 128 | scope.createModelClassic( ctmFile, callback ); 129 | 130 | } 131 | 132 | } 133 | 134 | //var e = Date.now(); 135 | //console.log( "CTM data parse time [worker]: " + (e-s) + " ms" ); 136 | 137 | }; 138 | 139 | worker.postMessage( { "data": binaryData, "offsets": offsets } ); 140 | 141 | } else { 142 | 143 | 144 | for ( var i = 0; i < offsets.length; i ++ ) { 145 | 146 | var stream = new CTM.Stream( binaryData ); 147 | stream.offset = offsets[ i ]; 148 | 149 | var ctmFile = new CTM.File( stream ); 150 | 151 | if ( useBuffers ) { 152 | 153 | scope.createModelBuffers( ctmFile, callback ); 154 | 155 | } else { 156 | 157 | scope.createModelClassic( ctmFile, callback ); 158 | 159 | } 160 | 161 | } 162 | 163 | //var e = Date.now(); 164 | //console.log( "CTM data parse time [inline]: " + (e-s) + " ms" ); 165 | 166 | } 167 | 168 | } else { 169 | 170 | console.error( "Couldn't load [" + url + "] [" + xhr.status + "]" ); 171 | 172 | } 173 | 174 | } else if ( xhr.readyState == 3 ) { 175 | 176 | if ( callbackProgress ) { 177 | 178 | if ( length == 0 ) { 179 | 180 | length = xhr.getResponseHeader( "Content-Length" ); 181 | 182 | } 183 | 184 | callbackProgress( { total: length, loaded: xhr.responseText.length } ); 185 | 186 | } 187 | 188 | } else if ( xhr.readyState == 2 ) { 189 | 190 | length = xhr.getResponseHeader( "Content-Length" ); 191 | 192 | } 193 | 194 | } 195 | 196 | xhr.overrideMimeType( "text/plain; charset=x-user-defined" ); 197 | xhr.open( "GET", url, true ); 198 | xhr.send( null ); 199 | 200 | }; 201 | 202 | 203 | THREE.CTMLoader.prototype.createModelBuffers = function ( file, callback ) { 204 | 205 | var gl = this.context; 206 | 207 | var Model = function ( ) { 208 | 209 | var scope = this; 210 | 211 | var dynamic = false, 212 | computeNormals = true, 213 | normalizeNormals = true, 214 | reorderVertices = true; 215 | 216 | scope.materials = []; 217 | 218 | THREE.BufferGeometry.call( this ); 219 | 220 | // init GL buffers 221 | 222 | var vertexIndexArray = file.body.indices, 223 | vertexPositionArray = file.body.vertices, 224 | vertexNormalArray = file.body.normals; 225 | 226 | var vertexUvArray, vertexColorArray; 227 | 228 | if ( file.body.uvMaps !== undefined && file.body.uvMaps.length > 0 ) { 229 | 230 | vertexUvArray = file.body.uvMaps[ 0 ].uv; 231 | 232 | } 233 | 234 | if ( file.body.attrMaps !== undefined && file.body.attrMaps.length > 0 && file.body.attrMaps[ 0 ].name === "Color" ) { 235 | 236 | vertexColorArray = file.body.attrMaps[ 0 ].attr; 237 | 238 | } 239 | 240 | //console.log( "vertices", vertexPositionArray.length/3 ); 241 | //console.log( "triangles", vertexIndexArray.length/3 ); 242 | 243 | // compute face normals from scratch 244 | // (must be done before computing offsets) 245 | 246 | if ( vertexNormalArray === undefined && computeNormals ) { 247 | 248 | var nElements = vertexPositionArray.length; 249 | 250 | vertexNormalArray = new Float32Array( nElements ); 251 | 252 | var vA, vB, vC, x, y, z, 253 | 254 | pA = new THREE.Vector3(), 255 | pB = new THREE.Vector3(), 256 | pC = new THREE.Vector3(), 257 | 258 | cb = new THREE.Vector3(), 259 | ab = new THREE.Vector3(); 260 | 261 | for ( var i = 0; i < vertexIndexArray.length; i += 3 ) { 262 | 263 | vA = vertexIndexArray[ i ]; 264 | vB = vertexIndexArray[ i + 1 ]; 265 | vC = vertexIndexArray[ i + 2 ]; 266 | 267 | x = vertexPositionArray[ vA * 3 ]; 268 | y = vertexPositionArray[ vA * 3 + 1 ]; 269 | z = vertexPositionArray[ vA * 3 + 2 ]; 270 | pA.set( x, y, z ); 271 | 272 | x = vertexPositionArray[ vB * 3 ]; 273 | y = vertexPositionArray[ vB * 3 + 1 ]; 274 | z = vertexPositionArray[ vB * 3 + 2 ]; 275 | pB.set( x, y, z ); 276 | 277 | x = vertexPositionArray[ vC * 3 ]; 278 | y = vertexPositionArray[ vC * 3 + 1 ]; 279 | z = vertexPositionArray[ vC * 3 + 2 ]; 280 | pC.set( x, y, z ); 281 | 282 | cb.sub( pC, pB ); 283 | ab.sub( pA, pB ); 284 | cb.crossSelf( ab ); 285 | 286 | vertexNormalArray[ vA * 3 ] += cb.x; 287 | vertexNormalArray[ vA * 3 + 1 ] += cb.y; 288 | vertexNormalArray[ vA * 3 + 2 ] += cb.z; 289 | 290 | vertexNormalArray[ vB * 3 ] += cb.x; 291 | vertexNormalArray[ vB * 3 + 1 ] += cb.y; 292 | vertexNormalArray[ vB * 3 + 2 ] += cb.z; 293 | 294 | vertexNormalArray[ vC * 3 ] += cb.x; 295 | vertexNormalArray[ vC * 3 + 1 ] += cb.y; 296 | vertexNormalArray[ vC * 3 + 2 ] += cb.z; 297 | 298 | } 299 | 300 | if ( normalizeNormals ) { 301 | 302 | for ( var i = 0; i < nElements; i += 3 ) { 303 | 304 | x = vertexNormalArray[ i ]; 305 | y = vertexNormalArray[ i + 1 ]; 306 | z = vertexNormalArray[ i + 2 ]; 307 | 308 | var n = 1.0 / Math.sqrt( x * x + y * y + z * z ); 309 | 310 | vertexNormalArray[ i ] *= n; 311 | vertexNormalArray[ i + 1 ] *= n; 312 | vertexNormalArray[ i + 2 ] *= n; 313 | 314 | } 315 | 316 | } 317 | 318 | } 319 | 320 | // reorder vertices 321 | // (needed for buffer splitting, to keep together face vertices) 322 | 323 | if ( reorderVertices ) { 324 | 325 | var newFaces = new Uint32Array( vertexIndexArray.length ), 326 | newVertices = new Float32Array( vertexPositionArray.length ); 327 | 328 | var newNormals, newUvs, newColors; 329 | 330 | if ( vertexNormalArray ) newNormals = new Float32Array( vertexNormalArray.length ); 331 | if ( vertexUvArray ) newUvs = new Float32Array( vertexUvArray.length ); 332 | if ( vertexColorArray ) newColors = new Float32Array( vertexColorArray.length ); 333 | 334 | var indexMap = {}, vertexCounter = 0; 335 | 336 | function handleVertex( v ) { 337 | 338 | if ( indexMap[ v ] === undefined ) { 339 | 340 | indexMap[ v ] = vertexCounter; 341 | 342 | var sx = v * 3, 343 | sy = v * 3 + 1, 344 | sz = v * 3 + 2, 345 | 346 | dx = vertexCounter * 3, 347 | dy = vertexCounter * 3 + 1, 348 | dz = vertexCounter * 3 + 2; 349 | 350 | newVertices[ dx ] = vertexPositionArray[ sx ]; 351 | newVertices[ dy ] = vertexPositionArray[ sy ]; 352 | newVertices[ dz ] = vertexPositionArray[ sz ]; 353 | 354 | if ( vertexNormalArray ) { 355 | 356 | newNormals[ dx ] = vertexNormalArray[ sx ]; 357 | newNormals[ dy ] = vertexNormalArray[ sy ]; 358 | newNormals[ dz ] = vertexNormalArray[ sz ]; 359 | 360 | } 361 | 362 | if ( vertexUvArray ) { 363 | 364 | newUvs[ vertexCounter * 2 ] = vertexUvArray[ v * 2 ]; 365 | newUvs[ vertexCounter * 2 + 1 ] = vertexUvArray[ v * 2 + 1 ]; 366 | 367 | } 368 | 369 | if ( vertexColorArray ) { 370 | 371 | newColors[ vertexCounter * 4 ] = vertexNormalArray[ v * 4 ]; 372 | newColors[ vertexCounter * 4 + 1 ] = vertexNormalArray[ v * 4 + 1 ]; 373 | newColors[ vertexCounter * 4 + 2 ] = vertexNormalArray[ v * 4 + 2 ]; 374 | newColors[ vertexCounter * 4 + 3 ] = vertexNormalArray[ v * 4 + 3 ]; 375 | 376 | } 377 | 378 | vertexCounter += 1; 379 | 380 | } 381 | 382 | } 383 | 384 | var a, b, c; 385 | 386 | for ( var i = 0; i < vertexIndexArray.length; i += 3 ) { 387 | 388 | a = vertexIndexArray[ i ]; 389 | b = vertexIndexArray[ i + 1 ]; 390 | c = vertexIndexArray[ i + 2 ]; 391 | 392 | handleVertex( a ); 393 | handleVertex( b ); 394 | handleVertex( c ); 395 | 396 | newFaces[ i ] = indexMap[ a ]; 397 | newFaces[ i + 1 ] = indexMap[ b ]; 398 | newFaces[ i + 2 ] = indexMap[ c ]; 399 | 400 | } 401 | 402 | vertexIndexArray = newFaces; 403 | vertexPositionArray = newVertices; 404 | 405 | if ( vertexNormalArray ) vertexNormalArray = newNormals; 406 | if ( vertexUvArray ) vertexUvArray = newUvs; 407 | if ( vertexColorArray ) vertexColorArray = newColors; 408 | 409 | } 410 | 411 | // compute offsets 412 | 413 | scope.offsets = []; 414 | 415 | var indices = vertexIndexArray; 416 | 417 | var start = 0, 418 | min = vertexPositionArray.length, 419 | max = 0, 420 | minPrev = min; 421 | 422 | for ( var i = 0; i < indices.length; ) { 423 | 424 | for ( var j = 0; j < 3; ++ j ) { 425 | 426 | var idx = indices[ i ++ ]; 427 | 428 | if ( idx < min ) min = idx; 429 | if ( idx > max ) max = idx; 430 | 431 | } 432 | 433 | if ( max - min > 65535 ) { 434 | 435 | i -= 3; 436 | 437 | for ( var k = start; k < i; ++ k ) { 438 | 439 | indices[ k ] -= minPrev; 440 | 441 | } 442 | 443 | scope.offsets.push( { start: start, count: i - start, index: minPrev } ); 444 | 445 | start = i; 446 | min = vertexPositionArray.length; 447 | max = 0; 448 | 449 | } 450 | 451 | minPrev = min; 452 | 453 | } 454 | 455 | for ( var k = start; k < i; ++ k ) { 456 | 457 | indices[ k ] -= minPrev; 458 | 459 | } 460 | 461 | scope.offsets.push( { start: start, count: i - start, index: minPrev } ); 462 | 463 | 464 | // indices 465 | 466 | scope.vertexIndexBuffer = gl.createBuffer(); 467 | gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, scope.vertexIndexBuffer ); 468 | gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, new Uint16Array( vertexIndexArray ), gl.STATIC_DRAW ); 469 | 470 | scope.vertexIndexBuffer.itemSize = 1; 471 | scope.vertexIndexBuffer.numItems = vertexIndexArray.length; 472 | 473 | // vertices 474 | 475 | scope.vertexPositionBuffer = gl.createBuffer(); 476 | gl.bindBuffer( gl.ARRAY_BUFFER, scope.vertexPositionBuffer ); 477 | gl.bufferData( gl.ARRAY_BUFFER, vertexPositionArray, gl.STATIC_DRAW ); 478 | 479 | scope.vertexPositionBuffer.itemSize = 3; 480 | scope.vertexPositionBuffer.numItems = vertexPositionArray.length; 481 | 482 | // normals 483 | 484 | if ( vertexNormalArray !== undefined ) { 485 | 486 | scope.vertexNormalBuffer = gl.createBuffer(); 487 | gl.bindBuffer( gl.ARRAY_BUFFER, scope.vertexNormalBuffer ); 488 | gl.bufferData( gl.ARRAY_BUFFER, vertexNormalArray, gl.STATIC_DRAW ); 489 | 490 | scope.vertexNormalBuffer.itemSize = 3; 491 | scope.vertexNormalBuffer.numItems = vertexNormalArray.length; 492 | 493 | } 494 | 495 | // uvs 496 | 497 | if ( vertexUvArray !== undefined ) { 498 | 499 | // "fix" flipping 500 | 501 | for ( var i = 0; i < vertexUvArray.length; i += 2 ) { 502 | 503 | vertexUvArray[ i + 1 ] = 1 - vertexUvArray[ i + 1 ]; 504 | 505 | } 506 | 507 | scope.vertexUvBuffer = gl.createBuffer(); 508 | gl.bindBuffer( gl.ARRAY_BUFFER, scope.vertexUvBuffer ); 509 | gl.bufferData( gl.ARRAY_BUFFER, vertexUvArray, gl.STATIC_DRAW ); 510 | 511 | scope.vertexUvBuffer.itemSize = 2; 512 | scope.vertexUvBuffer.numItems = vertexUvArray.length; 513 | 514 | } 515 | 516 | // colors 517 | 518 | if ( vertexColorArray !== undefined ) { 519 | 520 | scope.vertexColorBuffer = gl.createBuffer(); 521 | gl.bindBuffer( gl.ARRAY_BUFFER, scope.vertexColorBuffer ); 522 | gl.bufferData( gl.ARRAY_BUFFER, vertexColorArray, gl.STATIC_DRAW ); 523 | 524 | scope.vertexColorBuffer.itemSize = 4; 525 | scope.vertexColorBuffer.numItems = vertexColorArray.length; 526 | 527 | } 528 | 529 | // compute bounding sphere and bounding box 530 | // (must do it now as we don't keep typed arrays after setting GL buffers) 531 | 532 | scope.boundingBox = { min: new THREE.Vector3( Infinity, Infinity, Infinity ), max: new THREE.Vector3( -Infinity, -Infinity, -Infinity ) }; 533 | 534 | var vertices = file.body.vertices, 535 | bb = scope.boundingBox, 536 | radius, maxRadius = 0, 537 | x, y, z; 538 | 539 | for ( var i = 0, il = vertices.length; i < il; i += 3 ) { 540 | 541 | x = vertices[ i ]; 542 | y = vertices[ i + 1 ]; 543 | z = vertices[ i + 2 ]; 544 | 545 | // bounding sphere 546 | 547 | radius = Math.sqrt( x * x + y * y + z * z ); 548 | if ( radius > maxRadius ) maxRadius = radius; 549 | 550 | // bounding box 551 | 552 | if ( x < bb.min.x ) { 553 | 554 | bb.min.x = x; 555 | 556 | } else if ( x > bb.max.x ) { 557 | 558 | bb.max.x = x; 559 | 560 | } 561 | 562 | if ( y < bb.min.y ) { 563 | 564 | bb.min.y = y; 565 | 566 | } else if ( y > bb.max.y ) { 567 | 568 | bb.max.y = y; 569 | 570 | } 571 | 572 | if ( z < bb.min.z ) { 573 | 574 | bb.min.z = z; 575 | 576 | } else if ( z > bb.max.z ) { 577 | 578 | bb.max.z = z; 579 | 580 | } 581 | 582 | } 583 | 584 | scope.boundingSphere = { radius: maxRadius }; 585 | 586 | // keep references to typed arrays 587 | 588 | if ( dynamic ) { 589 | 590 | scope.vertexIndexArray = vertexIndexArray; 591 | scope.vertexPositionArray = vertexPositionArray; 592 | scope.vertexNormalArray = vertexNormalArray; 593 | scope.vertexUvArray = vertexUvArray; 594 | scope.vertexColorArray = vertexColorArray; 595 | 596 | } 597 | 598 | } 599 | 600 | Model.prototype = new THREE.BufferGeometry(); 601 | Model.prototype.constructor = Model; 602 | 603 | callback( new Model() ); 604 | 605 | }; 606 | 607 | THREE.CTMLoader.prototype.createModelClassic = function ( file, callback ) { 608 | 609 | var Model = function ( ) { 610 | 611 | var scope = this; 612 | 613 | scope.materials = []; 614 | 615 | THREE.Geometry.call( this ); 616 | 617 | var normals = [], 618 | uvs = [], 619 | colors = []; 620 | 621 | init_vertices( file.body.vertices ); 622 | 623 | if ( file.body.normals !== undefined ) 624 | init_normals( file.body.normals ); 625 | 626 | if ( file.body.uvMaps !== undefined && file.body.uvMaps.length > 0 ) 627 | init_uvs( file.body.uvMaps[ 0 ].uv ); 628 | 629 | if ( file.body.attrMaps !== undefined && file.body.attrMaps.length > 0 && file.body.attrMaps[ 0 ].name === "Color" ) 630 | init_colors( file.body.attrMaps[ 0 ].attr ); 631 | 632 | var hasNormals = normals.length > 0 ? true : false, 633 | hasUvs = uvs.length > 0 ? true : false, 634 | hasColors = colors.length > 0 ? true : false; 635 | 636 | init_faces( file.body.indices ); 637 | 638 | this.computeCentroids(); 639 | this.computeFaceNormals(); 640 | //this.computeTangents(); 641 | 642 | function init_vertices( buffer ) { 643 | 644 | var x, y, z, i, il = buffer.length; 645 | 646 | for( i = 0; i < il; i += 3 ) { 647 | 648 | x = buffer[ i ]; 649 | y = buffer[ i + 1 ]; 650 | z = buffer[ i + 2 ]; 651 | 652 | vertex( scope, x, y, z ); 653 | 654 | } 655 | 656 | }; 657 | 658 | function init_normals( buffer ) { 659 | 660 | var x, y, z, i, il = buffer.length; 661 | 662 | for( i = 0; i < il; i += 3 ) { 663 | 664 | x = buffer[ i ]; 665 | y = buffer[ i + 1 ]; 666 | z = buffer[ i + 2 ]; 667 | 668 | normals.push( x, y, z ); 669 | 670 | } 671 | 672 | }; 673 | 674 | function init_colors( buffer ) { 675 | 676 | var r, g, b, a, i, il = buffer.length; 677 | 678 | for( i = 0; i < il; i += 4 ) { 679 | 680 | r = buffer[ i ]; 681 | g = buffer[ i + 1 ]; 682 | b = buffer[ i + 2 ]; 683 | a = buffer[ i + 3 ]; 684 | 685 | var color = new THREE.Color(); 686 | color.setRGB( r, g, b ); 687 | 688 | colors.push( color ); 689 | 690 | } 691 | 692 | }; 693 | 694 | 695 | function init_uvs( buffer ) { 696 | 697 | var u, v, i, il = buffer.length; 698 | 699 | for( i = 0; i < il; i += 2 ) { 700 | 701 | u = buffer[ i ]; 702 | v = buffer[ i + 1 ]; 703 | 704 | uvs.push( u, 1 - v ); 705 | 706 | } 707 | 708 | }; 709 | 710 | function init_faces( buffer ) { 711 | 712 | var a, b, c, 713 | u1, v1, u2, v2, u3, v3, 714 | m, face, 715 | i, il = buffer.length; 716 | 717 | m = 0; // all faces defaulting to material 0 718 | 719 | for( i = 0; i < il; i += 3 ) { 720 | 721 | a = buffer[ i ]; 722 | b = buffer[ i + 1 ]; 723 | c = buffer[ i + 2 ]; 724 | 725 | if ( hasNormals ){ 726 | 727 | face = f3n( scope, normals, a, b, c, m, a, b, c ); 728 | 729 | } else { 730 | 731 | face = f3( scope, a, b, c, m ); 732 | 733 | } 734 | 735 | if ( hasColors ) { 736 | 737 | face.vertexColors[ 0 ] = colors[ a ]; 738 | face.vertexColors[ 1 ] = colors[ b ]; 739 | face.vertexColors[ 2 ] = colors[ c ]; 740 | 741 | } 742 | 743 | if ( hasUvs ) { 744 | 745 | u1 = uvs[ a * 2 ]; 746 | v1 = uvs[ a * 2 + 1 ]; 747 | 748 | u2 = uvs[ b * 2 ]; 749 | v2 = uvs[ b * 2 + 1 ]; 750 | 751 | u3 = uvs[ c * 2 ]; 752 | v3 = uvs[ c * 2 + 1 ]; 753 | 754 | uv3( scope.faceVertexUvs[ 0 ], u1, v1, u2, v2, u3, v3 ); 755 | 756 | } 757 | 758 | } 759 | 760 | } 761 | 762 | }; 763 | 764 | function vertex ( scope, x, y, z ) { 765 | 766 | scope.vertices.push( new THREE.Vertex( new THREE.Vector3( x, y, z ) ) ); 767 | 768 | }; 769 | 770 | function f3 ( scope, a, b, c, mi ) { 771 | 772 | var face = new THREE.Face3( a, b, c, null, null, mi ); 773 | 774 | scope.faces.push( face ); 775 | 776 | return face; 777 | 778 | }; 779 | 780 | function f3n ( scope, normals, a, b, c, mi, na, nb, nc ) { 781 | 782 | var nax = normals[ na * 3 ], 783 | nay = normals[ na * 3 + 1 ], 784 | naz = normals[ na * 3 + 2 ], 785 | 786 | nbx = normals[ nb * 3 ], 787 | nby = normals[ nb * 3 + 1 ], 788 | nbz = normals[ nb * 3 + 2 ], 789 | 790 | ncx = normals[ nc * 3 ], 791 | ncy = normals[ nc * 3 + 1 ], 792 | ncz = normals[ nc * 3 + 2 ]; 793 | 794 | var na = new THREE.Vector3( nax, nay, naz ), 795 | nb = new THREE.Vector3( nbx, nby, nbz ), 796 | nc = new THREE.Vector3( ncx, ncy, ncz ); 797 | 798 | var face = new THREE.Face3( a, b, c, [ na, nb, nc ], null, mi ); 799 | 800 | scope.faces.push( face ); 801 | 802 | return face; 803 | 804 | }; 805 | 806 | function uv3 ( where, u1, v1, u2, v2, u3, v3 ) { 807 | 808 | var uv = []; 809 | uv.push( new THREE.UV( u1, v1 ) ); 810 | uv.push( new THREE.UV( u2, v2 ) ); 811 | uv.push( new THREE.UV( u3, v3 ) ); 812 | where.push( uv ); 813 | 814 | }; 815 | 816 | Model.prototype = new THREE.Geometry(); 817 | Model.prototype.constructor = Model; 818 | 819 | callback( new Model() ); 820 | 821 | }; 822 | -------------------------------------------------------------------------------- /r48/js/ctm/CTMWorker.js: -------------------------------------------------------------------------------- 1 | importScripts( "lzma.js", "ctm.js" ); 2 | 3 | self.onmessage = function( event ) { 4 | 5 | var files = []; 6 | 7 | for ( var i = 0; i < event.data.offsets.length; i ++ ) { 8 | 9 | var stream = new CTM.Stream( event.data.data ); 10 | stream.offset = event.data.offsets[ i ]; 11 | 12 | files[ i ] = new CTM.File( stream ); 13 | 14 | } 15 | 16 | self.postMessage( files ); 17 | self.close(); 18 | 19 | } 20 | -------------------------------------------------------------------------------- /r48/js/ctm/ctm.js: -------------------------------------------------------------------------------- 1 | 2 | var CTM = CTM || {}; 3 | 4 | CTM.CompressionMethod = { 5 | RAW: 0x00574152, 6 | MG1: 0x0031474d, 7 | MG2: 0x0032474d 8 | }; 9 | 10 | CTM.Flags = { 11 | NORMALS: 0x00000001 12 | }; 13 | 14 | CTM.File = function(stream){ 15 | this.load(stream); 16 | }; 17 | 18 | CTM.File.prototype.load = function(stream){ 19 | this.header = new CTM.FileHeader(stream); 20 | 21 | this.body = new CTM.FileBody(this.header); 22 | 23 | this.getReader().read(stream, this.body); 24 | }; 25 | 26 | CTM.File.prototype.getReader = function(){ 27 | var reader; 28 | 29 | switch(this.header.compressionMethod){ 30 | case CTM.CompressionMethod.RAW: 31 | reader = new CTM.ReaderRAW(); 32 | break; 33 | case CTM.CompressionMethod.MG1: 34 | reader = new CTM.ReaderMG1(); 35 | break; 36 | case CTM.CompressionMethod.MG2: 37 | reader = new CTM.ReaderMG2(); 38 | break; 39 | } 40 | 41 | return reader; 42 | }; 43 | 44 | CTM.FileHeader = function(stream){ 45 | stream.readInt32(); //magic "OCTM" 46 | this.fileFormat = stream.readInt32(); 47 | this.compressionMethod = stream.readInt32(); 48 | this.vertexCount = stream.readInt32(); 49 | this.triangleCount = stream.readInt32(); 50 | this.uvMapCount = stream.readInt32(); 51 | this.attrMapCount = stream.readInt32(); 52 | this.flags = stream.readInt32(); 53 | this.comment = stream.readString(); 54 | }; 55 | 56 | CTM.FileHeader.prototype.hasNormals = function(){ 57 | return this.flags & CTM.Flags.NORMALS; 58 | }; 59 | 60 | CTM.FileBody = function(header){ 61 | var i = header.triangleCount * 3, 62 | v = header.vertexCount * 3, 63 | n = header.hasNormals()? header.vertexCount * 3: 0, 64 | u = header.vertexCount * 2, 65 | a = header.vertexCount * 4, 66 | j = 0; 67 | 68 | var data = new ArrayBuffer( 69 | (i + v + n + (u * header.uvMapCount) + (a * header.attrMapCount) ) * 4); 70 | 71 | this.indices = new Uint32Array(data, 0, i); 72 | 73 | this.vertices = new Float32Array(data, i * 4, v); 74 | 75 | if ( header.hasNormals() ){ 76 | this.normals = new Float32Array(data, (i + v) * 4, n); 77 | } 78 | 79 | if (header.uvMapCount){ 80 | this.uvMaps = []; 81 | for (j = 0; j < header.uvMapCount; ++ j){ 82 | this.uvMaps[j] = {uv: new Float32Array(data, 83 | (i + v + n + (j * u) ) * 4, u) }; 84 | } 85 | } 86 | 87 | if (header.attrMapCount){ 88 | this.attrMaps = []; 89 | for (j = 0; j < header.attrMapCount; ++ j){ 90 | this.attrMaps[j] = {attr: new Float32Array(data, 91 | (i + v + n + (u * header.uvMapCount) + (j * a) ) * 4, a) }; 92 | } 93 | } 94 | }; 95 | 96 | CTM.FileMG2Header = function(stream){ 97 | stream.readInt32(); //magic "MG2H" 98 | this.vertexPrecision = stream.readFloat32(); 99 | this.normalPrecision = stream.readFloat32(); 100 | this.lowerBoundx = stream.readFloat32(); 101 | this.lowerBoundy = stream.readFloat32(); 102 | this.lowerBoundz = stream.readFloat32(); 103 | this.higherBoundx = stream.readFloat32(); 104 | this.higherBoundy = stream.readFloat32(); 105 | this.higherBoundz = stream.readFloat32(); 106 | this.divx = stream.readInt32(); 107 | this.divy = stream.readInt32(); 108 | this.divz = stream.readInt32(); 109 | 110 | this.sizex = (this.higherBoundx - this.lowerBoundx) / this.divx; 111 | this.sizey = (this.higherBoundy - this.lowerBoundy) / this.divy; 112 | this.sizez = (this.higherBoundz - this.lowerBoundz) / this.divz; 113 | }; 114 | 115 | CTM.ReaderRAW = function(){ 116 | }; 117 | 118 | CTM.ReaderRAW.prototype.read = function(stream, body){ 119 | this.readIndices(stream, body.indices); 120 | this.readVertices(stream, body.vertices); 121 | 122 | if (body.normals){ 123 | this.readNormals(stream, body.normals); 124 | } 125 | if (body.uvMaps){ 126 | this.readUVMaps(stream, body.uvMaps); 127 | } 128 | if (body.attrMaps){ 129 | this.readAttrMaps(stream, body.attrMaps); 130 | } 131 | }; 132 | 133 | CTM.ReaderRAW.prototype.readIndices = function(stream, indices){ 134 | stream.readInt32(); //magic "INDX" 135 | stream.readArrayInt32(indices); 136 | }; 137 | 138 | CTM.ReaderRAW.prototype.readVertices = function(stream, vertices){ 139 | stream.readInt32(); //magic "VERT" 140 | stream.readArrayFloat32(vertices); 141 | }; 142 | 143 | CTM.ReaderRAW.prototype.readNormals = function(stream, normals){ 144 | stream.readInt32(); //magic "NORM" 145 | stream.readArrayFloat32(normals); 146 | }; 147 | 148 | CTM.ReaderRAW.prototype.readUVMaps = function(stream, uvMaps){ 149 | var i = 0; 150 | for (; i < uvMaps.length; ++ i){ 151 | stream.readInt32(); //magic "TEXC" 152 | 153 | uvMaps[i].name = stream.readString(); 154 | uvMaps[i].filename = stream.readString(); 155 | stream.readArrayFloat32(uvMaps[i].uv); 156 | } 157 | }; 158 | 159 | CTM.ReaderRAW.prototype.readAttrMaps = function(stream, attrMaps){ 160 | var i = 0; 161 | for (; i < attrMaps.length; ++ i){ 162 | stream.readInt32(); //magic "ATTR" 163 | 164 | attrMaps[i].name = stream.readString(); 165 | stream.readArrayFloat32(attrMaps[i].attr); 166 | } 167 | }; 168 | 169 | CTM.ReaderMG1 = function(){ 170 | }; 171 | 172 | CTM.ReaderMG1.prototype.read = function(stream, body){ 173 | this.readIndices(stream, body.indices); 174 | this.readVertices(stream, body.vertices); 175 | 176 | if (body.normals){ 177 | this.readNormals(stream, body.normals); 178 | } 179 | if (body.uvMaps){ 180 | this.readUVMaps(stream, body.uvMaps); 181 | } 182 | if (body.attrMaps){ 183 | this.readAttrMaps(stream, body.attrMaps); 184 | } 185 | }; 186 | 187 | CTM.ReaderMG1.prototype.readIndices = function(stream, indices){ 188 | stream.readInt32(); //magic "INDX" 189 | stream.readInt32(); //packed size 190 | 191 | var interleaved = new CTM.InterleavedStream(indices, 3); 192 | LZMA.decompress(stream, stream, interleaved, interleaved.data.length); 193 | 194 | CTM.restoreIndices(indices, indices.length); 195 | }; 196 | 197 | CTM.ReaderMG1.prototype.readVertices = function(stream, vertices){ 198 | stream.readInt32(); //magic "VERT" 199 | stream.readInt32(); //packed size 200 | 201 | var interleaved = new CTM.InterleavedStream(vertices, 1); 202 | LZMA.decompress(stream, stream, interleaved, interleaved.data.length); 203 | }; 204 | 205 | CTM.ReaderMG1.prototype.readNormals = function(stream, normals){ 206 | stream.readInt32(); //magic "NORM" 207 | stream.readInt32(); //packed size 208 | 209 | var interleaved = new CTM.InterleavedStream(normals, 3); 210 | LZMA.decompress(stream, stream, interleaved, interleaved.data.length); 211 | }; 212 | 213 | CTM.ReaderMG1.prototype.readUVMaps = function(stream, uvMaps){ 214 | var i = 0; 215 | for (; i < uvMaps.length; ++ i){ 216 | stream.readInt32(); //magic "TEXC" 217 | 218 | uvMaps[i].name = stream.readString(); 219 | uvMaps[i].filename = stream.readString(); 220 | 221 | stream.readInt32(); //packed size 222 | 223 | var interleaved = new CTM.InterleavedStream(uvMaps[i].uv, 2); 224 | LZMA.decompress(stream, stream, interleaved, interleaved.data.length); 225 | } 226 | }; 227 | 228 | CTM.ReaderMG1.prototype.readAttrMaps = function(stream, attrMaps){ 229 | var i = 0; 230 | for (; i < attrMaps.length; ++ i){ 231 | stream.readInt32(); //magic "ATTR" 232 | 233 | attrMaps[i].name = stream.readString(); 234 | 235 | stream.readInt32(); //packed size 236 | 237 | var interleaved = new CTM.InterleavedStream(attrMaps[i].attr, 4); 238 | LZMA.decompress(stream, stream, interleaved, interleaved.data.length); 239 | } 240 | }; 241 | 242 | CTM.ReaderMG2 = function(){ 243 | }; 244 | 245 | CTM.ReaderMG2.prototype.read = function(stream, body){ 246 | this.MG2Header = new CTM.FileMG2Header(stream); 247 | 248 | this.readVertices(stream, body.vertices); 249 | this.readIndices(stream, body.indices); 250 | 251 | if (body.normals){ 252 | this.readNormals(stream, body); 253 | } 254 | if (body.uvMaps){ 255 | this.readUVMaps(stream, body.uvMaps); 256 | } 257 | if (body.attrMaps){ 258 | this.readAttrMaps(stream, body.attrMaps); 259 | } 260 | }; 261 | 262 | CTM.ReaderMG2.prototype.readVertices = function(stream, vertices){ 263 | stream.readInt32(); //magic "VERT" 264 | stream.readInt32(); //packed size 265 | 266 | var interleaved = new CTM.InterleavedStream(vertices, 3); 267 | LZMA.decompress(stream, stream, interleaved, interleaved.data.length); 268 | 269 | var gridIndices = this.readGridIndices(stream, vertices); 270 | 271 | CTM.restoreVertices(vertices, this.MG2Header, gridIndices, this.MG2Header.vertexPrecision); 272 | }; 273 | 274 | CTM.ReaderMG2.prototype.readGridIndices = function(stream, vertices){ 275 | stream.readInt32(); //magic "GIDX" 276 | stream.readInt32(); //packed size 277 | 278 | var gridIndices = new Uint32Array(vertices.length / 3); 279 | 280 | var interleaved = new CTM.InterleavedStream(gridIndices, 1); 281 | LZMA.decompress(stream, stream, interleaved, interleaved.data.length); 282 | 283 | CTM.restoreGridIndices(gridIndices, gridIndices.length); 284 | 285 | return gridIndices; 286 | }; 287 | 288 | CTM.ReaderMG2.prototype.readIndices = function(stream, indices){ 289 | stream.readInt32(); //magic "INDX" 290 | stream.readInt32(); //packed size 291 | 292 | var interleaved = new CTM.InterleavedStream(indices, 3); 293 | LZMA.decompress(stream, stream, interleaved, interleaved.data.length); 294 | 295 | CTM.restoreIndices(indices, indices.length); 296 | }; 297 | 298 | CTM.ReaderMG2.prototype.readNormals = function(stream, body){ 299 | stream.readInt32(); //magic "NORM" 300 | stream.readInt32(); //packed size 301 | 302 | var interleaved = new CTM.InterleavedStream(body.normals, 3); 303 | LZMA.decompress(stream, stream, interleaved, interleaved.data.length); 304 | 305 | var smooth = CTM.calcSmoothNormals(body.indices, body.vertices); 306 | 307 | CTM.restoreNormals(body.normals, smooth, this.MG2Header.normalPrecision); 308 | }; 309 | 310 | CTM.ReaderMG2.prototype.readUVMaps = function(stream, uvMaps){ 311 | var i = 0; 312 | for (; i < uvMaps.length; ++ i){ 313 | stream.readInt32(); //magic "TEXC" 314 | 315 | uvMaps[i].name = stream.readString(); 316 | uvMaps[i].filename = stream.readString(); 317 | 318 | var precision = stream.readFloat32(); 319 | 320 | stream.readInt32(); //packed size 321 | 322 | var interleaved = new CTM.InterleavedStream(uvMaps[i].uv, 2); 323 | LZMA.decompress(stream, stream, interleaved, interleaved.data.length); 324 | 325 | CTM.restoreMap(uvMaps[i].uv, 2, precision); 326 | } 327 | }; 328 | 329 | CTM.ReaderMG2.prototype.readAttrMaps = function(stream, attrMaps){ 330 | var i = 0; 331 | for (; i < attrMaps.length; ++ i){ 332 | stream.readInt32(); //magic "ATTR" 333 | 334 | attrMaps[i].name = stream.readString(); 335 | 336 | var precision = stream.readFloat32(); 337 | 338 | stream.readInt32(); //packed size 339 | 340 | var interleaved = new CTM.InterleavedStream(attrMaps[i].attr, 4); 341 | LZMA.decompress(stream, stream, interleaved, interleaved.data.length); 342 | 343 | CTM.restoreMap(attrMaps[i].attr, 4, precision); 344 | } 345 | }; 346 | 347 | CTM.restoreIndices = function(indices, len){ 348 | var i = 3; 349 | if (len > 0){ 350 | indices[2] += indices[0]; 351 | } 352 | for (; i < len; i += 3){ 353 | indices[i] += indices[i - 3]; 354 | 355 | if (indices[i] === indices[i - 3]){ 356 | indices[i + 1] += indices[i - 2]; 357 | }else{ 358 | indices[i + 1] += indices[i]; 359 | } 360 | 361 | indices[i + 2] += indices[i]; 362 | } 363 | }; 364 | 365 | CTM.restoreGridIndices = function(gridIndices, len){ 366 | var i = 1; 367 | for (; i < len; ++ i){ 368 | gridIndices[i] += gridIndices[i - 1]; 369 | } 370 | }; 371 | 372 | CTM.restoreVertices = function(vertices, grid, gridIndices, precision){ 373 | var gridIdx, delta, x, y, z, 374 | intVertices = new Uint32Array(vertices.buffer, vertices.byteOffset, vertices.length), 375 | ydiv = grid.divx, zdiv = ydiv * grid.divy, 376 | prevGridIdx = 0x7fffffff, prevDelta = 0, 377 | i = 0, j = 0, len = gridIndices.length; 378 | 379 | for (; i < len; j += 3){ 380 | x = gridIdx = gridIndices[i ++]; 381 | 382 | z = ~~(x / zdiv); 383 | x -= ~~(z * zdiv); 384 | y = ~~(x / ydiv); 385 | x -= ~~(y * ydiv); 386 | 387 | delta = intVertices[j]; 388 | if (gridIdx === prevGridIdx){ 389 | delta += prevDelta; 390 | } 391 | 392 | vertices[j] = grid.lowerBoundx + 393 | x * grid.sizex + precision * delta; 394 | vertices[j + 1] = grid.lowerBoundy + 395 | y * grid.sizey + precision * intVertices[j + 1]; 396 | vertices[j + 2] = grid.lowerBoundz + 397 | z * grid.sizez + precision * intVertices[j + 2]; 398 | 399 | prevGridIdx = gridIdx; 400 | prevDelta = delta; 401 | } 402 | }; 403 | 404 | CTM.restoreNormals = function(normals, smooth, precision){ 405 | var ro, phi, theta, sinPhi, 406 | nx, ny, nz, by, bz, len, 407 | intNormals = new Uint32Array(normals.buffer, normals.byteOffset, normals.length), 408 | i = 0, k = normals.length, 409 | PI_DIV_2 = 3.141592653589793238462643 * 0.5; 410 | 411 | for (; i < k; i += 3){ 412 | ro = intNormals[i] * precision; 413 | phi = intNormals[i + 1]; 414 | 415 | if (phi === 0){ 416 | normals[i] = smooth[i] * ro; 417 | normals[i + 1] = smooth[i + 1] * ro; 418 | normals[i + 2] = smooth[i + 2] * ro; 419 | }else{ 420 | 421 | if (phi <= 4){ 422 | theta = (intNormals[i + 2] - 2) * PI_DIV_2; 423 | }else{ 424 | theta = ( (intNormals[i + 2] * 4 / phi) - 2) * PI_DIV_2; 425 | } 426 | 427 | phi *= precision * PI_DIV_2; 428 | sinPhi = ro * Math.sin(phi); 429 | 430 | nx = sinPhi * Math.cos(theta); 431 | ny = sinPhi * Math.sin(theta); 432 | nz = ro * Math.cos(phi); 433 | 434 | bz = smooth[i + 1]; 435 | by = smooth[i] - smooth[i + 2]; 436 | 437 | len = Math.sqrt(2 * bz * bz + by * by); 438 | if (len > 1e-20){ 439 | by /= len; 440 | bz /= len; 441 | } 442 | 443 | normals[i] = smooth[i] * nz + 444 | (smooth[i + 1] * bz - smooth[i + 2] * by) * ny - bz * nx; 445 | normals[i + 1] = smooth[i + 1] * nz - 446 | (smooth[i + 2] + smooth[i] ) * bz * ny + by * nx; 447 | normals[i + 2] = smooth[i + 2] * nz + 448 | (smooth[i] * by + smooth[i + 1] * bz) * ny + bz * nx; 449 | } 450 | } 451 | }; 452 | 453 | CTM.restoreMap = function(map, count, precision){ 454 | var delta, value, 455 | intMap = new Uint32Array(map.buffer, map.byteOffset, map.length), 456 | i = 0, j, len = map.length; 457 | 458 | for (; i < count; ++ i){ 459 | delta = 0; 460 | 461 | for (j = i; j < len; j += count){ 462 | value = intMap[j]; 463 | 464 | delta += value & 1? -( (value + 1) >> 1): value >> 1; 465 | 466 | map[j] = delta * precision; 467 | } 468 | } 469 | }; 470 | 471 | CTM.calcSmoothNormals = function(indices, vertices){ 472 | var smooth = new Float32Array(vertices.length), 473 | indx, indy, indz, nx, ny, nz, 474 | v1x, v1y, v1z, v2x, v2y, v2z, len, 475 | i, k; 476 | 477 | for (i = 0, k = indices.length; i < k;){ 478 | indx = indices[i ++] * 3; 479 | indy = indices[i ++] * 3; 480 | indz = indices[i ++] * 3; 481 | 482 | v1x = vertices[indy] - vertices[indx]; 483 | v2x = vertices[indz] - vertices[indx]; 484 | v1y = vertices[indy + 1] - vertices[indx + 1]; 485 | v2y = vertices[indz + 1] - vertices[indx + 1]; 486 | v1z = vertices[indy + 2] - vertices[indx + 2]; 487 | v2z = vertices[indz + 2] - vertices[indx + 2]; 488 | 489 | nx = v1y * v2z - v1z * v2y; 490 | ny = v1z * v2x - v1x * v2z; 491 | nz = v1x * v2y - v1y * v2x; 492 | 493 | len = Math.sqrt(nx * nx + ny * ny + nz * nz); 494 | if (len > 1e-10){ 495 | nx /= len; 496 | ny /= len; 497 | nz /= len; 498 | } 499 | 500 | smooth[indx] += nx; 501 | smooth[indx + 1] += ny; 502 | smooth[indx + 2] += nz; 503 | smooth[indy] += nx; 504 | smooth[indy + 1] += ny; 505 | smooth[indy + 2] += nz; 506 | smooth[indz] += nx; 507 | smooth[indz + 1] += ny; 508 | smooth[indz + 2] += nz; 509 | } 510 | 511 | for (i = 0, k = smooth.length; i < k; i += 3){ 512 | len = Math.sqrt(smooth[i] * smooth[i] + 513 | smooth[i + 1] * smooth[i + 1] + 514 | smooth[i + 2] * smooth[i + 2]); 515 | 516 | if(len > 1e-10){ 517 | smooth[i] /= len; 518 | smooth[i + 1] /= len; 519 | smooth[i + 2] /= len; 520 | } 521 | } 522 | 523 | return smooth; 524 | }; 525 | 526 | CTM.isLittleEndian = (function(){ 527 | var buffer = new ArrayBuffer(2), 528 | bytes = new Uint8Array(buffer), 529 | ints = new Uint16Array(buffer); 530 | 531 | bytes[0] = 1; 532 | 533 | return ints[0] === 1; 534 | }()); 535 | 536 | CTM.InterleavedStream = function(data, count){ 537 | this.data = new Uint8Array(data.buffer, data.byteOffset, data.byteLength); 538 | this.offset = CTM.isLittleEndian? 3: 0; 539 | this.count = count * 4; 540 | this.len = this.data.length; 541 | }; 542 | 543 | CTM.InterleavedStream.prototype.writeByte = function(value){ 544 | this.data[this.offset] = value; 545 | 546 | this.offset += this.count; 547 | if (this.offset >= this.len){ 548 | 549 | this.offset -= this.len - 4; 550 | if (this.offset >= this.count){ 551 | 552 | this.offset -= this.count + (CTM.isLittleEndian? 1: -1); 553 | } 554 | } 555 | }; 556 | 557 | CTM.Stream = function(data){ 558 | this.data = data; 559 | this.offset = 0; 560 | }; 561 | 562 | CTM.Stream.prototype.TWO_POW_MINUS23 = Math.pow(2, -23); 563 | 564 | CTM.Stream.prototype.TWO_POW_MINUS126 = Math.pow(2, -126); 565 | 566 | CTM.Stream.prototype.readByte = function(){ 567 | return this.data.charCodeAt(this.offset ++) & 0xff; 568 | }; 569 | 570 | CTM.Stream.prototype.readInt32 = function(){ 571 | var i = this.readByte(); 572 | i |= this.readByte() << 8; 573 | i |= this.readByte() << 16; 574 | return i | (this.readByte() << 24); 575 | }; 576 | 577 | CTM.Stream.prototype.readFloat32 = function(){ 578 | var m = this.readByte(); 579 | m += this.readByte() << 8; 580 | 581 | var b1 = this.readByte(); 582 | var b2 = this.readByte(); 583 | 584 | m += (b1 & 0x7f) << 16; 585 | var e = ( (b2 & 0x7f) << 1) | ( (b1 & 0x80) >>> 7); 586 | var s = b2 & 0x80? -1: 1; 587 | 588 | if (e === 255){ 589 | return m !== 0? NaN: s * Infinity; 590 | } 591 | if (e > 0){ 592 | return s * (1 + (m * this.TWO_POW_MINUS23) ) * Math.pow(2, e - 127); 593 | } 594 | if (m !== 0){ 595 | return s * m * this.TWO_POW_MINUS126; 596 | } 597 | return s * 0; 598 | }; 599 | 600 | CTM.Stream.prototype.readString = function(){ 601 | var len = this.readInt32(); 602 | 603 | this.offset += len; 604 | 605 | return this.data.substr(this.offset - len, len); 606 | }; 607 | 608 | CTM.Stream.prototype.readArrayInt32 = function(array){ 609 | var i = 0, len = array.length; 610 | 611 | while(i < len){ 612 | array[i ++] = this.readInt32(); 613 | } 614 | 615 | return array; 616 | }; 617 | 618 | CTM.Stream.prototype.readArrayFloat32 = function(array){ 619 | var i = 0, len = array.length; 620 | 621 | while(i < len){ 622 | array[i ++] = this.readFloat32(); 623 | } 624 | 625 | return array; 626 | }; 627 | -------------------------------------------------------------------------------- /r48/js/ctm/license/OpenCTM.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009-2010 Marcus Geelnard 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgment in the product documentation would be 14 | appreciated but is not required. 15 | 16 | 2. Altered source versions must be plainly marked as such, and must not 17 | be misrepresented as being the original software. 18 | 19 | 3. This notice may not be removed or altered from any source 20 | distribution. 21 | -------------------------------------------------------------------------------- /r48/js/ctm/license/js-lzma.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Juan Mellado 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /r48/js/ctm/license/js-openctm.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Juan Mellado 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /r48/js/ctm/lzma.js: -------------------------------------------------------------------------------- 1 | 2 | var LZMA = LZMA || {}; 3 | 4 | LZMA.OutWindow = function(){ 5 | this._windowSize = 0; 6 | }; 7 | 8 | LZMA.OutWindow.prototype.create = function(windowSize){ 9 | if ( (!this._buffer) || (this._windowSize !== windowSize) ){ 10 | this._buffer = []; 11 | } 12 | this._windowSize = windowSize; 13 | this._pos = 0; 14 | this._streamPos = 0; 15 | }; 16 | 17 | LZMA.OutWindow.prototype.flush = function(){ 18 | var size = this._pos - this._streamPos; 19 | if (size !== 0){ 20 | while(size --){ 21 | this._stream.writeByte(this._buffer[this._streamPos ++]); 22 | } 23 | if (this._pos >= this._windowSize){ 24 | this._pos = 0; 25 | } 26 | this._streamPos = this._pos; 27 | } 28 | }; 29 | 30 | LZMA.OutWindow.prototype.releaseStream = function(){ 31 | this.flush(); 32 | this._stream = null; 33 | }; 34 | 35 | LZMA.OutWindow.prototype.setStream = function(stream){ 36 | this.releaseStream(); 37 | this._stream = stream; 38 | }; 39 | 40 | LZMA.OutWindow.prototype.init = function(solid){ 41 | if (!solid){ 42 | this._streamPos = 0; 43 | this._pos = 0; 44 | } 45 | }; 46 | 47 | LZMA.OutWindow.prototype.copyBlock = function(distance, len){ 48 | var pos = this._pos - distance - 1; 49 | if (pos < 0){ 50 | pos += this._windowSize; 51 | } 52 | while(len --){ 53 | if (pos >= this._windowSize){ 54 | pos = 0; 55 | } 56 | this._buffer[this._pos ++] = this._buffer[pos ++]; 57 | if (this._pos >= this._windowSize){ 58 | this.flush(); 59 | } 60 | } 61 | }; 62 | 63 | LZMA.OutWindow.prototype.putByte = function(b){ 64 | this._buffer[this._pos ++] = b; 65 | if (this._pos >= this._windowSize){ 66 | this.flush(); 67 | } 68 | }; 69 | 70 | LZMA.OutWindow.prototype.getByte = function(distance){ 71 | var pos = this._pos - distance - 1; 72 | if (pos < 0){ 73 | pos += this._windowSize; 74 | } 75 | return this._buffer[pos]; 76 | }; 77 | 78 | LZMA.RangeDecoder = function(){ 79 | }; 80 | 81 | LZMA.RangeDecoder.prototype.setStream = function(stream){ 82 | this._stream = stream; 83 | }; 84 | 85 | LZMA.RangeDecoder.prototype.releaseStream = function(){ 86 | this._stream = null; 87 | }; 88 | 89 | LZMA.RangeDecoder.prototype.init = function(){ 90 | var i = 5; 91 | 92 | this._code = 0; 93 | this._range = -1; 94 | 95 | while(i --){ 96 | this._code = (this._code << 8) | this._stream.readByte(); 97 | } 98 | }; 99 | 100 | LZMA.RangeDecoder.prototype.decodeDirectBits = function(numTotalBits){ 101 | var result = 0, i = numTotalBits, t; 102 | 103 | while(i --){ 104 | this._range >>>= 1; 105 | t = (this._code - this._range) >>> 31; 106 | this._code -= this._range & (t - 1); 107 | result = (result << 1) | (1 - t); 108 | 109 | if ( (this._range & 0xff000000) === 0){ 110 | this._code = (this._code << 8) | this._stream.readByte(); 111 | this._range <<= 8; 112 | } 113 | } 114 | 115 | return result; 116 | }; 117 | 118 | LZMA.RangeDecoder.prototype.decodeBit = function(probs, index){ 119 | var prob = probs[index], 120 | newBound = (this._range >>> 11) * prob; 121 | 122 | if ( (this._code ^ 0x80000000) < (newBound ^ 0x80000000) ){ 123 | this._range = newBound; 124 | probs[index] += (2048 - prob) >>> 5; 125 | if ( (this._range & 0xff000000) === 0){ 126 | this._code = (this._code << 8) | this._stream.readByte(); 127 | this._range <<= 8; 128 | } 129 | return 0; 130 | } 131 | 132 | this._range -= newBound; 133 | this._code -= newBound; 134 | probs[index] -= prob >>> 5; 135 | if ( (this._range & 0xff000000) === 0){ 136 | this._code = (this._code << 8) | this._stream.readByte(); 137 | this._range <<= 8; 138 | } 139 | return 1; 140 | }; 141 | 142 | LZMA.initBitModels = function(probs, len){ 143 | while(len --){ 144 | probs[len] = 1024; 145 | } 146 | }; 147 | 148 | LZMA.BitTreeDecoder = function(numBitLevels){ 149 | this._models = []; 150 | this._numBitLevels = numBitLevels; 151 | }; 152 | 153 | LZMA.BitTreeDecoder.prototype.init = function(){ 154 | LZMA.initBitModels(this._models, 1 << this._numBitLevels); 155 | }; 156 | 157 | LZMA.BitTreeDecoder.prototype.decode = function(rangeDecoder){ 158 | var m = 1, i = this._numBitLevels; 159 | 160 | while(i --){ 161 | m = (m << 1) | rangeDecoder.decodeBit(this._models, m); 162 | } 163 | return m - (1 << this._numBitLevels); 164 | }; 165 | 166 | LZMA.BitTreeDecoder.prototype.reverseDecode = function(rangeDecoder){ 167 | var m = 1, symbol = 0, i = 0, bit; 168 | 169 | for (; i < this._numBitLevels; ++ i){ 170 | bit = rangeDecoder.decodeBit(this._models, m); 171 | m = (m << 1) | bit; 172 | symbol |= bit << i; 173 | } 174 | return symbol; 175 | }; 176 | 177 | LZMA.reverseDecode2 = function(models, startIndex, rangeDecoder, numBitLevels){ 178 | var m = 1, symbol = 0, i = 0, bit; 179 | 180 | for (; i < numBitLevels; ++ i){ 181 | bit = rangeDecoder.decodeBit(models, startIndex + m); 182 | m = (m << 1) | bit; 183 | symbol |= bit << i; 184 | } 185 | return symbol; 186 | }; 187 | 188 | LZMA.LenDecoder = function(){ 189 | this._choice = []; 190 | this._lowCoder = []; 191 | this._midCoder = []; 192 | this._highCoder = new LZMA.BitTreeDecoder(8); 193 | this._numPosStates = 0; 194 | }; 195 | 196 | LZMA.LenDecoder.prototype.create = function(numPosStates){ 197 | for (; this._numPosStates < numPosStates; ++ this._numPosStates){ 198 | this._lowCoder[this._numPosStates] = new LZMA.BitTreeDecoder(3); 199 | this._midCoder[this._numPosStates] = new LZMA.BitTreeDecoder(3); 200 | } 201 | }; 202 | 203 | LZMA.LenDecoder.prototype.init = function(){ 204 | var i = this._numPosStates; 205 | LZMA.initBitModels(this._choice, 2); 206 | while(i --){ 207 | this._lowCoder[i].init(); 208 | this._midCoder[i].init(); 209 | } 210 | this._highCoder.init(); 211 | }; 212 | 213 | LZMA.LenDecoder.prototype.decode = function(rangeDecoder, posState){ 214 | if (rangeDecoder.decodeBit(this._choice, 0) === 0){ 215 | return this._lowCoder[posState].decode(rangeDecoder); 216 | } 217 | if (rangeDecoder.decodeBit(this._choice, 1) === 0){ 218 | return 8 + this._midCoder[posState].decode(rangeDecoder); 219 | } 220 | return 16 + this._highCoder.decode(rangeDecoder); 221 | }; 222 | 223 | LZMA.Decoder2 = function(){ 224 | this._decoders = []; 225 | }; 226 | 227 | LZMA.Decoder2.prototype.init = function(){ 228 | LZMA.initBitModels(this._decoders, 0x300); 229 | }; 230 | 231 | LZMA.Decoder2.prototype.decodeNormal = function(rangeDecoder){ 232 | var symbol = 1; 233 | 234 | do{ 235 | symbol = (symbol << 1) | rangeDecoder.decodeBit(this._decoders, symbol); 236 | }while(symbol < 0x100); 237 | 238 | return symbol & 0xff; 239 | }; 240 | 241 | LZMA.Decoder2.prototype.decodeWithMatchByte = function(rangeDecoder, matchByte){ 242 | var symbol = 1, matchBit, bit; 243 | 244 | do{ 245 | matchBit = (matchByte >> 7) & 1; 246 | matchByte <<= 1; 247 | bit = rangeDecoder.decodeBit(this._decoders, ( (1 + matchBit) << 8) + symbol); 248 | symbol = (symbol << 1) | bit; 249 | if (matchBit !== bit){ 250 | while(symbol < 0x100){ 251 | symbol = (symbol << 1) | rangeDecoder.decodeBit(this._decoders, symbol); 252 | } 253 | break; 254 | } 255 | }while(symbol < 0x100); 256 | 257 | return symbol & 0xff; 258 | }; 259 | 260 | LZMA.LiteralDecoder = function(){ 261 | }; 262 | 263 | LZMA.LiteralDecoder.prototype.create = function(numPosBits, numPrevBits){ 264 | var i; 265 | 266 | if (this._coders 267 | && (this._numPrevBits === numPrevBits) 268 | && (this._numPosBits === numPosBits) ){ 269 | return; 270 | } 271 | this._numPosBits = numPosBits; 272 | this._posMask = (1 << numPosBits) - 1; 273 | this._numPrevBits = numPrevBits; 274 | 275 | this._coders = []; 276 | 277 | i = 1 << (this._numPrevBits + this._numPosBits); 278 | while(i --){ 279 | this._coders[i] = new LZMA.Decoder2(); 280 | } 281 | }; 282 | 283 | LZMA.LiteralDecoder.prototype.init = function(){ 284 | var i = 1 << (this._numPrevBits + this._numPosBits); 285 | while(i --){ 286 | this._coders[i].init(); 287 | } 288 | }; 289 | 290 | LZMA.LiteralDecoder.prototype.getDecoder = function(pos, prevByte){ 291 | return this._coders[( (pos & this._posMask) << this._numPrevBits) 292 | + ( (prevByte & 0xff) >>> (8 - this._numPrevBits) )]; 293 | }; 294 | 295 | LZMA.Decoder = function(){ 296 | this._outWindow = new LZMA.OutWindow(); 297 | this._rangeDecoder = new LZMA.RangeDecoder(); 298 | this._isMatchDecoders = []; 299 | this._isRepDecoders = []; 300 | this._isRepG0Decoders = []; 301 | this._isRepG1Decoders = []; 302 | this._isRepG2Decoders = []; 303 | this._isRep0LongDecoders = []; 304 | this._posSlotDecoder = []; 305 | this._posDecoders = []; 306 | this._posAlignDecoder = new LZMA.BitTreeDecoder(4); 307 | this._lenDecoder = new LZMA.LenDecoder(); 308 | this._repLenDecoder = new LZMA.LenDecoder(); 309 | this._literalDecoder = new LZMA.LiteralDecoder(); 310 | this._dictionarySize = -1; 311 | this._dictionarySizeCheck = -1; 312 | 313 | this._posSlotDecoder[0] = new LZMA.BitTreeDecoder(6); 314 | this._posSlotDecoder[1] = new LZMA.BitTreeDecoder(6); 315 | this._posSlotDecoder[2] = new LZMA.BitTreeDecoder(6); 316 | this._posSlotDecoder[3] = new LZMA.BitTreeDecoder(6); 317 | }; 318 | 319 | LZMA.Decoder.prototype.setDictionarySize = function(dictionarySize){ 320 | if (dictionarySize < 0){ 321 | return false; 322 | } 323 | if (this._dictionarySize !== dictionarySize){ 324 | this._dictionarySize = dictionarySize; 325 | this._dictionarySizeCheck = Math.max(this._dictionarySize, 1); 326 | this._outWindow.create( Math.max(this._dictionarySizeCheck, 4096) ); 327 | } 328 | return true; 329 | }; 330 | 331 | LZMA.Decoder.prototype.setLcLpPb = function(lc, lp, pb){ 332 | var numPosStates = 1 << pb; 333 | 334 | if (lc > 8 || lp > 4 || pb > 4){ 335 | return false; 336 | } 337 | 338 | this._literalDecoder.create(lp, lc); 339 | 340 | this._lenDecoder.create(numPosStates); 341 | this._repLenDecoder.create(numPosStates); 342 | this._posStateMask = numPosStates - 1; 343 | 344 | return true; 345 | }; 346 | 347 | LZMA.Decoder.prototype.init = function(){ 348 | var i = 4; 349 | 350 | this._outWindow.init(false); 351 | 352 | LZMA.initBitModels(this._isMatchDecoders, 192); 353 | LZMA.initBitModels(this._isRep0LongDecoders, 192); 354 | LZMA.initBitModels(this._isRepDecoders, 12); 355 | LZMA.initBitModels(this._isRepG0Decoders, 12); 356 | LZMA.initBitModels(this._isRepG1Decoders, 12); 357 | LZMA.initBitModels(this._isRepG2Decoders, 12); 358 | LZMA.initBitModels(this._posDecoders, 114); 359 | 360 | this._literalDecoder.init(); 361 | 362 | while(i --){ 363 | this._posSlotDecoder[i].init(); 364 | } 365 | 366 | this._lenDecoder.init(); 367 | this._repLenDecoder.init(); 368 | this._posAlignDecoder.init(); 369 | this._rangeDecoder.init(); 370 | }; 371 | 372 | LZMA.Decoder.prototype.decode = function(inStream, outStream, outSize){ 373 | var state = 0, rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0, nowPos64 = 0, prevByte = 0, 374 | posState, decoder2, len, distance, posSlot, numDirectBits; 375 | 376 | this._rangeDecoder.setStream(inStream); 377 | this._outWindow.setStream(outStream); 378 | 379 | this.init(); 380 | 381 | while(outSize < 0 || nowPos64 < outSize){ 382 | posState = nowPos64 & this._posStateMask; 383 | 384 | if (this._rangeDecoder.decodeBit(this._isMatchDecoders, (state << 4) + posState) === 0){ 385 | decoder2 = this._literalDecoder.getDecoder(nowPos64 ++, prevByte); 386 | 387 | if (state >= 7){ 388 | prevByte = decoder2.decodeWithMatchByte(this._rangeDecoder, this._outWindow.getByte(rep0) ); 389 | }else{ 390 | prevByte = decoder2.decodeNormal(this._rangeDecoder); 391 | } 392 | this._outWindow.putByte(prevByte); 393 | 394 | state = state < 4? 0: state - (state < 10? 3: 6); 395 | 396 | }else{ 397 | 398 | if (this._rangeDecoder.decodeBit(this._isRepDecoders, state) === 1){ 399 | len = 0; 400 | if (this._rangeDecoder.decodeBit(this._isRepG0Decoders, state) === 0){ 401 | if (this._rangeDecoder.decodeBit(this._isRep0LongDecoders, (state << 4) + posState) === 0){ 402 | state = state < 7? 9: 11; 403 | len = 1; 404 | } 405 | }else{ 406 | if (this._rangeDecoder.decodeBit(this._isRepG1Decoders, state) === 0){ 407 | distance = rep1; 408 | }else{ 409 | if (this._rangeDecoder.decodeBit(this._isRepG2Decoders, state) === 0){ 410 | distance = rep2; 411 | }else{ 412 | distance = rep3; 413 | rep3 = rep2; 414 | } 415 | rep2 = rep1; 416 | } 417 | rep1 = rep0; 418 | rep0 = distance; 419 | } 420 | if (len === 0){ 421 | len = 2 + this._repLenDecoder.decode(this._rangeDecoder, posState); 422 | state = state < 7? 8: 11; 423 | } 424 | }else{ 425 | rep3 = rep2; 426 | rep2 = rep1; 427 | rep1 = rep0; 428 | 429 | len = 2 + this._lenDecoder.decode(this._rangeDecoder, posState); 430 | state = state < 7? 7: 10; 431 | 432 | posSlot = this._posSlotDecoder[len <= 5? len - 2: 3].decode(this._rangeDecoder); 433 | if (posSlot >= 4){ 434 | 435 | numDirectBits = (posSlot >> 1) - 1; 436 | rep0 = (2 | (posSlot & 1) ) << numDirectBits; 437 | 438 | if (posSlot < 14){ 439 | rep0 += LZMA.reverseDecode2(this._posDecoders, 440 | rep0 - posSlot - 1, this._rangeDecoder, numDirectBits); 441 | }else{ 442 | rep0 += this._rangeDecoder.decodeDirectBits(numDirectBits - 4) << 4; 443 | rep0 += this._posAlignDecoder.reverseDecode(this._rangeDecoder); 444 | if (rep0 < 0){ 445 | if (rep0 === -1){ 446 | break; 447 | } 448 | return false; 449 | } 450 | } 451 | }else{ 452 | rep0 = posSlot; 453 | } 454 | } 455 | 456 | if (rep0 >= nowPos64 || rep0 >= this._dictionarySizeCheck){ 457 | return false; 458 | } 459 | 460 | this._outWindow.copyBlock(rep0, len); 461 | nowPos64 += len; 462 | prevByte = this._outWindow.getByte(0); 463 | } 464 | } 465 | 466 | this._outWindow.flush(); 467 | this._outWindow.releaseStream(); 468 | this._rangeDecoder.releaseStream(); 469 | 470 | return true; 471 | }; 472 | 473 | LZMA.Decoder.prototype.setDecoderProperties = function(properties){ 474 | var value, lc, lp, pb, dictionarySize; 475 | 476 | if (properties.size < 5){ 477 | return false; 478 | } 479 | 480 | value = properties.readByte(); 481 | lc = value % 9; 482 | value = ~~(value / 9); 483 | lp = value % 5; 484 | pb = ~~(value / 5); 485 | 486 | if ( !this.setLcLpPb(lc, lp, pb) ){ 487 | return false; 488 | } 489 | 490 | dictionarySize = properties.readByte(); 491 | dictionarySize |= properties.readByte() << 8; 492 | dictionarySize |= properties.readByte() << 16; 493 | dictionarySize += properties.readByte() * 16777216; 494 | 495 | return this.setDictionarySize(dictionarySize); 496 | }; 497 | 498 | LZMA.decompress = function(properties, inStream, outStream, outSize){ 499 | var decoder = new LZMA.Decoder(); 500 | 501 | if ( !decoder.setDecoderProperties(properties) ){ 502 | throw "Incorrect stream properties"; 503 | } 504 | 505 | if ( !decoder.decode(inStream, outStream, outSize) ){ 506 | throw "Error in data stream"; 507 | } 508 | 509 | return true; 510 | }; 511 | -------------------------------------------------------------------------------- /r48/js/extras/Shaders.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * THREE.Extras.Shaders contains extra Fx shaders like godrays 3 | * 4 | * @author Thibaut 'BKcore' Despoulain 5 | * 6 | */ 7 | 8 | THREE = THREE || {}; 9 | THREE.Extras = THREE.Extras || {}; 10 | 11 | THREE.Extras.Shaders = { 12 | // Volumetric Light Approximation (Godrays) 13 | Godrays: { 14 | uniforms: { 15 | tDiffuse: {type: "t", value:0, texture:null}, 16 | fX: {type: "f", value: 0.5}, 17 | fY: {type: "f", value: 0.5}, 18 | fExposure: {type: "f", value: 0.6}, 19 | fDecay: {type: "f", value: 0.93}, 20 | fDensity: {type: "f", value: 0.96}, 21 | fWeight: {type: "f", value: 0.4}, 22 | fClamp: {type: "f", value: 1.0} 23 | }, 24 | 25 | vertexShader: [ 26 | "varying vec2 vUv;", 27 | 28 | "void main() {", 29 | 30 | "vUv = vec2( uv.x, 1.0 - uv.y );", 31 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 32 | 33 | "}" 34 | ].join("\n"), 35 | 36 | fragmentShader: [ 37 | "varying vec2 vUv;", 38 | "uniform sampler2D tDiffuse;", 39 | 40 | "uniform float fX;", 41 | "uniform float fY;", 42 | "uniform float fExposure;", 43 | "uniform float fDecay;", 44 | "uniform float fDensity;", 45 | "uniform float fWeight;", 46 | "uniform float fClamp;", 47 | 48 | "const int iSamples = 20;", 49 | 50 | "void main()", 51 | "{", 52 | "vec2 deltaTextCoord = vec2(vUv - vec2(fX,fY));", 53 | "deltaTextCoord *= 1.0 / float(iSamples) * fDensity;", 54 | "vec2 coord = vUv;", 55 | "float illuminationDecay = 1.0;", 56 | "vec4 FragColor = vec4(0.0);", 57 | 58 | "for(int i=0; i < iSamples ; i++)", 59 | "{", 60 | "coord -= deltaTextCoord;", 61 | "vec4 texel = texture2D(tDiffuse, coord);", 62 | "texel *= illuminationDecay * fWeight;", 63 | 64 | "FragColor += texel;", 65 | 66 | "illuminationDecay *= fDecay;", 67 | "}", 68 | "FragColor *= fExposure;", 69 | "FragColor = clamp(FragColor, 0.0, fClamp);", 70 | "gl_FragColor = FragColor;", 71 | "}" 72 | ].join("\n") 73 | }, 74 | 75 | // Coeff'd additive buffer blending 76 | Additive: { 77 | uniforms: { 78 | tDiffuse: { type: "t", value: 0, texture: null }, 79 | tAdd: { type: "t", value: 1, texture: null }, 80 | fCoeff: { type: "f", value: 1.0 } 81 | }, 82 | 83 | vertexShader: [ 84 | "varying vec2 vUv;", 85 | 86 | "void main() {", 87 | 88 | "vUv = vec2( uv.x, 1.0 - uv.y );", 89 | "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", 90 | 91 | "}" 92 | ].join("\n"), 93 | 94 | fragmentShader: [ 95 | "uniform sampler2D tDiffuse;", 96 | "uniform sampler2D tAdd;", 97 | "uniform float fCoeff;", 98 | 99 | "varying vec2 vUv;", 100 | 101 | "void main() {", 102 | 103 | "vec4 texel = texture2D( tDiffuse, vUv );", 104 | "vec4 add = texture2D( tAdd, vUv );", 105 | "gl_FragColor = texel + add * fCoeff;", 106 | 107 | "}" 108 | ].join("\n") 109 | } 110 | }; -------------------------------------------------------------------------------- /r48/js/extras/Utils.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * THREE.Extras.UTils contains extra useful methods 3 | * 4 | * @author Thibaut 'BKcore' Despoulain 5 | * 6 | */ 7 | 8 | THREE = THREE || {}; 9 | THREE.Extras = THREE.Extras || {}; 10 | THREE.Extras.Utils = THREE.Extras.Utils || {}; 11 | 12 | /*! Projects object origin into screen space coordinates using provided camera */ 13 | THREE.Extras.Utils.projectOnScreen = function(object, camera) 14 | { 15 | var mat = new THREE.Matrix4(); 16 | mat.multiply( camera.matrixWorldInverse, object.matrixWorld); 17 | mat.multiply( camera.projectionMatrix , mat); 18 | 19 | var c = mat.n44; 20 | var lPos = new THREE.Vector3(mat.n14/c, mat.n24/c, mat.n34/c); 21 | lPos.multiplyScalar(0.5); 22 | lPos.addScalar(0.5); 23 | return lPos; 24 | } -------------------------------------------------------------------------------- /r48/js/postprocessing/BloomPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.BloomPass = function( strength, kernelSize, sigma, resolution ) { 6 | 7 | strength = ( strength !== undefined ) ? strength : 1; 8 | kernelSize = ( kernelSize !== undefined ) ? kernelSize : 25; 9 | sigma = ( sigma !== undefined ) ? sigma : 4.0; 10 | resolution = ( resolution !== undefined ) ? resolution : 256; 11 | 12 | // render targets 13 | 14 | var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat }; 15 | 16 | this.renderTargetX = new THREE.WebGLRenderTarget( resolution, resolution, pars ); 17 | this.renderTargetY = new THREE.WebGLRenderTarget( resolution, resolution, pars ); 18 | 19 | // screen material 20 | 21 | var screenShader = THREE.ShaderExtras[ "screen" ]; 22 | 23 | this.screenUniforms = THREE.UniformsUtils.clone( screenShader.uniforms ); 24 | 25 | this.screenUniforms[ "opacity" ].value = strength; 26 | 27 | this.materialScreen = new THREE.ShaderMaterial( { 28 | 29 | uniforms: this.screenUniforms, 30 | vertexShader: screenShader.vertexShader, 31 | fragmentShader: screenShader.fragmentShader, 32 | blending: THREE.AdditiveBlending, 33 | transparent: true 34 | 35 | } ); 36 | 37 | // convolution material 38 | 39 | var convolutionShader = THREE.ShaderExtras[ "convolution" ]; 40 | 41 | this.convolutionUniforms = THREE.UniformsUtils.clone( convolutionShader.uniforms ); 42 | 43 | this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurx; 44 | this.convolutionUniforms[ "cKernel" ].value = THREE.ShaderExtras.buildKernel( sigma ); 45 | 46 | this.materialConvolution = new THREE.ShaderMaterial( { 47 | 48 | uniforms: this.convolutionUniforms, 49 | vertexShader: "#define KERNEL_SIZE " + kernelSize + ".0\n" + convolutionShader.vertexShader, 50 | fragmentShader: "#define KERNEL_SIZE " + kernelSize + "\n" + convolutionShader.fragmentShader 51 | 52 | } ); 53 | 54 | this.enabled = true; 55 | this.needsSwap = false; 56 | this.clear = false; 57 | 58 | }; 59 | 60 | THREE.BloomPass.prototype = { 61 | 62 | render: function ( renderer, writeBuffer, readBuffer, delta, maskActive ) { 63 | 64 | if ( maskActive ) renderer.context.disable( renderer.context.STENCIL_TEST ); 65 | 66 | // Render quad with blured scene into texture (convolution pass 1) 67 | 68 | THREE.EffectComposer.quad.material = this.materialConvolution; 69 | 70 | this.convolutionUniforms[ "tDiffuse" ].texture = readBuffer; 71 | this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurX; 72 | 73 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, this.renderTargetX, true ); 74 | 75 | 76 | // Render quad with blured scene into texture (convolution pass 2) 77 | 78 | this.convolutionUniforms[ "tDiffuse" ].texture = this.renderTargetX; 79 | this.convolutionUniforms[ "uImageIncrement" ].value = THREE.BloomPass.blurY; 80 | 81 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, this.renderTargetY, true ); 82 | 83 | // Render original scene with superimposed blur to texture 84 | 85 | THREE.EffectComposer.quad.material = this.materialScreen; 86 | 87 | this.screenUniforms[ "tDiffuse" ].texture = this.renderTargetY; 88 | 89 | if ( maskActive ) renderer.context.enable( renderer.context.STENCIL_TEST ); 90 | 91 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, readBuffer, this.clear ); 92 | 93 | } 94 | 95 | }; 96 | 97 | THREE.BloomPass.blurX = new THREE.Vector2( 0.001953125, 0.0 ); 98 | THREE.BloomPass.blurY = new THREE.Vector2( 0.0, 0.001953125 ); 99 | 100 | 101 | -------------------------------------------------------------------------------- /r48/js/postprocessing/DotScreenPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.DotScreenPass = function( center, angle, scale ) { 6 | 7 | var shader = THREE.ShaderExtras[ "dotscreen" ]; 8 | 9 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 10 | 11 | if ( center !== undefined ) 12 | this.uniforms[ "center" ].value.copy( center ); 13 | 14 | if ( angle !== undefined ) this.uniforms[ "angle"].value = angle; 15 | if ( scale !== undefined ) this.uniforms[ "scale"].value = scale; 16 | 17 | this.material = new THREE.ShaderMaterial( { 18 | 19 | uniforms: this.uniforms, 20 | vertexShader: shader.vertexShader, 21 | fragmentShader: shader.fragmentShader 22 | 23 | } ); 24 | 25 | this.enabled = true; 26 | this.renderToScreen = false; 27 | this.needsSwap = true; 28 | 29 | }; 30 | 31 | THREE.DotScreenPass.prototype = { 32 | 33 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 34 | 35 | this.uniforms[ "tDiffuse" ].texture = readBuffer; 36 | this.uniforms[ "tSize" ].value.set( readBuffer.width, readBuffer.height ); 37 | 38 | THREE.EffectComposer.quad.material = this.material; 39 | 40 | if ( this.renderToScreen ) { 41 | 42 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera ); 43 | 44 | } else { 45 | 46 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, writeBuffer, false ); 47 | 48 | } 49 | 50 | } 51 | 52 | }; 53 | -------------------------------------------------------------------------------- /r48/js/postprocessing/EffectComposer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.EffectComposer = function( renderer, renderTarget ) { 6 | 7 | this.renderer = renderer; 8 | 9 | this.renderTarget1 = renderTarget; 10 | 11 | if ( this.renderTarget1 === undefined ) { 12 | 13 | this.renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBufer: false }; 14 | this.renderTarget1 = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, this.renderTargetParameters ); 15 | 16 | } 17 | 18 | this.renderTarget2 = this.renderTarget1.clone(); 19 | 20 | this.writeBuffer = this.renderTarget1; 21 | this.readBuffer = this.renderTarget2; 22 | 23 | this.passes = []; 24 | 25 | this.copyPass = new THREE.ShaderPass( THREE.ShaderExtras[ "screen" ] ); 26 | 27 | }; 28 | 29 | THREE.EffectComposer.prototype = { 30 | 31 | swapBuffers: function() { 32 | 33 | var tmp = this.readBuffer; 34 | this.readBuffer = this.writeBuffer; 35 | this.writeBuffer = tmp; 36 | 37 | }, 38 | 39 | addPass: function ( pass ) { 40 | 41 | this.passes.push( pass ); 42 | 43 | }, 44 | 45 | render: function ( delta ) { 46 | 47 | this.writeBuffer = this.renderTarget1; 48 | this.readBuffer = this.renderTarget2; 49 | 50 | var maskActive = false; 51 | 52 | var pass, i, il = this.passes.length; 53 | 54 | for ( i = 0; i < il; i ++ ) { 55 | 56 | pass = this.passes[ i ]; 57 | 58 | if ( !pass.enabled ) continue; 59 | 60 | pass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive ); 61 | 62 | if ( pass.needsSwap ) { 63 | 64 | if ( maskActive ) { 65 | 66 | var context = this.renderer.context; 67 | 68 | context.stencilFunc( context.NOTEQUAL, 1, 0xffffffff ); 69 | 70 | this.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta ); 71 | 72 | context.stencilFunc( context.EQUAL, 1, 0xffffffff ); 73 | 74 | } 75 | 76 | this.swapBuffers(); 77 | 78 | } 79 | 80 | if ( pass instanceof THREE.MaskPass ) { 81 | 82 | maskActive = true; 83 | 84 | } else if ( pass instanceof THREE.ClearMaskPass ) { 85 | 86 | maskActive = false; 87 | 88 | } 89 | 90 | } 91 | 92 | }, 93 | 94 | reset: function ( renderTarget ) { 95 | 96 | this.renderTarget1 = renderTarget; 97 | 98 | if ( this.renderTarget1 === undefined ) { 99 | 100 | this.renderTarget1 = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, this.renderTargetParameters ); 101 | 102 | } 103 | 104 | this.renderTarget2 = this.renderTarget1.clone(); 105 | 106 | this.writeBuffer = this.renderTarget1; 107 | this.readBuffer = this.renderTarget2; 108 | 109 | THREE.EffectComposer.quad.scale.set( window.innerWidth, window.innerHeight, 1 ); 110 | 111 | THREE.EffectComposer.camera.left = window.innerWidth / - 2; 112 | THREE.EffectComposer.camera.right = window.innerWidth / 2; 113 | THREE.EffectComposer.camera.top = window.innerHeight / 2; 114 | THREE.EffectComposer.camera.bottom = window.innerHeight / - 2; 115 | 116 | THREE.EffectComposer.camera.updateProjectionMatrix(); 117 | 118 | } 119 | 120 | }; 121 | 122 | // shared ortho camera 123 | 124 | THREE.EffectComposer.camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, -10000, 10000 ); 125 | 126 | // shared fullscreen quad scene 127 | 128 | THREE.EffectComposer.geometry = new THREE.PlaneGeometry( 1, 1 ); 129 | 130 | THREE.EffectComposer.quad = new THREE.Mesh( THREE.EffectComposer.geometry, null ); 131 | THREE.EffectComposer.quad.position.z = -100; 132 | THREE.EffectComposer.quad.scale.set( window.innerWidth, window.innerHeight, 1 ); 133 | 134 | THREE.EffectComposer.scene = new THREE.Scene(); 135 | THREE.EffectComposer.scene.add( THREE.EffectComposer.quad ); 136 | THREE.EffectComposer.scene.add( THREE.EffectComposer.camera ); 137 | -------------------------------------------------------------------------------- /r48/js/postprocessing/FilmPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.FilmPass = function( noiseIntensity, scanlinesIntensity, scanlinesCount, grayscale ) { 6 | 7 | var shader = THREE.ShaderExtras[ "film" ]; 8 | 9 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 10 | 11 | this.material = new THREE.ShaderMaterial( { 12 | 13 | uniforms: this.uniforms, 14 | vertexShader: shader.vertexShader, 15 | fragmentShader: shader.fragmentShader 16 | 17 | } ); 18 | 19 | if ( grayscale !== undefined ) this.uniforms.grayscale.value = grayscale; 20 | if ( noiseIntensity !== undefined ) this.uniforms.nIntensity.value = noiseIntensity; 21 | if ( scanlinesIntensity !== undefined ) this.uniforms.sIntensity.value = scanlinesIntensity; 22 | if ( scanlinesCount !== undefined ) this.uniforms.sCount.value = scanlinesCount; 23 | 24 | this.enabled = true; 25 | this.renderToScreen = false; 26 | this.needsSwap = true; 27 | 28 | }; 29 | 30 | THREE.FilmPass.prototype = { 31 | 32 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 33 | 34 | this.uniforms[ "tDiffuse" ].texture = readBuffer; 35 | this.uniforms[ "time" ].value += delta; 36 | 37 | THREE.EffectComposer.quad.material = this.material; 38 | 39 | if ( this.renderToScreen ) { 40 | 41 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera ); 42 | 43 | } else { 44 | 45 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, writeBuffer, false ); 46 | 47 | } 48 | 49 | } 50 | 51 | }; 52 | -------------------------------------------------------------------------------- /r48/js/postprocessing/MaskPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.MaskPass = function ( scene, camera ) { 6 | 7 | this.scene = scene; 8 | this.camera = camera; 9 | 10 | this.enabled = true; 11 | this.clear = true; 12 | this.needsSwap = false; 13 | 14 | this.inverse = false; 15 | 16 | }; 17 | 18 | THREE.MaskPass.prototype = { 19 | 20 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 21 | 22 | var context = renderer.context; 23 | 24 | // don't update color or depth 25 | 26 | context.colorMask( false, false, false, false ); 27 | context.depthMask( false ); 28 | 29 | // set up stencil 30 | 31 | var writeValue, clearValue; 32 | 33 | if ( this.inverse ) { 34 | 35 | writeValue = 0; 36 | clearValue = 1; 37 | 38 | } else { 39 | 40 | writeValue = 1; 41 | clearValue = 0; 42 | 43 | } 44 | 45 | context.enable( context.STENCIL_TEST ); 46 | context.stencilOp( context.REPLACE, context.REPLACE, context.REPLACE ); 47 | context.stencilFunc( context.ALWAYS, writeValue, 0xffffffff ); 48 | context.clearStencil( clearValue ); 49 | 50 | // draw into the stencil buffer 51 | 52 | renderer.render( this.scene, this.camera, readBuffer, this.clear ); 53 | renderer.render( this.scene, this.camera, writeBuffer, this.clear ); 54 | 55 | // re-enable update of color and depth 56 | 57 | context.colorMask( true, true, true, true ); 58 | context.depthMask( true ); 59 | 60 | // only render where stencil is set to 1 61 | 62 | context.stencilFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1 63 | context.stencilOp( context.KEEP, context.KEEP, context.KEEP ); 64 | 65 | } 66 | 67 | }; 68 | 69 | 70 | THREE.ClearMaskPass = function () { 71 | 72 | this.enabled = true; 73 | 74 | }; 75 | 76 | THREE.ClearMaskPass.prototype = { 77 | 78 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 79 | 80 | var context = renderer.context; 81 | 82 | context.disable( context.STENCIL_TEST ); 83 | 84 | } 85 | 86 | }; 87 | -------------------------------------------------------------------------------- /r48/js/postprocessing/RenderPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.RenderPass = function ( scene, camera, overrideMaterial, clearColor, clearAlpha ) { 6 | 7 | this.scene = scene; 8 | this.camera = camera; 9 | 10 | this.overrideMaterial = overrideMaterial; 11 | 12 | this.clearColor = clearColor; 13 | this.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 1; 14 | 15 | this.oldClearColor = new THREE.Color(); 16 | this.oldClearAlpha = 1; 17 | 18 | this.enabled = true; 19 | this.clear = true; 20 | this.needsSwap = false; 21 | 22 | }; 23 | 24 | THREE.RenderPass.prototype = { 25 | 26 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 27 | 28 | this.scene.overrideMaterial = this.overrideMaterial; 29 | 30 | if ( this.clearColor ) { 31 | 32 | this.oldClearColor.copy( renderer.getClearColor() ); 33 | this.oldClearAlpha = renderer.getClearAlpha(); 34 | 35 | renderer.setClearColor( this.clearColor, this.clearAlpha ); 36 | 37 | } 38 | 39 | renderer.render( this.scene, this.camera, readBuffer, this.clear ); 40 | 41 | if ( this.clearColor ) { 42 | 43 | renderer.setClearColor( this.oldClearColor, this.oldClearAlpha ); 44 | 45 | } 46 | 47 | this.scene.overrideMaterial = null; 48 | 49 | } 50 | 51 | }; 52 | -------------------------------------------------------------------------------- /r48/js/postprocessing/SavePass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.SavePass = function( renderTarget ) { 6 | 7 | var shader = THREE.ShaderExtras[ "screen" ]; 8 | 9 | this.textureID = "tDiffuse"; 10 | 11 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 12 | 13 | this.material = new THREE.ShaderMaterial( { 14 | 15 | uniforms: this.uniforms, 16 | vertexShader: shader.vertexShader, 17 | fragmentShader: shader.fragmentShader 18 | 19 | } ); 20 | 21 | this.renderTarget = renderTarget; 22 | 23 | if ( this.renderTarget === undefined ) { 24 | 25 | this.renderTargetParameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBFormat, stencilBufer: false }; 26 | this.renderTarget = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight, this.renderTargetParameters ); 27 | 28 | } 29 | 30 | this.enabled = true; 31 | this.needsSwap = false; 32 | this.clear = false; 33 | 34 | }; 35 | 36 | THREE.SavePass.prototype = { 37 | 38 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 39 | 40 | if ( this.uniforms[ this.textureID ] ) { 41 | 42 | this.uniforms[ this.textureID ].texture = readBuffer; 43 | 44 | } 45 | 46 | THREE.EffectComposer.quad.material = this.material; 47 | 48 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, this.renderTarget, this.clear ); 49 | 50 | } 51 | 52 | }; 53 | -------------------------------------------------------------------------------- /r48/js/postprocessing/ShaderPass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.ShaderPass = function( shader, textureID ) { 6 | 7 | this.textureID = ( textureID !== undefined ) ? textureID : "tDiffuse"; 8 | 9 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 10 | 11 | this.material = new THREE.ShaderMaterial( { 12 | 13 | uniforms: this.uniforms, 14 | vertexShader: shader.vertexShader, 15 | fragmentShader: shader.fragmentShader 16 | 17 | } ); 18 | 19 | this.renderToScreen = false; 20 | 21 | this.enabled = true; 22 | this.needsSwap = true; 23 | this.clear = false; 24 | 25 | }; 26 | 27 | THREE.ShaderPass.prototype = { 28 | 29 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 30 | 31 | if ( this.uniforms[ this.textureID ] ) { 32 | 33 | this.uniforms[ this.textureID ].texture = readBuffer; 34 | 35 | } 36 | 37 | THREE.EffectComposer.quad.material = this.material; 38 | 39 | if ( this.renderToScreen ) { 40 | 41 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera ); 42 | 43 | } else { 44 | 45 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, writeBuffer, this.clear ); 46 | 47 | } 48 | 49 | } 50 | 51 | }; 52 | -------------------------------------------------------------------------------- /r48/js/postprocessing/TexturePass.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | */ 4 | 5 | THREE.TexturePass = function( texture, opacity ) { 6 | 7 | var shader = THREE.ShaderExtras[ "screen" ]; 8 | 9 | this.uniforms = THREE.UniformsUtils.clone( shader.uniforms ); 10 | 11 | this.uniforms[ "opacity" ].value = ( opacity !== undefined ) ? opacity : 1.0; 12 | this.uniforms[ "tDiffuse" ].texture = texture; 13 | 14 | this.material = new THREE.ShaderMaterial( { 15 | 16 | uniforms: this.uniforms, 17 | vertexShader: shader.vertexShader, 18 | fragmentShader: shader.fragmentShader 19 | 20 | } ); 21 | 22 | this.enabled = true; 23 | this.needsSwap = false; 24 | 25 | }; 26 | 27 | THREE.TexturePass.prototype = { 28 | 29 | render: function ( renderer, writeBuffer, readBuffer, delta ) { 30 | 31 | THREE.EffectComposer.quad.material = this.material; 32 | 33 | renderer.render( THREE.EffectComposer.scene, THREE.EffectComposer.camera, readBuffer ); 34 | 35 | } 36 | 37 | }; 38 | -------------------------------------------------------------------------------- /r48/tron/glow256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/glow256.png -------------------------------------------------------------------------------- /r48/tron/pixel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/pixel.png -------------------------------------------------------------------------------- /r48/tron/seq/glowseq_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/seq/glowseq_0.png -------------------------------------------------------------------------------- /r48/tron/seq/glowseq_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/seq/glowseq_1.png -------------------------------------------------------------------------------- /r48/tron/seq/glowseq_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/seq/glowseq_10.png -------------------------------------------------------------------------------- /r48/tron/seq/glowseq_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/seq/glowseq_11.png -------------------------------------------------------------------------------- /r48/tron/seq/glowseq_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/seq/glowseq_12.png -------------------------------------------------------------------------------- /r48/tron/seq/glowseq_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/seq/glowseq_13.png -------------------------------------------------------------------------------- /r48/tron/seq/glowseq_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/seq/glowseq_14.png -------------------------------------------------------------------------------- /r48/tron/seq/glowseq_15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/seq/glowseq_15.png -------------------------------------------------------------------------------- /r48/tron/seq/glowseq_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/seq/glowseq_16.png -------------------------------------------------------------------------------- /r48/tron/seq/glowseq_17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/seq/glowseq_17.png -------------------------------------------------------------------------------- /r48/tron/seq/glowseq_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/seq/glowseq_18.png -------------------------------------------------------------------------------- /r48/tron/seq/glowseq_19.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/seq/glowseq_19.png -------------------------------------------------------------------------------- /r48/tron/seq/glowseq_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/seq/glowseq_2.png -------------------------------------------------------------------------------- /r48/tron/seq/glowseq_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/seq/glowseq_3.png -------------------------------------------------------------------------------- /r48/tron/seq/glowseq_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/seq/glowseq_4.png -------------------------------------------------------------------------------- /r48/tron/seq/glowseq_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/seq/glowseq_5.png -------------------------------------------------------------------------------- /r48/tron/seq/glowseq_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/seq/glowseq_6.png -------------------------------------------------------------------------------- /r48/tron/seq/glowseq_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/seq/glowseq_7.png -------------------------------------------------------------------------------- /r48/tron/seq/glowseq_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/seq/glowseq_8.png -------------------------------------------------------------------------------- /r48/tron/seq/glowseq_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/seq/glowseq_9.png -------------------------------------------------------------------------------- /r48/tron/trondisk_diffuse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/trondisk_diffuse.jpg -------------------------------------------------------------------------------- /r48/tron/trondisk_glow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BKcore/Three.js-experiments-pool/855a3b2ed3bc63101157fc5f63b34af5ade53803/r48/tron/trondisk_glow.png -------------------------------------------------------------------------------- /r48/webgl_tron.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | three.js webgl - io - OBJ converter 5 | 6 | 7 | 21 | 22 | 23 | 24 |
25 |

Tron disk demo

26 |

Model by Thibaut Despoulain. 27 |

28 | 29 | 30 | 31 | 32 | 33 | 34 | 169 | 170 | 171 | 172 | -------------------------------------------------------------------------------- /r48/webgl_tron_glow.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | three.js webgl - io - OBJ converter 5 | 6 | 7 | 21 | 22 | 23 | 24 |
25 |

Tron disk demo

26 |

Model by Thibaut Despoulain. 27 |

28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 254 | 255 | 256 | 257 | -------------------------------------------------------------------------------- /r48/webgl_tron_glow_animated.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tron disk, animated selective glow (Three.js) - Thibaut Despoulain 5 | 6 | 7 | 28 | 29 | 30 | 31 |
32 |

Tron disk, animated selective glow (Three.js)

33 |

Model & render by Thibaut Despoulain. 34 |

35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 280 | 281 | 282 | 283 | -------------------------------------------------------------------------------- /r48/webgl_tron_glow_particles.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tron disk, selective glow, particles, icosahedrons (Three.js) - Thibaut Despoulain 5 | 6 | 7 | 28 | 29 | 30 | 31 |
32 |

Tron disk, selective glow, particles, icosahedrons (Three.js)

33 |

Model & render by Thibaut Despoulain. 34 |

35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 431 | 432 | 433 | 434 | -------------------------------------------------------------------------------- /r48/webgl_tron_godrays.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Tron disk, selective glow, particles, icosahedrons (Three.js) - Thibaut Despoulain 5 | 6 | 7 | 28 | 29 | 30 | 31 |
32 |

Model & render by Thibaut Despoulain, tutorial here. 33 |

Tron disk, Volumetric Light Approximation (Three.js)

34 |
35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 300 | 301 | 302 | 303 | --------------------------------------------------------------------------------