if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then require "lldebugger".start() end local util = require "util" local launch = require "launch" local iui = require "lib.iui" local backend = require "lib.lovr-iui" -- modify for nested lovr path for api iui.resourcePath = "lovr/" .. iui.resourcePath backend.resourcePath = "lovr/" .. backend.resourcePath api.iui = iui api.backend = backend local ecs = api.ecs -- ecs systems local interactionsUpdater local renderer --- @type Texture local envTex --- @type LovrIUIWorldWindow local mainWindow function lovr.load() if launch.mode == "desktop" then backend.mouse = require "lib.lovr-mouse" lovr.system.setKeyRepeat(true) end iui.load(backend) api.exec( api.ext, "load") if iui.idiom == "vr" then lovr.headset.setPassthrough("opaque") mainWindow = backend.worldWindow.new() api.mainWindow = mainWindow end end function lovr.update(dt) if lovr.system.isKeyDown("escape") then lovr.event.quit() end ecs.update( ecs.world, dt, ecs.filter('updatesystem') ) iui.beginFrame(dt) if iui.idiom == "desktop" then -- In desktop mode, we use IUI's standard window API to fill the screen. iui.beginWindow(lovr.system.getWindowDimensions()) api.exec( api.ext, "update", dt) iui.endWindow() elseif iui.idiom == "vr" then -- In VR mode, we have access to the backend's `LovrIUIWorldWindow` -- class, which handles windowing in world-space. if mainWindow:beginFrame() then iui.beginWindow(mainWindow.w, mainWindow.h) api.exec( api.ext, "update", dt) iui.endWindow() mainWindow:endFrame() end end iui.endFrame() end function lovr.draw(pass) if iui.idiom == "desktop" then backend.graphics.pass = pass iui.draw() end if api.iui.idiom == "vr" then pass:setClear(0.5, 0.5, 0.5) end api.exec(api.ext, "draw",pass) ecs.update( ecs.world, pass, ecs.filter('drawsystem') ) -- Dot if selectedBox then pass:setColor(0, 0, 1) pass:sphere(hitpoint, .01) end -- Laser pointer local hand = vec3(lovr.headset.getPosition('hand/left/point')) local direction = quat(lovr.headset.getOrientation('hand/left/point')):direction() pass:setColor(1, 1, 1) pass:line(hand, selectedBox and hitpoint or (hand + direction * 50)) if api.mainWindow then api.mainWindow:draw(pass) end return false end function lovr.recenter() if iui.idiom == "vr" then mainWindow:recenter() end end if launch.mode == "desktop" then function lovr.mousemoved(x, y, dx, dy) backend.mousemoved(x, y, dx, dy) interactionsUpdater['mouse']['moved'] = {x=x, y=y, button=button} end function lovr.mousepressed(x, y, button) backend.mousepressed(x, y, button) interactionsUpdater['mouse']['pressed'] = {x=x, y=y, button=button} end function lovr.mousereleased(x, y, button) backend.mousereleased(x, y, button) interactionsUpdater['mouse']['released'] = {x=x, y=y, button=button} print("ja") end function lovr.wheelmoved(x, y) backend.wheelmoved(x, y) interactionsUpdater['mouse']['wheel'] = {x=x, y=y} end function lovr.keypressed(key, scancode, isRepeat) backend.keypressed(key, scancode, isRepeat) end function lovr.keyreleased(key, scancode) backend.keyreleased(key, scancode) end function lovr.textinput(text) backend.textinput(text) end end local initECS = function(ecs) ecs.world = ecs.world() -- lovr.draw => ecs.drawsystem (render-logic thread) renderer = ecs.processingSystem() renderer.filter = ecs.requireAny('model') renderer.drawsystem = true function renderer:process(obj, pass) if obj['model'] ~= nil then pass:setMaterial() pass:setCullMode('none') pass:draw( obj['model'], obj['x'] or 0, obj['y'] or 0, obj['z'] or 0, 1, 0, 1, 0, 0, 1) end end ecs.addSystem( ecs.world, renderer ) -- lovr.update => ecs updatesystem (game-logic thread) local updater = ecs.processingSystem() updater.updatesystem = true updater.filter = ecs.requireAll('update') function updater:process(obj, dt) print_r(obj['data']) end ecs.addSystem( ecs.world, updater ) end function initInteractions(ecs) ecs.worldPhysics = lovr.physics.newWorld(0, 0, 0) interactionsUpdater = ecs.processingSystem() interactionsUpdater.updatesystem = true interactionsUpdater.filter = ecs.requireAll('collider') -- collider vars interactionsUpdater.mouse = { released = false} interactionsUpdater.hitpoint = lovr.math.newVec3() interactionsUpdater.selectedBox = nil function interactionsUpdater:process(obj, dt) ecs.worldPhysics:update(dt) local ox, oy, oz = lovr.headset.getPosition('hand/left/point') local dx, dy, dz = quat(lovr.headset.getOrientation('hand/left/point')):direction():mul(50):unpack() local collider, shape, x, y, z = ecs.worldPhysics:raycast(ox, oy, oz, ox + dx, oy + dy, oz + dz) if collider then if lovr.headset.isDown(hand, 'trigger') then local node = collider:getUserData() selectedBox = collider hitpoint:set(x, y, z) print( "collide with " .. node['name'] .. " => " .. node['extras']['href'] ) print("buttondown") end if lovr.headset.wasReleased(hand, 'trigger') or interactionsUpdater['mouse']['released'] then print('click!') end end -- reset mouse mouse['released'] = false mouse['pressed'] = false end ecs.addSystem( ecs.world, interactionsUpdater ) end initECS(api.ecs) initInteractions(api.ecs)