sensor rewrite

This commit is contained in:
kepler155c@gmail.com
2019-04-02 03:42:08 -04:00
parent 71b343cf86
commit 54ed32ecd9
2 changed files with 236 additions and 234 deletions

View File

@@ -1,10 +1,11 @@
local Config = require('config')
local Event = require('event')
local Project = require('neural.project')
local UI = require('ui')
local Util = require('util')
local Config = require('config')
local Event = require('event')
local UI = require('ui')
local Util = require('util')
local device = _G.device
local colors = _G.colors
local device = _G.device
local gps = _G.gps
local glasses = device['plethora:glasses']
local intro = device['plethora:introspection']
@@ -13,71 +14,138 @@ local sensor = device['plethora:sensor'] or
UI:configure('Sensor', ...)
local target
local projecting = { }
local offset
local canvas = glasses and intro and glasses.canvas3d().create()
local config = Config.load('Sensor', {
ignore = { }
})
if not config.ignore then
config.ignore = { }
end
local page = UI.Page {
tabs = UI.Tabs {
listing = UI.Tab {
tabTitle = 'Listing',
menuBar = UI.MenuBar {
buttons = {
{ text = 'Ignore', event = 'ignore' },
{ text = 'Details', event = 'detail' },
},
},
grid = UI.ScrollingGrid {
y = 2,
columns = {
{ heading = 'Name', key = 'displayName' },
{ heading = 'X', key = 'x', width = 3, align = 'right' },
{ heading = 'Y', key = 'y', width = 3, align = 'right' },
{ heading = 'Z', key = 'z', width = 3, align = 'right' },
},
sortColumn = 'displayName',
},
},
summary = UI.Tab {
tabTitle = 'Summary',
menuBar = UI.MenuBar {
buttons = {
{ text = 'Projector', event = 'project' },
{ text = 'Ignore', event = 'ignore' },
},
},
grid = UI.ScrollingGrid {
y = 2,
columns = {
{ heading = 'Name', key = 'displayName' },
{ heading = 'Count', key = 'count', width = 5, align = 'right' },
},
sortColumn = 'displayName',
},
},
accelerators = {
q = 'quit',
},
},
}
local listing = page.tabs.listing
local summary = page.tabs.summary
local detail = UI.Page {
menuBar = UI.MenuBar {
buttons = {
{ text = 'Projector', event = 'project' },
{ text = 'Totals', event = 'totals' },
{ text = 'Ignore', event = 'ignore' },
{ text = 'Details', event = 'detail' },
{ text = 'Back', event = 'back', x = -6 },
},
},
grid = UI.ScrollingGrid {
y = 2,
columns = {
{ heading = 'Name', key = 'displayName' },
{ heading = ' X', key = 'x', width = 3, align = 'right' },
{ heading = ' Y', key = 'y', width = 3, align = 'right' },
{ heading = ' Z', key = 'z', width = 3, align = 'right' },
},
values = sensor.sense(),
sortColumn = 'displayName',
},
accelerators = {
q = 'quit',
},
detail = UI.SlideOut {
menuBar = UI.MenuBar {
buttons = {
{ text = 'Projector', event = 'project-target' },
{ text = 'Back', event = 'hide', x = -6 },
},
},
grid = UI.ScrollingGrid {
y = 2,
columns = {
{ heading = 'Name', key = 'name' },
{ heading = 'Value', key = 'value' },
},
sortColumn = 'name',
autospace = true,
{ heading = 'Name', key = 'name' },
{ heading = 'Value', key = 'value' },
},
sortColumn = 'name',
autospace = true,
},
}
function page.grid:getDisplayValues(row)
row = Util.shallowCopy(row)
row.x = row.x and math.floor(row.x) or ''
row.y = row.y and math.floor(row.y) or ''
row.z = row.z and math.floor(row.z) or ''
return row
local function getPoint()
local pt = { gps.locate() }
return {
x = pt[1],
y = pt[2],
z = pt[3],
}
end
function page.detail:show(entity)
self.entity = entity -- to allow for debugging in Lua
local function project(entities)
if canvas then
local pos = getPoint()
local pts = { }
if not offset then
offset = pos
end
for _, b in pairs(entities) do
if b.x then
pts[table.concat({
math.floor(pos.x + b.x),
math.floor(pos.y + b.y),
math.floor(pos.z + b.z) }, ':')] = b
end
end
for key, b in pairs(pts) do
if not projecting[key] then
local box = canvas.addBox(
pos.x - offset.x + b.x,
pos.y - offset.y + b.y - .25,
pos.z - offset.z + b.z,
.25, .25, .25)
box.setDepthTested(false)
projecting[key] = box
end
end
for key, box in pairs(projecting) do
if not pts[key] then
box.remove()
projecting[key] = nil
end
end
end
end
local function ignoreEntity(entity)
if entity then
config.ignore[entity.name] = true
Config.update('Sensor', config)
end
end
function detail:enable(entity)
local function update()
local t = { }
for k,v in pairs(self.entity) do
local meta = sensor.getMetaByID(entity.id) or { }
for k,v in pairs(meta) do
if type(v) ~= 'table' then
table.insert(t, {
name = k,
@@ -85,115 +153,151 @@ function page.detail:show(entity)
})
end
end
project({ meta })
return t
end
if entity.id then
self.handler = Event.onInterval(.5, function()
local e = sensor.getMetaByID(self.entity.id)
if e then
self.entity = e
self.grid:setValues(update())
self.grid:draw()
self.grid:sync()
end
end)
end
self.handler = Event.onInterval(.5, function()
self.grid:setValues(update())
self.grid:draw()
self.grid:sync()
end)
self.grid:setValues(update())
return UI.SlideOut.show(self)
return UI.Page.enable(self)
end
function page.detail:hide()
function detail:disable()
if self.handler then
Event.off(self.handler)
self.handler = nil
end
return UI.SlideOut.hide(self)
project({ })
return UI.Page.disable(self)
end
function detail:eventHandler(event)
if event.type == 'back' then
return UI:setPreviousPage()
end
return UI.Page.eventHandler(self, event)
end
function listing.grid:getDisplayValues(row)
row = Util.shallowCopy(row)
row.x = row.x and math.floor(row.x) or ''
row.y = row.y and math.floor(row.y) or ''
row.z = row.z and math.floor(row.z) or ''
return row
end
function listing:enable()
self.handler = Event.onInterval(.5, function()
local entities = sensor.sense()
Util.filterInplace(entities, function(e) return not config.ignore[e.name] end)
self.grid:setValues(entities)
self.grid:draw()
self:sync()
end)
return UI.Tab.enable(self)
end
function listing:disable()
Event.off(self.handler)
UI.Tab.disable(self)
end
function listing:eventHandler(event)
if event.type == 'detail' or event.type == 'grid_select' then
local selected = self.grid:getSelected()
if selected then
UI:setPage(detail, selected)
end
elseif event.type == 'ignore' then
ignoreEntity(self.grid:getSelected())
end
return UI.Tab.eventHandler(self, event)
end
function summary:enable()
self.handler = Event.onInterval(.5, function()
local entities = sensor.sense()
Util.filterInplace(entities, function(e) return not config.ignore[e.name] end)
local t = { }
local highlight = { }
for _,v in pairs(entities) do
if t[v.name] then
t[v.name].count = t[v.name].count + 1
else
t[v.name] = { displayName = v.displayName, count = 1, name = v.name }
end
if self.target == v.name then
table.insert(highlight, v)
end
end
project(highlight)
self.grid:setValues(t)
self.grid:draw()
self:sync()
end)
self.target = nil
return UI.Tab.enable(self)
end
function summary:disable()
project({ })
Event.off(self.handler)
UI.Tab.disable(self)
end
function summary.grid:getRowTextColor(row, selected)
if row.name == self.parent.target then
return colors.yellow
end
return UI.Grid:getRowTextColor(row, selected)
end
function summary:eventHandler(event)
if event.type == 'ignore' then
ignoreEntity(self.grid:getSelected())
elseif event.type == 'project' or event.type == 'grid_select' then
local selected = self.grid:getSelected()
if selected then
self.target = selected.name
self.grid:draw()
end
end
return UI.Tab.eventHandler(self, event)
end
function page:eventHandler(event)
if event.type == 'quit' then
Event.exitPullEvents()
elseif event.type == 'totals' then
config.totals = not config.totals
Config.update('Sensor', config)
elseif event.type == 'detail' or event.type == 'grid_select' then
local selected = self.grid:getSelected()
if selected then
target = selected.name
self.detail:show(selected)
end
elseif event.type == 'hide' then
self.detail:hide()
elseif event.type == 'ignore' then
local selected = self.grid:getSelected()
if selected then
config.ignore[selected.name] = true
end
Config.update('Sensor', config)
elseif event.type == 'project' or event.type == 'project-target' then
if event.type == 'project' then
target = nil
end
if glasses then
config.projecting = not config.projecting
if config.projecting then
Project:init(glasses.canvas())
else
Project.canvas:clear()
end
end
elseif event.type == 'tab_activate' then
config.activeTab = event.activated.tabTitle
Config.update('Sensor', config)
end
UI.Page.eventHandler(self, event)
end
Event.onInterval(.5, function()
local entities = sensor.sense()
Util.filterInplace(entities, function(e) return not config.ignore[e.name] end)
if config.projecting and glasses and intro then
local meta = intro.getMetaOwner()
Project.canvas:clear()
local t = entities
if target then
t = Util.filter(entities, function(e) return e.name == target end)
end
Project:drawPoints(meta, t, 'X', 0xFFDF50AA)
end
if config.totals then
local t = { }
for _,v in pairs(entities) do
if t[v.name] then
t[v.name].z = t[v.name].z + 1
else
t[v.name] = { displayName = v.displayName, z = 1, name = v.name }
end
end
entities = t
end
page.grid:setValues(entities)
page.grid:draw()
page:sync()
end)
if config.projecting and glasses then
Project:init(glasses.canvas())
if config.activeTab then
page.tabs:selectTab(Util.find(page.tabs.children, 'tabTitle', config.activeTab))
end
UI:setPage(page)
UI:pullEvents()
if config.projecting and glasses then
Project.canvas:clear()
if canvas then
canvas:clear()
end

View File

@@ -1,102 +0,0 @@
------------------------------------------------------------------------------------------
-- ORE3D - Fully Immersive Augmented Reality X-RAY Vision for Ore Mining using Plethora --
------------------------------------------------------------------------------------------
-- CREATED BY:
-- HydroNitrogen (a.k.a. GoogleTech, Wendelstein7)
-- Bram S. (a.k.a ThatBram0101, bram0101)
-- LICENCE: ZLIB/libpng Licence (Zlib) (MODIFIED)
-- Copyright (c) 2018 HydroNitrogen & Bram S.
-- This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
-- Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
-- 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
-- 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
-- 3. Every version, altered and original, must always contain a link to the following internet page: https://energetic.pw/computercraft/ore3d
-- 4. This notice may not be removed or altered from any source distribution.
-- VERSION 2018-03-29 15:52 (Dates are way easier than version numbers, :P )
local FOV = math.rad(70) -- Change according to your Minecraft settings! Minecraft default: 75
local ASPECT_RATIO = 1.8 -- Aspect ratio of your view - for a full HD screen: fullscreen: 1.7777, windowed: 1.8
local hintToBehind = true -- Show all blocks behind you on the sides of your screen
local CHAR_SIZE = 16 -- the base size of the indicators
local SCRHOR = (1 / math.tan(FOV / 2)) / ASPECT_RATIO
local SCRVER = (1 / math.tan(FOV / 2))
-- Convert to perspective projection, removes a dimention (z) (optimized, uses precalculated values)
local function toPerspective(x, y, z)
return SCRHOR * x / z, SCRVER * y / z
end
local function getCharSize(d) -- Calculates size of indicators using distance
return CHAR_SIZE / d
end
local Project = { }
function Project:init(canvas)
self.canvas = canvas
self.cx, self.cy = canvas.getSize()
self.cxhalf = self.cx / 2
self.cyhalf = self.cy / 2
end
function Project:ndcToSpc(x, y)
return x * self.cxhalf + self.cxhalf, y * self.cyhalf + self.cyhalf
end
function Project:isOnScreen(x, y, d) -- determines if something is visible
return (x >= 1 and x - getCharSize(d) < self.cx) and (y >= 1 and y - getCharSize(d) < self.cy)
end
function Project:drawPoints(meta, pts, isBlock, color)
local yaw = math.rad(meta.yaw)
local pitch = math.rad(meta.pitch)
local ysin = math.sin(yaw)
local ycos = math.cos(yaw)
local psin = math.sin(pitch)
local pcos = math.cos(pitch)
local function rotate(x, y, z) -- Matrix operation: rotate (optimized, uses precalculated values)
local newx = ycos * x + ysin * z
local newz = -ysin * x + ycos * z
local newy = pcos * y - psin * newz
newz = psin * y + pcos * newz
return newx,newy,newz
end
for _, b in pairs(pts) do
if isBlock then
--b.x = b.x - .5
--b.y = b.y - 1
--b.z = b.z - .5
end
local x, y, z = rotate(b.x - meta.x, -b.y + meta.y, b.z - meta.z)
local d = math.sqrt(x * x + y * y + z * z)
if hintToBehind and z < 0 then z = 0.001 end
if z >= 0 or hintToBehind then -- render only if point is visible OR hintToBehind is enabled
x,y = toPerspective(x, y, -z)
x,y = self:ndcToSpc(x, y)
if hintToBehind or self:isOnScreen(x, y, d) then
x = math.min(math.max(x, 1), self.cx - 10 * getCharSize(d))
y = math.min(math.max(self.cy - y, 1), self.cy - 10 * getCharSize(d))
self.canvas.addDot({ x, y }, color, 32 / d)
end
end
end
end
return Project