{"version":3,"sources":["webpack:///./src/js/utils/orbitControls.js","webpack:///./src/js/data/config.js","webpack:///./src/js/utils/detector.js","webpack:///./src/js/app/components/renderer.js","webpack:///./src/js/app/components/camera.js","webpack:///./src/js/app/components/light.js","webpack:///./src/js/app/components/controls.js","webpack:///./src/js/app/helpers/material.js","webpack:///./src/js/app/helpers/stats.js","webpack:///./src/js/app/helpers/geometry.js","webpack:///./src/js/utils/helpers.js","webpack:///./src/js/app/model/texture.js","webpack:///./src/js/app/helpers/meshHelper.js","webpack:///./src/js/app/model/model.js","webpack:///./src/js/utils/keyboard.js","webpack:///./src/js/app/managers/interaction.js","webpack:///./src/js/app/managers/datGUI.js","webpack:///./src/js/app/main.js","webpack:///./src/js/app.js"],"names":["module","exports","THREE","MOUSE","OrbitConstraint","object","this","target","Vector3","minDistance","maxDistance","Infinity","minZoom","maxZoom","minPolarAngle","maxPolarAngle","Math","PI","minAzimuthAngle","maxAzimuthAngle","enableDamping","dampingFactor","theta","phi","v","offset","quat","quatInverse","lastPosition","lastQuaternion","scope","EPS","phiDelta","thetaDelta","scale","panOffset","zoomChanged","getPolarAngle","getAzimuthalAngle","rotateLeft","angle","rotateUp","panLeft","distance","te","matrix","elements","set","multiplyScalar","add","panUp","pan","deltaX","deltaY","screenWidth","screenHeight","PerspectiveCamera","targetDistance","position","clone","sub","length","tan","fov","OrthographicCamera","right","left","top","bottom","console","warn","dollyIn","dollyScale","zoom","max","min","updateProjectionMatrix","dollyOut","update","Quaternion","setFromUnitVectors","up","inverse","copy","applyQuaternion","atan2","x","z","sqrt","y","radius","sin","cos","lookAt","distanceToSquared","dot","quaternion","OrbitControls","domElement","constraint","undefined","document","Object","defineProperty","get","enabled","center","enableZoom","zoomSpeed","enableRotate","rotateSpeed","enablePan","keyPanSpeed","autoRotate","autoRotateSpeed","enableKeys","keys","LEFT","UP","RIGHT","BOTTOM","mouseButtons","ORBIT","ZOOM","MIDDLE","PAN","rotateStart","Vector2","rotateEnd","rotateDelta","panStart","panEnd","panDelta","dollyStart","dollyEnd","dollyDelta","STATE","NONE","ROTATE","DOLLY","TOUCH_ROTATE","TOUCH_DOLLY","TOUCH_PAN","state","target0","position0","zoom0","changeEvent","type","startEvent","endEvent","element","body","clientWidth","clientHeight","getZoomScale","pow","onMouseDown","event","preventDefault","button","clientX","clientY","addEventListener","onMouseMove","onMouseUp","dispatchEvent","subVectors","removeEventListener","onMouseWheel","stopPropagation","delta","wheelDelta","detail","onKeyDown","keyCode","touchstart","touches","pageX","pageY","dx","dy","touchmove","touchend","contextmenu","reset","dispose","window","prototype","create","EventDispatcher","constructor","defineProperties","value","noZoom","noRotate","noPan","noKeys","staticMoving","dynamicDampingFactor","isDev","isShowingStats","isLoaded","isTweening","isRotating","isMouseMoving","isMouseOver","maxAnisotropy","dpr","easing","TWEEN","Easing","Quadratic","InOut","duration","model","path","texture","imageFiles","name","image","mesh","enableHelper","wireframe","translucent","material","color","emissive","fog","near","camera","far","aspect","posX","posY","posZ","controls","ambientLight","directionalLight","intensity","shadow","helperEnabled","bias","mapWidth","mapHeight","pointLight","hemiLight","groundColor","canvas","CanvasRenderingContext2D","webgl","createElement","WebGLRenderingContext","getContext","e","workers","Worker","fileapi","File","FileReader","FileList","Blob","getWebGLErrorMessage","id","style","fontFamily","fontSize","fontWeight","textAlign","background","padding","width","margin","innerHTML","join","addGetWebGLMessage","parameters","parent","appendChild","Renderer","scene","container","threeRenderer","antialias","setClearColor","setPixelRatio","devicePixelRatio","shadowMap","Config","getMaxAnisotropy","updateSize","setSize","offsetWidth","offsetHeight","render","Camera","renderer","height","threeCamera","Light","init","visible","castShadow","mapSize","directionalLightHelper","lightName","Controls","orbitControls","threeControls","Material","basic","side","standard","shading","roughness","metalness","wire","rS","bS","glS","tS","Geometry","geo","widthSegments","heightSegments","rotation","receiveShadow","Stats","start","tick","frame","end","BrowserStats","glStats","threeStats","rStats","CSSPath","userTimingAPI","values","caption","over","average","avgMs","fps","below","calls","raf","rstats","groups","fractions","base","steps","plugins","Helpers","fn","threshhold","last","deferTimer","context","now","Date","args","arguments","clearTimeout","setTimeout","apply","xhr","lengthComputable","percentComplete","loaded","total","log","round","error","replace","setHex","needsUpdate","geometry","vertexColors","verticesNeedUpdate","normalsNeedUpdate","colorsNeedUpdate","materialKey","textures","key","Texture","loader","promiseArray","setPath","forEach","imageFile","push","Promise","resolve","reject","load","anisotropy","modelOBJ","logProgress","Error","all","then","i","reason","MeshHelper","wireLine","depthTest","opacity","transparent","edges","edgesLine","Model","manager","obj","traverse","child","map","UV","logError","ALIAS","Keyboard","keyCodes","onKeyChange","onBlur","prop","keyDesc","split","pressed","indexOf","toUpperCase","charCodeAt","aliases","aliasKeys","shiftKey","ctrlKey","altKey","metaKey","Interaction","timeout","keyboard","throttle","onMouseLeave","onMouseOver","repeat","eventMatches","DatGUI","main","gui","dat","GUI","light","cameraFolder","addFolder","cameraFOVGui","onChange","onFinishChange","cameraAspectGui","addColor","cameraFogNearGui","density","controlsFolder","controlsAutoRotateSpeedGui","meshFolder","ambientLightFolder","directionalLightFolder","directionalLightIntensityGui","directionalLightPositionXGui","directionalLightPositionYGui","directionalLightPositionZGui","shadowFolder","shadowNearGui","shadowFarGui","shadowTopGui","shadowRightGui","shadowBottomGui","shadowLeftGui","shadowBiasGui","pointLightFolder","pointLightIntensityGui","pointLightDistanceGui","pointLightPositionXGui","pointLightPositionYGui","pointLightPositionZGui","hemiLightFolder","hemiLightIntensityGui","hemiLightPositionXGui","hemiLightPositionYGui","hemiLightPositionZGui","Main","clock","place","make","stats","setUp","onProgress","item","onLoad","querySelector","display","requestAnimationFrame","bind","Detector","getElementById"],"mappings":"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","file":"0.app.js","sourcesContent":["module.exports = function(THREE) {\n var MOUSE = THREE.MOUSE\n if (!MOUSE)\n MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 };\n\n /**\n * @author qiao / https://github.com/qiao\n * @author mrdoob / http://mrdoob.com\n * @author alteredq / http://alteredqualia.com/\n * @author WestLangley / http://github.com/WestLangley\n * @author erich666 / http://erichaines.com\n */\n /*global THREE, console */\n\n function OrbitConstraint ( object ) {\n\n this.object = object;\n\n // \"target\" sets the location of focus, where the object orbits around\n // and where it pans with respect to.\n this.target = new THREE.Vector3();\n\n // Limits to how far you can dolly in and out ( PerspectiveCamera only )\n this.minDistance = 0;\n this.maxDistance = Infinity;\n\n // Limits to how far you can zoom in and out ( OrthographicCamera only )\n this.minZoom = 0;\n this.maxZoom = Infinity;\n\n // How far you can orbit vertically, upper and lower limits.\n // Range is 0 to Math.PI radians.\n this.minPolarAngle = 0; // radians\n this.maxPolarAngle = Math.PI; // radians\n\n // How far you can orbit horizontally, upper and lower limits.\n // If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n this.minAzimuthAngle = - Infinity; // radians\n this.maxAzimuthAngle = Infinity; // radians\n\n // Set to true to enable damping (inertia)\n // If damping is enabled, you must call controls.update() in your animation loop\n this.enableDamping = false;\n this.dampingFactor = 0.25;\n\n ////////////\n // internals\n\n var scope = this;\n\n var EPS = 0.000001;\n\n // Current position in spherical coordinate system.\n var theta;\n var phi;\n\n // Pending changes\n var phiDelta = 0;\n var thetaDelta = 0;\n var scale = 1;\n var panOffset = new THREE.Vector3();\n var zoomChanged = false;\n\n // API\n\n this.getPolarAngle = function () {\n\n return phi;\n\n };\n\n this.getAzimuthalAngle = function () {\n\n return theta;\n\n };\n\n this.rotateLeft = function ( angle ) {\n\n thetaDelta -= angle;\n\n };\n\n this.rotateUp = function ( angle ) {\n\n phiDelta -= angle;\n\n };\n\n // pass in distance in world space to move left\n this.panLeft = function() {\n\n var v = new THREE.Vector3();\n\n return function panLeft ( distance ) {\n\n var te = this.object.matrix.elements;\n\n // get X column of matrix\n v.set( te[ 0 ], te[ 1 ], te[ 2 ] );\n v.multiplyScalar( - distance );\n\n panOffset.add( v );\n\n };\n\n }();\n\n // pass in distance in world space to move up\n this.panUp = function() {\n\n var v = new THREE.Vector3();\n\n return function panUp ( distance ) {\n\n var te = this.object.matrix.elements;\n\n // get Y column of matrix\n v.set( te[ 4 ], te[ 5 ], te[ 6 ] );\n v.multiplyScalar( distance );\n\n panOffset.add( v );\n\n };\n\n }();\n\n // pass in x,y of change desired in pixel space,\n // right and down are positive\n this.pan = function ( deltaX, deltaY, screenWidth, screenHeight ) {\n\n if ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n // perspective\n var position = scope.object.position;\n var offset = position.clone().sub( scope.target );\n var targetDistance = offset.length();\n\n // half of the fov is center to top of screen\n targetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n // we actually don't use screenWidth, since perspective camera is fixed to screen height\n scope.panLeft( 2 * deltaX * targetDistance / screenHeight );\n scope.panUp( 2 * deltaY * targetDistance / screenHeight );\n\n } else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n // orthographic\n scope.panLeft( deltaX * ( scope.object.right - scope.object.left ) / screenWidth );\n scope.panUp( deltaY * ( scope.object.top - scope.object.bottom ) / screenHeight );\n\n } else {\n\n // camera neither orthographic or perspective\n console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\n }\n\n };\n\n this.dollyIn = function ( dollyScale ) {\n\n if ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n scale /= dollyScale;\n\n } else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n scope.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom * dollyScale ) );\n scope.object.updateProjectionMatrix();\n zoomChanged = true;\n\n } else {\n\n console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\n }\n\n };\n\n this.dollyOut = function ( dollyScale ) {\n\n if ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n scale *= dollyScale;\n\n } else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n scope.object.zoom = Math.max( this.minZoom, Math.min( this.maxZoom, this.object.zoom / dollyScale ) );\n scope.object.updateProjectionMatrix();\n zoomChanged = true;\n\n } else {\n\n console.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\n }\n\n };\n\n this.update = function() {\n\n var offset = new THREE.Vector3();\n\n // so camera.up is the orbit axis\n var quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );\n var quatInverse = quat.clone().inverse();\n\n var lastPosition = new THREE.Vector3();\n var lastQuaternion = new THREE.Quaternion();\n\n return function () {\n\n var position = this.object.position;\n\n offset.copy( position ).sub( this.target );\n\n // rotate offset to \"y-axis-is-up\" space\n offset.applyQuaternion( quat );\n\n // angle from z-axis around y-axis\n\n theta = Math.atan2( offset.x, offset.z );\n\n // angle from y-axis\n\n phi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );\n\n theta += thetaDelta;\n phi += phiDelta;\n\n // restrict theta to be between desired limits\n theta = Math.max( this.minAzimuthAngle, Math.min( this.maxAzimuthAngle, theta ) );\n\n // restrict phi to be between desired limits\n phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, phi ) );\n\n // restrict phi to be betwee EPS and PI-EPS\n phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );\n\n var radius = offset.length() * scale;\n\n // restrict radius to be between desired limits\n radius = Math.max( this.minDistance, Math.min( this.maxDistance, radius ) );\n\n // move target to panned location\n this.target.add( panOffset );\n\n offset.x = radius * Math.sin( phi ) * Math.sin( theta );\n offset.y = radius * Math.cos( phi );\n offset.z = radius * Math.sin( phi ) * Math.cos( theta );\n\n // rotate offset back to \"camera-up-vector-is-up\" space\n offset.applyQuaternion( quatInverse );\n\n position.copy( this.target ).add( offset );\n\n this.object.lookAt( this.target );\n\n if ( this.enableDamping === true ) {\n\n thetaDelta *= ( 1 - this.dampingFactor );\n phiDelta *= ( 1 - this.dampingFactor );\n\n } else {\n\n thetaDelta = 0;\n phiDelta = 0;\n\n }\n\n scale = 1;\n panOffset.set( 0, 0, 0 );\n\n // update condition is:\n // min(camera displacement, camera rotation in radians)^2 > EPS\n // using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n if ( zoomChanged ||\n lastPosition.distanceToSquared( this.object.position ) > EPS ||\n 8 * ( 1 - lastQuaternion.dot( this.object.quaternion ) ) > EPS ) {\n\n lastPosition.copy( this.object.position );\n lastQuaternion.copy( this.object.quaternion );\n zoomChanged = false;\n\n return true;\n\n }\n\n return false;\n\n };\n\n }();\n\n };\n\n\n // This set of controls performs orbiting, dollying (zooming), and panning. It maintains\n // the \"up\" direction as +Y, unlike the TrackballControls. Touch on tablet and phones is\n // supported.\n //\n // Orbit - left mouse / touch: one finger move\n // Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n // Pan - right mouse, or arrow keys / touch: three finter swipe\n\n function OrbitControls ( object, domElement ) {\n\n var constraint = new OrbitConstraint( object );\n\n this.domElement = ( domElement !== undefined ) ? domElement : document;\n\n // API\n\n Object.defineProperty( this, 'constraint', {\n\n get: function() {\n\n return constraint;\n\n }\n\n } );\n\n this.getPolarAngle = function () {\n\n return constraint.getPolarAngle();\n\n };\n\n this.getAzimuthalAngle = function () {\n\n return constraint.getAzimuthalAngle();\n\n };\n\n // Set to false to disable this control\n this.enabled = true;\n\n // center is old, deprecated; use \"target\" instead\n this.center = this.target;\n\n // This option actually enables dollying in and out; left as \"zoom\" for\n // backwards compatibility.\n // Set to false to disable zooming\n this.enableZoom = true;\n this.zoomSpeed = 1.0;\n\n // Set to false to disable rotating\n this.enableRotate = true;\n this.rotateSpeed = 1.0;\n\n // Set to false to disable panning\n this.enablePan = true;\n this.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\n // Set to true to automatically rotate around the target\n // If auto-rotate is enabled, you must call controls.update() in your animation loop\n this.autoRotate = false;\n this.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\n // Set to false to disable use of the keys\n this.enableKeys = true;\n\n // The four arrow keys\n this.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\n // Mouse buttons\n this.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };\n\n ////////////\n // internals\n\n var scope = this;\n\n var rotateStart = new THREE.Vector2();\n var rotateEnd = new THREE.Vector2();\n var rotateDelta = new THREE.Vector2();\n\n var panStart = new THREE.Vector2();\n var panEnd = new THREE.Vector2();\n var panDelta = new THREE.Vector2();\n\n var dollyStart = new THREE.Vector2();\n var dollyEnd = new THREE.Vector2();\n var dollyDelta = new THREE.Vector2();\n\n var STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };\n\n var state = STATE.NONE;\n\n // for reset\n\n this.target0 = this.target.clone();\n this.position0 = this.object.position.clone();\n this.zoom0 = this.object.zoom;\n\n // events\n\n var changeEvent = { type: 'change' };\n var startEvent = { type: 'start' };\n var endEvent = { type: 'end' };\n\n // pass in x,y of change desired in pixel space,\n // right and down are positive\n function pan( deltaX, deltaY ) {\n\n var element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n constraint.pan( deltaX, deltaY, element.clientWidth, element.clientHeight );\n\n }\n\n this.update = function () {\n\n if ( this.autoRotate && state === STATE.NONE ) {\n\n constraint.rotateLeft( getAutoRotationAngle() );\n\n }\n\n if ( constraint.update() === true ) {\n\n this.dispatchEvent( changeEvent );\n\n }\n\n };\n\n this.reset = function () {\n\n state = STATE.NONE;\n\n this.target.copy( this.target0 );\n this.object.position.copy( this.position0 );\n this.object.zoom = this.zoom0;\n\n this.object.updateProjectionMatrix();\n this.dispatchEvent( changeEvent );\n\n this.update();\n\n };\n\n function getAutoRotationAngle() {\n\n return 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n }\n\n function getZoomScale() {\n\n return Math.pow( 0.95, scope.zoomSpeed );\n\n }\n\n function onMouseDown( event ) {\n\n if ( scope.enabled === false ) return;\n\n event.preventDefault();\n\n if ( event.button === scope.mouseButtons.ORBIT ) {\n\n if ( scope.enableRotate === false ) return;\n\n state = STATE.ROTATE;\n\n rotateStart.set( event.clientX, event.clientY );\n\n } else if ( event.button === scope.mouseButtons.ZOOM ) {\n\n if ( scope.enableZoom === false ) return;\n\n state = STATE.DOLLY;\n\n dollyStart.set( event.clientX, event.clientY );\n\n } else if ( event.button === scope.mouseButtons.PAN ) {\n\n if ( scope.enablePan === false ) return;\n\n state = STATE.PAN;\n\n panStart.set( event.clientX, event.clientY );\n\n }\n\n if ( state !== STATE.NONE ) {\n\n document.addEventListener( 'mousemove', onMouseMove, false );\n document.addEventListener( 'mouseup', onMouseUp, false );\n scope.dispatchEvent( startEvent );\n\n }\n\n }\n\n function onMouseMove( event ) {\n\n if ( scope.enabled === false ) return;\n\n event.preventDefault();\n\n var element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n if ( state === STATE.ROTATE ) {\n\n if ( scope.enableRotate === false ) return;\n\n rotateEnd.set( event.clientX, event.clientY );\n rotateDelta.subVectors( rotateEnd, rotateStart );\n\n // rotating across whole screen goes 360 degrees around\n constraint.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n // rotating up and down along whole screen attempts to go 360, but limited to 180\n constraint.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n rotateStart.copy( rotateEnd );\n\n } else if ( state === STATE.DOLLY ) {\n\n if ( scope.enableZoom === false ) return;\n\n dollyEnd.set( event.clientX, event.clientY );\n dollyDelta.subVectors( dollyEnd, dollyStart );\n\n if ( dollyDelta.y > 0 ) {\n\n constraint.dollyIn( getZoomScale() );\n\n } else if ( dollyDelta.y < 0 ) {\n\n constraint.dollyOut( getZoomScale() );\n\n }\n\n dollyStart.copy( dollyEnd );\n\n } else if ( state === STATE.PAN ) {\n\n if ( scope.enablePan === false ) return;\n\n panEnd.set( event.clientX, event.clientY );\n panDelta.subVectors( panEnd, panStart );\n\n pan( panDelta.x, panDelta.y );\n\n panStart.copy( panEnd );\n\n }\n\n if ( state !== STATE.NONE ) scope.update();\n\n }\n\n function onMouseUp( /* event */ ) {\n\n if ( scope.enabled === false ) return;\n\n document.removeEventListener( 'mousemove', onMouseMove, false );\n document.removeEventListener( 'mouseup', onMouseUp, false );\n scope.dispatchEvent( endEvent );\n state = STATE.NONE;\n\n }\n\n function onMouseWheel( event ) {\n\n if ( scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE ) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n var delta = 0;\n\n if ( event.wheelDelta !== undefined ) {\n\n // WebKit / Opera / Explorer 9\n\n delta = event.wheelDelta;\n\n } else if ( event.detail !== undefined ) {\n\n // Firefox\n\n delta = - event.detail;\n\n }\n\n if ( delta > 0 ) {\n\n constraint.dollyOut( getZoomScale() );\n\n } else if ( delta < 0 ) {\n\n constraint.dollyIn( getZoomScale() );\n\n }\n\n scope.update();\n scope.dispatchEvent( startEvent );\n scope.dispatchEvent( endEvent );\n\n }\n\n function onKeyDown( event ) {\n\n if ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;\n\n switch ( event.keyCode ) {\n\n case scope.keys.UP:\n pan( 0, scope.keyPanSpeed );\n scope.update();\n break;\n\n case scope.keys.BOTTOM:\n pan( 0, - scope.keyPanSpeed );\n scope.update();\n break;\n\n case scope.keys.LEFT:\n pan( scope.keyPanSpeed, 0 );\n scope.update();\n break;\n\n case scope.keys.RIGHT:\n pan( - scope.keyPanSpeed, 0 );\n scope.update();\n break;\n\n }\n\n }\n\n function touchstart( event ) {\n\n if ( scope.enabled === false ) return;\n\n switch ( event.touches.length ) {\n\n case 1:\t// one-fingered touch: rotate\n\n if ( scope.enableRotate === false ) return;\n\n state = STATE.TOUCH_ROTATE;\n\n rotateStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n break;\n\n case 2:\t// two-fingered touch: dolly\n\n if ( scope.enableZoom === false ) return;\n\n state = STATE.TOUCH_DOLLY;\n\n var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n var distance = Math.sqrt( dx * dx + dy * dy );\n dollyStart.set( 0, distance );\n break;\n\n case 3: // three-fingered touch: pan\n\n if ( scope.enablePan === false ) return;\n\n state = STATE.TOUCH_PAN;\n\n panStart.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n break;\n\n default:\n\n state = STATE.NONE;\n\n }\n\n if ( state !== STATE.NONE ) scope.dispatchEvent( startEvent );\n\n }\n\n function touchmove( event ) {\n\n if ( scope.enabled === false ) return;\n\n event.preventDefault();\n event.stopPropagation();\n\n var element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n switch ( event.touches.length ) {\n\n case 1: // one-fingered touch: rotate\n\n if ( scope.enableRotate === false ) return;\n if ( state !== STATE.TOUCH_ROTATE ) return;\n\n rotateEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n rotateDelta.subVectors( rotateEnd, rotateStart );\n\n // rotating across whole screen goes 360 degrees around\n constraint.rotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n // rotating up and down along whole screen attempts to go 360, but limited to 180\n constraint.rotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n rotateStart.copy( rotateEnd );\n\n scope.update();\n break;\n\n case 2: // two-fingered touch: dolly\n\n if ( scope.enableZoom === false ) return;\n if ( state !== STATE.TOUCH_DOLLY ) return;\n\n var dx = event.touches[ 0 ].pageX - event.touches[ 1 ].pageX;\n var dy = event.touches[ 0 ].pageY - event.touches[ 1 ].pageY;\n var distance = Math.sqrt( dx * dx + dy * dy );\n\n dollyEnd.set( 0, distance );\n dollyDelta.subVectors( dollyEnd, dollyStart );\n\n if ( dollyDelta.y > 0 ) {\n\n constraint.dollyOut( getZoomScale() );\n\n } else if ( dollyDelta.y < 0 ) {\n\n constraint.dollyIn( getZoomScale() );\n\n }\n\n dollyStart.copy( dollyEnd );\n\n scope.update();\n break;\n\n case 3: // three-fingered touch: pan\n\n if ( scope.enablePan === false ) return;\n if ( state !== STATE.TOUCH_PAN ) return;\n\n panEnd.set( event.touches[ 0 ].pageX, event.touches[ 0 ].pageY );\n panDelta.subVectors( panEnd, panStart );\n\n pan( panDelta.x, panDelta.y );\n\n panStart.copy( panEnd );\n\n scope.update();\n break;\n\n default:\n\n state = STATE.NONE;\n\n }\n\n }\n\n function touchend( /* event */ ) {\n\n if ( scope.enabled === false ) return;\n\n scope.dispatchEvent( endEvent );\n state = STATE.NONE;\n\n }\n\n function contextmenu( event ) {\n\n event.preventDefault();\n\n }\n\n this.dispose = function() {\n\n this.domElement.removeEventListener( 'contextmenu', contextmenu, false );\n this.domElement.removeEventListener( 'mousedown', onMouseDown, false );\n this.domElement.removeEventListener( 'mousewheel', onMouseWheel, false );\n this.domElement.removeEventListener( 'MozMousePixelScroll', onMouseWheel, false ); // firefox\n\n this.domElement.removeEventListener( 'touchstart', touchstart, false );\n this.domElement.removeEventListener( 'touchend', touchend, false );\n this.domElement.removeEventListener( 'touchmove', touchmove, false );\n\n document.removeEventListener( 'mousemove', onMouseMove, false );\n document.removeEventListener( 'mouseup', onMouseUp, false );\n\n window.removeEventListener( 'keydown', onKeyDown, false );\n\n }\n\n this.domElement.addEventListener( 'contextmenu', contextmenu, false );\n\n this.domElement.addEventListener( 'mousedown', onMouseDown, false );\n this.domElement.addEventListener( 'mousewheel', onMouseWheel, false );\n this.domElement.addEventListener( 'MozMousePixelScroll', onMouseWheel, false ); // firefox\n\n this.domElement.addEventListener( 'touchstart', touchstart, false );\n this.domElement.addEventListener( 'touchend', touchend, false );\n this.domElement.addEventListener( 'touchmove', touchmove, false );\n\n window.addEventListener( 'keydown', onKeyDown, false );\n\n // force an update at start\n this.update();\n\n };\n\n OrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );\n OrbitControls.prototype.constructor = OrbitControls;\n\n Object.defineProperties( OrbitControls.prototype, {\n\n object: {\n\n get: function () {\n\n return this.constraint.object;\n\n }\n\n },\n\n target: {\n\n get: function () {\n\n return this.constraint.target;\n\n },\n\n set: function ( value ) {\n\n console.warn( 'THREE.OrbitControls: target is now immutable. Use target.set() instead.' );\n this.constraint.target.copy( value );\n\n }\n\n },\n\n minDistance : {\n\n get: function () {\n\n return this.constraint.minDistance;\n\n },\n\n set: function ( value ) {\n\n this.constraint.minDistance = value;\n\n }\n\n },\n\n maxDistance : {\n\n get: function () {\n\n return this.constraint.maxDistance;\n\n },\n\n set: function ( value ) {\n\n this.constraint.maxDistance = value;\n\n }\n\n },\n\n minZoom : {\n\n get: function () {\n\n return this.constraint.minZoom;\n\n },\n\n set: function ( value ) {\n\n this.constraint.minZoom = value;\n\n }\n\n },\n\n maxZoom : {\n\n get: function () {\n\n return this.constraint.maxZoom;\n\n },\n\n set: function ( value ) {\n\n this.constraint.maxZoom = value;\n\n }\n\n },\n\n minPolarAngle : {\n\n get: function () {\n\n return this.constraint.minPolarAngle;\n\n },\n\n set: function ( value ) {\n\n this.constraint.minPolarAngle = value;\n\n }\n\n },\n\n maxPolarAngle : {\n\n get: function () {\n\n return this.constraint.maxPolarAngle;\n\n },\n\n set: function ( value ) {\n\n this.constraint.maxPolarAngle = value;\n\n }\n\n },\n\n minAzimuthAngle : {\n\n get: function () {\n\n return this.constraint.minAzimuthAngle;\n\n },\n\n set: function ( value ) {\n\n this.constraint.minAzimuthAngle = value;\n\n }\n\n },\n\n maxAzimuthAngle : {\n\n get: function () {\n\n return this.constraint.maxAzimuthAngle;\n\n },\n\n set: function ( value ) {\n\n this.constraint.maxAzimuthAngle = value;\n\n }\n\n },\n\n enableDamping : {\n\n get: function () {\n\n return this.constraint.enableDamping;\n\n },\n\n set: function ( value ) {\n\n this.constraint.enableDamping = value;\n\n }\n\n },\n\n dampingFactor : {\n\n get: function () {\n\n return this.constraint.dampingFactor;\n\n },\n\n set: function ( value ) {\n\n this.constraint.dampingFactor = value;\n\n }\n\n },\n\n // backward compatibility\n\n noZoom: {\n\n get: function () {\n\n console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n return ! this.enableZoom;\n\n },\n\n set: function ( value ) {\n\n console.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n this.enableZoom = ! value;\n\n }\n\n },\n\n noRotate: {\n\n get: function () {\n\n console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n return ! this.enableRotate;\n\n },\n\n set: function ( value ) {\n\n console.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n this.enableRotate = ! value;\n\n }\n\n },\n\n noPan: {\n\n get: function () {\n\n console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n return ! this.enablePan;\n\n },\n\n set: function ( value ) {\n\n console.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n this.enablePan = ! value;\n\n }\n\n },\n\n noKeys: {\n\n get: function () {\n\n console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n return ! this.enableKeys;\n\n },\n\n set: function ( value ) {\n\n console.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n this.enableKeys = ! value;\n\n }\n\n },\n\n staticMoving : {\n\n get: function () {\n\n console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n return ! this.constraint.enableDamping;\n\n },\n\n set: function ( value ) {\n\n console.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n this.constraint.enableDamping = ! value;\n\n }\n\n },\n\n dynamicDampingFactor : {\n\n get: function () {\n\n console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n return this.constraint.dampingFactor;\n\n },\n\n set: function ( value ) {\n\n console.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n this.constraint.dampingFactor = value;\n\n }\n\n }\n\n } );\n\n return OrbitControls;\n}\n","import TWEEN from 'tween.js';\r\n\r\n// This object contains the state of the app\r\nexport default {\r\n isDev: false,\r\n isShowingStats: true,\r\n isLoaded: false,\r\n isTweening: false,\r\n isRotating: true,\r\n isMouseMoving: false,\r\n isMouseOver: false,\r\n maxAnisotropy: 1,\r\n dpr: 1,\r\n easing: TWEEN.Easing.Quadratic.InOut,\r\n duration: 500,\r\n model: {\r\n path: './assets/models/Teapot.json',\r\n scale: 20\r\n },\r\n texture: {\r\n path: './assets/textures/',\r\n imageFiles: [\r\n {name: 'UV', image: 'UV_Grid_Sm.jpg'}\r\n ]\r\n },\r\n mesh: {\r\n enableHelper: false,\r\n wireframe: false,\r\n translucent: false,\r\n material: {\r\n color: 0xffffff,\r\n emissive: 0xffffff\r\n }\r\n },\r\n fog: {\r\n color: 0xffffff,\r\n near: 0.0008\r\n },\r\n camera: {\r\n fov: 40,\r\n near: 2,\r\n far: 1000,\r\n aspect: 1,\r\n posX: 0,\r\n posY: 30,\r\n posZ: 40\r\n },\r\n controls: {\r\n autoRotate: true,\r\n autoRotateSpeed: -0.5,\r\n rotateSpeed: 0.5,\r\n zoomSpeed: 0.8,\r\n minDistance: 200,\r\n maxDistance: 600,\r\n minPolarAngle: Math.PI / 5,\r\n maxPolarAngle: Math.PI / 2,\r\n minAzimuthAngle: -Infinity,\r\n maxAzimuthAngle: Infinity,\r\n enableDamping: true,\r\n dampingFactor: 0.5,\r\n enableZoom: true,\r\n target: {\r\n x: 0,\r\n y: 0,\r\n z: 0\r\n }\r\n },\r\n ambientLight: {\r\n enabled: true,\r\n color: 0x141414\r\n },\r\n directionalLight: {\r\n enabled: true,\r\n color: 0xf0f0f0,\r\n intensity: 0.4,\r\n x: -75,\r\n y: 280,\r\n z: 150\r\n },\r\n shadow: {\r\n enabled: true,\r\n helperEnabled: true,\r\n bias: 0,\r\n mapWidth: 2048,\r\n mapHeight: 2048,\r\n near: 250,\r\n far: 400,\r\n top: 100,\r\n right: 100,\r\n bottom: -100,\r\n left: -100\r\n },\r\n pointLight: {\r\n enabled: true,\r\n color: 0xffffff,\r\n intensity: 0.34,\r\n distance: 115,\r\n x: 0,\r\n y: 0,\r\n z: 0\r\n },\r\n hemiLight: {\r\n enabled: true,\r\n color: 0xc8c8c8,\r\n groundColor: 0xffffff,\r\n intensity: 0.55,\r\n x: 0,\r\n y: 0,\r\n z: 0\r\n }\r\n};\r\n","/**\r\n * @author alteredq / http://alteredqualia.com/\r\n * @author mr.doob / http://mrdoob.com/\r\n */\r\n\r\nexport default {\r\n canvas: !!window.CanvasRenderingContext2D,\r\n webgl: (function() {\r\n try {\r\n var canvas = document.createElement('canvas');\r\n\r\n return !!(window.WebGLRenderingContext && (canvas.getContext('webgl') || canvas.getContext('experimental-webgl')));\r\n } catch(e) {\r\n return false;\r\n }\r\n })(),\r\n\r\n workers: !!window.Worker,\r\n fileapi: window.File && window.FileReader && window.FileList && window.Blob,\r\n\r\n getWebGLErrorMessage: function() {\r\n var element = document.createElement('div');\r\n element.id = 'webgl-error-message';\r\n element.style.fontFamily = 'monospace';\r\n element.style.fontSize = '13px';\r\n element.style.fontWeight = 'normal';\r\n element.style.textAlign = 'center';\r\n element.style.background = '#fff';\r\n element.style.color = '#000';\r\n element.style.padding = '1.5em';\r\n element.style.width = '400px';\r\n element.style.margin = '5em auto 0';\r\n\r\n if(!this.webgl) {\r\n element.innerHTML = window.WebGLRenderingContext ? [\r\n 'Your graphics card does not seem to support WebGL.
',\r\n 'Find out how to get it here.'\r\n ].join('\\n') : [\r\n 'Your browser does not seem to support WebGL.
',\r\n 'Find out how to get it here.'\r\n ].join('\\n');\r\n }\r\n\r\n return element;\r\n },\r\n\r\n addGetWebGLMessage: function(parameters) {\r\n var parent, id, element;\r\n\r\n parameters = parameters || {};\r\n\r\n parent = parameters.parent !== undefined ? parameters.parent : document.body;\r\n id = parameters.id !== undefined ? parameters.id : 'oldie';\r\n\r\n element = this.getWebGLErrorMessage();\r\n element.id = id;\r\n\r\n parent.appendChild(element);\r\n }\r\n};\r\n","import * as THREE from 'three';\n\nimport Config from '../../data/config';\n\n// Main webGL renderer class\nexport default class Renderer {\n constructor(scene, container) {\n // Properties\n this.scene = scene;\n this.container = container;\n\n // Create WebGL renderer and set its antialias\n this.threeRenderer = new THREE.WebGLRenderer({antialias: true});\n\n // Set clear color to fog to enable fog or to hex color for no fog\n this.threeRenderer.setClearColor(scene.fog.color);\n this.threeRenderer.setPixelRatio(window.devicePixelRatio); // For retina\n\n // Appends canvas\n container.appendChild(this.threeRenderer.domElement);\n\n // Shadow map options\n this.threeRenderer.shadowMap.enabled = true;\n this.threeRenderer.shadowMap.type = THREE.PCFSoftShadowMap;\n\n // Get anisotropy for textures\n Config.maxAnisotropy = this.threeRenderer.getMaxAnisotropy();\n\n // Initial size update set to canvas container\n this.updateSize();\n\n // Listeners\n document.addEventListener('DOMContentLoaded', () => this.updateSize(), false);\n window.addEventListener('resize', () => this.updateSize(), false);\n }\n\n updateSize() {\n this.threeRenderer.setSize(this.container.offsetWidth, this.container.offsetHeight);\n }\n\n render(scene, camera) {\n // Renders scene to canvas target\n this.threeRenderer.render(scene, camera);\n }\n}\n","import * as THREE from 'three';\r\n\r\nimport Config from '../../data/config';\r\n\r\n// Class that creates and updates the main camera\r\nexport default class Camera {\r\n constructor(renderer) {\r\n const width = renderer.domElement.width;\r\n const height = renderer.domElement.height;\r\n\r\n // Create and position a Perspective Camera\r\n this.threeCamera = new THREE.PerspectiveCamera(Config.camera.fov, width / height, Config.camera.near, Config.camera.far);\r\n this.threeCamera.position.set(Config.camera.posX, Config.camera.posY, Config.camera.posZ);\r\n\r\n // Initial sizing\r\n this.updateSize(renderer);\r\n \r\n // Listeners\r\n window.addEventListener('resize', () => this.updateSize(renderer), false);\r\n }\r\n\r\n updateSize(renderer) {\r\n // Update camera aspect ratio with window aspect ratio\r\n this.threeCamera.aspect = renderer.domElement.width / renderer.domElement.height;\r\n\r\n // Always call updateProjectionMatrix on camera change\r\n this.threeCamera.updateProjectionMatrix();\r\n }\r\n}\r\n","import * as THREE from 'three';\n\nimport Config from '../../data/config';\n\n// Sets up and places all lights in scene\nexport default class Light {\n constructor(scene) {\n this.scene = scene;\n\n this.init();\n }\n\n init() {\n // Ambient\n this.ambientLight = new THREE.AmbientLight(Config.ambientLight.color);\n this.ambientLight.visible = Config.ambientLight.enabled;\n\n // Point light\n this.pointLight = new THREE.PointLight(Config.pointLight.color, Config.pointLight.intensity, Config.pointLight.distance);\n this.pointLight.position.set(Config.pointLight.x, Config.pointLight.y, Config.pointLight.z);\n this.pointLight.visible = Config.pointLight.enabled;\n\n // Directional light\n this.directionalLight = new THREE.DirectionalLight(Config.directionalLight.color, Config.directionalLight.intensity);\n this.directionalLight.position.set(Config.directionalLight.x, Config.directionalLight.y, Config.directionalLight.z);\n this.directionalLight.visible = Config.directionalLight.enabled;\n\n // Shadow map\n this.directionalLight.castShadow = Config.shadow.enabled;\n this.directionalLight.shadow.bias = Config.shadow.bias;\n this.directionalLight.shadow.camera.near = Config.shadow.near;\n this.directionalLight.shadow.camera.far = Config.shadow.far;\n this.directionalLight.shadow.camera.left = Config.shadow.left;\n this.directionalLight.shadow.camera.right = Config.shadow.right;\n this.directionalLight.shadow.camera.top = Config.shadow.top;\n this.directionalLight.shadow.camera.bottom = Config.shadow.bottom;\n this.directionalLight.shadow.mapSize.width = Config.shadow.mapWidth;\n this.directionalLight.shadow.mapSize.height = Config.shadow.mapHeight;\n\n // Shadow camera helper\n this.directionalLightHelper = new THREE.CameraHelper(this.directionalLight.shadow.camera);\n this.directionalLightHelper.visible = Config.shadow.helperEnabled;\n\n // Hemisphere light\n this.hemiLight = new THREE.HemisphereLight(Config.hemiLight.color, Config.hemiLight.groundColor, Config.hemiLight.intensity);\n this.hemiLight.position.set(Config.hemiLight.x, Config.hemiLight.y, Config.hemiLight.z);\n this.hemiLight.visible = Config.hemiLight.enabled;\n }\n\n place(lightName) {\n switch(lightName) {\n case 'ambient':\n this.scene.add(this.ambientLight);\n break;\n\n case 'directional':\n this.scene.add(this.directionalLight);\n this.scene.add(this.directionalLightHelper);\n break;\n\n case 'point':\n this.scene.add(this.pointLight);\n break;\n\n case 'hemi':\n this.scene.add(this.hemiLight);\n break;\n }\n }\n}\n","import * as THREE from 'three';\n\nimport OrbitControls from '../../utils/orbitControls';\nimport Config from '../../data/config';\n\n// Controls based on orbit controls\nexport default class Controls {\n constructor(camera, container) {\n // Orbit controls first needs to pass in THREE to constructor\n const orbitControls = new OrbitControls(THREE);\n this.threeControls = new orbitControls(camera, container);\n\n this.init();\n }\n\n init() {\n this.threeControls.target.set(Config.controls.target.x, Config.controls.target.y, Config.controls.target.z);\n this.threeControls.autoRotate = Config.controls.autoRotate;\n this.threeControls.autoRotateSpeed = Config.controls.autoRotateSpeed;\n this.threeControls.rotateSpeed = Config.controls.rotateSpeed;\n this.threeControls.zoomSpeed = Config.controls.zoomSpeed;\n this.threeControls.minDistance = Config.controls.minDistance;\n this.threeControls.maxDistance = Config.controls.maxDistance;\n this.threeControls.minPolarAngle = Config.controls.minPolarAngle;\n this.threeControls.maxPolarAngle = Config.controls.maxPolarAngle;\n this.threeControls.enableDamping = Config.controls.enableDamping;\n this.threeControls.enableZoom = Config.controls.enableZoom;\n this.threeControls.dampingFactor = Config.controls.dampingFactor;\n }\n}\n","import * as THREE from 'three';\n\nimport Config from '../../data/config';\n\n// USe this class as a helper to set up some default materials\nexport default class Material {\n constructor(color) {\n this.basic = new THREE.MeshBasicMaterial({\n color,\n side: THREE.DoubleSide\n });\n\n this.standard = new THREE.MeshStandardMaterial({\n color,\n shading: THREE.FlatShading,\n roughness: 1,\n metalness: 0,\n side: THREE.DoubleSide\n });\n\n this.wire = new THREE.MeshBasicMaterial({wireframe: true});\n }\n}\n\n","// Local vars for rStats\r\nlet rS, bS, glS, tS;\r\n\r\nexport default class Stats {\r\n constructor(renderer) {\r\n this.renderer = renderer;\r\n }\r\n\r\n setUp() {\r\n bS = new BrowserStats();\r\n glS = new glStats();\r\n tS = new threeStats(this.renderer.threeRenderer);\r\n\r\n rS = new rStats({\r\n CSSPath: './css/',\r\n userTimingAPI: true,\r\n values: {\r\n frame: { caption: 'Total frame time (ms)', over: 16, average: true, avgMs: 100 },\r\n fps: { caption: 'Framerate (FPS)', below: 30 },\r\n calls: { caption: 'Calls (three.js)', over: 3000 },\r\n raf: { caption: 'Time since last rAF (ms)', average: true, avgMs: 100 },\r\n rstats: { caption: 'rStats update (ms)', average: true, avgMs: 100 },\r\n texture: { caption: 'GenTex', average: true, avgMs: 100 }\r\n },\r\n groups: [\r\n { caption: 'Framerate', values: ['fps', 'raf'] },\r\n { caption: 'Frame Budget', values: ['frame', 'texture', 'setup', 'render'] }\r\n ],\r\n fractions: [\r\n { base: 'frame', steps: ['texture', 'setup', 'render'] }\r\n ],\r\n plugins: [bS, tS, glS]\r\n });\r\n };\r\n\r\n static start() {\r\n rS('frame').start();\r\n glS.start();\r\n\r\n rS('rAF').tick();\r\n rS('FPS').frame();\r\n\r\n rS('render').start();\r\n };\r\n\r\n static end() {\r\n rS('render').end(); // render finished\r\n rS('frame').end(); // frame finished\r\n\r\n // Local rStats update\r\n rS('rStats').start();\r\n rS().update();\r\n rS('rStats').end();\r\n };\r\n}\r\n","import * as THREE from 'three';\n\nimport Material from './material';\n\nimport Config from '../../data/config';\n\n// This helper class can be used to create and then place geometry in the scene\nexport default class Geometry {\n constructor(scene) {\n this.scene = scene;\n this.geo = null;\n }\n\n make(type) {\n if(type === 'plane') {\n return (width, height, widthSegments = 1, heightSegments = 1) => {\n this.geo = new THREE.PlaneGeometry(width, height, widthSegments, heightSegments);\n };\n }\n\n if(type === 'sphere') {\n return (radius, widthSegments = 32, heightSegments = 32) => {\n this.geo = new THREE.SphereGeometry(radius, widthSegments, heightSegments);\n };\n }\n }\n\n place(position, rotation) {\n const material = new Material(0xeeeeee).standard;\n const mesh = new THREE.Mesh(this.geo, material);\n\n // Use ES6 spread to set position and rotation from passed in array\n mesh.position.set(...position);\n mesh.rotation.set(...rotation);\n\n if(Config.shadow.enabled) {\n mesh.receiveShadow = true;\n }\n\n this.scene.add(mesh);\n }\n}\n","// Provides simple static functions that are used multiple times in the app\nexport default class Helpers {\n static throttle(fn, threshhold, scope) {\n threshhold || (threshhold = 250);\n let last, deferTimer;\n\n return function() {\n const context = scope || this;\n\n const now = +new Date,\n args = arguments;\n\n if(last && now < last + threshhold) {\n clearTimeout(deferTimer);\n deferTimer = setTimeout(function() {\n last = now;\n fn.apply(context, args);\n }, threshhold);\n }\n else {\n last = now;\n fn.apply(context, args);\n }\n };\n }\n\n static logProgress() {\n return function(xhr) {\n if(xhr.lengthComputable) {\n const percentComplete = xhr.loaded / xhr.total * 100;\n\n console.log(Math.round(percentComplete, 2) + '% downloaded');\n }\n }\n }\n\n static logError() {\n return function(xhr) {\n console.error(xhr);\n }\n }\n\n static handleColorChange(color) {\n return (value) => {\n if(typeof value === 'string') {\n value = value.replace('#', '0x');\n }\n\n color.setHex(value);\n };\n }\n\n static update(mesh) {\n this.needsUpdate(mesh.material, mesh.geometry);\n }\n\n static needsUpdate(material, geometry) {\n return function() {\n material.shading = +material.shading; //Ensure number\n material.vertexColors = +material.vertexColors; //Ensure number\n material.side = +material.side; //Ensure number\n material.needsUpdate = true;\n geometry.verticesNeedUpdate = true;\n geometry.normalsNeedUpdate = true;\n geometry.colorsNeedUpdate = true;\n };\n }\n\n static updateTexture(material, materialKey, textures) {\n return function(key) {\n material[materialKey] = textures[key];\n material.needsUpdate = true;\n };\n }\n}\n","import * as THREE from 'three';\n// Promise polyfill for IE\nimport { Promise } from 'es6-promise';\n\nimport Helpers from '../../utils/helpers';\nimport Config from '../../data/config';\n\n// This class preloads all textures in the imageFiles array in the Config via ES6 Promises.\n// Once all textures are done loading the model itself will be loaded after the Promise .then() callback.\n// Using promises to preload textures prevents issues when applying textures to materials\n// before the textures have loaded.\nexport default class Texture {\n constructor() {\n // Prop that will contain all loaded textures\n this.textures = {};\n }\n\n load() {\n const loader = new THREE.TextureLoader();\n const maxAnisotropy = Config.maxAnisotropy;\n const imageFiles = Config.texture.imageFiles;\n const promiseArray = [];\n\n loader.setPath(Config.texture.path);\n\n imageFiles.forEach(imageFile => {\n // Add an individual Promise for each image in array\n promiseArray.push(new Promise((resolve, reject) => {\n // Each Promise will attempt to load the image file\n loader.load(imageFile.image,\n // This gets called on load with the loaded texture\n texture => {\n texture.anisotropy = maxAnisotropy;\n\n // Resolve Promise with object of texture if it is instance of THREE.Texture\n const modelOBJ = {};\n modelOBJ[imageFile.name] = texture;\n if(modelOBJ[imageFile.name] instanceof THREE.Texture)\n resolve(modelOBJ);\n },\n Helpers.logProgress(),\n xhr => reject(new Error(xhr + 'An error occurred loading while loading ' + imageFile.image))\n )\n }));\n });\n\n // Iterate through all Promises in array and return another Promise when all have resolved or console log reason when any reject\n return Promise.all(promiseArray).then(textures => {\n // Set the textures prop object to have name be the resolved texture\n for(let i = 0; i < textures.length; i++) {\n this.textures[Object.keys(textures[i])[0]] = textures[i][Object.keys(textures[i])[0]];\n }\n }, reason => console.log(reason));\n }\n}\n","import * as THREE from 'three';\n\n// Simple mesh helper that shows edges, wireframes, and face and vertex normals\nexport default class MeshHelper {\n constructor(scene, mesh) {\n const wireframe = new THREE.WireframeGeometry(mesh.geometry);\n const wireLine = new THREE.LineSegments(wireframe);\n wireLine.material.depthTest = false;\n wireLine.material.opacity = 0.25;\n wireLine.material.transparent = true;\n mesh.add(wireLine);\n\n const edges = new THREE.EdgesGeometry(mesh.geometry);\n const edgesLine = new THREE.LineSegments(edges);\n edgesLine.material.depthTest = false;\n edgesLine.material.opacity = 0.25;\n edgesLine.material.transparent = true;\n mesh.add(edgesLine);\n\n scene.add(new THREE.BoxHelper(mesh));\n scene.add(new THREE.FaceNormalsHelper(mesh, 2));\n scene.add(new THREE.VertexNormalsHelper(mesh, 2));\n }\n}\n","import * as THREE from 'three';\r\n\r\nimport Material from '../helpers/material';\r\nimport MeshHelper from '../helpers/meshHelper';\r\nimport Helpers from '../../utils/helpers';\r\nimport Config from '../../data/config';\r\n\r\n// Loads in a single object from the config file\r\nexport default class Model {\r\n constructor(scene, manager, textures) {\r\n this.scene = scene;\r\n this.textures = textures;\r\n\r\n // Manager is passed in to loader to determine when loading done in main\r\n this.loader = new THREE.ObjectLoader(manager);\r\n this.obj = null;\r\n }\r\n\r\n load() {\r\n // Load model with ObjectLoader\r\n this.loader.load(\r\n Config.model.path,\r\n obj => {\r\n obj.traverse(child => {\r\n if(child instanceof THREE.Mesh) {\r\n // Create material for mesh and set its map to texture by name from preloaded textures\r\n const material = new Material(0xffffff).standard;\r\n material.map = this.textures.UV;\r\n child.material = material;\r\n\r\n // Set to cast and receive shadow if enabled\r\n if(Config.shadow.enabled) {\r\n child.receiveShadow = true;\r\n child.castShadow = true;\r\n }\r\n }\r\n });\r\n\r\n // Add mesh helper if Dev\r\n if(Config.isDev && Config.mesh.enableHelper) {\r\n new MeshHelper(this.scene, obj);\r\n }\r\n\r\n // Set prop to obj so it can be accessed from outside the class\r\n this.obj = obj;\r\n\r\n obj.scale.multiplyScalar(Config.model.scale);\r\n this.scene.add(obj);\r\n },\r\n Helpers.logProgress(),\r\n Helpers.logError()\r\n );\r\n }\r\n}\r\n","const ALIAS = {\r\n 'left'\t\t: 37,\r\n 'up'\t\t : 38,\r\n 'right'\t\t: 39,\r\n 'down'\t\t: 40,\r\n 'space'\t\t: 32,\r\n 'tab'\t\t : 9,\r\n 'escape'\t: 27\r\n};\r\n\r\nexport default class Keyboard {\r\n constructor(domElement) {\r\n this.domElement = domElement || document;\r\n this.keyCodes = {};\r\n\r\n // bind keyEvents\r\n this.domElement.addEventListener('keydown', (event) => this.onKeyChange(event), false);\r\n this.domElement.addEventListener('keyup', (event) => this.onKeyChange(event), false);\r\n\r\n // bind window blur\r\n window.addEventListener('blur', () => this.onBlur, false);\r\n }\r\n\r\n destroy() {\r\n this.domElement.removeEventListener('keydown', (event) => this.onKeyChange(event), false);\r\n this.domElement.removeEventListener('keyup', (event) => this.onKeyChange(event), false);\r\n\r\n // unbind window blur event\r\n window.removeEventListener('blur', () => this.onBlur, false);\r\n }\r\n\r\n onBlur() {\r\n for(const prop in this.keyCodes)\r\n this.keyCodes[prop] = false;\r\n }\r\n\r\n onKeyChange(event) {\r\n // log to debug\r\n //console.log('onKeyChange', event, event.keyCode, event.shiftKey, event.ctrlKey, event.altKey, event.metaKey)\r\n\r\n // update this.keyCodes\r\n const keyCode = event.keyCode;\r\n this.keyCodes[keyCode] = event.type === 'keydown';\r\n }\r\n\r\n pressed(keyDesc) {\r\n const keys = keyDesc.split('+');\r\n for(let i = 0; i < keys.length; i++) {\r\n const key = keys[i];\r\n let pressed = false;\r\n if(Object.keys(ALIAS).indexOf(key) != -1) {\r\n pressed = this.keyCodes[ALIAS[key]];\r\n } else {\r\n pressed = this.keyCodes[key.toUpperCase().charCodeAt(0)];\r\n }\r\n if(!pressed)\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n eventMatches(event, keyDesc) {\r\n const aliases = ALIAS;\r\n const aliasKeys = Object.keys(aliases);\r\n const keys = keyDesc.split('+');\r\n // log to debug\r\n // console.log('eventMatches', event, event.keyCode, event.shiftKey, event.ctrlKey, event.altKey, event.metaKey)\r\n for(let i = 0; i < keys.length; i++) {\r\n const key = keys[i];\r\n let pressed = false;\r\n if(key === 'shift') {\r\n pressed = event.shiftKey ? true : false;\r\n } else if(key === 'ctrl') {\r\n pressed = event.ctrlKey ? true : false;\r\n } else if(key === 'alt') {\r\n pressed = event.altKey ? true : false;\r\n } else if(key === 'meta') {\r\n pressed = event.metaKey ? true : false;\r\n } else if(aliasKeys.indexOf(key) !== -1) {\r\n pressed = event.keyCode === aliases[key];\r\n } else if(event.keyCode === key.toUpperCase().charCodeAt(0)) {\r\n pressed = true;\r\n }\r\n if(!pressed)\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n}\r\n","import Keyboard from '../../utils/keyboard';\nimport Helpers from '../../utils/helpers';\nimport Config from '../../data/config';\n\n// Manages all input interactions\nexport default class Interaction {\n constructor(renderer, scene, camera, controls) {\n // Properties\n this.renderer = renderer;\n this.scene = scene;\n this.camera = camera;\n this.controls = controls;\n\n this.timeout = null;\n\n // Instantiate keyboard helper\n this.keyboard = new Keyboard();\n\n // Listeners\n // Mouse events\n this.renderer.domElement.addEventListener('mousemove', (event) => Helpers.throttle(this.onMouseMove(event), 250), false);\n this.renderer.domElement.addEventListener('mouseleave', (event) => this.onMouseLeave(event), false);\n this.renderer.domElement.addEventListener('mouseover', (event) => this.onMouseOver(event), false);\n\n // Keyboard events\n this.keyboard.domElement.addEventListener('keydown', (event) => {\n // Only once\n if(event.repeat) {\n return;\n }\n\n if(this.keyboard.eventMatches(event, 'escape')) {\n console.log('Escape pressed');\n }\n });\n }\n\n onMouseOver(event) {\n event.preventDefault();\n\n Config.isMouseOver = true;\n }\n\n onMouseLeave(event) {\n event.preventDefault();\n\n Config.isMouseOver = false;\n }\n\n onMouseMove(event) {\n event.preventDefault();\n\n clearTimeout(this.timeout);\n\n this.timeout = setTimeout(function() {\n Config.isMouseMoving = false;\n }, 200);\n\n Config.isMouseMoving = true;\n }\n}\n","import Config from '../../data/config';\n\n// Manages all dat.GUI interactions\nexport default class DatGUI {\n constructor(main, mesh) {\n const gui = new dat.GUI();\n\n this.camera = main.camera.threeCamera;\n this.controls = main.controls.threeControls;\n this.light = main.light;\n\n /* Global */\n //gui.close();\n\n /* Camera */\n const cameraFolder = gui.addFolder('Camera');\n const cameraFOVGui = cameraFolder.add(Config.camera, 'fov', 0, 180).name('Camera FOV');\n cameraFOVGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.camera.fov = value;\n });\n cameraFOVGui.onFinishChange(() => {\n this.camera.updateProjectionMatrix();\n\n this.controls.enableRotate = true;\n });\n const cameraAspectGui = cameraFolder.add(Config.camera, 'aspect', 0, 4).name('Camera Aspect');\n cameraAspectGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.camera.aspect = value;\n });\n cameraAspectGui.onFinishChange(() => {\n this.camera.updateProjectionMatrix();\n\n this.controls.enableRotate = true;\n });\n const cameraFogColorGui = cameraFolder.addColor(Config.fog, 'color').name('Fog Color');\n cameraFogColorGui.onChange((value) => {\n main.scene.fog.color.setHex(value);\n });\n const cameraFogNearGui = cameraFolder.add(Config.fog, 'near', 0.000, 0.010).name('Fog Near');\n cameraFogNearGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n main.scene.fog.density = value;\n });\n cameraFogNearGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n });\n\n\n /* Controls */\n const controlsFolder = gui.addFolder('Controls');\n controlsFolder.add(Config.controls, 'autoRotate').name('Auto Rotate').onChange((value) => {\n this.controls.autoRotate = value;\n });\n const controlsAutoRotateSpeedGui = controlsFolder.add(Config.controls, 'autoRotateSpeed', -1, 1).name('Rotation Speed');\n controlsAutoRotateSpeedGui.onChange((value) => {\n this.controls.enableRotate = false;\n this.controls.autoRotateSpeed = value;\n });\n controlsAutoRotateSpeedGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n });\n\n\n /* Mesh */\n const meshFolder = gui.addFolder('Mesh');\n meshFolder.add(Config.mesh, 'translucent', true).name('Translucent').onChange((value) => {\n if(value) {\n mesh.material.transparent = true;\n mesh.material.opacity = 0.5;\n } else {\n mesh.material.opacity = 1.0;\n }\n });\n meshFolder.add(Config.mesh, 'wireframe', true).name('Wireframe').onChange((value) => {\n mesh.material.wireframe = value;\n });\n\n\n /* Lights */\n // Ambient Light\n const ambientLightFolder = gui.addFolder('Ambient Light');\n ambientLightFolder.add(Config.ambientLight, 'enabled').name('Enabled').onChange((value) => {\n this.light.ambientLight.visible = value;\n });\n ambientLightFolder.addColor(Config.ambientLight, 'color').name('Color').onChange((value) => {\n this.light.ambientLight.color.setHex(value);\n });\n\n\n // Directional Light\n const directionalLightFolder = gui.addFolder('Directional Light');\n directionalLightFolder.add(Config.directionalLight, 'enabled').name('Enabled').onChange((value) => {\n this.light.directionalLight.visible = value;\n });\n directionalLightFolder.addColor(Config.directionalLight, 'color').name('Color').onChange((value) => {\n this.light.directionalLight.color.setHex(value);\n });\n const directionalLightIntensityGui = directionalLightFolder.add(Config.directionalLight, 'intensity', 0, 2).name('Intensity');\n directionalLightIntensityGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.light.directionalLight.intensity = value;\n });\n directionalLightIntensityGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n });\n const directionalLightPositionXGui = directionalLightFolder.add(Config.directionalLight, 'x', -1000, 1000).name('Position X');\n directionalLightPositionXGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.light.directionalLight.position.x = value;\n });\n directionalLightPositionXGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n });\n const directionalLightPositionYGui = directionalLightFolder.add(Config.directionalLight, 'y', -1000, 1000).name('Position Y');\n directionalLightPositionYGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.light.directionalLight.position.y = value;\n });\n directionalLightPositionYGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n });\n const directionalLightPositionZGui = directionalLightFolder.add(Config.directionalLight, 'z', -1000, 1000).name('Position Z');\n directionalLightPositionZGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.light.directionalLight.position.z = value;\n });\n directionalLightPositionZGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n });\n\n // Shadow Map\n const shadowFolder = gui.addFolder('Shadow Map');\n shadowFolder.add(Config.shadow, 'enabled').name('Enabled').onChange((value) => {\n this.light.directionalLight.castShadow = value;\n });\n shadowFolder.add(Config.shadow, 'helperEnabled').name('Helper Enabled').onChange((value) => {\n this.light.directionalLightHelper.visible = value;\n });\n const shadowNearGui = shadowFolder.add(Config.shadow, 'near', 0, 400).name('Near');\n shadowNearGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.light.directionalLight.shadow.camera.near = value;\n });\n shadowNearGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n this.light.directionalLight.shadow.map.dispose();\n this.light.directionalLight.shadow.map = null;\n this.light.directionalLightHelper.update();\n });\n const shadowFarGui = shadowFolder.add(Config.shadow, 'far', 0, 1200).name('Far');\n shadowFarGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.light.directionalLight.shadow.camera.far = value;\n });\n shadowFarGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n this.light.directionalLight.shadow.map.dispose();\n this.light.directionalLight.shadow.map = null;\n this.light.directionalLightHelper.update();\n });\n const shadowTopGui = shadowFolder.add(Config.shadow, 'top', -400, 400).name('Top');\n shadowTopGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.light.directionalLight.shadow.camera.top = value;\n });\n shadowTopGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n this.light.directionalLight.shadow.map.dispose();\n this.light.directionalLight.shadow.map = null;\n this.light.directionalLightHelper.update();\n });\n const shadowRightGui = shadowFolder.add(Config.shadow, 'right', -400, 400).name('Right');\n shadowRightGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.light.directionalLight.shadow.camera.right = value;\n });\n shadowRightGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n this.light.directionalLight.shadow.map.dispose();\n this.light.directionalLight.shadow.map = null;\n this.light.directionalLightHelper.update();\n });\n const shadowBottomGui = shadowFolder.add(Config.shadow, 'bottom', -400, 400).name('Bottom');\n shadowBottomGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.light.directionalLight.shadow.camera.bottom = value;\n });\n shadowBottomGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n this.light.directionalLight.shadow.map.dispose();\n this.light.directionalLight.shadow.map = null;\n this.light.directionalLightHelper.update();\n });\n const shadowLeftGui = shadowFolder.add(Config.shadow, 'left', -400, 400).name('Left');\n shadowLeftGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.light.directionalLight.shadow.camera.left = value;\n });\n shadowLeftGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n this.light.directionalLight.shadow.map.dispose();\n this.light.directionalLight.shadow.map = null;\n this.light.directionalLightHelper.update();\n });\n const shadowBiasGui = shadowFolder.add(Config.shadow, 'bias', -0.000010, 1).name('Bias');\n shadowBiasGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.light.directionalLight.shadow.bias = value;\n });\n shadowBiasGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n this.light.directionalLight.shadow.map.dispose();\n this.light.directionalLight.shadow.map = null;\n this.light.directionalLightHelper.update();\n });\n\n\n // Point Light\n const pointLightFolder = gui.addFolder('Point Light');\n pointLightFolder.add(Config.pointLight, 'enabled').name('Enabled').onChange((value) => {\n this.light.pointLight.visible = value;\n });\n pointLightFolder.addColor(Config.pointLight, 'color').name('Color').onChange((value) => {\n this.light.pointLight.color.setHex(value);\n });\n const pointLightIntensityGui = pointLightFolder.add(Config.pointLight, 'intensity', 0, 2).name('Intensity');\n pointLightIntensityGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.light.pointLight.intensity = value;\n });\n pointLightIntensityGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n });\n const pointLightDistanceGui = pointLightFolder.add(Config.pointLight, 'distance', 0, 1000).name('Distance');\n pointLightDistanceGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.light.pointLight.distance = value;\n });\n pointLightDistanceGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n });\n const pointLightPositionXGui = pointLightFolder.add(Config.pointLight, 'x', -1000, 1000).name('Position X');\n pointLightPositionXGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.light.pointLight.position.x = value;\n });\n pointLightPositionXGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n });\n const pointLightPositionYGui = pointLightFolder.add(Config.pointLight, 'y', -1000, 1000).name('Position Y');\n pointLightPositionYGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.light.pointLight.position.y = value;\n });\n pointLightPositionYGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n });\n const pointLightPositionZGui = pointLightFolder.add(Config.pointLight, 'z', -1000, 1000).name('Position Z');\n pointLightPositionZGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.light.pointLight.position.z = value;\n });\n pointLightPositionZGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n });\n\n\n // Hemi Light\n const hemiLightFolder = gui.addFolder('Hemi Light');\n hemiLightFolder.add(Config.hemiLight, 'enabled').name('Enabled').onChange((value) => {\n this.light.hemiLight.visible = value;\n });\n hemiLightFolder.addColor(Config.hemiLight, 'color').name('Color').onChange((value) => {\n this.light.hemiLight.color.setHex(value);\n });\n hemiLightFolder.addColor(Config.hemiLight, 'groundColor').name('ground Color').onChange((value) => {\n this.light.hemiLight.groundColor.setHex(value);\n });\n const hemiLightIntensityGui = hemiLightFolder.add(Config.hemiLight, 'intensity', 0, 2).name('Intensity');\n hemiLightIntensityGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.light.hemiLight.intensity = value;\n });\n hemiLightIntensityGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n });\n const hemiLightPositionXGui = hemiLightFolder.add(Config.hemiLight, 'x', -1000, 1000).name('Position X');\n hemiLightPositionXGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.light.hemiLight.position.x = value;\n });\n hemiLightPositionXGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n });\n const hemiLightPositionYGui = hemiLightFolder.add(Config.hemiLight, 'y', -500, 1000).name('Position Y');\n hemiLightPositionYGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.light.hemiLight.position.y = value;\n });\n hemiLightPositionYGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n });\n const hemiLightPositionZGui = hemiLightFolder.add(Config.hemiLight, 'z', -1000, 1000).name('Position Z');\n hemiLightPositionZGui.onChange((value) => {\n this.controls.enableRotate = false;\n\n this.light.hemiLight.position.z = value;\n });\n hemiLightPositionZGui.onFinishChange(() => {\n this.controls.enableRotate = true;\n });\n }\n}\n","// Global imports -\nimport * as THREE from 'three';\nimport TWEEN from 'tween.js';\n\n// Local imports -\n// Components\nimport Renderer from './components/renderer';\nimport Camera from './components/camera';\nimport Light from './components/light';\nimport Controls from './components/controls';\n\n// Helpers\nimport Geometry from './helpers/geometry';\nimport Stats from './helpers/stats';\n\n// Model\nimport Texture from './model/texture';\nimport Model from './model/model';\n\n// Managers\nimport Interaction from './managers/interaction';\nimport DatGUI from './managers/datGUI';\n\n// data\nimport Config from './../data/config';\n// -- End of imports\n\n// This class instantiates and ties all of the components together, starts the loading process and renders the main loop\nexport default class Main {\n constructor(container) {\n // Set container property to container element\n this.container = container;\n\n // Start Three clock\n this.clock = new THREE.Clock();\n\n // Main scene creation\n this.scene = new THREE.Scene();\n this.scene.fog = new THREE.FogExp2(Config.fog.color, Config.fog.near);\n\n // Get Device Pixel Ratio first for retina\n if(window.devicePixelRatio) {\n Config.dpr = window.devicePixelRatio;\n }\n\n // Main renderer constructor\n this.renderer = new Renderer(this.scene, container);\n\n // Components instantiations\n this.camera = new Camera(this.renderer.threeRenderer);\n this.controls = new Controls(this.camera.threeCamera, container);\n this.light = new Light(this.scene);\n\n // Create and place lights in scene\n const lights = ['ambient', 'directional', 'point', 'hemi'];\n lights.forEach((light) => this.light.place(light));\n\n // Create and place geo in scene\n this.geometry = new Geometry(this.scene);\n this.geometry.make('plane')(150, 150, 10, 10);\n this.geometry.place([0, -20, 0], [Math.PI / 2, 0, 0]);\n\n // Set up rStats if dev environment\n if(Config.isDev && Config.isShowingStats) {\n this.stats = new Stats(this.renderer);\n this.stats.setUp();\n }\n\n // Instantiate texture class\n this.texture = new Texture();\n\n // Start loading the textures and then go on to load the model after the texture Promises have resolved\n this.texture.load().then(() => {\n this.manager = new THREE.LoadingManager();\n\n // Textures loaded, load model\n this.model = new Model(this.scene, this.manager, this.texture.textures);\n this.model.load();\n\n // onProgress callback\n this.manager.onProgress = (item, loaded, total) => {\n console.log(`${item}: ${loaded} ${total}`);\n };\n\n // All loaders done now\n this.manager.onLoad = () => {\n // Set up interaction manager with the app now that the model is finished loading\n new Interaction(this.renderer.threeRenderer, this.scene, this.camera.threeCamera, this.controls.threeControls);\n\n // Add dat.GUI controls if dev\n if(Config.isDev) {\n new DatGUI(this, this.model.obj);\n }\n\n // Everything is now fully loaded\n Config.isLoaded = true;\n this.container.querySelector('#loading').style.display = 'none';\n };\n });\n\n // Start render which does not wait for model fully loaded\n this.render();\n }\n\n render() {\n // Render rStats if Dev\n if(Config.isDev && Config.isShowingStats) {\n Stats.start();\n }\n\n // Call render function and pass in created scene and camera\n this.renderer.render(this.scene, this.camera.threeCamera);\n\n // rStats has finished determining render call now\n if(Config.isDev && Config.isShowingStats) {\n Stats.end();\n }\n\n // Delta time is sometimes needed for certain updates\n //const delta = this.clock.getDelta();\n\n // Call any vendor or module frame updates here\n TWEEN.update();\n this.controls.threeControls.update();\n\n // RAF\n requestAnimationFrame(this.render.bind(this)); // Bind the main class instead of window object\n }\n}\n","import Config from './data/config';\r\nimport Detector from './utils/detector';\r\nimport Main from './app/main';\r\n\r\n// Styles\r\nimport './../css/app.scss';\r\n\r\n// Check environment and set the Config helper\r\nif(__ENV__ === 'dev') {\r\n console.log('----- RUNNING IN DEV ENVIRONMENT! -----');\r\n\r\n Config.isDev = true;\r\n}\r\n\r\nfunction init() {\r\n // Check for webGL capabilities\r\n if(!Detector.webgl) {\r\n Detector.addGetWebGLMessage();\r\n } else {\r\n const container = document.getElementById('appContainer');\r\n new Main(container);\r\n }\r\n}\r\n\r\ninit();\r\n"],"sourceRoot":""}