UNPKG

@aidinabedi/playcanvas

Version:

PlayCanvas WebGL game engine

1,687 lines (1,686 loc) 1.88 MB
/* * PlayCanvas Engine v1.26.0-dev revision 4d6f7be2 * Copyright 2011-2020 PlayCanvas Ltd. All rights reserved. */ ;(function (root, factory) { if (typeof define === 'function' && define.amd) { define([], factory); } else if (typeof module === 'object' && module.exports) { module.exports = factory(); } else { root.pc = factory(); } }(this, function () { if (!Array.prototype.find) { Object.defineProperty(Array.prototype, "find", {value:function(predicate) { if (this == null) { throw TypeError('"this" is null or not defined'); } var o = Object(this); var len = o.length >>> 0; if (typeof predicate !== "function") { throw TypeError("predicate must be a function"); } var thisArg = arguments[1]; var k = 0; while (k < len) { var kValue = o[k]; if (predicate.call(thisArg, kValue, k, o)) { return kValue; } k++; } return undefined; }, configurable:true, writable:true}); } ;Math.log2 = Math.log2 || function(x) { return Math.log(x) * Math.LOG2E; }; if (!Math.sign) { Math.sign = function(x) { return (x > 0) - (x < 0) || +x; }; } ;if (typeof Object.assign != "function") { Object.defineProperty(Object, "assign", {value:function assign(target, varArgs) { if (target == null) { throw new TypeError("Cannot convert undefined or null to object"); } var to = Object(target); for (var index = 1; index < arguments.length; index++) { var nextSource = arguments[index]; if (nextSource != null) { for (var nextKey in nextSource) { if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { to[nextKey] = nextSource[nextKey]; } } } } return to; }, writable:true, configurable:true}); } ;(function() { if (typeof navigator === "undefined" || typeof document === "undefined") { return; } navigator.pointer = navigator.pointer || navigator.webkitPointer || navigator.mozPointer; var pointerlockchange = function() { var e = document.createEvent("CustomEvent"); e.initCustomEvent("pointerlockchange", true, false, null); document.dispatchEvent(e); }; var pointerlockerror = function() { var e = document.createEvent("CustomEvent"); e.initCustomEvent("pointerlockerror", true, false, null); document.dispatchEvent(e); }; document.addEventListener("webkitpointerlockchange", pointerlockchange, false); document.addEventListener("webkitpointerlocklost", pointerlockchange, false); document.addEventListener("mozpointerlockchange", pointerlockchange, false); document.addEventListener("mozpointerlocklost", pointerlockchange, false); document.addEventListener("webkitpointerlockerror", pointerlockerror, false); document.addEventListener("mozpointerlockerror", pointerlockerror, false); if (Element.prototype.mozRequestPointerLock) { Element.prototype.requestPointerLock = function() { this.mozRequestPointerLock(); }; } else { Element.prototype.requestPointerLock = Element.prototype.requestPointerLock || Element.prototype.webkitRequestPointerLock || Element.prototype.mozRequestPointerLock; } if (!Element.prototype.requestPointerLock && navigator.pointer) { Element.prototype.requestPointerLock = function() { var el = this; document.pointerLockElement = el; navigator.pointer.lock(el, pointerlockchange, pointerlockerror); }; } document.exitPointerLock = document.exitPointerLock || document.webkitExitPointerLock || document.mozExitPointerLock; if (!document.exitPointerLock) { document.exitPointerLock = function() { if (navigator.pointer) { document.pointerLockElement = null; navigator.pointer.unlock(); } }; } })(); (function() { if (typeof window === "undefined") { return; } var lastTime = 0; var vendors = ["ms", "moz", "webkit", "o"]; for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { window.requestAnimationFrame = window[vendors[x] + "RequestAnimationFrame"]; window.cancelAnimationFrame = window[vendors[x] + "CancelAnimationFrame"] || window[vendors[x] + "CancelRequestAnimationFrame"]; } if (!window.requestAnimationFrame) { window.requestAnimationFrame = function(callback, element) { var currTime = (new Date).getTime(); var timeToCall = Math.max(0, 16 - (currTime - lastTime)); var id = window.setTimeout(function() { callback(currTime + timeToCall); }, timeToCall); lastTime = currTime + timeToCall; return id; }; } if (!window.cancelAnimationFrame) { window.cancelAnimationFrame = function(id) { clearTimeout(id); }; } })(); if (!String.prototype.endsWith) { String.prototype.endsWith = function(search, this_len) { if (this_len === undefined || this_len > this.length) { this_len = this.length; } return this.substring(this_len - search.length, this_len) === search; }; } if (!String.prototype.includes) { String.prototype.includes = function(search, start) { if (typeof start !== "number") { start = 0; } if (start + search.length > this.length) { return false; } else { return this.indexOf(search, start) !== -1; } }; } if (!String.prototype.startsWith) { String.prototype.startsWith = function(search, pos) { return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; }; } ;var _typeLookup = function() { var result = {}; var names = ["Array", "Object", "Function", "Date", "RegExp", "Float32Array"]; for (var i = 0; i < names.length; i++) { result["[object " + names[i] + "]"] = names[i].toLowerCase(); } return result; }(); var pc = {version:"1.26.0-dev", revision:"4d6f7be2", config:{}, common:{}, apps:{}, data:{}, unpack:function() { console.warn("pc.unpack has been deprecated and will be removed shortly. Please update your code."); }, makeArray:function(arr) { var i, ret = [], length = arr.length; for (i = 0; i < length; ++i) { ret.push(arr[i]); } return ret; }, type:function(obj) { if (obj === null) { return "null"; } var type = typeof obj; if (type === "undefined" || type === "number" || type === "string" || type === "boolean") { return type; } return _typeLookup[Object.prototype.toString.call(obj)]; }, extend:function(target, ex) { var prop, copy; for (prop in ex) { copy = ex[prop]; if (pc.type(copy) == "object") { target[prop] = pc.extend({}, copy); } else { if (pc.type(copy) == "array") { target[prop] = pc.extend([], copy); } else { target[prop] = copy; } } } return target; }, isDefined:function(o) { var a; return o !== a; }}; if (typeof exports !== "undefined") { exports.pc = pc; } ;Object.assign(pc, function() { var Color = function(r, g, b, a) { var length = r && r.length; if (length === 3 || length === 4) { this.r = r[0]; this.g = r[1]; this.b = r[2]; this.a = r[3] !== undefined ? r[3] : 1; } else { this.r = r || 0; this.g = g || 0; this.b = b || 0; this.a = a !== undefined ? a : 1; } }; Object.assign(Color.prototype, {clone:function() { return new pc.Color(this.r, this.g, this.b, this.a); }, copy:function(rhs) { this.r = rhs.r; this.g = rhs.g; this.b = rhs.b; this.a = rhs.a; return this; }, set:function(r, g, b, a) { this.r = r; this.g = g; this.b = b; this.a = a === undefined ? 1 : a; return this; }, lerp:function(lhs, rhs, alpha) { this.r = lhs.r + alpha * (rhs.r - lhs.r); this.g = lhs.g + alpha * (rhs.g - lhs.g); this.b = lhs.b + alpha * (rhs.b - lhs.b); this.a = lhs.a + alpha * (rhs.a - lhs.a); return this; }, fromString:function(hex) { var i = parseInt(hex.replace("#", "0x"), 16); var bytes; if (hex.length > 7) { bytes = pc.math.intToBytes32(i); } else { bytes = pc.math.intToBytes24(i); bytes[3] = 255; } this.set(bytes[0] / 255, bytes[1] / 255, bytes[2] / 255, bytes[3] / 255); return this; }, toString:function(alpha) { var s = "#" + ((1 << 24) + (Math.round(this.r * 255) << 16) + (Math.round(this.g * 255) << 8) + Math.round(this.b * 255)).toString(16).slice(1); if (alpha === true) { var a = Math.round(this.a * 255).toString(16); if (this.a < 16 / 255) { s += "0" + a; } else { s += a; } } return s; }}); return {Color:Color}; }()); pc.guid = function() { return {create:function() { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) { var r = Math.random() * 16 | 0, v = c == "x" ? r : r & 3 | 8; return v.toString(16); }); }}; }(); Object.assign(pc, function() { var Timer = function Timer() { this._isRunning = false; this._a = 0; this._b = 0; }; Object.assign(Timer.prototype, {start:function() { this._isRunning = true; this._a = pc.now(); }, stop:function() { this._isRunning = false; this._b = pc.now(); }, getMilliseconds:function() { return this._b - this._a; }}); return {Timer:Timer, now:typeof window !== "undefined" && window.performance && window.performance.now && window.performance.timing ? function() { return window.performance.now(); } : Date.now}; }()); Object.assign(pc, function() { return {hashCode:function(str) { var hash = 0; for (var i = 0, len = str.length; i < len; i++) { hash = (hash << 5) - hash + str.charCodeAt(i); hash |= 0; } return hash; }}; }()); Object.assign(pc, function() { return {createURI:function(options) { var s = ""; if ((options.authority || options.scheme) && (options.host || options.hostpath)) { throw new Error("Can't have 'scheme' or 'authority' and 'host' or 'hostpath' option"); } if (options.host && options.hostpath) { throw new Error("Can't have 'host' and 'hostpath' option"); } if (options.path && options.hostpath) { throw new Error("Can't have 'path' and 'hostpath' option"); } if (options.scheme) { s += options.scheme + ":"; } if (options.authority) { s += "//" + options.authority; } if (options.host) { s += options.host; } if (options.path) { s += options.path; } if (options.hostpath) { s += options.hostpath; } if (options.query) { s += "?" + options.query; } if (options.fragment) { s += "#" + options.fragment; } return s; }, URI:function(uri) { var re = /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/, result = uri.match(re); this.scheme = result[2]; this.authority = result[4]; this.path = result[5]; this.query = result[7]; this.fragment = result[9]; this.toString = function() { var s = ""; if (this.scheme) { s += this.scheme + ":"; } if (this.authority) { s += "//" + this.authority; } s += this.path; if (this.query) { s += "?" + this.query; } if (this.fragment) { s += "#" + this.fragment; } return s; }; this.getQuery = function() { var vars; var pair; var result = {}; if (this.query) { vars = decodeURIComponent(this.query).split("&"); vars.forEach(function(item, index, arr) { pair = item.split("="); result[pair[0]] = pair[1]; }, this); } return result; }; this.setQuery = function(params) { var q = ""; for (var key in params) { if (params.hasOwnProperty(key)) { if (q !== "") { q += "&"; } q += encodeURIComponent(key) + "=" + encodeURIComponent(params[key]); } } this.query = q; }; }}; }()); Object.assign(pc, function() { var log = {write:function(text) { console.log(text); }, open:function() { pc.log.write("Powered by PlayCanvas " + pc.version + " " + pc.revision); }, info:function(text) { console.info("INFO: " + text); }, debug:function(text) { console.debug("DEBUG: " + text); }, error:function(text) { console.error("ERROR: " + text); }, warning:function(text) { console.warn("WARNING: " + text); }, alert:function(text) { pc.log.write("ALERT: " + text); alert(text); }, assert:function(condition, text) { if (condition === false) { pc.log.write("ASSERT: " + text); } }}; return {log:log}; }()); var logINFO = pc.log.info; var logDEBUG = pc.log.debug; var logWARNING = pc.log.warning; var logERROR = pc.log.error; var logALERT = pc.log.alert; var logASSERT = pc.log.assert; pc.path = function() { return {delimiter:"/", join:function() { var index; var num = arguments.length; var result = arguments[0]; for (index = 0; index < num - 1; ++index) { var one = arguments[index]; var two = arguments[index + 1]; if (!pc.isDefined(one) || !pc.isDefined(two)) { throw new Error("undefined argument to pc.path.join"); } if (two[0] === pc.path.delimiter) { result = two; continue; } if (one && two && one[one.length - 1] !== pc.path.delimiter && two[0] !== pc.path.delimiter) { result += pc.path.delimiter + two; } else { result += two; } } return result; }, normalize:function(path) { var lead = path.startsWith(pc.path.delimiter); var trail = path.endsWith(pc.path.delimiter); var parts = path.split("/"); var result = ""; var cleaned = []; for (var i = 0; i < parts.length; i++) { if (parts[i] === "") { continue; } if (parts[i] === ".") { continue; } if (parts[i] === ".." && cleaned.length > 0) { cleaned = cleaned.slice(0, cleaned.length - 2); continue; } if (i > 0) { cleaned.push(pc.path.delimiter); } cleaned.push(parts[i]); } result = cleaned.join(""); if (!lead && result[0] === pc.path.delimiter) { result = result.slice(1); } if (trail && result[result.length - 1] !== pc.path.delimiter) { result += pc.path.delimiter; } return result; }, split:function(path) { var parts = path.split(pc.path.delimiter); var tail = parts.slice(parts.length - 1)[0]; var head = parts.slice(0, parts.length - 1).join(pc.path.delimiter); return [head, tail]; }, getBasename:function(path) { return pc.path.split(path)[1]; }, getDirectory:function(path) { var parts = path.split(pc.path.delimiter); return parts.slice(0, parts.length - 1).join(pc.path.delimiter); }, getExtension:function(path) { var ext = path.split("?")[0].split(".").pop(); if (ext !== path) { return "." + ext; } return ""; }, isRelativePath:function(s) { return s.charAt(0) !== "/" && s.match(/:\/\//) === null; }, extractPath:function(s) { var path = ""; var parts = s.split("/"); var i = 0; if (parts.length > 1) { if (pc.path.isRelativePath(s)) { if (parts[0] === ".") { for (i = 0; i < parts.length - 1; ++i) { path += i === 0 ? parts[i] : "/" + parts[i]; } } else { if (parts[0] === "..") { for (i = 0; i < parts.length - 1; ++i) { path += i === 0 ? parts[i] : "/" + parts[i]; } } else { path = "."; for (i = 0; i < parts.length - 1; ++i) { path += "/" + parts[i]; } } } } else { for (i = 0; i < parts.length - 1; ++i) { path += i === 0 ? parts[i] : "/" + parts[i]; } } } return path; }}; }(); pc.string = function() { var ASCII_LOWERCASE = "abcdefghijklmnopqrstuvwxyz"; var ASCII_UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; var ASCII_LETTERS = ASCII_LOWERCASE + ASCII_UPPERCASE; var HIGH_SURROGATE_BEGIN = 55296; var HIGH_SURROGATE_END = 56319; var LOW_SURROGATE_BEGIN = 56320; var LOW_SURROGATE_END = 57343; var ZERO_WIDTH_JOINER = 8205; var REGIONAL_INDICATOR_BEGIN = 127462; var REGIONAL_INDICATOR_END = 127487; var FITZPATRICK_MODIFIER_BEGIN = 127995; var FITZPATRICK_MODIFIER_END = 127999; var DIACRITICAL_MARKS_BEGIN = 8400; var DIACRITICAL_MARKS_END = 8447; var VARIATION_MODIFIER_BEGIN = 65024; var VARIATION_MODIFIER_END = 65039; function getCodePointData(string, i) { var size = string.length; i = i || 0; if (i < 0 || i >= size) { return null; } var first = string.charCodeAt(i); var second; if (size > 1 && first >= HIGH_SURROGATE_BEGIN && first <= HIGH_SURROGATE_END) { second = string.charCodeAt(i + 1); if (second >= LOW_SURROGATE_BEGIN && second <= LOW_SURROGATE_END) { return {code:(first - HIGH_SURROGATE_BEGIN) * 1024 + second - LOW_SURROGATE_BEGIN + 65536, long:true}; } } return {code:first, long:false}; } function isCodeBetween(string, begin, end) { if (!string) { return false; } var codeData = getCodePointData(string); if (codeData) { var code = codeData.code; return code >= begin && code <= end; } return false; } function numCharsToTakeForNextSymbol(string, index) { if (index === string.length - 1) { return 1; } if (isCodeBetween(string[index], HIGH_SURROGATE_BEGIN, HIGH_SURROGATE_END)) { var first = string.substring(index, index + 2); var second = string.substring(index + 2, index + 4); if (isCodeBetween(second, FITZPATRICK_MODIFIER_BEGIN, FITZPATRICK_MODIFIER_END) || isCodeBetween(first, REGIONAL_INDICATOR_BEGIN, REGIONAL_INDICATOR_END) && isCodeBetween(second, REGIONAL_INDICATOR_BEGIN, REGIONAL_INDICATOR_END)) { return 4; } if (isCodeBetween(second, VARIATION_MODIFIER_BEGIN, VARIATION_MODIFIER_END)) { return 3; } return 2; } if (isCodeBetween(string[index + 1], VARIATION_MODIFIER_BEGIN, VARIATION_MODIFIER_END)) { return 2; } return 1; } return {ASCII_LOWERCASE:ASCII_LOWERCASE, ASCII_UPPERCASE:ASCII_UPPERCASE, ASCII_LETTERS:ASCII_LETTERS, format:function(s) { var i = 0, regexp, args = pc.makeArray(arguments); args.shift(); for (i = 0; i < args.length; i++) { regexp = new RegExp("\\{" + i + "\\}", "gi"); s = s.replace(regexp, args[i]); } return s; }, toBool:function(s, strict) { if (s === "true") { return true; } if (strict) { if (s === "false") { return false; } throw new TypeError("Not a boolean string"); } return false; }, getCodePoint:function(string, i) { var codePointData = getCodePointData(string, i); return codePointData && codePointData.code; }, getCodePoints:function(string) { if (typeof string !== "string") { throw new TypeError("Not a string"); } var i = 0; var arr = []; var codePoint; while (!!(codePoint = getCodePointData(string, i))) { arr.push(codePoint.code); i += codePoint.long ? 2 : 1; } return arr; }, getSymbols:function(string) { if (typeof string !== "string") { throw new TypeError("Not a string"); } var index = 0; var length = string.length; var output = []; var take = 0; var ch; while (index < length) { take += numCharsToTakeForNextSymbol(string, index + take); ch = string[index + take]; if (isCodeBetween(ch, DIACRITICAL_MARKS_BEGIN, DIACRITICAL_MARKS_END)) { ch = string[index + take++]; } if (isCodeBetween(ch, VARIATION_MODIFIER_BEGIN, VARIATION_MODIFIER_END)) { ch = string[index + take++]; } if (ch && ch.charCodeAt(0) === ZERO_WIDTH_JOINER) { ch = string[index + take++]; continue; } var char = string.substring(index, index + take); output.push(char); index += take; take = 0; } return output; }, fromCodePoint:function() { var chars = []; var current; var codePoint; var units; for (var i = 0; i < arguments.length; ++i) { current = Number(arguments[i]); codePoint = current - 65536; units = current > 65535 ? [(codePoint >> 10) + 55296, codePoint % 1024 + 56320] : [current]; chars.push(String.fromCharCode.apply(null, units)); } return chars.join(""); }}; }(); pc.debug = function() { var table = null; var row = null; var title = null; var field = null; return {display:function(data) { function init() { table = document.createElement("table"); row = document.createElement("tr"); title = document.createElement("td"); field = document.createElement("td"); table.style.cssText = "position:absolute;font-family:sans-serif;font-size:12px;color:#cccccc"; table.style.top = "0px"; table.style.left = "0px"; table.style.border = "thin solid #cccccc"; document.body.appendChild(table); } if (!table) { init(); } table.innerHTML = ""; for (var key in data) { var r = row.cloneNode(); var t = title.cloneNode(); var f = field.cloneNode(); t.textContent = key; f.textContent = data[key]; r.appendChild(t); r.appendChild(f); table.appendChild(r); } }}; }(); Object.assign(pc, function() { var EventHandler = function() { this._callbacks = {}; this._callbackActive = {}; }; Object.assign(EventHandler.prototype, {_addCallback:function(name, callback, scope, once) { if (!name || typeof name !== "string" || !callback) { return; } if (!this._callbacks[name]) { this._callbacks[name] = []; } if (this._callbackActive[name] && this._callbackActive[name] === this._callbacks[name]) { this._callbackActive[name] = this._callbackActive[name].slice(); } this._callbacks[name].push({callback:callback, scope:scope || this, once:once || false}); }, on:function(name, callback, scope) { this._addCallback(name, callback, scope, false); return this; }, off:function(name, callback, scope) { if (name) { if (this._callbackActive[name] && this._callbackActive[name] === this._callbacks[name]) { this._callbackActive[name] = this._callbackActive[name].slice(); } } else { for (var key in this._callbackActive) { if (!this._callbacks[key]) { continue; } if (this._callbacks[key] !== this._callbackActive[key]) { continue; } this._callbackActive[key] = this._callbackActive[key].slice(); } } if (!name) { this._callbacks = {}; } else { if (!callback) { if (this._callbacks[name]) { this._callbacks[name] = []; } } else { var events = this._callbacks[name]; if (!events) { return this; } var count = events.length; for (var i = 0; i < count; i++) { if (events[i].callback !== callback) { continue; } if (scope && events[i].scope !== scope) { continue; } events[i--] = events[--count]; } events.length = count; } } return this; }, fire:function(name, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) { if (!name || !this._callbacks[name]) { return this; } var callbacks; if (!this._callbackActive[name]) { this._callbackActive[name] = this._callbacks[name]; } else { if (this._callbackActive[name] === this._callbacks[name]) { this._callbackActive[name] = this._callbackActive[name].slice(); } callbacks = this._callbacks[name].slice(); } for (var i = 0; (callbacks || this._callbackActive[name]) && i < (callbacks || this._callbackActive[name]).length; i++) { var evt = (callbacks || this._callbackActive[name])[i]; evt.callback.call(evt.scope, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); if (evt.once) { var ind = this._callbacks[name].indexOf(evt); if (ind !== -1) { if (this._callbackActive[name] === this._callbacks[name]) { this._callbackActive[name] = this._callbackActive[name].slice(); } this._callbacks[name].splice(ind, 1); } } } if (!callbacks) { this._callbackActive[name] = null; } return this; }, once:function(name, callback, scope) { this._addCallback(name, callback, scope, true); return this; }, hasEvent:function(name) { return this._callbacks[name] && this._callbacks[name].length !== 0 || false; }}); return {EventHandler:EventHandler}; }()); pc.events = {attach:function(target) { var ev = pc.events; target._addCallback = ev._addCallback; target.on = ev.on; target.off = ev.off; target.fire = ev.fire; target.once = ev.once; target.hasEvent = ev.hasEvent; target._callbacks = {}; target._callbackActive = {}; return target; }, _addCallback:pc.EventHandler.prototype._addCallback, on:pc.EventHandler.prototype.on, off:pc.EventHandler.prototype.off, fire:pc.EventHandler.prototype.fire, once:pc.EventHandler.prototype.once, hasEvent:pc.EventHandler.prototype.hasEvent}; Object.assign(pc, function() { var TagsCache = function(key) { this._index = {}; this._key = key || null; }; Object.assign(TagsCache.prototype, {addItem:function(item) { var tags = item.tags._list; for (var i = 0; i < tags.length; i++) { this.add(tags[i], item); } }, removeItem:function(item) { var tags = item.tags._list; for (var i = 0; i < tags.length; i++) { this.remove(tags[i], item); } }, add:function(tag, item) { if (this._index[tag] && this._index[tag].list.indexOf(item) !== -1) { return; } if (!this._index[tag]) { this._index[tag] = {list:[]}; if (this._key) { this._index[tag].keys = {}; } } this._index[tag].list.push(item); if (this._key) { this._index[tag].keys[item[this._key]] = item; } }, remove:function(tag, item) { if (!this._index[tag]) { return; } if (this._key) { if (!this._index[tag].keys[item[this._key]]) { return; } } var ind = this._index[tag].indexOf(item); if (ind === -1) { return; } this._index[tag].list.splice(ind, 1); if (this._key) { delete this._index[tag].keys[item[this._key]]; } if (this._index[tag].list.length === 0) { delete this._index[tag]; } }, find:function(args) { var self = this; var index = {}; var items = []; var i, n, t; var item, tag, tags, tagsRest, missingIndex; var sort = function(a, b) { return self._index[a].list.length - self._index[b].list.length; }; for (i = 0; i < args.length; i++) { tag = args[i]; if (tag instanceof Array) { if (tag.length === 0) { continue; } if (tag.length === 1) { tag = tag[0]; } else { missingIndex = false; for (t = 0; t < tag.length; t++) { if (!this._index[tag[t]]) { missingIndex = true; break; } } if (missingIndex) { continue; } tags = tag.slice(0).sort(sort); tagsRest = tags.slice(1); if (tagsRest.length === 1) { tagsRest = tagsRest[0]; } for (n = 0; n < this._index[tags[0]].list.length; n++) { item = this._index[tags[0]].list[n]; if ((this._key ? !index[item[this._key]] : items.indexOf(item) === -1) && item.tags.has(tagsRest)) { if (this._key) { index[item[this._key]] = true; } items.push(item); } } continue; } } if (tag && typeof tag === "string" && this._index[tag]) { for (n = 0; n < this._index[tag].list.length; n++) { item = this._index[tag].list[n]; if (this._key) { if (!index[item[this._key]]) { index[item[this._key]] = true; items.push(item); } } else { if (items.indexOf(item) === -1) { items.push(item); } } } } } return items; }}); var Tags = function(parent) { pc.EventHandler.call(this); this._index = {}; this._list = []; this._parent = parent; }; Tags.prototype = Object.create(pc.EventHandler.prototype); Tags.prototype.constructor = Tags; Object.assign(Tags.prototype, {add:function() { var changed = false; var tags = this._processArguments(arguments, true); if (!tags.length) { return changed; } for (var i = 0; i < tags.length; i++) { if (this._index[tags[i]]) { continue; } changed = true; this._index[tags[i]] = true; this._list.push(tags[i]); this.fire("add", tags[i], this._parent); } if (changed) { this.fire("change", this._parent); } return changed; }, remove:function() { var changed = false; if (!this._list.length) { return changed; } var tags = this._processArguments(arguments, true); if (!tags.length) { return changed; } for (var i = 0; i < tags.length; i++) { if (!this._index[tags[i]]) { continue; } changed = true; delete this._index[tags[i]]; this._list.splice(this._list.indexOf(tags[i]), 1); this.fire("remove", tags[i], this._parent); } if (changed) { this.fire("change", this._parent); } return changed; }, clear:function() { if (!this._list.length) { return; } var tags = this._list.slice(0); this._list = []; this._index = {}; for (var i = 0; i < tags.length; i++) { this.fire("remove", tags[i], this._parent); } this.fire("change", this._parent); }, has:function() { if (!this._list.length) { return false; } return this._has(this._processArguments(arguments)); }, _has:function(tags) { if (!this._list.length || !tags.length) { return false; } for (var i = 0; i < tags.length; i++) { if (tags[i].length === 1) { if (this._index[tags[i][0]]) { return true; } } else { var multiple = true; for (var t = 0; t < tags[i].length; t++) { if (this._index[tags[i][t]]) { continue; } multiple = false; break; } if (multiple) { return true; } } } return false; }, list:function() { return this._list.slice(0); }, _processArguments:function(args, flat) { var tags = []; var tmp = []; if (!args || !args.length) { return tags; } for (var i = 0; i < args.length; i++) { if (args[i] instanceof Array) { if (!flat) { tmp = []; } for (var t = 0; t < args[i].length; t++) { if (typeof args[i][t] !== "string") { continue; } if (flat) { tags.push(args[i][t]); } else { tmp.push(args[i][t]); } } if (!flat && tmp.length) { tags.push(tmp); } } else { if (typeof args[i] === "string") { if (flat) { tags.push(args[i]); } else { tags.push([args[i]]); } } } } return tags; }}); Object.defineProperty(Tags.prototype, "size", {get:function() { return this._list.length; }}); return {TagsCache:TagsCache, Tags:Tags}; }()); Object.assign(pc, function() { var AllocatePool = function(constructor, size) { this._constructor = constructor; this._pool = []; this._count = 0; this._resize(size); }; Object.assign(AllocatePool.prototype, {_resize:function(size) { if (size > this._pool.length) { for (var i = this._pool.length; i < size; i++) { this._pool[i] = new this._constructor; } } }, allocate:function() { if (this._count >= this._pool.length) { this._resize(this._pool.length * 2); } return this._pool[this._count++]; }, freeAll:function() { this._count = 0; }}); return {AllocatePool:AllocatePool}; }()); Object.assign(pc, function() { var platform = {desktop:false, mobile:false, ios:false, android:false, windows:false, xbox:false, gamepads:false, touch:false, workers:false, passiveEvents:false}; if (typeof navigator !== "undefined") { var ua = navigator.userAgent; if (/(windows|mac os|linux|cros)/i.test(ua)) { platform.desktop = true; } if (/xbox/i.test(ua)) { platform.xbox = true; } if (/(windows phone|iemobile|wpdesktop)/i.test(ua)) { platform.desktop = false; platform.mobile = true; platform.windows = true; } else { if (/android/i.test(ua)) { platform.desktop = false; platform.mobile = true; platform.android = true; } else { if (/ip([ao]d|hone)/i.test(ua)) { platform.desktop = false; platform.mobile = true; platform.ios = true; } } } if (typeof window !== "undefined") { platform.touch = "ontouchstart" in window || "maxTouchPoints" in navigator && navigator.maxTouchPoints > 0; } platform.gamepads = "getGamepads" in navigator; platform.workers = typeof Worker !== "undefined"; try { var opts = Object.defineProperty({}, "passive", {get:function() { platform.passiveEvents = true; return false; }}); window.addEventListener("testpassive", null, opts); window.removeEventListener("testpassive", null, opts); } catch (e) { } } return {platform:platform}; }()); Object.assign(pc, function() { var IndexedList = function() { this._list = []; this._index = {}; }; Object.assign(IndexedList.prototype, {push:function(key, item) { if (this._index[key]) { throw Error("Key already in index " + key); } var location = this._list.push(item) - 1; this._index[key] = location; }, has:function(key) { return this._index[key] !== undefined; }, get:function(key) { var location = this._index[key]; if (location !== undefined) { return this._list[location]; } return null; }, remove:function(key) { var location = this._index[key]; if (location !== undefined) { this._list.splice(location, 1); delete this._index[key]; for (key in this._index) { var idx = this._index[key]; if (idx > location) { this._index[key] = idx - 1; } } return true; } return false; }, list:function() { return this._list; }, clear:function() { this._list.length = 0; for (var prop in this._index) { delete this._index[prop]; } }}); return {IndexedList:IndexedList}; }()); pc.math = {DEG_TO_RAD:Math.PI / 180, RAD_TO_DEG:180 / Math.PI, clamp:function(value, min, max) { if (value >= max) { return max; } if (value <= min) { return min; } return value; }, intToBytes24:function(i) { var r, g, b; r = i >> 16 & 255; g = i >> 8 & 255; b = i & 255; return [r, g, b]; }, intToBytes32:function(i) { var r, g, b, a; r = i >> 24 & 255; g = i >> 16 & 255; b = i >> 8 & 255; a = i & 255; return [r, g, b, a]; }, bytesToInt24:function(r, g, b) { if (r.length) { b = r[2]; g = r[1]; r = r[0]; } return r << 16 | g << 8 | b; }, bytesToInt32:function(r, g, b, a) { if (r.length) { a = r[3]; b = r[2]; g = r[1]; r = r[0]; } return (r << 24 | g << 16 | b << 8 | a) >>> 32; }, lerp:function(a, b, alpha) { return a + (b - a) * pc.math.clamp(alpha, 0, 1); }, lerpAngle:function(a, b, alpha) { if (b - a > 180) { b -= 360; } if (b - a < -180) { b += 360; } return pc.math.lerp(a, b, pc.math.clamp(alpha, 0, 1)); }, powerOfTwo:function(x) { return x !== 0 && !(x & x - 1); }, nextPowerOfTwo:function(val) { val--; val |= val >> 1; val |= val >> 2; val |= val >> 4; val |= val >> 8; val |= val >> 16; val++; return val; }, random:function(min, max) { var diff = max - min; return Math.random() * diff + min; }, smoothstep:function(min, max, x) { if (x <= min) { return 0; } if (x >= max) { return 1; } x = (x - min) / (max - min); return x * x * (3 - 2 * x); }, smootherstep:function(min, max, x) { if (x <= min) { return 0; } if (x >= max) { return 1; } x = (x - min) / (max - min); return x * x * x * (x * (x * 6 - 15) + 10); }}; Object.assign(pc, function() { var Vec2 = function(x, y) { if (x && x.length === 2) { this.x = x[0]; this.y = x[1]; } else { this.x = x || 0; this.y = y || 0; } }; Object.assign(Vec2.prototype, {add:function(rhs) { this.x += rhs.x; this.y += rhs.y; return this; }, add2:function(lhs, rhs) { this.x = lhs.x + rhs.x; this.y = lhs.y + rhs.y; return this; }, clone:function() { return (new Vec2).copy(this); }, copy:function(rhs) { this.x = rhs.x; this.y = rhs.y; return this; }, distance:function(rhs) { var x = this.x - rhs.x; var y = this.y - rhs.y; return Math.sqrt(x * x + y * y); }, dot:function(rhs) { return this.x * rhs.x + this.y * rhs.y; }, equals:function(rhs) { return this.x === rhs.x && this.y === rhs.y; }, length:function() { return Math.sqrt(this.x * this.x + this.y * this.y); }, lengthSq:function() { return this.x * this.x + this.y * this.y; }, lerp:function(lhs, rhs, alpha) { this.x = lhs.x + alpha * (rhs.x - lhs.x); this.y = lhs.y + alpha * (rhs.y - lhs.y); return this; }, mul:function(rhs) { this.x *= rhs.x; this.y *= rhs.y; return this; }, mul2:function(lhs, rhs) { this.x = lhs.x * rhs.x; this.y = lhs.y * rhs.y; return this; }, normalize:function() { var lengthSq = this.x * this.x + this.y * this.y; if (lengthSq > 0) { var invLength = 1 / Math.sqrt(lengthSq); this.x *= invLength; this.y *= invLength; } return this; }, scale:function(scalar) { this.x *= scalar; this.y *= scalar; return this; }, set:function(x, y) { this.x = x; this.y = y; return this; }, sub:function(rhs) { this.x -= rhs.x; this.y -= rhs.y; return this; }, sub2:function(lhs, rhs) { this.x = lhs.x - rhs.x; this.y = lhs.y - rhs.y; return this; }, toString:function() { return "[" + this.x + ", " + this.y + "]"; }}); Object.defineProperties(Vec2, {ZERO:{value:new Vec2(0, 0)}, ONE:{value:new Vec2(1, 1)}, UP:{value:new Vec2(0, 1)}, DOWN:{value:new Vec2(0, -1)}, RIGHT:{value:new Vec2(1, 0)}, LEFT:{value:new Vec2(-1, 0)}}); return {Vec2:Vec2}; }()); Object.assign(pc, function() { var Vec3 = function(x, y, z) { if (x && x.length === 3) { this.x = x[0]; this.y = x[1]; this.z = x[2]; } else { this.x = x || 0; this.y = y || 0; this.z = z || 0; } }; Object.assign(Vec3.prototype, {add:function(rhs) { this.x += rhs.x; this.y += rhs.y; this.z += rhs.z; return this; }, add2:function(lhs, rhs) { this.x = lhs.x + rhs.x; this.y = lhs.y + rhs.y; this.z = lhs.z + rhs.z; return this; }, clone:function() { return (new Vec3).copy(this); }, copy:function(rhs) { this.x = rhs.x; this.y = rhs.y; this.z = rhs.z; return this; }, cross:function(lhs, rhs) { var lx = lhs.x; var ly = lhs.y; var lz = lhs.z; var rx = rhs.x; var ry = rhs.y; var rz = rhs.z; this.x = ly * rz - ry * lz; this.y = lz * rx - rz * lx; this.z = lx * ry - rx * ly; return this; }, distance:function(rhs) { var x = this.x - rhs.x; var y = this.y - rhs.y; var z = this.z - rhs.z; return Math.sqrt(x * x + y * y + z * z); }, dot:function(rhs) { return this.x * rhs.x + this.y * rhs.y + this.z * rhs.z; }, equals:function(rhs) { return this.x === rhs.x && this.y === rhs.y && this.z === rhs.z; }, length:function() { return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z); }, lengthSq:function() { return this.x * this.x + this.y * this.y + this.z * this.z; }, lerp:function(lhs, rhs, alpha) { this.x = lhs.x + alpha * (rhs.x - lhs.x); this.y = lhs.y + alpha * (rhs.y - lhs.y); this.z = lhs.z + alpha * (rhs.z - lhs.z); return this; }, mul:function(rhs) { this.x *= rhs.x; this.y *= rhs.y; this.z *= rhs.z; return this; }, mul2:function(lhs, rhs) { this.x = lhs.x * rhs.x; this.y = lhs.y * rhs.y; this.z = lhs.z * rhs.z; return this; }, normalize:function() { var lengthSq = this.x * this.x + this.y * this.y + this.z * this.z; if (lengthSq > 0) { var invLength = 1 / Math.sqrt(lengthSq); this.x *= invLength; this.y *= invLength; this.z *= invLength; } return this; }, project:function(rhs) { var a_dot_b = this.x * rhs.x + this.y * rhs.y + this.z * rhs.z; var b_dot_b = rhs.x * rhs.x + rhs.y * rhs.y + rhs.z * rhs.z; var s = a_dot_b / b_dot_b; this.x = rhs.x * s; this.y = rhs.y * s; this.z = rhs.z * s; return this; }, scale:function(scalar) { this.x *= scalar; this.y *= scalar; this.z *= scalar; return this; }, set:function(x, y, z) { this.x = x; this.y = y; this.z = z; return this; }, sub:function(rhs) { this.x -= rhs.x; this.y -= rhs.y; this.z -= rhs.z; return this; }, sub2:function(lhs, rhs) { this.x = lhs.x - rhs.x; this.y = lhs.y - rhs.y; this.z = lhs.z - rhs.z; return this; }, toString:function() { return "[" + this.x + ", " + this.y + ", " + this.z + "]"; }}); Object.defineProperties(Vec3, {ZERO:{value:new Vec3(0, 0, 0)}, ONE:{value:new Vec3(1, 1, 1)}, UP:{value:new Vec3(0, 1, 0)}, DOWN:{value:new Vec3(0, -1, 0)}, RIGHT:{value:new Vec3(1, 0, 0)}, LEFT:{value:new Vec3(-1, 0, 0)}, FORWARD:{value:new Vec3(0, 0, -1)}, BACK:{value:new Vec3(0, 0, 1)}}); return {Vec3:Vec3}; }()); Object.assign(pc, function() { var Vec4 = function(x, y, z, w) { if (x && x.length === 4) { this.x = x[0]; this.y = x[1]; this.z = x[2]; this.w = x[3]; } else { this.x = x || 0; this.y = y || 0; this.z = z || 0; this.w = w || 0; } }; Object.assign(Vec4.prototype, {add:function(rhs) { this.x += rhs.x; this.y += rhs.y; this.z += rhs.z; this.w += rhs.w; return this; }, add2:function(lhs, rhs) { this.x = lhs.x + rhs.x; this.y = lhs.y + rhs.y; this.z = lhs.z + rhs.z; this.w = lhs.w + rhs.w; return this; }, clone:function() { return (new Vec4).copy(this); }, copy:function(rhs) { this.x = rhs.x; this.y = rhs.y; this.z = rhs.z; this.w = rhs.w; return this; }, dot:function(rhs) { return this.x * rhs.x + this.y * rhs.y + this.z * rhs.z + this.w * rhs.w; }, equals:function(rhs) { return this.x === rhs.x && this.y === rhs.y && this.z === rhs.z && this.w === rhs.w; }, length:function() { return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w); }, lengthSq:function() { return this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; }, lerp:function(lhs, rhs, alpha) { this.x = lhs.x + alpha * (rhs.x - lhs.x); this.y = lhs.y + alpha * (rhs.y - lhs.y); this.z = lhs.z + alpha * (rhs.z - lhs.z); this.w = lhs.w + alpha * (rhs.w - lhs.w); return this; }, mul:function(rhs) { this.x *= rhs.x; this.y *= rhs.y; this.z *= rhs.z; this.w *= rhs.w; return this; }, mul2:function(lhs, rhs) { this.x = lhs.x * rhs.x; this.y = lhs.y * rhs.y; this.z = lhs.z * rhs.z; this.w = lhs.w * rhs.w; return this; }, normalize:function() { var lengthSq = this.x * this.x + this.y * this.y + this.z * this.z + this.w * this.w; if (lengthSq > 0) { var invLength = 1 / Math.sqrt(lengthSq); this.x *= invLength; this.y *= invLength; this.z *= invLength; this.w *= invLength; } return this; }, scale:function(scalar) { this.x *= scalar; this.y *= scalar; this.z *= scalar; this.w *= scalar; return this; }, set:function(x, y, z, w) { this.x = x; this.y = y; this.z = z; this.w = w; return this; }, sub:function(rhs) { this.x -= rhs.x; this.y -= rhs.y; this.z -= rhs.z; this.w -= rhs.w; return this; }, sub2:function(lhs, rhs) { this.x = lhs.x - rhs.x; this.y = lhs.y - rhs.y; this.z = lhs.z - rhs.z; this.w = lhs.w - rhs.w; return this; }, toString:function() { return "[" + this.x + ", " + this.y + ", " + this.z + ", " + this.w + "]"; }}); Object.defineProperties(Vec4, {ZERO:{value:new Vec4(0, 0, 0, 0)}, ONE:{value:new Vec4(1, 1, 1, 1)}}); return {Vec4:Vec4}; }()); Object.assign(pc, function() { var Mat3 = function() { var data; data = new Float32Array(9); data[0] = data[4] = data[8] = 1; this.data = data; }; Object.assign(Mat3.prototype, {clone:function() { return (new pc.Mat3).copy(this); }, copy:function(rhs) { var src = rhs.data; var dst = this.data; dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; dst[3] = src[3]; dst[4] = src[4]; dst[5] = src[5]; dst[6] = src[6]; dst[7] = src[7]; dst[8] = src[8]; return this; }, set:function(src) { var dst = this.data; dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; dst[3] = src[3]; dst[4] = src[4]; dst[5] = src[5]; dst[6] = src[6]; dst[7] = src[7]; dst[8] = src[8]; return this; }, equals:function(rhs) { var l = this.data; var r = rhs.data; return l[0] === r[0] && l[1] === r[1] && l[2] === r[2] && l[3] === r[3] && l[4] === r[4] && l[5] === r[5] && l[6] === r[6] && l[7] === r[7] && l[8] === r[8]; }, isIdentity:function() { var m = this.data; return m[0] === 1 && m[1] === 0 && m[2] === 0 && m[3] === 0 && m[4] === 1 && m[5] === 0 && m[6] === 0 && m[7] === 0 && m[8] === 1; }, setIdentity:function() { var m = this.data; m[0] = 1; m[1] = 0; m[2] = 0; m[3] = 0; m[4] = 1; m[5] = 0; m[6] = 0; m[7] = 0; m[8] = 1; return this; }, toString:function() { var t = "["; for (var i = 0; i < 9; i++) { t += this.data[i]; t += i !== 8 ? ", " : ""; } t += "]"; return t; }, transpose:function() { var m = this.data; var tmp; tmp = m[1]; m[1] = m[3]; m[3] = tmp; tmp = m[2]; m[2] = m[6]; m[6] = tmp; tmp = m[5]; m[5] = m[7]; m[7] = tmp; return this; }}); Object.defineProperties(Mat3, {ZERO:{value:(new Mat3).set([0, 0, 0, 0, 0, 0, 0, 0, 0])}, IDENTITY:{value:new Mat3}}); return {Mat3:Mat3}; }()); Object.assign(pc, function() { var Mat4 = function() { var data = new Float32Array(16); data[0] = data[5] = data[10] = data[15] = 1; this.data = data; }; Object.assign(Mat4.prototype, {add2:function(lhs, rhs) { var a = lhs.data, b = rhs.data, r = this.data; r[0] = a[0] + b[0]; r[1] = a[1] + b[1]; r[2] = a[2] + b[2]; r[3] = a[3] + b[3]; r[4] = a[4] + b[4]; r[5] = a[5] + b[5]; r[6] = a[6] + b[6]; r[7] = a[7] + b[7]; r[8] = a[8] + b[8]; r[9] = a[9] + b[9]; r[10] = a[10] + b[10]; r[11] = a[11] + b[11]; r[12] = a[12] + b[12]; r[13] = a[13] + b[13]; r[14] = a[14] + b[14]; r[15] = a[15] + b[15]; return this; }, add:function(rhs) { return this.add2(this, rhs); }, clone:function() { return (new pc.Mat4).copy(this); }, copy:function(rhs) { var src = rhs.data, dst = this.data; dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; dst[3] = src[3]; dst[4] = src[4]; dst[5] = src[5]; dst[6] = src[6]; dst[7] = src[7]; dst[8] = src[8]; dst[9] = src[9]; dst[10] = src[10]; dst[11] = src[11]; dst[12] = src[12]; dst[13] = src[13]; dst[14] = src[14]; dst[15] = src[15]; return this; }, equals:function(rhs) { var l = this.data, r = rhs.data; return l[0] === r[0] && l[1] === r[1] && l[2] === r[2] && l[3] === r[3] && l[4] === r[4] && l[5] === r[5] && l[6] === r[6] && l[7] === r[7] && l[8] === r[8] && l[9] === r[9] && l[10] === r[10] && l[11] === r[11] && l[12] === r[12] && l[13] === r[13] && l[14] === r[14] && l[15] === r[15]; }, isIdentity:function() { var m = this.data; return m[0] === 1 && m[1] === 0 && m[2] === 0 && m[3] === 0 && m[4] === 0 && m[5] === 1 && m[6] === 0 && m[7] === 0 && m[8] === 0 && m[9] === 0 && m[10] === 1 && m[11] === 0 && m[12] === 0 && m[13] === 0 && m[14] === 0 && m[15] === 1; }, mul2:function(lhs, rhs) { var a00, a01, a02, a03, a10, a11, a12, a13, a20, a21, a22, a23, a30, a31, a32, a33, b0, b1, b2, b3, a = lhs.data, b = rhs.data, r = this.data; a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; a30 = a[12]; a31 = a[13]; a32 = a[14]; a33 = a[15]; b0 = b[0]; b1 = b[1]; b2 = b[2]; b3 = b[3]; r[0] = a00 * b0 + a10 * b1 + a20 * b2 + a30 * b3; r[1] = a01 * b0 + a11 * b1 + a21 * b2 + a31 * b3; r[2] = a02 * b0 + a12 * b1 + a22 * b2 + a32 * b3; r[3] = a03 * b0 + a13 * b1 + a23 * b2 + a33 * b3; b0 = b[4]; b1 = b[5]; b2 = b[6]; b3 = b