diff --git a/.gitignore b/.gitignore index 79d784a..650b2b9 100644 --- a/.gitignore +++ b/.gitignore @@ -11,7 +11,6 @@ PanoPainter.sdf *.iml android/.idea android/android/build/ -android/android/gradle/ android/android/.gradle/ android/android/.externalNativeBuild/ android/android/.idea @@ -21,6 +20,11 @@ android/quest/.gradle/ android/quest/.externalNativeBuild/ android/quest/.idea android/quest/src/main/assets/ +android/focus/build/ +android/focus/.gradle/ +android/focus/.externalNativeBuild/ +android/focus/.idea +android/focus/src/main/assets/ android/local.properties data/brushes diff --git a/.gitmodules b/.gitmodules index 927159e..4ded6dc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -55,3 +55,6 @@ [submodule "libs/glad"] path = libs/glad url = https://bitbucket.org/omigamedev/glad.git +[submodule "libs/wave_sdk"] + path = libs/wave_sdk + url = https://bitbucket.org/omigamedev/wave_sdk.git diff --git a/android/android/build.gradle b/android/android/build.gradle index 49cee59..c82b031 100644 --- a/android/android/build.gradle +++ b/android/android/build.gradle @@ -64,13 +64,13 @@ def ver_tag = "git describe --tags --abbrev=0".execute().text.trim() println classpath android { - compileSdkVersion 26 + compileSdkVersion 28 android.buildToolsVersion "28.0.3" defaultConfig { applicationId = 'com.omixlab.panopainter' minSdkVersion 19 - targetSdkVersion 26 + targetSdkVersion 28 versionCode ver_count versionName "${ver_tag}.${ver_count}" // This block is different from the one you use to link Gradle diff --git a/android/android/src/main/java/com/omixlab/panopainter/PlatformActivity.java b/android/android/src/main/java/com/omixlab/panopainter/PlatformActivity.java new file mode 100644 index 0000000..9b9a805 --- /dev/null +++ b/android/android/src/main/java/com/omixlab/panopainter/PlatformActivity.java @@ -0,0 +1,6 @@ +package com.omixlab.panopainter; + +import android.app.NativeActivity; + +public class PlatformActivity extends NativeActivity { +} diff --git a/android/focus/CMakeLists.txt b/android/focus/CMakeLists.txt new file mode 100644 index 0000000..9bbebf3 --- /dev/null +++ b/android/focus/CMakeLists.txt @@ -0,0 +1,155 @@ +# Sets the minimum version of CMake required to build your native library. +# This ensures that a certain set of CMake features is available to +# your build. + +cmake_minimum_required(VERSION 3.4.1) + +# build native_app_glue as a static lib +add_library( + app-glue STATIC + ../../libs/native_app_glue/android_native_app_glue.c +) + +add_library(wvr_api SHARED IMPORTED) +set_target_properties( + wvr_api + PROPERTIES IMPORTED_LOCATION + ${CMAKE_SOURCE_DIR}/../../libs/wave_sdk/wvr_client/lib/${ANDROID_ABI}/libwvr_api.so +) + +# Specifies a library name, specifies whether the library is STATIC or +# SHARED, and provides relative paths to the source code. You can +# define multiple libraries by adding multiple add.library() commands, +# and CMake builds them for you. When you build your app, Gradle +# automatically packages shared libraries with your APK. + +# now build app's shared lib +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14") + +add_library( + native-lib SHARED + ../../libs/yoga/yoga/log.cpp + ../../libs/yoga/yoga/Utils.cpp + ../../libs/yoga/yoga/YGConfig.cpp + ../../libs/yoga/yoga/YGEnums.cpp + ../../libs/yoga/yoga/YGLayout.cpp + ../../libs/yoga/yoga/YGMarker.cpp + ../../libs/yoga/yoga/YGNode.cpp + ../../libs/yoga/yoga/YGNodePrint.cpp + ../../libs/yoga/yoga/YGStyle.cpp + ../../libs/yoga/yoga/YGValue.cpp + ../../libs/yoga/yoga/Yoga.cpp + ../../libs/tinyxml2/tinyxml2.cpp + ../../libs/jpeg/jpgd.cpp + ../../libs/jpeg/jpge.cpp + ../../libs/poly2tri/poly2tri/common/shapes.cc + ../../libs/poly2tri/poly2tri/sweep/advancing_front.cc + ../../libs/poly2tri/poly2tri/sweep/cdt.cc + ../../libs/poly2tri/poly2tri/sweep/sweep_context.cc + ../../libs/poly2tri/poly2tri/sweep/sweep.cc + ../../libs/fmt/src/format.cc + ../src/cpp/main.cpp + src/main/cpp/wave_vr.cpp + ../../src/pch.cpp + ../../src/util.cpp + ../../src/rtt.cpp + ../../src/bezier.cpp + ../../src/asset.cpp + ../../src/image.cpp + ../../src/texture.cpp + ../../src/font.cpp + ../../src/shader.cpp + ../../src/shape.cpp + ../../src/app.cpp + ../../src/app_cloud.cpp + ../../src/app_dialogs.cpp + ../../src/app_events.cpp + ../../src/app_layout.cpp + ../../src/app_shaders.cpp + ../../src/app_vr.cpp + ../../src/brush.cpp + ../../src/canvas.cpp + ../../src/canvas_layer.cpp + ../../src/canvas_actions.cpp + ../../src/canvas_modes.cpp + ../../src/log.cpp + ../../src/action.cpp + ../../src/layout.cpp + ../../src/version.cpp + ../../src/node.cpp + ../../src/node_about.cpp + ../../src/node_border.cpp + ../../src/node_button.cpp + ../../src/node_button_custom.cpp + ../../src/node_canvas.cpp + ../../src/node_checkbox.cpp + ../../src/node_color_quad.cpp + ../../src/node_colorwheel.cpp + ../../src/node_combobox.cpp + ../../src/node_changelog.cpp + ../../src/node_dialog_browse.cpp + ../../src/node_dialog_cloud.cpp + ../../src/node_dialog_open.cpp + ../../src/node_dialog_picker.cpp + ../../src/node_dialog_layer_rename.cpp + ../../src/node_dialog_resize.cpp + ../../src/node_icon.cpp + ../../src/node_image.cpp + ../../src/node_image_texture.cpp + ../../src/node_message_box.cpp + ../../src/node_panel_brush.cpp + ../../src/node_panel_color.cpp + ../../src/node_panel_grid.cpp + ../../src/node_panel_floating.cpp + ../../src/node_panel_layer.cpp + ../../src/node_panel_stroke.cpp + ../../src/node_panel_quick.cpp + ../../src/node_popup_menu.cpp + ../../src/node_progress_bar.cpp + ../../src/node_settings.cpp + ../../src/node_slider.cpp + ../../src/node_stroke_preview.cpp + ../../src/node_text.cpp + ../../src/node_text_input.cpp + ../../src/node_tool_bucket.cpp + ../../src/node_usermanual.cpp + ../../src/node_viewport.cpp + ../../src/node_scroll.cpp + ../../src/abr.cpp + ../../src/binary_stream.cpp + ../../src/serializer.cpp + ../../src/settings.cpp +) + +target_include_directories(native-lib PRIVATE + ../../libs/wave_sdk/wvr_client/include + src/main/cpp + ../src/cpp + ../../src + ../../libs/glm + ../../libs/tinyxml2 + ../../libs/yoga + ../../libs/stb + ../../libs/jpeg + ../../libs/curl-android-ios/android/include + ../../libs/poly2tri/poly2tri + ../../libs/base64 + ../../libs/sqlite3 + ../../libs/nanort + ../../libs/native_app_glue + ../../libs/hash-library + ../../libs/fmt/include +) + +# add lib dependencies +target_link_libraries( + native-lib + wvr_api + android + app-glue + ${CMAKE_SOURCE_DIR}/../../libs/curl-android-ios/android/${ANDROID_ABI}/libcurl.a + EGL + GLESv3 + log + z +) diff --git a/android/focus/build-run.bat b/android/focus/build-run.bat new file mode 100644 index 0000000..9036f94 --- /dev/null +++ b/android/focus/build-run.bat @@ -0,0 +1,4 @@ +xcopy /I /D /Y /S /E ..\data src\main\assets\data +call gradlew installDebug +call adb shell am start -n com.omigamedev/android.app.NativeActivity +pause \ No newline at end of file diff --git a/android/focus/build.gradle b/android/focus/build.gradle new file mode 100644 index 0000000..4068c9c --- /dev/null +++ b/android/focus/build.gradle @@ -0,0 +1,197 @@ +import java.util.regex.Matcher +import java.util.regex.Pattern + +buildscript { + repositories { + google() + jcenter() + maven { + url "https://plugins.gradle.org/m2/" + } + } + dependencies { + classpath 'com.android.tools.build:gradle:3.3.0' + classpath "gradle.plugin.com.gladed.gradle.androidgitversion:gradle-android-git-version:0.4.5" + } +} + +allprojects { + repositories { + google() // and here + jcenter() + flatDir{ + dirs '../../libs/wave_sdk/wvr_client' + } + } +} + +apply plugin: "com.android.application" +apply plugin: "com.gladed.androidgitversion" + +def jniDir = "src/main/jni" +def aarFilename = "wvr_client" + +// unzip aar +def unzipDir = file("${buildDir}/${aarFilename}") +def aarFile = file("${projectDir}/../../libs/wave_sdk/wvr_client/${aarFilename}.aar") +if (aarFile != null) { + copy { + println 'unzip ' + aarFile + from zipTree(aarFile) + into unzipDir + } +} + +def getCurrentFlavor() { + Gradle gradle = getGradle() + + if (gradle.getStartParameter().getTaskRequests().args.size() == 0) + return "" + String tskReqStr = gradle.getStartParameter().getTaskRequests().args[0][0] + Pattern pattern + + pattern = Pattern.compile("(\\w*)(Release|Debug)") + + Matcher matcher = pattern.matcher( tskReqStr ) + + if( matcher.find() ) + return matcher.group(2).toLowerCase() + else + { + println "NO MATCH FOUND" + return "" + } +} + +def flavor = getCurrentFlavor() +def flavor_cap = getCurrentFlavor().capitalize() + +Properties properties = new Properties() +properties.load(project.rootProject.file('local.properties').newDataInputStream()) +def sdkDir = properties.getProperty("sdk.dir") +def classpath = "build/intermediates/javac/${flavor}/compile${flavor_cap}JavaWithJavac/classes;${sdkDir}/platforms/android-26/android.jar;${unzipDir}/classes.jar" +def activity = "com.omixlab.panopainter.MainActivity" +def outpath = "src/main/cpp" + +def ver_branch = "git rev-parse --abbrev-ref HEAD".execute().text.trim() +def ver_hash = "git log --pretty=format:%h -n 1".execute().text.trim() +def ver_count = Integer.parseInt("git rev-list --count HEAD".execute().text.trim()) +def ver_tag = "git describe --tags --abbrev=0".execute().text.trim() + +println classpath + +android { + compileSdkVersion 28 + android.buildToolsVersion "28.0.3" + + defaultConfig { + applicationId = 'com.omixlab.panopainter' + minSdkVersion 19 + targetSdkVersion 28 + versionCode ver_count + versionName "${ver_tag}.${ver_count}" + // This block is different from the one you use to link Gradle + // to your CMake or ndk-build script. + externalNativeBuild { + // For ndk-build, instead use the ndkBuild block + cmake { + // Passes optional arguments to CMake. + //arguments "-DANDROID_ARM_NEON=TRUE", "-DANDROID_TOOLCHAIN=clang" + // Sets optional flags for the C compiler. + //cFlags "-D_EXAMPLE_C_FLAG1", "-D_EXAMPLE_C_FLAG2" + // Sets a flag to enable format macro constants for the C++ compiler. + cppFlags "-D__FOCUS__=1" + arguments "-DANDROID_TOOLCHAIN=clang", + //"-DANDROID_PLATFORM=android-19", + "-DANDROID_STL=c++_shared", + "-DCMAKE_BUILD_TYPE=${flavor_cap}", + "-DANDROID_ARM_NEON=TRUE" + } + } + ndk { + // Specifies the ABI configurations of your native + // libraries Gradle should build and package with your APK. + // abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a' + abiFilters 'armeabi-v7a' + } + } + + // productFlavors { + // main { + // externalNativeBuild { + // cmake { + // targets "native-lib-demo" + // } + // } + // } + // } + + signingConfigs { + release { + storeFile file("ppkey.jks") + storePassword "om4r@Pano#Painter_2018" + keyAlias "PanoPainter" + keyPassword "om4r@Pano#Painter_2018" + } + } + + buildTypes { + release { + minifyEnabled false + proguardFile getDefaultProguardFile('proguard-android.txt') + signingConfig signingConfigs.release + } + } + + // Encapsulates your external native build configurations. + externalNativeBuild { + // Encapsulates your CMake build configurations. + cmake { + // Provides a relative path to your CMake build script. + path "CMakeLists.txt" + } + } + + sourceSets { + main { + manifest.srcFile 'src/main/AndroidManifest.xml' + java.srcDirs = ['../src/java', 'src/main/java'] + jniLibs.srcDirs = ['../../libs/wave_sdk/wvr_client/lib'] + res.srcDirs = ['../src/res'] + //assets.srcDirs = ['../../assets'] + } + } + +} + +task copyFiles(type: Copy) { + from '../../data/' + into 'src/main/assets/data' +} +preBuild.dependsOn(copyFiles) + +task generateVersioning(type: Exec) { + workingDir "$projectDir/../../" + commandLine 'python', 'scripts/pre-build.py', flavor +} +copyFiles.dependsOn(generateVersioning) + +task generateJavaH(type: Exec) { + ignoreExitValue true + workingDir "$projectDir" + commandLine 'javah', "-jni", "-force", "-cp", "$classpath", "-d", "$outpath", "$activity" +} +//generateVersioning.dependsOn(generateJavaH) + +tasks.whenTaskAdded { task -> + if (task.name.contains('externalNativeBuild')) { + // This dependecy *is* set. This can be seen by using task copyLibs(type: Copy, dependsOn: 'bundleDebug') + // together with this and get a circular dependency. + task.dependsOn generateJavaH + } +} + +dependencies { + compile fileTree(include: ['*.jar'], dir: 'libs') + compile "com.htc.vr.aar:${aarFilename}@aar" +} diff --git a/android/focus/build_sdk.gradle b/android/focus/build_sdk.gradle new file mode 100644 index 0000000..9997423 --- /dev/null +++ b/android/focus/build_sdk.gradle @@ -0,0 +1,55 @@ +def jniDir = "src/main/jni" +def aarFilename = "wvr_client" + +// unzip aar +def unzipDir = file("${buildDir}/${aarFilename}") +def aarFile = file("${projectDir}/libs/${aarFilename}.aar") +if (aarFile != null) { + copy { + println 'unzip ' + aarFile + from zipTree(aarFile) + into unzipDir + } +} + +android { + defaultConfig { + externalNativeBuild { ndkBuild { + def VR_SDK_ROOT = "${buildDir}/${aarFilename}" + arguments "VR_SDK_ROOT=$VR_SDK_ROOT" + }} + ndk { + abiFilters 'armeabi-v7a' + } + } + + externalNativeBuild { + ndkBuild { + path "${jniDir}/Android.mk" + } + } + + buildTypes { + release { + externalNativeBuild { ndkBuild { + arguments "NDK_DEBUG=0" + }} + } + debug { + externalNativeBuild { ndkBuild { + arguments "NDK_DEBUG=1" + }} + } + } +} + +repositories { + flatDir{ + dirs 'libs' + } +} + +dependencies { + compile fileTree(include: ['*.jar'], dir: 'libs') + compile "com.htc.vr.aar:${aarFilename}@aar" +} diff --git a/android/focus/gradle.properties b/android/focus/gradle.properties new file mode 100644 index 0000000..8bd86f6 --- /dev/null +++ b/android/focus/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/android/focus/gradle/wrapper/gradle-wrapper.jar b/android/focus/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..8c0fb64 Binary files /dev/null and b/android/focus/gradle/wrapper/gradle-wrapper.jar differ diff --git a/android/focus/gradle/wrapper/gradle-wrapper.properties b/android/focus/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..b0a0ae5 --- /dev/null +++ b/android/focus/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Mon May 27 02:40:42 CEST 2019 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-all.zip diff --git a/android/focus/gradlew b/android/focus/gradlew new file mode 100644 index 0000000..91a7e26 --- /dev/null +++ b/android/focus/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# 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 +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# 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\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +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" ] ; 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"` + + # 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 + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/android/focus/gradlew.bat b/android/focus/gradlew.bat new file mode 100644 index 0000000..8a0b282 --- /dev/null +++ b/android/focus/gradlew.bat @@ -0,0 +1,90 @@ +@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 + +@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= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@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 Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_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=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +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 diff --git a/android/focus/local.properties b/android/focus/local.properties new file mode 100644 index 0000000..4d3a32a --- /dev/null +++ b/android/focus/local.properties @@ -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. +#Mon Oct 08 14:04:19 CEST 2018 +ndk.dir=C\:\\Users\\omar\\AppData\\Local\\Android\\Sdk\\ndk-bundle +sdk.dir=C\:\\Users\\omar\\AppData\\Local\\Android\\Sdk diff --git a/android/focus/ppkey.jks b/android/focus/ppkey.jks new file mode 100644 index 0000000..0e2fae0 Binary files /dev/null and b/android/focus/ppkey.jks differ diff --git a/android/focus/src/main/AndroidManifest.xml b/android/focus/src/main/AndroidManifest.xml new file mode 100644 index 0000000..9add0c2 --- /dev/null +++ b/android/focus/src/main/AndroidManifest.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + diff --git a/android/focus/src/main/cpp/wave_vr.cpp b/android/focus/src/main/cpp/wave_vr.cpp new file mode 100644 index 0000000..139e10b --- /dev/null +++ b/android/focus/src/main/cpp/wave_vr.cpp @@ -0,0 +1,398 @@ +#include "pch.h" +#include "wave_vr.h" +#include "log.h" +#include "rtt.h" +#include "app.h" +#include "canvas.h" +#include + +extern "C" bool WVR_EXPORT WVR_IsATWActive(); +extern "C" void WVR_EXPORT WVR_SetATWActive(bool isActive, void *anativeWindow = nullptr); +extern "C" void WVR_EXPORT WVR_PauseATW(); // New Api to replace SetATWActive(false) +extern "C" void WVR_EXPORT WVR_ResumeATW(); // New Api to replace SetATWActive(true) +extern "C" void WVR_EXPORT WVR_OnDisable(); // New Api to replace SetATWActive(false) on Unity3D OnDisable +extern "C" void WVR_EXPORT WVR_OnApplicationQuit(); // New Api to handle OnApplicationQuit case +extern "C" void WVR_EXPORT WVR_SetRenderThreadId(int tid); + +void android_async_lock(); +bool android_async_trylock(); +void android_async_swap(); +void android_async_unlock(); + +RTT ovr_eyes[3][2]; + +struct WaveController : public VRController +{ + void update_state(double predictedDisplayTime, glm::vec3 head_pos) + { + /* + vrapi_GetInputTrackingState(ovr_context, id, predictedDisplayTime, &tracking); + glm::vec3 c_pos = glm::make_vec3((float*)&tracking.HeadPose.Pose.Position); + auto c_rot_ovr = ovrMatrix4f_CreateFromQuaternion(&tracking.HeadPose.Pose.Orientation); + auto c_rot_ovr_tp = ovrMatrix4f_Transpose(&c_rot_ovr); + glm::mat4 c_rot = glm::make_mat4((float*)&c_rot_ovr_tp); + m_mat = glm::translate(c_pos) * c_rot; + + // update controllers + state.Header.ControllerType = ovrControllerType_TrackedRemote; + vrapi_GetCurrentInputState(ovr_context, id, &state.Header); + + update_analog(kButton::Trigger, {state.IndexTrigger, 0}); + update_analog(kButton::Grip, {state.GripTrigger, 0}); + update_analog(kButton::Pad, glm::make_vec2((float*)&state.Joystick)); + update_digital(kButton::Trigger, state.Buttons & ovrButton_Trigger, {state.IndexTrigger, 0}); + update_digital(kButton::Pad, state.Buttons & ovrButton_Joystick, glm::make_vec2((float*)&state.Joystick)); + update_digital(kButton::A, state.Buttons & ovrButton_A); + */ + } + void update_digital(kButton b, bool pressed, glm::vec2 axis = {0, 0}) + { + /* + if (pressed && !m_buttons[(int)b]) + { + m_buttons[(int)b] = true; + App::I.vr_digital(*this, b, kAction::Press, axis); + } + if (!pressed && m_buttons[(int)b]) + { + m_buttons[(int)b] = false; + App::I.vr_digital(*this, b, kAction::Release, axis); + } + */ + } + void update_analog(kButton b, glm::vec2 force) + { + /* + float l = glm::compMax(glm::abs(force)); + const float zero = 0.01f; + if (l > zero && !m_analog_buttons[(int)b]) + { + m_analog_buttons[(int)b] = true; + App::I.vr_analog(*this, b, kAction::Press, force); + } + if (l <= zero && m_analog_buttons[(int)b]) + { + m_analog_buttons[(int)b] = false; + App::I.vr_analog(*this, b, kAction::Release, force); + } + */ + } + + float get_trigger_value() const override { + /* + if (id == -1) + return 0.f; + return state.IndexTrigger; + */ + return 0; + } +}; + +WaveController controllers[2]; +extern struct engine g_engine; + +int vr_main(int argc, char *argv[]) +{ + LOG("vr_main"); + + LOG("WVR_SetATWActive"); + WVR_SetATWActive(true, g_engine.app->window); + + // We has the display config from device service, so we don't this logic. + WVR_RenderInitParams_t pp = { WVR_GraphicsApiType_OpenGL, WVR_RenderConfig_Default }; + WVR_RenderError render_error = WVR_RenderError_LibNotSupported; + render_error = WVR_RenderInit(&pp); + + if (render_error != WVR_RenderError_None) + LOG("WVR Render Init Failed"); + + // Loading the WVR Runtime + WVR_InitError eError = WVR_InitError_None; + LOG("initVR():start call WVR_Init"); + eError = WVR_Init(WVR_AppType_VRContent); + LOG("initVR():start call WVR_Init end"); + if (eError != WVR_InitError_None) { + LOG("Unable to init VR runtime: %s", WVR_GetInitErrorString(eError)); + return 1;// false; + } + + LOG("WVR_SetRenderThreadId"); + WVR_SetRenderThreadId((int)gettid()); + + WVR_InputAttribute inputIdAndTypes[] = { + {WVR_InputId_Alias1_Menu, WVR_InputType_Button, WVR_AnalogType_None}, + {WVR_InputId_Alias1_Touchpad, WVR_InputType_Button | WVR_InputType_Touch | WVR_InputType_Analog, WVR_AnalogType_2D}, + {WVR_InputId_Alias1_Trigger, WVR_InputType_Button , WVR_AnalogType_None}, + {WVR_InputId_Alias1_Digital_Trigger, WVR_InputType_Button , WVR_AnalogType_None} + }; + WVR_SetInputRequest(WVR_DeviceType_HMD, inputIdAndTypes, sizeof(inputIdAndTypes) / sizeof(*inputIdAndTypes)); + WVR_SetInputRequest(WVR_DeviceType_Controller_Right, inputIdAndTypes, sizeof(inputIdAndTypes) / sizeof(*inputIdAndTypes)); + WVR_SetInputRequest(WVR_DeviceType_Controller_Left, inputIdAndTypes, sizeof(inputIdAndTypes) / sizeof(*inputIdAndTypes)); + + // Must initialize render runtime before all OpenGL code. + WVR_RenderInitParams_t param; + param = { WVR_GraphicsApiType_OpenGL, WVR_RenderConfig_Timewarp_Asynchronous }; + + WVR_RenderError pError = WVR_RenderInit(¶m); + if (pError != WVR_RenderError_None) { + LOG("Present init failed - Error[%d]", pError); + } + + auto mInteractionMode = WVR_GetInteractionMode(); + auto mGazeTriggerType = WVR_GetGazeTriggerType(); + LOG("initVR() mInteractionMode: %d, mGazeTriggerType: %d", mInteractionMode, mGazeTriggerType); + + uint32_t w, h; + WVR_GetRenderTargetSize(&w, &h); + std::vector rtt_eyes[2]; + WVR_TextureQueueHandle_t tq[2]; + + for (int eye = 0; eye < 2; eye++) + { + tq[eye] = WVR_ObtainTextureQueue(WVR_TextureTarget_2D, WVR_TextureFormat_RGBA, + WVR_TextureType_UnsignedByte, w, h, 0); + for (int i = 0; i < WVR_GetTextureQueueLength(tq[eye]); i++) + { + auto t = WVR_GetTexture(tq[eye], i); + rtt_eyes[eye].emplace_back(); + rtt_eyes[eye].back().create(w, h, (int)t.id); + rtt_eyes[eye].back().bindFramebuffer(); + glClearColor(1, 0, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + rtt_eyes[eye].back().unbindFramebuffer(); + LOG("WVR create texture %d for eye %d", i, eye); + } + } + + android_async_lock(); + + LOG("init app"); + App::I->initLog(); + App::I->zoom = 1.f; + App::I->width = 1024; + App::I->height = 1024; + App::I->redraw = true; + App::I->init(); + //App::I.resize(1024, 1024); + App::I->vr_active = true; + App::I->has_vr = true; + App::I->vr_only = true; + LOG("init app done"); + + android_async_unlock(); + + LOG("WVR enter render loop"); + bool running = true; + while (running) + { + android_async_lock(); + WVR_DevicePosePair_t devices[WVR_DEVICE_COUNT_LEVEL_1]; + WVR_GetSyncPose(WVR_PoseOriginModel_OriginOnHead, devices, WVR_DEVICE_COUNT_LEVEL_1); + + LOG("WVR RENDER FRAME"); + for (int eye = 0; eye < 2; eye++) + { + int i = WVR_GetAvailableTextureIndex(tq[eye]); + auto t = WVR_GetTexture(tq[eye], i); + WVR_SubmitError e; + e = WVR_SubmitFrame((WVR_Eye)eye, &t, &devices[WVR_DEVICE_HMD].pose); + if (e != WVR_SubmitError_None) + { + LOG("submit error: %d", (int)e) + running = false; + break; + } + } + glClearColor(0, 1, 0, 1); + glClear(GL_COLOR_BUFFER_BIT); + glFinish(); + android_async_unlock(); + } + LOG("WVR render loop finished"); + return 0; +} + +void wave_init(JavaVM* vm, JNIEnv* jni, jobject activity_class) +{ + //vr_main(0, nullptr); + /* + java.Vm = vm; + java.Env = jni; + java.ActivityObject = activity_class; + + LOG("init OVR"); + const ovrInitParms initParms = vrapi_DefaultInitParms( &java ); + int32_t initResult = vrapi_Initialize( &initParms ); + if ( initResult != VRAPI_INITIALIZE_SUCCESS ) + { + // If intialization failed, vrapi_* function calls will not be available. + exit( 0 ); + } + auto result = ovr_PlatformInitializeAndroid("1687982804637910", activity_class, jni); + LOG("ovr_PlatformInitializeAndroid result %d", result); + */ + LOG("WVR register main"); + //WVR_RegisterMain(vr_main); +} + +void wave_init_vr(EGLDisplay display, EGLContext context, ANativeWindow* surface) +{ + vr_main(0, nullptr); + /* + LOG("init swapchain"); + int rtt_w = vrapi_GetSystemPropertyInt(&java, VRAPI_SYS_PROP_SUGGESTED_EYE_TEXTURE_WIDTH); + int rtt_h = vrapi_GetSystemPropertyInt(&java, VRAPI_SYS_PROP_SUGGESTED_EYE_TEXTURE_HEIGHT); + LOG("ovr suggested texture size %d %d", rtt_w, rtt_h); + for (int eye = 0; eye < 2; eye++) + { + swap_chain[eye] = vrapi_CreateTextureSwapChain3(VRAPI_TEXTURE_TYPE_2D, GL_RGBA8, rtt_w, rtt_h, 1, 3); + swap_chain_count = vrapi_GetTextureSwapChainLength(swap_chain[eye]); + for (int i = 0; i < swap_chain_count; i++) + { + auto texid = vrapi_GetTextureSwapChainHandle(swap_chain[eye], i); + if (ovr_eyes[i][eye].create(rtt_w, rtt_h, texid, GL_RGBA8, true)) + { + ovr_eyes[i][eye].bindTexture(); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + ovr_eyes[i][eye].unbindTexture(); + LOG("create eye %d", eye); + } + else + { + LOG("FAILED create fb for eye %d", eye); + } + } + } + + LOG("vrapi_DefaultModeParms"); + ovrModeParms parms = vrapi_DefaultModeParms( &java ); + // No need to reset the FLAG_FULLSCREEN window flag when using a View + //parms.Flags &= ~VRAPI_MODE_FLAG_RESET_WINDOW_FULLSCREEN; + + parms.Flags |= VRAPI_MODE_FLAG_NATIVE_WINDOW; + parms.Display = (size_t)display; + parms.WindowSurface = (size_t)surface; + parms.ShareContext = (size_t)context; + LOG("enter vr mode"); + ovr_context = vrapi_EnterVrMode(&parms); + if (!ovr_context) + { + LOG("EnterVRMode FAILED"); + } + LOG("vr mode entered"); + + vrapi_SetClockLevels(ovr_context, 2, 2); + vrapi_SetPerfThread(ovr_context, VRAPI_PERF_THREAD_TYPE_MAIN, gettid()); + vrapi_SetPerfThread(ovr_context, VRAPI_PERF_THREAD_TYPE_RENDERER, 0); + */ +} + +void wave_release_vr() +{ + /* + vrapi_LeaveVrMode(ovr_context); + ovr_context = nullptr; + for (int eye = 0; eye < 2; eye++) + { + vrapi_DestroyTextureSwapChain(swap_chain[eye]); + swap_chain[eye] = nullptr; + for (int i = 0; i < swap_chain_count; i++) + ovr_eyes[eye][i].destroy(); + } + swap_chain_index = 0; + swap_chain_count = 0; + LOG("leave vr mode"); + */ +} + +void wave_draw(float dt) +{ + /* + const double predictedDisplayTime = vrapi_GetPredictedDisplayTime(ovr_context, ovr_frame); + const ovrTracking2 tracking = vrapi_GetPredictedTracking2(ovr_context, predictedDisplayTime); + auto pose_ovr = ovrMatrix4f_CreateFromQuaternion(&tracking.HeadPose.Pose.Orientation); + auto pose_ovr_tp = ovrMatrix4f_Transpose(&pose_ovr); + glm::mat4 pose = glm::make_mat4(reinterpret_cast(&pose_ovr_tp)); + glm::vec3 head_pos = glm::make_vec3((float*)&tracking.HeadPose.Pose.Position); + + if (controllers[0].id == -1) + { + // init controller + ovrInputCapabilityHeader capsHeader; + for (int i = 0; ; i++) + { + if ( vrapi_EnumerateInputDevices( ovr_context, i, &capsHeader ) >= 0 ) + { + if ( capsHeader.Type == ovrControllerType_TrackedRemote ) + { + ovrInputTrackedRemoteCapabilities remoteCaps; + remoteCaps.Header = capsHeader; + if ( vrapi_GetInputDeviceCapabilities( ovr_context, &remoteCaps.Header ) >= 0 ) + { + // remote is connected + if (remoteCaps.ControllerCapabilities & ovrControllerCaps_RightHand) + { + // right controller found + controllers[0].id = capsHeader.DeviceID; + LOG("found controller id %d", (int)controllers[0].id); + break; + } + } + } + } + else + { + break; + } + } + } + + if (controllers[0].id != -1) + { + controllers[0].update_state(predictedDisplayTime, head_pos); + App::I.vr_controllers[0] = controllers[0]; + } + App::I.vr_head = pose; + App::I.vr_update(dt); + + // update hmd + auto layer = vrapi_DefaultLayerProjection2(); + //ovrVector4f red = {1, 1, 0, 1}; + //auto layer = vrapi_DefaultLayerSolidColorProjection2(&red); + layer.HeadPose = tracking.HeadPose; + for (int eye = 0; eye < 2; eye++) + { + auto& rtt = ovr_eyes[swap_chain_index][eye]; + rtt.bindFramebuffer(); + rtt.clear({1, 0, 1, 1}); + glViewport(0, 0, rtt.getWidth(), rtt.getHeight()); + auto proj_ovr = ovrMatrix4f_Transpose(&tracking.Eye[eye].ProjectionMatrix); + glm::mat4 proj = glm::make_mat4(reinterpret_cast(&proj_ovr)); + auto view_ovr = ovrMatrix4f_Transpose(&tracking.Eye[eye].ViewMatrix); + glm::mat4 view = glm::make_mat4(reinterpret_cast(&view_ovr)); + App::I.vr_draw(proj, view, pose); + rtt.unbindFramebuffer(); + layer.Textures[eye].ColorSwapChain = swap_chain[eye]; + layer.Textures[eye].SwapChainIndex = swap_chain_index; + layer.Textures[eye].TexCoordsFromTanAngles = + ovrMatrix4f_TanAngleMatrixFromProjection(&tracking.Eye[eye].ProjectionMatrix); + } + layer.Header.Flags |= VRAPI_FRAME_LAYER_FLAG_CHROMATIC_ABERRATION_CORRECTION; + + const ovrLayerHeader2 * layers[] = { &layer.Header }; + + ovrSubmitFrameDescription2 frameDesc = { 0 }; + frameDesc.Flags = 0; + frameDesc.SwapInterval = 1; + frameDesc.FrameIndex = ovr_frame; + frameDesc.DisplayTime = predictedDisplayTime; + frameDesc.LayerCount = 1; + frameDesc.Layers = layers; + + vrapi_SubmitFrame2(ovr_context, &frameDesc); + + ovr_frame++; + swap_chain_index = (swap_chain_index + 1) % swap_chain_count; + */ +} diff --git a/android/focus/src/main/cpp/wave_vr.h b/android/focus/src/main/cpp/wave_vr.h new file mode 100644 index 0000000..a8cfd0a --- /dev/null +++ b/android/focus/src/main/cpp/wave_vr.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +void wave_init(JavaVM* vm, JNIEnv* jni, jobject activity_class); +void wave_init_vr(EGLDisplay display, EGLContext context, ANativeWindow* surface); +void wave_release_vr(); +void wave_draw(float dt); diff --git a/android/focus/src/main/java/com/omixlab/panopainter/Platform.java b/android/focus/src/main/java/com/omixlab/panopainter/Platform.java new file mode 100644 index 0000000..f84e928 --- /dev/null +++ b/android/focus/src/main/java/com/omixlab/panopainter/Platform.java @@ -0,0 +1,5 @@ +package com.omixlab.panopainter; + +public class Platform { + public static final String[] Libs = new String[]{"wvr_api"}; +} diff --git a/android/focus/src/main/java/com/omixlab/panopainter/PlatformActivity.java b/android/focus/src/main/java/com/omixlab/panopainter/PlatformActivity.java new file mode 100644 index 0000000..ef9627b --- /dev/null +++ b/android/focus/src/main/java/com/omixlab/panopainter/PlatformActivity.java @@ -0,0 +1,9 @@ +package com.omixlab.panopainter; + +import com.htc.vr.sdk.VR; +import com.htc.vr.sdk.VRActivity; +import com.htc.vr.sdk.VRNativeActivity; +import com.omixlab.panopainter.Platform; + +public class PlatformActivity extends VRActivity { +} diff --git a/android/quest/build.gradle b/android/quest/build.gradle index 49575cc..ab5ff0c 100644 --- a/android/quest/build.gradle +++ b/android/quest/build.gradle @@ -83,7 +83,7 @@ android { // Sets optional flags for the C compiler. //cFlags "-D_EXAMPLE_C_FLAG1", "-D_EXAMPLE_C_FLAG2" // Sets a flag to enable format macro constants for the C++ compiler. - cppFlags "-D__QUEST__" + cppFlags "-D__QUEST__=1" arguments "-DANDROID_TOOLCHAIN=clang", //"-DANDROID_PLATFORM=android-19", "-DANDROID_STL=c++_shared", diff --git a/android/quest/src/main/cpp/oculus_vr.cpp b/android/quest/src/main/cpp/oculus_vr.cpp index be8b199..5e322d0 100644 --- a/android/quest/src/main/cpp/oculus_vr.cpp +++ b/android/quest/src/main/cpp/oculus_vr.cpp @@ -44,12 +44,12 @@ struct QuestController : public VRController if (pressed && !m_buttons[(int)b]) { m_buttons[(int)b] = true; - App::I.vr_digital(*this, b, kAction::Press, axis); + App::I->vr_digital(*this, b, kAction::Press, axis); } if (!pressed && m_buttons[(int)b]) { m_buttons[(int)b] = false; - App::I.vr_digital(*this, b, kAction::Release, axis); + App::I->vr_digital(*this, b, kAction::Release, axis); } } void update_analog(kButton b, glm::vec2 force) @@ -59,12 +59,12 @@ struct QuestController : public VRController if (l > zero && !m_analog_buttons[(int)b]) { m_analog_buttons[(int)b] = true; - App::I.vr_analog(*this, b, kAction::Press, force); + App::I->vr_analog(*this, b, kAction::Press, force); } if (l <= zero && m_analog_buttons[(int)b]) { m_analog_buttons[(int)b] = false; - App::I.vr_analog(*this, b, kAction::Release, force); + App::I->vr_analog(*this, b, kAction::Release, force); } } @@ -205,10 +205,10 @@ void oculus_draw(float dt) if (controllers[0].id != -1) { controllers[0].update_state(predictedDisplayTime, head_pos); - App::I.vr_controllers[0] = controllers[0]; + App::I->vr_controllers[0] = controllers[0]; } - App::I.vr_head = pose; - App::I.vr_update(dt); + App::I->vr_head = pose; + App::I->vr_update(dt); // update hmd auto layer = vrapi_DefaultLayerProjection2(); @@ -225,7 +225,7 @@ void oculus_draw(float dt) glm::mat4 proj = glm::make_mat4(reinterpret_cast(&proj_ovr)); auto view_ovr = ovrMatrix4f_Transpose(&tracking.Eye[eye].ViewMatrix); glm::mat4 view = glm::make_mat4(reinterpret_cast(&view_ovr)); - App::I.vr_draw(proj, view, pose); + App::I->vr_draw(proj, view, pose); rtt.unbindFramebuffer(); layer.Textures[eye].ColorSwapChain = swap_chain[eye]; layer.Textures[eye].SwapChainIndex = swap_chain_index; diff --git a/android/quest/src/main/java/com/omixlab/panopainter/PlatformActivity.java b/android/quest/src/main/java/com/omixlab/panopainter/PlatformActivity.java new file mode 100644 index 0000000..9b9a805 --- /dev/null +++ b/android/quest/src/main/java/com/omixlab/panopainter/PlatformActivity.java @@ -0,0 +1,6 @@ +package com.omixlab.panopainter; + +import android.app.NativeActivity; + +public class PlatformActivity extends NativeActivity { +} diff --git a/android/src/cpp/main.cpp b/android/src/cpp/main.cpp index 7aeeadc..95ac54c 100644 --- a/android/src/cpp/main.cpp +++ b/android/src/cpp/main.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include // for prctl( PR_SET_NAME ) #include @@ -37,6 +38,8 @@ #ifdef __QUEST__ #include "oculus_vr.h" +#elif __FOCUS__ +#include "wave_vr.h" #endif typedef void (*GLDEBUGPROC)(GLenum source, @@ -234,6 +237,13 @@ std::function pick_file_callback; std::function pick_file_callback_context; extern "C" { +#ifdef __FOCUS__ +JNIEXPORT void JNICALL Java_com_omixlab_panopainter_MainActivity_init_vr(JNIEnv *env, jobject activity, jobject am) +{ + Asset::m_am = AAssetManager_fromJava(env, am); + wave_init(0, 0, 0); +} +#endif JNIEXPORT void JNICALL Java_com_omixlab_panopainter_MainActivity_pickFileCallback(JNIEnv *env, jobject, jstring path) { const char* path_utf = env->GetStringUTFChars(path, nullptr); @@ -538,6 +548,8 @@ static int engine_init_display(struct engine* engine) { #ifdef __QUEST__ oculus_init_vr(display, context, engine->app->window); +#elif __FOCUS__ + wave_init_vr(display, context, engine->app->window); #endif if (resuming_context) @@ -663,7 +675,7 @@ static int engine_init_display(struct engine* engine) { #else float density = get_display_density(); LOG("density %f", density); - App::I->zoom = density;// / 1.5; + App::I->zoom = density / 1.5; App::I->width = w; App::I->height = h; App::I->redraw = true; @@ -1017,6 +1029,8 @@ void android_main(struct android_app* state) { #ifdef __QUEST__ oculus_init(state->activity->vm, jni, state->activity->clazz); +#elif __FOCUS__ + wave_init(state->activity->vm, jni, state->activity->clazz); #endif // Note that AttachCurrentThread will reset the thread name. diff --git a/android/src/java/com/omixlab/panopainter/MainActivity.java b/android/src/java/com/omixlab/panopainter/MainActivity.java index 63ab78f..ad80763 100644 --- a/android/src/java/com/omixlab/panopainter/MainActivity.java +++ b/android/src/java/com/omixlab/panopainter/MainActivity.java @@ -1,11 +1,11 @@ package com.omixlab.panopainter; import android.Manifest; -import android.app.NativeActivity; import android.content.ClipData; import android.content.ClipboardManager; import android.content.Intent; import android.content.pm.PackageManager; +import android.content.res.AssetManager; import android.graphics.Rect; import android.net.Uri; import android.os.Bundle; @@ -16,9 +16,7 @@ import android.view.ViewTreeObserver; import java.io.File; -import com.omixlab.panopainter.Platform; - -public class MainActivity extends NativeActivity { +public class MainActivity extends PlatformActivity { static { for (String lib : Platform.Libs) System.loadLibrary(lib); @@ -29,6 +27,7 @@ public class MainActivity extends NativeActivity { @Override protected void onCreate(Bundle savedInstanceState) { + //init_vr(getAssets()); super.onCreate(savedInstanceState); clipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE); checkPermissionReadStorage(); @@ -50,6 +49,7 @@ public class MainActivity extends NativeActivity { }); } + public native void init_vr(AssetManager am); public native void pickFileCallback(String path); public native void pickExternalCallback(String path); public native void contentRectChanged(int wnd_w, int wnd_h, int rect_left, int rect_top, int rect_right, int rect_bottom); diff --git a/libs/wave_sdk b/libs/wave_sdk new file mode 160000 index 0000000..b47b1a2 --- /dev/null +++ b/libs/wave_sdk @@ -0,0 +1 @@ +Subproject commit b47b1a2aa08d2a0ca476500526503661a8156976 diff --git a/src/app_cloud.cpp b/src/app_cloud.cpp index 77a739b..aadf262 100644 --- a/src/app_cloud.cpp +++ b/src/app_cloud.cpp @@ -25,7 +25,7 @@ void App::cloud_upload() if (Canvas::I->m_unsaved) { - Canvas::I->project_save_thread(doc_path); + Canvas::I->project_save_thread(doc_path, true); } auto pb = show_progress("Uploading"); diff --git a/src/canvas.cpp b/src/canvas.cpp index 4711ab5..93b873f 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -2275,7 +2275,7 @@ void Canvas::project_save(std::function on_complete) { std::thread t([=] { BT_SetTerminate(); - bool ret = project_save_thread(App::I->doc_path); + bool ret = project_save_thread(App::I->doc_path, true); if (on_complete) on_complete(ret); }); @@ -2290,7 +2290,7 @@ void Canvas::project_save(std::string file_path, std::function on_co { std::thread t([=] { BT_SetTerminate(); - bool ret = project_save_thread(file_path); + bool ret = project_save_thread(file_path, true); if (on_complete) on_complete(ret); }); @@ -2302,7 +2302,7 @@ void Canvas::project_save(std::string file_path, std::function on_co } } -bool Canvas::project_save_thread(std::string file_path) +bool Canvas::project_save_thread(std::string file_path, bool show_progress) { // already saved, nothing to do if (!m_unsaved && file_path == App::I->doc_path) @@ -2355,14 +2355,10 @@ bool Canvas::project_save_thread(std::string file_path) // load thumbnail Image thumb = thumbnail_generate(ppi_header.thumb_header.width, ppi_header.thumb_header.height); - auto pb = std::make_shared(); - pb->m_manager = &App::I->layout; - pb->init(); - pb->create(); - pb->loaded(); - pb->m_progress->SetWidthP(0); - pb->m_title->set_text("Saving Pano Project"); - App::I->layout[App::I->main_id]->add_child(pb); + + std::shared_ptr pb; + if (show_progress) + pb = App::I->show_progress("Saving Pano Project"); thumb.flip(); fwrite(thumb.data(), thumb.size(), 1, fp); @@ -2423,7 +2419,8 @@ bool Canvas::project_save_thread(std::string file_path) } progress++; float p = (float)progress / total * 100.f; - pb->m_progress->SetWidthP(p); + if (show_progress) + pb->m_progress->SetWidthP(p); LOG("progress: %f", p); } } @@ -2464,7 +2461,8 @@ bool Canvas::project_save_thread(std::string file_path) m_newdoc = false; } - pb->destroy(); + if (show_progress) + pb->destroy(); App::I->title_update(); return success; diff --git a/src/canvas.h b/src/canvas.h index ffe29e2..e7953ff 100644 --- a/src/canvas.h +++ b/src/canvas.h @@ -210,7 +210,7 @@ public: void export_cubes(); void project_save(std::function on_complete = nullptr); void project_save(std::string file_path, std::function on_complete = nullptr); - bool project_save_thread(std::string file_path); + bool project_save_thread(std::string file_path, bool show_progress); void project_open(std::string file_path, std::function on_complete = nullptr); bool project_open_thread(std::string file_path); void inject_xmp(std::string jpg_path); diff --git a/src/main.cpp b/src/main.cpp index de9bef7..88e7269 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -531,7 +531,7 @@ static void SetupExceptionHandler() oss << std::put_time(&tm, "%d-%m-%Y %H-%M-%S"); auto path = App::I->data_path + "/" + App::I->doc_name + "-recovery (" + oss.str() + ").ppi"; - Canvas::I->project_save_thread(path); + Canvas::I->project_save_thread(path, false); static char abspath[MAX_PATH]; GetFullPathNameA(path.c_str(), MAX_PATH, abspath, NULL); static char message[4096]; diff --git a/src/node_panel_grid.cpp b/src/node_panel_grid.cpp index 6712bc2..086503e 100644 --- a/src/node_panel_grid.cpp +++ b/src/node_panel_grid.cpp @@ -137,13 +137,10 @@ void NodePanelGrid::init_controls() }; m_commit->on_click = [this](Node*) { - gl_state gl; - gl.save(); Canvas::I->draw_objects([this](const glm::mat4& camera, const glm::mat4& proj, int i) { draw_heightmap(proj, camera, true); }); m_groud_opacity->set_value(0); - gl.restore(); }; m_hm_texres->on_select = [this](Node*, int index) { int texres = get_texres();