kaleidoscopejs
Version:
360º video/image viewer
1,948 lines (1,794 loc) • 517 kB
JavaScript
var utils = {
isiOS: function isiOS() {
return /(ipad|iphone|ipod)/ig.test(navigator.userAgent);
},
isEdge: function isEdge() {
return /(Edge)/ig.test(navigator.userAgent);
},
shouldUseAudioDriver: function shouldUseAudioDriver() {
var isOldiOSOnIphone = /iphone.*(7|8|9)_[0-9]/i.test(navigator.userAgent);
var isWebView = /(iPhone|iPod).*AppleWebKit(?!.*Safari)/i.test(navigator.userAgent);
return isOldiOSOnIphone || isWebView;
},
shouldUseCanvasInBetween: function shouldUseCanvasInBetween() {
return /trident|edge/i.test(navigator.userAgent);
}
};
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
writable: true,
configurable: true
}
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
function _assertThisInitialized(self) {
if (self === void 0) {
throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
}
return self;
}
function _possibleConstructorReturn(self, call) {
if (call && (typeof call === "object" || typeof call === "function")) {
return call;
}
return _assertThisInitialized(self);
}
function _superPropBase(object, property) {
while (!Object.prototype.hasOwnProperty.call(object, property)) {
object = _getPrototypeOf(object);
if (object === null) break;
}
return object;
}
function _get(target, property, receiver) {
if (typeof Reflect !== "undefined" && Reflect.get) {
_get = Reflect.get;
} else {
_get = function _get(target, property, receiver) {
var base = _superPropBase(target, property);
if (!base) return;
var desc = Object.getOwnPropertyDescriptor(base, property);
if (desc.get) {
return desc.get.call(receiver);
}
return desc.value;
};
}
return _get(target, property, receiver || target);
}
// File:src/Three.js
/**
* @author mrdoob / http://mrdoob.com/
*/
var THREE = {
REVISION: '75'
}; //
var threejs360 = THREE; //
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];
}
});
}
if (Object.assign === undefined) {
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
Object.defineProperty(Object, 'assign', {
writable: true,
configurable: true,
value: function (target) {
if (target === undefined || target === null) {
throw new TypeError("Cannot convert first argument to object");
}
var to = Object(target);
for (var i = 1, n = arguments.length; i !== n; ++i) {
var nextSource = arguments[i];
if (nextSource === undefined || nextSource === null) continue;
nextSource = Object(nextSource);
var keysArray = Object.keys(nextSource);
for (var nextIndex = 0, len = keysArray.length; nextIndex !== len; ++nextIndex) {
var nextKey = keysArray[nextIndex];
var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
if (desc !== undefined && desc.enumerable) {
to[nextKey] = nextSource[nextKey];
}
}
}
return to;
}
});
} // 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; // Tone Mapping modes
THREE.NoToneMapping = 0; // do not do any tone mapping, not even exposure (required for special purpose passes.)
THREE.LinearToneMapping = 1; // only apply exposure.
THREE.ReinhardToneMapping = 2;
THREE.Uncharted2ToneMapping = 3; // John Hable
THREE.CineonToneMapping = 4; // optimized filmic operator by Jim Hejl and Richard Burgess-Dawson
// Mapping modes
THREE.UVMapping = 300;
THREE.CubeReflectionMapping = 301;
THREE.CubeRefractionMapping = 302;
THREE.EquirectangularReflectionMapping = 303;
THREE.EquirectangularRefractionMapping = 304;
THREE.SphericalReflectionMapping = 305;
THREE.CubeUVReflectionMapping = 306;
THREE.CubeUVRefractionMapping = 307; // 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; // ETC compressed texture formats
THREE.RGB_ETC1_Format = 2151; // Loop styles for AnimationAction
THREE.LoopOnce = 2200;
THREE.LoopRepeat = 2201;
THREE.LoopPingPong = 2202; // Interpolation
THREE.InterpolateDiscrete = 2300;
THREE.InterpolateLinear = 2301;
THREE.InterpolateSmooth = 2302; // Interpolant ending modes
THREE.ZeroCurvatureEnding = 2400;
THREE.ZeroSlopeEnding = 2401;
THREE.WrapAroundEnding = 2402; // Triangle Draw modes
THREE.TrianglesDrawMode = 0;
THREE.TriangleStripDrawMode = 1;
THREE.TriangleFanDrawMode = 2; // Texture Encodings
THREE.LinearEncoding = 3000; // No encoding at all.
THREE.sRGBEncoding = 3001;
THREE.GammaEncoding = 3007; // uses GAMMA_FACTOR, for backwards compatibility with WebGLRenderer.gammaInput/gammaOutput
// The following Texture Encodings are for RGB-only (no alpha) HDR light emission sources.
// These encodings should not specified as output encodings except in rare situations.
THREE.RGBEEncoding = 3002; // AKA Radiance.
THREE.LogLuvEncoding = 3003;
THREE.RGBM7Encoding = 3004;
THREE.RGBM16Encoding = 3005;
THREE.RGBDEncoding = 3006; // MaxRange is 256.
// File:src/math/Math.js
/**
* @author alteredq / http://alteredqualia.com/
* @author mrdoob / http://mrdoob.com/
*/
THREE.Math = {
generateUUID: function () {
// http://www.broofa.com/Tools/Math.uuid.htm
var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
var uuid = new Array(36);
var rnd = 0,
r;
return function () {
for (var i = 0; i < 36; i++) {
if (i === 8 || i === 13 || i === 18 || i === 23) {
uuid[i] = '-';
} else if (i === 14) {
uuid[i] = '4';
} else {
if (rnd <= 0x02) rnd = 0x2000000 + Math.random() * 0x1000000 | 0;
r = rnd & 0xf;
rnd = rnd >> 4;
uuid[i] = chars[i === 19 ? r & 0x3 | 0x8 : r];
}
}
return uuid.join('');
};
}(),
clamp: function (value, min, max) {
return Math.max(min, Math.min(max, value));
},
// compute euclidian modulo of m % n
// https://en.wikipedia.org/wiki/Modulo_operation
euclideanModulo: function (n, m) {
return (n % m + m) % m;
},
// Linear mapping from range <a1, a2> to range <b1, b2>
mapLinear: function (x, a1, a2, b1, b2) {
return b1 + (x - a1) * (b2 - b1) / (a2 - a1);
},
// http://en.wikipedia.org/wiki/Smoothstep
smoothstep: function (x, min, max) {
if (x <= min) return 0;
if (x >= max) return 1;
x = (x - min) / (max - min);
return x * x * (3 - 2 * x);
},
smootherstep: function (x, min, max) {
if (x <= min) return 0;
if (x >= max) return 1;
x = (x - min) / (max - min);
return x * x * x * (x * (x * 6 - 15) + 10);
},
random16: function () {
return Math.random();
},
// Random integer from <low, high> interval
randInt: function (low, high) {
return low + Math.floor(Math.random() * (high - low + 1));
},
// Random float from <low, high> interval
randFloat: function (low, high) {
return low + Math.random() * (high - low);
},
// Random float from <-range/2, range/2> interval
randFloatSpread: function (range) {
return range * (0.5 - Math.random());
},
degToRad: function () {
var degreeToRadiansFactor = Math.PI / 180;
return function (degrees) {
return degrees * degreeToRadiansFactor;
};
}(),
radToDeg: function () {
var radianToDegreesFactor = 180 / Math.PI;
return function (radians) {
return radians * radianToDegreesFactor;
};
}(),
isPowerOfTwo: function (value) {
return (value & value - 1) === 0 && value !== 0;
},
nearestPowerOfTwo: function (value) {
return Math.pow(2, Math.round(Math.log(value) / Math.LN2));
},
nextPowerOfTwo: function (value) {
value--;
value |= value >> 1;
value |= value >> 2;
value |= value >> 4;
value |= value >> 8;
value |= value >> 16;
value++;
return value;
}
}; // 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;
},
setScalar: function (scalar) {
this.r = scalar;
this.g = scalar;
this.b = scalar;
},
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;
}
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);
}
}
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/Vector2.js
/**
* @author mrdoob / http://mrdoob.com/
* @author philogb / http://blog.thejit.org/
* @author egraether / http://egraether.com/
* @author zz85 / http://www.lab4games.net/zz85/blog
*/
THREE.Vector2 = function (x, y) {
this.x = x || 0;
this.y = y || 0;
};
THREE.Vector2.prototype = {
constructor: THREE.Vector2,
get width() {
return this.x;
},
set width(value) {
this.x = value;
},
get height() {
return this.y;
},
set height(value) {
this.y = value;
},
//
set: function (x, y) {
this.x = x;
this.y = y;
return this;
},
setScalar: function (scalar) {
this.x = scalar;
this.y = scalar;
return this;
},
setX: function (x) {
this.x = x;
return this;
},
setY: function (y) {
this.y = y;
return this;
},
setComponent: function (index, value) {
switch (index) {
case 0:
this.x = value;
break;
case 1:
this.y = value;
break;
default:
throw new Error('index is out of range: ' + index);
}
},
getComponent: function (index) {
switch (index) {
case 0:
return this.x;
case 1:
return this.y;
default:
throw new Error('index is out of range: ' + index);
}
},
clone: function () {
return new this.constructor(this.x, this.y);
},
copy: function (v) {
this.x = v.x;
this.y = v.y;
return this;
},
add: function (v, w) {
if (w !== undefined) {
return this.addVectors(v, w);
}
this.x += v.x;
this.y += v.y;
return this;
},
addScalar: function (s) {
this.x += s;
this.y += s;
return this;
},
addVectors: function (a, b) {
this.x = a.x + b.x;
this.y = a.y + b.y;
return this;
},
addScaledVector: function (v, s) {
this.x += v.x * s;
this.y += v.y * s;
return this;
},
sub: function (v, w) {
if (w !== undefined) {
return this.subVectors(v, w);
}
this.x -= v.x;
this.y -= v.y;
return this;
},
subScalar: function (s) {
this.x -= s;
this.y -= s;
return this;
},
subVectors: function (a, b) {
this.x = a.x - b.x;
this.y = a.y - b.y;
return this;
},
multiply: function (v) {
this.x *= v.x;
this.y *= v.y;
return this;
},
multiplyScalar: function (scalar) {
if (isFinite(scalar)) {
this.x *= scalar;
this.y *= scalar;
} else {
this.x = 0;
this.y = 0;
}
return this;
},
divide: function (v) {
this.x /= v.x;
this.y /= v.y;
return this;
},
divideScalar: function (scalar) {
return this.multiplyScalar(1 / scalar);
},
min: function (v) {
this.x = Math.min(this.x, v.x);
this.y = Math.min(this.y, v.y);
return this;
},
max: function (v) {
this.x = Math.max(this.x, v.x);
this.y = Math.max(this.y, v.y);
return this;
},
clamp: function (min, max) {
// This function assumes min < max, if this assumption isn't true it will not operate correctly
this.x = Math.max(min.x, Math.min(max.x, this.x));
this.y = Math.max(min.y, Math.min(max.y, this.y));
return this;
},
clampScalar: function () {
var min, max;
return function clampScalar(minVal, maxVal) {
if (min === undefined) {
min = new THREE.Vector2();
max = new THREE.Vector2();
}
min.set(minVal, minVal);
max.set(maxVal, maxVal);
return this.clamp(min, max);
};
}(),
clampLength: function (min, max) {
var length = this.length();
this.multiplyScalar(Math.max(min, Math.min(max, length)) / length);
return this;
},
floor: function () {
this.x = Math.floor(this.x);
this.y = Math.floor(this.y);
return this;
},
ceil: function () {
this.x = Math.ceil(this.x);
this.y = Math.ceil(this.y);
return this;
},
round: function () {
this.x = Math.round(this.x);
this.y = Math.round(this.y);
return this;
},
roundToZero: function () {
this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x);
this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y);
return this;
},
negate: function () {
this.x = -this.x;
this.y = -this.y;
return this;
},
dot: function (v) {
return this.x * v.x + this.y * v.y;
},
lengthSq: function () {
return this.x * this.x + this.y * this.y;
},
length: function () {
return Math.sqrt(this.x * this.x + this.y * this.y);
},
lengthManhattan: function () {
return Math.abs(this.x) + Math.abs(this.y);
},
normalize: function () {
return this.divideScalar(this.length());
},
angle: function () {
// computes the angle in radians with respect to the positive x-axis
var angle = Math.atan2(this.y, this.x);
if (angle < 0) angle += 2 * Math.PI;
return angle;
},
distanceTo: function (v) {
return Math.sqrt(this.distanceToSquared(v));
},
distanceToSquared: function (v) {
var dx = this.x - v.x,
dy = this.y - v.y;
return dx * dx + dy * dy;
},
setLength: function (length) {
return this.multiplyScalar(length / this.length());
},
lerp: function (v, alpha) {
this.x += (v.x - this.x) * alpha;
this.y += (v.y - this.y) * alpha;
return this;
},
lerpVectors: function (v1, v2, alpha) {
this.subVectors(v2, v1).multiplyScalar(alpha).add(v1);
return this;
},
equals: function (v) {
return v.x === this.x && v.y === this.y;
},
fromArray: function (array, offset) {
if (offset === undefined) offset = 0;
this.x = array[offset];
this.y = array[offset + 1];
return this;
},
toArray: function (array, offset) {
if (array === undefined) array = [];
if (offset === undefined) offset = 0;
array[offset] = this.x;
array[offset + 1] = this.y;
return array;
},
fromAttribute: function (attribute, index, offset) {
if (offset === undefined) offset = 0;
index = index * attribute.itemSize + offset;
this.x = attribute.array[index];
this.y = attribute.array[index + 1];
return this;
},
rotateAround: function (center, angle) {
var c = Math.cos(angle),
s = Math.sin(angle);
var x = this.x - center.x;
var y = this.y - center.y;
this.x = x * c - y * s + center.x;
this.y = x * s + y * c + center.y;
return this;
}
}; // File:src/math/Vector3.js
/**
* @author mrdoob / http://mrdoob.com/
* @author *kile / http://kile.stravaganza.org/
* @author philogb / http://blog.thejit.org/
* @author mikael emtinger / http://gomo.se/
* @author egraether / http://egraether.com/
* @author WestLangley / http://github.com/WestLangley
*/
THREE.Vector3 = function (x, y, z) {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
};
THREE.Vector3.prototype = {
constructor: THREE.Vector3,
set: function (x, y, z) {
this.x = x;
this.y = y;
this.z = z;
return this;
},
setScalar: function (scalar) {
this.x = scalar;
this.y = scalar;
this.z = scalar;
return this;
},
setX: function (x) {
this.x = x;
return this;
},
setY: function (y) {
this.y = y;
return this;
},
setZ: function (z) {
this.z = z;
return this;
},
setComponent: function (index, value) {
switch (index) {
case 0:
this.x = value;
break;
case 1:
this.y = value;
break;
case 2:
this.z = value;
break;
default:
throw new Error('index is out of range: ' + index);
}
},
getComponent: function (index) {
switch (index) {
case 0:
return this.x;
case 1:
return this.y;
case 2:
return this.z;
default:
throw new Error('index is out of range: ' + index);
}
},
clone: function () {
return new this.constructor(this.x, this.y, this.z);
},
copy: function (v) {
this.x = v.x;
this.y = v.y;
this.z = v.z;
return this;
},
add: function (v, w) {
if (w !== undefined) {
return this.addVectors(v, w);
}
this.x += v.x;
this.y += v.y;
this.z += v.z;
return this;
},
addScalar: function (s) {
this.x += s;
this.y += s;
this.z += s;
return this;
},
addVectors: function (a, b) {
this.x = a.x + b.x;
this.y = a.y + b.y;
this.z = a.z + b.z;
return this;
},
addScaledVector: function (v, s) {
this.x += v.x * s;
this.y += v.y * s;
this.z += v.z * s;
return this;
},
sub: function (v, w) {
if (w !== undefined) {
return this.subVectors(v, w);
}
this.x -= v.x;
this.y -= v.y;
this.z -= v.z;
return this;
},
subScalar: function (s) {
this.x -= s;
this.y -= s;
this.z -= s;
return this;
},
subVectors: function (a, b) {
this.x = a.x - b.x;
this.y = a.y - b.y;
this.z = a.z - b.z;
return this;
},
multiply: function (v, w) {
if (w !== undefined) {
return this.multiplyVectors(v, w);
}
this.x *= v.x;
this.y *= v.y;
this.z *= v.z;
return this;
},
multiplyScalar: function (scalar) {
if (isFinite(scalar)) {
this.x *= scalar;
this.y *= scalar;
this.z *= scalar;
} else {
this.x = 0;
this.y = 0;
this.z = 0;
}
return this;
},
multiplyVectors: function (a, b) {
this.x = a.x * b.x;
this.y = a.y * b.y;
this.z = a.z * b.z;
return this;
},
applyEuler: function () {
var quaternion;
return function applyEuler(euler) {
if (quaternion === undefined) quaternion = new THREE.Quaternion();
this.applyQuaternion(quaternion.setFromEuler(euler));
return this;
};
}(),
applyAxisAngle: function () {
var quaternion;
return function applyAxisAngle(axis, angle) {
if (quaternion === undefined) quaternion = new THREE.Quaternion();
this.applyQuaternion(quaternion.setFromAxisAngle(axis, angle));
return this;
};
}(),
applyMatrix3: function (m) {
var x = this.x;
var y = this.y;
var z = this.z;
var e = m.elements;
this.x = e[0] * x + e[3] * y + e[6] * z;
this.y = e[1] * x + e[4] * y + e[7] * z;
this.z = e[2] * x + e[5] * y + e[8] * z;
return this;
},
applyMatrix4: function (m) {
// input: THREE.Matrix4 affine matrix
var x = this.x,
y = this.y,
z = this.z;
var e = m.elements;
this.x = e[0] * x + e[4] * y + e[8] * z + e[12];
this.y = e[1] * x + e[5] * y + e[9] * z + e[13];
this.z = e[2] * x + e[6] * y + e[10] * z + e[14];
return this;
},
applyProjection: function (m) {
// input: THREE.Matrix4 projection matrix
var x = this.x,
y = this.y,
z = this.z;
var e = m.elements;
var d = 1 / (e[3] * x + e[7] * y + e[11] * z + e[15]); // perspective divide
this.x = (e[0] * x + e[4] * y + e[8] * z + e[12]) * d;
this.y = (e[1] * x + e[5] * y + e[9] * z + e[13]) * d;
this.z = (e[2] * x + e[6] * y + e[10] * z + e[14]) * d;
return this;
},
applyQuaternion: function (q) {
var x = this.x;
var y = this.y;
var z = this.z;
var qx = q.x;
var qy = q.y;
var qz = q.z;
var qw = q.w; // calculate quat * vector
var ix = qw * x + qy * z - qz * y;
var iy = qw * y + qz * x - qx * z;
var iz = qw * z + qx * y - qy * x;
var iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat
this.x = ix * qw + iw * -qx + iy * -qz - iz * -qy;
this.y = iy * qw + iw * -qy + iz * -qx - ix * -qz;
this.z = iz * qw + iw * -qz + ix * -qy - iy * -qx;
return this;
},
project: function () {
var matrix;
return function project(camera) {
if (matrix === undefined) matrix = new THREE.Matrix4();
matrix.multiplyMatrices(camera.projectionMatrix, matrix.getInverse(camera.matrixWorld));
return this.applyProjection(matrix);
};
}(),
unproject: function () {
var matrix;
return function unproject(camera) {
if (matrix === undefined) matrix = new THREE.Matrix4();
matrix.multiplyMatrices(camera.matrixWorld, matrix.getInverse(camera.projectionMatrix));
return this.applyProjection(matrix);
};
}(),
transformDirection: function (m) {
// input: THREE.Matrix4 affine matrix
// vector interpreted as a direction
var x = this.x,
y = this.y,
z = this.z;
var e = m.elements;
this.x = e[0] * x + e[4] * y + e[8] * z;
this.y = e[1] * x + e[5] * y + e[9] * z;
this.z = e[2] * x + e[6] * y + e[10] * z;
this.normalize();
return this;
},
divide: function (v) {
this.x /= v.x;
this.y /= v.y;
this.z /= v.z;
return this;
},
divideScalar: function (scalar) {
return this.multiplyScalar(1 / scalar);
},
min: function (v) {
this.x = Math.min(this.x, v.x);
this.y = Math.min(this.y, v.y);
this.z = Math.min(this.z, v.z);
return this;
},
max: function (v) {
this.x = Math.max(this.x, v.x);
this.y = Math.max(this.y, v.y);
this.z = Math.max(this.z, v.z);
return this;
},
clamp: function (min, max) {
// This function assumes min < max, if this assumption isn't true it will not operate correctly
this.x = Math.max(min.x, Math.min(max.x, this.x));
this.y = Math.max(min.y, Math.min(max.y, this.y));
this.z = Math.max(min.z, Math.min(max.z, this.z));
return this;
},
clampScalar: function () {
var min, max;
return function clampScalar(minVal, maxVal) {
if (min === undefined) {
min = new THREE.Vector3();
max = new THREE.Vector3();
}
min.set(minVal, minVal, minVal);
max.set(maxVal, maxVal, maxVal);
return this.clamp(min, max);
};
}(),
clampLength: function (min, max) {
var length = this.length();
this.multiplyScalar(Math.max(min, Math.min(max, length)) / length);
return this;
},
floor: function () {
this.x = Math.floor(this.x);
this.y = Math.floor(this.y);
this.z = Math.floor(this.z);
return this;
},
ceil: function () {
this.x = Math.ceil(this.x);
this.y = Math.ceil(this.y);
this.z = Math.ceil(this.z);
return this;
},
round: function () {
this.x = Math.round(this.x);
this.y = Math.round(this.y);
this.z = Math.round(this.z);
return this;
},
roundToZero: function () {
this.x = this.x < 0 ? Math.ceil(this.x) : Math.floor(this.x);
this.y = this.y < 0 ? Math.ceil(this.y) : Math.floor(this.y);
this.z = this.z < 0 ? Math.ceil(this.z) : Math.floor(this.z);
return this;
},
negate: function () {
this.x = -this.x;
this.y = -this.y;
this.z = -this.z;
return this;
},
dot: function (v) {
return this.x * v.x + this.y * v.y + this.z * v.z;
},
lengthSq: function () {
return this.x * this.x + this.y * this.y + this.z * this.z;
},
length: function () {
return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
},
lengthManhattan: function () {
return Math.abs(this.x) + Math.abs(this.y) + Math.abs(this.z);
},
normalize: function () {
return this.divideScalar(this.length());
},
setLength: function (length) {
return this.multiplyScalar(length / this.length());
},
lerp: function (v, alpha) {
this.x += (v.x - this.x) * alpha;
this.y += (v.y - this.y) * alpha;
this.z += (v.z - this.z) * alpha;
return this;
},
lerpVectors: function (v1, v2, alpha) {
this.subVectors(v2, v1).multiplyScalar(alpha).add(v1);
return this;
},
cross: function (v, w) {
if (w !== undefined) {
return this.crossVectors(v, w);
}
var x = this.x,
y = this.y,
z = this.z;
this.x = y * v.z - z * v.y;
this.y = z * v.x - x * v.z;
this.z = x * v.y - y * v.x;
return this;
},
crossVectors: function (a, b) {
var ax = a.x,
ay = a.y,
az = a.z;
var bx = b.x,
by = b.y,
bz = b.z;
this.x = ay * bz - az * by;
this.y = az * bx - ax * bz;
this.z = ax * by - ay * bx;
return this;
},
projectOnVector: function () {
var v1, dot;
return function projectOnVector(vector) {
if (v1 === undefined) v1 = new THREE.Vector3();
v1.copy(vector).normalize();
dot = this.dot(v1);
return this.copy(v1).multiplyScalar(dot);
};
}(),
projectOnPlane: function () {
var v1;
return function projectOnPlane(planeNormal) {
if (v1 === undefined) v1 = new THREE.Vector3();
v1.copy(this).projectOnVector(planeNormal);
return this.sub(v1);
};
}(),
reflect: function () {
// reflect incident vector off plane orthogonal to normal
// normal is assumed to have unit length
var v1;
return function reflect(normal) {
if (v1 === undefined) v1 = new THREE.Vector3();
return this.sub(v1.copy(normal).multiplyScalar(2 * this.dot(normal)));
};
}(),
angleTo: function (v) {
var theta = this.dot(v) / Math.sqrt(this.lengthSq() * v.lengthSq()); // clamp, to handle numerical problems
return Math.acos(THREE.Math.clamp(theta, -1, 1));
},
distanceTo: function (v) {
return Math.sqrt(this.distanceToSquared(v));
},
distanceToSquared: function (v) {
var dx = this.x - v.x;
var dy = this.y - v.y;
var dz = this.z - v.z;
return dx * dx + dy * dy + dz * dz;
},
setFromSpherical: function (s) {
var sinPhiRadius = Math.sin(s.phi) * s.radius;
this.x = sinPhiRadius * Math.sin(s.theta);
this.y = Math.cos(s.phi) * s.radius;
this.z = sinPhiRadius * Math.cos(s.theta);
return this;
},
setFromMatrixPosition: function (m) {
return this.setFromMatrixColumn(m, 3);
},
setFromMatrixScale: function (m) {
var sx = this.setFromMatrixColumn(m, 0).length();
var sy = this.setFromMatrixColumn(m, 1).length();
var sz = this.setFromMatrixColumn(m, 2).length();
this.x = sx;
this.y = sy;
this.z = sz;
return this;
},
setFromMatrixColumn: function (m, index) {
if (typeof m === 'number') {
m = arguments[1];
index = arguments[0];
}
return this.fromArray(m.elements, index * 4);
},
equals: function (v) {
return v.x === this.x && v.y === this.y && v.z === this.z;
},
fromArray: function (array, offset) {
if (offset === undefined) offset = 0;
this.x = array[offset];
this.y = array[offset + 1];
this.z = array[offset + 2];
return this;
},
toArray: function (array, offset) {
if (array === undefined) array = [];
if (offset === undefined) offset = 0;
array[offset] = this.x;
array[offset + 1] = this.y;
array[offset + 2] = this.z;
return array;
},
fromAttribute: function (attribute, index, offset) {
if (offset === undefined) offset = 0;
index = index * attribute.itemSize + offset;
this.x = attribute.array[index];
this.y = attribute.array[index + 1];
this.z = attribute.array[index + 2];
return this;
}
}; // File:src/math/Vector4.js
/**
* @author supereggbert / http://www.paulbrunt.co.uk/
* @author philogb / http://blog.thejit.org/
* @author mikael emtinger / http://gomo.se/
* @author egraether / http://egraether.com/
* @author WestLangley / http://github.com/WestLangley
*/
THREE.Vector4 = function (x, y, z, w) {
this.x = x || 0;
this.y = y || 0;
this.z = z || 0;
this.w = w !== undefined ? w : 1;
};
THREE.Vector4.prototype = {
constructor: THREE.Vector4,
set: function (x, y, z, w) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
return this;
},
setScalar: function (scalar) {
this.x = scalar;
this.y = scalar;
this.z = scalar;
this.w = scalar;
return this;
},
setX: function (x) {
this.x = x;
return this;
},
setY: function (y) {
this.y = y;
return this;
},
setZ: function (z) {
this.z = z;
return this;
},
setW: function (w) {
this.w = w;
return this;
},
setComponent: function (index, value) {
switch (index) {
case 0:
this.x = value;
break;
case 1:
this.y = value;
break;
case 2:
this.z = value;
break;
case 3:
this.w = value;
break;
default:
throw new Error('index is out of range: ' + index);
}
},
getComponent: function (index) {
switch (index) {
case 0:
return this.x;
case 1:
return this.y;
case 2:
return this.z;
case 3:
return this.w;
default:
throw new Error('index is out of range: ' + index);
}
},
clone: function () {
return new this.constructor(this.x, this.y, this.z, this.w);
},
copy: function (v) {
this.x = v.x;
this.y = v.y;
this.z = v.z;
this.w = v.w !== undefined ? v.w : 1;
return this;
},
add: function (v, w) {
if (w !== undefined) {
return this.addVectors(v, w);
}
this.x += v.x;
this.y += v.y;
this.z += v.z;
this.w += v.w;
return this;
},
addScalar: function (s) {
this.x += s;
this.y += s;
this.z += s;
this.w += s;
return this;
},
addVectors: function (a, b) {
this.x = a.x + b.x;
this.y = a.y + b.y;
this.z = a.z + b.z;
this.w = a.w + b.w;
return this;
},
addScaledVector: function (v, s) {
this.x += v.x * s;
this.y += v.y * s;
this.z += v.z * s;
this.w += v.w * s;
return this;
},
sub: function (v, w) {
if (w !== undefined) {
return this.subVectors(v, w);
}
this.x -= v.x;
this.y -= v.y;
this.z -= v.z;
this.w -= v.w;
return this;
},
subScalar: function (s) {
this.x -= s;
this.y -= s;
this.z -= s;
this.w -= s;
return this;
},
subVectors: function (a, b) {
this.x = a.x - b.x;
this.y = a.y - b.y;
this.z = a.z - b.z;
this.w = a.w - b.w;
return this;
},
multiplyScalar: function (scalar) {
if (isFinite(scalar)) {
this.x *= scalar;
this.y *= scalar;
this.z *= scalar;
this.w *= scalar;
} else {
this.x = 0;
this.y = 0;
this.z = 0;
this.w = 0;
}
return this;
},
applyMatrix4: function (m) {
var x = this.x;
var y = this.y;
var z = this.z;
var w = this.w;
var e = m.elements;
this.x = e[0] * x + e[4] * y + e[8] * z + e[12] * w;
this.y = e[1] * x + e[5] * y + e[9] * z + e[13] * w;
this.z = e[2] * x + e[6] * y + e[10] * z + e[14] * w;
this.w = e[3] * x + e[7] * y + e[11] * z + e[15] * w;
return this;
},
divideScalar: function (scalar) {
return this.multiplyScalar(1 / scalar);
},
setAxisAngleFromQuaternion: function (q) {
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToAngle/index.htm
// q is assumed to be normalized
this.w = 2 * Math.acos(q.w);
var s = Math.sqrt(1 - q.w * q.w);
if (s < 0.0001) {
this.x = 1;
this.y = 0;
this.z = 0;
} else {
this.x = q.x / s;
this.y = q.y / s;
this.z = q.z / s;
}
return this;
},
setAxisAngleFromRotationMatrix: function (m) {
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/index.htm
// assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled)
var angle,
x,
y,
z,
// variables for result
epsilon = 0.01,
// margin to allow for rounding errors
epsilon2 = 0.1,
// margin to distinguish between 0 and 180 degrees
te = m.elements,
m11 = te[0],
m12 = te[4],
m13 = te[8],
m21 = te[1],
m22 = te[5],
m23 = te[9],
m31 = te[2],
m32 = te[6],
m33 = te[10];
if (Math.abs(m12 - m21) < epsilon && Math.abs(m13 - m31) < epsilon && Math.abs(m23 - m32) < epsilon) {
// singularity found
// first check for identity matrix which must have +1 for all terms
// in leading diagonal and zero in other terms
if (Math.abs(m12 + m21) < epsilon2 && Math.abs(m13 + m31) < epsilon2 && Math.abs(m23 + m32) < epsilon2 && Math.abs(m11 + m22 + m33 - 3) < epsilon2) {
// this singularity is identity matrix so angle = 0
this.set(1, 0, 0, 0);
return this; // zero angle, arbitrary axis
} // otherwise this singularity is angle = 180
angle = Math.PI;
var xx = (m11 + 1) / 2;
var yy = (m22 + 1) / 2;
var zz = (m33 + 1) / 2;
var xy = (m12 + m21) / 4;
var xz = (m13 + m31) / 4;
var yz = (m23 + m32) / 4;
if (xx > yy && xx > zz) {
// m11 is the largest diagonal term
if (xx < epsilon) {
x = 0;
y = 0.707106781;
z = 0.707106781;
} else {
x = Math.sqrt(xx);
y = xy / x;
z = xz / x;
}
} else if (yy > zz) {
// m22 is the largest diagonal term
if (yy < epsilon) {
x = 0.707106781;
y = 0;
z = 0.707106781;