mirror of
https://github.com/DrBeef/QuestZDoom.git
synced 2025-04-24 10:08:52 +00:00
Merge 22de518bbe
into 5f2c42fa09
This commit is contained in:
commit
a1aa322d44
45 changed files with 14204 additions and 3494 deletions
216
.github/workflows/build.yaml
vendored
Normal file
216
.github/workflows/build.yaml
vendored
Normal file
|
@ -0,0 +1,216 @@
|
|||
name: Continuous Integration
|
||||
|
||||
on:
|
||||
|
||||
pull_request:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
paths-ignore:
|
||||
- '**/README.md'
|
||||
- '**/LICENSE'
|
||||
# branches:
|
||||
# - master
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.name }} | ${{ matrix.build_type }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-20.04, windows-latest]
|
||||
build_type: [Release, Debug]
|
||||
include:
|
||||
- progdir: Projects/Android
|
||||
- ndk: 21.4.7075529
|
||||
- build_type: Release
|
||||
build_folder: release
|
||||
- build_type: Debug
|
||||
build_folder: debug
|
||||
- os: windows-latest
|
||||
name: Visual Studio 64-bit
|
||||
extra_options: -A x64
|
||||
- os: ubuntu-20.04
|
||||
name: Linux GCC 11
|
||||
deps_cmdline: "sudo apt update && sudo apt install g++-11 libsdl2-dev libgtk-3-dev"
|
||||
extra_options: "-DCMAKE_C_COMPILER=gcc-11 -DCMAKE_CXX_COMPILER=g++-11"
|
||||
|
||||
steps:
|
||||
# - name: Checkout SDK Mobile
|
||||
# uses: actions/checkout@v3
|
||||
# with:
|
||||
# repository: emawind84/ovr_sdk_mobile
|
||||
# token: ${{ secrets.GH_PAT }}
|
||||
# path: ''
|
||||
|
||||
- name: Checkout QuestZDoom
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 1
|
||||
submodules: true
|
||||
path: ''
|
||||
- run: git fetch --deepen=100
|
||||
working-directory: ${{ matrix.progdir }}/jni/gzdoom-g3.3mgw_mobile
|
||||
|
||||
- name: Checkout SDK Mobile
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 1
|
||||
repository: emawind84/ovr_sdk_mobile_dist
|
||||
path: 'sdk'
|
||||
|
||||
- name: Checkout META SDK Native Libraries
|
||||
run: 7z x ovr_openxr_mobile_sdk_47.0.zip -ometasdk
|
||||
working-directory: sdk
|
||||
|
||||
- name: Prepare META SDK Native Libraries
|
||||
shell: bash
|
||||
run: >
|
||||
mv sdk/metasdk/OpenXR/Libs/Android/arm64-v8a/Release/libopenxr_loader.so
|
||||
Projects/Android/libs/arm64-v8a/libopenxr_loader_meta.so
|
||||
|
||||
- name: Checkout PICO SDK Native Libraries
|
||||
run: 7z x Pico_OpenXR_SDK_v210.zip -opicosdk
|
||||
working-directory: sdk
|
||||
|
||||
- name: Prepare PICO SDK Libraries
|
||||
shell: bash
|
||||
run: >
|
||||
mv sdk/picosdk/libs/android.arm64-v8a/libopenxr_loader.so
|
||||
Projects/Android/libs/arm64-v8a/libopenxr_loader_pico.so
|
||||
|
||||
# - uses: actions/cache@v3
|
||||
# with:
|
||||
# path: |
|
||||
# ~/.gradle/caches
|
||||
# ~/.gradle/wrapper
|
||||
# key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
# restore-keys: |
|
||||
# ${{ runner.os }}-gradle-
|
||||
|
||||
- name: Install Dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
if [[ ! -z "${{ matrix.deps_cmdline }}" ]]; then
|
||||
eval ${{ matrix.deps_cmdline }}
|
||||
fi
|
||||
|
||||
- name: Configure CMAKE
|
||||
shell: bash
|
||||
run: >
|
||||
cmake -B build
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
|
||||
-DPK3_QUIET_ZIPDIR=ON ${{ matrix.extra_options }}
|
||||
.
|
||||
working-directory: ${{ matrix.progdir }}/jni/gzdoom-g3.3mgw_mobile
|
||||
|
||||
- name: Prepare PK3 packages
|
||||
shell: bash
|
||||
run: |
|
||||
cmake --build build \
|
||||
--config ${{ matrix.build_type }} \
|
||||
--target lzdoom_pk3 lights_pk3 lz_game_support_pk3 \
|
||||
--parallel 3
|
||||
cp build/*.pk3 ../../../../assets/res
|
||||
working-directory: ${{ matrix.progdir }}/jni/gzdoom-g3.3mgw_mobile
|
||||
|
||||
- name: Revision update
|
||||
shell: bash
|
||||
run: cmake --build build --config ${{ matrix.build_type }} --target revision_check
|
||||
working-directory: ${{ matrix.progdir }}/jni/gzdoom-g3.3mgw_mobile
|
||||
|
||||
- name: Setup NDK for Ubuntu
|
||||
if: matrix.os == 'ubuntu-20.04'
|
||||
shell: bash
|
||||
run: echo "y" | ${{ env.SDKMANAGER }} "ndk;${{ matrix.ndk }}"
|
||||
env:
|
||||
SDKMANAGER: ${ANDROID_SDK_ROOT}/cmdline-tools/latest/bin/sdkmanager
|
||||
|
||||
- name: Setup NDK for Windows
|
||||
if: matrix.os == 'windows-latest'
|
||||
shell: pwsh
|
||||
run: |
|
||||
$sdkRoot = "C:\Android\android-sdk"
|
||||
$sdkManager = "$sdkRoot\cmdline-tools\latest\bin\sdkmanager.bat"
|
||||
& $sdkManager --sdk_root=$sdkRoot "ndk;${{ matrix.ndk }}"
|
||||
|
||||
- name: Set up JDK 11 for x64
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '11'
|
||||
distribution: 'temurin'
|
||||
architecture: x64
|
||||
|
||||
- name: Validate Gradle wrapper
|
||||
uses: gradle/wrapper-validation-action@v1
|
||||
|
||||
- name: Setup gradle
|
||||
uses: gradle/gradle-build-action@v2
|
||||
with:
|
||||
build-root-directory: ${{ matrix.progdir }}
|
||||
cache-read-only: true
|
||||
cache-disabled: false
|
||||
|
||||
- name: Set execution flag for gradlew
|
||||
shell: bash
|
||||
run: chmod +x gradlew
|
||||
working-directory: ${{ matrix.progdir }}
|
||||
|
||||
- name: Build with gradle
|
||||
id: gradle_build
|
||||
shell: bash
|
||||
run: ./gradlew :Projects:Android:assemble${{ matrix.build_type }}
|
||||
working-directory: ${{ matrix.progdir }}
|
||||
|
||||
- name: Sign app APK
|
||||
if: matrix.build_type == 'Release'
|
||||
uses: ilharp/sign-android-release@v1
|
||||
id: sign_app_apk
|
||||
with:
|
||||
releaseDir: ${{ matrix.progdir }}/build/outputs/apk/release
|
||||
signingKey: ${{ secrets.SIGNING_KEY }}
|
||||
keyAlias: ${{ secrets.ALIAS }}
|
||||
keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
|
||||
keyPassword: ${{ secrets.KEY_PASSWORD }}
|
||||
buildToolsVersion: 33.0.0
|
||||
|
||||
- name: Prepare signed APK
|
||||
shell: bash
|
||||
run: mv --force '${{steps.sign_app_apk.outputs.signedFile}}' questzdoom-${{ matrix.build_folder }}.apk
|
||||
if: ${{ steps.sign_app_apk.outcome == 'success' }}
|
||||
working-directory: ${{ matrix.progdir }}/build/outputs/apk/${{ matrix.build_folder }}
|
||||
|
||||
- name: Upload package
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ${{ matrix.name }} ${{ matrix.build_type }}
|
||||
path: ${{ matrix.progdir }}/build/outputs/apk/${{ matrix.build_folder }}/*-${{ matrix.build_folder }}.apk
|
||||
if-no-files-found: error
|
||||
retention-days: 30
|
||||
|
||||
- name: Prepare package for release
|
||||
if: runner.os == 'Linux'
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: ${{ matrix.name }} ${{ matrix.build_type }}
|
||||
path: release
|
||||
|
||||
- name: Display structure of release files
|
||||
if: runner.os == 'Linux'
|
||||
shell: bash
|
||||
run: ls -R
|
||||
working-directory: release
|
||||
|
||||
- name: Prepare release
|
||||
uses: softprops/action-gh-release@v1
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
with:
|
||||
prerelease: true
|
||||
draft: true
|
||||
files: |
|
||||
release/*.apk
|
||||
LICENSE.txt
|
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -15,9 +15,6 @@ $RECYCLE.BIN/
|
|||
*.o
|
||||
*.d
|
||||
|
||||
#binaries
|
||||
*.so
|
||||
|
||||
#libs
|
||||
*.a
|
||||
|
||||
|
@ -36,5 +33,9 @@ Projects/Android/.externalNativeBuild/*
|
|||
*.bin
|
||||
*.ser
|
||||
Projects/Android/.idea/*
|
||||
.gradle/*
|
||||
**/local.properties
|
||||
Projects/Android/.gradle/*
|
||||
Projects/Android/Android.iml
|
||||
Projects/Android/libs/arm64-v8a/libopenxr_loader_meta.so
|
||||
Projects/Android/libs/arm64-v8a/libopenxr_loader_pico.so
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.drbeef.questzdoom"
|
||||
android:versionCode="31"
|
||||
android:versionName="1.4.0" android:installLocation="auto" >
|
||||
android:versionCode="35"
|
||||
android:versionName="1.6.1" android:installLocation="auto" >
|
||||
|
||||
<!-- Tell the system this app requires OpenGL ES 3.1. -->
|
||||
<uses-feature android:glEsVersion="0x00030001" android:required="true"/>
|
||||
|
@ -17,9 +17,17 @@
|
|||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
|
||||
<application android:allowBackup="false" android:icon="@drawable/ic_qquest" android:label="@string/qzdoom">
|
||||
|
||||
|
||||
<meta-data android:name="com.samsung.android.vr.application.mode" android:value="vr_only"/>
|
||||
|
||||
<!-- META QUEST -->
|
||||
<meta-data android:name="com.oculus.supportedDevices" android:value="quest|quest2"/>
|
||||
<meta-data android:name="com.oculus.ossplash" android:value="true"/>
|
||||
|
||||
<!-- PICO XR -->
|
||||
<meta-data android:name="pvr.app.type" android:value="vr" />
|
||||
|
||||
<!-- The activity is the built-in NativeActivity framework class. -->
|
||||
<!-- launchMode is set to singleTask because there should never be multiple copies of the app running. -->
|
||||
<!-- Theme.Black.NoTitleBar.Fullscreen gives solid black instead of a (bad stereoscopic) gradient on app transition. -->
|
||||
|
@ -39,6 +47,7 @@
|
|||
<!-- This filter lets the apk show up as a launchable icon. -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
@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
|
|
@ -1,52 +1,60 @@
|
|||
apply plugin: 'com.android.application'
|
||||
apply from: "${rootProject.projectDir}/VrApp.gradle"
|
||||
apply from: "${rootProject.projectDir}/XrApp.gradle"
|
||||
|
||||
android {
|
||||
// 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.
|
||||
// Use only letters to remain compatible with the package name.
|
||||
project.archivesBaseName = "questzdoom"
|
||||
// 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.
|
||||
// Use only letters to remain compatible with the package name.
|
||||
project.archivesBaseName = "questzdoom"
|
||||
|
||||
defaultConfig {
|
||||
// Gradle replaces the manifest package with this value, which must
|
||||
// be unique on a system. If you don't change it, a new app
|
||||
// will replace an older one.
|
||||
applicationId "com.drbeef." + project.archivesBaseName
|
||||
compileSdkVersion 26
|
||||
|
||||
// override app plugin abiFilters for both 32 and 64-bit support
|
||||
externalNativeBuild {
|
||||
ndk {
|
||||
defaultConfig {
|
||||
minSdkVersion 24
|
||||
targetSdkVersion 26
|
||||
|
||||
// Gradle replaces the manifest package with this value, which must
|
||||
// be unique on a system. If you don't change it, a new app
|
||||
// will replace an older one.
|
||||
applicationId "com.drbeef." + project.archivesBaseName
|
||||
|
||||
// override app plugin abiFilters for both 32 and 64-bit support
|
||||
externalNativeBuild {
|
||||
ndk {
|
||||
abiFilters 'arm64-v8a'
|
||||
}
|
||||
ndkBuild {
|
||||
abiFilters 'arm64-v8a'
|
||||
if (project.hasProperty("openxr_hmd"))
|
||||
arguments 'OPENXR_HMD=' + project.getProperty("openxr_hmd")
|
||||
}
|
||||
}
|
||||
ndkBuild {
|
||||
abiFilters 'arm64-v8a'
|
||||
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
manifest.srcFile 'AndroidManifest.xml'
|
||||
java.srcDirs = ['../../java']
|
||||
jniLibs.srcDir 'libs'
|
||||
res.srcDirs = ['../../res']
|
||||
assets.srcDirs = ['../../assets', 'jni/gzdoom-g3.3mgw_mobile/fm_banks', 'jni/gzdoom-g3.3mgw_mobile/soundfont']
|
||||
}
|
||||
}
|
||||
minSdkVersion 24
|
||||
targetSdkVersion 26
|
||||
|
||||
// packagingOptions {
|
||||
// specify the path to your object binaries, or generally:
|
||||
// doNotStrip '**.so'
|
||||
// }
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
manifest.srcFile 'AndroidManifest.xml'
|
||||
java.srcDirs = ['../../java']
|
||||
jniLibs.srcDir 'libs'
|
||||
res.srcDirs = ['../../res']
|
||||
assets.srcDirs = ['../../assets', 'jni/gzdoom-g3.3mgw_mobile/fm_banks', 'jni/gzdoom-g3.3mgw_mobile/soundfont']
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility = '1.8'
|
||||
targetCompatibility = '1.8'
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
exclude 'lib/arm64-v8a/libopenxr_loader.so'
|
||||
}
|
||||
|
||||
ndkVersion = "21.4.7075529"
|
||||
|
||||
compileSdkVersion = 24
|
||||
buildToolsVersion = '29.0.1'
|
||||
|
||||
/* buildTypes {
|
||||
release {
|
||||
debuggable true
|
||||
|
@ -55,8 +63,8 @@ android {
|
|||
}
|
||||
|
||||
dependencies {
|
||||
implementation "com.android.support:support-compat:24.2.0"
|
||||
implementation "com.android.support:support-core-utils:24.2.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'])
|
||||
}
|
||||
|
||||
|
@ -67,4 +75,6 @@ buildscript {
|
|||
repositories {
|
||||
google()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//tasks.register("prepareKotlinBuildScriptModel"){}
|
|
@ -1,29 +0,0 @@
|
|||
#!/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()
|
BIN
Projects/Android/gradle/wrapper/gradle-wrapper.jar
vendored
BIN
Projects/Android/gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
|
@ -1,6 +1,6 @@
|
|||
#Sat Feb 20 22:20:15 GMT 2021
|
||||
#Fri Dec 23 16:20:08 KST 2022
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
|
|
@ -1,14 +1,9 @@
|
|||
# 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-19
|
||||
|
||||
APP_CFLAGS += -Wl,--no-undefined, -march=armv8+crc
|
||||
|
||||
APPLICATIONMK_PATH = $(call my-dir)
|
||||
NDK_MODULE_PATH := $(APPLICATIONMK_PATH)/../..
|
||||
|
||||
TOP_DIR := $(APPLICATIONMK_PATH)
|
||||
SUPPORT_LIBS := $(APPLICATIONMK_PATH)/SupportLibs
|
||||
|
|
20
Projects/Android/jni/OpenXR-SDK/include/CMakeLists.txt
Normal file
20
Projects/Android/jni/OpenXR-SDK/include/CMakeLists.txt
Normal file
|
@ -0,0 +1,20 @@
|
|||
# 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)
|
101
Projects/Android/jni/OpenXR-SDK/include/openxr/CMakeLists.txt
Normal file
101
Projects/Android/jni/OpenXR-SDK/include/openxr/CMakeLists.txt
Normal file
|
@ -0,0 +1,101 @@
|
|||
# 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
|
||||
)
|
4581
Projects/Android/jni/OpenXR-SDK/include/openxr/openxr.h
Normal file
4581
Projects/Android/jni/OpenXR-SDK/include/openxr/openxr.h
Normal file
File diff suppressed because it is too large
Load diff
690
Projects/Android/jni/OpenXR-SDK/include/openxr/openxr_platform.h
Normal file
690
Projects/Android/jni/OpenXR-SDK/include/openxr/openxr_platform.h
Normal file
|
@ -0,0 +1,690 @@
|
|||
#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
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
** 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
|
3158
Projects/Android/jni/OpenXR-SDK/include/openxr/openxr_reflection.h
Normal file
3158
Projects/Android/jni/OpenXR-SDK/include/openxr/openxr_reflection.h
Normal file
File diff suppressed because it is too large
Load diff
113
Projects/Android/jni/OpenXR-SDK/src/common/openxr_helpers.h
Normal file
113
Projects/Android/jni/OpenXR-SDK/src/common/openxr_helpers.h
Normal file
|
@ -0,0 +1,113 @@
|
|||
#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_
|
787
Projects/Android/jni/OpenXR-SDK/src/common/xr_linear.h
Normal file
787
Projects/Android/jni/OpenXR-SDK/src/common/xr_linear.h
Normal file
|
@ -0,0 +1,787 @@
|
|||
// 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_
|
569
Projects/Android/jni/QzDoom/OpenXrInput.cpp
Normal file
569
Projects/Android/jni/QzDoom/OpenXrInput.cpp
Normal file
|
@ -0,0 +1,569 @@
|
|||
#include "VrInput.h"
|
||||
|
||||
extern ovrApp gAppState;
|
||||
|
||||
XrResult CheckXrResult(XrResult res, const char* originator) {
|
||||
if (XR_FAILED(res)) {
|
||||
ALOGE("error: %s", originator);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#define CHECK_XRCMD(cmd) CheckXrResult(cmd, #cmd);
|
||||
|
||||
#define SIDE_LEFT 0
|
||||
#define SIDE_RIGHT 1
|
||||
#define SIDE_COUNT 2
|
||||
|
||||
|
||||
XrActionSet actionSet = nullptr;
|
||||
XrAction grabAction;
|
||||
XrAction poseAction;
|
||||
XrAction vibrateAction;
|
||||
XrAction quitAction;
|
||||
XrAction touchpadAction;
|
||||
XrAction AXAction;
|
||||
XrAction homeAction;
|
||||
XrAction BYAction;
|
||||
XrAction backAction;
|
||||
XrAction sideAction;
|
||||
XrAction triggerAction;
|
||||
XrAction joystickAction;
|
||||
XrAction batteryAction;
|
||||
XrAction AXTouchAction;
|
||||
XrAction BYTouchAction;
|
||||
XrAction thumbstickTouchAction;
|
||||
XrAction TriggerTouchAction;
|
||||
XrAction ThumbrestTouchAction;
|
||||
XrAction GripAction;
|
||||
XrAction AAction;
|
||||
XrAction BAction;
|
||||
XrAction XAction;
|
||||
XrAction YAction;
|
||||
XrAction ATouchAction;
|
||||
XrAction BTouchAction;
|
||||
XrAction XTouchAction;
|
||||
XrAction YTouchAction;
|
||||
XrAction aimAction;
|
||||
|
||||
XrSpace aimSpace[SIDE_COUNT];
|
||||
XrPath handSubactionPath[SIDE_COUNT];
|
||||
XrSpace handSpace[SIDE_COUNT];
|
||||
|
||||
|
||||
|
||||
XrActionSuggestedBinding ActionSuggestedBinding(XrAction action, XrPath path) {
|
||||
XrActionSuggestedBinding asb;
|
||||
asb.action = action;
|
||||
asb.binding = path;
|
||||
return asb;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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.
|
||||
{
|
||||
XrActionSetCreateInfo actionSetInfo = {};
|
||||
actionSetInfo.type = XR_TYPE_ACTION_SET_CREATE_INFO;
|
||||
strcpy(actionSetInfo.actionSetName, "gameplay");
|
||||
strcpy(actionSetInfo.localizedActionSetName, "Gameplay");
|
||||
actionSetInfo.priority = 0;
|
||||
actionSetInfo.next = NULL;
|
||||
CHECK_XRCMD(xrCreateActionSet(gAppState.Instance, &actionSetInfo, &actionSet));
|
||||
}
|
||||
|
||||
// Get the XrPath for the left and right hands - we will use them as subaction paths.
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/left", &handSubactionPath[SIDE_LEFT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/right", &handSubactionPath[SIDE_RIGHT]));
|
||||
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
|
||||
//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];
|
||||
XrPath squeezeValuePath[SIDE_COUNT];
|
||||
XrPath squeezeClickPath[SIDE_COUNT];
|
||||
XrPath posePath[SIDE_COUNT];
|
||||
XrPath hapticPath[SIDE_COUNT];
|
||||
XrPath menuClickPath[SIDE_COUNT];
|
||||
XrPath systemPath[SIDE_COUNT];
|
||||
XrPath thumbrestPath[SIDE_COUNT];
|
||||
XrPath triggerTouchPath[SIDE_COUNT];
|
||||
XrPath triggerValuePath[SIDE_COUNT];
|
||||
XrPath thumbstickClickPath[SIDE_COUNT];
|
||||
XrPath thumbstickTouchPath[SIDE_COUNT];
|
||||
XrPath thumbstickPosPath[SIDE_COUNT];
|
||||
XrPath aimPath[SIDE_COUNT];
|
||||
|
||||
XrPath touchpadPath[SIDE_COUNT];
|
||||
XrPath AXValuePath[SIDE_COUNT];
|
||||
XrPath homeClickPath[SIDE_COUNT];
|
||||
XrPath BYValuePath[SIDE_COUNT];
|
||||
XrPath backPath[SIDE_COUNT];
|
||||
XrPath sideClickPath[SIDE_COUNT];
|
||||
XrPath triggerPath[SIDE_COUNT];
|
||||
XrPath joystickPath[SIDE_COUNT];
|
||||
XrPath batteryPath[SIDE_COUNT];
|
||||
|
||||
XrPath GripPath[SIDE_COUNT];
|
||||
XrPath AXTouchPath[SIDE_COUNT];
|
||||
XrPath BYTouchPath[SIDE_COUNT];
|
||||
XrPath RockerTouchPath[SIDE_COUNT];
|
||||
XrPath TriggerTouchPath[SIDE_COUNT];
|
||||
XrPath ThumbresetTouchPath[SIDE_COUNT];
|
||||
|
||||
XrPath AValuePath[SIDE_COUNT];
|
||||
XrPath BValuePath[SIDE_COUNT];
|
||||
XrPath XValuePath[SIDE_COUNT];
|
||||
XrPath YValuePath[SIDE_COUNT];
|
||||
XrPath ATouchPath[SIDE_COUNT];
|
||||
XrPath BTouchPath[SIDE_COUNT];
|
||||
XrPath XTouchPath[SIDE_COUNT];
|
||||
XrPath YTouchPath[SIDE_COUNT];
|
||||
|
||||
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]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/right/input/menu/click", &menuClickPath[SIDE_RIGHT]));
|
||||
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/left/input/squeeze/value", &squeezeValuePath[SIDE_LEFT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/right/input/squeeze/value", &squeezeValuePath[SIDE_RIGHT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/left/input/squeeze/click", &squeezeClickPath[SIDE_LEFT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/right/input/squeeze/click", &squeezeClickPath[SIDE_RIGHT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/left/input/grip/pose", &posePath[SIDE_LEFT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/right/input/grip/pose", &posePath[SIDE_RIGHT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/left/input/aim/pose", &aimPath[SIDE_LEFT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/right/input/aim/pose", &aimPath[SIDE_RIGHT]));
|
||||
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/left/output/haptic", &hapticPath[SIDE_LEFT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/right/output/haptic", &hapticPath[SIDE_RIGHT]));
|
||||
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/left/input/trigger/touch", &triggerTouchPath[SIDE_LEFT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/right/input/trigger/touch", &triggerTouchPath[SIDE_RIGHT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/left/input/trigger/value", &triggerValuePath[SIDE_LEFT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/right/input/trigger/value", &triggerValuePath[SIDE_RIGHT]));
|
||||
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/left/input/thumbstick/click", &thumbstickClickPath[SIDE_LEFT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/right/input/thumbstick/click", &thumbstickClickPath[SIDE_RIGHT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/left/input/thumbstick/touch", &thumbstickTouchPath[SIDE_LEFT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/right/input/thumbstick/touch", &thumbstickTouchPath[SIDE_RIGHT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/left/input/thumbstick", &thumbstickPosPath[SIDE_LEFT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/right/input/thumbstick", &thumbstickPosPath[SIDE_RIGHT]));
|
||||
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/left/input/system/click", &systemPath[SIDE_LEFT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/right/input/system/click", &systemPath[SIDE_RIGHT]));
|
||||
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]));
|
||||
|
||||
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]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/right/input/battery/value", &batteryPath[SIDE_RIGHT]));
|
||||
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/left/input/x/click", &XValuePath[SIDE_LEFT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/left/input/y/click", &YValuePath[SIDE_LEFT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/right/input/a/click", &AValuePath[SIDE_RIGHT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/right/input/b/click", &BValuePath[SIDE_RIGHT]));
|
||||
CHECK_XRCMD(xrStringToPath(gAppState.Instance, "/user/hand/left/input/x/touch", &XTouchPath[SIDE_LEFT]));
|
||||
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]));
|
||||
|
||||
|
||||
XrResult result;
|
||||
|
||||
//First try Pico Devices
|
||||
{
|
||||
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(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(sideAction, squeezeClickPath[SIDE_LEFT]);
|
||||
bindings[currBinding++] = ActionSuggestedBinding(sideAction, squeezeClickPath[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(homeAction, systemPath[SIDE_LEFT]);
|
||||
bindings[currBinding++] = ActionSuggestedBinding(homeAction, systemPath[SIDE_RIGHT]);
|
||||
bindings[currBinding++] = ActionSuggestedBinding(backAction, backPath[SIDE_LEFT]);
|
||||
bindings[currBinding++] = ActionSuggestedBinding(backAction, backPath[SIDE_RIGHT]);
|
||||
bindings[currBinding++] = ActionSuggestedBinding(batteryAction, batteryPath[SIDE_LEFT]);
|
||||
bindings[currBinding++] = ActionSuggestedBinding(batteryAction, batteryPath[SIDE_RIGHT]);
|
||||
|
||||
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 = 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);
|
||||
}
|
||||
|
||||
XrActionSpaceCreateInfo actionSpaceInfo = {};
|
||||
actionSpaceInfo.type = XR_TYPE_ACTION_SPACE_CREATE_INFO;
|
||||
actionSpaceInfo.action = poseAction;
|
||||
actionSpaceInfo.poseInActionSpace.orientation.w = 1.f;
|
||||
actionSpaceInfo.subactionPath = handSubactionPath[SIDE_LEFT];
|
||||
CHECK_XRCMD(xrCreateActionSpace(gAppState.Session, &actionSpaceInfo, &handSpace[SIDE_LEFT]));
|
||||
actionSpaceInfo.subactionPath = handSubactionPath[SIDE_RIGHT];
|
||||
CHECK_XRCMD(xrCreateActionSpace(gAppState.Session, &actionSpaceInfo, &handSpace[SIDE_RIGHT]));
|
||||
actionSpaceInfo.action = aimAction;
|
||||
actionSpaceInfo.poseInActionSpace.orientation.w = 1.f;
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
void TBXR_UpdateControllers( )
|
||||
{
|
||||
TBXR_SyncActions();
|
||||
|
||||
//get controller poses
|
||||
for (int i = 0; i < 2; i++) {
|
||||
XrSpaceVelocity vel = {};
|
||||
vel.type = XR_TYPE_SPACE_VELOCITY;
|
||||
XrSpaceLocation loc = {};
|
||||
loc.type = XR_TYPE_SPACE_LOCATION;
|
||||
loc.next = &vel;
|
||||
XrResult res = xrLocateSpace(aimSpace[i], gAppState.CurrentSpace, gAppState.FrameState.predictedDisplayTime, &loc);
|
||||
if (res != XR_SUCCESS) {
|
||||
ALOGE("xrLocateSpace error: %d", (int)res);
|
||||
}
|
||||
|
||||
gAppState.TrackedController[i].Active = (loc.locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT) != 0;
|
||||
gAppState.TrackedController[i].Pose = loc.pose;
|
||||
gAppState.TrackedController[i].Velocity = vel;
|
||||
}
|
||||
|
||||
leftRemoteTracking_new = gAppState.TrackedController[0];
|
||||
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(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;
|
||||
|
||||
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(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;
|
||||
|
||||
//thumbstick
|
||||
XrActionStateVector2f moveJoystickState;
|
||||
moveJoystickState = GetActionStateVector2(joystickAction, SIDE_LEFT);
|
||||
leftTrackedRemoteState_new.Joystick.x = moveJoystickState.currentState.x;
|
||||
leftTrackedRemoteState_new.Joystick.y = moveJoystickState.currentState.y;
|
||||
|
||||
moveJoystickState = GetActionStateVector2(joystickAction, SIDE_RIGHT);
|
||||
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)
|
||||
{
|
||||
int channel = i;
|
||||
if ((i + 1) & chan)
|
||||
{
|
||||
if (vibration_channel_duration[channel] > 0.0f)
|
||||
return;
|
||||
|
||||
if (vibration_channel_duration[channel] == -1.0f && duration != 0.0f)
|
||||
return;
|
||||
|
||||
vibration_channel_duration[channel] = duration;
|
||||
vibration_channel_intensity[channel] = 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 = vibrateAction;
|
||||
hapticActionInfo.subactionPath = handSubactionPath[i];
|
||||
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 = vibrateAction;
|
||||
hapticActionInfo.subactionPath = handSubactionPath[i];
|
||||
OXR(xrStopHapticFeedback(gAppState.Session, &hapticActionInfo));
|
||||
}
|
||||
}
|
||||
}
|
759
Projects/Android/jni/QzDoom/QzDoom_OpenXR.cpp
Normal file
759
Projects/Android/jni/QzDoom/QzDoom_OpenXR.cpp
Normal file
|
@ -0,0 +1,759 @@
|
|||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
#include <sys/prctl.h> // for prctl( PR_SET_NAME )
|
||||
#include <android/log.h>
|
||||
#include <android/native_window_jni.h> // for native window JNI
|
||||
#include <android/input.h>
|
||||
|
||||
#include "cmdlib.h"
|
||||
#include "argtable3.h"
|
||||
#include "VrInput.h"
|
||||
|
||||
|
||||
//#define ENABLE_GL_DEBUG
|
||||
#define ENABLE_GL_DEBUG_VERBOSE 1
|
||||
|
||||
//Let's go to the maximum!
|
||||
extern int NUM_MULTI_SAMPLES;
|
||||
extern int REFRESH ;
|
||||
extern float SS_MULTIPLIER ;
|
||||
|
||||
|
||||
/* global arg_xxx structs */
|
||||
struct arg_dbl *ss;
|
||||
struct arg_int *cpu;
|
||||
struct arg_int *gpu;
|
||||
struct arg_int *msaa;
|
||||
struct arg_int *refresh;
|
||||
struct arg_end *end;
|
||||
|
||||
char **argv;
|
||||
int argc=0;
|
||||
|
||||
|
||||
//Define all variables here that were externs in the VrCommon.h
|
||||
bool qzdoom_initialised;
|
||||
long long global_time;
|
||||
float playerYaw;
|
||||
bool resetDoomYaw;
|
||||
bool resetPreviousPitch;
|
||||
float doomYaw;
|
||||
float previousPitch;
|
||||
float vrFOV;
|
||||
vec3_t worldPosition;
|
||||
vec3_t hmdPosition;
|
||||
vec3_t hmdorientation;
|
||||
vec3_t positionDeltaThisFrame;
|
||||
vec3_t weaponangles;
|
||||
vec3_t weaponoffset;
|
||||
bool weaponStabilised;
|
||||
|
||||
vec3_t offhandangles;
|
||||
vec3_t offhandoffset;
|
||||
bool player_moving;
|
||||
bool shutdown;
|
||||
bool ready_teleport;
|
||||
bool trigger_teleport;
|
||||
bool cinemamode;
|
||||
|
||||
//This is now controlled by the engine
|
||||
static bool useVirtualScreen = false;
|
||||
|
||||
static bool hasIWADs = false;
|
||||
static bool hasLauncher = false;
|
||||
|
||||
extern const char* M_GetActiveProfile();
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
|
||||
QuestZDoom Stuff
|
||||
|
||||
================================================================================
|
||||
*/
|
||||
|
||||
void QzDoom_setUseScreenLayer(bool use)
|
||||
{
|
||||
useVirtualScreen = use;
|
||||
}
|
||||
|
||||
int QzDoom_SetRefreshRate(int refreshRate)
|
||||
{
|
||||
XrResult result = XR_SUCCESS;
|
||||
if (strstr(gAppState.OpenXRHMD, "meta") != NULL)
|
||||
{
|
||||
OXR(result = gAppState.pfnRequestDisplayRefreshRate(gAppState.Session, (float) refreshRate));
|
||||
}
|
||||
|
||||
return XR_SUCCEEDED(result) ? 0 : -1;
|
||||
}
|
||||
|
||||
void QzDoom_GetScreenRes(uint32_t *width, uint32_t *height)
|
||||
{
|
||||
int iWidth, iHeight;
|
||||
TBXR_GetScreenRes(&iWidth, &iHeight);
|
||||
*width = iWidth;
|
||||
*height = iHeight;
|
||||
}
|
||||
|
||||
bool VR_UseScreenLayer()
|
||||
{
|
||||
return useVirtualScreen || cinemamode;
|
||||
}
|
||||
|
||||
float VR_GetScreenLayerDistance()
|
||||
{
|
||||
return 4.0f;
|
||||
}
|
||||
|
||||
static void UnEscapeQuotes( char *arg )
|
||||
{
|
||||
char *last = NULL;
|
||||
while( *arg ) {
|
||||
if( *arg == '"' && *last == '\\' ) {
|
||||
char *c_curr = arg;
|
||||
char *c_last = last;
|
||||
while( *c_curr ) {
|
||||
*c_last = *c_curr;
|
||||
c_last = c_curr;
|
||||
c_curr++;
|
||||
}
|
||||
*c_last = '\0';
|
||||
}
|
||||
last = arg;
|
||||
arg++;
|
||||
}
|
||||
}
|
||||
|
||||
static int ParseCommandLine(char *cmdline, char **argv)
|
||||
{
|
||||
char *bufp;
|
||||
char *lastp = NULL;
|
||||
int argc, last_argc;
|
||||
argc = last_argc = 0;
|
||||
for ( bufp = cmdline; *bufp; ) {
|
||||
while ( isspace(*bufp) ) {
|
||||
++bufp;
|
||||
}
|
||||
if ( *bufp == '"' ) {
|
||||
++bufp;
|
||||
if ( *bufp ) {
|
||||
if ( argv ) {
|
||||
argv[argc] = bufp;
|
||||
}
|
||||
++argc;
|
||||
}
|
||||
while ( *bufp && ( *bufp != '"' || *lastp == '\\' ) ) {
|
||||
lastp = bufp;
|
||||
++bufp;
|
||||
}
|
||||
} else {
|
||||
if ( *bufp ) {
|
||||
if ( argv ) {
|
||||
argv[argc] = bufp;
|
||||
}
|
||||
++argc;
|
||||
}
|
||||
while ( *bufp && ! isspace(*bufp) ) {
|
||||
++bufp;
|
||||
}
|
||||
}
|
||||
if ( *bufp ) {
|
||||
if ( argv ) {
|
||||
*bufp = '\0';
|
||||
}
|
||||
++bufp;
|
||||
}
|
||||
if( argv && last_argc != argc ) {
|
||||
UnEscapeQuotes( argv[last_argc] );
|
||||
}
|
||||
last_argc = argc;
|
||||
}
|
||||
if ( argv ) {
|
||||
argv[argc] = NULL;
|
||||
}
|
||||
return(argc);
|
||||
}
|
||||
|
||||
|
||||
void VR_SetHMDOrientation(float pitch, float yaw, float roll)
|
||||
{
|
||||
VectorSet(hmdorientation, pitch, yaw, roll);
|
||||
|
||||
if (!VR_UseScreenLayer())
|
||||
{
|
||||
playerYaw = yaw;
|
||||
}
|
||||
}
|
||||
|
||||
void VR_SetHMDPosition(float x, float y, float z )
|
||||
{
|
||||
VectorSet(hmdPosition, x, y, z);
|
||||
|
||||
positionDeltaThisFrame[0] = (worldPosition[0] - x);
|
||||
positionDeltaThisFrame[1] = (worldPosition[1] - y);
|
||||
positionDeltaThisFrame[2] = (worldPosition[2] - z);
|
||||
|
||||
worldPosition[0] = x;
|
||||
worldPosition[1] = y;
|
||||
worldPosition[2] = z;
|
||||
}
|
||||
|
||||
void VR_GetMove(float *joy_forward, float *joy_side, float *hmd_forward, float *hmd_side, float *up,
|
||||
float *yaw, float *pitch, float *roll)
|
||||
{
|
||||
*joy_forward = remote_movementForward;
|
||||
*hmd_forward = positional_movementForward;
|
||||
*up = remote_movementUp;
|
||||
*joy_side = remote_movementSideways;
|
||||
*hmd_side = positional_movementSideways;
|
||||
*yaw = cinemamode ? cinemamodeYaw : hmdorientation[YAW] + snapTurn;
|
||||
*pitch = cinemamode ? cinemamodePitch : hmdorientation[PITCH];
|
||||
*roll = cinemamode ? 0.0f : hmdorientation[ROLL];
|
||||
}
|
||||
|
||||
void VR_DoomMain(int argc, char** argv);
|
||||
|
||||
void VR_Init()
|
||||
{
|
||||
//Initialise all our variables
|
||||
playerYaw = 0.0f;
|
||||
resetDoomYaw = true;
|
||||
resetPreviousPitch = true;
|
||||
remote_movementSideways = 0.0f;
|
||||
remote_movementForward = 0.0f;
|
||||
remote_movementUp = 0.0f;
|
||||
positional_movementSideways = 0.0f;
|
||||
positional_movementForward = 0.0f;
|
||||
snapTurn = 0.0f;
|
||||
cinemamodeYaw = 0.0f;
|
||||
cinemamodePitch = 0.0f;
|
||||
|
||||
//init randomiser
|
||||
srand(time(NULL));
|
||||
|
||||
shutdown = false;
|
||||
ready_teleport = false;
|
||||
trigger_teleport = false;
|
||||
|
||||
cinemamode = false;
|
||||
|
||||
chdir("/sdcard/QuestZDoom");
|
||||
}
|
||||
|
||||
void * AppThreadFunction(void * parm ) {
|
||||
gAppThread = (ovrAppThread *) parm;
|
||||
|
||||
java.Vm = gAppThread->JavaVm;
|
||||
java.Vm->AttachCurrentThread(&java.Env, NULL);
|
||||
java.ActivityObject = gAppThread->ActivityObject;
|
||||
|
||||
jclass cls = java.Env->GetObjectClass(java.ActivityObject);
|
||||
|
||||
// Note that AttachCurrentThread will reset the thread name.
|
||||
prctl(PR_SET_NAME, (long) "AppThreadFunction", 0, 0, 0);
|
||||
|
||||
//Set device defaults
|
||||
if (SS_MULTIPLIER == 0.0f)
|
||||
{
|
||||
//GB Override as refresh is now 72 by default as we decided a higher res is better as 90hz has stutters
|
||||
SS_MULTIPLIER = 1.25f;
|
||||
}
|
||||
else if (SS_MULTIPLIER > 1.5f)
|
||||
{
|
||||
SS_MULTIPLIER = 1.5f;
|
||||
}
|
||||
|
||||
gAppState.MainThreadTid = gettid();
|
||||
|
||||
VR_Init();
|
||||
|
||||
TBXR_InitialiseOpenXR();
|
||||
|
||||
TBXR_EnterVR();
|
||||
TBXR_InitRenderer();
|
||||
TBXR_InitActions();
|
||||
|
||||
TBXR_WaitForSessionActive();
|
||||
|
||||
if (REFRESH != 0)
|
||||
{
|
||||
QzDoom_SetRefreshRate(REFRESH);
|
||||
}
|
||||
|
||||
if (hasIWADs && hasLauncher)
|
||||
{
|
||||
//Should now be all set up and ready - start the Doom main loop
|
||||
VR_DoomMain(argc, argv);
|
||||
}
|
||||
|
||||
TBXR_LeaveVR();
|
||||
|
||||
//Ask Java to shut down
|
||||
VR_Shutdown();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//All the stuff we want to do each frame specifically for this game
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
memcpy(projection, gAppState.ProjectionMatrices[eye].m, 16 * sizeof(float));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
extern "C" {
|
||||
void jni_haptic_event(const char *event, int position, int intensity, float angle, float yHeight);
|
||||
void jni_haptic_updateevent(const char *event, int intensity, float angle);
|
||||
void jni_haptic_stopevent(const char *event);
|
||||
void jni_haptic_endframe();
|
||||
void jni_haptic_enable();
|
||||
void jni_haptic_disable();
|
||||
};
|
||||
|
||||
void VR_ExternalHapticEvent(const char* event, int position, int flags, int intensity, float angle, float yHeight )
|
||||
{
|
||||
jni_haptic_event(event, position, intensity, angle, yHeight);
|
||||
}
|
||||
|
||||
void VR_HapticStopEvent(const char* event)
|
||||
{
|
||||
jni_haptic_stopevent(event);
|
||||
}
|
||||
|
||||
void VR_HapticEnable()
|
||||
{
|
||||
static bool firstTime = true;
|
||||
if (firstTime) {
|
||||
jni_haptic_enable();
|
||||
firstTime = false;
|
||||
jni_haptic_event("fire_pistol", 0, 100, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void VR_HapticDisable()
|
||||
{
|
||||
jni_haptic_disable();
|
||||
}
|
||||
|
||||
void VR_HapticEvent(const char* event, int position, int intensity, float angle, float yHeight )
|
||||
{
|
||||
static char buffer[256];
|
||||
|
||||
memset(buffer, 0, 256);
|
||||
for(int i = 0; event[i]; i++)
|
||||
{
|
||||
buffer[i] = tolower(event[i]);
|
||||
}
|
||||
|
||||
jni_haptic_event(buffer, position, intensity, angle, yHeight);
|
||||
}
|
||||
|
||||
void QzDoom_Vibrate(float duration, int channel, float intensity )
|
||||
{
|
||||
TBXR_Vibrate(duration, channel+1, intensity);
|
||||
}
|
||||
|
||||
void VR_HandleControllerInput() {
|
||||
TBXR_UpdateControllers();
|
||||
|
||||
//Call additional control schemes here
|
||||
switch (vr_control_scheme)
|
||||
{
|
||||
case RIGHT_HANDED_DEFAULT:
|
||||
HandleInput_Default(vr_control_scheme,
|
||||
&rightTrackedRemoteState_new, &rightTrackedRemoteState_old, &rightRemoteTracking_new,
|
||||
&leftTrackedRemoteState_new, &leftTrackedRemoteState_old, &leftRemoteTracking_new,
|
||||
xrButton_A, xrButton_B, xrButton_X, xrButton_Y);
|
||||
break;
|
||||
case LEFT_HANDED_DEFAULT:
|
||||
case LEFT_HANDED_ALT:
|
||||
HandleInput_Default(vr_control_scheme,
|
||||
&leftTrackedRemoteState_new, &leftTrackedRemoteState_old, &leftRemoteTracking_new,
|
||||
&rightTrackedRemoteState_new, &rightTrackedRemoteState_old, &rightRemoteTracking_new,
|
||||
xrButton_X, xrButton_Y, xrButton_A, xrButton_B);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
|
||||
Activity lifecycle
|
||||
|
||||
================================================================================
|
||||
*/
|
||||
|
||||
jmethodID android_shutdown;
|
||||
jmethodID android_reload;
|
||||
static JavaVM *jVM;
|
||||
static jobject jniCallbackObj=0;
|
||||
|
||||
void jni_shutdown()
|
||||
{
|
||||
ALOGV("Calling: jni_shutdown");
|
||||
JNIEnv *env;
|
||||
jobject tmp;
|
||||
if ((jVM->GetEnv((void**) &env, JNI_VERSION_1_4))<0)
|
||||
{
|
||||
jVM->AttachCurrentThread(&env, NULL);
|
||||
}
|
||||
return env->CallVoidMethod(jniCallbackObj, android_shutdown);
|
||||
}
|
||||
|
||||
void VR_Shutdown()
|
||||
{
|
||||
jni_shutdown();
|
||||
}
|
||||
|
||||
void jni_reload(const char* profile)
|
||||
{
|
||||
ALOGV("Calling: jni_reload");
|
||||
JNIEnv *env;
|
||||
jobject tmp;
|
||||
if ((jVM->GetEnv((void**) &env, JNI_VERSION_1_4))<0)
|
||||
{
|
||||
jVM->AttachCurrentThread(&env, NULL);
|
||||
}
|
||||
jstring jprofile = env->NewStringUTF(profile);
|
||||
return env->CallVoidMethod(jniCallbackObj, android_reload, jprofile);
|
||||
}
|
||||
|
||||
|
||||
void QzDoom_Restart()
|
||||
{
|
||||
const char* profile = M_GetActiveProfile();
|
||||
//Ask Java to restart the app
|
||||
jni_reload(profile);
|
||||
}
|
||||
|
||||
|
||||
jmethodID android_haptic_event;
|
||||
jmethodID android_haptic_stopevent;
|
||||
jmethodID android_haptic_enable;
|
||||
jmethodID android_haptic_disable;
|
||||
|
||||
void jni_haptic_event(const char* event, int position, int intensity, float angle, float yHeight)
|
||||
{
|
||||
JNIEnv *env;
|
||||
jobject tmp;
|
||||
if ((jVM->GetEnv((void**) &env, JNI_VERSION_1_4))<0)
|
||||
{
|
||||
jVM->AttachCurrentThread(&env, NULL);
|
||||
}
|
||||
|
||||
jstring StringArg1 = env->NewStringUTF(event);
|
||||
|
||||
return env->CallVoidMethod(jniCallbackObj, android_haptic_event, StringArg1, position, intensity, angle, yHeight);
|
||||
}
|
||||
|
||||
void jni_haptic_stopevent(const char* event)
|
||||
{
|
||||
ALOGV("Calling: jni_haptic_stopevent");
|
||||
JNIEnv *env;
|
||||
jobject tmp;
|
||||
if ((jVM->GetEnv((void**) &env, JNI_VERSION_1_4))<0)
|
||||
{
|
||||
jVM->AttachCurrentThread(&env, NULL);
|
||||
}
|
||||
|
||||
jstring StringArg1 = env->NewStringUTF(event);
|
||||
|
||||
return env->CallVoidMethod(jniCallbackObj, android_haptic_stopevent, StringArg1);
|
||||
}
|
||||
|
||||
|
||||
void jni_haptic_enable()
|
||||
{
|
||||
ALOGV("Calling: jni_haptic_enable");
|
||||
JNIEnv *env;
|
||||
jobject tmp;
|
||||
if ((jVM->GetEnv((void**) &env, JNI_VERSION_1_4))<0)
|
||||
{
|
||||
jVM->AttachCurrentThread(&env, NULL);
|
||||
}
|
||||
|
||||
return env->CallVoidMethod(jniCallbackObj, android_haptic_enable);
|
||||
}
|
||||
|
||||
void jni_haptic_disable()
|
||||
{
|
||||
ALOGV("Calling: jni_haptic_disable");
|
||||
JNIEnv *env;
|
||||
jobject tmp;
|
||||
if ((jVM->GetEnv((void**) &env, JNI_VERSION_1_4))<0)
|
||||
{
|
||||
jVM->AttachCurrentThread(&env, NULL);
|
||||
}
|
||||
|
||||
return env->CallVoidMethod(jniCallbackObj, android_haptic_disable);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
int JNI_OnLoad(JavaVM* vm, void* reserved)
|
||||
{
|
||||
JNIEnv *env;
|
||||
jVM = vm;
|
||||
if(vm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK)
|
||||
{
|
||||
ALOGE("Failed JNI_OnLoad");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return JNI_VERSION_1_4;
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL Java_com_drbeef_questzdoom_GLES3JNILib_onCreate( JNIEnv * env, jclass activityClass, jobject activity,
|
||||
jstring commandLineParams, jboolean jHasIWADs, jboolean jHasLauncher)
|
||||
{
|
||||
ALOGV( " GLES3JNILib::onCreate()" );
|
||||
|
||||
/* the global arg_xxx structs are initialised within the argtable */
|
||||
void *argtable[] = {
|
||||
ss = arg_dbl0("s", "supersampling", "<double>", "super sampling value (default: Q1: 1.2, Q2: 1.35)"),
|
||||
cpu = arg_int0("c", "cpu", "<int>", "CPU perf index 1-4 (default: 2)"),
|
||||
gpu = arg_int0("g", "gpu", "<int>", "GPU perf index 1-4 (default: 3)"),
|
||||
msaa = arg_int0("m", "msaa", "<int>", "MSAA (default: 1)"),
|
||||
refresh = arg_int0("r", "refresh", "<int>", "Refresh Rate (default: Q1: 72, Q2: 72)"),
|
||||
end = arg_end(20)
|
||||
};
|
||||
|
||||
hasIWADs = jHasIWADs != 0;
|
||||
hasLauncher = jHasLauncher != 0;
|
||||
|
||||
jboolean iscopy;
|
||||
const char *arg = env->GetStringUTFChars(commandLineParams, &iscopy);
|
||||
|
||||
char *cmdLine = NULL;
|
||||
if (arg && strlen(arg))
|
||||
{
|
||||
cmdLine = strdup(arg);
|
||||
}
|
||||
|
||||
env->ReleaseStringUTFChars(commandLineParams, arg);
|
||||
|
||||
ALOGV("Command line %s", cmdLine);
|
||||
argv = (char**)malloc(sizeof(char*) * 255);
|
||||
argc = ParseCommandLine(strdup(cmdLine), argv);
|
||||
|
||||
/* verify the argtable[] entries were allocated sucessfully */
|
||||
if (arg_nullcheck(argtable) == 0) {
|
||||
/* Parse the command line as defined by argtable[] */
|
||||
arg_parse(argc, argv, argtable);
|
||||
|
||||
if (ss->count > 0 && ss->dval[0] > 0.0)
|
||||
{
|
||||
SS_MULTIPLIER = ss->dval[0];
|
||||
}
|
||||
|
||||
if (msaa->count > 0 && msaa->ival[0] > 0 && msaa->ival[0] < 10)
|
||||
{
|
||||
NUM_MULTI_SAMPLES = msaa->ival[0];
|
||||
}
|
||||
|
||||
if (refresh->count > 0 && refresh->ival[0] > 0 && refresh->ival[0] <= 120)
|
||||
{
|
||||
REFRESH = refresh->ival[0];
|
||||
}
|
||||
}
|
||||
|
||||
ovrAppThread * appThread = (ovrAppThread *) malloc( sizeof( ovrAppThread ) );
|
||||
ovrAppThread_Create( appThread, env, activity, activityClass );
|
||||
|
||||
surfaceMessageQueue_Enable(&appThread->MessageQueue, true);
|
||||
srufaceMessage message;
|
||||
surfaceMessage_Init(&message, MESSAGE_ON_CREATE, MQ_WAIT_PROCESSED);
|
||||
surfaceMessageQueue_PostMessage(&appThread->MessageQueue, &message);
|
||||
|
||||
return (jlong)((size_t)appThread);
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_questzdoom_GLES3JNILib_onStart( JNIEnv * env, jobject obj, jlong handle, jobject obj1)
|
||||
{
|
||||
ALOGV( " GLES3JNILib::onStart()" );
|
||||
|
||||
|
||||
jniCallbackObj = (jobject)env->NewGlobalRef( obj1);
|
||||
jclass callbackClass = env->GetObjectClass( jniCallbackObj);
|
||||
|
||||
android_shutdown = env->GetMethodID(callbackClass,"shutdown","()V");
|
||||
android_reload = env->GetMethodID(callbackClass,"reload","(Ljava/lang/String;)V");
|
||||
|
||||
android_haptic_event = env->GetMethodID(callbackClass, "haptic_event", "(Ljava/lang/String;IIFF)V");
|
||||
android_haptic_stopevent = env->GetMethodID(callbackClass, "haptic_stopevent", "(Ljava/lang/String;)V");
|
||||
android_haptic_enable = env->GetMethodID(callbackClass, "haptic_enable", "()V");
|
||||
android_haptic_disable = env->GetMethodID(callbackClass, "haptic_disable", "()V");
|
||||
|
||||
ovrAppThread * appThread = (ovrAppThread *)((size_t)handle);
|
||||
srufaceMessage message;
|
||||
surfaceMessage_Init(&message, MESSAGE_ON_START, MQ_WAIT_PROCESSED);
|
||||
surfaceMessageQueue_PostMessage(&appThread->MessageQueue, &message);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_questzdoom_GLES3JNILib_onResume( JNIEnv * env, jobject obj, jlong handle )
|
||||
{
|
||||
ALOGV( " GLES3JNILib::onResume()" );
|
||||
ovrAppThread * appThread = (ovrAppThread *)((size_t)handle);
|
||||
srufaceMessage message;
|
||||
surfaceMessage_Init(&message, MESSAGE_ON_RESUME, MQ_WAIT_PROCESSED);
|
||||
surfaceMessageQueue_PostMessage(&appThread->MessageQueue, &message);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_questzdoom_GLES3JNILib_onPause( JNIEnv * env, jobject obj, jlong handle )
|
||||
{
|
||||
ALOGV( " GLES3JNILib::onPause()" );
|
||||
ovrAppThread * appThread = (ovrAppThread *)((size_t)handle);
|
||||
srufaceMessage message;
|
||||
surfaceMessage_Init(&message, MESSAGE_ON_PAUSE, MQ_WAIT_PROCESSED);
|
||||
surfaceMessageQueue_PostMessage(&appThread->MessageQueue, &message);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_questzdoom_GLES3JNILib_onStop( JNIEnv * env, jobject obj, jlong handle )
|
||||
{
|
||||
ALOGV( " GLES3JNILib::onStop()" );
|
||||
ovrAppThread * appThread = (ovrAppThread *)((size_t)handle);
|
||||
srufaceMessage message;
|
||||
surfaceMessage_Init(&message, MESSAGE_ON_STOP, MQ_WAIT_PROCESSED);
|
||||
surfaceMessageQueue_PostMessage(&appThread->MessageQueue, &message);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_questzdoom_GLES3JNILib_onDestroy( JNIEnv * env, jobject obj, jlong handle )
|
||||
{
|
||||
ALOGV( " GLES3JNILib::onDestroy()" );
|
||||
ovrAppThread * appThread = (ovrAppThread *)((size_t)handle);
|
||||
srufaceMessage message;
|
||||
surfaceMessage_Init(&message, MESSAGE_ON_DESTROY, MQ_WAIT_PROCESSED);
|
||||
surfaceMessageQueue_PostMessage(&appThread->MessageQueue, &message);
|
||||
surfaceMessageQueue_Enable(&appThread->MessageQueue, false);
|
||||
|
||||
ovrAppThread_Destroy( appThread, env );
|
||||
free( appThread );
|
||||
}
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
|
||||
Surface lifecycle
|
||||
|
||||
================================================================================
|
||||
*/
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_questzdoom_GLES3JNILib_onSurfaceCreated( JNIEnv * env, jobject obj, jlong handle, jobject surface )
|
||||
{
|
||||
ALOGV( " GLES3JNILib::onSurfaceCreated()" );
|
||||
ovrAppThread * appThread = (ovrAppThread *)((size_t)handle);
|
||||
|
||||
ANativeWindow * newNativeWindow = ANativeWindow_fromSurface( env, surface );
|
||||
if ( ANativeWindow_getWidth( newNativeWindow ) < ANativeWindow_getHeight( newNativeWindow ) )
|
||||
{
|
||||
// An app that is relaunched after pressing the home button gets an initial surface with
|
||||
// the wrong orientation even though android:screenOrientation="landscape" is set in the
|
||||
// manifest. The choreographer callback will also never be called for this surface because
|
||||
// the surface is immediately replaced with a new surface with the correct orientation.
|
||||
ALOGE( " Surface not in landscape mode!" );
|
||||
}
|
||||
|
||||
ALOGV( " NativeWindow = ANativeWindow_fromSurface( env, surface )" );
|
||||
appThread->NativeWindow = newNativeWindow;
|
||||
srufaceMessage message;
|
||||
surfaceMessage_Init(&message, MESSAGE_ON_SURFACE_CREATED, MQ_WAIT_PROCESSED);
|
||||
surfaceMessage_SetPointerParm(&message, 0, appThread->NativeWindow);
|
||||
surfaceMessageQueue_PostMessage(&appThread->MessageQueue, &message);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_questzdoom_GLES3JNILib_onSurfaceChanged( JNIEnv * env, jobject obj, jlong handle, jobject surface )
|
||||
{
|
||||
ALOGV( " GLES3JNILib::onSurfaceChanged()" );
|
||||
ovrAppThread * appThread = (ovrAppThread *)((size_t)handle);
|
||||
|
||||
ANativeWindow * newNativeWindow = ANativeWindow_fromSurface( env, surface );
|
||||
if ( ANativeWindow_getWidth( newNativeWindow ) < ANativeWindow_getHeight( newNativeWindow ) )
|
||||
{
|
||||
// An app that is relaunched after pressing the home button gets an initial surface with
|
||||
// the wrong orientation even though android:screenOrientation="landscape" is set in the
|
||||
// manifest. The choreographer callback will also never be called for this surface because
|
||||
// the surface is immediately replaced with a new surface with the correct orientation.
|
||||
ALOGE( " Surface not in landscape mode!" );
|
||||
}
|
||||
|
||||
if ( newNativeWindow != appThread->NativeWindow )
|
||||
{
|
||||
if ( appThread->NativeWindow != NULL )
|
||||
{
|
||||
srufaceMessage message;
|
||||
surfaceMessage_Init(&message, MESSAGE_ON_SURFACE_DESTROYED, MQ_WAIT_PROCESSED);
|
||||
surfaceMessageQueue_PostMessage(&appThread->MessageQueue, &message);
|
||||
ALOGV( " ANativeWindow_release( NativeWindow )" );
|
||||
ANativeWindow_release( appThread->NativeWindow );
|
||||
appThread->NativeWindow = NULL;
|
||||
}
|
||||
if ( newNativeWindow != NULL )
|
||||
{
|
||||
ALOGV( " NativeWindow = ANativeWindow_fromSurface( env, surface )" );
|
||||
appThread->NativeWindow = newNativeWindow;
|
||||
srufaceMessage message;
|
||||
surfaceMessage_Init(&message, MESSAGE_ON_SURFACE_CREATED, MQ_WAIT_PROCESSED);
|
||||
surfaceMessage_SetPointerParm(&message, 0, appThread->NativeWindow);
|
||||
surfaceMessageQueue_PostMessage(&appThread->MessageQueue, &message);
|
||||
}
|
||||
}
|
||||
else if ( newNativeWindow != NULL )
|
||||
{
|
||||
ANativeWindow_release( newNativeWindow );
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_questzdoom_GLES3JNILib_onSurfaceDestroyed( JNIEnv * env, jobject obj, jlong handle )
|
||||
{
|
||||
ALOGV( " GLES3JNILib::onSurfaceDestroyed()" );
|
||||
ovrAppThread * appThread = (ovrAppThread *)((size_t)handle);
|
||||
srufaceMessage message;
|
||||
surfaceMessage_Init(&message, MESSAGE_ON_SURFACE_DESTROYED, MQ_WAIT_PROCESSED);
|
||||
surfaceMessageQueue_PostMessage(&appThread->MessageQueue, &message);
|
||||
ALOGV( " ANativeWindow_release( NativeWindow )" );
|
||||
ANativeWindow_release( appThread->NativeWindow );
|
||||
appThread->NativeWindow = NULL;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_drbeef_questzdoom_GLES3JNILib_prepareEnvironment(JNIEnv * env, jclass obj, jstring path) {
|
||||
auto p = env->GetStringUTFChars(path, NULL);
|
||||
progdir = p;
|
||||
chdir(p);
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load diff
2030
Projects/Android/jni/QzDoom/TBXR_Common.cpp
Normal file
2030
Projects/Android/jni/QzDoom/TBXR_Common.cpp
Normal file
File diff suppressed because it is too large
Load diff
338
Projects/Android/jni/QzDoom/TBXR_Common.h
Normal file
338
Projects/Android/jni/QzDoom/TBXR_Common.h
Normal file
|
@ -0,0 +1,338 @@
|
|||
#if !defined(tbxr_common_h)
|
||||
#define tbxr_common_h
|
||||
|
||||
//OpenXR
|
||||
#define XR_USE_GRAPHICS_API_OPENGL_ES 1
|
||||
#define XR_USE_PLATFORM_ANDROID 1
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <GLES3/gl3.h>
|
||||
#include <GLES3/gl3ext.h>
|
||||
#include <jni.h>
|
||||
#include <openxr/openxr.h>
|
||||
#include <openxr/openxr_platform.h>
|
||||
#include <openxr_helpers.h>
|
||||
|
||||
#include <android/native_window_jni.h>
|
||||
#include <android/log.h>
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define DEBUG 1
|
||||
#endif
|
||||
|
||||
#define LOG_TAG "TBXR"
|
||||
|
||||
|
||||
#define ALOGE(...) __android_log_print( ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__ )
|
||||
|
||||
#if DEBUG
|
||||
#define ALOGV(...) __android_log_print( ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__ )
|
||||
#else
|
||||
#define ALOGV(...)
|
||||
#endif
|
||||
|
||||
enum { ovrMaxLayerCount = 1 };
|
||||
enum { ovrMaxNumEyes = 2 };
|
||||
|
||||
typedef enum xrButton_ {
|
||||
xrButton_A = 0x00000001,
|
||||
xrButton_B = 0x00000002,
|
||||
xrButton_RThumb = 0x00000004,
|
||||
xrButton_RShoulder = 0x00000008,
|
||||
xrButton_X = 0x00000100,
|
||||
xrButton_Y = 0x00000200,
|
||||
xrButton_LThumb = 0x00000400,
|
||||
xrButton_LShoulder = 0x00000800,
|
||||
xrButton_Up = 0x00010000,
|
||||
xrButton_Down = 0x00020000,
|
||||
xrButton_Left = 0x00040000,
|
||||
xrButton_Right = 0x00080000,
|
||||
xrButton_Enter = 0x00100000,
|
||||
xrButton_Back = 0x00200000,
|
||||
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;
|
||||
} ovrInputStateTrackedRemote;
|
||||
|
||||
typedef struct {
|
||||
GLboolean Active;
|
||||
XrPosef Pose;
|
||||
XrSpaceVelocity Velocity;
|
||||
} ovrTrackedController;
|
||||
|
||||
typedef enum control_scheme {
|
||||
RIGHT_HANDED_DEFAULT = 0,
|
||||
LEFT_HANDED_DEFAULT = 10,
|
||||
LEFT_HANDED_ALT = 11
|
||||
} control_scheme_t;
|
||||
|
||||
typedef struct {
|
||||
float M[4][4];
|
||||
} ovrMatrix4f;
|
||||
|
||||
|
||||
typedef struct {
|
||||
XrSwapchain Handle;
|
||||
uint32_t Width;
|
||||
uint32_t Height;
|
||||
} ovrSwapChain;
|
||||
|
||||
typedef struct {
|
||||
int Width;
|
||||
int Height;
|
||||
int Multisamples;
|
||||
uint32_t TextureSwapChainLength;
|
||||
uint32_t TextureSwapChainIndex;
|
||||
ovrSwapChain ColorSwapChain;
|
||||
XrSwapchainImageOpenGLESKHR* ColorSwapChainImage;
|
||||
GLuint* DepthBuffers;
|
||||
GLuint* FrameBuffers;
|
||||
} ovrFramebuffer;
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
|
||||
ovrRenderer
|
||||
|
||||
================================================================================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ovrFramebuffer FrameBuffer[ovrMaxNumEyes];
|
||||
} ovrRenderer;
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
|
||||
ovrApp
|
||||
|
||||
================================================================================
|
||||
*/
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MQ_WAIT_NONE, // don't wait
|
||||
MQ_WAIT_RECEIVED, // wait until the consumer thread has received the message
|
||||
MQ_WAIT_PROCESSED // wait until the consumer thread has processed the message
|
||||
} ovrMQWait;
|
||||
|
||||
#define MAX_MESSAGE_PARMS 8
|
||||
#define MAX_MESSAGES 1024
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int Id;
|
||||
ovrMQWait Wait;
|
||||
long long Parms[MAX_MESSAGE_PARMS];
|
||||
} srufaceMessage;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
srufaceMessage Messages[MAX_MESSAGES];
|
||||
volatile int Head; // dequeue at the head
|
||||
volatile int Tail; // enqueue at the tail
|
||||
ovrMQWait Wait;
|
||||
volatile bool EnabledFlag;
|
||||
volatile bool PostedFlag;
|
||||
volatile bool ReceivedFlag;
|
||||
volatile bool ProcessedFlag;
|
||||
pthread_mutex_t Mutex;
|
||||
pthread_cond_t PostedCondition;
|
||||
pthread_cond_t ReceivedCondition;
|
||||
pthread_cond_t ProcessedCondition;
|
||||
} surfaceMessageQueue;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
JavaVM * JavaVm;
|
||||
jobject ActivityObject;
|
||||
jclass ActivityClass;
|
||||
pthread_t Thread;
|
||||
surfaceMessageQueue MessageQueue;
|
||||
ANativeWindow * NativeWindow;
|
||||
} ovrAppThread;
|
||||
|
||||
|
||||
typedef union {
|
||||
XrCompositionLayerProjection Projection;
|
||||
XrCompositionLayerQuad Quad;
|
||||
} xrCompositorLayer_Union;
|
||||
|
||||
#define GL(func) func;
|
||||
|
||||
// Forward declarations
|
||||
XrInstance TBXR_GetXrInstance();
|
||||
|
||||
#if defined(DEBUG)
|
||||
static void
|
||||
OXR_CheckErrors(XrInstance instance, XrResult result, const char* function, bool failOnError) {
|
||||
if (XR_FAILED(result)) {
|
||||
char errorBuffer[XR_MAX_RESULT_STRING_SIZE];
|
||||
xrResultToString(instance, result, errorBuffer);
|
||||
if (failOnError) {
|
||||
ALOGE("OpenXR error: %s: %s\n", function, errorBuffer);
|
||||
} else {
|
||||
ALOGV("OpenXR error: %s: %s\n", function, errorBuffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG)
|
||||
#define OXR(func) OXR_CheckErrors(TBXR_GetXrInstance(), func, #func, true);
|
||||
#else
|
||||
#define OXR(func) func;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
EGLint MajorVersion;
|
||||
EGLint MinorVersion;
|
||||
EGLDisplay Display;
|
||||
EGLConfig Config;
|
||||
EGLSurface TinySurface;
|
||||
EGLSurface MainSurface;
|
||||
EGLContext Context;
|
||||
} ovrEgl;
|
||||
|
||||
/// Java details about an activity
|
||||
typedef struct ovrJava_ {
|
||||
JavaVM* Vm; //< Java Virtual Machine
|
||||
JNIEnv* Env; //< Thread specific environment
|
||||
jobject ActivityObject; //< Java activity object
|
||||
} ovrJava;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ovrJava Java;
|
||||
ovrEgl Egl;
|
||||
ANativeWindow* NativeWindow;
|
||||
bool Resumed;
|
||||
bool Focused;
|
||||
int FrameSetupRefCount;
|
||||
char* OpenXRHMD;
|
||||
|
||||
float Width;
|
||||
float Height;
|
||||
|
||||
XrInstance Instance;
|
||||
XrSession Session;
|
||||
XrViewConfigurationProperties ViewportConfig;
|
||||
XrViewConfigurationView ViewConfigurationView[ovrMaxNumEyes];
|
||||
XrSystemId SystemId;
|
||||
XrSpace HeadSpace;
|
||||
XrSpace StageSpace;
|
||||
XrSpace FakeStageSpace;
|
||||
XrSpace CurrentSpace;
|
||||
GLboolean SessionActive;
|
||||
XrPosef xfStageFromHead;
|
||||
XrView* Projections;
|
||||
XrMatrix4x4f ProjectionMatrices[2];
|
||||
|
||||
|
||||
float currentDisplayRefreshRate;
|
||||
float* SupportedDisplayRefreshRates;
|
||||
uint32_t RequestedDisplayRefreshRateIndex;
|
||||
uint32_t NumSupportedDisplayRefreshRates;
|
||||
PFN_xrGetDisplayRefreshRateFB pfnGetDisplayRefreshRate;
|
||||
PFN_xrRequestDisplayRefreshRateFB pfnRequestDisplayRefreshRate;
|
||||
|
||||
XrFrameState FrameState;
|
||||
int SwapInterval;
|
||||
int MainThreadTid;
|
||||
int RenderThreadTid;
|
||||
xrCompositorLayer_Union Layers[ovrMaxLayerCount];
|
||||
int LayerCount;
|
||||
ovrRenderer Renderer;
|
||||
ovrTrackedController TrackedController[2];
|
||||
} ovrApp;
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
MESSAGE_ON_CREATE,
|
||||
MESSAGE_ON_START,
|
||||
MESSAGE_ON_RESUME,
|
||||
MESSAGE_ON_PAUSE,
|
||||
MESSAGE_ON_STOP,
|
||||
MESSAGE_ON_DESTROY,
|
||||
MESSAGE_ON_SURFACE_CREATED,
|
||||
MESSAGE_ON_SURFACE_DESTROYED
|
||||
};
|
||||
|
||||
extern ovrAppThread * gAppThread;
|
||||
extern ovrApp gAppState;
|
||||
extern ovrJava java;
|
||||
|
||||
|
||||
void ovrTrackedController_Clear(ovrTrackedController* controller);
|
||||
|
||||
void * AppThreadFunction(void * parm );
|
||||
|
||||
void ovrAppThread_Create( ovrAppThread * appThread, JNIEnv * env, jobject activityObject, jclass activityClass );
|
||||
void ovrAppThread_Destroy( ovrAppThread * appThread, JNIEnv * env );
|
||||
|
||||
/*
|
||||
* Surface Lifecycle Message Queue
|
||||
*/
|
||||
void surfaceMessage_Init(srufaceMessage * message, const int id, const int wait );
|
||||
void * surfaceMessage_GetPointerParm(srufaceMessage * message, int index );
|
||||
void surfaceMessage_SetPointerParm(srufaceMessage * message, int index, void * ptr );
|
||||
|
||||
void surfaceMessageQueue_Create(surfaceMessageQueue * messageQueue );
|
||||
void surfaceMessageQueue_Destroy(surfaceMessageQueue * messageQueue );
|
||||
void surfaceMessageQueue_Enable(surfaceMessageQueue * messageQueue, const bool set );
|
||||
void surfaceMessageQueue_PostMessage(surfaceMessageQueue * messageQueue, const srufaceMessage * message );
|
||||
|
||||
//Functions that need to be implemented by the game specific code
|
||||
void VR_FrameSetup();
|
||||
bool VR_UseScreenLayer();
|
||||
float VR_GetScreenLayerDistance();
|
||||
bool VR_GetVRProjection(int eye, float zNear, float zFar, float* projection);
|
||||
void VR_HandleControllerInput();
|
||||
void VR_SetHMDOrientation(float pitch, float yaw, float roll );
|
||||
void VR_SetHMDPosition(float x, float y, float z );
|
||||
void VR_HapticEvent(const char* event, int position, int intensity, float angle, float yHeight );
|
||||
void VR_HapticUpdateEvent(const char* event, int intensity, float angle );
|
||||
void VR_HapticEndFrame();
|
||||
void VR_HapticStopEvent(const char* event);
|
||||
void VR_HapticEnable();
|
||||
void VR_HapticDisable();
|
||||
void VR_Shutdown();
|
||||
|
||||
|
||||
//Reusable Team Beef OpenXR stuff (in TBXR_Common.cpp)
|
||||
double TBXR_GetTimeInMilliSeconds();
|
||||
int TBXR_GetRefresh();
|
||||
void TBXR_Recenter();
|
||||
void TBXR_InitialiseOpenXR();
|
||||
void TBXR_WaitForSessionActive();
|
||||
void TBXR_InitRenderer();
|
||||
void TBXR_EnterVR();
|
||||
void TBXR_LeaveVR( );
|
||||
void TBXR_GetScreenRes(int *width, int *height);
|
||||
void TBXR_InitActions( void );
|
||||
void TBXR_Vibrate(int duration, int channel, float intensity );
|
||||
void TBXR_ProcessHaptics();
|
||||
bool TBXR_FrameSetup();
|
||||
void TBXR_updateProjections();
|
||||
void TBXR_UpdateControllers( );
|
||||
void TBXR_prepareEyeBuffer(int eye );
|
||||
void TBXR_finishEyeBuffer(int eye );
|
||||
void TBXR_submitFrame();
|
||||
|
||||
#endif //vrcommon_h
|
|
@ -1,13 +1,22 @@
|
|||
#if !defined(vrcommon_h)
|
||||
#define vrcommon_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#include "TBXR_Common.h"
|
||||
|
||||
#include "c_cvars.h"
|
||||
|
||||
EXTERN_CVAR(Int, vr_control_scheme)
|
||||
EXTERN_CVAR(Bool, vr_move_use_offhand)
|
||||
EXTERN_CVAR(Float, vr_weaponRotate);
|
||||
EXTERN_CVAR(Float, vr_snapTurn);
|
||||
EXTERN_CVAR(Float, vr_ipd);
|
||||
EXTERN_CVAR(Float, vr_weaponScale);
|
||||
EXTERN_CVAR(Bool, vr_teleport);
|
||||
EXTERN_CVAR(Bool, vr_switch_sticks);
|
||||
EXTERN_CVAR(Bool, vr_secondary_button_mappings);
|
||||
EXTERN_CVAR(Bool, vr_two_handed_weapons);
|
||||
EXTERN_CVAR(Bool, vr_crouch_use_button);
|
||||
|
||||
//#include <VrApi_Ext.h>
|
||||
#include <VrApi_Input.h>
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
|
@ -50,16 +59,6 @@ extern vec3_t positionDeltaThisFrame;
|
|||
extern vec3_t weaponangles;
|
||||
extern vec3_t weaponoffset;
|
||||
|
||||
extern bool weaponStabilised;
|
||||
extern float vr_weapon_pitchadjust;
|
||||
extern bool vr_moveuseoffhand;
|
||||
extern bool vr_switchsticks;
|
||||
extern bool vr_secondarybuttonmappings;
|
||||
extern bool vr_twohandedweapons;
|
||||
extern float vr_snapturn_angle;
|
||||
extern float vr_use_teleport;
|
||||
|
||||
|
||||
extern vec3_t offhandangles;
|
||||
extern vec3_t offhandoffset;
|
||||
|
||||
|
@ -69,43 +68,18 @@ extern bool ready_teleport;
|
|||
extern bool trigger_teleport;
|
||||
|
||||
extern bool shutdown;
|
||||
void shutdownVR();
|
||||
|
||||
float radians(float deg);
|
||||
float degrees(float rad);
|
||||
bool isMultiplayer();
|
||||
double GetTimeInMilliSeconds();
|
||||
float length(float x, float y);
|
||||
float nonLinearFilter(float in);
|
||||
bool between(float min, float val, float max);
|
||||
void rotateAboutOrigin(float v1, float v2, float rotation, vec2_t out);
|
||||
void QuatToYawPitchRoll(ovrQuatf q, vec3_t rotation, vec3_t out);
|
||||
void handleTrackedControllerButton(ovrInputStateTrackedRemote * trackedRemoteState, ovrInputStateTrackedRemote * prevTrackedRemoteState, uint32_t button, int key);
|
||||
void QuatToYawPitchRoll(XrQuaternionf q, vec3_t rotation, vec3_t out);
|
||||
|
||||
//Called from engine code
|
||||
bool QzDoom_useScreenLayer();
|
||||
void QzDoom_GetScreenRes(uint32_t *width, uint32_t *height);
|
||||
void QzDoom_Vibrate(float duration, int channel, float intensity );
|
||||
bool QzDoom_processMessageQueue();
|
||||
void QzDoom_FrameSetup();
|
||||
void QzDoom_setUseScreenLayer(bool use);
|
||||
void QzDoom_processHaptics();
|
||||
void QzDoom_getHMDOrientation(ovrTracking2 *tracking);
|
||||
void QzDoom_getTrackedRemotesOrientation(int vr_control_scheme);
|
||||
int QzDoom_SetRefreshRate(int refreshRate);
|
||||
void QzDoom_Restart();
|
||||
|
||||
void QzDoom_HapticEvent(const char* event, int position, int intensity, float angle, float yHeight );
|
||||
void QzDoom_HapticEnable();
|
||||
void QzDoom_HapticDisable();
|
||||
|
||||
void incrementFrameIndex();
|
||||
|
||||
void QzDoom_prepareEyeBuffer(int eye );
|
||||
void QzDoom_finishEyeBuffer(int eye );
|
||||
void QzDoom_submitFrame(ovrTracking2 *tracking);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif //vrcommon_h
|
|
@ -1,595 +0,0 @@
|
|||
/************************************************************************************
|
||||
|
||||
Filename : VrCompositor.c
|
||||
|
||||
*************************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/prctl.h> // for prctl( PR_SET_NAME )
|
||||
#include <android/log.h>
|
||||
#include <android/window.h> // for AWINDOW_FLAG_KEEP_SCREEN_ON
|
||||
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <GLES3/gl3.h>
|
||||
#include <GLES3/gl3ext.h>
|
||||
|
||||
|
||||
|
||||
#include <VrApi.h>
|
||||
#include <VrApi_Helpers.h>
|
||||
|
||||
#include "VrCompositor.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
|
||||
renderState
|
||||
|
||||
================================================================================
|
||||
*/
|
||||
|
||||
|
||||
void getCurrentRenderState( renderState * state)
|
||||
{
|
||||
state->VertexBuffer = 0;
|
||||
state->IndexBuffer = 0;
|
||||
state->VertexArrayObject = 0;
|
||||
state->Program = 0;
|
||||
|
||||
glGetIntegerv(GL_ARRAY_BUFFER, &state->VertexBuffer );
|
||||
glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER, &state->IndexBuffer );
|
||||
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &state->VertexArrayObject );
|
||||
glGetIntegerv(GL_CURRENT_PROGRAM, &state->Program );
|
||||
}
|
||||
|
||||
void restoreRenderState( renderState * state )
|
||||
{
|
||||
GL( glUseProgram( state->Program ) );
|
||||
GL( glBindVertexArray( state->VertexArrayObject ) );
|
||||
GL( glBindBuffer( GL_ARRAY_BUFFER, state->VertexBuffer ) );
|
||||
GL( glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, state->IndexBuffer ) );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
|
||||
ovrGeometry
|
||||
|
||||
================================================================================
|
||||
*/
|
||||
|
||||
enum VertexAttributeLocation
|
||||
{
|
||||
VERTEX_ATTRIBUTE_LOCATION_POSITION,
|
||||
VERTEX_ATTRIBUTE_LOCATION_COLOR,
|
||||
VERTEX_ATTRIBUTE_LOCATION_UV,
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
enum VertexAttributeLocation location;
|
||||
const char * name;
|
||||
} ovrVertexAttribute;
|
||||
|
||||
static ovrVertexAttribute ProgramVertexAttributes[] =
|
||||
{
|
||||
{ VERTEX_ATTRIBUTE_LOCATION_POSITION, "vertexPosition" },
|
||||
{ VERTEX_ATTRIBUTE_LOCATION_COLOR, "vertexColor" },
|
||||
{ VERTEX_ATTRIBUTE_LOCATION_UV, "vertexUv" },
|
||||
};
|
||||
|
||||
static void ovrGeometry_Clear( ovrGeometry * geometry )
|
||||
{
|
||||
geometry->VertexBuffer = 0;
|
||||
geometry->IndexBuffer = 0;
|
||||
geometry->VertexArrayObject = 0;
|
||||
geometry->VertexCount = 0;
|
||||
geometry->IndexCount = 0;
|
||||
for ( int i = 0; i < MAX_VERTEX_ATTRIB_POINTERS; i++ )
|
||||
{
|
||||
memset( &geometry->VertexAttribs[i], 0, sizeof( geometry->VertexAttribs[i] ) );
|
||||
geometry->VertexAttribs[i].Index = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void ovrGeometry_CreateGroundPlane( ovrGeometry * geometry )
|
||||
{
|
||||
typedef struct
|
||||
{
|
||||
float positions[4][4];
|
||||
unsigned char colors[4][4];
|
||||
} ovrCubeVertices;
|
||||
|
||||
static const ovrCubeVertices cubeVertices =
|
||||
{
|
||||
// positions
|
||||
{
|
||||
{ 4.5f, -1.2f, 4.5f, 1.0f },
|
||||
{ 4.5f, -1.2f, -4.5f, 1.0f },
|
||||
{ -4.5f, -1.2f, -4.5f, 1.0f },
|
||||
{ -4.5f, -1.2f, 4.5f, 1.0f }
|
||||
},
|
||||
// colors
|
||||
{
|
||||
{ 255, 0, 0, 255 },
|
||||
{ 0, 255, 0, 255 },
|
||||
{ 0, 0, 255, 255 },
|
||||
{ 255, 255, 0, 255 },
|
||||
},
|
||||
};
|
||||
|
||||
static const unsigned short cubeIndices[6] =
|
||||
{
|
||||
0, 1, 2,
|
||||
0, 2, 3,
|
||||
};
|
||||
|
||||
geometry->VertexCount = 4;
|
||||
geometry->IndexCount = 6;
|
||||
|
||||
geometry->VertexAttribs[0].Index = VERTEX_ATTRIBUTE_LOCATION_POSITION;
|
||||
geometry->VertexAttribs[0].Size = 4;
|
||||
geometry->VertexAttribs[0].Type = GL_FLOAT;
|
||||
geometry->VertexAttribs[0].Normalized = false;
|
||||
geometry->VertexAttribs[0].Stride = sizeof( cubeVertices.positions[0] );
|
||||
geometry->VertexAttribs[0].Pointer = (const GLvoid *)offsetof( ovrCubeVertices, positions );
|
||||
|
||||
geometry->VertexAttribs[1].Index = VERTEX_ATTRIBUTE_LOCATION_COLOR;
|
||||
geometry->VertexAttribs[1].Size = 4;
|
||||
geometry->VertexAttribs[1].Type = GL_UNSIGNED_BYTE;
|
||||
geometry->VertexAttribs[1].Normalized = true;
|
||||
geometry->VertexAttribs[1].Stride = sizeof( cubeVertices.colors[0] );
|
||||
geometry->VertexAttribs[1].Pointer = (const GLvoid *)offsetof( ovrCubeVertices, colors );
|
||||
|
||||
renderState state;
|
||||
getCurrentRenderState(&state);
|
||||
|
||||
GL( glGenBuffers( 1, &geometry->VertexBuffer ) );
|
||||
GL( glBindBuffer( GL_ARRAY_BUFFER, geometry->VertexBuffer ) );
|
||||
GL( glBufferData( GL_ARRAY_BUFFER, sizeof( cubeVertices ), &cubeVertices, GL_STATIC_DRAW ) );
|
||||
|
||||
GL( glGenBuffers( 1, &geometry->IndexBuffer ) );
|
||||
GL( glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, geometry->IndexBuffer ) );
|
||||
GL( glBufferData( GL_ELEMENT_ARRAY_BUFFER, sizeof( cubeIndices ), cubeIndices, GL_STATIC_DRAW ) );
|
||||
|
||||
restoreRenderState(&state);
|
||||
}
|
||||
|
||||
static void ovrGeometry_Destroy( ovrGeometry * geometry )
|
||||
{
|
||||
GL( glDeleteBuffers( 1, &geometry->IndexBuffer ) );
|
||||
GL( glDeleteBuffers( 1, &geometry->VertexBuffer ) );
|
||||
|
||||
ovrGeometry_Clear( geometry );
|
||||
}
|
||||
|
||||
static void ovrGeometry_CreateVAO( ovrGeometry * geometry )
|
||||
{
|
||||
renderState state;
|
||||
getCurrentRenderState(&state);
|
||||
|
||||
GL( glGenVertexArrays( 1, &geometry->VertexArrayObject ) );
|
||||
GL( glBindVertexArray( geometry->VertexArrayObject ) );
|
||||
|
||||
GL( glBindBuffer( GL_ARRAY_BUFFER, geometry->VertexBuffer ) );
|
||||
|
||||
for ( int i = 0; i < MAX_VERTEX_ATTRIB_POINTERS; i++ )
|
||||
{
|
||||
if ( geometry->VertexAttribs[i].Index != -1 )
|
||||
{
|
||||
GL( glEnableVertexAttribArray( geometry->VertexAttribs[i].Index ) );
|
||||
GL( glVertexAttribPointer( geometry->VertexAttribs[i].Index, geometry->VertexAttribs[i].Size,
|
||||
geometry->VertexAttribs[i].Type, geometry->VertexAttribs[i].Normalized,
|
||||
geometry->VertexAttribs[i].Stride, geometry->VertexAttribs[i].Pointer ) );
|
||||
}
|
||||
}
|
||||
|
||||
GL( glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, geometry->IndexBuffer ) );
|
||||
|
||||
restoreRenderState(&state);
|
||||
}
|
||||
|
||||
static void ovrGeometry_DestroyVAO( ovrGeometry * geometry )
|
||||
{
|
||||
GL( glDeleteVertexArrays( 1, &geometry->VertexArrayObject ) );
|
||||
}
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
|
||||
ovrProgram
|
||||
|
||||
================================================================================
|
||||
*/
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
enum
|
||||
{
|
||||
UNIFORM_VIEW_PROJ_MATRIX,
|
||||
} index;
|
||||
enum
|
||||
{
|
||||
UNIFORM_TYPE_VECTOR4,
|
||||
UNIFORM_TYPE_MATRIX4X4,
|
||||
UNIFORM_TYPE_INT,
|
||||
UNIFORM_TYPE_BUFFER,
|
||||
} type;
|
||||
const char * name;
|
||||
} ovrUniform;
|
||||
|
||||
static ovrUniform ProgramUniforms[] =
|
||||
{
|
||||
{ UNIFORM_VIEW_PROJ_MATRIX, UNIFORM_TYPE_MATRIX4X4, "viewProjectionMatrix" },
|
||||
};
|
||||
|
||||
static void ovrProgram_Clear( ovrProgram * program )
|
||||
{
|
||||
program->Program = 0;
|
||||
program->VertexShader = 0;
|
||||
program->FragmentShader = 0;
|
||||
memset( program->UniformLocation, 0, sizeof( program->UniformLocation ) );
|
||||
memset( program->UniformBinding, 0, sizeof( program->UniformBinding ) );
|
||||
memset( program->Textures, 0, sizeof( program->Textures ) );
|
||||
}
|
||||
|
||||
static bool ovrProgram_Create( ovrProgram * program, const char * vertexSource, const char * fragmentSource )
|
||||
{
|
||||
GLint r;
|
||||
|
||||
GL( program->VertexShader = glCreateShader( GL_VERTEX_SHADER ) );
|
||||
|
||||
GL( glShaderSource( program->VertexShader, 1, &vertexSource, 0 ) );
|
||||
GL( glCompileShader( program->VertexShader ) );
|
||||
GL( glGetShaderiv( program->VertexShader, GL_COMPILE_STATUS, &r ) );
|
||||
if ( r == GL_FALSE )
|
||||
{
|
||||
GLchar msg[4096];
|
||||
GL( glGetShaderInfoLog( program->VertexShader, sizeof( msg ), 0, msg ) );
|
||||
ALOGE( "%s\n%s\n", vertexSource, msg );
|
||||
return false;
|
||||
}
|
||||
|
||||
GL( program->FragmentShader = glCreateShader( GL_FRAGMENT_SHADER ) );
|
||||
GL( glShaderSource( program->FragmentShader, 1, &fragmentSource, 0 ) );
|
||||
GL( glCompileShader( program->FragmentShader ) );
|
||||
GL( glGetShaderiv( program->FragmentShader, GL_COMPILE_STATUS, &r ) );
|
||||
if ( r == GL_FALSE )
|
||||
{
|
||||
GLchar msg[4096];
|
||||
GL( glGetShaderInfoLog( program->FragmentShader, sizeof( msg ), 0, msg ) );
|
||||
ALOGE( "%s\n%s\n", fragmentSource, msg );
|
||||
return false;
|
||||
}
|
||||
|
||||
GL( program->Program = glCreateProgram() );
|
||||
GL( glAttachShader( program->Program, program->VertexShader ) );
|
||||
GL( glAttachShader( program->Program, program->FragmentShader ) );
|
||||
|
||||
// Bind the vertex attribute locations.
|
||||
for ( int i = 0; i < sizeof( ProgramVertexAttributes ) / sizeof( ProgramVertexAttributes[0] ); i++ )
|
||||
{
|
||||
GL( glBindAttribLocation( program->Program, ProgramVertexAttributes[i].location, ProgramVertexAttributes[i].name ) );
|
||||
}
|
||||
|
||||
GL( glLinkProgram( program->Program ) );
|
||||
GL( glGetProgramiv( program->Program, GL_LINK_STATUS, &r ) );
|
||||
if ( r == GL_FALSE )
|
||||
{
|
||||
GLchar msg[4096];
|
||||
GL( glGetProgramInfoLog( program->Program, sizeof( msg ), 0, msg ) );
|
||||
ALOGE( "Linking program failed: %s\n", msg );
|
||||
return false;
|
||||
}
|
||||
|
||||
int numBufferBindings = 0;
|
||||
|
||||
// Get the uniform locations.
|
||||
memset( program->UniformLocation, -1, sizeof( program->UniformLocation ) );
|
||||
for ( int i = 0; i < sizeof( ProgramUniforms ) / sizeof( ProgramUniforms[0] ); i++ )
|
||||
{
|
||||
const int uniformIndex = ProgramUniforms[i].index;
|
||||
if ( ProgramUniforms[i].type == UNIFORM_TYPE_BUFFER )
|
||||
{
|
||||
GL( program->UniformLocation[uniformIndex] = glGetUniformBlockIndex( program->Program, ProgramUniforms[i].name ) );
|
||||
program->UniformBinding[uniformIndex] = numBufferBindings++;
|
||||
GL( glUniformBlockBinding( program->Program, program->UniformLocation[uniformIndex], program->UniformBinding[uniformIndex] ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
GL( program->UniformLocation[uniformIndex] = glGetUniformLocation( program->Program, ProgramUniforms[i].name ) );
|
||||
program->UniformBinding[uniformIndex] = program->UniformLocation[uniformIndex];
|
||||
}
|
||||
}
|
||||
|
||||
renderState state;
|
||||
getCurrentRenderState(&state);
|
||||
|
||||
GL( glUseProgram( program->Program ) );
|
||||
|
||||
// Get the texture locations.
|
||||
for ( int i = 0; i < MAX_PROGRAM_TEXTURES; i++ )
|
||||
{
|
||||
char name[32];
|
||||
sprintf( name, "Texture%i", i );
|
||||
program->Textures[i] = glGetUniformLocation( program->Program, name );
|
||||
if ( program->Textures[i] != -1 )
|
||||
{
|
||||
GL( glUniform1i( program->Textures[i], i ) );
|
||||
}
|
||||
}
|
||||
|
||||
restoreRenderState(&state);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ovrProgram_Destroy( ovrProgram * program )
|
||||
{
|
||||
if ( program->Program != 0 )
|
||||
{
|
||||
GL( glDeleteProgram( program->Program ) );
|
||||
program->Program = 0;
|
||||
}
|
||||
if ( program->VertexShader != 0 )
|
||||
{
|
||||
GL( glDeleteShader( program->VertexShader ) );
|
||||
program->VertexShader = 0;
|
||||
}
|
||||
if ( program->FragmentShader != 0 )
|
||||
{
|
||||
GL( glDeleteShader( program->FragmentShader ) );
|
||||
program->FragmentShader = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static const char VERTEX_SHADER[] =
|
||||
"#version 300 es\n"
|
||||
"in vec3 vertexPosition;\n"
|
||||
"in vec4 vertexColor;\n"
|
||||
"uniform mat4 viewProjectionMatrix;\n"
|
||||
"out vec4 fragmentColor;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" gl_Position = viewProjectionMatrix * vec4( vertexPosition, 1.0 );\n"
|
||||
" fragmentColor = vertexColor;\n"
|
||||
"}\n";
|
||||
|
||||
static const char FRAGMENT_SHADER[] =
|
||||
"#version 300 es\n"
|
||||
"in lowp vec4 fragmentColor;\n"
|
||||
"out lowp vec4 outColor;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" outColor = fragmentColor;\n"
|
||||
"}\n";
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
|
||||
ovrScene
|
||||
|
||||
================================================================================
|
||||
*/
|
||||
|
||||
void ovrScene_Clear( ovrScene * scene )
|
||||
{
|
||||
scene->CreatedScene = false;
|
||||
scene->CreatedVAOs = false;
|
||||
ovrProgram_Clear( &scene->Program );
|
||||
ovrGeometry_Clear( &scene->GroundPlane );
|
||||
ovrRenderer_Clear( &scene->CylinderRenderer );
|
||||
|
||||
scene->CylinderWidth = 0;
|
||||
scene->CylinderHeight = 0;
|
||||
}
|
||||
|
||||
bool ovrScene_IsCreated( ovrScene * scene )
|
||||
{
|
||||
return scene->CreatedScene;
|
||||
}
|
||||
|
||||
void ovrScene_CreateVAOs( ovrScene * scene )
|
||||
{
|
||||
if ( !scene->CreatedVAOs )
|
||||
{
|
||||
ovrGeometry_CreateVAO( &scene->GroundPlane );
|
||||
scene->CreatedVAOs = true;
|
||||
}
|
||||
}
|
||||
|
||||
void ovrScene_DestroyVAOs( ovrScene * scene )
|
||||
{
|
||||
if ( scene->CreatedVAOs )
|
||||
{
|
||||
ovrGeometry_DestroyVAO( &scene->GroundPlane );
|
||||
scene->CreatedVAOs = false;
|
||||
}
|
||||
}
|
||||
|
||||
void ovrScene_Create( int width, int height, ovrScene * scene, const ovrJava * java )
|
||||
{
|
||||
// Simple ground plane geometry.
|
||||
{
|
||||
ovrProgram_Create( &scene->Program, VERTEX_SHADER, FRAGMENT_SHADER );
|
||||
ovrGeometry_CreateGroundPlane( &scene->GroundPlane );
|
||||
ovrScene_CreateVAOs( scene );
|
||||
}
|
||||
|
||||
// Create Cylinder renderer
|
||||
{
|
||||
scene->CylinderWidth = width;
|
||||
scene->CylinderHeight = height;
|
||||
|
||||
//Create cylinder renderer
|
||||
ovrRenderer_Create( width, height, &scene->CylinderRenderer, java );
|
||||
}
|
||||
|
||||
scene->CreatedScene = true;
|
||||
}
|
||||
|
||||
void ovrScene_Destroy( ovrScene * scene )
|
||||
{
|
||||
ovrScene_DestroyVAOs( scene );
|
||||
ovrProgram_Destroy( &scene->Program );
|
||||
ovrGeometry_Destroy( &scene->GroundPlane );
|
||||
ovrRenderer_Destroy( &scene->CylinderRenderer );
|
||||
|
||||
scene->CreatedScene = false;
|
||||
}
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
|
||||
ovrRenderer
|
||||
|
||||
================================================================================
|
||||
*/
|
||||
|
||||
ovrLayerProjection2 ovrRenderer_RenderGroundPlaneToEyeBuffer( ovrRenderer * renderer, const ovrJava * java,
|
||||
const ovrScene * scene, const ovrTracking2 * tracking )
|
||||
{
|
||||
ovrLayerProjection2 layer = vrapi_DefaultLayerProjection2();
|
||||
layer.HeadPose = tracking->HeadPose;
|
||||
for ( int eye = 0; eye < VRAPI_FRAME_LAYER_EYE_MAX; eye++ )
|
||||
{
|
||||
ovrFramebuffer * frameBuffer = &renderer->FrameBuffer[eye];
|
||||
layer.Textures[eye].ColorSwapChain = frameBuffer->ColorTextureSwapChain;
|
||||
layer.Textures[eye].SwapChainIndex = frameBuffer->ProcessingTextureSwapChainIndex;
|
||||
layer.Textures[eye].TexCoordsFromTanAngles = ovrMatrix4f_TanAngleMatrixFromProjection( &tracking->Eye[eye].ProjectionMatrix );
|
||||
}
|
||||
layer.Header.Flags |= VRAPI_FRAME_LAYER_FLAG_CHROMATIC_ABERRATION_CORRECTION;
|
||||
|
||||
for ( int eye = 0; eye < VRAPI_FRAME_LAYER_EYE_MAX; eye++ )
|
||||
{
|
||||
ovrFramebuffer * frameBuffer = &renderer->FrameBuffer[eye];
|
||||
ovrFramebuffer_SetCurrent( frameBuffer );
|
||||
|
||||
renderState state;
|
||||
getCurrentRenderState(&state);
|
||||
|
||||
GL( glUseProgram( scene->Program.Program ) );
|
||||
|
||||
ovrMatrix4f viewProjMatrix = ovrMatrix4f_Multiply( &tracking->Eye[eye].ProjectionMatrix, &tracking->Eye[eye].ViewMatrix );
|
||||
glUniformMatrix4fv( scene->Program.UniformLocation[UNIFORM_VIEW_PROJ_MATRIX], 1, GL_TRUE, &viewProjMatrix.M[0][0] );
|
||||
|
||||
GL( glEnable( GL_SCISSOR_TEST ) );
|
||||
GL( glDepthMask( GL_TRUE ) );
|
||||
GL( glEnable( GL_DEPTH_TEST ) );
|
||||
GL( glDepthFunc( GL_LEQUAL ) );
|
||||
GL( glEnable( GL_CULL_FACE ) );
|
||||
GL( glCullFace( GL_BACK ) );
|
||||
GL( glViewport( 0, 0, frameBuffer->Width, frameBuffer->Height ) );
|
||||
GL( glScissor( 0, 0, frameBuffer->Width, frameBuffer->Height ) );
|
||||
GL( glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ) );
|
||||
GL( glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) );
|
||||
|
||||
//bind buffers
|
||||
GL( glBindBuffer( GL_ARRAY_BUFFER, scene->GroundPlane.VertexBuffer ) );
|
||||
GL( glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, scene->GroundPlane.IndexBuffer ) );
|
||||
GL( glBindVertexArray( scene->GroundPlane.VertexArrayObject ) );
|
||||
|
||||
GL( glDrawElements( GL_TRIANGLES, scene->GroundPlane.IndexCount, GL_UNSIGNED_SHORT, NULL ) );
|
||||
|
||||
restoreRenderState(&state);
|
||||
|
||||
// Explicitly clear the border texels to black when GL_CLAMP_TO_BORDER is not available.
|
||||
ovrFramebuffer_ClearEdgeTexels( frameBuffer );
|
||||
|
||||
ovrFramebuffer_Resolve( frameBuffer );
|
||||
ovrFramebuffer_Advance( frameBuffer );
|
||||
}
|
||||
|
||||
ovrFramebuffer_SetNone();
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
// Assumes landscape cylinder shape.
|
||||
static ovrMatrix4f CylinderModelMatrix( const int texWidth, const int texHeight,
|
||||
const ovrVector3f translation,
|
||||
const float rotateYaw,
|
||||
const float rotatePitch,
|
||||
const float radius,
|
||||
const float density )
|
||||
{
|
||||
const ovrMatrix4f scaleMatrix = ovrMatrix4f_CreateScale( radius, radius * (float)texHeight * VRAPI_PI / density, radius );
|
||||
const ovrMatrix4f transMatrix = ovrMatrix4f_CreateTranslation( translation.x, translation.y, translation.z );
|
||||
const ovrMatrix4f rotXMatrix = ovrMatrix4f_CreateRotation( rotateYaw, 0.0f, 0.0f );
|
||||
const ovrMatrix4f rotYMatrix = ovrMatrix4f_CreateRotation( 0.0f, rotatePitch, 0.0f );
|
||||
|
||||
const ovrMatrix4f m0 = ovrMatrix4f_Multiply( &transMatrix, &scaleMatrix );
|
||||
const ovrMatrix4f m1 = ovrMatrix4f_Multiply( &rotXMatrix, &m0 );
|
||||
const ovrMatrix4f m2 = ovrMatrix4f_Multiply( &rotYMatrix, &m1 );
|
||||
|
||||
return m2;
|
||||
}
|
||||
|
||||
ovrLayerCylinder2 BuildCylinderLayer( ovrRenderer * cylinderRenderer,
|
||||
const int textureWidth, const int textureHeight,
|
||||
const ovrTracking2 * tracking, float rotatePitch )
|
||||
{
|
||||
ovrLayerCylinder2 layer = vrapi_DefaultLayerCylinder2();
|
||||
|
||||
const float fadeLevel = 1.0f;
|
||||
layer.Header.ColorScale.x =
|
||||
layer.Header.ColorScale.y =
|
||||
layer.Header.ColorScale.z =
|
||||
layer.Header.ColorScale.w = fadeLevel;
|
||||
layer.Header.SrcBlend = VRAPI_FRAME_LAYER_BLEND_SRC_ALPHA;
|
||||
layer.Header.DstBlend = VRAPI_FRAME_LAYER_BLEND_ONE_MINUS_SRC_ALPHA;
|
||||
|
||||
//layer.Header.Flags = VRAPI_FRAME_LAYER_FLAG_CLIP_TO_TEXTURE_RECT;
|
||||
|
||||
layer.HeadPose = tracking->HeadPose;
|
||||
|
||||
const float density = 4500.0f;
|
||||
const float rotateYaw = 0.0f;
|
||||
const float radius = 4.0f;
|
||||
const ovrVector3f translation = { 0.0f, 0.0f, -2.5f };
|
||||
|
||||
ovrMatrix4f cylinderTransform =
|
||||
CylinderModelMatrix( textureWidth, textureHeight, translation,
|
||||
rotateYaw, rotatePitch, radius, density );
|
||||
|
||||
const float circScale = density * 0.5f / textureWidth;
|
||||
const float circBias = -circScale * ( 0.5f * ( 1.0f - 1.0f / circScale ) );
|
||||
|
||||
for ( int eye = 0; eye < VRAPI_FRAME_LAYER_EYE_MAX; eye++ )
|
||||
{
|
||||
ovrFramebuffer * cylinderFrameBuffer = &cylinderRenderer->FrameBuffer[eye];
|
||||
|
||||
ovrMatrix4f modelViewMatrix = ovrMatrix4f_Multiply( &tracking->Eye[eye].ViewMatrix, &cylinderTransform );
|
||||
layer.Textures[eye].TexCoordsFromTanAngles = ovrMatrix4f_Inverse( &modelViewMatrix );
|
||||
layer.Textures[eye].ColorSwapChain = cylinderFrameBuffer->ColorTextureSwapChain;
|
||||
layer.Textures[eye].SwapChainIndex = cylinderFrameBuffer->ReadyTextureSwapChainIndex;
|
||||
|
||||
// Texcoord scale and bias is just a representation of the aspect ratio. The positioning
|
||||
// of the cylinder is handled entirely by the TexCoordsFromTanAngles matrix.
|
||||
|
||||
const float texScaleX = circScale;
|
||||
const float texBiasX = circBias;
|
||||
const float texScaleY = -0.5f;
|
||||
const float texBiasY = texScaleY * ( 0.5f * ( 1.0f - ( 1.0f / texScaleY ) ) );
|
||||
|
||||
layer.Textures[eye].TextureMatrix.M[0][0] = texScaleX;
|
||||
layer.Textures[eye].TextureMatrix.M[0][2] = texBiasX;
|
||||
layer.Textures[eye].TextureMatrix.M[1][1] = texScaleY;
|
||||
layer.Textures[eye].TextureMatrix.M[1][2] = -texBiasY;
|
||||
|
||||
layer.Textures[eye].TextureRect.width = 1.0f;
|
||||
layer.Textures[eye].TextureRect.height = 1.0f;
|
||||
}
|
||||
|
||||
return layer;
|
||||
}
|
|
@ -1,217 +0,0 @@
|
|||
/************************************************************************************
|
||||
|
||||
Filename : VrCompositor.h
|
||||
|
||||
*************************************************************************************/
|
||||
|
||||
#include "VrInput.h"
|
||||
|
||||
#define CHECK_GL_ERRORS
|
||||
#ifdef CHECK_GL_ERRORS
|
||||
|
||||
static const char * GlErrorString( GLenum error )
|
||||
{
|
||||
switch ( error )
|
||||
{
|
||||
case GL_NO_ERROR: return "GL_NO_ERROR";
|
||||
case GL_INVALID_ENUM: return "GL_INVALID_ENUM";
|
||||
case GL_INVALID_VALUE: return "GL_INVALID_VALUE";
|
||||
case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION";
|
||||
case GL_INVALID_FRAMEBUFFER_OPERATION: return "GL_INVALID_FRAMEBUFFER_OPERATION";
|
||||
case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY";
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static void GLCheckErrors( int line )
|
||||
{
|
||||
for ( int i = 0; i < 10; i++ )
|
||||
{
|
||||
const GLenum error = glGetError();
|
||||
if ( error == GL_NO_ERROR )
|
||||
{
|
||||
break;
|
||||
}
|
||||
ALOGE( "GL error on line %d: %s", line, GlErrorString( error ) );
|
||||
}
|
||||
}
|
||||
|
||||
#define GL( func ) func; GLCheckErrors( __LINE__ );
|
||||
|
||||
#else // CHECK_GL_ERRORS
|
||||
|
||||
#define GL( func ) func;
|
||||
|
||||
#endif // CHECK_GL_ERRORS
|
||||
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
|
||||
ovrFramebuffer
|
||||
|
||||
================================================================================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int Width;
|
||||
int Height;
|
||||
int Multisamples;
|
||||
int TextureSwapChainLength;
|
||||
int ProcessingTextureSwapChainIndex;
|
||||
int ReadyTextureSwapChainIndex;
|
||||
ovrTextureSwapChain * ColorTextureSwapChain;
|
||||
GLuint * DepthBuffers;
|
||||
GLuint * FrameBuffers;
|
||||
} ovrFramebuffer;
|
||||
|
||||
void ovrFramebuffer_SetCurrent( ovrFramebuffer * frameBuffer );
|
||||
void ovrFramebuffer_Destroy( ovrFramebuffer * frameBuffer );
|
||||
void ovrFramebuffer_SetNone();
|
||||
void ovrFramebuffer_Resolve( ovrFramebuffer * frameBuffer );
|
||||
void ovrFramebuffer_Advance( ovrFramebuffer * frameBuffer );
|
||||
void ovrFramebuffer_ClearEdgeTexels( ovrFramebuffer * frameBuffer );
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
|
||||
ovrRenderer
|
||||
|
||||
================================================================================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ovrFramebuffer FrameBuffer[VRAPI_FRAME_LAYER_EYE_MAX];
|
||||
int NumBuffers;
|
||||
} ovrRenderer;
|
||||
|
||||
|
||||
void ovrRenderer_Clear( ovrRenderer * renderer );
|
||||
void ovrRenderer_Create( int width, int height, ovrRenderer * renderer, const ovrJava * java );
|
||||
void ovrRenderer_Destroy( ovrRenderer * renderer );
|
||||
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
|
||||
renderState
|
||||
|
||||
================================================================================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GLint VertexBuffer;
|
||||
GLint IndexBuffer;
|
||||
GLint VertexArrayObject;
|
||||
GLint Program;
|
||||
GLint VertexShader;
|
||||
GLint FragmentShader;
|
||||
} renderState;
|
||||
|
||||
void getCurrentRenderState( renderState * state);
|
||||
void restoreRenderState( renderState * state );
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
|
||||
ovrGeometry
|
||||
|
||||
================================================================================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GLint Index;
|
||||
GLint Size;
|
||||
GLenum Type;
|
||||
GLboolean Normalized;
|
||||
GLsizei Stride;
|
||||
const GLvoid * Pointer;
|
||||
} ovrVertexAttribPointer;
|
||||
|
||||
#define MAX_VERTEX_ATTRIB_POINTERS 3
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GLuint VertexBuffer;
|
||||
GLuint IndexBuffer;
|
||||
GLuint VertexArrayObject;
|
||||
int VertexCount;
|
||||
int IndexCount;
|
||||
ovrVertexAttribPointer VertexAttribs[MAX_VERTEX_ATTRIB_POINTERS];
|
||||
} ovrGeometry;
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
|
||||
ovrProgram
|
||||
|
||||
================================================================================
|
||||
*/
|
||||
|
||||
#define MAX_PROGRAM_UNIFORMS 8
|
||||
#define MAX_PROGRAM_TEXTURES 8
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GLuint Program;
|
||||
GLuint VertexShader;
|
||||
GLuint FragmentShader;
|
||||
// These will be -1 if not used by the program.
|
||||
GLint UniformLocation[MAX_PROGRAM_UNIFORMS]; // ProgramUniforms[].name
|
||||
GLint UniformBinding[MAX_PROGRAM_UNIFORMS]; // ProgramUniforms[].name
|
||||
GLint Textures[MAX_PROGRAM_TEXTURES]; // Texture%i
|
||||
} ovrProgram;
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
|
||||
ovrScene
|
||||
|
||||
================================================================================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool CreatedScene;
|
||||
bool CreatedVAOs;
|
||||
ovrProgram Program;
|
||||
ovrGeometry GroundPlane;
|
||||
|
||||
//Proper renderer for stereo rendering to the cylinder layer
|
||||
ovrRenderer CylinderRenderer;
|
||||
|
||||
int CylinderWidth;
|
||||
int CylinderHeight;
|
||||
} ovrScene;
|
||||
|
||||
bool ovrScene_IsCreated( ovrScene * scene );
|
||||
void ovrScene_Clear( ovrScene * scene );
|
||||
void ovrScene_Create( int width, int height, ovrScene * scene, const ovrJava * java );
|
||||
void ovrScene_CreateVAOs( ovrScene * scene );
|
||||
void ovrScene_DestroyVAOs( ovrScene * scene );
|
||||
void ovrScene_Destroy( ovrScene * scene );
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
|
||||
ovrRenderer
|
||||
|
||||
================================================================================
|
||||
*/
|
||||
|
||||
ovrLayerProjection2 ovrRenderer_RenderGroundPlaneToEyeBuffer( ovrRenderer * renderer, const ovrJava * java,
|
||||
const ovrScene * scene, const ovrTracking2 * tracking );
|
||||
|
||||
ovrLayerProjection2 ovrRenderer_RenderToEyeBuffer( ovrRenderer * renderer, const ovrJava * java,
|
||||
const ovrTracking2 * tracking );
|
||||
|
||||
ovrLayerCylinder2 BuildCylinderLayer( ovrRenderer * cylinderRenderer,
|
||||
const int textureWidth, const int textureHeight,
|
||||
const ovrTracking2 * tracking, float rotateYaw );
|
||||
;
|
||||
|
||||
|
|
@ -5,12 +5,25 @@
|
|||
#include "VrCommon.h"
|
||||
|
||||
|
||||
extern ovrInputStateTrackedRemote leftTrackedRemoteState_old;
|
||||
extern ovrInputStateTrackedRemote leftTrackedRemoteState_new;
|
||||
extern ovrTrackedController leftRemoteTracking_new;
|
||||
|
||||
void acquireTrackedRemotesData(const ovrMobile *Ovr, double displayTime);
|
||||
extern ovrInputStateTrackedRemote rightTrackedRemoteState_old;
|
||||
extern ovrInputStateTrackedRemote rightTrackedRemoteState_new;
|
||||
extern ovrTrackedController rightRemoteTracking_new;
|
||||
|
||||
void HandleInput_Default( int control_scheme, ovrInputStateGamepad *pFootTrackingNew, ovrInputStateGamepad *pFootTrackingOld, ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
|
||||
ovrInputStateTrackedRemote *pDominantTrackedRemoteOld, ovrTracking* pDominantTracking,
|
||||
ovrInputStateTrackedRemote *pOffTrackedRemoteNew, ovrInputStateTrackedRemote *pOffTrackedRemoteOld, ovrTracking* pOffTracking,
|
||||
extern float remote_movementSideways;
|
||||
extern float remote_movementForward;
|
||||
extern float remote_movementUp;
|
||||
extern float positional_movementSideways;
|
||||
extern float positional_movementForward;
|
||||
extern float snapTurn;
|
||||
|
||||
|
||||
void HandleInput_Default( int control_scheme, ovrInputStateTrackedRemote *pDominantTrackedRemoteNew,
|
||||
ovrInputStateTrackedRemote *pDominantTrackedRemoteOld, ovrTrackedController* pDominantTracking,
|
||||
ovrInputStateTrackedRemote *pOffTrackedRemoteNew, ovrInputStateTrackedRemote *pOffTrackedRemoteOld, ovrTrackedController* pOffTracking,
|
||||
int domButton1, int domButton2, int offButton1, int offButton2 );
|
||||
|
||||
|
||||
|
|
|
@ -1,160 +0,0 @@
|
|||
/************************************************************************************
|
||||
|
||||
Filename : VrInputRight.c
|
||||
Content : Handles common controller input functionality
|
||||
Created : September 2019
|
||||
Authors : Simon Brown
|
||||
|
||||
*************************************************************************************/
|
||||
|
||||
#include <VrApi.h>
|
||||
#include <VrApi_Helpers.h>
|
||||
#include <VrApi_SystemUtils.h>
|
||||
#include <VrApi_Input.h>
|
||||
#include <VrApi_Types.h>
|
||||
|
||||
#include "VrInput.h"
|
||||
|
||||
ovrInputStateTrackedRemote leftTrackedRemoteState_old;
|
||||
ovrInputStateTrackedRemote leftTrackedRemoteState_new;
|
||||
ovrTracking leftRemoteTracking_new;
|
||||
|
||||
ovrInputStateTrackedRemote rightTrackedRemoteState_old;
|
||||
ovrInputStateTrackedRemote rightTrackedRemoteState_new;
|
||||
ovrTracking rightRemoteTracking_new;
|
||||
|
||||
ovrInputStateGamepad footTrackedRemoteState_old;
|
||||
ovrInputStateGamepad footTrackedRemoteState_new;
|
||||
|
||||
|
||||
ovrDeviceID controllerIDs[2];
|
||||
|
||||
float remote_movementSideways;
|
||||
float remote_movementForward;
|
||||
float remote_movementUp;
|
||||
float positional_movementSideways;
|
||||
float positional_movementForward;
|
||||
float snapTurn;
|
||||
|
||||
float cinemamodeYaw;
|
||||
float cinemamodePitch;
|
||||
|
||||
void Joy_GenerateButtonEvents(int oldbuttons, int newbuttons, int numbuttons, int base);
|
||||
|
||||
void handleTrackedControllerButton(ovrInputStateTrackedRemote * trackedRemoteState, ovrInputStateTrackedRemote * prevTrackedRemoteState, uint32_t button, int key)
|
||||
{
|
||||
Joy_GenerateButtonEvents(prevTrackedRemoteState->Buttons & button ? 1 : 0, trackedRemoteState->Buttons & button ? 1 : 0, 1, key);
|
||||
}
|
||||
|
||||
static void Matrix4x4_Transform (const matrix4x4 *in, const float v[3], float out[3])
|
||||
{
|
||||
out[0] = v[0] * (*in)[0][0] + v[1] * (*in)[0][1] + v[2] * (*in)[0][2] + (*in)[0][3];
|
||||
out[1] = v[0] * (*in)[1][0] + v[1] * (*in)[1][1] + v[2] * (*in)[1][2] + (*in)[1][3];
|
||||
out[2] = v[0] * (*in)[2][0] + v[1] * (*in)[2][1] + v[2] * (*in)[2][2] + (*in)[2][3];
|
||||
}
|
||||
|
||||
void Matrix4x4_CreateFromEntity( matrix4x4 out, const vec3_t angles, const vec3_t origin, float scale );
|
||||
|
||||
void rotateAboutOrigin(float v1, float v2, float rotation, vec2_t out)
|
||||
{
|
||||
vec3_t temp = {0.0f, 0.0f, 0.0f};
|
||||
temp[0] = v1;
|
||||
temp[1] = v2;
|
||||
|
||||
vec3_t v = {0.0f, 0.0f, 0.0f};
|
||||
matrix4x4 matrix;
|
||||
vec3_t angles = {0.0f, rotation, 0.0f};
|
||||
vec3_t origin = {0.0f, 0.0f, 0.0f};
|
||||
Matrix4x4_CreateFromEntity(matrix, angles, origin, 1.0f);
|
||||
Matrix4x4_Transform(&matrix, temp, v);
|
||||
|
||||
out[0] = v[0];
|
||||
out[1] = v[1];
|
||||
}
|
||||
|
||||
float length(float x, float y)
|
||||
{
|
||||
return sqrtf(powf(x, 2.0f) + powf(y, 2.0f));
|
||||
}
|
||||
|
||||
#define NLF_DEADZONE 0.1
|
||||
#define NLF_POWER 2.2
|
||||
|
||||
float nonLinearFilter(float in)
|
||||
{
|
||||
float val = 0.0f;
|
||||
if (in > NLF_DEADZONE)
|
||||
{
|
||||
val = in;
|
||||
val -= NLF_DEADZONE;
|
||||
val /= (1.0f - NLF_DEADZONE);
|
||||
val = powf(val, NLF_POWER);
|
||||
}
|
||||
else if (in < -NLF_DEADZONE)
|
||||
{
|
||||
val = in;
|
||||
val += NLF_DEADZONE;
|
||||
val /= (1.0f - NLF_DEADZONE);
|
||||
val = -powf(fabsf(val), NLF_POWER);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
bool between(float min, float val, float max)
|
||||
{
|
||||
return (min < val) && (val < max);
|
||||
}
|
||||
|
||||
void acquireTrackedRemotesData(const ovrMobile *Ovr, double displayTime) {//The amount of yaw changed by controller
|
||||
for ( int i = 0; ; i++ ) {
|
||||
ovrInputCapabilityHeader capsHeader;
|
||||
ovrResult result = vrapi_EnumerateInputDevices(Ovr, i, &capsHeader);
|
||||
if (result < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (capsHeader.Type == ovrControllerType_Gamepad) {
|
||||
|
||||
ovrInputGamepadCapabilities remoteCaps;
|
||||
remoteCaps.Header = capsHeader;
|
||||
if (vrapi_GetInputDeviceCapabilities(Ovr, &remoteCaps.Header) >= 0) {
|
||||
// remote is connected
|
||||
ovrInputStateGamepad remoteState;
|
||||
remoteState.Header.ControllerType = ovrControllerType_Gamepad;
|
||||
if ( vrapi_GetCurrentInputState( Ovr, capsHeader.DeviceID, &remoteState.Header ) >= 0 )
|
||||
{
|
||||
// act on device state returned in remoteState
|
||||
footTrackedRemoteState_new = remoteState;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (capsHeader.Type == ovrControllerType_TrackedRemote) {
|
||||
ovrTracking remoteTracking;
|
||||
ovrInputTrackedRemoteCapabilities remoteCaps;
|
||||
remoteCaps.Header = capsHeader;
|
||||
if ( vrapi_GetInputDeviceCapabilities( Ovr, &remoteCaps.Header ) >= 0 )
|
||||
{
|
||||
// remote is connected
|
||||
ovrInputStateTrackedRemote remoteState;
|
||||
remoteState.Header.ControllerType = ovrControllerType_TrackedRemote;
|
||||
|
||||
if(vrapi_GetCurrentInputState(Ovr, capsHeader.DeviceID, &remoteState.Header) >= 0) {
|
||||
if (vrapi_GetInputTrackingState(Ovr, capsHeader.DeviceID, displayTime,
|
||||
&remoteTracking) >= 0) {
|
||||
// act on device state returned in remoteState
|
||||
if (remoteCaps.ControllerCapabilities & ovrControllerCaps_RightHand) {
|
||||
rightTrackedRemoteState_new = remoteState;
|
||||
rightRemoteTracking_new = remoteTracking;
|
||||
controllerIDs[1] = capsHeader.DeviceID;
|
||||
} else {
|
||||
leftTrackedRemoteState_new = remoteState;
|
||||
leftRemoteTracking_new = remoteTracking;
|
||||
controllerIDs[0] = capsHeader.DeviceID;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
98
Projects/Android/jni/QzDoom/VrInputCommon.cpp
Normal file
98
Projects/Android/jni/QzDoom/VrInputCommon.cpp
Normal file
|
@ -0,0 +1,98 @@
|
|||
/************************************************************************************
|
||||
|
||||
Filename : VrInputRight.c
|
||||
Content : Handles common controller input functionality
|
||||
Created : September 2019
|
||||
Authors : Simon Brown
|
||||
|
||||
*************************************************************************************/
|
||||
|
||||
|
||||
#include "VrInput.h"
|
||||
|
||||
ovrInputStateTrackedRemote leftTrackedRemoteState_old;
|
||||
ovrInputStateTrackedRemote leftTrackedRemoteState_new;
|
||||
ovrTrackedController leftRemoteTracking_new;
|
||||
|
||||
ovrInputStateTrackedRemote rightTrackedRemoteState_old;
|
||||
ovrInputStateTrackedRemote rightTrackedRemoteState_new;
|
||||
ovrTrackedController rightRemoteTracking_new;
|
||||
|
||||
|
||||
float remote_movementSideways;
|
||||
float remote_movementForward;
|
||||
float remote_movementUp;
|
||||
float positional_movementSideways;
|
||||
float positional_movementForward;
|
||||
float snapTurn;
|
||||
|
||||
float cinemamodeYaw;
|
||||
float cinemamodePitch;
|
||||
|
||||
void Joy_GenerateButtonEvents(int oldbuttons, int newbuttons, int numbuttons, int base);
|
||||
|
||||
void handleTrackedControllerButton(ovrInputStateTrackedRemote * trackedRemoteState, ovrInputStateTrackedRemote * prevTrackedRemoteState, uint32_t button, int key)
|
||||
{
|
||||
Joy_GenerateButtonEvents(prevTrackedRemoteState->Buttons & button ? 1 : 0, trackedRemoteState->Buttons & button ? 1 : 0, 1, key);
|
||||
}
|
||||
|
||||
static void Matrix4x4_Transform (const matrix4x4 *in, const float v[3], float out[3])
|
||||
{
|
||||
out[0] = v[0] * (*in)[0][0] + v[1] * (*in)[0][1] + v[2] * (*in)[0][2] + (*in)[0][3];
|
||||
out[1] = v[0] * (*in)[1][0] + v[1] * (*in)[1][1] + v[2] * (*in)[1][2] + (*in)[1][3];
|
||||
out[2] = v[0] * (*in)[2][0] + v[1] * (*in)[2][1] + v[2] * (*in)[2][2] + (*in)[2][3];
|
||||
}
|
||||
|
||||
void Matrix4x4_CreateFromEntity( matrix4x4 out, const vec3_t angles, const vec3_t origin, float scale );
|
||||
|
||||
void rotateAboutOrigin(float v1, float v2, float rotation, vec2_t out)
|
||||
{
|
||||
vec3_t temp = {0.0f, 0.0f, 0.0f};
|
||||
temp[0] = v1;
|
||||
temp[1] = v2;
|
||||
|
||||
vec3_t v = {0.0f, 0.0f, 0.0f};
|
||||
matrix4x4 matrix;
|
||||
vec3_t angles = {0.0f, rotation, 0.0f};
|
||||
vec3_t origin = {0.0f, 0.0f, 0.0f};
|
||||
Matrix4x4_CreateFromEntity(matrix, angles, origin, 1.0f);
|
||||
Matrix4x4_Transform(&matrix, temp, v);
|
||||
|
||||
out[0] = v[0];
|
||||
out[1] = v[1];
|
||||
}
|
||||
|
||||
float length(float x, float y)
|
||||
{
|
||||
return sqrtf(powf(x, 2.0f) + powf(y, 2.0f));
|
||||
}
|
||||
|
||||
#define NLF_DEADZONE 0.1
|
||||
#define NLF_POWER 2.2
|
||||
|
||||
float nonLinearFilter(float in)
|
||||
{
|
||||
float val = 0.0f;
|
||||
if (in > NLF_DEADZONE)
|
||||
{
|
||||
val = in > 1.0f ? 1.0f : in;
|
||||
val -= NLF_DEADZONE;
|
||||
val /= (1.0f - NLF_DEADZONE);
|
||||
val = powf(val, NLF_POWER);
|
||||
}
|
||||
else if (in < -NLF_DEADZONE)
|
||||
{
|
||||
val = in < -1.0f ? -1.0f : in;
|
||||
val += NLF_DEADZONE;
|
||||
val /= (1.0f - NLF_DEADZONE);
|
||||
val = -powf(fabsf(val), NLF_POWER);
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
bool between(float min, float val, float max)
|
||||
{
|
||||
return (min < val) && (val < max);
|
||||
}
|
||||
|
|
@ -7,11 +7,7 @@ Authors : Simon Brown
|
|||
|
||||
*************************************************************************************/
|
||||
|
||||
#include <VrApi.h>
|
||||
#include <VrApi_Helpers.h>
|
||||
#include <VrApi_SystemUtils.h>
|
||||
#include <VrApi_Input.h>
|
||||
#include <VrApi_Types.h>
|
||||
|
||||
#include <android/keycodes.h>
|
||||
|
||||
#include "VrInput.h"
|
||||
|
@ -20,17 +16,11 @@ Authors : Simon Brown
|
|||
|
||||
extern ovrInputStateTrackedRemote leftTrackedRemoteState_old;
|
||||
extern ovrInputStateTrackedRemote leftTrackedRemoteState_new;
|
||||
extern ovrTracking leftRemoteTracking_new;
|
||||
extern ovrTrackedController leftRemoteTracking_new;
|
||||
|
||||
extern ovrInputStateTrackedRemote rightTrackedRemoteState_old;
|
||||
extern ovrInputStateTrackedRemote rightTrackedRemoteState_new;
|
||||
extern ovrTracking rightRemoteTracking_new;
|
||||
|
||||
extern ovrInputStateGamepad footTrackedRemoteState_old;
|
||||
extern ovrInputStateGamepad footTrackedRemoteState_new;
|
||||
|
||||
|
||||
extern ovrDeviceID controllerIDs[2];
|
||||
extern ovrTrackedController rightRemoteTracking_new;
|
||||
|
||||
extern float remote_movementSideways;
|
||||
extern float remote_movementForward;
|
||||
|
@ -42,29 +32,30 @@ extern float snapTurn;
|
|||
extern float cinemamodeYaw;
|
||||
extern float cinemamodePitch;
|
||||
|
||||
extern bool weaponStabilised;
|
||||
|
||||
int getGameState();
|
||||
int getMenuState();
|
||||
void Joy_GenerateButtonEvents(int oldbuttons, int newbuttons, int numbuttons, int base);
|
||||
float getViewpointYaw();
|
||||
|
||||
void HandleInput_Default( int control_scheme, ovrInputStateGamepad *pFootTrackingNew, ovrInputStateGamepad *pFootTrackingOld,
|
||||
ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovrInputStateTrackedRemote *pDominantTrackedRemoteOld, ovrTracking* pDominantTracking,
|
||||
ovrInputStateTrackedRemote *pOffTrackedRemoteNew, ovrInputStateTrackedRemote *pOffTrackedRemoteOld, ovrTracking* pOffTracking,
|
||||
void HandleInput_Default( int control_scheme, ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovrInputStateTrackedRemote *pDominantTrackedRemoteOld, ovrTrackedController* pDominantTracking,
|
||||
ovrInputStateTrackedRemote *pOffTrackedRemoteNew, ovrInputStateTrackedRemote *pOffTrackedRemoteOld, ovrTrackedController* pOffTracking,
|
||||
int domButton1, int domButton2, int offButton1, int offButton2 )
|
||||
|
||||
{
|
||||
//Menu button - invoke menu
|
||||
handleTrackedControllerButton(&leftTrackedRemoteState_new, &leftTrackedRemoteState_old, ovrButton_Enter, KEY_ESCAPE);
|
||||
handleTrackedControllerButton(&rightTrackedRemoteState_new, &rightTrackedRemoteState_old, ovrButton_Enter, KEY_ESCAPE); // For users who have switched the buttons
|
||||
handleTrackedControllerButton(&leftTrackedRemoteState_new, &leftTrackedRemoteState_old, xrButton_Enter, KEY_ESCAPE);
|
||||
handleTrackedControllerButton(&rightTrackedRemoteState_new, &rightTrackedRemoteState_old, xrButton_Enter, KEY_ESCAPE); // For users who have switched the buttons
|
||||
|
||||
//Dominant Grip works like a shift key
|
||||
bool dominantGripPushedOld = vr_secondarybuttonmappings ?
|
||||
(pDominantTrackedRemoteOld->Buttons & ovrButton_GripTrigger) != 0 : false;
|
||||
bool dominantGripPushedNew = vr_secondarybuttonmappings ?
|
||||
(pDominantTrackedRemoteNew->Buttons & ovrButton_GripTrigger) != 0 : false;
|
||||
bool dominantGripPushedOld = vr_secondary_button_mappings ?
|
||||
(pDominantTrackedRemoteOld->Buttons & xrButton_GripTrigger) : false;
|
||||
bool dominantGripPushedNew = vr_secondary_button_mappings ?
|
||||
(pDominantTrackedRemoteNew->Buttons & xrButton_GripTrigger) : false;
|
||||
|
||||
ovrInputStateTrackedRemote *pPrimaryTrackedRemoteNew, *pPrimaryTrackedRemoteOld, *pSecondaryTrackedRemoteNew, *pSecondaryTrackedRemoteOld;
|
||||
if (vr_switchsticks)
|
||||
if (vr_switch_sticks)
|
||||
{
|
||||
pPrimaryTrackedRemoteNew = pOffTrackedRemoteNew;
|
||||
pPrimaryTrackedRemoteOld = pOffTrackedRemoteOld;
|
||||
|
@ -129,19 +120,19 @@ void HandleInput_Default( int control_scheme, ovrInputStateGamepad *pFootTrackin
|
|||
// Only do the following if we are definitely not in the menu
|
||||
if (getMenuState() == 0)
|
||||
{
|
||||
float distance = sqrtf(powf(pOffTracking->HeadPose.Pose.Position.x -
|
||||
pDominantTracking->HeadPose.Pose.Position.x, 2) +
|
||||
powf(pOffTracking->HeadPose.Pose.Position.y -
|
||||
pDominantTracking->HeadPose.Pose.Position.y, 2) +
|
||||
powf(pOffTracking->HeadPose.Pose.Position.z -
|
||||
pDominantTracking->HeadPose.Pose.Position.z, 2));
|
||||
float distance = sqrtf(powf(pOffTracking->Pose.position.x -
|
||||
pDominantTracking->Pose.position.x, 2) +
|
||||
powf(pOffTracking->Pose.position.y -
|
||||
pDominantTracking->Pose.position.y, 2) +
|
||||
powf(pOffTracking->Pose.position.z -
|
||||
pDominantTracking->Pose.position.z, 2));
|
||||
|
||||
//Turn on weapon stabilisation?
|
||||
if (vr_twohandedweapons &&
|
||||
(pOffTrackedRemoteNew->Buttons & ovrButton_GripTrigger) !=
|
||||
(pOffTrackedRemoteOld->Buttons & ovrButton_GripTrigger)) {
|
||||
if (vr_two_handed_weapons &&
|
||||
(pOffTrackedRemoteNew->Buttons & xrButton_GripTrigger) !=
|
||||
(pOffTrackedRemoteOld->Buttons & xrButton_GripTrigger)) {
|
||||
|
||||
if (pOffTrackedRemoteNew->Buttons & ovrButton_GripTrigger) {
|
||||
if (pOffTrackedRemoteNew->Buttons & xrButton_GripTrigger) {
|
||||
if (distance < 0.50f) {
|
||||
weaponStabilised = true;
|
||||
}
|
||||
|
@ -153,9 +144,9 @@ void HandleInput_Default( int control_scheme, ovrInputStateGamepad *pFootTrackin
|
|||
//dominant hand stuff first
|
||||
{
|
||||
///Weapon location relative to view
|
||||
weaponoffset[0] = pDominantTracking->HeadPose.Pose.Position.x - hmdPosition[0];
|
||||
weaponoffset[1] = pDominantTracking->HeadPose.Pose.Position.y - hmdPosition[1];
|
||||
weaponoffset[2] = pDominantTracking->HeadPose.Pose.Position.z - hmdPosition[2];
|
||||
weaponoffset[0] = pDominantTracking->Pose.position.x - hmdPosition[0];
|
||||
weaponoffset[1] = pDominantTracking->Pose.position.y - hmdPosition[1];
|
||||
weaponoffset[2] = pDominantTracking->Pose.position.z - hmdPosition[2];
|
||||
|
||||
vec2_t v;
|
||||
float yawRotation = getViewpointYaw() - hmdorientation[YAW];
|
||||
|
@ -164,23 +155,22 @@ void HandleInput_Default( int control_scheme, ovrInputStateGamepad *pFootTrackin
|
|||
weaponoffset[2] = v[0];
|
||||
|
||||
//Set gun angles
|
||||
const ovrQuatf quatRemote = pDominantTracking->HeadPose.Pose.Orientation;
|
||||
vec3_t rotation = {0};
|
||||
rotation[PITCH] = vr_weapon_pitchadjust;
|
||||
QuatToYawPitchRoll(quatRemote, rotation, weaponangles);
|
||||
rotation[PITCH] = vr_weaponRotate;
|
||||
QuatToYawPitchRoll(pDominantTracking->Pose.orientation, rotation, weaponangles);
|
||||
|
||||
|
||||
if (weaponStabilised) {
|
||||
float z = pOffTracking->HeadPose.Pose.Position.z -
|
||||
pDominantTracking->HeadPose.Pose.Position.z;
|
||||
float x = pOffTracking->HeadPose.Pose.Position.x -
|
||||
pDominantTracking->HeadPose.Pose.Position.x;
|
||||
float y = pOffTracking->HeadPose.Pose.Position.y -
|
||||
pDominantTracking->HeadPose.Pose.Position.y;
|
||||
float z = pOffTracking->Pose.position.z -
|
||||
pDominantTracking->Pose.position.z;
|
||||
float x = pOffTracking->Pose.position.x -
|
||||
pDominantTracking->Pose.position.x;
|
||||
float y = pOffTracking->Pose.position.y -
|
||||
pDominantTracking->Pose.position.y;
|
||||
float zxDist = length(x, z);
|
||||
|
||||
if (zxDist != 0.0f && z != 0.0f) {
|
||||
VectorSet(weaponangles, -degrees(atanf(y / zxDist)), -degrees(atan2f(x, -z)),
|
||||
VectorSet(weaponangles, -RAD2DEG(atanf(y / zxDist)), -RAD2DEG(atan2f(x, -z)),
|
||||
weaponangles[ROLL]);
|
||||
}
|
||||
}
|
||||
|
@ -190,9 +180,9 @@ void HandleInput_Default( int control_scheme, ovrInputStateGamepad *pFootTrackin
|
|||
|
||||
//off-hand stuff
|
||||
{
|
||||
offhandoffset[0] = pOffTracking->HeadPose.Pose.Position.x - hmdPosition[0];
|
||||
offhandoffset[1] = pOffTracking->HeadPose.Pose.Position.y - hmdPosition[1];
|
||||
offhandoffset[2] = pOffTracking->HeadPose.Pose.Position.z - hmdPosition[2];
|
||||
offhandoffset[0] = pOffTracking->Pose.position.x - hmdPosition[0];
|
||||
offhandoffset[1] = pOffTracking->Pose.position.y - hmdPosition[1];
|
||||
offhandoffset[2] = pOffTracking->Pose.position.z - hmdPosition[2];
|
||||
|
||||
vec2_t v;
|
||||
float yawRotation = getViewpointYaw() - hmdorientation[YAW];
|
||||
|
@ -201,10 +191,10 @@ void HandleInput_Default( int control_scheme, ovrInputStateGamepad *pFootTrackin
|
|||
offhandoffset[2] = v[0];
|
||||
|
||||
vec3_t rotation = {0};
|
||||
rotation[PITCH] = vr_weapon_pitchadjust;
|
||||
QuatToYawPitchRoll(pOffTracking->HeadPose.Pose.Orientation, rotation, offhandangles);
|
||||
rotation[PITCH] = vr_weaponRotate;
|
||||
QuatToYawPitchRoll(pOffTracking->Pose.orientation, rotation, offhandangles);
|
||||
|
||||
if (vr_moveuseoffhand) {
|
||||
if (vr_move_use_offhand) {
|
||||
controllerYawHeading = offhandangles[YAW] - hmdorientation[YAW];
|
||||
} else {
|
||||
controllerYawHeading = 0.0f;
|
||||
|
@ -214,9 +204,9 @@ void HandleInput_Default( int control_scheme, ovrInputStateGamepad *pFootTrackin
|
|||
//Positional movement
|
||||
{
|
||||
ALOGV(" Right-Controller-Position: %f, %f, %f",
|
||||
pDominantTracking->HeadPose.Pose.Position.x,
|
||||
pDominantTracking->HeadPose.Pose.Position.y,
|
||||
pDominantTracking->HeadPose.Pose.Position.z);
|
||||
pDominantTracking->Pose.position.x,
|
||||
pDominantTracking->Pose.position.y,
|
||||
pDominantTracking->Pose.position.z);
|
||||
|
||||
vec2_t v;
|
||||
rotateAboutOrigin(positionDeltaThisFrame[0], positionDeltaThisFrame[2],
|
||||
|
@ -232,12 +222,12 @@ void HandleInput_Default( int control_scheme, ovrInputStateGamepad *pFootTrackin
|
|||
//Off-hand specific stuff
|
||||
{
|
||||
ALOGV(" Left-Controller-Position: %f, %f, %f",
|
||||
pOffTracking->HeadPose.Pose.Position.x,
|
||||
pOffTracking->HeadPose.Pose.Position.y,
|
||||
pOffTracking->HeadPose.Pose.Position.z);
|
||||
pOffTracking->Pose.position.x,
|
||||
pOffTracking->Pose.position.y,
|
||||
pOffTracking->Pose.position.z);
|
||||
|
||||
//Teleport - only does anything if vr_teleport cvar is true
|
||||
if (vr_use_teleport) {
|
||||
if (vr_teleport) {
|
||||
if ((pSecondaryTrackedRemoteOld->Joystick.y > 0.7f) && !ready_teleport) {
|
||||
ready_teleport = true;
|
||||
} else if ((pSecondaryTrackedRemoteOld->Joystick.y < 0.7f) && ready_teleport) {
|
||||
|
@ -250,8 +240,9 @@ void HandleInput_Default( int control_scheme, ovrInputStateGamepad *pFootTrackin
|
|||
//and we don't get movement jitter when the joystick doesn't quite center properly
|
||||
float dist = length(pSecondaryTrackedRemoteNew->Joystick.x, pSecondaryTrackedRemoteNew->Joystick.y);
|
||||
float nlf = nonLinearFilter(dist);
|
||||
float x = nlf * pSecondaryTrackedRemoteNew->Joystick.x + pFootTrackingNew->LeftJoystick.x;
|
||||
float y = nlf * pSecondaryTrackedRemoteNew->Joystick.y - pFootTrackingNew->LeftJoystick.y;
|
||||
dist = (dist > 1.0f) ? dist : 1.0f;
|
||||
float x = nlf * (pSecondaryTrackedRemoteNew->Joystick.x / dist);
|
||||
float y = nlf * (pSecondaryTrackedRemoteNew->Joystick.y / dist);
|
||||
|
||||
//Apply a simple deadzone
|
||||
player_moving = (fabs(x) + fabs(y)) > 0.05f;
|
||||
|
@ -271,42 +262,44 @@ void HandleInput_Default( int control_scheme, ovrInputStateGamepad *pFootTrackin
|
|||
|
||||
if (!cinemamode && !dominantGripPushedNew)
|
||||
{
|
||||
// Turning logic
|
||||
static int increaseSnap = true;
|
||||
if (pPrimaryTrackedRemoteNew->Joystick.x > 0.6f) {
|
||||
if (increaseSnap) {
|
||||
resetDoomYaw = true;
|
||||
snapTurn -= vr_snapturn_angle;
|
||||
if (vr_snapturn_angle > 10.0f) {
|
||||
increaseSnap = false;
|
||||
}
|
||||
static int decreaseSnap = true;
|
||||
|
||||
if (snapTurn < -180.0f) {
|
||||
snapTurn += 360.f;
|
||||
}
|
||||
float joy = pPrimaryTrackedRemoteNew->Joystick.x;
|
||||
if (vr_snapTurn <= 10.0f && abs(joy) > 0.05f)
|
||||
{
|
||||
increaseSnap = false;
|
||||
decreaseSnap = false;
|
||||
snapTurn -= vr_snapTurn * nonLinearFilter(joy);
|
||||
}
|
||||
|
||||
// Turning logic
|
||||
if (joy > 0.6f && increaseSnap) {
|
||||
resetDoomYaw = true;
|
||||
snapTurn -= vr_snapTurn;
|
||||
if (vr_snapTurn > 10.0f) {
|
||||
increaseSnap = false;
|
||||
}
|
||||
} else if (pPrimaryTrackedRemoteNew->Joystick.x < 0.4f) {
|
||||
} else if (joy < 0.4f) {
|
||||
increaseSnap = true;
|
||||
}
|
||||
|
||||
static int decreaseSnap = true;
|
||||
if (pPrimaryTrackedRemoteNew->Joystick.x < -0.6f) {
|
||||
if (decreaseSnap) {
|
||||
resetDoomYaw = true;
|
||||
snapTurn += vr_snapturn_angle;
|
||||
|
||||
//If snap turn configured for less than 10 degrees
|
||||
if (vr_snapturn_angle > 10.0f) {
|
||||
decreaseSnap = false;
|
||||
}
|
||||
|
||||
if (snapTurn > 180.0f) {
|
||||
snapTurn -= 360.f;
|
||||
}
|
||||
if (joy < -0.6f && decreaseSnap) {
|
||||
resetDoomYaw = true;
|
||||
snapTurn += vr_snapTurn;
|
||||
if (vr_snapTurn > 10.0f) {
|
||||
decreaseSnap = false;
|
||||
}
|
||||
} else if (pPrimaryTrackedRemoteNew->Joystick.x > -0.4f) {
|
||||
} else if (joy > -0.4f) {
|
||||
decreaseSnap = true;
|
||||
}
|
||||
|
||||
if (snapTurn < -180.0f) {
|
||||
snapTurn += 360.f;
|
||||
}
|
||||
else if (snapTurn > 180.0f) {
|
||||
snapTurn -= 360.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -328,13 +321,13 @@ void HandleInput_Default( int control_scheme, ovrInputStateGamepad *pFootTrackin
|
|||
|
||||
//If snap turn set to 0, then we can use left/right on the stick as mappable functions
|
||||
Joy_GenerateButtonEvents(
|
||||
(pPrimaryTrackedRemoteOld->Joystick.x > 0.7f && !dominantGripPushedOld && !vr_snapturn_angle ? 1 : 0),
|
||||
(pPrimaryTrackedRemoteNew->Joystick.x > 0.7f && !dominantGripPushedNew && !vr_snapturn_angle ? 1 : 0),
|
||||
(pPrimaryTrackedRemoteOld->Joystick.x > 0.7f && !dominantGripPushedOld && !vr_snapTurn ? 1 : 0),
|
||||
(pPrimaryTrackedRemoteNew->Joystick.x > 0.7f && !dominantGripPushedNew && !vr_snapTurn ? 1 : 0),
|
||||
1, KEY_MWHEELLEFT);
|
||||
|
||||
Joy_GenerateButtonEvents(
|
||||
(pPrimaryTrackedRemoteOld->Joystick.x < -0.7f && !dominantGripPushedOld && !vr_snapturn_angle ? 1 : 0),
|
||||
(pPrimaryTrackedRemoteNew->Joystick.x < -0.7f && !dominantGripPushedNew && !vr_snapturn_angle ? 1 : 0),
|
||||
(pPrimaryTrackedRemoteOld->Joystick.x < -0.7f && !dominantGripPushedOld && !vr_snapTurn ? 1 : 0),
|
||||
(pPrimaryTrackedRemoteNew->Joystick.x < -0.7f && !dominantGripPushedNew && !vr_snapTurn ? 1 : 0),
|
||||
1, KEY_MWHEELRIGHT);
|
||||
}
|
||||
|
||||
|
@ -343,8 +336,8 @@ void HandleInput_Default( int control_scheme, ovrInputStateGamepad *pFootTrackin
|
|||
{
|
||||
//Fire
|
||||
Joy_GenerateButtonEvents(
|
||||
((pDominantTrackedRemoteOld->Buttons & ovrButton_Trigger) != 0) && !dominantGripPushedOld ? 1 : 0,
|
||||
((pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) != 0) && !dominantGripPushedNew ? 1 : 0,
|
||||
((pDominantTrackedRemoteOld->Buttons & xrButton_Trigger) != 0) && !dominantGripPushedOld ? 1 : 0,
|
||||
((pDominantTrackedRemoteNew->Buttons & xrButton_Trigger) != 0) && !dominantGripPushedNew ? 1 : 0,
|
||||
1, KEY_PAD_RTRIGGER);
|
||||
|
||||
//"Use" (open door, toggle switch etc)
|
||||
|
@ -361,24 +354,30 @@ void HandleInput_Default( int control_scheme, ovrInputStateGamepad *pFootTrackin
|
|||
|
||||
// Inv Use
|
||||
Joy_GenerateButtonEvents(
|
||||
((pDominantTrackedRemoteOld->Buttons & ovrButton_Joystick) != 0) && !dominantGripPushedOld ? 1 : 0,
|
||||
((pDominantTrackedRemoteNew->Buttons & ovrButton_Joystick) != 0) && !dominantGripPushedNew ? 1 : 0,
|
||||
((pDominantTrackedRemoteOld->Buttons & xrButton_Joystick) != 0) && !dominantGripPushedOld ? 1 : 0,
|
||||
((pDominantTrackedRemoteNew->Buttons & xrButton_Joystick) != 0) && !dominantGripPushedNew ? 1 : 0,
|
||||
1, KEY_ENTER);
|
||||
|
||||
//No Default Binding
|
||||
Joy_GenerateButtonEvents(
|
||||
((pDominantTrackedRemoteOld->Touches & ovrTouch_ThumbRest) != 0) && !dominantGripPushedOld ? 1 : 0,
|
||||
((pDominantTrackedRemoteNew->Touches & ovrTouch_ThumbRest) != 0) && !dominantGripPushedNew ? 1 : 0,
|
||||
((pDominantTrackedRemoteOld->Touches & xrButton_ThumbRest) != 0) && !dominantGripPushedOld ? 1 : 0,
|
||||
((pDominantTrackedRemoteNew->Touches & xrButton_ThumbRest) != 0) && !dominantGripPushedNew ? 1 : 0,
|
||||
1, KEY_JOY5);
|
||||
|
||||
//Use grip as an extra button
|
||||
//Alt-Fire
|
||||
Joy_GenerateButtonEvents(
|
||||
((pDominantTrackedRemoteOld->Buttons & xrButton_GripTrigger) != 0) && !dominantGripPushedOld ? 1 : 0,
|
||||
((pDominantTrackedRemoteNew->Buttons & xrButton_GripTrigger) != 0) && !dominantGripPushedNew ? 1 : 0,
|
||||
1, KEY_PAD_LTRIGGER);
|
||||
}
|
||||
|
||||
//Dominant Hand - Secondary keys (grip pushed)
|
||||
{
|
||||
//Alt-Fire
|
||||
Joy_GenerateButtonEvents(
|
||||
((pDominantTrackedRemoteOld->Buttons & ovrButton_Trigger) != 0) && dominantGripPushedOld ? 1 : 0,
|
||||
((pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) != 0) && dominantGripPushedNew ? 1 : 0,
|
||||
((pDominantTrackedRemoteOld->Buttons & xrButton_Trigger) != 0) && dominantGripPushedOld ? 1 : 0,
|
||||
((pDominantTrackedRemoteNew->Buttons & xrButton_Trigger) != 0) && dominantGripPushedNew ? 1 : 0,
|
||||
1, KEY_PAD_LTRIGGER);
|
||||
|
||||
//Crouch
|
||||
|
@ -391,26 +390,20 @@ void HandleInput_Default( int control_scheme, ovrInputStateGamepad *pFootTrackin
|
|||
Joy_GenerateButtonEvents(
|
||||
((primaryButtonsOld & primaryButton2) != 0) && dominantGripPushedOld ? 1 : 0,
|
||||
((primaryButtonsNew & primaryButton2) != 0) && dominantGripPushedNew ? 1 : 0,
|
||||
1, KEY_RSHIFT);
|
||||
1, KEY_BACKSPACE);
|
||||
|
||||
//No Binding
|
||||
Joy_GenerateButtonEvents(
|
||||
((pDominantTrackedRemoteOld->Buttons & ovrButton_Joystick) != 0) && dominantGripPushedOld ? 1 : 0,
|
||||
((pDominantTrackedRemoteNew->Buttons & ovrButton_Joystick) != 0) && dominantGripPushedNew ? 1 : 0,
|
||||
((pDominantTrackedRemoteOld->Buttons & xrButton_Joystick) != 0) && dominantGripPushedOld ? 1 : 0,
|
||||
((pDominantTrackedRemoteNew->Buttons & xrButton_Joystick) != 0) && dominantGripPushedNew ? 1 : 0,
|
||||
1, KEY_TAB);
|
||||
|
||||
//No Default Binding
|
||||
Joy_GenerateButtonEvents(
|
||||
((pDominantTrackedRemoteOld->Touches & ovrTouch_ThumbRest) != 0) && dominantGripPushedOld ? 1 : 0,
|
||||
((pDominantTrackedRemoteNew->Touches & ovrTouch_ThumbRest) != 0) && dominantGripPushedNew ? 1 : 0,
|
||||
((pDominantTrackedRemoteOld->Touches & xrButton_ThumbRest) != 0) && dominantGripPushedOld ? 1 : 0,
|
||||
((pDominantTrackedRemoteNew->Touches & xrButton_ThumbRest) != 0) && dominantGripPushedNew ? 1 : 0,
|
||||
1, KEY_JOY6);
|
||||
|
||||
//Use grip as an extra button
|
||||
//Alt-Fire
|
||||
Joy_GenerateButtonEvents(
|
||||
((pDominantTrackedRemoteOld->Buttons & ovrButton_GripTrigger) != 0) && !dominantGripPushedOld ? 1 : 0,
|
||||
((pDominantTrackedRemoteNew->Buttons & ovrButton_GripTrigger) != 0) && !dominantGripPushedNew ? 1 : 0,
|
||||
1, KEY_PAD_LTRIGGER);
|
||||
}
|
||||
|
||||
|
||||
|
@ -418,8 +411,8 @@ void HandleInput_Default( int control_scheme, ovrInputStateGamepad *pFootTrackin
|
|||
{
|
||||
//No Default Binding
|
||||
Joy_GenerateButtonEvents(
|
||||
((pOffTrackedRemoteOld->Buttons & ovrButton_Trigger) != 0) && !dominantGripPushedOld ? 1 : 0,
|
||||
((pOffTrackedRemoteNew->Buttons & ovrButton_Trigger) != 0) && !dominantGripPushedNew ? 1 : 0,
|
||||
((pOffTrackedRemoteOld->Buttons & xrButton_Trigger) != 0) && !dominantGripPushedOld ? 1 : 0,
|
||||
((pOffTrackedRemoteNew->Buttons & xrButton_Trigger) != 0) && !dominantGripPushedNew ? 1 : 0,
|
||||
1, KEY_LSHIFT);
|
||||
|
||||
//No Default Binding
|
||||
|
@ -436,19 +429,19 @@ void HandleInput_Default( int control_scheme, ovrInputStateGamepad *pFootTrackin
|
|||
|
||||
//"Use" (open door, toggle switch etc) - Can be rebound for other uses
|
||||
Joy_GenerateButtonEvents(
|
||||
((pOffTrackedRemoteOld->Buttons & ovrButton_Joystick) != 0) && !dominantGripPushedOld ? 1 : 0,
|
||||
((pOffTrackedRemoteNew->Buttons & ovrButton_Joystick) != 0) && !dominantGripPushedNew ? 1 : 0,
|
||||
((pOffTrackedRemoteOld->Buttons & xrButton_Joystick) != 0) && !dominantGripPushedOld ? 1 : 0,
|
||||
((pOffTrackedRemoteNew->Buttons & xrButton_Joystick) != 0) && !dominantGripPushedNew ? 1 : 0,
|
||||
1, KEY_SPACE);
|
||||
|
||||
//No Default Binding
|
||||
Joy_GenerateButtonEvents(
|
||||
((pOffTrackedRemoteOld->Touches & ovrTouch_ThumbRest) != 0) && !dominantGripPushedOld ? 1 : 0,
|
||||
((pOffTrackedRemoteNew->Touches & ovrTouch_ThumbRest) != 0) && !dominantGripPushedNew ? 1 : 0,
|
||||
((pOffTrackedRemoteOld->Touches & xrButton_ThumbRest) != 0) && !dominantGripPushedOld ? 1 : 0,
|
||||
((pOffTrackedRemoteNew->Touches & xrButton_ThumbRest) != 0) && !dominantGripPushedNew ? 1 : 0,
|
||||
1, KEY_JOY7);
|
||||
|
||||
Joy_GenerateButtonEvents(
|
||||
((pOffTrackedRemoteOld->Buttons & ovrButton_GripTrigger) != 0) && !dominantGripPushedOld ? 1 : 0,
|
||||
((pOffTrackedRemoteNew->Buttons & ovrButton_GripTrigger) != 0) && !dominantGripPushedNew ? 1 : 0,
|
||||
((pOffTrackedRemoteOld->Buttons & xrButton_GripTrigger) != 0) && !dominantGripPushedOld ? 1 : 0,
|
||||
((pOffTrackedRemoteNew->Buttons & xrButton_GripTrigger) != 0) && !dominantGripPushedNew ? 1 : 0,
|
||||
1, KEY_PAD_RTHUMB);
|
||||
}
|
||||
|
||||
|
@ -456,8 +449,8 @@ void HandleInput_Default( int control_scheme, ovrInputStateGamepad *pFootTrackin
|
|||
{
|
||||
//No Default Binding
|
||||
Joy_GenerateButtonEvents(
|
||||
((pOffTrackedRemoteOld->Buttons & ovrButton_Trigger) != 0) && dominantGripPushedOld ? 1 : 0,
|
||||
((pOffTrackedRemoteNew->Buttons & ovrButton_Trigger) != 0) && dominantGripPushedNew ? 1 : 0,
|
||||
((pOffTrackedRemoteOld->Buttons & xrButton_Trigger) != 0) && dominantGripPushedOld ? 1 : 0,
|
||||
((pOffTrackedRemoteNew->Buttons & xrButton_Trigger) != 0) && dominantGripPushedNew ? 1 : 0,
|
||||
1, KEY_LALT);
|
||||
|
||||
//Move Down
|
||||
|
@ -474,19 +467,19 @@ void HandleInput_Default( int control_scheme, ovrInputStateGamepad *pFootTrackin
|
|||
|
||||
//Land
|
||||
Joy_GenerateButtonEvents(
|
||||
((pOffTrackedRemoteOld->Buttons & ovrButton_Joystick) != 0) && dominantGripPushedOld ? 1 : 0,
|
||||
((pOffTrackedRemoteNew->Buttons & ovrButton_Joystick) != 0) && dominantGripPushedNew ? 1 : 0,
|
||||
((pOffTrackedRemoteOld->Buttons & xrButton_Joystick) != 0) && dominantGripPushedOld ? 1 : 0,
|
||||
((pOffTrackedRemoteNew->Buttons & xrButton_Joystick) != 0) && dominantGripPushedNew ? 1 : 0,
|
||||
1, KEY_HOME);
|
||||
|
||||
//No Default Binding
|
||||
Joy_GenerateButtonEvents(
|
||||
((pOffTrackedRemoteOld->Touches & ovrTouch_ThumbRest) != 0) && dominantGripPushedOld ? 1 : 0,
|
||||
((pOffTrackedRemoteNew->Touches & ovrTouch_ThumbRest) != 0) && dominantGripPushedNew ? 1 : 0,
|
||||
((pOffTrackedRemoteOld->Touches & xrButton_ThumbRest) != 0) && dominantGripPushedOld ? 1 : 0,
|
||||
((pOffTrackedRemoteNew->Touches & xrButton_ThumbRest) != 0) && dominantGripPushedNew ? 1 : 0,
|
||||
1, KEY_JOY8);
|
||||
|
||||
Joy_GenerateButtonEvents(
|
||||
((pOffTrackedRemoteOld->Buttons & ovrButton_GripTrigger) != 0) && dominantGripPushedOld && !vr_twohandedweapons ? 1 : 0,
|
||||
((pOffTrackedRemoteNew->Buttons & ovrButton_GripTrigger) != 0) && dominantGripPushedNew && !vr_twohandedweapons ? 1 : 0,
|
||||
((pOffTrackedRemoteOld->Buttons & xrButton_GripTrigger) != 0) && dominantGripPushedOld && !vr_two_handed_weapons ? 1 : 0,
|
||||
((pOffTrackedRemoteNew->Buttons & xrButton_GripTrigger) != 0) && dominantGripPushedNew && !vr_two_handed_weapons ? 1 : 0,
|
||||
1, KEY_PAD_DPAD_UP);
|
||||
}
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 88800f0fc2f5a8cb41b0714ebfd234b9f0ba624e
|
||||
Subproject commit cd597da0c6cf0ecfcb0789d3fc5d5d02aad04b37
|
4
Projects/Android/libs/arm64-v8a/readme.txt
Normal file
4
Projects/Android/libs/arm64-v8a/readme.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
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
|
|
@ -1,9 +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.
|
||||
#Wed Feb 02 12:33:02 GMT 2022
|
||||
ndk.dir=C\:\\Users\\simon\\AppData\\Local\\Android\\Sdk\\ndk\\20.0.5594570
|
||||
sdk.dir=C\:\\Users\\Simon\\AppData\\Local\\Android\\Sdk
|
|
@ -1,4 +1,4 @@
|
|||
rootProject.projectDir = new File(settingsDir, '../../../..')
|
||||
rootProject.name = "QuestzDoom"
|
||||
rootProject.projectDir = new File(settingsDir, '../..')
|
||||
rootProject.name = "QuestZDoom"
|
||||
|
||||
include ':', 'VrSamples:QuestzDoom:Projects:Android'
|
||||
include ':', 'Projects:Android'
|
||||
|
|
13
Projects/AndroidPrebuilt/jni/Android.mk
Normal file
13
Projects/AndroidPrebuilt/jni/Android.mk
Normal file
|
@ -0,0 +1,13 @@
|
|||
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
|
BIN
Projects/AndroidPrebuilt/jni/libopenxr_loader.so
Normal file
BIN
Projects/AndroidPrebuilt/jni/libopenxr_loader.so
Normal file
Binary file not shown.
|
@ -1,27 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.id=":VrSamples:QuestzDoom:Projects" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/Android" external.system.id="GRADLE" external.system.module.group="QuestzDoom.VrSamples.QuestzDoom" 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=":VrSamples:QuestzDoom:Projects" />
|
||||
<option name="LAST_SUCCESSFUL_SYNC_AGP_VERSION" />
|
||||
<option name="LAST_KNOWN_AGP_VERSION" />
|
||||
</configuration>
|
||||
</facet>
|
||||
<facet type="java-gradle" name="Java-Gradle">
|
||||
<configuration>
|
||||
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
|
||||
<option name="BUILDABLE" value="false" />
|
||||
</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>
|
|
@ -1,6 +1,8 @@
|
|||

|
||||
===
|
||||
|
||||
[](https://github.com/emawind84/QuestZDoom/actions/workflows/build.yaml)
|
||||
|
||||
Welcome to the VR port of the popular LZDoom/GZDoom engine for the Oculus Quest.
|
||||
|
||||
This is built solely for the Oculus Quest VR HMD and will *not* run on any other device.
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.id=":VrSamples:QuestzDoom" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/Projects/Android" external.system.id="GRADLE" external.system.module.group="QuestzDoom.VrSamples" 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=":VrSamples:QuestzDoom" />
|
||||
<option name="LAST_SUCCESSFUL_SYNC_AGP_VERSION" />
|
||||
<option name="LAST_KNOWN_AGP_VERSION" />
|
||||
</configuration>
|
||||
</facet>
|
||||
<facet type="java-gradle" name="Java-Gradle">
|
||||
<configuration>
|
||||
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
|
||||
<option name="BUILDABLE" value="false" />
|
||||
</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>
|
238
XrApp.gradle
Normal file
238
XrApp.gradle
Normal file
|
@ -0,0 +1,238 @@
|
|||
import org.gradle.internal.os.OperatingSystem;
|
||||
import com.android.ddmlib.AndroidDebugBridge
|
||||
import com.android.ddmlib.IDevice
|
||||
import com.android.ddmlib.CollectingOutputReceiver
|
||||
import org.apache.tools.ant.taskdefs.condition.Os
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.0.0'
|
||||
}
|
||||
|
||||
tasks.register("wrapper")
|
||||
}
|
||||
|
||||
class XrAppPlugin implements Plugin<Project> {
|
||||
Project project = null
|
||||
|
||||
void installApk( IDevice device, File apkFile, String applicationId ) {
|
||||
project.logger.quiet "Installing ${applicationId} on device ${device.serialNumber}"
|
||||
|
||||
String toinstall = "/data/local/tmp/toinstall.apk"
|
||||
|
||||
try {
|
||||
device.pushFile( apkFile.path, toinstall )
|
||||
} catch ( Exception e ) {
|
||||
throw new RuntimeException( "Failed to push ${apkFile.path} to ${toinstall}. ${e}", e )
|
||||
}
|
||||
|
||||
while ( true ) {
|
||||
try {
|
||||
device.installRemotePackage( toinstall, true )
|
||||
break
|
||||
} catch ( Exception e ) {
|
||||
project.logger.quiet "Failed to install ${applicationId} on device ${device.serialNumber} (${e}). Trying to uninstall first."
|
||||
}
|
||||
try {
|
||||
device.uninstallPackage( applicationId )
|
||||
} catch ( Exception e ) {
|
||||
throw new RuntimeException( "Failed to uninstall ${applicationId}. ${e}", e )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void stopApk( IDevice device, String packageName ) {
|
||||
CollectingOutputReceiver receiver = new CollectingOutputReceiver()
|
||||
device.executeShellCommand( "am force-stop ${packageName}", receiver )
|
||||
}
|
||||
|
||||
void runApk( IDevice device, manifestFile ) {
|
||||
CollectingOutputReceiver receiver = new CollectingOutputReceiver()
|
||||
def activityClass = new XmlSlurper().parse( manifestFile ).application.activity.find{ it.'intent-filter'.find{ filter ->
|
||||
return filter.action .find{it.'@android:name'.text() == 'android.intent.action.MAIN' } \
|
||||
&& ( filter.category.find{it.'@android:name'.text() == 'android.intent.category.LAUNCHER'} \
|
||||
|| filter.category.find{it.'@android:name'.text() == 'android.intent.category.INFO'} )
|
||||
}}.'@android:name'
|
||||
def startActivity = "${project.android.defaultConfig.applicationId}/${activityClass}"
|
||||
project.logger.quiet "Starting \'$startActivity\' on ${project.deviceMap.size()} devices:"
|
||||
project.logger.quiet "- ${device.serialNumber}"
|
||||
device.executeShellCommand( "am start $startActivity", receiver )
|
||||
}
|
||||
|
||||
void apply( Project project ) {
|
||||
this.project = project
|
||||
|
||||
// FIXME: The Task.leftShift(Closure) method has been deprecated and is scheduled to be removed in Gradle 5.0. Please use Task.doLast(Action) instead.
|
||||
project.task( "cleanWorkAround" ) {
|
||||
description "Workaround for .externalNativeBuild not being deleted on clean"
|
||||
}.doLast {
|
||||
project.delete project.file( ".externalNativeBuild" )
|
||||
}
|
||||
|
||||
project.android {
|
||||
compileSdkVersion 26
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 24
|
||||
targetSdkVersion 25
|
||||
|
||||
externalNativeBuild {
|
||||
ndk {
|
||||
}
|
||||
ndkBuild {
|
||||
def numProcs = Runtime.runtime.availableProcessors()
|
||||
arguments "V=0", "-j$numProcs", "-C$project.buildDir.parent", "APP_PLATFORM=android-24", "NDK_TOOLCHAIN_VERSION=clang", "APP_STL=c++_static"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
path '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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WORKAROUND: On Mac OS X, running ndk-build clean with a high num of parallel executions
|
||||
// set may result in the following build error: rm: fts_read: No such file or directory.
|
||||
// Currently, there isn't a good way to specify numProcs=1 only on clean. So, in order
|
||||
// to work around the issue, delete the auto-generated .externalNativeBuild artifacts
|
||||
// (where $numProcs specified) before executing the clean task.
|
||||
project.clean.dependsOn project.cleanWorkAround
|
||||
|
||||
project.clean {
|
||||
// remove the auto-generated debug keystore (currently generated by python build script)
|
||||
// delete "android.debug.keystore"
|
||||
}
|
||||
|
||||
project.afterEvaluate {
|
||||
Task initDeviceList = project.task( "initDeviceList()" ).doLast {
|
||||
project.ext.deviceMap = [ : ]
|
||||
if (project.hasProperty( "should_install" ) == true) {
|
||||
AndroidDebugBridge.initIfNeeded( false )
|
||||
AndroidDebugBridge bridge = AndroidDebugBridge.createBridge( project.android.getAdbExe().absolutePath, false )
|
||||
|
||||
long timeOut = 30000 // 30 sec
|
||||
int sleepTime = 1000
|
||||
while ( !bridge.hasInitialDeviceList() && timeOut > 0 ) {
|
||||
sleep( sleepTime )
|
||||
timeOut -= sleepTime
|
||||
}
|
||||
if ( timeOut <= 0 && !bridge.hasInitialDeviceList() ) {
|
||||
throw new RuntimeException( "Timeout getting device list.", null )
|
||||
}
|
||||
|
||||
// if a device is connected both physically and over the network, only include the physical ID
|
||||
if ( project.hasProperty( "should_install" ) == true ) {
|
||||
bridge.devices.split { it.getProperty( "ro.serialno" ) != it.serialNumber }.each {
|
||||
it.collectEntries( project.deviceMap, { [ ( it.getProperty( "ro.serialno" )) : it ] } )
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
project.task( "stopApk", dependsOn: initDeviceList ) {
|
||||
description "Stops app if currently running on device"
|
||||
}.doLast {
|
||||
project.deviceMap.each { deviceSerial, device ->
|
||||
stopApk( device, android.defaultConfig.applicationId )
|
||||
}
|
||||
}
|
||||
|
||||
project.android.applicationVariants.all { variant ->
|
||||
Task installAndRun = project.task( "installAndRun${variant.name.capitalize()}" ) {
|
||||
dependsOn variant.assembleProvider.get()
|
||||
dependsOn initDeviceList
|
||||
onlyIf { project.hasProperty( "should_install" ) }
|
||||
description "Installs and runs the APK file"
|
||||
}.doLast { variant.outputs.each { output ->
|
||||
if ( output.outputFile.exists() ) {
|
||||
if ( project.deviceMap.size() == 0 ) {
|
||||
project.logger.quiet "Install requested, but no devices found."
|
||||
} else {
|
||||
project.deviceMap.each { deviceSerial, device ->
|
||||
installApk( device, output.outputFile, project.android.defaultConfig.applicationId )
|
||||
runApk( device, new File(output.processManifest.manifestOutputDirectory.get().asFile, "AndroidManifest.xml"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
variant.assembleProvider.get().finalizedBy installAndRun
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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") {}
|
||||
}
|
||||
|
||||
|
||||
|
||||
apply plugin: XrAppPlugin
|
Binary file not shown.
Binary file not shown.
22
build.gradle
Normal file
22
build.gradle
Normal file
|
@ -0,0 +1,22 @@
|
|||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:4.0.0'
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
|
3
gradle.properties
Normal file
3
gradle.properties
Normal file
|
@ -0,0 +1,3 @@
|
|||
org.gradle.jvmargs=-Xmx1536M
|
||||
org.gradle.caching=true
|
||||
org.gradle.configureondemand=true
|
|
@ -2,36 +2,60 @@
|
|||
package com.drbeef.questzdoom;
|
||||
|
||||
|
||||
import static android.system.Os.setenv;
|
||||
|
||||
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.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.RemoteException;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.util.Log;
|
||||
import android.os.RemoteException;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.drbeef.externalhapticsservice.HapticServiceClient;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Locale;
|
||||
|
||||
@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( "qzdoom" );
|
||||
}
|
||||
|
||||
|
@ -44,13 +68,30 @@ import java.io.OutputStream;
|
|||
private static final int WRITE_EXTERNAL_STORAGE_PERMISSION_ID = 2;
|
||||
|
||||
private String commandLineParams;
|
||||
private String progdir = "/sdcard/QuestZDoom";
|
||||
|
||||
private SurfaceView mView;
|
||||
private SurfaceHolder mSurfaceHolder;
|
||||
private long mNativeHandle;
|
||||
|
||||
public void shutdown() {
|
||||
System.exit(0);
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
// If yes, run the fancy new function to end the app and
|
||||
// remove it from the task list.
|
||||
finishAndRemoveTask();
|
||||
} else {
|
||||
// If not, then just end the app without removing it from
|
||||
// the task list.
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
public void reload(String profile) {
|
||||
if (profile != null && !profile.isEmpty()) {
|
||||
copy_file(progdir + "/commandline_" + profile + ".txt", progdir + "/commandline.txt");
|
||||
copy_file(progdir + "/profiles/commandline_" + profile + ".txt", progdir + "/commandline.txt");
|
||||
}
|
||||
restartApplication(this);
|
||||
}
|
||||
|
||||
public void haptic_event(String event, int position, int intensity, float angle, float yHeight) {
|
||||
|
@ -63,7 +104,7 @@ import java.io.OutputStream;
|
|||
}
|
||||
catch (RemoteException r)
|
||||
{
|
||||
Log.v(APPLICATION, r.toString());
|
||||
Log.e(APPLICATION, r.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +117,7 @@ import java.io.OutputStream;
|
|||
}
|
||||
catch (RemoteException r)
|
||||
{
|
||||
Log.v(APPLICATION, r.toString());
|
||||
Log.e(APPLICATION, r.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +130,7 @@ import java.io.OutputStream;
|
|||
}
|
||||
catch (RemoteException r)
|
||||
{
|
||||
Log.v(APPLICATION, r.toString());
|
||||
Log.e(APPLICATION, r.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -102,7 +143,7 @@ import java.io.OutputStream;
|
|||
}
|
||||
catch (RemoteException r)
|
||||
{
|
||||
Log.v(APPLICATION, r.toString());
|
||||
Log.e(APPLICATION, r.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -151,8 +192,13 @@ import java.io.OutputStream;
|
|||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] results) {
|
||||
if (requestCode == WRITE_EXTERNAL_STORAGE_PERMISSION_ID) {
|
||||
finish();
|
||||
System.exit(0);
|
||||
if (results.length > 0 && results[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
create();
|
||||
}
|
||||
else {
|
||||
finish();
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,50 +212,50 @@ import java.io.OutputStream;
|
|||
}
|
||||
|
||||
public void create() {
|
||||
|
||||
copy_asset("/sdcard/QuestZDoom", "commandline.txt", false);
|
||||
copy_asset(progdir, "commandline.txt", false);
|
||||
|
||||
//Create all required folders
|
||||
new File("/sdcard/QuestZDoom/res").mkdirs();
|
||||
new File("/sdcard/QuestZDoom/mods").mkdirs();
|
||||
new File("/sdcard/QuestZDoom/wads").mkdirs();
|
||||
new File("/sdcard/QuestZDoom/soundfonts").mkdirs();
|
||||
new File(progdir, "res").mkdirs();
|
||||
new File(progdir, "mods").mkdirs();
|
||||
new File(progdir, "wads").mkdirs();
|
||||
new File(progdir, "soundfonts").mkdirs();
|
||||
|
||||
copy_asset("/sdcard/QuestZDoom", "res/lzdoom.pk3", true);
|
||||
copy_asset("/sdcard/QuestZDoom", "res/lz_game_support.pk3", true);
|
||||
copy_asset("/sdcard/QuestZDoom", "res/lights.pk3", true);
|
||||
copy_asset("/sdcard/QuestZDoom", "res/brightmaps.pk3", true);
|
||||
copy_asset(progdir, "res/lzdoom.pk3", true);
|
||||
copy_asset(progdir, "res/lz_game_support.pk3", true);
|
||||
copy_asset(progdir, "res/lights.pk3", true);
|
||||
copy_asset(progdir, "res/brightmaps.pk3", true);
|
||||
|
||||
copy_asset("/sdcard/QuestZDoom", "mods/Ultimate-Cheat-Menu.zip", false);
|
||||
copy_asset("/sdcard/QuestZDoom", "mods/laser-sight-0.5.5-vr.pk3", false);
|
||||
copy_asset(progdir, "mods/Ultimate-Cheat-Menu.zip", true);
|
||||
copy_asset(progdir, "mods/laser-sight-0.5.5-vr.pk3", true);
|
||||
|
||||
copy_asset("/sdcard/QuestZDoom/soundfonts", "qzdoom.sf2", false);
|
||||
copy_asset("/sdcard/QuestZDoom/fm_banks", "GENMIDI.GS.wopl", false);
|
||||
copy_asset("/sdcard/QuestZDoom/fm_banks", "gs-by-papiezak-and-sneakernets.wopn", false);
|
||||
//copy_asset("/sdcard/QuestZDoom/audiopack", "snd_fluidsynth/fluidsynth.sf2", false);
|
||||
copy_asset(progdir + "/soundfonts", "qzdoom.sf2", false);
|
||||
copy_asset(progdir + "/fm_banks", "GENMIDI.GS.wopl", false);
|
||||
copy_asset(progdir + "/fm_banks", "gs-by-papiezak-and-sneakernets.wopn", false);
|
||||
|
||||
//Read these from a file and pass through
|
||||
commandLineParams = new String("qzdoom");
|
||||
|
||||
//See if user is trying to use command line params
|
||||
if(new File("/sdcard/QuestZDoom/commandline.txt").exists()) // should exist!
|
||||
String commandLineFilePath = progdir + "/commandline.txt";
|
||||
GLES3JNILib.prepareEnvironment(progdir);
|
||||
if(new File(commandLineFilePath).exists()) // should exist!
|
||||
{
|
||||
BufferedReader br;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader("/sdcard/QuestZDoom/commandline.txt"));
|
||||
br = new BufferedReader(new FileReader(commandLineFilePath));
|
||||
String s;
|
||||
StringBuilder sb=new StringBuilder(0);
|
||||
while ((s=br.readLine())!=null)
|
||||
while ((s=br.readLine())!=null) {
|
||||
if (s.indexOf("#", 0) == 0) continue;
|
||||
sb.append(s + " ");
|
||||
}
|
||||
br.close();
|
||||
|
||||
commandLineParams = new String(sb.toString());
|
||||
} catch (FileNotFoundException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
Log.e(APPLICATION, e.toString());
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -222,12 +268,12 @@ import java.io.OutputStream;
|
|||
//If there are no IWADS, then should exit after creating the folders
|
||||
//to allow the launcher app to do its thing, otherwise it would crash anyway
|
||||
//Check that launcher is installed too
|
||||
boolean hasIWADs = ((new File("/sdcard/QuestZDoom/wads").listFiles().length) > 0);
|
||||
boolean hasLauncher = //(new File("/sdcard/QuestZDoom/no_launcher").exists()) || //Allow users to run without launcher if they _really_ want to
|
||||
boolean hasIWADs = ((new File(progdir, "wads").listFiles().length) > 0);
|
||||
boolean hasLauncher = new File(progdir, "no_launcher").exists() || //Allow users to run without launcher if they _really_ want to
|
||||
isPackageInstalled("com.Baggyg.QuestZDoom_Launcher", this.getPackageManager());
|
||||
mNativeHandle = GLES3JNILib.onCreate( this, commandLineParams, hasIWADs, hasLauncher );
|
||||
}
|
||||
|
||||
|
||||
public void copy_asset(String path, String name, boolean force) {
|
||||
File f = new File(path + "/" + name);
|
||||
if (!f.exists() || force) {
|
||||
|
@ -259,6 +305,22 @@ import java.io.OutputStream;
|
|||
|
||||
}
|
||||
|
||||
public void copy_file(String path_in, String path_out)
|
||||
{
|
||||
File file_in = new File(path_in);
|
||||
if (file_in.exists()) {
|
||||
File file_out = new File(path_out);
|
||||
try (
|
||||
InputStream in = new BufferedInputStream(new FileInputStream(file_in));
|
||||
OutputStream out = new BufferedOutputStream(new FileOutputStream(file_out)))
|
||||
{
|
||||
copy_stream(in, out);
|
||||
} catch (IOException e) {
|
||||
Log.e(APPLICATION, e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void copy_stream(InputStream in, OutputStream out)
|
||||
throws IOException {
|
||||
byte[] buf = new byte[1024];
|
||||
|
@ -362,4 +424,30 @@ import java.io.OutputStream;
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Working method for restarting the activity
|
||||
* @param activity
|
||||
*/
|
||||
private void restartApplication(final @NonNull Activity activity) {
|
||||
// Systems at 29/Q and later don't allow relaunch, but System.exit(0) on
|
||||
// all supported systems will relaunch ... but by killing the process, then
|
||||
// restarting the process with the back stack intact. We must make sure that
|
||||
// the launch activity is the only thing in the back stack before exiting.
|
||||
final PackageManager pm = activity.getPackageManager();
|
||||
final Intent intent = pm.getLaunchIntentForPackage(activity.getPackageName());
|
||||
activity.finishAffinity(); // Finishes all activities.
|
||||
activity.startActivity(intent); // Start the launch activity
|
||||
System.exit(0); // System finishes and automatically relaunches us.
|
||||
}
|
||||
|
||||
/**
|
||||
* Working method for restarting the activity
|
||||
*/
|
||||
private void restartApplicationSecondMethod() {
|
||||
Intent intent = getIntent();
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
|
||||
startActivity(intent);
|
||||
Runtime.getRuntime().exit(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,4 +20,6 @@ public class GLES3JNILib
|
|||
public static native void onSurfaceCreated( long handle, Surface s );
|
||||
public static native void onSurfaceChanged( long handle, Surface s );
|
||||
public static native void onSurfaceDestroyed( long handle );
|
||||
|
||||
public static native void prepareEnvironment(String path);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue