osmarks

ARC

Jul 30th, 2018
1,401
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --[[
  2. ARC: AR Client
  3. Uses Plethora overlay glasses and modems to display 3D signage transmitted from local "beacons"
  4. ]]
  5.  
  6. local m = peripheral.find "modem"
  7. local mods = peripheral.wrap "back"
  8.  
  9. if not m then error "Modem required." end
  10. if not mods then error "Is this even on a neural interface?" end
  11. if not mods.canvas3d then error "Overlay glasses required." end
  12.  
  13. local canv = mods.canvas3d()
  14.  
  15. local object_channel = 666
  16.  
  17. m.open(object_channel)
  18.  
  19. local x, y, z
  20.  
  21. -- convert position to string for use as table key
  22. local function serialize_position(p)
  23.     return string.format("%f,%f,%f", p[1], p[2], p[3])
  24. end
  25.  
  26. -- Generate a string representation of a table, for easy comparison. Not really hashing, I guess.
  27. local function hash_table(x)
  28.     if type(x) == "table" then
  29.         local out = ""
  30.         for k, v in pairs(x) do
  31.             if type(k) ~= "string" or not k:match "^_" then -- ignore keys beginning with _
  32.                 out = out .. hash_table(k) .. ":" .. hash_table(v) .. ";"
  33.             end
  34.         end
  35.         return out
  36.     else
  37.         return tostring(x)
  38.     end
  39. end
  40.  
  41. -- honestly not that elegant, but it works
  42. -- TODO: do this more efficiently/nicely somehow?
  43. local function tables_match(x, y)
  44.     return hash_table(x) == hash_table(y)
  45. end
  46.  
  47. local objects = {}
  48. local timers = {}
  49.  
  50. local function redraw(object)
  51.     local frame = object._frame
  52.     frame.clear()
  53. end
  54.  
  55. local function process_object(object)
  56.     local pos = serialize_position(object.position)
  57.     if objects[pos] then
  58.         if not tables_match(object, objects[pos]) then
  59.             print("redrawing", pos)
  60.             objects[pos] = object
  61.             redraw(objects[pos])
  62.         end
  63.         local t = os.startTimer(20)
  64.         timers[t] = pos
  65.     else
  66.         print("new object at", pos)
  67.         if x then
  68.             local frame =
  69.         else
  70.             print("GPS error, cannot create object")
  71.         end
  72.     end
  73. end
  74.  
  75. local function main_loop()
  76.     while true do
  77.         local event, timer, channel, reply_channel, message, distance = os.pullEvent()
  78.         if event == "modem_message" and channel == object_channel and distance and type(message) == "table" then -- ensure message is from this dimension and otherwise valid
  79.             for _, object in pairs(msg) do
  80.                 local ok, err = pcall(process_object, object)
  81.                 if not ok then printError(err) end
  82.             end
  83.         elseif event == "timer" then
  84.             local objpos = timers[timer]
  85.             if objpos then
  86.                 local obj = objects[objpos]
  87.                 if obj then
  88.                     print(objpos, "timed out")
  89.                     obj._frame.remove()
  90.                     objects[objpos] = nil
  91.                 end
  92.             end
  93.         end
  94.     end
  95. end
  96.  
  97. -- Request location every second
  98. local function GPS_loop()
  99.     while true do
  100.         x, y, z = gps.locate()
  101.         sleep(1)
  102.     end
  103. end
  104.  
  105. parallel.waitForAll(GPS_loop, main_loop)
RAW Paste Data