Guest User

Untitled

a guest
Aug 14th, 2013
213
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // If another instance of the Shipviewer is loading the external JSONP resources, then we wait for it and add instance of ourselves ot the waiting list.
  2.  
  3. function CCPShipViewer(options) {
  4.     function tick() {
  5.         requestAnimFrame(tick), device.Tick()
  6.     }
  7.  
  8.     function Render() {
  9.         if (scene.objects.length > 1 && ref.selectedShip != null && !shipAssembled) {
  10.             for (var a = 0; a < scene.objects.length; ++a)
  11.                 if (typeof scene.objects[a]._objectLoaded != "undefined" && !scene.objects[a]._objectLoaded) return !0;
  12.             shipAssembled = !0;
  13.             for (var a = 0; a + 1 < scene.objects.length; ++a)
  14.                 for (var b = 0; b < scene.objects[a].locators.length; ++b)
  15.                     if (scene.objects[a].locators[b].name == "locator_attach_" + modules[a]) {
  16.                         var c = scene.objects[a].locators[b].transform;
  17.                         mat4.translate(scene.objects[a].transform, [c[12], c[13], c[14]], scene.objects[a + 1].transform);
  18.                         break
  19.                     }
  20.         }
  21.         if (ref.pendingResources == 0 && ref.selectedShip != null) {
  22.             if (ship && ship.boundingSphereCenter && minZoomDistance == -1) {
  23.                 var d = ship.boundingSphereRadius;
  24.                 loadingShip && ref.afterShipLoaded(), UpdateTurrets(), ship.boosters = resMan.GetObject(shipBooster, "EveBoosterSet"), minZoomDistance = settings.minZoomDistance || -1, minZoomDistance == -1 && ref.showOverlay ? minZoomDistance = d * 2.5 + 1 : minZoomDistance == -1 && (minZoomDistance = d * 1.3), ref.showOverlay ? camera.distance = minZoomDistance * 1.08 : camera.distance = minZoomDistance * 1.5, camera.currDistance = camera.distance * 2, ship.boosterGain = 0
  25.             }
  26.             if (showFPS) {
  27.                 var e = new Date;
  28.                 e = e.getTime(), prevTime == 0 && (prevTime = e);
  29.                 var f = (e - prevTime) * .001;
  30.                 document.getElementById(ref.containerId + "_FPS").innerHTML = "FPS: " + Math.floor(1 / f + .5), prevTime = e, e = null
  31.             }
  32.             camera.Update(f), scene.Update(f), device.SetStandardStates(device.RM_OPAQUE), device.gl.clearColor(0, 0, 0, 0), device.gl.clearDepth(1), device.gl.viewport(0, 0, device.gl.viewportWidth, device.gl.viewportHeight), device.gl.clear(device.gl.COLOR_BUFFER_BIT | device.gl.DEPTH_BUFFER_BIT), ship && ship.boosterGain < boosterGain && (ship.boosterGain += boosterGain / 80);
  33.             if (quality == 3) {
  34.                 var g = camera.GetView(),
  35.                     h = mat4.inverse(g, mat4.create()),
  36.                     i = mat4.multiplyVec4(h, [1, 1, 2, 0], quat4.create());
  37.                 vec3.set(i, scene.sunDirection)
  38.             }
  39.             device.SetProjection(camera.GetProjection()), device.SetView(camera.GetView()), scene.Render(), ref.postprocessEnabled && postprocess.Render()
  40.         }
  41.         return !0
  42.     }
  43.  
  44.     function ChangeTurret(a, b) {
  45.         var c = "locator_turret_" + a;
  46.         for (var d = 0; d < ship.turretSets.length; ++d)
  47.             if (ship.turretSets[d].locatorName == c) {
  48.                 ship.turretSets.splice(d, 1);
  49.                 break
  50.             }
  51.         ship.RebuildTurretPositions(), resMan.GetObject(b.model, undefined, function (a) {
  52.             a.locatorName = c, ApplyColorScheme(a), ship.turretSets.push(a), ship.RebuildTurretPositions()
  53.         })
  54.     }
  55.  
  56.     function UpdateTurrets() {
  57.         var slots = new Object;
  58.         for (var i = 0; i < ship.locators.length; ++i) {
  59.             var match = /^locator_turret_([0-9]+)[a-z]$/i.exec(ship.locators[i].name);
  60.             if (match) {
  61.                 var index = parseInt(match[1]);
  62.                 slots[index] = !0
  63.             }
  64.         }
  65.         if (ref.selectedShip.turrets != null)
  66.             for (slot in slots) {
  67.                 var turret = eval(ref.selectedShip.turrets[slot]);
  68.                 turret != undefined && ChangeTurret(slot, turret)
  69.             }
  70.     }
  71.  
  72.     function ApplyColorScheme(a) {
  73.         if (shipColorScheme && a.turretEffect && a.turretEffect.name != "not_overridable") {
  74.             var b = resMan.GetObjectNoInitialize(shipColorSchemePath);
  75.             for (param in b.parameters)
  76.                 if (typeof b.parameters[param].resourcePath == "undefined") {
  77.                     if (a.turretEffect.name == "half_overridable" && param == "GlowColor") continue;
  78.                     a.turretEffect.parameters[param] = b.parameters[param]
  79.                 }
  80.             a.turretEffect.BindParameters()
  81.         }
  82.     }
  83.  
  84.     function SelectShip(shipName) {
  85.         if (!loadingShip) {
  86.             if (shipName == undefined || shipName == "") {
  87.                 alert("CCP ShipViewer: Shipname not specified."), ref.selectedShip = null;
  88.                 return
  89.             }
  90.             shipName = shipName.replace("%20", "").replace(" ", "").replace("-", "").toLowerCase(), ref.postprocess = !1, ref.selectedShip = eval("CCPShipResourceList." + shipName);
  91.             if (ref.selectedShip == undefined) {
  92.                 alert("CCP ShipViewer: Ship '" + shipName + "' does not exist.");
  93.                 return
  94.             }
  95.             ref.selectedShipFact = eval("CCPShipFactList." + shipName);
  96.             var factShipName = ref.selectedShipFact.name;
  97.             loadingShip = !0;
  98.             var loadingBar = document.createElement("div");
  99.             loadingBar.id = "Loading_" + ref.containerId, loadingBar.className = "CCPShipViewerLoading", loadingBar.innerHTML = "Loading Ship " + factShipName, ref.container.appendChild(loadingBar), ref.container.insertBefore(loadingBar, ref.container.childNodes[0]), loadingBar = null, window.setTimeout(function () {
  100.                 settings.beforeShipChanged && settings.beforeShipChanged(ref.selectedShipFact);
  101.                 if (ref.isWebGL) {
  102.                     resMan.Clear(), ship = null, scene.objects = [];
  103.                     if (settings.showCubemap == undefined || settings.showCubemap != !1) ref.showOverlay == !0 ? scene.sky = resMan.GetObject("res:/skyboxoverlay.red", "EveSkybox") : scene.sky = resMan.GetObject("res:/skybox.red", "EveSkybox");
  104.                     shipBooster = ref.selectedShip.booster;
  105.                     if (ref.selectedShip.model.length == 1) ship = resMan.GetObject(ref.selectedShip.model[0], "EveShip"), scene.objects[0] = ship;
  106.                     else {
  107.                         shipAssembled = !1;
  108.                         for (var i = 0; i < ref.selectedShip.model.length; ++i) scene.objects[i] = resMan.GetObject(ref.selectedShip.model[i], "EveShip");
  109.                         ship = scene.objects[ref.selectedShip.model.length - 1]
  110.                     }
  111.                     minZoomDistance = -1, scene.SetEnvMapPath(0, eval(ref.selectedShip.nebula)[0]), scene.SetEnvMapPath(1, eval(ref.selectedShip.nebula)[1])
  112.                 } else {
  113.                     var fallbackImage = document.createElement("img");
  114.                     fallbackImage.id = "fallbackImage", fallbackImage.alt = ref.selectedShipFact.name, fallbackImage.src = ref.assetsPath + "fallback/" + shipName + ".jpg", fallbackImage.style.width = ref.width + "px", fallbackImage.style.height = ref.height + "px", ref.onFallbackImageLoaded(fallbackImage)
  115.                 }
  116.             }, 10)
  117.         }
  118.     }
  119.  
  120.     function TestCamera(a) {
  121.         this.distance = 1, this.currDistance = 1, this.minDistance = -1, this.fov = 60, this.rotationX = -0.4, this.rotationY = 0, this._dragX = 0, this._dragY = 0, this._lastRotationX = 0, this._lastRotationY = 0, this._rotationSpeedX = 0, this._rotationSpeedY = 0, this._measureRotation = null, this._moveEvent = null, this._upEvent = null;
  122.         var b = this,
  123.             c = navigator.userAgent;
  124.         c.indexOf("Chrome") == -1 && c.indexOf("Safari") == -1 ? (ref.container.addEventListener("DOMMouseScroll", function (c) {
  125.             return b.handleWheel(c, a)
  126.         }, !1), ref.container.addEventListener("mousewheel", function (c) {
  127.             return b.handleWheel(c, a)
  128.         }, !1)) : ref.container.addEventListener("mousewheel", function (c) {
  129.             return b.onDocumentMouseWheel(c, a)
  130.         }, !1)
  131.     }
  132.     var settings = options || {};
  133.     if (!settings.parentElementId) alert("CCP Shipviewer: You must specify the parentElementId parameter. This should be an id of the element on your page which holds the shipviewer.");
  134.     else {
  135.         if (!settings.defaultShip) {
  136.             alert("CCP Shipviewer: You must specify the defaultShip parameter. The defaultShip parameter specifies the name of the ship you want to display.");
  137.             return
  138.         }
  139.         var nebulaList = {
  140.             amarr: ["res:/texture/cubemap/amarr/a04_cube.cube", "res:/texture/cubemap/amarr/a04_cube_blur.cube"],
  141.             caldari: ["res:/texture/cubemap/caldari/c16_cube.cube", "res:/texture/cubemap/caldari/c16_cube_blur.cube"],
  142.             gallente: ["res:/texture/cubemap/gallente/g04_cube.cube", "res:/texture/cubemap/gallente/g04_cube_blur.cube"],
  143.             minmatar: ["res:/texture/cubemap/minmatar/m01_cube.cube", "res:/texture/cubemap/minmatar/m01_cube_blur.cube"]
  144.         }, turretList = {
  145.                 dualgigabeamlaseri: {
  146.                     name: "Dual Giga Beam Laser I",
  147.                     model: "res:/dx9/model/turret/energy/beam/xl/beam_gigadual_t1.red",
  148.                     colorScheme: "res:/dx9/model/turret/shaderpreset/turretpreset_amarr_t1.red"
  149.                 }
  150.             }, ref = this,
  151.             PI = Math.PI,
  152.             container = document.getElementById(settings.parentElementId);
  153.         ShipViewerWaitingList = ShipViewerWaitingList || [], ref.assetsPath = settings.assetsPath || "", ref.height = settings.height || 250, ref.width = settings.width || ref.container.clientWidth || 237, ref.cubeMap = settings.cubeMap || "res:/Texture/fitting_cubesss.cube", ref.overlayPath = settings.overlayPath, ref.pendingResources = 0, ref.shipResourceFileName = "shipresources.js", ref.shipFactsFileName = "shipfacts.js", ref.isWebGL = checkWebGLSupport(), ref.postprocessEnabled = !1, ref.selectedShip = null, ref.overlayPath != undefined ? ref.showOverlay = !0 : ref.showOverlay = !1, ref.postprocessEnabled = !ref.showOverlay;
  154.         var postprocess = null;
  155.         this.containerId = settings.parentElementId, this.theta = 45, this.onMouseDownTheta = 45, this.phi = 60, this.onMouseDownPhi = 60, this.isMouseDown = !1, this.phiDiff = 0, this.thetaDiff = 0;
  156.         var loadingShip = !1,
  157.             device = null,
  158.             shipAssembled = !1,
  159.             defaultShip = settings.defaultShip || "",
  160.             quality = settings.quality || 0,
  161.             boosterGain = settings.boosterGain || .3,
  162.             showFPS = settings.showFPS || !1,
  163.             pitchWave = 0,
  164.             pitchSmallWave = 0,
  165.             rollWave = 0,
  166.             rollSmallWave = 0,
  167.             doAnimation = !0,
  168.             onMouseDownPosition = [0, 0],
  169.             ship = null,
  170.             boosters = null,
  171.             scene = null,
  172.             camera = null,
  173.             shipColorScheme = null,
  174.             shipColorSchemePath = null,
  175.             prevTime = 0,
  176.             minZoomDistance = -1,
  177.             shipBooster = "",
  178.             restorePosition, restoreLeft, restoreTop, restoreWidth, restoreHeight, restoreIndex;
  179.         if (ref.isWebGL) {
  180.             function Tw2ObjectReader(a) {
  181.                 this.xmlNode = a
  182.             }
  183.             Tw2ObjectReader.prototype.Construct = function (a) {
  184.                 this._inputStack = [], this._inputStack.push([this.xmlNode.documentElement, this, "result"]), this._initializeObjects = [];
  185.                 var b = this;
  186.                 return function () {
  187.                     return b.ConstructFromNode(a, !0)
  188.                 }
  189.             }, Tw2ObjectReader.prototype.ConstructAsync = function (a) {
  190.                 this._inputStack = [], this._inputStack.push([this.xmlNode.documentElement, this, "result"]);
  191.                 while (!this.ConstructFromNode(a, !1));
  192.                 return this.result
  193.             }, Tw2ObjectReader.prototype.ConstructFromNode = function (initialize, async) {
  194.                 var now = new Date,
  195.                     startTime = now.getTime();
  196.                 while (this._inputStack.length) {
  197.                     var endTime = now.getTime();
  198.                     if (async && resMan.prepareBudget < (endTime - startTime) * .001) return !1;
  199.                     var inputData = this._inputStack.shift(),
  200.                         xmlNode = inputData[0],
  201.                         parent = inputData[1],
  202.                         index = inputData[2];
  203.                     if (xmlNode == null) {
  204.                         initialize && typeof parent.Initialize != "undefined" && this._initializeObjects.push(parent);
  205.                         continue
  206.                     }
  207.                     var type = xmlNode.attributes.getNamedItem("type");
  208.                     if (type) {
  209.                         var object = null;
  210.                         if (type.value == "dict") object = new Object;
  211.                         else try {
  212.                             object = eval("new " + type.value + "()")
  213.                         } catch (e) {
  214.                             return
  215.                         }
  216.                         for (var i = 0; i < xmlNode.childNodes.length; ++i) {
  217.                             var child = xmlNode.childNodes[i];
  218.                             if (child.nodeName == "#text") continue;
  219.                             if (type.value != "dict" && typeof object[child.nodeName] == "undefined") {
  220.                                 log.LogWarn('YAML: object "' + type.value + '" does not have property "' + child.nodeName + '"');
  221.                                 continue
  222.                             }
  223.                             this._inputStack.push([child, object, child.nodeName])
  224.                         }
  225.                         this._inputStack.push([null, object, null]), parent[index] = object;
  226.                         continue
  227.                     }
  228.                     var list = xmlNode.attributes.getNamedItem("list");
  229.                     if (list) {
  230.                         object = [];
  231.                         var arrayIndex = 0;
  232.                         for (var i = 0; i < xmlNode.childNodes.length; ++i) {
  233.                             var child = xmlNode.childNodes[i];
  234.                             if (child.nodeName == "#text") continue;
  235.                             this._inputStack.push([child, object, arrayIndex++])
  236.                         }
  237.                         this._inputStack.push([null, object, null]), parent[index] = object;
  238.                         continue
  239.                     }
  240.                     var value = "";
  241.                     for (var i = 0; i < xmlNode.childNodes.length; ++i) {
  242.                         var child = xmlNode.childNodes[i];
  243.                         child.nodeName == "#text" && (value += child.data)
  244.                     }
  245.                     var json = xmlNode.attributes.getNamedItem("json");
  246.                     if (json) {
  247.                         try {
  248.                             parent[index] = eval(value)
  249.                         } catch (e) {}
  250.                         continue
  251.                     }
  252.                     var capture = /^(\-?\d+\.\d+(?:e|E\-?\d+)?)/.exec(value);
  253.                     if (capture) {
  254.                         parent[index] = parseFloat(capture[1]);
  255.                         continue
  256.                     }
  257.                     capture = /^(\-?\d+)/.exec(value);
  258.                     if (capture) {
  259.                         parent[index] = parseInt(capture[1]);
  260.                         continue
  261.                     }
  262.                     capture = /^\b(enabled|true|yes|on)\b/.exec(value);
  263.                     if (capture) {
  264.                         parent[index] = !0;
  265.                         continue
  266.                     }
  267.                     capture = /^\b(disabled|false|no|off)\b/.exec(value);
  268.                     if (capture) {
  269.                         parent[index] = !1;
  270.                         continue
  271.                     }
  272.                     parent[index] = value
  273.                 }
  274.                 while (this._initializeObjects.length) {
  275.                     var endTime = now.getTime();
  276.                     if (async && resMan.prepareBudget < (endTime - startTime) * .001) return !1;
  277.                     var object = this._initializeObjects.pop();
  278.                     object.Initialize()
  279.                 }
  280.                 return !0
  281.             };
  282.  
  283.             function Tw2Log() {
  284.                 this._Log = function (a, b) {
  285.                     return
  286.                 }, this.Log = function (a) {
  287.                     this._Log("Info", a)
  288.                 }, this.LogWarn = function (a) {
  289.                     this._Log("Warning", a)
  290.                 }, this.LogErr = function (a) {
  291.                     this._Log("Error", a)
  292.                 }
  293.             }
  294.             log = new Tw2Log;
  295.  
  296.             function Tw2Resource() {
  297.                 ref.pendingResources++, this.path = "", this._isLoading = !1, this._isGood = !1, this._notifications = []
  298.             }
  299.             Tw2Resource.prototype.IsLoading = function () {
  300.                 return this._isLoading
  301.             }, Tw2Resource.prototype.IsGood = function () {
  302.                 return this._isGood
  303.             }, Tw2Resource.prototype.LoadStarted = function () {
  304.                 this._isLoading = !0;
  305.                 for (var a = 0; a < this._notifications.length; ++a) this._notifications[a].ReleaseCachedData(this)
  306.             }, Tw2Resource.prototype.LoadFinished = function (a) {
  307.                 this._isLoading = !1, a || (this._isGood = !1)
  308.             }, Tw2Resource.prototype.PrepareFinished = function (a) {
  309.                 ref.pendingResources--, this._isLoading = !1, this._isGood = a;
  310.                 for (var b = 0; b < this._notifications.length; ++b) this._notifications[b].RebuildCachedData(this)
  311.             }, Tw2Resource.prototype.SetIsGood = function (a) {
  312.                 this._isGood = a
  313.             }, Tw2Resource.prototype.RegisterNotification = function (a) {
  314.                 for (var b = 0; b < this._notifications.length; ++b)
  315.                     if (this._notifications[b] == a) return;
  316.                 this._notifications[this._notifications.length] = a, this._isGood && a.RebuildCachedData(this)
  317.             }, Tw2Resource.prototype.UnregisterNotification = function (a) {
  318.                 for (var b = 0; b < this._notifications.length; ++b)
  319.                     if (this._notifications[b] == a) {
  320.                         this._notifications.splice(b, 1);
  321.                         return
  322.                     }
  323.             };
  324.  
  325.             function Inherit(a, b) {
  326.                 for (i in b.prototype) i in a.prototype || (a.prototype[i] = b.prototype[i]);
  327.                 a.prototype._super = b.prototype
  328.             }
  329.  
  330.             function Tw2VariableStore() {
  331.                 this._variables = new Object
  332.             }
  333.             Tw2VariableStore.prototype.RegisterVariableWithType = function (a, b, c) {
  334.                 return this._variables[a] = new c(a, b)
  335.             }, Tw2VariableStore.prototype.RegisterType = function (a, b) {
  336.                 return this._variables[a] = new b(a)
  337.             }, Tw2VariableStore.prototype.RegisterVariable = function (a, b) {
  338.                 if (b.constructor == (new glMatrixArrayType).constructor) {
  339.                     if (b.length == 16) return this.RegisterVariableWithType(a, b, Tw2MatrixParameter);
  340.                     if (b.length == 4) return this.RegisterVariableWithType(a, b, Tw2Vector4Parameter);
  341.                     if (b.length == 3) return this.RegisterVariableWithType(a, b, Tw2Vector3Parameter);
  342.                     if (b.length == 2) return this.RegisterVariableWithType(a, b, Tw2Vector2Parameter)
  343.                 } else if (typeof b == "string") return this.RegisterVariableWithType(a, b, Tw2TextureParameter)
  344.             };
  345.             var variableStore = new Tw2VariableStore;
  346.  
  347.             function Tw2MotherLode() {
  348.                 this._loadedObjects = new Object, this.Find = function (a) {
  349.                     return a in this._loadedObjects ? this._loadedObjects[a] : null
  350.                 }, this.Add = function (a, b) {
  351.                     this._loadedObjects[a] = b
  352.                 }, this.Clear = function () {
  353.                     this._loadedObjects = new Object
  354.                 }
  355.             }
  356.  
  357.             function Tw2LoadingObject() {
  358.                 this._super.constructor.call(this), this.object = null, this._redContents = null, this._objects = []
  359.             }
  360.             Tw2LoadingObject.prototype.AddObject = function (a, b, c) {
  361.                 if (this.IsGood()) {
  362.                     this.CreateObject(a, c, b);
  363.                     return !1
  364.                 }
  365.                 a._objectLoading = !0, a._loadCallback = b, typeof c != "undefined" && !c && (a._noInitialization = !0), this._objects[this._objects.length] = a;
  366.                 return !1
  367.             }, Tw2LoadingObject.prototype.CreateObject = function (a, b, c) {
  368.                 function d(a, b, c, d) {
  369.                     var e = new Tw2ObjectReader(a._redContents),
  370.                         f = null;
  371.                     return function () {
  372.                         f == null && (f = e.Construct(c));
  373.                         while (!f()) return !0;
  374.                         f = null;
  375.                         var g = e.result;
  376.                         for (var h in g) b[h] = g[h];
  377.                         b._objectLoaded = !0, delete b._objectLoading, typeof d != "undefined" && d(b), log.Log("Prepared " + a.path), a.PrepareFinished(!0);
  378.                         return !1
  379.                     }
  380.                 }
  381.                 a._objectLoading = !0, device.Schedule(d(this, a, b, c))
  382.             }, Tw2LoadingObject.prototype.Prepare = function (a, b) {
  383.                 typeof this._inPrepare == "undefined" && (this._redContents = b, log.Log("Preparing " + this.path), this._constructor = new Tw2ObjectReader(this._redContents), this._constructorFunction = null, this._inPrepare = 0);
  384.                 while (this._inPrepare < this._objects.length) {
  385.                     if (this._constructorFunction == null) {
  386.                         var c = !0;
  387.                         typeof this._objects[this._inPrepare]._noInitialization != "undefined" && (c = !1), delete this._objects[this._inPrepare]._noInitialization, this._constructorFunction = this._constructor.Construct(c)
  388.                     }
  389.                     while (!this._constructorFunction()) return !0;
  390.                     this._constructorFunction = null;
  391.                     var d = this._constructor.result;
  392.                     for (var e in d) this._objects[this._inPrepare][e] = d[e];
  393.                     this._objects[this._inPrepare]._objectLoaded = !0, delete this._objects[this._inPrepare]._objectLoading, typeof this._objects[this._inPrepare]._loadCallback != "undefined" && this._objects[this._inPrepare]._loadCallback(this._objects[this._inPrepare]), this._inPrepare++
  394.                 }
  395.                 log.Log("Prepared " + this.path), delete this._inPrepare, delete this._constructorFunction, delete this._constructor, this.PrepareFinished(!0)
  396.             }, Inherit(Tw2LoadingObject, Tw2Resource);
  397.  
  398.             function Tw2ResMan() {
  399.                 function _DoLoadResource(a, b) {
  400.                     return function () {
  401.                         readyState = 0;
  402.                         try {
  403.                             readyState = a.readyState
  404.                         } catch (c) {
  405.                             log.LogErr('ResMan: communication error when loading  "' + b.path + '" (readyState ' + readyState + ")"), b.LoadFinished(!1);
  406.                             return
  407.                         }
  408.                         if (readyState === 4)
  409.                             if (a.status === 200) {
  410.                                 b.LoadFinished(!0);
  411.                                 var d = null,
  412.                                     e = null;
  413.                                 try {
  414.                                     d = a.responseText, e = a.responseXML
  415.                                 } catch (c) {
  416.                                     d = a.response
  417.                                 }
  418.                                 resMan._prepareQueue.push([b, d, e])
  419.                             } else log.LogErr('ResMan: communication error when loading  "' + b.path + '" (code ' + a.status + ")"), b.LoadFinished(!1)
  420.                     }
  421.                 }
  422.  
  423.                 function PrepareLoop() {
  424.                     resMan.prepareBudget = resMan.maxPrepareTime;
  425.                     var a = new Date,
  426.                         b = a.getTime();
  427.                     resMan._prepareQueue.length && log.Log("Prepare frame " + resMan._prepareQueue.length);
  428.                     var c = 0;
  429.                     while (resMan._prepareQueue.length) {
  430.                         resMan._prepareQueue[0][0].Prepare(resMan._prepareQueue[0][1], resMan._prepareQueue[0][2]) || (resMan._prepareQueue.shift(), c++);
  431.                         var a = new Date;
  432.                         resMan.prepareBudget -= (a.getTime() - b) * .001;
  433.                         if (resMan.prepareBudget < 0) break
  434.                     }
  435.                     c && log.Log("Prepared  " + c + " in " + (resMan.maxPrepareTime - resMan.prepareBudget) + " sec");
  436.                     return !0
  437.                 }
  438.  
  439.                 function _GetPathExt(a) {
  440.                     if (a.substr(0, 5) == "str:/") {
  441.                         var b = a.indexOf("/", 5);
  442.                         return b == -1 ? null : a.substr(5, b - 5)
  443.                     }
  444.                     var c = a.lastIndexOf(".");
  445.                     return c == -1 ? null : a.substr(c + 1)
  446.                 }
  447.  
  448.                 function _NormalizePath(a) {
  449.                     if (a.substr(0, 5) == "str:/") return a;
  450.                     a = a.toLowerCase(), a.replace("\\", "/");
  451.                     return a
  452.                 }
  453.                 this._extensions = new Object, this.motherLode = new Tw2MotherLode, this.maxPrepareTime = .05, this.prepareBudget = 0, this._prepareQueue = [], this.RegisterExtension = function (a, b) {
  454.                     this._extensions[a] = b
  455.                 }, this._CreateHttpRequest = function () {
  456.                     var a = null;
  457.                     if (window.XMLHttpRequest) a = new XMLHttpRequest;
  458.                     else if (window.ActiveXObject) try {
  459.                         a = new ActiveXObject("Msxml2.XMLHTTP")
  460.                     } catch (b) {
  461.                         try {
  462.                             a = new ActiveXObject("Microsoft.XMLHTTP")
  463.                         } catch (b) {}
  464.                     }
  465.                     a || log.LogErr("ResMan: could not create an XMLHTTP instance");
  466.                     return a
  467.                 }, this.LogPathString = function (a) {
  468.                     return a.substr(0, 5) == "str:/" && a.length > 64 ? a.substr(0, 64) + "..." : a
  469.                 }, this.BuildUrl = function (a) {
  470.                     return a == "overlaypath.png" ? ref.overlayPath : a.substr(0, 5) != "res:/" ? a : ref.assetsPath + a.substr(5)
  471.                 }, this.GetResource = function (a, b) {
  472.                     a = _NormalizePath(a);
  473.                     if (!b) {
  474.                         d = this.motherLode.Find(a);
  475.                         if (d !== null) return d
  476.                     }
  477.                     var c = _GetPathExt(a);
  478.                     if (c == null) {
  479.                         log.LogErr("ResMan: unknown extension for path " + this.LogPathString(a));
  480.                         return null
  481.                     }
  482.                     if (c in this._extensions) {
  483.                         log.Log('ResMan: loading "' + this.LogPathString(a) + '"');
  484.                         var d = new this._extensions[c];
  485.                         d.path = a, b || this.motherLode.Add(a, d);
  486.                         if ("DoCustomLoad" in d) d.DoCustomLoad(a);
  487.                         else if (a.substr(0, 5) == "str:/") {
  488.                             d.LoadStarted(), d.LoadFinished(!0);
  489.                             var e = a.substr(a.indexOf("/", 5) + 1),
  490.                                 f = null;
  491.                             if (window.DOMParser) {
  492.                                 var g = new DOMParser;
  493.                                 f = g.parseFromString(e, "text/xml")
  494.                             } else f = new ActiveXObject("Microsoft.XMLDOM"), f.async = "false", f.loadXML(e);
  495.                             d.Prepare(e, f)
  496.                         } else {
  497.                             var h = this._CreateHttpRequest();
  498.                             h.onreadystatechange = _DoLoadResource(h, d), log.Log('ResMan: requesting "' + this.BuildUrl(a) + '"'), h.open("GET", this.BuildUrl(a)), d.constructor.prototype && d.constructor.prototype.requestResponseType && (h.responseType = d.constructor.prototype.requestResponseType), d.LoadStarted();
  499.                             try {
  500.                                 h.send()
  501.                             } catch (i) {
  502.                                 log.LogErr("ResMan: error sending resource HTTP request: " + i.toString())
  503.                             }
  504.                         }
  505.                         return d
  506.                     }
  507.                     log.LogErr("ResMan: unregistered extension  " + c);
  508.                     return null
  509.                 }, this.GetObject = function (a, b, c) {
  510.                     return this._GetObject(a, b, c, !0)
  511.                 }, this.GetObjectNoInitialize = function (a, b, c) {
  512.                     return this._GetObject(a, b, c, !1)
  513.                 }, this._GetObject = function (path, type, callback, initialize) {
  514.                     path = _NormalizePath(path);
  515.                     var obj = null;
  516.                     typeof type != "undefined" ? obj = eval("new " + type + "()") : obj = new Object;
  517.                     var res = this.motherLode.Find(path);
  518.                     if (res !== null) {
  519.                         res.AddObject(obj, callback, initialize);
  520.                         return obj
  521.                     }
  522.                     res = new Tw2LoadingObject, res.path = path, res.AddObject(obj, callback, initialize), this.motherLode.Add(path, res);
  523.                     if (path.substr(0, 5) == "str:/") {
  524.                         obj.LoadStarted(), obj._objectLoaded = !1, obj.LoadFinished(!0);
  525.                         var contents = path.substr(path.indexOf("/", 5) + 1),
  526.                             xmlDoc = null;
  527.                         if (window.DOMParser) {
  528.                             var parser = new DOMParser;
  529.                             xmlDoc = parser.parseFromString(contents, "text/xml")
  530.                         } else xmlDoc = new ActiveXObject("Microsoft.XMLDOM"), xmlDoc.async = "false", xmlDoc.loadXML(contents);
  531.                         obj.Prepare(contents, xmlDoc)
  532.                     } else {
  533.                         var httpRequest = this._CreateHttpRequest();
  534.                         httpRequest.onreadystatechange = _DoLoadResource(httpRequest, res), log.Log('ResMan: requesting "' + this.BuildUrl(path) + '"'), httpRequest.open("GET", this.BuildUrl(path)), res.LoadStarted(), obj._objectLoaded = !1;
  535.                         try {
  536.                             httpRequest.send()
  537.                         } catch (e) {
  538.                             log.LogErr("ResMan: error sending object HTTP request: " + e.toString())
  539.                         }
  540.                     }
  541.                     return obj
  542.                 }, this.Clear = function () {
  543.                     this.motherLode.Clear()
  544.                 }, this.Start = function () {
  545.                     device.Schedule(PrepareLoop)
  546.                 }
  547.             }
  548.             var resMan = new Tw2ResMan;
  549.  
  550.             function Tw2FloatParameter(a, b) {
  551.                 typeof a != "undefined" ? this.name = a : this.name = "", typeof b != "undefined" ? this.value = b : this.value = 1
  552.             }
  553.             Tw2FloatParameter.prototype.Apply = function (a, b) {
  554.                 device.gl.uniform1f(b, this.value)
  555.             };
  556.  
  557.             function Tw2GeometryBinaryMesh() {
  558.                 this.name = "", this.declaration = new Tw2VertexDeclaration, this.areas = [], this.buffer = null, this.bufferData = null, this.indexes = null, this.minBounds = vec3.create(), this.maxBounds = vec3.create(), this.boundsSpherePosition = vec3.create(), this.boundsSphereRadius = 0, this.bones = []
  559.             }
  560.  
  561.             function Tw2GeometryBinRes() {
  562.                 this._super.constructor.call(this), this.meshes = [], this.minBounds = vec3.create(), this.maxBounds = vec3.create(), this.boundsSpherePosition = vec3.create(), this.boundsSphereRadius = 0, this.models = [], this.animations = []
  563.             }
  564.  
  565.             function boundsIncludePoint(a, b, c) {
  566.                 a[0] > c[0] && (a[0] = c[0]), a[1] > c[1] && (a[1] = c[1]), a[2] > c[2] && (a[2] = c[2]), b[0] < c[0] && (b[0] = c[0]), b[1] < c[1] && (b[1] = c[1]), b[2] < c[2] && (b[2] = c[2])
  567.             }
  568.             Tw2GeometryBinRes.prototype.requestResponseType = "arraybuffer", Tw2GeometryBinRes.prototype.Prepare = function (a) {
  569.                 function B() {
  570.                     var a = b.ReadUInt8();
  571.                     if (a == 0) return null;
  572.                     var c = b.ReadUInt8(),
  573.                         d = new Tw2GeometryCurve;
  574.                     d.dimension = c, d.degree = b.ReadUInt8();
  575.                     var e = b.ReadUInt32();
  576.                     d.knots = new Float32Array(e);
  577.                     for (var f = 0; f < e; ++f) d.knots[f] = b.ReadFloat32();
  578.                     var g = b.ReadUInt32();
  579.                     d.controls = new Float32Array(g);
  580.                     for (var f = 0; f < g; ++f) d.controls[f] = b.ReadFloat32();
  581.                     return d
  582.                 }
  583.  
  584.                 function e() {
  585.                     if (b.ReadIndexBuffer) return b.ReadIndexBuffer();
  586.                     var a = b.ReadUInt8(),
  587.                         c = b.ReadUInt32();
  588.                     if (a == 0) {
  589.                         var d = new Uint16Array(c);
  590.                         for (var e = 0; e < c; ++e) d[e] = b.ReadUInt16();
  591.                         return d
  592.                     }
  593.                     var d = new Uint32Array(c);
  594.                     for (var e = 0; e < c; ++e) d[e] = b.ReadUInt32();
  595.                     return d
  596.                 }
  597.  
  598.                 function d(a) {
  599.                     var d = b.ReadUInt8(),
  600.                         e = 0;
  601.                     for (var f = 0; f < d; ++f) {
  602.                         var g = new Tw2VertexElement;
  603.                         g.usage = b.ReadUInt8(), g.usageIndex = b.ReadUInt8(), g.fileType = b.ReadUInt8(), g.type = g.fileType >> 5, g.offset = e, a.elements[f] = g, e += g.type + 1
  604.                     }
  605.                     a.stride = e;
  606.                     if (b.ReadVertexBuffer) return b.ReadVertexBuffer(a);
  607.                     var h = b.ReadUInt32();
  608.                     if (h == 0) return null;
  609.                     var i = new Float32Array(e * h),
  610.                         j = 0;
  611.                     for (var k = 0; k < h; ++k)
  612.                         for (var f = 0; f < d; ++f) switch (a.elements[f].fileType & 15) {
  613.                         case 0:
  614.                             if (a.elements[f].fileType & 16)
  615.                                 for (var l = 0; l <= a.elements[f].type; ++l) i[j++] = b.ReadInt8() / 127;
  616.                             else
  617.                                 for (var l = 0; l <= a.elements[f].type; ++l) i[j++] = b.ReadInt8();
  618.                             break;
  619.                         case 1:
  620.                             if (a.elements[f].fileType & 16)
  621.                                 for (var l = 0; l <= a.elements[f].type; ++l) i[j++] = b.ReadInt8() / 32767;
  622.                             else
  623.                                 for (var l = 0; l <= a.elements[f].type; ++l) i[j++] = b.ReadInt16();
  624.                             break;
  625.                         case 2:
  626.                             for (var l = 0; l <= a.elements[f].type; ++l) i[j++] = b.ReadInt32();
  627.                             break;
  628.                         case 3:
  629.                             for (var l = 0; l <= a.elements[f].type; ++l) i[j++] = b.ReadFloat16();
  630.                             break;
  631.                         case 4:
  632.                             for (var l = 0; l <= a.elements[f].type; ++l) i[j++] = b.ReadFloat32();
  633.                             break;
  634.                         case 8:
  635.                             if (a.elements[f].fileType & 16)
  636.                                 for (var l = 0; l <= a.elements[f].type; ++l) i[j++] = b.ReadUInt8() / 255;
  637.                             else
  638.                                 for (var l = 0; l <= a.elements[f].type; ++l) i[j++] = b.ReadUInt8();
  639.                             break;
  640.                         case 9:
  641.                             if (a.elements[f].fileType & 16)
  642.                                 for (var l = 0; l <= a.elements[f].type; ++l) i[j++] = b.ReadUInt8() / 65535;
  643.                             else
  644.                                 for (var l = 0; l <= a.elements[f].type; ++l) i[j++] = b.ReadUInt16();
  645.                             break;
  646.                         case 10:
  647.                             for (var l = 0; l <= a.elements[f].type; ++l) i[j++] = b.ReadUInt32();
  648.                             break;
  649.                         default:
  650.                             log.LogErr("Error loading wbg data " + c.path);
  651.                             throw 1
  652.                         }
  653.                     return i
  654.                 }
  655.                 var b = new Tw2BinaryReader(new Uint8Array(a)),
  656.                     c = this,
  657.                     f = b.ReadUInt8(),
  658.                     g = b.ReadUInt8();
  659.                 for (var h = 0; h < g; ++h) {
  660.                     var i = new Tw2GeometryBinaryMesh;
  661.                     i.name = b.ReadString();
  662.                     var j = d(i.declaration);
  663.                     i.buffer = device.gl.createBuffer(), device.gl.bindBuffer(device.gl.ARRAY_BUFFER, i.buffer), device.gl.bufferData(device.gl.ARRAY_BUFFER, j, device.gl.STATIC_DRAW);
  664.                     var k = e();
  665.                     i.indexes = device.gl.createBuffer(), device.gl.bindBuffer(device.gl.ELEMENT_ARRAY_BUFFER, i.indexes), device.gl.bufferData(device.gl.ELEMENT_ARRAY_BUFFER, k, device.gl.STATIC_DRAW);
  666.                     var l = b.ReadUInt8();
  667.                     for (var m = 0; m < l; ++m) i.areas[m] = new Tw2GeometryMeshArea, i.areas[m].name = b.ReadString(), i.areas[m].start = b.ReadUInt32(), i.areas[m].count = b.ReadUInt32(), i.areas[m].minBounds = vec3.create([b.ReadFloat32(), b.ReadFloat32(), b.ReadFloat32()]), i.areas[m].maxBounds = vec3.create([b.ReadFloat32(), b.ReadFloat32(), b.ReadFloat32()]);
  668.                     var n = b.ReadUInt8();
  669.                     i.boneBindings = [];
  670.                     for (var m = 0; m < n; ++m) i.boneBindings[m] = b.ReadString();
  671.                     var o = b.ReadUInt16();
  672.                     if (o) {
  673.                         i.bufferData = j, i.blendShapes = [];
  674.                         for (var m = 0; m < o; ++m) i.blendShapes[m] = new Tw2BlendShapeData, i.blendShapes[m].name = b.ReadString(), i.blendShapes[m].buffer = d(i.blendShapes[m].declaration), i.blendShapes[m].indexes = e()
  675.                     }
  676.                     this.meshes[h] = i
  677.                 }
  678.                 var p = b.ReadUInt8();
  679.                 for (var q = 0; q < p; ++q) {
  680.                     var r = new Tw2GeometryModel;
  681.                     r.name = b.ReadString(), r.skeleton = new Tw2GeometrySkeleton;
  682.                     var s = b.ReadUInt8();
  683.                     for (var t = 0; t < s; ++t) {
  684.                         var u = new Tw2GeometryBone;
  685.                         u.name = b.ReadString();
  686.                         var v = b.ReadUInt8();
  687.                         u.parentIndex = b.ReadUInt8(), u.parentIndex == 255 && (u.parentIndex = -1), v & 1 ? vec3.set([b.ReadFloat32(), b.ReadFloat32(), b.ReadFloat32()], u.position) : vec3.set([0, 0, 0], u.position), v & 2 ? quat4.set([b.ReadFloat32(), b.ReadFloat32(), b.ReadFloat32(), b.ReadFloat32()], u.orientation) : quat4.set([0, 0, 0, 1], u.orientation);
  688.                         if (v & 4)
  689.                             for (var w = 0; w < 9; ++w) u.scaleShear[w] = b.ReadFloat32();
  690.                         else mat3.identity(u.scaleShear);
  691.                         r.skeleton.bones[t] = u
  692.                     }
  693.                     for (var t = 0; t < r.skeleton.bones.length; ++t) r.skeleton.bones[t].UpdateTransform(), r.skeleton.bones[t].parentIndex != -1 ? mat4.multiply(r.skeleton.bones[r.skeleton.bones[t].parentIndex].worldTransform, r.skeleton.bones[t].localTransform, r.skeleton.bones[t].worldTransform) : mat4.set(r.skeleton.bones[t].localTransform, r.skeleton.bones[t].worldTransform), mat4.inverse(r.skeleton.bones[t].worldTransform, r.skeleton.bones[t].worldTransformInv);
  694.                     var x = b.ReadUInt8();
  695.                     for (var t = 0; t < x; ++t) {
  696.                         var y = new Tw2GeometryMeshBinding;
  697.                         y.mesh = this.meshes[b.ReadUInt8()];
  698.                         for (var z = 0; z < y.mesh.boneBindings.length; ++z) {
  699.                             var A = y.mesh.boneBindings[z],
  700.                                 u = r.FindBoneByName(A);
  701.                             u == null ? log.LogErr("Tw2GeometryBinRes: mesh '" + y.mesh.name + "' in file '" + this.path + "' has invalid bone name '" + A + "' for model '" + r.name + "'") : y.bones[y.bones.length] = u
  702.                         }
  703.                         r.meshBindings[r.meshBindings.length] = y
  704.                     }
  705.                     this.models[this.models.length] = r
  706.                 }
  707.                 var C = b.ReadUInt8();
  708.                 for (var m = 0; m < C; ++m) {
  709.                     var D = new Tw2GeometryAnimation;
  710.                     D.name = b.ReadString(), D.duration = b.ReadFloat32();
  711.                     var E = b.ReadUInt8();
  712.                     for (var t = 0; t < E; ++t) {
  713.                         var F = new Tw2GeometryTrackGroup;
  714.                         F.name = b.ReadString();
  715.                         for (var G = 0; G < this.models.length; ++G)
  716.                             if (this.models[G].name == A) {
  717.                                 F.model = this.models[G];
  718.                                 break
  719.                             }
  720.                         var H = b.ReadUInt8();
  721.                         for (var w = 0; w < H; ++w) {
  722.                             var I = new Tw2GeometryTransformTrack;
  723.                             I.name = b.ReadString(), I.orientation = B(), I.position = B(), I.scaleShear = B();
  724.                             if (I.orientation) {
  725.                                 var J = 0,
  726.                                     K = 0,
  727.                                     L = 0,
  728.                                     M = 0;
  729.                                 for (var N = 0; N < I.orientation.controls.length; N += 4) {
  730.                                     var O = I.orientation.controls[N],
  731.                                         P = I.orientation.controls[N + 1],
  732.                                         Q = I.orientation.controls[N + 2],
  733.                                         R = I.orientation.controls[N + 3];
  734.                                     J * O + K * P + L * Q + M * R < 0 && (I.orientation.controls[N] = -O, I.orientation.controls[N + 1] = -P, I.orientation.controls[N + 2] = -Q, I.orientation.controls[N + 3] = -R), J = O, K = P, L = Q, M = R
  735.                                 }
  736.                             }
  737.                             F.transformTracks[F.transformTracks.length] = I
  738.                         }
  739.                         D.trackGroups[D.trackGroups.length] = F
  740.                     }
  741.                     this.animations[this.animations.length] = D
  742.                 }
  743.                 this.PrepareFinished(!0)
  744.             }, Tw2GeometryBinRes.prototype.RenderAreas = function (a, b, c, d, e) {
  745.                 if (!this.IsGood()) return !1;
  746.                 var f = d.GetEffectRes();
  747.                 if (!f.IsGood()) return !1;
  748.                 if (a >= this.meshes.length) return !1;
  749.                 var g = d.GetActiveTechnique(),
  750.                     h = this.meshes[a];
  751.                 for (var i = 0; i < d.GetPassCount(g); ++i) {
  752.                     d.ApplyPass(g, i);
  753.                     var j = d.GetPassInput(g, i);
  754.                     for (var k = 0; k < j.elements.length; ++k) {
  755.                         var l = h.declaration.Find(j.elements[k]);
  756.                         if (l == -1) {
  757.                             log.LogErr("Error binding vertex buffer to effect attribute for usage " + j.elements[k].usage + " and index " + j.elements[k].usageIndex);
  758.                             return !1
  759.                         }
  760.                         device.gl.enableVertexAttribArray(j.elements[k].attribute), device.gl.bindBuffer(device.gl.ARRAY_BUFFER, h.buffer), device.gl.vertexAttribPointer(j.elements[k].attribute, h.declaration.elements[l].type + 1, device.gl.FLOAT, !1, h.declaration.stride * 4, h.declaration.elements[l].offset * 4)
  761.                     }
  762.                     device.gl.bindBuffer(device.gl.ELEMENT_ARRAY_BUFFER, h.indexes);
  763.                     if (typeof e != "undefined") {
  764.                         var m = [];
  765.                         for (var k = 0; k < c; ++k) k + b < h.areas.length && m.push([device.gl.TRIANGLES, h.areas[k + b].count * 3, device.gl.UNSIGNED_SHORT, h.areas[k + b].start * 2]);
  766.                         e(i, m)
  767.                     } else
  768.                         for (var k = 0; k < c; ++k) k + b < h.areas.length && device.gl.drawElements(device.gl.TRIANGLES, h.areas[k + b].count * 3, device.gl.UNSIGNED_SHORT, h.areas[k + b].start * 2)
  769.                 }
  770.                 return !0
  771.             }, Tw2GeometryBinRes.prototype.RenderDebugInfo = function (a) {
  772.                 if (!this.IsGood()) return !1;
  773.                 for (var b = 0; b < this.models.length; ++b)
  774.                     if (this.models[b].skeleton)
  775.                         for (var c = 0; c < this.models[b].skeleton.bones.length; ++c) {
  776.                             var d = this.models[b].skeleton.bones[c];
  777.                             if (d.parentIndex >= 0) {
  778.                                 var e = this.models[b].skeleton.bones[d.parentIndex];
  779.                                 a.AddLine([d.worldTransform[12], d.worldTransform[13], d.worldTransform[14]], [e.worldTransform[12], e.worldTransform[13], e.worldTransform[14]], [0, .7, 0, 1], [0, .7, 0, 1])
  780.                             }
  781.                         }
  782.             }, Inherit(Tw2GeometryBinRes, Tw2Resource), resMan.RegisterExtension("wbg", Tw2GeometryBinRes);
  783.  
  784.             function Tw2Vector2Parameter(a, b) {
  785.                 typeof a != "undefined" ? this.name = a : this.name = "", typeof b != "undefined" ? this.value = b : this.value = [1, 1]
  786.             }
  787.             Tw2Vector2Parameter.prototype.Apply = function (a, b) {
  788.                 device.gl.uniform2fv(b, this.value)
  789.             };
  790.  
  791.             function Tw2Vector3Parameter(a, b) {
  792.                 typeof a != "undefined" ? this.name = a : this.name = "", typeof b != "undefined" ? this.value = vec3.create(b) : this.value = vec3.create([1, 1, 1])
  793.             }
  794.             Tw2Vector3Parameter.prototype.Apply = function (a, b) {
  795.                 device.gl.uniform3fv(b, this.value)
  796.             };
  797.  
  798.             function Tw2Vector4Parameter(a, b) {
  799.                 typeof a != "undefined" ? this.name = a : this.name = "", typeof b != "undefined" ? this.value = b : this.value = [1, 1, 1, 1]
  800.             }
  801.             Tw2Vector4Parameter.prototype.Apply = function (a, b) {
  802.                 device.gl.uniform4fv(b, this.value)
  803.             };
  804.  
  805.             function Tw2VariableParameter(a, b) {
  806.                 typeof a != "undefined" ? this.name = a : this.name = "", typeof b != "undefined" ? this.variableName = b : this.variableName = ""
  807.             }
  808.             Tw2VariableParameter.prototype.Apply = function (a, b) {
  809.                 typeof variableStore._variables[this.variableName] != "undefined" && variableStore._variables[this.variableName].Apply(a, b)
  810.             };
  811.  
  812.             function Tw2MatrixParameter(a, b) {
  813.                 typeof a != "undefined" ? this.name = a : this.name = "", typeof b != "undefined" ? this.value = b : (this.value = mat4.create(), mat4.identity(this.value))
  814.             }
  815.             Tw2MatrixParameter.prototype.Apply = function (a, b) {
  816.                 device.gl.uniformMatrix4fv(b, !1, this.value)
  817.             };
  818.  
  819.             function Tw2TextureParameter(a, b) {
  820.                 typeof a != "undefined" ? this.name = a : this.name = "", this.textureRes = null, this.wrapS = 10497, this.wrapT = 10497, typeof b != "undefined" ? this.resourcePath = b : this.resourcePath = ""
  821.             }
  822.             Tw2TextureParameter.prototype.SetTexturePath = function (a) {
  823.                 this.resourcePath = a, this.resourcePath != "" && (this.textureRes = resMan.GetResource(this.resourcePath))
  824.             }, Tw2TextureParameter.prototype.Initialize = function () {
  825.                 this.resourcePath != "" && (this.textureRes = resMan.GetResource(this.resourcePath))
  826.             }, Tw2TextureParameter.prototype.Apply = function (a, b) {
  827.                 var c = device.ActivateTexture();
  828.                 this.textureRes == null || !this.textureRes.IsGood() ? this.textureRes.isCube ? device.gl.bindTexture(device.gl.TEXTURE_CUBE_MAP, device.GetFallbackCubeMap()) : device.gl.bindTexture(device.gl.TEXTURE_2D, device.GetFallbackTexture()) : this.textureRes.isCube ? (device.gl.bindTexture(device.gl.TEXTURE_CUBE_MAP, this.textureRes.texture), device.gl.texParameteri(device.gl.TEXTURE_CUBE_MAP, device.gl.TEXTURE_WRAP_S, device.gl.CLAMP_TO_EDGE), device.gl.texParameteri(device.gl.TEXTURE_CUBE_MAP, device.gl.TEXTURE_WRAP_T, device.gl.CLAMP_TO_EDGE)) : (device.gl.bindTexture(device.gl.TEXTURE_2D, this.textureRes.texture), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_WRAP_S, this.wrapS), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_WRAP_T, this.wrapT)), device.gl.uniform1i(b, c)
  829.             };
  830.  
  831.             function Tw2TransformParameter(a) {
  832.                 typeof a != "undefined" ? this.name = a : this.name = "", this.scaling = vec3.create([1, 1, 1]), this.rotationCenter = vec3.create([0, 0, 0]), this.rotation = [0, 0, 0, 1], this.translation = vec3.create([0, 0, 0]), this.worldTransform = mat4.create(), mat4.identity(this.worldTransform)
  833.             }
  834.             Tw2TransformParameter.prototype.Apply = function (a, b) {
  835.                 if (b) {
  836.                     mat4.identity(this.worldTransform), mat4.scale(this.worldTransform, this.scaling);
  837.                     var c = mat4.create();
  838.                     mat4.identity(c), mat4.translate(c, this.rotationCenter);
  839.                     var d = mat4.create();
  840.                     mat4.identity(d), mat4.translate(d, [-this.rotationCenter[0], -this.rotationCenter[1], -this.rotationCenter[2]]);
  841.                     var e = mat4.create();
  842.                     e[0] = 1 - 2 * this.rotation[1] * this.rotation[1] - 2 * this.rotation[2] * this.rotation[2], e[4] = 2 * this.rotation[0] * this.rotation[1] - 2 * this.rotation[2] * this.rotation[3], e[8] = 2 * this.rotation[0] * this.rotation[2] + 2 * this.rotation[1] * this.rotation[3], e[1] = 2 * this.rotation[0] * this.rotation[1] + 2 * this.rotation[2] * this.rotation[3], e[5] = 1 - 2 * this.rotation[0] * this.rotation[0] - 2 * this.rotation[2] * this.rotation[2], e[9] = 2 * this.rotation[1] * this.rotation[2] - 2 * this.rotation[0] * this.rotation[3], e[2] = 2 * this.rotation[0] * this.rotation[2] - 2 * this.rotation[1] * this.rotation[3], e[6] = 2 * this.rotation[1] * this.rotation[2] + 2 * this.rotation[0] * this.rotation[3], e[10] = 1 - 2 * this.rotation[0] * this.rotation[0] - 2 * this.rotation[1] * this.rotation[1], e[15] = 1, mat4.multiply(this.worldTransform, d), mat4.multiply(this.worldTransform, e), mat4.multiply(this.worldTransform, c), mat4.translate(this.worldTransform, this.translation), device.gl.uniformMatrix4fv(b, !1, this.worldTransform)
  843.                 }
  844.             };
  845.  
  846.             function Tw2Device() {
  847.                 this.RM_ANY = -1, this.RM_OPAQUE = 0, this.RM_DECAL = 1, this.RM_TRANSPARENT = 2, this.RM_ADDITIVE = 3, this.RM_DEPTH = 4, this.RM_FULLSCREEN = 5, this.gl = null, this.debugMode = !1, this.mipLevelSkipCount = 0, this._scheduled = [], this._activeTextures = 0, this._quadBuffer = null, this._currentRenderMode = null, this._whiteTexture = null, this._whiteCube = null, this.world = mat4.create(), mat4.identity(this.world), this.worldInverse = mat4.create(), mat4.identity(this.worldInverse), this.view = mat4.create(), mat4.identity(this.view), this.projection = mat4.create(), mat4.identity(this.projection), this.eyePosition = vec3.create(), this.perObjectData = null, variableStore.RegisterVariable("u_World", this.world), variableStore.RegisterVariable("u_WorldInverse", this.worldInverse), variableStore.RegisterType("u_WorldInverseTranspose", Tw2MatrixParameter), variableStore.RegisterVariable("u_View", this.view), variableStore.RegisterType("u_ViewInverseTranspose", Tw2MatrixParameter), variableStore.RegisterVariable("u_Projection", this.projection), variableStore.RegisterType("u_ViewProjection", Tw2MatrixParameter), variableStore.RegisterType("u_ProjectionInverse", Tw2MatrixParameter), variableStore.RegisterType("u_ViewProjectionInverse", Tw2MatrixParameter), variableStore.RegisterType("u_EyePosition", Tw2Vector3Parameter), variableStore.RegisterType("u_Time", Tw2Vector4Parameter), this.startTime = new Date, this.CreateDevice = function (a) {
  848.                     this.gl = null;
  849.                     try {
  850.                         this.gl = a.getContext("webgl"), this.gl.viewportWidth = a.width, this.gl.viewportHeight = a.height
  851.                     } catch (b) {
  852.                         try {
  853.                             this.gl = a.getContext("experimental-webgl"), this.gl.viewportWidth = a.width, this.gl.viewportHeight = a.height
  854.                         } catch (b) {}
  855.                     }
  856.                     this.gl ? this.debugMode && (this.gl = WebGLDebugUtils.makeDebugContext(this.gl)) : log.LogErr("Could not initialise WebGL"), this._activeTextures = 0, this._quadBuffer = this.gl.createBuffer(), this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this._quadBuffer);
  857.                     var c = [1, 1, 0, -1, 1, 0, 1, -1, 0, -1, -1, 0];
  858.                     this.gl.bufferData(this.gl.ARRAY_BUFFER, new Float32Array(c), this.gl.STATIC_DRAW)
  859.                 }, this.Schedule = function (a) {
  860.                     this._scheduled[this._scheduled.length] = a
  861.                 }, this.Tick = function () {
  862.                     var a = new Date;
  863.                     a = a.getTime();
  864.                     var b = (a - this.startTime) * .001;
  865.                     variableStore._variables.u_Time.value = [b, 0, 0, 0];
  866.                     for (var c = 0; c < this._scheduled.length; ++c) this._scheduled[c]() || (this._scheduled.splice(c, 1), --c)
  867.                 }, this.ResetActiveTextures = function () {
  868.                     this._activeTextures = 0
  869.                 }, this.ActivateTexture = function () {
  870.                     this.gl.activeTexture(device.gl.TEXTURE0 + this._activeTextures);
  871.                     return this._activeTextures++
  872.                 }, this.SetWorld = function (a) {
  873.                     mat4.set(a, this.world);
  874.                     var b = mat4.create();
  875.                     mat4.inverse(this.world, this.worldInverse), variableStore._variables.u_WorldInverse.value.set(this.worldInverse), mat4.transpose(this.worldInverse, b), variableStore._variables.u_WorldInverseTranspose.value.set(b)
  876.                 }, this.SetView = function (a) {
  877.                     mat4.set(a, this.view);
  878.                     var b = mat4.create();
  879.                     mat4.inverse(this.view, b), mat4.transpose(b), variableStore._variables.u_ViewInverseTranspose.value.set(b);
  880.                     var c = mat4.create();
  881.                     mat4.multiply(this.projection, this.view, c), variableStore._variables.u_ViewProjection.value.set(c), mat4.inverse(c), variableStore._variables.u_ViewProjectionInverse.value.set(c);
  882.                     var d = mat4.create();
  883.                     mat4.inverse(this.view, d), this.eyePosition = vec3.create([0, 0, 0]), mat4.multiplyVec3(d, this.eyePosition), variableStore._variables.u_EyePosition.value.set(this.eyePosition)
  884.                 }, this.SetProjection = function (a) {
  885.                     mat4.set(a, this.projection);
  886.                     var b = mat4.create();
  887.                     mat4.multiply(this.projection, this.view, b), variableStore._variables.u_ViewProjection.value.set(b);
  888.                     var c = mat4.create();
  889.                     mat4.inverse(this.projection, c), variableStore._variables.u_ProjectionInverse.value.set(c)
  890.                 }, this.GetEyePosition = function () {
  891.                     return this.eyePosition
  892.                 }, this.RenderFullScreenQuad = function (a) {
  893.                     if ( !! a) {
  894.                         var b = a.GetEffectRes();
  895.                         if (!b.IsGood()) return;
  896.                         var c = a.GetActiveTechnique();
  897.                         for (var d = 0; d < a.GetPassCount(c); ++d) {
  898.                             a.ApplyPass(c, d);
  899.                             var e = a.GetPassInput(c, d);
  900.                             device.gl.enableVertexAttribArray(0), device.gl.bindBuffer(device.gl.ARRAY_BUFFER, this._quadBuffer), device.gl.vertexAttribPointer(0, 3, device.gl.FLOAT, !1, 0, 0), device.gl.drawArrays(device.gl.TRIANGLE_STRIP, 0, 4)
  901.                         }
  902.                     }
  903.                 }, this.SetStandardStates = function (a) {
  904.                     if (this._currentRenderMode != a) {
  905.                         this.gl.frontFace(this.gl.CCW);
  906.                         switch (a) {
  907.                         case this.RM_OPAQUE:
  908.                             this.gl.enable(this.gl.DEPTH_TEST), this.gl.enable(this.gl.CULL_FACE), this.gl.disable(this.gl.BLEND), this.gl.depthFunc(this.gl.LEQUAL), this.gl.blendEquationSeparate(this.gl.FUNC_ADD, this.gl.FUNC_ADD), this.gl.blendFuncSeparate(this.gl.ONE, this.gl.ZERO, this.gl.ONE, this.gl.ZERO), this.gl.disable(this.gl.POLYGON_OFFSET_FILL), this.gl.depthMask(!0);
  909.                             break;
  910.                         case this.RM_TRANSPARENT:
  911.                         case this.RM_DECAL:
  912.                             this.gl.enable(this.gl.DEPTH_TEST), this.gl.enable(this.gl.CULL_FACE), this.gl.enable(this.gl.BLEND), this.gl.depthMask(!1), this.gl.depthFunc(this.gl.LEQUAL), this.gl.enable(this.gl.POLYGON_OFFSET_FILL), this.gl.polygonOffset(-1, 0), this.gl.blendEquationSeparate(this.gl.FUNC_ADD, this.gl.FUNC_ADD), this.gl.blendFuncSeparate(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA, this.gl.ONE, this.gl.ONE);
  913.                             break;
  914.                         case this.RM_ADDITIVE:
  915.                             this.gl.enable(this.gl.DEPTH_TEST), this.gl.disable(this.gl.CULL_FACE), this.gl.enable(this.gl.BLEND), this.gl.depthFunc(this.gl.LEQUAL), this.gl.depthMask(!1), this.gl.blendEquation(this.gl.FUNC_ADD), this.gl.disable(this.gl.POLYGON_OFFSET_FILL), this.gl.blendFunc(this.gl.ONE, this.gl.ONE);
  916.                             break;
  917.                         case this.RM_FULLSCREEN:
  918.                             this.gl.disable(this.gl.DEPTH_TEST), this.gl.enable(this.gl.CULL_FACE), this.gl.disable(this.gl.BLEND), this.gl.depthFunc(this.gl.LEQUAL), this.gl.blendEquationSeparate(this.gl.FUNC_ADD, this.gl.FUNC_ADD), this.gl.blendFuncSeparate(this.gl.ONE, this.gl.ZERO, this.gl.ONE, this.gl.ZERO), this.gl.disable(this.gl.POLYGON_OFFSET_FILL), this.gl.depthMask(!0);
  919.                             break;
  920.                         default:
  921.                             return
  922.                         }
  923.                         this._currentRenderMode = a
  924.                     }
  925.                 }, this.GetFallbackTexture = function () {
  926.                     this._whiteTexture == null && (this._whiteTexture = device.gl.createTexture(), device.gl.bindTexture(device.gl.TEXTURE_2D, this._whiteTexture), device.gl.texImage2D(device.gl.TEXTURE_2D, 0, device.gl.RGBA, 1, 1, 0, device.gl.RGBA, device.gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 0, 0])), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MAG_FILTER, device.gl.LINEAR), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MIN_FILTER, device.gl.LINEAR_MIPMAP_LINEAR), device.gl.bindTexture(device.gl.TEXTURE_2D, null));
  927.                     return this._whiteTexture
  928.                 }, this.GetFallbackCubeMap = function () {
  929.                     if (this._whiteCube == null) {
  930.                         this._whiteCube = device.gl.createTexture(), device.gl.bindTexture(device.gl.TEXTURE_CUBE_MAP, this._whiteCube);
  931.                         for (var a = 0; a < 6; ++a) device.gl.texImage2D(device.gl.TEXTURE_CUBE_MAP_POSITIVE_X + a, 0, device.gl.RGBA, 1, 1, 0, device.gl.RGBA, device.gl.UNSIGNED_BYTE, new Uint8Array([0, 0, 0, 0]));
  932.                         device.gl.texParameteri(device.gl.TEXTURE_CUBE_MAP, device.gl.TEXTURE_MAG_FILTER, device.gl.LINEAR), device.gl.texParameteri(device.gl.TEXTURE_CUBE_MAP, device.gl.TEXTURE_MIN_FILTER, device.gl.LINEAR_MIPMAP_LINEAR), device.gl.generateMipmap(device.gl.TEXTURE_CUBE_MAP), device.gl.bindTexture(device.gl.TEXTURE_CUBE_MAP, null)
  933.                     }
  934.                     return this._whiteCube
  935.                 }
  936.             }
  937.             device = new Tw2Device, resMan.Start();
  938.  
  939.             function Tw2PerObjectData() {
  940.                 this._super.constructor.call(this)
  941.             }
  942.             Tw2PerObjectData.prototype.SetPerObjectData = function () {
  943.                 typeof this.world != "undefined" ? device.SetWorld(this.world) : device.SetWorld(mat4.identity(mat4.create()))
  944.             }, Tw2PerObjectData.prototype.ApplyShaderParameters = function (a) {
  945.                 for (var b in this._variables) this._variables[b].Apply(a, device.gl.getUniformLocation(a, b))
  946.             }, Inherit(Tw2PerObjectData, Tw2VariableStore);
  947.  
  948.             function Tw2SkinnedPerObjectData(a, b, c) {
  949.                 this._variables = new Object, this.perObjectData = typeof c == "undefined" ? null : c, this.worldArray = null, this.worldArray = a;
  950.                 return
  951.             }
  952.             Tw2SkinnedPerObjectData.prototype.SetPerObjectData = function () {
  953.                 this.perObjectData && this.perObjectData.SetPerObjectData(), typeof this.world != "undefined" ? device.SetWorld(this.world) : device.SetWorld(mat4.identity(mat4.create()))
  954.             }, Tw2SkinnedPerObjectData.prototype.ApplyShaderParameters = function (a) {
  955.                 this._super.ApplyShaderParameters.call(this, a), this.perObjectData && this.perObjectData.ApplyShaderParameters(a);
  956.                 if (this.worldArray != null) {
  957.                     var b = device.gl.getUniformLocation(a, "u_BoneMatrixes");
  958.                     device.gl.uniformMatrix4fv(b, !1, this.worldArray)
  959.                 }
  960.             }, Inherit(Tw2SkinnedPerObjectData, Tw2PerObjectData);
  961.  
  962.             function Tw2RenderTarget() {
  963.                 this.texture = null, this._frameBuffer = null, this.width = null, this.height = null, this.hasDepth = null
  964.             }
  965.             Tw2RenderTarget.prototype.Destroy = function () {
  966.                 this.texture && (device.gl.deleteTexture(this.texture.texture), this.texture = null), this._renderBuffer && (device.gl.deleteRenderbuffer(this._renderBuffer), this._renderBuffer = null), this._frameBuffer && (device.gl.deleteFramebuffer(this._frameBuffer), this._frameBuffer = null)
  967.             }, Tw2RenderTarget.prototype.Create = function (a, b, c) {
  968.                 this.Destroy(), this.texture = new Tw2TextureRes, this.texture.Attach(device.gl.createTexture()), this._frameBuffer = device.gl.createFramebuffer(), device.gl.bindFramebuffer(device.gl.FRAMEBUFFER, this._frameBuffer), device.gl.bindTexture(device.gl.TEXTURE_2D, this.texture.texture), device.gl.texImage2D(device.gl.TEXTURE_2D, 0, device.gl.RGBA, a, b, 0, device.gl.RGBA, device.gl.UNSIGNED_BYTE, null), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MAG_FILTER, device.gl.LINEAR), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MIN_FILTER, device.gl.LINEAR), device.gl.bindTexture(device.gl.TEXTURE_2D, null), this._renderBuffer = null, c && (this._renderBuffer = device.gl.createRenderbuffer(), device.gl.bindRenderbuffer(device.gl.RENDERBUFFER, this._renderBuffer), device.gl.renderbufferStorage(device.gl.RENDERBUFFER, device.gl.DEPTH_COMPONENT16, a, b)), device.gl.framebufferTexture2D(device.gl.FRAMEBUFFER, device.gl.COLOR_ATTACHMENT0, device.gl.TEXTURE_2D, this.texture.texture, 0), c && device.gl.framebufferRenderbuffer(device.gl.FRAMEBUFFER, device.gl.DEPTH_ATTACHMENT, device.gl.RENDERBUFFER, this._renderBuffer), device.gl.bindRenderbuffer(device.gl.RENDERBUFFER, null), device.gl.bindFramebuffer(device.gl.FRAMEBUFFER, null), this.width = a, this.height = b, this.hasDepth = c
  969.             }, Tw2RenderTarget.prototype.Set = function () {
  970.                 this._oldViewport = device.gl.getParameter(device.gl.VIEWPORT), device.gl.bindFramebuffer(device.gl.FRAMEBUFFER, this._frameBuffer), device.gl.viewport(0, 0, this.width, this.height)
  971.             }, Tw2RenderTarget.prototype.Unset = function () {
  972.                 device.gl.bindFramebuffer(device.gl.FRAMEBUFFER, null), device.gl.viewport(this._oldViewport[0], this._oldViewport[1], this._oldViewport[2], this._oldViewport[3])
  973.             };
  974.  
  975.             function Tw2PostProcess() {
  976.                 this.width = 0, this.height = 0, this.texture = null, this.halfRT = new Tw2RenderTarget, this.quadRT0 = new Tw2RenderTarget, this.quadRT1 = new Tw2RenderTarget, this.luminance = new Tw2FloatParameter("Luminance", .06), this.middleGray = new Tw2FloatParameter("MiddleGray", .28), this.whiteCutoff = new Tw2FloatParameter("WhiteCutoff", .8), this.bloomStrength = new Tw2FloatParameter("Strength", 1), this.highpass = new Tw2Effect, this.highpass.effectFilePath = "res:/Graphics/Effect/managed/postprocess/highpass.fx", this.highpass.Initialize(), this.highpass.parameters.texture = new Tw2TextureParameter("texture"), this.highpass.parameters.texture.wrapS = device.gl.CLAMP_TO_EDGE, this.highpass.parameters.texture.wrapT = device.gl.CLAMP_TO_EDGE, this.highpass.parameters.Luminance = this.luminance, this.highpass.parameters.MiddleGray = this.middleGray, this.highpass.parameters.WhiteCutoff = this.whiteCutoff, this.copy = new Tw2Effect, this.copy.effectFilePath = "res:/Graphics/Effect/managed/postprocess/copy.fx", this.copy.Initialize(), this.copy.parameters.texture = new Tw2TextureParameter("texture"), this.copy.parameters.texture.wrapS = device.gl.CLAMP_TO_EDGE, this.copy.parameters.texture.wrapT = device.gl.CLAMP_TO_EDGE, this.copy.parameters.Strength = new Tw2FloatParameter("Strength", 1), this.combine = new Tw2Effect, this.combine.effectFilePath = "res:/Graphics/Effect/managed/postprocess/copy.fx", this.combine.Initialize(), this.combine.parameters.texture = new Tw2TextureParameter("texture"), this.combine.parameters.texture.wrapS = device.gl.CLAMP_TO_EDGE, this.combine.parameters.texture.wrapT = device.gl.CLAMP_TO_EDGE, this.combine.parameters.Strength = this.bloomStrength, this.blur = new Tw2Effect, this.blur.effectFilePath = "res:/Graphics/Effect/managed/postprocess/blur.fx", this.blur.Initialize(), this.blur.parameters.texture = new Tw2TextureParameter("texture"), this.blur.parameters.texture.wrapS = device.gl.CLAMP_TO_EDGE, this.blur.parameters.texture.wrapT = device.gl.CLAMP_TO_EDGE, this.blur.parameters.direction = new Tw2Vector2Parameter("direction")
  977.             }
  978.             Tw2PostProcess.prototype.Render = function () {
  979.                 var a = device.gl.viewportWidth,
  980.                     b = device.gl.viewportHeight;
  981.                 if (!(a <= 0 || b <= 0)) {
  982.                     this.texture == null && (this.texture = new Tw2TextureRes, this.texture.Attach(device.gl.createTexture()));
  983.                     if (a != this.width || b != this.height) device.gl.bindTexture(device.gl.TEXTURE_2D, this.texture.texture), device.gl.texImage2D(device.gl.TEXTURE_2D, 0, device.gl.RGBA, a, b, 0, device.gl.RGBA, device.gl.UNSIGNED_BYTE, null), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_WRAP_S, device.gl.CLAMP_TO_EDGE), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_WRAP_T, device.gl.CLAMP_TO_EDGE), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MAG_FILTER, device.gl.LINEAR), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MIN_FILTER, device.gl.LINEAR), device.gl.bindTexture(device.gl.TEXTURE_2D, null), this.halfRT.Create(a / 2, b / 2, !1), this.quadRT0.Create(a / 4, b / 4, !1), this.quadRT1.Create(a / 4, b / 4, !1), this.width = a, this.height = b;
  984.                     device.gl.bindTexture(device.gl.TEXTURE_2D, this.texture.texture), device.gl.copyTexImage2D(device.gl.TEXTURE_2D, 0, device.gl.RGBA, 0, 0, a, b, 0), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_WRAP_S, device.gl.CLAMP_TO_EDGE), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_WRAP_T, device.gl.CLAMP_TO_EDGE), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MAG_FILTER, device.gl.LINEAR), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MIN_FILTER, device.gl.LINEAR), device.gl.bindTexture(device.gl.TEXTURE_2D, null), device.SetStandardStates(device.RM_OPAQUE), this.halfRT.Set(), this.highpass.parameters.texture.textureRes = this.texture, device.RenderFullScreenQuad(this.highpass), this.quadRT0.Set(), this.copy.parameters.texture.textureRes = this.halfRT.texture, device.RenderFullScreenQuad(this.copy), this.quadRT1.Set(), this.blur.parameters.texture.textureRes = this.quadRT0.texture, this.blur.parameters.direction.value = [0, 4 / b], device.RenderFullScreenQuad(this.blur), this.quadRT0.Set(), this.blur.parameters.texture.textureRes = this.quadRT1.texture, this.blur.parameters.direction.value = [4 / a, 0], device.RenderFullScreenQuad(this.blur), this.halfRT.Unset(), device.SetStandardStates(device.RM_ADDITIVE), this.combine.parameters.texture.textureRes = this.quadRT0.texture, device.RenderFullScreenQuad(this.combine)
  985.                 }
  986.             };
  987.  
  988.             function Tw2BatchAccumulator(a) {
  989.                 this.batches = [], this.count = 0, this._sortMethod = a
  990.             }
  991.             Tw2BatchAccumulator.prototype.Commit = function (a) {
  992.                 this.batches[this.count++] = a
  993.             }, Tw2BatchAccumulator.prototype.Clear = function () {
  994.                 this.count = 0
  995.             }, Tw2BatchAccumulator.prototype.Render = function (a) {
  996.                 typeof this._sortMethod != "undefined" && this.batches.sort(this._sortMethod);
  997.                 for (var b = 0; b < this.count; ++b) this.batches[b].renderMode != device.RM_ANY && device.SetStandardStates(this.batches[b].renderMode), device.perObjectData = null, this.batches[b].perObjectData && (this.batches[b].perObjectData.SetPerObjectData(), device.perObjectData = this.batches[b].perObjectData), this.batches[b].Commit(a), device.perObjectData = null
  998.             };
  999.  
  1000.             function Tw2RenderBatch() {
  1001.                 this.renderMode = device.RM_ANY, this.perObjectData = null
  1002.             }
  1003.  
  1004.             function Tw2ForwardingRenderBatch() {
  1005.                 this.geometryProvider = null
  1006.             }
  1007.             Tw2ForwardingRenderBatch.prototype.Commit = function (a) {
  1008.                 this.geometryProvider && this.geometryProvider.Render(this, a)
  1009.             }, Inherit(Tw2ForwardingRenderBatch, Tw2RenderBatch);
  1010.  
  1011.             function Tw2BinaryReader(a) {
  1012.                 this.data = a, this.cursor = 0
  1013.             }
  1014.             Tw2BinaryReader.prototype.ReadUInt8 = function () {
  1015.                 return this.data[this.cursor++]
  1016.             }, Tw2BinaryReader.prototype.ReadInt8 = function () {
  1017.                 var a = this.data[this.cursor++];
  1018.                 a > 127 && (a = a - 255 - 1);
  1019.                 return a
  1020.             }, Tw2BinaryReader.prototype.ReadUInt16 = function () {
  1021.                 return this.data[this.cursor++] + (this.data[this.cursor++] << 8)
  1022.             }, Tw2BinaryReader.prototype.ReadInt16 = function () {
  1023.                 var a = this.data[this.cursor++] + (this.data[this.cursor++] << 8);
  1024.                 a > 32767 && (a = a - 65535 - 1);
  1025.                 return a
  1026.             }, Tw2BinaryReader.prototype.ReadUInt32 = function () {
  1027.                 return this.data[this.cursor++] + (this.data[this.cursor++] << 8) + (this.data[this.cursor++] << 16) + (this.data[this.cursor++] << 24)
  1028.             }, Tw2BinaryReader.prototype.ReadInt32 = function () {
  1029.                 var a = this.data[this.cursor++] + (this.data[this.cursor++] << 8) + (this.data[this.cursor++] << 16) + (this.data[this.cursor++] << 24);
  1030.                 a > 2147483647 && (a = a - 4294967295 - 1);
  1031.                 return a
  1032.             }, Tw2BinaryReader.prototype.ReadFloat16 = function () {
  1033.                 var a = this.data[this.cursor++],
  1034.                     b = this.data[this.cursor++],
  1035.                     c = 1 - 2 * (b >> 7),
  1036.                     d = (b >> 2 & 31) - 15,
  1037.                     e = (b & 3) << 8 | a;
  1038.                 return e == 0 && d == -15 ? 0 : c * (1 + e * Math.pow(2, -10)) * Math.pow(2, d)
  1039.             }, Tw2BinaryReader.prototype.ReadFloat32 = function () {
  1040.                 var a = this.data[this.cursor++],
  1041.                     b = this.data[this.cursor++],
  1042.                     c = this.data[this.cursor++],
  1043.                     d = this.data[this.cursor++],
  1044.                     e = 1 - 2 * (d >> 7),
  1045.                     f = (d << 1 & 255 | c >> 7) - 127,
  1046.                     g = (c & 127) << 16 | b << 8 | a;
  1047.                 return g == 0 && f == -127 ? 0 : e * (1 + g * Math.pow(2, -23)) * Math.pow(2, f)
  1048.             }, Tw2BinaryReader.prototype.ReadString = function () {
  1049.                 var a = this.data[this.cursor++],
  1050.                     b = "";
  1051.                 for (var c = 0; c < a; ++c) b += String.fromCharCode(this.data[this.cursor++]);
  1052.                 return b
  1053.             };
  1054.  
  1055.             function Tw2GeometryBatch() {
  1056.                 this._super.constructor.call(this), this.geometryRes = null, this.meshIx = 0, this.start = 0, this.count = 1, this.effect = null, this.batchDepth = 0
  1057.             }
  1058.             Tw2GeometryBatch.prototype.Commit = function (a) {
  1059.                 var b = typeof a == "undefined" ? this.effect : a;
  1060.                 this.geometryRes && b && this.geometryRes.RenderAreas(this.meshIx, this.start, this.count, b)
  1061.             }, Inherit(Tw2GeometryBatch, Tw2RenderBatch);
  1062.  
  1063.             function Tw2GeometryMeshArea() {
  1064.                 this.name = "", this.start = 0, this.count = 0, this.minBounds = vec3.create(), this.maxBounds = vec3.create(), this.boundsSpherePosition = vec3.create(), this.boundsSphereRadius = 0
  1065.             }
  1066.  
  1067.             function Tw2GeometryMeshBinding() {
  1068.                 this.mesh = null, this.bones = []
  1069.             }
  1070.  
  1071.             function Tw2GeometryModel() {
  1072.                 this.name = "", this.meshBindings = [], this.skeleton = null
  1073.             }
  1074.             Tw2GeometryModel.prototype.FindBoneByName = function (a) {
  1075.                 if (this.skeleton == null) return null;
  1076.                 for (var b = 0; b < this.skeleton.bones.length; ++b)
  1077.                     if (this.skeleton.bones[b].name == a) return this.skeleton.bones[b];
  1078.                 return null
  1079.             };
  1080.  
  1081.             function Tw2GeometrySkeleton() {
  1082.                 this.bones = []
  1083.             }
  1084.  
  1085.             function Tw2GeometryBone() {
  1086.                 this.name = "", this.parentIndex = -1, this.position = vec3.create(), this.orientation = quat4.create(), this.scaleShear = mat3.create(), this.localTransform = mat4.create(), this.worldTransform = mat4.create(), this.worldTransformInv = mat4.create()
  1087.             }
  1088.             Tw2GeometryBone.prototype.UpdateTransform = function () {
  1089.                 mat3.toMat4(this.scaleShear, this.localTransform), mat4.multiply(this.localTransform, mat4.transpose(quat4.toMat4(quat4.normalize(this.orientation)))), this.localTransform[12] = this.position[0], this.localTransform[13] = this.position[1], this.localTransform[14] = this.position[2];
  1090.                 return this.localTransform
  1091.             };
  1092.  
  1093.             function Tw2GeometryAnimation() {
  1094.                 this.name = "", this.duration = 0, this.trackGroups = []
  1095.             }
  1096.  
  1097.             function Tw2GeometryTrackGroup() {
  1098.                 this.name = "", this.model = null, this.transformTracks = []
  1099.             }
  1100.  
  1101.             function Tw2GeometryTransformTrack() {
  1102.                 this.name = "", this.position = null, this.orientation = null, this.scaleShear = null
  1103.             }
  1104.  
  1105.             function Tw2GeometryCurve() {
  1106.                 this.dimension = 0, this.degree = 0, this.knots = null, this.controls = null
  1107.             }
  1108.  
  1109.             function Tw2BlendShapeData() {
  1110.                 this.name = "", this.declaration = new Tw2VertexDeclaration, this.buffers = [], this.indexes = null, this.weightProxy = null
  1111.             }
  1112.  
  1113.             function Tw2GeometryMesh() {
  1114.                 this.name = "", this.declaration = new Tw2VertexDeclaration, this.buffers = [], this.bufferData = [], this.areas = [], this.indexes = null, this.minBounds = vec3.create(), this.maxBounds = vec3.create(), this.boundsSpherePosition = vec3.create(), this.boundsSphereRadius = 0, this.bones = []
  1115.             }
  1116.             Tw2GeometryMesh.prototype.CreateBuffer = function (a, b) {
  1117.                 var c = this.buffers.length;
  1118.                 this.buffers[c] = device.gl.createBuffer(), this.bufferData[c] = new Float32Array(b), device.gl.bindBuffer(device.gl.ARRAY_BUFFER, this.buffers[c]), device.gl.bufferData(device.gl.ARRAY_BUFFER, this.bufferData[c], device.gl.STATIC_DRAW), this.buffers[c].itemSize = a.type + 1, this.buffers[c].numItems = b.length / (a.type + 1)
  1119.             };
  1120.  
  1121.             function Tw2GeometryRes() {
  1122.                 this._super.constructor.call(this), this.meshes = [], this.minBounds = vec3.create(), this.maxBounds = vec3.create(), this.boundsSpherePosition = vec3.create(), this.boundsSphereRadius = 0, this.models = [], this.animations = []
  1123.             }
  1124.  
  1125.             function boundsIncludePoint(a, b, c) {
  1126.                 a[0] > c[0] && (a[0] = c[0]), a[1] > c[1] && (a[1] = c[1]), a[2] > c[2] && (a[2] = c[2]), b[0] < c[0] && (b[0] = c[0]), b[1] < c[1] && (b[1] = c[1]), b[2] < c[2] && (b[2] = c[2])
  1127.             }
  1128.             Tw2GeometryRes.prototype.Prepare = function (data) {
  1129.                 try {
  1130.                     data = eval("([" + data + "])")
  1131.                 } catch (e) {
  1132.                     log.LogErr("Error loading gr2 data " + this.path), this.PrepareFinished(!1);
  1133.                     return
  1134.                 }
  1135.                 for (var meshIx = 0; meshIx < data[0].length; ++meshIx) {
  1136.                     var mesh = new Tw2GeometryMesh;
  1137.                     mesh.name = data[0][meshIx][0];
  1138.                     for (var declIx = 0; declIx < data[0][meshIx][1].length; ++declIx) {
  1139.                         var element = new Tw2VertexElement(data[0][meshIx][1][declIx][0], data[0][meshIx][1][declIx][1], data[0][meshIx][1][declIx][2]);
  1140.                         mesh.declaration.elements[mesh.declaration.elements.length] = element
  1141.                     }
  1142.                     for (var i = 0; i < data[0][meshIx][1].length; ++i) mesh.CreateBuffer(mesh.declaration.elements[i], data[0][meshIx][2][i]);
  1143.                     mesh.indexes = device.gl.createBuffer(), device.gl.bindBuffer(device.gl.ELEMENT_ARRAY_BUFFER, mesh.indexes), device.gl.bufferData(device.gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(data[0][meshIx][3]), device.gl.STATIC_DRAW);
  1144.                     if (data[0][meshIx].length > 6) {
  1145.                         var annotations = data[0][meshIx][6];
  1146.                         mesh.blendShapes = [];
  1147.                         for (var i = 0; i < annotations.length; ++i) {
  1148.                             mesh.blendShapes[i] = new Tw2BlendShapeData, mesh.blendShapes[i].name = annotations[i][0];
  1149.                             if (annotations[i].length > 1) {
  1150.                                 for (var declIx = 0; declIx < annotations[i][1].length; ++declIx) {
  1151.                                     var element = new Tw2VertexElement(annotations[i][1][declIx][0], annotations[i][1][declIx][1], annotations[i][1][declIx][2]);
  1152.                                     mesh.blendShapes[i].declaration.elements[declIx] = element, mesh.blendShapes[i].buffers[declIx] = new Float32Array(annotations[i][2][declIx])
  1153.                                 }
  1154.                                 mesh.blendShapes[i].indexes = new Uint16Array(annotations[i][3])
  1155.                             }
  1156.                         }
  1157.                     }
  1158.                     var positions = mesh.declaration.Find(new Tw2VertexElement(0, 0, 0)),
  1159.                         positionStride = 3;
  1160.                     positions != -1 && mesh.declaration.elements[positions].type >= 2 ? (positionStride = mesh.declaration.elements[positions].type + 1, positions = data[0][meshIx][2][positions]) : positions = null, mesh.areas = [];
  1161.                     for (var i = 0; i < data[0][meshIx][4].length; ++i) mesh.areas[i] = new Tw2GeometryMeshArea, mesh.areas[i].name = data[0][meshIx][4][i][0], mesh.areas[i].start = data[0][meshIx][4][i][1], mesh.areas[i].count = data[0][meshIx][4][i][2], mesh.areas[i].minBounds = vec3.create([data[0][meshIx][4][i][3], data[0][meshIx][4][i][4], data[0][meshIx][4][i][5]]), mesh.areas[i].maxBounds = vec3.create([data[0][meshIx][4][i][6], data[0][meshIx][4][i][7], data[0][meshIx][4][i][8]]), mesh.areas[i].boundsSpherePosition = vec3.create([data[0][meshIx][4][i][9], data[0][meshIx][4][i][10], data[0][meshIx][4][i][11]]), mesh.areas[i].boundsSphereRadius = data[0][meshIx][4][i][12];
  1162.                     if (mesh.areas.length) {
  1163.                         vec3.set(mesh.areas[0].minBounds, mesh.minBounds), vec3.set(mesh.areas[0].maxBounds, mesh.maxBounds);
  1164.                         for (var i = 1; i < mesh.areas.length; ++i) boundsIncludePoint(mesh.minBounds, mesh.maxBounds, mesh.areas[i].minBounds), boundsIncludePoint(mesh.minBounds, mesh.maxBounds, mesh.areas[i].maxBounds);
  1165.                         vec3.add(mesh.maxBounds, mesh.minBounds, mesh.boundsSpherePosition), mesh.boundsSpherePosition[0] *= .5, mesh.boundsSpherePosition[1] *= .5, mesh.boundsSpherePosition[2] *= .5;
  1166.                         var size = vec3.create();
  1167.                         vec3.subtract(mesh.maxBounds, mesh.minBounds, size), mesh.boundsSphereRadius = vec3.length(size)
  1168.                     }
  1169.                     this.meshes[this.meshes.length] = mesh
  1170.                 }
  1171.                 if (this.meshes.length) {
  1172.                     vec3.set(this.meshes[0].minBounds, this.minBounds), vec3.set(this.meshes[0].maxBounds, this.maxBounds);
  1173.                     for (var i = 1; i < this.meshes.length; ++i) boundsIncludePoint(this.minBounds, this.maxBounds, this.meshes[i].minBounds), boundsIncludePoint(this.minBounds, this.maxBounds, this.meshes[i].maxBounds);
  1174.                     vec3.add(this.maxBounds, this.minBounds, this.boundsSpherePosition), this.boundsSpherePosition[0] *= .5, this.boundsSpherePosition[1] *= .5, this.boundsSpherePosition[2] *= .5;
  1175.                     var size = vec3.create();
  1176.                     vec3.subtract(this.maxBounds, this.minBounds, size), this.boundsSphereRadius = vec3.length(size)
  1177.                 }
  1178.                 if (data.length > 1)
  1179.                     for (var i = 0; i < data[1].length; ++i) {
  1180.                         var model = new Tw2GeometryModel;
  1181.                         model.name = data[1][i][0], model.skeleton = new Tw2GeometrySkeleton;
  1182.                         for (var j = 0; j < data[1][i][1].length; ++j) {
  1183.                             var bone = new Tw2GeometryBone,
  1184.                                 boneData = data[1][i][1][j];
  1185.                             bone.name = boneData[0], bone.parentIndex = boneData[1], vec3.set([boneData[2], boneData[3], boneData[4]], bone.position), boneData.length == 9 || boneData.length == 18 ? quat4.set([boneData[5], boneData[6], boneData[7], boneData[8]], bone.orientation) : quat4.set([0, 0, 0, 1], bone.orientation), boneData.length == 14 ? mat3.set(boneData.slice(5), bone.scaleShear) : boneData.length == 18 ? mat3.set(boneData.slice(9), bone.scaleShear) : mat3.identity(bone.scaleShear), model.skeleton.bones[model.skeleton.bones.length] = bone
  1186.                         }
  1187.                         for (var j = 0; j < model.skeleton.bones.length; ++j) model.skeleton.bones[j].UpdateTransform(), model.skeleton.bones[j].parentIndex != -1 ? mat4.multiply(model.skeleton.bones[model.skeleton.bones[j].parentIndex].worldTransform, model.skeleton.bones[j].localTransform, model.skeleton.bones[j].worldTransform) : mat4.set(model.skeleton.bones[j].localTransform, model.skeleton.bones[j].worldTransform), mat4.inverse(model.skeleton.bones[j].worldTransform, model.skeleton.bones[j].worldTransformInv);
  1188.                         if (data[1][i].length > 2)
  1189.                             for (var j = 0; j < data[1][i][2].length; ++j) {
  1190.                                 var meshIx = data[1][i][2][j],
  1191.                                     binding = new Tw2GeometryMeshBinding;
  1192.                                 binding.mesh = this.meshes[meshIx];
  1193.                                 if (data[0][meshIx].length > 5)
  1194.                                     for (var b = 0; b < data[0][meshIx][5].length; ++b) {
  1195.                                         var name = data[0][meshIx][5][b],
  1196.                                             bone = model.FindBoneByName(name);
  1197.                                         bone == null ? log.LogErr("Tw2GeometryRes: mesh '" + this.meshes[meshIx].name + "' in file '" + this.path + "' has invalid bone name '" + name + "' for model '" + model.name + "'") : binding.bones[binding.bones.length] = bone
  1198.                                     }
  1199.                                 model.meshBindings[model.meshBindings.length] = binding
  1200.                             }
  1201.                         this.models[this.models.length] = model
  1202.                     }
  1203.                 if (data.length > 2)
  1204.                     for (var i = 0; i < data[2].length; ++i) {
  1205.                         var animation = new Tw2GeometryAnimation;
  1206.                         animation.name = data[2][i][0], animation.duration = data[2][i][1];
  1207.                         for (var j = 0; j < data[2][i][2].length; ++j) {
  1208.                             var group = new Tw2GeometryTrackGroup;
  1209.                             group.name = data[2][i][2][j][0];
  1210.                             for (var m = 0; m < this.models.length; ++m)
  1211.                                 if (this.models[m].name == name) {
  1212.                                     group.model = this.models[m];
  1213.                                     break
  1214.                                 }
  1215.                             for (var k = 0; k < data[2][i][2][j][1].length; ++k) {
  1216.                                 var track = new Tw2GeometryTransformTrack;
  1217.                                 track.name = data[2][i][2][j][1][k][0];
  1218.  
  1219.                                 function ReadCurve(a) {
  1220.                                     if (a == null) return null;
  1221.                                     var b = new Tw2GeometryCurve;
  1222.                                     b.dimension = a[0], b.degree = a[1], b.knots = a[2], b.controls = a[3];
  1223.                                     return b
  1224.                                 }
  1225.                                 track.orientation = ReadCurve(data[2][i][2][j][1][k][1]), track.position = ReadCurve(data[2][i][2][j][1][k][2]), track.scaleShear = ReadCurve(data[2][i][2][j][1][k][3]);
  1226.                                 if (track.orientation) {
  1227.                                     var lastX = 0,
  1228.                                         lastY = 0,
  1229.                                         lastZ = 0,
  1230.                                         lastW = 0;
  1231.                                     for (var n = 0; n < track.orientation.controls.length; n += 4) {
  1232.                                         var x = track.orientation.controls[n],
  1233.                                             y = track.orientation.controls[n + 1],
  1234.                                             z = track.orientation.controls[n + 2],
  1235.                                             w = track.orientation.controls[n + 3];
  1236.                                         lastX * x + lastY * y + lastZ * z + lastW * w < 0 && (track.orientation.controls[n] = -x, track.orientation.controls[n + 1] = -y, track.orientation.controls[n + 2] = -z, track.orientation.controls[n + 3] = -w), lastX = x, lastY = y, lastZ = z, lastW = w
  1237.                                     }
  1238.                                 }
  1239.                                 group.transformTracks[group.transformTracks.length] = track
  1240.                             }
  1241.                             animation.trackGroups[animation.trackGroups.length] = group
  1242.                         }
  1243.                         this.animations[this.animations.length] = animation
  1244.                     }
  1245.                 this.PrepareFinished(!0)
  1246.             }, Tw2GeometryRes.prototype.RenderAreas = function (a, b, c, d, e) {
  1247.                 if (!this.IsGood()) return !1;
  1248.                 var f = d.GetEffectRes();
  1249.                 if (!f.IsGood()) return !1;
  1250.                 if (a >= this.meshes.length) return !1;
  1251.                 var g = d.GetActiveTechnique(),
  1252.                     h = this.meshes[a];
  1253.                 for (var i = 0; i < d.GetPassCount(g); ++i) {
  1254.                     d.ApplyPass(g, i);
  1255.                     var j = d.GetPassInput(g, i);
  1256.                     for (var k = 0; k < j.elements.length; ++k) {
  1257.                         var l = h.declaration.Find(j.elements[k]);
  1258.                         if (l == -1) {
  1259.                             log.LogErr("Error binding vertex buffer to effect attribute for usage " + j.elements[k].usage + " and index " + j.elements[k].usageIndex);
  1260.                             return !1
  1261.                         }
  1262.                         device.gl.enableVertexAttribArray(j.elements[k].attribute), device.gl.bindBuffer(device.gl.ARRAY_BUFFER, h.buffers[l]), device.gl.vertexAttribPointer(j.elements[k].attribute, h.declaration.elements[l].type + 1, device.gl.FLOAT, !1, 0, 0)
  1263.                     }
  1264.                     device.gl.bindBuffer(device.gl.ELEMENT_ARRAY_BUFFER, h.indexes);
  1265.                     if (typeof e != "undefined") {
  1266.                         var m = [];
  1267.                         for (var k = 0; k < c; ++k) k + b < h.areas.length && m.push([device.gl.TRIANGLES, h.areas[k + b].count * 3, device.gl.UNSIGNED_SHORT, h.areas[k + b].start * 2]);
  1268.                         e(i, m)
  1269.                     } else
  1270.                         for (var k = 0; k < c; ++k) k + b < h.areas.length && device.gl.drawElements(device.gl.TRIANGLES, h.areas[k + b].count * 3, device.gl.UNSIGNED_SHORT, h.areas[k + b].start * 2)
  1271.                 }
  1272.                 return !0
  1273.             }, Tw2GeometryRes.prototype.RenderDebugInfo = function (a) {
  1274.                 if (!this.IsGood()) return !1;
  1275.                 for (var b = 0; b < this.models.length; ++b)
  1276.                     if (this.models[b].skeleton)
  1277.                         for (var c = 0; c < this.models[b].skeleton.bones.length; ++c) {
  1278.                             var d = this.models[b].skeleton.bones[c];
  1279.                             if (d.parentIndex >= 0) {
  1280.                                 var e = this.models[b].skeleton.bones[d.parentIndex];
  1281.                                 a.AddLine([d.worldTransform[12], d.worldTransform[13], d.worldTransform[14]], [e.worldTransform[12], e.worldTransform[13], e.worldTransform[14]], [0, .7, 0, 1], [0, .7, 0, 1])
  1282.                             }
  1283.                         }
  1284.             }, Inherit(Tw2GeometryRes, Tw2Resource), resMan.RegisterExtension("gr2", Tw2GeometryRes);
  1285.  
  1286.             function Tw2GeometryBatch() {
  1287.                 this._super.constructor.call(this), this.geometryRes = null, this.meshIx = 0, this.start = 0, this.count = 1, this.effect = null, this.batchDepth = 0
  1288.             }
  1289.             Tw2GeometryBatch.prototype.Commit = function (a) {
  1290.                 var b = typeof a == "undefined" ? this.effect : a;
  1291.                 this.geometryRes && b && this.geometryRes.RenderAreas(this.meshIx, this.start, this.count, b)
  1292.             }, Inherit(Tw2GeometryBatch, Tw2RenderBatch);
  1293.  
  1294.             function Tw2GeometryMeshArea() {
  1295.                 this.name = "", this.start = 0, this.count = 0, this.minBounds = vec3.create(), this.maxBounds = vec3.create(), this.boundsSpherePosition = vec3.create(), this.boundsSphereRadius = 0
  1296.             }
  1297.  
  1298.             function Tw2GeometryMeshBinding() {
  1299.                 this.mesh = null, this.bones = []
  1300.             }
  1301.  
  1302.             function Tw2GeometryModel() {
  1303.                 this.name = "", this.meshBindings = [], this.skeleton = null
  1304.             }
  1305.             Tw2GeometryModel.prototype.FindBoneByName = function (a) {
  1306.                 if (this.skeleton == null) return null;
  1307.                 for (var b = 0; b < this.skeleton.bones.length; ++b)
  1308.                     if (this.skeleton.bones[b].name == a) return this.skeleton.bones[b];
  1309.                 return null
  1310.             };
  1311.  
  1312.             function Tw2GeometrySkeleton() {
  1313.                 this.bones = []
  1314.             }
  1315.  
  1316.             function Tw2GeometryBone() {
  1317.                 this.name = "", this.parentIndex = -1, this.position = vec3.create(), this.orientation = quat4.create(), this.scaleShear = mat3.create(), this.localTransform = mat4.create(), this.worldTransform = mat4.create(), this.worldTransformInv = mat4.create()
  1318.             }
  1319.             Tw2GeometryBone.prototype.UpdateTransform = function () {
  1320.                 mat3.toMat4(this.scaleShear, this.localTransform), mat4.multiply(this.localTransform, mat4.transpose(quat4.toMat4(quat4.normalize(this.orientation)))), this.localTransform[12] = this.position[0], this.localTransform[13] = this.position[1], this.localTransform[14] = this.position[2];
  1321.                 return this.localTransform
  1322.             };
  1323.  
  1324.             function Tw2GeometryAnimation() {
  1325.                 this.name = "", this.duration = 0, this.trackGroups = []
  1326.             }
  1327.  
  1328.             function Tw2GeometryTrackGroup() {
  1329.                 this.name = "", this.model = null, this.transformTracks = []
  1330.             }
  1331.  
  1332.             function Tw2GeometryTransformTrack() {
  1333.                 this.name = "", this.position = null, this.orientation = null, this.scaleShear = null
  1334.             }
  1335.  
  1336.             function Tw2GeometryCurve() {
  1337.                 this.dimension = 0, this.degree = 0, this.knots = null, this.controls = null
  1338.             }
  1339.  
  1340.             function Tw2BlendShapeData() {
  1341.                 this.name = "", this.declaration = new Tw2VertexDeclaration, this.buffers = [], this.indexes = null, this.weightProxy = null
  1342.             }
  1343.             var tw2TextureResPremultipliedAlphaWorkaround = !1,
  1344.                 ffVersion = /Firefox\/(\d+)/.exec(navigator.userAgent);
  1345.             ffVersion && parseInt(ffVersion[1]) >= 8 && (tw2TextureResPremultipliedAlphaWorkaround = !0);
  1346.  
  1347.             function Tw2TextureRes() {
  1348.                 this._super.constructor.call(this), this.texture = null, this.isCube = !1, this.images = [], this.minFilter = 9987, this.magFilter = 9729, this._facesLoaded = 0
  1349.             }
  1350.             Tw2TextureRes.prototype.SetFiltering = function (a, b) {
  1351.                 this.minFilter = a, this.magFilter = b, this.IsGood() && (this.isCube ? (device.gl.bindTexture(device.gl.TEXTURE_CUBE_MAP, this.texture), device.gl.texParameteri(device.gl.TEXTURE_CUBE_MAP, device.gl.TEXTURE_MAG_FILTER, this.magFilter), device.gl.texParameteri(device.gl.TEXTURE_CUBE_MAP, device.gl.TEXTURE_MIN_FILTER, this.minFilter), device.gl.bindTexture(device.gl.TEXTURE_CUBE_MAP, null)) : (device.gl.bindTexture(device.gl.TEXTURE_2D, this.texture), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MAG_FILTER, this.magFilter), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MIN_FILTER, this.minFilter), device.gl.bindTexture(device.gl.TEXTURE_2D, null)))
  1352.             }, Tw2TextureRes.prototype.Prepare = function (a, b) {
  1353.                 if (a == "cube") {
  1354.                     this.texture = device.gl.createTexture(), device.gl.bindTexture(device.gl.TEXTURE_CUBE_MAP, this.texture);
  1355.                     for (var c = 0; c < 6; ++c) device.gl.texImage2D(device.gl.TEXTURE_CUBE_MAP_POSITIVE_X + c, 0, device.gl.RGBA, device.gl.RGBA, device.gl.UNSIGNED_BYTE, this.images[c]);
  1356.                     device.gl.texParameteri(device.gl.TEXTURE_CUBE_MAP, device.gl.TEXTURE_MAG_FILTER, this.magFilter), device.gl.texParameteri(device.gl.TEXTURE_CUBE_MAP, device.gl.TEXTURE_MIN_FILTER, this.minFilter), device.gl.generateMipmap(device.gl.TEXTURE_CUBE_MAP), device.gl.bindTexture(device.gl.TEXTURE_CUBE_MAP, null), this.PrepareFinished(!0)
  1357.                 } else if (tw2TextureResPremultipliedAlphaWorkaround) {
  1358.                     var d = device.gl.createTexture();
  1359.                     device.gl.bindTexture(device.gl.TEXTURE_2D, d), device.gl.texImage2D(device.gl.TEXTURE_2D, 0, device.gl.RGBA, device.gl.RGBA, device.gl.UNSIGNED_BYTE, this.images[0]), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MAG_FILTER, device.gl.NEAREST), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MIN_FILTER, device.gl.NEAREST), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_WRAP_S, device.gl.CLAMP_TO_EDGE), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_WRAP_T, device.gl.CLAMP_TO_EDGE), device.gl.generateMipmap(device.gl.TEXTURE_2D), device.gl.bindTexture(device.gl.TEXTURE_2D, null);
  1360.                     var e = device.gl.createTexture();
  1361.                     device.gl.bindTexture(device.gl.TEXTURE_2D, e), device.gl.texImage2D(device.gl.TEXTURE_2D, 0, device.gl.RGB, device.gl.RGB, device.gl.UNSIGNED_BYTE, this.images[0]), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MAG_FILTER, device.gl.NEAREST), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MIN_FILTER, device.gl.NEAREST), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_WRAP_S, device.gl.CLAMP_TO_EDGE), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_WRAP_T, device.gl.CLAMP_TO_EDGE), device.gl.generateMipmap(device.gl.TEXTURE_2D), device.gl.bindTexture(device.gl.TEXTURE_2D, null), this.texture = device.gl.createTexture(), device.gl.bindTexture(device.gl.TEXTURE_2D, this.texture), device.gl.texImage2D(device.gl.TEXTURE_2D, 0, device.gl.RGBA, this.images[0].width, this.images[0].height, 0, device.gl.RGBA, device.gl.UNSIGNED_BYTE, null), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MAG_FILTER, this.magFilter), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MIN_FILTER, this.minFilter), device.gl.generateMipmap(device.gl.TEXTURE_2D), device.gl.bindTexture(device.gl.TEXTURE_2D, null);
  1362.                     var f = ['<?xml version="1.0" ?>', "<effect>", "  <shaders>", '    <shader name="vs"><![CDATA[', "attribute vec3 a_Position;", "varying lowp vec2 v_TexCoord;", "void main(void) {", "    vec4 projPosition = vec4(a_Position.xy, 1.0, 1.0);", "    v_TexCoord = a_Position.xy * 0.5 + vec2(0.5, 0.5);", "    gl_Position = projPosition;", "}", "  ]]>", "    </shader>", '    <shader name="fs"><![CDATA[', "precision highp float;", "uniform sampler2D RGBTexture;", "uniform sampler2D ATexture;", "varying lowp vec2 v_TexCoord;", "void main(void) ", "{", "    vec4 rgbTex = texture2D(RGBTexture, v_TexCoord);", "    vec4 aTex = texture2D(ATexture, v_TexCoord);", "    gl_FragColor = vec4(rgbTex.rgb, aTex.a);", "}", "  ]]>", "    </shader>", "  </shaders>", "  <techniques>", '    <technique name="t0">', '      <pass name="p0" vertexShader="vs" fragmentShader="fs">', "      </pass>", "    </technique>", "  </techniques>", "</effect>"].join("\n");
  1363.                     typeof this._effect == "undefined" && (this._effect = resMan.GetResource("str:/fx/" + f));
  1364.                     if (!this._effect.IsGood()) return !0;
  1365.                     var g = device.gl.createFramebuffer();
  1366.                     device.gl.bindFramebuffer(device.gl.FRAMEBUFFER, g), device.gl.framebufferTexture2D(device.gl.FRAMEBUFFER, device.gl.COLOR_ATTACHMENT0, device.gl.TEXTURE_2D, this.texture, 0), device.gl.bindRenderbuffer(device.gl.RENDERBUFFER, null), device.gl.bindFramebuffer(device.gl.FRAMEBUFFER, null), device.gl.bindFramebuffer(device.gl.FRAMEBUFFER, g), device.gl.viewport(0, 0, this.images[0].width, this.images[0].height), this._effect.ApplyPass(0, 0);
  1367.                     var h = this._effect.techniques[0].passes[0].shaderProgram;
  1368.                     device.gl.activeTexture(device.gl.TEXTURE0), device.gl.bindTexture(device.gl.TEXTURE_2D, e), device.gl.activeTexture(device.gl.TEXTURE0 + 1), device.gl.bindTexture(device.gl.TEXTURE_2D, d);
  1369.                     var i = device.gl.getUniformLocation(h, "RGBTexture");
  1370.                     device.gl.uniform1i(i, 0), i = device.gl.getUniformLocation(h, "ATexture"), device.gl.uniform1i(i, 1), device.gl.enableVertexAttribArray(0), device.gl.bindBuffer(device.gl.ARRAY_BUFFER, device._quadBuffer), device.gl.vertexAttribPointer(0, 3, device.gl.FLOAT, !1, 0, 0), device.SetStandardStates(device.RM_OPAQUE), device.gl.disable(device.gl.DEPTH_TEST), device.gl.depthMask(!1), device.gl.drawArrays(device.gl.TRIANGLE_STRIP, 0, 4), device.gl.enable(device.gl.DEPTH_TEST), device.gl.depthMask(!0), device.gl.bindFramebuffer(device.gl.FRAMEBUFFER, null), device.gl.bindTexture(device.gl.TEXTURE_2D, this.texture), device.gl.generateMipmap(device.gl.TEXTURE_2D), device.gl.bindTexture(device.gl.TEXTURE_2D, null), device.gl.deleteFramebuffer(g), device.gl.deleteTexture(e), device.gl.deleteTexture(d), delete this._effect, this.PrepareFinished(!0)
  1371.                 } else this.texture = device.gl.createTexture(), device.gl.bindTexture(device.gl.TEXTURE_2D, this.texture), device.gl.texImage2D(device.gl.TEXTURE_2D, 0, device.gl.RGBA, device.gl.RGBA, device.gl.UNSIGNED_BYTE, this.images[0]), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MAG_FILTER, this.magFilter), device.gl.texParameteri(device.gl.TEXTURE_2D, device.gl.TEXTURE_MIN_FILTER, this.minFilter), device.gl.generateMipmap(device.gl.TEXTURE_2D), device.gl.bindTexture(device.gl.TEXTURE_2D, null), this.PrepareFinished(!0)
  1372.             }, Tw2TextureRes.prototype.DoCustomLoad = function (a) {
  1373.                 this.LoadStarted(), this.images = [];
  1374.                 var b = this;
  1375.                 a = resMan.BuildUrl(a);
  1376.                 var c = "";
  1377.                 device.mipLevelSkipCount > 0 && (c = "." + device.mipLevelSkipCount.toString());
  1378.                 if (a.substr(-5) == ".cube") {
  1379.                     this.isCube = !0, this._facesLoaded = 0;
  1380.                     var d = a.substr(0, a.length - 5),
  1381.                         e = [".px", ".nx", ".py", ".ny", ".pz", ".nz"];
  1382.                     for (var f = 0; f < 6; ++f) this.images[f] = new Image, this.images[f].crossOrigin = "anonymous", this.images[f].onload = function (a) {
  1383.                         b._facesLoaded++, b._facesLoaded >= 6 && (b.LoadFinished(!0), resMan._prepareQueue.push([b, "cube", null]))
  1384.                     }, this.images[f].src = d + c + e[f] + ".png"
  1385.                 } else {
  1386.                     this.isCube = !1, this.images[0] = new Image, this.images[0].crossOrigin = "anonymous", this.images[0].onload = function () {
  1387.                         b.LoadFinished(!0), resMan._prepareQueue.push([b, "", null])
  1388.                     };
  1389.                     if (device.mipLevelSkipCount > 0) {
  1390.                         var g = a.lastIndexOf(".");
  1391.                         g >= 0 && (a = a.substr(0, g) + c + a.substr(g))
  1392.                     }
  1393.                     this.images[0].src = a
  1394.                 }
  1395.             }, Tw2TextureRes.prototype.Attach = function (a) {
  1396.                 this.texture = a, this.LoadFinished(!0), this.PrepareFinished(!0)
  1397.             }, Inherit(Tw2TextureRes, Tw2Resource), resMan.RegisterExtension("png", Tw2TextureRes), resMan.RegisterExtension("cube", Tw2TextureRes);
  1398.  
  1399.             function Tw2VertexElement(a, b, c) {
  1400.                 this.usage = a, this.usageIndex = b, this.type = c
  1401.             }
  1402.  
  1403.             function Tw2VertexDeclaration() {
  1404.                 this.elements = []
  1405.             }
  1406.             Tw2VertexDeclaration.prototype.Join = function (a) {
  1407.                 var b = new Tw2VertexDeclaration;
  1408.                 for (var c = 0; c < this.elements.length; ++c) b.elements[b.elements.length] = this.elements[c];
  1409.                 for (var c = 0; c < a.elements.length; ++c) b.Find(a.elements[c]) == -1 && (b.elements[b.elements.length] = a.elements[c]);
  1410.                 return b
  1411.             }, Tw2VertexDeclaration.prototype.Find = function (a) {
  1412.                 for (var b = 0; b < this.elements.length; ++b)
  1413.                     if (this.elements[b].usage == a.usage && this.elements[b].usageIndex == a.usageIndex) return b;
  1414.                 return -1
  1415.             };
  1416.  
  1417.             function Tw2EffectRes() {
  1418.                 this._super.constructor.call(this), this.techniques = []
  1419.             }
  1420.             Tw2EffectRes.prototype.Prepare = function (a, b) {
  1421.                 function d(a, c, d) {
  1422.                     var e = b.getElementsByTagName("shader");
  1423.                     for (var f = 0; f < e.length; ++f)
  1424.                         if (e[f].attributes.getNamedItem("name") && e[f].attributes.getNamedItem("name").value == a) {
  1425.                             var g = device.gl.createShader(c),
  1426.                                 h = "";
  1427.                             for (var i = 0; i < e[f].childNodes.length; ++i) h += e[f].childNodes[i].data;
  1428.                             device.gl.shaderSource(g, h), device.gl.compileShader(g);
  1429.                             if (!device.gl.getShaderParameter(g, device.gl.COMPILE_STATUS)) {
  1430.                                 log.LogErr("Error compiling shader '" + a + "' (effect '" + d + "'): " + device.gl.getShaderInfoLog(g));
  1431.                                 return null
  1432.                             }
  1433.                             return g
  1434.                         }
  1435.                     return null
  1436.                 }
  1437.                 var c = b.getElementsByTagName("technique");
  1438.                 if (c.length == 0) log.LogErr("Effect does not have any techniques defined"), this.PrepareFinished(!1);
  1439.                 else {
  1440.                     var e = [/^a_Position([0-7]?)$/i, /^a_BlendWeight([0-7]?)$/i, /^a_BlendIndices([0-7]?)$/i, /^a_Normal([0-7]?)$/i, /^a_PSize([0-7]?)$/i, /^a_TexCoord([0-7]?)$/i, /^a_Tangent([0-7]?)$/i, /^a_Binormal([0-7]?)$/i, /^a_TessFactor([0-7]?)$/i, /^a_PositionNT([0-7]?)$/i, /^a_Color([0-7]?)$/i, /^a_Fog([0-7]?)$/i, /^a_Depth([0-7]?)$/i, /^a_Sample([0-7]?)$/i];
  1441.                     for (var f = 0; f < c.length; ++f) {
  1442.                         techniqueDesc = c[f], technique = new Object, technique.name = "";
  1443.                         try {
  1444.                             technique.name = techniqueDesc.attributes.getNamedItem("name").value
  1445.                         } catch (g) {}
  1446.                         technique.passes = [], passes = techniqueDesc.getElementsByTagName("pass"), c.length == 0 && log.LogWarn("Effect's technique '" + technique.name + "' contains no passes");
  1447.                         for (var h = 0; h < passes.length; ++h) {
  1448.                             pass = new Object, passDesc = passes[h], pass.name = "";
  1449.                             try {
  1450.                                 pass.name = passDesc.attributes.getNamedItem("name").value
  1451.                             } catch (g) {}
  1452.                             pass.vertexShader = null, pass.pixelShader = null;
  1453.                             try {
  1454.                                 vsName = passDesc.attributes.getNamedItem("vertexShader").value
  1455.                             } catch (g) {
  1456.                                 log.LogErr("Can't find vertex shader name for pass '" + pass.name + "'"), this.PrepareFinished(!1);
  1457.                                 return
  1458.                             }
  1459.                             pass.vertexShader = d(vsName, device.gl.VERTEX_SHADER, this.path);
  1460.                             if (pass.vertexShader == null) {
  1461.                                 this.PrepareFinished(!1);
  1462.                                 return
  1463.                             }
  1464.                             try {
  1465.                                 fsName = passDesc.attributes.getNamedItem("fragmentShader").value
  1466.                             } catch (g) {
  1467.                                 log.LogErr("Can't find fragment shader name for pass '" + pass.name + "'"), this.PrepareFinished(!1);
  1468.                                 return
  1469.                             }
  1470.                             pass.fragmentShader = d(fsName, device.gl.FRAGMENT_SHADER, this.path);
  1471.                             if (pass.fragmentShader == null) {
  1472.                                 this.PrepareFinished(!1);
  1473.                                 return
  1474.                             }
  1475.                             pass.shaderProgram = device.gl.createProgram(), device.gl.attachShader(pass.shaderProgram, pass.vertexShader), device.gl.attachShader(pass.shaderProgram, pass.fragmentShader), device.gl.linkProgram(pass.shaderProgram);
  1476.                             if (!device.gl.getProgramParameter(pass.shaderProgram, device.gl.LINK_STATUS)) {
  1477.                                 log.LogErr("Error linking shaders: " + device.gl.getProgramInfoLog(pass.shaderProgram)), this.PrepareFinished(!1);
  1478.                                 return
  1479.                             }
  1480.                             device.gl.useProgram(pass.shaderProgram), pass.vertexInput = new Tw2VertexDeclaration;
  1481.                             var i = device.gl.getProgramParameter(pass.shaderProgram, device.gl.ACTIVE_ATTRIBUTES);
  1482.                             for (var f = 0; f < i; ++f) {
  1483.                                 var j = device.gl.getActiveAttrib(pass.shaderProgram, f),
  1484.                                     k = !1;
  1485.                                 for (var l = 0; l < e.length; ++l) {
  1486.                                     var m = e[l].exec(j.name);
  1487.                                     if (m) {
  1488.                                         var n = 0;
  1489.                                         m[1] != "" && (n = 0 + m[1]), pass.vertexInput.elements[pass.vertexInput.elements.length] = new Tw2VertexElement(l, n), pass.vertexInput.elements[pass.vertexInput.elements.length - 1].attribute = device.gl.getAttribLocation(pass.shaderProgram, j.name), k = !0;
  1490.                                         break
  1491.                                     }
  1492.                                 }
  1493.                                 if (!k) {
  1494.                                     log.LogErr("Error linking vertex attribute named '" + j.name + "'"), this.PrepareFinished(!1);
  1495.                                     return
  1496.                                 }
  1497.                             }
  1498.                             pass.states = [], srcBlend = null, destBlend = null;
  1499.                             for (var f = 0; f < passDesc.childNodes.length; ++f) {
  1500.                                 var o = passDesc.childNodes[f];
  1501.                                 if (o.nodeName == "#text") continue;
  1502.                                 if (o.nodeName == "cullFace") {
  1503.                                     try {
  1504.                                         var p = o.attributes.getNamedItem("enable").value
  1505.                                     } catch (g) {
  1506.                                         log.LogWarn("Invalid value for cullFace render state in effect " + this.path)
  1507.                                     }
  1508.                                     p.toLowerCase() == "true" ? pass.states[pass.states.length] = [device.gl.enable, [device.gl.CULL_FACE]] : pass.states[pass.states.length] = [device.gl.disable, [device.gl.CULL_FACE]]
  1509.                                 } else if (o.nodeName == "depthMask") {
  1510.                                     try {
  1511.                                         var p = o.attributes.getNamedItem("enable").value
  1512.                                     } catch (g) {
  1513.                                         log.LogWarn("Invalid value for cullFace render state in effect " + this.path)
  1514.                                     }
  1515.                                     p.toLowerCase() == "true" ? pass.states[pass.states.length] = [device.gl.depthMask, [!0]] : pass.states[pass.states.length] = [device.gl.depthMask, [!1]]
  1516.                                 } else if (o.nodeName == "depthTest") {
  1517.                                     try {
  1518.                                         var p = o.attributes.getNamedItem("enable").value
  1519.                                     } catch (g) {
  1520.                                         log.LogWarn("Invalid value for depthTest render state in effect " + this.path)
  1521.                                     }
  1522.                                     p.toLowerCase() == "true" ? pass.states[pass.states.length] = [device.gl.enable, [device.gl.DEPTH_TEST]] : pass.states[pass.states.length] = [device.gl.disable, [device.gl.DEPTH_TEST]]
  1523.                                 } else if (o.nodeName == "alphaBlendEnable") {
  1524.                                     try {
  1525.                                         var p = o.attributes.getNamedItem("enable").value
  1526.                                     } catch (g) {
  1527.                                         log.LogWarn("Invalid value for alphaBlendEnable render state in effect " + this.path)
  1528.                                     }
  1529.                                     p.toLowerCase() == "true" ? pass.states[pass.states.length] = [device.gl.enable, [device.gl.BLEND]] : pass.states[pass.states.length] = [device.gl.disable, [device.gl.BLEND]]
  1530.                                 } else if (o.nodeName == "frontFace") {
  1531.                                     try {
  1532.                                         var p = o.attributes.getNamedItem("direction").value
  1533.                                     } catch (g) {
  1534.                                         log.LogWarn("Invalid value for frontFace render state in effect " + this.path)
  1535.                                     }
  1536.                                     p.toLowerCase() == "cw" ? pass.states[pass.states.length] = [device.gl.frontFace, [device.gl.CW]] : pass.states[pass.states.length] = [device.gl.frontFace, [device.gl.CCW]]
  1537.                                 } else if (o.nodeName == "srcBlend") {
  1538.                                     try {
  1539.                                         var p = o.attributes.getNamedItem("blend").value
  1540.                                     } catch (g) {
  1541.                                         log.LogWarn("Invalid value for srcBlend render state in effect " + this.path)
  1542.                                     }
  1543.                                     p.toLowerCase() == "srcalpha" ? srcBlend = device.gl.SRC_ALPHA : p.toLowerCase() == "one" && (srcBlend = device.gl.ONE)
  1544.                                 } else if (o.nodeName == "destBlend") {
  1545.                                     try {
  1546.                                         var p = o.attributes.getNamedItem("blend").value
  1547.                                     } catch (g) {
  1548.                                         log.LogWarn("Invalid value for destBlend render state in effect " + this.path)
  1549.                                     }
  1550.                                     p.toLowerCase() == "invsrcalpha" ? destBlend = device.gl.ONE_MINUS_SRC_ALPHA : p.toLowerCase() == "one" && (destBlend = device.gl.ONE)
  1551.                                 } else log.LogWarn("Unknown render state '" + o.nodeName + "' in effect " + this.path)
  1552.                             }
  1553.                             if (srcBlend != null || destBlend != null) srcBlend == null && (srcBlend = device.gl.ONE), destBlend == null && (destBlend = device.gl.ZERO), pass.states[pass.states.length] = [device.gl.blendFunc, [srcBlend, destBlend]];
  1554.                             technique.passes[technique.passes.length] = pass
  1555.                         }
  1556.                         technique.vertexInput = new Tw2VertexDeclaration;
  1557.                         for (var f = 0; f < technique.passes.length; ++f) technique.vertexInput = technique.vertexInput.Join(technique.passes[f].vertexInput);
  1558.                         this.techniques[this.techniques.length] = technique
  1559.                     }
  1560.                     this.PrepareFinished(!0)
  1561.                 }
  1562.             }, Tw2EffectRes.prototype.ApplyPass = function (a, b) {
  1563.                 device.gl.useProgram(this.techniques[a].passes[b].shaderProgram);
  1564.                 for (var c = 0; c < this.techniques[a].passes[b].states.length; ++c) this.techniques[a].passes[b].states[c][0].apply(device.gl, this.techniques[a].passes[b].states[c][1]);
  1565.                 this.techniques[a].passes[b].states.length && (device._currentRenderMode = null)
  1566.             }, Inherit(Tw2EffectRes, Tw2Resource), resMan.RegisterExtension("fx", Tw2EffectRes);
  1567.  
  1568.             function Tw2Effect() {
  1569.                 this.name = "", this.effectFilePath = "", this.effectRes = null, this.activeTechnique = 0, this.parameters = new Object, this.activeParameters = [], this.additionalParameters = null
  1570.             }
  1571.             Tw2Effect.prototype.Initialize = function () {
  1572.                 this.effectFilePath != "" && (this.effectRes = resMan.GetResource(this.effectFilePath), this.effectRes.RegisterNotification(this))
  1573.             }, Tw2Effect.prototype.GetEffectRes = function () {
  1574.                 return this.effectRes
  1575.             }, Tw2Effect.prototype.GetActiveTechnique = function () {
  1576.                 return this.activeTechnique
  1577.             }, Tw2Effect.prototype.ReleaseCachedData = function (a) {
  1578.                 this.activeParameters = []
  1579.             }, Tw2Effect.prototype.RebuildCachedData = function (a) {
  1580.                 a.IsGood() && this.BindParameters()
  1581.             }, Tw2Effect.prototype.FindParameter = function (a) {
  1582.                 return a in this.parameters ? this.parameters[a] : a in variableStore._variables ? variableStore._variables[a] : null
  1583.             }, Tw2Effect.prototype.BindParameters = function () {
  1584.                 if (this.effectRes == null || !this.effectRes.IsGood()) return !1;
  1585.                 this.activeParameters = [];
  1586.                 for (var a = 0; a < this.effectRes.techniques.length; ++a) {
  1587.                     this.activeParameters[a] = [];
  1588.                     for (var b = 0; b < this.effectRes.techniques[a].passes.length; ++b) {
  1589.                         var c = this.effectRes.techniques[a].passes[b];
  1590.                         this.activeParameters[a][b] = [];
  1591.                         var d = device.gl.getProgramParameter(c.shaderProgram, device.gl.ACTIVE_UNIFORMS);
  1592.                         for (var e = 0; e < d; ++e) {
  1593.                             var f = device.gl.getActiveUniform(c.shaderProgram, e),
  1594.                                 g = this.FindParameter(f.name);
  1595.                             g != null && (this.activeParameters[a][b][this.activeParameters[a][b].length] = [g, device.gl.getUniformLocation(c.shaderProgram, g.name)])
  1596.                         }
  1597.                     }
  1598.                 }
  1599.                 return !0
  1600.             }, Tw2Effect.prototype.ApplyPass = function (a, b) {
  1601.                 if (!(this.effectRes == null || !this.effectRes.IsGood() || a >= this.effectRes.techniques.length)) {
  1602.                     device.ResetActiveTextures(), this.effectRes.ApplyPass(a, b);
  1603.                     var c = this.activeParameters[a][b],
  1604.                         d = this.effectRes.techniques[a].passes[b].shaderProgram;
  1605.                     for (var e = 0; e < c.length; ++e) c[e][0].Apply(d, c[e][1]);
  1606.                     device.perObjectData && device.perObjectData.ApplyShaderParameters(d)
  1607.                 }
  1608.             }, Tw2Effect.prototype.GetPassCount = function (a) {
  1609.                 return this.effectRes == null || !this.effectRes.IsGood() || a >= this.effectRes.techniques.length ? 0 : this.effectRes.techniques[a].passes.length
  1610.             }, Tw2Effect.prototype.GetPassInput = function (a, b) {
  1611.                 return this.effectRes == null || !this.effectRes.IsGood() || a >= this.effectRes.techniques.length ? null : this.effectRes.techniques[a].passes[b].vertexInput
  1612.             };
  1613.  
  1614.             function Tw2MeshArea() {
  1615.                 this.name = "", this.effect = null, this.meshIndex = 0, this.index = 0, this.count = 1, this.debugIsHidden = !1
  1616.             }
  1617.  
  1618.             function Tw2Mesh() {
  1619.                 this.name = "", this.meshIndex = 0, this.geometryResPath = "", this.lowDetailGeometryResPath = "", this.geometryResource = null, this.opaqueAreas = [], this.transparentAreas = [], this.transparentAreas = [], this.additiveAreas = [], this.pickableAreas = [], this.decalAreas = [], this.depthAreas = [], this.debugIsHidden = !1
  1620.             }
  1621.             Tw2Mesh.prototype.Initialize = function () {
  1622.                 this.geometryResPath != "" && (this.geometryResource = resMan.GetResource(this.geometryResPath))
  1623.             }, Tw2Mesh.prototype._GetAreaBatches = function (a, b, c, d) {
  1624.                 for (var e = 0; e < a.length; ++e) {
  1625.                     var f = a[e];
  1626.                     if (f.effect == null || f.debugIsHidden) continue;
  1627.                     var g = new Tw2GeometryBatch;
  1628.                     g.renderMode = b, g.perObjectData = d, g.geometryRes = this.geometryResource, g.meshIx = f.meshIndex, g.start = f.index, g.count = f.count, g.effect = f.effect, c.Commit(g)
  1629.                 }
  1630.             }, Tw2Mesh.prototype.GetBatches = function (a, b, c) {
  1631.                 if (this.geometryResource == null || this.debugIsHidden) return !1;
  1632.                 a == device.RM_OPAQUE ? this._GetAreaBatches(this.opaqueAreas, a, b, c) : a == device.RM_DECAL ? this._GetAreaBatches(this.decalAreas, a, b, c) : a == device.RM_TRANSPARENT ? this._GetAreaBatches(this.transparentAreas, a, b, c) : a == device.RM_ADDITIVE && this._GetAreaBatches(this.additiveAreas, a, b, c);
  1633.                 return !0
  1634.             };
  1635.  
  1636.             function Tw2Track() {
  1637.                 this.trackRes = null, this.bone = null
  1638.             }
  1639.  
  1640.             function Tw2TrackGroup() {
  1641.                 this.trackGroupRes = null, this.model = null, this.transformTracks = []
  1642.             }
  1643.  
  1644.             function Tw2Animation() {
  1645.                 this.animationRes = null, this.time = 0, this.timeScale = 1, this.cycle = !1, this.isPlaying = !1, this.callback = null, this.trackGroups = []
  1646.             }
  1647.             Tw2Animation.prototype.IsFinished = function () {
  1648.                 return !this.cycle && this.time >= this.duration
  1649.             };
  1650.  
  1651.             function Tw2Bone() {
  1652.                 this.boneRes = null, this.localTransform = mat4.create(), this.worldTransform = mat4.create(), this.offsetTransform = mat4.create()
  1653.             }
  1654.  
  1655.             function Tw2Model() {
  1656.                 this.modelRes = null, this.bones = []
  1657.             }
  1658.  
  1659.             function Tw2AnimationController(a) {
  1660.                 this.geometryResources = [], this.models = [], this.animations = [], this.meshBindings = [], this.loaded = !1, this.update = !0, typeof a != "undefined" && this.SetGeometryResource(a)
  1661.             }
  1662.             Tw2AnimationController.prototype.SetGeometryResource = function (a) {
  1663.                 this.models = [], this.animations = [], this.meshBindings = [];
  1664.                 for (var b = 0; b < this.geometryResources.length; ++b) this.geometryResources[b].UnregisterNotification(this);
  1665.                 this.loaded = !1, this.geometryResources = [], a && (this.geometryResources.push(a), a.RegisterNotification(this))
  1666.             }, Tw2AnimationController.prototype.AddGeometryResource = function (a) {
  1667.                 for (var b = 0; b < this.geometryResources.length; ++b)
  1668.                     if (this.geometryResources[b] == a) return;
  1669.                 this.geometryResources.push(a), a.RegisterNotification(this)
  1670.             }, Tw2AnimationController.prototype.AddAnimationsFromRes = function (a) {
  1671.                 for (var b = 0; b < a.animations.length; ++b) {
  1672.                     var c = null;
  1673.                     for (var d = 0; d < this.animations.length; ++d)
  1674.                         if (this.animations[d].animationRes == a.animations[b]) {
  1675.                             c = this.animations[b];
  1676.                             break
  1677.                         }
  1678.                     c || (c = new Tw2Animation, c.animationRes = a.animations[b], this.animations.push(c));
  1679.                     for (var d = 0; d < c.animationRes.trackGroups.length; ++d) {
  1680.                         var e = !1;
  1681.                         for (var f = 0; f < c.trackGroups.length; ++f)
  1682.                             if (c.trackGroups[f].trackGroupRes == c.animationRes.trackGroups[d]) {
  1683.                                 e = !0;
  1684.                                 break
  1685.                             }
  1686.                         if (e) continue;
  1687.                         var g = null;
  1688.                         for (var f = 0; f < this.models.length; ++f)
  1689.                             if (this.models[f].modelRes.name == c.animationRes.trackGroups[d].name) {
  1690.                                 g = this.models[f];
  1691.                                 break
  1692.                             }
  1693.                         if (g != null) {
  1694.                             var h = new Tw2TrackGroup;
  1695.                             h.trackGroupRes = c.animationRes.trackGroups[d];
  1696.                             for (var f = 0; f < h.trackGroupRes.transformTracks.length; ++f)
  1697.                                 for (var i = 0; i < g.bones.length; ++i)
  1698.                                     if (g.bones[i].boneRes.name == h.trackGroupRes.transformTracks[f].name) {
  1699.                                         var j = new Tw2Track;
  1700.                                         j.trackRes = h.trackGroupRes.transformTracks[f], j.bone = g.bones[i], h.transformTracks.push(j);
  1701.                                         break
  1702.                                     }
  1703.                             c.trackGroups.push(h)
  1704.                         }
  1705.                     }
  1706.                 }
  1707.             }, Tw2AnimationController.prototype._AddModel = function (a) {
  1708.                 for (var b = 0; b < this.models.length; ++b)
  1709.                     if (this.models[b].modelRes.name == a.name) return null;
  1710.                 var c = new Tw2Model;
  1711.                 c.modelRes = a;
  1712.                 var d = a.skeleton;
  1713.                 if (d != null)
  1714.                     for (var e = 0; e < d.bones.length; ++e) {
  1715.                         var f = new Tw2Bone;
  1716.                         f.boneRes = d.bones[e], c.bones.push(f)
  1717.                     }
  1718.                 this.models.push(c);
  1719.                 return c
  1720.             }, Tw2AnimationController.prototype._FindMeshBindings = function (a) {
  1721.                 for (var b = 0; b < this.meshBindings.length; ++b)
  1722.                     if (this.meshBindings[b].resource == a) return this.meshBindings[b];
  1723.                 return null
  1724.             }, Tw2AnimationController.prototype.RebuildCachedData = function (a) {
  1725.                 var b = !1;
  1726.                 for (var c = 0; c < this.geometryResources.length; ++c)
  1727.                     if (this.geometryResources[c] == a) {
  1728.                         b = !0;
  1729.                         break
  1730.                     }
  1731.                 if ( !! b) {
  1732.                     var d = [];
  1733.                     if (a.meshes.length)
  1734.                         for (var c = 0; c < a.models.length; ++c) {
  1735.                             var e = this._AddModel(a.models[c]);
  1736.                             e && d.push(e)
  1737.                         }
  1738.                     for (var c = 0; c < this.geometryResources.length; ++c) this.AddAnimationsFromRes(this.geometryResources[c], this.models);
  1739.                     for (var c = 0; c < a.models.length; ++c) {
  1740.                         var e = null;
  1741.                         for (var f = 0; f < this.models.length; ++f)
  1742.                             if (this.models[f].modelRes.name == a.models[c].name) {
  1743.                                 e = this.models[f];
  1744.                                 break
  1745.                             }
  1746.                         if (e == null) continue;
  1747.                         for (var f = 0; f < a.models[c].meshBindings.length; ++f) {
  1748.                             var g = a.meshes.indexOf(a.models[c].meshBindings[f].mesh),
  1749.                                 h = this._FindMeshBindings(a);
  1750.                             h == null && (h = [], h.resource = a, this.meshBindings.push(h)), h[g] = new glMatrixArrayType(a.models[c].meshBindings[f].bones.length * 16);
  1751.                             for (var i = 0; i < a.models[c].meshBindings[f].bones.length; ++i)
  1752.                                 for (var j = 0; j < e.bones.length; ++j)
  1753.                                     if (e.bones[j].boneRes.name == a.models[c].meshBindings[f].bones[i].name) {
  1754.                                         e.bones[j].bindingArrays || (e.bones[j].bindingArrays = []);
  1755.                                         var k = {
  1756.                                             array: h[g],
  1757.                                             offset: i * 16
  1758.                                         };
  1759.                                         e.bones[j].bindingArrays[e.bones[j].bindingArrays.length] = k;
  1760.                                         break
  1761.                                     }
  1762.                         }
  1763.                     }
  1764.                     a.meshes.length && a.models.length && this.ResetBoneTransforms(a.models), this.loaded = !0
  1765.                 }
  1766.             }, Tw2AnimationController.prototype.PlayAnimation = function (a, b, c) {
  1767.                 for (var d = 0; d < this.animations.length; ++d) this.animations[d].animationRes.name == a && (this.animations[d].time = 0, this.animations[d].isPlaying = !0, typeof b != "undefined" && (this.animations[d].cycle = b), typeof c != "undefined" && (this.animations[d].callback = c))
  1768.             }, Tw2AnimationController.prototype.StopAnimation = function (a) {
  1769.                 for (var b = 0; b < this.animations.length; ++b) this.animations[b].animationRes.name == a && (this.animations[b].isPlaying = !1)
  1770.             }, Tw2AnimationController.prototype.StopAllAnimations = function () {
  1771.                 for (var a = 0; a < this.animations.length; ++a) this.animations[a].isPlaying = !1
  1772.             }, Tw2AnimationController.prototype.ResetBoneTransforms = function (a) {
  1773.                 for (var b = 0; b < this.models.length; ++b)
  1774.                     for (var c = 0; c < this.models[b].bones.length; ++c) {
  1775.                         var d = this.models[b].bones[c],
  1776.                             e = d.boneRes;
  1777.                         mat4.set(e.localTransform, d.localTransform), e.parentIndex != -1 ? mat4.multiply(d.localTransform, this.models[b].bones[d.boneRes.parentIndex].worldTransform, d.worldTransform) : mat4.set(d.localTransform, d.worldTransform), mat4.identity(d.offsetTransform)
  1778.                     }
  1779.                 var f = mat4.identity(mat4.create());
  1780.                 for (var b = 0; b < this.meshBindings.length; ++b)
  1781.                     for (var c = 0; c < this.meshBindings[b].length; ++c)
  1782.                         for (var g = 0; g * 16 < this.meshBindings[b][c].length; ++g)
  1783.                             for (var h = 0; h < 16; ++h) this.meshBindings[b][c][g * 16 + h] = f[h]
  1784.             }, Tw2AnimationController.prototype.Update = function (a) {
  1785.                 function b(a, b, c) {
  1786.                     var d = a.knots.length - 1,
  1787.                         e = 0;
  1788.                     for (var f = a.degree; f < a.knots.length; ++f)
  1789.                         if (a.knots[f] > b) {
  1790.                             if (f == 0) d = 0;
  1791.                             else {
  1792.                                 d = f;
  1793.                                 var g = a.knots[f] - a.knots[f - 1];
  1794.                                 g > 0 && (e = (b - a.knots[f - 1]) / g)
  1795.                             }
  1796.                             break
  1797.                         }
  1798.                     if (a.degree == 0)
  1799.                         for (var f = 0; f < a.dimension; ++f) c[f] = a.controls[d * a.dimension + f];
  1800.                     else if (a.degree == 1) {
  1801.                         var h = d - 1;
  1802.                         for (var f = 0; f < a.dimension; ++f) c[f] = a.controls[h * a.dimension + f] * (1 - e) + a.controls[d * a.dimension + f] * e
  1803.                     } else {
  1804.                         var i = (d - 2) * a.dimension,
  1805.                             j = (d - 1) * a.dimension,
  1806.                             k = d * a.dimension;
  1807.                         for (var f = 0; f < a.dimension; ++f) {
  1808.                             var l = (a.controls[i + f] - 2 * a.controls[j + f] + a.controls[k + f]) * .5,
  1809.                                 m = (-2 * a.controls[i + f] + 2 * a.controls[j + f]) * .5,
  1810.                                 n = (a.controls[i + f] + a.controls[j + f]) * .5;
  1811.                             c[f] = l * e * e + m * e + n
  1812.                         }
  1813.                     }
  1814.                 }
  1815.                 if (this.models != null && !! this.update) {
  1816.                     var c = !1;
  1817.                     for (var d = 0; d < this.animations.length; ++d) {
  1818.                         var e = this.animations[d];
  1819.                         if (e.isPlaying) {
  1820.                             var f = e.animationRes;
  1821.                             e.time += a * e.timeScale, e.time > f.duration && (e.callback != null && e.callback(this, e), e.cycle ? e.time = e.time % f.duration : (e.isPlaying = !1, e.time = f.duration));
  1822.                             for (var g = 0; g < e.trackGroups.length; ++g)
  1823.                                 for (var h = 0; h < e.trackGroups[g].transformTracks.length; ++h) {
  1824.                                     var i = e.trackGroups[g].transformTracks[h],
  1825.                                         j = vec3.create();
  1826.                                     i.trackRes.position ? b(i.trackRes.position, e.time, j) : vec3.set([0, 0, 0], j);
  1827.                                     var k = quat4.create();
  1828.                                     i.trackRes.orientation ? (b(i.trackRes.orientation, e.time, k), quat4.normalize(k)) : quat4.set([0, 0, 0, 1], k);
  1829.                                     var l = mat3.create();
  1830.                                     i.trackRes.scaleShear ? b(i.trackRes.scaleShear, e.time, l) : mat3.identity(l), mat3.toMat4(l, i.bone.localTransform), mat4.multiply(i.bone.localTransform, mat4.transpose(quat4.toMat4(k))), i.bone.localTransform[12] = j[0], i.bone.localTransform[13] = j[1], i.bone.localTransform[14] = j[2], c = !0
  1831.                                 }
  1832.                         }
  1833.                     }
  1834.                     for (var d = 0; d < this.models.length; ++d)
  1835.                         for (var g = 0; g < this.models[d].bones.length; ++g) {
  1836.                             var m = this.models[d].bones[g];
  1837.                             m.boneRes.parentIndex != -1 ? mat4.multiply(this.models[d].bones[m.boneRes.parentIndex].worldTransform, m.localTransform, m.worldTransform) : mat4.set(m.localTransform, m.worldTransform), mat4.multiply(m.worldTransform, m.boneRes.worldTransformInv, m.offsetTransform);
  1838.                             if (m.bindingArrays)
  1839.                                 for (var n = 0; n < m.bindingArrays.length; ++n)
  1840.                                     for (var o = 0; o < 16; ++o) m.bindingArrays[n].array[m.bindingArrays[n].offset + o] = m.offsetTransform[o]
  1841.                         }
  1842.                 }
  1843.             }, Tw2AnimationController.prototype.RenderDebugInfo = function (a) {
  1844.                 for (var b = 0; b < this.models.length; ++b)
  1845.                     for (var c = 0; c < this.models[b].bones.length; ++c) {
  1846.                         var d = this.models[b].bones[c];
  1847.                         if (d.boneRes.parentIndex >= 0) {
  1848.                             var e = this.models[b].bones[d.boneRes.parentIndex];
  1849.                             a.AddLine([d.worldTransform[12], d.worldTransform[13], d.worldTransform[14]], [e.worldTransform[12], e.worldTransform[13], e.worldTransform[14]])
  1850.                         }
  1851.                     }
  1852.             }, Tw2AnimationController.prototype.GetBoneMatrixes = function (a, b) {
  1853.                 if (this.geometryResources.length == 0) return [];
  1854.                 typeof b == "undefined" && (b = this.geometryResources[0]);
  1855.                 var c = this._FindMeshBindings(b);
  1856.                 return c && a < c.length ? c[a] : []
  1857.             }, Tw2AnimationController.prototype.FindModelForMesh = function (a, b) {
  1858.                 if (this.geometryResources.length == 0) return null;
  1859.                 typeof b == "undefined" && (b = this.geometryResources[0]);
  1860.                 if (!b.IsGood()) return null;
  1861.                 var c = b.meshes[a];
  1862.                 for (var d = 0; d < this.models.length; ++d)
  1863.                     for (var e = 0; e < this.models[d].modelRes.meshBindings.length; ++d)
  1864.                         if (this.models[d].modelRes.meshBindings[e].mesh = c) return this.models[d];
  1865.                 return null
  1866.             };
  1867.  
  1868.             function EveSkybox() {
  1869.                 this.envMapPath = "", this.envMapRes = null, this.effect = null
  1870.             }
  1871.             EveSkybox.prototype.Initialize = function () {
  1872.                 this.envMapPath != "" && (this.envMapRes = resMan.GetResource(eval(ref.selectedShip.nebula)[0]))
  1873.             }, EveSkybox.prototype.Render = function () {
  1874.                 this.envMapRes != null && (device.SetStandardStates(device.RM_OPAQUE), device.gl.disable(device.gl.DEPTH_TEST), device.RenderFullScreenQuad(this.effect), device.gl.enable(device.gl.DEPTH_TEST))
  1875.             };
  1876.  
  1877.             function EveLocator() {
  1878.                 this.name = "", this.transform = mat4.create()
  1879.             }
  1880.  
  1881.             function EveBoosterSet() {
  1882.                 this.display = !0, this.effect = null, this.glows = null, this.glowScale = 1, this.glowColor = [0, 0, 0, 0], this.symHaloScale = 1, this.haloScaleX = 1, this.haloScaleY = 1, this.maxVel = 250, this.haloColor = [0, 0, 0, 0], this.alwaysOn = !0, this._parentTransform = mat4.create(), this._wavePhase = mat4.create(), this._boosterTransforms = [];
  1883.                 var a = [],
  1884.                     b = [];
  1885.                 for (var c = 0; c < 4; ++c) {
  1886.                     var d = c * Math.PI / 4,
  1887.                         e = Math.cos(d) * .5,
  1888.                         f = Math.sin(d) * .5;
  1889.                     a.push(-e), a.push(-f), a.push(0), a.push(e), a.push(f), a.push(-1), a.push(-e), a.push(-f), a.push(-1), a.push(-e), a.push(-f), a.push(0), a.push(e), a.push(f), a.push(0), a.push(e), a.push(f), a.push(-1), b.push(1), b.push(1), b.push(0), b.push(0), b.push(1), b.push(0), b.push(1), b.push(1), b.push(0), b.push(1), b.push(0), b.push(0)
  1890.                 }
  1891.                 this._positions = device.gl.createBuffer(), device.gl.bindBuffer(device.gl.ARRAY_BUFFER, this._positions), device.gl.bufferData(device.gl.ARRAY_BUFFER, new Float32Array(a), device.gl.STATIC_DRAW), this._texCoords = device.gl.createBuffer(), device.gl.bindBuffer(device.gl.ARRAY_BUFFER, this._texCoords), device.gl.bufferData(device.gl.ARRAY_BUFFER, new Float32Array(b), device.gl.STATIC_DRAW), this.rebuildPending = !1
  1892.             }
  1893.             EveBoosterSet.prototype.Initialize = function () {
  1894.                 this.rebuildPending = !0
  1895.             }, EveBoosterSet.prototype.Clear = function () {
  1896.                 this._boosterTransforms = [], this._wavePhase = mat4.create(), this.glows && this.glows.Clear()
  1897.             }, EveBoosterSet.prototype.Add = function (a) {
  1898.                 var b = mat4.create();
  1899.                 mat4.set(a, b), this._boosterTransforms[this._boosterTransforms.length] = b, this._wavePhase[this._wavePhase.length] = Math.random();
  1900.                 if (this.glows) {
  1901.                     var c = vec3.create([a[12], a[13], a[14]]),
  1902.                         d = vec3.create([a[8], a[9], a[10]]),
  1903.                         e = vec3.length(d),
  1904.                         f = vec3.create();
  1905.                     vec3.subtract(c, vec3.scale(d, 2.5, f), f), this.glows.Add(f, 0, 0, e * this.glowScale, e * this.glowScale, 0, this.glowColor), vec3.subtract(c, vec3.scale(d, 3, f), f), this.glows.Add(f, 0, 1, e * this.symHaloScale, e * this.symHaloScale, 0, this.haloColor), vec3.subtract(c, vec3.scale(d, 3.01, f), f), this.glows.Add(f, 0, 1, e * this.haloScaleX, e * this.haloScaleY, 0, this.haloColor)
  1906.                 }
  1907.             }, EveBoosterSet.prototype.Rebuild = function () {
  1908.                 this.rebuildPending = !1, this.glows.RebuildBuffers()
  1909.             }, EveBoosterSet.prototype.Update = function (a, b) {
  1910.                 this.glows && this.glows.Update(a), this._parentTransform = b
  1911.             };
  1912.  
  1913.             function EveBoosterBatch() {
  1914.                 this.renderMode = device.RM_ANY, this.perObjectData = null, this.boosters = null
  1915.             }
  1916.             EveBoosterBatch.prototype.Commit = function (a) {
  1917.                 this.boosters.Render(a)
  1918.             }, EveBoosterSet.prototype.GetBatches = function (a, b, c) {
  1919.                 if (a == device.RM_ADDITIVE) {
  1920.                     if (this.effect && this._boosterTransforms.length) {
  1921.                         var d = new EveBoosterBatch;
  1922.                         d.perObjectData = c, d.boosters = this, d.renderMode = device.RM_ADDITIVE, b.Commit(d)
  1923.                     }
  1924.                     this.glows && this.glows.GetBatches(a, b, c)
  1925.                 }
  1926.             }, EveBoosterSet.prototype.Render = function (a) {
  1927.                 var b = typeof a == "undefined" ? this.effect : a,
  1928.                     c = b.GetEffectRes();
  1929.                 if (!c.IsGood()) return !1;
  1930.                 var d = b.GetActiveTechnique(),
  1931.                     e = mat4.create();
  1932.                 device.perObjectData.RegisterVariableWithType("WavePhase", this._wavePhase[f], Tw2FloatParameter);
  1933.                 for (var f = 0; f < this._boosterTransforms.length; ++f) {
  1934.                     mat4.multiply(this._parentTransform, this._boosterTransforms[f], e), device.SetWorld(e);
  1935.                     for (var g = 0; g < b.GetPassCount(d); ++g) {
  1936.                         b.ApplyPass(d, g);
  1937.                         var h = b.GetPassInput(d, g);
  1938.                         for (var i = 0; i < h.elements.length; ++i) {
  1939.                             if (h.elements[i].usage != 0 && h.elements[i].usage != 5) {
  1940.                                 log.LogErr("Error binding vertex buffer to effect attribute for usage " + h.elements[i].usage + " and index " + h.elements[i].usageIndex);
  1941.                                 return !1
  1942.                             }
  1943.                             device.gl.enableVertexAttribArray(i), h.elements[i].usage == 0 ? (device.gl.bindBuffer(device.gl.ARRAY_BUFFER, this._positions), device.gl.vertexAttribPointer(i, 3, device.gl.FLOAT, !1, 0, 0)) : (device.gl.bindBuffer(device.gl.ARRAY_BUFFER, this._texCoords), device.gl.vertexAttribPointer(i, 2, device.gl.FLOAT, !1, 0, 0))
  1944.                         }
  1945.                         device.gl.drawArrays(device.gl.TRIANGLES, 0, 24)
  1946.                     }
  1947.                 }
  1948.                 return !0
  1949.             };
  1950.  
  1951.             function EveSpriteSet() {
  1952.                 this.sprites = [], this.effect = null, this._time = 0, this.vertexBuffer = null, this.indexBuffer = null
  1953.             }
  1954.             EveSpriteSet.prototype.Initialize = function () {
  1955.                 this.RebuildBuffers(), this.effect && typeof this.effect.parameters.GradientMap != "undefined" && (this.effect.parameters.GradientMap.wrapS = 33071, this.effect.parameters.GradientMap.wrapT = 33071)
  1956.             }, EveSpriteSet.prototype.RebuildBuffers = function () {
  1957.                 var a = 12,
  1958.                     b = new Float32Array(this.sprites.length * 4 * a);
  1959.                 for (var c = 0; c < this.sprites.length; ++c) {
  1960.                     var d = c * 4 * a;
  1961.                     b[d + 0 * a + 0] = 1, b[d + 0 * a + 1] = 1, b[d + 1 * a + 0] = -1, b[d + 1 * a + 1] = 1, b[d + 2 * a + 0] = 1, b[d + 2 * a + 1] = -1, b[d + 3 * a + 0] = -1, b[d + 3 * a + 1] = -1;
  1962.                     for (var e = 0; e < 4; ++e) {
  1963.                         var f = d + e * a;
  1964.                         b[f + 2] = this.sprites[c].position[0], b[f + 3] = this.sprites[c].position[1], b[f + 4] = this.sprites[c].position[2], b[f + 5] = this.sprites[c].minScale, b[f + 6] = this.sprites[c].maxScale, b[f + 7] = this.sprites[c].blinkRate, b[f + 8] = this.sprites[c].blinkPhase, b[f + 9] = this.sprites[c].color[0], b[f + 10] = this.sprites[c].color[1], b[f + 11] = this.sprites[c].color[2]
  1965.                     }
  1966.                 }
  1967.                 this.vertexBuffer = device.gl.createBuffer(), device.gl.bindBuffer(device.gl.ARRAY_BUFFER, this.vertexBuffer), device.gl.bufferData(device.gl.ARRAY_BUFFER, b, device.gl.STATIC_DRAW), device.gl.bindBuffer(device.gl.ARRAY_BUFFER, null);
  1968.                 var g = new Uint16Array(this.sprites.length * 6);
  1969.                 for (var c = 0; c < this.sprites.length; ++c) {
  1970.                     var d = c * 6,
  1971.                         f = c * 4;
  1972.                     g[d] = f, g[d + 1] = f + 1, g[d + 2] = f + 2, g[d + 3] = f + 2, g[d + 4] = f + 1, g[d + 5] = f + 3
  1973.                 }
  1974.                 this.indexBuffer = device.gl.createBuffer(), device.gl.bindBuffer(device.gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer), device.gl.bufferData(device.gl.ELEMENT_ARRAY_BUFFER, g, device.gl.STATIC_DRAW), device.gl.bindBuffer(device.gl.ELEMENT_ARRAY_BUFFER, null), this.indexBuffer.count = this.sprites.length * 6
  1975.             };
  1976.  
  1977.             function EveSpriteSetBatch() {
  1978.                 this._super.constructor.call(this), this.spriteSet = null
  1979.             }
  1980.             EveSpriteSetBatch.prototype.Commit = function (a) {
  1981.                 this.spriteSet.Render(a)
  1982.             }, Inherit(EveSpriteSetBatch, Tw2RenderBatch), EveSpriteSet.prototype.GetBatches = function (a, b, c) {
  1983.                 if (a == device.RM_ADDITIVE) {
  1984.                     var d = new EveSpriteSetBatch;
  1985.                     d.renderMode = device.RM_ADDITIVE, d.spriteSet = this, d.perObjectData = c, b.Commit(d)
  1986.                 }
  1987.             }, EveSpriteSet.prototype.Render = function (a) {
  1988.                 var b = typeof a == "undefined" ? this.effect : a;
  1989.                 if ( !! b && !! this.vertexBuffer) {
  1990.                     var c = b.GetEffectRes();
  1991.                     if (!c.IsGood()) return;
  1992.                     var d = b.GetActiveTechnique();
  1993.                     device.SetStandardStates(device.RM_ADDITIVE), device.gl.enableVertexAttribArray(0), device.gl.enableVertexAttribArray(1), device.gl.enableVertexAttribArray(2), device.gl.bindBuffer(device.gl.ARRAY_BUFFER, this.vertexBuffer), device.gl.vertexAttribPointer(0, 4, device.gl.FLOAT, !1, 48, 0), device.gl.vertexAttribPointer(1, 4, device.gl.FLOAT, !1, 48, 16), device.gl.vertexAttribPointer(2, 4, device.gl.FLOAT, !1, 48, 32), device.gl.bindBuffer(device.gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
  1994.                     for (var e = 0; e < b.GetPassCount(d); ++e) b.ApplyPass(d, e), device.gl.drawElements(device.gl.TRIANGLES, this.indexBuffer.count, device.gl.UNSIGNED_SHORT, 0)
  1995.                 }
  1996.             }, EveSpriteSet.prototype.Update = function (a) {
  1997.                 this._time += a
  1998.             }, EveSpriteSet.prototype.Clear = function () {
  1999.                 this.sprites = []
  2000.             }, EveSpriteSet.prototype.Add = function (a, b, c, d, e, f, g) {
  2001.                 var h = new EveSpriteSetItem;
  2002.                 h.position = vec3.create(a), h.blinkRate = b, h.blinkPhase = c, h.minScale = d, h.maxScale = e, h.falloff = f, h.color = g, this.sprites[this.sprites.length] = h
  2003.             };
  2004.  
  2005.             function EveSpriteSetItem() {
  2006.                 this
  2007.                     .name = "", this.position = vec3.create([0, 0, 0]), this.blinkRate = 0, this.blinkPhase = 0, this.minScale = 1, this.maxScale = 1, this.falloff = 0, this.color = vec3.create([0, 0, 0])
  2008.             }
  2009.  
  2010.             function EveTransform() {
  2011.                 this.NONE = 0, this.BILLBOARD = 1, this.TRANSLATE_WITH_CAMERA = 2, this.LOOK_AT_CAMERA = 3, this.SIMPLE_HALO = 4, this.EVE_CAMERA_ROTATION_ALIGNED = 100, this.EVE_BOOSTER = 101, this.EVE_SIMPLE_HALO = 102, this.EVE_CAMERA_ROTATION = 103, this.name = "", this.display = !0, this.useDistanceBasedScale = !1, this.modifier = this.NONE, this.scaling = vec3.create([1, 1, 1]), this.translation = vec3.create([0, 0, 0]), this.rotation = [0, 0, 0, 1], this.localTransform = mat4.create(), this.rotationTransform = mat4.create(), mat4.identity(this.localTransform), this.worldTransform = mat4.create(), mat4.identity(this.worldTransform), this.sortValueMultiplier = 1, this.distanceBasedScaleArg1 = .2, this.distanceBasedScaleArg2 = .63, this.children = [], this.mesh = null
  2012.             }
  2013.             EveTransform.prototype.Initialize = function () {
  2014.                 mat4.identity(this.localTransform), mat4.translate(this.localTransform, this.translation), mat4.transpose(quat4.toMat4(this.rotation, this.rotationTransform)), mat4.multiply(this.localTransform, this.rotationTransform, this.localTransform), mat4.scale(this.localTransform, this.scaling)
  2015.             }, EveTransform.prototype.GetBatches = function (a, b) {
  2016.                 if ( !! this.display) {
  2017.                     if (this.mesh != null) {
  2018.                         var c = new Tw2PerObjectData;
  2019.                         c.world = this.worldTransform, this.mesh.GetBatches(a, b, c)
  2020.                     }
  2021.                     for (var d = 0; d < this.children.length; ++d) this.children[d].GetBatches(a, b)
  2022.                 }
  2023.             }, EveTransform.prototype.Update = function (a) {
  2024.                 for (var b = 0; b < this.children.length; ++b) this.children[b].Update(a)
  2025.             }, mat4.multiply3x3 = function (a, b, c) {
  2026.                 c || (c = b);
  2027.                 var d = b[0],
  2028.                     e = b[1];
  2029.                 b = b[2], c[0] = a[0] * d + a[4] * e + a[8] * b, c[1] = a[1] * d + a[5] * e + a[9] * b, c[2] = a[2] * d + a[6] * e + a[10] * b;
  2030.                 return c
  2031.             }, EveTransform.prototype.UpdateViewDependentData = function (a) {
  2032.                 switch (this.modifier) {
  2033.                 case this.BILLBOARD:
  2034.                 case this.SIMPLE_HALO:
  2035.                     mat4.multiply(a, this.localTransform, this.worldTransform);
  2036.                     var b = vec3.create();
  2037.                     vec3.set(this.scaling, b);
  2038.                     var c = vec3.length([a[0], a[1], a[2]]),
  2039.                         d = vec3.length([a[4], a[5], a[6]]),
  2040.                         e = vec3.length([a[8], a[9], a[10]]);
  2041.                     b[0] *= c, b[1] *= d, b[2] *= e;
  2042.                     if (this.modifier == this.SIMPLE_HALO) {
  2043.                         var f = vec3.create([this.worldTransform[12], this.worldTransform[13], this.worldTransform[14]]),
  2044.                             g = device.GetEyePosition(),
  2045.                             h = vec3.create();
  2046.                         vec3.subtract(g, f, h);
  2047.                         var i = vec3.create(),
  2048.                             j = vec3.dot(vec3.normalize(h), vec3.normalize(vec3.create([this.worldTransform[8], this.worldTransform[9], this.worldTransform[10]]), i));
  2049.                         j < 0 && (j = 0)
  2050.                     }
  2051.                     vec3.scale(b, j * j);
  2052.                     var k = mat4.create();
  2053.                     mat4.inverse(device.view, k), this.worldTransform[0] = k[0] * b, this.worldTransform[1] = k[1] * b, this.worldTransform[2] = k[2] * b, this.worldTransform[4] = k[4] * b, this.worldTransform[5] = k[5] * b, this.worldTransform[6] = k[6] * b, this.worldTransform[8] = k[8] * b, this.worldTransform[9] = k[9] * b, this.worldTransform[10] = k[10] * b;
  2054.                     break;
  2055.                 case this.EVE_CAMERA_ROTATION_ALIGNED:
  2056.                 case this.EVE_SIMPLE_HALO:
  2057.                     mat4.translate(a, this.translation, this.worldTransform);
  2058.                     var f = vec3.create([this.worldTransform[12], this.worldTransform[13], this.worldTransform[14]]),
  2059.                         g = device.GetEyePosition(),
  2060.                         h = vec3.create();
  2061.                     vec3.subtract(g, f, h);
  2062.                     var l = mat4.create();
  2063.                     mat4.transpose(a, l);
  2064.                     var m = vec3.create(h);
  2065.                     mat4.multiply3x3(l, m);
  2066.                     var c = vec3.length([a[0], a[1], a[2]]);
  2067.                     m[0] /= c;
  2068.                     var d = vec3.length([a[4], a[5], a[6]]);
  2069.                     m[1] /= d;
  2070.                     var e = vec3.length([a[8], a[9], a[10]]);
  2071.                     m[2] /= e;
  2072.                     var n = vec3.length(m);
  2073.                     vec3.normalize(m);
  2074.                     var o = vec3.create([device.view[0], device.view[4], device.view[8]]);
  2075.                     mat4.multiply3x3(l, o), vec3.normalize(o);
  2076.                     var p = vec3.create();
  2077.                     vec3.cross(m, o, p), vec3.normalize(p);
  2078.                     var q = mat4.create();
  2079.                     vec3.cross(p, m, o), q[0] = o[0], q[1] = o[1], q[2] = o[2], q[4] = p[0], q[5] = p[1], q[6] = p[2], q[8] = m[0], q[9] = m[1], q[10] = m[2], q[15] = 1, mat4.multiply(q, this.rotationTransform, q);
  2080.                     if (this.modifier == this.EVE_SIMPLE_HALO) {
  2081.                         var r = vec3.create();
  2082.                         vec3.normalize(vec3.create([this.worldTransform[8], this.worldTransform[9], this.worldTransform[10]]), r);
  2083.                         var s = vec3.create();
  2084.                         vec3.normalize(h, s);
  2085.                         var j = -vec3.dot(s, r);
  2086.                         j < 0 && (j = 0), mat4.multiply(this.worldTransform, q, this.worldTransform), mat4.scale(this.worldTransform, [this.scaling[0] * j, this.scaling[1] * j, this.scaling[2] * j])
  2087.                     } else mat4.scale(this.worldTransform, this.scaling), mat4.multiply(this.worldTransform, q, this.worldTransform);
  2088.                     break;
  2089.                 default:
  2090.                     mat4.multiply(a, this.localTransform, this.worldTransform)
  2091.                 }
  2092.                 for (var t = 0; t < this.children.length; ++t) this.children[t].UpdateViewDependentData(this.worldTransform)
  2093.             };
  2094.  
  2095.             function EveTurretData() {
  2096.                 this.visible = !0, this.localTransform = mat4.create()
  2097.             }
  2098.  
  2099.             function EveTurretSet() {
  2100.                 this.name = "", this.boundingSphere = [0, 0, 0, 0], this.bottomClipHeight = 0, this.locatorName = "", this.turretEffect = null, this.geometryResPath = "", this.sysBoneHeight = 0, this.firingEffectResPath = "", this.firingEffect = null, this.display = !0, this.geometryResource = null, this.animation = new Tw2AnimationController, this.turrets = [], this.STATE_INACTIVE = 0, this.STATE_IDLE = 1, this.STATE_FIRING = 2, this.STATE_PACKING = 3, this.STATE_UNPACKING = 4, this.state = this.STATE_IDLE, this.targetPosition = vec3.create()
  2101.             }
  2102.             EveTurretSet.prototype.Initialize = function () {
  2103.                 this.geometryResPath != "" && (this.geometryResource = resMan.GetResource(this.geometryResPath), this.animation.SetGeometryResource(this.geometryResource), this.geometryResource && this.geometryResource.RegisterNotification(this))
  2104.             }, EveTurretSet.prototype.RebuildCachedData = function (a) {
  2105.                 switch (this.state) {
  2106.                 case this.STATE_INACTIVE:
  2107.                     this.animation.PlayAnimation("Inactive", !0);
  2108.                     break;
  2109.                 case this.STATE_IDLE:
  2110.                     this.animation.PlayAnimation("Active", !0);
  2111.                     break;
  2112.                 case this.STATE_FIRING:
  2113.                     this.animation.PlayAnimation("Fire", !0);
  2114.                     break;
  2115.                 case this.STATE_PACKING:
  2116.                     this.EnterStateIdle();
  2117.                     break;
  2118.                 case this.STATE_UNPACKING:
  2119.                     this.EnterStateDeactive()
  2120.                 }
  2121.             }, EveTurretSet.prototype.SetLocalTransform = function (a, b) {
  2122.                 if (a >= this.turrets.length) {
  2123.                     var c = new EveTurretData;
  2124.                     c.localTransform = b, this.turrets[a] = c
  2125.                 } else this.turrets[a].localTransform = b
  2126.             }, EveTurretSet.prototype.GetBatches = function (a, b, c) {
  2127.                 if (this.geometryResource == null || !this.display) return !1;
  2128.                 if (a == device.RM_OPAQUE) {
  2129.                     var d = new Tw2ForwardingRenderBatch;
  2130.                     d.perObjectData = c, d.geometryProvider = this, b.Commit(d)
  2131.                 }
  2132.                 this.firingEffect && this.firingEffect.GetBatches(a, b, c);
  2133.                 return !0
  2134.             }, EveTurretSet.prototype.Update = function (a) {
  2135.                 this.animation.Update(a);
  2136.                 if (this.firingEffect) {
  2137.                     for (var b = 0; b < this.turrets.length; ++b) this.firingEffect.SetMuzzlePosition(b, [this.turrets[b].localTransform[12], this.turrets[b].localTransform[13], this.turrets[b].localTransform[14]]), this.firingEffect.SetTargetPosition(this.targetPosition);
  2138.                     this.firingEffect.Update(a)
  2139.                 }
  2140.             }, EveTurretSet.prototype.Render = function (a, b) {
  2141.                 var c = typeof b == "undefined" ? this.turretEffect : b,
  2142.                     d = device.perObjectData,
  2143.                     e = d ? d.world : mat4.identity(mat4.create());
  2144.                 for (var f = 0; f < this.turrets.length; ++f) {
  2145.                     var g = this.animation.GetBoneMatrixes(0),
  2146.                         h = mat4.create();
  2147.                     mat4.multiply(e, this.turrets[f].localTransform, h), device.perObjectData = new Tw2SkinnedPerObjectData(g, h, d);
  2148.                     var i = quat4.create([0, 1, 0, -this.bottomClipHeight]);
  2149.                     mat4.multiplyVec4(mat4.transpose(mat4.inverse(h, mat4.create())), i), device.perObjectData.RegisterVariable("TurretClipPlane", i), this.geometryResource.RenderAreas(0, 0, 1, c)
  2150.                 }
  2151.             }, EveTurretSet.prototype.EnterStateDeactive = function () {
  2152.                 if (this.state != this.STATE_INACTIVE && this.state != this.STATE_PACKING) {
  2153.                     var a = this;
  2154.                     this.animation.StopAllAnimations(), this.animation.PlayAnimation("Pack", !1, function () {
  2155.                         a.state = a.STATE_INACTIVE, a.animation.PlayAnimation("Inactive", !0)
  2156.                     }), this.state = this.STATE_PACKING
  2157.                 }
  2158.             }, EveTurretSet.prototype.EnterStateIdle = function () {
  2159.                 if (this.state != this.STATE_IDLE && this.state != this.STATE_UNPACKING) {
  2160.                     var a = this;
  2161.                     this.animation.StopAllAnimations(), this.state == this.STATE_FIRING ? a.animation.PlayAnimation("Active", !0) : this.animation.PlayAnimation("Deploy", !1, function () {
  2162.                         a.state = a.STATE_IDLE, a.animation.PlayAnimation("Active", !0)
  2163.                     }), this.state = this.STATE_UNPACKING
  2164.                 }
  2165.             }, EveTurretSet.prototype.EnterStateFiring = function () {
  2166.                 if (this.state != this.STATE_FIRING) {
  2167.                     var a = this;
  2168.                     this.animation.StopAllAnimations(), this.state == this.STATE_INACTIVE ? (this.animation.PlayAnimation("Deploy", !1, function () {
  2169.                         a.state = a.STATE_FIRING, a.Fire(), a.animation.PlayAnimation("Fire", !0, function () {
  2170.                             a.Fire()
  2171.                         })
  2172.                     }), this.state = this.STATE_UNPACKING) : (a.state = a.STATE_FIRING, a.Fire(), a.animation.PlayAnimation("Fire", !0, function () {
  2173.                         a.Fire()
  2174.                     }))
  2175.                 }
  2176.             }, EveTurretSet.prototype.ForceStateDeactive = function () {
  2177.                 this.state != this.STATE_INACTIVE && (this.animation.StopAllAnimations(), this.animation.PlayAnimation("Inactive", !0), this.state = this.STATE_INACTIVE)
  2178.             }, EveTurretSet.prototype.ForceStateIdle = function () {
  2179.                 this.state != this.STATE_IDLE && (this.animation.StopAllAnimations(), this.animation.PlayAnimation("Active", !0), this.state = this.STATE_IDLE)
  2180.             }, EveTurretSet.prototype.Fire = function () {
  2181.                 this.firingEffect && this.firingEffect.Fire()
  2182.             };
  2183.  
  2184.             function EveSpaceObjectDecal() {
  2185.                 this.display = !0, this.decalEffect = null, this.name = "", this.decalGeometryPath = "", this.decalIndex = 0, this.decalGeometry = null, this.position = vec3.create(), this.rotation = quat4.create(), this.scaling = vec3.create(), this.decalMatrix = mat4.create(), this.invDecalMatrix = mat4.create(), this.parentGeometry = null, variableStore.RegisterType("u_DecalMatrix", Tw2MatrixParameter), variableStore.RegisterType("u_InvDecalMatrix", Tw2MatrixParameter)
  2186.             }
  2187.             EveSpaceObjectDecal.prototype.Initialize = function () {
  2188.                 this.decalGeometryPath != "" && (this.decalGeometry = resMan.GetResource(this.decalGeometryPath)), mat4.scale(mat4.transpose(quat4.toMat4(this.rotation, this.decalMatrix)), this.scaling), this.decalMatrix[12] = this.position[0], this.decalMatrix[13] = this.position[1], this.decalMatrix[14] = this.position[2], mat4.inverse(this.decalMatrix, this.invDecalMatrix)
  2189.             }, EveSpaceObjectDecal.prototype.SetParentGeometry = function (a) {
  2190.                 this.parentGeometry = a
  2191.             }, EveSpaceObjectDecal.prototype.GetBatches = function (a, b, c) {
  2192.                 if (a == device.RM_DECAL && this.display && this.decalEffect && this.parentGeometry && this.parentGeometry.IsGood() && this.decalGeometry && this.decalGeometry.IsGood()) {
  2193.                     var d = new Tw2ForwardingRenderBatch;
  2194.                     d.perObjectData = c, d.geometryProvider = this, d.renderMode = device.RM_DECAL, b.Commit(d)
  2195.                 }
  2196.             }, EveSpaceObjectDecal.prototype.Render = function (a, b) {
  2197.                 var c = this.parentGeometry.meshes[0].indexes,
  2198.                     d = this.parentGeometry.meshes[0].areas[0].start,
  2199.                     e = this.parentGeometry.meshes[0].areas[0].count;
  2200.                 mat4.set(this.decalMatrix, variableStore._variables.u_DecalMatrix.value), mat4.set(this.invDecalMatrix, variableStore._variables.u_InvDecalMatrix.value), this.parentGeometry.meshes[0].indexes = this.decalGeometry.meshes[this.decalIndex].indexes, this.parentGeometry.meshes[0].areas[0].start = this.decalGeometry.meshes[this.decalIndex].areas[0].start, this.parentGeometry.meshes[0].areas[0].count = this.decalGeometry.meshes[this.decalIndex].areas[0].count, this.parentGeometry.RenderAreas(0, 0, 1, b ? b : this.decalEffect), this.parentGeometry.meshes[0].indexes = c, this.parentGeometry.meshes[0].areas[0].start = d, this.parentGeometry.meshes[0].areas[0].count = e
  2201.             };
  2202.  
  2203.             function EveShip() {
  2204.                 this.name = "", this.mesh = null, this.spriteSets = [], this.boundingSphereCenter = vec3.create(), this.boundingSphereRadius = 0, this.boosterGain = 1, this.boosters = null, this.locators = [], this.turretSets = [], this.decals = [], this.transform = mat4.create(), mat4.identity(this.transform), this.children = [], this._turretSetsLocatorInfo = [], this.animation = new Tw2AnimationController
  2205.             }
  2206.  
  2207.             function EveTurretSetLocatorInfo() {
  2208.                 this.isJoint = !1, this.locatorTransforms = []
  2209.             }
  2210.             EveShip.prototype.Initialize = function () {
  2211.                 if (this.mesh) {
  2212.                     this.animation.SetGeometryResource(this.mesh.geometryResource);
  2213.                     for (var a = 0; a < this.decals.length; ++a) this.decals[a].SetParentGeometry(this.mesh.geometryResource)
  2214.                 }
  2215.             }, EveShip.prototype.GetBatches = function (a, b) {
  2216.                 for (var c = 0; c < this.children.length; ++c) this.children[c].UpdateViewDependentData(this.transform);
  2217.                 var d = null;
  2218.                 this.animation.animations.length ? (d = new Tw2SkinnedPerObjectData(this.animation.GetBoneMatrixes(0), this.transform), d.world = this.transform) : (d = new Tw2PerObjectData, d.world = this.transform), d.RegisterVariableWithType("u_BoosterGain", this.boosterGain, Tw2FloatParameter), this.mesh != null && this.mesh.GetBatches(a, b, d);
  2219.                 for (var c = 0; c < this.spriteSets.length; ++c) this.spriteSets[c].GetBatches(a, b, d);
  2220.                 for (var c = 0; c < this.children.length; ++c) this.children[c].GetBatches(a, b);
  2221.                 for (var c = 0; c < this.turretSets.length; ++c) this.turretSets[c].GetBatches(a, b, d);
  2222.                 for (var c = 0; c < this.decals.length; ++c) this.decals[c].GetBatches(a, b, d);
  2223.                 this.boosters && this.boosters.GetBatches(a, b, d)
  2224.             }, EveShip.prototype.Update = function (a) {
  2225.                 for (var b = 0; b < this.spriteSets.length; ++b) this.spriteSets[b].Update(a);
  2226.                 this.boosters && (this.boosters.rebuildPending && this.RebuildBoosterSet(), this.boosters.Update(a, this.transform));
  2227.                 for (var b = 0; b < this.children.length; ++b) this.children[b].Update(a);
  2228.                 this.animation.Update(a);
  2229.                 for (var b = 0; b < this.turretSets.length; ++b) {
  2230.                     if (b < this._turretSetsLocatorInfo.length && this._turretSetsLocatorInfo[b].isJoint)
  2231.                         for (var c = 0; c < this._turretSetsLocatorInfo[b].locatorTransforms.length; ++c) this.turretSets[b].SetLocalTransform(c, this._turretSetsLocatorInfo[b].locatorTransforms[c]);
  2232.                     this.turretSets[b].Update(a)
  2233.                 }
  2234.             }, EveShip.prototype.RebuildBoosterSet = function () {
  2235.                 if ( !! this.boosters) {
  2236.                     this.boosters.Clear();
  2237.                     var a = "locator_booster";
  2238.                     for (var b = 0; b < this.locators.length; ++b) this.locators[b].name.substr(0, a.length) == a && this.boosters.Add(this.locators[b].transform);
  2239.                     this.boosters.Rebuild()
  2240.                 }
  2241.             }, EveShip.prototype.RebuildTurretPositions = function () {
  2242.                 this._turretSetsLocatorInfo = [];
  2243.                 for (var a = 0; a < this.turretSets.length; ++a) {
  2244.                     var b = this.turretSets[a].locatorName,
  2245.                         c = this.GetLocatorCount(b),
  2246.                         d = new EveTurretSetLocatorInfo;
  2247.                     for (var e = 0; e < c; ++e) {
  2248.                         var f = b + String.fromCharCode("a".charCodeAt(0) + e),
  2249.                             g = this.FindLocatorJointByName(f);
  2250.                         g != null ? d.isJoint = !0 : g = this.FindLocatorTransformByName(f), g != null && (this.turretSets[a].SetLocalTransform(e, g), d.locatorTransforms[d.locatorTransforms.length] = g)
  2251.                     }
  2252.                     this._turretSetsLocatorInfo[this._turretSetsLocatorInfo.length] = d
  2253.                 }
  2254.             }, EveShip.prototype.GetLocatorCount = function (a) {
  2255.                 var b = 0;
  2256.                 for (var c = 0; c < this.locators.length; ++c) this.locators[c].name.substr(0, a.length) == a && ++b;
  2257.                 return b
  2258.             }, EveShip.prototype.FindLocatorJointByName = function (a) {
  2259.                 var b = this.animation.FindModelForMesh(0);
  2260.                 if (b != null)
  2261.                     for (var c = 0; c < b.bones.length; ++c)
  2262.                         if (b.bones[c].boneRes.name == a) return b.bones[c].worldTransform;
  2263.                 return null
  2264.             }, EveShip.prototype.FindLocatorTransformByName = function (a) {
  2265.                 for (var b = 0; b < this.locators.length; ++b)
  2266.                     if (this.locators[b].name == a) return this.locators[b].transform;
  2267.                 return null
  2268.             }, EveShip.prototype.RenderDebugInfo = function (a) {
  2269.                 this.animation.RenderDebugInfo(a)
  2270.             };
  2271.  
  2272.             function EveSpaceScene() {
  2273.                 this.objects = [], this.sky = null, this.envMap1ResPath = "", this.envMap2ResPath = "", this.envMap3ResPath = "", this.envMap1Res = null, this.envMap2Res = null, this.envMap3Res = null, this._envMap1Handle = variableStore.RegisterVariable("EnvMap1", ""), this._envMap2Handle = variableStore.RegisterVariable("EnvMap2", ""), this._envMap3Handle = variableStore.RegisterVariable("EnvMap3", ""), variableStore.RegisterType("u_sunDirection", Tw2Vector3Parameter), variableStore.RegisterType("u_sunColor", Tw2Vector3Parameter), variableStore.RegisterType("u_ambientColor", Tw2Vector3Parameter), this.renderDebugInfo = !1, this._debugHelper = null, this._batches = new Tw2BatchAccumulator, this.sunDirection = vec3.create([1, 1, 1]), this.sunColor = vec3.create([1, 1, 1]), this.ambientColor = vec3.create([.1, .1, .1])
  2274.             }
  2275.             EveSpaceScene.prototype.Initialize = function () {
  2276.                 this.envMap1ResPath != "" && (this.envMap1Res = resMan.GetResource(this.envMap1ResPath)), this.envMap2ResPath != "" && (this.envMap2Res = resMan.GetResource(this.envMap2ResPath)), this.envMap3ResPath != "" && (this.envMap3Res = resMan.GetResource(this.envMap3ResPath))
  2277.             }, EveSpaceScene.prototype.SetEnvMapPath = function (a, b) {
  2278.                 switch (a) {
  2279.                 case 0:
  2280.                     this.envMap1ResPath = b, this.envMap1ResPath != "" ? this.envMap1Res = resMan.GetResource(this.envMap1ResPath) : this.envMap1Res = null;
  2281.                     break;
  2282.                 case 1:
  2283.                     this.envMap2ResPath = b, this.envMap2ResPath != "" ? this.envMap2Res = resMan.GetResource(this.envMap2ResPath) : this.envMap2Res = null;
  2284.                     break;
  2285.                 case 2:
  2286.                     this.envMap3ResPath = b, this.envMap3ResPath != "" ? this.envMap3Res = resMan.GetResource(this.envMap3ResPath) : this.envMap3Res = null
  2287.                 }
  2288.             }, EveSpaceScene.prototype.RenderBatches = function (a) {
  2289.                 for (var b = 0; b < this.objects.length; ++b) typeof this.objects[b].GetBatches != "undefined" && this.objects[b].GetBatches(a, this._batches)
  2290.             }, EveSpaceScene.prototype.Render = function () {
  2291.                 var a = vec3.create(this.sunDirection);
  2292.                 vec3.normalize(a), variableStore._variables.u_sunDirection.value.set(a), variableStore._variables.u_sunColor.value.set(this.sunColor), variableStore._variables.u_ambientColor.value.set(this.ambientColor), this._envMap1Handle.textureRes = this.envMap1Res, this._envMap2Handle.textureRes = this.envMap2Res, this._envMap3Handle.textureRes = this.envMap3Res, this.sky && this.sky.Render();
  2293.                 for (var b = 0; b < this.objects.length; ++b) typeof this.objects[b].ViewDependentUpdate != "undefined" && this.objects[b].ViewDependentUpdate();
  2294.                 this._batches.Clear(), this.RenderBatches(device.RM_OPAQUE), this.RenderBatches(device.RM_DECAL), this.RenderBatches(device.RM_TRANSPARENT), this.RenderBatches(device.RM_ADDITIVE), this._batches.Render();
  2295.                 if (this.renderDebugInfo) {
  2296.                     this._debugHelper == null && (this._debugHelper = new Tw2DebugRenderer);
  2297.                     for (var b = 0; b < this.objects.length; ++b) typeof this.objects[b].RenderDebugInfo != "undefined" && this.objects[b].RenderDebugInfo(this._debugHelper);
  2298.                     this._debugHelper.Render()
  2299.                 }
  2300.             }, EveSpaceScene.prototype.Update = function (a) {
  2301.                 for (var b = 0; b < this.objects.length; ++b) typeof this.objects[b].Update != "undefined" && this.objects[b].Update(a)
  2302.             }
  2303.         }
  2304.         TestCamera.prototype.GetView = function () {
  2305.             var a = mat4.create();
  2306.             mat4.identity(a), mat4.translate(a, [0, 0, -this.currDistance]), mat4.rotateX(a, -this.rotationX), mat4.rotateY(a, this.rotationY), ship != null && (mat4.rotateX(ship.transform, Math.cos(pitchWave += .001) / 15e3 - Math.cos(pitchSmallWave += .005) / 2e4), mat4.rotateZ(ship.transform, Math.cos(rollWave += .001) / 15e3 - Math.cos(rollSmallWave += .005) / 2e4));
  2307.             return a
  2308.         }, TestCamera.prototype.GetProjection = function () {
  2309.             var a = mat4.create();
  2310.             mat4.perspective(this.fov, device.gl.viewportWidth / device.gl.viewportHeight, 1, this.currDistance * 2, a);
  2311.             return a
  2312.         }, TestCamera.prototype.Update = function (a) {
  2313.             if (this.currDistance != this.distance) {
  2314.                 var b = this.currDistance - this.distance;
  2315.                 this.currDistance -= b / 4
  2316.             }
  2317.             ref.phiDiff != 0 && (ref.cameraChanged = !0, ref.phiDiff *= .82, ref.phi -= ref.phiDiff, ref.phiDiff < .001 && ref.phiDiff > -0.001 && (ref.phiDiff = 0)), ref.thetaDiff != 0 && (ref.cameraChanged = !0, ref.thetaDiff *= .82, ref.theta -= ref.thetaDiff, ref.thetaDiff < .001 && ref.thetaDiff > -0.001 && (ref.thetaDiff = 0)), doAnimation ? this.rotationY += .005 : (this.rotationX += ref.phiDiff, this.rotationY += ref.thetaDiff, this.rotationX > 1.6 ? this.rotationX = 1.6 : this.rotationX < -1.6 && (this.rotationX = -1.6))
  2318.         }, TestCamera.prototype.AddRadius = function (a) {
  2319.             this.distance -= a * ship.boundingSphereRadius / 300, this.distance < minZoomDistance ? this.distance = minZoomDistance : this.distance > minZoomDistance * 10 && (this.distance = minZoomDistance * 10)
  2320.         }, TestCamera.prototype.onDocumentMouseWheel = function (a, b) {
  2321.             a.preventDefault(), a.returnValue = !1, a.cancelBubble = !0, isNaN(a.wheelDeltaY) || this.AddRadius(a.wheelDeltaY)
  2322.         }, TestCamera.prototype.handleWheel = function (a, b) {
  2323.             a.preventDefault(), a.returnValue = !1, a.cancelBubble = !0;
  2324.             var c = 0;
  2325.             a || (a = window.event), a.wheelDelta ? c = a.wheelDelta : a.detail && (c = a.detail), c < 120 && c > 0 ? c = -120 : c < 0 && c > -120 && (c = 120), this.AddRadius(c)
  2326.         }, CCPShipViewer.prototype.afterShipLoaded = function () {
  2327.             loadingShip = !1;
  2328.             var a = document.getElementById(ref.containerId);
  2329.             if (a != undefined) {
  2330.                 var b = document.getElementById("Loading_" + ref.containerId);
  2331.                 b != undefined && a.removeChild(b)
  2332.             }
  2333.             settings.afterShipChanged && settings.afterShipChanged(ref.selectedShipFact)
  2334.         }, CCPShipViewer.prototype.onFallbackImageError = function () {
  2335.             var a = document.getElementById("fallbackImage");
  2336.             a != undefined && document.getElementById(ref.containerId).removeChild(a), ref.afterShipLoaded()
  2337.         }, CCPShipViewer.prototype.onFallbackImageLoaded = function (a) {
  2338.             var b = document.getElementById("fallbackImage");
  2339.             b != undefined && document.getElementById(ref.containerId).removeChild(b), document.getElementById(ref.containerId).appendChild(a), ref.afterShipLoaded()
  2340.         };
  2341.         var modules = ["defensive", "engineering", "offensive", "propulsion"];
  2342.         CCPShipViewer.prototype.selectShip = function (a) {
  2343.             SelectShip(a)
  2344.         }, CCPShipViewer.prototype.getShipList = function () {
  2345.             return CCPShipFactList
  2346.         }, CCPShipViewer.prototype.getResource = function (a) {
  2347.             ShipViewerLoadingResources = !0, ref.pendingResources++, ref.JSONP.get(a, {}, null)
  2348.         }, CCPShipViewer.prototype.onResourceLoaded = function () {
  2349.             ref.pendingResources--;
  2350.             if (ref.pendingResources == 0) {
  2351.                 ShipViewerLoadingResources = !1;
  2352.                 for (var a = 0; a < ShipViewerWaitingList.length; a++) ShipViewerWaitingList[a].resourcesLoaded || ShipViewerWaitingList[a].onAllResourcesLoaded();
  2353.                 ShipViewerWaitingList = []
  2354.             }
  2355.         }, CCPShipViewer.prototype.onAllResourcesLoaded = function () {
  2356.             ref.resourcesLoaded = !0, ref.container.style.width = ref.width + "px", ref.container.clientHeight == 0 && (ref.container.style.height = ref.height + "px");
  2357.             if (ref.isWebGL) {
  2358.                 var a = document.createElement("canvas");
  2359.                 a.width = ref.width, a.height = ref.height, a.id = "canvas_" + ref.containerId, camera = new TestCamera(a);
  2360.                 if (showFPS) {
  2361.                     var b = document.createElement("div");
  2362.                     b.style.height = "22px", b.style.color = "#FFF", b.style.background = "#000", b.id = ref.containerId + "_FPS", ref.container.appendChild(b)
  2363.                 }
  2364.                 ref.container.appendChild(a), ref.container.addEventListener("mousedown", ref.onMouseDown, !1), device.CreateDevice(a), device.mipLevelSkipCount = quality;
  2365.                 var c = vec3.create([1, 1, 1]);
  2366.                 vec3.normalize(c), variableStore._variables.u_sunDirection = new Tw2Vector3Parameter("u_sunDirection", c), variableStore._variables.u_sunColor = new Tw2Vector3Parameter("u_sunColor", vec3.create([1, 1, 1])), variableStore._variables.u_ambientColor = new Tw2Vector3Parameter("u_ambientColor", vec3.create([.1, .1, .1])), scene = new EveSpaceScene, postprocess = new Tw2PostProcess, device.Schedule(Render), tick()
  2367.             }
  2368.             var d = document.getElementById(ref.containerId);
  2369.             d != undefined && d.removeChild(document.getElementById("Loading_" + ref.containerId));
  2370.             if (settings.onLoaded) {
  2371.                 var e = ref.getRenderType();
  2372.                 settings.onLoaded({
  2373.                     renderType: e
  2374.                 })
  2375.             }
  2376.             defaultShip != "" && SelectShip(defaultShip)
  2377.         }, CCPShipViewer.prototype.getRenderType = function () {
  2378.             return ref.isWebGL ? "webgl" : "static image"
  2379.         }, CCPShipViewer.prototype.MaximizeCanvas = function () {
  2380.             var a = document.getElementById("canvas_" + ref.containerId);
  2381.             restoreIndex = a.style.zIndex || 0, restorePosition = a.style.position, restoreLeft = a.style.left, restoreTop = a.style.top, restoreWidth = a.style.width || a.clientWidth, restoreHeight = a.style.height || a.clientHeight, a.style.position = "fixed", a.style.left = "0px", a.style.top = "0", a.style.width = "100%", a.style.height = "100%", a.style.zIndex = 200, a.width = a.clientWidth, a.height = a.clientHeight, device.gl.viewportWidth = a.clientWidth, device.gl.viewportHeight = a.clientHeight, window.addEventListener("resize", ref.onCanvasResize, !1)
  2382.         }, CCPShipViewer.prototype.RestoreCanvas = function () {
  2383.             var a = document.getElementById("canvas_" + ref.containerId);
  2384.             a.style.zIndex = restoreIndex, a.style.position = restorePosition, a.style.left = restoreLeft, a.style.top = restoreTop, a.style.width = restoreWidth, a.style.height = restoreHeight, a.width = a.clientWidth, a.height = a.clientHeight, device.gl.viewportWidth = a.clientWidth, device.gl.viewportHeight = a.clientHeight, window.removeEventListener("resize", ref.onCanvasResize, !1)
  2385.         }, CCPShipViewer.prototype.onCanvasResize = function () {
  2386.             var a = document.getElementById("canvas_" + ref.containerId);
  2387.             a.width = a.clientWidth, a.height = a.clientHeight, device.gl.viewportWidth = a.clientWidth, device.gl.viewportHeight = a.clientHeight
  2388.         }, CCPShipViewer.prototype.init = function (a) {
  2389.             ref.containerId = a, ref.container = document.getElementById(ref.containerId);
  2390.             var b = document.createElement("div");
  2391.             b.id = "Loading_" + ref.containerId, b.className = "CCPShipViewerLoading", b.innerHTML = "Loading Shipviewer", ref.container.appendChild(b), b = null, ref.pendingResources = 0, ShipViewerLoadingResources || (CCPShipFactList != undefined && CCPShipResourceList != undefined ? ref.onAllResourcesLoaded() : (window.CCPShipResources = function (a) {
  2392.                 CCPShipResourceList = a, ref.onResourceLoaded()
  2393.             }, window.CCPShipFacts = function (a) {
  2394.                 CCPShipFactList = a, ref.onResourceLoaded()
  2395.             }, ref.getResource(ref.assetsPath + ref.shipResourceFileName), ref.getResource(ref.assetsPath + ref.shipFactsFileName))), ShipViewerWaitingList.push(ref)
  2396.         }, CCPShipViewer.prototype.onMouseUp = function (a) {
  2397.             a.preventDefault(), ref.isMouseDown = !1, document.removeEventListener("mousemove", ref.onMouseMove, !1), document.removeEventListener("mouseup", ref.onMouseUp, !1)
  2398.         }, CCPShipViewer.prototype.onMouseDown = function (a) {
  2399.             a.preventDefault(), ref.isMouseDown = !0, onMouseDownPosition[0] = a.clientX, onMouseDownPosition[1] = a.clientY, ref.onMouseDownTheta = ref.theta, ref.onMouseDownPhi = ref.phi, ref.lastPhi = ref.phi, ref.lastTheta = ref.theta, doAnimation = !1, document.addEventListener("mousemove", ref.onMouseMove, !1), document.addEventListener("mouseup", ref.onMouseUp, !1)
  2400.         }, CCPShipViewer.prototype.onMouseMove = function (a) {
  2401.             if (ref.isMouseDown) {
  2402.                 var b = -((a.clientX - onMouseDownPosition[0]) * .01) + ref.onMouseDownTheta,
  2403.                     c = (a.clientY - onMouseDownPosition[1]) * .01 + ref.onMouseDownPhi;
  2404.                 c = Math.min(179, Math.max(-179, c)), ref.phiDiff += (ref.lastPhi - c) / 4, ref.thetaDiff += (ref.lastTheta - b) / 4, ref.lastPhi = c, ref.lastTheta = b
  2405.             }
  2406.         }, CCPShipViewer.prototype.createHttpRequest = function () {
  2407.             var a = null;
  2408.             if (window.XMLHttpRequest) a = new XMLHttpRequest;
  2409.             else if (window.ActiveXObject) try {
  2410.                 a = new ActiveXObject("Msxml2.XMLHTTP")
  2411.             } catch (b) {
  2412.                 try {
  2413.                     a = new ActiveXObject("Microsoft.XMLHTTP")
  2414.                 } catch (b) {}
  2415.             }
  2416.             a || log.LogErr("CCP Shipviewer: could not create an XMLHTTP instance");
  2417.             return a
  2418.         }, CCPShipViewer.prototype.JSONP = function () {
  2419.             function g(b, g, h, i) {
  2420.                 c = "?", g = g || {};
  2421.                 for (d in g) g.hasOwnProperty(d) && (c += encodeURIComponent(d) + "=" + encodeURIComponent(g[d]) + "&");
  2422.                 var j = "json_" + ++a;
  2423.                 e[j] = function (a) {
  2424.                     h(a);
  2425.                     try {
  2426.                         delete e[j]
  2427.                     } catch (b) {}
  2428.                     e[j] = null
  2429.                 }, f(b);
  2430.                 return j
  2431.             }
  2432.  
  2433.             function f(a) {
  2434.                 var c = document.createElement("script"),
  2435.                     d = !1;
  2436.                 c.src = a, c.async = !0, c.onload = c.onreadystatechange = function () {
  2437.                     !d && (!this.readyState || this.readyState === "loaded" || this.readyState === "complete") && (d = !0, c.onload = c.onreadystatechange = null, c && c.parentNode && c.parentNode.removeChild(c))
  2438.                 }, b || (b = document.getElementsByTagName("head")[0]), b.appendChild(c)
  2439.             }
  2440.             var a = 0,
  2441.                 b, c, d, e = this;
  2442.             return {
  2443.                 get: g
  2444.             }
  2445.         }(), window.requestAnimFrame = function () {
  2446.             return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (a, b) {
  2447.                 window.setTimeout(a, 1e3 / 60)
  2448.             }
  2449.         }(), this.init(settings.parentElementId)
  2450.     }
  2451. }
  2452.  
  2453. function checkWebGLSupport() {
  2454.     if (/Firefox[\/\s](\d+\.\d+)/.test(navigator.userAgent)) {
  2455.         var a = new Number(RegExp.$1);
  2456.         if (a < 8) return !1
  2457.     }
  2458.     if ( !! window.WebGLRenderingContext == !1) return !1;
  2459.     var b = !1;
  2460.     try {
  2461.         var c = document.createElement("canvas");
  2462.         b = !(!window.WebGLRenderingContext || !c.getContext("experimental-webgl") && !c.getContext("webgl")), c = undefined
  2463.     } catch (d) {
  2464.         b = !1
  2465.     }
  2466.     return b
  2467. }
  2468. var ShipViewerWaitingList, ShipViewerLoadingResources, CCPShipResourceList, CCPShipFactList;
  2469. glMatrixArrayType = typeof Float32Array != "undefined" ? Float32Array : typeof WebGLFloatArray != "undefined" ? WebGLFloatArray : Array;
  2470. var vec3 = {};
  2471. vec3.create = function (a) {
  2472.     var b = new glMatrixArrayType(3);
  2473.     a && (b[0] = a[0], b[1] = a[1], b[2] = a[2]);
  2474.     return b
  2475. }, vec3.set = function (a, b) {
  2476.     b[0] = a[0], b[1] = a[1], b[2] = a[2];
  2477.     return b
  2478. }, vec3.add = function (a, b, c) {
  2479.     if (!c || a == c) {
  2480.         a[0] += b[0], a[1] += b[1], a[2] += b[2];
  2481.         return a
  2482.     }
  2483.     c[0] = a[0] + b[0], c[1] = a[1] + b[1], c[2] = a[2] + b[2];
  2484.     return c
  2485. }, vec3.subtract = function (a, b, c) {
  2486.     if (!c || a == c) {
  2487.         a[0] -= b[0], a[1] -= b[1], a[2] -= b[2];
  2488.         return a
  2489.     }
  2490.     c[0] = a[0] - b[0], c[1] = a[1] - b[1], c[2] = a[2] - b[2];
  2491.     return c
  2492. }, vec3.negate = function (a, b) {
  2493.     b || (b = a), b[0] = -a[0], b[1] = -a[1], b[2] = -a[2];
  2494.     return b
  2495. }, vec3.scale = function (a, b, c) {
  2496.     if (!c || a == c) {
  2497.         a[0] *= b, a[1] *= b, a[2] *= b;
  2498.         return a
  2499.     }
  2500.     c[0] = a[0] * b, c[1] = a[1] * b, c[2] = a[2] * b;
  2501.     return c
  2502. }, vec3.normalize = function (a, b) {
  2503.     b || (b = a);
  2504.     var c = a[0],
  2505.         d = a[1],
  2506.         e = a[2],
  2507.         f = Math.sqrt(c * c + d * d + e * e);
  2508.     if (!f) {
  2509.         b[0] = 0, b[1] = 0, b[2] = 0;
  2510.         return b
  2511.     }
  2512.     if (f == 1) {
  2513.         b[0] = c, b[1] = d, b[2] = e;
  2514.         return b
  2515.     }
  2516.     f = 1 / f, b[0] = c * f, b[1] = d * f, b[2] = e * f;
  2517.     return b
  2518. }, vec3.cross = function (a, b, c) {
  2519.     c || (c = a);
  2520.     var d = a[0],
  2521.         e = a[1];
  2522.     a = a[2];
  2523.     var f = b[0],
  2524.         g = b[1];
  2525.     b = b[2], c[0] = e * b - a * g, c[1] = a * f - d * b, c[2] = d * g - e * f;
  2526.     return c
  2527. }, vec3.length = function (a) {
  2528.     var b = a[0],
  2529.         c = a[1];
  2530.     a = a[2];
  2531.     return Math.sqrt(b * b + c * c + a * a)
  2532. }, vec3.dot = function (a, b) {
  2533.     return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
  2534. }, vec3.direction = function (a, b, c) {
  2535.     c || (c = a);
  2536.     var d = a[0] - b[0],
  2537.         e = a[1] - b[1];
  2538.     a = a[2] - b[2], b = Math.sqrt(d * d + e * e + a * a);
  2539.     if (!b) {
  2540.         c[0] = 0, c[1] = 0, c[2] = 0;
  2541.         return c
  2542.     }
  2543.     b = 1 / b, c[0] = d * b, c[1] = e * b, c[2] = a * b;
  2544.     return c
  2545. }, vec3.lerp = function (a, b, c, d) {
  2546.     d || (d = a), d[0] = a[0] + c * (b[0] - a[0]), d[1] = a[1] + c * (b[1] - a[1]), d[2] = a[2] + c * (b[2] - a[2]);
  2547.     return d
  2548. }, vec3.str = function (a) {
  2549.     return "[" + a[0] + ", " + a[1] + ", " + a[2] + "]"
  2550. };
  2551. var mat3 = {};
  2552. mat3.create = function (a) {
  2553.     var b = new glMatrixArrayType(9);
  2554.     a && (b[0] = a[0], b[1] = a[1], b[2] = a[2], b[3] = a[3], b[4] = a[4], b[5] = a[5], b[6] = a[6], b[7] = a[7], b[8] = a[8], b[9] = a[9]);
  2555.     return b
  2556. }, mat3.set = function (a, b) {
  2557.     b[0] = a[0], b[1] = a[1], b[2] = a[2], b[3] = a[3], b[4] = a[4], b[5] = a[5], b[6] = a[6], b[7] = a[7], b[8] = a[8];
  2558.     return b
  2559. }, mat3.identity = function (a) {
  2560.     a[0] = 1, a[1] = 0, a[2] = 0, a[3] = 0, a[4] = 1, a[5] = 0, a[6] = 0, a[7] = 0, a[8] = 1;
  2561.     return a
  2562. }, mat3.transpose = function (a, b) {
  2563.     if (!b || a == b) {
  2564.         var c = a[1],
  2565.             d = a[2],
  2566.             e = a[5];
  2567.         a[1] = a[3], a[2] = a[6], a[3] = c, a[5] = a[7], a[6] = d, a[7] = e;
  2568.         return a
  2569.     }
  2570.     b[0] = a[0], b[1] = a[3], b[2] = a[6], b[3] = a[1], b[4] = a[4], b[5] = a[7], b[6] = a[2], b[7] = a[5], b[8] = a[8];
  2571.     return b
  2572. }, mat3.toMat4 = function (a, b) {
  2573.     b || (b = mat4.create()), b[0] = a[0], b[1] = a[1], b[2] = a[2], b[3] = 0, b[4] = a[3], b[5] = a[4], b[6] = a[5], b[7] = 0, b[8] = a[6], b[9] = a[7], b[10] = a[8], b[11] = 0, b[12] = 0, b[13] = 0, b[14] = 0, b[15] = 1;
  2574.     return b
  2575. }, mat3.str = function (a) {
  2576.     return "[" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + "]"
  2577. };
  2578. var mat4 = {};
  2579. mat4.create = function (a) {
  2580.     var b = new glMatrixArrayType(16);
  2581.     a && (b[0] = a[0], b[1] = a[1], b[2] = a[2], b[3] = a[3], b[4] = a[4], b[5] = a[5], b[6] = a[6], b[7] = a[7], b[8] = a[8], b[9] = a[9], b[10] = a[10], b[11] = a[11], b[12] = a[12], b[13] = a[13], b[14] = a[14], b[15] = a[15]);
  2582.     return b
  2583. }, mat4.set = function (a, b) {
  2584.     b[0] = a[0], b[1] = a[1], b[2] = a[2], b[3] = a[3], b[4] = a[4], b[5] = a[5], b[6] = a[6], b[7] = a[7], b[8] = a[8], b[9] = a[9], b[10] = a[10], b[11] = a[11], b[12] = a[12], b[13] = a[13], b[14] = a[14], b[15] = a[15];
  2585.     return b
  2586. }, mat4.identity = function (a) {
  2587.     a[0] = 1, a[1] = 0, a[2] = 0, a[3] = 0, a[4] = 0, a[5] = 1, a[6] = 0, a[7] = 0, a[8] = 0, a[9] = 0, a[10] = 1, a[11] = 0, a[12] = 0, a[13] = 0, a[14] = 0, a[15] = 1;
  2588.     return a
  2589. }, mat4.transpose = function (a, b) {
  2590.     if (!b || a == b) {
  2591.         var c = a[1],
  2592.             d = a[2],
  2593.             e = a[3],
  2594.             f = a[6],
  2595.             g = a[7],
  2596.             h = a[11];
  2597.         a[1] = a[4], a[2] = a[8], a[3] = a[12], a[4] = c, a[6] = a[9], a[7] = a[13], a[8] = d, a[9] = f, a[11] = a[14], a[12] = e, a[13] = g, a[14] = h;
  2598.         return a
  2599.     }
  2600.     b[0] = a[0], b[1] = a[4], b[2] = a[8], b[3] = a[12], b[4] = a[1], b[5] = a[5], b[6] = a[9], b[7] = a[13], b[8] = a[2], b[9] = a[6], b[10] = a[10], b[11] = a[14], b[12] = a[3], b[13] = a[7], b[14] = a[11], b[15] = a[15];
  2601.     return b
  2602. }, mat4.determinant = function (a) {
  2603.     var b = a[0],
  2604.         c = a[1],
  2605.         d = a[2],
  2606.         e = a[3],
  2607.         f = a[4],
  2608.         g = a[5],
  2609.         h = a[6],
  2610.         i = a[7],
  2611.         j = a[8],
  2612.         k = a[9],
  2613.         l = a[10],
  2614.         m = a[11],
  2615.         n = a[12],
  2616.         o = a[13],
  2617.         p = a[14];
  2618.     a = a[15];
  2619.     return n * k * h * e - j * o * h * e - n * g * l * e + f * o * l * e + j * g * p * e - f * k * p * e - n * k * d * i + j * o * d * i + n * c * l * i - b * o * l * i - j * c * p * i + b * k * p * i + n * g * d * m - f * o * d * m - n * c * h * m + b * o * h * m + f * c * p * m - b * g * p * m - j * g * d * a + f * k * d * a + j * c * h * a - b * k * h * a - f * c * l * a + b * g * l * a
  2620. }, mat4.inverse = function (a, b) {
  2621.     b || (b = a);
  2622.     var c = a[0],
  2623.         d = a[1],
  2624.         e = a[2],
  2625.         f = a[3],
  2626.         g = a[4],
  2627.         h = a[5],
  2628.         i = a[6],
  2629.         j = a[7],
  2630.         k = a[8],
  2631.         l = a[9],
  2632.         m = a[10],
  2633.         n = a[11],
  2634.         o = a[12],
  2635.         p = a[13],
  2636.         q = a[14],
  2637.         r = a[15],
  2638.         s = c * h - d * g,
  2639.         t = c * i - e * g,
  2640.         u = c * j - f * g,
  2641.         v = d * i - e * h,
  2642.         w = d * j - f * h,
  2643.         x = e * j - f * i,
  2644.         y = k * p - l * o,
  2645.         z = k * q - m * o,
  2646.         A = k * r - n * o,
  2647.         B = l * q - m * p,
  2648.         C = l * r - n * p,
  2649.         D = m * r - n * q,
  2650.         E = 1 / (s * D - t * C + u * B + v * A - w * z + x * y);
  2651.     b[0] = (h * D - i * C + j * B) * E, b[1] = (-d * D + e * C - f * B) * E, b[2] = (p * x - q * w + r * v) * E, b[3] = (-l * x + m * w - n * v) * E, b[4] = (-g * D + i * A - j * z) * E, b[5] = (c * D - e * A + f * z) * E, b[6] = (-o * x + q * u - r * t) * E, b[7] = (k * x - m * u + n * t) * E, b[8] = (g * C - h * A + j * y) * E, b[9] = (-c * C + d * A - f * y) * E, b[10] = (o * w - p * u + r * s) * E, b[11] = (-k * w + l * u - n * s) * E, b[12] = (-g * B + h * z - i * y) * E, b[13] = (c * B - d * z + e * y) * E, b[14] = (-o * v + p * t - q * s) * E, b[15] = (k * v - l * t + m * s) * E;
  2652.     return b
  2653. }, mat4.toRotationMat = function (a, b) {
  2654.     b || (b = mat4.create()), b[0] = a[0], b[1] = a[1], b[2] = a[2], b[3] = a[3], b[4] = a[4], b[5] = a[5], b[6] = a[6], b[7] = a[7], b[8] = a[8], b[9] = a[9], b[10] = a[10], b[11] = a[11], b[12] = 0, b[13] = 0, b[14] = 0, b[15] = 1;
  2655.     return b
  2656. }, mat4.toMat3 = function (a, b) {
  2657.     b || (b = mat3.create()), b[0] = a[0], b[1] = a[1], b[2] = a[2], b[3] = a[4], b[4] = a[5], b[5] = a[6], b[6] = a[8], b[7] = a[9], b[8] = a[10];
  2658.     return b
  2659. }, mat4.toInverseMat3 = function (a, b) {
  2660.     var c = a[0],
  2661.         d = a[1],
  2662.         e = a[2],
  2663.         f = a[4],
  2664.         g = a[5],
  2665.         h = a[6],
  2666.         i = a[8],
  2667.         j = a[9],
  2668.         k = a[10],
  2669.         l = k * g - h * j,
  2670.         m = -k * f + h * i,
  2671.         n = j * f - g * i,
  2672.         o = c * l + d * m + e * n;
  2673.     if (!o) return null;
  2674.     o = 1 / o, b || (b = mat3.create()), b[0] = l * o, b[1] = (-k * d + e * j) * o, b[2] = (h * d - e * g) * o, b[3] = m * o, b[4] = (k * c - e * i) * o, b[5] = (-h * c + e * f) * o, b[6] = n * o, b[7] = (-j * c + d * i) * o, b[8] = (g * c - d * f) * o;
  2675.     return b
  2676. }, mat4.multiply = function (a, b, c) {
  2677.     c || (c = a);
  2678.     var d = a[0],
  2679.         e = a[1],
  2680.         f = a[2],
  2681.         g = a[3],
  2682.         h = a[4],
  2683.         i = a[5],
  2684.         j = a[6],
  2685.         k = a[7],
  2686.         l = a[8],
  2687.         m = a[9],
  2688.         n = a[10],
  2689.         o = a[11],
  2690.         p = a[12],
  2691.         q = a[13],
  2692.         r = a[14];
  2693.     a = a[15];
  2694.     var s = b[0],
  2695.         t = b[1],
  2696.         u = b[2],
  2697.         v = b[3],
  2698.         w = b[4],
  2699.         x = b[5],
  2700.         y = b[6],
  2701.         z = b[7],
  2702.         A = b[8],
  2703.         B = b[9],
  2704.         C = b[10],
  2705.         D = b[11],
  2706.         E = b[12],
  2707.         F = b[13],
  2708.         G = b[14];
  2709.     b = b[15], c[0] = s * d + t * h + u * l + v * p, c[1] = s * e + t * i + u * m + v * q, c[2] = s * f + t * j + u * n + v * r, c[3] = s * g + t * k + u * o + v * a, c[4] = w * d + x * h + y * l + z * p, c[5] = w * e + x * i + y * m + z * q, c[6] = w * f + x * j + y * n + z * r, c[7] = w * g + x * k + y * o + z * a, c[8] = A * d + B * h + C * l + D * p, c[9] = A * e + B * i + C * m + D * q, c[10] = A * f + B * j + C * n + D * r, c[11] = A * g + B * k + C * o + D * a, c[12] = E * d + F * h + G * l + b * p, c[13] = E * e + F * i + G * m + b * q, c[14] = E * f + F * j + G * n + b * r, c[15] = E * g + F * k + G * o + b * a;
  2710.     return c
  2711. }, mat4.multiplyVec3 = function (a, b, c) {
  2712.     c || (c = b);
  2713.     var d = b[0],
  2714.         e = b[1];
  2715.     b = b[2], c[0] = a[0] * d + a[4] * e + a[8] * b + a[12], c[1] = a[1] * d + a[5] * e + a[9] * b + a[13], c[2] = a[2] * d + a[6] * e + a[10] * b + a[14];
  2716.     return c
  2717. }, mat4.multiplyVec4 = function (a, b, c) {
  2718.     c || (c = b);
  2719.     var d = b[0],
  2720.         e = b[1],
  2721.         f = b[2];
  2722.     b = b[3], c[0] = a[0] * d + a[4] * e + a[8] * f + a[12] * b, c[1] = a[1] * d + a[5] * e + a[9] * f + a[13] * b, c[2] = a[2] * d + a[6] * e + a[10] * f + a[14] * b, c[3] = a[3] * d + a[7] * e + a[11] * f + a[15] * b;
  2723.     return c
  2724. }, mat4.translate = function (a, b, c) {
  2725.     var d = b[0],
  2726.         e = b[1];
  2727.     b = b[2];
  2728.     if (!c || a == c) {
  2729.         a[12] = a[0] * d + a[4] * e + a[8] * b + a[12], a[13] = a[1] * d + a[5] * e + a[9] * b + a[13], a[14] = a[2] * d + a[6] * e + a[10] * b + a[14], a[15] = a[3] * d + a[7] * e + a[11] * b + a[15];
  2730.         return a
  2731.     }
  2732.     var f = a[0],
  2733.         g = a[1],
  2734.         h = a[2],
  2735.         i = a[3],
  2736.         j = a[4],
  2737.         k = a[5],
  2738.         l = a[6],
  2739.         m = a[7],
  2740.         n = a[8],
  2741.         o = a[9],
  2742.         p = a[10],
  2743.         q = a[11];
  2744.     c[0] = f, c[1] = g, c[2] = h, c[3] = i, c[4] = j, c[5] = k, c[6] = l, c[7] = m, c[8] = n, c[9] = o, c[10] = p, c[11] = q, c[12] = f * d + j * e + n * b + a[12], c[13] = g * d + k * e + o * b + a[13], c[14] = h * d + l * e + p * b + a[14], c[15] = i * d + m * e + q * b + a[15];
  2745.     return c
  2746. }, mat4.scale = function (a, b, c) {
  2747.     var d = b[0],
  2748.         e = b[1];
  2749.     b = b[2];
  2750.     if (!c || a == c) {
  2751.         a[0] *= d, a[1] *= d, a[2] *= d, a[3] *= d, a[4] *= e, a[5] *= e, a[6] *= e, a[7] *= e, a[8] *= b, a[9] *= b, a[10] *= b, a[11] *= b;
  2752.         return a
  2753.     }
  2754.     c[0] = a[0] * d, c[1] = a[1] * d, c[2] = a[2] * d, c[3] = a[3] * d, c[4] = a[4] * e, c[5] = a[5] * e, c[6] = a[6] * e, c[7] = a[7] * e, c[8] = a[8] * b, c[9] = a[9] * b, c[10] = a[10] * b, c[11] = a[11] * b, c[12] = a[12], c[13] = a[13], c[14] = a[14], c[15] = a[15];
  2755.     return c
  2756. }, mat4.rotate = function (a, b, c, d) {
  2757.     var e = c[0],
  2758.         f = c[1];
  2759.     c = c[2];
  2760.     var g = Math.sqrt(e * e + f * f + c * c);
  2761.     if (!g) return null;
  2762.     g != 1 && (g = 1 / g, e *= g, f *= g, c *= g);
  2763.     var h = Math.sin(b),
  2764.         i = Math.cos(b),
  2765.         j = 1 - i;
  2766.     b = a[0], g = a[1];
  2767.     var k = a[2],
  2768.         l = a[3],
  2769.         m = a[4],
  2770.         n = a[5],
  2771.         o = a[6],
  2772.         p = a[7],
  2773.         q = a[8],
  2774.         r = a[9],
  2775.         s = a[10],
  2776.         t = a[11],
  2777.         u = e * e * j + i,
  2778.         v = f * e * j + c * h,
  2779.         w = c * e * j - f * h,
  2780.         x = e * f * j - c * h,
  2781.         y = f * f * j + i,
  2782.         z = c * f * j + e * h,
  2783.         A = e * c * j + f * h;
  2784.     e = f * c * j - e * h, f = c * c * j + i, d ? a != d && (d[12] = a[12], d[13] = a[13], d[14] = a[14], d[15] = a[15]) : d = a, d[0] = b * u + m * v + q * w, d[1] = g * u + n * v + r * w, d[2] = k * u + o * v + s * w, d[3] = l * u + p * v + t * w, d[4] = b * x + m * y + q * z, d[5] = g * x + n * y + r * z, d[6] = k * x + o * y + s * z, d[7] = l * x + p * y + t * z, d[8] = b * A + m * e + q * f, d[9] = g * A + n * e + r * f, d[10] = k * A + o * e + s * f, d[11] = l * A + p * e + t * f;
  2785.     return d
  2786. }, mat4.rotateX = function (a, b, c) {
  2787.     var d = Math.sin(b);
  2788.     b = Math.cos(b);
  2789.     var e = a[4],
  2790.         f = a[5],
  2791.         g = a[6],
  2792.         h = a[7],
  2793.         i = a[8],
  2794.         j = a[9],
  2795.         k = a[10],
  2796.         l = a[11];
  2797.     c ? a != c && (c[0] = a[0], c[1] = a[1], c[2] = a[2], c[3] = a[3], c[12] = a[12], c[13] = a[13], c[14] = a[14], c[15] = a[15]) : c = a, c[4] = e * b + i * d, c[5] = f * b + j * d, c[6] = g * b + k * d, c[7] = h * b + l * d, c[8] = e * -d + i * b, c[9] = f * -d + j * b, c[10] = g * -d + k * b, c[11] = h * -d + l * b;
  2798.     return c
  2799. }, mat4.rotateY = function (a, b, c) {
  2800.     var d = Math.sin(b);
  2801.     b = Math.cos(b);
  2802.     var e = a[0],
  2803.         f = a[1],
  2804.         g = a[2],
  2805.         h = a[3],
  2806.         i = a[8],
  2807.         j = a[9],
  2808.         k = a[10],
  2809.         l = a[11];
  2810.     c ? a != c && (c[4] = a[4], c[5] = a[5], c[6] = a[6], c[7] = a[7], c[12] = a[12], c[13] = a[13], c[14] = a[14], c[15] = a[15]) : c = a, c[0] = e * b + i * -d, c[1] = f * b + j * -d, c[2] = g * b + k * -d, c[3] = h * b + l * -d, c[8] = e * d + i * b, c[9] = f * d + j * b, c[10] = g * d + k * b, c[11] = h * d + l * b;
  2811.     return c
  2812. }, mat4.rotateZ = function (a, b, c) {
  2813.     var d = Math.sin(b);
  2814.     b = Math.cos(b);
  2815.     var e = a[0],
  2816.         f = a[1],
  2817.         g = a[2],
  2818.         h = a[3],
  2819.         i = a[4],
  2820.         j = a[5],
  2821.         k = a[6],
  2822.         l = a[7];
  2823.     c ? a != c && (c[8] = a[8], c[9] = a[9], c[10] = a[10], c[11] = a[11], c[12] = a[12], c[13] = a[13], c[14] = a[14], c[15] = a[15]) : c = a, c[0] = e * b + i * d, c[1] = f * b + j * d, c[2] = g * b + k * d, c[3] = h * b + l * d, c[4] = e * -d + i * b, c[5] = f * -d + j * b, c[6] = g * -d + k * b, c[7] = h * -d + l * b;
  2824.     return c
  2825. }, mat4.frustum = function (a, b, c, d, e, f, g) {
  2826.     g || (g = mat4.create());
  2827.     var h = b - a,
  2828.         i = d - c,
  2829.         j = f - e;
  2830.     g[0] = e * 2 / h, g[1] = 0, g[2] = 0, g[3] = 0, g[4] = 0, g[5] = e * 2 / i, g[6] = 0, g[7] = 0, g[8] = (b + a) / h, g[9] = (d + c) / i, g[10] = -(f + e) / j, g[11] = -1, g[12] = 0, g[13] = 0, g[14] = -(f * e * 2) / j, g[15] = 0;
  2831.     return g
  2832. }, mat4.perspective = function (a, b, c, d, e) {
  2833.     a = c * Math.tan(a * Math.PI / 360), b = a * b;
  2834.     return mat4.frustum(-b, b, -a, a, c, d, e)
  2835. }, mat4.ortho = function (a, b, c, d, e, f, g) {
  2836.     g || (g = mat4.create());
  2837.     var h = b - a,
  2838.         i = d - c,
  2839.         j = f - e;
  2840.     g[0] = 2 / h, g[1] = 0, g[2] = 0, g[3] = 0, g[4] = 0, g[5] = 2 / i, g[6] = 0, g[7] = 0, g[8] = 0, g[9] = 0, g[10] = -2 / j, g[11] = 0, g[12] = -(a + b) / h, g[13] = -(d + c) / i, g[14] = -(f + e) / j, g[15] = 1;
  2841.     return g
  2842. }, mat4.lookAt = function (a, b, c, d) {
  2843.     d || (d = mat4.create());
  2844.     var e = a[0],
  2845.         f = a[1];
  2846.     a = a[2];
  2847.     var g = c[0],
  2848.         h = c[1],
  2849.         i = c[2];
  2850.     c = b[1];
  2851.     var j = b[2];
  2852.     if (e == b[0] && f == c && a == j) return mat4.identity(d);
  2853.     var k, l, m, n;
  2854.     c = e - b[0], j = f - b[1], b = a - b[2], n = 1 / Math.sqrt(c * c + j * j + b * b), c *= n, j *= n, b *= n, k = h * b - i * j, i = i * c - g * b, g = g * j - h * c, (n = Math.sqrt(k * k + i * i + g * g)) ? (n = 1 / n, k *= n, i *= n, g *= n) : g = i = k = 0, h = j * g - b * i, l = b * k - c * g, m = c * i - j * k, (n = Math.sqrt(h * h + l * l + m * m)) ? (n = 1 / n, h *= n, l *= n, m *= n) : m = l = h = 0, d[0] = k, d[1] = h, d[2] = c, d[3] = 0, d[4] = i, d[5] = l, d[6] = j, d[7] = 0, d[8] = g, d[9] = m, d[10] = b, d[11] = 0, d[12] = -(k * e + i * f + g * a), d[13] = -(h * e + l * f + m * a), d[14] = -(c * e + j * f + b * a), d[15] = 1;
  2855.     return d
  2856. }, mat4.str = function (a) {
  2857.     return "[" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + ", " + a[4] + ", " + a[5] + ", " + a[6] + ", " + a[7] + ", " + a[8] + ", " + a[9] + ", " + a[10] + ", " + a[11] + ", " + a[12] + ", " + a[13] + ", " + a[14] + ", " + a[15] + "]"
  2858. }, quat4 = {}, quat4.create = function (a) {
  2859.     var b = new glMatrixArrayType(4);
  2860.     a && (b[0] = a[0], b[1] = a[1], b[2] = a[2], b[3] = a[3]);
  2861.     return b
  2862. }, quat4.set = function (a, b) {
  2863.     b[0] = a[0], b[1] = a[1], b[2] = a[2], b[3] = a[3];
  2864.     return b
  2865. }, quat4.calculateW = function (a, b) {
  2866.     var c = a[0],
  2867.         d = a[1],
  2868.         e = a[2];
  2869.     if (!b || a == b) {
  2870.         a[3] = -Math.sqrt(Math.abs(1 - c * c - d * d - e * e));
  2871.         return a
  2872.     }
  2873.     b[0] = c, b[1] = d, b[2] = e, b[3] = -Math.sqrt(Math.abs(1 - c * c - d * d - e * e));
  2874.     return b
  2875. }, quat4.inverse = function (a, b) {
  2876.     if (!b || a == b) {
  2877.         a[0] *= 1, a[1] *= 1, a[2] *= 1;
  2878.         return a
  2879.     }
  2880.     b[0] = -a[0], b[1] = -a[1], b[2] = -a[2], b[3] = a[3];
  2881.     return b
  2882. }, quat4.length = function (a) {
  2883.     var b = a[0],
  2884.         c = a[1],
  2885.         d = a[2];
  2886.     a = a[3];
  2887.     return Math.sqrt(b * b + c * c + d * d + a * a)
  2888. }, quat4.normalize = function (a, b) {
  2889.     b || (b = a);
  2890.     var c = a[0],
  2891.         d = a[1],
  2892.         e = a[2],
  2893.         f = a[3],
  2894.         g = Math.sqrt(c * c + d * d + e * e + f * f);
  2895.     if (g == 0) {
  2896.         b[0] = 0, b[1] = 0, b[2] = 0, b[3] = 0;
  2897.         return b
  2898.     }
  2899.     g = 1 / g, b[0] = c * g, b[1] = d * g, b[2] = e * g, b[3] = f * g;
  2900.     return b
  2901. }, quat4.multiply = function (a, b, c) {
  2902.     c || (c = a);
  2903.     var d = a[0],
  2904.         e = a[1],
  2905.         f = a[2];
  2906.     a = a[3];
  2907.     var g = b[0],
  2908.         h = b[1],
  2909.         i = b[2];
  2910.     b = b[3], c[0] = d * b + a * g + e * i - f * h, c[1] = e * b + a * h + f * g - d * i, c[2] = f * b + a * i + d * h - e * g, c[3] = a * b - d * g - e * h - f * i;
  2911.     return c
  2912. }, quat4.multiplyVec3 = function (a, b, c) {
  2913.     c || (c = b);
  2914.     var d = b[0],
  2915.         e = b[1],
  2916.         f = b[2];
  2917.     b = a[0];
  2918.     var g = a[1],
  2919.         h = a[2];
  2920.     a = a[3];
  2921.     var i = a * d + g * f - h * e,
  2922.         j = a * e + h * d - b * f,
  2923.         k = a * f + b * e - g * d;
  2924.     d = -b * d - g * e - h * f, c[0] = i * a + d * -b + j * -h - k * -g, c[1] = j * a + d * -g + k * -b - i * -h, c[2] = k * a + d * -h + i * -g - j * -b;
  2925.     return c
  2926. }, quat4.toMat3 = function (a, b) {
  2927.     b || (b = mat3.create());
  2928.     var c = a[0],
  2929.         d = a[1],
  2930.         e = a[2],
  2931.         f = a[3],
  2932.         g = c + c,
  2933.         h = d + d,
  2934.         i = e + e,
  2935.         j = c * g,
  2936.         k = c * h;
  2937.     c = c * i;
  2938.     var l = d * h;
  2939.     d = d * i, e = e * i, g = f * g, h = f * h, f = f * i, b[0] = 1 - (l + e), b[1] = k - f, b[2] = c + h, b[3] = k + f, b[4] = 1 - (j + e), b[5] = d - g, b[6] = c - h, b[7] = d + g, b[8] = 1 - (j + l);
  2940.     return b
  2941. }, quat4.toMat4 = function (a, b) {
  2942.     b || (b = mat4.create());
  2943.     var c = a[0],
  2944.         d = a[1],
  2945.         e = a[2],
  2946.         f = a[3],
  2947.         g = c + c,
  2948.         h = d + d,
  2949.         i = e + e,
  2950.         j = c * g,
  2951.         k = c * h;
  2952.     c = c * i;
  2953.     var l = d * h;
  2954.     d = d * i, e = e * i, g = f * g, h = f * h, f = f * i, b[0] = 1 - (l + e), b[1] = k - f, b[2] = c + h, b[3] = 0, b[4] = k + f, b[5] = 1 - (j + e), b[6] = d - g, b[7] = 0, b[8] = c - h, b[9] = d + g, b[10] = 1 - (j + l), b[11] = 0, b[12] = 0, b[13] = 0, b[14] = 0, b[15] = 1;
  2955.     return b
  2956. }, quat4.slerp = function (a, b, c, d) {
  2957.     d || (d = a);
  2958.     var e = c;
  2959.     a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3] < 0 && (e = -1 * c), d[0] = 1 - c * a[0] + e * b[0], d[1] = 1 - c * a[1] + e * b[1], d[2] = 1 - c * a[2] + e * b[2], d[3] = 1 - c * a[3] + e * b[3];
  2960.     return d
  2961. }, quat4.str = function (a) {
  2962.     return "[" + a[0] + ", " + a[1] + ", " + a[2] + ", " + a[3] + "]"
  2963. }
Add Comment
Please, Sign In to add comment