Compare commits

..

No commits in common. "master" and "v1.5.3" have entirely different histories.

35 changed files with 1503 additions and 10140 deletions

17
.gitignore vendored
View file

@ -15,6 +15,8 @@ $RECYCLE.BIN/
*.o
*.d
#binaries
*.so
#libs
*.a
@ -30,24 +32,9 @@ Projects/Android/.cxx/*
Projects/Android/.externalNativeBuild/*
*.bin
Projects/Android/.gradle/*
.gradle/*
*.ser
Projects/Android/.idea/codeStyles/Project.xml
*.xml
Projects/Android/.gradle/*
drbeef-release-key.keystore
Projects/Android/.idea/.name
Projects/Android/jni/SupportLibs/liboggvorbis/libs/armeabi-v7a/libogg.so
Projects/Android/jni/SupportLibs/liboggvorbis/libs/armeabi-v7a/libvorbis-jni.so
Projects/Android/jni/SupportLibs/liboggvorbis/libs/armeabi-v7a/libvorbis.so
Projects/Android/jni/SupportLibs/liboggvorbis/libs/armeabi/libogg.so
Projects/Android/jni/SupportLibs/liboggvorbis/libs/armeabi/libvorbis-jni.so
Projects/Android/jni/SupportLibs/liboggvorbis/libs/armeabi/libvorbis.so
Projects/Android/jni/SupportLibs/liboggvorbis/libs/mips/libogg.so
Projects/Android/jni/SupportLibs/liboggvorbis/libs/mips/libvorbis-jni.so
Projects/Android/jni/SupportLibs/liboggvorbis/libs/mips/libvorbis.so
Projects/Android/jni/SupportLibs/liboggvorbis/libs/x86/libogg.so
Projects/Android/jni/SupportLibs/liboggvorbis/libs/x86/libvorbis-jni.so
Projects/Android/jni/SupportLibs/liboggvorbis/libs/x86/libvorbis.so
Projects/Android/libs/arm64-v8a/libopenxr_loader_meta.so
Projects/Android/libs/arm64-v8a/libopenxr_loader_pico.so

View file

@ -0,0 +1,122 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":XrSamples:QuakeQuest:Projects:Android" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="QuakeQuest.XrSamples.QuakeQuest.Projects" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle">
<configuration>
<option name="GRADLE_PROJECT_PATH" value=":XrSamples:QuakeQuest:Projects:Android" />
<option name="LAST_SUCCESSFUL_SYNC_AGP_VERSION" value="4.0.2" />
<option name="LAST_KNOWN_AGP_VERSION" value="4.0.2" />
</configuration>
</facet>
<facet type="native-android-gradle" name="Native-Android-Gradle">
<configuration>
<option name="SELECTED_BUILD_VARIANT" value="debug-arm64-v8a" />
</configuration>
</facet>
<facet type="android" name="Android">
<configuration>
<option name="SELECTED_BUILD_VARIANT" value="debug" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
<afterSyncTasks>
<task>generateDebugSources</task>
</afterSyncTasks>
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/../../res" />
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/../../res;file://$MODULE_DIR$/src/debug/res;file://$MODULE_DIR$/build/generated/res/rs/debug" />
<option name="TEST_RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/androidTest/res;file://$MODULE_DIR$/src/test/res;file://$MODULE_DIR$/src/androidTestDebug/res;file://$MODULE_DIR$/src/testDebug/res;file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/../../assets" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/build/intermediates/javac/debug/classes" />
<output-test url="file://$MODULE_DIR$/build/intermediates/javac/debugUnitTest/classes" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/jni/SupportLibs/liboggvorbis/libogg" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/jni/SupportLibs/liboggvorbis/libvorbis" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/jni/SupportLibs/liboggvorbis/libvorbis-jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/jni/QuakeQuestSrc" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/jni/darkplaces" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/ap_generated_sources/debug/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debug/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/renderscript_source_output_dir/debug/out" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/ap_generated_sources/debugAndroidTest/out" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/aidl_source_output_dir/debugAndroidTest/out" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/renderscript_source_output_dir/debugAndroidTest/out" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/ap_generated_sources/debugUnitTest/out" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTestDebug/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/jni" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/shaders" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/jni" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/shaders" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/jni" isTestSource="false" />
<excludeFolder url="file://$MODULE_DIR$/.cxx" />
<excludeFolder url="file://$MODULE_DIR$/.externalNativeBuild" />
<excludeFolder url="file://$MODULE_DIR$/build" />
</content>
<content url="file://$MODULE_DIR$/../../assets">
<sourceFolder url="file://$MODULE_DIR$/../../assets" type="java-resource" />
</content>
<content url="file://$MODULE_DIR$/../../java">
<sourceFolder url="file://$MODULE_DIR$/../../java" isTestSource="false" />
</content>
<content url="file://$MODULE_DIR$/../../res">
<sourceFolder url="file://$MODULE_DIR$/../../res" type="java-resource" />
</content>
<orderEntry type="jdk" jdkName="Android API 26 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" name="Gradle: com.android.support:support-annotations:26.1.0@jar" level="project" />
<orderEntry type="library" name="Gradle: android.arch.lifecycle:common:1.0.0@jar" level="project" />
<orderEntry type="library" name="Gradle: android.arch.core:common:1.0.0@jar" level="project" />
<orderEntry type="library" name="Gradle: com.android.support:support-core-utils:26.1.0@aar" level="project" />
<orderEntry type="library" name="Gradle: com.android.support:support-compat:26.1.0@aar" level="project" />
<orderEntry type="library" name="Gradle: android.arch.lifecycle:runtime:1.0.0@aar" level="project" />
<orderEntry type="library" name="Gradle: android-android-26" level="project" />
</component>
</module>

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.drbeef.quakequest"
android:versionCode="26"
android:versionName="1.5.7"
android:versionCode="22"
android:versionName="1.5.3"
android:installLocation="auto" >
<!-- Tell the system this app requires OpenGL ES 3.1. -->
@ -14,7 +14,7 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="false"
@ -25,14 +25,12 @@
<!-- META QUEST -->
<meta-data android:name="com.samsung.android.vr.application.mode" android:value="vr_only"/>
<meta-data android:name="com.oculus.supportedDevices" android:value="quest|quest2"/>
<meta-data android:name="com.oculus.vr.focusaware" android:value="true" />
<!-- PICO XR -->
<meta-data android:name="pvr.app.type" android:value="vr" />
<activity
android:exported="true"
android:name="com.drbeef.quakequest.GLES3JNIActivity"
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
android:label="@string/quakequest"
@ -40,10 +38,8 @@
android:screenOrientation="landscape"
android:excludeFromRecents="true"
android:configChanges="screenSize|screenLayout|orientation|keyboardHidden|keyboard|navigation|uiMode">
<!-- Tell NativeActivity the name of the .so -->
<meta-data android:name="android.app.lib_name" android:value="quakequest" />
<!-- This filter lets the apk show up as a launchable icon. -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />

View file

@ -0,0 +1,29 @@
@rem Only edit the master copy of this file in SDK_ROOT/bin/scripts/build/perproject
@setlocal enableextensions enabledelayedexpansion
@if not exist "build.gradle" @echo Build script must be executed from project directory. & goto :Abort
@set P=..
:TryAgain
@rem @echo P = %P%
@if exist "%P%\bin\scripts\build\build.py.bat" goto :Found
@if exist "%P%\bin\scripts\build" @echo "Could not find build.py.bat" & goto :Abort
@set P=%P%\..
@goto :TryAgain
:Found
@set P=%P%\bin\scripts\build
@call %P%\build.py.bat %1 %2 %3 %4 %5
@goto :End
:Abort
:End

View file

@ -1,20 +1,7 @@
buildscript {
repositories {
google() // For Gradle 4.0+
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.2.1'
}
}
apply plugin: 'com.android.application'
apply from: "${rootProject.projectDir}/VrApp.gradle"
android {
namespace = "com.drbeef.quakequest"
// This is the name of the generated apk file, which will have
// -debug.apk or -release.apk appended to it.
// The filename doesn't effect the Android installation process.
@ -28,84 +15,19 @@ android {
applicationId "com.drbeef." + project.archivesBaseName
// override app plugin abiFilters for both 32 and 64-bit support
externalNativeBuild {
ndk {
abiFilters 'arm64-v8a'
}
ndkBuild {
def numProcs = Runtime.runtime.availableProcessors()
arguments "V=0", "-j$numProcs", "-C$project.buildDir.parent", "APP_PLATFORM=android-29", "NDK_TOOLCHAIN_VERSION=clang", "APP_STL=c++_static"
abiFilters 'arm64-v8a'
}
}
externalNativeBuild {
ndk {
abiFilters 'arm64-v8a'
}
ndkBuild {
abiFilters 'arm64-v8a'
}
}
minSdkVersion 32
targetSdkVersion 32
minSdkVersion 26
targetSdkVersion 26
}
externalNativeBuild {
ndkBuild {
path file('jni/Android.mk')
}
}
signingConfigs {
def keystorePath = (project.hasProperty('key.store')) ?
new File(project.getProperty('key.store')) :
project.file('android.debug.keystore')
def keystorePassword = (project.hasProperty('key.store.password')) ?
project.getProperty('key.store.password') : 'android'
def keystoreKeyAlias = (project.hasProperty('key.alias')) ?
project.getProperty('key.alias') : 'androiddebugkey'
def keystoreKeyPassword = (project.hasProperty('key.alias.password')) ?
project.getProperty('key.alias.password') : 'android'
debug {
storeFile keystorePath
storePassword keystorePassword
keyAlias keystoreKeyAlias
keyPassword keystoreKeyPassword
v2SigningEnabled true
}
release {
storeFile keystorePath
storePassword keystorePassword
keyAlias keystoreKeyAlias
keyPassword keystoreKeyPassword
v2SigningEnabled true
}
}
buildTypes {
debug {
signingConfig signingConfigs.debug
debuggable true
jniDebuggable true
externalNativeBuild {
ndkBuild {
arguments "NDK_DEBUG=1","USE_ASAN=1"
}
}
}
release {
signingConfig signingConfigs.release
debuggable false
jniDebuggable false
externalNativeBuild {
ndkBuild {
arguments "NDK_DEBUG=0","USE_ASAN=0"
}
}
}
}
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
@ -119,41 +41,21 @@ android {
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
}
lintOptions {
checkReleaseBuilds false
disable 'ExpiredTargetSdkVersion'
}
packagingOptions {
exclude 'lib/arm64-v8a/libopenxr_loader.so'
}
compileSdkVersion = 32
buildToolsVersion = '29.0.3'
ndkVersion '25.1.8937393'
compileSdkVersion = 26
buildToolsVersion = '29.0.1'
}
dependencies {
implementation "com.android.support:support-compat:28.0.0"
implementation "com.android.support:support-core-utils:28.0.0"
implementation "com.android.support:support-compat:26.1.0"
implementation "com.android.support:support-core-utils:26.1.0"
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
}
repositories {
google()
}
buildscript {
repositories {
google()
}
}
// Workaround to fix issue in Android Studio Chipmunk 2021.2.1 and later
// where opening a project would result in a 'prepareKotlinBuildScriptModel'
// not found error
if (!tasks.findByName("prepareKotlinBuildScriptModel")) {
tasks.register("prepareKotlinBuildScriptModel") {}
}

29
Projects/Android/build.py Normal file
View file

@ -0,0 +1,29 @@
#!/usr/bin/python
# This first bit of code is common bootstrapping code
# to determine the SDK root, and to set up the import
# path for additional python code.
#begin bootstrap
import os
import sys
def init():
root = os.path.realpath( os.path.dirname(os.path.realpath(__file__) ) )
os.chdir(root) # make sure we are always executing from the project directory
while( os.path.isdir( os.path.join(root, 'bin/scripts/build') ) == False ):
root = os.path.realpath( os.path.join(root, '..') )
if( len(root) <= 5 ): # Should catch both Posix and Windows root directories (e.g. '/' and 'C:\')
print('Unable to find SDK root. Exiting.')
sys.exit(1)
root = os.path.abspath(root)
os.environ['OCULUS_SDK_PATH'] = root
sys.path.append( root + "/bin/scripts/build" )
init()
import ovrbuild
ovrbuild.init()
#end bootstrap
ovrbuild.build()

View file

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-all.zip

172
Projects/Android/gradlew vendored Normal file
View file

@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

84
Projects/Android/gradlew.bat vendored Normal file
View file

@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View file

@ -6,14 +6,20 @@ LOCAL_PATH:= $(call my-dir)
#--------------------------------------------------------
include $(CLEAR_VARS)
# Uncomment for the correct headset - slight changes required in OpenXR implementation
#OPENXR_HMD = -DMETA_QUEST
OPENXR_HMD = -DPICO_XR
LOCAL_CFLAGS := $(OPENXR_HMD)
LOCAL_MODULE := quakequest
LOCAL_LDLIBS := -llog -landroid -lGLESv3 -lEGL -lOpenSLES # include default libraries
LOCAL_C_INCLUDES := ../QuakeQuestSrc/ \
../darkplaces/ \
$(SUPPORT_LIBS)/liboggvorbis/include \
${TOP_DIR}/OpenXR-SDK/include \
${TOP_DIR}/OpenXR-SDK/src/common
$(TOP_DIR)/../../../../../3rdParty/khronos/openxr/OpenXR-SDK/include \
$(TOP_DIR)/../../../../../3rdParty/khronos/openxr/OpenXR-SDK/src/common \
$(TOP_DIR)/../../../../../OpenXR/Include
LOCAL_SHARED_LIBRARIES := openxr_loader libvorbis libogg libvorbis-jni
@ -123,7 +129,8 @@ SRC_COMMON := \
SRC_QUEST := \
QuakeQuestSrc/argtable3.c \
QuakeQuestSrc/QuakeQuest_OpenXR.c \
QuakeQuestSrc/OpenXrInput.c \
QuakeQuestSrc/OpenXrInput_MetaQuest.c \
QuakeQuestSrc/OpenXrInput_PicoXR.c \
QuakeQuestSrc/TBXR_Common.c \
LOCAL_SRC_FILES := \
@ -138,4 +145,4 @@ LOCAL_SRC_FILES := \
include $(BUILD_SHARED_LIBRARY)
include $(SUPPORT_LIBS)/liboggvorbis/Android.mk
$(call import-module,AndroidPrebuilt/jni)
$(call import-module,OpenXR/Projects/AndroidPrebuilt/jni)

View file

@ -1,9 +1,14 @@
# MAKEFILE_LIST specifies the current used Makefiles, of which this is the last
# one. I use that to obtain the Application.mk dir then import the root
# Application.mk.
ROOT_DIR := $(dir $(lastword $(MAKEFILE_LIST)))../../../../..
NDK_MODULE_PATH := $(ROOT_DIR)
APP_PLATFORM := android-24
APP_CFLAGS += -Wl,--no-undefined
APPLICATIONMK_PATH = $(call my-dir)
NDK_MODULE_PATH := $(APPLICATIONMK_PATH)/../..
TOP_DIR := $(APPLICATIONMK_PATH)
SUPPORT_LIBS := $(APPLICATIONMK_PATH)/SupportLibs

View file

@ -1,20 +0,0 @@
# Copyright (c) 2017 The Khronos Group Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Author:
#
add_subdirectory(openxr)

View file

@ -1,101 +0,0 @@
# Copyright (c) 2017-2022, The Khronos Group Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Author:
#
# Copy the openxr_platform_defines.h file and place it in the binary (build) directory.
configure_file(openxr_platform_defines.h ${CMAKE_CURRENT_BINARY_DIR}/openxr_platform_defines.h COPYONLY)
# Generate OpenXR header files.
set(HEADERS
openxr.h
openxr_platform.h
openxr_reflection.h)
set(HAVE_PREGENERATED TRUE)
set(SOURCE_HEADERS)
foreach(output ${HEADERS})
list(APPEND SOURCE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/${output})
if(NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${output})
set(HAVE_PREGENERATED FALSE)
endif()
endforeach()
set(XR_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../..)
if(HAVE_PREGENERATED AND NOT BUILD_FORCE_GENERATION)
add_custom_target(generate_openxr_header
COMMENT "Using found pre-generated OpenXR headers.")
set(INSTALL_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/openxr_platform_defines.h
${SOURCE_HEADERS})
else()
set(GENERATED_HEADERS)
set(OUTPUT_STAMPS)
# Copy the openxr_platform_defines.h file and place it in the binary (build) directory.
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/openxr_platform_defines.h
${CMAKE_CURRENT_BINARY_DIR}/openxr_platform_defines.h
COPYONLY)
# Generate the header files and place it in the binary (build) directory.
foreach(output ${HEADERS})
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${output}
COMMAND ${PYTHON_EXECUTABLE} ${XR_ROOT}/specification/scripts/genxr.py
-registry ${XR_ROOT}/specification/registry/xr.xml
-o ${CMAKE_CURRENT_BINARY_DIR} ${output}
DEPENDS
${XR_ROOT}/specification/scripts/genxr.py
${XR_ROOT}/specification/scripts/cgenerator.py
${XR_ROOT}/specification/scripts/creflectiongenerator.py
${XR_ROOT}/specification/scripts/generator.py
${XR_ROOT}/specification/scripts/reg.py
${XR_ROOT}/specification/registry/xr.xml
COMMENT "Generating ${CMAKE_CURRENT_BINARY_DIR}/${output}"
)
list(APPEND GENERATED_HEADERS "${CMAKE_CURRENT_BINARY_DIR}/${output}")
endforeach()
set_source_files_properties(
${GENERATED_HEADERS}
PROPERTIES GENERATED TRUE
)
set(INSTALL_HEADERS
${CMAKE_CURRENT_BINARY_DIR}/openxr_platform_defines.h
${GENERATED_HEADERS})
# Define generate_openxr_header target to generate the OpenXR header files.
# Other targets that need the OpenXR headers should use generate_openxr_header as a dependency.
add_custom_target(generate_openxr_header
SOURCES ${XR_ROOT}/specification/registry/xr.xml
DEPENDS
${GENERATED_HEADERS}
${OUTPUT_STAMPS}
)
endif()
set_target_properties(generate_openxr_header PROPERTIES FOLDER ${CODEGEN_FOLDER})
if(NOT CMAKE_INSTALL_INCDIR)
set(CMAKE_INSTALL_INCDIR include)
endif()
INSTALL(FILES ${INSTALL_HEADERS}
DESTINATION ${CMAKE_INSTALL_INCDIR}/openxr
COMPONENT Headers
)

File diff suppressed because it is too large Load diff

View file

@ -1,690 +0,0 @@
#ifndef OPENXR_PLATFORM_H_
#define OPENXR_PLATFORM_H_ 1
/*
** Copyright 2017-2022 The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0 OR MIT
*/
/*
** This header is generated from the Khronos OpenXR XML API Registry.
**
*/
#include "openxr.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef XR_USE_PLATFORM_ANDROID
#define XR_KHR_android_thread_settings 1
#define XR_KHR_android_thread_settings_SPEC_VERSION 5
#define XR_KHR_ANDROID_THREAD_SETTINGS_EXTENSION_NAME "XR_KHR_android_thread_settings"
typedef enum XrAndroidThreadTypeKHR {
XR_ANDROID_THREAD_TYPE_APPLICATION_MAIN_KHR = 1,
XR_ANDROID_THREAD_TYPE_APPLICATION_WORKER_KHR = 2,
XR_ANDROID_THREAD_TYPE_RENDERER_MAIN_KHR = 3,
XR_ANDROID_THREAD_TYPE_RENDERER_WORKER_KHR = 4,
XR_ANDROID_THREAD_TYPE_MAX_ENUM_KHR = 0x7FFFFFFF
} XrAndroidThreadTypeKHR;
typedef XrResult (XRAPI_PTR *PFN_xrSetAndroidApplicationThreadKHR)(XrSession session, XrAndroidThreadTypeKHR threadType, uint32_t threadId);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrSetAndroidApplicationThreadKHR(
XrSession session,
XrAndroidThreadTypeKHR threadType,
uint32_t threadId);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_PLATFORM_ANDROID */
#ifdef XR_USE_PLATFORM_ANDROID
#define XR_KHR_android_surface_swapchain 1
#define XR_KHR_android_surface_swapchain_SPEC_VERSION 4
#define XR_KHR_ANDROID_SURFACE_SWAPCHAIN_EXTENSION_NAME "XR_KHR_android_surface_swapchain"
typedef XrResult (XRAPI_PTR *PFN_xrCreateSwapchainAndroidSurfaceKHR)(XrSession session, const XrSwapchainCreateInfo* info, XrSwapchain* swapchain, jobject* surface);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrCreateSwapchainAndroidSurfaceKHR(
XrSession session,
const XrSwapchainCreateInfo* info,
XrSwapchain* swapchain,
jobject* surface);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_PLATFORM_ANDROID */
#ifdef XR_USE_PLATFORM_ANDROID
#define XR_KHR_android_create_instance 1
#define XR_KHR_android_create_instance_SPEC_VERSION 3
#define XR_KHR_ANDROID_CREATE_INSTANCE_EXTENSION_NAME "XR_KHR_android_create_instance"
// XrInstanceCreateInfoAndroidKHR extends XrInstanceCreateInfo
typedef struct XrInstanceCreateInfoAndroidKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
void* XR_MAY_ALIAS applicationVM;
void* XR_MAY_ALIAS applicationActivity;
} XrInstanceCreateInfoAndroidKHR;
#endif /* XR_USE_PLATFORM_ANDROID */
#ifdef XR_USE_GRAPHICS_API_VULKAN
#define XR_KHR_vulkan_swapchain_format_list 1
#define XR_KHR_vulkan_swapchain_format_list_SPEC_VERSION 4
#define XR_KHR_VULKAN_SWAPCHAIN_FORMAT_LIST_EXTENSION_NAME "XR_KHR_vulkan_swapchain_format_list"
typedef struct XrVulkanSwapchainFormatListCreateInfoKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
uint32_t viewFormatCount;
const VkFormat* viewFormats;
} XrVulkanSwapchainFormatListCreateInfoKHR;
#endif /* XR_USE_GRAPHICS_API_VULKAN */
#ifdef XR_USE_GRAPHICS_API_OPENGL
#define XR_KHR_opengl_enable 1
#define XR_KHR_opengl_enable_SPEC_VERSION 10
#define XR_KHR_OPENGL_ENABLE_EXTENSION_NAME "XR_KHR_opengl_enable"
#ifdef XR_USE_PLATFORM_WIN32
// XrGraphicsBindingOpenGLWin32KHR extends XrSessionCreateInfo
typedef struct XrGraphicsBindingOpenGLWin32KHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
HDC hDC;
HGLRC hGLRC;
} XrGraphicsBindingOpenGLWin32KHR;
#endif // XR_USE_PLATFORM_WIN32
#ifdef XR_USE_PLATFORM_XLIB
// XrGraphicsBindingOpenGLXlibKHR extends XrSessionCreateInfo
typedef struct XrGraphicsBindingOpenGLXlibKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
Display* xDisplay;
uint32_t visualid;
GLXFBConfig glxFBConfig;
GLXDrawable glxDrawable;
GLXContext glxContext;
} XrGraphicsBindingOpenGLXlibKHR;
#endif // XR_USE_PLATFORM_XLIB
#ifdef XR_USE_PLATFORM_XCB
// XrGraphicsBindingOpenGLXcbKHR extends XrSessionCreateInfo
typedef struct XrGraphicsBindingOpenGLXcbKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
xcb_connection_t* connection;
uint32_t screenNumber;
xcb_glx_fbconfig_t fbconfigid;
xcb_visualid_t visualid;
xcb_glx_drawable_t glxDrawable;
xcb_glx_context_t glxContext;
} XrGraphicsBindingOpenGLXcbKHR;
#endif // XR_USE_PLATFORM_XCB
#ifdef XR_USE_PLATFORM_WAYLAND
// XrGraphicsBindingOpenGLWaylandKHR extends XrSessionCreateInfo
typedef struct XrGraphicsBindingOpenGLWaylandKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
struct wl_display* display;
} XrGraphicsBindingOpenGLWaylandKHR;
#endif // XR_USE_PLATFORM_WAYLAND
typedef struct XrSwapchainImageOpenGLKHR {
XrStructureType type;
void* XR_MAY_ALIAS next;
uint32_t image;
} XrSwapchainImageOpenGLKHR;
typedef struct XrGraphicsRequirementsOpenGLKHR {
XrStructureType type;
void* XR_MAY_ALIAS next;
XrVersion minApiVersionSupported;
XrVersion maxApiVersionSupported;
} XrGraphicsRequirementsOpenGLKHR;
typedef XrResult (XRAPI_PTR *PFN_xrGetOpenGLGraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsOpenGLKHR* graphicsRequirements);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrGetOpenGLGraphicsRequirementsKHR(
XrInstance instance,
XrSystemId systemId,
XrGraphicsRequirementsOpenGLKHR* graphicsRequirements);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_GRAPHICS_API_OPENGL */
#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
#define XR_KHR_opengl_es_enable 1
#define XR_KHR_opengl_es_enable_SPEC_VERSION 8
#define XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME "XR_KHR_opengl_es_enable"
#ifdef XR_USE_PLATFORM_ANDROID
// XrGraphicsBindingOpenGLESAndroidKHR extends XrSessionCreateInfo
typedef struct XrGraphicsBindingOpenGLESAndroidKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
EGLDisplay display;
EGLConfig config;
EGLContext context;
} XrGraphicsBindingOpenGLESAndroidKHR;
#endif // XR_USE_PLATFORM_ANDROID
typedef struct XrSwapchainImageOpenGLESKHR {
XrStructureType type;
void* XR_MAY_ALIAS next;
uint32_t image;
} XrSwapchainImageOpenGLESKHR;
typedef struct XrGraphicsRequirementsOpenGLESKHR {
XrStructureType type;
void* XR_MAY_ALIAS next;
XrVersion minApiVersionSupported;
XrVersion maxApiVersionSupported;
} XrGraphicsRequirementsOpenGLESKHR;
typedef XrResult (XRAPI_PTR *PFN_xrGetOpenGLESGraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsOpenGLESKHR* graphicsRequirements);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrGetOpenGLESGraphicsRequirementsKHR(
XrInstance instance,
XrSystemId systemId,
XrGraphicsRequirementsOpenGLESKHR* graphicsRequirements);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_GRAPHICS_API_OPENGL_ES */
#ifdef XR_USE_GRAPHICS_API_VULKAN
#define XR_KHR_vulkan_enable 1
#define XR_KHR_vulkan_enable_SPEC_VERSION 8
#define XR_KHR_VULKAN_ENABLE_EXTENSION_NAME "XR_KHR_vulkan_enable"
// XrGraphicsBindingVulkanKHR extends XrSessionCreateInfo
typedef struct XrGraphicsBindingVulkanKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
VkInstance instance;
VkPhysicalDevice physicalDevice;
VkDevice device;
uint32_t queueFamilyIndex;
uint32_t queueIndex;
} XrGraphicsBindingVulkanKHR;
typedef struct XrSwapchainImageVulkanKHR {
XrStructureType type;
void* XR_MAY_ALIAS next;
VkImage image;
} XrSwapchainImageVulkanKHR;
typedef struct XrGraphicsRequirementsVulkanKHR {
XrStructureType type;
void* XR_MAY_ALIAS next;
XrVersion minApiVersionSupported;
XrVersion maxApiVersionSupported;
} XrGraphicsRequirementsVulkanKHR;
typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanInstanceExtensionsKHR)(XrInstance instance, XrSystemId systemId, uint32_t bufferCapacityInput, uint32_t* bufferCountOutput, char* buffer);
typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanDeviceExtensionsKHR)(XrInstance instance, XrSystemId systemId, uint32_t bufferCapacityInput, uint32_t* bufferCountOutput, char* buffer);
typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanGraphicsDeviceKHR)(XrInstance instance, XrSystemId systemId, VkInstance vkInstance, VkPhysicalDevice* vkPhysicalDevice);
typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanGraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsVulkanKHR* graphicsRequirements);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanInstanceExtensionsKHR(
XrInstance instance,
XrSystemId systemId,
uint32_t bufferCapacityInput,
uint32_t* bufferCountOutput,
char* buffer);
XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanDeviceExtensionsKHR(
XrInstance instance,
XrSystemId systemId,
uint32_t bufferCapacityInput,
uint32_t* bufferCountOutput,
char* buffer);
XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanGraphicsDeviceKHR(
XrInstance instance,
XrSystemId systemId,
VkInstance vkInstance,
VkPhysicalDevice* vkPhysicalDevice);
XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanGraphicsRequirementsKHR(
XrInstance instance,
XrSystemId systemId,
XrGraphicsRequirementsVulkanKHR* graphicsRequirements);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_GRAPHICS_API_VULKAN */
#ifdef XR_USE_GRAPHICS_API_D3D11
#define XR_KHR_D3D11_enable 1
#define XR_KHR_D3D11_enable_SPEC_VERSION 9
#define XR_KHR_D3D11_ENABLE_EXTENSION_NAME "XR_KHR_D3D11_enable"
// XrGraphicsBindingD3D11KHR extends XrSessionCreateInfo
typedef struct XrGraphicsBindingD3D11KHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
ID3D11Device* device;
} XrGraphicsBindingD3D11KHR;
typedef struct XrSwapchainImageD3D11KHR {
XrStructureType type;
void* XR_MAY_ALIAS next;
ID3D11Texture2D* texture;
} XrSwapchainImageD3D11KHR;
typedef struct XrGraphicsRequirementsD3D11KHR {
XrStructureType type;
void* XR_MAY_ALIAS next;
LUID adapterLuid;
D3D_FEATURE_LEVEL minFeatureLevel;
} XrGraphicsRequirementsD3D11KHR;
typedef XrResult (XRAPI_PTR *PFN_xrGetD3D11GraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsD3D11KHR* graphicsRequirements);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrGetD3D11GraphicsRequirementsKHR(
XrInstance instance,
XrSystemId systemId,
XrGraphicsRequirementsD3D11KHR* graphicsRequirements);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_GRAPHICS_API_D3D11 */
#ifdef XR_USE_GRAPHICS_API_D3D12
#define XR_KHR_D3D12_enable 1
#define XR_KHR_D3D12_enable_SPEC_VERSION 9
#define XR_KHR_D3D12_ENABLE_EXTENSION_NAME "XR_KHR_D3D12_enable"
// XrGraphicsBindingD3D12KHR extends XrSessionCreateInfo
typedef struct XrGraphicsBindingD3D12KHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
ID3D12Device* device;
ID3D12CommandQueue* queue;
} XrGraphicsBindingD3D12KHR;
typedef struct XrSwapchainImageD3D12KHR {
XrStructureType type;
void* XR_MAY_ALIAS next;
ID3D12Resource* texture;
} XrSwapchainImageD3D12KHR;
typedef struct XrGraphicsRequirementsD3D12KHR {
XrStructureType type;
void* XR_MAY_ALIAS next;
LUID adapterLuid;
D3D_FEATURE_LEVEL minFeatureLevel;
} XrGraphicsRequirementsD3D12KHR;
typedef XrResult (XRAPI_PTR *PFN_xrGetD3D12GraphicsRequirementsKHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsD3D12KHR* graphicsRequirements);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrGetD3D12GraphicsRequirementsKHR(
XrInstance instance,
XrSystemId systemId,
XrGraphicsRequirementsD3D12KHR* graphicsRequirements);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_GRAPHICS_API_D3D12 */
#ifdef XR_USE_PLATFORM_WIN32
#define XR_KHR_win32_convert_performance_counter_time 1
#define XR_KHR_win32_convert_performance_counter_time_SPEC_VERSION 1
#define XR_KHR_WIN32_CONVERT_PERFORMANCE_COUNTER_TIME_EXTENSION_NAME "XR_KHR_win32_convert_performance_counter_time"
typedef XrResult (XRAPI_PTR *PFN_xrConvertWin32PerformanceCounterToTimeKHR)(XrInstance instance, const LARGE_INTEGER* performanceCounter, XrTime* time);
typedef XrResult (XRAPI_PTR *PFN_xrConvertTimeToWin32PerformanceCounterKHR)(XrInstance instance, XrTime time, LARGE_INTEGER* performanceCounter);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrConvertWin32PerformanceCounterToTimeKHR(
XrInstance instance,
const LARGE_INTEGER* performanceCounter,
XrTime* time);
XRAPI_ATTR XrResult XRAPI_CALL xrConvertTimeToWin32PerformanceCounterKHR(
XrInstance instance,
XrTime time,
LARGE_INTEGER* performanceCounter);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_PLATFORM_WIN32 */
#ifdef XR_USE_TIMESPEC
#define XR_KHR_convert_timespec_time 1
#define XR_KHR_convert_timespec_time_SPEC_VERSION 1
#define XR_KHR_CONVERT_TIMESPEC_TIME_EXTENSION_NAME "XR_KHR_convert_timespec_time"
typedef XrResult (XRAPI_PTR *PFN_xrConvertTimespecTimeToTimeKHR)(XrInstance instance, const struct timespec* timespecTime, XrTime* time);
typedef XrResult (XRAPI_PTR *PFN_xrConvertTimeToTimespecTimeKHR)(XrInstance instance, XrTime time, struct timespec* timespecTime);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrConvertTimespecTimeToTimeKHR(
XrInstance instance,
const struct timespec* timespecTime,
XrTime* time);
XRAPI_ATTR XrResult XRAPI_CALL xrConvertTimeToTimespecTimeKHR(
XrInstance instance,
XrTime time,
struct timespec* timespecTime);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_TIMESPEC */
#ifdef XR_USE_PLATFORM_ANDROID
#define XR_KHR_loader_init_android 1
#define XR_KHR_loader_init_android_SPEC_VERSION 1
#define XR_KHR_LOADER_INIT_ANDROID_EXTENSION_NAME "XR_KHR_loader_init_android"
typedef struct XrLoaderInitInfoAndroidKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
void* XR_MAY_ALIAS applicationVM;
void* XR_MAY_ALIAS applicationContext;
} XrLoaderInitInfoAndroidKHR;
#endif /* XR_USE_PLATFORM_ANDROID */
#ifdef XR_USE_GRAPHICS_API_VULKAN
#define XR_KHR_vulkan_enable2 1
#define XR_KHR_vulkan_enable2_SPEC_VERSION 2
#define XR_KHR_VULKAN_ENABLE2_EXTENSION_NAME "XR_KHR_vulkan_enable2"
typedef XrFlags64 XrVulkanInstanceCreateFlagsKHR;
// Flag bits for XrVulkanInstanceCreateFlagsKHR
typedef XrFlags64 XrVulkanDeviceCreateFlagsKHR;
// Flag bits for XrVulkanDeviceCreateFlagsKHR
typedef struct XrVulkanInstanceCreateInfoKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
XrSystemId systemId;
XrVulkanInstanceCreateFlagsKHR createFlags;
PFN_vkGetInstanceProcAddr pfnGetInstanceProcAddr;
const VkInstanceCreateInfo* vulkanCreateInfo;
const VkAllocationCallbacks* vulkanAllocator;
} XrVulkanInstanceCreateInfoKHR;
typedef struct XrVulkanDeviceCreateInfoKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
XrSystemId systemId;
XrVulkanDeviceCreateFlagsKHR createFlags;
PFN_vkGetInstanceProcAddr pfnGetInstanceProcAddr;
VkPhysicalDevice vulkanPhysicalDevice;
const VkDeviceCreateInfo* vulkanCreateInfo;
const VkAllocationCallbacks* vulkanAllocator;
} XrVulkanDeviceCreateInfoKHR;
typedef XrGraphicsBindingVulkanKHR XrGraphicsBindingVulkan2KHR;
typedef struct XrVulkanGraphicsDeviceGetInfoKHR {
XrStructureType type;
const void* XR_MAY_ALIAS next;
XrSystemId systemId;
VkInstance vulkanInstance;
} XrVulkanGraphicsDeviceGetInfoKHR;
typedef XrSwapchainImageVulkanKHR XrSwapchainImageVulkan2KHR;
typedef XrGraphicsRequirementsVulkanKHR XrGraphicsRequirementsVulkan2KHR;
typedef XrResult (XRAPI_PTR *PFN_xrCreateVulkanInstanceKHR)(XrInstance instance, const XrVulkanInstanceCreateInfoKHR* createInfo, VkInstance* vulkanInstance, VkResult* vulkanResult);
typedef XrResult (XRAPI_PTR *PFN_xrCreateVulkanDeviceKHR)(XrInstance instance, const XrVulkanDeviceCreateInfoKHR* createInfo, VkDevice* vulkanDevice, VkResult* vulkanResult);
typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanGraphicsDevice2KHR)(XrInstance instance, const XrVulkanGraphicsDeviceGetInfoKHR* getInfo, VkPhysicalDevice* vulkanPhysicalDevice);
typedef XrResult (XRAPI_PTR *PFN_xrGetVulkanGraphicsRequirements2KHR)(XrInstance instance, XrSystemId systemId, XrGraphicsRequirementsVulkanKHR* graphicsRequirements);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrCreateVulkanInstanceKHR(
XrInstance instance,
const XrVulkanInstanceCreateInfoKHR* createInfo,
VkInstance* vulkanInstance,
VkResult* vulkanResult);
XRAPI_ATTR XrResult XRAPI_CALL xrCreateVulkanDeviceKHR(
XrInstance instance,
const XrVulkanDeviceCreateInfoKHR* createInfo,
VkDevice* vulkanDevice,
VkResult* vulkanResult);
XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanGraphicsDevice2KHR(
XrInstance instance,
const XrVulkanGraphicsDeviceGetInfoKHR* getInfo,
VkPhysicalDevice* vulkanPhysicalDevice);
XRAPI_ATTR XrResult XRAPI_CALL xrGetVulkanGraphicsRequirements2KHR(
XrInstance instance,
XrSystemId systemId,
XrGraphicsRequirementsVulkanKHR* graphicsRequirements);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_GRAPHICS_API_VULKAN */
#ifdef XR_USE_PLATFORM_EGL
#define XR_MNDX_egl_enable 1
#define XR_MNDX_egl_enable_SPEC_VERSION 1
#define XR_MNDX_EGL_ENABLE_EXTENSION_NAME "XR_MNDX_egl_enable"
// XrGraphicsBindingEGLMNDX extends XrSessionCreateInfo
typedef struct XrGraphicsBindingEGLMNDX {
XrStructureType type;
const void* XR_MAY_ALIAS next;
PFNEGLGETPROCADDRESSPROC getProcAddress;
EGLDisplay display;
EGLConfig config;
EGLContext context;
} XrGraphicsBindingEGLMNDX;
#endif /* XR_USE_PLATFORM_EGL */
#ifdef XR_USE_PLATFORM_WIN32
#define XR_MSFT_perception_anchor_interop 1
#define XR_MSFT_perception_anchor_interop_SPEC_VERSION 1
#define XR_MSFT_PERCEPTION_ANCHOR_INTEROP_EXTENSION_NAME "XR_MSFT_perception_anchor_interop"
typedef XrResult (XRAPI_PTR *PFN_xrCreateSpatialAnchorFromPerceptionAnchorMSFT)(XrSession session, IUnknown* perceptionAnchor, XrSpatialAnchorMSFT* anchor);
typedef XrResult (XRAPI_PTR *PFN_xrTryGetPerceptionAnchorFromSpatialAnchorMSFT)(XrSession session, XrSpatialAnchorMSFT anchor, IUnknown** perceptionAnchor);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrCreateSpatialAnchorFromPerceptionAnchorMSFT(
XrSession session,
IUnknown* perceptionAnchor,
XrSpatialAnchorMSFT* anchor);
XRAPI_ATTR XrResult XRAPI_CALL xrTryGetPerceptionAnchorFromSpatialAnchorMSFT(
XrSession session,
XrSpatialAnchorMSFT anchor,
IUnknown** perceptionAnchor);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_PLATFORM_WIN32 */
#ifdef XR_USE_PLATFORM_WIN32
#define XR_MSFT_holographic_window_attachment 1
#define XR_MSFT_holographic_window_attachment_SPEC_VERSION 1
#define XR_MSFT_HOLOGRAPHIC_WINDOW_ATTACHMENT_EXTENSION_NAME "XR_MSFT_holographic_window_attachment"
#ifdef XR_USE_PLATFORM_WIN32
// XrHolographicWindowAttachmentMSFT extends XrSessionCreateInfo
typedef struct XrHolographicWindowAttachmentMSFT {
XrStructureType type;
const void* XR_MAY_ALIAS next;
IUnknown* holographicSpace;
IUnknown* coreWindow;
} XrHolographicWindowAttachmentMSFT;
#endif // XR_USE_PLATFORM_WIN32
#endif /* XR_USE_PLATFORM_WIN32 */
#ifdef XR_USE_PLATFORM_ANDROID
#define XR_FB_android_surface_swapchain_create 1
#define XR_FB_android_surface_swapchain_create_SPEC_VERSION 1
#define XR_FB_ANDROID_SURFACE_SWAPCHAIN_CREATE_EXTENSION_NAME "XR_FB_android_surface_swapchain_create"
typedef XrFlags64 XrAndroidSurfaceSwapchainFlagsFB;
// Flag bits for XrAndroidSurfaceSwapchainFlagsFB
static const XrAndroidSurfaceSwapchainFlagsFB XR_ANDROID_SURFACE_SWAPCHAIN_SYNCHRONOUS_BIT_FB = 0x00000001;
static const XrAndroidSurfaceSwapchainFlagsFB XR_ANDROID_SURFACE_SWAPCHAIN_USE_TIMESTAMPS_BIT_FB = 0x00000002;
#ifdef XR_USE_PLATFORM_ANDROID
// XrAndroidSurfaceSwapchainCreateInfoFB extends XrSwapchainCreateInfo
typedef struct XrAndroidSurfaceSwapchainCreateInfoFB {
XrStructureType type;
const void* XR_MAY_ALIAS next;
XrAndroidSurfaceSwapchainFlagsFB createFlags;
} XrAndroidSurfaceSwapchainCreateInfoFB;
#endif // XR_USE_PLATFORM_ANDROID
#endif /* XR_USE_PLATFORM_ANDROID */
#ifdef XR_USE_PLATFORM_WIN32
#define XR_OCULUS_audio_device_guid 1
#define XR_OCULUS_audio_device_guid_SPEC_VERSION 1
#define XR_OCULUS_AUDIO_DEVICE_GUID_EXTENSION_NAME "XR_OCULUS_audio_device_guid"
#define XR_MAX_AUDIO_DEVICE_STR_SIZE_OCULUS 128
typedef XrResult (XRAPI_PTR *PFN_xrGetAudioOutputDeviceGuidOculus)(XrInstance instance, wchar_t buffer[XR_MAX_AUDIO_DEVICE_STR_SIZE_OCULUS]);
typedef XrResult (XRAPI_PTR *PFN_xrGetAudioInputDeviceGuidOculus)(XrInstance instance, wchar_t buffer[XR_MAX_AUDIO_DEVICE_STR_SIZE_OCULUS]);
#ifndef XR_NO_PROTOTYPES
#ifdef XR_EXTENSION_PROTOTYPES
XRAPI_ATTR XrResult XRAPI_CALL xrGetAudioOutputDeviceGuidOculus(
XrInstance instance,
wchar_t buffer[XR_MAX_AUDIO_DEVICE_STR_SIZE_OCULUS]);
XRAPI_ATTR XrResult XRAPI_CALL xrGetAudioInputDeviceGuidOculus(
XrInstance instance,
wchar_t buffer[XR_MAX_AUDIO_DEVICE_STR_SIZE_OCULUS]);
#endif /* XR_EXTENSION_PROTOTYPES */
#endif /* !XR_NO_PROTOTYPES */
#endif /* XR_USE_PLATFORM_WIN32 */
#ifdef XR_USE_GRAPHICS_API_VULKAN
#define XR_FB_foveation_vulkan 1
#define XR_FB_foveation_vulkan_SPEC_VERSION 1
#define XR_FB_FOVEATION_VULKAN_EXTENSION_NAME "XR_FB_foveation_vulkan"
// XrSwapchainImageFoveationVulkanFB extends XrSwapchainImageVulkanKHR
typedef struct XrSwapchainImageFoveationVulkanFB {
XrStructureType type;
void* XR_MAY_ALIAS next;
VkImage image;
uint32_t width;
uint32_t height;
} XrSwapchainImageFoveationVulkanFB;
#endif /* XR_USE_GRAPHICS_API_VULKAN */
#ifdef XR_USE_PLATFORM_ANDROID
#define XR_FB_swapchain_update_state_android_surface 1
#define XR_FB_swapchain_update_state_android_surface_SPEC_VERSION 1
#define XR_FB_SWAPCHAIN_UPDATE_STATE_ANDROID_SURFACE_EXTENSION_NAME "XR_FB_swapchain_update_state_android_surface"
#ifdef XR_USE_PLATFORM_ANDROID
typedef struct XrSwapchainStateAndroidSurfaceDimensionsFB {
XrStructureType type;
void* XR_MAY_ALIAS next;
uint32_t width;
uint32_t height;
} XrSwapchainStateAndroidSurfaceDimensionsFB;
#endif // XR_USE_PLATFORM_ANDROID
#endif /* XR_USE_PLATFORM_ANDROID */
#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
#define XR_FB_swapchain_update_state_opengl_es 1
#define XR_FB_swapchain_update_state_opengl_es_SPEC_VERSION 1
#define XR_FB_SWAPCHAIN_UPDATE_STATE_OPENGL_ES_EXTENSION_NAME "XR_FB_swapchain_update_state_opengl_es"
#ifdef XR_USE_GRAPHICS_API_OPENGL_ES
typedef struct XrSwapchainStateSamplerOpenGLESFB {
XrStructureType type;
void* XR_MAY_ALIAS next;
EGLenum minFilter;
EGLenum magFilter;
EGLenum wrapModeS;
EGLenum wrapModeT;
EGLenum swizzleRed;
EGLenum swizzleGreen;
EGLenum swizzleBlue;
EGLenum swizzleAlpha;
float maxAnisotropy;
XrColor4f borderColor;
} XrSwapchainStateSamplerOpenGLESFB;
#endif // XR_USE_GRAPHICS_API_OPENGL_ES
#endif /* XR_USE_GRAPHICS_API_OPENGL_ES */
#ifdef XR_USE_GRAPHICS_API_VULKAN
#define XR_FB_swapchain_update_state_vulkan 1
#define XR_FB_swapchain_update_state_vulkan_SPEC_VERSION 1
#define XR_FB_SWAPCHAIN_UPDATE_STATE_VULKAN_EXTENSION_NAME "XR_FB_swapchain_update_state_vulkan"
#ifdef XR_USE_GRAPHICS_API_VULKAN
typedef struct XrSwapchainStateSamplerVulkanFB {
XrStructureType type;
void* XR_MAY_ALIAS next;
VkFilter minFilter;
VkFilter magFilter;
VkSamplerMipmapMode mipmapMode;
VkSamplerAddressMode wrapModeS;
VkSamplerAddressMode wrapModeT;
VkComponentSwizzle swizzleRed;
VkComponentSwizzle swizzleGreen;
VkComponentSwizzle swizzleBlue;
VkComponentSwizzle swizzleAlpha;
float maxAnisotropy;
XrColor4f borderColor;
} XrSwapchainStateSamplerVulkanFB;
#endif // XR_USE_GRAPHICS_API_VULKAN
#endif /* XR_USE_GRAPHICS_API_VULKAN */
#ifdef XR_USE_GRAPHICS_API_VULKAN
#define XR_META_vulkan_swapchain_create_info 1
#define XR_META_vulkan_swapchain_create_info_SPEC_VERSION 1
#define XR_META_VULKAN_SWAPCHAIN_CREATE_INFO_EXTENSION_NAME "XR_META_vulkan_swapchain_create_info"
// XrVulkanSwapchainCreateInfoMETA extends XrSwapchainCreateInfo
typedef struct XrVulkanSwapchainCreateInfoMETA {
XrStructureType type;
const void* XR_MAY_ALIAS next;
VkImageCreateFlags additionalCreateFlags;
VkImageUsageFlags additionalUsageFlags;
} XrVulkanSwapchainCreateInfoMETA;
#endif /* XR_USE_GRAPHICS_API_VULKAN */
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,110 +0,0 @@
/*
** Copyright (c) 2017-2022, The Khronos Group Inc.
**
** SPDX-License-Identifier: Apache-2.0 OR MIT
*/
#ifndef OPENXR_PLATFORM_DEFINES_H_
#define OPENXR_PLATFORM_DEFINES_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/* Platform-specific calling convention macros.
*
* Platforms should define these so that OpenXR clients call OpenXR functions
* with the same calling conventions that the OpenXR implementation expects.
*
* XRAPI_ATTR - Placed before the return type in function declarations.
* Useful for C++11 and GCC/Clang-style function attribute syntax.
* XRAPI_CALL - Placed after the return type in function declarations.
* Useful for MSVC-style calling convention syntax.
* XRAPI_PTR - Placed between the '(' and '*' in function pointer types.
*
* Function declaration: XRAPI_ATTR void XRAPI_CALL xrFunction(void);
* Function pointer type: typedef void (XRAPI_PTR *PFN_xrFunction)(void);
*/
#if defined(_WIN32)
#define XRAPI_ATTR
// On Windows, functions use the stdcall convention
#define XRAPI_CALL __stdcall
#define XRAPI_PTR XRAPI_CALL
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH < 7
#error "API not supported for the 'armeabi' NDK ABI"
#elif defined(__ANDROID__) && defined(__ARM_ARCH) && __ARM_ARCH >= 7 && defined(__ARM_32BIT_STATE)
// On Android 32-bit ARM targets, functions use the "hardfloat"
// calling convention, i.e. float parameters are passed in registers. This
// is true even if the rest of the application passes floats on the stack,
// as it does by default when compiling for the armeabi-v7a NDK ABI.
#define XRAPI_ATTR __attribute__((pcs("aapcs-vfp")))
#define XRAPI_CALL
#define XRAPI_PTR XRAPI_ATTR
#else
// On other platforms, use the default calling convention
#define XRAPI_ATTR
#define XRAPI_CALL
#define XRAPI_PTR
#endif
#include <stddef.h>
#if !defined(XR_NO_STDINT_H)
#if defined(_MSC_VER) && (_MSC_VER < 1600)
typedef signed __int8 int8_t;
typedef unsigned __int8 uint8_t;
typedef signed __int16 int16_t;
typedef unsigned __int16 uint16_t;
typedef signed __int32 int32_t;
typedef unsigned __int32 uint32_t;
typedef signed __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
#include <stdint.h>
#endif
#endif // !defined( XR_NO_STDINT_H )
// XR_PTR_SIZE (in bytes)
#if (defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__))
#define XR_PTR_SIZE 8
#else
#define XR_PTR_SIZE 4
#endif
// Needed so we can use clang __has_feature portably.
#if !defined(XR_COMPILER_HAS_FEATURE)
#if defined(__clang__)
#define XR_COMPILER_HAS_FEATURE(x) __has_feature(x)
#else
#define XR_COMPILER_HAS_FEATURE(x) 0
#endif
#endif
// Identifies if the current compiler has C++11 support enabled.
// Does not by itself identify if any given C++11 feature is present.
#if !defined(XR_CPP11_ENABLED) && defined(__cplusplus)
#if defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__)
#define XR_CPP11_ENABLED 1
#elif defined(_MSC_VER) && (_MSC_VER >= 1600)
#define XR_CPP11_ENABLED 1
#elif (__cplusplus >= 201103L) // 201103 is the first C++11 version.
#define XR_CPP11_ENABLED 1
#endif
#endif
// Identifies if the current compiler supports C++11 nullptr.
#if !defined(XR_CPP_NULLPTR_SUPPORTED)
#if defined(XR_CPP11_ENABLED) && \
((defined(__clang__) && XR_COMPILER_HAS_FEATURE(cxx_nullptr)) || \
(defined(__GNUC__) && (((__GNUC__ * 1000) + __GNUC_MINOR__) >= 4006)) || \
(defined(_MSC_VER) && (_MSC_VER >= 1600)) || \
(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403)))
#define XR_CPP_NULLPTR_SUPPORTED 1
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,113 +0,0 @@
#ifndef OPENXR_HELPERS_H_
#define OPENXR_HELPERS_H_
#include <xr_linear.h>
static inline XrTime ToXrTime(const double timeInSeconds) {
return (timeInSeconds * 1e9);
}
static inline double FromXrTime(const XrTime time) {
return (time * 1e-9);
}
static inline XrQuaternionf XrQuaternionf_Identity() {
XrQuaternionf r;
r.x = r.y = r.z = 0.0;
r.w = 1.0f;
return r;
}
static inline XrVector3f XrVector3f_Zero() {
XrVector3f r;
r.x = r.y = r.z = 0.0f;
return r;
}
static inline float XrVector3f_LengthSquared(const XrVector3f v) {
return XrVector3f_Dot(&v, &v);
}
static inline XrVector3f XrVector3f_ScalarMultiply(const XrVector3f v, float scale) {
XrVector3f u;
u.x = v.x * scale;
u.y = v.y * scale;
u.z = v.z * scale;
return u;
}
static inline XrVector3f XrVector3f_Normalized(const XrVector3f v) {
float rcpLen = 1.0f / XrVector3f_Length(&v);
return XrVector3f_ScalarMultiply(v, rcpLen);
}
static inline XrQuaternionf XrQuaternionf_Inverse(const XrQuaternionf q) {
XrQuaternionf r;
r.x = -q.x;
r.y = -q.y;
r.z = -q.z;
r.w = q.w;
return r;
}
static inline XrVector3f XrQuaternionf_Rotate(const XrQuaternionf a, const XrVector3f v) {
XrVector3f r;
XrQuaternionf q = {v.x, v.y, v.z, 0.0f};
XrQuaternionf aq;
XrQuaternionf_Multiply(&aq, &q, &a);
XrQuaternionf aInv = XrQuaternionf_Inverse(a);
XrQuaternionf aqaInv;
XrQuaternionf_Multiply(&aqaInv, &aInv, &aq);
r.x = aqaInv.x;
r.y = aqaInv.y;
r.z = aqaInv.z;
return r;
}
static inline XrQuaternionf XrQuaternionf_CreateFromVectorAngle(
const XrVector3f axis,
const float angle) {
XrQuaternionf r;
if (XrVector3f_LengthSquared(axis) == 0.0f) {
return XrQuaternionf_Identity();
}
XrVector3f unitAxis = XrVector3f_Normalized(axis);
float sinHalfAngle = sinf(angle * 0.5f);
r.w = cosf(angle * 0.5f);
r.x = unitAxis.x * sinHalfAngle;
r.y = unitAxis.y * sinHalfAngle;
r.z = unitAxis.z * sinHalfAngle;
return r;
}
static inline XrPosef XrPosef_Identity() {
XrPosef r;
r.orientation = XrQuaternionf_Identity();
r.position = XrVector3f_Zero();
return r;
}
static inline XrPosef XrPosef_Inverse(const XrPosef a) {
XrPosef b;
b.orientation = XrQuaternionf_Inverse(a.orientation);
b.position = XrQuaternionf_Rotate(b.orientation, XrVector3f_ScalarMultiply(a.position, -1.0f));
return b;
}
static inline XrVector3f XrPosef_Transform(const XrPosef a, const XrVector3f v) {
XrVector3f r0 = XrQuaternionf_Rotate(a.orientation, v);
XrVector3f result;
XrVector3f_Add(&result, &r0, &a.position);
return result;
}
static inline XrPosef XrPosef_Multiply(const XrPosef a, const XrPosef b) {
XrPosef c;
XrQuaternionf_Multiply(&c.orientation, &b.orientation, &a.orientation);
c.position = XrPosef_Transform(a, b.position);
return c;
}
#endif //OPENXR_HELPERS_H_

View file

@ -1,787 +0,0 @@
// Copyright (c) 2017 The Khronos Group Inc.
// Copyright (c) 2016 Oculus VR, LLC.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: J.M.P. van Waveren
//
#ifndef XR_LINEAR_H_
#define XR_LINEAR_H_
#if defined(OS_LINUX_XCB) || defined(OS_LINUX_XCB_GLX) || defined(OS_LINUX_WAYLAND)
#pragma GCC diagnostic ignored "-Wunused-function"
#pragma clang diagnostic ignored "-Wunused-function"
#endif
#include <openxr/openxr.h>
/*
================================================================================================
Description : Vector, matrix and quaternion math.
Author : J.M.P. van Waveren
Date : 12/10/2016
Language : C99
Format : Indent 4 spaces - no tabs.
Copyright : Copyright (c) 2016 Oculus VR, LLC. All Rights reserved.
DESCRIPTION
===========
All matrices are column-major.
INTERFACE
=========
XrVector2f
XrVector3f
XrVector4f
XrQuaternionf
XrMatrix4x4f
inline static void XrVector3f_Set(XrVector3f* v, const float value);
inline static void XrVector3f_Add(XrVector3f* result, const XrVector3f* a, const XrVector3f* b);
inline static void XrVector3f_Sub(XrVector3f* result, const XrVector3f* a, const XrVector3f* b);
inline static void XrVector3f_Min(XrVector3f* result, const XrVector3f* a, const XrVector3f* b);
inline static void XrVector3f_Max(XrVector3f* result, const XrVector3f* a, const XrVector3f* b);
inline static void XrVector3f_Decay(XrVector3f* result, const XrVector3f* a, const float value);
inline static void XrVector3f_Lerp(XrVector3f* result, const XrVector3f* a, const XrVector3f* b, const float fraction);
inline static void XrVector3f_Scale(XrVector3f* result, const XrVector3f* a, const float scaleFactor);
inline static void XrVector3f_Normalize(XrVector3f* v);
inline static float XrVector3f_Length(const XrVector3f* v);
inline static void XrQuaternionf_Lerp(XrQuaternionf* result, const XrQuaternionf* a, const XrQuaternionf* b, const float fraction);
inline static void XrQuaternionf_Multiply(XrQuaternionf* result, const XrQuaternionf* a, const XrQuaternionf* b;
inline static void XrMatrix4x4f_CreateIdentity(XrMatrix4x4f* result);
inline static void XrMatrix4x4f_CreateTranslation(XrMatrix4x4f* result, const float x, const float y, const float z);
inline static void XrMatrix4x4f_CreateRotation(XrMatrix4x4f* result, const float degreesX, const float degreesY,
const float degreesZ);
inline static void XrMatrix4x4f_CreateScale(XrMatrix4x4f* result, const float x, const float y, const float z);
inline static void XrMatrix4x4f_CreateTranslationRotationScale(XrMatrix4x4f* result, const XrVector3f* translation,
const XrQuaternionf* rotation, const XrVector3f* scale);
inline static void XrMatrix4x4f_CreateProjection(XrMatrix4x4f* result, const float tanAngleLeft, const float tanAngleRight,
const float tanAngleUp, float const tanAngleDown, const float nearZ,
const float farZ);
inline static void XrMatrix4x4f_CreateProjectionFov(XrMatrix4x4f* result, const float fovDegreesLeft, const float fovDegreesRight,
const float fovDegreeUp, const float fovDegreesDown, const float nearZ,
const float farZ);
inline static void XrMatrix4x4f_CreateFromQuaternion(XrMatrix4x4f* result, const XrQuaternionf* src);
inline static void XrMatrix4x4f_CreateOffsetScaleForBounds(XrMatrix4x4f* result, const XrMatrix4x4f* matrix, const XrVector3f* mins,
const XrVector3f* maxs);
inline static bool XrMatrix4x4f_IsAffine(const XrMatrix4x4f* matrix, const float epsilon);
inline static bool XrMatrix4x4f_IsOrthogonal(const XrMatrix4x4f* matrix, const float epsilon);
inline static bool XrMatrix4x4f_IsOrthonormal(const XrMatrix4x4f* matrix, const float epsilon);
inline static bool XrMatrix4x4f_IsRigidBody(const XrMatrix4x4f* matrix, const float epsilon);
inline static void XrMatrix4x4f_GetTranslation(XrVector3f* result, const XrMatrix4x4f* src);
inline static void XrMatrix4x4f_GetRotation(XrQuaternionf* result, const XrMatrix4x4f* src);
inline static void XrMatrix4x4f_GetScale(XrVector3f* result, const XrMatrix4x4f* src);
inline static void XrMatrix4x4f_Multiply(XrMatrix4x4f* result, const XrMatrix4x4f* a, const XrMatrix4x4f* b);
inline static void XrMatrix4x4f_Transpose(XrMatrix4x4f* result, const XrMatrix4x4f* src);
inline static void XrMatrix4x4f_Invert(XrMatrix4x4f* result, const XrMatrix4x4f* src);
inline static void XrMatrix4x4f_InvertRigidBody(XrMatrix4x4f* result, const XrMatrix4x4f* src);
inline static void XrMatrix4x4f_TransformVector3f(XrVector3f* result, const XrMatrix4x4f* m, const XrVector3f* v);
inline static void XrMatrix4x4f_TransformVector4f(XrVector4f* result, const XrMatrix4x4f* m, const XrVector4f* v);
inline static void XrMatrix4x4f_TransformBounds(XrVector3f* resultMins, XrVector3f* resultMaxs, const XrMatrix4x4f* matrix,
const XrVector3f* mins, const XrVector3f* maxs);
inline static bool XrMatrix4x4f_CullBounds(const XrMatrix4x4f* mvp, const XrVector3f* mins, const XrVector3f* maxs);
================================================================================================
*/
#include <assert.h>
#include <math.h>
#include <stdbool.h>
#define MATH_PI 3.14159265358979323846f
#define DEFAULT_NEAR_Z 0.015625f // exact floating point representation
#define INFINITE_FAR_Z 0.0f
static const XrColor4f XrColorRed = {1.0f, 0.0f, 0.0f, 1.0f};
static const XrColor4f XrColorGreen = {0.0f, 1.0f, 0.0f, 1.0f};
static const XrColor4f XrColorBlue = {0.0f, 0.0f, 1.0f, 1.0f};
static const XrColor4f XrColorYellow = {1.0f, 1.0f, 0.0f, 1.0f};
static const XrColor4f XrColorPurple = {1.0f, 0.0f, 1.0f, 1.0f};
static const XrColor4f XrColorCyan = {0.0f, 1.0f, 1.0f, 1.0f};
static const XrColor4f XrColorLightGrey = {0.7f, 0.7f, 0.7f, 1.0f};
static const XrColor4f XrColorDarkGrey = {0.3f, 0.3f, 0.3f, 1.0f};
typedef enum GraphicsAPI { GRAPHICS_VULKAN, GRAPHICS_OPENGL, GRAPHICS_OPENGL_ES, GRAPHICS_D3D } GraphicsAPI;
// Column-major, pre-multiplied. This type does not exist in the OpenXR API and is provided for convenience.
typedef struct XrMatrix4x4f {
float m[16];
} XrMatrix4x4f;
inline static float XrRcpSqrt(const float x) {
const float SMALLEST_NON_DENORMAL = 1.1754943508222875e-038f; // ( 1U << 23 )
const float rcp = (x >= SMALLEST_NON_DENORMAL) ? 1.0f / sqrtf(x) : 1.0f;
return rcp;
}
inline static void XrVector3f_Set(XrVector3f* v, const float value) {
v->x = value;
v->y = value;
v->z = value;
}
inline static void XrVector3f_Add(XrVector3f* result, const XrVector3f* a, const XrVector3f* b) {
result->x = a->x + b->x;
result->y = a->y + b->y;
result->z = a->z + b->z;
}
inline static void XrVector3f_Sub(XrVector3f* result, const XrVector3f* a, const XrVector3f* b) {
result->x = a->x - b->x;
result->y = a->y - b->y;
result->z = a->z - b->z;
}
inline static void XrVector3f_Min(XrVector3f* result, const XrVector3f* a, const XrVector3f* b) {
result->x = (a->x < b->x) ? a->x : b->x;
result->y = (a->y < b->y) ? a->y : b->y;
result->z = (a->z < b->z) ? a->z : b->z;
}
inline static void XrVector3f_Max(XrVector3f* result, const XrVector3f* a, const XrVector3f* b) {
result->x = (a->x > b->x) ? a->x : b->x;
result->y = (a->y > b->y) ? a->y : b->y;
result->z = (a->z > b->z) ? a->z : b->z;
}
inline static void XrVector3f_Decay(XrVector3f* result, const XrVector3f* a, const float value) {
result->x = (fabsf(a->x) > value) ? ((a->x > 0.0f) ? (a->x - value) : (a->x + value)) : 0.0f;
result->y = (fabsf(a->y) > value) ? ((a->y > 0.0f) ? (a->y - value) : (a->y + value)) : 0.0f;
result->z = (fabsf(a->z) > value) ? ((a->z > 0.0f) ? (a->z - value) : (a->z + value)) : 0.0f;
}
inline static void XrVector3f_Lerp(XrVector3f* result, const XrVector3f* a, const XrVector3f* b, const float fraction) {
result->x = a->x + fraction * (b->x - a->x);
result->y = a->y + fraction * (b->y - a->y);
result->z = a->z + fraction * (b->z - a->z);
}
inline static void XrVector3f_Scale(XrVector3f* result, const XrVector3f* a, const float scaleFactor) {
result->x = a->x * scaleFactor;
result->y = a->y * scaleFactor;
result->z = a->z * scaleFactor;
}
inline static float XrVector3f_Dot(const XrVector3f* a, const XrVector3f* b) { return a->x * b->x + a->y * b->y + a->z * b->z; }
// Compute cross product, which generates a normal vector.
// Direction vector can be determined by right-hand rule: Pointing index finder in
// direction a and middle finger in direction b, thumb will point in Cross(a, b).
inline static void XrVector3f_Cross(XrVector3f* result, const XrVector3f* a, const XrVector3f* b) {
result->x = a->y * b->z - a->z * b->y;
result->y = a->z * b->x - a->x * b->z;
result->z = a->x * b->y - a->y * b->x;
}
inline static void XrVector3f_Normalize(XrVector3f* v) {
const float lengthRcp = XrRcpSqrt(v->x * v->x + v->y * v->y + v->z * v->z);
v->x *= lengthRcp;
v->y *= lengthRcp;
v->z *= lengthRcp;
}
inline static float XrVector3f_Length(const XrVector3f* v) { return sqrtf(v->x * v->x + v->y * v->y + v->z * v->z); }
inline static void XrQuaternionf_CreateFromAxisAngle(XrQuaternionf* result, const XrVector3f* axis, const float angleInRadians) {
float s = sinf(angleInRadians / 2.0f);
float lengthRcp = XrRcpSqrt(axis->x * axis->x + axis->y * axis->y + axis->z * axis->z);
result->x = s * axis->x * lengthRcp;
result->y = s * axis->y * lengthRcp;
result->z = s * axis->z * lengthRcp;
result->w = cosf(angleInRadians / 2.0f);
}
inline static void XrQuaternionf_Lerp(XrQuaternionf* result, const XrQuaternionf* a, const XrQuaternionf* b, const float fraction) {
const float s = a->x * b->x + a->y * b->y + a->z * b->z + a->w * b->w;
const float fa = 1.0f - fraction;
const float fb = (s < 0.0f) ? -fraction : fraction;
const float x = a->x * fa + b->x * fb;
const float y = a->y * fa + b->y * fb;
const float z = a->z * fa + b->z * fb;
const float w = a->w * fa + b->w * fb;
const float lengthRcp = XrRcpSqrt(x * x + y * y + z * z + w * w);
result->x = x * lengthRcp;
result->y = y * lengthRcp;
result->z = z * lengthRcp;
result->w = w * lengthRcp;
}
inline static void XrQuaternionf_Multiply(XrQuaternionf* result, const XrQuaternionf* a, const XrQuaternionf* b) {
result->x = (b->w * a->x) + (b->x * a->w) + (b->y * a->z) - (b->z * a->y);
result->y = (b->w * a->y) - (b->x * a->z) + (b->y * a->w) + (b->z * a->x);
result->z = (b->w * a->z) + (b->x * a->y) - (b->y * a->x) + (b->z * a->w);
result->w = (b->w * a->w) - (b->x * a->x) - (b->y * a->y) - (b->z * a->z);
}
// Use left-multiplication to accumulate transformations.
inline static void XrMatrix4x4f_Multiply(XrMatrix4x4f* result, const XrMatrix4x4f* a, const XrMatrix4x4f* b) {
result->m[0] = a->m[0] * b->m[0] + a->m[4] * b->m[1] + a->m[8] * b->m[2] + a->m[12] * b->m[3];
result->m[1] = a->m[1] * b->m[0] + a->m[5] * b->m[1] + a->m[9] * b->m[2] + a->m[13] * b->m[3];
result->m[2] = a->m[2] * b->m[0] + a->m[6] * b->m[1] + a->m[10] * b->m[2] + a->m[14] * b->m[3];
result->m[3] = a->m[3] * b->m[0] + a->m[7] * b->m[1] + a->m[11] * b->m[2] + a->m[15] * b->m[3];
result->m[4] = a->m[0] * b->m[4] + a->m[4] * b->m[5] + a->m[8] * b->m[6] + a->m[12] * b->m[7];
result->m[5] = a->m[1] * b->m[4] + a->m[5] * b->m[5] + a->m[9] * b->m[6] + a->m[13] * b->m[7];
result->m[6] = a->m[2] * b->m[4] + a->m[6] * b->m[5] + a->m[10] * b->m[6] + a->m[14] * b->m[7];
result->m[7] = a->m[3] * b->m[4] + a->m[7] * b->m[5] + a->m[11] * b->m[6] + a->m[15] * b->m[7];
result->m[8] = a->m[0] * b->m[8] + a->m[4] * b->m[9] + a->m[8] * b->m[10] + a->m[12] * b->m[11];
result->m[9] = a->m[1] * b->m[8] + a->m[5] * b->m[9] + a->m[9] * b->m[10] + a->m[13] * b->m[11];
result->m[10] = a->m[2] * b->m[8] + a->m[6] * b->m[9] + a->m[10] * b->m[10] + a->m[14] * b->m[11];
result->m[11] = a->m[3] * b->m[8] + a->m[7] * b->m[9] + a->m[11] * b->m[10] + a->m[15] * b->m[11];
result->m[12] = a->m[0] * b->m[12] + a->m[4] * b->m[13] + a->m[8] * b->m[14] + a->m[12] * b->m[15];
result->m[13] = a->m[1] * b->m[12] + a->m[5] * b->m[13] + a->m[9] * b->m[14] + a->m[13] * b->m[15];
result->m[14] = a->m[2] * b->m[12] + a->m[6] * b->m[13] + a->m[10] * b->m[14] + a->m[14] * b->m[15];
result->m[15] = a->m[3] * b->m[12] + a->m[7] * b->m[13] + a->m[11] * b->m[14] + a->m[15] * b->m[15];
}
// Creates the transpose of the given matrix.
inline static void XrMatrix4x4f_Transpose(XrMatrix4x4f* result, const XrMatrix4x4f* src) {
result->m[0] = src->m[0];
result->m[1] = src->m[4];
result->m[2] = src->m[8];
result->m[3] = src->m[12];
result->m[4] = src->m[1];
result->m[5] = src->m[5];
result->m[6] = src->m[9];
result->m[7] = src->m[13];
result->m[8] = src->m[2];
result->m[9] = src->m[6];
result->m[10] = src->m[10];
result->m[11] = src->m[14];
result->m[12] = src->m[3];
result->m[13] = src->m[7];
result->m[14] = src->m[11];
result->m[15] = src->m[15];
}
// Returns a 3x3 minor of a 4x4 matrix.
inline static float XrMatrix4x4f_Minor(const XrMatrix4x4f* matrix, int r0, int r1, int r2, int c0, int c1, int c2) {
return matrix->m[4 * r0 + c0] *
(matrix->m[4 * r1 + c1] * matrix->m[4 * r2 + c2] - matrix->m[4 * r2 + c1] * matrix->m[4 * r1 + c2]) -
matrix->m[4 * r0 + c1] *
(matrix->m[4 * r1 + c0] * matrix->m[4 * r2 + c2] - matrix->m[4 * r2 + c0] * matrix->m[4 * r1 + c2]) +
matrix->m[4 * r0 + c2] *
(matrix->m[4 * r1 + c0] * matrix->m[4 * r2 + c1] - matrix->m[4 * r2 + c0] * matrix->m[4 * r1 + c1]);
}
// Calculates the inverse of a 4x4 matrix.
inline static void XrMatrix4x4f_Invert(XrMatrix4x4f* result, const XrMatrix4x4f* src) {
const float rcpDet =
1.0f / (src->m[0] * XrMatrix4x4f_Minor(src, 1, 2, 3, 1, 2, 3) - src->m[1] * XrMatrix4x4f_Minor(src, 1, 2, 3, 0, 2, 3) +
src->m[2] * XrMatrix4x4f_Minor(src, 1, 2, 3, 0, 1, 3) - src->m[3] * XrMatrix4x4f_Minor(src, 1, 2, 3, 0, 1, 2));
result->m[0] = XrMatrix4x4f_Minor(src, 1, 2, 3, 1, 2, 3) * rcpDet;
result->m[1] = -XrMatrix4x4f_Minor(src, 0, 2, 3, 1, 2, 3) * rcpDet;
result->m[2] = XrMatrix4x4f_Minor(src, 0, 1, 3, 1, 2, 3) * rcpDet;
result->m[3] = -XrMatrix4x4f_Minor(src, 0, 1, 2, 1, 2, 3) * rcpDet;
result->m[4] = -XrMatrix4x4f_Minor(src, 1, 2, 3, 0, 2, 3) * rcpDet;
result->m[5] = XrMatrix4x4f_Minor(src, 0, 2, 3, 0, 2, 3) * rcpDet;
result->m[6] = -XrMatrix4x4f_Minor(src, 0, 1, 3, 0, 2, 3) * rcpDet;
result->m[7] = XrMatrix4x4f_Minor(src, 0, 1, 2, 0, 2, 3) * rcpDet;
result->m[8] = XrMatrix4x4f_Minor(src, 1, 2, 3, 0, 1, 3) * rcpDet;
result->m[9] = -XrMatrix4x4f_Minor(src, 0, 2, 3, 0, 1, 3) * rcpDet;
result->m[10] = XrMatrix4x4f_Minor(src, 0, 1, 3, 0, 1, 3) * rcpDet;
result->m[11] = -XrMatrix4x4f_Minor(src, 0, 1, 2, 0, 1, 3) * rcpDet;
result->m[12] = -XrMatrix4x4f_Minor(src, 1, 2, 3, 0, 1, 2) * rcpDet;
result->m[13] = XrMatrix4x4f_Minor(src, 0, 2, 3, 0, 1, 2) * rcpDet;
result->m[14] = -XrMatrix4x4f_Minor(src, 0, 1, 3, 0, 1, 2) * rcpDet;
result->m[15] = XrMatrix4x4f_Minor(src, 0, 1, 2, 0, 1, 2) * rcpDet;
}
// Calculates the inverse of a rigid body transform.
inline static void XrMatrix4x4f_InvertRigidBody(XrMatrix4x4f* result, const XrMatrix4x4f* src) {
result->m[0] = src->m[0];
result->m[1] = src->m[4];
result->m[2] = src->m[8];
result->m[3] = 0.0f;
result->m[4] = src->m[1];
result->m[5] = src->m[5];
result->m[6] = src->m[9];
result->m[7] = 0.0f;
result->m[8] = src->m[2];
result->m[9] = src->m[6];
result->m[10] = src->m[10];
result->m[11] = 0.0f;
result->m[12] = -(src->m[0] * src->m[12] + src->m[1] * src->m[13] + src->m[2] * src->m[14]);
result->m[13] = -(src->m[4] * src->m[12] + src->m[5] * src->m[13] + src->m[6] * src->m[14]);
result->m[14] = -(src->m[8] * src->m[12] + src->m[9] * src->m[13] + src->m[10] * src->m[14]);
result->m[15] = 1.0f;
}
// Creates an identity matrix.
inline static void XrMatrix4x4f_CreateIdentity(XrMatrix4x4f* result) {
result->m[0] = 1.0f;
result->m[1] = 0.0f;
result->m[2] = 0.0f;
result->m[3] = 0.0f;
result->m[4] = 0.0f;
result->m[5] = 1.0f;
result->m[6] = 0.0f;
result->m[7] = 0.0f;
result->m[8] = 0.0f;
result->m[9] = 0.0f;
result->m[10] = 1.0f;
result->m[11] = 0.0f;
result->m[12] = 0.0f;
result->m[13] = 0.0f;
result->m[14] = 0.0f;
result->m[15] = 1.0f;
}
// Creates a translation matrix.
inline static void XrMatrix4x4f_CreateTranslation(XrMatrix4x4f* result, const float x, const float y, const float z) {
result->m[0] = 1.0f;
result->m[1] = 0.0f;
result->m[2] = 0.0f;
result->m[3] = 0.0f;
result->m[4] = 0.0f;
result->m[5] = 1.0f;
result->m[6] = 0.0f;
result->m[7] = 0.0f;
result->m[8] = 0.0f;
result->m[9] = 0.0f;
result->m[10] = 1.0f;
result->m[11] = 0.0f;
result->m[12] = x;
result->m[13] = y;
result->m[14] = z;
result->m[15] = 1.0f;
}
// Creates a rotation matrix.
// If -Z=forward, +Y=up, +X=right, then degreesX=pitch, degreesY=yaw, degreesZ=roll.
inline static void XrMatrix4x4f_CreateRotation(XrMatrix4x4f* result, const float degreesX, const float degreesY,
const float degreesZ) {
const float sinX = sinf(degreesX * (MATH_PI / 180.0f));
const float cosX = cosf(degreesX * (MATH_PI / 180.0f));
const XrMatrix4x4f rotationX = {{1, 0, 0, 0, 0, cosX, sinX, 0, 0, -sinX, cosX, 0, 0, 0, 0, 1}};
const float sinY = sinf(degreesY * (MATH_PI / 180.0f));
const float cosY = cosf(degreesY * (MATH_PI / 180.0f));
const XrMatrix4x4f rotationY = {{cosY, 0, -sinY, 0, 0, 1, 0, 0, sinY, 0, cosY, 0, 0, 0, 0, 1}};
const float sinZ = sinf(degreesZ * (MATH_PI / 180.0f));
const float cosZ = cosf(degreesZ * (MATH_PI / 180.0f));
const XrMatrix4x4f rotationZ = {{cosZ, sinZ, 0, 0, -sinZ, cosZ, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}};
XrMatrix4x4f rotationXY;
XrMatrix4x4f_Multiply(&rotationXY, &rotationY, &rotationX);
XrMatrix4x4f_Multiply(result, &rotationZ, &rotationXY);
}
// Creates a scale matrix.
inline static void XrMatrix4x4f_CreateScale(XrMatrix4x4f* result, const float x, const float y, const float z) {
result->m[0] = x;
result->m[1] = 0.0f;
result->m[2] = 0.0f;
result->m[3] = 0.0f;
result->m[4] = 0.0f;
result->m[5] = y;
result->m[6] = 0.0f;
result->m[7] = 0.0f;
result->m[8] = 0.0f;
result->m[9] = 0.0f;
result->m[10] = z;
result->m[11] = 0.0f;
result->m[12] = 0.0f;
result->m[13] = 0.0f;
result->m[14] = 0.0f;
result->m[15] = 1.0f;
}
// Creates a matrix from a quaternion.
inline static void XrMatrix4x4f_CreateFromQuaternion(XrMatrix4x4f* result, const XrQuaternionf* quat) {
const float x2 = quat->x + quat->x;
const float y2 = quat->y + quat->y;
const float z2 = quat->z + quat->z;
const float xx2 = quat->x * x2;
const float yy2 = quat->y * y2;
const float zz2 = quat->z * z2;
const float yz2 = quat->y * z2;
const float wx2 = quat->w * x2;
const float xy2 = quat->x * y2;
const float wz2 = quat->w * z2;
const float xz2 = quat->x * z2;
const float wy2 = quat->w * y2;
result->m[0] = 1.0f - yy2 - zz2;
result->m[1] = xy2 + wz2;
result->m[2] = xz2 - wy2;
result->m[3] = 0.0f;
result->m[4] = xy2 - wz2;
result->m[5] = 1.0f - xx2 - zz2;
result->m[6] = yz2 + wx2;
result->m[7] = 0.0f;
result->m[8] = xz2 + wy2;
result->m[9] = yz2 - wx2;
result->m[10] = 1.0f - xx2 - yy2;
result->m[11] = 0.0f;
result->m[12] = 0.0f;
result->m[13] = 0.0f;
result->m[14] = 0.0f;
result->m[15] = 1.0f;
}
// Creates a combined translation(rotation(scale(object))) matrix.
inline static void XrMatrix4x4f_CreateTranslationRotationScale(XrMatrix4x4f* result, const XrVector3f* translation,
const XrQuaternionf* rotation, const XrVector3f* scale) {
XrMatrix4x4f scaleMatrix;
XrMatrix4x4f_CreateScale(&scaleMatrix, scale->x, scale->y, scale->z);
XrMatrix4x4f rotationMatrix;
XrMatrix4x4f_CreateFromQuaternion(&rotationMatrix, rotation);
XrMatrix4x4f translationMatrix;
XrMatrix4x4f_CreateTranslation(&translationMatrix, translation->x, translation->y, translation->z);
XrMatrix4x4f combinedMatrix;
XrMatrix4x4f_Multiply(&combinedMatrix, &rotationMatrix, &scaleMatrix);
XrMatrix4x4f_Multiply(result, &translationMatrix, &combinedMatrix);
}
// Creates a projection matrix based on the specified dimensions.
// The projection matrix transforms -Z=forward, +Y=up, +X=right to the appropriate clip space for the graphics API.
// The far plane is placed at infinity if farZ <= nearZ.
// An infinite projection matrix is preferred for rasterization because, except for
// things *right* up against the near plane, it always provides better precision:
// "Tightening the Precision of Perspective Rendering"
// Paul Upchurch, Mathieu Desbrun
// Journal of Graphics Tools, Volume 16, Issue 1, 2012
inline static void XrMatrix4x4f_CreateProjection(XrMatrix4x4f* result, GraphicsAPI graphicsApi, const float tanAngleLeft,
const float tanAngleRight, const float tanAngleUp, float const tanAngleDown,
const float nearZ, const float farZ) {
const float tanAngleWidth = tanAngleRight - tanAngleLeft;
// Set to tanAngleDown - tanAngleUp for a clip space with positive Y down (Vulkan).
// Set to tanAngleUp - tanAngleDown for a clip space with positive Y up (OpenGL / D3D / Metal).
const float tanAngleHeight = graphicsApi == GRAPHICS_VULKAN ? (tanAngleDown - tanAngleUp) : (tanAngleUp - tanAngleDown);
// Set to nearZ for a [-1,1] Z clip space (OpenGL / OpenGL ES).
// Set to zero for a [0,1] Z clip space (Vulkan / D3D / Metal).
const float offsetZ = (graphicsApi == GRAPHICS_OPENGL || graphicsApi == GRAPHICS_OPENGL_ES) ? nearZ : 0;
if (farZ <= nearZ) {
// place the far plane at infinity
result->m[0] = 2.0f / tanAngleWidth;
result->m[4] = 0.0f;
result->m[8] = (tanAngleRight + tanAngleLeft) / tanAngleWidth;
result->m[12] = 0.0f;
result->m[1] = 0.0f;
result->m[5] = 2.0f / tanAngleHeight;
result->m[9] = (tanAngleUp + tanAngleDown) / tanAngleHeight;
result->m[13] = 0.0f;
result->m[2] = 0.0f;
result->m[6] = 0.0f;
result->m[10] = -1.0f;
result->m[14] = -(nearZ + offsetZ);
result->m[3] = 0.0f;
result->m[7] = 0.0f;
result->m[11] = -1.0f;
result->m[15] = 0.0f;
} else {
// normal projection
result->m[0] = 2.0f / tanAngleWidth;
result->m[4] = 0.0f;
result->m[8] = (tanAngleRight + tanAngleLeft) / tanAngleWidth;
result->m[12] = 0.0f;
result->m[1] = 0.0f;
result->m[5] = 2.0f / tanAngleHeight;
result->m[9] = (tanAngleUp + tanAngleDown) / tanAngleHeight;
result->m[13] = 0.0f;
result->m[2] = 0.0f;
result->m[6] = 0.0f;
result->m[10] = -(farZ + offsetZ) / (farZ - nearZ);
result->m[14] = -(farZ * (nearZ + offsetZ)) / (farZ - nearZ);
result->m[3] = 0.0f;
result->m[7] = 0.0f;
result->m[11] = -1.0f;
result->m[15] = 0.0f;
}
}
// Creates a projection matrix based on the specified FOV.
inline static void XrMatrix4x4f_CreateProjectionFov(XrMatrix4x4f* result, GraphicsAPI graphicsApi, const XrFovf fov,
const float nearZ, const float farZ) {
const float tanLeft = tanf(fov.angleLeft);
const float tanRight = tanf(fov.angleRight);
const float tanDown = tanf(fov.angleDown);
const float tanUp = tanf(fov.angleUp);
XrMatrix4x4f_CreateProjection(result, graphicsApi, tanLeft, tanRight, tanUp, tanDown, nearZ, farZ);
}
// Creates a matrix that transforms the -1 to 1 cube to cover the given 'mins' and 'maxs' transformed with the given 'matrix'.
inline static void XrMatrix4x4f_CreateOffsetScaleForBounds(XrMatrix4x4f* result, const XrMatrix4x4f* matrix, const XrVector3f* mins,
const XrVector3f* maxs) {
const XrVector3f offset = {(maxs->x + mins->x) * 0.5f, (maxs->y + mins->y) * 0.5f, (maxs->z + mins->z) * 0.5f};
const XrVector3f scale = {(maxs->x - mins->x) * 0.5f, (maxs->y - mins->y) * 0.5f, (maxs->z - mins->z) * 0.5f};
result->m[0] = matrix->m[0] * scale.x;
result->m[1] = matrix->m[1] * scale.x;
result->m[2] = matrix->m[2] * scale.x;
result->m[3] = matrix->m[3] * scale.x;
result->m[4] = matrix->m[4] * scale.y;
result->m[5] = matrix->m[5] * scale.y;
result->m[6] = matrix->m[6] * scale.y;
result->m[7] = matrix->m[7] * scale.y;
result->m[8] = matrix->m[8] * scale.z;
result->m[9] = matrix->m[9] * scale.z;
result->m[10] = matrix->m[10] * scale.z;
result->m[11] = matrix->m[11] * scale.z;
result->m[12] = matrix->m[12] + matrix->m[0] * offset.x + matrix->m[4] * offset.y + matrix->m[8] * offset.z;
result->m[13] = matrix->m[13] + matrix->m[1] * offset.x + matrix->m[5] * offset.y + matrix->m[9] * offset.z;
result->m[14] = matrix->m[14] + matrix->m[2] * offset.x + matrix->m[6] * offset.y + matrix->m[10] * offset.z;
result->m[15] = matrix->m[15] + matrix->m[3] * offset.x + matrix->m[7] * offset.y + matrix->m[11] * offset.z;
}
// Returns true if the given matrix is affine.
inline static bool XrMatrix4x4f_IsAffine(const XrMatrix4x4f* matrix, const float epsilon) {
return fabsf(matrix->m[3]) <= epsilon && fabsf(matrix->m[7]) <= epsilon && fabsf(matrix->m[11]) <= epsilon &&
fabsf(matrix->m[15] - 1.0f) <= epsilon;
}
// Returns true if the given matrix is orthogonal.
inline static bool XrMatrix4x4f_IsOrthogonal(const XrMatrix4x4f* matrix, const float epsilon) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (i != j) {
if (fabsf(matrix->m[4 * i + 0] * matrix->m[4 * j + 0] + matrix->m[4 * i + 1] * matrix->m[4 * j + 1] +
matrix->m[4 * i + 2] * matrix->m[4 * j + 2]) > epsilon) {
return false;
}
if (fabsf(matrix->m[4 * 0 + i] * matrix->m[4 * 0 + j] + matrix->m[4 * 1 + i] * matrix->m[4 * 1 + j] +
matrix->m[4 * 2 + i] * matrix->m[4 * 2 + j]) > epsilon) {
return false;
}
}
}
}
return true;
}
// Returns true if the given matrix is orthonormal.
inline static bool XrMatrix4x4f_IsOrthonormal(const XrMatrix4x4f* matrix, const float epsilon) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
const float kd = (i == j) ? 1.0f : 0.0f; // Kronecker delta
if (fabsf(kd - (matrix->m[4 * i + 0] * matrix->m[4 * j + 0] + matrix->m[4 * i + 1] * matrix->m[4 * j + 1] +
matrix->m[4 * i + 2] * matrix->m[4 * j + 2])) > epsilon) {
return false;
}
if (fabsf(kd - (matrix->m[4 * 0 + i] * matrix->m[4 * 0 + j] + matrix->m[4 * 1 + i] * matrix->m[4 * 1 + j] +
matrix->m[4 * 2 + i] * matrix->m[4 * 2 + j])) > epsilon) {
return false;
}
}
}
return true;
}
// Returns true if the given matrix is a rigid body transform.
inline static bool XrMatrix4x4f_IsRigidBody(const XrMatrix4x4f* matrix, const float epsilon) {
return XrMatrix4x4f_IsAffine(matrix, epsilon) && XrMatrix4x4f_IsOrthonormal(matrix, epsilon);
}
// Get the translation from a combined translation(rotation(scale(object))) matrix.
inline static void XrMatrix4x4f_GetTranslation(XrVector3f* result, const XrMatrix4x4f* src) {
assert(XrMatrix4x4f_IsAffine(src, 1e-4f));
assert(XrMatrix4x4f_IsOrthogonal(src, 1e-4f));
result->x = src->m[12];
result->y = src->m[13];
result->z = src->m[14];
}
// Get the rotation from a combined translation(rotation(scale(object))) matrix.
inline static void XrMatrix4x4f_GetRotation(XrQuaternionf* result, const XrMatrix4x4f* src) {
assert(XrMatrix4x4f_IsAffine(src, 1e-4f));
assert(XrMatrix4x4f_IsOrthogonal(src, 1e-4f));
const float rcpScaleX = XrRcpSqrt(src->m[0] * src->m[0] + src->m[1] * src->m[1] + src->m[2] * src->m[2]);
const float rcpScaleY = XrRcpSqrt(src->m[4] * src->m[4] + src->m[5] * src->m[5] + src->m[6] * src->m[6]);
const float rcpScaleZ = XrRcpSqrt(src->m[8] * src->m[8] + src->m[9] * src->m[9] + src->m[10] * src->m[10]);
const float m[9] = {src->m[0] * rcpScaleX, src->m[1] * rcpScaleX, src->m[2] * rcpScaleX,
src->m[4] * rcpScaleY, src->m[5] * rcpScaleY, src->m[6] * rcpScaleY,
src->m[8] * rcpScaleZ, src->m[9] * rcpScaleZ, src->m[10] * rcpScaleZ};
if (m[0 * 3 + 0] + m[1 * 3 + 1] + m[2 * 3 + 2] > 0.0f) {
float t = +m[0 * 3 + 0] + m[1 * 3 + 1] + m[2 * 3 + 2] + 1.0f;
float s = XrRcpSqrt(t) * 0.5f;
result->w = s * t;
result->z = (m[0 * 3 + 1] - m[1 * 3 + 0]) * s;
result->y = (m[2 * 3 + 0] - m[0 * 3 + 2]) * s;
result->x = (m[1 * 3 + 2] - m[2 * 3 + 1]) * s;
} else if (m[0 * 3 + 0] > m[1 * 3 + 1] && m[0 * 3 + 0] > m[2 * 3 + 2]) {
float t = +m[0 * 3 + 0] - m[1 * 3 + 1] - m[2 * 3 + 2] + 1.0f;
float s = XrRcpSqrt(t) * 0.5f;
result->x = s * t;
result->y = (m[0 * 3 + 1] + m[1 * 3 + 0]) * s;
result->z = (m[2 * 3 + 0] + m[0 * 3 + 2]) * s;
result->w = (m[1 * 3 + 2] - m[2 * 3 + 1]) * s;
} else if (m[1 * 3 + 1] > m[2 * 3 + 2]) {
float t = -m[0 * 3 + 0] + m[1 * 3 + 1] - m[2 * 3 + 2] + 1.0f;
float s = XrRcpSqrt(t) * 0.5f;
result->y = s * t;
result->x = (m[0 * 3 + 1] + m[1 * 3 + 0]) * s;
result->w = (m[2 * 3 + 0] - m[0 * 3 + 2]) * s;
result->z = (m[1 * 3 + 2] + m[2 * 3 + 1]) * s;
} else {
float t = -m[0 * 3 + 0] - m[1 * 3 + 1] + m[2 * 3 + 2] + 1.0f;
float s = XrRcpSqrt(t) * 0.5f;
result->z = s * t;
result->w = (m[0 * 3 + 1] - m[1 * 3 + 0]) * s;
result->x = (m[2 * 3 + 0] + m[0 * 3 + 2]) * s;
result->y = (m[1 * 3 + 2] + m[2 * 3 + 1]) * s;
}
}
// Get the scale from a combined translation(rotation(scale(object))) matrix.
inline static void XrMatrix4x4f_GetScale(XrVector3f* result, const XrMatrix4x4f* src) {
assert(XrMatrix4x4f_IsAffine(src, 1e-4f));
assert(XrMatrix4x4f_IsOrthogonal(src, 1e-4f));
result->x = sqrtf(src->m[0] * src->m[0] + src->m[1] * src->m[1] + src->m[2] * src->m[2]);
result->y = sqrtf(src->m[4] * src->m[4] + src->m[5] * src->m[5] + src->m[6] * src->m[6]);
result->z = sqrtf(src->m[8] * src->m[8] + src->m[9] * src->m[9] + src->m[10] * src->m[10]);
}
// Transforms a 3D vector.
inline static void XrMatrix4x4f_TransformVector3f(XrVector3f* result, const XrMatrix4x4f* m, const XrVector3f* v) {
const float w = m->m[3] * v->x + m->m[7] * v->y + m->m[11] * v->z + m->m[15];
const float rcpW = 1.0f / w;
result->x = (m->m[0] * v->x + m->m[4] * v->y + m->m[8] * v->z + m->m[12]) * rcpW;
result->y = (m->m[1] * v->x + m->m[5] * v->y + m->m[9] * v->z + m->m[13]) * rcpW;
result->z = (m->m[2] * v->x + m->m[6] * v->y + m->m[10] * v->z + m->m[14]) * rcpW;
}
// Transforms a 4D vector.
inline static void XrMatrix4x4f_TransformVector4f(XrVector4f* result, const XrMatrix4x4f* m, const XrVector4f* v) {
result->x = m->m[0] * v->x + m->m[4] * v->y + m->m[8] * v->z + m->m[12] * v->w;
result->y = m->m[1] * v->x + m->m[5] * v->y + m->m[9] * v->z + m->m[13] * v->w;
result->z = m->m[2] * v->x + m->m[6] * v->y + m->m[10] * v->z + m->m[14] * v->w;
result->w = m->m[3] * v->x + m->m[7] * v->y + m->m[11] * v->z + m->m[15] * v->w;
}
// Transforms the 'mins' and 'maxs' bounds with the given 'matrix'.
inline static void XrMatrix4x4f_TransformBounds(XrVector3f* resultMins, XrVector3f* resultMaxs, const XrMatrix4x4f* matrix,
const XrVector3f* mins, const XrVector3f* maxs) {
assert(XrMatrix4x4f_IsAffine(matrix, 1e-4f));
const XrVector3f center = {(mins->x + maxs->x) * 0.5f, (mins->y + maxs->y) * 0.5f, (mins->z + maxs->z) * 0.5f};
const XrVector3f extents = {maxs->x - center.x, maxs->y - center.y, maxs->z - center.z};
const XrVector3f newCenter = {matrix->m[0] * center.x + matrix->m[4] * center.y + matrix->m[8] * center.z + matrix->m[12],
matrix->m[1] * center.x + matrix->m[5] * center.y + matrix->m[9] * center.z + matrix->m[13],
matrix->m[2] * center.x + matrix->m[6] * center.y + matrix->m[10] * center.z + matrix->m[14]};
const XrVector3f newExtents = {
fabsf(extents.x * matrix->m[0]) + fabsf(extents.y * matrix->m[4]) + fabsf(extents.z * matrix->m[8]),
fabsf(extents.x * matrix->m[1]) + fabsf(extents.y * matrix->m[5]) + fabsf(extents.z * matrix->m[9]),
fabsf(extents.x * matrix->m[2]) + fabsf(extents.y * matrix->m[6]) + fabsf(extents.z * matrix->m[10])};
XrVector3f_Sub(resultMins, &newCenter, &newExtents);
XrVector3f_Add(resultMaxs, &newCenter, &newExtents);
}
// Returns true if the 'mins' and 'maxs' bounds is completely off to one side of the projection matrix.
inline static bool XrMatrix4x4f_CullBounds(const XrMatrix4x4f* mvp, const XrVector3f* mins, const XrVector3f* maxs) {
if (maxs->x <= mins->x && maxs->y <= mins->y && maxs->z <= mins->z) {
return false;
}
XrVector4f c[8];
for (int i = 0; i < 8; i++) {
const XrVector4f corner = {(i & 1) != 0 ? maxs->x : mins->x, (i & 2) != 0 ? maxs->y : mins->y,
(i & 4) != 0 ? maxs->z : mins->z, 1.0f};
XrMatrix4x4f_TransformVector4f(&c[i], mvp, &corner);
}
int i;
for (i = 0; i < 8; i++) {
if (c[i].x > -c[i].w) {
break;
}
}
if (i == 8) {
return true;
}
for (i = 0; i < 8; i++) {
if (c[i].x < c[i].w) {
break;
}
}
if (i == 8) {
return true;
}
for (i = 0; i < 8; i++) {
if (c[i].y > -c[i].w) {
break;
}
}
if (i == 8) {
return true;
}
for (i = 0; i < 8; i++) {
if (c[i].y < c[i].w) {
break;
}
}
if (i == 8) {
return true;
}
for (i = 0; i < 8; i++) {
if (c[i].z > -c[i].w) {
break;
}
}
if (i == 8) {
return true;
}
for (i = 0; i < 8; i++) {
if (c[i].z < c[i].w) {
break;
}
}
return i == 8;
}
#endif // XR_LINEAR_H_

View file

@ -0,0 +1,502 @@
#ifdef META_QUEST
#include "VrCommon.h"
extern ovrApp gAppState;
XrSpace CreateActionSpace(XrAction poseAction, XrPath subactionPath) {
XrActionSpaceCreateInfo asci = {};
asci.type = XR_TYPE_ACTION_SPACE_CREATE_INFO;
asci.action = poseAction;
asci.poseInActionSpace.orientation.w = 1.0f;
asci.subactionPath = subactionPath;
XrSpace actionSpace = XR_NULL_HANDLE;
OXR(xrCreateActionSpace(gAppState.Session, &asci, &actionSpace));
return actionSpace;
}
XrActionSuggestedBinding ActionSuggestedBinding(XrAction action, const char* bindingString) {
XrActionSuggestedBinding asb;
asb.action = action;
XrPath bindingPath;
OXR(xrStringToPath(gAppState.Instance, bindingString, &bindingPath));
asb.binding = bindingPath;
return asb;
}
XrActionSet CreateActionSet(int priority, const char* name, const char* localizedName) {
XrActionSetCreateInfo asci = {};
asci.type = XR_TYPE_ACTION_SET_CREATE_INFO;
asci.next = NULL;
asci.priority = priority;
strcpy(asci.actionSetName, name);
strcpy(asci.localizedActionSetName, localizedName);
XrActionSet actionSet = XR_NULL_HANDLE;
OXR(xrCreateActionSet(gAppState.Instance, &asci, &actionSet));
return actionSet;
}
XrAction CreateAction(
XrActionSet actionSet,
XrActionType type,
const char* actionName,
const char* localizedName,
int countSubactionPaths,
XrPath* subactionPaths) {
ALOGV("CreateAction %s, %" PRIi32, actionName, countSubactionPaths);
XrActionCreateInfo aci = {};
aci.type = XR_TYPE_ACTION_CREATE_INFO;
aci.next = NULL;
aci.actionType = type;
if (countSubactionPaths > 0) {
aci.countSubactionPaths = countSubactionPaths;
aci.subactionPaths = subactionPaths;
}
strcpy(aci.actionName, actionName);
strcpy(aci.localizedActionName, localizedName ? localizedName : actionName);
XrAction action = XR_NULL_HANDLE;
OXR(xrCreateAction(actionSet, &aci, &action));
return action;
}
bool ActionPoseIsActive(XrAction action, XrPath subactionPath) {
XrActionStateGetInfo getInfo = {};
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
getInfo.action = action;
getInfo.subactionPath = subactionPath;
XrActionStatePose state = {};
state.type = XR_TYPE_ACTION_STATE_POSE;
OXR(xrGetActionStatePose(gAppState.Session, &getInfo, &state));
return state.isActive != XR_FALSE;
}
XrActionStateFloat GetActionStateFloat(XrAction action) {
XrActionStateGetInfo getInfo = {};
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
getInfo.action = action;
XrActionStateFloat state = {};
state.type = XR_TYPE_ACTION_STATE_FLOAT;
OXR(xrGetActionStateFloat(gAppState.Session, &getInfo, &state));
return state;
}
XrActionStateBoolean GetActionStateBoolean(XrAction action) {
XrActionStateGetInfo getInfo = {};
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
getInfo.action = action;
XrActionStateBoolean state = {};
state.type = XR_TYPE_ACTION_STATE_BOOLEAN;
OXR(xrGetActionStateBoolean(gAppState.Session, &getInfo, &state));
return state;
}
XrActionStateVector2f GetActionStateVector2(XrAction action) {
XrActionStateGetInfo getInfo = {};
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
getInfo.action = action;
XrActionStateVector2f state = {};
state.type = XR_TYPE_ACTION_STATE_VECTOR2F;
OXR(xrGetActionStateVector2f(gAppState.Session, &getInfo, &state));
return state;
}
//OpenXR
XrPath leftHandPath;
XrPath rightHandPath;
XrAction handPoseLeftAction;
XrAction handPoseRightAction;
XrAction indexLeftAction;
XrAction indexRightAction;
XrAction menuAction;
XrAction buttonAAction;
XrAction buttonBAction;
XrAction buttonXAction;
XrAction buttonYAction;
XrAction gripLeftAction;
XrAction gripRightAction;
XrAction moveOnLeftJoystickAction;
XrAction moveOnRightJoystickAction;
XrAction thumbstickLeftClickAction;
XrAction thumbstickRightClickAction;
XrAction vibrateLeftFeedback;
XrAction vibrateRightFeedback;
XrActionSet runningActionSet;
XrSpace leftControllerAimSpace = XR_NULL_HANDLE;
XrSpace rightControllerAimSpace = XR_NULL_HANDLE;
bool inputInitialized = false;
bool useSimpleProfile = false;
void TBXR_InitActions( void )
{
// Actions
runningActionSet = CreateActionSet(1, "running_action_set", "Action Set used on main loop");
indexLeftAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "index_left", "Index left", 0, NULL);
indexRightAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "index_right", "Index right", 0, NULL);
menuAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "menu_action", "Menu", 0, NULL);
buttonAAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "button_a", "Button A", 0, NULL);
buttonBAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "button_b", "Button B", 0, NULL);
buttonXAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "button_x", "Button X", 0, NULL);
buttonYAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "button_y", "Button Y", 0, NULL);
gripLeftAction = CreateAction(runningActionSet, XR_ACTION_TYPE_FLOAT_INPUT, "grip_left", "Grip left", 0, NULL);
gripRightAction = CreateAction(runningActionSet, XR_ACTION_TYPE_FLOAT_INPUT, "grip_right", "Grip right", 0, NULL);
moveOnLeftJoystickAction = CreateAction(runningActionSet, XR_ACTION_TYPE_VECTOR2F_INPUT, "move_on_left_joy", "Move on left Joy", 0, NULL);
moveOnRightJoystickAction = CreateAction(runningActionSet, XR_ACTION_TYPE_VECTOR2F_INPUT, "move_on_right_joy", "Move on right Joy", 0, NULL);
thumbstickLeftClickAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "thumbstick_left", "Thumbstick left", 0, NULL);
thumbstickRightClickAction = CreateAction(runningActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "thumbstick_right", "Thumbstick right", 0, NULL);
vibrateLeftFeedback = CreateAction(runningActionSet, XR_ACTION_TYPE_VIBRATION_OUTPUT, "vibrate_left_feedback", "Vibrate Left Controller Feedback", 0, NULL);
vibrateRightFeedback = CreateAction(runningActionSet, XR_ACTION_TYPE_VIBRATION_OUTPUT, "vibrate_right_feedback", "Vibrate Right Controller Feedback", 0, NULL);
OXR(xrStringToPath(gAppState.Instance, "/user/hand/left", &leftHandPath));
OXR(xrStringToPath(gAppState.Instance, "/user/hand/right", &rightHandPath));
handPoseLeftAction = CreateAction(runningActionSet, XR_ACTION_TYPE_POSE_INPUT, "hand_pose_left", NULL, 1, &leftHandPath);
handPoseRightAction = CreateAction(runningActionSet, XR_ACTION_TYPE_POSE_INPUT, "hand_pose_right", NULL, 1, &rightHandPath);
if (leftControllerAimSpace == XR_NULL_HANDLE) {
leftControllerAimSpace = CreateActionSpace(handPoseLeftAction, leftHandPath);
}
if (rightControllerAimSpace == XR_NULL_HANDLE) {
rightControllerAimSpace = CreateActionSpace(handPoseRightAction, rightHandPath);
}
XrPath interactionProfilePath = XR_NULL_PATH;
XrPath interactionProfilePathTouch = XR_NULL_PATH;
XrPath interactionProfilePathKHRSimple = XR_NULL_PATH;
OXR(xrStringToPath(gAppState.Instance, "/interaction_profiles/oculus/touch_controller", &interactionProfilePathTouch));
OXR(xrStringToPath(gAppState.Instance, "/interaction_profiles/khr/simple_controller", &interactionProfilePathKHRSimple));
// Toggle this to force simple as a first choice, otherwise use it as a last resort
if (useSimpleProfile) {
ALOGV("xrSuggestInteractionProfileBindings found bindings for Khronos SIMPLE controller");
interactionProfilePath = interactionProfilePathKHRSimple;
} else {
// Query Set
XrActionSet queryActionSet = CreateActionSet(1, "query_action_set", "Action Set used to query device caps");
XrAction dummyAction = CreateAction(queryActionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "dummy_action", "Dummy Action", 0, NULL);
// Map bindings
XrActionSuggestedBinding bindings[1];
int currBinding = 0;
bindings[currBinding++] = ActionSuggestedBinding(dummyAction, "/user/hand/right/input/system/click");
XrInteractionProfileSuggestedBinding suggestedBindings = {};
suggestedBindings.type = XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING;
suggestedBindings.next = NULL;
suggestedBindings.suggestedBindings = bindings;
suggestedBindings.countSuggestedBindings = currBinding;
// Try all
suggestedBindings.interactionProfile = interactionProfilePathTouch;
XrResult suggestTouchResult = xrSuggestInteractionProfileBindings(gAppState.Instance, &suggestedBindings);
OXR(suggestTouchResult);
if (XR_SUCCESS == suggestTouchResult) {
ALOGV("xrSuggestInteractionProfileBindings found bindings for QUEST controller");
interactionProfilePath = interactionProfilePathTouch;
}
if (interactionProfilePath == XR_NULL_PATH) {
// Simple as a fallback
bindings[0] = ActionSuggestedBinding(dummyAction, "/user/hand/right/input/select/click");
suggestedBindings.interactionProfile = interactionProfilePathKHRSimple;
XrResult suggestKHRSimpleResult = xrSuggestInteractionProfileBindings(gAppState.Instance, &suggestedBindings);
OXR(suggestKHRSimpleResult);
if (XR_SUCCESS == suggestKHRSimpleResult) {
ALOGV("xrSuggestInteractionProfileBindings found bindings for Khronos SIMPLE controller");
interactionProfilePath = interactionProfilePathKHRSimple;
} else {
ALOGE("xrSuggestInteractionProfileBindings did NOT find any bindings.");
assert(false);
}
}
}
// Action creation
{
// Map bindings
XrActionSuggestedBinding bindings[32]; // large enough for all profiles
int currBinding = 0;
{
if (interactionProfilePath == interactionProfilePathTouch) {
bindings[currBinding++] = ActionSuggestedBinding(indexLeftAction, "/user/hand/left/input/trigger");
bindings[currBinding++] = ActionSuggestedBinding(indexRightAction, "/user/hand/right/input/trigger");
bindings[currBinding++] = ActionSuggestedBinding(menuAction, "/user/hand/left/input/menu/click");
bindings[currBinding++] = ActionSuggestedBinding(buttonXAction, "/user/hand/left/input/x/click");
bindings[currBinding++] = ActionSuggestedBinding(buttonYAction, "/user/hand/left/input/y/click");
bindings[currBinding++] = ActionSuggestedBinding(buttonAAction, "/user/hand/right/input/a/click");
bindings[currBinding++] = ActionSuggestedBinding(buttonBAction, "/user/hand/right/input/b/click");
bindings[currBinding++] = ActionSuggestedBinding(gripLeftAction, "/user/hand/left/input/squeeze/value");
bindings[currBinding++] = ActionSuggestedBinding(gripRightAction, "/user/hand/right/input/squeeze/value");
bindings[currBinding++] = ActionSuggestedBinding(moveOnLeftJoystickAction, "/user/hand/left/input/thumbstick");
bindings[currBinding++] = ActionSuggestedBinding(moveOnRightJoystickAction, "/user/hand/right/input/thumbstick");
bindings[currBinding++] = ActionSuggestedBinding(thumbstickLeftClickAction, "/user/hand/left/input/thumbstick/click");
bindings[currBinding++] = ActionSuggestedBinding(thumbstickRightClickAction, "/user/hand/right/input/thumbstick/click");
bindings[currBinding++] = ActionSuggestedBinding(vibrateLeftFeedback, "/user/hand/left/output/haptic");
bindings[currBinding++] = ActionSuggestedBinding(vibrateRightFeedback, "/user/hand/right/output/haptic");
bindings[currBinding++] = ActionSuggestedBinding(handPoseLeftAction, "/user/hand/left/input/aim/pose");
bindings[currBinding++] = ActionSuggestedBinding(handPoseRightAction, "/user/hand/right/input/aim/pose");
}
if (interactionProfilePath == interactionProfilePathKHRSimple) {
bindings[currBinding++] = ActionSuggestedBinding(indexLeftAction, "/user/hand/left/input/select/click");
bindings[currBinding++] = ActionSuggestedBinding(indexRightAction, "/user/hand/right/input/select/click");
bindings[currBinding++] = ActionSuggestedBinding(buttonAAction, "/user/hand/left/input/menu/click");
bindings[currBinding++] = ActionSuggestedBinding(buttonXAction, "/user/hand/right/input/menu/click");
bindings[currBinding++] = ActionSuggestedBinding(vibrateLeftFeedback, "/user/hand/left/output/haptic");
bindings[currBinding++] = ActionSuggestedBinding(vibrateRightFeedback, "/user/hand/right/output/haptic");
bindings[currBinding++] = ActionSuggestedBinding(handPoseLeftAction, "/user/hand/left/input/aim/pose");
bindings[currBinding++] = ActionSuggestedBinding(handPoseRightAction, "/user/hand/right/input/aim/pose");
}
}
XrInteractionProfileSuggestedBinding suggestedBindings = {};
suggestedBindings.type = XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING;
suggestedBindings.next = NULL;
suggestedBindings.interactionProfile = interactionProfilePath;
suggestedBindings.suggestedBindings = bindings;
suggestedBindings.countSuggestedBindings = currBinding;
OXR(xrSuggestInteractionProfileBindings(gAppState.Instance, &suggestedBindings));
// Enumerate actions
XrPath actionPathsBuffer[32];
char stringBuffer[256];
XrAction actionsToEnumerate[] = {
indexLeftAction,
indexRightAction,
menuAction,
buttonAAction,
buttonBAction,
buttonXAction,
buttonYAction,
gripLeftAction,
gripRightAction,
moveOnLeftJoystickAction,
moveOnRightJoystickAction,
thumbstickLeftClickAction,
thumbstickRightClickAction,
vibrateLeftFeedback,
vibrateRightFeedback,
handPoseLeftAction,
handPoseRightAction
};
for (size_t i = 0; i < sizeof(actionsToEnumerate) / sizeof(actionsToEnumerate[0]); ++i) {
XrBoundSourcesForActionEnumerateInfo enumerateInfo = {};
enumerateInfo.type = XR_TYPE_BOUND_SOURCES_FOR_ACTION_ENUMERATE_INFO;
enumerateInfo.next = NULL;
enumerateInfo.action = actionsToEnumerate[i];
// Get Count
uint32_t countOutput = 0;
OXR(xrEnumerateBoundSourcesForAction(
gAppState.Session, &enumerateInfo, 0 /* request size */, &countOutput, NULL));
ALOGV(
"xrEnumerateBoundSourcesForAction action=%lld count=%u",
(long long)enumerateInfo.action,
countOutput);
if (countOutput < 32) {
OXR(xrEnumerateBoundSourcesForAction(
gAppState.Session, &enumerateInfo, 32, &countOutput, actionPathsBuffer));
for (uint32_t a = 0; a < countOutput; ++a) {
XrInputSourceLocalizedNameGetInfo nameGetInfo = {};
nameGetInfo.type = XR_TYPE_INPUT_SOURCE_LOCALIZED_NAME_GET_INFO;
nameGetInfo.next = NULL;
nameGetInfo.sourcePath = actionPathsBuffer[a];
nameGetInfo.whichComponents = XR_INPUT_SOURCE_LOCALIZED_NAME_USER_PATH_BIT |
XR_INPUT_SOURCE_LOCALIZED_NAME_INTERACTION_PROFILE_BIT |
XR_INPUT_SOURCE_LOCALIZED_NAME_COMPONENT_BIT;
uint32_t stringCount = 0u;
OXR(xrGetInputSourceLocalizedName(
gAppState.Session, &nameGetInfo, 0, &stringCount, NULL));
if (stringCount < 256) {
OXR(xrGetInputSourceLocalizedName(
gAppState.Session, &nameGetInfo, 256, &stringCount, stringBuffer));
char pathStr[256];
uint32_t strLen = 0;
OXR(xrPathToString(
gAppState.Instance,
actionPathsBuffer[a],
(uint32_t)sizeof(pathStr),
&strLen,
pathStr));
ALOGV(
" -> path = %lld `%s` -> `%s`",
(long long)actionPathsBuffer[a],
pathStr,
stringBuffer);
}
}
}
}
}
// Attach to session
XrSessionActionSetsAttachInfo attachInfo = {};
attachInfo.type = XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO;
attachInfo.next = NULL;
attachInfo.countActionSets = 1;
attachInfo.actionSets = &runningActionSet;
OXR(xrAttachSessionActionSets(gAppState.Session, &attachInfo));
inputInitialized = true;
}
void TBXR_SyncActions( void )
{
// sync action data
XrActiveActionSet activeActionSet = {};
activeActionSet.actionSet = runningActionSet;
activeActionSet.subactionPath = XR_NULL_PATH;
XrActionsSyncInfo syncInfo = {};
syncInfo.type = XR_TYPE_ACTIONS_SYNC_INFO;
syncInfo.next = NULL;
syncInfo.countActiveActionSets = 1;
syncInfo.activeActionSets = &activeActionSet;
OXR(xrSyncActions(gAppState.Session, &syncInfo));
// query input action states
XrActionStateGetInfo getInfo = {};
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
getInfo.next = NULL;
getInfo.subactionPath = XR_NULL_PATH;
}
void TBXR_UpdateControllers( )
{
TBXR_SyncActions();
//get controller poses
XrAction controller[] = {handPoseLeftAction, handPoseRightAction};
XrPath subactionPath[] = {leftHandPath, rightHandPath};
XrSpace controllerSpace[] = {leftControllerAimSpace, rightControllerAimSpace};
for (int i = 0; i < 2; i++) {
if (ActionPoseIsActive(controller[i], subactionPath[i])) {
XrSpaceVelocity vel = {};
vel.type = XR_TYPE_SPACE_VELOCITY;
XrSpaceLocation loc = {};
loc.type = XR_TYPE_SPACE_LOCATION;
loc.next = &vel;
OXR(xrLocateSpace(controllerSpace[i], gAppState.CurrentSpace, gAppState.FrameState.predictedDisplayTime, &loc));
gAppState.TrackedController[i].Active = (loc.locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT) != 0;
gAppState.TrackedController[i].Pose = loc.pose;
gAppState.TrackedController[i].Velocity = vel;
} else {
ovrTrackedController_Clear(&gAppState.TrackedController[i]);
}
}
leftRemoteTracking_new = gAppState.TrackedController[0];
rightRemoteTracking_new = gAppState.TrackedController[1];
memset(&leftTrackedRemoteState_new, 0, sizeof leftTrackedRemoteState_new);
memset(&rightTrackedRemoteState_new, 0, sizeof rightTrackedRemoteState_new);
//button mapping
if (GetActionStateBoolean(menuAction).currentState) leftTrackedRemoteState_new.Buttons |= xrButton_Enter;
if (GetActionStateBoolean(buttonXAction).currentState) leftTrackedRemoteState_new.Buttons |= xrButton_X;
if (GetActionStateBoolean(buttonYAction).currentState) leftTrackedRemoteState_new.Buttons |= xrButton_Y;
leftTrackedRemoteState_new.GripTrigger = GetActionStateFloat(gripLeftAction).currentState;
if (leftTrackedRemoteState_new.GripTrigger > 0.5f) leftTrackedRemoteState_new.Buttons |= xrButton_GripTrigger;
if (GetActionStateBoolean(thumbstickLeftClickAction).currentState) leftTrackedRemoteState_new.Buttons |= xrButton_LThumb;
if (GetActionStateBoolean(buttonAAction).currentState) rightTrackedRemoteState_new.Buttons |= xrButton_A;
if (GetActionStateBoolean(buttonBAction).currentState) rightTrackedRemoteState_new.Buttons |= xrButton_B;
rightTrackedRemoteState_new.GripTrigger = GetActionStateFloat(gripRightAction).currentState;
if (rightTrackedRemoteState_new.GripTrigger > 0.5f) rightTrackedRemoteState_new.Buttons |= xrButton_GripTrigger;
if (GetActionStateBoolean(thumbstickRightClickAction).currentState) rightTrackedRemoteState_new.Buttons |= xrButton_RThumb;
//index finger click
if (GetActionStateBoolean(indexLeftAction).currentState) leftTrackedRemoteState_new.Buttons |= xrButton_Trigger;
if (GetActionStateBoolean(indexRightAction).currentState) rightTrackedRemoteState_new.Buttons |= xrButton_Trigger;
//thumbstick
XrActionStateVector2f moveJoystickState;
moveJoystickState = GetActionStateVector2(moveOnLeftJoystickAction);
leftTrackedRemoteState_new.Joystick.x = moveJoystickState.currentState.x;
leftTrackedRemoteState_new.Joystick.y = moveJoystickState.currentState.y;
moveJoystickState = GetActionStateVector2(moveOnRightJoystickAction);
rightTrackedRemoteState_new.Joystick.x = moveJoystickState.currentState.x;
rightTrackedRemoteState_new.Joystick.y = moveJoystickState.currentState.y;
}
//0 = left, 1 = right
float vibration_channel_duration[2] = {0.0f, 0.0f};
float vibration_channel_intensity[2] = {0.0f, 0.0f};
void TBXR_Vibrate( int duration, int chan, float intensity )
{
for (int i = 0; i < 2; ++i)
{
if ((i + 1) & chan)
{
if (vibration_channel_duration[i] > 0.0f)
return;
if (vibration_channel_duration[i] == -1.0f && duration != 0.0f)
return;
vibration_channel_duration[i] = duration;
vibration_channel_intensity[i] = intensity;
}
}
}
void TBXR_ProcessHaptics() {
static float lastFrameTime = 0.0f;
float timestamp = (float)(TBXR_GetTimeInMilliSeconds());
float frametime = timestamp - lastFrameTime;
lastFrameTime = timestamp;
for (int i = 0; i < 2; ++i) {
if (vibration_channel_duration[i] > 0.0f ||
vibration_channel_duration[i] == -1.0f) {
// fire haptics using output action
XrHapticVibration vibration = {};
vibration.type = XR_TYPE_HAPTIC_VIBRATION;
vibration.next = NULL;
vibration.amplitude = vibration_channel_intensity[i];
vibration.duration = ToXrTime(vibration_channel_duration[i]);
vibration.frequency = 3000;
XrHapticActionInfo hapticActionInfo = {};
hapticActionInfo.type = XR_TYPE_HAPTIC_ACTION_INFO;
hapticActionInfo.next = NULL;
hapticActionInfo.action = i == 0 ? vibrateLeftFeedback : vibrateRightFeedback;
OXR(xrApplyHapticFeedback(gAppState.Session, &hapticActionInfo, (const XrHapticBaseHeader*)&vibration));
if (vibration_channel_duration[i] != -1.0f) {
vibration_channel_duration[i] -= frametime;
if (vibration_channel_duration[i] < 0.0f) {
vibration_channel_duration[i] = 0.0f;
vibration_channel_intensity[i] = 0.0f;
}
}
} else {
// Stop haptics
XrHapticActionInfo hapticActionInfo = {};
hapticActionInfo.type = XR_TYPE_HAPTIC_ACTION_INFO;
hapticActionInfo.next = NULL;
hapticActionInfo.action = i == 0 ? vibrateLeftFeedback : vibrateRightFeedback;
OXR(xrStopHapticFeedback(gAppState.Session, &hapticActionInfo));
}
}
}
#endif

View file

@ -1,10 +1,12 @@
#ifdef PICO_XR
#include "VrCommon.h"
extern ovrApp gAppState;
XrResult CheckXrResult(XrResult res, const char* originator) {
if (XR_FAILED(res)) {
ALOGE("error: %s", originator);
dpsnprintf("error: %s", originator);
}
return res;
}
@ -16,36 +18,39 @@ XrResult CheckXrResult(XrResult res, const char* originator) {
#define SIDE_COUNT 2
XrActionSet actionSet = NULL;
XrAction grabAction = 0;
XrAction poseAction = 0;
XrAction vibrateAction = 0;
XrAction quitAction = 0;
XrAction touchpadAction = 0;
XrAction AXAction = 0;
XrAction homeAction = 0;
XrAction BYAction = 0;
XrAction backAction = 0;
XrAction sideAction = 0;
XrAction triggerAction = 0;
XrAction joystickAction = 0;
XrAction batteryAction = 0;
XrAction AXTouchAction = 0;
XrAction BYTouchAction = 0;
XrAction thumbstickTouchAction = 0;
XrAction TriggerTouchAction = 0;
XrAction ThumbrestTouchAction = 0;
XrAction GripAction = 0;
XrAction AAction = 0;
XrAction BAction = 0;
XrAction XAction = 0;
XrAction YAction = 0;
XrAction ATouchAction = 0;
XrAction BTouchAction = 0;
XrAction XTouchAction = 0;
XrAction YTouchAction = 0;
XrAction aimAction = 0;
XrActionSet actionSet;
XrAction grabAction;
XrAction poseAction;
XrAction vibrateAction;
XrAction quitAction;
/*************************pico******************/
XrAction touchpadAction;
XrAction AXAction;
XrAction homeAction;
XrAction BYAction;
XrAction backAction;
XrAction sideAction;
XrAction triggerAction;
XrAction joystickAction;
XrAction batteryAction;
//---add new----------
XrAction AXTouchAction;
XrAction BYTouchAction;
XrAction RockerTouchAction;
XrAction TriggerTouchAction;
XrAction ThumbrestTouchAction;
XrAction GripAction;
//---add new----------zgt
XrAction AAction;
XrAction BAction;
XrAction XAction;
XrAction YAction;
XrAction ATouchAction;
XrAction BTouchAction;
XrAction XTouchAction;
XrAction YTouchAction;
XrAction aimAction;
/*************************pico******************/
XrSpace aimSpace[SIDE_COUNT];
XrPath handSubactionPath[SIDE_COUNT];
XrSpace handSpace[SIDE_COUNT];
@ -63,13 +68,11 @@ XrActionStateBoolean GetActionStateBoolean(XrAction action, int hand) {
XrActionStateGetInfo getInfo = {};
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
getInfo.action = action;
getInfo.next = NULL;
if (hand >= 0)
getInfo.subactionPath = handSubactionPath[hand];
XrActionStateBoolean state = {};
state.type = XR_TYPE_ACTION_STATE_BOOLEAN;
state.next = NULL;
CHECK_XRCMD(xrGetActionStateBoolean(gAppState.Session, &getInfo, &state));
return state;
}
@ -78,13 +81,11 @@ XrActionStateFloat GetActionStateFloat(XrAction action, int hand) {
XrActionStateGetInfo getInfo = {};
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
getInfo.action = action;
getInfo.next = NULL;
if (hand >= 0)
getInfo.subactionPath = handSubactionPath[hand];
XrActionStateFloat state = {};
state.type = XR_TYPE_ACTION_STATE_FLOAT;
state.next = NULL;
CHECK_XRCMD(xrGetActionStateFloat(gAppState.Session, &getInfo, &state));
return state;
}
@ -93,41 +94,15 @@ XrActionStateVector2f GetActionStateVector2(XrAction action, int hand) {
XrActionStateGetInfo getInfo = {};
getInfo.type = XR_TYPE_ACTION_STATE_GET_INFO;
getInfo.action = action;
getInfo.next = NULL;
if (hand >= 0)
getInfo.subactionPath = handSubactionPath[hand];
XrActionStateVector2f state = {};
state.type = XR_TYPE_ACTION_STATE_VECTOR2F;
state.next = NULL;
CHECK_XRCMD(xrGetActionStateVector2f(gAppState.Session, &getInfo, &state));
return state;
}
void CreateAction(
XrActionSet actionSet,
XrActionType type,
const char* actionName,
const char* localizedName,
int countSubactionPaths,
XrPath* subactionPaths,
XrAction* action) {
ALOGV("CreateAction %s, %", actionName, countSubactionPaths);
XrActionCreateInfo aci = {};
aci.type = XR_TYPE_ACTION_CREATE_INFO;
aci.next = NULL;
aci.actionType = type;
if (countSubactionPaths > 0) {
aci.countSubactionPaths = countSubactionPaths;
aci.subactionPaths = subactionPaths;
}
strcpy(aci.actionName, actionName);
strcpy(aci.localizedActionName, localizedName ? localizedName : actionName);
*action = XR_NULL_HANDLE;
OXR(xrCreateAction(actionSet, &aci, action));
}
void TBXR_InitActions( void )
{
// Create an action set.
@ -137,7 +112,6 @@ void TBXR_InitActions( void )
strcpy(actionSetInfo.actionSetName, "gameplay");
strcpy(actionSetInfo.localizedActionSetName, "Gameplay");
actionSetInfo.priority = 0;
actionSetInfo.next = NULL;
CHECK_XRCMD(xrCreateActionSet(gAppState.Instance, &actionSetInfo, &actionSet));
}
@ -148,40 +122,214 @@ void TBXR_InitActions( void )
// Create actions.
{
// Create an input action for grabbing objects with the left and right hands.
CreateAction(actionSet, XR_ACTION_TYPE_POSE_INPUT, "grab_object", "Grab Object", SIDE_COUNT, handSubactionPath, &grabAction);
XrActionCreateInfo actionInfo = {};
actionInfo.type = XR_TYPE_ACTION_CREATE_INFO;
actionInfo.actionType = XR_ACTION_TYPE_FLOAT_INPUT;
strcpy(actionInfo.actionName, "grab_object");
strcpy(actionInfo.localizedActionName, "Grab Object");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &grabAction));
// Create an input action getting the left and right hand poses.
CreateAction(actionSet, XR_ACTION_TYPE_POSE_INPUT, "hand_pose", "Hand Pose", SIDE_COUNT, handSubactionPath, &poseAction);
CreateAction(actionSet, XR_ACTION_TYPE_POSE_INPUT, "aim_pose", "Aim Pose", SIDE_COUNT, handSubactionPath, &aimAction);
actionInfo.actionType = XR_ACTION_TYPE_POSE_INPUT;
strcpy(actionInfo.actionName, "hand_pose");
strcpy(actionInfo.localizedActionName, "Hand Pose");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &poseAction));
actionInfo.actionType = XR_ACTION_TYPE_POSE_INPUT;
strcpy(actionInfo.actionName, "aim_pose");
strcpy(actionInfo.localizedActionName, "Aim Pose");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &aimAction));
// Create output actions for vibrating the left and right controller.
CreateAction(actionSet, XR_ACTION_TYPE_VIBRATION_OUTPUT, "vibrate_hand", "Vibrate Hand", SIDE_COUNT, handSubactionPath, &vibrateAction);
actionInfo.actionType = XR_ACTION_TYPE_VIBRATION_OUTPUT;
strcpy(actionInfo.actionName, "vibrate_hand");
strcpy(actionInfo.localizedActionName, "Vibrate Hand");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &vibrateAction));
// Create input actions for quitting the session using the left and right controller.
// Since it doesn't matter which hand did this, we do not specify subaction paths for it.
// We will just suggest bindings for both hands, where possible.
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
strcpy(actionInfo.actionName, "quit_session");
strcpy(actionInfo.localizedActionName, "Quit Session");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &quitAction));
/**********************************pico***************************************/
// Create input actions for toucpad key using the left and right controller.
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
strcpy(actionInfo.actionName, "touchpad");
strcpy(actionInfo.localizedActionName, "Touchpad");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &touchpadAction));
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
strcpy(actionInfo.actionName, "axkey");
strcpy(actionInfo.localizedActionName, "AXkey");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &AXAction));
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
strcpy(actionInfo.actionName, "homekey");
strcpy(actionInfo.localizedActionName, "Homekey");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &homeAction));
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
strcpy(actionInfo.actionName, "bykey");
strcpy(actionInfo.localizedActionName, "BYkey");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &BYAction));
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
strcpy(actionInfo.actionName, "backkey");
strcpy(actionInfo.localizedActionName, "Backkey");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &backAction));
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
strcpy(actionInfo.actionName, "sidekey");
strcpy(actionInfo.localizedActionName, "Sidekey");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &sideAction));
actionInfo.actionType = XR_ACTION_TYPE_FLOAT_INPUT;
strcpy(actionInfo.actionName, "trigger");
strcpy(actionInfo.localizedActionName, "Trigger");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &triggerAction));
actionInfo.actionType = XR_ACTION_TYPE_VECTOR2F_INPUT;
strcpy(actionInfo.actionName, "joystick");
strcpy(actionInfo.localizedActionName, "Joystick");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &joystickAction));
actionInfo.actionType = XR_ACTION_TYPE_FLOAT_INPUT;
strcpy(actionInfo.actionName, "battery");
strcpy(actionInfo.localizedActionName, "battery");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &batteryAction));
//------------------------add new---------------------------------
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
strcpy(actionInfo.actionName, "axtouch");
strcpy(actionInfo.localizedActionName, "AXtouch");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &AXTouchAction));
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
strcpy(actionInfo.actionName, "bytouch");
strcpy(actionInfo.localizedActionName, "BYtouch");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &BYTouchAction));
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
strcpy(actionInfo.actionName, "rockertouch");
strcpy(actionInfo.localizedActionName, "Rockertouch");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &RockerTouchAction));
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
strcpy(actionInfo.actionName, "triggertouch");
strcpy(actionInfo.localizedActionName, "Triggertouch");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &TriggerTouchAction));
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
strcpy(actionInfo.actionName, "thumbresttouch");
strcpy(actionInfo.localizedActionName, "Thumbresttouch");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &ThumbrestTouchAction));
actionInfo.actionType = XR_ACTION_TYPE_FLOAT_INPUT;
strcpy(actionInfo.actionName, "gripvalue");
strcpy(actionInfo.localizedActionName, "GripValue");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &GripAction));
//--------------add new----------zgt
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
strcpy(actionInfo.actionName, "akey");
strcpy(actionInfo.localizedActionName, "Akey");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &AAction));
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
strcpy(actionInfo.actionName, "bkey");
strcpy(actionInfo.localizedActionName, "Bkey");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &BAction));
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
strcpy(actionInfo.actionName, "xkey");
strcpy(actionInfo.localizedActionName, "Xkey");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &XAction));
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
strcpy(actionInfo.actionName, "ykey");
strcpy(actionInfo.localizedActionName, "Ykey");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &YAction));
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
strcpy(actionInfo.actionName, "atouch");
strcpy(actionInfo.localizedActionName, "Atouch");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &ATouchAction));
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
strcpy(actionInfo.actionName, "btouch");
strcpy(actionInfo.localizedActionName, "Btouch");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &BTouchAction));
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
strcpy(actionInfo.actionName, "xtouch");
strcpy(actionInfo.localizedActionName, "Xtouch");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &XTouchAction));
actionInfo.actionType = XR_ACTION_TYPE_BOOLEAN_INPUT;
strcpy(actionInfo.actionName, "ytouch");
strcpy(actionInfo.localizedActionName, "Ytouch");
actionInfo.countSubactionPaths = SIDE_COUNT;
actionInfo.subactionPaths = handSubactionPath;
CHECK_XRCMD(xrCreateAction(actionSet, &actionInfo, &YTouchAction));
/**********************************pico***************************************/
//All remaining actions (not necessarily supported by all controllers)
CreateAction(actionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "quit_session", "Quit Session", SIDE_COUNT, handSubactionPath, &quitAction);
CreateAction(actionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "touchpad", "Touchpad", SIDE_COUNT, handSubactionPath, &touchpadAction);
CreateAction(actionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "axkey", "AXkey", SIDE_COUNT, handSubactionPath, &AXAction);
CreateAction(actionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "homekey", "Homekey", SIDE_COUNT, handSubactionPath, &homeAction);
CreateAction(actionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "bykey", "BYkey", SIDE_COUNT, handSubactionPath, &BYAction);
CreateAction(actionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "backkey", "Backkey", SIDE_COUNT, handSubactionPath, &backAction);
CreateAction(actionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "sidekey", "Sidekey", SIDE_COUNT, handSubactionPath, &sideAction);
CreateAction(actionSet, XR_ACTION_TYPE_FLOAT_INPUT, "trigger", "Trigger", SIDE_COUNT, handSubactionPath, &triggerAction);
CreateAction(actionSet, XR_ACTION_TYPE_VECTOR2F_INPUT, "joystick", "Joystick", SIDE_COUNT, handSubactionPath, &joystickAction);
CreateAction(actionSet, XR_ACTION_TYPE_FLOAT_INPUT, "battery", "battery", SIDE_COUNT, handSubactionPath, &batteryAction);
CreateAction(actionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "axtouch", "AXtouch", SIDE_COUNT, handSubactionPath, &AXTouchAction);
CreateAction(actionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "bytouch", "BYtouch", SIDE_COUNT, handSubactionPath, &BYTouchAction);
CreateAction(actionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "rockertouch", "Rockertouch", SIDE_COUNT, handSubactionPath, &thumbstickTouchAction);
CreateAction(actionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "triggertouch", "Triggertouch", SIDE_COUNT, handSubactionPath, &TriggerTouchAction);
CreateAction(actionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "thumbresttouch", "Thumbresttouch", SIDE_COUNT, handSubactionPath, &ThumbrestTouchAction);
CreateAction(actionSet, XR_ACTION_TYPE_FLOAT_INPUT, "gripvalue", "GripValue", SIDE_COUNT, handSubactionPath, &GripAction);
CreateAction(actionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "akey", "Akey", SIDE_COUNT, handSubactionPath, &AAction);
CreateAction(actionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "bkey", "Bkey", SIDE_COUNT, handSubactionPath, &BAction);
CreateAction(actionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "xkey", "Xkey", SIDE_COUNT, handSubactionPath, &XAction);
CreateAction(actionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "ykey", "Ykey", SIDE_COUNT, handSubactionPath, &YAction);
CreateAction(actionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "atouch", "Atouch", SIDE_COUNT, handSubactionPath, &ATouchAction);
CreateAction(actionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "btouch", "Btouch", SIDE_COUNT, handSubactionPath, &BTouchAction);
CreateAction(actionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "xtouch", "Xtouch", SIDE_COUNT, handSubactionPath, &XTouchAction);
CreateAction(actionSet, XR_ACTION_TYPE_BOOLEAN_INPUT, "ytouch", "Ytouch", SIDE_COUNT, handSubactionPath, &YTouchAction);
}
XrPath selectPath[SIDE_COUNT];
@ -199,6 +347,7 @@ void TBXR_InitActions( void )
XrPath thumbstickPosPath[SIDE_COUNT];
XrPath aimPath[SIDE_COUNT];
/**************************pico************************************/
XrPath touchpadPath[SIDE_COUNT];
XrPath AXValuePath[SIDE_COUNT];
XrPath homeClickPath[SIDE_COUNT];
@ -208,14 +357,14 @@ void TBXR_InitActions( void )
XrPath triggerPath[SIDE_COUNT];
XrPath joystickPath[SIDE_COUNT];
XrPath batteryPath[SIDE_COUNT];
//--------------add new----------
XrPath GripPath[SIDE_COUNT];
XrPath AXTouchPath[SIDE_COUNT];
XrPath BYTouchPath[SIDE_COUNT];
XrPath RockerTouchPath[SIDE_COUNT];
XrPath TriggerTouchPath[SIDE_COUNT];
XrPath ThumbresetTouchPath[SIDE_COUNT];
//--------------add new----------zgt
XrPath AValuePath[SIDE_COUNT];
XrPath BValuePath[SIDE_COUNT];
XrPath XValuePath[SIDE_COUNT];
@ -224,7 +373,7 @@ void TBXR_InitActions( void )
XrPath BTouchPath[SIDE_COUNT];
XrPath XTouchPath[SIDE_COUNT];
XrPath YTouchPath[SIDE_COUNT];
/**************************pico************************************/
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/left/input/select/click", &selectPath[SIDE_LEFT]));
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/right/input/select/click", &selectPath[SIDE_RIGHT]));
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/left/input/menu/click", &menuClickPath[SIDE_LEFT]));
@ -259,6 +408,7 @@ void TBXR_InitActions( void )
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/left/input/thumbrest/touch", &thumbrestPath[SIDE_LEFT]));
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/right/input/thumbrest/touch", &thumbrestPath[SIDE_RIGHT]));
/**************************pico************************************/
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/left/input/back/click", &backPath[SIDE_LEFT]));
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/right/input/back/click", &backPath[SIDE_RIGHT]));
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/left/input/battery/value", &batteryPath[SIDE_LEFT]));
@ -272,24 +422,22 @@ void TBXR_InitActions( void )
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/left/input/y/touch", &YTouchPath[SIDE_LEFT]));
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/right/input/a/touch", &ATouchPath[SIDE_RIGHT]));
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/right/input/b/touch", &BTouchPath[SIDE_RIGHT]));
/**************************pico************************************/
XrActionSuggestedBinding bindings[128];
int currBinding = 0;
XrResult result;
//First try Pico Devices
// Suggest bindings for the Pico Neo 3 controller
{
XrPath picoMixedRealityInteractionProfilePath;
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/interaction_profiles/pico/neo3_controller",
&picoMixedRealityInteractionProfilePath));
XrActionSuggestedBinding bindings[128];
int currBinding = 0;
bindings[currBinding++] = ActionSuggestedBinding(touchpadAction, thumbstickClickPath[SIDE_LEFT]);
bindings[currBinding++] = ActionSuggestedBinding(touchpadAction, thumbstickClickPath[SIDE_RIGHT]);
bindings[currBinding++] = ActionSuggestedBinding(joystickAction, thumbstickPosPath[SIDE_LEFT]);
bindings[currBinding++] = ActionSuggestedBinding(joystickAction, thumbstickPosPath[SIDE_RIGHT]);
bindings[currBinding++] = ActionSuggestedBinding(thumbstickTouchAction, thumbstickTouchPath[SIDE_LEFT]);
bindings[currBinding++] = ActionSuggestedBinding(thumbstickTouchAction, thumbstickTouchPath[SIDE_RIGHT]);
bindings[currBinding++] = ActionSuggestedBinding(RockerTouchAction, thumbstickTouchPath[SIDE_LEFT]);
bindings[currBinding++] = ActionSuggestedBinding(RockerTouchAction, thumbstickTouchPath[SIDE_RIGHT]);
bindings[currBinding++] = ActionSuggestedBinding(triggerAction, triggerValuePath[SIDE_LEFT]);
bindings[currBinding++] = ActionSuggestedBinding(triggerAction, triggerValuePath[SIDE_RIGHT]);
@ -331,60 +479,7 @@ void TBXR_InitActions( void )
suggestedBindings.interactionProfile = picoMixedRealityInteractionProfilePath;
suggestedBindings.suggestedBindings = bindings;
suggestedBindings.countSuggestedBindings = currBinding;
suggestedBindings.next = NULL;
result = xrSuggestInteractionProfileBindings(gAppState.Instance, &suggestedBindings);
}
if (result != XR_SUCCESS)
{
XrPath touchControllerInteractionProfilePath;
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/interaction_profiles/oculus/touch_controller",
&touchControllerInteractionProfilePath));
XrActionSuggestedBinding bindings[128];
int currBinding = 0;
bindings[currBinding++] = ActionSuggestedBinding(touchpadAction, thumbstickClickPath[SIDE_LEFT]);
bindings[currBinding++] = ActionSuggestedBinding(touchpadAction, thumbstickClickPath[SIDE_RIGHT]);
bindings[currBinding++] = ActionSuggestedBinding(joystickAction, thumbstickPosPath[SIDE_LEFT]);
bindings[currBinding++] = ActionSuggestedBinding(joystickAction, thumbstickPosPath[SIDE_RIGHT]);
bindings[currBinding++] = ActionSuggestedBinding(thumbstickTouchAction, thumbstickTouchPath[SIDE_LEFT]);
bindings[currBinding++] = ActionSuggestedBinding(thumbstickTouchAction, thumbstickTouchPath[SIDE_RIGHT]);
bindings[currBinding++] = ActionSuggestedBinding(triggerAction, triggerValuePath[SIDE_LEFT]);
bindings[currBinding++] = ActionSuggestedBinding(triggerAction, triggerValuePath[SIDE_RIGHT]);
bindings[currBinding++] = ActionSuggestedBinding(TriggerTouchAction, triggerTouchPath[SIDE_LEFT]);
bindings[currBinding++] = ActionSuggestedBinding(TriggerTouchAction, triggerTouchPath[SIDE_RIGHT]);
bindings[currBinding++] = ActionSuggestedBinding(GripAction, squeezeValuePath[SIDE_LEFT]);
bindings[currBinding++] = ActionSuggestedBinding(GripAction, squeezeValuePath[SIDE_RIGHT]);
bindings[currBinding++] = ActionSuggestedBinding(poseAction, posePath[SIDE_LEFT]);
bindings[currBinding++] = ActionSuggestedBinding(poseAction, posePath[SIDE_RIGHT]);
bindings[currBinding++] = ActionSuggestedBinding(backAction, menuClickPath[SIDE_LEFT]);
bindings[currBinding++] = ActionSuggestedBinding(ThumbrestTouchAction, thumbrestPath[SIDE_LEFT]);
bindings[currBinding++] = ActionSuggestedBinding(ThumbrestTouchAction, thumbrestPath[SIDE_RIGHT]);
bindings[currBinding++] = ActionSuggestedBinding(vibrateAction, hapticPath[SIDE_LEFT]);
bindings[currBinding++] = ActionSuggestedBinding(vibrateAction, hapticPath[SIDE_RIGHT]);
bindings[currBinding++] = ActionSuggestedBinding(XTouchAction, XTouchPath[SIDE_LEFT]);
bindings[currBinding++] = ActionSuggestedBinding(YTouchAction, YTouchPath[SIDE_LEFT]);
bindings[currBinding++] = ActionSuggestedBinding(ATouchAction, ATouchPath[SIDE_RIGHT]);
bindings[currBinding++] = ActionSuggestedBinding(BTouchAction, BTouchPath[SIDE_RIGHT]);
bindings[currBinding++] = ActionSuggestedBinding(XAction, XValuePath[SIDE_LEFT]);
bindings[currBinding++] = ActionSuggestedBinding(YAction, YValuePath[SIDE_LEFT]);
bindings[currBinding++] = ActionSuggestedBinding(AAction, AValuePath[SIDE_RIGHT]);
bindings[currBinding++] = ActionSuggestedBinding(BAction, BValuePath[SIDE_RIGHT]);
bindings[currBinding++] = ActionSuggestedBinding(aimAction, aimPath[SIDE_LEFT]);
bindings[currBinding++] = ActionSuggestedBinding(aimAction, aimPath[SIDE_RIGHT]);
XrInteractionProfileSuggestedBinding suggestedBindings = {};
suggestedBindings.type = XR_TYPE_INTERACTION_PROFILE_SUGGESTED_BINDING;
suggestedBindings.interactionProfile = touchControllerInteractionProfilePath;
suggestedBindings.suggestedBindings = bindings;
suggestedBindings.countSuggestedBindings = currBinding;
suggestedBindings.next = NULL;
result = xrSuggestInteractionProfileBindings(gAppState.Instance, &suggestedBindings);
CHECK_XRCMD(xrSuggestInteractionProfileBindings(gAppState.Instance, &suggestedBindings));
}
XrActionSpaceCreateInfo actionSpaceInfo = {};
@ -400,31 +495,25 @@ void TBXR_InitActions( void )
actionSpaceInfo.subactionPath = handSubactionPath[SIDE_LEFT];
CHECK_XRCMD(xrCreateActionSpace(gAppState.Session, &actionSpaceInfo, &aimSpace[SIDE_LEFT]));
actionSpaceInfo.subactionPath = handSubactionPath[SIDE_RIGHT];
actionSpaceInfo.next = NULL;
CHECK_XRCMD(xrCreateActionSpace(gAppState.Session, &actionSpaceInfo, &aimSpace[SIDE_RIGHT]));
XrSessionActionSetsAttachInfo attachInfo = {};
attachInfo.type = XR_TYPE_SESSION_ACTION_SETS_ATTACH_INFO;
attachInfo.countActionSets = 1;
attachInfo.actionSets = &actionSet;
attachInfo.next = NULL;
CHECK_XRCMD(xrAttachSessionActionSets(gAppState.Session, &attachInfo));
}
void TBXR_SyncActions( void )
{
if (actionSet)
{
XrActiveActionSet activeActionSet = {};
activeActionSet.actionSet = actionSet;
activeActionSet.subactionPath = XR_NULL_PATH;
XrActionsSyncInfo syncInfo;
syncInfo.type = XR_TYPE_ACTIONS_SYNC_INFO;
syncInfo.countActiveActionSets = 1;
syncInfo.activeActionSets = &activeActionSet;
syncInfo.next = NULL;
CHECK_XRCMD(xrSyncActions(gAppState.Session, &syncInfo));
}
XrActiveActionSet activeActionSet = {};
activeActionSet.actionSet = actionSet;
activeActionSet.subactionPath = XR_NULL_PATH;
XrActionsSyncInfo syncInfo;
syncInfo.type = XR_TYPE_ACTIONS_SYNC_INFO;
syncInfo.countActiveActionSets = 1;
syncInfo.activeActionSets = &activeActionSet;
CHECK_XRCMD(xrSyncActions(gAppState.Session, &syncInfo));
}
void TBXR_UpdateControllers( )
@ -440,7 +529,7 @@ void TBXR_UpdateControllers( )
loc.next = &vel;
XrResult res = xrLocateSpace(aimSpace[i], gAppState.CurrentSpace, gAppState.FrameState.predictedDisplayTime, &loc);
if (res != XR_SUCCESS) {
ALOGE("xrLocateSpace error: %d", (int)res);
dpsnprintf("xrLocateSpace error: %d", (int)res);
}
gAppState.TrackedController[i].Active = (loc.locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT) != 0;
@ -452,42 +541,23 @@ void TBXR_UpdateControllers( )
rightRemoteTracking_new = gAppState.TrackedController[1];
//button mapping
leftTrackedRemoteState_new.Buttons = 0;
leftTrackedRemoteState_new.Touches = 0;
if (GetActionStateBoolean(backAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Buttons |= xrButton_Enter;
if (GetActionStateBoolean(XAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Buttons |= xrButton_X;
if (GetActionStateBoolean(XTouchAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Touches |= xrButton_X;
if (GetActionStateBoolean(YAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Buttons |= xrButton_Y;
if (GetActionStateBoolean(YTouchAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Touches |= xrButton_Y;
leftTrackedRemoteState_new.GripTrigger = GetActionStateFloat(GripAction, SIDE_LEFT).currentState;
if (leftTrackedRemoteState_new.GripTrigger > 0.5f) leftTrackedRemoteState_new.Buttons |= xrButton_GripTrigger;
if (GetActionStateBoolean(sideAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Buttons |= xrButton_GripTrigger;
if (GetActionStateBoolean(touchpadAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Buttons |= xrButton_LThumb;
if (GetActionStateBoolean(touchpadAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Buttons |= xrButton_Joystick;
if (GetActionStateBoolean(thumbstickTouchAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Touches |= xrButton_LThumb;
if (GetActionStateBoolean(thumbstickTouchAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Touches |= xrButton_Joystick;
leftTrackedRemoteState_new.IndexTrigger = GetActionStateFloat(triggerAction, SIDE_LEFT).currentState;
if (leftTrackedRemoteState_new.IndexTrigger > 0.5f) leftTrackedRemoteState_new.Buttons |= xrButton_Trigger;
if (GetActionStateBoolean(TriggerTouchAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Touches |= xrButton_Trigger;
if (GetActionStateBoolean(ThumbrestTouchAction, SIDE_LEFT).currentState) leftTrackedRemoteState_new.Touches |= xrButton_ThumbRest;
if (GetActionStateFloat(triggerAction, SIDE_LEFT).currentState > 0.5f) leftTrackedRemoteState_new.Buttons |= xrButton_Trigger;
rightTrackedRemoteState_new.Buttons = 0;
rightTrackedRemoteState_new.Touches = 0;
if (GetActionStateBoolean(backAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Buttons |= xrButton_Enter;
if (GetActionStateBoolean(AAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Buttons |= xrButton_A;
if (GetActionStateBoolean(ATouchAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Touches |= xrButton_A;
if (GetActionStateBoolean(BAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Buttons |= xrButton_B;
if (GetActionStateBoolean(BTouchAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Touches |= xrButton_B;
rightTrackedRemoteState_new.GripTrigger = GetActionStateFloat(GripAction, SIDE_RIGHT).currentState;
if (rightTrackedRemoteState_new.GripTrigger > 0.5f) rightTrackedRemoteState_new.Buttons |= xrButton_GripTrigger;
if (GetActionStateBoolean(sideAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Buttons |= xrButton_GripTrigger;
if (GetActionStateBoolean(touchpadAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Buttons |= xrButton_RThumb;
if (GetActionStateBoolean(touchpadAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Buttons |= xrButton_Joystick;
if (GetActionStateBoolean(thumbstickTouchAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Touches |= xrButton_RThumb;
if (GetActionStateBoolean(thumbstickTouchAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Touches |= xrButton_Joystick;
rightTrackedRemoteState_new.IndexTrigger = GetActionStateFloat(triggerAction, SIDE_RIGHT).currentState;
if (rightTrackedRemoteState_new.IndexTrigger > 0.5f) rightTrackedRemoteState_new.Buttons |= xrButton_Trigger;
if (GetActionStateBoolean(TriggerTouchAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Touches |= xrButton_Trigger;
if (GetActionStateBoolean(ThumbrestTouchAction, SIDE_RIGHT).currentState) rightTrackedRemoteState_new.Touches |= xrButton_ThumbRest;
if (GetActionStateFloat(triggerAction, SIDE_RIGHT).currentState > 0.5f) rightTrackedRemoteState_new.Buttons |= xrButton_Trigger;
//thumbstick
XrActionStateVector2f moveJoystickState;
@ -500,7 +570,6 @@ void TBXR_UpdateControllers( )
rightTrackedRemoteState_new.Joystick.y = moveJoystickState.currentState.y;
}
//0 = left, 1 = right
float vibration_channel_duration[2] = {0.0f, 0.0f};
float vibration_channel_intensity[2] = {0.0f, 0.0f};
@ -509,17 +578,16 @@ void TBXR_Vibrate( int duration, int chan, float intensity )
{
for (int i = 0; i < 2; ++i)
{
int channel = i;
if ((i + 1) & chan)
{
if (vibration_channel_duration[channel] > 0.0f)
if (vibration_channel_duration[i] > 0.0f)
return;
if (vibration_channel_duration[channel] == -1.0f && duration != 0.0f)
if (vibration_channel_duration[i] == -1.0f && duration != 0.0f)
return;
vibration_channel_duration[channel] = duration;
vibration_channel_intensity[channel] = intensity;
vibration_channel_duration[i] = duration;
vibration_channel_intensity[i] = intensity;
}
}
}
@ -567,3 +635,4 @@ void TBXR_ProcessHaptics() {
}
}
}
#endif //PICO_XR

View file

@ -38,7 +38,7 @@ char **argv;
int argc=0;
float playerHeight;
float playerYaw = -999.0f;
float playerYaw;
extern float worldPosition[3];
float hmdPosition[3];
@ -186,7 +186,7 @@ void VR_SetHMDOrientation(float pitch, float yaw, float roll)
{
VectorSet(hmdorientation, pitch, yaw, roll);
if (!VR_UseScreenLayer() || playerYaw == -999.0f)
if (!VR_UseScreenLayer())
{
playerYaw = yaw;
}
@ -221,7 +221,7 @@ void VR_Init()
//init randomiser
srand(time(NULL));
chdir((char*)getenv("QUAKEQUEST_DIR"));
chdir("/sdcard/QuakeQuest");
}
extern int runStatus;
@ -331,27 +331,24 @@ void VR_FrameSetup()
bool VR_GetVRProjection(int eye, float zNear, float zFar, float* projection)
{
if (strstr(gAppState.OpenXRHMD, "pico") != NULL)
{
XrMatrix4x4f_CreateProjectionFov(
&(gAppState.ProjectionMatrices[eye]), GRAPHICS_OPENGL_ES,
gAppState.Projections[eye].fov, zNear, zFar);
}
#ifdef PICO_XR
XrMatrix4x4f_CreateProjectionFov(
&(gAppState.ProjectionMatrices[eye]), GRAPHICS_OPENGL_ES,
gAppState.Projections[eye].fov, zNear, zFar);
#endif
if (strstr(gAppState.OpenXRHMD, "meta") != NULL)
{
XrFovf fov = {};
for (int eye = 0; eye < ovrMaxNumEyes; eye++)
{
fov.angleLeft += gAppState.Projections[eye].fov.angleLeft / 2.0f;
fov.angleRight += gAppState.Projections[eye].fov.angleRight / 2.0f;
fov.angleUp += gAppState.Projections[eye].fov.angleUp / 2.0f;
fov.angleDown += gAppState.Projections[eye].fov.angleDown / 2.0f;
}
XrMatrix4x4f_CreateProjectionFov(
&(gAppState.ProjectionMatrices[eye]), GRAPHICS_OPENGL_ES,
fov, zNear, zFar);
}
#ifdef META_QUEST
XrFovf fov = {};
for (int eye = 0; eye < ovrMaxNumEyes; eye++) {
fov.angleLeft += gAppState.Projections[eye].fov.angleLeft / 2.0f;
fov.angleRight += gAppState.Projections[eye].fov.angleRight / 2.0f;
fov.angleUp += gAppState.Projections[eye].fov.angleUp / 2.0f;
fov.angleDown += gAppState.Projections[eye].fov.angleDown / 2.0f;
}
XrMatrix4x4f_CreateProjectionFov(
&(gAppState.ProjectionMatrices[eye]), GRAPHICS_OPENGL_ES,
fov, zNear, zFar);
#endif
memcpy(projection, gAppState.ProjectionMatrices[eye].m, 16 * sizeof(float));
return true;

View file

@ -54,13 +54,17 @@ float SS_MULTIPLIER = 1.3f;
GLboolean stageSupported = GL_FALSE;
const char* const requiredExtensionNames_meta[] = {
#ifdef META_QUEST
const char* const requiredExtensionNames[] = {
XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME,
XR_EXT_PERFORMANCE_SETTINGS_EXTENSION_NAME,
XR_KHR_ANDROID_THREAD_SETTINGS_EXTENSION_NAME,
XR_FB_DISPLAY_REFRESH_RATE_EXTENSION_NAME,
XR_FB_COLOR_SPACE_EXTENSION_NAME};
#endif //META_QUEST
#ifdef PICO_XR
#define XR_PICO_CONFIGS_EXT_EXTENSION_NAME "XR_PICO_configs_ext"
enum ConfigsEXT
@ -113,17 +117,16 @@ typedef XrResult (XRAPI_PTR *PFN_xrSetConfigPICO) (
char * configData);
PFN_xrSetConfigPICO pfnXrSetConfigPICO;
const char* const requiredExtensionNames_pico[] = {
const char* const requiredExtensionNames[] = {
XR_KHR_ANDROID_CREATE_INSTANCE_EXTENSION_NAME,
XR_EXT_PERFORMANCE_SETTINGS_EXTENSION_NAME,
XR_KHR_OPENGL_ES_ENABLE_EXTENSION_NAME,
XR_PICO_CONFIGS_EXT_EXTENSION_NAME};
#endif //PICO_XR
const uint32_t numRequiredExtensions_meta =
sizeof(requiredExtensionNames_meta) / sizeof(requiredExtensionNames_meta[0]);
const uint32_t numRequiredExtensions_pico =
sizeof(requiredExtensionNames_pico) / sizeof(requiredExtensionNames_pico[0]);
const uint32_t numRequiredExtensions =
sizeof(requiredExtensionNames) / sizeof(requiredExtensionNames[0]);
/*
@ -916,19 +919,18 @@ void ovrApp_HandleSessionStateChanges(ovrApp* app, XrSessionState state) {
OXR(pfnPerfSettingsSetPerformanceLevelEXT(
app->Session, XR_PERF_SETTINGS_DOMAIN_GPU_EXT, gpuPerfLevel));
if (strstr(gAppState.OpenXRHMD, "meta") != NULL)
{
PFN_xrSetAndroidApplicationThreadKHR pfnSetAndroidApplicationThreadKHR = NULL;
OXR(xrGetInstanceProcAddr(
app->Instance,
"xrSetAndroidApplicationThreadKHR",
(PFN_xrVoidFunction * )(&pfnSetAndroidApplicationThreadKHR)));
#ifdef META_QUEST
PFN_xrSetAndroidApplicationThreadKHR pfnSetAndroidApplicationThreadKHR = NULL;
OXR(xrGetInstanceProcAddr(
app->Instance,
"xrSetAndroidApplicationThreadKHR",
(PFN_xrVoidFunction * )(&pfnSetAndroidApplicationThreadKHR)));
OXR(pfnSetAndroidApplicationThreadKHR(
app->Session, XR_ANDROID_THREAD_TYPE_APPLICATION_MAIN_KHR, app->MainThreadTid));
OXR(pfnSetAndroidApplicationThreadKHR(
app->Session, XR_ANDROID_THREAD_TYPE_RENDERER_MAIN_KHR, app->RenderThreadTid));
}
OXR(pfnSetAndroidApplicationThreadKHR(
app->Session, XR_ANDROID_THREAD_TYPE_APPLICATION_MAIN_KHR, app->MainThreadTid));
OXR(pfnSetAndroidApplicationThreadKHR(
app->Session, XR_ANDROID_THREAD_TYPE_RENDERER_MAIN_KHR, app->RenderThreadTid));
#endif
}
} else if (state == XR_SESSION_STATE_STOPPING) {
assert(app->SessionActive);
@ -977,6 +979,7 @@ GLboolean ovrApp_HandleXrEvents(ovrApp* app) {
perf_settings_event->fromLevel,
perf_settings_event->toLevel);
} break;
#ifdef META_QUEST
case XR_TYPE_EVENT_DATA_DISPLAY_REFRESH_RATE_CHANGED_FB: {
const XrEventDataDisplayRefreshRateChangedFB* refresh_rate_changed_event =
(XrEventDataDisplayRefreshRateChangedFB*)(baseEventHeader);
@ -985,6 +988,7 @@ GLboolean ovrApp_HandleXrEvents(ovrApp* app) {
refresh_rate_changed_event->fromDisplayRefreshRate,
refresh_rate_changed_event->toDisplayRefreshRate);
} break;
#endif
case XR_TYPE_EVENT_DATA_REFERENCE_SPACE_CHANGE_PENDING: {
XrEventDataReferenceSpaceChangePending* ref_space_change_event =
(XrEventDataReferenceSpaceChangePending*)(baseEventHeader);
@ -1405,90 +1409,89 @@ void TBXR_InitRenderer( ) {
gAppState.Instance, gAppState.SystemId, XR_VIEW_CONFIGURATION_TYPE_PRIMARY_STEREO, &gAppState.ViewportConfig));
if (strstr(gAppState.OpenXRHMD, "meta") != NULL)
{
XrSystemColorSpacePropertiesFB colorSpacePropertiesFB = {};
colorSpacePropertiesFB.type = XR_TYPE_SYSTEM_COLOR_SPACE_PROPERTIES_FB;
#ifdef META_QUEST
XrSystemColorSpacePropertiesFB colorSpacePropertiesFB = {};
colorSpacePropertiesFB.type = XR_TYPE_SYSTEM_COLOR_SPACE_PROPERTIES_FB;
XrSystemProperties systemProperties = {};
systemProperties.type = XR_TYPE_SYSTEM_PROPERTIES;
systemProperties.next = &colorSpacePropertiesFB;
OXR(xrGetSystemProperties(gAppState.Instance, gAppState.SystemId, &systemProperties));
XrSystemProperties systemProperties = {};
systemProperties.type = XR_TYPE_SYSTEM_PROPERTIES;
systemProperties.next = &colorSpacePropertiesFB;
OXR(xrGetSystemProperties(gAppState.Instance, gAppState.SystemId, &systemProperties));
// Enumerate the supported color space options for the system.
{
PFN_xrEnumerateColorSpacesFB pfnxrEnumerateColorSpacesFB = NULL;
OXR(xrGetInstanceProcAddr(
gAppState.Instance,
"xrEnumerateColorSpacesFB",
(PFN_xrVoidFunction*)(&pfnxrEnumerateColorSpacesFB)));
// Enumerate the supported color space options for the system.
{
PFN_xrEnumerateColorSpacesFB pfnxrEnumerateColorSpacesFB = NULL;
OXR(xrGetInstanceProcAddr(
gAppState.Instance,
"xrEnumerateColorSpacesFB",
(PFN_xrVoidFunction*)(&pfnxrEnumerateColorSpacesFB)));
uint32_t colorSpaceCountOutput = 0;
OXR(pfnxrEnumerateColorSpacesFB(gAppState.Session, 0, &colorSpaceCountOutput, NULL));
uint32_t colorSpaceCountOutput = 0;
OXR(pfnxrEnumerateColorSpacesFB(gAppState.Session, 0, &colorSpaceCountOutput, NULL));
XrColorSpaceFB* colorSpaces =
(XrColorSpaceFB*)malloc(colorSpaceCountOutput * sizeof(XrColorSpaceFB));
XrColorSpaceFB* colorSpaces =
(XrColorSpaceFB*)malloc(colorSpaceCountOutput * sizeof(XrColorSpaceFB));
OXR(pfnxrEnumerateColorSpacesFB(
gAppState.Session, colorSpaceCountOutput, &colorSpaceCountOutput, colorSpaces));
ALOGV("Supported ColorSpaces:");
OXR(pfnxrEnumerateColorSpacesFB(
gAppState.Session, colorSpaceCountOutput, &colorSpaceCountOutput, colorSpaces));
ALOGV("Supported ColorSpaces:");
for (uint32_t i = 0; i < colorSpaceCountOutput; i++) {
ALOGV("%d:%d", i, colorSpaces[i]);
}
for (uint32_t i = 0; i < colorSpaceCountOutput; i++) {
ALOGV("%d:%d", i, colorSpaces[i]);
}
const XrColorSpaceFB requestColorSpace = XR_COLOR_SPACE_REC2020_FB;
const XrColorSpaceFB requestColorSpace = XR_COLOR_SPACE_REC2020_FB;
PFN_xrSetColorSpaceFB pfnxrSetColorSpaceFB = NULL;
OXR(xrGetInstanceProcAddr(
gAppState.Instance, "xrSetColorSpaceFB", (PFN_xrVoidFunction*)(&pfnxrSetColorSpaceFB)));
PFN_xrSetColorSpaceFB pfnxrSetColorSpaceFB = NULL;
OXR(xrGetInstanceProcAddr(
gAppState.Instance, "xrSetColorSpaceFB", (PFN_xrVoidFunction*)(&pfnxrSetColorSpaceFB)));
OXR(pfnxrSetColorSpaceFB(gAppState.Session, requestColorSpace));
OXR(pfnxrSetColorSpaceFB(gAppState.Session, requestColorSpace));
free(colorSpaces);
}
free(colorSpaces);
}
// Get the supported display refresh rates for the system.
{
PFN_xrEnumerateDisplayRefreshRatesFB pfnxrEnumerateDisplayRefreshRatesFB = NULL;
OXR(xrGetInstanceProcAddr(
gAppState.Instance,
"xrEnumerateDisplayRefreshRatesFB",
(PFN_xrVoidFunction*)(&pfnxrEnumerateDisplayRefreshRatesFB)));
// Get the supported display refresh rates for the system.
{
PFN_xrEnumerateDisplayRefreshRatesFB pfnxrEnumerateDisplayRefreshRatesFB = NULL;
OXR(xrGetInstanceProcAddr(
gAppState.Instance,
"xrEnumerateDisplayRefreshRatesFB",
(PFN_xrVoidFunction*)(&pfnxrEnumerateDisplayRefreshRatesFB)));
OXR(pfnxrEnumerateDisplayRefreshRatesFB(
gAppState.Session, 0, &gAppState.NumSupportedDisplayRefreshRates, NULL));
OXR(pfnxrEnumerateDisplayRefreshRatesFB(
gAppState.Session, 0, &gAppState.NumSupportedDisplayRefreshRates, NULL));
gAppState.SupportedDisplayRefreshRates =
(float*)malloc(gAppState.NumSupportedDisplayRefreshRates * sizeof(float));
OXR(pfnxrEnumerateDisplayRefreshRatesFB(
gAppState.Session,
gAppState.NumSupportedDisplayRefreshRates,
&gAppState.NumSupportedDisplayRefreshRates,
gAppState.SupportedDisplayRefreshRates));
ALOGV("Supported Refresh Rates:");
for (uint32_t i = 0; i < gAppState.NumSupportedDisplayRefreshRates; i++) {
ALOGV("%d:%f", i, gAppState.SupportedDisplayRefreshRates[i]);
}
gAppState.SupportedDisplayRefreshRates =
(float*)malloc(gAppState.NumSupportedDisplayRefreshRates * sizeof(float));
OXR(pfnxrEnumerateDisplayRefreshRatesFB(
gAppState.Session,
gAppState.NumSupportedDisplayRefreshRates,
&gAppState.NumSupportedDisplayRefreshRates,
gAppState.SupportedDisplayRefreshRates));
ALOGV("Supported Refresh Rates:");
for (uint32_t i = 0; i < gAppState.NumSupportedDisplayRefreshRates; i++) {
ALOGV("%d:%f", i, gAppState.SupportedDisplayRefreshRates[i]);
}
OXR(xrGetInstanceProcAddr(
gAppState.Instance,
"xrGetDisplayRefreshRateFB",
(PFN_xrVoidFunction*)(&gAppState.pfnGetDisplayRefreshRate)));
OXR(xrGetInstanceProcAddr(
gAppState.Instance,
"xrGetDisplayRefreshRateFB",
(PFN_xrVoidFunction*)(&gAppState.pfnGetDisplayRefreshRate)));
OXR(gAppState.pfnGetDisplayRefreshRate(gAppState.Session, &gAppState.currentDisplayRefreshRate));
ALOGV("Current System Display Refresh Rate: %f", gAppState.currentDisplayRefreshRate);
OXR(gAppState.pfnGetDisplayRefreshRate(gAppState.Session, &gAppState.currentDisplayRefreshRate));
ALOGV("Current System Display Refresh Rate: %f", gAppState.currentDisplayRefreshRate);
OXR(xrGetInstanceProcAddr(
gAppState.Instance,
"xrRequestDisplayRefreshRateFB",
(PFN_xrVoidFunction*)(&gAppState.pfnRequestDisplayRefreshRate)));
OXR(xrGetInstanceProcAddr(
gAppState.Instance,
"xrRequestDisplayRefreshRateFB",
(PFN_xrVoidFunction*)(&gAppState.pfnRequestDisplayRefreshRate)));
// Test requesting the system default.
OXR(gAppState.pfnRequestDisplayRefreshRate(gAppState.Session, 0.0f));
ALOGV("Requesting system default display refresh rate");
}
}
// Test requesting the system default.
OXR(gAppState.pfnRequestDisplayRefreshRate(gAppState.Session, 0.0f));
ALOGV("Requesting system default display refresh rate");
}
#endif
uint32_t numOutputSpaces = 0;
OXR(xrEnumerateReferenceSpaces(gAppState.Session, 0, &numOutputSpaces, NULL));
@ -1518,16 +1521,15 @@ void TBXR_InitRenderer( ) {
gAppState.Projections[eye].type = XR_TYPE_VIEW;
}
if (strstr(gAppState.OpenXRHMD, "pico") != NULL)
{
xrGetInstanceProcAddr(gAppState.Instance,"xrSetConfigPICO", (PFN_xrVoidFunction*)(&pfnXrSetConfigPICO));
xrGetInstanceProcAddr(gAppState.Instance,"xrGetConfigPICO", (PFN_xrVoidFunction*)(&pfnXrGetConfigPICO));
#ifdef PICO_XR
xrGetInstanceProcAddr(gAppState.Instance,"xrSetConfigPICO", (PFN_xrVoidFunction*)(&pfnXrSetConfigPICO));
xrGetInstanceProcAddr(gAppState.Instance,"xrGetConfigPICO", (PFN_xrVoidFunction*)(&pfnXrGetConfigPICO));
pfnXrSetConfigPICO(gAppState.Session,TRACKING_ORIGIN,"0");
pfnXrSetConfigPICO(gAppState.Session,TRACKING_ORIGIN,"1");
pfnXrSetConfigPICO(gAppState.Session,TRACKING_ORIGIN,"0");
pfnXrSetConfigPICO(gAppState.Session,TRACKING_ORIGIN,"1");
pfnXrGetConfigPICO(gAppState.Session, GET_DISPLAY_RATE, &gAppState.currentDisplayRefreshRate);
}
pfnXrGetConfigPICO(gAppState.Session, GET_DISPLAY_RATE, &gAppState.currentDisplayRefreshRate);
#endif
ovrRenderer_Create(
gAppState.Session,
@ -1550,9 +1552,6 @@ void TBXR_InitialiseOpenXR()
ovrEgl_CreateContext(&gAppState.Egl, NULL);
EglInitExtensions();
//First, find out which HMD we are using
gAppState.OpenXRHMD = (char*)getenv("OPENXR_HMD");
PFN_xrInitializeLoaderKHR xrInitializeLoaderKHR;
xrGetInstanceProcAddr(
XR_NULL_HANDLE, "xrInitializeLoaderKHR", (PFN_xrVoidFunction*)&xrInitializeLoaderKHR);
@ -1578,28 +1577,22 @@ void TBXR_InitialiseOpenXR()
XrInstanceCreateInfo instanceCreateInfo;
memset(&instanceCreateInfo, 0, sizeof(instanceCreateInfo));
instanceCreateInfo.type = XR_TYPE_INSTANCE_CREATE_INFO;
#ifdef META_QUEST
instanceCreateInfo.next = NULL;
#endif
#ifdef PICO_XR
XrInstanceCreateInfoAndroidKHR instanceCreateInfoAndroid = {XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR};
instanceCreateInfoAndroid.applicationVM = java.Vm;
instanceCreateInfoAndroid.applicationActivity = java.ActivityObject;
instanceCreateInfo.next = (XrBaseInStructure*)&instanceCreateInfoAndroid;
#endif
instanceCreateInfo.createFlags = 0;
instanceCreateInfo.applicationInfo = appInfo;
instanceCreateInfo.enabledApiLayerCount = 0;
instanceCreateInfo.enabledApiLayerNames = NULL;
if (strstr(gAppState.OpenXRHMD, "meta") != NULL)
{
instanceCreateInfo.enabledExtensionCount = numRequiredExtensions_meta;
instanceCreateInfo.enabledExtensionNames = requiredExtensionNames_meta;
}
else
{
instanceCreateInfo.enabledExtensionCount = numRequiredExtensions_pico;
instanceCreateInfo.enabledExtensionNames = requiredExtensionNames_pico;
}
instanceCreateInfo.enabledExtensionCount = numRequiredExtensions;
instanceCreateInfo.enabledExtensionNames = requiredExtensionNames;
XrResult initResult;
OXR(initResult = xrCreateInstance(&instanceCreateInfo, &gAppState.Instance));
@ -1643,18 +1636,17 @@ void TBXR_InitialiseOpenXR()
OXR(pfnGetOpenGLESGraphicsRequirementsKHR(gAppState.Instance, gAppState.SystemId,
&graphicsRequirements));
if (strstr(gAppState.OpenXRHMD, "meta") != NULL)
{
XrSystemColorSpacePropertiesFB colorSpacePropertiesFB = {};
colorSpacePropertiesFB.type = XR_TYPE_SYSTEM_COLOR_SPACE_PROPERTIES_FB;
#ifdef META_QUEST
XrSystemColorSpacePropertiesFB colorSpacePropertiesFB = {};
colorSpacePropertiesFB.type = XR_TYPE_SYSTEM_COLOR_SPACE_PROPERTIES_FB;
XrSystemProperties systemProperties = {};
systemProperties.type = XR_TYPE_SYSTEM_PROPERTIES;
systemProperties.next = &colorSpacePropertiesFB;
OXR(xrGetSystemProperties(gAppState.Instance, gAppState.SystemId, &systemProperties));
XrSystemProperties systemProperties = {};
systemProperties.type = XR_TYPE_SYSTEM_PROPERTIES;
systemProperties.next = &colorSpacePropertiesFB;
OXR(xrGetSystemProperties(gAppState.Instance, gAppState.SystemId, &systemProperties));
ALOGV("System Color Space Properties: colorspace=%d", colorSpacePropertiesFB.colorSpace);
}
ALOGV("System Color Space Properties: colorspace=%d", colorSpacePropertiesFB.colorSpace);
#endif
TBXR_InitialiseResolution();
}

View file

@ -11,7 +11,7 @@
#include <jni.h>
#include <openxr/openxr.h>
#include <openxr/openxr_platform.h>
#include <openxr_helpers.h>
#include <openxr/openxr_oculus_helpers.h>
#include <android/native_window_jni.h>
#include <android/log.h>
@ -55,16 +55,11 @@ typedef enum xrButton_ {
xrButton_GripTrigger = 0x04000000,
xrButton_Trigger = 0x20000000,
xrButton_Joystick = 0x80000000,
//Define additional controller touch points (not button presses)
xrButton_ThumbRest = 0x00000010,
xrButton_EnumSize = 0x7fffffff
} xrButton;
typedef struct {
uint32_t Buttons;
uint32_t Touches;
float IndexTrigger;
float GripTrigger;
XrVector2f Joystick;
@ -228,7 +223,6 @@ typedef struct
bool Focused;
bool Visible;
bool FrameSetup;
char* OpenXRHMD;
float Width;
float Height;

View file

@ -3597,7 +3597,7 @@ static void M_Credits_Draw (void)
" QQQQQQQQ QQQQQQQQ ",
" QQQ QQQ ",
" Q Q ",
" Q Q v1.5.7");
" Q Q v1.5.3");
int i, l, linelength, firstline, lastline, lines;
for (i = 0, linelength = 0, firstline = 9999, lastline = -1;m_credits_message[i];i++)

View file

@ -1,4 +0,0 @@
Into this folder copy the libopenxr_loader.so for each HMD required to support, suffixed with the headset type:
libopenxr_loader_meta.so
libopenxr_loader_pico.so

View file

@ -4,5 +4,6 @@
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Thu Dec 12 20:21:11 GMT 2019
sdk.dir=C\:\\Users\\Simon\\AppData\\Local\\Android\\Sdk
#Sat Oct 13 12:29:31 BST 2018
ndk.dir=C\:\\Users\\Simon\\AppData\\Local\\Android\\Sdk\\ndk-bundle
sdk.dir=C\:\\Users\\Simon\\AppData\\Local\\Android\\sdk

View file

@ -1 +1,4 @@
rootProject.projectDir = new File(settingsDir, '../../../..')
rootProject.name = "QuakeQuest"
include ':', 'XrSamples:QuakeQuest:Projects:Android'

View file

@ -1,13 +0,0 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := openxr_loader
LOCAL_SRC_FILES := lib$(LOCAL_MODULE).so
# NOTE: This check is added to prevent the following error when running a "make clean" where
# the prebuilt lib may have been deleted: "LOCAL_SRC_FILES points to a missing file"
ifneq (,$(wildcard $(LOCAL_PATH)/$(LOCAL_SRC_FILES)))
include $(PREBUILT_SHARED_LIBRARY)
endif

27
Projects/Projects.iml Normal file
View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":XrSamples:QuakeQuest:Projects" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/Android" external.system.id="GRADLE" external.system.module.group="QuakeQuest.XrSamples.QuakeQuest" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="java-gradle" name="Java-Gradle">
<configuration>
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
<option name="BUILDABLE" value="false" />
</configuration>
</facet>
<facet type="android-gradle" name="Android-Gradle">
<configuration>
<option name="GRADLE_PROJECT_PATH" value=":XrSamples:QuakeQuest:Projects" />
<option name="LAST_SUCCESSFUL_SYNC_AGP_VERSION" />
<option name="LAST_KNOWN_AGP_VERSION" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
<excludeFolder url="file://$MODULE_DIR$/build" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

27
XrSamples-QuakeQuest.iml Normal file
View file

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":VrSamples:QuakeQuest" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/Projects/Android" external.system.id="GRADLE" external.system.module.group="QuakeQuest.VrSamples" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="java-gradle" name="Java-Gradle">
<configuration>
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
<option name="BUILDABLE" value="false" />
</configuration>
</facet>
<facet type="android-gradle" name="Android-Gradle">
<configuration>
<option name="GRADLE_PROJECT_PATH" value=":VrSamples:QuakeQuest" />
<option name="LAST_SUCCESSFUL_SYNC_AGP_VERSION" />
<option name="LAST_KNOWN_AGP_VERSION" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
<excludeFolder url="file://$MODULE_DIR$/build" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View file

@ -1,8 +0,0 @@
org.gradle.jvmargs=-Xmx1536M \
--add-exports=java.base/sun.nio.ch=ALL-UNNAMED \
--add-opens=java.base/java.lang=ALL-UNNAMED \
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED \
--add-opens=java.base/java.io=ALL-UNNAMED \
--add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED
org.gradle.caching=true
org.gradle.configureondemand=true

View file

@ -1,7 +1,6 @@
package com.drbeef.quakequest;
import static android.system.Os.setenv;
import java.io.BufferedReader;
import java.io.File;
@ -11,21 +10,14 @@ import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Locale;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Settings;
import android.system.ErrnoException;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
@ -37,50 +29,36 @@ import android.support.v4.content.ContextCompat;
@SuppressLint("SdCardPath") public class GLES3JNIActivity extends Activity implements SurfaceHolder.Callback
{
private static String manufacturer = "";
// Load the gles3jni library right away to make sure JNI_OnLoad() gets called as the very first thing.
static
{
manufacturer = Build.MANUFACTURER.toLowerCase(Locale.ROOT);
if (manufacturer.contains("oculus")) // rename oculus to meta as this will probably happen in the future anyway
{
manufacturer = "meta";
}
try
{
//Load manufacturer specific loader
System.loadLibrary("openxr_loader_" + manufacturer);
setenv("OPENXR_HMD", manufacturer, true);
} catch (Exception e)
{}
System.loadLibrary( "quakequest" );
}
private static final String TAG = "QuakeQuest";
private int permissionCount = 0;
private static final int READ_EXTERNAL_STORAGE_PERMISSION_ID = 1;
private static final int WRITE_EXTERNAL_STORAGE_PERMISSION_ID = 2;
String commandLineParams;
private SurfaceHolder mSurfaceHolder;
private SurfaceView mView;
private SurfaceHolder mSurfaceHolder;
private long mNativeHandle;
String dir;
private final boolean m_asynchronousTracking = false;
@Override protected void onCreate( Bundle icicle )
{
Log.v( TAG, "----------------------------------------------------------------" );
Log.v( TAG, "GLES3JNIActivity::onCreate()" );
super.onCreate( icicle );
SurfaceView mView = new SurfaceView(this);
setContentView(mView);
mView = new SurfaceView( this );
setContentView( mView );
mView.getHolder().addCallback( this );
dir = "/sdcard/QuakeQuest";
//dir = getBaseContext().getExternalFilesDir(null).getAbsolutePath();
// Force the screen to stay on, rather than letting it dim and shut off
// while the user is watching a movie.
getWindow().addFlags( WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON );
@ -95,47 +73,80 @@ import android.support.v4.content.ContextCompat;
/** Initializes the Activity only if the permission has been granted. */
private void checkPermissionsAndInitialize() {
if (!Environment.isExternalStorageManager()) {
//request for the permission
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
Uri uri = Uri.fromParts("package", getPackageName(), null);
intent.setData(uri);
startActivityForResult(intent, 1);
// Boilerplate for checking runtime permissions in Android.
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(
GLES3JNIActivity.this,
new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
WRITE_EXTERNAL_STORAGE_PERMISSION_ID);
}
else
{
permissionCount++;
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(
GLES3JNIActivity.this,
new String[] {Manifest.permission.READ_EXTERNAL_STORAGE},
READ_EXTERNAL_STORAGE_PERMISSION_ID);
}
else
{
permissionCount++;
}
if (permissionCount == 2) {
// Permissions have already been granted.
create();
}
}
/** Handles the user accepting the permission. */
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
create();
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] results) {
if (requestCode == READ_EXTERNAL_STORAGE_PERMISSION_ID) {
if (results.length > 0 && results[0] == PackageManager.PERMISSION_GRANTED) {
permissionCount++;
}
else
{
System.exit(0);
}
}
if (requestCode == WRITE_EXTERNAL_STORAGE_PERMISSION_ID) {
if (results.length > 0 && results[0] == PackageManager.PERMISSION_GRANTED) {
permissionCount++;
}
else
{
System.exit(0);
}
}
checkPermissionsAndInitialize();
}
public void create() {
public void create()
{
//This will copy the shareware version of quake if user doesn't have anything installed
copy_asset(dir + "/id1", "pak0.pak");
copy_asset(dir + "/id1", "config.cfg");
copy_asset(dir, "commandline.txt");
try {
setenv("QUAKEQUEST_DIR", dir, true);
} catch (Exception ignored)
{
System.exit(-9);;
}
copy_asset("/sdcard/QuakeQuest/id1", "pak0.pak");
copy_asset("/sdcard/QuakeQuest/id1", "config.cfg");
copy_asset("/sdcard/QuakeQuest", "commandline.txt");
//Read these from a file and pass through
commandLineParams = new String("quake");
//See if user is trying to use command line params
if(new File(dir + "/commandline.txt").exists()) // should exist!
if(new File("/sdcard/QuakeQuest/commandline.txt").exists()) // should exist!
{
BufferedReader br;
try {
br = new BufferedReader(new FileReader(dir + "/commandline.txt"));
br = new BufferedReader(new FileReader("/sdcard/QuakeQuest/commandline.txt"));
String s;
StringBuilder sb=new StringBuilder(0);
while ((s=br.readLine())!=null)

View file

@ -1,8 +0,0 @@
## This file must *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Thu Dec 12 20:21:11 GMT 2019
sdk.dir=C\:\\Users\\Simon\\AppData\\Local\\Android\\Sdk