they take the same arguments so we can't overload
the function parameterically.
also I find it pretty confusing that lovr uses
overloads so much in the api,
so I really don't mind having
a separate constructor :S
By looking for failed start and requesting then;
and then emitting a new event type when
permission has been granted or rejected;
and then using that event in the default
boot.lua to re-start capture.
- The lovr.headset.renderTo callback can now be nil, causing an empty frame to be submitted to the compositor.
- lovr.mirror will still be called if lovr.draw is nil. This means the window will be (correctly?) cleared to the background color now if lovr.draw is nil.
This prevents runtimes from thinking the app is missing/unresponsive when lovr.draw is absent. To get the old behavior, just don't call lovr.headset.renderTo.
lookAt() returns view matrix that can be used to transform the camera
perspective. target() returns model matrix that is used to change
model transform. Results are matrix inversions of one another. Now both
functions exist it is possible to use right one and avoid extra matrix
inversion.
- Link against dl (this was probably why ffi.load didn't work)
- Store shared libraries in the apk uncompressed
- Libraries are added during the "package" aapt call instead of "add".
- Because -0 (used to store uncompressed) only works during package.
- classes.dex is added here too now.
- There's only one aapt invocation now, which is kinda nice.
- The lib folder needs to be in a subfolder now ("raw" was chosen).
- Because "package" and "add" subcommands work differently.
- Store shared libraries in the apk page aligned
- Required passing -p to the zipalign invocation.
- This is needed because dlopen("zip!path") needs it.
- android:extractNativeLibs="false" is added to the XML manifest.
- apk sizes are bigger, but disk usage and install time should improve.
- Fix a bug with moving plugin libraries into the lib folder with CMake.
- Use lovrFilesystemGetSource instead of lovrFilesystemGetExecutablePath
to get the proper path to the apk.
- The plugins folder can contain native plugins.
- CMake will build plugins with CMakeLists in them
- They can check the LOVR variable to see if they are being built inside LOVR.
- They can set the LOVR_PLUGIN_TARGETS variable to a list of targets they build.
- If blank, all non-imported targets added in the folder will be used.
- The libraries built by their targets will be moved next to the executable or into the apk.
- The library loader now tries to load libraries next to the executable or in the APK.
- It is "fixed function" now, this may be improved in the future.
- The lovr.filesystem C require path has been removed.
- enet and cjson have been removed. Use plugins.
In boot.lua, it assumes that lovr.headset.init will assert if no driver
is available. This was previously only true on the first call to it,
since after it's initialized, it'll just return early and won't assert.
This will later crash since your lua code will now see a lovr.headset
being available, but calling anything in it will crash since
lovrHeadsetDisplayDriver is NULL
After this fix, initialized becomes false before boot sets up the
headset module again, so that the assertion fires correctly.
Zero as default makes more sense. Colliders can come to full stop which
allows them to go to sleep for CPU optimization. Also in zero gravity
colliders crawling through air with 0.01 velocity are infuriating.
It seems to me like that lovrRelease will delete textureData->blob immediately,
which means the windowing system later can't use it because it's already freed.
There's already a free on line 378 which looks more correct.
Also, icon appears flipped if 'flipped' is set to true here on Linux. Is GLFW
inconsistent between linux and windows, or should it indeed be false?
OpenXR basically has a hard requirement that a graphics API is available
before its session can be created. Currently the graphics module isn't
always around when headset initialization takes place. Polling the
graphics availability in update/renderTo has some consequences for calls
made to the headset module in lovr.load or during the first few frames.
So instead we're going to delay headset initialization to a special
function that is called after modules are required. It can also be
called manually if the window creation is delayed.
- Make the renderloop synchronous by hijacking the RAF to run on the
XRSession when active.
- Convert os_web to use emscripten's native HTML5 interface instead
of going through GLFW.
- Stop using preinitialized GL context -- lovrPlatformCreateWindow
now creates the context.
- GLES2/3 emulation is not necessary.
- Remove inline sessions. The VR simulator is used to render to the
Canvas instead. webxr_attach and webxr_detach are used to replace
replace the active headset driver with the webxr driver when an
immersive session starts.
- Add noop desktop_getSkeleton.
- lovr.headset.newModel accepts an optional options table as the
second argument. There is currently a single option named
'animated' that can be used to request an animatable model.
Currently it isn't clear if this should be a hint or not.
- lovr.headset.animate (name pending) can be called with a device
and a model (usually with an animated model from headset.newModel,
but this is not required). The function attempts to animate the
Model to match the pose of the device in an opaque driver-specific
way, and returns whether or not this was successful.
- OpenVR has models for controllers with a system called "components"
that can be used to animate the individual buttons. Now the OpenVR
headset driver implements the 'animate' function to make use of the
controller components, to easily load and render animated controllers.
Add entrypoints, headset backend code, fill in the Activity, and
add various special cases to account for the asynchronous render loop,
lack of sRGB support, and OpenGL state resets.
lovr.log is a new callback that is invoked whenever LÖVR wants to
send the project a message. For example, this could be a performance
warning from the graphics module, an error message from one of the
headset backends, or an API deprecation notice.
The callback's signature is (message, level, tag). The message is a
string containing the message to log, level is a string that is currently
one of "debug", "info", "warn", "error", and tag is an optional string
that is used to indicate the source of the message for grouping purposes.
The default implementation of the callback just prints the message,
but the callback can be overridden to do things like filter messages,
write them to a file, or even render them in VR. Projects can also
invoke the callback directly to log their own messages.
Tightness parameter is amount of force is exerted on collider to resolve
collisions and enforce joint operation. Low values make joints loose,
high values make it tight and can cause collider to overshot the joint
target. With tightness set to 0 the joint loses its function. Going
above 1 puts even more energy into joint oscillations. Tightness
parameter is called ERP in ODE manual.
The responseTime affects the time constant of physics simulation, both
for collisions and for joint inertia. Low responseTime values make
simulation tight and fast, higher values make it sluggish. For
collisions it affects how fast penetration is resolved, with higher
values resulting in spongy objects with more surface penetration and
slower collision resolving. For joints the responseTime is similar to
inertia, with higher responseTime values resulting in slow oscillations.
The oscillation frequency is also affected by collider mass, so
responseTime can be used to tweak the joint to get desired frequency
with specific collider mass. Values higher than 1 are often desirable,
especially for very light objects. Unlike tightness, responseTime is
tweaked in orders of magnitude with useful values (depending on mass)
being between 10^-8 and 10^8.
Both parameters can be applied to World for simulation-wide usage, or
specified per-joint in case of distance and ball joints. Other joints
don't allow customizing these parameters, and will use World settings
instead..
When creating shapes and joints, arguments accept either coordinate
numbers as before, or vec3 objects. For functions that receive more than
one set of coordinates, any combination of coordinates and vectors is
accepted.
There are 4 new devices: beacon/1 through beacon/4. They represent
tracking reference like StemaVR base stations or Oculus cameras.
There are 4 because that's how many base stations you can have in
a single tracking setup.
Right now only OpenVR exposes poses for them.
When creating colliders, setting gravity or casting rays on world,
arguments accept either coordinate numbers as before, or vec3 objects.
For functions that receive more than one set of coordinates, any
combination of coordinates and vectors is accepted.
Based on Slack conversation, the following changes:
- lovr.event.quit("restart") no longer supported
- lovr.event.quit no longer takes restart "cookie"
- When lovr.event.restart() called, lovr.quit() is not called, instead lovr.restart() is called
- Value returned from lovr.restart(), when called, becomes the cookie
- lovr.event.quit takes the lovr.event.quit() return code as an argument
lovr.run() is unchanged, it still returns (exit code | "restart", cookie).
- There is now just one "playing" state.
- Instead of rewind, use :seek(0).
Note that now there is no way to resume or rewind all tracked sources.
This can be improved in the future if there's a need for it, probably
using variadic or table-based variants of the audio module functions.
Lua was happily compiling nil chunks and making them return empty
strings, which was not a good error experience in situations where
your file couldn't be loaded properly. Now we return nil plus an
error message, which matches LOVE and other Lua conventions.