UNPKG

threedeescene

Version:

A wrapper for Three.js assisting the creation of Three.js apps

1,679 lines (1,260 loc) 927 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["ThreeDeeScene"] = factory(); else root["ThreeDeeScene"] = factory(); })(this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ function(module, exports, __webpack_require__) { var ThreeDeeSprite = __webpack_require__(1); var THREE = __webpack_require__(2); var OrbitControls = __webpack_require__(4)(THREE); var ColorHelpers = __webpack_require__(5); var Helpers = __webpack_require__(3); /*Get requestAnimationFrame working for all browsers */ window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.oRequestAnimationFrame; /** * Created by grahamclapham on 05/06/2014. * Dependencies ThreeJs (http://threejs.org/) and Three.js OrbitControls.js (https://github.com/mrdoob/three.js/blob/master/examples/js/controls/OrbitControls.js) */ ThreeDeeScene = function (opt_target, opt_initialiser) { var _scope = function () { this._private = { //APP target: null, width: 100, height: 100, fullscreen: true, backgroundColour: 0xcccccc, _aspect: null, _scene: null, //LIGHTS _light: null, lightColour: 0xffffff, _lightAmbient: null, ambientColour: 0xffffff, _lights: [], //CAMERA fov: 15, //— Camera frustum vertical field of view. near: 0.1, //— Camera frustum near plane. far: 20000, //— Camera frustum far plane. _camera: null, cameraX: 0, cameraY: 0, cameraZ: 15, //ACTION _sprites: [], _materials: [], _datum: [], _scene: new THREE.Scene(), _mouse: new THREE.Vector2(), //_projector : new THREE.Projector(), _raycaster: new THREE.Raycaster(), _bufferGeometry: new THREE.BufferGeometry(), _renderer: new THREE.WebGLRenderer({ antialias: true, alpha: true, shadowMapEnabled: true }), _orbitControl: null, orbit: true, // is the scene controlled by an mouse controlled orbiter? _dispatcher: null, _frameEvent: null }; _setUp.apply(this, arguments); }; /* Constants */ _scope.HOVERED = "hovered"; _scope.CLICKED = "clicked"; _scope.FRAME_EVENT = "frameEvent"; var _setUp = function () { //First, have you got a config object? // If so apply all the properties. if (arguments[1] && typeof arguments[1] == 'object') { _onConfigSet.call(this, arguments[1]); } // test to see if the first item is a DOM element if (arguments[0] && arguments[0].nodeType === 1) { this.setTarget(arguments[0]); } }; var _onConfigSet = function () { for (var value in arguments[0]) { //Underscore properties are not to be changed. if (String(value).charAt(0) != '_') this._private[value] = arguments[0][value]; //console.log("THE VALUE ",value," -- ",arguments[0][value]); } }; //// var _onTargetSet = function () { _initScene.call(this); }; ///// var _initScene = function () { //this.getRenderer().setClearColor(this.getBackgroundColour(),.0); this._private._dispatcher = document.createElement("div"); this._private._frameEvent = new CustomEvent(_scope.FRAME_EVENT, { 'detail': "frameEntered" }); this._private._clickEvent = new CustomEvent(_scope.CLICKED, { 'detail': "clicked" }); if (this.getTarget()) this._private.target.appendChild(this.getRenderer().domElement); _initCamera.call(this); _initLights.call(this); _initMaterials.call(this); _initAnimation.call(this); // console.log("FULLSCREEN IS SET TO ", this.getFullScreen()); if (this.getFullScreen()) { _initWindowResize.call(this); _onWindowResize.call(this); } else { _setFixedSize.call(this); } var scope = this; this.getTarget().addEventListener('mousemove', function (e) { scope.documentMouseMove(e); }, false); this.getTarget().addEventListener('mousedown', function (e) { scope.documentMouseDown(e); }, false); }; var _setFixedSize = function () { this.getRenderer().setSize(this.getWidth(), this.getHeight()); this._private._camera.aspect = this.getWidth() / this.getHeight(); this._private._camera.updateProjectionMatrix(); }; ////// var _initCamera = function () { // Create a camera, zoom it out from the model a bit, and add it to the scene. this._private._camera = new THREE.PerspectiveCamera(this.getFov(), this._private._aspect, this.getNear(), this.getFar()); this._private._camera.position.x = this._private.cameraX; this._private._camera.position.y = this._private.cameraY; this._private._camera.position.z = this._private.cameraZ; //this.getCamera().position.set(-50,6,0); this._private._scene.add(this.getCamera()); }; var _refreshCamera = function () { this._private._camera.position.x = this._private.cameraX; this._private._camera.position.y = this._private.cameraY; this._private._camera.position.z = this._private.cameraZ; this._private._camera.near = this._private.near; this._private._camera.far = this._private.far; this._private._camera.fov = this._private.fov; this._private._camera.updateProjectionMatrix(); }; ///// var _initLights = function () { // Create a light, set its position, and add it to the scene. var _light = this._private._light = new THREE.PointLight(this.getLightColour()); _light.position.set(-100, 200, 100); _light.castShadow = true; _light.shadowMapWidth = 2048; _light.shadowMapHeight = 2048; _light.shadowCameraFov = 45; this._private._scene.add(_light); // ...and now the ambient light var _lightAmbient = this._private._lightAmbient = new THREE.DirectionalLight(this.getAmbientLightColour(), 1); _lightAmbient.position.set(100, -700, -300); this._private._scene.add(_lightAmbient); }; /* Default materials - if none are set */ var _initMaterials = function () { this._private._materials[0] = new THREE.MeshPhongMaterial({ color: 0xccff33 }); }; var _initAnimation = function () { if (this._private.orbit) this._private._orbitControl = new OrbitControls(this._private._camera, this._private._renderer.domElement); requestAnimationFrame(this.animate.bind(this)); }; var _onSpriteAdded = function (sp) { // console.log("SpriteAdded ") sp.setScene(this); }; var _initWindowResize = function () { var _this = this; this._private._windowListener = window.addEventListener('resize', function () { if (_this.getFullScreen()) _onWindowResize.call(_this); }); }; var _onDocumentMouseMove = function () { for (var i = 0; i < this._private._sprites.length; i++) { _hitTest.call(this, i); } }; var _hitTest = function (index) { this._private._vector = new THREE.Vector3(this._private._mouse.x, this._private._mouse.y, 1); var direction = new THREE.Vector3(0, 0, -1).transformDirection(this._private._camera.matrixWorld); this._private._raycaster.setFromCamera(this._private._mouse, this._private._camera); var __sprite = this._private._sprites[index]; var mesh = __sprite.getMesh(); var intersects = []; try { intersects = this._private._raycaster.intersectObject(mesh); } catch (err) { console.log("Intersects eror: ", err); } if (intersects.length > 0) { var intersect = intersects[0]; __sprite.setHit(true); } else { __sprite.setHit(false); } }; var _onWindowResize = function () { var WIDTH = window.innerWidth, HEIGHT = window.innerHeight; this._private._renderer.setSize(WIDTH, HEIGHT); this._private._camera.aspect = WIDTH / HEIGHT; this._private._camera.updateProjectionMatrix(); }; var _onSizeChanged = function () { this.setFullScreen(false); _setFixedSize.call(this); }; // Renders the scene and updates the render as needed. /* ENUMS */ /* Methods */ _scope.prototype = { animate: function () { this._private._renderer.render(this._private._scene, this._private._camera); //this.cube.rotation.y += 0.1; this._private._dispatcher.dispatchEvent(this._private._frameEvent); requestAnimationFrame(this.animate.bind(this)); }, listen: function (event, opt_callback) { this._private._dispatcher.addEventListener(event, opt_callback); }, addSprite: function (value) { var alreadyAdded = false; for (var sp in this._private._sprites) { if (this._private._sprites[sp] == value) { alreadyAdded = true; } } if (!alreadyAdded) { this._private._sprites.push(value); _onSpriteAdded.call(this, value); } }, stripPx: function (value) { var _s = String(value).replace("px", ""); var _n = parseFloat(_s); return !isNaN(_n) ? _n : 0; }, documentMouseMove: function (event, targ) { event.preventDefault(); var el = this.getTarget(); var style = el.currentStyle || window.getComputedStyle(el); var _xOffset = this.stripPx(style["padding-left"]); var _yOffset = this.stripPx(style["padding-top"]); var _rect = this.getTarget().getBoundingClientRect(); var xMouseCalc = (event.clientX - _rect.left - _xOffset) / window.innerWidth * 2 - 1; var yMouseCalc = -((event.clientY - _rect.top - _yOffset) / window.innerHeight) * 2 + 1; this._private._mouse.x = xMouseCalc; this._private._mouse.y = yMouseCalc; _onDocumentMouseMove.call(this); }, documentMouseDown: function () { // console.log("Mouse Down", this.getHovered()); this._private._dispatcher.dispatchEvent(this._private._clickEvent); }, getHovered: function () { var _hovered = []; for (var sp in this._private._sprites) { if (this._private._sprites[sp].getHit()) { _hovered.push(this._private._sprites[sp]); } } return _hovered; }, getTarget: function () { return this._private.target; }, setTarget: function (value) { if (Helpers.chekDomElementIsValid(value)) { this._private.target = value; _onTargetSet.apply(this); } else { throw new Error("The value passed must be a DOM element"); } }, getWidth: function () { return this._private.width; }, setWidth: function (value) { this._private.width = Helpers.checkNumberValid(value); _onSizeChanged.call(this); }, getHeight: function () { return this._private.height; }, setHeight: function (value) { this._private.height = Helpers.checkNumberValid(value); _onSizeChanged.call(this); }, getCamera: function () { return this._private._camera; }, getCameraX: function () { return this._private.cameraX; }, setCameraX: function (value) { this._private.cameraX = Helpers.checkNumberValid(value); _refreshCamera.call(this); }, getCameraY: function () { return this._private.cameraY; }, setCameraY: function (value) { this._private.cameraY = Helpers.checkNumberValid(value); _refreshCamera.call(this); }, getCameraZ: function () { return this._private.cameraZ; }, setCameraZ: function (value) { this._private.cameraZ = Helpers.checkNumberValid(value); _refreshCamera.call(this); }, getRenderer: function () { return this._private._renderer; }, getFov: function () { return this._private.fov; }, setFov: function (value) { this._private.fov = Helpers.checkNumberValid(value); _refreshCamera.call(this); }, getNear: function () { return this._private.near; }, setNear: function (value) { this._private.near = Helpers.checkNumberValid(value); _refreshCamera.call(this); }, getFar: function () { return this._private.far; }, setFar: function (value) { this._private.far = Helpers.checkNumberValid(value); _refreshCamera.call(this); }, // in the short tern, just to ensure all number passed are not NaNs... colourHelper: function (value) { var _passed = true; if (value.length) { for (var i = 0; i < value.length; i++) { if (isNaN(value[i])) _passed = false; } } return _passed; }, getBackgroundColour: function () { return this._private.backgroundColour; }, setBackgroundColour: function (value) { this._private.backgroundColour = value; }, getLightColour: function () { return this._private.lightColour; }, setLightColour: function (value) { this._private.lightColour = value; console.log("New light col : ", value); try { this._private._light.color = new THREE.Color(value); } catch (err) { console.log(err); } }, getAmbientLightColour: function () { return this._private.ambientColour; }, setAmbientLightColour: function (value) { this._private.ambientColour = value; console.log("New ambient col : ", value); try { this._private._lightAmbient.color = new THREE.Color(value); } catch (err) { console.log(err); } }, getScene: function () { return this._private._scene; }, getFullScreen: function () { return this._private.fullscreen; }, setFullScreen: function (value) { this._private.fullscreen = value; } }; return _scope; }(); module.exports = { Scene: ThreeDeeScene, Sprite: ThreeDeeSprite, THREE: THREE, ColorHelpers: ColorHelpers }; /***/ }, /* 1 */ /***/ function(module, exports, __webpack_require__) { var THREE = __webpack_require__(2), Helpers = __webpack_require__(3); var standardController = function () { var _this = this; this.listen(this.SPRITE_HIT_CHANGED, function (e) { _onHitEvent.call(_this, e); }); }; var _onHitEvent = function (e) { this.getHit() ? _onMouseIn.call(this, e) : _onMouseOut.call(this, e); }; var _onMouseIn = function (e) { this.setMaterial(this.getHoverMaterial()); }; var _onMouseOut = function (e) { this.setMaterial(this._private.materialUnhovered); }; var defaultMaterial = new THREE.MeshPhongMaterial(); defaultMaterial.shininess = 100; defaultMaterial.shading = THREE.SmoothShading; defaultMaterial.id = "defaultMaterial"; var defaultGeometry = new THREE.SphereGeometry(1, 32, 32); ThreeDeeSprite = function (modelURL, material, opt_initialiser, opt_controller) { var _scope = function (modelURL, material, opt_initialiser, opt_controller) { this._private = { material: null, materialDefault: null, materialUnhovered: null, materialHover: null, blenderModel: null, hit: false, textureMap: null, _imgTexture: null, bumpMap: null, bumpScale: .02, _x: 1, _y: 1, _z: 1, _xRotation: 0, _yRotation: 0, _zRotation: 0, _imgBump: null, _spriteEventDispatcher: null, _texturLoader: null, data: { name: "The name of the sprite is default" } }; /* Statics */ this.SPRITE_HIT_CHANGED = "spriteHitChanged"; this._private._spriteEventDispatcher = document.createElement("div"); this._private.materialDefault = defaultMaterial; this._private.materialUnhovered = material ? material : defaultMaterial; this._private.material = this._private.materialUnhovered; this._private._opt_initialiser = opt_initialiser ? opt_initialiser : {}; for (var value in this._private._opt_initialiser) { //Underscore properties are not to be changed. if (String(value).charAt(0) != '_') this._private[value] = this._private._opt_initialiser[value]; console.log("Setting config to ", this._private[value]); } this._contoller = opt_controller ? opt_controller : standardController; this._contoller.call(this); this._private.modelURL = modelURL ? modelURL : null; this._loader = new THREE.JSONLoader(); // was a default hover material set in the config? if (!this.getHoverMaterial()) { var color = new THREE.Color(1, 1, 0); var material = new THREE.MeshPhongMaterial(); material.emissive = color; material.shininess = 100; material.shading = THREE.SmoothShading; this._private.materialHover = material; } _initSprite.call(this); }; // internal business logic var _initSprite = function () { if (this._private.textureMap) _initTextureMap.call(this); if (this._private.bumpMap) _initBumpmap.call(this); this._private.modelURL ? _intModel.call(this) : _initDefaultModel.call(this); }; var _intModel = function () { var scope = this; this._loader.load(this._private.modelURL, function (geometry) { _onGeometrySet.call(scope, geometry); }); }; var _initDefaultModel = function () { this._private._mesh = mesh = new THREE.Mesh(defaultGeometry, this._private.material); _onGeometrySet.call(this, defaultGeometry); }; var _onGeometrySet = function (geometry) { var mesh; this._private._mesh = mesh = new THREE.Mesh(geometry, this._private.material); for (var prop in this._private._opt_initialiser) { mesh[prop] = this._private._opt_initialiser[prop]; } // position transforms need to be applied individually... if (this._private._opt_initialiser.position) { this._private._x = this._private._opt_initialiser.position.x; this._private._y = this._private._opt_initialiser.position.y; this._private._z = this._private._opt_initialiser.position.z; mesh.position.x = this._private._x; mesh.position.y = this._private._y; mesh.position.z = this._private._z; } // rotation transforms need to be applied individually... if (this._private._opt_initialiser.rotation) { this._private._x = this._private._opt_initialiser.rotation.x; this._private._y = this._private._opt_initialiser.rotation.y; this._private._z = this._private._opt_initialiser.rotation.z; mesh.rotation.x = this._private._xRotation; mesh.rotation.y = this._private._yRotation; mesh.rotation.z = this._private._zRotation; } // ...and scale transforms need to be applied individually too if (this._private._opt_initialiser.scale) { mesh.scale.x = this._private._opt_initialiser.scale.x; mesh.scale.y = this._private._opt_initialiser.scale.y; mesh.scale.z = this._private._opt_initialiser.scale.z; } try { this.addToScene(); } catch (err) { console.log(err); } }; var _updatePosition = function () { var mesh = this._private._mesh; mesh.position.x = this._private._x; mesh.position.y = this._private._y; mesh.position.z = this._private._z; // mesh.rotation.x = this._private._xRotation; mesh.rotation.y = this._private._yRotation; mesh.rotation.z = this._private._zRotation; }; var _initTextureMap = function () { var _this = this; var tex = new THREE.TextureLoader(); tex.load(this.getTextureMap(), function (evt) { _this.getMaterial().map = evt; _this.getMaterial().needsUpdate = true; }); }; var _initBumpmap = function () { var _this = this; var tex = new THREE.TextureLoader(); tex.load(this.getBumpMap(), function (evt) { _this.getMaterial().bumpScale = _this.getBumpScale(); _this.getMaterial().bumpMap = evt; _this.getMaterial().needsUpdate = true; }); }; var _onSceneSet = function () { // Due to the asynchronous way the models load this mesh may not yet be defined. // If so the mesh should be added during the callback from the loader (this._loader.load... etc) try { this.addToScene(); } catch (e) { //--- } }; var _onHitChanged = function () { console.log("I'VE BEEN HIT >>>> ", this.getData().name); this.getDispatcher().dispatchEvent(this.getEvent(this.SPRITE_HIT_CHANGED, { data: this.getData(), target: this })); }; /* Methods */ _scope.prototype = { /** * Sets the Scene which the Sprite belongs to. * @param value */ setScene: function (value) { console.log("THE SCEN CONSTRUCTOR = ", value); this._private.scene = value; _onSceneSet.call(this); }, getController: function () { return this._contoller; }, addToScene: function () { if (!this._private._mesh || !this._private.scene.getScene()) return; var _this = this; _this._private.scene.getScene().add(_this._private._mesh); this._private.scene.listen(_scope.FRAME_EVENT, function () { this._contoller.call(this); }.bind(this)); }, listen: function (event, opt_callback) { this._private._spriteEventDispatcher.addEventListener(event, opt_callback); }, getMesh: function () { return this._private._mesh; }, setMaterial: function (value) { this._private.material = value; try { this.getMesh().material = this.getMaterial(); } catch (err) { //-- console.log("Error setting material "); } }, getMaterial: function () { return this._private.material; }, setDefaultMaterial: function (value) { this._private.materialDefault = value; }, getDefaultMaterial: function () { return this._private.materialDefault; }, setHoverMaterial: function (value) { this._private.materialHover = value; }, getHoverMaterial: function () { return this._private.materialHover; }, getHit: function () { return this._private.hit; }, setHit: function (value) { if (this._private.hit != value) { this._private.hit = value; _onHitChanged.call(this); } }, setX: function (value) { this._private._x = value; _updatePosition.call(this); }, getX: function () { return this._private._x; }, setY: function (value) { this._private._y = value; _updatePosition.call(this); }, getY: function () { return this._private._y; }, setZ: function (value) { this._private._z = value; _updatePosition.call(this); }, getZ: function () { return this._private._z; }, setXrotation: function (value) { this._private._xRotation = Helpers.checkNumberValid(value); _updatePosition.call(this); }, getXrotation: function (value) { return this._private._xRotation; }, setYrotation: function (value) { this._private._yRotation = Helpers.checkNumberValid(value);; _updatePosition.call(this); }, getYrotation: function (value) { return this._private._yRotation; }, setZrotation: function (value) { this._private._zRotation = Helpers.checkNumberValid(value);; _updatePosition.call(this); }, getZrotation: function (value) { return this._private._zRotation; }, getData: function () { return this._private.data; }, setData: function (value) { this._private.data = value; }, getTextureMap: function () { return this._private.textureMap; }, setTextureMap: function (value) { this._private.textureMap = value; _initTextureMap.call(this); }, getBumpScale: function () { return this._private.bumpScale; }, setBumpScale: function (value) { this._private.bumpScale = value; _initBumpmap.call(this); //var mesh = this.getMesh() // mesh.material = this.getMaterial(); //mesh.updateMatrix(); }, setBumpMap: function (value) { this._private.bumpMap = value; _initBumpmap.call(this); }, getBumpMap: function () { return this._private.bumpMap; }, getDispatcher: function () { return this._private._spriteEventDispatcher; }, getEvent: function (eventName, payload) { return new CustomEvent(eventName, { 'detail': payload }); } }; // return _scope; }(); module.exports = ThreeDeeSprite; /***/ }, /* 2 */ /***/ function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;var self = self || {};// File:src/Three.js /** * @author mrdoob / http://mrdoob.com/ */ var THREE = { REVISION: '73' }; // if ( true ) { !(__WEBPACK_AMD_DEFINE_FACTORY__ = (THREE), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); } else if ( 'undefined' !== typeof exports && 'undefined' !== typeof module ) { module.exports = THREE; } // polyfills if ( self.requestAnimationFrame === undefined || self.cancelAnimationFrame === undefined ) { // Missing in Android stock browser. ( function () { var lastTime = 0; var vendors = [ 'ms', 'moz', 'webkit', 'o' ]; for ( var x = 0; x < vendors.length && ! self.requestAnimationFrame; ++ x ) { self.requestAnimationFrame = self[ vendors[ x ] + 'RequestAnimationFrame' ]; self.cancelAnimationFrame = self[ vendors[ x ] + 'CancelAnimationFrame' ] || self[ vendors[ x ] + 'CancelRequestAnimationFrame' ]; } if ( self.requestAnimationFrame === undefined && self.setTimeout !== undefined ) { self.requestAnimationFrame = function ( callback ) { var currTime = Date.now(), timeToCall = Math.max( 0, 16 - ( currTime - lastTime ) ); var id = self.setTimeout( function () { callback( currTime + timeToCall ); }, timeToCall ); lastTime = currTime + timeToCall; return id; }; } if ( self.cancelAnimationFrame === undefined && self.clearTimeout !== undefined ) { self.cancelAnimationFrame = function ( id ) { self.clearTimeout( id ); }; } } )(); } // if ( self.performance === undefined ) { self.performance = {}; } if ( self.performance.now === undefined ) { ( function () { var start = Date.now(); self.performance.now = function () { return Date.now() - start; } } )(); } // if ( Number.EPSILON === undefined ) { Number.EPSILON = Math.pow( 2, -52 ); } // if ( Math.sign === undefined ) { // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign Math.sign = function ( x ) { return ( x < 0 ) ? - 1 : ( x > 0 ) ? 1 : + x; }; } if ( Function.prototype.name === undefined && Object.defineProperty !== undefined ) { // Missing in IE9-11. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name Object.defineProperty( Function.prototype, 'name', { get: function () { return this.toString().match( /^\s*function\s*(\S*)\s*\(/ )[ 1 ]; } } ); } // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent.button THREE.MOUSE = { LEFT: 0, MIDDLE: 1, RIGHT: 2 }; // GL STATE CONSTANTS THREE.CullFaceNone = 0; THREE.CullFaceBack = 1; THREE.CullFaceFront = 2; THREE.CullFaceFrontBack = 3; THREE.FrontFaceDirectionCW = 0; THREE.FrontFaceDirectionCCW = 1; // SHADOWING TYPES THREE.BasicShadowMap = 0; THREE.PCFShadowMap = 1; THREE.PCFSoftShadowMap = 2; // MATERIAL CONSTANTS // side THREE.FrontSide = 0; THREE.BackSide = 1; THREE.DoubleSide = 2; // shading THREE.FlatShading = 1; THREE.SmoothShading = 2; // colors THREE.NoColors = 0; THREE.FaceColors = 1; THREE.VertexColors = 2; // blending modes THREE.NoBlending = 0; THREE.NormalBlending = 1; THREE.AdditiveBlending = 2; THREE.SubtractiveBlending = 3; THREE.MultiplyBlending = 4; THREE.CustomBlending = 5; // custom blending equations // (numbers start from 100 not to clash with other // mappings to OpenGL constants defined in Texture.js) THREE.AddEquation = 100; THREE.SubtractEquation = 101; THREE.ReverseSubtractEquation = 102; THREE.MinEquation = 103; THREE.MaxEquation = 104; // custom blending destination factors THREE.ZeroFactor = 200; THREE.OneFactor = 201; THREE.SrcColorFactor = 202; THREE.OneMinusSrcColorFactor = 203; THREE.SrcAlphaFactor = 204; THREE.OneMinusSrcAlphaFactor = 205; THREE.DstAlphaFactor = 206; THREE.OneMinusDstAlphaFactor = 207; // custom blending source factors //THREE.ZeroFactor = 200; //THREE.OneFactor = 201; //THREE.SrcAlphaFactor = 204; //THREE.OneMinusSrcAlphaFactor = 205; //THREE.DstAlphaFactor = 206; //THREE.OneMinusDstAlphaFactor = 207; THREE.DstColorFactor = 208; THREE.OneMinusDstColorFactor = 209; THREE.SrcAlphaSaturateFactor = 210; // depth modes THREE.NeverDepth = 0; THREE.AlwaysDepth = 1; THREE.LessDepth = 2; THREE.LessEqualDepth = 3; THREE.EqualDepth = 4; THREE.GreaterEqualDepth = 5; THREE.GreaterDepth = 6; THREE.NotEqualDepth = 7; // TEXTURE CONSTANTS THREE.MultiplyOperation = 0; THREE.MixOperation = 1; THREE.AddOperation = 2; // Mapping modes THREE.UVMapping = 300; THREE.CubeReflectionMapping = 301; THREE.CubeRefractionMapping = 302; THREE.EquirectangularReflectionMapping = 303; THREE.EquirectangularRefractionMapping = 304; THREE.SphericalReflectionMapping = 305; // Wrapping modes THREE.RepeatWrapping = 1000; THREE.ClampToEdgeWrapping = 1001; THREE.MirroredRepeatWrapping = 1002; // Filters THREE.NearestFilter = 1003; THREE.NearestMipMapNearestFilter = 1004; THREE.NearestMipMapLinearFilter = 1005; THREE.LinearFilter = 1006; THREE.LinearMipMapNearestFilter = 1007; THREE.LinearMipMapLinearFilter = 1008; // Data types THREE.UnsignedByteType = 1009; THREE.ByteType = 1010; THREE.ShortType = 1011; THREE.UnsignedShortType = 1012; THREE.IntType = 1013; THREE.UnsignedIntType = 1014; THREE.FloatType = 1015; THREE.HalfFloatType = 1025; // Pixel types //THREE.UnsignedByteType = 1009; THREE.UnsignedShort4444Type = 1016; THREE.UnsignedShort5551Type = 1017; THREE.UnsignedShort565Type = 1018; // Pixel formats THREE.AlphaFormat = 1019; THREE.RGBFormat = 1020; THREE.RGBAFormat = 1021; THREE.LuminanceFormat = 1022; THREE.LuminanceAlphaFormat = 1023; // THREE.RGBEFormat handled as THREE.RGBAFormat in shaders THREE.RGBEFormat = THREE.RGBAFormat; //1024; // DDS / ST3C Compressed texture formats THREE.RGB_S3TC_DXT1_Format = 2001; THREE.RGBA_S3TC_DXT1_Format = 2002; THREE.RGBA_S3TC_DXT3_Format = 2003; THREE.RGBA_S3TC_DXT5_Format = 2004; // PVRTC compressed texture formats THREE.RGB_PVRTC_4BPPV1_Format = 2100; THREE.RGB_PVRTC_2BPPV1_Format = 2101; THREE.RGBA_PVRTC_4BPPV1_Format = 2102; THREE.RGBA_PVRTC_2BPPV1_Format = 2103; // Loop styles for AnimationAction THREE.LoopOnce = 2200; THREE.LoopRepeat = 2201; THREE.LoopPingPong = 2202; // DEPRECATED THREE.Projector = function () { console.error( 'THREE.Projector has been moved to /examples/js/renderers/Projector.js.' ); this.projectVector = function ( vector, camera ) { console.warn( 'THREE.Projector: .projectVector() is now vector.project().' ); vector.project( camera ); }; this.unprojectVector = function ( vector, camera ) { console.warn( 'THREE.Projector: .unprojectVector() is now vector.unproject().' ); vector.unproject( camera ); }; this.pickingRay = function ( vector, camera ) { console.error( 'THREE.Projector: .pickingRay() is now raycaster.setFromCamera().' ); }; }; THREE.CanvasRenderer = function () { console.error( 'THREE.CanvasRenderer has been moved to /examples/js/renderers/CanvasRenderer.js' ); this.domElement = document.createElement( 'canvas' ); this.clear = function () {}; this.render = function () {}; this.setClearColor = function () {}; this.setSize = function () {}; }; // File:src/math/Color.js /** * @author mrdoob / http://mrdoob.com/ */ THREE.Color = function ( color ) { if ( arguments.length === 3 ) { return this.fromArray( arguments ); } return this.set( color ); }; THREE.Color.prototype = { constructor: THREE.Color, r: 1, g: 1, b: 1, set: function ( value ) { if ( value instanceof THREE.Color ) { this.copy( value ); } else if ( typeof value === 'number' ) { this.setHex( value ); } else if ( typeof value === 'string' ) { this.setStyle( value ); } return this; }, setHex: function ( hex ) { hex = Math.floor( hex ); this.r = ( hex >> 16 & 255 ) / 255; this.g = ( hex >> 8 & 255 ) / 255; this.b = ( hex & 255 ) / 255; return this; }, setRGB: function ( r, g, b ) { this.r = r; this.g = g; this.b = b; return this; }, setHSL: function () { function hue2rgb( p, q, t ) { if ( t < 0 ) t += 1; if ( t > 1 ) t -= 1; if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t; if ( t < 1 / 2 ) return q; if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t ); return p; } return function ( h, s, l ) { // h,s,l ranges are in 0.0 - 1.0 h = THREE.Math.euclideanModulo( h, 1 ); s = THREE.Math.clamp( s, 0, 1 ); l = THREE.Math.clamp( l, 0, 1 ); if ( s === 0 ) { this.r = this.g = this.b = l; } else { var p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s ); var q = ( 2 * l ) - p; this.r = hue2rgb( q, p, h + 1 / 3 ); this.g = hue2rgb( q, p, h ); this.b = hue2rgb( q, p, h - 1 / 3 ); } return this; }; }(), setStyle: function ( style ) { function handleAlpha( string ) { if ( string === undefined ) return; if ( parseFloat( string ) < 1 ) { console.warn( 'THREE.Color: Alpha component of ' + style + ' will be ignored.' ); } } var m; if ( m = /^((?:rgb|hsl)a?)\(\s*([^\)]*)\)/.exec( style ) ) { // rgb / hsl var color; var name = m[ 1 ]; var components = m[ 2 ]; switch ( name ) { case 'rgb': case 'rgba': if ( color = /^(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { // rgb(255,0,0) rgba(255,0,0,0.5) this.r = Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255; this.g = Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255; this.b = Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255; handleAlpha( color[ 5 ] ); return this; } if ( color = /^(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5) this.r = Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100; this.g = Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100; this.b = Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100; handleAlpha( color[ 5 ] ); return this; } break; case 'hsl': case 'hsla': if ( color = /^([0-9]*\.?[0-9]+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([0-9]*\.?[0-9]+)\s*)?$/.exec( components ) ) { // hsl(120,50%,50%) hsla(120,50%,50%,0.5) var h = parseFloat( color[ 1 ] ) / 360; var s = parseInt( color[ 2 ], 10 ) / 100; var l = parseInt( color[ 3 ], 10 ) / 100; handleAlpha( color[ 5 ] ); return this.setHSL( h, s, l ); } break; } } else if ( m = /^\#([A-Fa-f0-9]+)$/.exec( style ) ) { // hex color var hex = m[ 1 ]; var size = hex.length; if ( size === 3 ) { // #ff0 this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 0 ), 16 ) / 255; this.g = parseInt( hex.charAt( 1 ) + hex.charAt( 1 ), 16 ) / 255; this.b = parseInt( hex.charAt( 2 ) + hex.charAt( 2 ), 16 ) / 255; return this; } else if ( size === 6 ) { // #ff0000 this.r = parseInt( hex.charAt( 0 ) + hex.charAt( 1 ), 16 ) / 255; this.g = parseInt( hex.charAt( 2 ) + hex.charAt( 3 ), 16 ) / 255; this.b = parseInt( hex.charAt( 4 ) + hex.charAt( 5 ), 16 ) / 255; return this; } } if ( style && style.length > 0 ) { // color keywords var hex = THREE.ColorKeywords[ style ]; if ( hex !== undefined ) { // red this.setHex( hex ); } else { // unknown color console.warn( 'THREE.Color: Unknown color ' + style ); } } return this; }, clone: function () { return new this.constructor( this.r, this.g, this.b ); }, copy: function ( color ) { this.r = color.r; this.g = color.g; this.b = color.b; return this; }, copyGammaToLinear: function ( color, gammaFactor ) { if ( gammaFactor === undefined ) gammaFactor = 2.0; this.r = Math.pow( color.r, gammaFactor ); this.g = Math.pow( color.g, gammaFactor ); this.b = Math.pow( color.b, gammaFactor ); return this; }, copyLinearToGamma: function ( color, gammaFactor ) { if ( gammaFactor === undefined ) gammaFactor = 2.0; var safeInverse = ( gammaFactor > 0 ) ? ( 1.0 / gammaFactor ) : 1.0; this.r = Math.pow( color.r, safeInverse ); this.g = Math.pow( color.g, safeInverse ); this.b = Math.pow( color.b, safeInverse ); return this; }, convertGammaToLinear: function () { var r = this.r, g = this.g, b = this.b; this.r = r * r; this.g = g * g; this.b = b * b; return this; }, convertLinearToGamma: function () { this.r = Math.sqrt( this.r ); this.g = Math.sqrt( this.g ); this.b = Math.sqrt( this.b ); return this; }, getHex: function () { return ( this.r * 255 ) << 16 ^ ( this.g * 255 ) << 8 ^ ( this.b * 255 ) << 0; }, getHexString: function () { return ( '000000' + this.getHex().toString( 16 ) ).slice( - 6 ); }, getHSL: function ( optionalTarget ) { // h,s,l ranges are in 0.0 - 1.0 var hsl = optionalTarget || { h: 0, s: 0, l: 0 }; var r = this.r, g = this.g, b = this.b; var max = Math.max( r, g, b ); var min = Math.min( r, g, b ); var hue, saturation; var lightness = ( min + max ) / 2.0; if ( min === max ) { hue = 0; saturation = 0; } else { var delta = max - min; saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min ); switch ( max ) { case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break; case g: hue = ( b - r ) / delta + 2; break; case b: hue = ( r - g ) / delta + 4; break; } hue /= 6; } hsl.h = hue; hsl.s = saturation; hsl.l = lightness; return hsl; }, getStyle: function () { return 'rgb(' + ( ( this.r * 255 ) | 0 ) + ',' + ( ( this.g * 255 ) | 0 ) + ',' + ( ( this.b * 255 ) | 0 ) + ')'; }, offsetHSL: function ( h, s, l ) { var hsl = this.getHSL(); hsl.h += h; hsl.s += s; hsl.l += l; this.setHSL( hsl.h, hsl.s, hsl.l ); return this; }, add: function ( color ) { this.r += color.r; this.g += color.g; this.b += color.b; return this; }, addColors: function ( color1, color2 ) { this.r = color1.r + color2.r; this.g = color1.g + color2.g; this.b = color1.b + color2.b; return this; }, addScalar: function ( s ) { this.r += s; this.g += s; this.b += s; return this; }, multiply: function ( color ) { this.r *= color.r; this.g *= color.g; this.b *= color.b; return this; }, multiplyScalar: function ( s ) { this.r *= s; this.g *= s; this.b *= s; return this; }, lerp: function ( color, alpha ) { this.r += ( color.r - this.r ) * alpha; this.g += ( color.g - this.g ) * alpha; this.b += ( color.b - this.b ) * alpha; return this; }, equals: function ( c ) { return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b ); }, fromArray: function ( array, offset ) { if ( offset === undefined ) offset = 0; this.r = array[ offset ]; this.g = array[ offset + 1 ]; this.b = array[ offset + 2 ]; return this; }, toArray: function ( array, offset ) { if ( array === undefined ) array = []; if ( offset === undefined ) offset = 0; array[ offset ] = this.r; array[ offset + 1 ] = this.g; array[ offset + 2 ] = this.b; return array; } }; THREE.ColorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF, 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2, 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50, 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B, 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B, 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F, 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3, 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222, 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700, 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4, 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00, 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3, 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA, 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32, 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3, 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC, 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD, 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6, 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9, 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F, 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE, 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA, 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0, 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 }; // File:src/math/Quaternion.js /** * @author mikael emtinger / http://gomo.se/ * @author alteredq / http://alteredqualia.com/ * @author WestLangley / http://github.com/WestLangley * @