### Implement Event Handling System with LOVR Source: https://context7.com/bjornbytes/lovr/llms.txt Shows how to use the lovr.event module to process system, input, and custom events. It includes examples of polling events, handling key and mouse inputs, pushing custom events, and quitting the application. ```lua function lovr.run() lovr.event.pump() for name, a, b, c, d in lovr.event.poll() do if name == 'quit' then return a or 0 elseif name == 'restart' then return 'restart', a elseif name == 'keypressed' then lovr.keypressed(a, b) -- key, scancode elseif name == 'keyreleased' then lovr.keyreleased(a, b) elseif name == 'mousepressed' then lovr.mousepressed(a, b, c) -- x, y, button elseif name == 'mousereleased' then lovr.mousereleased(a, b, c) elseif name == 'threaderror' then print('Thread error:', a, b) end if lovr.handlers[name] then lovr.handlers[name](a, b, c, d) end end end -- Push custom events lovr.event.push('myevent', { data = 'value' }, 123) -- Quit application function lovr.keypressed(key) if key == 'escape' then lovr.event.quit(0) elseif key == 'r' then lovr.event.restart() end end ``` -------------------------------- ### LÖVR 3D Model Loading and Drawing Source: https://github.com/bjornbytes/lovr/blob/dev/README.md This example demonstrates how to load and draw a 3D model in LÖVR. The `lovr.load()` function is used to initialize the model by calling `lovr.graphics.newModel()`, and `pass:draw()` in `lovr.draw()` is used to render it in the scene. ```lua function lovr.load() model = lovr.graphics.newModel('model.gltf') end function lovr.draw(pass) pass:draw(model, x, y, z) end ``` -------------------------------- ### LÖVR Spinning Cube Example Source: https://github.com/bjornbytes/lovr/blob/dev/README.md This code snippet shows how to create a spinning cube in a LÖVR VR experience. It uses `lovr.draw` to render the cube and `lovr.timer.getTime()` to control the rotation speed, creating a dynamic visual effect. ```lua function lovr.draw(pass) pass:cube(0, 1.7, -1, .5, lovr.timer.getTime()) end ``` -------------------------------- ### Setup LÖVR Module and Canvas in JavaScript Source: https://github.com/bjornbytes/lovr/blob/dev/etc/lovr.html This snippet initializes the LÖVR WebAssembly module, configures its canvas element, and sets up standard output streams. It's essential for running LÖVR applications in a web environment. It expects a canvas element with the ID 'canvas' to be present in the HTML. ```javascript var container = document.querySelector('.container'); var canvas = document.getElementById('canvas'); var button = document.createElement('button'); button.textContent = 'Enter VR'; var Module = window.Module = { arguments: [], preRun: [], postRun: [], print: console.log.bind(console), printErr: console.error.bind(console), thisProgram: './lovr', canvas: canvas }; ``` -------------------------------- ### CMake Project Setup and Options Source: https://github.com/bjornbytes/lovr/blob/dev/CMakeLists.txt Configures the minimum CMake version, policy settings, project name, and defines various build options for enabling or disabling project modules and features. These options control aspects like audio, graphics, filesystem, and the use of external libraries like GLFW or LuaJIT. Options are typically boolean flags that influence the build process. ```cmake cmake_minimum_required(VERSION 3.5.0) cmake_policy(SET CMP0063 NEW) cmake_policy(SET CMP0079 NEW) cmake_policy(SET CMP0091 NEW) set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0" CACHE STRING "Minimum macOS deployment version") project(lovr) # Options option(LOVR_ENABLE_AUDIO "Enable the audio module" ON) option(LOVR_ENABLE_DATA "Enable the data module" ON) option(LOVR_ENABLE_EVENT "Enable the event module" ON) option(LOVR_ENABLE_FILESYSTEM "Enable the filesystem module" ON) option(LOVR_ENABLE_GRAPHICS "Enable the graphics module" ON) option(LOVR_ENABLE_HEADSET "Enable the headset module" ON) option(LOVR_ENABLE_MATH "Enable the math module" ON) option(LOVR_ENABLE_PHYSICS "Enable the physics module" ON) option(LOVR_ENABLE_SYSTEM "Enable the system module" ON) option(LOVR_ENABLE_THREAD "Enable the thread module" ON) option(LOVR_ENABLE_TIMER "Enable the timer module" ON) option(LOVR_ENABLE_UTF8 "Enable the utf8 module" ON) option(LOVR_USE_GLFW "Use GLFW for desktop windows" ON) option(LOVR_USE_LUAJIT "Use LuaJIT instead of Lua" ON) option(LOVR_USE_LUAU "Use Luau instead of Lua" OFF) option(LOVR_USE_GLSLANG "Use glslang to compile GLSL shaders" ON) option(LOVR_USE_VULKAN "Use the Vulkan renderer" ON) option(LOVR_USE_WEBGPU "Use the WebGPU renderer" OFF) option(LOVR_USE_STEAM_AUDIO "Enable the Steam Audio spatializer (be sure to also set LOVR_STEAM_AUDIO_PATH)" OFF) option(LOVR_SANITIZE "Enable Address Sanitizer" OFF) option(LOVR_PROFILE "Enable Tracy integration" OFF) option(LOVR_SYSTEM_GLFW "Use the system-provided glfw" OFF) option(LOVR_SYSTEM_LUA "Use the system-provided Lua" OFF) option(LOVR_SYSTEM_OPENXR "Use the system-provided OpenXR" OFF) option(LOVR_BUILD_EXE "Build an executable (or an apk on Android)" ON) option(LOVR_BUILD_SHARED "Build a shared library (takes precedence over LOVR_BUILD_EXE)" OFF) option(LOVR_BUILD_BUNDLE "On macOS, build a .app bundle instead of a raw program" OFF) option(LOVR_BUILD_WITH_SYMBOLS "Build with C function symbols exposed" OFF) ``` -------------------------------- ### Android Platform Setup Source: https://github.com/bjornbytes/lovr/blob/dev/CMakeLists.txt Configures build settings for the Android platform. It finds the required Java SDK, sets LOVR_USE_SIMULATOR to OFF, and ensures that if LOVR_BUILD_EXE is ON, LOVR_BUILD_SHARED is also set to ON. ```cmake elseif(ANDROID) find_package(Java REQUIRED) set(LOVR_USE_SIMULATOR OFF) if(LOVR_BUILD_EXE) set(LOVR_BUILD_SHARED ON) endif() endif() ``` -------------------------------- ### Configure Shared Library Output Directory (Unix CMake) Source: https://github.com/bjornbytes/lovr/blob/dev/CMakeLists.txt On Unix systems, this CMake code sets the 'RUNTIME_OUTPUT_DIRECTORY' for the 'lovr' target to '${CMAKE_BINARY_DIR}/bin'. It also configures the build to include the install rpath and sets it to '$ORIGIN', which is important for dynamically linked executables to find their shared libraries. ```cmake set_target_properties(lovr PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" BUILD_WITH_INSTALL_RPATH TRUE INSTALL_RPATH "$ORIGIN" ENABLE_EXPORTS ON ) ``` -------------------------------- ### Configure System Lua for LOVR (CMake) Source: https://github.com/bjornbytes/lovr/blob/dev/CMakeLists.txt Configures the system's Lua installation for the LOVR project. It searches for the Lua package, sets include paths, library directories, and links the Lua libraries. Alternatively, it builds Lua from source if not found on the system, including platform-specific configurations for MSVC and POSIX systems. ```cmake if(LOVR_SYSTEM_LUA) pkg_search_module(LUA REQUIRED lua) list(APPEND LOVR_LIB_DIRS ${LUA_LIBRARY_DIRS}) set(LOVR_LUA_INCLUDE ${LUA_INCLUDE_DIRS}) set(LOVR_LUA_LIB_DIR ${LUA_LIBRARY_DIRS}) set(LOVR_LUA ${LUA_LIBRARIES}) else() set(LUA_SRC lapi.c lauxlib.c lbaselib.c lcode.c ldblib.c ldebug.c ldo.c ldump.c lfunc.c lgc.c linit.c liolib.c llex.c lmathlib.c lmem.c loadlib.c lobject.c lopcodes.c loslib.c lparser.c lstate.c lstring.c lstrlib.c ltable.c ltablib.c ltm.c lundump.c lvm.c lzio.c ) list(TRANSFORM LUA_SRC PREPEND deps/lua/) add_library(lua SHARED ${LUA_SRC}) target_include_directories(lua INTERFACE deps/lua) if(MSVC) target_compile_definitions(lua PRIVATE LUA_BUILD_AS_DLL) target_compile_definitions(lua PRIVATE _CRT_SECURE_NO_WARNINGS) else() target_link_libraries(lua m) target_link_libraries(lua dl) target_compile_definitions(lua PRIVATE LUA_USE_DLOPEN) endif() set(LOVR_LUA lua) endif() endif() ``` -------------------------------- ### Run All LÖVR Tests (Console) Source: https://github.com/bjornbytes/lovr/blob/dev/README.md This command executes all the tests within the LÖVR framework. It assumes LÖVR has been built, and the executable is available in the `build/bin` directory. This is crucial for verifying the integrity of the framework after changes or builds. ```bash ./build/bin/lovr test ``` -------------------------------- ### Basic 'Hello World' in LÖVR Source: https://github.com/bjornbytes/lovr/blob/dev/README.md This snippet demonstrates the most basic LÖVR application, displaying 'Hello World!' in the VR scene. It utilizes the `lovr.draw` function, which is called every frame to render content. The `pass:text` function is used for drawing text. ```lua function lovr.draw(pass) pass:text('Hello World!', 0, 1.7, -3, .5) end ``` -------------------------------- ### Build LÖVR from Source using CMake (Console) Source: https://github.com/bjornbytes/lovr/blob/dev/README.md This is a command-line sequence for building the LÖVR framework from its source code using CMake. It involves creating a build directory, navigating into it, and then running CMake configuration and build commands. This process is essential for developers who want to compile LÖVR themselves. ```bash mkdir build cd build cmake .. cmake --build . ``` -------------------------------- ### Load LÖVR Project from .lovr File in JavaScript Source: https://github.com/bjornbytes/lovr/blob/dev/etc/lovr.html This code dynamically loads a LÖVR project (packaged as a .lovr zip file) into the virtual file system and adds it as a command-line argument for LÖVR. This enables running custom LÖVR applications served alongside the HTML. It requires a 'project' variable to be set with the filename of the .lovr file. ```javascript // To run a LÖVR project on this page, create a .lovr (zip) file of its folder and serve it // alongside the HTML file. Then set the 'project' variable below to the project's filename. // This downloads the .lovr file into the virtual filesystem and adds it as a virtual command // line argument before booting up LÖVR. // Example: var project = 'app.lovr'; var project = null; if (project) { Module.arguments.push(project); Module.preRun.push(function() { Module.FS_createPreloadedFile('/', project, project, true, false); }); } ``` -------------------------------- ### Integrate with VR Headset using lovr.headset Source: https://context7.com/bjornbytes/lovr/llms.txt Access VR headset tracking, controller input, and hand tracking data. Connect to the headset, retrieve its capabilities (like hand and eye tracking), and get pose and input data for hands and controllers. Supports haptic feedback and passthrough modes. ```lua function lovr.load() -- Connect to VR headset local connected, info = lovr.headset.connect() if connected then print('Connected to:', info) end -- Get headset capabilities local features = lovr.headset.getFeatures() print('Hand tracking:', features.handTracking) print('Eye tracking:', features.eyeTracking) print('Passthrough:', features.passthrough) end function lovr.draw(pass) -- Get headset pose local hx, hy, hz, hangle, hax, hay, haz = lovr.headset.getPose('head') -- Iterate over active hands for _, hand in ipairs(lovr.headset.getHands()) do local x, y, z = lovr.headset.getPosition(hand) local angle, ax, ay, az = lovr.headset.getOrientation(hand) -- Draw hand position pass:sphere(vec3(x, y, z), 0.05) -- Get hand skeleton (26 joints) if lovr.headset.isTracked(hand, true) then for i = 1, 26 do local jx, jy, jz = lovr.headset.getSkeleton(hand, i) pass:sphere(vec3(jx, jy, jz), 0.01) end end -- Check button states if lovr.headset.wasPressed(hand, 'trigger') then print(hand, 'trigger pressed') end -- Get analog input local tx, ty = lovr.headset.getAxis(hand, 'thumbstick') local gripStrength = lovr.headset.getAxis(hand, 'grip') end -- Draw controller models for _, hand in ipairs(lovr.headset.getHands()) do local model = lovr.headset.getControllerModel(hand) if model then pass:draw(model, lovr.headset.getPose(hand)) end end end -- Handle haptic feedback function fireTriggerHaptics(hand) lovr.headset.vibrate(hand, 0.8, 0.2) -- 80% strength for 0.2 seconds end -- Set passthrough mode for mixed reality lovr.headset.setPassthrough('blend') -- Configure foveated rendering for performance lovr.headset.setFoveation(0, 'high') -- Layer 0, high foveation ``` -------------------------------- ### Perform File Operations with LOVR Filesystem Source: https://context7.com/bjornbytes/lovr/llms.txt Covers various file system operations using the lovr.filesystem module, including setting an application identity, accessing special directories, mounting archives, reading/writing files, listing directory contents, and retrieving file information. ```lua function lovr.load() -- Set app identity for save directory lovr.filesystem.setIdentity('myapp') -- Get special directories print('Save dir:', lovr.filesystem.getSaveDirectory()) print('Source dir:', lovr.filesystem.getSource()) -- Mount archives lovr.filesystem.mount('assets.zip') -- Check file existence if lovr.filesystem.isFile('config.json') then local contents = lovr.filesystem.read('config.json') config = loadJSON(contents) end -- Write to save directory local saveData = { highScore = 1000, playerName = 'Hero' } lovr.filesystem.write('save.json', encodeJSON(saveData)) -- List directory contents local files = lovr.filesystem.getDirectoryItems('levels') for _, filename in ipairs(files) do print('Found:', filename) end -- File info local info = lovr.filesystem.getInfo('data.bin') if info then print('Size:', info.size, 'Modified:', info.lastModified) end end -- Create directories lovr.filesystem.createDirectory('saves/profiles') -- Remove files lovr.filesystem.remove('temp.dat') ``` -------------------------------- ### Configure glslang for LOVR (CMake) Source: https://github.com/bjornbytes/lovr/blob/dev/CMakeLists.txt Configures the glslang shader compiler for the LOVR project. It disables various glslang features like HLSL support and installation, and conditionally enables binaries based on the target platform (excluding Emscripten). It also sets interface include directories and runtime output directory for the standalone target. ```cmake if(LOVR_USE_GLSLANG) set(ENABLE_HLSL OFF CACHE BOOL "") set(ENABLE_SPVREMAPPER OFF CACHE BOOL "") set(ENABLE_GLSLANG_INSTALL OFF CACHE BOOL "") set(ENABLE_OPT OFF CACHE BOOL "") set(ENABLE_CTEST OFF CACHE BOOL "") set(BUILD_EXTERNAL OFF CACHE BOOL "") set(BUILD_SHARED_LIBS OFF) if(NOT EMSCRIPTEN) set(ENABLE_GLSLANG_BINARIES ON CACHE BOOL "") else() set(ENABLE_GLSLANG_BINARIES OFF CACHE BOOL "") endif() add_subdirectory(deps/glslang glslang) target_include_directories(glslang INTERFACE deps/glslang/glslang/Include deps/glslang/glslang/Public) if(TARGET glslang-standalone) set_target_properties(glslang-standalone PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/glslang/glslang") endif() set(LOVR_GLSLANG glslang glslang-default-resource-limits) endif() ``` -------------------------------- ### Create and Use Custom Shaders with LOVR Graphics Source: https://context7.com/bjornbytes/lovr/llms.txt Demonstrates creating custom GLSL shaders (vertex, fragment, and compute) using lovr.graphics.newShader. It covers setting shader uniforms and dispatching compute work, suitable for advanced rendering and parallel processing. ```lua -- Create shader with vertex and fragment code local shader = lovr.graphics.newShader([[ // Vertex shader vec4 lovrmain() { return DefaultPosition; } ]], [[ // Fragment shader Constants { float time; vec3 color; }; vec4 lovrmain() { vec3 animated = color * (0.5 + 0.5 * sin(time + vWorldPosition.x)); return vec4(animated, 1.0); } ]]) -- Use shader with uniforms function lovr.draw(pass) pass:setShader(shader) pass:send('time', lovr.timer.getTime()) pass:send('color', { 1, 0.5, 0.2 }) pass:cube(0, 1.7, -2, 0.5) pass:setShader() -- Reset to default end -- Compute shader example local computeShader = lovr.graphics.newShader([[ layout(local_size_x = 64) in; layout(set = 0, binding = 0) buffer ParticleBuffer { vec4 particles[]; }; Constants { float dt; }; void lovrmain() { uint id = GlobalThreadID.x; vec3 pos = particles[id].xyz; vec3 vel = vec3(0, -9.81 * dt, 0); pos += vel * dt; if (pos.y < 0) { pos.y = 0; vel.y *= -0.5; } particles[id] = vec4(pos, 1.0); } ]], { compute = true }) -- Dispatch compute work function lovr.update(dt) local pass = lovr.graphics.getPass('compute') pass:setShader(computeShader) pass:send('ParticleBuffer', particleBuffer) pass:send('dt', dt) pass:compute(math.ceil(particleCount / 64)) lovr.graphics.submit(pass) end ``` -------------------------------- ### Create and Control Spatial Audio Sources in LOVR Source: https://context7.com/bjornbytes/lovr/llms.txt This snippet demonstrates how to create and manage spatialized audio sources. It covers loading sound files, creating sources with spatial properties, setting listener position and orientation, updating them based on headset data, and controlling playback, volume, pitch, and position of individual sources. Dependencies include sound file loading and headset data retrieval. ```lua function lovr.load() -- Load sound files local soundData = lovr.data.newSound('explosion.ogg') local musicData = lovr.data.newSound('ambient.mp3', { stream = true }) -- Create audio sources explosionSource = lovr.audio.newSource(soundData, { spatial = true, volume = 0.8, pitchMultiplier = 1.0 }) musicSource = lovr.audio.newSource(musicData, { spatial = false, looping = true, volume = 0.3 }) -- Start background music musicSource:play() -- Configure audio listener (typically head position) lovr.audio.setPosition(0, 1.7, 0) lovr.audio.setOrientation(0, 0, -1, 0, 1, 0) end function lovr.update(dt) -- Update listener position from headset local hx, hy, hz = lovr.headset.getPosition('head') local angle, ax, ay, az = lovr.headset.getOrientation('head') lovr.audio.setPosition(hx, hy, hz) lovr.audio.setOrientation(lovr.math.quat(angle, ax, ay, az):direction()) end function playExplosionAt(x, y, z) -- Position source in 3D space explosionSource:setPosition(x, y, z) -- Configure attenuation explosionSource:setAttenuationDistance(1, 10) -- Ref distance, max distance explosionSource:setAttenuationRolloff(1.0) -- Falloff curve -- Optional: directional cone explosionSource:setCone(math.pi/4, math.pi/2, 0, 1, 0) -- Inner/outer angles, direction -- Play with optional pitch variation explosionSource:setPitch(0.9 + math.random() * 0.2) explosionSource:play() end -- Check source state function lovr.update(dt) if explosionSource:isPlaying() then print('Time:', explosionSource:tell(), '/', explosionSource:getDuration()) end -- Seek to position musicSource:seek(30.0) -- Jump to 30 seconds -- Volume control local volume = musicSource:getVolume() musicSource:setVolume(volume * 0.95) -- Fade out end ``` -------------------------------- ### GLFW Dependency Integration Source: https://github.com/bjornbytes/lovr/blob/dev/CMakeLists.txt Integrates the GLFW library for windowing and input handling, provided that LOVR_USE_GLFW is enabled and the target platform is not Emscripten or Android. It supports using system-installed GLFW or building it from a subdirectory dependency. It also appends GLFW include and library directories to the build paths. ```cmake if(LOVR_USE_GLFW AND NOT (EMSCRIPTEN OR ANDROID)) if(LOVR_SYSTEM_GLFW) pkg_search_module(GLFW REQUIRED glfw3) list(APPEND LOVR_INCLUDES ${GLFW_INCLUDE_DIRS}) list(APPEND LOVR_LIB_DIRS ${GLFW_LIBRARY_DIRS}) set(LOVR_GLFW ${GLFW_LIBRARIES}) else() set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "") set(GLFW_BUILD_TESTS OFF CACHE BOOL "") set(GLFW_BUILD_DOCS OFF CACHE BOOL "") set(GLFW_BUILD_WAYLAND OFF CACHE BOOL "") set(GLFW_INSTALL OFF CACHE BOOL "") set(GLFW_LIBRARY_TYPE "SHARED") add_subdirectory(deps/glfw glfw) set(LOVR_GLFW glfw) endif() endif() ``` -------------------------------- ### Configure Windows Build for LOVR Project Source: https://github.com/bjornbytes/lovr/blob/dev/CMakeLists.txt Sets up compilation and linking for the Windows platform, including specific compiler warnings to ignore, linker subsystems, and entry points. It also defines a function to copy DLLs after the build. ```cmake if(WIN32) target_sources(lovr PRIVATE src/core/os_win32.c etc/lovr.rc) if(MSVC) set_target_properties(lovr PROPERTIES COMPILE_FLAGS /wd4244) # Excuse anonymous union for type punning set_source_files_properties(src/util.c src/modules/graphics/graphics.c PROPERTIES COMPILE_FLAGS /wd4116) # Excuse unsigned negation for flag-magic bit math set_source_files_properties(src/modules/audio/audio.c PROPERTIES COMPILE_FLAGS /wd4146) set_source_files_properties(src/lib/minimp3/minimp3.c PROPERTIES COMPILE_FLAGS /wd4267) if(NOT LOVR_BUILD_SHARED) set_target_properties(lovr PROPERTIES LINK_FLAGS_DEBUG "/SUBSYSTEM:console /ENTRY:WinMainCRTStartup") set_target_properties(lovr PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:windows /ENTRY:WinMainCRTStartup") endif() else() set_target_properties(lovr PROPERTIES COMPILE_FLAGS "-MP") endif() target_compile_definitions(lovr PRIVATE _CRT_SECURE_NO_WARNINGS) target_compile_definitions(lovr PRIVATE _CRT_NONSTDC_NO_WARNINGS) if(MSVC_VERSION VERSION_LESS 1900) target_compile_definitions(lovr PRIVATE inline=_inline snprintf=_snprintf) endif() function(move_dll) if(TARGET ${ARGV0}) add_custom_command(TARGET move_files POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ $/$ ) endif() endfunction() move_dll(${LOVR_GLFW}) move_dll(${LOVR_LUA}) move_dll(${LOVR_MSDF}) move_dll(${LOVR_JOLT}) move_dll(${LOVR_GLSLANG}) move_dll(${LOVR_OPENXR}) move_dll(${LOVR_PHONON}) foreach(target ${ALL_PLUGIN_TARGETS}) move_dll(${target}) endforeach() move_resource("lovrc.bat") endif() ``` -------------------------------- ### Configure Steam Audio (Phonon) Library for LOVR Source: https://github.com/bjornbytes/lovr/blob/dev/CMakeLists.txt This CMake code configures the Steam Audio (Phonon) library for the LOVR project. It checks for the necessary Steam Audio path and sets up the library import and include directories. Platform-specific library and import library locations are defined for Android, Windows, macOS, and Linux. ```cmake if(LOVR_USE_STEAM_AUDIO) if(NOT LOVR_STEAM_AUDIO_PATH) message(FATAL_ERROR "LOVR_USE_STEAM_AUDIO requires the LOVR_STEAM_AUDIO_PATH to be set to the location of the Steam Audio folder") endif() add_library(Phonon SHARED IMPORTED) target_include_directories(Phonon INTERFACE "${LOVR_STEAM_AUDIO_PATH}/include") if(ANDROID) set_target_properties(Phonon PROPERTIES IMPORTED_LOCATION "${LOVR_STEAM_AUDIO_PATH}/lib/Android/arm64/libphonon.so") elseif(WIN32) set_target_properties(Phonon PROPERTIES IMPORTED_IMPLIB "${LOVR_STEAM_AUDIO_PATH}/lib/Windows/x64/phonon.lib") set_target_properties(Phonon PROPERTIES IMPORTED_LOCATION "${LOVR_STEAM_AUDIO_PATH}/bin/Windows/x64/phonon.dll") elseif(APPLE) set_target_properties(Phonon PROPERTIES IMPORTED_LOCATION "${LOVR_STEAM_AUDIO_PATH}/lib/OSX/libphonon.dylib" IMPORTED_SONAME "@rpath/libphonon.dylib") # It doesn't make sense this line is required, but it is else() # Assume Linux. Note: This has *not* been tested. FIXME: When is the .so copied? set_target_properties(Phonon PROPERTIES IMPORTED_LOCATION "${LOVR_STEAM_AUDIO_PATH}/lib/Linux/x64/libphonon.so") endif() set(LOVR_PHONON Phonon) endif() ``` -------------------------------- ### Run Specific LÖVR Module Tests (Console) Source: https://github.com/bjornbytes/lovr/blob/dev/README.md This command allows running tests for a specific module within the LÖVR framework. By appending the module name (e.g., 'data') to the test command, developers can isolate and test individual components of the framework efficiently. ```bash ./build/bin/lovr test data ``` -------------------------------- ### Filesystem Additions Source: https://github.com/bjornbytes/lovr/blob/dev/CHANGES.md New functionalities and features added to the Lovr filesystem module. ```APIDOC ## Filesystem Additions ### Description This section details new additions to the Lovr filesystem module, including file watching capabilities and new file handling functions. ### New Features - `--watch` CLI flag, `lovr.filechanged` event, and `lovr.filesystem.watch/unwatch`. - `File` object and `lovr.filesystem.newFile`. - `lovr.filesystem.getBundlePath` (for internal boot code). - `lovr.filesystem.setSource` (for internal boot code). ``` -------------------------------- ### General Additions Source: https://github.com/bjornbytes/lovr/blob/dev/CHANGES.md General additions to the Lovr engine. ```APIDOC ## General Additions ### Description This section details general additions to the Lovr engine, specifically regarding Lua 5.4 features. ### New Features - Support for declaring objects as to-be-closed variables in Lua 5.4. ``` -------------------------------- ### Rendering Commands with LÖVR Pass System (Lua) Source: https://context7.com/bjornbytes/lovr/llms.txt The Pass system allows recording and submitting drawing operations. It supports setting rendering states like color, culling, and depth testing. Primitives, text, models, and custom shaders can be drawn. Also supports compute shader dispatch. ```lua function lovr.draw(pass) -- Set rendering state pass:setColor(1, 0.5, 0.5) pass:setCullMode('back') pass:setDepthTest('less') pass:setWireframe(false) -- Draw 3D primitives with transformations pass:cube(0, 1.7, -3, 0.5, lovr.timer.getTime()) pass:sphere(vec3(2, 1.7, -2), 0.3) pass:plane(0, 0, -5, 10, 10, math.pi/2, 1, 0, 0) -- Draw text in 3D space pass:text('Hello VR!', 0, 2, -2, 0.2, math.pi/4, 0, 1, 0) -- Draw models with materials if model then pass:draw(model, x, y, z, scale, angle, ax, ay, az) end -- Draw with custom shaders and buffers pass:setShader(customShader) pass:send('time', lovr.timer.getTime()) pass:mesh(vertices, indices) -- Compute shader dispatch pass:compute(computeShader, 64, 1, 1) end ``` -------------------------------- ### LOVR Math: Vector, Quaternion, and Matrix Operations Source: https://context7.com/bjornbytes/lovr/llms.txt This snippet showcases high-performance vector, quaternion, and matrix math operations provided by LOVR. It includes vector creation and arithmetic, quaternion rotations and direction extraction, matrix transformations (translation, rotation, scaling), component unpacking, vector transformation, matrix inversion, and the creation of projection and view matrices. It also demonstrates curve interpolation. ```lua -- Vector creation and operations local v1 = vec3(1, 2, 3) local v2 = vec3(4, 5, 6) local sum = v1 + v2 -- vec3(5, 7, 9) local diff = v2 - v1 -- vec3(3, 3, 3) local scaled = v1 * 2 -- vec3(2, 4, 6) local dot = v1:dot(v2) -- 32 local cross = v1:cross(v2) -- vec3(-3, 6, -3) local len = v1:length() -- 3.74... local normalized = v1:normalize() -- Quaternion rotations local q1 = quat(math.pi/2, 0, 1, 0) -- 90 degrees around Y axis local q2 = quat(math.pi/4, 1, 0, 0) -- 45 degrees around X axis local combined = q1 * q2 -- Combined rotation local forward = q1:direction() -- Get forward vector -- Matrix transformations local mat = mat4() mat:translate(0, 1.7, -3) mat:rotate(math.pi/4, 0, 1, 0) mat:scale(2, 2, 2) -- Extract components local x, y, z, sx, sy, sz, angle, ax, ay, az = mat:unpack() -- Transform vectors local worldPos = vec3(5, 0, 0) local localPos = mat:mul(worldPos) -- Inverse transformations local invMat = mat4(mat):invert() -- Projection matrices local projection = mat4():perspective( math.rad(90), -- FOV 1440/900, -- Aspect ratio 0.1, -- Near plane 100 -- Far plane ) -- View matrix from pose local view = mat4():target( 0, 1.7, 5, -- Eye position 0, 1.7, 0, -- Target position 0, 1, 0 -- Up vector ) -- Curve interpolation local curve = lovr.math.newCurve({ vec3(0, 0, 0), vec3(1, 2, 1), vec3(2, 1, 2), vec3(3, 0, 3) }) local t = 0.5 local point = curve:evaluate(t) local tangent = curve:getTangent(t) ``` -------------------------------- ### System Additions Source: https://github.com/bjornbytes/lovr/blob/dev/CHANGES.md New functionalities and features added to the Lovr system module. ```APIDOC ## System Additions ### Description This section details new additions to the Lovr system module, focusing on window state, mouse input, and clipboard access. ### New Features - `lovr.system.isWindowVisible` and `lovr.system.isWindowFocused`. - `lovr.system.wasMousePressed` and `lovr.system.wasMouseReleased`. - `lovr.system.get/setClipboardText`. - `lovr.system.openConsole` (for internal Lua code). - KeyCodes for numpad keys. ``` -------------------------------- ### Configure Jolt Physics for LOVR (CMake) Source: https://github.com/bjornbytes/lovr/blob/dev/CMakeLists.txt Configures the Jolt physics engine for the LOVR project when physics is enabled. It sets build options for Jolt, including shared library settings and debug/release configurations. Also includes MSVC-specific runtime library settings. ```cmake if(LOVR_ENABLE_PHYSICS) set(BUILD_SHARED_LIBS OFF) set(JPH_BUILD_SHARED ON CACHE BOOL "") set(DEBUG_RENDERER_IN_DEBUG_AND_RELEASE OFF CACHE BOOL "") set(PROFILER_IN_DEBUG_AND_RELEASE OFF CACHE BOOL "") set(ENABLE_OBJECT_STREAM OFF CACHE BOOL "") add_subdirectory(deps/joltc jolt) set_target_properties(Jolt joltc PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>DLL") set(LOVR_JOLT joltc) endif() ``` -------------------------------- ### Emscripten Platform Configuration Source: https://github.com/bjornbytes/lovr/blob/dev/CMakeLists.txt Configures build settings specifically for the Emscripten platform. This includes setting linker flags for optimization and WebGPU support, modifying C/C++ compiler flags, setting the executable suffix to '.html', and explicitly enabling WebGPU while disabling Vulkan. ```cmake if(EMSCRIPTEN) string(CONCAT EMSCRIPTEN_LINKER_FLAGS "-Os " "-sUSE_WEBGPU=1 " "-sFORCE_FILESYSTEM=1 " "-sINITIAL_HEAP=1677721600 " "-sEXPORTED_FUNCTIONS=_main " "-sEXPORTED_RUNTIME_METHODS=getValue,setValue " "--shell-file \"${PROJECT_SOURCE_DIR}/etc/lovr.html\"") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Os") if(LOVR_ENABLE_THREAD) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pthread") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") endif() set(CMAKE_EXECUTABLE_SUFFIX ".html") set(LOVR_USE_WEBGPU ON) set(LOVR_USE_VULKAN OFF) endif() ``` -------------------------------- ### Configure Android Build for LOVR Project Source: https://github.com/bjornbytes/lovr/blob/dev/CMakeLists.txt Sets up compilation for the Android platform, reading the manifest, configuring Java package names, and setting SDK versions. It also links against necessary Android libraries and specifies include directories for native activities. ```cmake elseif(ANDROID) set(ANDROID_MANIFEST "${PROJECT_SOURCE_DIR}/etc/AndroidManifest.xml" CACHE STRING "The AndroidManifest.xml file to use") file(READ ${ANDROID_MANIFEST} ANDROID_MANIFEST_CONTENT) string(REGEX MATCH "package=\\"([^\"]*)\"" _ ${ANDROID_MANIFEST_CONTENT}) set(ANDROID_PACKAGE ${CMAKE_MATCH_1}) string(REPLACE "." "_" ANDROID_PACKAGE_C ${ANDROID_PACKAGE}) string(REPLACE "." "/" ANDROID_PACKAGE_JAVA ${ANDROID_PACKAGE}) configure_file(${PROJECT_SOURCE_DIR}/etc/Activity.java ${PROJECT_BINARY_DIR}/Activity.java) target_compile_definitions(lovr PRIVATE "LOVR_JAVA_PACKAGE=${ANDROID_PACKAGE_C}") set(ANDROID_MIN_SDK_VERSION ${ANDROID_NATIVE_API_LEVEL}) set(ANDROID_TARGET_SDK_VERSION ${ANDROID_MIN_SDK_VERSION} CACHE STRING "The targetSdkVersion to use") target_sources(lovr PRIVATE src/core/os_android.c) target_link_libraries(lovr log android dl) target_include_directories(lovr PRIVATE "${ANDROID_NDK}/sources/android/native_app_glue") # Dynamically linked targets output libraries in raw/lib/ for easy including in apk with aapt set_target_properties( lovr ${LOVR_JOLT} ${LOVR_MSDF} ${LOVR_LUA} ${LOVR_GLSLANG} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/raw/lib/${ANDROID_ABI}" ) endif() ``` -------------------------------- ### Strip Libraries on Release Build Source: https://github.com/bjornbytes/lovr/blob/dev/CMakeLists.txt This CMake snippet defines a custom target 'strip' that runs after the main build in release configurations. It uses the 'strip' command to remove debugging symbols from shared object (.so) files in the 'raw/lib/${ANDROID_ABI}' directory, reducing the size of the final APK. Dependencies ensure this runs after the main build and before APK packaging. ```cmake add_custom_target( strip ALL WORKING_DIRECTORY ${PROJECT_BINARY_DIR} COMMAND ${CMAKE_STRIP} raw/lib/${ANDROID_ABI}/*.so ) add_dependencies(strip lovr) add_dependencies(buildAPK strip) ``` -------------------------------- ### Configure LuaJIT for LOVR (CMake) Source: https://github.com/bjornbytes/lovr/blob/dev/CMakeLists.txt Configures the LuaJIT interpreter for the LOVR project. It supports using system-installed LuaJIT or building it from source, setting include paths, library directories, and linking libraries accordingly. Includes specific configurations for MSVC. ```cmake elseif(LOVR_USE_LUAJIT AND NOT EMSCRIPTEN) if(LOVR_SYSTEM_LUA) pkg_search_module(LUAJIT REQUIRED luajit) list(APPEND LOVR_LIB_DIRS ${LUAJIT_LIBRARY_DIRS}) set(LOVR_LUA_INCLUDE ${LUAJIT_INCLUDE_DIRS}) set(LOVR_LUA_LIB_DIR ${LUAJIT_LIBRARY_DIRS}) set(LOVR_LUA ${LUAJIT_LIBRARIES}) else() set(BUILD_SHARED_LIBS ON) add_subdirectory(deps/luajit luajit) set_target_properties(luajit PROPERTIES EXCLUDE_FROM_ALL 1) if(MSVC) target_compile_definitions(libluajit PRIVATE _CRT_SECURE_NO_WARNINGS) target_compile_definitions(minilua PRIVATE _CRT_SECURE_NO_WARNINGS) target_compile_definitions(buildvm PRIVATE _CRT_SECURE_NO_WARNINGS) endif() set(LOVR_LUA_INCLUDE deps/luajit/src ${CMAKE_BINARY_DIR}/luajit) set(LOVR_LUA libluajit) endif() else() ``` -------------------------------- ### Load 3D Models with lovr.data.newModelData Source: https://context7.com/bjornbytes/lovr/llms.txt Load 3D models from various formats (e.g., glTF) including animations, materials, and skeletal hierarchies. Inspect model properties, extract animation and mesh data, and create GPU-renderable models. Supports animating models over time. ```lua -- Load glTF model with all features local modelData = lovr.data.newModelData('assets/character.gltf') -- Inspect model structure print('Node count:', modelData:getNodeCount()) print('Animation count:', modelData:getAnimationCount()) print('Material count:', modelData:getMaterialCount()) print('Texture count:', modelData:getTextureCount()) -- Get animation info for i = 1, modelData:getAnimationCount() do local name = modelData:getAnimationName(i) local duration = modelData:getAnimationDuration(i) print('Animation:', name, 'Duration:', duration) end -- Extract mesh data local primitiveCount = modelData:getMeshCount() for i = 1, primitiveCount do local vertices = modelData:getMeshVertexCount(i) local indices = modelData:getMeshIndexCount(i) print('Mesh', i, ':', vertices, 'vertices,', indices, 'indices') end -- Create GPU model for rendering function lovr.load() model = lovr.graphics.newModel(modelData) animator = lovr.graphics.newBuffer({ { 'pose', 'mat4' } }, modelData:getNodeCount()) end function lovr.update(dt) -- Animate model animationTime = (animationTime or 0) + dt model:animate(1, animationTime) -- Play animation 1 end function lovr.draw(pass) pass:draw(model, 0, 0, -3, 1, lovr.timer.getTime(), 0, 1, 0) end ``` -------------------------------- ### Configure Emscripten Build for LOVR Project Source: https://github.com/bjornbytes/lovr/blob/dev/CMakeLists.txt Sets up compilation for the Emscripten platform, enabling exports and configuring a favicon. This configuration is used for building the project to run in a web browser. ```cmake elseif(EMSCRIPTEN) target_sources(lovr PRIVATE src/core/os_wasm.c) set_target_properties(lovr PROPERTIES ENABLE_EXPORTS ON) configure_file(etc/lovr.ico favicon.ico COPYONLY) endif() ``` -------------------------------- ### Configure LÖVR Library Build Source: https://github.com/bjornbytes/lovr/blob/dev/CMakeLists.txt Sets up the source files for the LÖVR library. It conditionally appends the main C file if an executable is being built. This is a core part of the build process, defining what goes into the final library or executable. ```cmake set(LOVR_SRC src/core/fs.c src/api/api.c src/api/l_lovr.c src/util.c ) if(LOVR_BUILD_EXE) list(APPEND LOVR_SRC src/main.c) endif() if(LOVR_BUILD_SHARED) add_library(lovr SHARED ${LOVR_SRC}) elseif(LOVR_BUILD_EXE) add_executable(lovr ${LOVR_SRC}) else() return() endif() ``` -------------------------------- ### lovr.graphics Pass System - Rendering Commands Source: https://context7.com/bjornbytes/lovr/llms.txt The Pass system is LÖVR's command-based rendering API, where all drawing operations are recorded and submitted together. It allows setting rendering states and drawing various primitives, text, models, and executing compute shaders. ```APIDOC ## lovr.graphics Pass System ### Description The Pass system is LÖVR's command-based rendering API, where all drawing operations are recorded and submitted together. ### Method `lovr.draw(pass)` ### Parameters #### Path Parameters - `pass` (Pass) - Required - The rendering pass object provided by LÖVR. ### Request Example (This is typically part of the `lovr.draw` callback) ```lua function lovr.draw(pass) -- Set rendering state pass:setColor(1, 0.5, 0.5) pass:setCullMode('back') pass:setDepthTest('less') pass:setWireframe(false) -- Draw 3D primitives with transformations pass:cube(0, 1.7, -3, 0.5, lovr.timer.getTime()) pass:sphere(vec3(2, 1.7, -2), 0.3) pass:plane(0, 0, -5, 10, 10, math.pi/2, 1, 0, 0) -- Draw text in 3D space pass:text('Hello VR!', 0, 2, -2, 0.2, math.pi/4, 0, 1, 0) -- Draw models with materials if model then pass:draw(model, x, y, z, scale, angle, ax, ay, az) end -- Draw with custom shaders and buffers pass:setShader(customShader) pass:send('time', lovr.timer.getTime()) pass:mesh(vertices, indices) -- Compute shader dispatch pass:compute(computeShader, 64, 1, 1) end ``` ### Response (Rendering commands modify the GPU state and render output, no direct response object) ### Key Pass Methods - `setColor(r, g, b, a)` - `setCullMode(mode)` - `setDepthTest(test)` - `setWireframe(enable)` - `cube(...)` - `sphere(...)` - `plane(...)` - `text(...)` - `draw(model, ...)` - `setShader(shader)` - `send(name, value)` - `mesh(vertices, indices)` - `compute(shader, x, y, z)` ``` -------------------------------- ### Unix-like System Configuration Source: https://github.com/bjornbytes/lovr/blob/dev/CMakeLists.txt Sets up build configurations for Unix-like systems. It disables the automatic skipping of RPATH on non-macOS systems to ensure proper library linking and finds PkgConfig for managing system dependencies. ```cmake elseif(UNIX) find_package(PkgConfig) if(NOT APPLE) set(CMAKE_SKIP_RPATH OFF) endif() endif() ```