-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathNewWaypointer.json
More file actions
1 lines (1 loc) · 43.8 KB
/
NewWaypointer.json
File metadata and controls
1 lines (1 loc) · 43.8 KB
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":[]}},"-3":{"name":"player","type":{"events":[],"methods":[]}},"-2":{"name":"construct","type":{"events":[],"methods":[]}},"-4":{"name":"system","type":{"events":[],"methods":[]}},"-5":{"name":"library","type":{"events":[],"methods":[]}}},"handlers":[{"code":"local sqrt, len, max, print = math.sqrt, string.len, math.max, system.print\n\nlocal lowLatencyMode = true --export: enables low latency for screen render, which can sometimes bug out if a frame gets skipped. A restart is required then.\nlocal smooth = true --export: enables full FPS rendering, which increases the preceived performance for an actual performance impact.\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 = require('atlas')\n\nlocal function bTW(bool)\n if bool then\n return \"enabled\"\n else\n return \"disabled\"\n end\nend\nlocal localeIndex = {\n ['en-US'] = 1,\n ['fr-FR'] = 2,\n ['de-De'] = 3\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\nprojector = Projector()\nprojector.setSmooth(smooth)\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}]]\nwaypointObjectGroup.setStyle(css)\n\nif not highPerformanceMode then\n waypointObjectGroup.setGlow(true, glowRadius)\nend\nif not lowLatencyMode then\n projector.setLowLatency(lowLatencyMode)\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, data.localeType, opacity,dU,c,c1,stroke)\n c,c1 = drawText(content, tx + 60 - keyframe*10, ty+(font+5)*3, warpCost .. ' Warp Cells', opacity,dU,c,c1,stroke)\n else\n c,c1 = drawText(content, tx + 60 - keyframe*10, ty+(font+5)*2, data.localeType, opacity,dU,c,c1,stroke)\n end\n end\n return c\nend\nlocal concat,unpack = table.concat,table.unpack\nlocal function draw(tx,ty,tz,data)\n local dU, c = {},1\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 local _,distance = data.getWaypointInfo()\n if data.type == 'Planet' then\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 elseif data.type == 'Moon' then\n if distance > 20 then\n return ''\n end\n else\n if distance > 10 then\n return ''\n end\n end\n local stroke = colorWarp\n \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 c=drawInfo(content, tx + size + 5, ty - size + 5, data,dU,c,c1+1,stroke,distanceToMouse)\n return concat(content):format(unpack(dU))\nend\nlocal solarWaypoints = objectBuilder\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.getSinglePointBuilder()\nlocal localizationIndex = localeIndex[system.getLocale()]\nlocal i = 1\nfor k,stellar in pairs(waypointInfo[0]) do\n local wCenter = stellar.center\n local wName = stellar.name[localizationIndex]\n local wRadius = stellar.radius\n local wType = stellar.type[1]\n local wlType = stellar.type[localizationIndex]\n \n local waypointObject = Waypoint(wCenter[1],wCenter[2],wCenter[3], wRadius * 1.25, wName, wType, wlType, subId)\n local customSVG = builder.addSinglePointSVG()\n waypoints[i] = {wCenter, waypoint}\n customSVG.setPosition({wCenter[1], wCenter[2], wCenter[3]})\n \t .setData(waypointObject)\n \t .setDrawFunction(draw)\n \t .build()\n i = i + 1\nend\nunit.setTimer(\"update\", 1/1000) -- The timer to update the screen\nsystem.showScreen(1)\nunit.hide()\nrot = 0","filter":{"args":[],"signature":"start()","slotKey":"-1"},"key":"0"},{"code":"local svg, index = projector.getSVG()\nsystem.setScreen(svg)","filter":{"args":[{"value":"update"}],"signature":"onTimer(tag)","slotKey":"-1"},"key":"1"},{"code":"waypoint = true","filter":{"args":[{"value":"option1"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"2"},{"code":"projector.refresh()","filter":{"args":[{"value":"option2"}],"signature":"onActionStart(action)","slotKey":"-4"},"key":"3"},{"code":"function LinkedList(name, prefix)\n local functions = {}\n local internalDataTable = {}\n local internalTableSize = 0\n local removeKey,addKey,indexKey,refKey = prefix .. 'Remove',prefix .. 'Add',prefix..'index',prefix..'ref'\n \n functions[removeKey] = function (node)\n local tblSize,internalDataTable = internalTableSize,internalDataTable\n if tblSize > 1 then\n if node[indexKey] == -1 then return end\n local lastElement,replaceNodeIndex = internalDataTable[tblSize],node[indexKey]\n internalDataTable[replaceNodeIndex] = lastElement\n internalDataTable[tblSize] = nil\n lastElement[indexKey] = replaceNodeIndex\n internalTableSize = tblSize - 1\n node[indexKey] = -1\n node[refKey] = nil\n elseif tblSize == 1 then\n internalDataTable[1] = nil\n internalTableSize = 0\n node[indexKey] = -1\n node[refKey] = nil\n end\n end\n\n functions[addKey] = function (node, override)\n local indexKey,refKey = indexKey,refKey\n if node[indexKey] and node[indexKey] ~= -1 then\n if not node[refKey] == functions or override then\n node[refKey][removeKey](node)\n else\n return\n end\n end\n local tblSize = internalTableSize + 1\n \n internalDataTable[tblSize] = node\n node[indexKey] = tblSize\n node[refKey] = functions\n internalTableSize = tblSize\n end\n\n functions[prefix .. 'GetData'] = function ()\n return internalDataTable, internalTableSize\n end\n\n return functions\nend\n\nlocal math = math\nlocal sin, cos, rad, type = math.sin,math.cos,math.rad, type\n\nfunction RotMatrixToQuat(m1,m2,m3)\n local m11,m22,m33 = m1[1],m2[2],m3[3]\n local t=m11+m22+m33\n if t>0 then\n local s=0.5/(t+1)^(0.5)\n return (m2[3]-m3[2])*s,(m3[1]-m1[3])*s,(m1[2]-m2[1])*s,0.25/s\n elseif m11>m22 and m11>m33 then\n local s = 1/(2*(1+m11-m22-m33)^(0.5))\n return 0.25/s,(m2[1]+m1[2])*s,(m3[1]+m1[3])*s,(m2[3]-m3[2])*s\n elseif m22>m33 then\n local s=1/(2*(1+m22-m11-m33)^(0.5))\n return (m2[1]+m1[2])*s,0.25/s,(m3[2]+m2[3])*s,(m3[1]-m1[3])*s\n else\n local s=1/(2*(1+m33-m11-m22)^(0.5))\n return (m3[1]+m1[3])*s,(m3[2]+m2[3])*s,0.25/s,(m1[2]-m2[1])*s\n end\nend\n\nfunction GetQuaternion(x,y,z,w)\n if type(x) == 'number' then\n if w == nil then\n if x == x and y == y and z == z then\n local rad,sin,cos = rad,sin,cos\n x,y,z = -rad(x * 0.5),rad(y * 0.5),-rad(z * 0.5)\n local sP,sH,sR=sin(x),sin(y),sin(z)\n local cP,cH,cR=cos(x),cos(y),cos(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 0,0,0,1\n end\n else\n return x,y,z,w\n end\n elseif type(x) == 'table' then\n if #x == 3 then\n local x,y,z,w = RotMatrixToQuat(x, y, z)\n return x,y,z,-w\n elseif #x == 4 then\n return x[1],x[2],x[3],x[4]\n else\n print('Unsupported Rotation!')\n end\n end\nend\nfunction QuaternionMultiply(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\nend\n\nfunction RotatePoint(ax,ay,az,aw,oX,oY,oZ,wX,wY,wZ)\n local t1,t2,t3 = 2*(ax*oY - ay*oX),2*(ax*oZ - az*oX),2*(ay*oZ - az*oY)\n return \n oX + ay*t1 + az*t2 + aw*t3 + wX,\n oY - ax*t1 - aw*t2 + az*t3 + wY,\n oZ + aw*t1 - ax*t2 - ay*t3 + wZ\nend\nfunction getRotationManager(out_rotation, wXYZ, name)\n --====================--\n --Local Math Functions--\n --====================--\n local print,type,unpack,multiply,rotatePoint,getQuaternion = DUSystem.print,type,table.unpack,QuaternionMultiply,RotatePoint,GetQuaternion\n\n local superManager,needsUpdate,notForwarded,needNormal = nil,false,true,false\n local outBubble = nil\n --=================--\n --Positional Values--\n --=================--\n local pX,pY,pZ = wXYZ[1],wXYZ[2],wXYZ[3] -- These are original values, for relative to super rotation\n local positionIsRelative = false\n local doRotateOri,doRotatePos = true,true\n local posY = math.random()*0.00001\n\n --==================--\n --Orientation Values--\n --==================--\n local tix,tiy,tiz,tiw = 0,0,0,1 -- temp intermediate rotation values\n\n local ix,iy,iz,iw = 0,0,0,1 -- intermediate rotation values\n local nx,ny,nz = 0,1,0\n\n local subRotQueue = {}\n local subRotations = LinkedList(name, 'sub')\n\n --==============--\n --Function Array--\n --==============--\n local out = {}\n\n --=======--\n --=Cache=--\n --=======--\n local cache = {0,0,0,1,0,0,0,0,0,0}\n \n --============================--\n --Primary Processing Functions--\n --============================--\n local function process(wx,wy,wz,ww,lX,lY,lZ,lTX,lTY,lTZ)\n if not wx then\n wx,wy,wz,ww,lX,lY,lZ,lTX,lTY,lTZ = unpack(cache)\n else\n cache = {wx,wy,wz,ww,lX,lY,lZ,lTX,lTY,lTZ}\n end\n local dx,dy,dz = pX,pY,pZ\n if not positionIsRelative then\n dx,dy,dz = dx - lX, dy - lY, dz - lZ\n end\n if doRotatePos then\n wXYZ[1],wXYZ[2],wXYZ[3] = rotatePoint(wx,wy,wz,-ww,dx,dy,dz,lTX,lTY,lTZ)\n else\n wXYZ[1],wXYZ[2],wXYZ[3] = dx+lTX,dy+lTY,dz+lTZ\n end\n if doRotateOri then\n wx,wy,wz,ww = multiply(ix,iy,iz,iw,wx,wy,wz,ww)\n else\n wx,wy,wz,ww = ix,iy,iz,iw\n end\n \n out_rotation[1],out_rotation[2],out_rotation[3],out_rotation[4] = wx,wy,wz,ww\n if needNormal then\n nx,ny,nz = 2*(wx*wy+wz*ww),1-2*(wx*wx+wz*wz),2*(wy*wz-wx*ww)\n end\n local subRots,subRotsSize = subRotations.subGetData()\n \n for i=1, subRotsSize do\n subRots[i].update(wx,wy,wz,ww,pX,pY,pZ,wXYZ[1],wXYZ[2],wXYZ[3])\n end\n needsUpdate = false\n notForwarded = true\n end\n out.update = process\n local function validate()\n if not superManager then\n process()\n else\n superManager.bubble()\n end\n end\n local function rotate()\n local tx,ty,tz,tw = getQuaternion(tix,tiy,tiz,tiw)\n if tx ~= ix or ty~= iy or tz ~= iz or tw ~= iw then\n ix, iy, iz, iw = tx, ty, tz, tw\n validate()\n out.bubble()\n return true\n end\n return false\n end\n function out.enableNormal()\n needNormal = true\n end\n function out.disableNormal()\n needNormal = false\n end\n function out.setSuperManager(rotManager)\n superManager = rotManager\n if not rotManager then\n cache = {0,0,0,1,0,0,0,0,0,0}\n needsUpdate = true\n end\n end\n function out.addToQueue(func)\n if not needsUpdate then\n subRotQueue[#subRotQueue+1] = func\n end\n end\n\n function out.addSubRotation(rotManager)\n rotManager.setSuperManager(out)\n subRotations.subAdd(rotManager, true)\n out.bubble()\n end\n function out.remove()\n if superManager then\n superManager.removeSubRotation(out)\n out.setSuperManager(false)\n out.bubble()\n end\n end\n function out.removeSubRotation(sub)\n sub.setSuperManager(false)\n subRotations.subRemove(sub)\n end\n function out.bubble()\n if superManager and not needsUpdate then\n subRotQueue = {}\n needsUpdate = true\n notForwarded = false\n superManager.addToQueue(process)\n else\n needsUpdate = true\n end\n end\n\n function out.checkUpdate()\n local neededUpdate = needsUpdate\n if neededUpdate and notForwarded then\n process()\n subRotQueue = {}\n elseif notForwarded then\n for i=1, #subRotQueue do\n subRotQueue[i]()\n end\n subRotQueue = {}\n else\n superManager.checkUpdate()\n end\n return neededUpdate\n end\n local outBubble = out.bubble\n local function assignFunctions(inFuncArr,specialCall)\n inFuncArr.update = process\n function inFuncArr.getPosition() return pX,pY,pZ end\n function inFuncArr.getRotationManger() return out end\n function inFuncArr.getSubRotationData() return subRotations.subGetData() end\n inFuncArr.checkUpdate = out.checkUpdate\n function inFuncArr.setPosition(tx,ty,tz)\n if type(tx) == 'table' then\n tx,ty,tz = tx[1],tx[2],tx[3]\n end\n if not (tx ~= tx or ty ~= ty or tz ~= tz) then\n local tmpY = ty+posY\n if pX ~= tx or pY ~= tmpY or pZ ~= tz then\n pX,pY,pZ = tx,tmpY,tz\n outBubble()\n return true\n end\n end\n return false\n end\n function inFuncArr.getNormal()\n return nx,ny,nz\n end\n function inFuncArr.rotateXYZ(rotX,rotY,rotZ,rotW)\n if rotX and rotY and rotZ then\n tix,tiy,tiz,tiw = rotX,rotY,rotZ,rotW\n rotate()\n if specialCall then specialCall() end\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 local result = rotate()\n if specialCall then specialCall() end\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 return false\n end\n\n end\n\n function inFuncArr.rotateX(rotX) tix = rotX; tiw = nil; rotate(); if specialCall then specialCall() end end\n function inFuncArr.rotateY(rotY) tiy = rotY; tiw = nil; rotate(); if specialCall then specialCall() end end\n function inFuncArr.rotateZ(rotZ) tiz = rotZ; tiw = nil; rotate(); if specialCall then specialCall() end end\n\n function inFuncArr.setDoRotateOri(rot) doRotateOri = rot; outBubble() end\n function inFuncArr.setDoRotatePos(rot) doRotatePos = rot; outBubble() end\n \n function inFuncArr.setPositionIsRelative(isRelative) positionIsRelative = isRelative; outBubble() end\n function inFuncArr.getRotation() return ix, iy, iz, iw end\n end\n out.assignFunctions = assignFunctions\n\n return out\nend","filter":{"args":[],"signature":"onStart()","slotKey":"-5"},"key":"4"},{"code":"function Projector()\n -- Localize frequently accessed data\n local construct, player, system, math = DUConstruct, DUPlayer, DUSystem, math\n \n -- Internal Parameters\n local frameBuffer,frameRender,isSmooth,lowLatency = {'',''},true,true,true\n\n -- Localize frequently accessed functions\n --- System-based function calls\n local getWidth, getHeight, getTime, setScreen =\n system.getScreenWidth,\n system.getScreenHeight,\n system.getArkTime,\n system.setScreen\n\n --- Camera-based function calls\n \n local getCamWorldRight, getCamWorldFwd, getCamWorldUp, getCamWorldPos =\n system.getCameraWorldRight,\n system.getCameraWorldForward,\n system.getCameraWorldUp,\n system.getCameraWorldPos\n \n local getConWorldRight, getConWorldFwd, getConWorldUp, getConWorldPos = \n construct.getWorldRight,\n construct.getWorldForward,\n construct.getWorldUp,\n construct.getWorldPosition\n\n --- Manager-based function calls\n ---- Quaternion operations\n local rotMatrixToQuat,quatMulti = RotMatrixToQuat,QuaternionMultiply\n \n -- Localize Math functions\n local tan, atan, rad = math.tan, math.atan, math.rad\n\n --- FOV Paramters\n local horizontalFov = system.getCameraHorizontalFov\n local fnearDivAspect = 0\n\n local objectGroups = LinkedList('Group', '')\n\n local self = {}\n\n function self.getSize(size, zDepth, max, min)\n local pSize = atan(size, zDepth) * fnearDivAspect\n if max then\n if pSize >= max then\n return max\n else\n if min then\n if pSize < min then\n return min\n end\n end\n return pSize\n end\n end\n return pSize\n end\n \n function self.refresh() frameRender = not frameRender; end\n \n function self.setLowLatency(low) lowLatency = low; end\n \n function self.setSmooth(iss) isSmooth = iss; end\n\n function self.addObjectGroup(objectGroup) objectGroups.Add(objectGroup) end\n\n function self.removeObjectGroup(objectGroup) objectGroups.Remove(objectGroup) end\n \n function self.getSVG()\n local getTime, atan, sort, unpack, format, concat, quatMulti = getTime, atan, table.sort, table.unpack, string.format, table.concat, quatMulti\n local startTime = getTime()\n frameRender = not frameRender\n local isClicked = false\n if clicked then\n clicked = false\n isClicked = true\n end\n local isHolding = holding\n\n local buffer = {}\n\n local width,height = getWidth(), getHeight()\n local aspect = width/height\n local tanFov = tan(rad(horizontalFov() * 0.5))\n \n --- Matrix Subprocessing\n local nearDivAspect = (width*0.5) / tanFov\n fnearDivAspect = nearDivAspect\n\n -- Localize projection matrix values\n local px1 = 1 / tanFov\n local pz3 = px1 * aspect\n\n local pxw,pzw = px1 * width * 0.5, -pz3 * height * 0.5\n \n --- View Matrix Processing\n --- View Matrix Processing\n \n \n -- Localize screen info\n local objectGroupsArray,objectGroupSize = objectGroups.GetData()\n local svgBuffer,svgZBuffer,svgBufferCounter = {},{},0\n\n local processPure = ProcessPureModule\n local processUI = ProcessUIModule\n local processRots = ProcessOrientations\n local processEvents = ProcessActionEvents\n if processPure == nil then\n processPure = function(zBC) return zBC end\n end\n if processUI == nil then\n processUI = function(zBC) return zBC end\n processRots = function() end\n processEvents = function() end\n end\n local predefinedRotations = {}\n local camR,camF,camU,camP = getCamWorldRight(),getCamWorldFwd(),getCamWorldUp(),getCamWorldPos()\n \n do\n local cwr,cwf,cwu = getConWorldRight(),getConWorldFwd(),getConWorldUp()\n ConstructReferential.rotateXYZ(cwr,cwf,cwu)\n ConstructOriReferential.rotateXYZ(cwr,cwf,cwu)\n ConstructReferential.setPosition(getConWorldPos())\n ConstructReferential.checkUpdate()\n ConstructOriReferential.checkUpdate()\n end\n local vx,vy,vz,vw = rotMatrixToQuat(camR,camF,camU)\n \n local vxx,vxy,vxz,vyx,vyy,vyz,vzx,vzy,vzz = camR[1]*pxw,camR[2]*pxw,camR[3]*pxw,camF[1],camF[2],camF[3],camU[1]*pzw,camU[2]*pzw,camU[3]*pzw\n local ex,ey,ez = camP[1],camP[2],camP[3]\n local deltaPreProcessing = getTime() - startTime\n local deltaDrawProcessing, deltaEvent, deltaZSort, deltaZBufferCopy, deltaPostProcessing = 0,0,0,0,0\n for i = 1, objectGroupSize do\n local objectGroup = objectGroupsArray[i]\n if objectGroup.enabled == false then\n goto not_enabled\n end\n local objects = objectGroup.objects\n\n local avgZ, avgZC = 0, 0\n local zBuffer, zSorter, zBC = {},{}, 0\n\n local notIntersected = true\n for m = 1, #objects do\n local obj = objects[m]\n if not obj[1] then\n goto is_nil\n end\n\n obj.checkUpdate()\n local objOri, objPos, oriType, posType = obj[5], obj[6], obj[7], obj[8]\n local objX,objY,objZ = objPos[1]-ex,objPos[2]-ey,objPos[3]-ez\n local mx,my,mz,mw = objOri[1], objOri[2], objOri[3], objOri[4]\n \n local a,b,c,d = quatMulti(mx,my,mz,mw,vx,vy,vz,vw)\n local aa, ab, ac, ad, bb, bc, bd, cc, cd = 2*a*a, 2*a*b, 2*a*c, 2*a*d, 2*b*b, 2*b*c, 2*b*d, 2*c*c, 2*c*d\n \n local mXX, mXY, mXZ,\n mYX, mYY, mYZ,\n mZX, mZY, mZZ = \n (1 - bb - cc)*pxw, (ab + cd)*pxw, (ac - bd)*pxw,\n (ab - cd), (1 - aa - cc), (bc + ad),\n (ac + bd)*pzw, (bc - ad)*pzw, (1 - aa - bb)*pzw\n \n local mWX,mWY,mWZ = ((vxx*objX+vxy*objY+vxz*objZ)),(vyx*objX+vyy*objY+vyz*objZ),((vzx*objX+vzy*objY+vzz*objZ))\n\n local processRotations = processRots(predefinedRotations,vx,vy,vz,vw,pxw,pzw)\n predefinedRotations[mx .. ',' .. my .. ',' .. mz .. ',' .. mw] = {mXX,mXZ,mYX,mYZ,mZX,mZZ}\n \n avgZ = avgZ + mWY\n local uiGroups = obj[4]\n \n -- Process Actionables\n local eventStartTime = getTime()\n obj.previousUI = processEvents(uiGroups, obj.previousUI, isClicked, isHolding, vyx, vyy, vyz, processRotations, ex,ey,ez, sort)\n local drawProcessingStartTime = getTime()\n deltaEvent = deltaEvent + drawProcessingStartTime - eventStartTime\n -- Progress Pure\n \n zBC = processPure(zBC, obj[2], obj[3], zBuffer, zSorter,\n mXX, mXY, mXZ,\n mYX, mYY, mYZ,\n mZX, mZY, mZZ,\n mWX, mWY, mWZ\n )\n -- Process UI\n zBC = processUI(zBC, uiGroups, zBuffer, zSorter,\n vxx, vxy, vxz,\n vyx, vyy, vyz,\n vzx, vzy, vzz,\n ex,ey,ez,\n processRotations,nearDivAspect)\n deltaDrawProcessing = deltaDrawProcessing + getTime() - drawProcessingStartTime\n ::is_nil::\n end\n local zSortingStartTime = getTime()\n if objectGroup.isZSorting then\n sort(zSorter)\n end\n local zBufferCopyStartTime = getTime()\n deltaZSort = deltaZSort + zBufferCopyStartTime - zSortingStartTime\n local drawStringData = {}\n for zC = 1, zBC do\n drawStringData[zC] = zBuffer[zSorter[zC]]\n end\n local postProcessingStartTime = getTime()\n deltaZBufferCopy = deltaZBufferCopy + postProcessingStartTime - zBufferCopyStartTime\n if zBC > 0 then\n local dpth = avgZ / avgZC\n local actualSVGCode = concat(drawStringData)\n local beginning, ending = '', ''\n if isSmooth then\n ending = '</div>'\n if frameRender then\n beginning = '<div class=\"second\" style=\"visibility: hidden\">'\n else\n beginning = '<style>.first{animation: f1 0.008s infinite linear;} .second{animation: f2 0.008s infinite linear;} @keyframes f1 {from {visibility: hidden;} to {visibility: hidden;}} @keyframes f2 {from {visibility: visible;} to { visibility: visible;}}</style><div class=\"first\">'\n end\n end\n local styleHeader = ('<style>svg{background:none;width:%gpx;height:%gpx;position:absolute;top:0px;left:0px;}'):format(width,height)\n local svgHeader = ('<svg viewbox=\"-%g -%g %g %g\"'):format(width*0.5,height*0.5,width,height)\n \n svgBufferCounter = svgBufferCounter + 1\n svgZBuffer[svgBufferCounter] = dpth\n \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 svgBuffer[dpth] = concat({\n beginning,\n '<div class=\"', objectGroup.class ,'\">',\n styleHeader,\n objectGroup.style,\n '.blur { filter: blur(',size,'px) brightness(60%) saturate(3);',\n objectGroup.gStyle, '}</style>',\n svgHeader,\n ' class=\"blur\">',\n actualSVGCode,'</svg>',\n svgHeader, '>',\n actualSVGCode,\n '</svg></div>',\n ending\n })\n \n else\n svgBuffer[dpth] = concat({\n beginning,\n '<div class=\"', objectGroup.class ,'\">',\n styleHeader,\n objectGroup.style, '}</style>',\n svgHeader, '>',\n actualSVGCode,\n '</svg></div>',\n ending\n })\n end\n end\n deltaPostProcessing = deltaPostProcessing + getTime() - postProcessingStartTime\n ::not_enabled::\n end\n \n sort(svgZBuffer)\n \n for i = 1, svgBufferCounter do\n buffer[i] = svgBuffer[svgZBuffer[i]]\n end\n \n if frameRender then\n frameBuffer[2] = concat(buffer)\n return concat(frameBuffer), deltaPreProcessing, deltaDrawProcessing, deltaEvent, deltaZSort, deltaZBufferCopy, deltaPostProcessing\n else\n if isSmooth then\n frameBuffer[1] = concat(buffer)\n if lowLatency then\n setScreen('<div>Refresh Required</div>') -- magical things happen when doing this for some reason, some really, really weird reason.\n end\n else\n frameBuffer[1] = ''\n end\n return nil\n end\n end\n return self\nend","filter":{"args":[],"signature":"onStart()","slotKey":"-5"},"key":"5"},{"code":"function LoadPureModule(self, singleGroup, multiGroup)\n \n function self.getMultiPointBuilder(groupId)\n local builder = {}\n local multiplePoints = LinkedList('','')\n multiGroup[#multiGroup+1] = multiplePoints\n function builder.addMultiPointSVG()\n local shown = false\n local pointSetX,pointSetY,pointSetZ={},{},{}\n local mp = {pointSetX,pointSetY,pointSetZ,false,false}\n local self={}\n local pC=1\n function self.show() \n if not shown then \n shown = true\n multiplePoints.Add(mp)\n end\n end\n function self.hide()\n if shown then \n shown = false\n multiplePoints.Remove(mp)\n end\n end\n function self.addPoint(point)\n pointSetX[pC]=point[1]\n pointSetY[pC]=point[2]\n pointSetZ[pC]=point[3]\n pC=pC+1\n return self\n end\n function self.setPoints(bulk)\n for i=1,#bulk do\n local point = bulk[i]\n pointSetX[i]=point[1]\n pointSetY[i]=point[2]\n pointSetZ[i]=point[3]\n end\n pC=#bulk+1\n return self\n end\n function self.setDrawFunction(draw)\n mp[4] = draw\n return self\n end\n function self.setData(dat)\n mp[5] = dat\n return self\n end\n function self.build()\n if pC > 1 then\n multiplePoints.Add(mp)\n shown = true\n else print(\"WARNING! Malformed multi-point build operation, no points specified. Ignoring.\")\n end\n end\n return self\n end\n return builder\n end\n \n function self.getSinglePointBuilder(groupId)\n local builder = {}\n local points = LinkedList('','')\n singleGroup[#singleGroup+1] = points\n function builder.addSinglePointSVG()\n local shown = false\n local outArr = {false,false,false,false,false}\n\n function self.setPosition(px,py,pz)\n if type(px) == 'table' then\n outArr[1],outArr[2],outArr[3]=px[1],px[2],px[3]\n else\n outArr[1],outArr[2],outArr[3]=px,py,pz\n end\n return self\n end\n \n function self.setDrawFunction(draw)\n outArr[4] = draw\n return self\n end\n \n function self.setData(dat)\n outArr[5] = dat\n return self\n end\n \n function self.show()\n if ~shown then\n shown = true\n end\n end\n function self.hide() \n if shown then\n points.Remove(outArr)\n shown = false\n end\n end\n function self.build()\n points.Add(outArr)\n shown = true\n return self\n end\n return self\n end\n return builder\n end\nend\n\nfunction ProcessPureModule(zBC, singleGroup, multiGroup, zBuffer, zSorter,\n mXX, mXY, mXZ,\n mYX, mYY, mYZ,\n mZX, mZY, mZZ,\n mXW, mYW, mZW)\n for cG = 1, #singleGroup do\n local group = singleGroup[cG]\n local singleGroups,singleSize = group.GetData()\n for sGC = 1, singleSize do\n local singleGroup = singleGroups[sGC]\n local x,y,z = singleGroup[1], singleGroup[2], singleGroup[3]\n local pz = mYX*x + mYY*y + mYZ*z + mYW\n if pz < 0 then goto disabled end\n zBC = zBC + 1\n zSorter[zBC] = -pz\n zBuffer[-pz] = singleGroup[4]((mXX*x + mXY*y + mXZ*z + mXW)/pz,(mZX*x + mZY*y + mZZ*z + mZW)/pz,pz,singleGroup[5])\n ::disabled::\n end\n end\n for cG = 1, #multiGroup do\n local group = multiGroup[cG]\n local multiGroups,groupSize = group.GetData()\n for mGC = 1, groupSize do\n local multiGroup = multiGroups[mGC]\n\n local tPointsX,tPointsY,tPointsZ = {},{},{}\n local pointsX,pointsY,pointsZ = multiGroup[1],multiGroup[2],multiGroup[3]\n local size = #pointsX\n local mGAvg = 0\n for pC=1,size do\n local x,y,z = pointsX[pC],pointsY[pC],pointsZ[pC]\n local pz = mYX*x + mYY*y + mYZ*z + mYW\n if pz < 0 then\n goto disabled\n end\n\n tPointsX[pC],tPointsY[pC] = (mXX*x + mXY*y + mXZ*z + mXW)/pz,(mZX*x + mZY*y + mZZ*z + mZW)/pz\n mGAvg = mGAvg + pz\n end\n local depth = -mGAvg/size\n zBC = zBC + 1\n zSorter[zBC] = depth\n zBuffer[depth] = multiGroup[4](tPointsX,tPointsY,depth,multiGroup[5])\n ::disabled::\n end\n end\n return zBC\nend","filter":{"args":[],"signature":"onStart()","slotKey":"-5"},"key":"6"},{"code":"positionTypes = {\n globalP=false,\n localP=true\n}\norientationTypes = {\n globalO=false,\n localO=true \n}\nlocal print = DUSystem.print\nfunction ObjectGroup(objects, transX, transY)\n local objects=objects or {}\n local self={style='',gStyle='',class='default', objects=objects,transX=transX,transY=transY,enabled=true,glow=false,gRad=10,scale = false,isZSorting=true}\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.removeObject(id) objects[id] = {} end\n\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.setZSort(isZSorting) self.isZSorting = isZSorting end\n\n function self.setClass(class) self.class = class end\n function self.setStyle(style) self.style = style 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\nConstructReferential = getRotationManager({0,0,0,1},{0,0,0}, 'Construct')\nConstructReferential.assignFunctions(ConstructReferential)\nConstructOriReferential = getRotationManager({0,0,0,1},{0,0,0}, 'ConstructOri')\nConstructOriReferential.assignFunctions(ConstructOriReferential)\nfunction Object(posType, oriType)\n\n local multiGroup,singleGroup,uiGroups={},{},{}\n local positionType=positionType\n local orientationType=orientationType\n local ori = {0,0,0,1}\n local position = {0,0,0}\n local objRotationHandler = getRotationManager(ori,position, 'Object Rotation Handler')\n \n local self = {\n true, -- 1\n multiGroup, -- 2\n singleGroup, -- 3\n uiGroups, -- 4\n ori, -- 5\n position, -- 6\n oriType, -- 7\n posType -- 8\n }\n objRotationHandler.assignFunctions(self)\n self.setPositionIsRelative(true)\n self.setPositionIsRelative = nil\n function self.hide() self[1] = false end\n function self.show() self[1] = true end\n\n local loadUIModule = LoadUIModule\n if loadUIModule == nil then\n print('No UI Module installed.')\n loadUIModule = function() end\n end\n local loadPureModule = LoadPureModule\n if loadPureModule == nil then\n print('No Pure Module installed.')\n loadPureModule = function() end\n end\n\n loadPureModule(self, multiGroup, singleGroup)\n loadUIModule(self, uiGroups, objRotationHandler)\n local function choose()\n objRotationHandler.remove()\n local oriType,posType = self[7],self[8]\n if oriType and posType then\n ConstructReferential.addSubRotation(objRotationHandler)\n elseif oriType then\n ConstructOriReferential.addSubRotation(objRotationHandler)\n end\n self.setDoRotateOri(oriType)\n self.setDoRotatePos(posType)\n end\n choose()\n function self.setOrientationType(orientationType)\n self[7] = orientationType\n choose()\n end\n function self.setPositionType(positionType)\n self[8] = positionType\n choose()\n end\n \n function self.getRotationManager()\n return objRotationHandler\n end\n function self.addSubObject(object)\n return objRotationHandler.addSubRotation(object.getRotationManager())\n end\n function self.removeSubObject(id)\n objRotationHandler.removeSubRotation(id)\n end\n\n return self\nend\n\nfunction ObjectBuilderLinear()\n local self = {}\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 function self.build()\n return Object(positionType, orientationType)\n end\n return self\n end\n return self\n end\n return self\nend","filter":{"args":[],"signature":"onStart()","slotKey":"-5"},"key":"7"},{"code":"function Waypoint(x,y,z, radius, name, type, localeType, 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 = construct.getWorldPosition,construct.getMass\n \n local keyframe = 0\n local self = {\n radius = radius,\n x = x,\n y = y,\n z = z,\n name = name,\n type = type,\n localeType = localeType,\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":"onStart()","slotKey":"-5"},"key":"8"}],"methods":[],"events":[]}