luax wip
This commit is contained in:
parent
9360423a5c
commit
f4b633d560
28 changed files with 180 additions and 58 deletions
|
|
@ -53,6 +53,10 @@ $ ./lovr xurfer
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Longterm goal
|
||||||
|
|
||||||
|
* Android launcher for OpenXR & WebXR apps
|
||||||
|
|
||||||
## Security
|
## Security
|
||||||
|
|
||||||
Instead of the traditional sandbox-in-a-browser-model (Chromium/Firefox e.g.), we suggest running XURFER via [bubblewrap](https://github.com/meta-quest/bubblewrap)
|
Instead of the traditional sandbox-in-a-browser-model (Chromium/Firefox e.g.), we suggest running XURFER via [bubblewrap](https://github.com/meta-quest/bubblewrap)
|
||||||
|
|
|
||||||
19
nix/luax-release.sh
Executable file
19
nix/luax-release.sh
Executable file
|
|
@ -0,0 +1,19 @@
|
||||||
|
#!/bin/sh
|
||||||
|
export PATH=$PATH:.
|
||||||
|
which luax || {
|
||||||
|
wget "https://cdelord.fr/pub/luax/10.10.0/luax-linux-x86_64-musl"
|
||||||
|
ln -s luax-linux-x86_64-musl luax
|
||||||
|
chmod +x luax
|
||||||
|
}
|
||||||
|
|
||||||
|
cd xurfer
|
||||||
|
files="$(find * -type f | grep lua | grep -vE '(runtime/lov*)')"
|
||||||
|
echo $files
|
||||||
|
|
||||||
|
luax compile -t list | tail -n+3 | awk '$1 ~ /[a-z]-[a-z]/ {print $1}' | \
|
||||||
|
while read platform; do
|
||||||
|
#luax compile -t $platform -o ./../xurfer-$platform ${files}
|
||||||
|
# TODO: luaX needs unique modulenames : main.lua clashes in the binary
|
||||||
|
luax compile -t $platform -o ./../xurfer-$platform conf.lua ecs.lua events.lua ext/kitchensink/main.lua ext/xrfragments/main.lua #ext/xrfragments/level2.lua ext/xrfragments/level4.lua ext/xrfragments/lovr-xrf.lua ext/skeleton/main.lua ext/unixy/main.lua ext/gazecontrol/main.lua ext/janusxr/main.lua ext/http-lovr/main.lua ext/startupscene/main.lua ext/3DFile/main.lua ext/tween/main.lua ext/tween/tween.lua ext/AudioFile/main.lua ext/button/main.lua ext/URI/main.lua init.lua lib/lust.lua lib/tiny-ecs.lua lib/xmlSimple.lua lib/json.lua lib/url.lua main.lua runtime/lua/conf.lua runtime/lua/main.lua runtime/lua/api.lua runtime/detect.lua test/main.lua util.lua
|
||||||
|
exit
|
||||||
|
done
|
||||||
|
|
@ -1,8 +1,13 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
export DEBUG=1
|
export DEBUG=1
|
||||||
cd xurfer
|
cd xurfer
|
||||||
runtime="/home/leon/apps/lovr-v0.18.0-x86_64.AppImage"
|
#./main.lua
|
||||||
|
#runtime="/home/leon/apps/lovr-v0.18.0-x86_64.AppImage"
|
||||||
|
runtime="/home/leon/apps/lovr-v0.18.1-x86_64.AppImage"
|
||||||
#appimage-run $runtime . test.glb
|
#appimage-run $runtime . test.glb
|
||||||
appimage-run $runtime . https://snips.sh/f/_U5-XctEVE?r=1
|
appimage-run $runtime . https://snips.sh/f/_U5-XctEVE?r=1
|
||||||
#appimage-run $runtime . http://localhost:8080/simple-a.glb
|
#appimage-run $runtime . http://localhost:8080/simple-a.glb
|
||||||
#appimage-run $runtime . http://localhost:8080/level3-4-playaudio.glb
|
#appimage-run $runtime . http://localhost:8080/level3-4-playaudio.glb
|
||||||
|
#appimage-run $runtime . http://localhost:8080/simple-b.glb
|
||||||
|
#appimage-run $runtime . test.localhost.jml0
|
||||||
|
#appimage-run $runtime . http://localhost:8080/simple-b-wireframe.glb
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
-- default argument
|
-- default argument
|
||||||
|
--@LIB
|
||||||
if arg[1] == nil then
|
if arg[1] == nil then
|
||||||
arg[1] = "https://snips.sh/f/_U5-XctEVE?r=1"
|
arg[1] = "https://snips.sh/f/_U5-XctEVE?r=1"
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
--@LIB
|
||||||
local ecs = require("lib/tiny-ecs")
|
local ecs = require("lib/tiny-ecs")
|
||||||
|
|
||||||
ecs.init = function(api)
|
ecs.init = function(api)
|
||||||
|
|
|
||||||
10
xurfer/events.lua
Normal file
10
xurfer/events.lua
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
--@LIB
|
||||||
|
return {
|
||||||
|
input = {
|
||||||
|
pointer = { released = false, pressed = false, moved = false, hover = false, wheel = false},
|
||||||
|
key = { released = false, pressed = false },
|
||||||
|
input = false, -- string if true,
|
||||||
|
collider = false, -- lovr collider
|
||||||
|
hitpoint = false, -- {x=0, y=0, z=0}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
--@LIB
|
||||||
local api = ...
|
local api = ...
|
||||||
local ecs = api.ecs
|
local ecs = api.ecs
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
--@LIB
|
||||||
local api = ...
|
local api = ...
|
||||||
local ecs = api.ecs
|
local ecs = api.ecs
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
--@LIB
|
||||||
local api = ...
|
local api = ...
|
||||||
local ecs = api.ecs
|
local ecs = api.ecs
|
||||||
|
|
||||||
|
|
|
||||||
63
xurfer/ext/button/main.lua
Normal file
63
xurfer/ext/button/main.lua
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
--@LIB
|
||||||
|
local api = ...
|
||||||
|
local ecs = api.ecs
|
||||||
|
|
||||||
|
-- this is an input extension which adds data the input-event
|
||||||
|
-- which is fed to update-calls of extensions and ECS
|
||||||
|
|
||||||
|
local button
|
||||||
|
button = {
|
||||||
|
name = "button",
|
||||||
|
enabled = true,
|
||||||
|
settings = { -- keep this settings serializable (no functions e.g.) + use lovr key-names
|
||||||
|
|
||||||
|
-- (SHIFT) TAB/ENTER as described in the Accessibility guidelines
|
||||||
|
-- of XR (URI) fragments: https://xrfragment.org/#accessibility
|
||||||
|
{ event={name="next"}, key="tab" },
|
||||||
|
{ event={name="previous"}, key="tab", shift=true},
|
||||||
|
{ event={name="select"}, key="return", pointer={released=true} },
|
||||||
|
{ event={name="select"}, key="space", pointer={released=true} },
|
||||||
|
|
||||||
|
},
|
||||||
|
state = { shift = false },
|
||||||
|
|
||||||
|
init = function()
|
||||||
|
if not api.settings.button then
|
||||||
|
api.settings.button = button.settings
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
isShift = function(key) return key == "rshift" or key == "lshift" end,
|
||||||
|
|
||||||
|
matchKey = function(mapping, event)
|
||||||
|
return mapping.key ~= nil and
|
||||||
|
mapping.shift == (button.state.shift or nil) and
|
||||||
|
mapping.key == event.key
|
||||||
|
end,
|
||||||
|
|
||||||
|
input = function(dt,input)
|
||||||
|
-- sense shift state
|
||||||
|
if input.key.pressed and button.isShift(input.key.pressed.key) then button.state.shift = true end
|
||||||
|
if input.key.released and button.isShift(input.key.released.key) then button.state.shift = false end
|
||||||
|
|
||||||
|
local mappings = api.settings.button
|
||||||
|
-- process keymapping
|
||||||
|
if input.key.released then
|
||||||
|
foreach(mappings, function(k,mapping)
|
||||||
|
if button.matchKey( mapping, input.key.released ) then
|
||||||
|
input[ mapping.event.name ] = mapping.event -- add to input event (so update-calls can see it)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
-- process keymapping
|
||||||
|
if input.pointer.released then
|
||||||
|
foreach(mappings, function(k,mapping)
|
||||||
|
if mapping.pointer and mapping.pointer.released then
|
||||||
|
input[ mapping.event.name ] = mapping.event -- add to input event (so update-calls can see it)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}
|
||||||
|
|
||||||
|
return button
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
--@LIB
|
||||||
local api = ...
|
local api = ...
|
||||||
local ecs = api.ecs
|
local ecs = api.ecs
|
||||||
|
|
||||||
|
|
@ -25,7 +26,6 @@ gctl = {
|
||||||
init = function()
|
init = function()
|
||||||
--lovr.mouse.setRelativeMode(true)
|
--lovr.mouse.setRelativeMode(true)
|
||||||
gctl.initVisor()
|
gctl.initVisor()
|
||||||
gctl.extendECS()
|
|
||||||
api.player.matrix = lovr.math.newMat4()
|
api.player.matrix = lovr.math.newMat4()
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
|
@ -84,23 +84,6 @@ gctl = {
|
||||||
pass:plane(x, y, z, scale, scale, angle, ax, ay, az)
|
pass:plane(x, y, z, scale, scale, angle, ax, ay, az)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
-- ECS API docs: https://bakpakin.github.io/tiny-ecs/doc
|
|
||||||
extendECS = function()
|
|
||||||
|
|
||||||
local visorSystem = ecs.processingSystem({
|
|
||||||
updatethread = true,
|
|
||||||
filter = ecs.requireAll('mycomponent'),
|
|
||||||
onAdd = function(self,obj) print_r(obj) end,
|
|
||||||
onRemove = function(self,obj) end,
|
|
||||||
process = function(self,obj) end,
|
|
||||||
})
|
|
||||||
ecs.addSystem( api.world, visorSystem )
|
|
||||||
|
|
||||||
ecs.add( api.world, { visor = gctl.visor } )
|
|
||||||
--gctl.visor.commit() -- notify other systems to update entitycache
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return gctl
|
return gctl
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
--@LIB
|
||||||
-- this extension will make network requests run async in LoVR runtime
|
-- this extension will make network requests run async in LoVR runtime
|
||||||
|
|
||||||
local api = ...
|
local api = ...
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
|
--@LIB
|
||||||
local api = ...
|
local api = ...
|
||||||
|
|
||||||
local sample
|
local sample
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
--@LIB
|
||||||
local api = ...
|
local api = ...
|
||||||
local ecs = api.ecs
|
local ecs = api.ecs
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
--@LIB
|
||||||
local api = ...
|
local api = ...
|
||||||
local envTex
|
local envTex
|
||||||
local shader
|
local shader
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
--@LIB
|
||||||
local api = ...
|
local api = ...
|
||||||
local tween = require "ext/tween/tween" -- https://github.com/kikito/tween.lua
|
local tween = require "ext/tween/tween" -- https://github.com/kikito/tween.lua
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
--@LIB
|
||||||
local tween = {
|
local tween = {
|
||||||
_VERSION = 'tween 2.1.1',
|
_VERSION = 'tween 2.1.1',
|
||||||
_DESCRIPTION = 'tweening for lua',
|
_DESCRIPTION = 'tweening for lua',
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
--@LIB
|
||||||
-- The unixy extension allows proxying api-functions through cli apps.
|
-- The unixy extension allows proxying api-functions through cli apps.
|
||||||
-- Why?
|
-- Why?
|
||||||
-- Sometimes the host OS already has cli-apps which can make up for missing lua functionality.
|
-- Sometimes the host OS already has cli-apps which can make up for missing lua functionality.
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
--@LIB
|
||||||
local api = ...
|
local api = ...
|
||||||
local xrf = require("ext/xrfragments/lovr-xrf")
|
local xrf = require("ext/xrfragments/lovr-xrf")
|
||||||
local url = require("url")
|
local url = require("url")
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
--@LIB
|
||||||
local xrf = require("ext/xrfragments/lovr-xrf")
|
local xrf = require("ext/xrfragments/lovr-xrf")
|
||||||
local url = require("url")
|
local url = require("url")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
--@LIB
|
||||||
-- Copyright 2026 Leon van Kammen / coderofsalvation. All rights reserved.
|
-- Copyright 2026 Leon van Kammen / coderofsalvation. All rights reserved.
|
||||||
--
|
--
|
||||||
-- Redistribution and use in source and binary forms, with or without modification, are
|
-- Redistribution and use in source and binary forms, with or without modification, are
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
--@LIB=xrfragment/main.lua
|
||||||
local api = ...
|
local api = ...
|
||||||
local url = require('url')
|
local url = require('url')
|
||||||
local ecs = api.ecs
|
local ecs = api.ecs
|
||||||
|
|
@ -19,7 +20,7 @@ xrfimpl = {
|
||||||
local href = obj.node.extras.href
|
local href = obj.node.extras.href
|
||||||
trace("\n[xrf] href was clicked: " .. href)
|
trace("\n[xrf] href was clicked: " .. href)
|
||||||
api.ext.exec("onClick", obj, collider)
|
api.ext.exec("onClick", obj, collider)
|
||||||
local ok = xrf.level2.load( href, obj, api.ext.URI.current, xrfimpl.onLoad)
|
local ok = xrf.level2.load( href, obj, referer, xrfimpl.onLoad)
|
||||||
or
|
or
|
||||||
xrf.level4.import( href, obj, referer, xrfimpl.onImport)
|
xrf.level4.import( href, obj, referer, xrfimpl.onImport)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1 +1,2 @@
|
||||||
|
--@LIB
|
||||||
print("hello!")
|
print("hello!")
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@ function url.parse(url_string)
|
||||||
URN = "",
|
URN = "",
|
||||||
isLocal = false
|
isLocal = false
|
||||||
}
|
}
|
||||||
|
if not url_string then return URI end
|
||||||
local remaining = url_string
|
local remaining = url_string
|
||||||
local protocol = string.match(remaining, "^(%w+://)") -- protocol
|
local protocol = string.match(remaining, "^(%w+://)") -- protocol
|
||||||
if protocol then
|
if protocol then
|
||||||
|
|
@ -152,11 +153,18 @@ url.getAbsolute = function(href,referer,keephash)
|
||||||
if referer ~= nil and URL.protocol == 'file' and URLref.protocol ~= 'file' then
|
if referer ~= nil and URL.protocol == 'file' and URLref.protocol ~= 'file' then
|
||||||
URL.protocol = URLref.protocol or ''
|
URL.protocol = URLref.protocol or ''
|
||||||
URL.domain = URLref.domain or ''
|
URL.domain = URLref.domain or ''
|
||||||
URL.string = URL.protocol .. '://' .. URL.domain .. '/' .. URL.path .. URL.hash
|
URL.string = URL.protocol .. '://' .. URL.domain .. '/'
|
||||||
if keephash then
|
if href[1] == "/" then
|
||||||
URL.URN = URL.string
|
URL.string = URL.string .. URL.path
|
||||||
else
|
else
|
||||||
URL.URN = URL.string:gsub("#.*", "")
|
URL.string = URL.string ..
|
||||||
|
URLref.path:sub( 0, URLref.path:find( URLref.file,1,true)-1 ) ..
|
||||||
|
URL.file
|
||||||
|
end
|
||||||
|
URL.string = URL.string .. URL.hash
|
||||||
|
URL = url.parse(URL.string) -- reparse
|
||||||
|
if keephash then
|
||||||
|
URL.hash = URLref.hash
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
URL.referer = referer
|
URL.referer = referer
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
---------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
--
|
--@LIB
|
||||||
-- xml.lua - XML parser for use with the Corona SDK.
|
-- xml.lua - XML parser for use with the Corona SDK.
|
||||||
-- https://github.com/Cluain/Lua-Simple-XML-Parser
|
-- https://github.com/Cluain/Lua-Simple-XML-Parser
|
||||||
--
|
--
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
#!/usr/bin/env lua
|
#!/usr/bin/env lua
|
||||||
|
--please do not remove the following luaX tag:
|
||||||
|
--@MAIN
|
||||||
|
--
|
||||||
-- -- GLB URLS
|
-- -- GLB URLS
|
||||||
-- ./lovr xurfer https://coderofsalvation.codeberg.page/xrfragment-haxe/example/assets/example.glb?bar=1&f=2#foo'
|
-- ./lovr xurfer https://coderofsalvation.codeberg.page/xrfragment-haxe/example/assets/example.glb?bar=1&f=2#foo'
|
||||||
-- ./lovr xurfer https://codeberg.org/coderofsalvation/xrfragment/raw/branch/main/assets/template/website/website.glb'
|
-- ./lovr xurfer https://codeberg.org/coderofsalvation/xrfragment/raw/branch/main/assets/template/website/website.glb'
|
||||||
|
|
@ -37,6 +40,10 @@ api = {
|
||||||
max = 10000, -- max plugins (used for sorting)
|
max = 10000, -- max plugins (used for sorting)
|
||||||
exec = function(...) util.exec(api.ext,...) end -- util function to call func on each extension
|
exec = function(...) util.exec(api.ext,...) end -- util function to call func on each extension
|
||||||
},
|
},
|
||||||
|
settings = { -- settings to store to ~/.config/xurfer/config.lua e.g.
|
||||||
|
version="0.0.1"
|
||||||
|
},
|
||||||
|
events = require('events'),
|
||||||
i = 1
|
i = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@ function lovr.load()
|
||||||
end
|
end
|
||||||
|
|
||||||
function lovr.update(dt)
|
function lovr.update(dt)
|
||||||
|
local event = interactions.collect()
|
||||||
ecs.update( api.world, dt, ecs.filterUpdate )
|
ecs.update( api.world, dt, ecs.filterUpdate )
|
||||||
|
|
||||||
iui.beginFrame(dt)
|
iui.beginFrame(dt)
|
||||||
|
|
@ -89,7 +90,7 @@ function lovr.update(dt)
|
||||||
-- In desktop mode, we use IUI's standard window API to fill the screen.
|
-- In desktop mode, we use IUI's standard window API to fill the screen.
|
||||||
iui.beginWindow(lovr.system.getWindowDimensions())
|
iui.beginWindow(lovr.system.getWindowDimensions())
|
||||||
|
|
||||||
api.ext.exec("update", dt, interactions.event )
|
api.ext.exec("update", dt, event )
|
||||||
|
|
||||||
iui.endWindow()
|
iui.endWindow()
|
||||||
|
|
||||||
|
|
@ -99,7 +100,7 @@ function lovr.update(dt)
|
||||||
if mainWindow:beginFrame() then
|
if mainWindow:beginFrame() then
|
||||||
iui.beginWindow(mainWindow.w, mainWindow.h)
|
iui.beginWindow(mainWindow.w, mainWindow.h)
|
||||||
|
|
||||||
api.ext.exec("update", dt, interactions.event )
|
api.ext.exec("update", dt, event )
|
||||||
|
|
||||||
iui.endWindow()
|
iui.endWindow()
|
||||||
|
|
||||||
|
|
@ -108,6 +109,7 @@ function lovr.update(dt)
|
||||||
end
|
end
|
||||||
|
|
||||||
iui.endFrame()
|
iui.endFrame()
|
||||||
|
interactions.clear()
|
||||||
end
|
end
|
||||||
|
|
||||||
function lovr.draw(pass)
|
function lovr.draw(pass)
|
||||||
|
|
@ -129,7 +131,7 @@ function lovr.draw(pass)
|
||||||
|
|
||||||
|
|
||||||
-- -- Dot
|
-- -- Dot
|
||||||
--if interactions.selectedBox then
|
--if interactions.hitpoint then
|
||||||
-- pass:setColor(0, 0, 1)
|
-- pass:setColor(0, 0, 1)
|
||||||
-- pass:sphere( interactions.hitpoint, .01)
|
-- pass:sphere( interactions.hitpoint, .01)
|
||||||
--end
|
--end
|
||||||
|
|
@ -173,7 +175,6 @@ end
|
||||||
function lovr.wheelmoved(x, y)
|
function lovr.wheelmoved(x, y)
|
||||||
backend.wheelmoved(x, y)
|
backend.wheelmoved(x, y)
|
||||||
interactions.pointer.wheel = {x=x, y=y}
|
interactions.pointer.wheel = {x=x, y=y}
|
||||||
print_r(interactions.pointer.wheel)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function lovr.keypressed(key, scancode, isRepeat)
|
function lovr.keypressed(key, scancode, isRepeat)
|
||||||
|
|
@ -197,12 +198,13 @@ function initInteractions(ecs)
|
||||||
interactions = ecs.processingSystem()
|
interactions = ecs.processingSystem()
|
||||||
interactions.updatethread = true
|
interactions.updatethread = true
|
||||||
interactions.filter = function(obj) return true end -- always run
|
interactions.filter = function(obj) return true end -- always run
|
||||||
-- collider vars
|
interactions.pointer = util.clone( api.events.input.pointer )
|
||||||
interactions.pointer = { released = false, pressed = false, moved = false, hover = false, wheel = false}
|
interactions.key = util.clone( api.events.input.key )
|
||||||
interactions.key = { released = false, pressed = false }
|
|
||||||
interactions.input = ""
|
interactions.input = ""
|
||||||
|
-- collider vars
|
||||||
interactions.hitpoint = vector()
|
interactions.hitpoint = vector()
|
||||||
interactions.selectedBox = nil
|
interactions.selectedBox = nil
|
||||||
|
interactions.direction = quat():direction()
|
||||||
interactions.clearTable = function(o) foreach( o, function(k,v) o[k] = false end ) end
|
interactions.clearTable = function(o) foreach( o, function(k,v) o[k] = false end ) end
|
||||||
interactions.clear = function()
|
interactions.clear = function()
|
||||||
interactions.clearTable( interactions.pointer )
|
interactions.clearTable( interactions.pointer )
|
||||||
|
|
@ -210,23 +212,20 @@ function initInteractions(ecs)
|
||||||
interactions.input = false
|
interactions.input = false
|
||||||
end
|
end
|
||||||
|
|
||||||
function interactions:process(obj, dt)
|
interactions.collect = function(dt)
|
||||||
ecs.worldPhysics:update(dt)
|
local castsrc = 'head' -- 'hand/left/point'
|
||||||
|
local event = util.clone(api.events.input)
|
||||||
local castsrc = 'hand/left/point'
|
interactions.event = event -- for convenience (ecs systems can always reach it)
|
||||||
local castsrc = 'head'
|
|
||||||
|
|
||||||
local ox, oy, oz = lovr.headset.getPosition(castsrc)
|
local ox, oy, oz = lovr.headset.getPosition(castsrc)
|
||||||
|
|
||||||
local direction = quat(lovr.headset.getOrientation(castsrc)):direction()
|
interactions.direction = quat(lovr.headset.getOrientation(castsrc)):direction()
|
||||||
if direction ~= nil then
|
if interactions.direction ~= nil then
|
||||||
local dx, dy, dz = vector( direction * 50 ):unpack()
|
local dx, dy, dz = vector( interactions.direction * 50 ):unpack()
|
||||||
local collider, shape, x, y, z = ecs.worldPhysics:raycast(ox, oy, oz, ox + dx, oy + dy, oz + dz)
|
local collider, shape, x, y, z = ecs.worldPhysics:raycast(ox, oy, oz, ox + dx, oy + dy, oz + dz)
|
||||||
|
|
||||||
if collider then
|
if collider then
|
||||||
interactions.pointer.hover = true
|
|
||||||
local node = collider:getUserData()
|
local node = collider:getUserData()
|
||||||
interactions.selectedBox = collider
|
interactions.pointer.hover = true
|
||||||
interactions.hitpoint.x = x
|
interactions.hitpoint.x = x
|
||||||
interactions.hitpoint.y = y
|
interactions.hitpoint.y = y
|
||||||
interactions.hitpoint.z = z
|
interactions.hitpoint.z = z
|
||||||
|
|
@ -239,22 +238,29 @@ function initInteractions(ecs)
|
||||||
interactions.pointer.released = true
|
interactions.pointer.released = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if interactions.pointer.released and node.onclick ~= nil then
|
event.collider = collider
|
||||||
node.onclick(node,collider)
|
event.node = node
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
event.direction = util.clone(direction)
|
||||||
|
event.input = interactions.input
|
||||||
|
event.pointer = util.clone(interactions.pointer)
|
||||||
|
event.key = util.clone(interactions.key)
|
||||||
|
event.hitpoint = { x = interactions.hitpoint.x, y = interactions.hitpoint.y, z = interactions.z }
|
||||||
|
--event.head = { x = ox, y = oy, z = oz, direction = direction},
|
||||||
|
api.ext.exec('input', dt, event )
|
||||||
|
return event
|
||||||
|
end
|
||||||
|
|
||||||
|
function interactions:process(obj, dt)
|
||||||
|
ecs.worldPhysics:update(dt)
|
||||||
|
local event = interactions.event
|
||||||
|
if event.collider then
|
||||||
|
--if event.pointer.released and event.node and event.node.onclick ~= nil then
|
||||||
|
if event.select and event.node and event.node.onclick ~= nil then
|
||||||
|
event.node.onclick(event.node, event.collider)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
-- backup & reset stuff
|
|
||||||
interactions.event = {
|
|
||||||
input = util.clone(interactions.input),
|
|
||||||
pointer = util.clone(interactions.pointer),
|
|
||||||
key = util.clone(interactions.key),
|
|
||||||
hitpoint = { x = interactions.hitpoint.x, y = interactions.hitpoint.y, z = interactions.z },
|
|
||||||
--head = { x = ox, y = oy, z = oz, direction = direction},
|
|
||||||
collider = collider
|
|
||||||
}
|
|
||||||
-- clear interactions
|
|
||||||
interactions.clear()
|
|
||||||
end
|
end
|
||||||
ecs.addSystem( api.world, interactions )
|
ecs.addSystem( api.world, interactions )
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
--@LIB
|
||||||
local lust = require 'lust'
|
local lust = require 'lust'
|
||||||
local describe, it, expect = lust.describe, lust.it, lust.expect
|
local describe, it, expect = lust.describe, lust.it, lust.expect
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue