mirror of
https://github.com/DrBeef/RTCWQuest.git
synced 2024-11-14 08:30:53 +00:00
Adding stuff
This commit is contained in:
parent
026e59ce58
commit
ed2e26394c
35 changed files with 11371 additions and 47 deletions
93
.gitignore
vendored
93
.gitignore
vendored
|
@ -1,52 +1,51 @@
|
|||
# Prerequisites
|
||||
# Windows image file caches
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
|
||||
# Folder config file
|
||||
Desktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# build files
|
||||
*.o
|
||||
*.d
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Linker output
|
||||
*.ilk
|
||||
*.map
|
||||
*.exp
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
#binaries
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
#libs
|
||||
*.a
|
||||
|
||||
# Debug files
|
||||
*.dSYM/
|
||||
*.su
|
||||
*.idb
|
||||
*.pdb
|
||||
|
||||
# Kernel Module Compile Results
|
||||
*.mod*
|
||||
*.cmd
|
||||
.tmp_versions/
|
||||
modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
#files created by build
|
||||
.idea
|
||||
*.apk
|
||||
*.ap_
|
||||
*.class
|
||||
projects/Android/build/*
|
||||
assets/oculussig*
|
||||
Projects/Android/.externalNativeBuild/ndkBuild/debug/arm64-v8a/android_gradle_build.json
|
||||
*.json
|
||||
Projects/Android/.externalNativeBuild/ndkBuild/debug/arm64-v8a/ndkBuild_build_command.txt
|
||||
Projects/Android/.externalNativeBuild/ndkBuild/debug/arm64-v8a/ndkBuild_build_output.txt
|
||||
Projects/Android/.externalNativeBuild/ndkBuild/release/arm64-v8a/ndkBuild_build_command.txt
|
||||
Projects/Android/.externalNativeBuild/ndkBuild/release/armeabi-v7a/ndkBuild_build_output.txt
|
||||
*.bin
|
||||
Projects/Android/.gradle/4.4/fileHashes/fileHashes.lock
|
||||
*.ser
|
||||
Projects/Android/.idea/codeStyles/Project.xml
|
||||
Projects/Android/.externalNativeBuild/ndkBuild/debug/armeabi-v7a/ndkBuild_build_command.txt
|
||||
Projects/Android/.externalNativeBuild/ndkBuild/release/armeabi-v7a/ndkBuild_build_command.txt
|
||||
Projects/Android/.externalNativeBuild/ndkBuild/debug/armeabi-v7a/ndkBuild_build_output.txt
|
||||
Projects/Android/.externalNativeBuild/ndkBuild/release/arm64-v8a/ndkBuild_build_output.txt
|
||||
Projects/Android/.gradle/4.6/fileHashes/fileHashes.lock
|
||||
Projects/Android/.gradle/vcsWorkingDirs/gc.properties
|
||||
drbeef-release-key.keystore
|
||||
assets/pak6.pak
|
||||
Projects/Android/Android.iml
|
||||
Projects/Projects.iml
|
||||
VrSamples-Quake2Quest.iml
|
||||
|
|
43
Projects/Android/AndroidManifest.xml
Normal file
43
Projects/Android/AndroidManifest.xml
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.drbeef.quake2quest"
|
||||
android:versionCode="13"
|
||||
android:versionName="1.0.2" android:installLocation="auto" >
|
||||
|
||||
<!-- Tell the system this app requires OpenGL ES 3.1. -->
|
||||
<uses-feature android:glEsVersion="0x00030001" android:required="true"/>
|
||||
|
||||
<uses-feature android:name="android.hardware.vr.headtracking" android:version="1"
|
||||
android:required="true" />
|
||||
|
||||
<!-- Network access needed for OVRMonitor -->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<!-- Volume Control -->
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<application android:allowBackup="false" android:icon="@drawable/ic_qquest" android:label="@string/quake2quest">
|
||||
<meta-data android:name="com.samsung.android.vr.application.mode" android:value="vr_only"/>
|
||||
<!-- 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. -->
|
||||
<!-- If targeting API level 24+, configChanges should additionally include 'density'. -->
|
||||
<!-- If targeting API level 24+, android:resizeableActivity="false" should be added. -->
|
||||
<activity
|
||||
android:name="com.drbeef.quake2quest.GLES3JNIActivity"
|
||||
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen"
|
||||
android:label="@string/quake2quest"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="landscape"
|
||||
android:excludeFromRecents="false"
|
||||
android:configChanges="screenSize|screenLayout|orientation|keyboardHidden|keyboard|navigation|uiMode">
|
||||
<!-- Tell NativeActivity the name of the .so -->
|
||||
<meta-data android:name="android.app.lib_name" android:value="quake2quest" />
|
||||
<!-- 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.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
</manifest>
|
BIN
Projects/Android/android.debug.keystore
Normal file
BIN
Projects/Android/android.debug.keystore
Normal file
Binary file not shown.
29
Projects/Android/build.bat
Normal file
29
Projects/Android/build.bat
Normal file
|
@ -0,0 +1,29 @@
|
|||
@rem Only edit the master copy of this file in SDK_ROOT/bin/scripts/build/perproject
|
||||
|
||||
@setlocal enableextensions enabledelayedexpansion
|
||||
|
||||
@if not exist "build.gradle" @echo Build script must be executed from project directory. & goto :Abort
|
||||
|
||||
@set P=..
|
||||
|
||||
:TryAgain
|
||||
|
||||
@rem @echo P = %P%
|
||||
|
||||
@if exist "%P%\bin\scripts\build\build.py.bat" goto :Found
|
||||
|
||||
@if exist "%P%\bin\scripts\build" @echo "Could not find build.py.bat" & goto :Abort
|
||||
|
||||
@set P=%P%\..
|
||||
|
||||
@goto :TryAgain
|
||||
|
||||
:Found
|
||||
|
||||
@set P=%P%\bin\scripts\build
|
||||
@call %P%\build.py.bat %1 %2 %3 %4 %5
|
||||
@goto :End
|
||||
|
||||
:Abort
|
||||
|
||||
:End
|
59
Projects/Android/build.gradle
Normal file
59
Projects/Android/build.gradle
Normal file
|
@ -0,0 +1,59 @@
|
|||
apply plugin: 'com.android.application'
|
||||
apply from: "${rootProject.projectDir}/VrApp.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 = "quake2quest"
|
||||
|
||||
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
|
||||
|
||||
// override app plugin abiFilters for both 32 and 64-bit support
|
||||
externalNativeBuild {
|
||||
ndk {
|
||||
abiFilters 'armeabi-v7a'
|
||||
}
|
||||
ndkBuild {
|
||||
abiFilters 'armeabi-v7a'
|
||||
}
|
||||
}
|
||||
minSdkVersion 24
|
||||
targetSdkVersion 26
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
manifest.srcFile 'AndroidManifest.xml'
|
||||
java.srcDirs = ['../../java']
|
||||
jniLibs.srcDir 'libs'
|
||||
res.srcDirs = ['../../res']
|
||||
assets.srcDirs = ['../../assets']
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility = '1.8'
|
||||
targetCompatibility = '1.8'
|
||||
}
|
||||
compileSdkVersion = 24
|
||||
buildToolsVersion = '29.0.1'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "com.android.support:support-compat:24.2.0"
|
||||
implementation "com.android.support:support-core-utils:24.2.0"
|
||||
}
|
||||
|
||||
repositories {
|
||||
google()
|
||||
}
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
}
|
||||
}
|
29
Projects/Android/build.py
Normal file
29
Projects/Android/build.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# This first bit of code is common bootstrapping code
|
||||
# to determine the SDK root, and to set up the import
|
||||
# path for additional python code.
|
||||
|
||||
#begin bootstrap
|
||||
import os
|
||||
import sys
|
||||
|
||||
def init():
|
||||
root = os.path.realpath( os.path.dirname(os.path.realpath(__file__) ) )
|
||||
os.chdir(root) # make sure we are always executing from the project directory
|
||||
while( os.path.isdir( os.path.join(root, 'bin/scripts/build') ) == False ):
|
||||
root = os.path.realpath( os.path.join(root, '..') )
|
||||
if( len(root) <= 5 ): # Should catch both Posix and Windows root directories (e.g. '/' and 'C:\')
|
||||
print('Unable to find SDK root. Exiting.')
|
||||
sys.exit(1)
|
||||
root = os.path.abspath(root)
|
||||
os.environ['OCULUS_SDK_PATH'] = root
|
||||
sys.path.append( root + "/bin/scripts/build" )
|
||||
|
||||
init()
|
||||
import ovrbuild
|
||||
ovrbuild.init()
|
||||
#end bootstrap
|
||||
|
||||
|
||||
ovrbuild.build()
|
BIN
Projects/Android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
Projects/Android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
Projects/Android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
Projects/Android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
#Sat Jul 27 06:47:04 BST 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
|
172
Projects/Android/gradlew
vendored
Normal file
172
Projects/Android/gradlew
vendored
Normal file
|
@ -0,0 +1,172 @@
|
|||
#!/usr/bin/env sh
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
84
Projects/Android/gradlew.bat
vendored
Normal file
84
Projects/Android/gradlew.bat
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
10
Projects/Android/jni/Android.mk
Normal file
10
Projects/Android/jni/Android.mk
Normal file
|
@ -0,0 +1,10 @@
|
|||
include $(GL4ES_PATH)/Android.mk
|
||||
include $(SUPPORT_LIBS)/SDL2/SDL2/Android.mk
|
||||
include $(SUPPORT_LIBS)/SDL2/SDL2_mixer/Android.mk
|
||||
include $(SUPPORT_LIBS)/jpeg8d/Android.mk
|
||||
include $(SUPPORT_LIBS)/libzip/Android.mk
|
||||
include $(SUPPORT_LIBS)/libpng/Android.mk
|
||||
include $(SUPPORT_LIBS)/sigc++/Android.mk
|
||||
include $(TOP_DIR)/quake2/Android.mk
|
||||
include $(TOP_DIR)/quake2/Android_game.mk
|
||||
include $(TOP_DIR)/quake2/Android_gl1.mk
|
22
Projects/Android/jni/Application.mk
Normal file
22
Projects/Android/jni/Application.mk
Normal file
|
@ -0,0 +1,22 @@
|
|||
# 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
|
||||
|
||||
APPLICATIONMK_PATH = $(call my-dir)
|
||||
|
||||
TOP_DIR := $(APPLICATIONMK_PATH)
|
||||
SUPPORT_LIBS := $(APPLICATIONMK_PATH)/SupportLibs
|
||||
GL4ES_PATH := $(SUPPORT_LIBS)/gl4es
|
||||
|
||||
APP_ALLOW_MISSING_DEPS=true
|
||||
|
||||
APP_MODULES := yquake2 yquake2_game gl4es yquake2_gl1
|
||||
APP_STL := c++_shared
|
||||
|
||||
|
2015
Projects/Android/jni/RTCWVR/RTCWVR_SurfaceView.c
Normal file
2015
Projects/Android/jni/RTCWVR/RTCWVR_SurfaceView.c
Normal file
File diff suppressed because it is too large
Load diff
67
Projects/Android/jni/RTCWVR/VrCommon.h
Normal file
67
Projects/Android/jni/RTCWVR/VrCommon.h
Normal file
|
@ -0,0 +1,67 @@
|
|||
#if !defined(vrcommon_h)
|
||||
#define vrcommon_h
|
||||
|
||||
#include <VrApi_Ext.h>
|
||||
#include <VrApi_Input.h>
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#include "mathlib.h"
|
||||
|
||||
#define LOG_TAG "Quake2VR"
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define DEBUG 1
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
bool quake2_initialised;
|
||||
|
||||
long long global_time;
|
||||
|
||||
float playerHeight;
|
||||
float playerYaw;
|
||||
|
||||
bool showingScreenLayer;
|
||||
float vrFOV;
|
||||
|
||||
vec3_t worldPosition;
|
||||
|
||||
vec3_t hmdPosition;
|
||||
vec3_t hmdorientation;
|
||||
vec3_t positionDeltaThisFrame;
|
||||
|
||||
vec3_t weaponangles;
|
||||
vec3_t weaponoffset;
|
||||
|
||||
vec3_t flashlightangles;
|
||||
vec3_t flashlightoffset;
|
||||
|
||||
#define DUCK_NOTDUCKED 0
|
||||
#define DUCK_BUTTON 1
|
||||
#define DUCK_CROUCHED 2
|
||||
int ducked;
|
||||
|
||||
bool player_moving;
|
||||
|
||||
|
||||
float radians(float deg);
|
||||
float degrees(float rad);
|
||||
qboolean 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, float pitchAdjust, vec3_t out);
|
||||
bool useScreenLayer();
|
||||
void handleTrackedControllerButton(ovrInputStateTrackedRemote * trackedRemoteState, ovrInputStateTrackedRemote * prevTrackedRemoteState, uint32_t button, int key);
|
||||
|
||||
#endif //vrcommon_h
|
595
Projects/Android/jni/RTCWVR/VrCompositor.c
Normal file
595
Projects/Android/jni/RTCWVR/VrCompositor.c
Normal file
|
@ -0,0 +1,595 @@
|
|||
/************************************************************************************
|
||||
|
||||
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->TextureSwapChainIndex;
|
||||
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 = 2.0f;
|
||||
const ovrVector3f translation = { 0.0f, playerHeight, -0.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->TextureSwapChainIndex;
|
||||
|
||||
// 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;
|
||||
}
|
217
Projects/Android/jni/RTCWVR/VrCompositor.h
Normal file
217
Projects/Android/jni/RTCWVR/VrCompositor.h
Normal file
|
@ -0,0 +1,217 @@
|
|||
/************************************************************************************
|
||||
|
||||
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 TextureSwapChainIndex;
|
||||
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];
|
||||
ovrMatrix4f ProjectionMatrix;
|
||||
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
|
||||
{
|
||||
GLuint VertexBuffer;
|
||||
GLuint IndexBuffer;
|
||||
GLuint VertexArrayObject;
|
||||
GLuint Program;
|
||||
GLuint VertexShader;
|
||||
GLuint FragmentShader;
|
||||
} renderState;
|
||||
|
||||
void getCurrentRenderState( renderState * state);
|
||||
void restoreRenderState( renderState * state );
|
||||
|
||||
/*
|
||||
================================================================================
|
||||
|
||||
ovrGeometry
|
||||
|
||||
================================================================================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GLuint 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 );
|
||||
;
|
||||
|
||||
|
11
Projects/Android/jni/RTCWVR/VrCvars.h
Normal file
11
Projects/Android/jni/RTCWVR/VrCvars.h
Normal file
|
@ -0,0 +1,11 @@
|
|||
cvar_t *vr_snapturn_angle;
|
||||
cvar_t *vr_positional_factor;
|
||||
cvar_t *vr_walkdirection;
|
||||
cvar_t *vr_weapon_pitchadjust;
|
||||
cvar_t *vr_lasersight;
|
||||
cvar_t *vr_control_scheme;
|
||||
cvar_t *vr_height_adjust;
|
||||
cvar_t *vr_worldscale;
|
||||
cvar_t *vr_weaponscale;
|
||||
cvar_t *vr_weapon_stabilised;
|
||||
cvar_t *vr_comfort_mask;
|
37
Projects/Android/jni/RTCWVR/VrInput.h
Normal file
37
Projects/Android/jni/RTCWVR/VrInput.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
|
||||
#if !defined(vrinput_h)
|
||||
#define vrinput_h
|
||||
|
||||
#include "VrCommon.h"
|
||||
|
||||
//New control scheme definitions to be defined L1VR_SurfaceView.c enumeration
|
||||
enum control_scheme;
|
||||
|
||||
ovrInputStateTrackedRemote leftTrackedRemoteState_old;
|
||||
ovrInputStateTrackedRemote leftTrackedRemoteState_new;
|
||||
ovrTracking leftRemoteTracking_new;
|
||||
|
||||
ovrInputStateTrackedRemote rightTrackedRemoteState_old;
|
||||
ovrInputStateTrackedRemote rightTrackedRemoteState_new;
|
||||
ovrTracking rightRemoteTracking_new;
|
||||
|
||||
ovrDeviceID controllerIDs[2];
|
||||
|
||||
float remote_movementSideways;
|
||||
float remote_movementForward;
|
||||
float remote_movementUp;
|
||||
float positional_movementSideways;
|
||||
float positional_movementForward;
|
||||
float snapTurn;
|
||||
|
||||
void sendButtonAction(const char* action, long buttonDown);
|
||||
void sendButtonActionSimple(const char* action);
|
||||
|
||||
void acquireTrackedRemotesData(const ovrMobile *Ovr, double displayTime);
|
||||
|
||||
void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovrInputStateTrackedRemote *pDominantTrackedRemoteOld, ovrTracking* pDominantTracking,
|
||||
ovrInputStateTrackedRemote *pOffTrackedRemoteNew, ovrInputStateTrackedRemote *pOffTrackedRemoteOld, ovrTracking* pOffTracking,
|
||||
int domButton1, int domButton2, int offButton1, int offButton2 );
|
||||
|
||||
|
||||
#endif //vrinput_h
|
142
Projects/Android/jni/RTCWVR/VrInputCommon.c
Normal file
142
Projects/Android/jni/RTCWVR/VrInputCommon.c
Normal file
|
@ -0,0 +1,142 @@
|
|||
/************************************************************************************
|
||||
|
||||
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"
|
||||
|
||||
//keys.h
|
||||
void Key_Event (int key, qboolean down, unsigned time);
|
||||
|
||||
void handleTrackedControllerButton(ovrInputStateTrackedRemote * trackedRemoteState, ovrInputStateTrackedRemote * prevTrackedRemoteState, uint32_t button, int key)
|
||||
{
|
||||
if ((trackedRemoteState->Buttons & button) != (prevTrackedRemoteState->Buttons & button))
|
||||
{
|
||||
Key_Event(key, (trackedRemoteState->Buttons & button) != 0, global_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void sendButtonActionSimple(const char* action)
|
||||
{
|
||||
char command[256];
|
||||
snprintf( command, sizeof( command ), "%s\n", action );
|
||||
Cbuf_AddText( command );
|
||||
}
|
||||
|
||||
bool between(float min, float val, float max)
|
||||
{
|
||||
return (min < val) && (val < max);
|
||||
}
|
||||
|
||||
void sendButtonAction(const char* action, long buttonDown)
|
||||
{
|
||||
char command[256];
|
||||
snprintf( command, sizeof( command ), "%s\n", action );
|
||||
if (!buttonDown)
|
||||
{
|
||||
command[0] = '-';
|
||||
}
|
||||
Cbuf_AddText( command );
|
||||
}
|
||||
|
||||
void acquireTrackedRemotesData(const ovrMobile *Ovr, double displayTime) {//The amount of yaw changed by controller
|
||||
for ( int i = 0; ; i++ ) {
|
||||
ovrInputCapabilityHeader cap;
|
||||
ovrResult result = vrapi_EnumerateInputDevices(Ovr, i, &cap);
|
||||
if (result < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (cap.Type == ovrControllerType_TrackedRemote) {
|
||||
ovrTracking remoteTracking;
|
||||
ovrInputStateTrackedRemote trackedRemoteState;
|
||||
trackedRemoteState.Header.ControllerType = ovrControllerType_TrackedRemote;
|
||||
result = vrapi_GetCurrentInputState(Ovr, cap.DeviceID, &trackedRemoteState.Header);
|
||||
|
||||
if (result == ovrSuccess) {
|
||||
ovrInputTrackedRemoteCapabilities remoteCapabilities;
|
||||
remoteCapabilities.Header = cap;
|
||||
result = vrapi_GetInputDeviceCapabilities(Ovr, &remoteCapabilities.Header);
|
||||
|
||||
result = vrapi_GetInputTrackingState(Ovr, cap.DeviceID, displayTime,
|
||||
&remoteTracking);
|
||||
|
||||
if (remoteCapabilities.ControllerCapabilities & ovrControllerCaps_RightHand) {
|
||||
rightTrackedRemoteState_new = trackedRemoteState;
|
||||
rightRemoteTracking_new = remoteTracking;
|
||||
controllerIDs[1] = cap.DeviceID;
|
||||
} else{
|
||||
leftTrackedRemoteState_new = trackedRemoteState;
|
||||
leftRemoteTracking_new = remoteTracking;
|
||||
controllerIDs[0] = cap.DeviceID;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
376
Projects/Android/jni/RTCWVR/VrInputDefault.c
Normal file
376
Projects/Android/jni/RTCWVR/VrInputDefault.c
Normal file
|
@ -0,0 +1,376 @@
|
|||
/************************************************************************************
|
||||
|
||||
Filename : VrInputDefault.c
|
||||
Content : Handles default controller input
|
||||
Created : August 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"
|
||||
#include "VrCvars.h"
|
||||
|
||||
#include "../quake2/src/client/header/client.h"
|
||||
|
||||
extern cvar_t *cl_forwardspeed;
|
||||
cvar_t *sv_cheats;
|
||||
extern cvar_t *vr_weapon_stabilised;
|
||||
|
||||
|
||||
void HandleInput_Default( ovrInputStateTrackedRemote *pDominantTrackedRemoteNew, ovrInputStateTrackedRemote *pDominantTrackedRemoteOld, ovrTracking* pDominantTracking,
|
||||
ovrInputStateTrackedRemote *pOffTrackedRemoteNew, ovrInputStateTrackedRemote *pOffTrackedRemoteOld, ovrTracking* pOffTracking,
|
||||
int domButton1, int domButton2, int offButton1, int offButton2 )
|
||||
|
||||
{
|
||||
//Ensure handedness is set correctly
|
||||
Cvar_Set("hand", vr_control_scheme->value < 10 ? "0" : "1");
|
||||
|
||||
//Get the cvar
|
||||
sv_cheats = Cvar_Get("cheats", "0", CVAR_ARCHIVE);
|
||||
|
||||
static qboolean dominantGripPushed = false;
|
||||
static float dominantGripPushTime = 0.0f;
|
||||
static qboolean inventoryManagementMode = false;
|
||||
|
||||
//Show screen view (if in multiplayer toggle scoreboard)
|
||||
if (((pOffTrackedRemoteNew->Buttons & offButton2) !=
|
||||
(pOffTrackedRemoteOld->Buttons & offButton2)) &&
|
||||
(pOffTrackedRemoteNew->Buttons & offButton2)) {
|
||||
|
||||
showingScreenLayer = !showingScreenLayer;
|
||||
|
||||
//Check we are in multiplayer
|
||||
if (isMultiplayer()) {
|
||||
sendButtonActionSimple("score");
|
||||
}
|
||||
}
|
||||
|
||||
//Menu button
|
||||
handleTrackedControllerButton(&leftTrackedRemoteState_new, &leftTrackedRemoteState_old, ovrButton_Enter, K_ESCAPE);
|
||||
|
||||
if (cls.key_dest == key_menu)
|
||||
{
|
||||
int leftJoyState = (pOffTrackedRemoteNew->Joystick.x > 0.7f ? 1 : 0);
|
||||
if (leftJoyState != (pOffTrackedRemoteOld->Joystick.x > 0.7f ? 1 : 0)) {
|
||||
Key_Event(K_RIGHTARROW, leftJoyState, global_time);
|
||||
}
|
||||
leftJoyState = (pOffTrackedRemoteNew->Joystick.x < -0.7f ? 1 : 0);
|
||||
if (leftJoyState != (pOffTrackedRemoteOld->Joystick.x < -0.7f ? 1 : 0)) {
|
||||
Key_Event(K_LEFTARROW, leftJoyState, global_time);
|
||||
}
|
||||
leftJoyState = (pOffTrackedRemoteNew->Joystick.y < -0.7f ? 1 : 0);
|
||||
if (leftJoyState != (pOffTrackedRemoteOld->Joystick.y < -0.7f ? 1 : 0)) {
|
||||
Key_Event(K_DOWNARROW, leftJoyState, global_time);
|
||||
}
|
||||
leftJoyState = (pOffTrackedRemoteNew->Joystick.y > 0.7f ? 1 : 0);
|
||||
if (leftJoyState != (pOffTrackedRemoteOld->Joystick.y > 0.7f ? 1 : 0)) {
|
||||
Key_Event(K_UPARROW, leftJoyState, global_time);
|
||||
}
|
||||
|
||||
handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, domButton1, K_ENTER);
|
||||
handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, ovrButton_Trigger, K_ENTER);
|
||||
handleTrackedControllerButton(pDominantTrackedRemoteNew, pDominantTrackedRemoteOld, domButton2, K_ESCAPE);
|
||||
}
|
||||
else
|
||||
{
|
||||
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));
|
||||
|
||||
//Turn on weapon stabilisation?
|
||||
if ((pOffTrackedRemoteNew->Buttons & ovrButton_GripTrigger) !=
|
||||
(pOffTrackedRemoteOld->Buttons & ovrButton_GripTrigger)) {
|
||||
|
||||
if (pOffTrackedRemoteNew->Buttons & ovrButton_GripTrigger)
|
||||
{
|
||||
if (distance < 0.50f)
|
||||
{
|
||||
Cvar_ForceSet("vr_weapon_stabilised", "1.0");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Cvar_ForceSet("vr_weapon_stabilised", "0.0");
|
||||
}
|
||||
}
|
||||
|
||||
//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];
|
||||
|
||||
{
|
||||
vec2_t v;
|
||||
rotateAboutOrigin(-weaponoffset[0], weaponoffset[2], (cl.refdef.viewangles[YAW] - hmdorientation[YAW]), v);
|
||||
weaponoffset[0] = v[0];
|
||||
weaponoffset[2] = v[1];
|
||||
}
|
||||
|
||||
//Set gun angles - We need to calculate all those we might need (including adjustments) for the client to then take its pick
|
||||
const ovrQuatf quatRemote = pDominantTracking->HeadPose.Pose.Orientation;
|
||||
QuatToYawPitchRoll(quatRemote, vr_weapon_pitchadjust->value, weaponangles);
|
||||
weaponangles[YAW] += (cl.refdef.viewangles[YAW] - hmdorientation[YAW]);
|
||||
weaponangles[ROLL] *= -1.0f;
|
||||
|
||||
|
||||
if (vr_weapon_stabilised->value == 1.0f)
|
||||
{
|
||||
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 zxDist = length(x, z);
|
||||
|
||||
if (zxDist != 0.0f && z != 0.0f) {
|
||||
VectorSet(weaponangles, -degrees(atanf(y / zxDist)), (cl.refdef.viewangles[YAW] - hmdorientation[YAW]) - degrees(atan2f(x, -z)), weaponangles[ROLL]);
|
||||
}
|
||||
}
|
||||
|
||||
if ((pDominantTrackedRemoteNew->Buttons & ovrButton_GripTrigger) !=
|
||||
(pDominantTrackedRemoteOld->Buttons & ovrButton_GripTrigger)) {
|
||||
|
||||
sendButtonActionSimple("inven");
|
||||
inventoryManagementMode = (pDominantTrackedRemoteNew->Buttons & ovrButton_GripTrigger) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
float controllerYawHeading = 0.0f;
|
||||
//off-hand stuff
|
||||
{
|
||||
flashlightoffset[0] = pOffTracking->HeadPose.Pose.Position.x - hmdPosition[0];
|
||||
flashlightoffset[1] = pOffTracking->HeadPose.Pose.Position.y - hmdPosition[1];
|
||||
flashlightoffset[2] = pOffTracking->HeadPose.Pose.Position.z - hmdPosition[2];
|
||||
|
||||
vec2_t v;
|
||||
rotateAboutOrigin(-flashlightoffset[0], flashlightoffset[2], (cl.refdef.viewangles[YAW] - hmdorientation[YAW]), v);
|
||||
flashlightoffset[0] = v[0];
|
||||
flashlightoffset[2] = v[1];
|
||||
|
||||
QuatToYawPitchRoll(pOffTracking->HeadPose.Pose.Orientation, 15.0f, flashlightangles);
|
||||
|
||||
flashlightangles[YAW] += (cl.refdef.viewangles[YAW] - hmdorientation[YAW]);
|
||||
|
||||
if (vr_walkdirection->value == 0) {
|
||||
controllerYawHeading = -cl.refdef.viewangles[YAW] + flashlightangles[YAW];
|
||||
}
|
||||
else
|
||||
{
|
||||
controllerYawHeading = 0.0f;//-cl.viewangles[YAW];
|
||||
}
|
||||
}
|
||||
|
||||
//Right-hand specific stuff
|
||||
{
|
||||
ALOGV(" Right-Controller-Position: %f, %f, %f",
|
||||
pDominantTracking->HeadPose.Pose.Position.x,
|
||||
pDominantTracking->HeadPose.Pose.Position.y,
|
||||
pDominantTracking->HeadPose.Pose.Position.z);
|
||||
|
||||
//This section corrects for the fact that the controller actually controls direction of movement, but we want to move relative to the direction the
|
||||
//player is facing for positional tracking
|
||||
float multiplier = (vr_positional_factor->value) / (cl_forwardspeed->value *
|
||||
((pOffTrackedRemoteNew->Buttons & ovrButton_Trigger) ? 1.5f : 1.0f));
|
||||
|
||||
vec2_t v;
|
||||
rotateAboutOrigin(-positionDeltaThisFrame[0] * multiplier,
|
||||
positionDeltaThisFrame[2] * multiplier, /*cl.refdef.viewangles[YAW]*/ - hmdorientation[YAW], v);
|
||||
positional_movementSideways = v[0];
|
||||
positional_movementForward = v[1];
|
||||
|
||||
ALOGV(" positional_movementSideways: %f, positional_movementForward: %f",
|
||||
positional_movementSideways,
|
||||
positional_movementForward);
|
||||
|
||||
//Jump (B Button)
|
||||
handleTrackedControllerButton(pDominantTrackedRemoteNew,
|
||||
pDominantTrackedRemoteOld, domButton2, K_SPACE);
|
||||
|
||||
//We need to record if we have started firing primary so that releasing trigger will stop firing, if user has pushed grip
|
||||
//in meantime, then it wouldn't stop the gun firing and it would get stuck
|
||||
static bool firingPrimary = false;
|
||||
|
||||
{
|
||||
//Fire Primary
|
||||
if ((pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger) !=
|
||||
(pDominantTrackedRemoteOld->Buttons & ovrButton_Trigger)) {
|
||||
|
||||
firingPrimary = (pDominantTrackedRemoteNew->Buttons & ovrButton_Trigger);
|
||||
|
||||
if (inventoryManagementMode)
|
||||
{
|
||||
if (firingPrimary)
|
||||
sendButtonActionSimple("invuse");
|
||||
}
|
||||
else
|
||||
{
|
||||
sendButtonAction("+attack", firingPrimary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Duck with A
|
||||
if ((pDominantTrackedRemoteNew->Buttons & domButton1) !=
|
||||
(pDominantTrackedRemoteOld->Buttons & domButton1) &&
|
||||
ducked != DUCK_CROUCHED) {
|
||||
ducked = (pDominantTrackedRemoteNew->Buttons & domButton1) ? DUCK_BUTTON : DUCK_NOTDUCKED;
|
||||
sendButtonAction("+movedown", (pDominantTrackedRemoteNew->Buttons & domButton1));
|
||||
}
|
||||
|
||||
//Weapon/Inventory Chooser
|
||||
static qboolean itemSwitched = false;
|
||||
if (between(-0.2f, pDominantTrackedRemoteNew->Joystick.x, 0.2f) &&
|
||||
(between(0.8f, pDominantTrackedRemoteNew->Joystick.y, 1.0f) ||
|
||||
between(-1.0f, pDominantTrackedRemoteNew->Joystick.y, -0.8f)))
|
||||
{
|
||||
if (!itemSwitched) {
|
||||
if (between(0.8f, pDominantTrackedRemoteNew->Joystick.y, 1.0f))
|
||||
{
|
||||
if (inventoryManagementMode)
|
||||
{
|
||||
sendButtonActionSimple("invprev");
|
||||
}
|
||||
else
|
||||
{
|
||||
sendButtonActionSimple("weapprev");
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (inventoryManagementMode)
|
||||
{
|
||||
sendButtonActionSimple("invnext");
|
||||
}
|
||||
else
|
||||
{
|
||||
sendButtonActionSimple("weapnext");
|
||||
}
|
||||
}
|
||||
itemSwitched = true;
|
||||
}
|
||||
} else {
|
||||
itemSwitched = false;
|
||||
}
|
||||
}
|
||||
|
||||
//Left-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);
|
||||
|
||||
//Laser-sight
|
||||
if ((pDominantTrackedRemoteNew->Buttons & ovrButton_Joystick) !=
|
||||
(pDominantTrackedRemoteOld->Buttons & ovrButton_Joystick)
|
||||
&& (pDominantTrackedRemoteNew->Buttons & ovrButton_Joystick)) {
|
||||
|
||||
if (vr_lasersight->value != 0.0)
|
||||
{
|
||||
Cvar_ForceSet("vr_lasersight", "0.0");
|
||||
} else {
|
||||
Cvar_ForceSet("vr_lasersight", "1.0");
|
||||
}
|
||||
}
|
||||
|
||||
//Apply a filter and quadratic scaler so small movements are easier to make
|
||||
float dist = length(pOffTrackedRemoteNew->Joystick.x, pOffTrackedRemoteNew->Joystick.y);
|
||||
float nlf = nonLinearFilter(dist);
|
||||
float x = nlf * pOffTrackedRemoteNew->Joystick.x;
|
||||
float y = nlf * pOffTrackedRemoteNew->Joystick.y;
|
||||
|
||||
player_moving = (fabs(x) + fabs(y)) > 0.05f;
|
||||
|
||||
//Adjust to be off-hand controller oriented
|
||||
vec2_t v;
|
||||
rotateAboutOrigin(x, y, controllerYawHeading, v);
|
||||
|
||||
remote_movementSideways = v[0];
|
||||
remote_movementForward = v[1];
|
||||
ALOGV(" remote_movementSideways: %f, remote_movementForward: %f",
|
||||
remote_movementSideways,
|
||||
remote_movementForward);
|
||||
|
||||
|
||||
//show help computer while X/A pressed
|
||||
if ((pOffTrackedRemoteNew->Buttons & offButton1) !=
|
||||
(pOffTrackedRemoteOld->Buttons & offButton1)) {
|
||||
sendButtonActionSimple("cmd help");
|
||||
}
|
||||
|
||||
|
||||
//Use (Action)
|
||||
if ((pOffTrackedRemoteNew->Buttons & ovrButton_Joystick) !=
|
||||
(pOffTrackedRemoteOld->Buttons & ovrButton_Joystick)
|
||||
&& (pOffTrackedRemoteNew->Buttons & ovrButton_Joystick)) {
|
||||
|
||||
//If cheats enabled, give all weapons/pickups to player
|
||||
if (sv_cheats->value == 1.0f) {
|
||||
Cbuf_AddText("give all\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//We need to record if we have started firing primary so that releasing trigger will stop definitely firing, if user has pushed grip
|
||||
//in meantime, then it wouldn't stop the gun firing and it would get stuck
|
||||
static bool firingPrimary = false;
|
||||
|
||||
//Run
|
||||
handleTrackedControllerButton(pOffTrackedRemoteNew,
|
||||
pOffTrackedRemoteOld,
|
||||
ovrButton_Trigger, K_SHIFT);
|
||||
|
||||
static int increaseSnap = true;
|
||||
if (pDominantTrackedRemoteNew->Joystick.x > 0.6f)
|
||||
{
|
||||
if (increaseSnap)
|
||||
{
|
||||
snapTurn -= vr_snapturn_angle->value;
|
||||
if (vr_snapturn_angle->value > 10.0f) {
|
||||
increaseSnap = false;
|
||||
}
|
||||
|
||||
if (snapTurn < -180.0f)
|
||||
{
|
||||
snapTurn += 360.f;
|
||||
}
|
||||
}
|
||||
} else if (pDominantTrackedRemoteNew->Joystick.x < 0.4f) {
|
||||
increaseSnap = true;
|
||||
}
|
||||
|
||||
static int decreaseSnap = true;
|
||||
if (pDominantTrackedRemoteNew->Joystick.x < -0.6f)
|
||||
{
|
||||
if (decreaseSnap)
|
||||
{
|
||||
snapTurn += vr_snapturn_angle->value;
|
||||
|
||||
//If snap turn configured for less than 10 degrees
|
||||
if (vr_snapturn_angle->value > 10.0f) {
|
||||
decreaseSnap = false;
|
||||
}
|
||||
|
||||
if (snapTurn > 180.0f)
|
||||
{
|
||||
snapTurn -= 360.f;
|
||||
}
|
||||
}
|
||||
} else if (pDominantTrackedRemoteNew->Joystick.x > -0.4f)
|
||||
{
|
||||
decreaseSnap = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Save state
|
||||
rightTrackedRemoteState_old = rightTrackedRemoteState_new;
|
||||
leftTrackedRemoteState_old = leftTrackedRemoteState_new;
|
||||
}
|
5019
Projects/Android/jni/RTCWVR/argtable3.c
Normal file
5019
Projects/Android/jni/RTCWVR/argtable3.c
Normal file
File diff suppressed because it is too large
Load diff
305
Projects/Android/jni/RTCWVR/argtable3.h
Normal file
305
Projects/Android/jni/RTCWVR/argtable3.h
Normal file
|
@ -0,0 +1,305 @@
|
|||
/*******************************************************************************
|
||||
* This file is part of the argtable3 library.
|
||||
*
|
||||
* Copyright (C) 1998-2001,2003-2011,2013 Stewart Heitmann
|
||||
* <sheitmann@users.sourceforge.net>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* * Neither the name of STEWART HEITMANN nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL STEWART HEITMANN BE LIABLE FOR ANY DIRECT,
|
||||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef ARGTABLE3
|
||||
#define ARGTABLE3
|
||||
|
||||
#include <stdio.h> /* FILE */
|
||||
#include <time.h> /* struct tm */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ARG_REX_ICASE 1
|
||||
|
||||
/* bit masks for arg_hdr.flag */
|
||||
enum
|
||||
{
|
||||
ARG_TERMINATOR=0x1,
|
||||
ARG_HASVALUE=0x2,
|
||||
ARG_HASOPTVALUE=0x4
|
||||
};
|
||||
|
||||
typedef void (arg_resetfn)(void *parent);
|
||||
typedef int (arg_scanfn)(void *parent, const char *argval);
|
||||
typedef int (arg_checkfn)(void *parent);
|
||||
typedef void (arg_errorfn)(void *parent, FILE *fp, int error, const char *argval, const char *progname);
|
||||
|
||||
|
||||
/*
|
||||
* The arg_hdr struct defines properties that are common to all arg_xxx structs.
|
||||
* The argtable library requires each arg_xxx struct to have an arg_hdr
|
||||
* struct as its first data member.
|
||||
* The argtable library functions then use this data to identify the
|
||||
* properties of the command line option, such as its option tags,
|
||||
* datatype string, and glossary strings, and so on.
|
||||
* Moreover, the arg_hdr struct contains pointers to custom functions that
|
||||
* are provided by each arg_xxx struct which perform the tasks of parsing
|
||||
* that particular arg_xxx arguments, performing post-parse checks, and
|
||||
* reporting errors.
|
||||
* These functions are private to the individual arg_xxx source code
|
||||
* and are the pointer to them are initiliased by that arg_xxx struct's
|
||||
* constructor function. The user could alter them after construction
|
||||
* if desired, but the original intention is for them to be set by the
|
||||
* constructor and left unaltered.
|
||||
*/
|
||||
struct arg_hdr
|
||||
{
|
||||
char flag; /* Modifier flags: ARG_TERMINATOR, ARG_HASVALUE. */
|
||||
const char *shortopts; /* String defining the short options */
|
||||
const char *longopts; /* String defiing the long options */
|
||||
const char *datatype; /* Description of the argument data type */
|
||||
const char *glossary; /* Description of the option as shown by arg_print_glossary function */
|
||||
int mincount; /* Minimum number of occurences of this option accepted */
|
||||
int maxcount; /* Maximum number of occurences if this option accepted */
|
||||
void *parent; /* Pointer to parent arg_xxx struct */
|
||||
arg_resetfn *resetfn; /* Pointer to parent arg_xxx reset function */
|
||||
arg_scanfn *scanfn; /* Pointer to parent arg_xxx scan function */
|
||||
arg_checkfn *checkfn; /* Pointer to parent arg_xxx check function */
|
||||
arg_errorfn *errorfn; /* Pointer to parent arg_xxx error function */
|
||||
void *priv; /* Pointer to private header data for use by arg_xxx functions */
|
||||
};
|
||||
|
||||
struct arg_rem
|
||||
{
|
||||
struct arg_hdr hdr; /* The mandatory argtable header struct */
|
||||
};
|
||||
|
||||
struct arg_lit
|
||||
{
|
||||
struct arg_hdr hdr; /* The mandatory argtable header struct */
|
||||
int count; /* Number of matching command line args */
|
||||
};
|
||||
|
||||
struct arg_int
|
||||
{
|
||||
struct arg_hdr hdr; /* The mandatory argtable header struct */
|
||||
int count; /* Number of matching command line args */
|
||||
int *ival; /* Array of parsed argument values */
|
||||
};
|
||||
|
||||
struct arg_dbl
|
||||
{
|
||||
struct arg_hdr hdr; /* The mandatory argtable header struct */
|
||||
int count; /* Number of matching command line args */
|
||||
double *dval; /* Array of parsed argument values */
|
||||
};
|
||||
|
||||
struct arg_str
|
||||
{
|
||||
struct arg_hdr hdr; /* The mandatory argtable header struct */
|
||||
int count; /* Number of matching command line args */
|
||||
const char **sval; /* Array of parsed argument values */
|
||||
};
|
||||
|
||||
struct arg_rex
|
||||
{
|
||||
struct arg_hdr hdr; /* The mandatory argtable header struct */
|
||||
int count; /* Number of matching command line args */
|
||||
const char **sval; /* Array of parsed argument values */
|
||||
};
|
||||
|
||||
struct arg_file
|
||||
{
|
||||
struct arg_hdr hdr; /* The mandatory argtable header struct */
|
||||
int count; /* Number of matching command line args*/
|
||||
const char **filename; /* Array of parsed filenames (eg: /home/foo.bar) */
|
||||
const char **basename; /* Array of parsed basenames (eg: foo.bar) */
|
||||
const char **extension; /* Array of parsed extensions (eg: .bar) */
|
||||
};
|
||||
|
||||
struct arg_date
|
||||
{
|
||||
struct arg_hdr hdr; /* The mandatory argtable header struct */
|
||||
const char *format; /* strptime format string used to parse the date */
|
||||
int count; /* Number of matching command line args */
|
||||
struct tm *tmval; /* Array of parsed time values */
|
||||
};
|
||||
|
||||
enum {ARG_ELIMIT=1, ARG_EMALLOC, ARG_ENOMATCH, ARG_ELONGOPT, ARG_EMISSARG};
|
||||
struct arg_end
|
||||
{
|
||||
struct arg_hdr hdr; /* The mandatory argtable header struct */
|
||||
int count; /* Number of errors encountered */
|
||||
int *error; /* Array of error codes */
|
||||
void **parent; /* Array of pointers to offending arg_xxx struct */
|
||||
const char **argval; /* Array of pointers to offending argv[] string */
|
||||
};
|
||||
|
||||
|
||||
/**** arg_xxx constructor functions *********************************/
|
||||
|
||||
struct arg_rem* arg_rem(const char* datatype, const char* glossary);
|
||||
|
||||
struct arg_lit* arg_lit0(const char* shortopts,
|
||||
const char* longopts,
|
||||
const char* glossary);
|
||||
struct arg_lit* arg_lit1(const char* shortopts,
|
||||
const char* longopts,
|
||||
const char *glossary);
|
||||
struct arg_lit* arg_litn(const char* shortopts,
|
||||
const char* longopts,
|
||||
int mincount,
|
||||
int maxcount,
|
||||
const char *glossary);
|
||||
|
||||
struct arg_key* arg_key0(const char* keyword,
|
||||
int flags,
|
||||
const char* glossary);
|
||||
struct arg_key* arg_key1(const char* keyword,
|
||||
int flags,
|
||||
const char* glossary);
|
||||
struct arg_key* arg_keyn(const char* keyword,
|
||||
int flags,
|
||||
int mincount,
|
||||
int maxcount,
|
||||
const char* glossary);
|
||||
|
||||
struct arg_int* arg_int0(const char* shortopts,
|
||||
const char* longopts,
|
||||
const char* datatype,
|
||||
const char* glossary);
|
||||
struct arg_int* arg_int1(const char* shortopts,
|
||||
const char* longopts,
|
||||
const char* datatype,
|
||||
const char *glossary);
|
||||
struct arg_int* arg_intn(const char* shortopts,
|
||||
const char* longopts,
|
||||
const char *datatype,
|
||||
int mincount,
|
||||
int maxcount,
|
||||
const char *glossary);
|
||||
|
||||
struct arg_dbl* arg_dbl0(const char* shortopts,
|
||||
const char* longopts,
|
||||
const char* datatype,
|
||||
const char* glossary);
|
||||
struct arg_dbl* arg_dbl1(const char* shortopts,
|
||||
const char* longopts,
|
||||
const char* datatype,
|
||||
const char *glossary);
|
||||
struct arg_dbl* arg_dbln(const char* shortopts,
|
||||
const char* longopts,
|
||||
const char *datatype,
|
||||
int mincount,
|
||||
int maxcount,
|
||||
const char *glossary);
|
||||
|
||||
struct arg_str* arg_str0(const char* shortopts,
|
||||
const char* longopts,
|
||||
const char* datatype,
|
||||
const char* glossary);
|
||||
struct arg_str* arg_str1(const char* shortopts,
|
||||
const char* longopts,
|
||||
const char* datatype,
|
||||
const char *glossary);
|
||||
struct arg_str* arg_strn(const char* shortopts,
|
||||
const char* longopts,
|
||||
const char* datatype,
|
||||
int mincount,
|
||||
int maxcount,
|
||||
const char *glossary);
|
||||
|
||||
struct arg_rex* arg_rex0(const char* shortopts,
|
||||
const char* longopts,
|
||||
const char* pattern,
|
||||
const char* datatype,
|
||||
int flags,
|
||||
const char* glossary);
|
||||
struct arg_rex* arg_rex1(const char* shortopts,
|
||||
const char* longopts,
|
||||
const char* pattern,
|
||||
const char* datatype,
|
||||
int flags,
|
||||
const char *glossary);
|
||||
struct arg_rex* arg_rexn(const char* shortopts,
|
||||
const char* longopts,
|
||||
const char* pattern,
|
||||
const char* datatype,
|
||||
int mincount,
|
||||
int maxcount,
|
||||
int flags,
|
||||
const char *glossary);
|
||||
|
||||
struct arg_file* arg_file0(const char* shortopts,
|
||||
const char* longopts,
|
||||
const char* datatype,
|
||||
const char* glossary);
|
||||
struct arg_file* arg_file1(const char* shortopts,
|
||||
const char* longopts,
|
||||
const char* datatype,
|
||||
const char *glossary);
|
||||
struct arg_file* arg_filen(const char* shortopts,
|
||||
const char* longopts,
|
||||
const char* datatype,
|
||||
int mincount,
|
||||
int maxcount,
|
||||
const char *glossary);
|
||||
|
||||
struct arg_date* arg_date0(const char* shortopts,
|
||||
const char* longopts,
|
||||
const char* format,
|
||||
const char* datatype,
|
||||
const char* glossary);
|
||||
struct arg_date* arg_date1(const char* shortopts,
|
||||
const char* longopts,
|
||||
const char* format,
|
||||
const char* datatype,
|
||||
const char *glossary);
|
||||
struct arg_date* arg_daten(const char* shortopts,
|
||||
const char* longopts,
|
||||
const char* format,
|
||||
const char* datatype,
|
||||
int mincount,
|
||||
int maxcount,
|
||||
const char *glossary);
|
||||
|
||||
struct arg_end* arg_end(int maxerrors);
|
||||
|
||||
|
||||
/**** other functions *******************************************/
|
||||
int arg_nullcheck(void **argtable);
|
||||
int arg_parse(int argc, char **argv, void **argtable);
|
||||
void arg_print_option(FILE *fp, const char *shortopts, const char *longopts, const char *datatype, const char *suffix);
|
||||
void arg_print_syntax(FILE *fp, void **argtable, const char *suffix);
|
||||
void arg_print_syntaxv(FILE *fp, void **argtable, const char *suffix);
|
||||
void arg_print_glossary(FILE *fp, void **argtable, const char *format);
|
||||
void arg_print_glossary_gnu(FILE *fp, void **argtable);
|
||||
void arg_print_errors(FILE* fp, struct arg_end* end, const char* progname);
|
||||
void arg_freetable(void **argtable, size_t n);
|
||||
|
||||
/**** deprecated functions, for back-compatibility only ********/
|
||||
void arg_free(void **argtable);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
525
Projects/Android/jni/RTCWVR/mathlib.c
Normal file
525
Projects/Android/jni/RTCWVR/mathlib.c
Normal file
|
@ -0,0 +1,525 @@
|
|||
/*
|
||||
mathlib.c - internal mathlib
|
||||
Copyright (C) 2010 Uncle Mike
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "mathlib.h"
|
||||
|
||||
unsigned short FloatToHalf( float v )
|
||||
{
|
||||
unsigned int i = *((unsigned int *)&v);
|
||||
unsigned int e = (i >> 23) & 0x00ff;
|
||||
unsigned int m = i & 0x007fffff;
|
||||
unsigned short h;
|
||||
|
||||
if( e <= 127 - 15 )
|
||||
h = ((m | 0x00800000) >> (127 - 14 - e)) >> 13;
|
||||
else h = (i >> 13) & 0x3fff;
|
||||
|
||||
h |= (i >> 16) & 0xc000;
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
float HalfToFloat( unsigned short h )
|
||||
{
|
||||
unsigned int f = (h << 16) & 0x80000000;
|
||||
unsigned int em = h & 0x7fff;
|
||||
|
||||
if( em > 0x03ff )
|
||||
{
|
||||
f |= (em << 13) + ((127 - 15) << 23);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int m = em & 0x03ff;
|
||||
|
||||
if( m != 0 )
|
||||
{
|
||||
unsigned int e = (em >> 10) & 0x1f;
|
||||
|
||||
while(( m & 0x0400 ) == 0 )
|
||||
{
|
||||
m <<= 1;
|
||||
e--;
|
||||
}
|
||||
|
||||
m &= 0x3ff;
|
||||
f |= ((e + (127 - 14)) << 23) | (m << 13);
|
||||
}
|
||||
}
|
||||
|
||||
return *((float *)&f);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
NearestPOW
|
||||
=================
|
||||
*/
|
||||
int NearestPOW( int value, qboolean roundDown )
|
||||
{
|
||||
int n = 1;
|
||||
|
||||
if( value <= 0 ) return 1;
|
||||
while( n < value ) n <<= 1;
|
||||
|
||||
if( roundDown )
|
||||
{
|
||||
if( n > value ) n >>= 1;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
// remap a value in the range [A,B] to [C,D].
|
||||
float RemapVal( float val, float A, float B, float C, float D )
|
||||
{
|
||||
return C + (D - C) * (val - A) / (B - A);
|
||||
}
|
||||
|
||||
float ApproachVal( float target, float value, float speed )
|
||||
{
|
||||
float delta = target - value;
|
||||
|
||||
if( delta > speed )
|
||||
value += speed;
|
||||
else if( delta < -speed )
|
||||
value -= speed;
|
||||
else value = target;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
rsqrt
|
||||
=================
|
||||
*/
|
||||
float rsqrt( float number )
|
||||
{
|
||||
int i;
|
||||
float x, y;
|
||||
|
||||
if( number == 0.0f )
|
||||
return 0.0f;
|
||||
|
||||
x = number * 0.5f;
|
||||
i = *(int *)&number; // evil floating point bit level hacking
|
||||
i = 0x5f3759df - (i >> 1); // what the fuck?
|
||||
y = *(float *)&i;
|
||||
y = y * (1.5f - (x * y * y)); // first iteration
|
||||
|
||||
return y;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SinCos
|
||||
=================
|
||||
*/
|
||||
void SinCos( float radians, float *sine, float *cosine )
|
||||
{
|
||||
#if _MSC_VER == 1200
|
||||
_asm
|
||||
{
|
||||
fld dword ptr [radians]
|
||||
fsincos
|
||||
|
||||
mov edx, dword ptr [cosine]
|
||||
mov eax, dword ptr [sine]
|
||||
|
||||
fstp dword ptr [edx]
|
||||
fstp dword ptr [eax]
|
||||
}
|
||||
#else
|
||||
// I think, better use math.h function, instead of ^
|
||||
#if defined (__linux__) && !defined (__ANDROID__)
|
||||
sincosf(radians, sine, cosine);
|
||||
#else
|
||||
*sine = sinf(radians);
|
||||
*cosine = cosf(radians);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef XASH_VECTORIZE_SINCOS
|
||||
void SinCosFastVector4(float r1, float r2, float r3, float r4,
|
||||
float *s0, float *s1, float *s2, float *s3,
|
||||
float *c0, float *c1, float *c2, float *c3)
|
||||
{
|
||||
v4sf rad_vector = {r1, r2, r3, r4};
|
||||
v4sf sin_vector, cos_vector;
|
||||
|
||||
sincos_ps(rad_vector, &sin_vector, &cos_vector);
|
||||
|
||||
*s0 = s4f_x(sin_vector);
|
||||
*s1 = s4f_y(sin_vector);
|
||||
*s2 = s4f_z(sin_vector);
|
||||
*s3 = s4f_w(sin_vector);
|
||||
|
||||
*c0 = s4f_x(cos_vector);
|
||||
*c1 = s4f_y(cos_vector);
|
||||
*c2 = s4f_z(cos_vector);
|
||||
*c3 = s4f_w(cos_vector);
|
||||
}
|
||||
|
||||
void SinCosFastVector3(float r1, float r2, float r3,
|
||||
float *s0, float *s1, float *s2,
|
||||
float *c0, float *c1, float *c2)
|
||||
{
|
||||
v4sf rad_vector = {r1, r2, r3, 0};
|
||||
v4sf sin_vector, cos_vector;
|
||||
|
||||
sincos_ps(rad_vector, &sin_vector, &cos_vector);
|
||||
|
||||
*s0 = s4f_x(sin_vector);
|
||||
*s1 = s4f_y(sin_vector);
|
||||
*s2 = s4f_z(sin_vector);
|
||||
|
||||
*c0 = s4f_x(cos_vector);
|
||||
*c1 = s4f_y(cos_vector);
|
||||
*c2 = s4f_z(cos_vector);
|
||||
}
|
||||
|
||||
void SinCosFastVector2(float r1, float r2,
|
||||
float *s0, float *s1,
|
||||
float *c0, float *c1)
|
||||
{
|
||||
v4sf rad_vector = {r1, r2, 0, 0};
|
||||
v4sf sin_vector, cos_vector;
|
||||
|
||||
sincos_ps(rad_vector, &sin_vector, &cos_vector);
|
||||
|
||||
*s0 = s4f_x(sin_vector);
|
||||
*s1 = s4f_y(sin_vector);
|
||||
|
||||
*c0 = s4f_x(cos_vector);
|
||||
*c1 = s4f_y(cos_vector);
|
||||
}
|
||||
|
||||
void SinFastVector3(float r1, float r2, float r3,
|
||||
float *s0, float *s1, float *s2)
|
||||
{
|
||||
v4sf rad_vector = {r1, r2, r3, 0};
|
||||
v4sf sin_vector;
|
||||
|
||||
sin_vector = sin_ps(rad_vector);
|
||||
|
||||
*s0 = s4f_x(sin_vector);
|
||||
*s1 = s4f_y(sin_vector);
|
||||
*s2 = s4f_z(sin_vector);
|
||||
}
|
||||
#endif
|
||||
|
||||
float VectorNormalizeLength2( const vec3_t v, vec3_t out )
|
||||
{
|
||||
float length, ilength;
|
||||
|
||||
length = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
|
||||
length = sqrt( length );
|
||||
|
||||
if( length )
|
||||
{
|
||||
ilength = 1.0f / length;
|
||||
out[0] = v[0] * ilength;
|
||||
out[1] = v[1] * ilength;
|
||||
out[2] = v[2] * ilength;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
void VectorVectors( const vec3_t forward, vec3_t right, vec3_t up )
|
||||
{
|
||||
float d;
|
||||
|
||||
right[0] = forward[2];
|
||||
right[1] = -forward[0];
|
||||
right[2] = forward[1];
|
||||
|
||||
d = DotProduct( forward, right );
|
||||
VectorMA( right, -d, forward, right );
|
||||
VectorNormalize( right );
|
||||
CrossProduct( right, forward, up );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
AngleVectors
|
||||
|
||||
=================
|
||||
|
||||
void GAME_EXPORT AngleVectors( const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up )
|
||||
{
|
||||
static float sr, sp, sy, cr, cp, cy;
|
||||
|
||||
#ifdef XASH_VECTORIZE_SINCOS
|
||||
SinCosFastVector3( DEG2RAD(angles[YAW]), DEG2RAD(angles[PITCH]), DEG2RAD(angles[ROLL]),
|
||||
&sy, &sp, &sr,
|
||||
&cy, &cp, &cr);
|
||||
#else
|
||||
SinCos( DEG2RAD( angles[YAW] ), &sy, &cy );
|
||||
SinCos( DEG2RAD( angles[PITCH] ), &sp, &cp );
|
||||
SinCos( DEG2RAD( angles[ROLL] ), &sr, &cr );
|
||||
#endif
|
||||
|
||||
if( forward )
|
||||
{
|
||||
forward[0] = cp * cy;
|
||||
forward[1] = cp * sy;
|
||||
forward[2] = -sp;
|
||||
}
|
||||
|
||||
if( right )
|
||||
{
|
||||
right[0] = (-1.0f * sr * sp * cy + -1.0f * cr * -sy );
|
||||
right[1] = (-1.0f * sr * sp * sy + -1.0f * cr * cy );
|
||||
right[2] = (-1.0f * sr * cp);
|
||||
}
|
||||
|
||||
if( up )
|
||||
{
|
||||
up[0] = (cr * sp * cy + -sr * -sy );
|
||||
up[1] = (cr * sp * sy + -sr * cy );
|
||||
up[2] = (cr * cp);
|
||||
}
|
||||
}
|
||||
|
||||
*
|
||||
=================
|
||||
VectorAngles
|
||||
|
||||
=================
|
||||
*/
|
||||
void VectorAngles( const float *forward, float *angles )
|
||||
{
|
||||
float tmp, yaw, pitch;
|
||||
|
||||
if( !forward || !angles )
|
||||
{
|
||||
if( angles ) VectorClear( angles );
|
||||
return;
|
||||
}
|
||||
|
||||
if( forward[1] == 0 && forward[0] == 0 )
|
||||
{
|
||||
// fast case
|
||||
yaw = 0;
|
||||
if( forward[2] > 0 )
|
||||
pitch = 90.0f;
|
||||
else pitch = 270.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
yaw = ( atan2( forward[1], forward[0] ) * 180 / M_PI );
|
||||
if( yaw < 0 ) yaw += 360;
|
||||
|
||||
tmp = sqrt( forward[0] * forward[0] + forward[1] * forward[1] );
|
||||
pitch = ( atan2( forward[2], tmp ) * 180 / M_PI );
|
||||
if( pitch < 0 ) pitch += 360;
|
||||
}
|
||||
|
||||
VectorSet( angles, pitch, yaw, 0 );
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
VectorsAngles
|
||||
|
||||
=================
|
||||
*/
|
||||
void VectorsAngles( const vec3_t forward, const vec3_t right, const vec3_t up, vec3_t angles )
|
||||
{
|
||||
float pitch, cpitch, yaw, roll;
|
||||
|
||||
pitch = -asin( forward[2] );
|
||||
cpitch = cos( pitch );
|
||||
|
||||
if( fabs( cpitch ) > EQUAL_EPSILON ) // gimball lock?
|
||||
{
|
||||
cpitch = 1.0f / cpitch;
|
||||
pitch = RAD2DEG( pitch );
|
||||
yaw = RAD2DEG( atan2( forward[1] * cpitch, forward[0] * cpitch ));
|
||||
roll = RAD2DEG( atan2( -right[2] * cpitch, up[2] * cpitch ));
|
||||
}
|
||||
else
|
||||
{
|
||||
pitch = forward[2] > 0 ? -90.0f : 90.0f;
|
||||
yaw = RAD2DEG( atan2( right[0], -right[1] ));
|
||||
roll = 180.0f;
|
||||
}
|
||||
|
||||
angles[PITCH] = pitch;
|
||||
angles[YAW] = yaw;
|
||||
angles[ROLL] = roll;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
InterpolateAngles
|
||||
=================
|
||||
*/
|
||||
void InterpolateAngles( vec3_t start, vec3_t end, vec3_t out, float frac )
|
||||
{
|
||||
float d, ang1, ang2;
|
||||
int i;
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
ang1 = start[i];
|
||||
ang2 = end[i];
|
||||
d = ang1 - ang2;
|
||||
|
||||
if( d > 180.0f ) d -= 360.0f;
|
||||
else if( d < -180.0f ) d += 360.0f;
|
||||
|
||||
out[i] = ang2 + d * frac;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
BoundsIntersect
|
||||
=================
|
||||
*/
|
||||
qboolean BoundsIntersect( const vec3_t mins1, const vec3_t maxs1, const vec3_t mins2, const vec3_t maxs2 )
|
||||
{
|
||||
if( mins1[0] > maxs2[0] || mins1[1] > maxs2[1] || mins1[2] > maxs2[2] )
|
||||
return false;
|
||||
if( maxs1[0] < mins2[0] || maxs1[1] < mins2[1] || maxs1[2] < mins2[2] )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
BoundsAndSphereIntersect
|
||||
=================
|
||||
*/
|
||||
qboolean BoundsAndSphereIntersect( const vec3_t mins, const vec3_t maxs, const vec3_t origin, float radius )
|
||||
{
|
||||
if( mins[0] > origin[0] + radius || mins[1] > origin[1] + radius || mins[2] > origin[2] + radius )
|
||||
return false;
|
||||
if( maxs[0] < origin[0] - radius || maxs[1] < origin[1] - radius || maxs[2] < origin[2] - radius )
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// studio utils
|
||||
//
|
||||
/*
|
||||
====================
|
||||
AngleQuaternion
|
||||
|
||||
====================
|
||||
*/
|
||||
void AngleQuaternion( const vec3_t angles, vec4_t q )
|
||||
{
|
||||
float sr, sp, sy, cr, cp, cy;
|
||||
|
||||
#ifdef XASH_VECTORIZE_SINCOS
|
||||
SinCosFastVector3( angles[2] * 0.5f, angles[1] * 0.5f, angles[0] * 0.5f,
|
||||
&sy, &sp, &sr,
|
||||
&cy, &cp, &cr);
|
||||
#else
|
||||
float angle;
|
||||
|
||||
angle = angles[2] * 0.5f;
|
||||
SinCos( angle, &sy, &cy );
|
||||
angle = angles[1] * 0.5f;
|
||||
SinCos( angle, &sp, &cp );
|
||||
angle = angles[0] * 0.5f;
|
||||
SinCos( angle, &sr, &cr );
|
||||
#endif
|
||||
|
||||
q[0] = sr * cp * cy - cr * sp * sy; // X
|
||||
q[1] = cr * sp * cy + sr * cp * sy; // Y
|
||||
q[2] = cr * cp * sy - sr * sp * cy; // Z
|
||||
q[3] = cr * cp * cy + sr * sp * sy; // W
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
QuaternionSlerp
|
||||
|
||||
====================
|
||||
*/
|
||||
void QuaternionSlerp( const vec4_t p, vec4_t q, float t, vec4_t qt )
|
||||
{
|
||||
float omega, sclp, sclq;
|
||||
float cosom, sinom;
|
||||
float a = 0.0f;
|
||||
float b = 0.0f;
|
||||
int i;
|
||||
|
||||
// decide if one of the quaternions is backwards
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
a += (p[i] - q[i]) * (p[i] - q[i]);
|
||||
b += (p[i] + q[i]) * (p[i] + q[i]);
|
||||
}
|
||||
|
||||
if( a > b )
|
||||
{
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
q[i] = -q[i];
|
||||
}
|
||||
}
|
||||
|
||||
cosom = p[0] * q[0] + p[1] * q[1] + p[2] * q[2] + p[3] * q[3];
|
||||
|
||||
if(( 1.0 + cosom ) > 0.000001f )
|
||||
{
|
||||
if(( 1.0f - cosom ) > 0.000001f )
|
||||
{
|
||||
omega = acos( cosom );
|
||||
|
||||
#ifdef XASH_VECTORIZE_SINCOS
|
||||
SinFastVector3( omega, ( 1.0f - t ) * omega, t * omega,
|
||||
&sinom, &sclp, &sclq );
|
||||
sclp /= sinom;
|
||||
sclq /= sinom;
|
||||
#else
|
||||
sinom = sin( omega );
|
||||
sclp = sin(( 1.0f - t ) * omega ) / sinom;
|
||||
sclq = sin( t * omega ) / sinom;
|
||||
#endif
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
sclp = 1.0f - t;
|
||||
sclq = t;
|
||||
}
|
||||
|
||||
for( i = 0; i < 4; i++ )
|
||||
qt[i] = sclp * p[i] + sclq * q[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
qt[0] = -q[1];
|
||||
qt[1] = q[0];
|
||||
qt[2] = -q[3];
|
||||
qt[3] = q[2];
|
||||
sclp = sin(( 1.0f - t ) * ( 0.5f * M_PI ));
|
||||
sclq = sin( t * ( 0.5f * M_PI ));
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
qt[i] = sclp * p[i] + sclq * qt[i];
|
||||
}
|
||||
}
|
211
Projects/Android/jni/RTCWVR/mathlib.h
Normal file
211
Projects/Android/jni/RTCWVR/mathlib.h
Normal file
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
mathlib.h - base math functions
|
||||
Copyright (C) 2007 Uncle Mike
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef MATHLIB_H
|
||||
#define MATHLIB_H
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "../quake2/src/common/header/common.h"
|
||||
#include "../quake2/src/client/header/keyboard.h"
|
||||
|
||||
|
||||
// euler angle order
|
||||
#define PITCH 0
|
||||
#define YAW 1
|
||||
#define ROLL 2
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI (float)3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#ifndef M_PI2
|
||||
#define M_PI2 (float)6.28318530717958647692
|
||||
#endif
|
||||
|
||||
#define M_PI_F ((float)(M_PI))
|
||||
#define M_PI2_F ((float)(M_PI2))
|
||||
|
||||
#define RAD2DEG( x ) ((float)(x) * (float)(180.f / M_PI))
|
||||
#define DEG2RAD( x ) ((float)(x) * (float)(M_PI / 180.f))
|
||||
|
||||
#define SIDE_FRONT 0
|
||||
#define SIDE_BACK 1
|
||||
#define SIDE_ON 2
|
||||
#define SIDE_CROSS -2
|
||||
|
||||
#define PLANE_X 0 // 0 - 2 are axial planes
|
||||
#define PLANE_Y 1 // 3 needs alternate calc
|
||||
#define PLANE_Z 2
|
||||
#define PLANE_NONAXIAL 3
|
||||
|
||||
#define EQUAL_EPSILON 0.001f
|
||||
#define STOP_EPSILON 0.1f
|
||||
#define ON_EPSILON 0.1f
|
||||
|
||||
#define RAD_TO_STUDIO (32768.0 / M_PI)
|
||||
#define STUDIO_TO_RAD (M_PI / 32768.0)
|
||||
#define nanmask (255<<23)
|
||||
|
||||
#define Q_rint(x) ((x) < 0 ? ((int)((x)-0.5f)) : ((int)((x)+0.5f)))
|
||||
#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask)
|
||||
|
||||
#define VectorIsNAN(v) (IS_NAN(v[0]) || IS_NAN(v[1]) || IS_NAN(v[2]))
|
||||
//#define DotProduct(x,y) ((x)[0]*(y)[0]+(x)[1]*(y)[1]+(x)[2]*(y)[2])
|
||||
#define DotProductAbs(x,y) (abs((x)[0]*(y)[0])+abs((x)[1]*(y)[1])+abs((x)[2]*(y)[2]))
|
||||
#define DotProductFabs(x,y) (fabs((x)[0]*(y)[0])+fabs((x)[1]*(y)[1])+fabs((x)[2]*(y)[2]))
|
||||
#define CrossProduct(a,b,c) ((c)[0]=(a)[1]*(b)[2]-(a)[2]*(b)[1],(c)[1]=(a)[2]*(b)[0]-(a)[0]*(b)[2],(c)[2]=(a)[0]*(b)[1]-(a)[1]*(b)[0])
|
||||
#define Vector2Subtract(a,b,c) ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1])
|
||||
//#define VectorSubtract(a,b,c) ((c)[0]=(a)[0]-(b)[0],(c)[1]=(a)[1]-(b)[1],(c)[2]=(a)[2]-(b)[2])
|
||||
#define Vector2Add(a,b,c) ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1])
|
||||
//#define VectorAdd(a,b,c) ((c)[0]=(a)[0]+(b)[0],(c)[1]=(a)[1]+(b)[1],(c)[2]=(a)[2]+(b)[2])
|
||||
#define Vector2Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1])
|
||||
//#define VectorCopy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2])
|
||||
#define Vector4Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])
|
||||
//#define VectorScale(in, scale, out) ((out)[0] = (in)[0] * (scale),(out)[1] = (in)[1] * (scale),(out)[2] = (in)[2] * (scale))
|
||||
#define VectorCompare(v1,v2) ((v1)[0]==(v2)[0] && (v1)[1]==(v2)[1] && (v1)[2]==(v2)[2])
|
||||
//#define VectorDivide( in, d, out ) VectorScale( in, (1.0f / (d)), out )
|
||||
#define VectorMax(a) ( max((a)[0], max((a)[1], (a)[2])) )
|
||||
#define VectorAvg(a) ( ((a)[0] + (a)[1] + (a)[2]) / 3 )
|
||||
#define VectorLength(a) ( sqrt( DotProduct( a, a )))
|
||||
#define VectorLength2(a) (DotProduct( a, a ))
|
||||
#define VectorDistance(a, b) (sqrt( VectorDistance2( a, b )))
|
||||
#define VectorDistance2(a, b) (((a)[0] - (b)[0]) * ((a)[0] - (b)[0]) + ((a)[1] - (b)[1]) * ((a)[1] - (b)[1]) + ((a)[2] - (b)[2]) * ((a)[2] - (b)[2]))
|
||||
#define Vector2Average(a,b,o) ((o)[0]=((a)[0]+(b)[0])*0.5,(o)[1]=((a)[1]+(b)[1])*0.5)
|
||||
#define VectorAverage(a,b,o) ((o)[0]=((a)[0]+(b)[0])*0.5,(o)[1]=((a)[1]+(b)[1])*0.5,(o)[2]=((a)[2]+(b)[2])*0.5)
|
||||
#define Vector2Set(v, x, y) ((v)[0]=(x),(v)[1]=(y))
|
||||
//#define VectorSet(v, x, y, z) ((v)[0]=(x),(v)[1]=(y),(v)[2]=(z))
|
||||
#define Vector4Set(v, a, b, c, d) ((v)[0]=(a),(v)[1]=(b),(v)[2]=(c),(v)[3] = (d))
|
||||
//#define VectorClear(x) ((x)[0]=(x)[1]=(x)[2]=0)
|
||||
#define Vector2Lerp( v1, lerp, v2, c ) ((c)[0] = (v1)[0] + (lerp) * ((v2)[0] - (v1)[0]), (c)[1] = (v1)[1] + (lerp) * ((v2)[1] - (v1)[1]))
|
||||
#define VectorLerp( v1, lerp, v2, c ) ((c)[0] = (v1)[0] + (lerp) * ((v2)[0] - (v1)[0]), (c)[1] = (v1)[1] + (lerp) * ((v2)[1] - (v1)[1]), (c)[2] = (v1)[2] + (lerp) * ((v2)[2] - (v1)[2]))
|
||||
#define VectorNormalize( v ) { float ilength = (float)sqrt(DotProduct(v, v));if (ilength) ilength = 1.0f / ilength;v[0] *= ilength;v[1] *= ilength;v[2] *= ilength; }
|
||||
#define VectorNormalize2( v, dest ) {float ilength = (float)sqrt(DotProduct(v,v));if (ilength) ilength = 1.0f / ilength;dest[0] = v[0] * ilength;dest[1] = v[1] * ilength;dest[2] = v[2] * ilength; }
|
||||
#define VectorNormalizeFast( v ) {float ilength = (float)rsqrt(DotProduct(v,v)); v[0] *= ilength; v[1] *= ilength; v[2] *= ilength; }
|
||||
#define VectorNormalizeLength( v ) VectorNormalizeLength2((v), (v))
|
||||
//#define VectorNegate(x, y) ((y)[0] = -(x)[0], (y)[1] = -(x)[1], (y)[2] = -(x)[2])
|
||||
#define VectorM(scale1, b1, c) ((c)[0] = (scale1) * (b1)[0],(c)[1] = (scale1) * (b1)[1],(c)[2] = (scale1) * (b1)[2])
|
||||
#define VectorMA(a, scale, b, c) ((c)[0] = (a)[0] + (scale) * (b)[0],(c)[1] = (a)[1] + (scale) * (b)[1],(c)[2] = (a)[2] + (scale) * (b)[2])
|
||||
#define VectorMAMAM(scale1, b1, scale2, b2, scale3, b3, c) ((c)[0] = (scale1) * (b1)[0] + (scale2) * (b2)[0] + (scale3) * (b3)[0],(c)[1] = (scale1) * (b1)[1] + (scale2) * (b2)[1] + (scale3) * (b3)[1],(c)[2] = (scale1) * (b1)[2] + (scale2) * (b2)[2] + (scale3) * (b3)[2])
|
||||
#define VectorIsNull( v ) ((v)[0] == 0.0f && (v)[1] == 0.0f && (v)[2] == 0.0f)
|
||||
#define Vector2IsNull( v ) ((v)[0] == 0.0f && (v)[1] == 0.0f)
|
||||
#define MakeRGBA( out, x, y, z, w ) Vector4Set( out, x, y, z, w )
|
||||
#define PlaneDist(point,plane) ((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal))
|
||||
#define PlaneDiff(point,plane) (((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal)) - (plane)->dist)
|
||||
#define boundmax( num, high ) ( (num) < (high) ? (num) : (high) )
|
||||
#define boundmin( num, low ) ( (num) >= (low) ? (num) : (low) )
|
||||
#define bound( low, num, high ) ( boundmin( boundmax(num, high), low ))
|
||||
//#define bound( min, num, max ) ((num) >= (min) ? ((num) < (max) ? (num) : (max)) : (min))
|
||||
|
||||
float rsqrt( float number );
|
||||
float anglemod( const float a );
|
||||
unsigned short FloatToHalf( float v );
|
||||
float HalfToFloat( unsigned short h );
|
||||
int SignbitsForPlane( const vec3_t normal );
|
||||
int NearestPOW( int value, qboolean roundDown );
|
||||
void SinCos( float radians, float *sine, float *cosine );
|
||||
#ifdef XASH_VECTORIZE_SINCOS
|
||||
void SinCosFastVector4(float r1, float r2, float r3, float r4,
|
||||
float *s0, float *s1, float *s2, float *s3,
|
||||
float *c0, float *c1, float *c2, float *c3)
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((nonnull))
|
||||
#endif
|
||||
;
|
||||
|
||||
void SinCosFastVector3( float r1, float r2, float r3,
|
||||
float *s0, float *s1, float *s2,
|
||||
float *c0, float *c1, float *c2)
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((nonnull))
|
||||
#endif
|
||||
;
|
||||
|
||||
void SinCosFastVector2( float r1, float r2,
|
||||
float *s0, float *s1,
|
||||
float *c0, float *c1)
|
||||
#if defined(__GNUC__)
|
||||
__attribute__((nonnull))
|
||||
#endif
|
||||
;
|
||||
#endif
|
||||
float VectorNormalizeLength2( const vec3_t v, vec3_t out );
|
||||
void VectorVectors( const vec3_t forward, vec3_t right, vec3_t up );
|
||||
void VectorAngles( const float *forward, float *angles );
|
||||
//void AngleVectors( const vec3_t angles, vec3_t forward, vec3_t right, vec3_t up );
|
||||
void VectorsAngles( const vec3_t forward, const vec3_t right, const vec3_t up, vec3_t angles );
|
||||
void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees );
|
||||
|
||||
void ClearBounds( vec3_t mins, vec3_t maxs );
|
||||
//void AddPointToBounds( const vec3_t v, vec3_t mins, vec3_t maxs );
|
||||
qboolean BoundsIntersect( const vec3_t mins1, const vec3_t maxs1, const vec3_t mins2, const vec3_t maxs2 );
|
||||
qboolean BoundsAndSphereIntersect( const vec3_t mins, const vec3_t maxs, const vec3_t origin, float radius );
|
||||
float RadiusFromBounds( const vec3_t mins, const vec3_t maxs );
|
||||
|
||||
void AngleQuaternion( const vec3_t angles, vec4_t q );
|
||||
void QuaternionSlerp( const vec4_t p, vec4_t q, float t, vec4_t qt );
|
||||
float RemapVal( float val, float A, float B, float C, float D );
|
||||
float ApproachVal( float target, float value, float speed );
|
||||
void InterpolateAngles( vec3_t start, vec3_t end, vec3_t output, float frac );
|
||||
|
||||
//
|
||||
// matrixlib.c
|
||||
//
|
||||
#define Matrix3x4_LoadIdentity( mat ) Matrix3x4_Copy( mat, matrix3x4_identity )
|
||||
#define Matrix3x4_Copy( out, in ) Q_memcpy( out, in, sizeof( matrix3x4 ))
|
||||
|
||||
#define cmatrix3x4 vec4_t *const
|
||||
#define cmatrix4x4 vec4_t *const
|
||||
typedef vec_t matrix3x4[3][4];
|
||||
typedef vec_t matrix4x4[4][4];
|
||||
|
||||
void Matrix3x4_VectorTransform( cmatrix3x4 in, const float v[3], float out[3] );
|
||||
void Matrix3x4_VectorITransform( cmatrix3x4 in, const float v[3], float out[3] );
|
||||
void Matrix3x4_VectorRotate( cmatrix3x4 in, const float v[3], float out[3] );
|
||||
void Matrix3x4_VectorIRotate( cmatrix3x4 in, const float v[3], float out[3] );
|
||||
void Matrix3x4_ConcatTransforms( matrix3x4 out, cmatrix3x4 in1, cmatrix3x4 in2 );
|
||||
void Matrix3x4_FromOriginQuat( matrix3x4 out, const vec4_t quaternion, const vec3_t origin );
|
||||
void Matrix3x4_CreateFromEntity( matrix3x4 out, const vec3_t angles, const vec3_t origin, float scale );
|
||||
void Matrix3x4_TransformPositivePlane( cmatrix3x4 in, const vec3_t normal, float d, vec3_t out, float *dist );
|
||||
void Matrix3x4_SetOrigin( matrix3x4 out, float x, float y, float z );
|
||||
void Matrix3x4_Invert_Simple( matrix3x4 out, cmatrix3x4 in1 );
|
||||
void Matrix3x4_OriginFromMatrix( cmatrix3x4 in, float *out );
|
||||
|
||||
#define Matrix4x4_LoadIdentity( mat ) Matrix4x4_Copy( mat, matrix4x4_identity )
|
||||
#define Matrix4x4_Copy( out, in ) Q_memcpy( out, in, sizeof( matrix4x4 ))
|
||||
|
||||
void Matrix4x4_Concat (matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2);
|
||||
void Matrix4x4_CreateTranslate (matrix4x4 out, double x, double y, double z);
|
||||
void Matrix4x4_VectorTransform( cmatrix4x4 in, const float v[3], float out[3] );
|
||||
void Matrix4x4_VectorITransform( cmatrix4x4 in, const float v[3], float out[3] );
|
||||
void Matrix4x4_VectorRotate( cmatrix4x4 in, const float v[3], float out[3] );
|
||||
void Matrix4x4_VectorIRotate( cmatrix4x4 in, const float v[3], float out[3] );
|
||||
void Matrix4x4_ConcatTransforms( matrix4x4 out, cmatrix4x4 in1, cmatrix4x4 in2 );
|
||||
void Matrix4x4_FromOriginQuat( matrix4x4 out, const vec4_t quaternion, const vec3_t origin );
|
||||
void Matrix4x4_CreateFromEntity( matrix4x4 out, const vec3_t angles, const vec3_t origin, float scale );
|
||||
void Matrix4x4_TransformPositivePlane( cmatrix4x4 in, const vec3_t normal, float d, vec3_t out, float *dist );
|
||||
void Matrix4x4_TransformStandardPlane( cmatrix4x4 in, const vec3_t normal, float d, vec3_t out, float *dist );
|
||||
void Matrix4x4_ConvertToEntity( cmatrix4x4 in, vec3_t angles, vec3_t origin );
|
||||
void Matrix4x4_SetOrigin( matrix4x4 out, float x, float y, float z );
|
||||
void Matrix4x4_Invert_Simple( matrix4x4 out, cmatrix4x4 in1 );
|
||||
void Matrix4x4_OriginFromMatrix( cmatrix4x4 in, float *out );
|
||||
void Matrix4x4_Transpose( matrix4x4 out, cmatrix4x4 in1 );
|
||||
qboolean Matrix4x4_Invert_Full( matrix4x4 out, cmatrix4x4 in1 );
|
||||
|
||||
extern vec3_t vec3_origin;
|
||||
extern const matrix3x4 matrix3x4_identity;
|
||||
extern const matrix4x4 matrix4x4_identity;
|
||||
|
||||
#endif//MATHLIB_H
|
852
Projects/Android/jni/RTCWVR/matrixlib.c
Normal file
852
Projects/Android/jni/RTCWVR/matrixlib.c
Normal file
|
@ -0,0 +1,852 @@
|
|||
/*
|
||||
matrixlib.c - internal matrixlib
|
||||
Copyright (C) 2010 Uncle Mike
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
//#include "common.h"
|
||||
#include "mathlib.h"
|
||||
|
||||
const matrix3x4 matrix3x4_identity =
|
||||
{
|
||||
{ 1, 0, 0, 0 }, // PITCH [forward], org[0]
|
||||
{ 0, 1, 0, 0 }, // YAW [right] , org[1]
|
||||
{ 0, 0, 1, 0 }, // ROLL [up] , org[2]
|
||||
};
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
Matrix3x4 operations
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
void Matrix3x4_VectorTransform( cmatrix3x4 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 Matrix3x4_VectorITransform( cmatrix3x4 in, const float v[3], float out[3] )
|
||||
{
|
||||
vec3_t dir;
|
||||
|
||||
dir[0] = v[0] - in[0][3];
|
||||
dir[1] = v[1] - in[1][3];
|
||||
dir[2] = v[2] - in[2][3];
|
||||
|
||||
out[0] = dir[0] * in[0][0] + dir[1] * in[1][0] + dir[2] * in[2][0];
|
||||
out[1] = dir[0] * in[0][1] + dir[1] * in[1][1] + dir[2] * in[2][1];
|
||||
out[2] = dir[0] * in[0][2] + dir[1] * in[1][2] + dir[2] * in[2][2];
|
||||
}
|
||||
|
||||
void Matrix3x4_VectorRotate( cmatrix3x4 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];
|
||||
out[1] = v[0] * in[1][0] + v[1] * in[1][1] + v[2] * in[1][2];
|
||||
out[2] = v[0] * in[2][0] + v[1] * in[2][1] + v[2] * in[2][2];
|
||||
}
|
||||
|
||||
void Matrix3x4_VectorIRotate( cmatrix3x4 in, const float v[3], float out[3] )
|
||||
{
|
||||
out[0] = v[0] * in[0][0] + v[1] * in[1][0] + v[2] * in[2][0];
|
||||
out[1] = v[0] * in[0][1] + v[1] * in[1][1] + v[2] * in[2][1];
|
||||
out[2] = v[0] * in[0][2] + v[1] * in[1][2] + v[2] * in[2][2];
|
||||
}
|
||||
|
||||
void Matrix3x4_ConcatTransforms( matrix3x4 out, cmatrix3x4 in1, cmatrix3x4 in2 )
|
||||
{
|
||||
out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + in1[0][2] * in2[2][0];
|
||||
out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + in1[0][2] * in2[2][1];
|
||||
out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + in1[0][2] * in2[2][2];
|
||||
out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + in1[0][2] * in2[2][3] + in1[0][3];
|
||||
out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + in1[1][2] * in2[2][0];
|
||||
out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + in1[1][2] * in2[2][1];
|
||||
out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + in1[1][2] * in2[2][2];
|
||||
out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + in1[1][2] * in2[2][3] + in1[1][3];
|
||||
out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + in1[2][2] * in2[2][0];
|
||||
out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + in1[2][2] * in2[2][1];
|
||||
out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2];
|
||||
out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + in1[2][2] * in2[2][3] + in1[2][3];
|
||||
}
|
||||
|
||||
void Matrix3x4_SetOrigin( matrix3x4 out, float x, float y, float z )
|
||||
{
|
||||
out[0][3] = x;
|
||||
out[1][3] = y;
|
||||
out[2][3] = z;
|
||||
}
|
||||
|
||||
void Matrix3x4_OriginFromMatrix( cmatrix3x4 in, float *out )
|
||||
{
|
||||
out[0] = in[0][3];
|
||||
out[1] = in[1][3];
|
||||
out[2] = in[2][3];
|
||||
}
|
||||
|
||||
void Matrix3x4_FromOriginQuat( matrix3x4 out, const vec4_t quaternion, const vec3_t origin )
|
||||
{
|
||||
out[0][0] = 1.0f - 2.0f * quaternion[1] * quaternion[1] - 2.0f * quaternion[2] * quaternion[2];
|
||||
out[1][0] = 2.0f * quaternion[0] * quaternion[1] + 2.0f * quaternion[3] * quaternion[2];
|
||||
out[2][0] = 2.0f * quaternion[0] * quaternion[2] - 2.0f * quaternion[3] * quaternion[1];
|
||||
|
||||
out[0][1] = 2.0f * quaternion[0] * quaternion[1] - 2.0f * quaternion[3] * quaternion[2];
|
||||
out[1][1] = 1.0f - 2.0f * quaternion[0] * quaternion[0] - 2.0f * quaternion[2] * quaternion[2];
|
||||
out[2][1] = 2.0f * quaternion[1] * quaternion[2] + 2.0f * quaternion[3] * quaternion[0];
|
||||
|
||||
out[0][2] = 2.0f * quaternion[0] * quaternion[2] + 2.0f * quaternion[3] * quaternion[1];
|
||||
out[1][2] = 2.0f * quaternion[1] * quaternion[2] - 2.0f * quaternion[3] * quaternion[0];
|
||||
out[2][2] = 1.0f - 2.0f * quaternion[0] * quaternion[0] - 2.0f * quaternion[1] * quaternion[1];
|
||||
|
||||
out[0][3] = origin[0];
|
||||
out[1][3] = origin[1];
|
||||
out[2][3] = origin[2];
|
||||
}
|
||||
|
||||
void Matrix3x4_CreateFromEntity( matrix3x4 out, const vec3_t angles, const vec3_t origin, float scale )
|
||||
{
|
||||
float angle, sr, sp, sy, cr, cp, cy;
|
||||
|
||||
if( angles[ROLL] )
|
||||
{
|
||||
#ifdef XASH_VECTORIZE_SINCOS
|
||||
SinCosFastVector3( DEG2RAD(angles[YAW]), DEG2RAD(angles[PITCH]), DEG2RAD(angles[ROLL]),
|
||||
&sy, &sp, &sr,
|
||||
&cy, &cp, &cr);
|
||||
#else
|
||||
angle = angles[YAW] * (M_PI2 / 360.0f);
|
||||
SinCos( angle, &sy, &cy );
|
||||
angle = angles[PITCH] * (M_PI2 / 360.0f);
|
||||
SinCos( angle, &sp, &cp );
|
||||
angle = angles[ROLL] * (M_PI2 / 360.0f);
|
||||
SinCos( angle, &sr, &cr );
|
||||
#endif
|
||||
|
||||
out[0][0] = (cp*cy) * scale;
|
||||
out[0][1] = (sr*sp*cy+cr*-sy) * scale;
|
||||
out[0][2] = (cr*sp*cy+-sr*-sy) * scale;
|
||||
out[0][3] = origin[0];
|
||||
out[1][0] = (cp*sy) * scale;
|
||||
out[1][1] = (sr*sp*sy+cr*cy) * scale;
|
||||
out[1][2] = (cr*sp*sy+-sr*cy) * scale;
|
||||
out[1][3] = origin[1];
|
||||
out[2][0] = (-sp) * scale;
|
||||
out[2][1] = (sr*cp) * scale;
|
||||
out[2][2] = (cr*cp) * scale;
|
||||
out[2][3] = origin[2];
|
||||
}
|
||||
else if( angles[PITCH] )
|
||||
{
|
||||
#ifdef XASH_VECTORIZE_SINCOS
|
||||
SinCosFastVector2( DEG2RAD(angles[YAW]), DEG2RAD(angles[PITCH]),
|
||||
&sy, &sp,
|
||||
&cy, &cp);
|
||||
#else
|
||||
angle = angles[YAW] * (M_PI2 / 360.0f);
|
||||
SinCos( angle, &sy, &cy );
|
||||
angle = angles[PITCH] * (M_PI2 / 360.0f);
|
||||
SinCos( angle, &sp, &cp );
|
||||
#endif
|
||||
|
||||
out[0][0] = (cp*cy) * scale;
|
||||
out[0][1] = (-sy) * scale;
|
||||
out[0][2] = (sp*cy) * scale;
|
||||
out[0][3] = origin[0];
|
||||
out[1][0] = (cp*sy) * scale;
|
||||
out[1][1] = (cy) * scale;
|
||||
out[1][2] = (sp*sy) * scale;
|
||||
out[1][3] = origin[1];
|
||||
out[2][0] = (-sp) * scale;
|
||||
out[2][1] = 0.0f;
|
||||
out[2][2] = (cp) * scale;
|
||||
out[2][3] = origin[2];
|
||||
}
|
||||
else if( angles[YAW] )
|
||||
{
|
||||
angle = angles[YAW] * (M_PI2 / 360.0f);
|
||||
SinCos( angle, &sy, &cy );
|
||||
|
||||
out[0][0] = (cy) * scale;
|
||||
out[0][1] = (-sy) * scale;
|
||||
out[0][2] = 0.0f;
|
||||
out[0][3] = origin[0];
|
||||
out[1][0] = (sy) * scale;
|
||||
out[1][1] = (cy) * scale;
|
||||
out[1][2] = 0.0f;
|
||||
out[1][3] = origin[1];
|
||||
out[2][0] = 0.0f;
|
||||
out[2][1] = 0.0f;
|
||||
out[2][2] = scale;
|
||||
out[2][3] = origin[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
out[0][0] = scale;
|
||||
out[0][1] = 0.0f;
|
||||
out[0][2] = 0.0f;
|
||||
out[0][3] = origin[0];
|
||||
out[1][0] = 0.0f;
|
||||
out[1][1] = scale;
|
||||
out[1][2] = 0.0f;
|
||||
out[1][3] = origin[1];
|
||||
out[2][0] = 0.0f;
|
||||
out[2][1] = 0.0f;
|
||||
out[2][2] = scale;
|
||||
out[2][3] = origin[2];
|
||||
}
|
||||
}
|
||||
|
||||
void Matrix3x4_TransformPositivePlane( cmatrix3x4 in, const vec3_t normal, float d, vec3_t out, float *dist )
|
||||
{
|
||||
float scale = sqrt( in[0][0] * in[0][0] + in[0][1] * in[0][1] + in[0][2] * in[0][2] );
|
||||
float iscale = 1.0f / scale;
|
||||
|
||||
out[0] = (normal[0] * in[0][0] + normal[1] * in[0][1] + normal[2] * in[0][2]) * iscale;
|
||||
out[1] = (normal[0] * in[1][0] + normal[1] * in[1][1] + normal[2] * in[1][2]) * iscale;
|
||||
out[2] = (normal[0] * in[2][0] + normal[1] * in[2][1] + normal[2] * in[2][2]) * iscale;
|
||||
*dist = d * scale + ( out[0] * in[0][3] + out[1] * in[1][3] + out[2] * in[2][3] );
|
||||
}
|
||||
|
||||
void Matrix3x4_Invert_Simple( matrix3x4 out, cmatrix3x4 in1 )
|
||||
{
|
||||
// we only support uniform scaling, so assume the first row is enough
|
||||
// (note the lack of sqrt here, because we're trying to undo the scaling,
|
||||
// this means multiplying by the inverse scale twice - squaring it, which
|
||||
// makes the sqrt a waste of time)
|
||||
float scale = 1.0f / (in1[0][0] * in1[0][0] + in1[0][1] * in1[0][1] + in1[0][2] * in1[0][2]);
|
||||
|
||||
// invert the rotation by transposing and multiplying by the squared
|
||||
// recipricol of the input matrix scale as described above
|
||||
out[0][0] = in1[0][0] * scale;
|
||||
out[0][1] = in1[1][0] * scale;
|
||||
out[0][2] = in1[2][0] * scale;
|
||||
out[1][0] = in1[0][1] * scale;
|
||||
out[1][1] = in1[1][1] * scale;
|
||||
out[1][2] = in1[2][1] * scale;
|
||||
out[2][0] = in1[0][2] * scale;
|
||||
out[2][1] = in1[1][2] * scale;
|
||||
out[2][2] = in1[2][2] * scale;
|
||||
|
||||
// invert the translate
|
||||
out[0][3] = -(in1[0][3] * out[0][0] + in1[1][3] * out[0][1] + in1[2][3] * out[0][2]);
|
||||
out[1][3] = -(in1[0][3] * out[1][0] + in1[1][3] * out[1][1] + in1[2][3] * out[1][2]);
|
||||
out[2][3] = -(in1[0][3] * out[2][0] + in1[1][3] * out[2][1] + in1[2][3] * out[2][2]);
|
||||
}
|
||||
|
||||
const matrix4x4 matrix4x4_identity =
|
||||
{
|
||||
{ 1, 0, 0, 0 }, // PITCH
|
||||
{ 0, 1, 0, 0 }, // YAW
|
||||
{ 0, 0, 1, 0 }, // ROLL
|
||||
{ 0, 0, 0, 1 }, // ORIGIN
|
||||
};
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
Matrix4x4 operations
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
void Matrix4x4_VectorTransform( cmatrix4x4 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_VectorITransform( cmatrix4x4 in, const float v[3], float out[3] )
|
||||
{
|
||||
vec3_t dir;
|
||||
|
||||
dir[0] = v[0] - in[0][3];
|
||||
dir[1] = v[1] - in[1][3];
|
||||
dir[2] = v[2] - in[2][3];
|
||||
|
||||
out[0] = dir[0] * in[0][0] + dir[1] * in[1][0] + dir[2] * in[2][0];
|
||||
out[1] = dir[0] * in[0][1] + dir[1] * in[1][1] + dir[2] * in[2][1];
|
||||
out[2] = dir[0] * in[0][2] + dir[1] * in[1][2] + dir[2] * in[2][2];
|
||||
}
|
||||
|
||||
void Matrix4x4_VectorRotate( cmatrix4x4 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];
|
||||
out[1] = v[0] * in[1][0] + v[1] * in[1][1] + v[2] * in[1][2];
|
||||
out[2] = v[0] * in[2][0] + v[1] * in[2][1] + v[2] * in[2][2];
|
||||
}
|
||||
|
||||
void Matrix4x4_VectorIRotate( cmatrix4x4 in, const float v[3], float out[3] )
|
||||
{
|
||||
out[0] = v[0] * in[0][0] + v[1] * in[1][0] + v[2] * in[2][0];
|
||||
out[1] = v[0] * in[0][1] + v[1] * in[1][1] + v[2] * in[2][1];
|
||||
out[2] = v[0] * in[0][2] + v[1] * in[1][2] + v[2] * in[2][2];
|
||||
}
|
||||
|
||||
void Matrix4x4_ConcatTransforms( matrix4x4 out, cmatrix4x4 in1, cmatrix4x4 in2 )
|
||||
{
|
||||
out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + in1[0][2] * in2[2][0];
|
||||
out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + in1[0][2] * in2[2][1];
|
||||
out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + in1[0][2] * in2[2][2];
|
||||
out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + in1[0][2] * in2[2][3] + in1[0][3];
|
||||
out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + in1[1][2] * in2[2][0];
|
||||
out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + in1[1][2] * in2[2][1];
|
||||
out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + in1[1][2] * in2[2][2];
|
||||
out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + in1[1][2] * in2[2][3] + in1[1][3];
|
||||
out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + in1[2][2] * in2[2][0];
|
||||
out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + in1[2][2] * in2[2][1];
|
||||
out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2];
|
||||
out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + in1[2][2] * in2[2][3] + in1[2][3];
|
||||
}
|
||||
|
||||
void Matrix4x4_SetOrigin( matrix4x4 out, float x, float y, float z )
|
||||
{
|
||||
out[0][3] = x;
|
||||
out[1][3] = y;
|
||||
out[2][3] = z;
|
||||
}
|
||||
|
||||
void Matrix4x4_OriginFromMatrix( cmatrix4x4 in, float *out )
|
||||
{
|
||||
out[0] = in[0][3];
|
||||
out[1] = in[1][3];
|
||||
out[2] = in[2][3];
|
||||
}
|
||||
|
||||
void Matrix4x4_FromOriginQuat( matrix4x4 out, const vec4_t quaternion, const vec3_t origin )
|
||||
{
|
||||
out[0][0] = 1.0f - 2.0f * quaternion[1] * quaternion[1] - 2.0f * quaternion[2] * quaternion[2];
|
||||
out[1][0] = 2.0f * quaternion[0] * quaternion[1] + 2.0f * quaternion[3] * quaternion[2];
|
||||
out[2][0] = 2.0f * quaternion[0] * quaternion[2] - 2.0f * quaternion[3] * quaternion[1];
|
||||
out[0][3] = origin[0];
|
||||
out[0][1] = 2.0f * quaternion[0] * quaternion[1] - 2.0f * quaternion[3] * quaternion[2];
|
||||
out[1][1] = 1.0f - 2.0f * quaternion[0] * quaternion[0] - 2.0f * quaternion[2] * quaternion[2];
|
||||
out[2][1] = 2.0f * quaternion[1] * quaternion[2] + 2.0f * quaternion[3] * quaternion[0];
|
||||
out[1][3] = origin[1];
|
||||
out[0][2] = 2.0f * quaternion[0] * quaternion[2] + 2.0f * quaternion[3] * quaternion[1];
|
||||
out[1][2] = 2.0f * quaternion[1] * quaternion[2] - 2.0f * quaternion[3] * quaternion[0];
|
||||
out[2][2] = 1.0f - 2.0f * quaternion[0] * quaternion[0] - 2.0f * quaternion[1] * quaternion[1];
|
||||
out[2][3] = origin[2];
|
||||
out[3][0] = 0.0f;
|
||||
out[3][1] = 0.0f;
|
||||
out[3][2] = 0.0f;
|
||||
out[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
void Matrix4x4_CreateTranslate (matrix4x4 out, double x, double y, double z)
|
||||
{
|
||||
out[0][0]=1.0f;
|
||||
out[0][1]=0.0f;
|
||||
out[0][2]=0.0f;
|
||||
out[0][3]=x;
|
||||
out[1][0]=0.0f;
|
||||
out[1][1]=1.0f;
|
||||
out[1][2]=0.0f;
|
||||
out[1][3]=y;
|
||||
out[2][0]=0.0f;
|
||||
out[2][1]=0.0f;
|
||||
out[2][2]=1.0f;
|
||||
out[2][3]=z;
|
||||
out[3][0]=0.0f;
|
||||
out[3][1]=0.0f;
|
||||
out[3][2]=0.0f;
|
||||
out[3][3]=1.0f;
|
||||
}
|
||||
|
||||
void Matrix4x4_Concat (matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2)
|
||||
{
|
||||
out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + in1[0][2] * in2[2][0] + in1[0][3] * in2[3][0];
|
||||
out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + in1[0][2] * in2[2][1] + in1[0][3] * in2[3][1];
|
||||
out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + in1[0][2] * in2[2][2] + in1[0][3] * in2[3][2];
|
||||
out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + in1[0][2] * in2[2][3] + in1[0][3] * in2[3][3];
|
||||
out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + in1[1][2] * in2[2][0] + in1[1][3] * in2[3][0];
|
||||
out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + in1[1][2] * in2[2][1] + in1[1][3] * in2[3][1];
|
||||
out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + in1[1][2] * in2[2][2] + in1[1][3] * in2[3][2];
|
||||
out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + in1[1][2] * in2[2][3] + in1[1][3] * in2[3][3];
|
||||
out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + in1[2][2] * in2[2][0] + in1[2][3] * in2[3][0];
|
||||
out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + in1[2][2] * in2[2][1] + in1[2][3] * in2[3][1];
|
||||
out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2] + in1[2][3] * in2[3][2];
|
||||
out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + in1[2][2] * in2[2][3] + in1[2][3] * in2[3][3];
|
||||
out[3][0] = in1[3][0] * in2[0][0] + in1[3][1] * in2[1][0] + in1[3][2] * in2[2][0] + in1[3][3] * in2[3][0];
|
||||
out[3][1] = in1[3][0] * in2[0][1] + in1[3][1] * in2[1][1] + in1[3][2] * in2[2][1] + in1[3][3] * in2[3][1];
|
||||
out[3][2] = in1[3][0] * in2[0][2] + in1[3][1] * in2[1][2] + in1[3][2] * in2[2][2] + in1[3][3] * in2[3][2];
|
||||
out[3][3] = in1[3][0] * in2[0][3] + in1[3][1] * in2[1][3] + in1[3][2] * in2[2][3] + in1[3][3] * in2[3][3];
|
||||
}
|
||||
|
||||
void Matrix4x4_CreateFromEntity( matrix4x4 out, const vec3_t angles, const vec3_t origin, float scale )
|
||||
{
|
||||
float angle, sr, sp, sy, cr, cp, cy;
|
||||
|
||||
if( angles[ROLL] )
|
||||
{
|
||||
#ifdef XASH_VECTORIZE_SINCOS
|
||||
SinCosFastVector3( DEG2RAD(angles[YAW]), DEG2RAD(angles[PITCH]), DEG2RAD(angles[ROLL]),
|
||||
&sy, &sp, &sr,
|
||||
&cy, &cp, &cr);
|
||||
#else
|
||||
angle = angles[YAW] * (M_PI2 / 360.0f);
|
||||
SinCos( angle, &sy, &cy );
|
||||
angle = angles[PITCH] * (M_PI2 / 360.0f);
|
||||
SinCos( angle, &sp, &cp );
|
||||
angle = angles[ROLL] * (M_PI2 / 360.0f);
|
||||
SinCos( angle, &sr, &cr );
|
||||
#endif
|
||||
|
||||
out[0][0] = (cp*cy) * scale;
|
||||
out[0][1] = (sr*sp*cy+cr*-sy) * scale;
|
||||
out[0][2] = (cr*sp*cy+-sr*-sy) * scale;
|
||||
out[0][3] = origin[0];
|
||||
out[1][0] = (cp*sy) * scale;
|
||||
out[1][1] = (sr*sp*sy+cr*cy) * scale;
|
||||
out[1][2] = (cr*sp*sy+-sr*cy) * scale;
|
||||
out[1][3] = origin[1];
|
||||
out[2][0] = (-sp) * scale;
|
||||
out[2][1] = (sr*cp) * scale;
|
||||
out[2][2] = (cr*cp) * scale;
|
||||
out[2][3] = origin[2];
|
||||
out[3][0] = 0.0f;
|
||||
out[3][1] = 0.0f;
|
||||
out[3][2] = 0.0f;
|
||||
out[3][3] = 1.0f;
|
||||
}
|
||||
else if( angles[PITCH] )
|
||||
{
|
||||
#ifdef XASH_VECTORIZE_SINCOS
|
||||
SinCosFastVector2( DEG2RAD(angles[YAW]), DEG2RAD(angles[PITCH]),
|
||||
&sy, &sp,
|
||||
&cy, &cp);
|
||||
#else
|
||||
angle = angles[YAW] * (M_PI2 / 360.0f);
|
||||
SinCos( angle, &sy, &cy );
|
||||
angle = angles[PITCH] * (M_PI2 / 360.0f);
|
||||
SinCos( angle, &sp, &cp );
|
||||
#endif
|
||||
|
||||
out[0][0] = (cp*cy) * scale;
|
||||
out[0][1] = (-sy) * scale;
|
||||
out[0][2] = (sp*cy) * scale;
|
||||
out[0][3] = origin[0];
|
||||
out[1][0] = (cp*sy) * scale;
|
||||
out[1][1] = (cy) * scale;
|
||||
out[1][2] = (sp*sy) * scale;
|
||||
out[1][3] = origin[1];
|
||||
out[2][0] = (-sp) * scale;
|
||||
out[2][1] = 0.0f;
|
||||
out[2][2] = (cp) * scale;
|
||||
out[2][3] = origin[2];
|
||||
out[3][0] = 0.0f;
|
||||
out[3][1] = 0.0f;
|
||||
out[3][2] = 0.0f;
|
||||
out[3][3] = 1.0f;
|
||||
}
|
||||
else if( angles[YAW] )
|
||||
{
|
||||
angle = angles[YAW] * (M_PI2 / 360.0f);
|
||||
SinCos( angle, &sy, &cy );
|
||||
|
||||
out[0][0] = (cy) * scale;
|
||||
out[0][1] = (-sy) * scale;
|
||||
out[0][2] = 0.0f;
|
||||
out[0][3] = origin[0];
|
||||
out[1][0] = (sy) * scale;
|
||||
out[1][1] = (cy) * scale;
|
||||
out[1][2] = 0.0f;
|
||||
out[1][3] = origin[1];
|
||||
out[2][0] = 0.0f;
|
||||
out[2][1] = 0.0f;
|
||||
out[2][2] = scale;
|
||||
out[2][3] = origin[2];
|
||||
out[3][0] = 0.0f;
|
||||
out[3][1] = 0.0f;
|
||||
out[3][2] = 0.0f;
|
||||
out[3][3] = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
out[0][0] = scale;
|
||||
out[0][1] = 0.0f;
|
||||
out[0][2] = 0.0f;
|
||||
out[0][3] = origin[0];
|
||||
out[1][0] = 0.0f;
|
||||
out[1][1] = scale;
|
||||
out[1][2] = 0.0f;
|
||||
out[1][3] = origin[1];
|
||||
out[2][0] = 0.0f;
|
||||
out[2][1] = 0.0f;
|
||||
out[2][2] = scale;
|
||||
out[2][3] = origin[2];
|
||||
out[3][0] = 0.0f;
|
||||
out[3][1] = 0.0f;
|
||||
out[3][2] = 0.0f;
|
||||
out[3][3] = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
void Matrix4x4_ConvertToEntity( cmatrix4x4 in, vec3_t angles, vec3_t origin )
|
||||
{
|
||||
float xyDist = sqrt( in[0][0] * in[0][0] + in[1][0] * in[1][0] );
|
||||
|
||||
// enough here to get angles?
|
||||
if( xyDist > 0.001f )
|
||||
{
|
||||
angles[0] = RAD2DEG( atan2( -in[2][0], xyDist ));
|
||||
angles[1] = RAD2DEG( atan2( in[1][0], in[0][0] ));
|
||||
angles[2] = RAD2DEG( atan2( in[2][1], in[2][2] ));
|
||||
}
|
||||
else // forward is mostly Z, gimbal lock
|
||||
{
|
||||
angles[0] = RAD2DEG( atan2( -in[2][0], xyDist ));
|
||||
angles[1] = RAD2DEG( atan2( -in[0][1], in[1][1] ));
|
||||
angles[2] = 0.0f;
|
||||
}
|
||||
|
||||
origin[0] = in[0][3];
|
||||
origin[1] = in[1][3];
|
||||
origin[2] = in[2][3];
|
||||
}
|
||||
|
||||
void Matrix4x4_TransformPositivePlane( cmatrix4x4 in, const vec3_t normal, float d, vec3_t out, float *dist )
|
||||
{
|
||||
float scale = sqrt( in[0][0] * in[0][0] + in[0][1] * in[0][1] + in[0][2] * in[0][2] );
|
||||
float iscale = 1.0f / scale;
|
||||
|
||||
out[0] = (normal[0] * in[0][0] + normal[1] * in[0][1] + normal[2] * in[0][2]) * iscale;
|
||||
out[1] = (normal[0] * in[1][0] + normal[1] * in[1][1] + normal[2] * in[1][2]) * iscale;
|
||||
out[2] = (normal[0] * in[2][0] + normal[1] * in[2][1] + normal[2] * in[2][2]) * iscale;
|
||||
*dist = d * scale + ( out[0] * in[0][3] + out[1] * in[1][3] + out[2] * in[2][3] );
|
||||
}
|
||||
|
||||
void Matrix4x4_TransformStandardPlane( cmatrix4x4 in, const vec3_t normal, float d, vec3_t out, float *dist )
|
||||
{
|
||||
float scale = sqrt( in[0][0] * in[0][0] + in[0][1] * in[0][1] + in[0][2] * in[0][2] );
|
||||
float iscale = 1.0f / scale;
|
||||
|
||||
out[0] = (normal[0] * in[0][0] + normal[1] * in[0][1] + normal[2] * in[0][2]) * iscale;
|
||||
out[1] = (normal[0] * in[1][0] + normal[1] * in[1][1] + normal[2] * in[1][2]) * iscale;
|
||||
out[2] = (normal[0] * in[2][0] + normal[1] * in[2][1] + normal[2] * in[2][2]) * iscale;
|
||||
*dist = d * scale - ( out[0] * in[0][3] + out[1] * in[1][3] + out[2] * in[2][3] );
|
||||
}
|
||||
|
||||
void Matrix4x4_Invert_Simple( matrix4x4 out, cmatrix4x4 in1 )
|
||||
{
|
||||
// we only support uniform scaling, so assume the first row is enough
|
||||
// (note the lack of sqrt here, because we're trying to undo the scaling,
|
||||
// this means multiplying by the inverse scale twice - squaring it, which
|
||||
// makes the sqrt a waste of time)
|
||||
float scale = 1.0f / (in1[0][0] * in1[0][0] + in1[0][1] * in1[0][1] + in1[0][2] * in1[0][2]);
|
||||
|
||||
// invert the rotation by transposing and multiplying by the squared
|
||||
// recipricol of the input matrix scale as described above
|
||||
out[0][0] = in1[0][0] * scale;
|
||||
out[0][1] = in1[1][0] * scale;
|
||||
out[0][2] = in1[2][0] * scale;
|
||||
out[1][0] = in1[0][1] * scale;
|
||||
out[1][1] = in1[1][1] * scale;
|
||||
out[1][2] = in1[2][1] * scale;
|
||||
out[2][0] = in1[0][2] * scale;
|
||||
out[2][1] = in1[1][2] * scale;
|
||||
out[2][2] = in1[2][2] * scale;
|
||||
|
||||
// invert the translate
|
||||
out[0][3] = -(in1[0][3] * out[0][0] + in1[1][3] * out[0][1] + in1[2][3] * out[0][2]);
|
||||
out[1][3] = -(in1[0][3] * out[1][0] + in1[1][3] * out[1][1] + in1[2][3] * out[1][2]);
|
||||
out[2][3] = -(in1[0][3] * out[2][0] + in1[1][3] * out[2][1] + in1[2][3] * out[2][2]);
|
||||
|
||||
// don't know if there's anything worth doing here
|
||||
out[3][0] = 0.0f;
|
||||
out[3][1] = 0.0f;
|
||||
out[3][2] = 0.0f;
|
||||
out[3][3] = 1.0f;
|
||||
}
|
||||
|
||||
void Matrix4x4_Transpose( matrix4x4 out, cmatrix4x4 in1 )
|
||||
{
|
||||
out[0][0] = in1[0][0];
|
||||
out[0][1] = in1[1][0];
|
||||
out[0][2] = in1[2][0];
|
||||
out[0][3] = in1[3][0];
|
||||
out[1][0] = in1[0][1];
|
||||
out[1][1] = in1[1][1];
|
||||
out[1][2] = in1[2][1];
|
||||
out[1][3] = in1[3][1];
|
||||
out[2][0] = in1[0][2];
|
||||
out[2][1] = in1[1][2];
|
||||
out[2][2] = in1[2][2];
|
||||
out[2][3] = in1[3][2];
|
||||
out[3][0] = in1[0][3];
|
||||
out[3][1] = in1[1][3];
|
||||
out[3][2] = in1[2][3];
|
||||
out[3][3] = in1[3][3];
|
||||
}
|
||||
|
||||
qboolean Matrix4x4_Invert_Full( matrix4x4 out, cmatrix4x4 in1 )
|
||||
{
|
||||
float *temp;
|
||||
float *r[4];
|
||||
float rtemp[4][8];
|
||||
float m[4];
|
||||
float s;
|
||||
|
||||
r[0] = rtemp[0];
|
||||
r[1] = rtemp[1];
|
||||
r[2] = rtemp[2];
|
||||
r[3] = rtemp[3];
|
||||
|
||||
r[0][0] = in1[0][0];
|
||||
r[0][1] = in1[0][1];
|
||||
r[0][2] = in1[0][2];
|
||||
r[0][3] = in1[0][3];
|
||||
r[0][4] = 1.0f;
|
||||
r[0][5] = 0.0f;
|
||||
r[0][6] = 0.0f;
|
||||
r[0][7] = 0.0f;
|
||||
|
||||
r[1][0] = in1[1][0];
|
||||
r[1][1] = in1[1][1];
|
||||
r[1][2] = in1[1][2];
|
||||
r[1][3] = in1[1][3];
|
||||
r[1][5] = 1.0f;
|
||||
r[1][4] = 0.0f;
|
||||
r[1][6] = 0.0f;
|
||||
r[1][7] = 0.0f;
|
||||
|
||||
r[2][0] = in1[2][0];
|
||||
r[2][1] = in1[2][1];
|
||||
r[2][2] = in1[2][2];
|
||||
r[2][3] = in1[2][3];
|
||||
r[2][6] = 1.0f;
|
||||
r[2][4] = 0.0f;
|
||||
r[2][5] = 0.0f;
|
||||
r[2][7] = 0.0f;
|
||||
|
||||
r[3][0] = in1[3][0];
|
||||
r[3][1] = in1[3][1];
|
||||
r[3][2] = in1[3][2];
|
||||
r[3][3] = in1[3][3];
|
||||
r[3][4] = 0.0f;
|
||||
r[3][5] = 0.0f;
|
||||
r[3][6] = 0.0f;
|
||||
r[3][7] = 1.0f;
|
||||
|
||||
if( fabs( r[3][0] ) > fabs( r[2][0] ))
|
||||
{
|
||||
temp = r[3];
|
||||
r[3] = r[2];
|
||||
r[2] = temp;
|
||||
}
|
||||
|
||||
if( fabs( r[2][0] ) > fabs( r[1][0] ))
|
||||
{
|
||||
temp = r[2];
|
||||
r[2] = r[1];
|
||||
r[1] = temp;
|
||||
}
|
||||
|
||||
if( fabs( r[1][0] ) > fabs( r[0][0] ))
|
||||
{
|
||||
temp = r[1];
|
||||
r[1] = r[0];
|
||||
r[0] = temp;
|
||||
}
|
||||
|
||||
if( r[0][0] )
|
||||
{
|
||||
m[1] = r[1][0] / r[0][0];
|
||||
m[2] = r[2][0] / r[0][0];
|
||||
m[3] = r[3][0] / r[0][0];
|
||||
|
||||
s = r[0][1];
|
||||
r[1][1] -= m[1] * s;
|
||||
r[2][1] -= m[2] * s;
|
||||
r[3][1] -= m[3] * s;
|
||||
|
||||
s = r[0][2];
|
||||
r[1][2] -= m[1] * s;
|
||||
r[2][2] -= m[2] * s;
|
||||
r[3][2] -= m[3] * s;
|
||||
|
||||
s = r[0][3];
|
||||
r[1][3] -= m[1] * s;
|
||||
r[2][3] -= m[2] * s;
|
||||
r[3][3] -= m[3] * s;
|
||||
|
||||
s = r[0][4];
|
||||
if( s )
|
||||
{
|
||||
r[1][4] -= m[1] * s;
|
||||
r[2][4] -= m[2] * s;
|
||||
r[3][4] -= m[3] * s;
|
||||
}
|
||||
|
||||
s = r[0][5];
|
||||
if( s )
|
||||
{
|
||||
r[1][5] -= m[1] * s;
|
||||
r[2][5] -= m[2] * s;
|
||||
r[3][5] -= m[3] * s;
|
||||
}
|
||||
|
||||
s = r[0][6];
|
||||
if( s )
|
||||
{
|
||||
r[1][6] -= m[1] * s;
|
||||
r[2][6] -= m[2] * s;
|
||||
r[3][6] -= m[3] * s;
|
||||
}
|
||||
|
||||
s = r[0][7];
|
||||
if( s )
|
||||
{
|
||||
r[1][7] -= m[1] * s;
|
||||
r[2][7] -= m[2] * s;
|
||||
r[3][7] -= m[3] * s;
|
||||
}
|
||||
|
||||
if( fabs( r[3][1] ) > fabs( r[2][1] ))
|
||||
{
|
||||
temp = r[3];
|
||||
r[3] = r[2];
|
||||
r[2] = temp;
|
||||
}
|
||||
|
||||
if( fabs( r[2][1] ) > fabs( r[1][1] ))
|
||||
{
|
||||
temp = r[2];
|
||||
r[2] = r[1];
|
||||
r[1] = temp;
|
||||
}
|
||||
|
||||
if( r[1][1] )
|
||||
{
|
||||
m[2] = r[2][1] / r[1][1];
|
||||
m[3] = r[3][1] / r[1][1];
|
||||
r[2][2] -= m[2] * r[1][2];
|
||||
r[3][2] -= m[3] * r[1][2];
|
||||
r[2][3] -= m[2] * r[1][3];
|
||||
r[3][3] -= m[3] * r[1][3];
|
||||
|
||||
s = r[1][4];
|
||||
if( s )
|
||||
{
|
||||
r[2][4] -= m[2] * s;
|
||||
r[3][4] -= m[3] * s;
|
||||
}
|
||||
|
||||
s = r[1][5];
|
||||
if( s )
|
||||
{
|
||||
r[2][5] -= m[2] * s;
|
||||
r[3][5] -= m[3] * s;
|
||||
}
|
||||
|
||||
s = r[1][6];
|
||||
if( s )
|
||||
{
|
||||
r[2][6] -= m[2] * s;
|
||||
r[3][6] -= m[3] * s;
|
||||
}
|
||||
|
||||
s = r[1][7];
|
||||
if( s )
|
||||
{
|
||||
r[2][7] -= m[2] * s;
|
||||
r[3][7] -= m[3] * s;
|
||||
}
|
||||
|
||||
if( fabs( r[3][2] ) > fabs( r[2][2] ))
|
||||
{
|
||||
temp = r[3];
|
||||
r[3] = r[2];
|
||||
r[2] = temp;
|
||||
}
|
||||
|
||||
if( r[2][2] )
|
||||
{
|
||||
m[3] = r[3][2] / r[2][2];
|
||||
r[3][3] -= m[3] * r[2][3];
|
||||
r[3][4] -= m[3] * r[2][4];
|
||||
r[3][5] -= m[3] * r[2][5];
|
||||
r[3][6] -= m[3] * r[2][6];
|
||||
r[3][7] -= m[3] * r[2][7];
|
||||
|
||||
if( r[3][3] )
|
||||
{
|
||||
s = 1.0f / r[3][3];
|
||||
r[3][4] *= s;
|
||||
r[3][5] *= s;
|
||||
r[3][6] *= s;
|
||||
r[3][7] *= s;
|
||||
|
||||
m[2] = r[2][3];
|
||||
s = 1.0f / r[2][2];
|
||||
r[2][4] = s * (r[2][4] - r[3][4] * m[2]);
|
||||
r[2][5] = s * (r[2][5] - r[3][5] * m[2]);
|
||||
r[2][6] = s * (r[2][6] - r[3][6] * m[2]);
|
||||
r[2][7] = s * (r[2][7] - r[3][7] * m[2]);
|
||||
|
||||
m[1] = r[1][3];
|
||||
r[1][4] -= r[3][4] * m[1];
|
||||
r[1][5] -= r[3][5] * m[1];
|
||||
r[1][6] -= r[3][6] * m[1];
|
||||
r[1][7] -= r[3][7] * m[1];
|
||||
|
||||
m[0] = r[0][3];
|
||||
r[0][4] -= r[3][4] * m[0];
|
||||
r[0][5] -= r[3][5] * m[0];
|
||||
r[0][6] -= r[3][6] * m[0];
|
||||
r[0][7] -= r[3][7] * m[0];
|
||||
|
||||
m[1] = r[1][2];
|
||||
s = 1.0f / r[1][1];
|
||||
r[1][4] = s * (r[1][4] - r[2][4] * m[1]);
|
||||
r[1][5] = s * (r[1][5] - r[2][5] * m[1]);
|
||||
r[1][6] = s * (r[1][6] - r[2][6] * m[1]);
|
||||
r[1][7] = s * (r[1][7] - r[2][7] * m[1]);
|
||||
|
||||
m[0] = r[0][2];
|
||||
r[0][4] -= r[2][4] * m[0];
|
||||
r[0][5] -= r[2][5] * m[0];
|
||||
r[0][6] -= r[2][6] * m[0];
|
||||
r[0][7] -= r[2][7] * m[0];
|
||||
|
||||
m[0] = r[0][1];
|
||||
s = 1.0f / r[0][0];
|
||||
r[0][4] = s * (r[0][4] - r[1][4] * m[0]);
|
||||
r[0][5] = s * (r[0][5] - r[1][5] * m[0]);
|
||||
r[0][6] = s * (r[0][6] - r[1][6] * m[0]);
|
||||
r[0][7] = s * (r[0][7] - r[1][7] * m[0]);
|
||||
|
||||
out[0][0] = r[0][4];
|
||||
out[0][1] = r[0][5];
|
||||
out[0][2] = r[0][6];
|
||||
out[0][3] = r[0][7];
|
||||
out[1][0] = r[1][4];
|
||||
out[1][1] = r[1][5];
|
||||
out[1][2] = r[1][6];
|
||||
out[1][3] = r[1][7];
|
||||
out[2][0] = r[2][4];
|
||||
out[2][1] = r[2][5];
|
||||
out[2][2] = r[2][6];
|
||||
out[2][3] = r[2][7];
|
||||
out[3][0] = r[3][4];
|
||||
out[3][1] = r[3][5];
|
||||
out[3][2] = r[3][6];
|
||||
out[3][3] = r[3][7];
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
9
Projects/Android/local.properties
Normal file
9
Projects/Android/local.properties
Normal file
|
@ -0,0 +1,9 @@
|
|||
## This file must *NOT* be checked into Version Control Systems,
|
||||
# as it contains information specific to your local configuration.
|
||||
#
|
||||
# Location of the SDK. This is only used by Gradle.
|
||||
# For customization when using a Version Control System, please read the
|
||||
# header note.
|
||||
#Thu Dec 12 20:21:11 GMT 2019
|
||||
ndk.dir=C\:\\Users\\Simon\\AppData\\Local\\Android\\Sdk\\ndk-bundle
|
||||
sdk.dir=C\:\\Users\\Simon\\AppData\\Local\\Android\\Sdk
|
4
Projects/Android/settings.gradle
Normal file
4
Projects/Android/settings.gradle
Normal file
|
@ -0,0 +1,4 @@
|
|||
rootProject.projectDir = new File(settingsDir, '../../../..')
|
||||
rootProject.name = "Quake2Quest"
|
||||
|
||||
include ':', 'VrSamples:Quake2Quest:Projects:Android'
|
25
VrSamples-RTCWQuest.iml
Normal file
25
VrSamples-RTCWQuest.iml
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module external.linked.project.id=":VrSamples:Quake2Quest" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/Projects/Android" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="android-gradle" name="Android-Gradle">
|
||||
<configuration>
|
||||
<option name="GRADLE_PROJECT_PATH" value=":VrSamples:Quake2Quest" />
|
||||
</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>
|
426
java/com/drbeef/rtcwquest/GLES3JNIActivity.java
Normal file
426
java/com/drbeef/rtcwquest/GLES3JNIActivity.java
Normal file
|
@ -0,0 +1,426 @@
|
|||
|
||||
package com.drbeef.quake2quest;
|
||||
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.AssetManager;
|
||||
|
||||
import android.media.AudioFormat;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioRecord;
|
||||
import android.media.AudioTrack;
|
||||
import android.media.MediaRecorder;
|
||||
import android.os.Bundle;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
import android.view.WindowManager;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
|
||||
import static android.system.Os.setenv;
|
||||
|
||||
@SuppressLint("SdCardPath") public class GLES3JNIActivity extends Activity implements SurfaceHolder.Callback
|
||||
{
|
||||
// Load the gles3jni library right away to make sure JNI_OnLoad() gets called as the very first thing.
|
||||
static
|
||||
{
|
||||
System.loadLibrary( "yquake2" );
|
||||
}
|
||||
|
||||
private static final String TAG = "Quake2Quest";
|
||||
|
||||
private int permissionCount = 0;
|
||||
private static final int READ_EXTERNAL_STORAGE_PERMISSION_ID = 1;
|
||||
private static final int WRITE_EXTERNAL_STORAGE_PERMISSION_ID = 2;
|
||||
|
||||
String commandLineParams;
|
||||
|
||||
private SurfaceView mView;
|
||||
private SurfaceHolder mSurfaceHolder;
|
||||
private long mNativeHandle;
|
||||
|
||||
// Main components
|
||||
protected static GLES3JNIActivity mSingleton;
|
||||
|
||||
// Audio
|
||||
protected static AudioTrack mAudioTrack;
|
||||
protected static AudioRecord mAudioRecord;
|
||||
|
||||
public static void initialize() {
|
||||
// The static nature of the singleton and Android quirkyness force us to initialize everything here
|
||||
// Otherwise, when exiting the app and returning to it, these variables *keep* their pre exit values
|
||||
mSingleton = null;
|
||||
mAudioTrack = null;
|
||||
mAudioRecord = null;
|
||||
}
|
||||
|
||||
@Override protected void onCreate( Bundle icicle )
|
||||
{
|
||||
Log.v( TAG, "----------------------------------------------------------------" );
|
||||
Log.v( TAG, "GLES3JNIActivity::onCreate()" );
|
||||
super.onCreate( icicle );
|
||||
|
||||
GLES3JNIActivity.initialize();
|
||||
|
||||
// So we can call stuff from static callbacks
|
||||
mSingleton = this;
|
||||
|
||||
|
||||
mView = new SurfaceView( this );
|
||||
setContentView( mView );
|
||||
mView.getHolder().addCallback( this );
|
||||
|
||||
// Force the screen to stay on, rather than letting it dim and shut off
|
||||
// while the user is watching a movie.
|
||||
getWindow().addFlags( WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON );
|
||||
|
||||
// Force screen brightness to stay at maximum
|
||||
WindowManager.LayoutParams params = getWindow().getAttributes();
|
||||
params.screenBrightness = 1.0f;
|
||||
getWindow().setAttributes( params );
|
||||
|
||||
checkPermissionsAndInitialize();
|
||||
}
|
||||
|
||||
/** Initializes the Activity only if the permission has been granted. */
|
||||
private void checkPermissionsAndInitialize() {
|
||||
// Boilerplate for checking runtime permissions in Android.
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
!= PackageManager.PERMISSION_GRANTED){
|
||||
ActivityCompat.requestPermissions(
|
||||
GLES3JNIActivity.this,
|
||||
new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
||||
WRITE_EXTERNAL_STORAGE_PERMISSION_ID);
|
||||
}
|
||||
else
|
||||
{
|
||||
permissionCount++;
|
||||
}
|
||||
|
||||
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
|
||||
!= PackageManager.PERMISSION_GRANTED)
|
||||
{
|
||||
ActivityCompat.requestPermissions(
|
||||
GLES3JNIActivity.this,
|
||||
new String[] {Manifest.permission.READ_EXTERNAL_STORAGE},
|
||||
READ_EXTERNAL_STORAGE_PERMISSION_ID);
|
||||
}
|
||||
else
|
||||
{
|
||||
permissionCount++;
|
||||
}
|
||||
|
||||
if (permissionCount == 2) {
|
||||
// Permissions have already been granted.
|
||||
create();
|
||||
}
|
||||
}
|
||||
|
||||
/** Handles the user accepting the permission. */
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] results) {
|
||||
if (requestCode == READ_EXTERNAL_STORAGE_PERMISSION_ID) {
|
||||
if (results.length > 0 && results[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
permissionCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (requestCode == WRITE_EXTERNAL_STORAGE_PERMISSION_ID) {
|
||||
if (results.length > 0 && results[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
permissionCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
checkPermissionsAndInitialize();
|
||||
}
|
||||
|
||||
public void create()
|
||||
{
|
||||
//This will copy the shareware version of quake2 if user doesn't have anything installed
|
||||
copy_asset("/sdcard/Quake2Quest", "pak0.pak");
|
||||
|
||||
//HD Textures
|
||||
copy_asset("/sdcard/Quake2Quest", "pak6.pak");
|
||||
|
||||
//Custom weapons
|
||||
copy_asset("/sdcard/Quake2Quest", "pak99.pak");
|
||||
|
||||
//Configuration files
|
||||
copy_asset("/sdcard/Quake2Quest", "config.cfg");
|
||||
copy_asset("/sdcard/Quake2Quest", "autoexec.cfg");
|
||||
copy_asset("/sdcard/Quake2Quest", "commandline.txt");
|
||||
|
||||
//Comfort Vignette Mask
|
||||
copy_asset("/sdcard/Quake2Quest", "vignette.tga");
|
||||
|
||||
//Read these from a file and pass through
|
||||
commandLineParams = new String("quake2");
|
||||
|
||||
//See if user is trying to use command line params
|
||||
if(new File("/sdcard/Quake2Quest/commandline.txt").exists()) // should exist!
|
||||
{
|
||||
BufferedReader br;
|
||||
try {
|
||||
br = new BufferedReader(new FileReader("/sdcard/Quake2Quest/commandline.txt"));
|
||||
String s;
|
||||
StringBuilder sb=new StringBuilder(0);
|
||||
while ((s=br.readLine())!=null)
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
setenv("YQUAKE2_GAMELIBDIR", getFilesDir().getParentFile().getPath() + "/lib", true);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
mNativeHandle = GLES3JNILib.onCreate( this, commandLineParams );
|
||||
}
|
||||
|
||||
public void copy_asset(String path, String name) {
|
||||
File f = new File(path + "/" + name);
|
||||
if (!f.exists()) {
|
||||
|
||||
//Ensure we have an appropriate folder
|
||||
String fullname = path + "/" + name;
|
||||
String directory = fullname.substring(0, fullname.lastIndexOf("/"));
|
||||
new File(directory).mkdirs();
|
||||
_copy_asset(name, path + "/" + name);
|
||||
}
|
||||
}
|
||||
|
||||
public void _copy_asset(String name_in, String name_out) {
|
||||
AssetManager assets = this.getAssets();
|
||||
|
||||
try {
|
||||
InputStream in = assets.open(name_in);
|
||||
OutputStream out = new FileOutputStream(name_out);
|
||||
|
||||
copy_stream(in, out);
|
||||
|
||||
out.close();
|
||||
in.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void copy_stream(InputStream in, OutputStream out)
|
||||
throws IOException {
|
||||
byte[] buf = new byte[1024];
|
||||
while (true) {
|
||||
int count = in.read(buf);
|
||||
if (count <= 0)
|
||||
break;
|
||||
out.write(buf, 0, count);
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onStart()
|
||||
{
|
||||
Log.v( TAG, "GLES3JNIActivity::onStart()" );
|
||||
super.onStart();
|
||||
|
||||
GLES3JNILib.onStart( mNativeHandle );
|
||||
}
|
||||
|
||||
@Override protected void onResume()
|
||||
{
|
||||
Log.v( TAG, "GLES3JNIActivity::onResume()" );
|
||||
super.onResume();
|
||||
|
||||
GLES3JNILib.onResume( mNativeHandle );
|
||||
}
|
||||
|
||||
@Override protected void onPause()
|
||||
{
|
||||
Log.v( TAG, "GLES3JNIActivity::onPause()" );
|
||||
GLES3JNILib.onPause( mNativeHandle );
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override protected void onStop()
|
||||
{
|
||||
Log.v( TAG, "GLES3JNIActivity::onStop()" );
|
||||
GLES3JNILib.onStop( mNativeHandle );
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
@Override protected void onDestroy()
|
||||
{
|
||||
Log.v( TAG, "GLES3JNIActivity::onDestroy()" );
|
||||
|
||||
if ( mSurfaceHolder != null )
|
||||
{
|
||||
GLES3JNILib.onSurfaceDestroyed( mNativeHandle );
|
||||
}
|
||||
|
||||
GLES3JNILib.onDestroy( mNativeHandle );
|
||||
|
||||
super.onDestroy();
|
||||
// Reset everything in case the user re opens the app
|
||||
GLES3JNIActivity.initialize();
|
||||
mNativeHandle = 0;
|
||||
}
|
||||
|
||||
@Override public void surfaceCreated( SurfaceHolder holder )
|
||||
{
|
||||
Log.v( TAG, "GLES3JNIActivity::surfaceCreated()" );
|
||||
if ( mNativeHandle != 0 )
|
||||
{
|
||||
GLES3JNILib.onSurfaceCreated( mNativeHandle, holder.getSurface() );
|
||||
mSurfaceHolder = holder;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void surfaceChanged( SurfaceHolder holder, int format, int width, int height )
|
||||
{
|
||||
Log.v( TAG, "GLES3JNIActivity::surfaceChanged()" );
|
||||
if ( mNativeHandle != 0 )
|
||||
{
|
||||
GLES3JNILib.onSurfaceChanged( mNativeHandle, holder.getSurface() );
|
||||
mSurfaceHolder = holder;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void surfaceDestroyed( SurfaceHolder holder )
|
||||
{
|
||||
Log.v( TAG, "GLES3JNIActivity::surfaceDestroyed()" );
|
||||
if ( mNativeHandle != 0 )
|
||||
{
|
||||
GLES3JNILib.onSurfaceDestroyed( mNativeHandle );
|
||||
mSurfaceHolder = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Audio
|
||||
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static int audioOpen(int sampleRate, boolean is16Bit, boolean isStereo, int desiredFrames) {
|
||||
int channelConfig = isStereo ? AudioFormat.CHANNEL_CONFIGURATION_STEREO : AudioFormat.CHANNEL_CONFIGURATION_MONO;
|
||||
int audioFormat = is16Bit ? AudioFormat.ENCODING_PCM_16BIT : AudioFormat.ENCODING_PCM_8BIT;
|
||||
int frameSize = (isStereo ? 2 : 1) * (is16Bit ? 2 : 1);
|
||||
|
||||
Log.v(TAG, "SDL audio: wanted " + (isStereo ? "stereo" : "mono") + " " + (is16Bit ? "16-bit" : "8-bit") + " " + (sampleRate / 1000f) + "kHz, " + desiredFrames + " frames buffer");
|
||||
|
||||
// Let the user pick a larger buffer if they really want -- but ye
|
||||
// gods they probably shouldn't, the minimums are horrifyingly high
|
||||
// latency already
|
||||
desiredFrames = Math.max(desiredFrames, (AudioTrack.getMinBufferSize(sampleRate, channelConfig, audioFormat) + frameSize - 1) / frameSize);
|
||||
|
||||
if (mAudioTrack == null) {
|
||||
mAudioTrack = new AudioTrack(AudioManager.STREAM_MUSIC, sampleRate,
|
||||
channelConfig, audioFormat, desiredFrames * frameSize, AudioTrack.MODE_STREAM);
|
||||
|
||||
// Instantiating AudioTrack can "succeed" without an exception and the track may still be invalid
|
||||
// Ref: https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/media/java/android/media/AudioTrack.java
|
||||
// Ref: http://developer.android.com/reference/android/media/AudioTrack.html#getState()
|
||||
|
||||
if (mAudioTrack.getState() != AudioTrack.STATE_INITIALIZED) {
|
||||
Log.e(TAG, "Failed during initialization of Audio Track");
|
||||
mAudioTrack = null;
|
||||
return -1;
|
||||
}
|
||||
|
||||
mAudioTrack.play();
|
||||
}
|
||||
|
||||
Log.v(TAG, "SDL audio: got " + ((mAudioTrack.getChannelCount() >= 2) ? "stereo" : "mono") + " " + ((mAudioTrack.getAudioFormat() == AudioFormat.ENCODING_PCM_16BIT) ? "16-bit" : "8-bit") + " " + (mAudioTrack.getSampleRate() / 1000f) + "kHz, " + desiredFrames + " frames buffer");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static void audioWriteShortBuffer(short[] buffer) {
|
||||
for (int i = 0; i < buffer.length; ) {
|
||||
int result = mAudioTrack.write(buffer, i, buffer.length - i);
|
||||
if (result > 0) {
|
||||
i += result;
|
||||
} else if (result == 0) {
|
||||
try {
|
||||
Thread.sleep(1);
|
||||
} catch(InterruptedException e) {
|
||||
// Nom nom
|
||||
}
|
||||
} else {
|
||||
Log.w(TAG, "SDL audio: error return from write(short)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called by SDL using JNI.
|
||||
*/
|
||||
public static void audioWriteByteBuffer(byte[] buffer) {
|
||||
for (int i = 0; i < buffer.length; ) {
|
||||
int result = mAudioTrack.write(buffer, i, buffer.length - i);
|
||||
if (result > 0) {
|
||||
i += result;
|
||||
} else if (result == 0) {
|
||||
try {
|
||||
Thread.sleep(1);
|
||||
} catch(InterruptedException e) {
|
||||
// Nom nom
|
||||
}
|
||||
} else {
|
||||
Log.w(TAG, "SDL audio: error return from write(byte)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** This method is called by SDL using JNI. */
|
||||
public static void audioClose() {
|
||||
if (mAudioTrack != null) {
|
||||
mAudioTrack.stop();
|
||||
mAudioTrack.release();
|
||||
mAudioTrack = null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
25
java/com/drbeef/rtcwquest/GLES3JNILib.java
Normal file
25
java/com/drbeef/rtcwquest/GLES3JNILib.java
Normal file
|
@ -0,0 +1,25 @@
|
|||
|
||||
package com.drbeef.quake2quest;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.view.Surface;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
// Wrapper for native library
|
||||
|
||||
public class GLES3JNILib
|
||||
{
|
||||
// Activity lifecycle
|
||||
public static native long onCreate( Activity obj, String commandLineParams );
|
||||
public static native void onStart( long handle );
|
||||
public static native void onResume( long handle );
|
||||
public static native void onPause( long handle );
|
||||
public static native void onStop( long handle );
|
||||
public static native void onDestroy( long handle );
|
||||
|
||||
// Surface lifecycle
|
||||
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 );
|
||||
}
|
BIN
res/drawable-hdpi/ic_qquest.png
Normal file
BIN
res/drawable-hdpi/ic_qquest.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
BIN
res/drawable-mdpi/ic_qquest.png
Normal file
BIN
res/drawable-mdpi/ic_qquest.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.6 KiB |
BIN
res/drawable-xhdpi/ic_qquest.png
Normal file
BIN
res/drawable-xhdpi/ic_qquest.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 17 KiB |
BIN
res/drawable-xxhdpi/ic_qquest.png
Normal file
BIN
res/drawable-xxhdpi/ic_qquest.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 25 KiB |
10
res/values/strings.xml
Normal file
10
res/values/strings.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<!-- This file contains resource definitions for displayed strings, allowing
|
||||
them to be changed based on the locale and options. -->
|
||||
|
||||
<resources>
|
||||
<!-- Simple strings. -->
|
||||
<string name="quake2quest">Quake2Quest</string>
|
||||
|
||||
</resources>
|
Loading…
Reference in a new issue