Although the name is unfortunate, this allows access to lovr.headset
when no window is opened or when the graphics module is disabled. This
requires the XR_MND_headless extension to be supported by the runtime.
Some Android header defines DEPTH, which clashes with a symbol in the
OpenXR driver. This change just stops using Android headers in there
and declares more granular private functions. It also removes a few
unused private os functions.
The "system" button on Valve Index controller may not be exposed to
applications through OpenXR. Oculus runtime throws error when binding
for that button is attempted.
The animation compute shader was not specializing the workgroup size
properly, so it was only working on GPUs with a subgroup size of 32.
The Quest 1 has a subgroup size of 32 and the Quest 2 has a subgroup
size of 64, so this resulted in hand models breaking on Quest 2 only!
Sigh, back to getPass. I don't even know at this point. Basically now
that we came up with a half-solution for temp buffers, it makes sense to
apply this to passes as well, since we aren't going with the workstream
idea and temp passes are more convenient than retained passes.
It uses newPass instead of getPass. Temporary objects had lifetime
issues that were nearly impossible to solve. And normal objects are
easier to understand because they behave like all other LÖVR objects.
However, Pass commands are not retained from frame to frame. Pass
objects must be re-recorded before every submit, and must be reset
before being recorded again.
Pass objects now provide a natural place for render-pass-related info
like clears and texture handles. They also allow more information to be
precomputed which should reduce overhead a bit.
It is now possible to request a stencil buffer and antialiasing on the
window and headset textures, via conf.lua.
lovr.graphics.setBackground should instead set the clear color on the
window pass. Though we're still going to try to do spherical harmonics
in some capacity.
There are still major issues with OpenXR that are going to be ironed
out, and the desktop driver hasn't been converted over to the new
headset Pass system yet. So lovr.headset integration is a bit WIP.
OpenXR provides APIs to enumerate the supported refresh-rates, and
selecting a new refresh-rate. This patch adds two new APIs to the
lovr.headset module:
- lovr.headset.getDisplayFrequencies():
Returns a table containing the supported refresh-rates on
success; nil otherwise.
- lovr.headset.setDisplayFrequency(refreshRate:number):
Returns true on success, false otherwise.
Only the OpenXR backend has support for this feature and it is
gated by the "refreshRate" feature flag, similarly to what the
"getDisplayFrequency()" API does.
Notes:
- We can actually use a single Activity.java file for oculus/pico now
- We can unconditionally compile os_android.c on Android
- No need for including extra jars in build system
- Headset rendering is guaranteed synchronous now, no need to ref L
- Add an "android flavor" build setting to differentiate between oculus
and pico devices, since they both use OpenXR.
- Update the pico manifest to reflect their OpenXR sample
- Remove some OpenGL hacks that aren't necessary anymore
This adds the ability to load and animate a mesh for hand tracking on
the Oculus Quest. It is more or less identical to the current
functionality on the vrapi driver.
One key part of this change is that getPose in OpenXR will see if action
spaces are active before locating their spaces. This is due to some
behavior observed on the Oculus Quest with hand tracking where pose
actions for controllers would return invalid data with all of the
location flags erroneously set. The only way to detect and work around
this is to check the pose action state. When this happens, we fall back
to returning the pose of the wrist joint, which is where the Oculus hand
mesh wants to be drawn. In the event that both controllers and hand
tracking are active, the controller pose will be returned by getPose but
the wrist joint can still be accessed using getSkeleton.
Note that this does not yet include support for properly scaling the
hand mesh.
There are numerous opportunities for optimization here that may be
investigated in the future, though performance is well within an
acceptable range right now.
Currently there is a single allocator function used in arr_t. Its
behavior depends on the values for the pointer and size arguments:
- If pointer is NULL, it should allocate new memory.
- If pointer is non-NULL and size is positive, it should resize memory.
- If size is zero, it should free memory.
All instances of arr_t use realloc for this right now. The problem
is that realloc's behavior is undefined when the size argument is zero.
On Windows and Linux, realloc will free the pointer, but on macOS this
isn't the case. This means that arr_t leaks memory on macOS.
It's best to not rely on undefined behavior like this, so let's instead
use a helper function that behaves the way we want.
The VrApi implementation now checks that X, Y, A, B buttons exist on that
specific controller. X,Y are on left; A,B on the right controller. That
mapping covers Quest Touch and Quest 2 controllers.