forked from Archaegeo/Archaegeo-Orbital-Hud
-
Notifications
You must be signed in to change notification settings - Fork 0
/
waypointer.json
1 lines (1 loc) · 104 KB
/
waypointer.json
1
{"slots":{"0":{"name":"core","type":{"events":[],"methods":[]}},"1":{"name":"databank","type":{"events":[],"methods":[]}},"2":{"name":"slot3","type":{"events":[],"methods":[]}},"3":{"name":"slot4","type":{"events":[],"methods":[]}},"4":{"name":"slot5","type":{"events":[],"methods":[]}},"5":{"name":"slot6","type":{"events":[],"methods":[]}},"6":{"name":"slot7","type":{"events":[],"methods":[]}},"7":{"name":"slot8","type":{"events":[],"methods":[]}},"8":{"name":"slot9","type":{"events":[],"methods":[]}},"9":{"name":"slot10","type":{"events":[],"methods":[]}},"-1":{"name":"unit","type":{"events":[],"methods":[]}},"-2":{"name":"system","type":{"events":[],"methods":[]}},"-3":{"name":"library","type":{"events":[],"methods":[]}}},"handlers":[{"code":"local sqrt, len, max, print = math.sqrt, string.len, math.max, system.print\n\nlocal highPerformanceMode = false --export: Disables glow effect which can improve FPS significantly in some cases.\nlocal glowRadius = 5 --export: Setting the pixel size of the glow effect.\nlocal loadWaypoints = true --export: Enable to load waypoints from Archaegeo's HUD's DB.\nlocal displayWarpCells = true --export: To display warp cells or not.\nlocal archHudWaypointSize = 0.01 --export: The size in meters of an ArchHud waypoint\nlocal archHudWPRender = 400 --export: The size in kilometers at which point ArchHud Waypoints do not render.\nlocal maxWaypointSize = 800 --export: The Max Size of a waypoint in pixels.\nlocal minWaypointSize = 15 --export: The min size of a waypoint in pixels.\nlocal infoHighlight = 200 --export: The number of pixels within info is displayed.\nlocal fontsize = 20 --export: font size\nlocal colorWarp = \"#ADD8E6\" --export: Colour of warpable waypoints\nlocal nonWarp = \"#FFA500\" --export: Colour of non-warpable waypoints\n\nwaypoint = false\nlocal waypointInfo = {\n {name = \"Madis\", center = {17465536,22665536,-34464}, radius=44300},\n {name = \"Alioth\", center = {-8,-8,-126303}, radius=126068},\n {name = \"Thades\", center = {29165536,10865536,65536}, radius=49000},\n {name = \"Talemai\", center = {-13234464,55765536,465536}, radius=57450},\n {name = \"Feli\", center = {-43534464,22565536,-48934464}, radius=60000},\n {name = \"Sicari\", center = {52765536,27165538,52065535}, radius=51100},\n {name = \"Sinnen\", center = {58665538,29665535,58165535}, radius=54950},\n {name = \"Teoma\", center = {80865538,54665536,-934463.94}, radius=62000},\n {name = \"Jago\", center = {-94134462,12765534,-3634464}, radius=61590},\n {name = \"Lacobus\", center = {98865536,-13534464,-934461.99}, radius=55650},\n {name = \"Symeon\", center = {14165536,-85634465,-934464.3}, radius=49050},\n {name = \"Symeon\", center = {14165536,-85634465,-934464.3}, radius=49050},\n {name = \"Ion\", center = {2865536.7,-99034464,-934462.02}, radius=44950}\n}\n\nlocal function bTW(bool)\n if bool then\n return \"enabled\"\n else\n return \"disabled\"\n end\nend\n\nprint(\"=======================\")\nprint(\"DU AR Waypoint System\")\nprint(\"=======================\")\nprint(\"Concept: Archaegeo\")\nprint(\"Coder : EasternGamer\")\nprint(\"=======================\")\nprint(\"Settings\")\nprint(\"=======================\")\nprint(\"Freelook : \" .. bTW(freelook))\nprint(\"Disp. Warp Cells: \" .. bTW(displayWarpCells))\nprint(\"Load saved WP : \" .. bTW(loadWaypoints))\nprint(\"Font Size : \" .. fontsize .. \"px\")\nprint(\"Max WP Render : \" .. archHudWPRender .. \"km\")\nprint(\"Max WP Size : \" .. maxWaypointSize .. \"px\")\nprint(\"Min WP Size : \" .. minWaypointSize .. \"px\")\nprint(\"ArchHUD WP Size : \" .. archHudWaypointSize .. \"m\")\nprint(\"Info HL Distance: \" .. infoHighlight .. \"px\")\nprint(\"=======================\")\n\nif loadWaypoints then\n if databank ~= nil then\n local getString = databank.getStringValue\n if getString ~= nil then\n local dbInfo = json.decode(getString(\"SavedLocations\"))\n if dbInfo ~= nil then\n local size = #waypointInfo\n local dbInfoSize = #dbInfo\n local c = 0\n print(\"Found \" .. dbInfoSize .. \" waypoints in databank.\")\n for i=1, #dbInfo do\n local dbEntry = dbInfo[i]\n local pos=dbEntry.position\n waypointInfo[size+c+1] = {name=dbEntry.name, center={pos.x, pos.y, pos.z}, radius=archHudWaypointSize}\n c=c+1\n end\n print(\"Loaded \" .. c .. \" waypoints.\")\n else\n print('ERROR! No data to read.')\n end\n else\n print('ERROR! Incorrect slot used for databank.')\n end\n else\n print(\"ERROR! No slot connected to databank slot.\")\n end\nend\n\nlocal position = {0,0,0}\nlocal offsetPos = {0,0,0}\nlocal orientation = {0,0,0}\nlocal width = system.getScreenWidth() / 2\nlocal height = system.getScreenHeight() / 2\nlocal objectBuilder = ObjectBuilderLinear()\n\ncamera = Camera(CameraTypes.player)\n\n--camera.setViewLock(not freelook)\nprojector = Projector(camera)\n\nwaypoints = {}\n\nlocal waypointObjectGroup = ObjectGroup()\nprojector.addObjectGroup(waypointObjectGroup)\n\nlocal css = [[\nsvg { \n stroke-width: 3; \n vertical-align:middle; \n text-anchor:start; \n fill: white; \n font-family: Refrigerator; \n font-size: ]] .. fontsize .. [[;\n}]]\n\nwaypointObjectGroup.setStyle(css)\nif not highPerformanceMode then\n waypointObjectGroup.setGlow(true, glowRadius)\nend\nlocal function drawText(content,x, y, text, opacity,uD,c,c2,stroke)\n uD[c],uD[c+1],uD[c+2],uD[c+3],uD[c+4],uD[c+5] = x,y,opacity,opacity,stroke,text\n content[c2] = '<text x=\"%g\" y=\"%g\" fill-opacity=\"%g\" stroke-opacity=\"%g\" stroke=\"%s\">%s</text>'\n return c+6,c2+1\nend\nlocal function drawHorizontalLine(content,x, y, length, thickness,dU,c,c2,stroke)\n dU[c],dU[c+1],dU[c+2],dU[c+3],dU[c+4]=thickness,stroke,x,y,length\n content[c2] = '<path fill=\"none\" stroke-width=\"%g\" stroke=\"%s\" d=\"M%g %gh%g\"/>'\n return c+5,c2+1\nend\nlocal maxD = sqrt(width*width + height*height)\nlocal function drawInfo(content,tx, ty, data,dU,c,c1,stroke,distanceToMouse)\n local font = fontsize\n local name,distance,warpCost,disKM,disM = data.getWaypointInfo()\n local keyframe = data.keyframe\n \n c,c1 = drawHorizontalLine(content, tx, ty + 3, len(name)*(font*0.6), 2,dU,c,c1,stroke)\n c,c1 = drawText(content, tx, ty, name, 1,dU,c,c1,stroke)\n \n if distanceToMouse <= infoHighlight then\n if keyframe < 6 then\n data.keyframe = keyframe + 1\n end\n else\n if keyframe ~= 0 then\n data.keyframe = keyframe - 1\n end\n end\n local opacity = keyframe/6\n if distanceToMouse < 25 and waypoint then\n system.setWaypoint('::pos{0,0,' .. data.x ..',' .. data.y .. ',' .. data.z ..'}')\n waypoint = false\n end\n if keyframe > 0 then\n local disText = ''\n if disM <=1000 then\n disText = disM .. ' M'\n elseif disKM <= 200 then\n disText = disKM .. ' KM'\n else\n disText = distance .. ' SU'\n end\n c,c1 = drawText(content, tx + 60 - keyframe*10, ty+font+5, disText, opacity,dU,c,c1,stroke)\n if displayWarpCells then\n c,c1 = drawText(content, tx + 60 - keyframe*10, ty+(font+5)*2, warpCost .. ' Warp Cells', opacity,dU,c,c1,stroke)\n end\n end\n --system.print(table.concat(content))\nend\nlocal concat = table.concat\nlocal function draw(tx,ty,tz,data,dU,c)\n local content,c1 = {},1\n local distanceToMouse = sqrt(tx*tx + ty*ty)\n local r = data.radius\n local off = (((tz/1000)/200))/100\n local size = max(projector.getSize(r, tz, 100000000, minWaypointSize) - off, 5)\n if size >= maxWaypointSize or distanceToMouse > maxD or (r==archHudWaypointSize*1.25 and tz>archHudWPRender*1000) then -- Don't display\n return ''\n end\n local stroke = colorWarp\n local _,distance = data.getWaypointInfo()\n if distance > 500 then\n stroke = nonWarp\n end\n content[c1] = '<circle cx=\"%g\" cy=\"%g\" r=\"%g\" fill=\"%s\" stroke=\"%s\"/>'\n dU[c],dU[c+1] = tx,ty\n c=c+2\n if r==archHudWaypointSize*1.25 then\n size = size /2\n dU[c] = size\n dU[c+1] = colorWarp\n else\n dU[c] = size\n dU[c+1] = 'none'\n end\n dU[c+2] = stroke\n c=c+3\n drawInfo(content, tx + size + 5, ty - size + 5, data,dU,c,c1+1,stroke,distanceToMouse)\n return concat(content)\nend\nlocal solarWaypoints = objectBuilder\n\t\t\t\t.setStyle('test')\n\t\t\t\t.setPosition({0,0,0})\n\t\t\t\t.setOffset({0,0,0})\n\t\t\t\t.setOrientation({0,0,0})\n\t\t\t\t.setPositionType(positionTypes.globalP)\n\t\t\t\t.setOrientationType(orientationTypes.globalO)\n\t\t\t\t.build()\nwaypointObjectGroup.addObject(solarWaypoints)\nlocal builder = solarWaypoints.setCustomSVGs(1, 'Test')\nfor ii = 1, #waypointInfo do\n local wDat = waypointInfo[ii]\n local wCenter = wDat.center\n local wName = wDat.name\n local wRadius = wDat.radius\n \n local waypointObject = Waypoint(wCenter[1],wCenter[2],wCenter[3], wRadius * 1.25, wName, subId)\n local customSVG = builder.addSinglePointSVG()\n waypoints[ii] = {wCenter, waypoint}\n customSVG.setPosition({wCenter[1], wCenter[2], wCenter[3]})\n \t .setData(waypointObject)\n \t .setDrawFunction(draw)\n \t .build()\nend\n\nunit.setTimer(\"update\", 1/1000) -- The timer to update the screen\nsystem.showScreen(1)\nunit.hide()","filter":{"args":[],"signature":"start()","slotKey":"-1"},"key":"0"},{"code":"local svg, index = projector.getSVG()\nlocal rendered = table.concat(svg)\nsystem.setScreen(rendered)","filter":{"args":[{"value":"update"}],"signature":"tick(timerId)","slotKey":"-1"},"key":"1"},{"code":"waypoint = true","filter":{"args":[{"value":"option1"}],"signature":"actionStart(action)","slotKey":"-2"},"key":"2"},{"code":"function Projector(camera)\n -- Localize frequently accessed data\n local utils = require(\"cpml.utils\")\n\n --local library=library\n local core, system, manager = core, system, getManager()\n\n -- Localize frequently accessed functions\n --- System-based function calls\n local getWidth, getHeight, getFov, getMouseDeltaX, getMouseDeltaY, print =\n system.getScreenWidth,\n system.getScreenHeight,\n system.getFov,\n system.getMouseDeltaX,\n system.getMouseDeltaY,\n system.print\n\n --- Core-based function calls\n local getCWorldR, getCWorldF, getCWorldU, getCWorldPos =\n core.getConstructWorldRight,\n core.getConstructWorldForward,\n core.getConstructWorldUp,\n core.getConstructWorldPos\n\n --- Camera-based function calls\n local getCameraLocalPos = system.getCameraPos\n local getCameraWorldPos = system.getCameraWorldPos\n local getCamWorldFwd, getCamWorldRight, getCamWorldUp =\n system.getCameraWorldForward,\n system.getCameraWorldRight,\n system.getCameraWorldUp\n local getCamLocalFwd, getCamLocalRight, getCamLocalUp =\n system.getCameraForward,\n system.getCameraRight,\n system.getCameraUp\n\n --- Manager-based function calls\n ---- Quaternion operations\n local t3DP, rotToEuler, rotToQuat = manager.transPoint3D, manager.rotMatrixToEuler, manager.rotMatrixToQuat\n\n -- Localize Math functions\n local maths = math\n local sin, cos, tan, rad, deg, sqrt, atan, ceil, floor =\n maths.sin,\n maths.cos,\n maths.tan,\n maths.rad,\n maths.deg,\n maths.sqrt,\n maths.atan,\n maths.ceil,\n maths.floor\n local rnd = utils.round\n -- Projection infomation\n --- Screen Parameters\n local width, height = getWidth() * 0.5, getHeight() * 0.5\n\n --- FOV Paramters\n local vertFov = system.getCameraVerticalFov\n local horizontalFov = system.getCameraHorizontalFov\n local tanFov = rad(vertFov())\n\n --- Matrix Subprocessing\n local aspect = width / height\n local fnearDivAspect = width / tanFov\n --- Matrix Paramters\n local x0 = 1 / tanFov\n local y0 = x0 * aspect\n\n local objectGroups = {}\n\n local self = {objectGroups = objectGroups}\n local oldSelected = false\n function self.getSize(size, zDepth, max, min)\n local pSize = atan(size, zDepth) * (fnearDivAspect)\n local max = max or pSize\n local min = min or pSize\n if pSize >= max then\n return max\n elseif pSize <= min then\n return min\n else\n return pSize\n end\n end\n\n local function matrixToQuat(m11, m21, m31, m12, m22, m32, m13, m23, m33)\n local t = m11 + m22 + m33\n if t > 0 then\n local s = 0.5 / sqrt(t + 1)\n return (m32 - m23) * s, (m13 - m31) * s, (m21 - m12) * s, 0.25 / s\n elseif m11 > m22 and m11 > m33 then\n local s = 2 * sqrt(1 + m11 - m22 - m33)\n return 0.25 * s, (m12 + m21) / s, (m13 + m31) / s, (m32 - m23) / s\n elseif m22 > m33 then\n local s = 2 * sqrt(1 + m22 - m11 - m33)\n return (m12 + m21) / s, 0.25 * s, (m23 + m32) / s, (m13 - m31) / s\n else\n local s = 2 * sqrt(1 + m33 - m11 - m22)\n return (m13 + m31) / s, (m23 + m32) / s, 0.25 * s, (m21 - m12) / s\n end\n end\n\n function self.addObjectGroup(objectGroup, id)\n local index = id or #objectGroups + 1\n objectGroups[index] = objectGroup\n return index\n end\n\n function self.removeObjectGroup(id)\n objectGroups[id] = {}\n end\n \n local cUX, cUY, cUZ, cFX, cFY, cFZ, cRX, cRY, cRZ, sx, sy, sz, sw =\n nil,\n nil,\n nil,\n nil,\n nil,\n nil,\n nil,\n nil,\n nil,\n nil,\n nil,\n nil,\n nil\n\n function self.getModelMatrix(mObject)\n local s, c = sin, cos\n local modelMatrices = {}\n\n -- Localize Object values.\n local objOri, objPos = mObject[10], mObject[12]\n local objPosX, objPosY, objPosZ = objPos[1], objPos[2], objPos[3]\n\n local cRX, cRY, cRZ, cFX, cFY, cFZ, cUX, cUY, cUZ, sx, sy, sz, sw =\n cRX,\n cRY,\n cRZ,\n cFX,\n cFY,\n cFZ,\n cUX,\n cUY,\n cUZ,\n -sx,\n -sy,\n -sz,\n sw\n local wwx, wwy, wwz, www = objOri[1], objOri[2], objOri[3], objOri[4]\n\n local wx, wy, wz, ww = wwx, wwy, wwz, www\n if mObject[9] == 2 then\n local mx, my, mz, mw =\n wx * sw + ww * sx + wy * sz - wz * sy,\n wy * sw + ww * sy + wz * sx - wx * sz,\n wz * sw + ww * sz + wx * sy - wy * sx,\n ww * sw - wx * sx - wy * sy - wz * sz\n wx, wy, wz, ww = mx, my, mz, mw\n end\n if mObject[8] == 2 then\n return wx, wy, wz, ww, cRX * objPosX + cFX * objPosY + cUX * objPosZ, cRY * objPosX + cFY * objPosY +\n cUY * objPosZ, cRZ * objPosX + cFZ * objPosY + cUZ * objPosZ, objPosX, objPosY, objPosZ\n else\n local cWorldPos = getCWorldPos()\n local oPX, oPY, oPZ = objPosX - cWorldPos[1], objPosY - cWorldPos[2], objPosZ - cWorldPos[3]\n return wx, wy, wz, ww, oPX, oPY, oPZ, \n cRX * oPX + cRY * oPY + cRZ * oPZ, \n cFX * oPX + cFY * oPY + cFZ * oPZ, \n cUX * oPX + cUY * oPY + cUZ * oPZ\n end\n end\n\n local function updateReferentials()\n local cU, cF, cR = getCWorldU(), getCWorldF(), getCWorldR()\n\n cRX, cRY, cRZ, cFX, cFY, cFZ, cUX, cUY, cUZ = cR[1], cR[2], cR[3], cF[1], cF[2], cF[3], cU[1], cU[2], cU[3]\n sx, sy, sz, sw = matrixToQuat(cRX, cRY, cRZ, cFX, cFY, cFZ, cUX, cUY, cUZ)\n end\n\n function self.getViewMatrix()\n updateReferentials()\n local id = camera.cType.id\n local fG, fL = id == 0, id == 1\n\n if fG or fL then -- To do and fix\n local s, c = sin, cos\n local cOrientation = camera.orientation\n local pitch, heading, roll = cOrientation[1] * 0.5, -cOrientation[2] * 0.5, cOrientation[3] * 0.5\n local sP, sR, sH = s(pitch), s(heading), s(roll)\n local cP, cR, cH = c(pitch), c(heading), c(roll)\n\n local cx, cy, cz, cw = sP * cR, sP * sR, cP * sR, cP * cR\n if fG then\n wx, wy, wz, ww = cx, cy, cz, cw\n else\n local mx, my, mz, mw =\n sx * cw + sw * cx + sy * cz - sz * cy,\n sy * cw + sw * cy + sz * cx - sx * cz,\n sz * cw + sw * cz + sx * cy - sy * cx,\n sw * cw - sx * cx - sy * cy - sz * cz\n wx, wy, wz, ww = mx, my, mz, mw\n end\n else\n local lEye = getCameraLocalPos()\n local lEyeX, lEyeY, lEyeZ = lEye[1], lEye[2], lEye[3]\n local lf, lr, lu, gf, gr, gu =\n getCamLocalFwd(),\n getCamLocalRight(),\n getCamLocalUp(),\n getCamWorldFwd(),\n getCamWorldRight(),\n getCamWorldUp()\n local lfx, lfy, lfz = lf[1], lf[2], lf[3]\n\n local dotX = lr[1] * lEyeX + lr[2] * lEyeY + lr[3] * lEyeZ\n local dotY = lfx * lEyeX + lfy * lEyeY + lfz * lEyeZ\n local dotZ = lu[1] * lEyeX + lu[2] * lEyeY + lu[3] * lEyeZ\n\n return gr[1], gr[2], gr[3], gf[1], gf[2], gf[3], gu[1], gu[2], gu[3], -dotX, -dotY, -dotZ, lEyeX, lEyeY, lEyeZ, lfx, lfy, lfz\n end\n end\n\n function self.getSVG(isvg, fc)\n local isClicked = false\n if clicked then\n clicked = false\n isClicked = true\n end\n local isHolding = isHolding\n \n local fullSVG = isvg or {}\n local fc = fc or 1\n\n local vx1, vy1, vz1, vx2, vy2, vz2, vx3, vy3, vz3, vw1, vw2, vw3, lCX, lCY, lCZ, VX, VY, VZ =\n self.getViewMatrix()\n local vx, vy, vz, vw = matrixToQuat(vx1, vy1, vz1, vx2, vy2, vz2, vx3, vy3, vz3)\n\n local atan, sort, format, unpack, concat, abs, getModelMatrix =\n atan,\n table.sort,\n string.format,\n table.unpack,\n table.concat,\n math.abs,\n self.getModelMatrix\n\n local function zSort(t1, t2)\n return t1[1] > t2[1]\n end\n\n local tanFov = tan(rad(horizontalFov() * 0.5))\n\n --- Matrix Subprocessing\n local nearDivAspect = width / tanFov\n fnearDivAspect = nearDivAspect\n \n -- Localize projection matrix values\n local px1 = 1 / tanFov\n local pz3 = px1 * aspect\n\n local pxw = px1 * width\n local pzw = -pz3 * height\n -- Localize screen info\n local width = width\n local height = height\n local nxB, pxB, nyB, pyB = -width * 2, width * 2, -height * 2, height * 2\n local dptPercision = 1\n local objectGroups = objectGroups\n local svgBuffer = {}\n local alpha = 1\n for i = 1, #objectGroups do\n local objectGroup = objectGroups[i]\n if objectGroup.enabled == false then\n goto not_enabled\n end\n\n local objGTransX = objectGroup.transX or width\n local objGTransY = objectGroup.transY or height\n local objects = objectGroup.objects\n\n local avgZ, avgZC = 0, 0\n local zBuffer, aBuffer, aBC, zBC = {}, {}, 0, 0\n local unpackData, drawStringData, uC, dU = {}, {}, 1, 1\n local notIntersected = true\n for m = 1, #objects do\n local obj = objects[m]\n if obj[12] == nil then\n goto is_nil\n end\n\n local mx, my, mz, mw, mw1, mw2, mw3, mXP, mYP, mZP = getModelMatrix(obj)\n\n local objStyle = obj[11]\n local vMX, vMY, vMZ, vMW =\n mx * vw + mw * vx + my * vz - mz * vy,\n my * vw + mw * vy + mz * vx - mx * vz,\n mz * vw + mw * vz + mx * vy - my * vx,\n mw * vw - mx * vx - my * vy - mz * vz\n\n local vMXvMX, vMYvMY, vMZvMZ = vMX * vMX, vMY * vMY, vMZ * vMZ\n\n local mXX, mXY, mXZ, mXW =\n (1 - 2 * (vMYvMY + vMZvMZ)) * pxw,\n 2 * (vMX * vMY + vMZ * vMW) * pxw,\n 2 * (vMX * vMZ - vMY * vMW) * pxw,\n (vw1 + vx1 * mw1 + vy1 * mw2 + vz1 * mw3) * pxw\n\n local mYX, mYY, mYZ, mYW =\n 2 * (vMX * vMY - vMZ * vMW),\n 1 - 2 * (vMXvMX + vMZvMZ),\n 2 * (vMY * vMZ + vMX * vMW),\n (vw2 + vx2 * mw1 + vy2 * mw2 + vz2 * mw3)\n\n local mZX, mZY, mZZ, mZW =\n 2 * (vMX * vMZ + vMY * vMW) * pzw,\n 2 * (vMY * vMZ - vMX * vMW) * pzw,\n (1 - 2 * (vMXvMX + vMYvMY)) * pzw,\n (vw3 + vx3 * mw1 + vy3 * mw2 + vz3 * mw3) * pzw\n\n avgZ = avgZ + mYW\n avgZC = avgZC + 1\n\n local P0XD, P0YD, P0ZD = lCX - mXP, lCY - mYP, lCZ - mZP\n\n local customGroups, uiGroups = obj[4], obj[6]\n for cG = 1, #customGroups do\n local customGroup = customGroups[cG]\n local multiGroups = customGroup[2]\n local singleGroups = customGroup[3]\n for mGC = 1, #multiGroups do\n local multiGroup = multiGroups[mGC]\n local pts = multiGroup[1]\n local tPoints = {}\n local ct = 1\n local mGAvg = 0\n for pC = 1, #pts do\n local p = pts[pC]\n local x, y, z = p[1], p[2], p[3]\n local pz = mYX * x + mYY * y + mYZ * z + mYW\n if pz < 0 then\n goto behindMG\n end\n\n tPoints[ct] = {\n (mXX * x + mXY * y + mXZ * z + mXW) / pz,\n (mZX * x + mZY * y + mZZ * z + mZW) / pz,\n pz\n }\n mGAvg = mGAvg + pz\n ct = ct + 1\n ::behindMG::\n end\n if ct ~= 1 then\n local drawFunction = multiGroup[2]\n local data = multiGroup[3]\n zBC = zBC + 1\n zBuffer[zBC] = {\n mGAvg/(ct-1),\n tPoints,\n data,\n drawFunction\n }\n end\n end\n for sGC = 1, #singleGroups do\n local singleGroup = singleGroups[sGC]\n local p = singleGroup[1]\n local x, y, z = p[1], p[2], p[3]\n local pz = mYX * x + mYY * y + mYZ * z + mYW\n if pz < 0 then\n goto behindSingle\n end\n\n local drawFunction = singleGroup[2]\n local data = singleGroup[3]\n zBC = zBC + 1\n zBuffer[zBC] = {\n pz,\n (mXX * x + mXY * y + mXZ * z + mXW) / pz,\n (mZX * x + mZY * y + mZZ * z + mZW) / pz,\n data,\n drawFunction,\n isCustomSingle = true\n }\n ::behindSingle::\n end\n end\n\n for uiC = 1, #uiGroups do\n local uiGroup = uiGroups[uiC]\n\n local elements = uiGroup[2]\n local modelElements = uiGroup[4]\n\n for eC = 1, #modelElements do\n local mod = modelElements[eC]\n local mXO, mYO, mZO = mod[10], mod[11], mod[12]\n\n local pointsInfo = mod[9]\n local pointsX, pointsY, pointsZ = pointsInfo[1], pointsInfo[2], pointsInfo[3]\n local tPointsX, tPointsY = {}, {}\n local size = #pointsX\n tPointsX[size] = false\n tPointsY[size] = false\n\n local xwAdd = mXX * mXO + mXY * mYO + mXZ * mZO + mXW\n local ywAdd = mYX * mXO + mYY * mYO + mYZ * mZO + mYW\n local zwAdd = mZX * mXO + mZY * mYO + mZZ * mZO + mZW\n\n for index = 1, size do\n local x, y, z = pointsX[index], pointsY[index], pointsZ[index]\n local pz = mYX * x + mYY * y + mYZ * z + ywAdd\n if pz > 0 then\n tPointsX[index] = (mXX * x + mXY * y + mXZ * z + xwAdd) / pz\n tPointsY[index] = (mZX * x + mZY * y + mZZ * z + zwAdd) / pz\n end\n end\n\n local lX, lY, lZ = 0.26726, 0.80178, 0.53452\n local ambience = 0.3\n local planes = mod[13]\n local planeNumber = #planes\n zBuffer[zBC + planeNumber] = false\n for p = 1, planeNumber do\n local plane = planes[p]\n local eXO, eYO, eZO = plane[1] + mXO, plane[2] + mYO, plane[3] + mZO\n local eCZ = mYX * eXO + mYY * eYO + mYZ * eZO + mYW\n if eCZ < 0 then\n goto behindElement\n end\n local p0X, p0Y, p0Z = P0XD - eXO, P0YD - eYO, P0ZD - eZO\n\n local NX, NY, NZ = plane[4], plane[5], plane[6]\n local dotValue = p0X * NX + p0Y * NY + p0Z * NZ\n\n if dotValue < 0 then\n goto behindElement\n end\n\n local brightness = (lX * NX + lY * NY + lZ * NZ)\n if brightness < 0 then\n brightness = (brightness * 0.1) * (1 - ambience) + ambience\n else\n brightness = (brightness) * (1 - ambience) + ambience\n end\n local r, g, b = plane[8] * brightness, plane[9] * brightness, plane[10] * brightness\n\n local indices = plane[7]\n local data = {r, g, b}\n local m = 4\n local indexSize = #indices\n data[m + indexSize * 2 - 1] = false\n\n for i = 1, indexSize do\n local index = indices[i]\n local pntX = tPointsX[index]\n if not pntX then\n goto behindElement\n end\n\n data[m] = pntX\n data[m + 1] = tPointsY[index]\n m = m + 2\n end\n zBC = zBC + 1\n zBuffer[zBC] = {\n eCZ,\n plane[11],\n eCZ,\n data,\n is3D = true\n }\n\n ::behindElement::\n end\n end\n for eC = 1, #elements do\n local el = elements[eC]\n if not el[6] then\n goto behindElement\n end\n el[16].checkUpdate()\n local eO = el[10]\n local eXO, eYO, eZO = eO[1], eO[2], eO[3]\n\n local eCZ = mYX * eXO + mYY * eYO + mYZ * eZO + mYW\n if eCZ < 0 then\n goto behindElement\n end\n \n local eCX = mXX * eXO + mXY * eYO + mXZ * eZO + mXW\n local eCY = mZX * eXO + mZY * eYO + mZZ * eZO + mZW\n\n local actions = el[4]\n local oRM = el[15]\n local fw = -oRM[4]\n local xxMult, xzMult, yxMult, yzMult, zxMult, zzMult\n\n if fw ~= -1 then\n local fx, fy, fz = oRM[1], oRM[2], oRM[3]\n local rx, ry, rz, rw =\n fx * vMW + fw * vMX + fy * vMZ - fz * vMY,\n fy * vMW + fw * vMY + fz * vMX - fx * vMZ,\n fz * vMW + fw * vMZ + fx * vMY - fy * vMX,\n fw * vMW - fx * vMX - fy * vMY - fz * vMZ\n\n local rxrx, ryry, rzrz = rx * rx, ry * ry, rz * rz\n xxMult, xzMult = (1 - 2 * (ryry + rzrz)) * pxw, 2 * (rx * rz - ry * rw) * pxw\n yxMult, yzMult = 2 * (rx * ry - rz * rw), 2 * (ry * rz + rx * rw)\n zxMult, zzMult = 2 * (rx * rz + ry * rw) * pzw, (1 - 2 * (rxrx + ryry)) * pzw\n else\n xxMult, xzMult = mXX, mXZ\n yxMult, yzMult = mYX, mYZ\n zxMult, zzMult = mZX, mZZ\n end\n\n zBC = zBC + 1\n if el[14] and actions[7] then\n aBC = aBC + 1\n local p0X, p0Y, p0Z = P0XD - eXO, P0YD - eYO, P0ZD - eZO\n\n local NX, NY, NZ = el[11], el[12], el[13]\n\n local t = -(p0X * NX + p0Y * NY + p0Z * NZ) / (VX * NX + VY * NY + VZ * NZ)\n local px, py, pz = p0X + t * VX, p0Y + t * VY, p0Z + t * VZ\n\n local oRM = el[15]\n local ox, oy, oz, ow = oRM[1], oRM[2], oRM[3], oRM[4]\n local oyoy = oy * oy\n zBuffer[zBC] = {\n eCZ,\n el,\n false,\n eCX,\n eCZ,\n eCY,\n xxMult, \n xzMult, \n yxMult, \n yzMult, \n zxMult, \n zzMult,\n isUI = true\n }\n aBuffer[aBC] = {\n eCZ,\n el,\n eCZ,\n 2 * ((0.5 - oyoy - oz * oz) * px + (ox * oy + oz * ow) * py + (ox * oz - oy * ow) * pz),\n 2 * ((ox * oz + oy * ow) * px + (oy * oz - ox * ow) * py + (0.5 - ox * ox - oyoy) * pz),\n actions,\n zBC\n }\n else\n zBuffer[zBC] = {\n eCZ,\n el,\n el[2],\n eCX,\n eCZ,\n eCY,\n xxMult, \n xzMult, \n yxMult, \n yzMult, \n zxMult, \n zzMult,\n isUI = true\n }\n end\n\n ::behindElement::\n end\n end\n ::is_nil::\n end\n if aBC > 0 then\n local newSelected = false\n sort(aBuffer, zSort)\n for aC = aBC, 1, -1 do\n local uiElmt = aBuffer[aC]\n\n local el = uiElmt[2]\n\n local hoverDraw, defaultDraw, clickDraw = el[1], el[2], el[3]\n local drawForm = defaultDraw\n local actions = el[4]\n\n if notIntersected then\n local eBounds = el[14]\n if eBounds and actions[7] then\n local pX, pZ = uiElmt[4], uiElmt[5]\n local inside = false\n if type(eBounds) == \"function\" then\n inside = eBounds(pX, pZ, uiElmt[3])\n else\n local N = #eBounds + 1\n local p1 = eBounds[1]\n local p1x, p1y = p1[1], p1[2]\n local offset = 0\n for eb = 2, N do\n local mod = eb % N\n if mod == 0 then\n offset = 1\n end\n local p2 = eBounds[mod + offset]\n p1x, p1y = p1[1], p1[2]\n local p2x, p2y = p2[1], p2[2]\n local minY, maxY\n if p1y < p2y then\n minY, maxY = p1y, p2y\n else\n minY, maxY = p2y, p1y\n end\n\n if pZ > minY and pZ <= maxY then\n local maxX = p1x > p2x and p1x or p2x\n if pX <= maxX then\n if p1y ~= p2y then\n if p1x == p2x or pX <= (pZ - p1y) * (p2x - p1x) / (p2y - p1y) + p1x then\n inside = not inside\n end\n end\n end\n end\n p1 = p2\n end\n end\n if not inside then\n goto broke\n end\n notIntersected = false\n drawForm = hoverDraw\n newSelected = uiElmt\n local eO = el[10]\n local identifier = actions[6]\n if oldSelected == false then\n local enter = actions[3]\n if enter then\n enter(identifier, pX, pZ)\n end\n --oldSelected = newSelected\n elseif newSelected[6] == oldSelected[6] then\n if isClicked then\n drawForm = clickDraw\n local clickAction = actions[1]\n if clickAction then\n clickAction(identifier, pX, pZ, eO[1], eO[2], eO[3])\n isClicked = false\n end\n elseif isHolding then\n local holdAction = actions[2]\n drawForm = clickDraw\n if holdAction then\n hovered = true\n holdAction(identifier, pX, pZ, eO[1], eO[2], eO[3])\n end\n else\n local hoverAction = actions[5]\n\n if hoverAction then\n hovered = true\n hoverAction(identifier, pX, pZ, eO[1], eO[2], eO[3])\n end\n end\n else\n local enter = actions[3]\n if enter then\n enter(identifier, pX, pY)\n end\n local leave = oldSelected[6][4]\n if leave then\n leave(identifier, pX, pY)\n end\n \n end\n ::broke::\n end\n end\n zBuffer[uiElmt[7]][3] = drawForm\n end\n\n if newSelected == false and oldSelected then\n local leave = oldSelected[6][4]\n if leave then\n leave()\n end\n \n end\n oldSelected = newSelected\n end\n sort(zBuffer, zSort)\n for zC = 1, zBC do\n local uiElmt = zBuffer[zC]\n if uiElmt.isUI then\n local el = uiElmt[2]\n local distance,el,drawForm,xwAdd,ywAdd,zwAdd,xxMult,xzMult,yxMult,yzMult,zxMult,zzMult=unpack(uiElmt)\n\n local count = 1\n\n local scale = el[5] or 1\n local drawOrder = el[7]\n local drawData = el[8]\n local points = el[9]\n\n local oUC = uC\n if drawData then\n local sizes = drawData[\"sizes\"]\n if sizes then\n uC = uC + #sizes\n end\n uC = uC + #drawData\n end\n\n local broken = false\n if not drawOrder then\n for ePC = 1, #points, 2 do\n local ex, ez = points[ePC] * scale, points[ePC + 1] * scale\n\n local pz = yxMult * ex + yzMult * ez + ywAdd\n if pz < 0 then\n broken = true\n break\n end\n\n distance = distance + pz\n count = count + 1\n\n unpackData[uC] = (xxMult * ex + xzMult * ez + xwAdd) / pz\n unpackData[uC + 1] = (zxMult * ex + zzMult * ez + zwAdd) / pz\n uC = uC + 2\n end\n else\n for ePC = 1, #points, 2 do\n local ex, ez = points[ePC] * scale, points[ePC + 1] * scale\n\n local pz = yxMult * ex + yzMult * ez + ywAdd\n if pz < 0 then\n broken = true\n break\n end\n\n distance = distance + pz\n count = count + 1\n\n local px = (xxMult * ex + xzMult * ez + xwAdd) / pz\n local py = (zxMult * ex + zzMult * ez + zwAdd) / pz\n\n local indexList = drawOrder[ePC] or {}\n for i = 1, #indexList do\n local index = indexList[i] + (uC - 1)\n unpackData[index] = px\n unpackData[index + 1] = py\n end\n end\n end\n mUC = uC\n uC = oUC\n if not broken and drawForm then\n local depthFactor = distance / count\n if drawData then\n local drawDatCount = #drawData\n local sizes = drawData[\"sizes\"]\n if sizes then\n for i = 1, #sizes do\n local size = sizes[i]\n local tSW = type(size)\n if tSW == \"number\" then\n unpackData[uC] = atan(size, depthFactor) * nearDivAspect\n elseif tSW == \"function\" then\n unpackData[uC] = size(depthFactor, nearDivAspect)\n end\n uC = uC + 1\n end\n end\n for dDC = 1, drawDatCount do\n unpackData[uC] = drawData[dDC]\n uC = uC + 1\n end\n end\n drawStringData[dU] = drawForm\n dU = dU + 1\n uC = mUC\n end\n elseif uiElmt.is3D then\n local data = uiElmt[4]\n for alm = 1, #data do\n unpackData[uC] = data[alm]\n uC = uC + 1\n end\n drawStringData[dU] = uiElmt[2]\n dU = dU + 1\n elseif uiElmt.isCustomSingle then\n local zDepth,x,y,data,drawFunction = uiElmt[1],uiElmt[2],uiElmt[3],uiElmt[4],uiElmt[5]\n local unpackSize = #unpackData\n drawStringData[dU] = drawFunction(x,y,zDepth,data,unpackData,uC) or '<text x=0 y=0>Error: N-CS</text>'\n dU = dU + 1\n local newUnpackSize = #unpackData\n if unpackSize ~= newUnpackSize then\n uC = newUnpackSize + 1\n end\n else\n local zDepth,points,data,drawFunction = uiElmt[1],uiElmt[2],uiElmt[3],uiElmt[4]\n local unpackSize = #unpackData\n drawStringData[dU] = drawFunction(points,data,unpackData,uC)\n dU = dU + 1\n local newUnpackSize = #unpackData\n if unpackSize ~= newUnpackSize then\n uC = newUnpackSize + 1\n end\n end\n end\n \n local svg = {\n format(\n '<svg viewbox=\"-%g -%g %g %g\">',\n objGTransX,\n objGTransY,\n width * 2,\n height * 2\n ),\n format(\n '<style> svg{width:%gpx;height:%gpx;position:absolute;top:0px;left:0px;} %s </style>',\n width * 2,\n height * 2,\n objectGroup.style\n ),\n format(concat(drawStringData), unpack(unpackData)),\n '</svg>'\n }\n if avgZC > 0 then\n local dpth = avgZ / avgZC\n svgBuffer[alpha] = {dpth, concat(svg)}\n alpha = alpha + 1\n if objectGroup.glow then\n local size\n if objectGroup.scale then\n size = atan(objectGroup.gRad, dpth) * nearDivAspect\n else\n size = objectGroup.gRad\n end\n svg[1] =\n format(\n '<svg viewbox=\"-%g -%g %g %g\" class=\"blur\">',\n objGTransX,\n objGTransY,\n width * 2,\n height * 2\n )\n svg[2] =\n [[\n <style> \n .blur {\n filter: blur(]] .. size .. [[px) \n brightness(100%)\n saturate(3);\n ]] .. objectGroup.gStyle .. [[\n }\n </style>]]\n svgBuffer[alpha] = {dpth + 0.1, concat(svg)}\n alpha = alpha + 1\n end\n end\n ::not_enabled::\n end\n sort(svgBuffer, zSort)\n local svgBufferSize = #svgBuffer\n if svgBufferSize > 0 then\n fc = fc - 1\n for dm = 1, svgBufferSize do\n fullSVG[fc + dm] = svgBuffer[dm][2]\n end\n end\n return fullSVG, fc + svgBufferSize + 1\n end\n return self\nend","filter":{"args":[],"signature":"start()","slotKey":"-3"},"key":"3"},{"code":"positionTypes = {\n globalP=1,\n localP=2\n}\norientationTypes = {\n globalO=1,\n localO=2 \n}\n\nlocal print = system.print\n\nlocal TEXT_ARRAY = {\n [10] = {{}, 16,'',10},--new line\n [32] = {{}, 10,'',32}, -- space\n [33] = {{4, 0, 3, 2, 5, 2, 4, 4, 4, 12}, 10, 'M%g %gL%g %gL%g %gZ M%g %gL%g %g',33}, -- !\n [34] = {{2, 10, 2, 6, 6, 10, 6, 6}, 6,'M%g %gL%g %g M%g %gL%g %g',34}, -- \"\n [35] = {{0, 4, 8, 4, 6, 2, 6, 10, 8, 8, 0, 8, 2, 10, 2, 2}, 10,'M%g %gL%g %g M%g %gL%g %g M%g %gL%g %g M%g %gL%g %g',35}, -- #\n [36] = {{6, 2, 2, 6, 6, 10, 4, 12, 4, 0}, 6,'M%g %gL%g %gL%g %g M%g %gL%g %g',36}, --$\n [37] = {{0, 0, 8, 12, 2, 10, 2, 8, 6, 4, 6, 2}, 10,'M%g %gL%g %g M%g %gL%g %g M%g %gL%g %g',37}, -- %\n [38] = {{8, 0, 4, 12, 8, 8, 0, 4, 4, 0, 8, 4}, 10,'M%g %gL%g %gL%g %gL%g %gL%g %gL%g %g',38}, --&\n [39] = {{0, 8, 0, 12}, 2,'M%g %gL%g %g',39}, --'\n \n [40] = {{6, 0, 2, 4, 2, 8, 6, 12}, 8,'M%g %gL%g %gL%g %gL%g %g',40}, --(\n [41] = {{2, 0, 6, 4, 6, 8, 2, 12}, 8,'M%g %gL%g %gL%g %gL%g %g',41}, --)\n [42] = {{0, 0, 4, 12, 8, 0, 0, 8, 8, 8, 0, 0}, 10,'M%g %gL%g %gL%g %gL%g %gL%g %gL%g %g',42}, --*\n [43] = {{1, 6, 7, 6, 4, 9, 4, 3}, 10,'M%g %gL%g %gM%g %gL%g %g',43}, -- +\n [44] = {{-1, -2, 1, 1}, 4,'M%g %gL%g %g',44}, -- ,\n [45] = {{2, 6, 6, 6}, 10,'M%g %gL%g %g',45}, -- -\n [46] = {{0, 0, 1, 0}, 3,'M%g %gL%g %g',46}, -- .\n [47] = {{0, 0, 8, 12}, 10,'M%g %gL%g %g',47}, -- /\n [48] = {{0, 0, 8, 0, 8, 12, 0, 12, 0, 0, 8, 12}, 10,'M%g %gL%g %gL%g %gL%g %gZ M%g %gL%g %g',48}, -- 0\n [49] = {{5, 0, 5, 12, 3, 10}, 10,'M%g %gL%g %gL%g %g',49}, -- 1\n\n \n [50] = {{0, 12, 8, 12, 8, 7, 0, 5, 0, 0, 8, 0}, 10,'M%g %gL%g %gL%g %gL%g %gL%g %gL%g %g',50}, -- 2\n [51] = {{0, 12, 8, 12, 8, 0, 0, 0, 0, 6, 8, 6}, 10,'M%g %gL%g %gL%g %gL%g %g M%g %gL%g %g',51}, -- 3\n [52] = {{0, 12, 0, 6, 8, 6, 8, 12, 8, 0}, 10,'M%g %gL%g %gL%g %g M%g %gL%g %g',52}, -- 4\n [53] = {{0, 0, 8, 0, 8, 6, 0, 7, 0, 12, 8, 12}, 10,'M%g %gL%g %gL%g %gL%g %gL%g %gL%g %g',53}, -- 5\n [54] = {{0, 12, 0, 0, 8, 0, 8, 5, 0, 7}, 10,'M%g %gL%g %gL%g %gL%g %gL%g %g',54}, -- 6\n [55] = {{0, 12, 8, 12, 8, 6, 4, 0}, 10,'M%g %gL%g %gL%g %gL%g %g',55}, -- 7\n [56] = {{0, 0, 8, 0, 8, 12, 0, 12, 0, 6, 8, 6}, 10,'M%g %gL%g %gL%g %gL%g %gZ M%g %gL%g %g',56}, -- 8\n [57] = {{8, 0, 8, 12, 0, 12, 0, 7, 8, 5}, 10,'M%g %gL%g %gL%g %gL%g %gL%g %g',57}, -- 9\n [58] = {{4, 9, 4, 7, 4, 5, 4, 3}, 2,'M%g %gL%g %g M%g %gL%g %g',58}, -- :\n [59] = {{4, 9, 4, 7, 4, 5, 1, 2}, 5,'M%g %gL%g %g M%g %gL%g %g',59}, -- ;\n \n [60] = {{6, 0, 2, 6, 6, 12}, 6,'M%g %gL%g %gL%g %g',60}, -- <\n [61] = {{1, 4, 7, 4, 1, 8, 7, 8}, 8,'M%g %gL%g %g M%g %gL%g %g',61}, -- =\n [62] = {{2, 0, 6, 6, 2, 12}, 6,'M%g %gL%g %gL%g %g',62}, -- >\n [63] = {{0, 8, 4, 12, 8, 8, 4, 4, 4, 1, 4, 0}, 10,'M%g %gL%g %gL%g %gL%g %g M%g %gL%g %g',63}, -- ?\n [64] = {{8, 4, 4, 0, 0, 4, 0, 8, 4, 12, 8, 8, 4, 4, 3, 6}, 10,'M%g %gL%g %gL%g %gL%g %gL%g %gL%g %gL%g %gL%g %g',64}, -- @\n [65] = {{0, 0, 0, 8, 4, 12, 8, 8, 8, 0, 0, 4, 8, 4}, 10,'M%g %gL%g %gL%g %gL%g %gL%g %g M%g %gL%g %g',65}, -- A\n [66] = {{0, 0, 0, 12, 4, 12, 8, 10, 4, 6, 8, 2, 4, 0}, 10,'M%g %gL%g %gL%g %gL%g %gL%g %gL%g %gL%g %gZ',66}, --B\n [67] = {{8, 0, 0, 0, 0, 12, 8, 12}, 10,'M%g %gL%g %gL%g %gL%g %g',67}, -- C\n [68] = {{0, 0, 0, 12, 4, 12, 8, 8, 8, 4, 4, 0}, 10,'M%g %gL%g %gL%g %gL%g %gL%g %gL%g %gZ',68}, -- D \n [69] = {{8, 0, 0, 0, 0, 12, 8, 12, 0, 6, 6, 6}, 10, 'M%g %gL%g %gL%g %gL%g %g M%g %gL%g %g',69}, -- E\n \n \n [70] = {{0, 0, 0, 12, 8, 12, 0, 6, 6, 6}, 10,'M%g %gL%g %gL%g %g M%g %gL%g %g',70}, -- F\n [71] = {{6, 6, 8, 4, 8, 0, 0, 0, 0, 12, 8, 12}, 10,'M%g %gL%g %gL%g %gL%g %gL%g %gL%g %g',71}, -- G\n [72] = {{0, 0, 0, 12, 0, 6, 8, 6, 8, 12, 8, 0}, 10,'M%g %gL%g %g M%g %gL%g %g M%g %gL%g %g',72}, -- H\n [73] = {{0, 0, 8, 0, 4, 0, 4, 12, 0, 12, 8, 12}, 10,'M%g %gL%g %g M%g %gL%g %g M%g %gL%g %g',73}, -- I\n [74] = {{0, 4, 4, 0, 8, 0, 8, 12}, 10,'M%g %gL%g %gL%g %gL%g %g',74}, -- J\n [75] = {{0, 0, 0, 12, 8, 12, 0, 6, 6, 0}, 10,'M%g %gL%g %g M%g %gL%g %gL%g %g',75}, -- K\n [76] = {{8, 0, 0, 0, 0, 12}, 10,'M%g %gL%g %gL%g %g',76}, -- L\n [77] = {{0, 0, 0, 12, 4, 8, 8, 12, 8, 0}, 10,'M%g %gL%g %gL%g %gL%g %gL%g %g',77}, -- M\n [78] = {{0, 0, 0, 12, 8, 0, 8, 12}, 10,'M%g %gL%g %gL%g %gL%g %g',78}, -- N\n [79] = {{0, 0, 0, 12, 8, 12, 8, 0}, 10,'M%g %gL%g %gL%g %gL%g %gZ',79}, -- O\n \n [80] = {{0, 0, 0, 12, 8, 12, 8, 6, 0, 5}, 10,'M%g %gL%g %gL%g %gL%g %gL%g %g',80}, -- P\n [81] = {{0, 0, 0, 12, 8, 12, 8, 4, 4, 4, 8, 0}, 10,'M%g %gL%g %gL%g %gL%g %gZ M%g %gL%g %g',81}, -- Q\n [82] = {{0, 0, 0, 12, 8, 12, 8, 6, 0, 5, 4, 5, 8, 0}, 10,'M%g %gL%g %gL%g %gL%g %gL%g %g M%g %gL%g %g',82}, -- R\n [83] = {{0, 2, 2, 0, 8, 0, 8, 5, 0, 7, 0, 12, 6, 12, 8, 10}, 10,'M%g %gL%g %gL%g %gL%g %gL%g %gL%g %gL%g %gL%g %g',83}, -- S\n [84] = {{0, 12, 8, 12, 4, 12, 4, 0}, 10,'M%g %gL%g %g M%g %gL%g %g',84}, -- T\n [85] = {{0, 12, 0, 2, 4, 0, 8, 2, 8, 12}, 10,'M%g %gL%g %gL%g %gL%g %gL%g %g',85}, -- U\n [86] = {{0, 12, 4, 0, 8, 12}, 10,'M%g %gL%g %gL%g %g',86}, -- V\n [87] = {{0, 12, 2, 0, 4, 4, 6, 0, 8, 12}, 10,'M%g %gL%g %gL%g %gL%g %gL%g %g',87}, -- W\n [88] = {{0, 0, 8, 12, 0, 12, 8, 0}, 10,'M%g %gL%g %g M%g %gL%g %g',88}, -- X\n [89] = {{0, 12, 4, 6, 8, 12, 4, 6, 4, 0}, 10,'M%g %gL%g %gL%g %g M%g %gL%g %g',89}, -- Y\n \n [90] = {{0, 12, 8, 12, 0, 0, 8, 0, 2, 6, 6, 6}, 10,'M%g %gL%g %gL%g %gL%g %g M%g %gL%g %g',90}, -- Z\n [91] = {{6, 0, 2, 0, 2, 12, 6, 12}, 6,'M%g %gL%g %gL%g %gL%g %g',91}, -- [\n [92] = {{0, 12, 8, 0}, 10,'M%g %gL%g %g',92}, -- \\\n [93] = {{2, 0, 6, 0, 6, 12, 2, 12}, 6,'M%g %gL%g %gL%g %gL%g %g',93}, -- ]\n [94] = {{2, 6, 4, 12, 6, 6}, 6,'M%g %gL%g %gL%g %g',94}, -- ^\n [95] = {{0, 0, 8, 0}, 10,'M%g %gL%g %g',95}, -- _\n [96] = {{2, 12, 6, 8}, 6,'M%g %gL%g %g',96}, -- `\n \n [123] = {{6, 0, 4, 2, 4, 10, 6, 12, 2, 6, 4, 6}, 6,'M%g %gL%g %gL%g %gL%g %g M%g %gL%g %g',123}, -- {\n [124] = {{4, 0, 4, 5, 4, 6, 4, 12}, 6,'M%g %gL%g %g M%g %gL%g %g',124}, -- |\n [125] = {{4, 0, 6, 2, 6, 10, 4, 12, 6, 6, 8, 6}, 6,'M%g %gL%g %gL%g %gL%g %g M%g %gL%g %g',125}, -- }\n [126] = {{0, 4, 2, 8, 6, 4, 8, 8}, 10,'M%g %gL%g %gL%g %gL%g %g',126}, -- ~\n}\n\nfunction ObjectGroup(objects, transX, transY)\n local objects=objects or {}\n local self={style='',gStyle='',objects=objects,transX=transX,transY=transY,enabled=true,glow=false,gRad=10,scale = false}\n function self.addObject(object, id)\n local id=id or #objects+1\n objects[id]=object\n return id\n end\n function self.setStyle(style) self.style = style end\n function self.removeObject(id) objects[id] = {} end\n function self.hide() self.enabled = false end\n function self.show() self.enabled = true end\n function self.isEnabled() return self.enabled end\n function self.setGlowStyle(gStyle) self.gStyle = gStyle end\n function self.setGlow(enable,radius,scale) self.glow = enable; self.gRad = radius or self.gRad; self.scale = scale or false end \n return self\nend\n\nlocal function RotationHandler(rotArray,resultantPos)\n \n --====================--\n --Local Math Functions--\n --====================--\n local manager,rad,sin,cos = getManager(),math.rad,math.sin,math.cos\n \n local function getQuaternion(x,y,z,w)\n if type(x) == 'number' then\n if w == nil then\n x = -rad(x * 0.5)\n y = rad(y * 0.5)\n z = -rad(z * 0.5)\n local s,c=sin,cos\n local sP,sH,sR=s(x),s(y),s(z)\n local cP,cH,cR=c(x),c(y),c(z)\n return (sP*cH*cR-cP*sH*sR),(cP*sH*cR+sP*cH*sR),(cP*cH*sR-sP*sH*cR),(cP*cH*cR+sP*sH*sR)\n else\n return x,y,z,w\n end\n elseif type(x) == 'table' then\n if #x == 3 then\n return manager.rotMatrixToQuat(x, y, z)\n elseif #x == 4 then\n return x[1],x[2],x[3],x[4]\n else\n system.print('Unsupported Rotation!')\n end\n end\n end\n local function multiply(ax,ay,az,aw,bx,by,bz,bw)\n return ax*bw+aw*bx+ay*bz-az*by,\n ay*bw+aw*by+az*bx-ax*bz,\n az*bw+aw*bz+ax*by-ay*bx,\n aw*bw-ax*bx-ay*by-az*bz\n end\n local function rotatePoint(ax,ay,az,aw,oX,oY,oZ,wX,wY,wZ)\n --local wxwx,wywy,wzwz=wx*wx,wy*wy,wz*wz\n local axax,ayay,azaz,awaw=ax*ax,ay*ay,az*az,aw*aw\n return \n 2*(oY*(ax*ay-aw*az)+oZ*(ax*az+aw*ay))+oX*(awaw+axax-ayay-azaz)+wX,\n 2*(oX*(aw*az+ax*ay)+oZ*(ay*az-aw*ax))+oY*(awaw-axax+ayay-azaz)+wY,\n 2*(oX*(ax*az-aw*ay)+oY*(ax*aw+ay*az))+oZ*(awaw-axax-ayay+azaz)+wZ \n end\n local superManager,needsUpdate = nil,false\n \n --=================--\n --Positional Values--\n --=================--\n local pX,pY,pZ = resultantPos[1],resultantPos[2],resultantPos[3] -- These are original values, for relative to super rotation\n local offX,offY,offZ = 0,0,0\n local wXYZ = resultantPos\n --==================--\n --Orientation Values--\n --==================--\n local tix,tiy,tiz,tiw = 0,0,0,1 -- temp intermediate rotation values\n local tdx,tdy,tdz,tdw = 0,0,0,1 -- temp default intermediate rotation values\n \n local ix,iy,iz,iw = 0,0,0,1 -- intermediate rotation values\n local dx,dy,dz,dw = 0,0,0,1 -- default intermediate rotation values\n \n local out_rotation = rotArray\n local subRotations = {}\n \n --==============--\n --Function Array--\n --==============--\n local out = {}\n \n --============================--\n --Primary Processing Functions--\n --============================--\n local function process(wx,wy,wz,ww,lX,lY,lZ,lTX,lTY,lTZ,n)\n local timeStart = system.getTime()\n \n n = n or 1\n wx,wy,wz,ww = wx or 0, wy or 0, wz or 0, ww or 1\n lX,lY,lZ = lX or pX, lY or pY, lZ or pZ\n lTX,lTY,lTZ = lTX or pX, lTY or pY, lTZ or pZ\n \n if n == 1 then\n --ww = -ww\n end\n \n local dX,dY,dZ = pX - lX, pY - lY, pZ - lZ\n\n if ww ~= 1 and ww ~= -1 then\n if dX ~= 0 or dY ~= 0 or dZ ~= 0 then\n wXYZ[1],wXYZ[2],wXYZ[3] = rotatePoint(wx,wy,wz,ww,dX,dY,dZ,lTX,lTY,lTZ)\n\t else\n wXYZ[1],wXYZ[2],wXYZ[3] = lTX,lTY,lTZ\n end\n if dw ~= 1 then\n wx,wy,wz,ww = multiply(wx,wy,wz,ww,dx,dy,dz,dw)\n end\n if iw ~= 1 then\n wx,wy,wz,ww = multiply(wx,wy,wz,ww,ix,iy,iz,iw)\n end\n else\n local nX,nY,nZ = lTX+dX,lTY+dY,lTZ+dZ\n wXYZ[1],wXYZ[2],wXYZ[3] = nX,nY,nZ\n if dw ~= 1 then\n if iw ~= 1 then\n wx,wy,wz,ww = multiply(dx,dy,dz,dw,ix,iy,iz,iw)\n else\n wx,wy,wz,ww = dx,dy,dz,dw\n end\n else\n if iw ~= 1 then\n wx,wy,wz,ww = ix,iy,iz,iw\n end\n end\n end\n out_rotation[1],out_rotation[2],out_rotation[3],out_rotation[4] = wx,wy,wz,ww\n for i=1, #subRotations do\n subRotations[i].update(wx,wy,wz,ww,pX,pY,pZ,wXYZ[1],wXYZ[2],wXYZ[3],n+1)\n\t end\n local endTime = system.getTime()\n needsUpdate = false\n --system.print(string.format('%.3fms', (endTime - timeStart)*1000))\n end\n local function validate()\n if not superManager then\n process()\n else\n superManager.bubble()\n end\n end\n local function rotate(isDefault)\n if isDefault then\n dx,dy,dz,dw = getQuaternion(tdx,tdy,tdz,tdw)\n else\n ix,iy,iz,iw = getQuaternion(tix,tiy,tiz,tiw)\n end\n validate()\n end\n \n out.update = process\n \n function out.setSuperManager(rotManager)\n superManager = rotManager\n end\n \n function out.addSubRotation(rotManager)\n rotManager.setSuperManager(out)\n subRotations[#subRotations + 1] = rotManager\n process()\n end\n function out.getPosition()\n return pX,pY,pZ\n end\n function out.setPosition(tx,ty,tz)\n pX,pY,pZ = tx,ty,tz\n out.bubble()\n end\n function out.bubble()\n if superManager then\n superManager.bubble()\n else\n needsUpdate = true\n end\n end\n function out.checkUpdate()\n if needsUpdate then\n local startTime = system.getTime()\n process()\n --logRotation.addValue(system.getTime() - startTime)\n end\n return needsUpdate\n end\n \n function out.rotateXYZ(rotX,rotY,rotZ,rotW)\n if rotX and rotY and rotZ then\n tix,tiy,tiz,tiw = rotX,rotY,rotZ,rotW\n rotate(false)\n else\n if type(rotX) == 'table' then\n if #rotX == 3 then\n tix,tiy,tiz,tiw = rotX[1],rotX[2],rotX[3],nil\n goto valid \n end\n end\n print('Invalid format. Must be three angles, or right, forward and up vectors, or a quaternion. Use radians if angles.')\n ::valid::\n end\n end\n \n function out.rotateX(rotX) tix = rotX; tiw = nil; rotate(false) end\n function out.rotateY(rotY) tiy = rotY; tiw = nil; rotate(false) end\n function out.rotateZ(rotZ) tiz = rotZ; tiw = nil; rotate(false) end\n \n function out.rotateDefaultXYZ(rotX,rotY,rotZ,rotW)\n if rotX and rotY and rotZ then\n tdx,tdy,tdz,tdw = rotX,rotY,rotZ,rotW\n rotate(true)\n else\n if type(rotX) == 'table' then\n if #rotX == 3 then\n tdx,tdy,tdz,tdw = rotX[1],rotX[2],rotX[3],nil\n goto valid \n end\n end\n print('Invalid format. Must be three angles, or right, forward and up vectors, or a quaternion. Use radians if angles.')\n ::valid::\n end\n end\n \n function out.rotateDefaultX(rotX) tdx = rotX; tdw = nil; rotate(true) end\n function out.rotateDefaultY(rotY) tdy = rotY; tdw = nil; rotate(true) end\n function out.rotateDefaultZ(rotZ) tdz = rotZ; tdw = nil; rotate(true) end\n return out\nend\n\n\nfunction Object(style, position, offset, orientation, positionType, orientationType, transX, transY)\n \n \n \n local rad,print=math.rad,system.print\n \n local position=position\n local positionOffset=offset\n \n local style=style\n local customGroups,uiGroups,subObjects={},{},{}\n local positionType=positionType\n local orientationType=orientationType\n local ori = {0,0,0,1}\n local objRotationHandler = RotationHandler(ori,position)\n objRotationHandler.rotateXYZ(orientation)\n \n local defs = {}\n local self = {\n false,false,false,customGroups,false,uiGroups,subObjects,\n positionType, --8\n orientationType, --9\n ori,\n style,\n position,\n offset,\n transX,\n transY,\n defs\n }\n function self.addDef(string)\n defs[#defs + 1] = string\n end\n function self.resetDefs()\n defs = {}\n end\n\n function self.setCustomSVGs(groupId,style,scale)\n local multiPoint={}\n local singlePoint={}\n local group={style,multiPoint,singlePoint}\n local scale=scale or 1\n local mC,sC=1,1\n self[4][groupId]=group\n local offset=positionOffset\n local offsetX,offsetY,offsetZ=offset[1],offset[2],offset[3]\n local self={}\n function self.addMultiPointSVG()\n local points={}\n local data=nil\n local drawFunction=nil\n local self={}\n local pC=1\n function self.addPoint(point)\n local point=point\n points[pC]={point[1]/scale+offsetX,point[2]/scale-offsetY,point[3]/scale-offsetZ}\n pC=pC+1\n return self\n end\n function self.bulkSetPoints(bulk)\n points=bulk\n pC=#points+1\n return self\n end\n function self.setData(dat)\n data=dat\n return self\n end\n function self.setDrawFunction(draw)\n drawFunction=draw\n return self\n end\n function self.build()\n if pC > 1 then\n if drawFunction ~= nil then\n multiPoint[mC]={points, drawFunction, data}\n mC=mC+1\n return points\n else print(\"WARNING! Malformed multi-point build operation, no draw function specified. Ignoring.\")\n end\n else print(\"WARNING! Malformed multi-point build operation, no points specified. Ignoring.\")\n end\n end\n return self\n end\n function self.addSinglePointSVG()\n local point,drawFunction,data=nil,nil,nil\n local self={}\n function self.setPosition(position)\n point={position[1]/scale+offsetX,position[2]/scale-offsetY,position[3]/scale-offsetZ}\n return self\n end\n function self.setDrawFunction(draw)\n drawFunction=draw\n return self\n end\n function self.setData(dat)\n data=dat\n return self\n end\n function self.build()\n if point~=nil then\n if drawFunction~=nil then\n singlePoint[sC]={point,drawFunction,data}\n sC=sC+1\n else print(\"WARNING! Malformed single point build operation, no draw function specified. Ignoring.\")\n end\n else print(\"WARNING! Malformed single point build operation, no point specified. Ignoring.\")\n end\n end\n return self\n end\n return self\n end\n function self.setUIElements(style, groupId)\n groupId = groupId or 1\n local sqrt, s, c,remove = math.sqrt, math.sin, math.cos, table.remove\n\n local function createNormal(points, rx, ry, rz, rw)\n if #points < 6 then\n print(\"Invalid Point Set!\")\n do\n return\n end\n end\n return 2*(rx*ry-rz*rw),1-2*(rx*rx+rz*rz),2*(ry*rz+rx*rw)\n end\n local function createBounds(points)\n local bounds = {}\n local size = #points\n if size >= 60 then\n return false\n end\n local delta = 1\n for i = 1, size, 2 do\n bounds[delta] = {points[i],points[i+1]}\n delta = delta + 1\n end\n return bounds\n end\n \n local elements = {}\n local modelElements = {}\n local elementClasses = {}\n local selectedElement = false\n \n local group = {style, elements, selectedElement,modelElements}\n\n self[6][groupId] = group\n\n local self = {}\n local pC, eC = 0, 0\n\n local function createUITemplate(x,y,z)\n \n local user = {}\n local raw = {}\n \n local huge = math.huge\n local maxX,minX,maxY,minY = -huge,huge,-huge,huge\n \n local pointSet = {}\n local actions = {false,false,false,false,false,false,false}\n local mainRotation = {0,0,0,1}\n local resultantPos = {x,y,z}\n local mRot = RotationHandler(mainRotation,resultantPos)\n \n --system.print(string.format('UI Create {%.2f,%.2f,%.2f}', resultantPos[1],resultantPos[2],resultantPos[3]))\n local elementData = {false, false, false, actions, false, true, false, false, pointSet, resultantPos, false,false,false,false, mainRotation,mRot}\n local subElements = {}\n local elementIndex = eC + 1\n elements[elementIndex] = elementData\n eC = elementIndex\n \n function user.addSubElement(element)\n local index = #subElements + 1\n if element then\n subElements[index] = element\n mRot.addSubRotation(element.getRotationManager())\n end\n return index\n end\n function user.removeSubElement(index)\n remove(subElements, index)\n end\n function user.getId()\n return elementIndex\n end\n function elementData.getId()\n return elementIndex\n end\n local function handleBound(x,y)\n if x > maxX then\n maxX = x\n end\n if x < minX then\n minX = x\n end\n if y > maxY then\n maxY = y\n end\n if y < minY then\n minY = y\n end\n end\n function user.addPoint(x,y)\n local pC = #pointSet\n if x and y then\n handleBound(x,y)\n pointSet[pC+1] = x\n pointSet[pC+2] = y\n else\n if type(x) == 'table' and #x > 0 then\n local x,y = x[1], x[2]\n handleBound(x,y)\n pointSet[pC+1] = x\n pointSet[pC+2] = y\n else\n print('Invalid format for point.')\n end\n end\n end\n function user.addPoints(points)\n local pnts = elementData[9]\n pointSet = pnts\n if points then\n local pointCount = #points\n if pointCount > 0 then\n local pType = type(points[1])\n if pType == 'number' then\n local startIndex = #pnts\n for i = 1, pointCount,2 do\n local index = startIndex + i\n \n local x,y = points[i],points[i+1]\n handleBound(x,y)\n \n pnts[index] = x\n pnts[index+1] = y\n end\n elseif pType == 'table' then\n \n local startIndex = #pnts\n local interval = 1\n for i = 1, pointCount do\n local index = startIndex + interval\n \n local point = points[i]\n local x,y = point[1],point[2]\n handleBound(x,y)\n \n pnts[index] = x\n pnts[index + 1] = y\n interval=interval+2\n end\n else\n print('No compatible format found.')\n end\n end\n end\n end\n \n function user.getRotationManager()\n return mRot\n end\n \n local function updateNormal()\n if elementData[14] then\n user.setNormal(createNormal(pointSet, mainRotation[1],mainRotation[2],mainRotation[3],mainRotation[4]))\n end\n end\n \n function user.rotateDefaultXYZ(rX,rY,rZ,rW) mRot.rotateDefaultXYZ(rX,rY,rZ,rW); updateNormal() end\n function user.rotateDefaultX(rX) mRot.rotateDefaultX(rX); updateNormal() end\n function user.rotateDefaultY(rY) mRot.rotateDefaultY(rY); updateNormal() end\n function user.rotateDefaultZ(rZ) mRot.rotateDefaultZ(rZ); updateNormal() end\n \n function user.rotateXYZ(rX,rY,rZ,rW) mRot.rotateXYZ(rX,rY,rZ,rW); updateNormal() end\n function user.rotateX(rX) mRot.rotateX(rX); updateNormal() end\n function user.rotateY(rY) mRot.rotateY(rY); updateNormal() end\n function user.rotateZ(rZ) mRot.rotateZ(rZ); updateNormal() end\n \n\n local function drawChecks()\n local defaultDraw = elementData[2]\n if defaultDraw then\n if not elementData[3] then\n elementData[3] = elementData[2]\n end\n if not elementData[1] then\n elementData[1] = elementData[2]\n end\n end\n end\n local function actionCheck()\n actions[7] = true\n end\n \n function user.setHoverDraw(hDraw) elementData[1] = hDraw; drawChecks() end\n function user.setDefaultDraw(dDraw) elementData[2] = dDraw; drawChecks() end\n function user.setClickDraw(cDraw) elementData[3] = cDraw; drawChecks() end\n \n function user.setClickAction(action) actions[1] = action; actionCheck() end\n function user.setHoldAction(action) actions[2] = action; actionCheck() end\n function user.setEnterAction(action) actions[3] = action; actionCheck() end\n function user.setLeaveAction(action) actions[4] = action; actionCheck() end\n function user.setHoverAction(action) actions[5] = action; actionCheck() end\n function user.setIdentifier(identifier) actions[6] = identifier; end\n \n function user.setScale(scale) \n elementData[5] = scale\n end\n \n function user.getMaxValues()\n return maxX,minX,maxY,minY\n end\n \n function user.hide() elementData[6] = false end\n function user.show() elementData[6] = true end\n function user.isShown() return elementData[6] end \n \n function user.remove() \n remove(elements,elementIndex)\n remove(elementClasses,elementIndex)\n for i = elementIndex, eC do\n elementClasses[i].setElementIndex(i)\n end\n end\n local psX,psY = 0,0\n function user.move(sx,sy,indices,updateHitbox)\n if not indices then\n for i = 1, #pointSet, 2 do\n pointSet[i] = pointSet[i] - psX + sx\n pointSet[i+1] = pointSet[i+1] - psY + sy\n end\n maxX,minX,maxY,minY = maxX+sx,minX+sx,maxY+sy,minY+sy\n else\n for i=1,#indices do\n local index = indices[i]*2-1\n pointSet[index] = pointSet[index] - psX + sx\n pointSet[index+1] = pointSet[index+1] - psY + sy\n end\n -- TODO: Check min-max values and update accordingly\n end\n psX = sx\n psY = sy\n \n if updateHitbox then\n user.setBounds(createBounds(pointSet))\n end\n end\n local ogPointSet = nil\n function user.moveTo(sx,sy,indices,updateHitbox,useOG)\n if not indices then\n print('ERROR: No indices specified!')\n else\n if not ogPointSet then\n ogPointSet = {table.unpack(pointSet)}\n end\n for i=1,#indices do\n local index = indices[i]*2-1\n if not useOG then\n pointSet[index] = sx\n pointSet[index+1] = sy\n else\n pointSet[index] = ogPointSet[index] + sx\n pointSet[index+1] = ogPointSet[index+1] + sy\n end\n end\n -- TODO: Check min-max values and update accordingly\n end\n if updateHitbox then\n user.setBounds(createBounds(pointSet))\n end\n end\n \n function user.setDrawOrder(indices)\n local drawOrder = {}\n for i=1, #indices do\n local index = indices[i]\n \n local order = drawOrder[index*2-1]\n if not order then\n order = {}\n drawOrder[index*2-1] = order\n end\n order[#order+1] = i*2-1\n end\n elementData[7] = drawOrder\n end\n \n function user.setDrawData(drawData) elementData[8] = drawData end\n function user.getDrawData() return elementData[8] end\n function user.setSizes(sizes) \n if not elementData[8] then\n elementData[8] = {['sizes'] = sizes}\n else\n elementData[8].sizes = sizes\n end\n end\n function user.getDrawOrder() return elementData[7] end\n \n function user.getPoints() return elementData[9] end\n \n function user.setDrawOrder(drawOrder) elementData[7] = drawOrder end\n function user.setDrawData(drawData) elementData[8] = drawData end\n \n function user.setPoints(points) pointSet = points; elementData[9] = pointSet end\n \n function user.setElementIndex(eI) elementIndex = eI end\n function user.getElementIndex(eI) return elementIndex end\n \n function user.setPosition(sx,sy,sz)\n mRot.setPosition(sx,sy,sz)\n end\n \n function user.setNormal(nx,ny,nz)\n elementData[11] = nx\n elementData[12] = ny\n elementData[13] = nz\n end\n \n function user.setBounds(bounds)\n elementData[14] = bounds\n end\n function user.getPosition() return mRot.getPosition() end\n \n function user.build(force, hasBounds)\n \n local nx, ny, nz = createNormal(pointSet, mainRotation[1],mainRotation[2],mainRotation[3],mainRotation[4])\n if nx then\n if elementData[2] then\n user.setNormal(nx,ny,nz)\n if not force then\n if hasBounds or hasBounds == nil then\n user.setBounds(createBounds(pointSet))\n else\n user.setBounds(false)\n end\n end\n else\n print(\"Element Malformed: No default draw.\")\n end\n else\n print(\"Element Malformed: Insufficient points.\")\n end\n end\n return user, elementData\n end\n\n function self.createText(tx, ty, tz)\n local concat,byte,upper = table.concat,string.byte,string.upper\n \n local userFunc, text = createUITemplate(tx, ty, tz)\n local textCache,offsetCacheX,offsetCacheY,txt = {},{},0,''\n local drawData = {['sizes']={0.08333333333},'white',1}\n local alignmentX,alignmentY = 'middle','middle'\n local wScale = 1\n local mx,my = 0,0\n local maxX,minX,maxY,minY = userFunc.getMaxValues()\n \n userFunc.setDrawData(drawData)\n \n function userFunc.getMaxValues()\n return maxX,minX,maxY,minY\n end\n function userFunc.getText()\n return txt\n end\n local function buildTextCache(text)\n txt = text\n local result = {byte(upper(text), 1, #text)}\n textCache = {}\n for k = 1, #result do\n local charCode = result[k]\n textCache[k] = TEXT_ARRAY[charCode]\n end\n end\n local function buildOffsetCache()\n offsetCacheX = {0}\n local offsetXCounter = 1\n local tmpX,tmpY = 0,0\n local fontSize = drawData.sizes[1] / wScale\n \n for k = 1, #textCache do\n local char = textCache[k]\n if char[4] == 10 then\n tmpY = tmpY + char[2] * fontSize\n if alignmentX == \"middle\" then\n tmpX = -tmpX * 0.5\n elseif alignmentX == \"end\" then\n tmpX = -tmpX\n elseif alignmentX == \"start\" then\n tmpX = 0\n end\n offsetCacheX[offsetXCounter] = tmpX\n offsetXCounter = offsetXCounter + 1\n tmpX = 0\n else\n tmpX = tmpX + char[2] * fontSize\n end\n end\n if alignmentX == \"middle\" then\n tmpX = -tmpX * 0.5\n elseif alignmentX == \"end\" then\n tmpX = -tmpX\n elseif alignmentX == \"start\" then\n tmpX = 0\n end\n if alignmentY == 'middle' then\n tmpY = tmpY + 12 * fontSize\n offsetCacheY = -tmpY * 0.5\n elseif alignmentY == 'top' then\n tmpY = tmpY + 12 * fontSize\n offsetCacheY = -tmpY\n elseif alignmentY == 'bottom' then\n offsetCacheY = 0\n end\n offsetCacheX[offsetXCounter] = tmpX\n end\n \n local function handleBound(x,y)\n if x > maxX then\n maxX = x\n end\n if x < minX then\n minX = x\n end\n if y > maxY then\n maxY = y\n end\n if y < minY then\n minY = y\n end\n end\n \n local function buildPoints()\n local offsetY = offsetCacheY\n local woffsetX,offsetXCounter = offsetCacheX[1],1\n local fontSize = drawData.sizes[1] / wScale\n\n local points,drawStrings = {},{'<path stroke-width=\"%gpx\" stroke=\"%s\" stroke-opacity=\"%g\" fill=\"none\" d=\"'}\n local count = 1\n \n local textCacheSize = #textCache\n \n for k = 1, textCacheSize do\n local char = textCache[k]\n drawStrings[k + 1] = char[3]\n \n local charPoints, charSize = char[1], char[2]\n for m = 1, #charPoints, 2 do\n local x,y = charPoints[m] * fontSize + woffsetX + mx, charPoints[m + 1] * fontSize + offsetY + my\n \n handleBound(x,y)\n \n points[count] = x\n points[count + 1] = y\n count = count + 2\n end\n woffsetX = woffsetX + charSize * fontSize\n if char[4] == 10 then\n offsetXCounter = offsetXCounter + 1\n woffsetX = offsetCacheX[offsetXCounter]\n offsetY = offsetY - charSize * fontSize\n end\n end\n\n drawStrings[textCacheSize+2] = '\"/>'\n \n userFunc.setDefaultDraw(concat(drawStrings))\n userFunc.setPoints(points)\n end\n \n function userFunc.setText(text)\n buildTextCache(text)\n buildOffsetCache()\n \n buildPoints()\n end\n \n function userFunc.setWeight(scale)\n local sizes = drawData.sizes\n sizes[1] = sizes[1] / wScale\n wScale = scale or wScale\n sizes[1] = sizes[1] * wScale\n if #textCache > 0 then\n buildPoints()\n end\n end\n local oldUserFunc = userFunc.move\n function userFunc.move(x,y)\n mx = mx + x\n my = my + y\n oldUserFunc(x,y)\n end\n function userFunc.setFontSize(size)\n local sizes = drawData.sizes\n sizes[1] = size * 0.08333333333\n if #textCache > 0 then\n buildOffsetCache()\n buildPoints()\n end\n end\n function userFunc.setAlignmentX(alignX)\n alignmentX = alignX\n if #textCache > 0 then\n buildOffsetCache()\n buildPoints()\n end\n end\n function userFunc.setAlignmentY(alignY)\n alignmentY = alignY\n if #textCache > 0 then\n buildOffsetCache()\n buildPoints()\n end\n end\n function userFunc.setFontColor(color)\n drawData[1] = color\n end\n function userFunc.setOpacity(opacity)\n drawData[2] = opacity\n end\n \n return userFunc,textTemplate\n end\n\n function self.createButton(bx, by, bz)\n local userFunc,button = createUITemplate(bx, by, bz)\n local txtFuncs\n function userFunc.setText(text,rx, ry, rz)\n rx,ry,rz = rx or 0, ry or -0.01, rz or 0\n if not txtFuncs then\n txtFuncs = self.createText(bx+rx, by+ry, bz+rz)\n userFunc.addSubElement(txtFuncs)\n else\n txtFuncs.setPosition(bx+rx, by+ry, bz+rz)\n end\n local maxX,minX,maxY,minY = userFunc.getMaxValues()\n local cheight = maxY-minY\n local cwidth = maxX-minX\n txtFuncs.setText(text)\n \n local tMaxX,tMinX,tMaxY,tMinY = txtFuncs.getMaxValues()\n local theight = tMaxY-tMinY\n local twidth = tMaxX-tMinX\n local r1,r2 = theight/cheight,twidth/cwidth\n if r1 < r2 then\n local size = theight/r2\n txtFuncs.setFontSize((size)*0.75)\n else\n local size = theight/r1\n txtFuncs.setFontSize((size)*0.75)\n end\n return txtFuncs\n end\n return userFunc\n end\n \n function self.createProgressBar(ex, ey, ez)\n \n local userFuncOut,outline = createUITemplate(ex, ey, ez)\n local userFuncFill,fill = createUITemplate(ex, ey, ez, 1)\n\n userFuncOut.addSubElement(userFuncFill)\n\n local sPointIndices = {}\n local ePointIndices = {}\n local intervals = {}\n local progress = 100\n \n function userFuncOut.getIntervals()\n return intervals\n end\n \n function userFuncOut.getProgress(pX)\n local points = userFuncFill.getPoints()\n if pX then\n local c = intervals[1]\n local xC = c[1]\n \n local prog = (pX - points[sPointIndices[1]])/xC\n if prog < 0 then \n return 0.001 \n elseif prog > 100 then \n return 100 \n else \n return prog \n end\n end\n return progress\n end\n \n local function makeIntervals()\n \n local sPCount = #sPointIndices\n local ePCount = #ePointIndices\n \n local points = userFuncFill.getPoints()\n if #points > 0 then\n if sPCount == ePCount and sPCount > 0 then\n for i=1, sPCount do\n local sPI = sPointIndices[i]\n local ePI = ePointIndices[i]\n \n local xChangePercent = (points[ePI]-points[sPI]) * 0.01\n local yChangePercent = (points[ePI+1]-points[sPI+1]) * 0.01\n intervals[i] = {xChangePercent,yChangePercent}\n end\n end\n end\n end\n \n function userFuncOut.setStartIndices(indices)\n for i=1, #indices do\n local index = indices[i]*2-1\n sPointIndices[i]=index\n end\n makeIntervals()\n end\n \n function userFuncOut.setEndIndices(indices)\n for i=1, #indices do\n local index = indices[i]*2-1\n ePointIndices[i]=index\n end\n makeIntervals()\n end\n \n local addPointsOld = userFuncOut.addPoints\n function userFuncOut.addPoints(points) \n addPointsOld(points)\n makeIntervals()\n end\n \n function userFuncOut.setProgress(prog)\n progress = prog or 0\n if progress < 0 then\n progress = 0\n end\n if progress > 100 then\n progress = 100\n end\n local points = userFuncOut.getPoints()\n \n for i=1, #ePointIndices do\n local c = intervals[i]\n local xC,yC = c[1],c[2]\n local sPI = sPointIndices[i]\n local ePI = ePointIndices[i]\n \n points[ePI] = points[sPI] + xC * progress\n points[ePI+1] = points[sPI+1] + yC * progress\n \n end\n end\n function userFuncOut.setFillPoints(points)\n userFuncFill.addPoints(points)\n end\n function userFuncOut.getFillDrawData()\n return userFuncFill.getDrawData() \n end\n function userFuncOut.setFillDrawData(drawData)\n userFuncFill.setDrawData(drawData)\n end\n function userFuncOut.setFillDraw(draw)\n userFuncFill.setDefaultDraw(draw)\n end\n function userFuncOut.setFillOffsetPosition(tx,ty,tz)\n userFuncFill.setOffsetPosition(tx,ty,tz)\n end\n \n return userFuncOut\n end\n function self.createCustomDraw(x,y,z)\n return createUITemplate(x,y,z)\n end\n local mElementIndex = 0\n function self.create3DObject(x,y,z)\n local userFunc = {}\n local pointSet = {{},{},{},{}}\n local drawStrings = {}\n local faces = {}\n \n local actions = {false,false,false,false,false,false}\n local elementData = {is3D = true, false, false, false, actions, false, true, false, false, pointSet, x, y, z,faces}\n local eC = mElementIndex + 1\n mElementIndex = eC\n local mElementIndex = eC\n modelElements[eC] = elementData\n \n function userFunc.addPoints(points,ref)\n local pntX,pntY,pntZ,rotation = pointSet[1],pointSet[2],pointSet[3],pointSet[4]\n local s1,s2 = #pntX, #points\n local total = s1+s2\n pntX[total] = false\n pntY[total] = false\n pntZ[total] = false\n \n for i=s1+1, total do\n local pnt = points[i]\n pntX[i] = pnt[1]\n pntY[i] = pnt[2]\n pntZ[i] = pnt[3]\n end\n end\n \n \n function userFunc.setFaces(newFaces,r,g,b)\n local concat,remove = table.concat,table.remove\n local pntX,pntY,pntZ = pointSet[1],pointSet[2],pointSet[3]\n \n local function getData(pointIndices)\n local pntCount = #pointIndices\n if pntCount > 2 then\n local p1i,p2i,p3i = pointIndices[1],pointIndices[2],pointIndices[3]\n local p1x,p1y,p1z,p2x,p2y,p2z,p3x,p3y,p3z = pntX[p1i],pntY[p1i],pntZ[p1i],pntX[p2i],pntY[p2i],pntZ[p2i],pntX[p3i],pntY[p3i],pntZ[p3i]\n \n local v1x,v1y,v1z = p2x-p1x,p2y-p1y,p2z-p1z\n local v2x,v2y,v2z = p3x-p1x,p3y-p1y,p3z-p1z\n local nx,ny,nz = v1y*v2z-v1z*v2y,v1z*v2x-v1x*v2z,v1x*v2y-v2x*v1y\n local mag = (nx*nx+ny*ny+nz*nz)^(0.5)\n nx,ny,nz = nx/mag,ny/mag,nz/mag\n local pX,pY,pZ = p1x+p2x+p3x,p1y+p2y+p3y,p1z+p2z+p3z\n local oData = nil\n if pntCount == 4 then\n local tmpOData = getData({pointIndices[4],pointIndices[1],pointIndices[3]})\n if not (tmpOData[4] == nx and tmpOData[5] == ny and tmpOData[6] == nz) then\n remove(pointIndices,4)\n oData = tmpOData\n end\n \n end\n local count = 3\n local string = {'<path color=rgb(%.f,%.f,%.f) d=\"M%.1f %.1fL%.1f %.1f %.1f %.1f'}\n local sCount = 2\n for i=4, #pointIndices do\n local pi = pointIndices[i]\n pX,pY,pZ = pX + pntX[pi],pY+ pntY[pi],pZ+ pntZ[pi] \n count = count + 1\n string[sCount] = ' %.1f %.1f'\n sCount = sCount + 1\n end\n string[sCount] = 'Z\"/>'\n --local pn1 = pointIndices[1]\n \n return {pX/count,pY/count,pZ/count,nx,ny,nz,pointIndices,r,g,b,concat(string)},oData\n end\n end\n local m = 1\n for i=1, #newFaces do\n local data,oData = getData(newFaces[i])\n faces[m] = data\n m=m+1\n if oData then\n faces[m] = oData\n m=m+1\n end\n end\n end\n \n function userFunc.setScale()\n end\n function userFunc.setDrawData(drawData) elementData[8] = drawData end\n \n return userFunc\n end\n function self.createSlider(uiElement, center)\n local self = {}\n return self\n end\n return self\n end\n \n function self.setPosition(posX, posY, posZ) self[11] = {posX, posY, posZ} end\n \n function self.rotateDefaultXYZ(rX,rY,rZ,rW) objRotationHandler.rotateDefaultXYZ(rX,rY,rZ,rW); end\n function self.rotateDefaultX(rX) objRotationHandler.rotateDefaultX(rX); end\n function self.rotateDefaultY(rY) objRotationHandler.rotateDefaultY(rY); end\n function self.rotateDefaultZ(rZ) objRotationHandler.rotateDefaultZ(rZ); end\n \n function self.rotateXYZ(rX,rY,rZ,rW) objRotationHandler.rotateXYZ(rX,rY,rZ,rW); end\n function self.rotateX(rX) objRotationHandler.rotateX(rX); end\n function self.rotateY(rY) objRotationHandler.rotateY(rY); end\n function self.rotateZ(rZ) objRotationHandler.rotateZ(rZ); end\n \n function self.addSubObject(object, id)\n local id=id or #self[6]+1\n self[6][id]=object\n return id\n end\n function self.removeSubObject(id)\n self[6][id]={}\n end\n \n function self.setSubObjects()\n local self={}\n local c=1\n function self.addSubObject(object)\n self[6][c]=object\n c=c+1\n return self\n end\n return self\n end\n \n return self\nend\n\nfunction ObjectBuilderLinear()\n local self={}\n function self.setStyle(style)\n local self={}\n local style=style\n function self.setPosition(pos)\n local self={}\n local pos=pos\n function self.setOffset(offset)\n local self={}\n local offset=offset\n function self.setOrientation(orientation)\n local self={}\n local orientation=orientation\n function self.setPositionType(positionType)\n local self={}\n local positionType=positionType\n function self.setOrientationType(orientationType)\n local self={}\n local orientationType = orientationType\n local transX,transY=nil,nil\n function self.setTranslation(translateX,translateY)\n transX,transY=translateX,translateY\n return self\n end\n function self.build()\n return Object(style,pos,offset,orientation,positionType,orientationType,transX,transY)\n end\n return self\n end\n return self\n end\n return self\n end\n return self\n end\n return self\n end\n return self\n end\n return self\nend","filter":{"args":[],"signature":"start()","slotKey":"-3"},"key":"4"},{"code":"local rad = math.rad\nCameraTypes={\n fixed={\n fLocal={\n name=\"fLocal\",\n id = 0\n },\n fGlobal={\n name=\"fGlobal\",\n id = 1\n }\n },\n player={\n name=\"player\",\n id = 2\n }\n}\n\nfunction Camera(camType, position, orientation)\n \n local isViewLocked = false\n \n local rad=math.rad\n local ori = orientation or {0,0,0}\n local self = {\n cType = camType or CameraTypes.player,\n position = (position or {0,0,0}), \n orientation = ori,\n isViewLocked = false\n }\n \n function self.rotateHeading(heading) self.orientation[2]=self.orientation[2]+rad(heading) end\n function self.rotatePitch(pitch) self.orientation[1]=self.orientation[1]+rad(pitch) end\n function self.rotateRoll(roll) self.orientation[3]=self.orientation[3]+rad(roll) end\n function self.setAlignmentType(alignmentType) self.cType = alignmentType end\n function self.setPosition(pos) self.position={pos[1],pos[2],pos[3]} end\n\n return self\nend","filter":{"args":[],"signature":"start()","slotKey":"-3"},"key":"5"},{"code":"function getManager()\n local self = {}\n -- Misc function calls\n local solve=library.systemResolution3\n local sqrt,atan,asin,acos,print=math.sqrt,math.atan,math.asin,math.acos,system.print\n \n --- Core-based function calls\n local gCWOR,gCWOF,gCWOU,gCLOR,gCLOF,gCLOU,gCWR,gCWF,gCWU=core.getConstructWorldOrientationRight,core.getConstructWorldOrientationForward,core.getConstructWorldOrientationUp,core.getConstructOrientationRight,core.getConstructOrientationForward,core.getConstructOrientationUp,core.getConstructWorldRight,core.getConstructWorldForward,core.getConstructWorldUp\n local gWTLC,gLTWC=nil,nil\n \n function self.getLocalToWorldConverter()\n local s=solve\n local r,f,u=gCWR(),gCWF(),gCWU()\n local tr = {r[1],f[1],u[1]}\n local tf = {r[2],f[2],u[2]}\n local tu = {r[3],f[3],u[3]}\n return function(c)\n return s(tr, tf, tu, c) \n end\n end\n\n function self.getWorldToLocalConverter()\n local xM,yM,zM=gCWR(),gCWF(),gCWU()\n local s = solve\n return function(w) return solve(xM,yM,zM,w) end\n end\n function self.quatToAxisAngle(ax,ay,az,aw)\n local awaw = 1/sqrt(1-aw*aw)\n\n return ax*awaw, ay*awaw, az*awaw, 2*acos(aw)\n end\n local function matrixToQuat(m11,m21,m31,m12,m22,m32,m13,m23,m33)\n local t=m11+m22+m33\n if t>0 then\n local s=0.5/sqrt(t+1)\n return (m32-m23)*s,(m13-m31)*s,(m21-m12)*s,0.25/s\n elseif m11>m22 and m11>m33 then\n local s = 2*sqrt(1+m11-m22-m33)\n return 0.25*s,(m12+m21)/s,(m13+m31)/s,(m32-m23)/s\n elseif m22>m33 then\n local s=2*sqrt(1+m22-m11-m33)\n return (m12+m21)/s,0.25*s,(m23+m32)/s,(m13-m31)/s\n else\n local s=2*sqrt(1+m33-m11- m22)\n return (m13+m31)/s,(m23+m32)/s,0.25*s,(m21-m12)/s\n end\n end\n \n function self.getPlayerLocalRotation()\n local fwd = unit.getMasterPlayerForward()\n local right = unit.getMasterPlayerRight()\n local up = unit.getMasterPlayerUp()\n\n return matrixToQuat(right[1],right[2],right[3],fwd[1],fwd[2],fwd[3],up[1],up[2],up[3])\n end\n \n \n function self.rotMatrixToQuat(rM1,rM2,rM3)\n if rM2 and rM3 then\n return matrixToQuat(rM1[1],rM1[2],rM1[3],rM2[1],rM2[2],rM2[3],rM3[1],rM3[2],rM3[3])\n else\n return matrixToQuat(rM1[1],rM1[5],rM1[9],rM1[2],rM1[6],rM1[10],rM1[3],rM1[7],rM1[11])\n end\n end\n function self.inverse(qX,qY,qZ,qW)\n return -qX,-qY,-qZ,qW\n end\n function self.inverseMulti(ax,ay,az,aw,bx,by,bz,bw)\n local axax,ayay,azaz,awaw=ax*ax,ay*ay,az*az,aw*aw\n return bx*(awaw-axax-ayay-azaz)+2*aw*(ax*bw+ay*bz-az*by),2*(bx*(aw*az+ax*ay)+bz*(ay*az-aw*ax))+by*(awaw-axax+ayay-azaz),2*(bx*(ax*az-aw*ay)+by*(ax*aw+ay*az))+bz*(awaw-axax-ayay+azaz),bw*(awaw+axax+ayay+azaz)\n end\n function self.transPoint3D(ax,ay,az,aw,bx,by,bz)\n local axax,ayay,azaz,awaw=ax*ax,ay*ay,az*az,aw*aw\n return \n 2*(by*(ax*ay-aw*az)+bz*(ax*az+aw*ay))+bx*(awaw+axax-ayay-azaz),\n 2*(bx*(aw*az+ax*ay)+bz*(ay*az-aw*ax))+by*(awaw-axax+ayay-azaz),\n 2*(bx*(ax*az-aw*ay)+by*(ax*aw+ay*az))+bz*(awaw-axax-ayay+azaz)\n end\n \n function self.transPoints3D(ax,ay,az,aw,points)\n \n local axax,ayay,azaz,awaw=ax*ax,ay*ay,az*az,aw*aw\n \n -- What I derived\n local a,b,c = (awaw+axax-ayay-azaz), 2*(ax*ay-aw*az), 2*(ax*az+aw*ay)\n local d,f,e = 2*(aw*az+ax*ay), (awaw-axax+ayay-azaz), 2*(ay*az-aw*ax)\n local g,h,i = 2*(ax*az-aw*ay), 2*(ax*aw+ay*az), (awaw-axax-ayay+azaz)\n \n local pts={}\n for i=1,#points,3 do\n local x,y,z=points[i],points[i+1],points[i+2]\n pts[i]=x*a+y*b+z*c\n pts[i+1]=x*d+y*e+z*f\n pts[i+2]=x*g+y*h+z*i\n end\n return pts\n end\n function self.transPoints2D(ax,ay,az,aw,points)\n local axax,ayay,azaz,awaw=ax*ax,ay*ay,az*az,aw*aw\n local b,c=2*(ax*az+aw*ay),(awaw+axax-ayay-azaz)\n local d,e=2*(aw*az+ax*ay),2*(ay*az-aw*ax)\n local g,i=2*(ax*az-aw*ay),(awaw-axax-ayay+azaz)\n local pts={}\n for i=1,#points,3 do\n local x,z=points[i],points[i+2]\n pts[i]=x*c+z*b\n pts[i+1]=x*d+z*e\n pts[i+2]=x*g+z*i\n end\n return pts\n end\n function self.multiply(ax,ay,az,aw,bx,by,bz,bw)\n return ax*bw+aw*bx+ay*bz-az*by,ay*bw+aw*by+az*bx-ax*bz,az*bw+aw*bz+ax*by-ay*bx,aw*bw-ax*bx-ay*by-az*bz\n end\n \n function self.transPoint2D(ax,ay,az,aw,x,y)\n local axax,ayay,azaz,awaw=ax*ax,ay*ay,az*az,aw*aw\n return 2*z*(ax*az+aw*ay)+x*(awaw+axax-ayay-azaz),2*(x*(aw*az+ax*ay)+z*(ay*az-aw*ax)),2*x*(ax*az-aw*ay)+z*(awaw-axax-ayay+azaz)\n end\n gWTLC,gLTWC=self.getWorldToLocalConverter,self.getLocalToWorldConverter\n return self\nend","filter":{"args":[],"signature":"start()","slotKey":"-3"},"key":"6"},{"code":"function Waypoint(x,y,z, radius, name, subId)\n local sqrt,ceil,floor,max=math.sqrt,math.ceil,math.floor,math.max\n local function round(value, precision)\n local value = value/precision\n local value = value >= 0 and floor(value+0.5) or ceil(value-0.5)\n return value * precision\n end\n \n local getCWorldPos,getCMass = core.getConstructWorldPos,core.getConstructMass\n \n local keyframe = 0\n local self = {\n radius = radius,\n x = x,\n y = y,\n z = z,\n name = name,\n subId = subId,\n keyframe = keyframe\n }\n \n function self.getWaypointInfo()\n local tons = getCMass() / 1000\n local cPos = getCWorldPos()\n local px,py,pz = self.x-cPos[1], self.y-cPos[2], self.z-cPos[3]\n local distance = sqrt(px*px + py*py + pz*pz)\n local warpCost = max(floor(tons*floor(((distance/1000)/200))*0.00024), 1)\n local name = self.name\n \n return name, round((distance/1000)/200, 0.01), warpCost,round((distance/1000), 0.01),round(distance, 0.01)\n end\n return self\nend","filter":{"args":[],"signature":"start()","slotKey":"-3"},"key":"7"}],"methods":[],"events":[]}