UNPKG

@bitsy/hecks

Version:

a collection of re-usable scripts for bitsy game maker

615 lines (548 loc) โ€ข 2.42 MB
/** ๐Ÿ“ฆ @file 3d @summary bitsy in three dee @license MIT @version 1.2.0 @requires 6.3 @author Sean S. LeBlanc & Elkie Nova @description Re-renders games in 3D instead of 2D. The 3D rendering is done through babylonjs, a 3D WebGL rendering engine. Notes: - The smooth moves hack is included to avoid jerky camera motion when the player moves - The transparent sprites hack is included with this since most 3D games would need it if wanted, you can prevent it from making things transparent by making the isTransparent function in the options always return false - Exit transition effects aren't implemented - The scene variable is exported, which means it's available at `window.hacks['3d'].scene` this is useful for debugging, or in combination with the JS dialog hack - No camera/mesh collision is included - The 3D library included is very large by hack filesize standards The Biggest Note: If you try this out and think "this would be great if only it did X instead of Y", it probably can with a bit of customization! Naturally there are dozens of potential ways bitsy could be translated to 3D, so I focused on covering what I imagined to be some of the most common use cases. If you need help customizing the hack to achieve a different style, feel free to reach out. The hackOptions below have relatively thorough documentation, but make sure to check out https://github.com/seleb/bitsy-hacks/wiki/3D-Hack-Examples for examples of different setups if you're new to 3D. additional features to help make more fancy 3d scenes from bitsy editor: * make arcs, bridges, ceilings, multiple floors, and such by layering bitsy rooms on top of each other. add tag-function '#stack(stackId,position)' to the names of the rooms you want to render together for example you can have rooms named 'theater #stack(a,0)', 'stage #stack(a,1)' and 'catwalks #stack(a,4)' and they will be displayd at the same time, the 'stage' right on top of the 'theater', and 'catwalks' three tiles higher than the 'stage' 'stackId' should only include letters (no numbers and special characters please), it specifies the room stack. rooms in the same stack will be rendered on top of each others, in layers. 'position' is the hight at which you want to display a specific room. you can use negative numbers and floating points too, like '#stack(fjk,-3.5)' note that two rooms in the same stack can be positioned at the same height (useful for layering drawings themselves right on top of each other to make use of more colors and other nifty workarounds) * specify the mesh to use for a specific drawing by appending its name with '#mesh(type)' there are following mesh types available: - plane: plane standing up straight - billboard: like plane, but turns to look at the camera - box: standard cube - floor: plane flat on the ground - tower1, tower2, up to tower16: box variations that are taller and tiled - wedge: base mesh for wedges, facing left with its slanted side - empty: use this one to make the drawings invisible you can have drawings with the names like this using this tag: 'sign #mesh(plane)', 'water #mesh(floor)' don't forget that you can combine '#mesh(type)' with transform tags * transform tags: translate (move), rotate and scale by adding tags to the drawing's name useful for making more complex shapes and more organic silhouettes by shifting models a bit off the grid, and configuring plane-type meshes to face a specific direction #t(x,y,z) for translation, #r(x,y,z) for rotation (in degrees), #s(x,y,z) for scaling. #t(1,0,0.5') and '#t(1,,.5)' are both examples of valid input omiting the number is the same as writing 0. note that this won't change anything on the given axis for rotation and translation, but it will for scaling * add #transparent(true)/#transparent(false) tag to the drawing's name to set transparency manually. sprites and items are transparent by defualt, and tiles are not check this out to learn how to work with wedges conveniently in the bitsy editor: https://github.com/aloelazoe/bitsy-hacks/wiki/how-to-use-wedges-with-3d-hack-and-replace-drawing-hack here is a template with 12 pre-configured wedge drawings you can use with 3d hack and replace drawing hack: https://gist.github.com/aloelazoe/9d02711a649d241d1e78f8d5e4beb9d7 if you have questions, suggestions or constructive feedback about additional features introduced in my fork, feel free to reach out on bitsy discord or twitter (aloelazoe) enjoy have fun with verticality triangularity and whatnot!!! โœง*[เน‘โŒ’ แด— โŒ’เน‘]โœง* HOW TO USE: 1. Copy-paste the contents of this file into a script tag after the bitsy source 2. Add the tags described above to the names of the rooms and drawings in bitsy editor to use additional features 3. Edit hackOptions below as needed */ this.hacks = this.hacks || {}; (function (exports, bitsy) { 'use strict'; var hackOptions$2 = { // Determines the resolution of the scene rendered // If auto is true, the width/height will be ignored, // and the scene will instead render at 1:1 with the canvas // use it if you want it to look crisp on any screen // otherwise, I recommend something in the range of 64-512 size: { auto: true, width: 128, height: 128, }, // If true, inputs are rotated to match the current camera direction // if you're using a camera that can be freely rotated, // this will generally be preferable, // but you may want to disable it for some setups // (e.g. a fixed third person camera) cameraRelativeMovement: true, // If true, left/right inputs are overridden to control 90-degree camera rotations // this requires `cameraRelativeMovement: true` to be usable, // and it's recommended to not add camera controls if used tankControls: false, // scene setup // a number of helper functions are provided to make this easier // but the only necessary thing is to create a camera and assign it to the scene init: function (scene) { scene.activeCamera = makeBaseCamera(); // creates a camera with some basic presets // makeOrthographic(camera, bitsy.mapsize); // makes the camera use orthographic projection (camera, size) makeFollowPlayer(scene.activeCamera); // locks the camera to the player addControls(scene.activeCamera); // adds rotate/zoom controls (also pan if not following player) // addFog(0.5, 1.0); // adds fog in the range (start, end) // addShader(`shader source`, 1.0); // adds a post-processing shader (shader source, downscale factor) }, // If true, dialog renders at the top // otherwise, renders at the bottom // (bitsy's typical position-based rendering doesn't make sense in 3D) topDialog: true, // Function used in transparent sprites hack isTransparent: function (drawing) { var name = drawing.name || ''; var match = name.match(/#transparent\(((true)|(false))\)/); if (match) { // 2nd capturing group will be undefined if the input said 'false' return Boolean(match[2]); } return !drawing.drw.includes('TIL'); }, // Function used to determine how a bitsy drawing is translated into a 3D object // available types are: // - 'plane': plane standing up straight // - 'billboard': like plane, but turns to look at the camera // - 'box': standard cube // - 'floor': plane flat on the ground // - 'tower1', 'tower2', etc: box variations that are taller and tiled // - 'wedge': base mesh for wedges, facing left with its slanted side // - 'empty': base mesh for wedges, facing left with its slanted side getType: function (drawing) { var drw = drawing.drw; var name = drawing.name || ''; // match the drawing's name against the regular expression // that describes #mesh(type) tag var meshMatch = name.match(/#mesh\((.+?)\)/); if (meshMatch) { if (meshTemplates[meshMatch[1]]) { return meshMatch[1]; } else { // if the specified mesh template doesn't exist, // display error message, but continue execution // to resolve the mesh with default logic console.error(`mesh template '${meshMatch[1]}' wasn't found`); } } // default if (drawing.id === bitsy.playerId) { return 'plane'; } if (drw.startsWith('ITM')) { return 'plane'; } if (drw.startsWith('SPR')) { return 'billboard'; } if (drawing.isWall) { return 'box'; } return 'floor'; }, // controls how the 'billboard' type behaves // recommendation: the default provided below, or BABYLON.TransformNode.BILLBOARDMODE_ALL getBillboardMode: function (BABYLON) { return BABYLON.TransformNode.BILLBOARDMODE_Y | BABYLON.TransformNode.BILLBOARDMODE_Z; }, // If true, textures will be preloaded before they're needed while idle // it's recommended to keep this on for more consistent performance post-startup // (without it, you may notice stutter the first time you enter a room) // but if you have a big, highly branching game with lots of art, // you may want to disable it preloadTextures: true, // function used to adjust mesh instances after they have been added to the scene meshExtraSetup: function (drawing, mesh) { var name = drawing.name || ''; // transform tags. #t(x,y,z): translate (move), #r(x,y,z): rotate, #s(x,y,z): scale // #m(1,0,0.5) and #m(1,,.5) are both examples of valid input // scale var scaleTag = name.match(/#s\((-?\.?\d*\.?\d*)?,(-?\.?\d*\.?\d*)?,(-?\.?\d*\.?\d*)?\)/); if (scaleTag) { mesh.scaling = new BABYLON$1.Vector3( Number(scaleTag[1]) || 0, Number(scaleTag[2]) || 0, Number(scaleTag[3]) || 0 ); } // rotate. input in degrees var rotateTag = name.match(/#r\((-?\.?\d*\.?\d*)?,(-?\.?\d*\.?\d*)?,(-?\.?\d*\.?\d*)?\)/); if (rotateTag) { mesh.rotation.x += radians(Number(rotateTag[1]) || 0); mesh.rotation.y += radians(Number(rotateTag[2]) || 0); mesh.rotation.z += radians(Number(rotateTag[3]) || 0); } // translate (move) var translateTag = name.match(/#t\((-?\.?\d*\.?\d*)?,(-?\.?\d*\.?\d*)?,(-?\.?\d*\.?\d*)?\)/); if (translateTag) { mesh.position.x += (Number(translateTag[1]) || 0); mesh.position.y += (Number(translateTag[2]) || 0); mesh.position.z += (Number(translateTag[3]) || 0); } }, // smooth moves hack options // duration of ease in ms duration: 100, // max distance to allow tweens delta: 1.5, // easing function ease: function(t) { t = 1 - Math.pow(1 - t, 2); return t; }, }; bitsy = bitsy && bitsy.hasOwnProperty('default') ? bitsy['default'] : bitsy; /** @file utils @summary miscellaneous bitsy utilities @author Sean S. LeBlanc */ /* Helper used to replace code in a script tag based on a search regex To inject code without erasing original string, using capturing groups; e.g. inject(/(some string)/,'injected before $1 injected after') */ function inject(searchRegex, replaceString) { // find the relevant script tag var scriptTags = document.getElementsByTagName('script'); var scriptTag; var code; for (var i = 0; i < scriptTags.length; ++i) { scriptTag = scriptTags[i]; var matchesSearch = scriptTag.textContent.search(searchRegex) !== -1; var isCurrentScript = scriptTag === document.currentScript; if (matchesSearch && !isCurrentScript) { code = scriptTag.textContent; break; } } // error-handling if (!code) { throw 'Couldn\'t find "' + searchRegex + '" in script tags'; } // modify the content code = code.replace(searchRegex, replaceString); // replace the old script tag with a new one using our modified code var newScriptTag = document.createElement('script'); newScriptTag.textContent = code; scriptTag.insertAdjacentElement('afterend', newScriptTag); scriptTag.remove(); } /** * Helper for getting an array with unique elements * @param {Array} array Original array * @return {Array} Copy of array, excluding duplicates */ function unique(array) { return array.filter(function (item, idx) { return array.indexOf(item) === idx; }); } /** @file kitsy-script-toolkit @summary makes it easier and cleaner to run code before and after Bitsy functions or to inject new code into Bitsy script tags @license WTFPL (do WTF you want) @version 4.0.1 @requires Bitsy Version: 4.5, 4.6 @author @mildmojo @description HOW TO USE: import {before, after, inject, addDialogTag, addDeferredDialogTag} from "./helpers/kitsy-script-toolkit"; before(targetFuncName, beforeFn); after(targetFuncName, afterFn); inject(searchRegex, replaceString); addDialogTag(tagName, dialogFn); addDeferredDialogTag(tagName, dialogFn); For more info, see the documentation at: https://github.com/seleb/bitsy-hacks/wiki/Coding-with-kitsy */ // Ex: before('load_game', function run() { alert('Loading!'); }); // before('show_text', function run(text) { return text.toUpperCase(); }); // before('show_text', function run(text, done) { done(text.toUpperCase()); }); function before(targetFuncName, beforeFn) { var kitsy = kitsyInit(); kitsy.queuedBeforeScripts[targetFuncName] = kitsy.queuedBeforeScripts[targetFuncName] || []; kitsy.queuedBeforeScripts[targetFuncName].push(beforeFn); } // Ex: after('load_game', function run() { alert('Loaded!'); }); function after(targetFuncName, afterFn) { var kitsy = kitsyInit(); kitsy.queuedAfterScripts[targetFuncName] = kitsy.queuedAfterScripts[targetFuncName] || []; kitsy.queuedAfterScripts[targetFuncName].push(afterFn); } function kitsyInit() { // return already-initialized kitsy if (bitsy.kitsy) { return bitsy.kitsy; } // Initialize kitsy bitsy.kitsy = { queuedInjectScripts: [], queuedBeforeScripts: {}, queuedAfterScripts: {} }; var oldStartFunc = bitsy.startExportedGame; bitsy.startExportedGame = function doAllInjections() { // Only do this once. bitsy.startExportedGame = oldStartFunc; // Rewrite scripts and hook everything up. doInjects(); applyAllHooks(); // Start the game bitsy.startExportedGame.apply(this, arguments); }; return bitsy.kitsy; } function doInjects() { bitsy.kitsy.queuedInjectScripts.forEach(function (injectScript) { inject(injectScript.searchRegex, injectScript.replaceString); }); _reinitEngine(); } function applyAllHooks() { var allHooks = unique(Object.keys(bitsy.kitsy.queuedBeforeScripts).concat(Object.keys(bitsy.kitsy.queuedAfterScripts))); allHooks.forEach(applyHook); } function applyHook(functionName) { var functionNameSegments = functionName.split('.'); var obj = bitsy; while (functionNameSegments.length > 1) { obj = obj[functionNameSegments.shift()]; } var lastSegment = functionNameSegments[0]; var superFn = obj[lastSegment]; var superFnLength = superFn ? superFn.length : 0; var functions = []; // start with befores functions = functions.concat(bitsy.kitsy.queuedBeforeScripts[functionName] || []); // then original if (superFn) { functions.push(superFn); } // then afters functions = functions.concat(bitsy.kitsy.queuedAfterScripts[functionName] || []); // overwrite original with one which will call each in order obj[lastSegment] = function () { var returnVal; var args = [].slice.call(arguments); var i = 0; function runBefore() { // All outta functions? Finish if (i === functions.length) { return returnVal; } // Update args if provided. if (arguments.length > 0) { args = [].slice.call(arguments); } if (functions[i].length > superFnLength) { // Assume funcs that accept more args than the original are // async and accept a callback as an additional argument. return functions[i++].apply(this, args.concat(runBefore.bind(this))); } else { // run synchronously returnVal = functions[i++].apply(this, args); if (returnVal && returnVal.length) { args = returnVal; } return runBefore.apply(this, args); } } return runBefore.apply(this, arguments); }; } function _reinitEngine() { // recreate the script and dialog objects so that they'll be // referencing the code with injections instead of the original bitsy.scriptModule = new bitsy.Script(); bitsy.scriptInterpreter = bitsy.scriptModule.CreateInterpreter(); bitsy.dialogModule = new bitsy.Dialog(); bitsy.dialogRenderer = bitsy.dialogModule.CreateRenderer(); bitsy.dialogBuffer = bitsy.dialogModule.CreateBuffer(); } /** ๐Ÿƒ @file smooth moves @summary ease the player's movement @license MIT @version 2.0.0 @requires Bitsy Version: 6.3 @author Sean S. LeBlanc @description Makes the player avatar ease in between positions instead of moving immediately. Speed and easing function are configurable. HOW TO USE: 1. Copy-paste this script into a script tag after the bitsy source 2. Edit hackOptions below as needed */ var hackOptions = { // duration of ease in ms duration: 100, // max distance to allow tweens delta: 1.5, // easing function ease: function(t) { t = 1 - Math.pow(1 - t, 2); return t; }, }; // smooth move var tweens = {}; var sprites = {}; function addTween(spr, fromX, fromY, toX, toY) { if (Math.abs(toX - fromX) + Math.abs(toY - fromY) > hackOptions.delta) { delete tweens[spr]; } else { var t = tweens[spr] = tweens[spr] || {}; t.fromX = fromX; t.fromY = fromY; t.toX = toX; t.toY = toY; t.start = bitsy.prevTime; } } before('onready', function() { tweens = {}; sprites = {}; }); // listen for changes in sprite positions to add tweens before('update', function() { Object.values(bitsy.sprite).forEach(spr => { if (spr.room === bitsy.curRoom) { var s = sprites[spr.id] = sprites[spr.id] || {}; s.x = spr.x; s.y = spr.y; } else { delete sprites[spr.id]; } }); }); function addTweens() { Object.entries(sprites).forEach(function (entry) { var spr = bitsy.sprite[entry[0]]; var pos = entry[1]; if (pos.x !== spr.x || pos.y !== spr.y) { addTween(spr.id, pos.x, pos.y, spr.x, spr.y); } }); } after('updateInput', addTweens); after('update', addTweens); // before drawing, update sprite positions to tweened values before('drawRoom', function () { Object.entries(tweens).forEach(function (entry) { var tween = entry[1]; var t = hackOptions.ease(Math.min(1, (bitsy.prevTime - tween.start) / hackOptions.duration)); var sprite = bitsy.sprite[entry[0]]; sprite.x = tween.fromX + (tween.toX - tween.fromX) * t; sprite.y = tween.fromY + (tween.toY - tween.fromY) * t; }); }); // after drawing, update sprite positions back to normal after('drawRoom', function () { Object.entries(tweens).forEach(function (entry) { var tween = entry[1]; var sprite = bitsy.sprite[entry[0]]; sprite.x = tween.toX; sprite.y = tween.toY; }); }); /** ๐Ÿ @file transparent sprites @summary makes all sprites have transparent backgrounds @license MIT @version 4.0.4 @requires Bitsy Version: 6.1 @author Sean S. LeBlanc @description Makes all sprites have transparent backgrounds. i.e. tiles can be seen underneath the player, sprites, and items. HOW TO USE: 1. Copy-paste this script into a script tag after the bitsy source 2. Edit hackOptions below as needed */ var hackOptions$1 = { isTransparent: function (drawing) { //return drawing.name == 'tea'; // specific transparent drawing //return ['tea', 'flower', 'hat'].indexOf(drawing.name) !== -1; // specific transparent drawing list //return drawing.name && drawing.name.indexOf('TRANSPARENT') !== -1; // transparent drawing flag in name return true; // all drawings are transparent }, }; var madeTransparent; var makeTransparent; before('onready', function() { madeTransparent = {}; makeTransparent = false; }); before('renderer.GetImage', function (drawing, paletteId, frameOverride) { // check cache first var cache = madeTransparent[drawing.drw] = madeTransparent[drawing.drw] || {}; var p = cache[paletteId] = cache[paletteId] || {}; var frameIndex = frameOverride || drawing.animation.frameIndex; var source = bitsy.renderer.GetImageSource(drawing.drw); if (p[frameIndex] === source) { // already made this transparent return; } // flag the next draw as needing to be made transparent p[frameIndex] = source; makeTransparent = hackOptions$1.isTransparent(drawing); }); before('drawTile', function (canvas) { if (makeTransparent) { // redraw with all bg pixels transparent var ctx = canvas.getContext('2d'); var data = ctx.getImageData(0, 0, canvas.width, canvas.height); var bg = bitsy.getPal(bitsy.getRoomPal(bitsy.player().room))[0]; for (let i = 0; i < data.data.length; i += 4) { var r = data.data[i]; var g = data.data[i + 1]; var b = data.data[i + 2]; if (r === bg[0] && g === bg[1] && b === bg[2]) { data.data[i + 3] = 0; } } ctx.putImageData(data, 0, 0); // clear the flag makeTransparent = false; } }); Array.prototype.flat||Object.defineProperty(Array.prototype,"flat",{configurable:!0,value:function r(){var t=isNaN(arguments[0])?1:Number(arguments[0]);return t?Array.prototype.reduce.call(this,function(a,e){return Array.isArray(e)?a.push.apply(a,r.call(e,t-1)):a.push(e),a},[]):Array.prototype.slice.call(this)},writable:!0}),Array.prototype.flatMap||Object.defineProperty(Array.prototype,"flatMap",{configurable:!0,value:function(r){return Array.prototype.map.apply(this,arguments).flat()},writable:!0}); var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function unwrapExports (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } function createCommonjsModule(fn, module) { return module = { exports: {} }, fn(module, module.exports), module.exports; } var babylon = createCommonjsModule(function (module, exports) { !function(e,t){module.exports=t();}("undefined"!=typeof self?self:"undefined"!=typeof commonjsGlobal?commonjsGlobal:commonjsGlobal,function(){return function(e){var t={};function i(n){if(t[n])return t[n].exports;var r=t[n]={i:n,l:!1,exports:{}};return e[n].call(r.exports,r,r.exports,i),r.l=!0,r.exports}return i.m=e,i.c=t,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n});},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0});},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)i.d(n,r,function(t){return e[t]}.bind(null,r));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i(i.s=129)}([function(e,t,i){i.d(t,"u",function(){return s}),i.d(t,"v",function(){return a}),i.d(t,"h",function(){return c}),i.d(t,"e",function(){return l}),i.d(t,"f",function(){return u}),i.d(t,"w",function(){return h}),i.d(t,"x",function(){return d}),i.d(t,"y",function(){return f}),i.d(t,"r",function(){return p}),i.d(t,"q",function(){return _}),i.d(t,"j",function(){return g}),i.d(t,"n",function(){return m}),i.d(t,"z",function(){return v}),i.d(t,"i",function(){return y}),i.d(t,"s",function(){return n}),i.d(t,"c",function(){return T}),i.d(t,"d",function(){return E}),i.d(t,"k",function(){return b}),i.d(t,"a",function(){return A}),i.d(t,"b",function(){return x}),i.d(t,"l",function(){return R}),i.d(t,"m",function(){return P}),i.d(t,"g",function(){return S}),i.d(t,"p",function(){return C}),i.d(t,"o",function(){return M}),i.d(t,"t",function(){return O});var n,r=i(34),o=i(12),s=1/2.2,a=2.2,c=.001,l=function(){function e(e,t,i){void 0===e&&(e=0),void 0===t&&(t=0),void 0===i&&(i=0),this.r=e,this.g=t,this.b=i;}return e.prototype.toString=function(){return "{R: "+this.r+" G:"+this.g+" B:"+this.b+"}"},e.prototype.getClassName=function(){return "Color3"},e.prototype.getHashCode=function(){var e=this.r||0;return e=397*(e=397*e^(this.g||0))^(this.b||0)},e.prototype.toArray=function(e,t){return void 0===t&&(t=0),e[t]=this.r,e[t+1]=this.g,e[t+2]=this.b,this},e.prototype.toColor4=function(e){return void 0===e&&(e=1),new u(this.r,this.g,this.b,e)},e.prototype.asArray=function(){var e=new Array;return this.toArray(e,0),e},e.prototype.toLuminance=function(){return .3*this.r+.59*this.g+.11*this.b},e.prototype.multiply=function(t){return new e(this.r*t.r,this.g*t.g,this.b*t.b)},e.prototype.multiplyToRef=function(e,t){return t.r=this.r*e.r,t.g=this.g*e.g,t.b=this.b*e.b,this},e.prototype.equals=function(e){return e&&this.r===e.r&&this.g===e.g&&this.b===e.b},e.prototype.equalsFloats=function(e,t,i){return this.r===e&&this.g===t&&this.b===i},e.prototype.scale=function(t){return new e(this.r*t,this.g*t,this.b*t)},e.prototype.scaleToRef=function(e,t){return t.r=this.r*e,t.g=this.g*e,t.b=this.b*e,this},e.prototype.scaleAndAddToRef=function(e,t){return t.r+=this.r*e,t.g+=this.g*e,t.b+=this.b*e,this},e.prototype.clampToRef=function(e,t,i){return void 0===e&&(e=0),void 0===t&&(t=1),i.r=o.a.Clamp(this.r,e,t),i.g=o.a.Clamp(this.g,e,t),i.b=o.a.Clamp(this.b,e,t),this},e.prototype.add=function(t){return new e(this.r+t.r,this.g+t.g,this.b+t.b)},e.prototype.addToRef=function(e,t){return t.r=this.r+e.r,t.g=this.g+e.g,t.b=this.b+e.b,this},e.prototype.subtract=function(t){return new e(this.r-t.r,this.g-t.g,this.b-t.b)},e.prototype.subtractToRef=function(e,t){return t.r=this.r-e.r,t.g=this.g-e.g,t.b=this.b-e.b,this},e.prototype.clone=function(){return new e(this.r,this.g,this.b)},e.prototype.copyFrom=function(e){return this.r=e.r,this.g=e.g,this.b=e.b,this},e.prototype.copyFromFloats=function(e,t,i){return this.r=e,this.g=t,this.b=i,this},e.prototype.set=function(e,t,i){return this.copyFromFloats(e,t,i)},e.prototype.toHexString=function(){var e=255*this.r|0,t=255*this.g|0,i=255*this.b|0;return "#"+o.a.ToHex(e)+o.a.ToHex(t)+o.a.ToHex(i)},e.prototype.toLinearSpace=function(){var t=new e;return this.toLinearSpaceToRef(t),t},e.prototype.toLinearSpaceToRef=function(e){return e.r=Math.pow(this.r,a),e.g=Math.pow(this.g,a),e.b=Math.pow(this.b,a),this},e.prototype.toGammaSpace=function(){var t=new e;return this.toGammaSpaceToRef(t),t},e.prototype.toGammaSpaceToRef=function(e){return e.r=Math.pow(this.r,s),e.g=Math.pow(this.g,s),e.b=Math.pow(this.b,s),this},e.FromHexString=function(t){if("#"!==t.substring(0,1)||7!==t.length)return new e(0,0,0);var i=parseInt(t.substring(1,3),16),n=parseInt(t.substring(3,5),16),r=parseInt(t.substring(5,7),16);return e.FromInts(i,n,r)},e.FromArray=function(t,i){return void 0===i&&(i=0),new e(t[i],t[i+1],t[i+2])},e.FromInts=function(t,i,n){return new e(t/255,i/255,n/255)},e.Lerp=function(t,i,n){var r=new e(0,0,0);return e.LerpToRef(t,i,n,r),r},e.LerpToRef=function(e,t,i,n){n.r=e.r+(t.r-e.r)*i,n.g=e.g+(t.g-e.g)*i,n.b=e.b+(t.b-e.b)*i;},e.Red=function(){return new e(1,0,0)},e.Green=function(){return new e(0,1,0)},e.Blue=function(){return new e(0,0,1)},e.Black=function(){return new e(0,0,0)},Object.defineProperty(e,"BlackReadOnly",{get:function(){return e._BlackReadOnly},enumerable:!0,configurable:!0}),e.White=function(){return new e(1,1,1)},e.Purple=function(){return new e(.5,0,.5)},e.Magenta=function(){return new e(1,0,1)},e.Yellow=function(){return new e(1,1,0)},e.Gray=function(){return new e(.5,.5,.5)},e.Teal=function(){return new e(0,1,1)},e.Random=function(){return new e(Math.random(),Math.random(),Math.random())},e._BlackReadOnly=e.Black(),e}(),u=function(){function e(e,t,i,n){void 0===e&&(e=0),void 0===t&&(t=0),void 0===i&&(i=0),void 0===n&&(n=1),this.r=e,this.g=t,this.b=i,this.a=n;}return e.prototype.addInPlace=function(e){return this.r+=e.r,this.g+=e.g,this.b+=e.b,this.a+=e.a,this},e.prototype.asArray=function(){var e=new Array;return this.toArray(e,0),e},e.prototype.toArray=function(e,t){return void 0===t&&(t=0),e[t]=this.r,e[t+1]=this.g,e[t+2]=this.b,e[t+3]=this.a,this},e.prototype.equals=function(e){return e&&this.r===e.r&&this.g===e.g&&this.b===e.b&&this.a===e.a},e.prototype.add=function(t){return new e(this.r+t.r,this.g+t.g,this.b+t.b,this.a+t.a)},e.prototype.subtract=function(t){return new e(this.r-t.r,this.g-t.g,this.b-t.b,this.a-t.a)},e.prototype.subtractToRef=function(e,t){return t.r=this.r-e.r,t.g=this.g-e.g,t.b=this.b-e.b,t.a=this.a-e.a,this},e.prototype.scale=function(t){return new e(this.r*t,this.g*t,this.b*t,this.a*t)},e.prototype.scaleToRef=function(e,t){return t.r=this.r*e,t.g=this.g*e,t.b=this.b*e,t.a=this.a*e,this},e.prototype.scaleAndAddToRef=function(e,t){return t.r+=this.r*e,t.g+=this.g*e,t.b+=this.b*e,t.a+=this.a*e,this},e.prototype.clampToRef=function(e,t,i){return void 0===e&&(e=0),void 0===t&&(t=1),i.r=o.a.Clamp(this.r,e,t),i.g=o.a.Clamp(this.g,e,t),i.b=o.a.Clamp(this.b,e,t),i.a=o.a.Clamp(this.a,e,t),this},e.prototype.multiply=function(t){return new e(this.r*t.r,this.g*t.g,this.b*t.b,this.a*t.a)},e.prototype.multiplyToRef=function(e,t){return t.r=this.r*e.r,t.g=this.g*e.g,t.b=this.b*e.b,t.a=this.a*e.a,t},e.prototype.toString=function(){return "{R: "+this.r+" G:"+this.g+" B:"+this.b+" A:"+this.a+"}"},e.prototype.getClassName=function(){return "Color4"},e.prototype.getHashCode=function(){var e=this.r||0;return e=397*(e=397*(e=397*e^(this.g||0))^(this.b||0))^(this.a||0)},e.prototype.clone=function(){return new e(this.r,this.g,this.b,this.a)},e.prototype.copyFrom=function(e){return this.r=e.r,this.g=e.g,this.b=e.b,this.a=e.a,this},e.prototype.copyFromFloats=function(e,t,i,n){return this.r=e,this.g=t,this.b=i,this.a=n,this},e.prototype.set=function(e,t,i,n){return this.copyFromFloats(e,t,i,n)},e.prototype.toHexString=function(){var e=255*this.r|0,t=255*this.g|0,i=255*this.b|0,n=255*this.a|0;return "#"+o.a.ToHex(e)+o.a.ToHex(t)+o.a.ToHex(i)+o.a.ToHex(n)},e.prototype.toLinearSpace=function(){var t=new e;return this.toLinearSpaceToRef(t),t},e.prototype.toLinearSpaceToRef=function(e){return e.r=Math.pow(this.r,a),e.g=Math.pow(this.g,a),e.b=Math.pow(this.b,a),e.a=this.a,this},e.prototype.toGammaSpace=function(){var t=new e;return this.toGammaSpaceToRef(t),t},e.prototype.toGammaSpaceToRef=function(e){return e.r=Math.pow(this.r,s),e.g=Math.pow(this.g,s),e.b=Math.pow(this.b,s),e.a=this.a,this},e.FromHexString=function(t){if("#"!==t.substring(0,1)||9!==t.length)return new e(0,0,0,0);var i=parseInt(t.substring(1,3),16),n=parseInt(t.substring(3,5),16),r=parseInt(t.substring(5,7),16),o=parseInt(t.substring(7,9),16);return e.FromInts(i,n,r,o)},e.Lerp=function(t,i,n){var r=new e(0,0,0,0);return e.LerpToRef(t,i,n,r),r},e.LerpToRef=function(e,t,i,n){n.r=e.r+(t.r-e.r)*i,n.g=e.g+(t.g-e.g)*i,n.b=e.b+(t.b-e.b)*i,n.a=e.a+(t.a-e.a)*i;},e.FromColor3=function(t,i){return void 0===i&&(i=1),new e(t.r,t.g,t.b,i)},e.FromArray=function(t,i){return void 0===i&&(i=0),new e(t[i],t[i+1],t[i+2],t[i+3])},e.FromInts=function(t,i,n,r){return new e(t/255,i/255,n/255,r/255)},e.CheckColors4=function(e,t){if(e.length===3*t){for(var i=[],n=0;n<e.length;n+=3){var r=n/3*4;i[r]=e[n],i[r+1]=e[n+1],i[r+2]=e[n+2],i[r+3]=1;}return i}return e},e}(),h=function(){function e(e,t){void 0===e&&(e=0),void 0===t&&(t=0),this.x=e,this.y=t;}return e.prototype.toString=function(){return "{X: "+this.x+" Y:"+this.y+"}"},e.prototype.getClassName=function(){return "Vector2"},e.prototype.getHashCode=function(){var e=this.x||0;return e=397*e^(this.y||0)},e.prototype.toArray=function(e,t){return void 0===t&&(t=0),e[t]=this.x,e[t+1]=this.y,this},e.prototype.asArray=function(){var e=new Array;return this.toArray(e,0),e},e.prototype.copyFrom=function(e){return this.x=e.x,this.y=e.y,this},e.prototype.copyFromFloats=function(e,t){return this.x=e,this.y=t,this},e.prototype.set=function(e,t){return this.copyFromFloats(e,t)},e.prototype.add=function(t){return new e(this.x+t.x,this.y+t.y)},e.prototype.addToRef=function(e,t){return t.x=this.x+e.x,t.y=this.y+e.y,this},e.prototype.addInPlace=function(e){return this.x+=e.x,this.y+=e.y,this},e.prototype.addVector3=function(t){return new e(this.x+t.x,this.y+t.y)},e.prototype.subtract=function(t){return new e(this.x-t.x,this.y-t.y)},e.prototype.subtractToRef=function(e,t){return t.x=this.x-e.x,t.y=this.y-e.y,this},e.prototype.subtractInPlace=function(e){return this.x-=e.x,this.y-=e.y,this},e.prototype.multiplyInPlace=function(e){return this.x*=e.x,this.y*=e.y,this},e.prototype.multiply=function(t){return new e(this.x*t.x,this.y*t.y)},e.prototype.multiplyToRef=function(e,t){return t.x=this.x*e.x,t.y=this.y*e.y,this},e.prototype.multiplyByFloats=function(t,i){return new e(this.x*t,this.y*i)},e.prototype.divide=function(t){return new e(this.x/t.x,this.y/t.y)},e.prototype.divideToRef=function(e,t){return t.x=this.x/e.x,t.y=this.y/e.y,this},e.prototype.divideInPlace=function(e){return this.divideToRef(e,this)},e.prototype.negate=function(){return new e(-this.x,-this.y)},e.prototype.scaleInPlace=function(e){return this.x*=e,this.y*=e,this},e.prototype.scale=function(t){var i=new e(0,0);return this.scaleToRef(t,i),i},e.prototype.scaleToRef=function(e,t){return t.x=this.x*e,t.y=this.y*e,this},e.prototype.scaleAndAddToRef=function(e,t){return t.x+=this.x*e,t.y+=this.y*e,this},e.prototype.equals=function(e){return e&&this.x===e.x&&this.y===e.y},e.prototype.equalsWithEpsilon=function(e,t){return void 0===t&&(t=c),e&&o.a.WithinEpsilon(this.x,e.x,t)&&o.a.WithinEpsilon(this.y,e.y,t)},e.prototype.floor=function(){return new e(Math.floor(this.x),Math.floor(this.y))},e.prototype.fract=function(){return new e(this.x-Math.floor(this.x),this.y-Math.floor(this.y))},e.prototype.length=function(){return Math.sqrt(this.x*this.x+this.y*this.y)},e.prototype.lengthSquared=function(){return this.x*this.x+this.y*this.y},e.prototype.normalize=function(){var e=this.length();if(0===e)return this;var t=1/e;return this.x*=t,this.y*=t,this},e.prototype.clone=function(){return new e(this.x,this.y)},e.Zero=function(){return new e(0,0)},e.One=function(){return new e(1,1)},e.FromArray=function(t,i){return void 0===i&&(i=0),new e(t[i],t[i+1])},e.FromArrayToRef=function(e,t,i){i.x=e[t],i.y=e[t+1];},e.CatmullRom=function(t,i,n,r,o){var s=o*o,a=o*s;return new e(.5*(2*i.x+(-t.x+n.x)*o+(2*t.x-5*i.x+4*n.x-r.x)*s+(-t.x+3*i.x-3*n.x+r.x)*a),.5*(2*i.y+(-t.y+n.y)*o+(2*t.y-5*i.y+4*n.y-r.y)*s+(-t.y+3*i.y-3*n.y+r.y)*a))},e.Clamp=function(t,i,n){var r=t.x;r=(r=r>n.x?n.x:r)<i.x?i.x:r;var o=t.y;return new e(r,o=(o=o>n.y?n.y:o)<i.y?i.y:o)},e.Hermite=function(t,i,n,r,o){var s=o*o,a=o*s,c=2*a-3*s+1,l=-2*a+3*s,u=a-2*s+o,h=a-s;return new e(t.x*c+n.x*l+i.x*u+r.x*h,t.y*c+n.y*l+i.y*u+r.y*h)},e.Lerp=function(t,i,n){return new e(t.x+(i.x-t.x)*n,t.y+(i.y-t.y)*n)},e.Dot=function(e,t){return e.x*t.x+e.y*t.y},e.Normalize=function(e){var t=e.clone();return t.normalize(),t},e.Minimize=function(t,i){return new e(t.x<i.x?t.x:i.x,t.y<i.y?t.y:i.y)},e.Maximize=function(t,i){return new e(t.x>i.x?t.x:i.x,t.y>i.y?t.y:i.y)},e.Transform=function(t,i){var n=e.Zero();return e.TransformToRef(t,i,n),n},e.TransformToRef=function(e,t,i){var n=t.m,r=e.x*n[0]+e.y*n[4]+n[12],o=e.x*n[1]+e.y*n[5]+n[13];i.x=r,i.y=o;},e.PointInTriangle=function(e,t,i,n){var r=.5*(-i.y*n.x+t.y*(-i.x+n.x)+t.x*(i.y-n.y)+i.x*n.y),o=r<0?-1:1,s=(t.y*n.x-t.x*n.y+(n.y-t.y)*e.x+(t.x-n.x)*e.y)*o,a=(t.x*i.y-t.y*i.x+(t.y-i.y)*e.x+(i.x-t.x)*e.y)*o;return s>0&&a>0&&s+a<2*r*o},e.Distance=function(t,i){return Math.sqrt(e.DistanceSquared(t,i))},e.DistanceSquared=function(e,t){var i=e.x-t.x,n=e.y-t.y;return i*i+n*n},e.Center=function(e,t){var i=e.add(t);return i.scaleInPlace(.5),i},e.DistanceOfPointFromSegment=function(t,i,n){var r=e.DistanceSquared(i,n);if(0===r)return e.Distance(t,i);var o=n.subtract(i),s=Math.max(0,Math.min(1,e.Dot(t.subtract(i),o)/r)),a=i.add(o.multiplyByFloats(s,s));return e.Distance(t,a)},e}(),d=function(){function e(e,t,i){void 0===e&&(e=0),void 0===t&&(t=0),void 0===i&&(i=0),this.x=e,this.y=t,this.z=i;}return e.prototype.toString=function(){return "{X: "+this.x+" Y:"+this.y+" Z:"+this.z+"}"},e.prototype.getClassName=function(){return "Vector3"},e.prototype.getHashCode=function(){var e=this.x||0;return e=397*(e=397*e^(this.y||0))^(this.z||0)},e.prototype.asArray=function(){var e=[];return this.toArray(e,0),e},e.prototype.toArray=function(e,t){return void 0===t&&(t=0),e[t]=this.x,e[t+1]=this.y,e[t+2]=this.z,this},e.prototype.toQuaternion=function(){return _.RotationYawPitchRoll(this.y,this.x,this.z)},e.prototype.addInPlace=function(e){return this.addInPlaceFromFloats(e.x,e.y,e.z)},e.prototype.addInPlaceFromFloats=function(e,t,i){return this.x+=e,this.y+=t,this.z+=i,this},e.prototype.add=function(t){return new e(this.x+t.x,this.y+t.y,this.z+t.z)},e.prototype.addToRef=function(e,t){return t.copyFromFloats(this.x+e.x,this.y+e.y,this.z+e.z)},e.prototype.subtractInPlace=function(e){return this.x-=e.x,this.y-=e.y,this.z-=e.z,this},e.prototype.subtract=function(t){return new e(this.x-t.x,this.y-t.y,this.z-t.z)},e.prototype.subtractToRef=function(e,t){return this.subtractFromFloatsToRef(e.x,e.y,e.z,t)},e.prototype.subtractFromFloats=function(t,i,n){return new e(this.x-t,this.y-i,this.z-n)},e.prototype.subtractFromFloatsToRef=function(e,t,i,n){return n.copyFromFloats(this.x-e,this.y-t,this.z-i)},e.prototype.negate=function(){return new e(-this.x,-this.y,-this.z)},e.prototype.scaleInPlace=function(e){return this.x*=e,this.y*=e,this.z*=e,this},e.prototype.scale=function(t){return new e(this.x*t,this.y*t,this.z*t)},e.prototype.scaleToRef=function(e,t){return t.copyFromFloats(this.x*e,this.y*e,this.z*e)},e.prototype.scaleAndAddToRef=function(e,t){return t.addInPlaceFromFloats(this.x*e,this.y*e,this.z*e)},e.prototype.equals=function(e){return e&&this.x===e.x&&this.y===e.y&&this.z===e.z},e.prototype.equalsWithEpsilon=function(e,t){return void 0===t&&(t=c),e&&o.a.WithinEpsilon(this.x,e.x,t)&&o.a.WithinEpsilon(this.y,e.y,t)&&o.a.WithinEpsilon(this.z,e.z,t)},e.prototype.equalsToFloats=function(e,t,i){return this.x===e&&this.y===t&&this.z===i},e.prototype.multiplyInPlace=function(e){return this.x*=e.x,this.y*=e.y,this.z*=e.z,this},e.prototype.multiply=function(e){return this.multiplyByFloats(e.x,e.y,e.z)},e.prototype.multiplyToRef=function(e,t){return t.copyFromFloats(this.x*e.x,this.y*e.y,this.z*e.z)},e.prototype.multiplyByFloats=function(t,i,n){return new e(this.x*t,this.y*i,this.z*n)},e.prototype.divide=function(t){return new e(this.x/t.x,this.y/t.y,this.z/t.z)},e.prototype.divideToRef=function(e,t){return t.copyFromFloats(this.x/e.x,this.y/e.y,this.z/e.z)},e.prototype.divideInPlace=function(e){return this.divideToRef(e,this)},e.prototype.minimizeInPlace=function(e){return this.minimizeInPlaceFromFloats(e.x,e.y,e.z)},e.prototype.maximizeInPlace=function(e){return this.maximizeInPlaceFromFloats(e.x,e.y,e.z)},e.prototype.minimizeInPlaceFromFloats=function(e,t,i){return e<this.x&&(this.x=e),t<this.y&&(this.y=t),i<this.z&&(this.z=i),this},e.prototype.maximizeInPlaceFromFloats=function(e,t,i){return e>this.x&&(this.x=e),t>this.y&&(this.y=t),i>this.z&&(this.z=i),this},e.prototype.isNonUniformWithinEpsilon=function(e){var t=Math.abs(this.x),i=Math.abs(this.y);if(!o.a.WithinEpsilon(t,i,e))return !0;var n=Math.abs(this.z);return !o.a.WithinEpsilon(t,n,e)||!o.a.WithinEpsilon(i,n,e)},Object.defineProperty(e.prototype,"isNonUniform",{get:function(){var e=Math.abs(this.x),t=Math.abs(this.y);if(e!==t)return !0;var i=Math.abs(this.z);return e!==i||t!==i},enumerable:!0,configurable:!0}),e.prototype.floor=function(){return new e(Math.floor(this.x),Math.floor(this.y),Math.floor(this.z))},e.prototype.fract=function(){return new e(this.x-Math.floor(this.x),this.y-Math.floor(this.y),this.z-Math.floor(this.z))},e.prototype.length=function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)},e.prototype.lengthSquared=function(){return this.x*this.x+this.y*this.y+this.z*this.z},e.prototype.normalize=function(){return this.normalizeFromLength(this.length())},e.prototype.reorderInPlace=function(e){var t=this;return "xyz"===(e=e.toLowerCase())?this:(I.Vector3[0].copyFrom(this),["x","y","z"].forEach(function(i,n){t[i]=I.Vector3[0][e[n]];}),this)},e.prototype.rotateByQuaternionToRef=function(t,i){return t.toRotationMatrix(I.Matrix[0]),e.TransformCoordinatesToRef(this,I.Matrix[0],i),i},e.prototype.rotateByQuaternionAroundPointToRef=function(e,t,i){return this.subtractToRef(t,I.Vector3[0]),I.Vector3[0].rotateByQuaternionToRef(e,I.Vector3[0]),t.addToRef(I.Vector3[0],i),i},e.prototype.normalizeFromLength=function(e){return 0===e||1===e?this:this.scaleInPlace(1/e)},e.prototype.normalizeToNew=function(){var t=new e(0,0,0);return this.normalizeToRef(t),t},e.prototype.normalizeToRef=function(e){var t=this.length();return 0===t||1===t?e.copyFromFloats(this.x,this.y,this.z):this.scaleToRef(1/t,e)},e.prototype.clone=function(){return new e(this.x,this.y,this.z)},e.prototype.copyFrom=function(e){return this.copyFromFloats(e.x,e.y,e.z)},e.prototype.copyFromFloats=function(e,t,i){return this.x=e,this.y=t,this.z=i,this},e.prototype.set=function(e,t,i){return this.copyFromFloats(e,t,i)},e.prototype.setAll=function(e){return this.x=this.y=this.z=e,this},e.GetClipFactor=function(t,i,n,r){var o=e.Dot(t,n)-r;return o/(o-(e.Dot(i,n)-r))},e.GetAngleBetweenVectors=function(t,i,n){var r=t.normalizeToRef(I.Vector3[1]),o=i.normalizeToRef(I.Vector3[2]),s=e.Dot(r,o),a=I.Vector3[3];return e.CrossToRef(r,o,a),e.Dot(a,n)>0?Math.acos(s):-Math.acos(s)},e.FromArray=function(t,i){return void 0===i&&(i=0),new e(t[i],t[i+1],t[i+2])},e.FromFloatArray=function(t,i){return e.FromArray(t,i)},e.FromArrayToRef=function(e,t,i){i.x=e[t],i.y=e[t+1],i.z=e[t+2];},e.FromFloatArrayToRef=function(t,i,n){return e.FromArrayToRef(t,i,n)},e.FromFloatsToRef=function(e,t,i,n){n.copyFromFloats(e,t,i);},e.Zero=function(){return new e(0,0,0)},e.One=function(){return new e(1,1,1)},e.Up=function(){return new e(0,1,0)},Object.defineProperty(e,"UpReadOnly",{get:function(){return e._UpReadOnly},enumerable:!0,configurable:!0}),e.Down=function(){return new e(0,-1,0)},e.Forward=function(){return new e(0,0,1)},e.Backward=function(){return new e(0,0,-1)},e.Right=function(){return new e(1,0,0)},e.Left=function(){return new e(-1,0,0)},e.TransformCoordinates=function(t,i){var n=e.Zero();return e.TransformCoordinatesToRef(t,i,n),n},e.TransformCoordinatesToRef=function(t,i,n){e.TransformCoordinatesFromFloatsToRef(t.x,t.y,t.z,i,n);},e.TransformCoordinatesFromFloatsToRef=function(e,t,i,n,r){var o=n.m,s=e*o[0]+t*o[4]+i*o[8]+o[12],a=e*o[1]+t*o[5]+i*o[9]+o[13],c=e*o[2]+t*o[6]+i*o[10]+o[14],l=1/(e*o[3]+t*o[7]+i*o[11]+o[15]);r.x=s*l,r.y=a*l,r.z=c*l;},e.TransformNormal=function(t,i){var n=e.Zero();return e.TransformNormalToRef(t,i,n),n},e.TransformNormalToRef=function(e,t,i){this.TransformNormalFromFloatsToRef(e.x,e.y,e.z,t,i);},e.TransformNormalFromFloatsToRef=function(e,t,i,n,r){var o=n.m;r.x=e*o[0]+t*o[4]+i*o[8],r.y=e*o[1]+t*o[5]+i*o[9],r.z=e*o[2]+t*o[6]+i*o[10];},e.CatmullRom=function(t,i,n,r,o){var s=o*o,a=o*s;return new e(.5*(2*i.x+(-t.x+n.x)*o+(2*t.x-5*i.x+4*n.x-r.x)*s+(-t.x+3*i.x-3*n.x+r.x)*a),.5*(2*i.y+(-t.y+n.y)*o+(2*t.y-5*i.y+4*n.y-r.y)*s+(-t.y+3*i.y-3*n.y+r.y)*a),.5*(2*i.z+(-t.z+n.z)*o+(2*t.z-5*i.z+4*n.z-r.z)*s+(-t.z+3*i.z-3*n.z+r.z)*a))},e.Clamp=function(t,i,n){var r=new e;return e.ClampToRef(t,i,n,r),r},e.ClampToRef=function(e,t,i,n){var r=e.x;r=(r=r>i.x?i.x:r)<t.x?t.x:r;var o=e.y;o=(o=o>i.y?i.y:o)<t.y?t.y:o;var s=e.z;s=(s=s>i.z?i.z:s)<t.z?t.z:s,n.copyFromFloats(r,o,s);},e.Hermite=function(t,i,n,r,o){var s=o*o,a=o*s,c=2*a-3*s+1,l=-2*a+3*s,u=a-2*s+o,h=a-s;return new e(t.x*c+n.x*l+i.x*u+r.x*h,t.y*c+n.y*l+i.y*u+r.y*h,t.z*c+n.z*l+i.z*u+r.z*h)},e.Lerp=function(t,i,n){var r=new e(0,0,0);return e.LerpToRef(t,i,n,r),r},e.LerpToRef=function(e,t,i,n){n.x=e.x+(t.x-e.x)*i,n.y=e.y+(t.y-e.y)*i,n.z=e.z+(t.z-e.z)*i;},e.Dot=function(e,t){return e.x*t.x+e.y*t.y+e.z*t.z},e.Cross=function(t,i){var n=e.Zero();return e.CrossToRef(t,i,n),n},e.CrossToRef=function(e,t,i){var n=e.y*t.z-e.z*t.y,r=e.z*t.x-e.x*t.z,o=e.x*t.y-e.y*t.x;i.copyFromFloats(n,r,o);},e.Normalize=function(t){var i=e.Zero();return e.NormalizeToRef(t,i),i},e.NormalizeToRef=function(e,t){e.normalizeToRef(t);},e.Project=function(t,i,n,r){var o=r.width,s=r.height,a=r.x,c=r.y,l=I.Matrix[1];g.FromValuesToRef(o/2,0,0,0,0,-s/2,0,0,0,0,.5,0,a+o/2,s/2+c,.5,1,l);var u=I.Matrix[0];return i.multiplyToRef(n,u),u.multiplyToRef(l,u),e.TransformCoordinates(t,u)},e._UnprojectFromInvertedMatrixToRef=function(t,i,n){e.TransformCoordinatesToRef(t,i,n);var r=i.m,s=t.x*r[3]+t.y*r[7]+t.z*r[11]+r[15];o.a.WithinEpsilon(s,1)&&n.scaleInPlace(1/s);},e.UnprojectFromTransform=function(t,i,n,r,o){var s=I.Matrix[0];r.multiplyToRef(o,s),s.invert(),t.x=t.x/i*2-1,t.y=-(t.y/n*2-1);var a=new e;return e._UnprojectFromInvertedMatrixToRef(t,s,a),a},e.Unproject=function(t,i,n,r,o,s){var a=e.Zero();return e.UnprojectToRef(t,i,n,r,o,s,a),a},e.UnprojectToRef=function(t,i,n,r,o,s,a){e.UnprojectFloatsToRef(t.x,t.y,t.z,i,n,r,o,s,a);},e.UnprojectFloatsToRef=function(t,i,n,r,o,s,a,c,l){var u=I.Matrix[0];s.multiplyToRef(a,u),u.multiplyToRef(c,u),u.invert();var h=I.Vector3[0];h.x=t/r*2-1,h.y=-(i/o*2-1),h.z=2*n-1,e._UnprojectFromInvertedMatrixToRef(h,u,l);},e.Minimize=function(e,t){var i=e.clone();return i.minimizeInPlace(t),i},e.Maximize=function(e,t){var i=e.clone();return i.maximizeInPlace(t),i},e.Distance=function(t,i){return Math.sqrt(e.DistanceSquared(t,i))},e.DistanceSquared=function(e,t){var i=e.x-t.x,n=e.y-t.y,r=e.z-t.z;return i*i+n*n+r*r},e.Center=function(e,t){var i=e.add(t);return i.scaleInPlace(.5),i},e.RotationFromAxis=function(t,i,n){var r=e.Zero();return e.RotationFromAxisToRef(t,i,n,r),r},e.RotationFromAxisToRef=function(e,t,i,n){var r=I.Quaternion[0];_.RotationQuaternionFromAxisToRef(e,t,i,r),r.toEulerAnglesToRef(n);},e._UpReadOnly=e.Up(),e}(),f=function(){function e(e,t,i,n){this.x=e,this.y=t,this.z=i,this.w=n;}return e.prototype.toString=function(){return "{X: "+this.x+" Y:"+this.y+" Z:"+this.z+" W:"+this.w+"}"},e.prototype.getClassName=function(){return "Vector4"},e.prototype.getHashCode=function(){var e=this.x||0;return e=397*(e=397*(e=397*e^(this.y||0))^(this.z||0))^(this.w||0)},e.prototype.asArray=function(){var e=new Array;return this.toArray(e,0),e},e.prototype.toArray=function(e,t){return void 0===t&&(t=0),e[t]=this.x,e[t+1]=this.y,e[t+2]=this.z,e[t+3]=this.w,this},e.prototype.addInPlace=function(e){return this.x+=e.x,this.y+=e.y,this.z+=e.z,this.w+=e.w,this},e.prototype.add=function(t){return new e(this.x+t.x,this.y+t.y,this.z+t.z,this.w+t.w)},e.prototype.addToRef=function(e,t){return t.x=this.x+e.x,t.y=this.y+e.y,t.z=this.z+e.z,t.w=this.w+e.w,this},e.prototype.subtractInPlace=function(e){return this.x-=e.x,this.y-=e.y,this.z-=e.z,this.w-=e.w,this},e.prototype.subtract=function(t){return new e(this.x-t.x,this.y-t.y,this.z-t.z,this.w-t.w)},e.prototype.subtractToRef=function(e,t){return t.x=this.x-e.x,t.y=this.y-e.y,t.z=this.z-e.z,t.w=this.w-e.w,this},e.prototype.subtractFromFloats=function(t,i,n,r){return new e(this.x-t,this.y-i,this.z-n,this.w-r)},e.prototype.subtractFromFloatsToRef=function(e,t,i,n,r){return r.x=this.x-e,r.y=this.y-t,r.z=this.z-i,r.w=this.w-n,this},e.prototype.negate=function(){return new e(-this.x,-this.y,-this.z,-this.w)},e.prototype.scaleInPlace=function(e){return this.x*=e,this.y*=e,this.z*=e,this.w*=e,this},e.prototype.scale=function(t){return new e(this.x*t,this.y*t,this.z*t,this.w*t)},e.prototype.scaleToRef=function(e,t){return t.x=this.x*e,t.y=this.y*e,t.z=this.z*e,t.w=this.w*e,this},e.prototype.scaleAndAddToRef=function(e,t){return t.x+=this.x*e,t.y+=this.y*e,t.z+=this.z*e,t.w+=this.w*e,this},e.prototype.equals=function(e){return e&&this.x===e.x&&this.y===e.y&&this.z===e.z&&this.w===e.w},e.prototype.equalsWithEpsilon=function(e,t){return void 0===t&&(t=c),e&&o.a.WithinEpsilon(this.x,e.x,t)&&o.a.WithinEpsilon(this.y,e.y,t)&&o.a.WithinEpsilon(this.z,e.z,t)&&o.a.WithinEpsilon(this.w,e.w,t)},e.prototype.equalsToFloats=function(e,t,i,n){return this.x===e&&this.y===t&&this.z===i&&this.w===n},e.prototype.multiplyInPlace=function(e){return this.x*=e.x,this.y*=e.y,this.z*=e.z,this.w*=e.w,this},e.prototype.multiply=function(t){return new e(this.x*t.x,this.y*t.y,this.z*t.z,this.w*t.w)},e.prototype.multiplyToRef=function(e,t){return t.x=this.x*e.x,t.y=this.y*e.y,t.z=this.z*e.z,t.w=this.w*e.w,this},e.prototype.multiplyByFloats=function(t,i,n,r){return new e(this.x*t,this.y*i,this.z*n,this.w*r)},e.prototype.divide=function(t){return new e(this.x/t.x,this.y/t.y,this.z/t.z,this.w/t.w)},e.prototype.divideToRef=function(e,t){return t.x=this.x/e.x,t.y=this.y/e.y,t.z=this.z/e.z,t.w=this.w/e.w,this},e.prototype.divideInPlace=function(e){return this.divideToRef(e,this)},e.prototype.minimizeInPlace=function(e){return e.x<this.x&&(this.x=e.x),e.y<this.y&&(this.y=e.y),e.z<this.z&&(this.z=e.z),e.w<this.w&&(this.w=e.w),this},e.prototype.maximizeInPlace=function(e){return e.x>this.x&&(this.x=e.x),e.y>this.y&&(this.y=e.y),e.z>this.z&&(this.z=e.z),e.w>this.w&&(this.w=e.w),this},e.prototype.floor=function(){return new e(Math.floor(this.x),Math.floor(this.y),Math.floor(this.z),Math.floor(this.w))},e.prototype.fract=function(){return new e(this.x-Math.floor(this.x),this.y-Math.floor(this.y),this.z-Math.floor(this.z),this.w-Math.floor(this.w))},e.prototype.length=function(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w)},e.prototype.lengthSquared=function(){return this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w},e.prototype.normalize=function(){var e=this.length();return 0===e?this:this.scaleInPlace(1/e)},e.prototype.toVector3=function(){return new d(this.x,this.y,this.z)},e.prototype.clone=function(){return new e(this.x,this.y,this.z,this.w)},e.prototype.