UNPKG

aframe-orbit-controls-component

Version:
1,850 lines (1,462 loc) 1.53 MB
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ require('aframe'); require('../index.js'); },{"../index.js":2,"aframe":3}],2:[function(require,module,exports){ // To avoid recalculation at every mouse movement tick var PI_2 = Math.PI / 2; AFRAME.registerComponent('orbit-controls', { schema: { enabled: { default: true } }, init: function () { this.previousPosition = new THREE.Vector3(); this.deltaPosition = new THREE.Vector3(); this.setupMouseControls(); this.setupHMDControls(); this.bindMethods(); var targetID = this.el.getAttribute('target'); this.distance = this.el.getAttribute('distance'); this.target3D = document.getElementById(targetID.replace('#', '')).object3D; window.target = this.target3D; window.camera = this.el; }, update: function () { if (!this.data.enabled) { return; } this.controls.update(); this.updateOrientation(); this.updatePosition(); }, play: function () { this.previousPosition.set(0, 0, 0); this.addEventListeners(); }, pause: function () { this.removeEventListeners(); }, tick: function (t) { this.update(); }, remove: function () { this.pause(); }, bindMethods: function () { this.onMouseDown = this.onMouseDown.bind(this); this.onMouseMove = this.onMouseMove.bind(this); this.releaseMouse = this.releaseMouse.bind(this); this.onTouchStart = this.onTouchStart.bind(this); this.onTouchMove = this.onTouchMove.bind(this); this.onTouchEnd = this.onTouchEnd.bind(this); }, setupMouseControls: function () { // The canvas where the scene is painted this.mouseDown = false; this.pitchObject = new THREE.Object3D(); this.yawObject = new THREE.Object3D(); this.yawObject.position.y = 10; this.yawObject.add(this.pitchObject); }, setupHMDControls: function () { this.dolly = new THREE.Object3D(); this.euler = new THREE.Euler(); this.controls = new THREE.VRControls(this.dolly); this.zeroQuaternion = new THREE.Quaternion(); }, addEventListeners: function () { var sceneEl = this.el.sceneEl; var canvasEl = sceneEl.canvas; // listen for canvas to load. if (!canvasEl) { sceneEl.addEventListener('render-target-loaded', this.addEventListeners.bind(this)); return; } // Mouse Events canvasEl.addEventListener('mousedown', this.onMouseDown, false); canvasEl.addEventListener('mousemove', this.onMouseMove, false); canvasEl.addEventListener('mouseup', this.releaseMouse, false); canvasEl.addEventListener('mouseout', this.releaseMouse, false); // Touch events canvasEl.addEventListener('touchstart', this.onTouchStart); canvasEl.addEventListener('touchmove', this.onTouchMove); canvasEl.addEventListener('touchend', this.onTouchEnd); }, removeEventListeners: function () { var sceneEl = document.querySelector('a-scene'); var canvasEl = sceneEl && sceneEl.canvas; if (!canvasEl) { return; } // Mouse Events canvasEl.removeEventListener('mousedown', this.onMouseDown); canvasEl.removeEventListener('mousemove', this.onMouseMove); canvasEl.removeEventListener('mouseup', this.releaseMouse); canvasEl.removeEventListener('mouseout', this.releaseMouse); // Touch events canvasEl.removeEventListener('touchstart', this.onTouchStart); canvasEl.removeEventListener('touchmove', this.onTouchMove); canvasEl.removeEventListener('touchend', this.onTouchEnd); }, updateOrientation: (function () { var hmdEuler = new THREE.Euler(); hmdEuler.order = 'YXZ'; return function () { var pitchObject = this.pitchObject; var yawObject = this.yawObject; var hmdQuaternion = this.calculateHMDQuaternion(); hmdEuler.setFromQuaternion(hmdQuaternion); this.el.setAttribute('rotation', { x: THREE.Math.radToDeg(hmdEuler.x) + THREE.Math.radToDeg(pitchObject.rotation.x), y: THREE.Math.radToDeg(hmdEuler.y) + THREE.Math.radToDeg(yawObject.rotation.y), z: THREE.Math.radToDeg(hmdEuler.z) + THREE.Math.radToDeg(yawObject.rotation.z) }); }; })(), calculateHMDQuaternion: (function () { var hmdQuaternion = new THREE.Quaternion(); return function () { var dolly = this.dolly; if (!this.zeroed && !dolly.quaternion.equals(this.zeroQuaternion)) { this.zeroOrientation(); this.zeroed = true; } hmdQuaternion.copy(this.zeroQuaternion).multiply(dolly.quaternion); return hmdQuaternion; }; })(), updatePosition: (function () { var position = new THREE.Vector3(); var quaternion = new THREE.Quaternion(); var scale = new THREE.Vector3(); return function () { var el = this.el; var deltaPosition = this.calculateDeltaPosition(); var currentPosition = this.target3D.position; this.el.object3D.matrixWorld.decompose(position, quaternion, scale); deltaPosition.applyQuaternion(quaternion); // Reset the Camera to 0 el.setAttribute('position', { x: this.target3D.position.x, y: this.target3D.position.y, z: this.target3D.position.z }); var targetCameraPosition = camera.object3D.translateOnAxis( new THREE.Vector3(0,0,1), this.distance ).position; el.setAttribute('position', { x: targetCameraPosition.x, y: targetCameraPosition.y, z: targetCameraPosition.z }); }; })(), calculateDeltaPosition: function () { var dolly = this.dolly; var deltaPosition = this.deltaPosition; var previousPosition = this.previousPosition; deltaPosition.copy(dolly.position); deltaPosition.sub(previousPosition); previousPosition.copy(dolly.position); return deltaPosition; }, updateHMDQuaternion: (function () { var hmdQuaternion = new THREE.Quaternion(); return function () { var dolly = this.dolly; this.controls.update(); if (!this.zeroed && !dolly.quaternion.equals(this.zeroQuaternion)) { this.zeroOrientation(); this.zeroed = true; } hmdQuaternion.copy(this.zeroQuaternion).multiply(dolly.quaternion); return hmdQuaternion; }; })(), zeroOrientation: function () { var euler = new THREE.Euler(); euler.setFromQuaternion(this.dolly.quaternion.clone().inverse()); // Cancel out roll and pitch. We want to only reset yaw euler.z = 0; euler.x = 0; this.zeroQuaternion.setFromEuler(euler); }, onMouseMove: function (event) { var pitchObject = this.pitchObject; var yawObject = this.yawObject; var previousMouseEvent = this.previousMouseEvent; if (!this.mouseDown || !this.data.enabled) { return; } var movementX = event.movementX || event.mozMovementX; var movementY = event.movementY || event.mozMovementY; if (movementX === undefined || movementY === undefined) { movementX = event.screenX - previousMouseEvent.screenX; movementY = event.screenY - previousMouseEvent.screenY; } this.previousMouseEvent = event; yawObject.rotation.y -= movementX * 0.002; pitchObject.rotation.x -= movementY * 0.002; pitchObject.rotation.x = Math.max(-PI_2, Math.min(PI_2, pitchObject.rotation.x)); }, onMouseDown: function (event) { this.mouseDown = true; this.previousMouseEvent = event; }, releaseMouse: function () { this.mouseDown = false; }, onTouchStart: function (e) { if (e.touches.length !== 1) { return; } this.touchStart = { x: e.touches[0].pageX, y: e.touches[0].pageY }; this.touchStarted = true; }, onTouchMove: function (e) { var deltaY; var yawObject = this.yawObject; if (!this.touchStarted) { return; } deltaY = 2 * Math.PI * (e.touches[0].pageX - this.touchStart.x) / this.el.sceneEl.canvas.clientWidth; // Limits touch orientaion to to yaw (y axis) yawObject.rotation.y -= deltaY * 0.5; this.touchStart = { x: e.touches[0].pageX, y: e.touches[0].pageY }; }, onTouchEnd: function () { this.touchStarted = false; } }); },{}],3:[function(require,module,exports){ (function (global){ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.AFRAME = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ 'use strict'; // For more information about browser field, check out the browser field at https://github.com/substack/browserify-handbook#browser-field. module.exports = { // Create a <link> tag with optional data attributes createLink: function(href, attributes) { var head = document.head || document.getElementsByTagName('head')[0]; var link = document.createElement('link'); link.href = href; link.rel = 'stylesheet'; for (var key in attributes) { if ( ! attributes.hasOwnProperty(key)) { continue; } var value = attributes[key]; link.setAttribute('data-' + key, value); } head.appendChild(link); }, // Create a <style> tag with optional data attributes createStyle: function(cssText, attributes) { var head = document.head || document.getElementsByTagName('head')[0], style = document.createElement('style'); style.type = 'text/css'; for (var key in attributes) { if ( ! attributes.hasOwnProperty(key)) { continue; } var value = attributes[key]; style.setAttribute('data-' + key, value); } if (style.sheet) { // for jsdom and IE9+ style.innerHTML = cssText; style.sheet.cssText = cssText; head.appendChild(style); } else if (style.styleSheet) { // for IE8 and below head.appendChild(style); style.styleSheet.cssText = cssText; } else { // for Chrome, Firefox, and Safari style.appendChild(document.createTextNode(cssText)); head.appendChild(style); } } }; },{}],2:[function(_dereq_,module,exports){ // shim for using process in browser var process = module.exports = {}; var queue = []; var draining = false; var currentQueue; var queueIndex = -1; function cleanUpNextTick() { draining = false; if (currentQueue.length) { queue = currentQueue.concat(queue); } else { queueIndex = -1; } if (queue.length) { drainQueue(); } } function drainQueue() { if (draining) { return; } var timeout = setTimeout(cleanUpNextTick); draining = true; var len = queue.length; while(len) { currentQueue = queue; queue = []; while (++queueIndex < len) { if (currentQueue) { currentQueue[queueIndex].run(); } } queueIndex = -1; len = queue.length; } currentQueue = null; draining = false; clearTimeout(timeout); } process.nextTick = function (fun) { var args = new Array(arguments.length - 1); if (arguments.length > 1) { for (var i = 1; i < arguments.length; i++) { args[i - 1] = arguments[i]; } } queue.push(new Item(fun, args)); if (queue.length === 1 && !draining) { setTimeout(drainQueue, 0); } }; // v8 likes predictible objects function Item(fun, array) { this.fun = fun; this.array = array; } Item.prototype.run = function () { this.fun.apply(null, this.array); }; process.title = 'browser'; process.browser = true; process.env = {}; process.argv = []; process.version = ''; // empty string to avoid regexp issues process.versions = {}; function noop() {} process.on = noop; process.addListener = noop; process.once = noop; process.off = noop; process.removeListener = noop; process.removeAllListeners = noop; process.emit = noop; process.binding = function (name) { throw new Error('process.binding is not supported'); }; process.cwd = function () { return '/' }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; process.umask = function() { return 0; }; },{}],3:[function(_dereq_,module,exports){ /** * This is the web browser implementation of `debug()`. * * Expose `debug()` as the module. */ exports = module.exports = _dereq_('./debug'); exports.log = log; exports.formatArgs = formatArgs; exports.save = save; exports.load = load; exports.useColors = useColors; exports.storage = 'undefined' != typeof chrome && 'undefined' != typeof chrome.storage ? chrome.storage.local : localstorage(); /** * Colors. */ exports.colors = [ 'lightseagreen', 'forestgreen', 'goldenrod', 'dodgerblue', 'darkorchid', 'crimson' ]; /** * Currently only WebKit-based Web Inspectors, Firefox >= v31, * and the Firebug extension (any Firefox version) are known * to support "%c" CSS customizations. * * TODO: add a `localStorage` variable to explicitly enable/disable colors */ function useColors() { // is webkit? http://stackoverflow.com/a/16459606/376773 return ('WebkitAppearance' in document.documentElement.style) || // is firebug? http://stackoverflow.com/a/398120/376773 (window.console && (console.firebug || (console.exception && console.table))) || // is firefox >= v31? // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages (navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31); } /** * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. */ exports.formatters.j = function(v) { return JSON.stringify(v); }; /** * Colorize log arguments if enabled. * * @api public */ function formatArgs() { var args = arguments; var useColors = this.useColors; args[0] = (useColors ? '%c' : '') + this.namespace + (useColors ? ' %c' : ' ') + args[0] + (useColors ? '%c ' : ' ') + '+' + exports.humanize(this.diff); if (!useColors) return args; var c = 'color: ' + this.color; args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1)); // the final "%c" is somewhat tricky, because there could be other // arguments passed either before or after the %c, so we need to // figure out the correct index to insert the CSS into var index = 0; var lastC = 0; args[0].replace(/%[a-z%]/g, function(match) { if ('%%' === match) return; index++; if ('%c' === match) { // we only are interested in the *last* %c // (the user may have provided their own) lastC = index; } }); args.splice(lastC, 0, c); return args; } /** * Invokes `console.log()` when available. * No-op when `console.log` is not a "function". * * @api public */ function log() { // this hackery is required for IE8/9, where // the `console.log` function doesn't have 'apply' return 'object' === typeof console && console.log && Function.prototype.apply.call(console.log, console, arguments); } /** * Save `namespaces`. * * @param {String} namespaces * @api private */ function save(namespaces) { try { if (null == namespaces) { exports.storage.removeItem('debug'); } else { exports.storage.debug = namespaces; } } catch(e) {} } /** * Load `namespaces`. * * @return {String} returns the previously persisted debug modes * @api private */ function load() { var r; try { r = exports.storage.debug; } catch(e) {} return r; } /** * Enable namespaces listed in `localStorage.debug` initially. */ exports.enable(load()); /** * Localstorage attempts to return the localstorage. * * This is necessary because safari throws * when a user disables cookies/localstorage * and you attempt to access it. * * @return {LocalStorage} * @api private */ function localstorage(){ try { return window.localStorage; } catch (e) {} } },{"./debug":4}],4:[function(_dereq_,module,exports){ /** * This is the common logic for both the Node.js and web browser * implementations of `debug()`. * * Expose `debug()` as the module. */ exports = module.exports = debug; exports.coerce = coerce; exports.disable = disable; exports.enable = enable; exports.enabled = enabled; exports.humanize = _dereq_('ms'); /** * The currently active debug mode names, and names to skip. */ exports.names = []; exports.skips = []; /** * Map of special "%n" handling functions, for the debug "format" argument. * * Valid key names are a single, lowercased letter, i.e. "n". */ exports.formatters = {}; /** * Previously assigned color. */ var prevColor = 0; /** * Previous log timestamp. */ var prevTime; /** * Select a color. * * @return {Number} * @api private */ function selectColor() { return exports.colors[prevColor++ % exports.colors.length]; } /** * Create a debugger with the given `namespace`. * * @param {String} namespace * @return {Function} * @api public */ function debug(namespace) { // define the `disabled` version function disabled() { } disabled.enabled = false; // define the `enabled` version function enabled() { var self = enabled; // set `diff` timestamp var curr = +new Date(); var ms = curr - (prevTime || curr); self.diff = ms; self.prev = prevTime; self.curr = curr; prevTime = curr; // add the `color` if not set if (null == self.useColors) self.useColors = exports.useColors(); if (null == self.color && self.useColors) self.color = selectColor(); var args = Array.prototype.slice.call(arguments); args[0] = exports.coerce(args[0]); if ('string' !== typeof args[0]) { // anything else let's inspect with %o args = ['%o'].concat(args); } // apply any `formatters` transformations var index = 0; args[0] = args[0].replace(/%([a-z%])/g, function(match, format) { // if we encounter an escaped % then don't increase the array index if (match === '%%') return match; index++; var formatter = exports.formatters[format]; if ('function' === typeof formatter) { var val = args[index]; match = formatter.call(self, val); // now we need to remove `args[index]` since it's inlined in the `format` args.splice(index, 1); index--; } return match; }); if ('function' === typeof exports.formatArgs) { args = exports.formatArgs.apply(self, args); } var logFn = enabled.log || exports.log || console.log.bind(console); logFn.apply(self, args); } enabled.enabled = true; var fn = exports.enabled(namespace) ? enabled : disabled; fn.namespace = namespace; return fn; } /** * Enables a debug mode by namespaces. This can include modes * separated by a colon and wildcards. * * @param {String} namespaces * @api public */ function enable(namespaces) { exports.save(namespaces); var split = (namespaces || '').split(/[\s,]+/); var len = split.length; for (var i = 0; i < len; i++) { if (!split[i]) continue; // ignore empty strings namespaces = split[i].replace(/\*/g, '.*?'); if (namespaces[0] === '-') { exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); } else { exports.names.push(new RegExp('^' + namespaces + '$')); } } } /** * Disable debug output. * * @api public */ function disable() { exports.enable(''); } /** * Returns true if the given mode name is enabled, false otherwise. * * @param {String} name * @return {Boolean} * @api public */ function enabled(name) { var i, len; for (i = 0, len = exports.skips.length; i < len; i++) { if (exports.skips[i].test(name)) { return false; } } for (i = 0, len = exports.names.length; i < len; i++) { if (exports.names[i].test(name)) { return true; } } return false; } /** * Coerce `val`. * * @param {Mixed} val * @return {Mixed} * @api private */ function coerce(val) { if (val instanceof Error) return val.stack || val.message; return val; } },{"ms":5}],5:[function(_dereq_,module,exports){ /** * Helpers. */ var s = 1000; var m = s * 60; var h = m * 60; var d = h * 24; var y = d * 365.25; /** * Parse or format the given `val`. * * Options: * * - `long` verbose formatting [false] * * @param {String|Number} val * @param {Object} options * @return {String|Number} * @api public */ module.exports = function(val, options){ options = options || {}; if ('string' == typeof val) return parse(val); return options.long ? long(val) : short(val); }; /** * Parse the given `str` and return milliseconds. * * @param {String} str * @return {Number} * @api private */ function parse(str) { str = '' + str; if (str.length > 10000) return; var match = /^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str); if (!match) return; var n = parseFloat(match[1]); var type = (match[2] || 'ms').toLowerCase(); switch (type) { case 'years': case 'year': case 'yrs': case 'yr': case 'y': return n * y; case 'days': case 'day': case 'd': return n * d; case 'hours': case 'hour': case 'hrs': case 'hr': case 'h': return n * h; case 'minutes': case 'minute': case 'mins': case 'min': case 'm': return n * m; case 'seconds': case 'second': case 'secs': case 'sec': case 's': return n * s; case 'milliseconds': case 'millisecond': case 'msecs': case 'msec': case 'ms': return n; } } /** * Short format for `ms`. * * @param {Number} ms * @return {String} * @api private */ function short(ms) { if (ms >= d) return Math.round(ms / d) + 'd'; if (ms >= h) return Math.round(ms / h) + 'h'; if (ms >= m) return Math.round(ms / m) + 'm'; if (ms >= s) return Math.round(ms / s) + 's'; return ms + 'ms'; } /** * Long format for `ms`. * * @param {Number} ms * @return {String} * @api private */ function long(ms) { return plural(ms, d, 'day') || plural(ms, h, 'hour') || plural(ms, m, 'minute') || plural(ms, s, 'second') || ms + ' ms'; } /** * Pluralization helper. */ function plural(ms, n, name) { if (ms < n) return; if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name; return Math.ceil(ms / n) + ' ' + name + 's'; } },{}],6:[function(_dereq_,module,exports){ 'use strict'; var isObj = _dereq_('is-obj'); var hasOwnProperty = Object.prototype.hasOwnProperty; var propIsEnumerable = Object.prototype.propertyIsEnumerable; function toObject(val) { if (val === null || val === undefined) { throw new TypeError('Sources cannot be null or undefined'); } return Object(val); } function assignKey(to, from, key) { var val = from[key]; if (val === undefined || val === null) { return; } if (hasOwnProperty.call(to, key)) { if (to[key] === undefined || to[key] === null) { throw new TypeError('Cannot convert undefined or null to object (' + key + ')'); } } if (!hasOwnProperty.call(to, key) || !isObj(val)) { to[key] = val; } else { to[key] = assign(Object(to[key]), from[key]); } } function assign(to, from) { if (to === from) { return to; } from = Object(from); for (var key in from) { if (hasOwnProperty.call(from, key)) { assignKey(to, from, key); } } if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(from); for (var i = 0; i < symbols.length; i++) { if (propIsEnumerable.call(from, symbols[i])) { assignKey(to, from, symbols[i]); } } } return to; } module.exports = function deepAssign(target) { target = toObject(target); for (var s = 1; s < arguments.length; s++) { assign(target, arguments[s]); } return target; }; },{"is-obj":7}],7:[function(_dereq_,module,exports){ 'use strict'; module.exports = function (x) { var type = typeof x; return x !== null && (type === 'object' || type === 'function'); }; },{}],8:[function(_dereq_,module,exports){ /*! (C) WebReflection Mit Style License */ (function(e,t,n,r){"use strict";function rt(e,t){for(var n=0,r=e.length;n<r;n++)vt(e[n],t)}function it(e){for(var t=0,n=e.length,r;t<n;t++)r=e[t],nt(r,b[ot(r)])}function st(e){return function(t){j(t)&&(vt(t,e),rt(t.querySelectorAll(w),e))}}function ot(e){var t=e.getAttribute("is"),n=e.nodeName.toUpperCase(),r=S.call(y,t?v+t.toUpperCase():d+n);return t&&-1<r&&!ut(n,t)?-1:r}function ut(e,t){return-1<w.indexOf(e+'[is="'+t+'"]')}function at(e){var t=e.currentTarget,n=e.attrChange,r=e.attrName,i=e.target;Q&&(!i||i===t)&&t.attributeChangedCallback&&r!=="style"&&e.prevValue!==e.newValue&&t.attributeChangedCallback(r,n===e[a]?null:e.prevValue,n===e[l]?null:e.newValue)}function ft(e){var t=st(e);return function(e){X.push(t,e.target)}}function lt(e){K&&(K=!1,e.currentTarget.removeEventListener(h,lt)),rt((e.target||t).querySelectorAll(w),e.detail===o?o:s),B&&pt()}function ct(e,t){var n=this;q.call(n,e,t),G.call(n,{target:n})}function ht(e,t){D(e,t),et?et.observe(e,z):(J&&(e.setAttribute=ct,e[i]=Z(e),e.addEventListener(p,G)),e.addEventListener(c,at)),e.createdCallback&&Q&&(e.created=!0,e.createdCallback(),e.created=!1)}function pt(){for(var e,t=0,n=F.length;t<n;t++)e=F[t],E.contains(e)||(n--,F.splice(t--,1),vt(e,o))}function dt(e){throw new Error("A "+e+" type is already registered")}function vt(e,t){var n,r=ot(e);-1<r&&(tt(e,b[r]),r=0,t===s&&!e[s]?(e[o]=!1,e[s]=!0,r=1,B&&S.call(F,e)<0&&F.push(e)):t===o&&!e[o]&&(e[s]=!1,e[o]=!0,r=1),r&&(n=e[t+"Callback"])&&n.call(e))}if(r in t)return;var i="__"+r+(Math.random()*1e5>>0),s="attached",o="detached",u="extends",a="ADDITION",f="MODIFICATION",l="REMOVAL",c="DOMAttrModified",h="DOMContentLoaded",p="DOMSubtreeModified",d="<",v="=",m=/^[A-Z][A-Z0-9]*(?:-[A-Z0-9]+)+$/,g=["ANNOTATION-XML","COLOR-PROFILE","FONT-FACE","FONT-FACE-SRC","FONT-FACE-URI","FONT-FACE-FORMAT","FONT-FACE-NAME","MISSING-GLYPH"],y=[],b=[],w="",E=t.documentElement,S=y.indexOf||function(e){for(var t=this.length;t--&&this[t]!==e;);return t},x=n.prototype,T=x.hasOwnProperty,N=x.isPrototypeOf,C=n.defineProperty,k=n.getOwnPropertyDescriptor,L=n.getOwnPropertyNames,A=n.getPrototypeOf,O=n.setPrototypeOf,M=!!n.__proto__,_=n.create||function mt(e){return e?(mt.prototype=e,new mt):this},D=O||(M?function(e,t){return e.__proto__=t,e}:L&&k?function(){function e(e,t){for(var n,r=L(t),i=0,s=r.length;i<s;i++)n=r[i],T.call(e,n)||C(e,n,k(t,n))}return function(t,n){do e(t,n);while((n=A(n))&&!N.call(n,t));return t}}():function(e,t){for(var n in t)e[n]=t[n];return e}),P=e.MutationObserver||e.WebKitMutationObserver,H=(e.HTMLElement||e.Element||e.Node).prototype,B=!N.call(H,E),j=B?function(e){return e.nodeType===1}:function(e){return N.call(H,e)},F=B&&[],I=H.cloneNode,q=H.setAttribute,R=H.removeAttribute,U=t.createElement,z=P&&{attributes:!0,characterData:!0,attributeOldValue:!0},W=P||function(e){J=!1,E.removeEventListener(c,W)},X,V=e.requestAnimationFrame||e.webkitRequestAnimationFrame||e.mozRequestAnimationFrame||e.msRequestAnimationFrame||function(e){setTimeout(e,10)},$=!1,J=!0,K=!0,Q=!0,G,Y,Z,et,tt,nt;O||M?(tt=function(e,t){N.call(t,e)||ht(e,t)},nt=ht):(tt=function(e,t){e[i]||(e[i]=n(!0),ht(e,t))},nt=tt),B?(J=!1,function(){var e=k(H,"addEventListener"),t=e.value,n=function(e){var t=new CustomEvent(c,{bubbles:!0});t.attrName=e,t.prevValue=this.getAttribute(e),t.newValue=null,t[l]=t.attrChange=2,R.call(this,e),this.dispatchEvent(t)},r=function(e,t){var n=this.hasAttribute(e),r=n&&this.getAttribute(e),i=new CustomEvent(c,{bubbles:!0});q.call(this,e,t),i.attrName=e,i.prevValue=n?r:null,i.newValue=t,n?i[f]=i.attrChange=1:i[a]=i.attrChange=0,this.dispatchEvent(i)},s=function(e){var t=e.currentTarget,n=t[i],r=e.propertyName,s;n.hasOwnProperty(r)&&(n=n[r],s=new CustomEvent(c,{bubbles:!0}),s.attrName=n.name,s.prevValue=n.value||null,s.newValue=n.value=t[r]||null,s.prevValue==null?s[a]=s.attrChange=0:s[f]=s.attrChange=1,t.dispatchEvent(s))};e.value=function(e,o,u){e===c&&this.attributeChangedCallback&&this.setAttribute!==r&&(this[i]={className:{name:"class",value:this.className}},this.setAttribute=r,this.removeAttribute=n,t.call(this,"propertychange",s)),t.call(this,e,o,u)},C(H,"addEventListener",e)}()):P||(E.addEventListener(c,W),E.setAttribute(i,1),E.removeAttribute(i),J&&(G=function(e){var t=this,n,r,s;if(t===e.target){n=t[i],t[i]=r=Z(t);for(s in r){if(!(s in n))return Y(0,t,s,n[s],r[s],a);if(r[s]!==n[s])return Y(1,t,s,n[s],r[s],f)}for(s in n)if(!(s in r))return Y(2,t,s,n[s],r[s],l)}},Y=function(e,t,n,r,i,s){var o={attrChange:e,currentTarget:t,attrName:n,prevValue:r,newValue:i};o[s]=e,at(o)},Z=function(e){for(var t,n,r={},i=e.attributes,s=0,o=i.length;s<o;s++)t=i[s],n=t.name,n!=="setAttribute"&&(r[n]=t.value);return r})),t[r]=function(n,r){c=n.toUpperCase(),$||($=!0,P?(et=function(e,t){function n(e,t){for(var n=0,r=e.length;n<r;t(e[n++]));}return new P(function(r){for(var i,s,o,u=0,a=r.length;u<a;u++)i=r[u],i.type==="childList"?(n(i.addedNodes,e),n(i.removedNodes,t)):(s=i.target,Q&&s.attributeChangedCallback&&i.attributeName!=="style"&&(o=s.getAttribute(i.attributeName),o!==i.oldValue&&s.attributeChangedCallback(i.attributeName,i.oldValue,o)))})}(st(s),st(o)),et.observe(t,{childList:!0,subtree:!0})):(X=[],V(function E(){while(X.length)X.shift().call(null,X.shift());V(E)}),t.addEventListener("DOMNodeInserted",ft(s)),t.addEventListener("DOMNodeRemoved",ft(o))),t.addEventListener(h,lt),t.addEventListener("readystatechange",lt),t.createElement=function(e,n){var r=U.apply(t,arguments),i=""+e,s=S.call(y,(n?v:d)+(n||i).toUpperCase()),o=-1<s;return n&&(r.setAttribute("is",n=n.toLowerCase()),o&&(o=ut(i.toUpperCase(),n))),Q=!t.createElement.innerHTMLHelper,o&&nt(r,b[s]),r},H.cloneNode=function(e){var t=I.call(this,!!e),n=ot(t);return-1<n&&nt(t,b[n]),e&&it(t.querySelectorAll(w)),t}),-2<S.call(y,v+c)+S.call(y,d+c)&&dt(n);if(!m.test(c)||-1<S.call(g,c))throw new Error("The type "+n+" is invalid");var i=function(){return f?t.createElement(l,c):t.createElement(l)},a=r||x,f=T.call(a,u),l=f?r[u].toUpperCase():c,c,p;return f&&-1<S.call(y,d+l)&&dt(l),p=y.push((f?v:d)+c)-1,w=w.concat(w.length?",":"",f?l+'[is="'+n.toLowerCase()+'"]':l),i.prototype=b[p]=T.call(a,"prototype")?a.prototype:_(H),rt(t.querySelectorAll(w),s),i}})(window,document,Object,"registerElement"); },{}],9:[function(_dereq_,module,exports){ /* eslint-disable no-unused-vars */ 'use strict'; var hasOwnProperty = Object.prototype.hasOwnProperty; var propIsEnumerable = Object.prototype.propertyIsEnumerable; function toObject(val) { if (val === null || val === undefined) { throw new TypeError('Object.assign cannot be called with null or undefined'); } return Object(val); } module.exports = Object.assign || function (target, source) { var from; var to = toObject(target); var symbols; for (var s = 1; s < arguments.length; s++) { from = Object(arguments[s]); for (var key in from) { if (hasOwnProperty.call(from, key)) { to[key] = from[key]; } } if (Object.getOwnPropertySymbols) { symbols = Object.getOwnPropertySymbols(from); for (var i = 0; i < symbols.length; i++) { if (propIsEnumerable.call(from, symbols[i])) { to[symbols[i]] = from[symbols[i]]; } } } } return to; }; },{}],10:[function(_dereq_,module,exports){ (function (global){ var performance = global.performance || {}; var present = (function () { var names = ['now', 'webkitNow', 'msNow', 'mozNow', 'oNow']; while (names.length) { var name = names.shift(); if (name in performance) { return performance[name].bind(performance); } } var dateNow = Date.now || function () { return new Date().getTime(); }; var navigationStart = (performance.timing || {}).navigationStart || dateNow(); return function () { return dateNow() - navigationStart; }; }()); present.performanceNow = performance.now; present.noConflict = function () { performance.now = present.performanceNow; }; present.conflict = function () { performance.now = present; }; present.conflict(); module.exports = present; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{}],11:[function(_dereq_,module,exports){ (function(root) { // Store setTimeout reference so promise-polyfill will be unaffected by // other code modifying setTimeout (like sinon.useFakeTimers()) var setTimeoutFunc = setTimeout; // Use polyfill for setImmediate for performance gains var asap = (typeof setImmediate === 'function' && setImmediate) || function(fn) { setTimeoutFunc(fn, 1); }; // Polyfill for Function.prototype.bind function bind(fn, thisArg) { return function() { fn.apply(thisArg, arguments); } } var isArray = Array.isArray || function(value) { return Object.prototype.toString.call(value) === "[object Array]" }; function Promise(fn) { if (typeof this !== 'object') throw new TypeError('Promises must be constructed via new'); if (typeof fn !== 'function') throw new TypeError('not a function'); this._state = null; this._value = null; this._deferreds = [] doResolve(fn, bind(resolve, this), bind(reject, this)) } function handle(deferred) { var me = this; if (this._state === null) { this._deferreds.push(deferred); return } asap(function() { var cb = me._state ? deferred.onFulfilled : deferred.onRejected if (cb === null) { (me._state ? deferred.resolve : deferred.reject)(me._value); return; } var ret; try { ret = cb(me._value); } catch (e) { deferred.reject(e); return; } deferred.resolve(ret); }) } function resolve(newValue) { try { //Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure if (newValue === this) throw new TypeError('A promise cannot be resolved with itself.'); if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) { var then = newValue.then; if (typeof then === 'function') { doResolve(bind(then, newValue), bind(resolve, this), bind(reject, this)); return; } } this._state = true; this._value = newValue; finale.call(this); } catch (e) { reject.call(this, e); } } function reject(newValue) { this._state = false; this._value = newValue; finale.call(this); } function finale() { for (var i = 0, len = this._deferreds.length; i < len; i++) { handle.call(this, this._deferreds[i]); } this._deferreds = null; } function Handler(onFulfilled, onRejected, resolve, reject){ this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; this.onRejected = typeof onRejected === 'function' ? onRejected : null; this.resolve = resolve; this.reject = reject; } /** * Take a potentially misbehaving resolver function and make sure * onFulfilled and onRejected are only called once. * * Makes no guarantees about asynchrony. */ function doResolve(fn, onFulfilled, onRejected) { var done = false; try { fn(function (value) { if (done) return; done = true; onFulfilled(value); }, function (reason) { if (done) return; done = true; onRejected(reason); }) } catch (ex) { if (done) return; done = true; onRejected(ex); } } Promise.prototype['catch'] = function (onRejected) { return this.then(null, onRejected); }; Promise.prototype.then = function(onFulfilled, onRejected) { var me = this; return new Promise(function(resolve, reject) { handle.call(me, new Handler(onFulfilled, onRejected, resolve, reject)); }) }; Promise.all = function () { var args = Array.prototype.slice.call(arguments.length === 1 && isArray(arguments[0]) ? arguments[0] : arguments); return new Promise(function (resolve, reject) { if (args.length === 0) return resolve([]); var remaining = args.length; function res(i, val) { try { if (val && (typeof val === 'object' || typeof val === 'function')) { var then = val.then; if (typeof then === 'function') { then.call(val, function (val) { res(i, val) }, reject); return; } } args[i] = val; if (--remaining === 0) { resolve(args); } } catch (ex) { reject(ex); } } for (var i = 0; i < args.length; i++) { res(i, args[i]); } }); }; Promise.resolve = function (value) { if (value && typeof value === 'object' && value.constructor === Promise) { return value; } return new Promise(function (resolve) { resolve(value); }); }; Promise.reject = function (value) { return new Promise(function (resolve, reject) { reject(value); }); }; Promise.race = function (values) { return new Promise(function (resolve, reject) { for(var i = 0, len = values.length; i < len; i++) { values[i].then(resolve, reject); } }); }; /** * Set the immediate function to execute callbacks * @param fn {function} Function to execute * @private */ Promise._setImmediateFn = function _setImmediateFn(fn) { asap = fn; }; if (typeof module !== 'undefined' && module.exports) { module.exports = Promise; } else if (!root.Promise) { root.Promise = Promise; } })(this); },{}],12:[function(_dereq_,module,exports){ 'use strict'; var raf = _dereq_('raf'); var now = _dereq_('time-now'); exports = module.exports = interval; function interval(delay, fn, ctx) { var start = now(); var data = Object.create(null); data.id = raf(loop); return data; function loop() { data.id = raf(loop); if ((now() - start) >= delay) { fn.call(ctx); start = now(); } } } exports.clear = clearInterval; function clearInterval(data) { raf.cancel(data.id); } },{"raf":13,"time-now":14}],13:[function(_dereq_,module,exports){ /** * Expose `requestAnimationFrame()`. */ exports = module.exports = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || fallback; /** * Fallback implementation. */ var prev = new Date().getTime(); function fallback(fn) { var curr = new Date().getTime(); var ms = Math.max(0, 16 - (curr - prev)); var req = setTimeout(fn, ms); prev = curr; return req; } /** * Cancel. */ var cancel = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.clearTimeout; exports.cancel = function(id){ cancel.call(window, id); }; },{}],14:[function(_dereq_,module,exports){ 'use strict'; module.exports = (function() { var perf = window && window.performance; if (perf && perf.now) { return perf.now.bind(perf); } else { return function() { return new Date().getTime(); }; } }()); },{}],15:[function(_dereq_,module,exports){ /* style-attr ==== Very simple parsing and stringifying of style attributes. `parse` ---- Convert a style attribute string to an object. - input: string (eg. anything you might see in a style attribute) - return: object */ function parse (raw) { var trim = function (s) { return s.trim(); }; var obj = {}; getKeyValueChunks(raw) .map(trim) .filter(Boolean) .forEach(function (item) { // split with `.indexOf` rather than `.split` because the value may also contain colons. var pos = item.indexOf(':'); var key = item.substr(0, pos).trim(); var val = item.substr(pos + 1).trim(); obj[key] = val; }); return obj; } /* `getKeyValueChunks` ---- Split a string into chunks matching `<key>: <value>` - input: string - return: Array<string> */ function getKeyValueChunks (raw) { var chunks = []; var offset = 0; var sep = ';'; var hasUnclosedUrl = /url\([^\)]+$/; var chunk = ''; var nextSplit; while (offset < raw.length) { nextSplit = raw.indexOf(sep, offset); if (nextSplit === -1) { nextSplit = raw.length; } chunk += raw.substring(offset, nextSplit); // data URIs can contain semicolons, so make sure we get the whole thing if (hasUnclosedUrl.test(chunk)) { chunk += ';'; offset = nextSplit + 1; continue; } chunks.push(chunk); chunk = ''; offset = nextSplit + 1; } return chunks; } /* `stringify` ---- Convert an object into an attribute string - input: object - return: string */ function stringify (obj) { return Object.keys(obj) .map(function (key) { return key + ':' + obj[key]; }) .join(';'); } /* `normalize` ---- Normalize an attribute string (eg. collapse duplicates) - input: string - return: string */ function normalize (str) { return stringify(parse(str)); } module.exports.parse = parse; module.exports.stringify = stringify; module.exports.normalize = normalize; },{}],16:[function(_dereq_,module,exports){ /** * @author Tim Knip / http://www.floorplanner.com/ / tim at floorplanner.com * @author Tony Parisi / http://www.tonyparisi.com/ */ THREE.ColladaLoader = function () { var COLLADA = null; var scene = null; var visualScene; var kinematicsModel; var readyCallbackFunc = null; var sources = {}; var images = {}; var animations = {}; var controllers = {}; var geometries = {}; var materials = {}; var effects = {}; var cameras = {}; var lights = {}; var animData; var kinematics; var visualScenes; var kinematicsModels; var baseUrl; var morphs; var skins; var flip_uv = true; var preferredShading = THREE.SmoothShading; var options = { // Force Geometry to always be centered at the local origin of the // containing Mesh. centerGeometry: false, // Axis conversion is done for geometries, animations, and controllers. // If we ever pull cameras or lights out of the COLLADA file, they'll // need extra work. convertUpAxis: false, subdivideFaces: true, upAxis: 'Y', // For reflective or refractive materials we'll use this cubemap defaultEnvMap: null }; var colladaUnit = 1.0; var colladaUp = 'Y'; var upConversion = null; function load ( url, readyCallback, progressCallback, failCallback ) { var length = 0; if ( document.implementation && document.implementation.createDocument ) { var request = new XMLHttpRequest(); request.onreadystatechange = function() { if ( request.readyState === 4 ) { if ( request.status === 0 || request.status === 200 ) { if ( request.response ) { readyCallbackFunc = readyCallback; parse( request.response, undefined, url ); } else { if ( failCallback ) { failCallback(); } else { console.error( "ColladaLoader: Empty or non-existing file (" + url + ")" ); } } } } else if ( request.readyState === 3 ) { if ( progressCallback ) { if ( length === 0 ) { length = request.getResponseHeader( "Content-Length" ); } progressCallback( { total: length, loaded: request.responseText.length } ); } } }; request.open( "GET", url, true ); request.send( null ); } else { alert( "Don't know how to parse XML!" ); } } function parse( text, callBack, url ) { COLLADA = new DOMParser().parseFromString( text, 'text/xml' ); callBack = callBack || readyCallbackFunc; if ( url !== undefined ) { var parts = url.split( '/' ); parts.pop(); baseUrl = ( parts.length < 1 ? '.' : parts.join( '/' ) ) + '/'; } parseAsset(); setUpConversion(); images = parseLib( "library_images image", _Image, "image" ); materials = parseLib( "library_materials material", Material, "material" ); effects = parseLib( "library_effects effect", Effect, "effect" ); geometries = parseLib( "library_geometries geometry", Geometry, "geometry" ); cameras = parseLib( "library_cameras camera", Camera, "camera" ); lights = parseLib( "library_lights light", Light, "light" ); controllers = parseLib( "library_controllers controller", Controller, "controller" ); animations = parseLib( "library_animations animation", Animation, "animation" ); visualScenes = parseLib( "library_visual_scenes visual_scene", VisualScene, "visual_scene" ); kinematicsModels = parseLib( "library_kinematics_models kinematics_model", KinematicsModel, "kinematics_model" ); morphs = []; skins = []; visualScene = parseScene(); scene = new THREE.Group(); for ( var i = 0; i < visualScene.nodes.length; i ++ ) { scene.add( createSceneGraph( visualScene.nodes[ i ] ) ); } // unit conversion scene.scale.multiplyScalar( colladaUnit ); createAnimations(); kinematicsModel = parseKinematicsModel(); createKinematics(); var result = { scene: scene, morphs: morphs, skins: skins, animations: animData, kinematics: kinematics, dae: { images: images, materials: materials, cameras: cameras, lights: lights, effects: effects, geometries: geometries, controllers: controllers, animations: animations, visualScenes: visualScenes, visualScene: visualScene, scene: visualScene, kinematicsModels: kinematicsModels, kinematicsModel: kinematicsModel } }; if ( callBack ) { callBack( result ); } return result; } function setPreferredShading ( shading ) { preferredShading = shading; } function parseAsset () { var elements = COLLADA.querySelectorAll('asset'); var element = elements[0]; if ( element && element.childNodes ) { for ( var i = 0; i < element.childNodes.length; i ++ ) { var child = element.childNodes[ i ]; switch ( child.nodeName ) { case 'unit': var meter = child.getAttribute( 'meter' ); if ( meter ) { colladaUnit = parseFloat( meter ); } break; case 'up_axis': colladaUp = child.textContent.charAt(0); break; } } } } function parseLib ( q, classSpec, prefix ) { var elements = COLLADA.querySelectorAll(q); var lib = {}; var i = 0; var elementsLength = elements.length; for ( var j = 0; j < elementsLength; j ++ ) { var element = elements[j]; var daeElement = ( new classSpec() ).parse( element ); if ( !daeElement.id || daeElement.id.length === 0 ) daeElement.id = prefix + ( i ++ ); lib[ daeElement.id ] = daeElement; } return lib; } function parseScene() { var sceneElement = COLLADA.querySelectorAll('scene instance_visual_scene')[0]; if ( sceneElement ) { var url = sceneElement.getAttribute( 'url' ).replace( /^#/, '' ); return visualScenes[ url.length > 0 ? url : 'visual_scene0' ]; } else { return null; } } function parseKinematicsModel() { var kinematicsModelElement = COLLADA.querySelectorAll('instance_kinematics_model')[0]; if ( kinematicsModelElement ) { var url = kinematicsModelElement.getAttribute( 'url' ).replace(/^#/, ''); return kinematicsModels[ url.length > 0 ? url : 'kinematics_model0' ]; } else { return null; } } function createAnimations() { animData = []; // fill in the keys recurseHierarchy( scene ); } function recurseHierarchy( node ) { var n = visualScene.getChildById( node.colladaId, true ), newData = null; if ( n && n.keys ) { newData = { fps: 60, hierarchy: [ { node: n, keys: n.keys, sids: n.sids } ], node: node, name: 'animation_' + node.name, length: 0 }; animData.push(newData); for ( var i = 0, il = n.keys.length; i < il; i ++ ) { newData.length = Math.max( newData.length, n.keys[i].time ); } } else { newData = { hierarchy: [ { keys: [], sids: [] } ] } } for ( var i = 0, il = node.children.length; i < il; i ++ ) { var d = recurseHierarchy( node.children[i] ); for ( var j = 0, jl = d.hierarchy.length; j < jl; j ++ ) { newData.hierarchy.push( { keys: [], sids: [] } ); } } return newData; } function calcAnimationBounds () { var start = 1000000; var end = -start; var frames = 0; var ID; for ( var id in animations ) { var animation = animations[ id ]; ID = ID || animation.id; for ( var i = 0; i < animation.sampler.length; i ++ ) { var sampler = animation.sampler[ i ]; sampler.create(); start = Math.min( start, sampler.startTime ); end = Math.max( end, sampler.endTime ); frames = Math.max( frames, sampler.input.length ); } } return { start:start, end:end, frames:frames,ID:I