From 77d4060fdb8b78ac2e1bdfeffaa9d75502bb3861 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Thu, 21 Feb 2019 11:37:50 -0800 Subject: [PATCH 01/33] bypassing onStop invoke.Delegate command which prevents the disconnect from Java hooks that are not initiated on restart. On Destroy, the onstop function is called to allow the hooks to finally disconnect and then terminate the app. --- .../oculus/OculusMobileActivity.java | 24 +++++++++++-------- .../qt5/android/bindings/QtActivity.java | 7 +++++- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/android/libraries/oculus/src/main/java/io/highfidelity/oculus/OculusMobileActivity.java b/android/libraries/oculus/src/main/java/io/highfidelity/oculus/OculusMobileActivity.java index 9ab07bb4dd..2aa7b4da05 100644 --- a/android/libraries/oculus/src/main/java/io/highfidelity/oculus/OculusMobileActivity.java +++ b/android/libraries/oculus/src/main/java/io/highfidelity/oculus/OculusMobileActivity.java @@ -34,7 +34,6 @@ public class OculusMobileActivity extends QtActivity implements SurfaceHolder.Ca private native void questNativeOnResume(); private native void questOnAppAfterLoad(); - private SurfaceView mView; private SurfaceHolder mSurfaceHolder; @@ -57,12 +56,15 @@ public class OculusMobileActivity extends QtActivity implements SurfaceHolder.Ca setContentView(mView); questOnAppAfterLoad(); }); + + } @Override protected void onDestroy() { Log.w(TAG, "QQQ onDestroy"); - + isPausing=false; + super.onStop(); nativeOnSurfaceChanged(null); Log.w(TAG, "QQQ onDestroy -- SUPER onDestroy"); @@ -78,6 +80,7 @@ public class OculusMobileActivity extends QtActivity implements SurfaceHolder.Ca questNativeOnResume(); nativeOnResume(); + isPausing=false; } @Override @@ -87,40 +90,41 @@ public class OculusMobileActivity extends QtActivity implements SurfaceHolder.Ca questNativeOnPause(); nativeOnPause(); + isPausing=true; } @Override protected void onStop(){ super.onStop(); - Log.w(TAG, "QQQ Onstop called"); + Log.w(TAG, "QQQ_ Onstop called"); } @Override - protected void onRestart(){ + protected void onRestart() { super.onRestart(); - Log.w(TAG, "QQQ onRestart called ****"); + Log.w(TAG, "QQQ_ onRestart called ****"); questOnAppAfterLoad(); } @Override public void surfaceCreated(SurfaceHolder holder) { - Log.w(TAG, "QQQ surfaceCreated ************************************"); + Log.w(TAG, "QQQ_ surfaceCreated ************************************"); nativeOnSurfaceChanged(holder.getSurface()); mSurfaceHolder = holder; } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { - Log.w(TAG, "QQQ surfaceChanged"); + Log.w(TAG, "QQQ_ surfaceChanged"); nativeOnSurfaceChanged(holder.getSurface()); mSurfaceHolder = holder; } @Override public void surfaceDestroyed(SurfaceHolder holder) { - Log.w(TAG, "QQQ surfaceDestroyed ***************************************************"); - nativeOnSurfaceChanged(null); - mSurfaceHolder = null; + Log.w(TAG, "QQQ_ surfaceDestroyed ***************************************************"); + // nativeOnSurfaceChanged(null); + // mSurfaceHolder = null; } } \ No newline at end of file diff --git a/android/libraries/qt/src/main/java/org/qtproject/qt5/android/bindings/QtActivity.java b/android/libraries/qt/src/main/java/org/qtproject/qt5/android/bindings/QtActivity.java index 46f2af46e7..85e93a4267 100644 --- a/android/libraries/qt/src/main/java/org/qtproject/qt5/android/bindings/QtActivity.java +++ b/android/libraries/qt/src/main/java/org/qtproject/qt5/android/bindings/QtActivity.java @@ -70,6 +70,7 @@ public class QtActivity extends Activity { public final String QT_ANDROID_DEFAULT_THEME = QT_ANDROID_THEMES[0]; // sets the default theme. private QtActivityLoader m_loader = new QtActivityLoader(this); + public boolean isPausing=false; public QtActivity() { } @@ -650,9 +651,13 @@ public class QtActivity extends Activity { @Override protected void onStop() { super.onStop(); - QtApplication.invokeDelegate(); + + if(!isPausing){ + QtApplication.invokeDelegate(); + } } + //--------------------------------------------------------------------------- @Override From fe33aadd698c6cc415b960418ca7de111e877509 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 21 Feb 2019 14:58:06 -0800 Subject: [PATCH 02/33] Assigning the default world detail and max render rate target in vr quest --- interface/src/LODManager.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 559bae1779..5817eafc25 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -19,13 +19,20 @@ #include #include +#include + #ifdef Q_OS_ANDROID -const float LOD_DEFAULT_QUALITY_LEVEL = 0.75f; // default quality level setting is High (lower framerate) +const float LOD_DEFAULT_QUALITY_LEVEL = 0.2; // default quality level setting is High (lower framerate) #else const float LOD_DEFAULT_QUALITY_LEVEL = 0.5f; // default quality level setting is Mid #endif const float LOD_MAX_LIKELY_DESKTOP_FPS = 60.0f; // this is essentially, V-synch fps +#ifdef Q_OS_ANDROID +const float LOD_MAX_LIKELY_HMD_FPS = 36.0f; // this is essentially, V-synch fps +#else const float LOD_MAX_LIKELY_HMD_FPS = 90.0f; // this is essentially, V-synch fps +#endif + const float LOD_OFFSET_FPS = 5.0f; // offset of FPS to add for computing the target framerate class AABox; From 9097d9c57cdf1416c32e1a661144d096fd8f8f79 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Thu, 21 Feb 2019 16:33:25 -0800 Subject: [PATCH 03/33] working on pause -> away mode. Even doesn't seem to be firing. Also found a spot where I left commented out code from lifecycle testing. --- android/apps/questInterface/src/main/cpp/native.cpp | 6 +++++- .../io/highfidelity/oculus/OculusMobileActivity.java | 10 +++++++--- interface/src/AndroidHelper.cpp | 4 ++++ interface/src/AndroidHelper.h | 3 ++- interface/src/Application.cpp | 10 ++++++++++ interface/src/Application.h | 3 ++- scripts/+android_questInterface/defaultScripts.js | 4 ++-- scripts/system/away.js | 3 ++- 8 files changed, 34 insertions(+), 9 deletions(-) diff --git a/android/apps/questInterface/src/main/cpp/native.cpp b/android/apps/questInterface/src/main/cpp/native.cpp index 3c1563c93d..547874b84e 100644 --- a/android/apps/questInterface/src/main/cpp/native.cpp +++ b/android/apps/questInterface/src/main/cpp/native.cpp @@ -61,7 +61,7 @@ extern "C" { Java_io_highfidelity_oculus_OculusMobileActivity_nativeInitOculusPlatform(JNIEnv *env, jobject obj){ initOculusPlatform(env, obj); } -QAndroidJniObject __interfaceActivity; + QAndroidJniObject __interfaceActivity; JNIEXPORT void JNICALL Java_io_highfidelity_oculus_OculusMobileActivity_questNativeOnCreate(JNIEnv *env, jobject obj) { @@ -80,6 +80,10 @@ QAndroidJniObject __interfaceActivity; }); } + JNIEXPORT void JNICALL + Java_io_highfidelity_oculus_OculusMobileActivity_questNativeAwayMode(JNIEnv *env, jobject obj) { + AndroidHelper::instance().toggleAwayMode(); + } JNIEXPORT void Java_io_highfidelity_oculus_OculusMobileActivity_questOnAppAfterLoad(JNIEnv* env, jobject obj) { diff --git a/android/libraries/oculus/src/main/java/io/highfidelity/oculus/OculusMobileActivity.java b/android/libraries/oculus/src/main/java/io/highfidelity/oculus/OculusMobileActivity.java index 2aa7b4da05..71ccfa84cd 100644 --- a/android/libraries/oculus/src/main/java/io/highfidelity/oculus/OculusMobileActivity.java +++ b/android/libraries/oculus/src/main/java/io/highfidelity/oculus/OculusMobileActivity.java @@ -34,6 +34,7 @@ public class OculusMobileActivity extends QtActivity implements SurfaceHolder.Ca private native void questNativeOnResume(); private native void questOnAppAfterLoad(); + private native void questNativeAwayMode(); private SurfaceView mView; private SurfaceHolder mSurfaceHolder; @@ -55,6 +56,7 @@ public class OculusMobileActivity extends QtActivity implements SurfaceHolder.Ca runOnUiThread(() -> { setContentView(mView); questOnAppAfterLoad(); + }); @@ -91,12 +93,14 @@ public class OculusMobileActivity extends QtActivity implements SurfaceHolder.Ca questNativeOnPause(); nativeOnPause(); isPausing=true; + } @Override protected void onStop(){ super.onStop(); Log.w(TAG, "QQQ_ Onstop called"); + questNativeAwayMode(); } @Override @@ -104,6 +108,7 @@ public class OculusMobileActivity extends QtActivity implements SurfaceHolder.Ca super.onRestart(); Log.w(TAG, "QQQ_ onRestart called ****"); questOnAppAfterLoad(); + questNativeAwayMode(); } @Override @@ -123,8 +128,7 @@ public class OculusMobileActivity extends QtActivity implements SurfaceHolder.Ca @Override public void surfaceDestroyed(SurfaceHolder holder) { Log.w(TAG, "QQQ_ surfaceDestroyed ***************************************************"); - // nativeOnSurfaceChanged(null); - // mSurfaceHolder = null; - + nativeOnSurfaceChanged(null); + mSurfaceHolder = null; } } \ No newline at end of file diff --git a/interface/src/AndroidHelper.cpp b/interface/src/AndroidHelper.cpp index 4f75d5bdb2..e5007d706e 100644 --- a/interface/src/AndroidHelper.cpp +++ b/interface/src/AndroidHelper.cpp @@ -45,6 +45,10 @@ void AndroidHelper::notifyBeforeEnterBackground() { emit beforeEnterBackground(); } +void AndroidHelper::notifyToggleAwayMode() { + emit toggleAwayMode(); +} + void AndroidHelper::notifyEnterBackground() { emit enterBackground(); } diff --git a/interface/src/AndroidHelper.h b/interface/src/AndroidHelper.h index f1cec6a43b..fca035a217 100644 --- a/interface/src/AndroidHelper.h +++ b/interface/src/AndroidHelper.h @@ -31,6 +31,7 @@ public: void notifyEnterForeground(); void notifyBeforeEnterBackground(); void notifyEnterBackground(); + void notifyToggleAwayMode(); void performHapticFeedback(int duration); void processURL(const QString &url); @@ -55,7 +56,7 @@ signals: void enterForeground(); void beforeEnterBackground(); void enterBackground(); - + void toggleAwayMode(); void hapticFeedbackRequested(int duration); void handleSignupCompleted(); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a611738445..a8d0cf6125 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2411,6 +2411,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo connect(&AndroidHelper::instance(), &AndroidHelper::beforeEnterBackground, this, &Application::beforeEnterBackground); connect(&AndroidHelper::instance(), &AndroidHelper::enterBackground, this, &Application::enterBackground); connect(&AndroidHelper::instance(), &AndroidHelper::enterForeground, this, &Application::enterForeground); + connect(&AndroidHelper::instance(), &AndroidHelper::toggleAwayMode, this, &Application::toggleAwayMode); + AndroidHelper::instance().notifyLoadComplete(); #endif pauseUntilLoginDetermined(); @@ -9135,6 +9137,8 @@ void Application::beforeEnterBackground() { clearDomainOctreeDetails(); } + + void Application::enterBackground() { QMetaObject::invokeMethod(DependencyManager::get().data(), "stop", Qt::BlockingQueuedConnection); @@ -9160,4 +9164,10 @@ void Application::enterForeground() { } #endif +void Application::toggleAwayMode(){ + auto key = QKeyEvent(QEvent::KeyPress,Qt::Key_Escape,Qt::NoModifier); + _keyboardMouseDevice->keyPressEvent(&key); + qDebug()<<"QQQ_ AWAY MODE "; +} + #include "Application.moc" diff --git a/interface/src/Application.h b/interface/src/Application.h index afd9f5f12f..d856297e41 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -338,7 +338,8 @@ public: void beforeEnterBackground(); void enterBackground(); void enterForeground(); -#endif + void toggleAwayMode(); + #endif signals: void svoImportRequested(const QString& url); diff --git a/scripts/+android_questInterface/defaultScripts.js b/scripts/+android_questInterface/defaultScripts.js index d22716302c..e996f71908 100644 --- a/scripts/+android_questInterface/defaultScripts.js +++ b/scripts/+android_questInterface/defaultScripts.js @@ -14,8 +14,8 @@ var DEFAULT_SCRIPTS_COMBINED = [ "system/request-service.js", "system/progress.js", - //"system/away.js", - "system/hmd.js", + "system/away.js", + //"system/hmd.js", "system/menu.js", "system/bubble.js", "system/pal.js", // "system/mod.js", // older UX, if you prefer diff --git a/scripts/system/away.js b/scripts/system/away.js index 45b6f43b73..c75d58a240 100644 --- a/scripts/system/away.js +++ b/scripts/system/away.js @@ -154,7 +154,7 @@ function goAway(fromStartup) { if (!isEnabled || isAway) { return; } - + console.warn('QQQ_ JS going away); // If we're entering away mode from some other state than startup, then we create our move timer immediately. // However if we're just stating up, we need to delay this process so that we don't think the initial teleport // is actually a move. @@ -176,6 +176,7 @@ function goActive() { return; } + console.warn('QQQ_ JS going active); UserActivityLogger.toggledAway(false); MyAvatar.isAway = false; From 94fc60f28517a2409be134ebfe359fedb09f507f Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 21 Feb 2019 16:34:50 -0800 Subject: [PATCH 04/33] Bad idea to include global here --- interface/src/LODManager.h | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 5817eafc25..87e871a3ab 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -19,7 +19,6 @@ #include #include -#include #ifdef Q_OS_ANDROID const float LOD_DEFAULT_QUALITY_LEVEL = 0.2; // default quality level setting is High (lower framerate) From ddc42585d81e53386c2213b4a8af3aaacc3430a6 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Thu, 21 Feb 2019 16:41:50 -0800 Subject: [PATCH 05/33] Cleanup syntax --- interface/src/LODManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 87e871a3ab..77cb1a0d39 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -21,7 +21,7 @@ #ifdef Q_OS_ANDROID -const float LOD_DEFAULT_QUALITY_LEVEL = 0.2; // default quality level setting is High (lower framerate) +const float LOD_DEFAULT_QUALITY_LEVEL = 0.2f; // default quality level setting is High (lower framerate) #else const float LOD_DEFAULT_QUALITY_LEVEL = 0.5f; // default quality level setting is Mid #endif From ae6a73c71033cd0d4815a7e7f754a8793e835f46 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 21 Feb 2019 16:42:47 -0800 Subject: [PATCH 06/33] Automatically go to quest-dev domain on startup --- .../src/OculusMobileDisplayPlugin.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp b/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp index 78d80443d8..bc8e1a5113 100644 --- a/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp +++ b/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp @@ -168,10 +168,8 @@ bool OculusMobileDisplayPlugin::isHmdMounted() const { static void goToDevMobile() { auto addressManager = DependencyManager::get(); auto currentAddress = addressManager->currentAddress().toString().toStdString(); - if (std::string::npos == currentAddress.find("dev-mobile")) { - addressManager->handleLookupString("hifi://dev-mobile/495.236,501.017,482.434/0,0.97452,0,-0.224301"); - //addressManager->handleLookupString("hifi://dev-mobile/504,498,491/0,0,0,0"); - //addressManager->handleLookupString("hifi://dev-mobile/0,-1,1"); + if (std::string::npos == currentAddress.find("quest-dev")) { + addressManager->handleLookupString("hifi://quest-dev"); } } @@ -217,12 +215,12 @@ bool OculusMobileDisplayPlugin::beginFrameRender(uint32_t frameIndex) { }); } - // static uint32_t count = 0; - // if ((++count % 1000) == 0) { - // AbstractViewStateInterface::instance()->postLambdaEvent([] { - // goToDevMobile(); - // }); - // } + static uint32_t count = 0; + if ((++count % 1000) == 0) { + AbstractViewStateInterface::instance()->postLambdaEvent([] { + goToDevMobile(); + }); + } return result && Parent::beginFrameRender(frameIndex); } From f04fdb2187a8d30fb50ffaf23d2254ee2d729307 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Fri, 22 Feb 2019 09:11:24 -0800 Subject: [PATCH 07/33] added esc key event to fire for the away animation when cycling pause/resume. Reverted change on surface destroy that nullified the surface. Forgot to remove that during testin. Removed comment in away.js with syntax error. Setting cpu/gpu levels back to 1/1 after vr mode is released. Noticed that OS stays in same cpu/gpu level after app closes. Hoping this will help reduce battery drain for user --- interface/src/Application.cpp | 12 ++++++++---- libraries/oculusMobile/src/ovr/VrHandler.cpp | 4 ++++ scripts/system/away.js | 3 +-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a8d0cf6125..730f1007a4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1756,6 +1756,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo #endif }); + // Setup the _keyboardMouseDevice, _touchscreenDevice, _touchscreenVirtualPadDevice and the user input mapper with the default bindings userInputMapper->registerDevice(_keyboardMouseDevice->getInputDevice()); // if the _touchscreenDevice is not supported it will not be registered @@ -9162,12 +9163,15 @@ void Application::enterForeground() { auto nodeList = DependencyManager::get(); nodeList->setSendDomainServerCheckInEnabled(true); } -#endif + void Application::toggleAwayMode(){ - auto key = QKeyEvent(QEvent::KeyPress,Qt::Key_Escape,Qt::NoModifier); - _keyboardMouseDevice->keyPressEvent(&key); - qDebug()<<"QQQ_ AWAY MODE "; + QKeyEvent event = QKeyEvent (QEvent::KeyPress, Qt::Key_Escape, Qt::NoModifier); + QCoreApplication::sendEvent (this, &event); } + +#endif + + #include "Application.moc" diff --git a/libraries/oculusMobile/src/ovr/VrHandler.cpp b/libraries/oculusMobile/src/ovr/VrHandler.cpp index b3b1416785..3fe3901517 100644 --- a/libraries/oculusMobile/src/ovr/VrHandler.cpp +++ b/libraries/oculusMobile/src/ovr/VrHandler.cpp @@ -140,7 +140,11 @@ struct VrSurface : public TaskQueue { if (vrReady != vrRunning) { if (vrRunning) { __android_log_write(ANDROID_LOG_WARN, "QQQ_OVR", "vrapi_LeaveVrMode"); + vrapi_SetClockLevels(session, 1, 1); + vrapi_SetExtraLatencyMode(session, VRAPI_EXTRA_LATENCY_MODE_OFF); + vrapi_SetDisplayRefreshRate(session, 60); vrapi_LeaveVrMode(session); + session = nullptr; oculusActivity = nullptr; } else { diff --git a/scripts/system/away.js b/scripts/system/away.js index c75d58a240..2407678bb7 100644 --- a/scripts/system/away.js +++ b/scripts/system/away.js @@ -154,7 +154,7 @@ function goAway(fromStartup) { if (!isEnabled || isAway) { return; } - console.warn('QQQ_ JS going away); + // If we're entering away mode from some other state than startup, then we create our move timer immediately. // However if we're just stating up, we need to delay this process so that we don't think the initial teleport // is actually a move. @@ -176,7 +176,6 @@ function goActive() { return; } - console.warn('QQQ_ JS going active); UserActivityLogger.toggledAway(false); MyAvatar.isAway = false; From 9c833f7e64f575912216ee9593e13de6e23331a9 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Fri, 22 Feb 2019 09:21:51 -0800 Subject: [PATCH 08/33] clean up --- .../java/io/highfidelity/oculus/OculusMobileActivity.java | 5 +---- interface/src/Application.cpp | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/android/libraries/oculus/src/main/java/io/highfidelity/oculus/OculusMobileActivity.java b/android/libraries/oculus/src/main/java/io/highfidelity/oculus/OculusMobileActivity.java index 71ccfa84cd..7672ddf271 100644 --- a/android/libraries/oculus/src/main/java/io/highfidelity/oculus/OculusMobileActivity.java +++ b/android/libraries/oculus/src/main/java/io/highfidelity/oculus/OculusMobileActivity.java @@ -51,15 +51,13 @@ public class OculusMobileActivity extends QtActivity implements SurfaceHolder.Ca nativeOnCreate(); questNativeOnCreate(); } + public void onAppLoadedComplete() { Log.w(TAG, "QQQ Load Completed"); runOnUiThread(() -> { setContentView(mView); questOnAppAfterLoad(); - }); - - } @Override @@ -93,7 +91,6 @@ public class OculusMobileActivity extends QtActivity implements SurfaceHolder.Ca questNativeOnPause(); nativeOnPause(); isPausing=true; - } @Override diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 730f1007a4..e8fed1b2da 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -9166,7 +9166,7 @@ void Application::enterForeground() { void Application::toggleAwayMode(){ - QKeyEvent event = QKeyEvent (QEvent::KeyPress, Qt::Key_Escape, Qt::NoModifier); + QKeyEvent event = QKeyEvent (QEvent::KeyPress, Qt::Key_Escape, Qt::NoModifier); QCoreApplication::sendEvent (this, &event); } From aa8563f3feb96f2a9f7bc48bf7ff9acc0acff786 Mon Sep 17 00:00:00 2001 From: danteruiz Date: Fri, 22 Feb 2019 10:10:34 -0800 Subject: [PATCH 09/33] fix quest ui elements --- .../src/RenderablePolyLineEntityItem.cpp | 15 +++++++- .../src/RenderableShapeEntityItem.cpp | 9 ++++- .../entities-renderer/paintStroke_forward.slp | 1 + .../src/paintStroke_forward.slf | 35 +++++++++++++++++++ .../render-utils/src/RenderForwardTask.cpp | 2 +- 5 files changed, 59 insertions(+), 3 deletions(-) create mode 100644 libraries/entities-renderer/src/entities-renderer/paintStroke_forward.slp create mode 100644 libraries/entities-renderer/src/paintStroke_forward.slf diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index 64c05b576b..c4ea6a2fea 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -29,6 +29,13 @@ gpu::PipelinePointer PolyLineEntityRenderer::_glowPipeline = nullptr; static const QUrl DEFAULT_POLYLINE_TEXTURE = PathUtils::resourcesUrl("images/paintStroke.png"); +#if defined(USE_GLES) +static bool DISABLE_DEFERRED = true; +#else +static const QString RENDER_FORWARD{ "HIFI_RENDER_FORWARD" }; +static bool DISABLE_DEFERRED = QProcessEnvironment::systemEnvironment().contains(RENDER_FORWARD); +#endif + PolyLineEntityRenderer::PolyLineEntityRenderer(const EntityItemPointer& entity) : Parent(entity) { _texture = DependencyManager::get()->getTexture(DEFAULT_POLYLINE_TEXTURE); @@ -44,7 +51,13 @@ PolyLineEntityRenderer::PolyLineEntityRenderer(const EntityItemPointer& entity) void PolyLineEntityRenderer::buildPipeline() { // FIXME: opaque pipeline - gpu::ShaderPointer program = gpu::Shader::createProgram(shader::entities_renderer::program::paintStroke); + gpu::ShaderPointer program; + if (DISABLE_DEFERRED) { + program = gpu::Shader::createProgram(shader::entities_renderer::program::paintStroke_forward); + } else { + program = gpu::Shader::createProgram(shader::entities_renderer::program::paintStroke); + } + { gpu::StatePointer state = gpu::StatePointer(new gpu::State()); state->setCullMode(gpu::State::CullMode::CULL_NONE); diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index d42a766faa..c3dae762c5 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -30,6 +30,13 @@ using namespace render::entities; // is a half unit sphere. However, the geometry cache renders a UNIT sphere, so we need to scale down. static const float SPHERE_ENTITY_SCALE = 0.5f; +#if defined(USE_GLES) +static bool DISABLE_DEFERRED = true; +#else +static const QString RENDER_FORWARD{ "HIFI_RENDER_FORWARD" }; +static bool DISABLE_DEFERRED = QProcessEnvironment::systemEnvironment().contains(RENDER_FORWARD); +#endif + static_assert(shader::render_utils::program::simple != 0, "Validate simple program exists"); static_assert(shader::render_utils::program::simple_transparent != 0, "Validate simple transparent program exists"); @@ -276,7 +283,7 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { // FIXME, support instanced multi-shape rendering using multidraw indirect outColor.a *= _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f; render::ShapePipelinePointer pipeline; - if (_renderLayer == RenderLayer::WORLD) { + if (_renderLayer == RenderLayer::WORLD && !DISABLE_DEFERRED) { pipeline = outColor.a < 1.0f ? geometryCache->getTransparentShapePipeline() : geometryCache->getOpaqueShapePipeline(); } else { pipeline = outColor.a < 1.0f ? geometryCache->getForwardTransparentShapePipeline() : geometryCache->getForwardOpaqueShapePipeline(); diff --git a/libraries/entities-renderer/src/entities-renderer/paintStroke_forward.slp b/libraries/entities-renderer/src/entities-renderer/paintStroke_forward.slp new file mode 100644 index 0000000000..4d49e0d3a4 --- /dev/null +++ b/libraries/entities-renderer/src/entities-renderer/paintStroke_forward.slp @@ -0,0 +1 @@ +VERTEX paintStroke \ No newline at end of file diff --git a/libraries/entities-renderer/src/paintStroke_forward.slf b/libraries/entities-renderer/src/paintStroke_forward.slf new file mode 100644 index 0000000000..b949332826 --- /dev/null +++ b/libraries/entities-renderer/src/paintStroke_forward.slf @@ -0,0 +1,35 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// paintStroke.frag +// fragment shader +// +// Created by Eric Levin on 8/10/2015 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +<@include paintStroke.slh@> +<$declarePolyLineBuffers()$> + +LAYOUT(binding=0) uniform sampler2D _texture; + +layout(location=0) in vec3 _normalWS; +layout(location=1) in vec2 _texCoord; +layout(location=2) in vec4 _color; +layout(location=3) in float _distanceFromCenter; +layout(location=0) out vec4 _fragColor0; + +void main(void) { + vec4 texel = texture(_texture, _texCoord); + int frontCondition = 1 - 2 * int(gl_FrontFacing); + vec3 color = _color.rgb * texel.rgb; + float alpha = texel.a * _color.a; + + alpha *= mix(1.0, pow(1.0 - abs(_distanceFromCenter), 10.0), _polylineData.faceCameraGlow.y); + + _fragColor0 = vec4(color, alpha); +} diff --git a/libraries/render-utils/src/RenderForwardTask.cpp b/libraries/render-utils/src/RenderForwardTask.cpp index df82d4b56d..c6f49bc92a 100755 --- a/libraries/render-utils/src/RenderForwardTask.cpp +++ b/libraries/render-utils/src/RenderForwardTask.cpp @@ -101,7 +101,6 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend const auto inFrontOpaquesInputs = DrawLayered3D::Inputs(inFrontOpaque, lightingModel, nullJitter).asVarying(); const auto inFrontTransparentsInputs = DrawLayered3D::Inputs(inFrontTransparent, lightingModel, nullJitter).asVarying(); task.addJob("DrawInFrontOpaque", inFrontOpaquesInputs, true); - task.addJob("DrawInFrontTransparent", inFrontTransparentsInputs, false); // Draw opaques forward const auto opaqueInputs = DrawForward::Inputs(opaques, lightingModel).asVarying(); @@ -114,6 +113,7 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend // Draw transparent objects forward const auto transparentInputs = DrawForward::Inputs(transparents, lightingModel).asVarying(); task.addJob("DrawTransparents", transparentInputs, shapePlumber); + task.addJob("DrawInFrontTransparent", inFrontTransparentsInputs, false); { // Debug the bounds of the rendered items, still look at the zbuffer From 109eb6288682c4116deee1fdfd3741814144f3f9 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 22 Feb 2019 11:07:40 -0800 Subject: [PATCH 10/33] requested changes --- libraries/render-utils/src/RenderForwardTask.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/render-utils/src/RenderForwardTask.cpp b/libraries/render-utils/src/RenderForwardTask.cpp index c6f49bc92a..73692b41c2 100755 --- a/libraries/render-utils/src/RenderForwardTask.cpp +++ b/libraries/render-utils/src/RenderForwardTask.cpp @@ -96,12 +96,6 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend // draw a stencil mask in hidden regions of the framebuffer. task.addJob("PrepareStencil", framebuffer); - // Layered - const auto nullJitter = Varying(glm::vec2(0.0f, 0.0f)); - const auto inFrontOpaquesInputs = DrawLayered3D::Inputs(inFrontOpaque, lightingModel, nullJitter).asVarying(); - const auto inFrontTransparentsInputs = DrawLayered3D::Inputs(inFrontTransparent, lightingModel, nullJitter).asVarying(); - task.addJob("DrawInFrontOpaque", inFrontOpaquesInputs, true); - // Draw opaques forward const auto opaqueInputs = DrawForward::Inputs(opaques, lightingModel).asVarying(); task.addJob("DrawOpaques", opaqueInputs, shapePlumber); @@ -113,6 +107,12 @@ void RenderForwardTask::build(JobModel& task, const render::Varying& input, rend // Draw transparent objects forward const auto transparentInputs = DrawForward::Inputs(transparents, lightingModel).asVarying(); task.addJob("DrawTransparents", transparentInputs, shapePlumber); + + // Layered + const auto nullJitter = Varying(glm::vec2(0.0f, 0.0f)); + const auto inFrontOpaquesInputs = DrawLayered3D::Inputs(inFrontOpaque, lightingModel, nullJitter).asVarying(); + const auto inFrontTransparentsInputs = DrawLayered3D::Inputs(inFrontTransparent, lightingModel, nullJitter).asVarying(); + task.addJob("DrawInFrontOpaque", inFrontOpaquesInputs, true); task.addJob("DrawInFrontTransparent", inFrontTransparentsInputs, false); { // Debug the bounds of the rendered items, still look at the zbuffer From 87d98e5b858828bba6a21d73cb496e7aef0b967b Mon Sep 17 00:00:00 2001 From: amantley Date: Tue, 8 Jan 2019 15:26:46 -0800 Subject: [PATCH 11/33] These are the squashed commits for the ik optimization for the Quest Implmented using a new AnimSplineIK node in the anim graph (cherry picked from commit 4fe03ba238659fee7763991f2499a315482b351f) --- CMakeLists.txt | 8 +- .../avatar-animation_withSplineIKNode.json | 2229 +++++++++++++++++ interface/src/avatar/MyAvatar.cpp | 4 + interface/src/avatar/MySkeletonModel.cpp | 30 + libraries/animation/src/AnimContext.h | 1 + .../animation/src/AnimInverseKinematics.cpp | 5 + libraries/animation/src/AnimNodeLoader.cpp | 51 + .../src/AnimPoleVectorConstraint.cpp | 2 +- libraries/animation/src/AnimSplineIK.cpp | 473 ++++ libraries/animation/src/AnimSplineIK.h | 104 + libraries/animation/src/AnimStateMachine.cpp | 1 - libraries/animation/src/IKTarget.h | 3 +- libraries/animation/src/Rig.cpp | 76 +- .../src/avatars-renderer/Avatar.cpp | 36 + .../src/avatars-renderer/Avatar.h | 9 + libraries/fbx/src/FBXSerializer.cpp | 14 + libraries/shared/src/AvatarConstants.h | 1 + libraries/shared/src/CubicHermiteSpline.h | 41 +- tools/unity-avatar-exporter/Assets/README.txt | 1 + 19 files changed, 3061 insertions(+), 28 deletions(-) create mode 100644 interface/resources/avatar/avatar-animation_withSplineIKNode.json create mode 100644 libraries/animation/src/AnimSplineIK.cpp create mode 100644 libraries/animation/src/AnimSplineIK.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c126dce56a..1ba5e1264f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,7 @@ else() set(MOBILE 0) endif() +set(HIFI_USE_OPTIMIZED_IK OFF) set(BUILD_CLIENT_OPTION ON) set(BUILD_SERVER_OPTION ON) set(BUILD_TESTS_OPTION OFF) @@ -115,7 +116,7 @@ if (USE_GLES AND (NOT ANDROID)) set(DISABLE_QML_OPTION ON) endif() - +option(HIFI_USE_OPTIMIZED_IK "USE OPTIMIZED IK" ${HIFI_USE_OPTIMIZED_IK_OPTION}) option(BUILD_CLIENT "Build client components" ${BUILD_CLIENT_OPTION}) option(BUILD_SERVER "Build server components" ${BUILD_SERVER_OPTION}) option(BUILD_TESTS "Build tests" ${BUILD_TESTS_OPTION}) @@ -146,6 +147,7 @@ foreach(PLATFORM_QT_COMPONENT ${PLATFORM_QT_COMPONENTS}) list(APPEND PLATFORM_QT_LIBRARIES "Qt5::${PLATFORM_QT_COMPONENT}") endforeach() +MESSAGE(STATUS "USE OPTIMIZED IK: " ${HIFI_USE_OPTIMIZED_IK}) MESSAGE(STATUS "Build server: " ${BUILD_SERVER}) MESSAGE(STATUS "Build client: " ${BUILD_CLIENT}) MESSAGE(STATUS "Build tests: " ${BUILD_TESTS}) @@ -191,6 +193,10 @@ find_package( Threads ) add_definitions(-DGLM_FORCE_RADIANS) add_definitions(-DGLM_ENABLE_EXPERIMENTAL) add_definitions(-DGLM_FORCE_CTOR_INIT) +if (HIFI_USE_OPTIMIZED_IK) + MESSAGE(STATUS "SET THE USE IK DEFINITION ") + add_definitions(-DHIFI_USE_OPTIMIZED_IK) +endif() set(HIFI_LIBRARY_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libraries") set(EXTERNAL_PROJECT_PREFIX "project") diff --git a/interface/resources/avatar/avatar-animation_withSplineIKNode.json b/interface/resources/avatar/avatar-animation_withSplineIKNode.json new file mode 100644 index 0000000000..b1f198c52c --- /dev/null +++ b/interface/resources/avatar/avatar-animation_withSplineIKNode.json @@ -0,0 +1,2229 @@ +{ + "version": "1.1", + "root": { + "id": "userAnimStateMachine", + "type": "stateMachine", + "data": { + "currentState": "userAnimNone", + "states": [ + { + "id": "userAnimNone", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { + "var": "userAnimA", + "state": "userAnimA" + }, + { + "var": "userAnimB", + "state": "userAnimB" + } + ] + }, + { + "id": "userAnimA", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { + "var": "userAnimNone", + "state": "userAnimNone" + }, + { + "var": "userAnimB", + "state": "userAnimB" + } + ] + }, + { + "id": "userAnimB", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { + "var": "userAnimNone", + "state": "userAnimNone" + }, + { + "var": "userAnimA", + "state": "userAnimA" + } + ] + } + ] + }, + "children": [ + { + "id": "userAnimNone", + "type": "poleVectorConstraint", + "data": { + "enabled": false, + "referenceVector": [ 0, 0, 1 ], + "baseJointName": "RightUpLeg", + "midJointName": "RightLeg", + "tipJointName": "RightFoot", + "enabledVar": "rightFootPoleVectorEnabled", + "poleVectorVar": "rightFootPoleVector" + }, + "children": [ + { + "id": "rightFootIK", + "type": "twoBoneIK", + "data": { + "alpha": 1.0, + "enabled": false, + "interpDuration": 15, + "baseJointName": "RightUpLeg", + "midJointName": "RightLeg", + "tipJointName": "RightFoot", + "midHingeAxis": [ -1, 0, 0 ], + "alphaVar": "rightFootIKAlpha", + "enabledVar": "rightFootIKEnabled", + "endEffectorRotationVarVar": "rightFootIKRotationVar", + "endEffectorPositionVarVar": "rightFootIKPositionVar" + }, + "children": [ + { + "id": "leftFootPoleVector", + "type": "poleVectorConstraint", + "data": { + "enabled": false, + "referenceVector": [ 0, 0, 1 ], + "baseJointName": "LeftUpLeg", + "midJointName": "LeftLeg", + "tipJointName": "LeftFoot", + "enabledVar": "leftFootPoleVectorEnabled", + "poleVectorVar": "leftFootPoleVector" + }, + "children": [ + { + "id": "leftFootIK", + "type": "twoBoneIK", + "data": { + "alpha": 1.0, + "enabled": false, + "interpDuration": 15, + "baseJointName": "LeftUpLeg", + "midJointName": "LeftLeg", + "tipJointName": "LeftFoot", + "midHingeAxis": [ -1, 0, 0 ], + "alphaVar": "leftFootIKAlpha", + "enabledVar": "leftFootIKEnabled", + "endEffectorRotationVarVar": "leftFootIKRotationVar", + "endEffectorPositionVarVar": "leftFootIKPositionVar" + }, + "children": [ + { + "id": "rightHandPoleVector", + "type": "poleVectorConstraint", + "data": { + "enabled": false, + "referenceVector": [ -1, 0, 0 ], + "baseJointName": "RightArm", + "midJointName": "RightForeArm", + "tipJointName": "RightHand", + "enabledVar": "rightHandPoleVectorEnabled", + "poleVectorVar": "rightHandPoleVector" + }, + "children": [ + { + "id": "rightHandIK", + "type": "twoBoneIK", + "data": { + "alpha": 1.0, + "enabled": false, + "interpDuration": 15, + "baseJointName": "RightArm", + "midJointName": "RightForeArm", + "tipJointName": "RightHand", + "midHingeAxis": [ 0, 0, -1 ], + "alphaVar": "rightHandIKAlpha", + "enabledVar": "rightHandIKEnabled", + "endEffectorRotationVarVar": "rightHandIKRotationVar", + "endEffectorPositionVarVar": "rightHandIKPositionVar" + }, + "children": [ + { + "id": "leftHandPoleVector", + "type": "poleVectorConstraint", + "data": { + "enabled": false, + "referenceVector": [ 1, 0, 0 ], + "baseJointName": "LeftArm", + "midJointName": "LeftForeArm", + "tipJointName": "LeftHand", + "enabledVar": "leftHandPoleVectorEnabled", + "poleVectorVar": "leftHandPoleVector" + }, + "children": [ + { + "id": "leftHandIK", + "type": "twoBoneIK", + "data": { + "alpha": 1.0, + "enabled": false, + "interpDuration": 15, + "baseJointName": "LeftArm", + "midJointName": "LeftForeArm", + "tipJointName": "LeftHand", + "midHingeAxis": [ 0, 0, 1 ], + "alphaVar": "leftHandIKAlpha", + "enabledVar": "leftHandIKEnabled", + "endEffectorRotationVarVar": "leftHandIKRotationVar", + "endEffectorPositionVarVar": "leftHandIKPositionVar" + }, + "children": [ + { + "id": "userSplineIK", + "type": "splineIK", + "data": { + "alpha": 1.0, + "enabled": false, + "interpDuration": 15, + "baseJointName": "Hips", + "midJointName": "Spine2", + "tipJointName": "Head", + "basePositionVar": "hipsPosition", + "baseRotationVar": "hipsRotation", + "midPositionVar": "spine2Position", + "midRotationVar": "spine2Rotation", + "tipPositionVar": "headPosition", + "tipRotationVar": "headRotation", + "alphaVar": "splineIKAlpha", + "enabledVar": "splineIKEnabled", + "tipTargetFlexCoefficients": [ 1.0, 1.0, 1.0, 1.0, 1.0 ], + "midTargetFlexCoefficients": [ 1.0, 1.0, 1.0 ] + }, + "children": [ + { + "id": "defaultPoseOverlay", + "type": "overlay", + "data": { + "alpha": 0.0, + "alphaVar": "defaultPoseOverlayAlpha", + "boneSet": "fullBody", + "boneSetVar": "defaultPoseOverlayBoneSet" + }, + "children": [ + { + "id": "defaultPose", + "type": "defaultPose", + "data": { + }, + "children": [] + }, + { + "id": "rightHandOverlay", + "type": "overlay", + "data": { + "alpha": 0.0, + "boneSet": "rightHand", + "alphaVar": "rightHandOverlayAlpha" + }, + "children": [ + { + "id": "rightHandStateMachine", + "type": "stateMachine", + "data": { + "currentState": "rightHandGrasp", + "states": [ + { + "id": "rightHandGrasp", + "interpTarget": 3, + "interpDuration": 3, + "transitions": [ + { + "var": "isRightIndexPoint", + "state": "rightIndexPoint" + }, + { + "var": "isRightThumbRaise", + "state": "rightThumbRaise" + }, + { + "var": "isRightIndexPointAndThumbRaise", + "state": "rightIndexPointAndThumbRaise" + } + ] + }, + { + "id": "rightIndexPoint", + "interpTarget": 15, + "interpDuration": 3, + "transitions": [ + { + "var": "isRightHandGrasp", + "state": "rightHandGrasp" + }, + { + "var": "isRightThumbRaise", + "state": "rightThumbRaise" + }, + { + "var": "isRightIndexPointAndThumbRaise", + "state": "rightIndexPointAndThumbRaise" + } + ] + }, + { + "id": "rightThumbRaise", + "interpTarget": 15, + "interpDuration": 3, + "transitions": [ + { + "var": "isRightHandGrasp", + "state": "rightHandGrasp" + }, + { + "var": "isRightIndexPoint", + "state": "rightIndexPoint" + }, + { + "var": "isRightIndexPointAndThumbRaise", + "state": "rightIndexPointAndThumbRaise" + } + ] + }, + { + "id": "rightIndexPointAndThumbRaise", + "interpTarget": 15, + "interpDuration": 3, + "transitions": [ + { + "var": "isRightHandGrasp", + "state": "rightHandGrasp" + }, + { + "var": "isRightIndexPoint", + "state": "rightIndexPoint" + }, + { + "var": "isRightThumbRaise", + "state": "rightThumbRaise" + } + ] + } + ] + }, + "children": [ + { + "id": "rightHandGrasp", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "rightHandGraspAlpha" + }, + "children": [ + { + "id": "rightHandGraspOpen", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/hydra_pose_open_right.fbx", + "startFrame": 0.0, + "endFrame": 0.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "rightHandGraspClosed", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/hydra_pose_closed_right.fbx", + "startFrame": 0.0, + "endFrame": 0.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "rightIndexPoint", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "rightHandGraspAlpha" + }, + "children": [ + { + "id": "rightIndexPointOpen", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/touch_point_open_right.fbx", + "startFrame": 15.0, + "endFrame": 15.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "rightIndexPointClosed", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/touch_point_closed_right.fbx", + "startFrame": 15.0, + "endFrame": 15.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "rightThumbRaise", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "rightHandGraspAlpha" + }, + "children": [ + { + "id": "rightThumbRaiseOpen", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/touch_thumb_open_right.fbx", + "startFrame": 15.0, + "endFrame": 15.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "rightThumbRaiseClosed", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/touch_thumb_closed_right.fbx", + "startFrame": 15.0, + "endFrame": 15.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "rightIndexPointAndThumbRaise", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "rightHandGraspAlpha" + }, + "children": [ + { + "id": "rightIndexPointAndThumbRaiseOpen", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/touch_thumb_point_open_right.fbx", + "startFrame": 15.0, + "endFrame": 15.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "rightIndexPointAndThumbRaiseClosed", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/touch_thumb_point_closed_right.fbx", + "startFrame": 15.0, + "endFrame": 15.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + } + ] + }, + { + "id": "leftHandOverlay", + "type": "overlay", + "data": { + "alpha": 0.0, + "boneSet": "leftHand", + "alphaVar": "leftHandOverlayAlpha" + }, + "children": [ + { + "id": "leftHandStateMachine", + "type": "stateMachine", + "data": { + "currentState": "leftHandGrasp", + "states": [ + { + "id": "leftHandGrasp", + "interpTarget": 3, + "interpDuration": 3, + "transitions": [ + { + "var": "isLeftIndexPoint", + "state": "leftIndexPoint" + }, + { + "var": "isLeftThumbRaise", + "state": "leftThumbRaise" + }, + { + "var": "isLeftIndexPointAndThumbRaise", + "state": "leftIndexPointAndThumbRaise" + } + ] + }, + { + "id": "leftIndexPoint", + "interpTarget": 15, + "interpDuration": 3, + "transitions": [ + { + "var": "isLeftHandGrasp", + "state": "leftHandGrasp" + }, + { + "var": "isLeftThumbRaise", + "state": "leftThumbRaise" + }, + { + "var": "isLeftIndexPointAndThumbRaise", + "state": "leftIndexPointAndThumbRaise" + } + ] + }, + { + "id": "leftThumbRaise", + "interpTarget": 15, + "interpDuration": 3, + "transitions": [ + { + "var": "isLeftHandGrasp", + "state": "leftHandGrasp" + }, + { + "var": "isLeftIndexPoint", + "state": "leftIndexPoint" + }, + { + "var": "isLeftIndexPointAndThumbRaise", + "state": "leftIndexPointAndThumbRaise" + } + ] + }, + { + "id": "leftIndexPointAndThumbRaise", + "interpTarget": 15, + "interpDuration": 3, + "transitions": [ + { + "var": "isLeftHandGrasp", + "state": "leftHandGrasp" + }, + { + "var": "isLeftIndexPoint", + "state": "leftIndexPoint" + }, + { + "var": "isLeftThumbRaise", + "state": "leftThumbRaise" + } + ] + } + ] + }, + "children": [ + { + "id": "leftHandGrasp", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "leftHandGraspAlpha" + }, + "children": [ + { + "id": "leftHandGraspOpen", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/hydra_pose_open_left.fbx", + "startFrame": 0.0, + "endFrame": 0.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "leftHandGraspClosed", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/hydra_pose_closed_left.fbx", + "startFrame": 10.0, + "endFrame": 10.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "leftIndexPoint", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "leftHandGraspAlpha" + }, + "children": [ + { + "id": "leftIndexPointOpen", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/touch_point_open_left.fbx", + "startFrame": 15.0, + "endFrame": 15.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "leftIndexPointClosed", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/touch_point_closed_left.fbx", + "startFrame": 15.0, + "endFrame": 15.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "leftThumbRaise", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "leftHandGraspAlpha" + }, + "children": [ + { + "id": "leftThumbRaiseOpen", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/touch_thumb_open_left.fbx", + "startFrame": 15.0, + "endFrame": 15.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "leftThumbRaiseClosed", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/touch_thumb_closed_left.fbx", + "startFrame": 15.0, + "endFrame": 15.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "leftIndexPointAndThumbRaise", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "leftHandGraspAlpha" + }, + "children": [ + { + "id": "leftIndexPointAndThumbRaiseOpen", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/touch_thumb_point_open_left.fbx", + "startFrame": 15.0, + "endFrame": 15.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "leftIndexPointAndThumbRaiseClosed", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/touch_thumb_point_closed_left.fbx", + "startFrame": 15.0, + "endFrame": 15.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + } + ] + }, + { + "id": "mainStateMachine", + "type": "stateMachine", + "data": { + "outputJoints": [ "LeftFoot", "RightFoot" ], + "currentState": "idle", + "states": [ + { + "id": "idle", + "interpTarget": 20, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "idleToWalkFwd", + "interpTarget": 12, + "interpDuration": 8, + "transitions": [ + { + "var": "idleToWalkFwdOnDone", + "state": "WALKFWD" + }, + { + "var": "isNotMoving", + "state": "idle" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "idleSettle", + "interpTarget": 15, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "idleSettleOnDone", + "state": "idle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + } + ] + }, + { + "id": "WALKFWD", + "interpTarget": 35, + "interpDuration": 10, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "WALKBWD", + "interpTarget": 35, + "interpDuration": 10, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "STRAFERIGHT", + "interpTarget": 25, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "STRAFELEFT", + "interpTarget": 25, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "turnRight", + "interpTarget": 6, + "interpDuration": 8, + "transitions": [ + { + "var": "isNotTurning", + "state": "idle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "turnLeft", + "interpTarget": 6, + "interpDuration": 8, + "transitions": [ + { + "var": "isNotTurning", + "state": "idle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "strafeRightHmd", + "interpTarget": 5, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + } + ] + }, + { + "id": "strafeLeftHmd", + "interpTarget": 5, + "interpDuration": 8, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotMoving", + "state": "idleSettle" + }, + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + } + ] + }, + { + "id": "fly", + "interpTarget": 6, + "interpDuration": 6, + "transitions": [ + { + "var": "isNotFlying", + "state": "idleSettle" + } + ] + }, + { + "id": "takeoffStand", + "interpTarget": 2, + "interpDuration": 2, + "transitions": [ + { + "var": "isNotTakeoff", + "state": "inAirStand" + } + ] + }, + { + "id": "TAKEOFFRUN", + "interpTarget": 2, + "interpDuration": 2, + "transitions": [ + { + "var": "isNotTakeoff", + "state": "INAIRRUN" + } + ] + }, + { + "id": "inAirStand", + "interpTarget": 3, + "interpDuration": 3, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotInAir", + "state": "landStandImpact" + } + ] + }, + { + "id": "INAIRRUN", + "interpTarget": 3, + "interpDuration": 3, + "interpType": "snapshotPrev", + "transitions": [ + { + "var": "isNotInAir", + "state": "WALKFWD" + } + ] + }, + { + "id": "landStandImpact", + "interpTarget": 1, + "interpDuration": 1, + "transitions": [ + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "landStandImpactOnDone", + "state": "landStand" + } + ] + }, + { + "id": "landStand", + "interpTarget": 1, + "interpDuration": 1, + "transitions": [ + { + "var": "isMovingForward", + "state": "WALKFWD" + }, + { + "var": "isMovingBackward", + "state": "WALKBWD" + }, + { + "var": "isMovingRight", + "state": "STRAFERIGHT" + }, + { + "var": "isMovingLeft", + "state": "STRAFELEFT" + }, + { + "var": "isTurningRight", + "state": "turnRight" + }, + { + "var": "isTurningLeft", + "state": "turnLeft" + }, + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "isInAirStand", + "state": "inAirStand" + }, + { + "var": "isInAirRun", + "state": "INAIRRUN" + }, + { + "var": "landStandOnDone", + "state": "idle" + }, + { + "var": "isMovingRightHmd", + "state": "strafeRightHmd" + }, + { + "var": "isMovingLeftHmd", + "state": "strafeLeftHmd" + } + ] + }, + { + "id": "LANDRUN", + "interpTarget": 2, + "interpDuration": 2, + "transitions": [ + { + "var": "isFlying", + "state": "fly" + }, + { + "var": "isTakeoffStand", + "state": "takeoffStand" + }, + { + "var": "isTakeoffRun", + "state": "TAKEOFFRUN" + }, + { + "var": "landRunOnDone", + "state": "WALKFWD" + } + ] + } + ] + }, + "children": [ + { + "id": "idle", + "type": "stateMachine", + "data": { + "currentState": "idleStand", + "states": [ + { + "id": "idleStand", + "interpTarget": 6, + "interpDuration": 10, + "transitions": [ + { + "var": "isTalking", + "state": "idleTalk" + } + ] + }, + { + "id": "idleTalk", + "interpTarget": 6, + "interpDuration": 10, + "transitions": [ + { + "var": "notIsTalking", + "state": "idleStand" + } + ] + } + ] + }, + "children": [ + { + "id": "idleStand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle.fbx", + "startFrame": 0.0, + "endFrame": 300.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "idleTalk", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/talk.fbx", + "startFrame": 0.0, + "endFrame": 800.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "WALKFWD", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.5, 1.8, 2.3, 3.2, 4.5 ], + "alphaVar": "moveForwardAlpha", + "desiredSpeedVar": "moveForwardSpeed" + }, + "children": [ + { + "id": "walkFwdShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_short_fwd.fbx", + "startFrame": 0.0, + "endFrame": 39.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdNormal_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_fwd.fbx", + "startFrame": 0.0, + "endFrame": 30.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_fwd_fast.fbx", + "startFrame": 0.0, + "endFrame": 25.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdJog_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_fwd.fbx", + "startFrame": 0.0, + "endFrame": 25.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkFwdRun_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/run_fwd.fbx", + "startFrame": 0.0, + "endFrame": 21.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "idleToWalkFwd", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle_to_walk.fbx", + "startFrame": 1.0, + "endFrame": 13.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "idleSettle", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/settle_to_idle.fbx", + "startFrame": 1.0, + "endFrame": 59.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "WALKBWD", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.6, 1.6, 2.3, 3.1 ], + "alphaVar": "moveBackwardAlpha", + "desiredSpeedVar": "moveBackwardSpeed" + }, + "children": [ + { + "id": "walkBwdShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_short_bwd.fbx", + "startFrame": 0.0, + "endFrame": 38.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "walkBwdFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_bwd_fast.fbx", + "startFrame": 0.0, + "endFrame": 27.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "jogBwd_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_bwd.fbx", + "startFrame": 0.0, + "endFrame": 24.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "runBwd_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/run_bwd.fbx", + "startFrame": 0.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "turnLeft", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/turn_left.fbx", + "startFrame": 0.0, + "endFrame": 32.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "turnRight", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/turn_left.fbx", + "startFrame": 0.0, + "endFrame": 32.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "STRAFELEFT", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.1, 0.5, 1.0, 2.6, 3.0 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "strafeLeftShortStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftWalk_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left.fbx", + "startFrame": 0.0, + "endFrame": 35.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftWalkFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 21.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftJog_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_left.fbx", + "startFrame": 0.0, + "endFrame": 24.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "STRAFERIGHT", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0.1, 0.5, 1.0, 2.6, 3.0 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "strafeRightShortStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightStep_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightWalk_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left.fbx", + "startFrame": 0.0, + "endFrame": 35.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightFast_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/walk_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 21.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightJog_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jog_left.fbx", + "startFrame": 0.0, + "endFrame": 24.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + } + ] + }, + { + "id": "strafeLeftHmd", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0, 0.5, 2.5 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "stepLeftShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "stepLeft_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "strafeLeftAnim_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + }, + { + "id": "strafeRightHmd", + "type": "blendLinearMove", + "data": { + "alpha": 0.0, + "desiredSpeed": 1.4, + "characteristicSpeeds": [ 0, 0.5, 2.5 ], + "alphaVar": "moveLateralAlpha", + "desiredSpeedVar": "moveLateralSpeed" + }, + "children": [ + { + "id": "stepRightShort_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_short_left.fbx", + "startFrame": 0.0, + "endFrame": 29.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "stepRight_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left.fbx", + "startFrame": 0.0, + "endFrame": 20.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + }, + { + "id": "strafeRightAnim_c", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/side_step_left_fast.fbx", + "startFrame": 0.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": true, + "mirrorFlag": true + }, + "children": [] + } + ] + }, + { + "id": "fly", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/fly.fbx", + "startFrame": 1.0, + "endFrame": 80.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "takeoffStand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_launch.fbx", + "startFrame": 2.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "TAKEOFFRUN", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 4.0, + "endFrame": 15.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirStand", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "inAirAlpha" + }, + "children": [ + { + "id": "inAirStandPreApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_apex.fbx", + "startFrame": 0.0, + "endFrame": 0.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirStandApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_apex.fbx", + "startFrame": 1.0, + "endFrame": 1.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirStandPostApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_apex.fbx", + "startFrame": 2.0, + "endFrame": 2.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + } + ] + }, + { + "id": "INAIRRUN", + "type": "blendLinear", + "data": { + "alpha": 0.0, + "alphaVar": "inAirAlpha" + }, + "children": [ + { + "id": "inAirRunPreApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 16.0, + "endFrame": 16.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirRunApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 22.0, + "endFrame": 22.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "inAirRunPostApex", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 33.0, + "endFrame": 33.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + } + ] + }, + { + "id": "landStandImpact", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", + "startFrame": 1.0, + "endFrame": 6.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "landStand", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_standing_land_settle.fbx", + "startFrame": 6.0, + "endFrame": 68.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + }, + { + "id": "LANDRUN", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/jump_running_launch_land.fbx", + "startFrame": 29.0, + "endFrame": 40.0, + "timeScale": 1.0, + "loopFlag": false + }, + "children": [] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "id": "userAnimA", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle.fbx", + "startFrame": 0.0, + "endFrame": 90.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "userAnimB", + "type": "clip", + "data": { + "url": "qrc:///avatar/animations/idle.fbx", + "startFrame": 0.0, + "endFrame": 90.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] + } +} diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index afb7a218f6..ff865172ae 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2951,6 +2951,10 @@ void MyAvatar::initAnimGraph() { graphUrl = _fstAnimGraphOverrideUrl; } else { graphUrl = PathUtils::resourcesUrl("avatar/avatar-animation.json"); + +#if defined(Q_OS_ANDROID) || defined(HIFI_USE_OPTIMIZED_IK) + graphUrl = PathUtils::resourcesUrl("avatar/avatar-animation_withSplineIKNode.json"); +#endif } emit animGraphUrlChanged(graphUrl); diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 26d69841d0..55c29b66c1 100755 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -10,12 +10,14 @@ #include #include +#include #include "Application.h" #include "InterfaceLogging.h" #include "AnimUtil.h" + MySkeletonModel::MySkeletonModel(Avatar* owningAvatar, QObject* parent) : SkeletonModel(owningAvatar, parent) { } @@ -33,6 +35,22 @@ Rig::CharacterControllerState convertCharacterControllerState(CharacterControlle }; } +#if defined(Q_OS_ANDROID) || defined(HIFI_USE_OPTIMIZED_IK) +static glm::vec3 computeSpine2WithHeadHipsSpline(MyAvatar* myAvatar, AnimPose hipsIKTargetPose, AnimPose headIKTargetPose) { + + // the the ik targets to compute the spline with + CubicHermiteSplineFunctorWithArcLength splineFinal(headIKTargetPose.rot(), headIKTargetPose.trans(), hipsIKTargetPose.rot(), hipsIKTargetPose.trans()); + + // measure the total arc length along the spline + float totalArcLength = splineFinal.arcLength(1.0f); + float tFinal = splineFinal.arcLengthInverse(myAvatar->getSpine2SplineRatio() * totalArcLength); + glm::vec3 spine2Translation = splineFinal(tFinal); + + return spine2Translation + myAvatar->getSpine2SplineOffset(); + +} +#endif + static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) { glm::mat4 worldToSensorMat = glm::inverse(myAvatar->getSensorToWorldMatrix()); @@ -233,6 +251,12 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { myAvatar->getControllerPoseInAvatarFrame(controller::Action::LEFT_HAND).isValid() && !(params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] & (uint8_t)Rig::ControllerFlags::Enabled)) { +#if defined(Q_OS_ANDROID) || defined(HIFI_USE_OPTIMIZED_IK) + AnimPose headAvatarSpace(avatarHeadPose.getRotation(), avatarHeadPose.getTranslation()); + AnimPose headRigSpace = avatarToRigPose * headAvatarSpace; + AnimPose hipsRigSpace = sensorToRigPose * sensorHips; + glm::vec3 spine2TargetTranslation = computeSpine2WithHeadHipsSpline(myAvatar, hipsRigSpace, headRigSpace); +#endif const float SPINE2_ROTATION_FILTER = 0.5f; AnimPose currentSpine2Pose; AnimPose currentHeadPose; @@ -243,6 +267,9 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { if (spine2Exists && headExists && hipsExists) { AnimPose rigSpaceYaw(myAvatar->getSpine2RotationRigSpace()); +#if defined(Q_OS_ANDROID) || defined(HIFI_USE_OPTIMIZED_IK) + rigSpaceYaw.rot() = safeLerp(Quaternions::IDENTITY, rigSpaceYaw.rot(), 0.5f); +#endif glm::vec3 u, v, w; glm::vec3 fwd = rigSpaceYaw.rot() * glm::vec3(0.0f, 0.0f, 1.0f); glm::vec3 up = currentHeadPose.trans() - currentHipsPose.trans(); @@ -253,6 +280,9 @@ void MySkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { } generateBasisVectors(up, fwd, u, v, w); AnimPose newSpinePose(glm::mat4(glm::vec4(w, 0.0f), glm::vec4(u, 0.0f), glm::vec4(v, 0.0f), glm::vec4(glm::vec3(0.0f, 0.0f, 0.0f), 1.0f))); +#if defined(Q_OS_ANDROID) || defined(HIFI_USE_OPTIMIZED_IK) + currentSpine2Pose.trans() = spine2TargetTranslation; +#endif currentSpine2Pose.rot() = safeLerp(currentSpine2Pose.rot(), newSpinePose.rot(), SPINE2_ROTATION_FILTER); params.primaryControllerPoses[Rig::PrimaryControllerType_Spine2] = currentSpine2Pose; params.primaryControllerFlags[Rig::PrimaryControllerType_Spine2] = (uint8_t)Rig::ControllerFlags::Enabled | (uint8_t)Rig::ControllerFlags::Estimated; diff --git a/libraries/animation/src/AnimContext.h b/libraries/animation/src/AnimContext.h index c455dd9c8f..e3ab5d9788 100644 --- a/libraries/animation/src/AnimContext.h +++ b/libraries/animation/src/AnimContext.h @@ -28,6 +28,7 @@ enum class AnimNodeType { InverseKinematics, DefaultPose, TwoBoneIK, + SplineIK, PoleVectorConstraint, NumTypes }; diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index d710e9d8ff..37859c939a 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -866,6 +866,11 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar //virtual const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut, const AnimPoseVec& underPoses) { +#ifdef Q_OS_ANDROID + // disable IK on android + return underPoses; +#endif + // allows solutionSource to be overridden by an animVar auto solutionSource = animVars.lookup(_solutionSourceVar, (int)_solutionSource); diff --git a/libraries/animation/src/AnimNodeLoader.cpp b/libraries/animation/src/AnimNodeLoader.cpp index dfa61e9fea..b637d131f8 100644 --- a/libraries/animation/src/AnimNodeLoader.cpp +++ b/libraries/animation/src/AnimNodeLoader.cpp @@ -26,6 +26,7 @@ #include "AnimInverseKinematics.h" #include "AnimDefaultPose.h" #include "AnimTwoBoneIK.h" +#include "AnimSplineIK.h" #include "AnimPoleVectorConstraint.h" using NodeLoaderFunc = AnimNode::Pointer (*)(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); @@ -41,6 +42,7 @@ static AnimNode::Pointer loadManipulatorNode(const QJsonObject& jsonObj, const Q static AnimNode::Pointer loadInverseKinematicsNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); static AnimNode::Pointer loadDefaultPoseNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); static AnimNode::Pointer loadTwoBoneIKNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); +static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); static AnimNode::Pointer loadPoleVectorConstraintNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl); static const float ANIM_GRAPH_LOAD_PRIORITY = 10.0f; @@ -61,6 +63,7 @@ static const char* animNodeTypeToString(AnimNode::Type type) { case AnimNode::Type::InverseKinematics: return "inverseKinematics"; case AnimNode::Type::DefaultPose: return "defaultPose"; case AnimNode::Type::TwoBoneIK: return "twoBoneIK"; + case AnimNode::Type::SplineIK: return "splineIK"; case AnimNode::Type::PoleVectorConstraint: return "poleVectorConstraint"; case AnimNode::Type::NumTypes: return nullptr; }; @@ -123,6 +126,7 @@ static NodeLoaderFunc animNodeTypeToLoaderFunc(AnimNode::Type type) { case AnimNode::Type::InverseKinematics: return loadInverseKinematicsNode; case AnimNode::Type::DefaultPose: return loadDefaultPoseNode; case AnimNode::Type::TwoBoneIK: return loadTwoBoneIKNode; + case AnimNode::Type::SplineIK: return loadSplineIKNode; case AnimNode::Type::PoleVectorConstraint: return loadPoleVectorConstraintNode; case AnimNode::Type::NumTypes: return nullptr; }; @@ -140,6 +144,7 @@ static NodeProcessFunc animNodeTypeToProcessFunc(AnimNode::Type type) { case AnimNode::Type::InverseKinematics: return processDoNothing; case AnimNode::Type::DefaultPose: return processDoNothing; case AnimNode::Type::TwoBoneIK: return processDoNothing; + case AnimNode::Type::SplineIK: return processDoNothing; case AnimNode::Type::PoleVectorConstraint: return processDoNothing; case AnimNode::Type::NumTypes: return nullptr; }; @@ -574,6 +579,52 @@ static AnimNode::Pointer loadDefaultPoseNode(const QJsonObject& jsonObj, const Q return node; } +static AnimNode::Pointer loadSplineIKNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { + READ_FLOAT(alpha, jsonObj, id, jsonUrl, nullptr); + READ_BOOL(enabled, jsonObj, id, jsonUrl, nullptr); + READ_FLOAT(interpDuration, jsonObj, id, jsonUrl, nullptr); + READ_STRING(baseJointName, jsonObj, id, jsonUrl, nullptr); + READ_STRING(midJointName, jsonObj, id, jsonUrl, nullptr); + READ_STRING(tipJointName, jsonObj, id, jsonUrl, nullptr); + READ_STRING(basePositionVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(baseRotationVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(midPositionVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(midRotationVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(tipPositionVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(tipRotationVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(alphaVar, jsonObj, id, jsonUrl, nullptr); + READ_STRING(enabledVar, jsonObj, id, jsonUrl, nullptr); + + auto tipFlexCoefficientsValue = jsonObj.value("tipTargetFlexCoefficients"); + if (!tipFlexCoefficientsValue.isArray()) { + qCCritical(animation) << "AnimNodeLoader, bad or missing tip flex array"; + return nullptr; + } + auto tipFlexCoefficientsArray = tipFlexCoefficientsValue.toArray(); + std::vector tipTargetFlexCoefficients; + for (const auto& value : tipFlexCoefficientsArray) { + tipTargetFlexCoefficients.push_back((float)value.toDouble()); + } + + auto midFlexCoefficientsValue = jsonObj.value("midTargetFlexCoefficients"); + if (!midFlexCoefficientsValue.isArray()) { + qCCritical(animation) << "AnimNodeLoader, bad or missing mid flex array"; + return nullptr; + } + auto midFlexCoefficientsArray = midFlexCoefficientsValue.toArray(); + std::vector midTargetFlexCoefficients; + for (const auto& midValue : midFlexCoefficientsArray) { + midTargetFlexCoefficients.push_back((float)midValue.toDouble()); + } + + auto node = std::make_shared(id, alpha, enabled, interpDuration, + baseJointName, midJointName, tipJointName, + basePositionVar, baseRotationVar, midPositionVar, midRotationVar, + tipPositionVar, tipRotationVar, alphaVar, enabledVar, + tipTargetFlexCoefficients, midTargetFlexCoefficients); + return node; +} + static AnimNode::Pointer loadTwoBoneIKNode(const QJsonObject& jsonObj, const QString& id, const QUrl& jsonUrl) { READ_FLOAT(alpha, jsonObj, id, jsonUrl, nullptr); READ_BOOL(enabled, jsonObj, id, jsonUrl, nullptr); diff --git a/libraries/animation/src/AnimPoleVectorConstraint.cpp b/libraries/animation/src/AnimPoleVectorConstraint.cpp index f017fe2348..c0600ee253 100644 --- a/libraries/animation/src/AnimPoleVectorConstraint.cpp +++ b/libraries/animation/src/AnimPoleVectorConstraint.cpp @@ -117,7 +117,7 @@ const AnimPoseVec& AnimPoleVectorConstraint::evaluate(const AnimVariantMap& anim if (axisLength > MIN_LENGTH && refVectorLength > MIN_LENGTH && sideVectorLength > MIN_LENGTH && refVectorProjLength > MIN_LENGTH && poleVectorProjLength > MIN_LENGTH) { - float dot = glm::clamp(glm::dot(refVectorProj / refVectorProjLength, poleVectorProj / poleVectorProjLength), 0.0f, 1.0f); + float dot = glm::clamp(glm::dot(refVectorProj / refVectorProjLength, poleVectorProj / poleVectorProjLength), -1.0f, 1.0f); float sideDot = glm::dot(poleVector, sideVector); float theta = copysignf(1.0f, sideDot) * acosf(dot); diff --git a/libraries/animation/src/AnimSplineIK.cpp b/libraries/animation/src/AnimSplineIK.cpp new file mode 100644 index 0000000000..cfb34560ff --- /dev/null +++ b/libraries/animation/src/AnimSplineIK.cpp @@ -0,0 +1,473 @@ +// +// AnimSplineIK.cpp +// +// Created by Angus Antley on 1/7/19. +// Copyright (c) 2019 High Fidelity, Inc. All rights reserved. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "AnimSplineIK.h" +#include "AnimationLogging.h" +#include "CubicHermiteSpline.h" +#include +#include "AnimUtil.h" + +static const float FRAMES_PER_SECOND = 30.0f; + +AnimSplineIK::AnimSplineIK(const QString& id, float alpha, bool enabled, float interpDuration, + const QString& baseJointName, + const QString& midJointName, + const QString& tipJointName, + const QString& basePositionVar, + const QString& baseRotationVar, + const QString& midPositionVar, + const QString& midRotationVar, + const QString& tipPositionVar, + const QString& tipRotationVar, + const QString& alphaVar, + const QString& enabledVar, + const std::vector tipTargetFlexCoefficients, + const std::vector midTargetFlexCoefficients) : + AnimNode(AnimNode::Type::SplineIK, id), + _alpha(alpha), + _enabled(enabled), + _interpDuration(interpDuration), + _baseJointName(baseJointName), + _midJointName(midJointName), + _tipJointName(tipJointName), + _basePositionVar(basePositionVar), + _baseRotationVar(baseRotationVar), + _midPositionVar(midPositionVar), + _midRotationVar(midRotationVar), + _tipPositionVar(tipPositionVar), + _tipRotationVar(tipRotationVar), + _alphaVar(alphaVar), + _enabledVar(enabledVar) +{ + + for (int i = 0; i < (int)tipTargetFlexCoefficients.size(); i++) { + if (i < MAX_NUMBER_FLEX_VARIABLES) { + _tipTargetFlexCoefficients[i] = tipTargetFlexCoefficients[i]; + } + } + _numTipTargetFlexCoefficients = std::min((int)tipTargetFlexCoefficients.size(), MAX_NUMBER_FLEX_VARIABLES); + + for (int i = 0; i < (int)midTargetFlexCoefficients.size(); i++) { + if (i < MAX_NUMBER_FLEX_VARIABLES) { + _midTargetFlexCoefficients[i] = midTargetFlexCoefficients[i]; + } + } + _numMidTargetFlexCoefficients = std::min((int)midTargetFlexCoefficients.size(), MAX_NUMBER_FLEX_VARIABLES); + +} + +AnimSplineIK::~AnimSplineIK() { + +} + +const AnimPoseVec& AnimSplineIK::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { + assert(_children.size() == 1); + if (_children.size() != 1) { + return _poses; + } + + const float MIN_ALPHA = 0.0f; + const float MAX_ALPHA = 1.0f; + float alpha = glm::clamp(animVars.lookup(_alphaVar, _alpha), MIN_ALPHA, MAX_ALPHA); + + // evaluate underPoses + AnimPoseVec underPoses = _children[0]->evaluate(animVars, context, dt, triggersOut); + + // if we don't have a skeleton, or jointName lookup failed or the spline alpha is 0 or there are no underposes. + if (!_skeleton || _baseJointIndex == -1 || _midJointIndex == -1 || _tipJointIndex == -1 || alpha < EPSILON || underPoses.size() == 0) { + // pass underPoses through unmodified. + _poses = underPoses; + return _poses; + } + + // guard against size change + if (underPoses.size() != _poses.size()) { + _poses = underPoses; + } + + // determine if we should interpolate + bool enabled = animVars.lookup(_enabledVar, _enabled); + if (enabled != _enabled) { + AnimChain poseChain; + poseChain.buildFromRelativePoses(_skeleton, _poses, _tipJointIndex); + if (enabled) { + beginInterp(InterpType::SnapshotToSolve, poseChain); + } else { + beginInterp(InterpType::SnapshotToUnderPoses, poseChain); + } + } + _enabled = enabled; + + // now that we have saved the previous _poses in _snapshotChain, we can update to the current underposes + _poses = underPoses; + + // don't build chains or do IK if we are disabled & not interping. + if (_interpType == InterpType::None && !enabled) { + return _poses; + } + + // compute under chain for possible interpolation + AnimChain underChain; + underChain.buildFromRelativePoses(_skeleton, underPoses, _tipJointIndex); + + AnimPose baseTargetAbsolutePose; + // if there is a baseJoint ik target in animvars then set the joint to that + // otherwise use the underpose + AnimPose baseJointUnderPose = _skeleton->getAbsolutePose(_baseJointIndex, _poses); + baseTargetAbsolutePose.rot() = animVars.lookupRigToGeometry(_baseRotationVar, baseJointUnderPose.rot()); + baseTargetAbsolutePose.trans() = animVars.lookupRigToGeometry(_basePositionVar, baseJointUnderPose.trans()); + + int baseParentIndex = _skeleton->getParentIndex(_baseJointIndex); + AnimPose baseParentAbsPose(Quaternions::IDENTITY,glm::vec3()); + if (baseParentIndex >= 0) { + baseParentAbsPose = _skeleton->getAbsolutePose(baseParentIndex, _poses); + } + _poses[_baseJointIndex] = baseParentAbsPose.inverse() * baseTargetAbsolutePose; + _poses[_baseJointIndex].scale() = glm::vec3(1.0f); + + // initialize the middle joint target + IKTarget midTarget; + midTarget.setType((int)IKTarget::Type::Spline); + midTarget.setIndex(_midJointIndex); + AnimPose absPoseMid = _skeleton->getAbsolutePose(_midJointIndex, _poses); + glm::quat midTargetRotation = animVars.lookupRigToGeometry(_midRotationVar, absPoseMid.rot()); + glm::vec3 midTargetPosition = animVars.lookupRigToGeometry(_midPositionVar, absPoseMid.trans()); + midTarget.setPose(midTargetRotation, midTargetPosition); + midTarget.setWeight(1.0f); + midTarget.setFlexCoefficients(_numMidTargetFlexCoefficients, _midTargetFlexCoefficients); + + // solve the lower spine spline + AnimChain midJointChain; + AnimPoseVec absolutePosesAfterBaseTipSpline; + absolutePosesAfterBaseTipSpline.resize(_poses.size()); + computeAbsolutePoses(absolutePosesAfterBaseTipSpline); + midJointChain.buildFromRelativePoses(_skeleton, _poses, midTarget.getIndex()); + solveTargetWithSpline(context, _baseJointIndex, midTarget, absolutePosesAfterBaseTipSpline, context.getEnableDebugDrawIKChains(), midJointChain); + midJointChain.outputRelativePoses(_poses); + + // initialize the tip target + IKTarget tipTarget; + tipTarget.setType((int)IKTarget::Type::Spline); + tipTarget.setIndex(_tipJointIndex); + AnimPose absPoseTip = _skeleton->getAbsolutePose(_tipJointIndex, _poses); + glm::quat tipRotation = animVars.lookupRigToGeometry(_tipRotationVar, absPoseTip.rot()); + glm::vec3 tipTranslation = animVars.lookupRigToGeometry(_tipPositionVar, absPoseTip.trans()); + tipTarget.setPose(tipRotation, tipTranslation); + tipTarget.setWeight(1.0f); + tipTarget.setFlexCoefficients(_numTipTargetFlexCoefficients, _tipTargetFlexCoefficients); + + // solve the upper spine spline + AnimChain upperJointChain; + AnimPoseVec finalAbsolutePoses; + finalAbsolutePoses.resize(_poses.size()); + computeAbsolutePoses(finalAbsolutePoses); + upperJointChain.buildFromRelativePoses(_skeleton, _poses, tipTarget.getIndex()); + solveTargetWithSpline(context, _midJointIndex, tipTarget, finalAbsolutePoses, context.getEnableDebugDrawIKChains(), upperJointChain); + upperJointChain.buildDirtyAbsolutePoses(); + upperJointChain.outputRelativePoses(_poses); + + // compute chain + AnimChain ikChain; + ikChain.buildFromRelativePoses(_skeleton, _poses, _tipJointIndex); + // blend with the underChain + ikChain.blend(underChain, alpha); + + // apply smooth interpolation when turning ik on and off + if (_interpType != InterpType::None) { + _interpAlpha += _interpAlphaVel * dt; + + // ease in expo + float easeInAlpha = 1.0f - powf(2.0f, -10.0f * _interpAlpha); + + if (_interpAlpha < 1.0f) { + AnimChain interpChain; + if (_interpType == InterpType::SnapshotToUnderPoses) { + interpChain = underChain; + interpChain.blend(_snapshotChain, easeInAlpha); + } else if (_interpType == InterpType::SnapshotToSolve) { + interpChain = ikChain; + interpChain.blend(_snapshotChain, easeInAlpha); + } + // copy interpChain into _poses + interpChain.outputRelativePoses(_poses); + } else { + // interpolation complete + _interpType = InterpType::None; + } + } + + if (_interpType == InterpType::None) { + if (enabled) { + // copy chain into _poses + ikChain.outputRelativePoses(_poses); + } else { + // copy under chain into _poses + underChain.outputRelativePoses(_poses); + } + } + + // debug render ik targets + if (context.getEnableDebugDrawIKTargets()) { + const vec4 WHITE(1.0f); + const vec4 GREEN(0.0f, 1.0f, 0.0f, 1.0f); + glm::mat4 rigToAvatarMat = createMatFromQuatAndPos(Quaternions::Y_180, glm::vec3()); + + glm::mat4 geomTargetMat = createMatFromQuatAndPos(tipTarget.getRotation(), tipTarget.getTranslation()); + glm::mat4 avatarTargetMat = rigToAvatarMat * context.getGeometryToRigMatrix() * geomTargetMat; + QString name = QString("ikTargetSplineTip"); + DebugDraw::getInstance().addMyAvatarMarker(name, glmExtractRotation(avatarTargetMat), extractTranslation(avatarTargetMat), WHITE); + + glm::mat4 geomTargetMat2 = createMatFromQuatAndPos(midTarget.getRotation(), midTarget.getTranslation()); + glm::mat4 avatarTargetMat2 = rigToAvatarMat * context.getGeometryToRigMatrix() * geomTargetMat2; + QString name2 = QString("ikTargetSplineMid"); + DebugDraw::getInstance().addMyAvatarMarker(name2, glmExtractRotation(avatarTargetMat2), extractTranslation(avatarTargetMat2), WHITE); + + glm::mat4 geomTargetMat3 = createMatFromQuatAndPos(baseTargetAbsolutePose.rot(), baseTargetAbsolutePose.trans()); + glm::mat4 avatarTargetMat3 = rigToAvatarMat * context.getGeometryToRigMatrix() * geomTargetMat3; + QString name3 = QString("ikTargetSplineBase"); + DebugDraw::getInstance().addMyAvatarMarker(name3, glmExtractRotation(avatarTargetMat3), extractTranslation(avatarTargetMat3), WHITE); + + + } else if (context.getEnableDebugDrawIKTargets() != _previousEnableDebugIKTargets) { + + // remove markers if they were added last frame. + QString name = QString("ikTargetSplineTip"); + DebugDraw::getInstance().removeMyAvatarMarker(name); + QString name2 = QString("ikTargetSplineMid"); + DebugDraw::getInstance().removeMyAvatarMarker(name2); + QString name3 = QString("ikTargetSplineBase"); + DebugDraw::getInstance().removeMyAvatarMarker(name3); + } + _previousEnableDebugIKTargets = context.getEnableDebugDrawIKTargets(); + + return _poses; +} + +void AnimSplineIK::lookUpIndices() { + assert(_skeleton); + + // look up bone indices by name + std::vector indices = _skeleton->lookUpJointIndices({ _baseJointName, _tipJointName, _midJointName }); + + // cache the results + _baseJointIndex = indices[0]; + _tipJointIndex = indices[1]; + _midJointIndex = indices[2]; +} + +void AnimSplineIK::computeAbsolutePoses(AnimPoseVec& absolutePoses) const { + int numJoints = (int)_poses.size(); + assert(numJoints <= _skeleton->getNumJoints()); + assert(numJoints == (int)absolutePoses.size()); + for (int i = 0; i < numJoints; ++i) { + int parentIndex = _skeleton->getParentIndex(i); + if (parentIndex < 0) { + absolutePoses[i] = _poses[i]; + } else { + absolutePoses[i] = absolutePoses[parentIndex] * _poses[i]; + } + } +} + +// for AnimDebugDraw rendering +const AnimPoseVec& AnimSplineIK::getPosesInternal() const { + return _poses; +} + +void AnimSplineIK::setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) { + AnimNode::setSkeletonInternal(skeleton); + lookUpIndices(); +} + +void AnimSplineIK::solveTargetWithSpline(const AnimContext& context, int base, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const { + + // build spline from tip to base + AnimPose tipPose = AnimPose(glm::vec3(1.0f), target.getRotation(), target.getTranslation()); + AnimPose basePose = absolutePoses[base]; + + CubicHermiteSplineFunctorWithArcLength spline; + if (target.getIndex() == _tipJointIndex) { + // set gain factors so that more curvature occurs near the tip of the spline. + const float HIPS_GAIN = 0.5f; + const float HEAD_GAIN = 1.0f; + spline = CubicHermiteSplineFunctorWithArcLength(tipPose.rot(), tipPose.trans(), basePose.rot(), basePose.trans(), HIPS_GAIN, HEAD_GAIN); + } else { + spline = CubicHermiteSplineFunctorWithArcLength(tipPose.rot(),tipPose.trans(), basePose.rot(), basePose.trans()); + } + float totalArcLength = spline.arcLength(1.0f); + + // This prevents the rotation interpolation from rotating the wrong physical way (but correct mathematical way) + // when the head is arched backwards very far. + glm::quat halfRot = safeLerp(basePose.rot(), tipPose.rot(), 0.5f); + if (glm::dot(halfRot * Vectors::UNIT_Z, basePose.rot() * Vectors::UNIT_Z) < 0.0f) { + tipPose.rot() = -tipPose.rot(); + } + + // find or create splineJointInfo for this target + const std::vector* splineJointInfoVec = findOrCreateSplineJointInfo(context, base, target); + + if (splineJointInfoVec && splineJointInfoVec->size() > 0) { + const int baseParentIndex = _skeleton->getParentIndex(base); + AnimPose parentAbsPose = (baseParentIndex >= 0) ? absolutePoses[baseParentIndex] : AnimPose(); + // go thru splineJointInfoVec backwards (base to tip) + for (int i = (int)splineJointInfoVec->size() - 1; i >= 0; i--) { + const SplineJointInfo& splineJointInfo = (*splineJointInfoVec)[i]; + float t = spline.arcLengthInverse(splineJointInfo.ratio * totalArcLength); + glm::vec3 trans = spline(t); + + // for base->tip splines, preform most twist toward the tip by using ease in function. t^2 + float rotT = t; + if (target.getIndex() == _tipJointIndex) { + rotT = t * t; + } + glm::quat twistRot = safeLerp(basePose.rot(), tipPose.rot(), rotT); + + // compute the rotation by using the derivative of the spline as the y-axis, and the twistRot x-axis + glm::vec3 y = glm::normalize(spline.d(t)); + glm::vec3 x = twistRot * Vectors::UNIT_X; + glm::vec3 u, v, w; + generateBasisVectors(y, x, v, u, w); + glm::mat3 m(u, v, glm::cross(u, v)); + glm::quat rot = glm::normalize(glm::quat_cast(m)); + + AnimPose desiredAbsPose = AnimPose(glm::vec3(1.0f), rot, trans) * splineJointInfo.offsetPose; + + // apply flex coefficent + AnimPose flexedAbsPose; + // get the number of flex coeff for this spline + float interpedCoefficient = 1.0f; + int numFlexCoeff = target.getNumFlexCoefficients(); + if (numFlexCoeff == (int)splineJointInfoVec->size()) { + // then do nothing special + interpedCoefficient = target.getFlexCoefficient(i); + } else { + // interp based on ratio of the joint. + if (splineJointInfo.ratio < 1.0f) { + float flexInterp = splineJointInfo.ratio * (float)(numFlexCoeff - 1); + int startCoeff = (int)glm::floor(flexInterp); + float partial = flexInterp - startCoeff; + interpedCoefficient = target.getFlexCoefficient(startCoeff) * (1.0f - partial) + target.getFlexCoefficient(startCoeff + 1) * partial; + } else { + interpedCoefficient = target.getFlexCoefficient(numFlexCoeff - 1); + } + } + ::blend(1, &absolutePoses[splineJointInfo.jointIndex], &desiredAbsPose, interpedCoefficient, &flexedAbsPose); + + AnimPose relPose = parentAbsPose.inverse() * flexedAbsPose; + + if (splineJointInfo.jointIndex != base) { + // constrain the amount the spine can stretch or compress + float length = glm::length(relPose.trans()); + const float EPSILON = 0.0001f; + if (length > EPSILON) { + float defaultLength = glm::length(_skeleton->getRelativeDefaultPose(splineJointInfo.jointIndex).trans()); + const float STRETCH_COMPRESS_PERCENTAGE = 0.15f; + const float MAX_LENGTH = defaultLength * (1.0f + STRETCH_COMPRESS_PERCENTAGE); + const float MIN_LENGTH = defaultLength * (1.0f - STRETCH_COMPRESS_PERCENTAGE); + if (length > MAX_LENGTH) { + relPose.trans() = (relPose.trans() / length) * MAX_LENGTH; + } else if (length < MIN_LENGTH) { + relPose.trans() = (relPose.trans() / length) * MIN_LENGTH; + } + } else { + relPose.trans() = glm::vec3(0.0f); + } + } + + if (!chainInfoOut.setRelativePoseAtJointIndex(splineJointInfo.jointIndex, relPose)) { + qCDebug(animation) << "error: joint not found in spline chain"; + } + + parentAbsPose = flexedAbsPose; + } + } + + if (debug) { + const vec4 CYAN(0.0f, 1.0f, 1.0f, 1.0f); + chainInfoOut.debugDraw(context.getRigToWorldMatrix() * context.getGeometryToRigMatrix(), CYAN); + } +} + +const std::vector* AnimSplineIK::findOrCreateSplineJointInfo(const AnimContext& context, int base, const IKTarget& target) const { + // find or create splineJointInfo for this target + auto iter = _splineJointInfoMap.find(target.getIndex()); + if (iter != _splineJointInfoMap.end()) { + return &(iter->second); + } else { + computeAndCacheSplineJointInfosForIKTarget(context, base, target); + auto iter = _splineJointInfoMap.find(target.getIndex()); + if (iter != _splineJointInfoMap.end()) { + return &(iter->second); + } + } + return nullptr; +} + +// pre-compute information about each joint influenced by this spline IK target. +void AnimSplineIK::computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, int base, const IKTarget& target) const { + std::vector splineJointInfoVec; + + // build spline between the default poses. + AnimPose tipPose = _skeleton->getAbsoluteDefaultPose(target.getIndex()); + AnimPose basePose = _skeleton->getAbsoluteDefaultPose(base); + + CubicHermiteSplineFunctorWithArcLength spline; + if (target.getIndex() == _tipJointIndex) { + // set gain factors so that more curvature occurs near the tip of the spline. + const float HIPS_GAIN = 0.5f; + const float HEAD_GAIN = 1.0f; + spline = CubicHermiteSplineFunctorWithArcLength(tipPose.rot(), tipPose.trans(), basePose.rot(), basePose.trans(), HIPS_GAIN, HEAD_GAIN); + } else { + spline = CubicHermiteSplineFunctorWithArcLength(tipPose.rot(), tipPose.trans(), basePose.rot(), basePose.trans()); + } + // measure the total arc length along the spline + float totalArcLength = spline.arcLength(1.0f); + + glm::vec3 baseToTip = tipPose.trans() - basePose.trans(); + float baseToTipLength = glm::length(baseToTip); + glm::vec3 baseToTipNormal = baseToTip / baseToTipLength; + + int index = target.getIndex(); + int endIndex = _skeleton->getParentIndex(base); + + while (index != endIndex) { + AnimPose defaultPose = _skeleton->getAbsoluteDefaultPose(index); + glm::vec3 baseToCurrentJoint = defaultPose.trans() - basePose.trans(); + float ratio = glm::dot(baseToCurrentJoint, baseToTipNormal) / baseToTipLength; + + // compute offset from spline to the default pose. + float t = spline.arcLengthInverse(ratio * totalArcLength); + + // compute the rotation by using the derivative of the spline as the y-axis, and the defaultPose x-axis + glm::vec3 y = glm::normalize(spline.d(t)); + glm::vec3 x = defaultPose.rot() * Vectors::UNIT_X; + glm::vec3 u, v, w; + generateBasisVectors(y, x, v, u, w); + glm::mat3 m(u, v, glm::cross(u, v)); + glm::quat rot = glm::normalize(glm::quat_cast(m)); + + AnimPose pose(glm::vec3(1.0f), rot, spline(t)); + AnimPose offsetPose = pose.inverse() * defaultPose; + + SplineJointInfo splineJointInfo = { index, ratio, offsetPose }; + splineJointInfoVec.push_back(splineJointInfo); + index = _skeleton->getParentIndex(index); + } + _splineJointInfoMap[target.getIndex()] = splineJointInfoVec; +} + +void AnimSplineIK::beginInterp(InterpType interpType, const AnimChain& chain) { + // capture the current poses in a snapshot. + _snapshotChain = chain; + + _interpType = interpType; + _interpAlphaVel = FRAMES_PER_SECOND / _interpDuration; + _interpAlpha = 0.0f; +} diff --git a/libraries/animation/src/AnimSplineIK.h b/libraries/animation/src/AnimSplineIK.h new file mode 100644 index 0000000000..a4d8da37ca --- /dev/null +++ b/libraries/animation/src/AnimSplineIK.h @@ -0,0 +1,104 @@ +// +// AnimSplineIK.h +// +// Created by Angus Antley on 1/7/19. +// Copyright (c) 2019 High Fidelity, Inc. All rights reserved. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_AnimSplineIK_h +#define hifi_AnimSplineIK_h + +#include "AnimNode.h" +#include "IKTarget.h" +#include "AnimChain.h" + +static const int MAX_NUMBER_FLEX_VARIABLES = 10; + +// Spline IK for the spine +class AnimSplineIK : public AnimNode { +public: + AnimSplineIK(const QString& id, float alpha, bool enabled, float interpDuration, + const QString& baseJointName, const QString& midJointName, const QString& tipJointName, + const QString& basePositionVar, const QString& baseRotationVar, + const QString& midPositionVar, const QString& midRotationVar, + const QString& tipPositionVar, const QString& tipRotationVar, + const QString& alphaVar, const QString& enabledVar, + const std::vector tipTargetFlexCoefficients, + const std::vector midTargetFlexCoefficients); + + virtual ~AnimSplineIK() override; + virtual const AnimPoseVec& evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) override; + +protected: + + enum class InterpType { + None = 0, + SnapshotToUnderPoses, + SnapshotToSolve, + NumTypes + }; + + void computeAbsolutePoses(AnimPoseVec& absolutePoses) const; + void loadPoses(const AnimPoseVec& poses); + + // for AnimDebugDraw rendering + virtual const AnimPoseVec& getPosesInternal() const override; + virtual void setSkeletonInternal(AnimSkeleton::ConstPointer skeleton) override; + + void lookUpIndices(); + void beginInterp(InterpType interpType, const AnimChain& chain); + + AnimPoseVec _poses; + + float _alpha; + bool _enabled; + float _interpDuration; + QString _baseJointName; + QString _midJointName; + QString _tipJointName; + QString _basePositionVar; + QString _baseRotationVar; + QString _midPositionVar; + QString _midRotationVar; + QString _tipPositionVar; + QString _tipRotationVar; + QString _alphaVar; // float - (0, 1) 0 means underPoses only, 1 means IK only. + QString _enabledVar; + + float _tipTargetFlexCoefficients[MAX_NUMBER_FLEX_VARIABLES]; + float _midTargetFlexCoefficients[MAX_NUMBER_FLEX_VARIABLES]; + int _numTipTargetFlexCoefficients { 0 }; + int _numMidTargetFlexCoefficients { 0 }; + + int _baseJointIndex { -1 }; + int _midJointIndex { -1 }; + int _tipJointIndex { -1 }; + + bool _previousEnableDebugIKTargets { false }; + + InterpType _interpType{ InterpType::None }; + float _interpAlphaVel{ 0.0f }; + float _interpAlpha{ 0.0f }; + AnimChain _snapshotChain; + + // used to pre-compute information about each joint influenced by a spline IK target. + struct SplineJointInfo { + int jointIndex; // joint in the skeleton that this information pertains to. + float ratio; // percentage (0..1) along the spline for this joint. + AnimPose offsetPose; // local offset from the spline to the joint. + }; + + void solveTargetWithSpline(const AnimContext& context, int base, const IKTarget& target, const AnimPoseVec& absolutePoses, bool debug, AnimChain& chainInfoOut) const; + void computeAndCacheSplineJointInfosForIKTarget(const AnimContext& context, int base, const IKTarget& target) const; + const std::vector* findOrCreateSplineJointInfo(const AnimContext& context, int base, const IKTarget& target) const; + mutable std::map> _splineJointInfoMap; + + // no copies + AnimSplineIK(const AnimSplineIK&) = delete; + AnimSplineIK& operator=(const AnimSplineIK&) = delete; + +}; +#endif // hifi_AnimSplineIK_h diff --git a/libraries/animation/src/AnimStateMachine.cpp b/libraries/animation/src/AnimStateMachine.cpp index fb13b8e71c..2c5d4ad0f3 100644 --- a/libraries/animation/src/AnimStateMachine.cpp +++ b/libraries/animation/src/AnimStateMachine.cpp @@ -22,7 +22,6 @@ AnimStateMachine::~AnimStateMachine() { } const AnimPoseVec& AnimStateMachine::evaluate(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut) { - float parentDebugAlpha = context.getDebugAlpha(_id); QString desiredStateID = animVars.lookup(_currentStateVar, _currentState->getID()); diff --git a/libraries/animation/src/IKTarget.h b/libraries/animation/src/IKTarget.h index 325a1b40b6..57eaff9c30 100644 --- a/libraries/animation/src/IKTarget.h +++ b/libraries/animation/src/IKTarget.h @@ -35,6 +35,8 @@ public: bool getPoleVectorEnabled() const { return _poleVectorEnabled; } int getIndex() const { return _index; } Type getType() const { return _type; } + int getNumFlexCoefficients() const { return (int)_numFlexCoefficients; } + float getFlexCoefficient(size_t chainDepth) const; void setPose(const glm::quat& rotation, const glm::vec3& translation); void setPoleVector(const glm::vec3& poleVector) { _poleVector = poleVector; } @@ -43,7 +45,6 @@ public: void setIndex(int index) { _index = index; } void setType(int); void setFlexCoefficients(size_t numFlexCoefficientsIn, const float* flexCoefficientsIn); - float getFlexCoefficient(size_t chainDepth) const; void setWeight(float weight) { _weight = weight; } float getWeight() const { return _weight; } diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index a9c57a4a15..be6240017f 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -34,7 +34,6 @@ #include "IKTarget.h" #include "PathUtils.h" - static int nextRigId = 1; static std::map rigRegistry; static std::mutex rigRegistryMutex; @@ -74,6 +73,20 @@ static const QString RIGHT_FOOT_IK_ROTATION_VAR("rightFootIKRotationVar"); static const QString MAIN_STATE_MACHINE_RIGHT_FOOT_ROTATION("mainStateMachineRightFootRotation"); static const QString MAIN_STATE_MACHINE_RIGHT_FOOT_POSITION("mainStateMachineRightFootPosition"); +static const QString LEFT_HAND_POSITION("leftHandPosition"); +static const QString LEFT_HAND_ROTATION("leftHandRotation"); +static const QString LEFT_HAND_IK_POSITION_VAR("leftHandIKPositionVar"); +static const QString LEFT_HAND_IK_ROTATION_VAR("leftHandIKRotationVar"); +static const QString MAIN_STATE_MACHINE_LEFT_HAND_POSITION("mainStateMachineLeftHandPosition"); +static const QString MAIN_STATE_MACHINE_LEFT_HAND_ROTATION("mainStateMachineLeftHandRotation"); + +static const QString RIGHT_HAND_POSITION("rightHandPosition"); +static const QString RIGHT_HAND_ROTATION("rightHandRotation"); +static const QString RIGHT_HAND_IK_POSITION_VAR("rightHandIKPositionVar"); +static const QString RIGHT_HAND_IK_ROTATION_VAR("rightHandIKRotationVar"); +static const QString MAIN_STATE_MACHINE_RIGHT_HAND_ROTATION("mainStateMachineRightHandRotation"); +static const QString MAIN_STATE_MACHINE_RIGHT_HAND_POSITION("mainStateMachineRightHandPosition"); + Rig::Rig() { // Ensure thread-safe access to the rigRegistry. @@ -1051,16 +1064,29 @@ void Rig::computeMotionAnimationState(float deltaTime, const glm::vec3& worldPos t += deltaTime; - if (_enableInverseKinematics != _lastEnableInverseKinematics) { - if (_enableInverseKinematics) { - _animVars.set("ikOverlayAlpha", 1.0f); - } else { - _animVars.set("ikOverlayAlpha", 0.0f); - } + if (_enableInverseKinematics) { + _animVars.set("ikOverlayAlpha", 1.0f); + _animVars.set("splineIKEnabled", true); + _animVars.set("leftHandIKEnabled", true); + _animVars.set("rightHandIKEnabled", true); + _animVars.set("leftFootIKEnabled", true); + _animVars.set("rightFootIKEnabled", true); + _animVars.set("leftFootPoleVectorEnabled", true); + _animVars.set("rightFootPoleVectorEnabled", true); + } else { + _animVars.set("ikOverlayAlpha", 0.0f); + _animVars.set("splineIKEnabled", false); + _animVars.set("leftHandIKEnabled", false); + _animVars.set("rightHandIKEnabled", false); + _animVars.set("leftFootIKEnabled", false); + _animVars.set("rightFootIKEnabled", false); + _animVars.set("leftHandPoleVectorEnabled", false); + _animVars.set("rightHandPoleVectorEnabled", false); + _animVars.set("leftFootPoleVectorEnabled", false); + _animVars.set("rightFootPoleVectorEnabled", false); } _lastEnableInverseKinematics = _enableInverseKinematics; } - _lastForward = forward; _lastPosition = worldPosition; _lastVelocity = workingVelocity; @@ -1251,6 +1277,7 @@ void Rig::computeHeadFromHMD(const AnimPose& hmdPose, glm::vec3& headPositionOut void Rig::updateHead(bool headEnabled, bool hipsEnabled, const AnimPose& headPose) { if (_animSkeleton) { if (headEnabled) { + _animVars.set("splineIKEnabled", true); _animVars.set("headPosition", headPose.trans()); _animVars.set("headRotation", headPose.rot()); if (hipsEnabled) { @@ -1265,6 +1292,7 @@ void Rig::updateHead(bool headEnabled, bool hipsEnabled, const AnimPose& headPos _animVars.set("headWeight", 8.0f); } } else { + _animVars.set("splineIKEnabled", false); _animVars.unset("headPosition"); _animVars.set("headRotation", headPose.rot()); _animVars.set("headType", (int)IKTarget::Type::RotationOnly); @@ -1396,8 +1424,22 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab const bool ENABLE_POLE_VECTORS = true; + if (headEnabled) { + // always do IK if head is enabled + _animVars.set("leftHandIKEnabled", true); + _animVars.set("rightHandIKEnabled", true); + } else { + // only do IK if we have a valid foot. + _animVars.set("leftHandIKEnabled", leftHandEnabled); + _animVars.set("rightHandIKEnabled", rightHandEnabled); + } + if (leftHandEnabled) { + // we need this for twoBoneIK version of hands. + _animVars.set(LEFT_HAND_IK_POSITION_VAR, LEFT_HAND_POSITION); + _animVars.set(LEFT_HAND_IK_ROTATION_VAR, LEFT_HAND_ROTATION); + glm::vec3 handPosition = leftHandPose.trans(); glm::quat handRotation = leftHandPose.rot(); @@ -1430,8 +1472,11 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab _animVars.set("leftHandPoleVectorEnabled", false); } } else { - _animVars.set("leftHandPoleVectorEnabled", false); + // need this for two bone ik + _animVars.set(LEFT_HAND_IK_POSITION_VAR, MAIN_STATE_MACHINE_LEFT_HAND_POSITION); + _animVars.set(LEFT_HAND_IK_ROTATION_VAR, MAIN_STATE_MACHINE_LEFT_HAND_ROTATION); + _animVars.set("leftHandPoleVectorEnabled", false); _animVars.unset("leftHandPosition"); _animVars.unset("leftHandRotation"); @@ -1445,6 +1490,10 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab if (rightHandEnabled) { + // need this for two bone IK + _animVars.set(RIGHT_HAND_IK_POSITION_VAR, RIGHT_HAND_POSITION); + _animVars.set(RIGHT_HAND_IK_ROTATION_VAR, RIGHT_HAND_ROTATION); + glm::vec3 handPosition = rightHandPose.trans(); glm::quat handRotation = rightHandPose.rot(); @@ -1478,8 +1527,12 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab _animVars.set("rightHandPoleVectorEnabled", false); } } else { - _animVars.set("rightHandPoleVectorEnabled", false); + // need this for two bone IK + _animVars.set(RIGHT_HAND_IK_POSITION_VAR, MAIN_STATE_MACHINE_RIGHT_HAND_POSITION); + _animVars.set(RIGHT_HAND_IK_ROTATION_VAR, MAIN_STATE_MACHINE_RIGHT_HAND_ROTATION); + + _animVars.set("rightHandPoleVectorEnabled", false); _animVars.unset("rightHandPosition"); _animVars.unset("rightHandRotation"); @@ -1697,6 +1750,7 @@ bool Rig::calculateElbowPoleVector(int handIndex, int elbowIndex, int armIndex, correctionVector = forwardAmount * frontVector; } poleVector = glm::normalize(attenuationVector + fullPoleVector + correctionVector); + return true; } @@ -1819,7 +1873,7 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo std::shared_ptr ikNode = getAnimInverseKinematicsNode(); for (int i = 0; i < (int)NumSecondaryControllerTypes; i++) { int index = indexOfJoint(secondaryControllerJointNames[i]); - if (index >= 0) { + if ((index >= 0) && (ikNode)) { if (params.secondaryControllerFlags[i] & (uint8_t)ControllerFlags::Enabled) { ikNode->setSecondaryTargetInRigFrame(index, params.secondaryControllerPoses[i]); } else { diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 395fc3b7b4..b842597b88 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -37,6 +37,7 @@ #include "RenderableModelEntityItem.h" #include +#include #include "Logging.h" @@ -1535,11 +1536,13 @@ void Avatar::setModelURLFinished(bool success) { void Avatar::rigReady() { buildUnscaledEyeHeightCache(); computeMultiSphereShapes(); + buildSpine2SplineRatioCache(); } // rig has been reset. void Avatar::rigReset() { clearUnscaledEyeHeightCache(); + clearSpine2SplineRatioCache(); } void Avatar::computeMultiSphereShapes() { @@ -1994,10 +1997,43 @@ void Avatar::buildUnscaledEyeHeightCache() { } } +void Avatar::buildSpine2SplineRatioCache() { + if (_skeletonModel) { + auto& rig = _skeletonModel->getRig(); + AnimPose hipsRigDefaultPose = rig.getAbsoluteDefaultPose(rig.indexOfJoint("Hips")); + AnimPose headRigDefaultPose(rig.getAbsoluteDefaultPose(rig.indexOfJoint("Head"))); + glm::vec3 basePosition = hipsRigDefaultPose.trans(); + glm::vec3 tipPosition = headRigDefaultPose.trans(); + glm::vec3 spine2Position = rig.getAbsoluteDefaultPose(rig.indexOfJoint("Spine2")).trans(); + + glm::vec3 baseToTip = tipPosition - basePosition; + float baseToTipLength = glm::length(baseToTip); + glm::vec3 baseToTipNormal = baseToTip / baseToTipLength; + glm::vec3 baseToSpine2 = spine2Position - basePosition; + + _spine2SplineRatio = glm::dot(baseToSpine2, baseToTipNormal) / baseToTipLength; + + CubicHermiteSplineFunctorWithArcLength defaultSpline(headRigDefaultPose.rot(), headRigDefaultPose.trans(), hipsRigDefaultPose.rot(), hipsRigDefaultPose.trans()); + + // measure the total arc length along the spline + float totalDefaultArcLength = defaultSpline.arcLength(1.0f); + float t = defaultSpline.arcLengthInverse(_spine2SplineRatio * totalDefaultArcLength); + glm::vec3 defaultSplineSpine2Translation = defaultSpline(t); + + _spine2SplineOffset = spine2Position - defaultSplineSpine2Translation; + } + +} + void Avatar::clearUnscaledEyeHeightCache() { _unscaledEyeHeightCache.set(DEFAULT_AVATAR_EYE_HEIGHT); } +void Avatar::clearSpine2SplineRatioCache() { + _spine2SplineRatio = DEFAULT_AVATAR_EYE_HEIGHT; + _spine2SplineOffset = glm::vec3(); +} + float Avatar::getUnscaledEyeHeightFromSkeleton() const { // TODO: if performance becomes a concern we can cache this value rather then computing it everytime. diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index 1e6893a410..1acee7439f 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -236,6 +236,7 @@ public: virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) override { return false; } virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) override { return false; } +<<<<<<< HEAD // world-space to avatar-space rigconversion functions /**jsdoc * @function MyAvatar.worldToJointPoint @@ -285,6 +286,10 @@ public: * @returns {Quat} */ Q_INVOKABLE glm::quat jointToWorldRotation(const glm::quat& rotation, const int jointIndex = -1) const; +======= + virtual glm::vec3 getSpine2SplineOffset() const { return _spine2SplineOffset; } + virtual float getSpine2SplineRatio() const { return _spine2SplineRatio; } +>>>>>>> cache the spine2 spline default offset and ratio virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override; virtual void setAttachmentData(const QVector& attachmentData) override; @@ -563,7 +568,9 @@ public slots: protected: float getUnscaledEyeHeightFromSkeleton() const; void buildUnscaledEyeHeightCache(); + void buildSpine2SplineRatioCache(); void clearUnscaledEyeHeightCache(); + void clearSpine2SplineRatioCache(); virtual const QString& getSessionDisplayNameForTransport() const override { return _empty; } // Save a tiny bit of bandwidth. Mixer won't look at what we send. QString _empty{}; virtual void maybeUpdateSessionDisplayNameFromTransport(const QString& sessionDisplayName) override { _sessionDisplayName = sessionDisplayName; } // don't use no-op setter! @@ -669,6 +676,8 @@ protected: float _displayNameAlpha { 1.0f }; ThreadSafeValueCache _unscaledEyeHeightCache { DEFAULT_AVATAR_EYE_HEIGHT }; + float _spine2SplineRatio { DEFAULT_SPINE2_SPLINE_PROPORTION }; + glm::vec3 _spine2SplineOffset; std::unordered_map _materials; std::mutex _materialsLock; diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index 9e7f422b40..30bd527546 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -1288,6 +1288,20 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr } joint.inverseBindRotation = joint.inverseDefaultRotation; joint.name = fbxModel.name; +<<<<<<< HEAD +======= + if (hfmModel.hfmToHifiJointNameMapping.contains(hfmModel.hfmToHifiJointNameMapping.key(joint.name))) { + joint.name = hfmModel.hfmToHifiJointNameMapping.key(fbxModel.name); + } + + foreach (const QString& childID, _connectionChildMap.values(modelID)) { + QString type = typeFlags.value(childID); + if (!type.isEmpty()) { + hfmModel.hasSkeletonJoints |= (joint.isSkeletonJoint = type.toLower().contains("Skeleton")); + break; + } + } +>>>>>>> implemented the splineIK in animSplineIK.cpp, todo: disable animinversekinematic.cpp joint.bindTransformFoundInCluster = false; diff --git a/libraries/shared/src/AvatarConstants.h b/libraries/shared/src/AvatarConstants.h index 103782bd3f..d55a63b960 100644 --- a/libraries/shared/src/AvatarConstants.h +++ b/libraries/shared/src/AvatarConstants.h @@ -20,6 +20,7 @@ const float DEFAULT_AVATAR_EYE_TO_TOP_OF_HEAD = 0.11f; // meters const float DEFAULT_AVATAR_NECK_TO_TOP_OF_HEAD = 0.185f; // meters const float DEFAULT_AVATAR_NECK_HEIGHT = DEFAULT_AVATAR_HEIGHT - DEFAULT_AVATAR_NECK_TO_TOP_OF_HEAD; const float DEFAULT_AVATAR_EYE_HEIGHT = DEFAULT_AVATAR_HEIGHT - DEFAULT_AVATAR_EYE_TO_TOP_OF_HEAD; +const float DEFAULT_SPINE2_SPLINE_PROPORTION = 0.71f; const float DEFAULT_AVATAR_SUPPORT_BASE_LEFT = -0.25f; const float DEFAULT_AVATAR_SUPPORT_BASE_RIGHT = 0.25f; const float DEFAULT_AVATAR_SUPPORT_BASE_FRONT = -0.20f; diff --git a/libraries/shared/src/CubicHermiteSpline.h b/libraries/shared/src/CubicHermiteSpline.h index cdbc64308d..c83000996b 100644 --- a/libraries/shared/src/CubicHermiteSpline.h +++ b/libraries/shared/src/CubicHermiteSpline.h @@ -66,19 +66,19 @@ public: memset(_values, 0, sizeof(float) * (NUM_SUBDIVISIONS + 1)); } CubicHermiteSplineFunctorWithArcLength(const glm::vec3& p0, const glm::vec3& m0, const glm::vec3& p1, const glm::vec3& m1) : CubicHermiteSplineFunctor(p0, m0, p1, m1) { - // initialize _values with the accumulated arcLength along the spline. - const float DELTA = 1.0f / NUM_SUBDIVISIONS; - float alpha = 0.0f; - float accum = 0.0f; - _values[0] = 0.0f; - glm::vec3 prevValue = this->operator()(alpha); - for (int i = 1; i < NUM_SUBDIVISIONS + 1; i++) { - glm::vec3 nextValue = this->operator()(alpha + DELTA); - accum += glm::distance(prevValue, nextValue); - alpha += DELTA; - _values[i] = accum; - prevValue = nextValue; - } + + initValues(); + } + + CubicHermiteSplineFunctorWithArcLength(const glm::quat& tipRot, const glm::vec3& tipTrans, const glm::quat& baseRot, const glm::vec3& baseTrans, float baseGain = 1.0f, float tipGain = 1.0f) : CubicHermiteSplineFunctor() { + + float linearDistance = glm::length(baseTrans - tipTrans); + _p0 = baseTrans; + _m0 = baseGain * linearDistance * (baseRot * Vectors::UNIT_Y); + _p1 = tipTrans; + _m1 = tipGain * linearDistance * (tipRot * Vectors::UNIT_Y); + + initValues(); } CubicHermiteSplineFunctorWithArcLength(const CubicHermiteSplineFunctorWithArcLength& orig) : CubicHermiteSplineFunctor(orig) { @@ -110,6 +110,21 @@ public: } protected: float _values[NUM_SUBDIVISIONS + 1]; + + void initValues() { + // initialize _values with the accumulated arcLength along the spline. + const float DELTA = 1.0f / NUM_SUBDIVISIONS; + float alpha = 0.0f; + float accum = 0.0f; + _values[0] = 0.0f; + for (int i = 1; i < NUM_SUBDIVISIONS + 1; i++) { + accum += glm::distance(this->operator()(alpha), + this->operator()(alpha + DELTA)); + alpha += DELTA; + _values[i] = accum; + } + + } }; #endif // hifi_CubicHermiteSpline_h diff --git a/tools/unity-avatar-exporter/Assets/README.txt b/tools/unity-avatar-exporter/Assets/README.txt index b81a620406..c84cec2978 100644 --- a/tools/unity-avatar-exporter/Assets/README.txt +++ b/tools/unity-avatar-exporter/Assets/README.txt @@ -2,6 +2,7 @@ High Fidelity, Inc. Avatar Exporter Version 0.2 + Note: It is recommended to use Unity versions between 2017.4.17f1 and 2018.2.12f1 for this Avatar Exporter. To create a new avatar project: From 9b73c83ebc048a8a2c384332c61d777b5558b247 Mon Sep 17 00:00:00 2001 From: amantley Date: Fri, 22 Feb 2019 11:50:38 -0800 Subject: [PATCH 12/33] removed merge markers (cherry picked from commit 4286142daac70269de155c99c9bbdb1f951eaff6) --- .../avatars-renderer/src/avatars-renderer/Avatar.h | 3 --- libraries/fbx/src/FBXSerializer.cpp | 14 -------------- 2 files changed, 17 deletions(-) diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index 1acee7439f..3d25c275b1 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -236,7 +236,6 @@ public: virtual bool setAbsoluteJointRotationInObjectFrame(int index, const glm::quat& rotation) override { return false; } virtual bool setAbsoluteJointTranslationInObjectFrame(int index, const glm::vec3& translation) override { return false; } -<<<<<<< HEAD // world-space to avatar-space rigconversion functions /**jsdoc * @function MyAvatar.worldToJointPoint @@ -286,10 +285,8 @@ public: * @returns {Quat} */ Q_INVOKABLE glm::quat jointToWorldRotation(const glm::quat& rotation, const int jointIndex = -1) const; -======= virtual glm::vec3 getSpine2SplineOffset() const { return _spine2SplineOffset; } virtual float getSpine2SplineRatio() const { return _spine2SplineRatio; } ->>>>>>> cache the spine2 spline default offset and ratio virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override; virtual void setAttachmentData(const QVector& attachmentData) override; diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index 30bd527546..9e7f422b40 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -1288,20 +1288,6 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr } joint.inverseBindRotation = joint.inverseDefaultRotation; joint.name = fbxModel.name; -<<<<<<< HEAD -======= - if (hfmModel.hfmToHifiJointNameMapping.contains(hfmModel.hfmToHifiJointNameMapping.key(joint.name))) { - joint.name = hfmModel.hfmToHifiJointNameMapping.key(fbxModel.name); - } - - foreach (const QString& childID, _connectionChildMap.values(modelID)) { - QString type = typeFlags.value(childID); - if (!type.isEmpty()) { - hfmModel.hasSkeletonJoints |= (joint.isSkeletonJoint = type.toLower().contains("Skeleton")); - break; - } - } ->>>>>>> implemented the splineIK in animSplineIK.cpp, todo: disable animinversekinematic.cpp joint.bindTransformFoundInCluster = false; From a87e49bb23ea6c23f979468f624bfe3ec112cb18 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 22 Feb 2019 15:01:30 -0800 Subject: [PATCH 13/33] start in quest dev --- interface/src/Application.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a611738445..3864ba30c0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2414,6 +2414,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo AndroidHelper::instance().notifyLoadComplete(); #endif pauseUntilLoginDetermined(); + +#if defined(Q_OS_ANDROID) + const QString QUEST_DEV = "hifi://quest-dev"; + DependencyManager::get()->handleLookupString(QUEST_DEV); +#endif } void Application::updateVerboseLogging() { From 5bf994626ca14723a9cd6cc3104052da48b3c07b Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Fri, 22 Feb 2019 16:28:36 -0800 Subject: [PATCH 14/33] scaling culling projection matrix by 1.5 to help reduce teh ugly effect of stuff getting cut off too early --- .../oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp b/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp index bc8e1a5113..3b8bf50724 100644 --- a/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp +++ b/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp @@ -120,7 +120,10 @@ QRectF OculusMobileDisplayPlugin::getPlayAreaRect() { } glm::mat4 OculusMobileDisplayPlugin::getEyeProjection(Eye eye, const glm::mat4& baseProjection) const { + qDebug()<< "QQQ_ " << __FUNCTION__; + glm::mat4 result = baseProjection; + VrHandler::withOvrMobile([&](ovrMobile* session){ auto trackingState = vrapi_GetPredictedTracking2(session, 0.0); result = ovr::Fov{ trackingState.Eye[eye].ProjectionMatrix }.withZ(baseProjection); @@ -136,9 +139,13 @@ glm::mat4 OculusMobileDisplayPlugin::getCullingProjection(const glm::mat4& baseP for (size_t i = 0; i < 2; ++i) { fovs[i].extract(trackingState.Eye[i].ProjectionMatrix); } + fovs[0].extend(fovs[1]); - return fovs[0].withZ(baseProjection); + result= glm::scale( fovs[0].withZ(baseProjection),glm::vec3(1.5f)); }); + + + return result; } From 5c1e5e0c460f3fc2ce2771bac33d52a7a433b22e Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Fri, 22 Feb 2019 16:30:17 -0800 Subject: [PATCH 15/33] cleanup --- .../oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp b/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp index 3b8bf50724..cf82d7aba5 100644 --- a/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp +++ b/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp @@ -120,8 +120,6 @@ QRectF OculusMobileDisplayPlugin::getPlayAreaRect() { } glm::mat4 OculusMobileDisplayPlugin::getEyeProjection(Eye eye, const glm::mat4& baseProjection) const { - qDebug()<< "QQQ_ " << __FUNCTION__; - glm::mat4 result = baseProjection; VrHandler::withOvrMobile([&](ovrMobile* session){ @@ -142,10 +140,9 @@ glm::mat4 OculusMobileDisplayPlugin::getCullingProjection(const glm::mat4& baseP fovs[0].extend(fovs[1]); result= glm::scale( fovs[0].withZ(baseProjection),glm::vec3(1.5f)); + return result; }); - - return result; } From dab0df1113ffe663f93ff20246353b6bf2408cfe Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Fri, 22 Feb 2019 18:03:23 -0800 Subject: [PATCH 16/33] Trying to fix the damn gamma --- .../display-plugins/OpenGLDisplayPlugin.cpp | 5 ++++- .../src/display-plugins/SrgbToLinear.slf | 3 ++- .../src/OculusMobileDisplayPlugin.cpp | 13 ++++++++++-- .../utilities/render/deferredLighting.qml | 21 +++++++++++++++++++ 4 files changed, 38 insertions(+), 4 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 20fc9a2290..28de13d8c2 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -516,6 +516,7 @@ void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, const gpu::Textur #ifndef USE_GLES batch.setPipeline(_presentPipeline); #else + //batch.setPipeline(_presentPipeline); batch.setPipeline(_simplePipeline); #endif batch.draw(gpu::TRIANGLE_STRIP, 4); @@ -630,7 +631,8 @@ void OpenGLDisplayPlugin::compositeScene() { batch.setStateScissorRect(ivec4(uvec2(), _compositeFramebuffer->getSize())); batch.resetViewTransform(); batch.setProjectionTransform(mat4()); - batch.setPipeline(_simplePipeline); + // batch.setPipeline(_simplePipeline); + batch.setPipeline(_presentPipeline); batch.setResourceTexture(0, _currentFrame->framebuffer->getRenderBuffer(0)); batch.draw(gpu::TRIANGLE_STRIP, 4); }); @@ -885,6 +887,7 @@ void OpenGLDisplayPlugin::updateCompositeFramebuffer() { auto renderSize = glm::uvec2(getRecommendedRenderSize()); if (!_compositeFramebuffer || _compositeFramebuffer->getSize() != renderSize) { _compositeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("OpenGLDisplayPlugin::composite", gpu::Element::COLOR_RGBA_32, renderSize.x, renderSize.y)); + // _compositeFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("OpenGLDisplayPlugin::composite", gpu::Element::COLOR_SRGBA_32, renderSize.x, renderSize.y)); } } diff --git a/libraries/display-plugins/src/display-plugins/SrgbToLinear.slf b/libraries/display-plugins/src/display-plugins/SrgbToLinear.slf index 8b324c81a5..428ec821a6 100644 --- a/libraries/display-plugins/src/display-plugins/SrgbToLinear.slf +++ b/libraries/display-plugins/src/display-plugins/SrgbToLinear.slf @@ -18,5 +18,6 @@ vec3 colorToLinearRGB(vec3 srgb) { void main(void) { outFragColor.a = 1.0; - outFragColor.rgb = colorToLinearRGB(texture(colorMap, varTexCoord0).rgb); + // outFragColor.rgb = colorToLinearRGB(texture(colorMap, varTexCoord0).rgb); + outFragColor.rgb = pow(texture(colorMap, varTexCoord0).rgb, vec3(1.0 / 2.2)); } diff --git a/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp b/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp index bc8e1a5113..ea1a81c4ae 100644 --- a/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp +++ b/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp @@ -6,6 +6,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "OculusMobileDisplayPlugin.h" +#include "../../oculusMobile/src/ovr/Helpers.h" #include #include @@ -58,7 +59,7 @@ void OculusMobileDisplayPlugin::deinit() { bool OculusMobileDisplayPlugin::internalActivate() { _renderTargetSize = { 1024, 512 }; - _cullingProjection = ovr::toGlm(ovrMatrix4f_CreateProjectionFov(90.0f, 90.0f, 0.0f, 0.0f, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)); + _cullingProjection = ovr::toGlm(ovrMatrix4f_CreateProjectionFov(90.0f, 90.0f, 90.0f, 90.0f, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)); withOvrJava([&](const ovrJava* java){ @@ -130,6 +131,7 @@ glm::mat4 OculusMobileDisplayPlugin::getEyeProjection(Eye eye, const glm::mat4& glm::mat4 OculusMobileDisplayPlugin::getCullingProjection(const glm::mat4& baseProjection) const { glm::mat4 result = baseProjection; + VrHandler::withOvrMobile([&](ovrMobile* session){ auto trackingState = vrapi_GetPredictedTracking2(session, 0.0); ovr::Fov fovs[2]; @@ -137,7 +139,14 @@ glm::mat4 OculusMobileDisplayPlugin::getCullingProjection(const glm::mat4& baseP fovs[i].extract(trackingState.Eye[i].ProjectionMatrix); } fovs[0].extend(fovs[1]); - return fovs[0].withZ(baseProjection); + float horizontalMargin = 1.1f; + float verticalMargin = 1.5f; + fovs[0].leftRightUpDown[0] *= horizontalMargin; + fovs[0].leftRightUpDown[1] *= horizontalMargin; + fovs[0].leftRightUpDown[2] *= verticalMargin; + fovs[0].leftRightUpDown[3] *= verticalMargin; + + return fovs[0].withZ(baseProjection); }); return result; } diff --git a/scripts/developer/utilities/render/deferredLighting.qml b/scripts/developer/utilities/render/deferredLighting.qml index f5c0b8c5da..d147585212 100644 --- a/scripts/developer/utilities/render/deferredLighting.qml +++ b/scripts/developer/utilities/render/deferredLighting.qml @@ -148,6 +148,27 @@ Rectangle { } } Separator {} + Column { + anchors.left: parent.left + anchors.right: parent.right + spacing: 5 + Repeater { + model: [ "MSAA:PrepareFramebuffer:numSamples:4:1" + ] + ConfigSlider { + label: qsTr(modelData.split(":")[0]) + integral: true + config: render.mainViewTask.getConfig(modelData.split(":")[1]) + property: modelData.split(":")[2] + max: modelData.split(":")[3] + min: modelData.split(":")[4] + + anchors.left: parent.left + anchors.right: parent.right + } + } + } + Separator {} Item { height: childrenRect.height From 26ad42b9657e9c348f4bd3f637a5da3bef57a79c Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Sun, 24 Feb 2019 19:07:56 -0800 Subject: [PATCH 17/33] FIxing the gamma correction for Quest, intoducing simple gpu lib conversion shaders --- .../display-plugins/OpenGLDisplayPlugin.cpp | 22 +++++++++++----- libraries/gpu/src/gpu/Color.slh | 21 ++++++++++++--- .../src/gpu/DrawTextureGammaLinearToSRGB.slf | 26 +++++++++++++++++++ .../src/gpu/DrawTextureGammaLinearToSRGB.slp | 1 + .../src/gpu/DrawTextureGammaSRGBToLinear.slf | 26 +++++++++++++++++++ .../src/gpu/DrawTextureGammaSRGBToLinear.slp | 1 + .../oculusMobile/src/ovr/Framebuffer.cpp | 11 ++++---- 7 files changed, 93 insertions(+), 15 deletions(-) create mode 100644 libraries/gpu/src/gpu/DrawTextureGammaLinearToSRGB.slf create mode 100644 libraries/gpu/src/gpu/DrawTextureGammaLinearToSRGB.slp create mode 100644 libraries/gpu/src/gpu/DrawTextureGammaSRGBToLinear.slf create mode 100644 libraries/gpu/src/gpu/DrawTextureGammaSRGBToLinear.slp diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 28de13d8c2..c536e6b6e2 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -380,16 +380,26 @@ void OpenGLDisplayPlugin::customizeContext() { scissorState->setScissorEnable(true); { +#ifdef Q_OS_ANDROID + gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTextureGammaLinearToSRGB); +#else gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTexture); - _simplePipeline = gpu::Pipeline::create(program, scissorState); - _hudPipeline = gpu::Pipeline::create(program, blendState); +#endif + _simplePipeline = gpu::Pipeline::create(program, scissorState); } - { - gpu::ShaderPointer program = gpu::Shader::createProgram(shader::display_plugins::program::SrgbToLinear); +#ifdef Q_OS_ANDROID + gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTextureGammaLinearToSRGB); +#else + gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTextureGammaSRGBToLinear); +#endif _presentPipeline = gpu::Pipeline::create(program, scissorState); } + { + gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTexture); + _hudPipeline = gpu::Pipeline::create(program, blendState); + } { gpu::ShaderPointer program = gpu::Shader::createProgram(shader::gpu::program::DrawTextureMirroredX); _mirrorHUDPipeline = gpu::Pipeline::create(program, blendState); @@ -516,7 +526,6 @@ void OpenGLDisplayPlugin::renderFromTexture(gpu::Batch& batch, const gpu::Textur #ifndef USE_GLES batch.setPipeline(_presentPipeline); #else - //batch.setPipeline(_presentPipeline); batch.setPipeline(_simplePipeline); #endif batch.draw(gpu::TRIANGLE_STRIP, 4); @@ -631,8 +640,7 @@ void OpenGLDisplayPlugin::compositeScene() { batch.setStateScissorRect(ivec4(uvec2(), _compositeFramebuffer->getSize())); batch.resetViewTransform(); batch.setProjectionTransform(mat4()); - // batch.setPipeline(_simplePipeline); - batch.setPipeline(_presentPipeline); + batch.setPipeline(_simplePipeline); batch.setResourceTexture(0, _currentFrame->framebuffer->getRenderBuffer(0)); batch.draw(gpu::TRIANGLE_STRIP, 4); }); diff --git a/libraries/gpu/src/gpu/Color.slh b/libraries/gpu/src/gpu/Color.slh index 65ddc0b01e..af61e5a34b 100644 --- a/libraries/gpu/src/gpu/Color.slh +++ b/libraries/gpu/src/gpu/Color.slh @@ -16,10 +16,10 @@ // YCoCg =====> Luma (Y) chrominance green (Cg) and chrominance orange (Co) // https://software.intel.com/en-us/node/503873 +// sRGB ====> Linear float color_scalar_sRGBToLinear(float value) { - const float SRGB_ELBOW = 0.04045; - - return mix(pow((value + 0.055) / 1.055, 2.4), value / 12.92, float(value <= SRGB_ELBOW)); + // Same as pow(value, 2.2) + return mix(pow((value + 0.055) / 1.055, 2.4), value / 12.92, float(value <= 0.04045)); } vec3 color_sRGBToLinear(vec3 srgb) { @@ -30,6 +30,21 @@ vec4 color_sRGBAToLinear(vec4 srgba) { return vec4(color_sRGBToLinear(srgba.xyz), srgba.w); } +// Linear ====> sRGB +float color_scalar_LinearTosRGB(float value) { + // Same as return pow(value, 1/2.2) + return mix(1.055 * pow(value, 0.41666) - 0.055, value * 12.92, float(value < 0.0031308)); +} + +vec3 color_LinearTosRGB(vec3 lrgb) { + // Same as return pow(lrgb, 1/2.2) + return vec3(color_scalar_LinearTosRGB(lrgb.r), color_scalar_LinearTosRGB(lrgb.g), color_scalar_LinearTosRGB(lrgb.b)); +} + +vec4 color_LinearTosRGBA(vec4 lrgba) { + return vec4(color_LinearTosRGB(lrgba.xyz), lrgba.w); +} + vec3 color_LinearToYCoCg(vec3 rgb) { // Y = R/4 + G/2 + B/4 // Co = R/2 - B/2 diff --git a/libraries/gpu/src/gpu/DrawTextureGammaLinearToSRGB.slf b/libraries/gpu/src/gpu/DrawTextureGammaLinearToSRGB.slf new file mode 100644 index 0000000000..017df1d88d --- /dev/null +++ b/libraries/gpu/src/gpu/DrawTextureGammaLinearToSRGB.slf @@ -0,0 +1,26 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// DrawTexture.frag +// +// Draw texture 0 fetched at texcoord.xy +// +// Created by Sam Gateau on 6/22/2015 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +<@include gpu/Color.slh@> + + +LAYOUT(binding=0) uniform sampler2D colorMap; + +layout(location=0) in vec2 varTexCoord0; +layout(location=0) out vec4 outFragColor; + +void main(void) { + outFragColor = color_LinearTosRGBA(texture(colorMap, varTexCoord0)); +} diff --git a/libraries/gpu/src/gpu/DrawTextureGammaLinearToSRGB.slp b/libraries/gpu/src/gpu/DrawTextureGammaLinearToSRGB.slp new file mode 100644 index 0000000000..f922364b75 --- /dev/null +++ b/libraries/gpu/src/gpu/DrawTextureGammaLinearToSRGB.slp @@ -0,0 +1 @@ +VERTEX DrawUnitQuadTexcoord diff --git a/libraries/gpu/src/gpu/DrawTextureGammaSRGBToLinear.slf b/libraries/gpu/src/gpu/DrawTextureGammaSRGBToLinear.slf new file mode 100644 index 0000000000..048384fe6c --- /dev/null +++ b/libraries/gpu/src/gpu/DrawTextureGammaSRGBToLinear.slf @@ -0,0 +1,26 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// DrawTexture.frag +// +// Draw texture 0 fetched at texcoord.xy +// +// Created by Sam Gateau on 6/22/2015 +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +<@include gpu/Color.slh@> + + +LAYOUT(binding=0) uniform sampler2D colorMap; + +layout(location=0) in vec2 varTexCoord0; +layout(location=0) out vec4 outFragColor; + +void main(void) { + outFragColor = color_sRGBAToLinear(texture(colorMap, varTexCoord0)); +} diff --git a/libraries/gpu/src/gpu/DrawTextureGammaSRGBToLinear.slp b/libraries/gpu/src/gpu/DrawTextureGammaSRGBToLinear.slp new file mode 100644 index 0000000000..f922364b75 --- /dev/null +++ b/libraries/gpu/src/gpu/DrawTextureGammaSRGBToLinear.slp @@ -0,0 +1 @@ +VERTEX DrawUnitQuadTexcoord diff --git a/libraries/oculusMobile/src/ovr/Framebuffer.cpp b/libraries/oculusMobile/src/ovr/Framebuffer.cpp index 4c4fd2a983..0f59eef614 100644 --- a/libraries/oculusMobile/src/ovr/Framebuffer.cpp +++ b/libraries/oculusMobile/src/ovr/Framebuffer.cpp @@ -32,18 +32,19 @@ void Framebuffer::create(const glm::uvec2& size) { _validTexture = false; // Depth renderbuffer - glGenRenderbuffers(1, &_depth); + /* glGenRenderbuffers(1, &_depth); glBindRenderbuffer(GL_RENDERBUFFER, _depth); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, _size.x, _size.y); glBindRenderbuffer(GL_RENDERBUFFER, 0); - +*/ // Framebuffer glGenFramebuffers(1, &_fbo); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo); - glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depth); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + // glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _fbo); + // glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, _depth); + // glBindFramebuffer(GL_FRAMEBUFFER, 0); _swapChain = vrapi_CreateTextureSwapChain3(VRAPI_TEXTURE_TYPE_2D, GL_RGBA8, _size.x, _size.y, 1, 3); + _length = vrapi_GetTextureSwapChainLength(_swapChain); if (!_length) { __android_log_write(ANDROID_LOG_WARN, "QQQ_OVR", "Unable to count swap chain textures"); From 4ee2b4322951e46f20355107758d6aea96c58245 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Sun, 24 Feb 2019 20:49:51 -0800 Subject: [PATCH 18/33] FIxing the gamma correction for Quest, intoducing simple gpu lib conversion shaders --- .../src/display-plugins/SrgbToLinear.slf | 23 ------------------- .../src/display-plugins/SrgbToLinear.slp | 1 - libraries/gpu/src/gpu/Color.slh | 8 +++++-- 3 files changed, 6 insertions(+), 26 deletions(-) delete mode 100644 libraries/display-plugins/src/display-plugins/SrgbToLinear.slf delete mode 100644 libraries/display-plugins/src/display-plugins/SrgbToLinear.slp diff --git a/libraries/display-plugins/src/display-plugins/SrgbToLinear.slf b/libraries/display-plugins/src/display-plugins/SrgbToLinear.slf deleted file mode 100644 index 428ec821a6..0000000000 --- a/libraries/display-plugins/src/display-plugins/SrgbToLinear.slf +++ /dev/null @@ -1,23 +0,0 @@ -// OpenGLDisplayPlugin_present.frag - -LAYOUT(binding=0) uniform sampler2D colorMap; - -layout(location=0) in vec2 varTexCoord0; - -layout(location=0) out vec4 outFragColor; - -float sRGBFloatToLinear(float value) { - const float SRGB_ELBOW = 0.04045; - - return mix(pow((value + 0.055) / 1.055, 2.4), value / 12.92, float(value <= SRGB_ELBOW)); -} - -vec3 colorToLinearRGB(vec3 srgb) { - return vec3(sRGBFloatToLinear(srgb.r), sRGBFloatToLinear(srgb.g), sRGBFloatToLinear(srgb.b)); -} - -void main(void) { - outFragColor.a = 1.0; - // outFragColor.rgb = colorToLinearRGB(texture(colorMap, varTexCoord0).rgb); - outFragColor.rgb = pow(texture(colorMap, varTexCoord0).rgb, vec3(1.0 / 2.2)); -} diff --git a/libraries/display-plugins/src/display-plugins/SrgbToLinear.slp b/libraries/display-plugins/src/display-plugins/SrgbToLinear.slp deleted file mode 100644 index c2c4bfbebd..0000000000 --- a/libraries/display-plugins/src/display-plugins/SrgbToLinear.slp +++ /dev/null @@ -1 +0,0 @@ -VERTEX gpu::vertex::DrawUnitQuadTexcoord diff --git a/libraries/gpu/src/gpu/Color.slh b/libraries/gpu/src/gpu/Color.slh index af61e5a34b..c676e66c6c 100644 --- a/libraries/gpu/src/gpu/Color.slh +++ b/libraries/gpu/src/gpu/Color.slh @@ -23,7 +23,10 @@ float color_scalar_sRGBToLinear(float value) { } vec3 color_sRGBToLinear(vec3 srgb) { - return vec3(color_scalar_sRGBToLinear(srgb.r), color_scalar_sRGBToLinear(srgb.g), color_scalar_sRGBToLinear(srgb.b)); + // return vec3(color_scalar_sRGBToLinear(srgb.r), color_scalar_sRGBToLinear(srgb.g), color_scalar_sRGBToLinear(srgb.b)); + // Same as pow(value, 2.2) + return mix(pow((srgb + vec3(0.055)) / vec3(1.055), vec3(2.4)), srgb / vec3(12.92), vec3(lessThanEqual(srgb, vec3(0.04045)))); + } vec4 color_sRGBAToLinear(vec4 srgba) { @@ -38,7 +41,8 @@ float color_scalar_LinearTosRGB(float value) { vec3 color_LinearTosRGB(vec3 lrgb) { // Same as return pow(lrgb, 1/2.2) - return vec3(color_scalar_LinearTosRGB(lrgb.r), color_scalar_LinearTosRGB(lrgb.g), color_scalar_LinearTosRGB(lrgb.b)); +// return vec3(color_scalar_LinearTosRGB(lrgb.r), color_scalar_LinearTosRGB(lrgb.g), color_scalar_LinearTosRGB(lrgb.b)); + return mix(vec3(1.055) * pow(vec3(lrgb), vec3(0.41666)) - vec3(0.055), vec3(lrgb) * vec3(12.92), vec3(lessThan(lrgb, vec3(0.0031308)))); } vec4 color_LinearTosRGBA(vec4 lrgba) { From df6d8f3be00c621023405f6b9bbfe5d3ab333755 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Sun, 24 Feb 2019 21:31:28 -0800 Subject: [PATCH 19/33] FIxing the gamma correction for Quest, intoducing simple gpu lib conversion shaders --- libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp b/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp index 7943d058bd..a63b954f02 100644 --- a/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp +++ b/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp @@ -6,7 +6,6 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "OculusMobileDisplayPlugin.h" -#include "../../oculusMobile/src/ovr/Helpers.h" #include #include From b563f21037878bb28812c9100d0cbedd5871809e Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 25 Feb 2019 09:32:27 -0800 Subject: [PATCH 20/33] Fix comments --- libraries/gpu/src/gpu/DrawTextureGammaLinearToSRGB.slf | 8 ++++---- libraries/gpu/src/gpu/DrawTextureGammaSRGBToLinear.slf | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/gpu/src/gpu/DrawTextureGammaLinearToSRGB.slf b/libraries/gpu/src/gpu/DrawTextureGammaLinearToSRGB.slf index 017df1d88d..3ca3a92f01 100644 --- a/libraries/gpu/src/gpu/DrawTextureGammaLinearToSRGB.slf +++ b/libraries/gpu/src/gpu/DrawTextureGammaLinearToSRGB.slf @@ -2,12 +2,12 @@ <$VERSION_HEADER$> // Generated on <$_SCRIBE_DATE$> // -// DrawTexture.frag +// DrawTextureGammaLinearToSRGB.frag // -// Draw texture 0 fetched at texcoord.xy +// Draw texture 0 fetched at texcoord.xy, and apply linear to sRGB color space conversion // -// Created by Sam Gateau on 6/22/2015 -// Copyright 2015 High Fidelity, Inc. +// Created by Sam Gateau on 2/24/2019 +// Copyright 2019 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/libraries/gpu/src/gpu/DrawTextureGammaSRGBToLinear.slf b/libraries/gpu/src/gpu/DrawTextureGammaSRGBToLinear.slf index 048384fe6c..870967ec3a 100644 --- a/libraries/gpu/src/gpu/DrawTextureGammaSRGBToLinear.slf +++ b/libraries/gpu/src/gpu/DrawTextureGammaSRGBToLinear.slf @@ -2,12 +2,12 @@ <$VERSION_HEADER$> // Generated on <$_SCRIBE_DATE$> // -// DrawTexture.frag +// DrawTextureGammaSRGBToLinear.frag // -// Draw texture 0 fetched at texcoord.xy +// Draw texture 0 fetched at texcoord.xy, and apply sRGB to Linear color space conversion // -// Created by Sam Gateau on 6/22/2015 -// Copyright 2015 High Fidelity, Inc. +// Created by Sam Gateau on 2/24/2019 +// Copyright 2019 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html From 5831db30891244ebdf9658e502080517a7d5030d Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 22 Feb 2019 13:35:52 -0800 Subject: [PATCH 21/33] Build quest demo apk on Jenkins --- android/apps/questInterface/build.gradle | 19 +++++++------ android/apps/questInterface/keystore.jks | Bin 0 -> 2223 bytes android/build_android.sh | 33 ++++++++++++++++++----- android/containerized_build.sh | 2 ++ 4 files changed, 38 insertions(+), 16 deletions(-) create mode 100644 android/apps/questInterface/keystore.jks diff --git a/android/apps/questInterface/build.gradle b/android/apps/questInterface/build.gradle index 3d13877607..bf600b5df1 100644 --- a/android/apps/questInterface/build.gradle +++ b/android/apps/questInterface/build.gradle @@ -44,10 +44,15 @@ android { } signingConfigs { release { - storeFile project.hasProperty("HIFI_ANDROID_KEYSTORE") ? file(HIFI_ANDROID_KEYSTORE) : null - storePassword project.hasProperty("HIFI_ANDROID_KEYSTORE_PASSWORD") ? HIFI_ANDROID_KEYSTORE_PASSWORD : '' - keyAlias project.hasProperty("HIFI_ANDROID_KEY_ALIAS") ? HIFI_ANDROID_KEY_ALIAS : '' - keyPassword project.hasProperty("HIFI_ANDROID_KEY_PASSWORD") ? HIFI_ANDROID_KEY_PASSWORD : '' + // Hack for Quest demo + storeFile file("keystore.jks") + storePassword "password" + keyAlias "key0" + keyPassword "password" + // storeFile project.hasProperty("HIFI_ANDROID_KEYSTORE") ? file(HIFI_ANDROID_KEYSTORE) : null + // storePassword project.hasProperty("HIFI_ANDROID_KEYSTORE_PASSWORD") ? HIFI_ANDROID_KEYSTORE_PASSWORD : '' + // keyAlias project.hasProperty("HIFI_ANDROID_KEY_ALIAS") ? HIFI_ANDROID_KEY_ALIAS : '' + // keyPassword project.hasProperty("HIFI_ANDROID_KEY_PASSWORD") ? HIFI_ANDROID_KEY_PASSWORD : '' v2SigningEnabled false } } @@ -133,12 +138,6 @@ android { assetList.each { file -> out.println(file) } } } - - variant.outputs.all { - if (RELEASE_NUMBER != '0') { - outputFileName = "app_" + RELEASE_NUMBER + "_" + RELEASE_TYPE + ".apk" - } - } } } diff --git a/android/apps/questInterface/keystore.jks b/android/apps/questInterface/keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..4b646122f6f20c60a69d27f15590bc69a757ef60 GIT binary patch literal 2223 zcmcgs={wX51O3fvX1rrx=GM4~5QE=bW0`ntS)(isLbC5-EMaVA(ny7CEs;T}s4SI2 zg|SDLNJ7XyGE|oA?o-eEKF|FN-Vf))Ip@nc=fm0O>~jDBfC2yj`3<3P=bXA`j(81FAhsS$ zAO5f&X%HvyB`iGj4 zwp#gCx-pp1C~MYb8jor+@}K(fqOz+(FEKiPyzx-2$z8qH zqHbD3rM+OPGOmC1O0m%KOxBp-dbsEAp5ORo$}*c$cKZgXxv-~aT!o*u5%*Vs-HdwU zW^#h@vSv*Y=de+XCtsBLVdL3YdheCo#+lu3yXwJnW8rPr@YKqv#!Df+u2*6?<%co~ z{SrGP@KZs&Yp2f>e0;N{dVM+@<@86K`v$P&JGgt3Zc)$7)lV90uYoNae;B5vLc_9$ zp5G~ZpfF{B9&jt_A^5K`vn`NZ)WCDLr$u}tYDMF6er$P^8dEVx?Wrw#7TQzN!3m`p zbf87ffQf>Dchzji;kkaR4K(%@jV6*!x{8RP^+-Aj3ncL8Pd}gP15)(Se)6$vPJSAC9mo!F%IGAkG>ld9d zIbuym8VlrW80aFhv8U!G^IZyBJ!!3BFW7x3G~SPRU$l70bkJXY*Dq6ZvO+jE8(;2? z*2OWXac@dgchXXm%24@D8QVy1N|l{Hdxg99RG3Lhy~3TMYAbxsa9wL{ez%L1?DqC4 z+Ff{mHK3Mf-V;hOmkW&H%N6bET1>yQw(xdq5-->6ec+h4sOG%Ys|Wl_}+^*VD$)aXn5q+T~o>mG9@H_Wmhd&p(1eT;KbWYuk*>1tN$q-W5g zVaF8fEN)NQMDz0${lMCs{QaaPe~IV7rfet+ehKc&=E03;@@a%cn`TX5=N!F--Om+m zbLcb2V&Bai{eeKLT62tsSH2ECI;a=$NFd!ssfX~g4LUp?fKS$kyL!_y0@`nB_DyFJ ztQRO+@3#b+_K(ALKea<1Q!)_wx{#PH8_q))C!r$DXj1QSmy9>x9Y^11QuFq51|1(8 zseax~9#zJZIW?Tr>6<&Qou4(Wj+aQ_7nby0El(<;`+B}%%KmgNtEDkyecPTnZk%WzDjZ4xGSkm#hUp+)Z0t7 zl(2Yc-H{TY(G|{oy_FlMY54T|sW@pS@9;FU6(Mp%DxPy1qJ;*;JiXfMy3E4kDi)H` zANLnVwY|{UADj{BYNG}F+eM_zSpO7EX3wnJc}K){#T8%86Ffro$TFhL>x5Lb@?Pnv|@#n3R{ zKnVlaaNkhyPf;vUgGl@f1VJL1r0yV!C8-dJMACoh|0e_;a^&CTAqW6QhwuU*9fE<< zArPQUqHp`-n-Mu(TzgUXg*)#2_ghBAwht9Jm9hful2-XWB9h0GzE;tmk)^x#?Wa3` z&We}lbI!Mf)LT~Zl%u|Fl4tIju4KtGj}Du{kPeE}5oltSRs3@0Q=^p--GIjzS|d6= zZ1F+#d|ZCkTD>bepd;0w%xGDsxc5(vE0>^Of04vMyK8lvh~>Mnc`euBmm5AGqUQ-S z@@jhf-Vnl=)^mT^HA5K}QQRcsnpciEJGBh=6swNKoUg zDRfp<_S%C4YRgoO8cq=2G#*8Y`o78#+c9Xvh1V~^R%D6R^H`^IG6&)#&8Riy)9;`# z2mrY!35tVaNSKWn4_pK;l#qF$NwhjkZ?C)Wc_~X>7?eSo|9eF4-y=c*X37vNCh^J) z>1d$^^&-k4*##0_Bik?*LCSTH+ptz!r)s;&1|6teZ)2C*i$CbtX|WVCYQ$fbbGw>7u_XWd7XkpJi?(T?Zp0@ zqJ4=#o%meLIYxha<-wpXv0cs5oTA7lIfdJXkJvf3#q5|RIn^va2$^hR??~2;1a>j+ zPGpc-d&SrWgOE+R+TQ;Dcz_U-z5};j!t84AFtb|uk8nS_z|QU~EV(Fh{;3obuLvzU KB59rbJmw!9zT}$# literal 0 HcmV?d00001 diff --git a/android/build_android.sh b/android/build_android.sh index a066332f9a..106a295750 100755 --- a/android/build_android.sh +++ b/android/build_android.sh @@ -1,11 +1,32 @@ #!/usr/bin/env bash set -xeuo pipefail + +ANDROID_BUILD_TYPE=release +ANDROID_BUILD_TARGET=assembleRelease + +case "$RELEASE_TYPE" in + PR) ANDROID_APK_SUFFIX=PR${RELEASE_NUMBER}-${SHA7}.apk ;; + *) ANDROID_APK_SUFFIX=${RELEASE_NUMBER}-${SHA7}.apk ;; +esac + + +# Interface build +ANDROID_APP=interface +ANDROID_OUTPUT_DIR=./apps/${ANDROID_APP}/build/outputs/apk/${ANDROID_BUILD_TYPE} +ANDROID_OUTPUT_FILE=${ANDROID_APP}-${ANDROID_BUILD_TYPE}-unsigned.apk +ANDROID_APK_NAME=HighFidelity-Beta-${ANDROID_APK_SUFFIX} ./gradlew -PHIFI_ANDROID_PRECOMPILED=${HIFI_ANDROID_PRECOMPILED} -PVERSION_CODE=${VERSION_CODE} -PRELEASE_NUMBER=${RELEASE_NUMBER} -PRELEASE_TYPE=${RELEASE_TYPE} ${ANDROID_APP}:${ANDROID_BUILD_TARGET} +cp ${ANDROID_OUTPUT_DIR}/${ANDROID_OUTPUT_FILE} ./${ANDROID_APK_NAME} + +# Quest Interface build +ANDROID_APP=questInterface +ANDROID_OUTPUT_DIR=./apps/${ANDROID_APP}/build/outputs/apk/${ANDROID_BUILD_TYPE} +ANDROID_OUTPUT_FILE=${ANDROID_APP}-${ANDROID_BUILD_TYPE}.apk +ANDROID_APK_NAME=HighFidelity-Quest-Beta-${ANDROID_APK_SUFFIX} +./gradlew -PHIFI_ANDROID_PRECOMPILED=${HIFI_ANDROID_PRECOMPILED} -PVERSION_CODE=${VERSION_CODE} -PRELEASE_NUMBER=${RELEASE_NUMBER} -PRELEASE_TYPE=${RELEASE_TYPE} ${ANDROID_APP}:${ANDROID_BUILD_TARGET} +cp ${ANDROID_OUTPUT_DIR}/${ANDROID_OUTPUT_FILE} ./${ANDROID_APK_NAME} + + + -# This is the actual output from gradle, which no longer attempts to muck with the naming of the APK -OUTPUT_APK=./apps/${ANDROID_APP}/build/outputs/apk/${ANDROID_BUILD_DIR}/${ANDROID_BUILT_APK_NAME} -# This is the APK name requested by Jenkins -TARGET_APK=./${ANDROID_APK_NAME} -# Make sure this matches up with the new ARTIFACT_EXPRESSION for jenkins builds, which should be "android/*.apk" -cp ${OUTPUT_APK} ${TARGET_APK} diff --git a/android/containerized_build.sh b/android/containerized_build.sh index 8b2f26cb50..34e620ad2e 100755 --- a/android/containerized_build.sh +++ b/android/containerized_build.sh @@ -9,6 +9,7 @@ docker build --build-arg BUILD_UID=`id -u` -t "${DOCKER_IMAGE_NAME}" -f docker/D # So make sure we use VERSION_CODE consistently test -z "$VERSION_CODE" && export VERSION_CODE=$VERSION +# FIXME figure out which of these actually need to be forwarded and which can be eliminated docker run \ --rm \ --security-opt seccomp:unconfined \ @@ -27,6 +28,7 @@ docker run \ -e OAUTH_CLIENT_SECRET \ -e OAUTH_CLIENT_ID \ -e OAUTH_REDIRECT_URI \ + -e SHA7 \ -e VERSION_CODE \ "${DOCKER_IMAGE_NAME}" \ sh -c "./build_android.sh" From 07753927590ef3af2d1aa51f22dd09ed1850f5f7 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Mon, 25 Feb 2019 14:05:54 -0800 Subject: [PATCH 22/33] adding market place back to the default scripts --- scripts/+android_questInterface/defaultScripts.js | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/+android_questInterface/defaultScripts.js b/scripts/+android_questInterface/defaultScripts.js index e996f71908..c294537419 100644 --- a/scripts/+android_questInterface/defaultScripts.js +++ b/scripts/+android_questInterface/defaultScripts.js @@ -25,6 +25,7 @@ var DEFAULT_SCRIPTS_COMBINED = [ "system/notifications.js", "system/commerce/wallet.js", "system/dialTone.js", + "system/marketplaces/marketplaces.js", "system/quickGoto.js", "system/firstPersonHMD.js", "system/tablet-ui/tabletUI.js", From 4c6bea48b2a713fce07934df97ed77b3ebd316a7 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Tue, 26 Feb 2019 14:48:34 -0800 Subject: [PATCH 23/33] fixed a case where _widths = 0 and widths-1 is not valid. --- .../src/RenderablePolyLineEntityItem.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index c4ea6a2fea..0ea8db7c15 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -184,8 +184,11 @@ void PolyLineEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo void PolyLineEntityRenderer::updateGeometry() { int maxNumVertices = std::min(_points.length(), _normals.length()); + qDebug()<<"QQQ_ widths size: "<< _widths.size(); + qDebug()<<"QQQ_ MaxNumbVertices: "<= 0) { + if (_widths.size() > 0) { for (int i = 1; i < maxNumVertices; i++) { float width = PolyLineEntityItem::DEFAULT_LINE_WIDTH; if (i < _widths.length()) { @@ -206,12 +209,15 @@ void PolyLineEntityRenderer::updateGeometry() { std::vector vertices; vertices.reserve(maxNumVertices); + for (int i = 0; i < maxNumVertices; i++) { // Position glm::vec3 point = _points[i]; - // uCoord - float width = i < _widths.size() ? _widths[i] : PolyLineEntityItem::DEFAULT_LINE_WIDTH; + float width=PolyLineEntityItem::DEFAULT_LINE_WIDTH; + if(_widths.size()>0 && i < _widths.size()) + width = _widths[i]; + if (i > 0) { // First uCoord is 0.0f if (!_isUVModeStretch) { accumulatedDistance += glm::distance(point, _points[i - 1]); From 5a7c8c312640c4975a5b94dc6662056b8be1ea0a Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Tue, 26 Feb 2019 14:53:44 -0800 Subject: [PATCH 24/33] removed debugg helpers --- .../entities-renderer/src/RenderablePolyLineEntityItem.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index 0ea8db7c15..ec8444ff35 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -183,10 +183,6 @@ void PolyLineEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo void PolyLineEntityRenderer::updateGeometry() { int maxNumVertices = std::min(_points.length(), _normals.length()); - - qDebug()<<"QQQ_ widths size: "<< _widths.size(); - qDebug()<<"QQQ_ MaxNumbVertices: "< 0) { for (int i = 1; i < maxNumVertices; i++) { @@ -215,8 +211,9 @@ void PolyLineEntityRenderer::updateGeometry() { glm::vec3 point = _points[i]; float width=PolyLineEntityItem::DEFAULT_LINE_WIDTH; - if(_widths.size()>0 && i < _widths.size()) + if(_widths.size()>0 && i < _widths.size()) { width = _widths[i]; + } if (i > 0) { // First uCoord is 0.0f if (!_isUVModeStretch) { From f5852139f75238a3b4b79eebfb63d22ae8ec6da4 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Tue, 26 Feb 2019 15:05:58 -0800 Subject: [PATCH 25/33] fixing comment since the original check was correct --- .../entities-renderer/src/RenderablePolyLineEntityItem.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index ec8444ff35..44b368d827 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -209,11 +209,7 @@ void PolyLineEntityRenderer::updateGeometry() { for (int i = 0; i < maxNumVertices; i++) { // Position glm::vec3 point = _points[i]; - - float width=PolyLineEntityItem::DEFAULT_LINE_WIDTH; - if(_widths.size()>0 && i < _widths.size()) { - width = _widths[i]; - } + float width = i < _widths.size() ? _widths[i] : PolyLineEntityItem::DEFAULT_LINE_WIDTH; if (i > 0) { // First uCoord is 0.0f if (!_isUVModeStretch) { From 19d584f0af1a6ebc2910edfe301319b322bdbad0 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Tue, 26 Feb 2019 15:28:28 -0800 Subject: [PATCH 26/33] added Sams suggestions to the logic --- .../src/RenderablePolyLineEntityItem.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp index 44b368d827..454e8b136a 100644 --- a/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderablePolyLineEntityItem.cpp @@ -185,15 +185,17 @@ void PolyLineEntityRenderer::updateGeometry() { int maxNumVertices = std::min(_points.length(), _normals.length()); bool doesStrokeWidthVary = false; if (_widths.size() > 0) { + float prevWidth = _widths[0]; for (int i = 1; i < maxNumVertices; i++) { - float width = PolyLineEntityItem::DEFAULT_LINE_WIDTH; - if (i < _widths.length()) { - width = _widths[i]; - } - if (width != _widths[i - 1]) { + float width = i < _widths.length() ? _widths[i] : PolyLineEntityItem::DEFAULT_LINE_WIDTH; + if (width != prevWidth) { doesStrokeWidthVary = true; break; } + if (i > _widths.length() + 1) { + break; + } + prevWidth = width; } } @@ -209,6 +211,7 @@ void PolyLineEntityRenderer::updateGeometry() { for (int i = 0; i < maxNumVertices; i++) { // Position glm::vec3 point = _points[i]; + // uCoord float width = i < _widths.size() ? _widths[i] : PolyLineEntityItem::DEFAULT_LINE_WIDTH; if (i > 0) { // First uCoord is 0.0f From 92cfa49bfb55fc780a1f2a34a437ef6d1001379f Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Wed, 27 Feb 2019 11:42:22 -0800 Subject: [PATCH 27/33] adding and testing command line parameter passing to application --- .../questInterface/src/main/AndroidManifest.xml | 2 +- .../questInterface/InterfaceActivity.java | 15 +++++++++++++++ .../questInterface/PermissionsChecker.java | 16 +++++++++++++++- .../oculus/OculusMobileActivity.java | 11 +++++++++++ interface/src/Application.cpp | 8 ++++---- 5 files changed, 46 insertions(+), 6 deletions(-) diff --git a/android/apps/questInterface/src/main/AndroidManifest.xml b/android/apps/questInterface/src/main/AndroidManifest.xml index a5de47bdce..0f3616612a 100644 --- a/android/apps/questInterface/src/main/AndroidManifest.xml +++ b/android/apps/questInterface/src/main/AndroidManifest.xml @@ -28,7 +28,7 @@ android:excludeFromRecents="true"> - + ()->handleLookupString(QUEST_DEV); +// / const QString QUEST_DEV = "hifi://quest-dev"; + // DependencyManager::get()->handleLookupString(QUEST_DEV); #endif } @@ -3669,8 +3669,8 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { // If this is a first run we short-circuit the address passed in if (_firstRun.get()) { #if !defined(Q_OS_ANDROID) - DependencyManager::get()->goToEntry(); - sentTo = SENT_TO_ENTRY; + // DependencyManager::get()->goToEntry(); + // sentTo = SENT_TO_ENTRY; #endif _firstRun.set(false); From 29ec5486f6f49d288692eb2c4e140d4ce1f49436 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Wed, 27 Feb 2019 15:31:23 -0800 Subject: [PATCH 28/33] manual pushing args to the app. Removed some debugging printouts --- .../questInterface/InterfaceActivity.java | 8 -------- .../io/highfidelity/oculus/OculusMobileActivity.java | 11 +++-------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/android/apps/questInterface/src/main/java/io/highfidelity/questInterface/InterfaceActivity.java b/android/apps/questInterface/src/main/java/io/highfidelity/questInterface/InterfaceActivity.java index 119b009e6a..cdc48dfa37 100644 --- a/android/apps/questInterface/src/main/java/io/highfidelity/questInterface/InterfaceActivity.java +++ b/android/apps/questInterface/src/main/java/io/highfidelity/questInterface/InterfaceActivity.java @@ -14,14 +14,6 @@ public class InterfaceActivity extends OculusMobileActivity { @Override public void onCreate(Bundle savedInstanceState) { - if(this.getIntent().hasExtra("applicationArguments")){ - System.out.println("QQQ_ InterfaceActivity: args EXISTS"); - System.out.println("QQQ_ "+ this.getIntent().getStringExtra("applicationArguments")); - } - else{ - System.out.println("QQQ_ InterfaceActivity: NO argmument"); - } - HifiUtils.upackAssets(getAssets(), getCacheDir().getAbsolutePath()); super.onCreate(savedInstanceState); } diff --git a/android/libraries/oculus/src/main/java/io/highfidelity/oculus/OculusMobileActivity.java b/android/libraries/oculus/src/main/java/io/highfidelity/oculus/OculusMobileActivity.java index 095236ecc3..75faf1e0dd 100644 --- a/android/libraries/oculus/src/main/java/io/highfidelity/oculus/OculusMobileActivity.java +++ b/android/libraries/oculus/src/main/java/io/highfidelity/oculus/OculusMobileActivity.java @@ -39,19 +39,14 @@ public class OculusMobileActivity extends QtActivity implements SurfaceHolder.Ca private SurfaceHolder mSurfaceHolder; public void onCreate(Bundle savedInstanceState) { - if(this.getIntent().hasExtra("applicationArguments")){ - System.out.println("QQQ_ OculusMobileActivity has arguments"); - System.out.println("QQQ_ "+ this.getIntent().getStringExtra("applicationArguments")); + if(getIntent().hasExtra("applicationArguments")){ + super.APPLICATION_PARAMETERS=getIntent().getStringExtra("applicationArguments"); } - else{ - System.out.println("QQQ_ OculusMobileActivity has NO arguments"); - } - - super.onCreate(savedInstanceState); + Log.w(TAG, "QQQ onCreate"); // Create a native surface for VR rendering (Qt GL surfaces are not suitable // because of the lack of fine control over the surface callbacks) From a425becc8a624ef215a94142b4cdf132673524e5 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Wed, 27 Feb 2019 15:35:33 -0800 Subject: [PATCH 29/33] clean up of debugging --- android/apps/questInterface/src/main/AndroidManifest.xml | 2 +- .../highfidelity/questInterface/PermissionsChecker.java | 6 ++++-- .../java/io/highfidelity/oculus/OculusMobileActivity.java | 1 - interface/src/Application.cpp | 8 ++++---- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/android/apps/questInterface/src/main/AndroidManifest.xml b/android/apps/questInterface/src/main/AndroidManifest.xml index 0f3616612a..a5de47bdce 100644 --- a/android/apps/questInterface/src/main/AndroidManifest.xml +++ b/android/apps/questInterface/src/main/AndroidManifest.xml @@ -28,7 +28,7 @@ android:excludeFromRecents="true"> - + ()->handleLookupString(QUEST_DEV); + const QString QUEST_DEV = "hifi://quest-dev"; + DependencyManager::get()->handleLookupString(QUEST_DEV); #endif } @@ -3669,8 +3669,8 @@ void Application::handleSandboxStatus(QNetworkReply* reply) { // If this is a first run we short-circuit the address passed in if (_firstRun.get()) { #if !defined(Q_OS_ANDROID) - // DependencyManager::get()->goToEntry(); - // sentTo = SENT_TO_ENTRY; + DependencyManager::get()->goToEntry(); + sentTo = SENT_TO_ENTRY; #endif _firstRun.set(false); From 95628dfc111e771842e60cd43ddf08ed70019005 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Wed, 27 Feb 2019 15:36:49 -0800 Subject: [PATCH 30/33] removing unused imports --- .../io/highfidelity/questInterface/InterfaceActivity.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/android/apps/questInterface/src/main/java/io/highfidelity/questInterface/InterfaceActivity.java b/android/apps/questInterface/src/main/java/io/highfidelity/questInterface/InterfaceActivity.java index cdc48dfa37..df05576ea9 100644 --- a/android/apps/questInterface/src/main/java/io/highfidelity/questInterface/InterfaceActivity.java +++ b/android/apps/questInterface/src/main/java/io/highfidelity/questInterface/InterfaceActivity.java @@ -1,16 +1,10 @@ package io.highfidelity.questInterface; -import android.content.Intent; import android.os.Bundle; -import android.text.TextUtils; - import io.highfidelity.oculus.OculusMobileActivity; import io.highfidelity.utils.HifiUtils; public class InterfaceActivity extends OculusMobileActivity { - public static final String DOMAIN_URL = "url"; - private static final String TAG = "Interface"; - public static final String EXTRA_ARGS = "args"; @Override public void onCreate(Bundle savedInstanceState) { From faedc61c37909f8b38beff48cbe6f47a60aea174 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Thu, 28 Feb 2019 10:54:30 -0800 Subject: [PATCH 31/33] removing quest-demo specific changes --- android/apps/questInterface/build.gradle | 13 ++++--------- .../highfidelity/oculus/OculusMobileActivity.java | 6 +++--- interface/src/Application.cpp | 6 ------ libraries/animation/src/AnimInverseKinematics.cpp | 6 ------ .../src/OculusMobileDisplayPlugin.cpp | 14 +++++++------- 5 files changed, 14 insertions(+), 31 deletions(-) diff --git a/android/apps/questInterface/build.gradle b/android/apps/questInterface/build.gradle index bf600b5df1..43ce0c0c37 100644 --- a/android/apps/questInterface/build.gradle +++ b/android/apps/questInterface/build.gradle @@ -44,15 +44,10 @@ android { } signingConfigs { release { - // Hack for Quest demo - storeFile file("keystore.jks") - storePassword "password" - keyAlias "key0" - keyPassword "password" - // storeFile project.hasProperty("HIFI_ANDROID_KEYSTORE") ? file(HIFI_ANDROID_KEYSTORE) : null - // storePassword project.hasProperty("HIFI_ANDROID_KEYSTORE_PASSWORD") ? HIFI_ANDROID_KEYSTORE_PASSWORD : '' - // keyAlias project.hasProperty("HIFI_ANDROID_KEY_ALIAS") ? HIFI_ANDROID_KEY_ALIAS : '' - // keyPassword project.hasProperty("HIFI_ANDROID_KEY_PASSWORD") ? HIFI_ANDROID_KEY_PASSWORD : '' + storeFile project.hasProperty("HIFI_ANDROID_KEYSTORE") ? file(HIFI_ANDROID_KEYSTORE) : null + storePassword project.hasProperty("HIFI_ANDROID_KEYSTORE_PASSWORD") ? HIFI_ANDROID_KEYSTORE_PASSWORD : '' + keyAlias project.hasProperty("HIFI_ANDROID_KEY_ALIAS") ? HIFI_ANDROID_KEY_ALIAS : '' + keyPassword project.hasProperty("HIFI_ANDROID_KEY_PASSWORD") ? HIFI_ANDROID_KEY_PASSWORD : '' v2SigningEnabled false } } diff --git a/android/libraries/oculus/src/main/java/io/highfidelity/oculus/OculusMobileActivity.java b/android/libraries/oculus/src/main/java/io/highfidelity/oculus/OculusMobileActivity.java index 125ed46ec9..8ee22749c9 100644 --- a/android/libraries/oculus/src/main/java/io/highfidelity/oculus/OculusMobileActivity.java +++ b/android/libraries/oculus/src/main/java/io/highfidelity/oculus/OculusMobileActivity.java @@ -108,14 +108,14 @@ public class OculusMobileActivity extends QtActivity implements SurfaceHolder.Ca @Override protected void onRestart() { super.onRestart(); - Log.w(TAG, "QQQ_ onRestart called ****"); + Log.w(TAG, "QQQ_ onRestart called"); questOnAppAfterLoad(); questNativeAwayMode(); } @Override public void surfaceCreated(SurfaceHolder holder) { - Log.w(TAG, "QQQ_ surfaceCreated ************************************"); + Log.w(TAG, "QQQ_ surfaceCreated"); nativeOnSurfaceChanged(holder.getSurface()); mSurfaceHolder = holder; } @@ -129,7 +129,7 @@ public class OculusMobileActivity extends QtActivity implements SurfaceHolder.Ca @Override public void surfaceDestroyed(SurfaceHolder holder) { - Log.w(TAG, "QQQ_ surfaceDestroyed ***************************************************"); + Log.w(TAG, "QQQ_ surfaceDestroyed"); nativeOnSurfaceChanged(null); mSurfaceHolder = null; } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 08785ecc90..c889377d6f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2413,15 +2413,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo connect(&AndroidHelper::instance(), &AndroidHelper::enterBackground, this, &Application::enterBackground); connect(&AndroidHelper::instance(), &AndroidHelper::enterForeground, this, &Application::enterForeground); connect(&AndroidHelper::instance(), &AndroidHelper::toggleAwayMode, this, &Application::toggleAwayMode); - AndroidHelper::instance().notifyLoadComplete(); #endif pauseUntilLoginDetermined(); - -#if defined(Q_OS_ANDROID) - const QString QUEST_DEV = "hifi://quest-dev"; - DependencyManager::get()->handleLookupString(QUEST_DEV); -#endif } void Application::updateVerboseLogging() { diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index 37859c939a..9a55b66a39 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -865,12 +865,6 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar //virtual const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, AnimVariantMap& triggersOut, const AnimPoseVec& underPoses) { - -#ifdef Q_OS_ANDROID - // disable IK on android - return underPoses; -#endif - // allows solutionSource to be overridden by an animVar auto solutionSource = animVars.lookup(_solutionSourceVar, (int)_solutionSource); diff --git a/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp b/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp index a63b954f02..9809d02866 100644 --- a/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp +++ b/libraries/oculusMobilePlugin/src/OculusMobileDisplayPlugin.cpp @@ -58,7 +58,7 @@ void OculusMobileDisplayPlugin::deinit() { bool OculusMobileDisplayPlugin::internalActivate() { _renderTargetSize = { 1024, 512 }; - _cullingProjection = ovr::toGlm(ovrMatrix4f_CreateProjectionFov(90.0f, 90.0f, 90.0f, 90.0f, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)); + _cullingProjection = ovr::toGlm(ovrMatrix4f_CreateProjectionFov(90.0f, 90.0f, 0.0f, 0.0f, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP)); withOvrJava([&](const ovrJava* java){ @@ -220,12 +220,12 @@ bool OculusMobileDisplayPlugin::beginFrameRender(uint32_t frameIndex) { }); } - static uint32_t count = 0; - if ((++count % 1000) == 0) { - AbstractViewStateInterface::instance()->postLambdaEvent([] { - goToDevMobile(); - }); - } + // static uint32_t count = 0; + // if ((++count % 1000) == 0) { + // AbstractViewStateInterface::instance()->postLambdaEvent([] { + // goToDevMobile(); + // }); + // } return result && Parent::beginFrameRender(frameIndex); } From ad69611b7cd1d9c1e1ae29204cdeee74b91d772e Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Fri, 1 Mar 2019 11:08:00 -0800 Subject: [PATCH 32/33] removing redef of the two functions in avatar.h --- libraries/avatars-renderer/src/avatars-renderer/Avatar.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index 9f713637f5..6c31f9fc93 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -287,8 +287,6 @@ public: * @returns {Quat} */ Q_INVOKABLE glm::quat jointToWorldRotation(const glm::quat& rotation, const int jointIndex = -1) const; - virtual glm::vec3 getSpine2SplineOffset() const { return _spine2SplineOffset; } - virtual float getSpine2SplineRatio() const { return _spine2SplineRatio; } virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override; virtual void setAttachmentData(const QVector& attachmentData) override; From 8802eeadf654e4ef2411961e19c8997067c36088 Mon Sep 17 00:00:00 2001 From: amerhifi <43353902+amerhifi@users.noreply.github.com> Date: Fri, 1 Mar 2019 12:46:50 -0800 Subject: [PATCH 33/33] Make CI android build signed, don't fail on quest build fails (#18) merging build changes --- android/apps/interface/build.gradle | 13 +++++-------- android/apps/{questInterface => }/keystore.jks | Bin android/apps/questInterface/build.gradle | 8 ++++---- android/build_android.sh | 17 ++++++++++------- android/docker/Dockerfile | 2 +- 5 files changed, 20 insertions(+), 20 deletions(-) rename android/apps/{questInterface => }/keystore.jks (100%) diff --git a/android/apps/interface/build.gradle b/android/apps/interface/build.gradle index 4163df03b7..f954fbc1f4 100644 --- a/android/apps/interface/build.gradle +++ b/android/apps/interface/build.gradle @@ -66,10 +66,10 @@ android { } signingConfigs { release { - storeFile project.hasProperty("HIFI_ANDROID_KEYSTORE") ? file(HIFI_ANDROID_KEYSTORE) : null - storePassword project.hasProperty("HIFI_ANDROID_KEYSTORE_PASSWORD") ? HIFI_ANDROID_KEYSTORE_PASSWORD : '' - keyAlias project.hasProperty("HIFI_ANDROID_KEY_ALIAS") ? HIFI_ANDROID_KEY_ALIAS : '' - keyPassword project.hasProperty("HIFI_ANDROID_KEY_PASSWORD") ? HIFI_ANDROID_KEY_PASSWORD : '' + storeFile project.hasProperty("HIFI_ANDROID_KEYSTORE") ? file(HIFI_ANDROID_KEYSTORE) : file('../keystore.jks') + storePassword project.hasProperty("HIFI_ANDROID_KEYSTORE_PASSWORD") ? HIFI_ANDROID_KEYSTORE_PASSWORD : 'password' + keyAlias project.hasProperty("HIFI_ANDROID_KEY_ALIAS") ? HIFI_ANDROID_KEY_ALIAS : 'key0' + keyPassword project.hasProperty("HIFI_ANDROID_KEY_PASSWORD") ? HIFI_ANDROID_KEY_PASSWORD : 'password' } } } @@ -90,10 +90,7 @@ android { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - signingConfig project.hasProperty("HIFI_ANDROID_KEYSTORE") && - project.hasProperty("HIFI_ANDROID_KEYSTORE_PASSWORD") && - project.hasProperty("HIFI_ANDROID_KEY_ALIAS") && - project.hasProperty("HIFI_ANDROID_KEY_PASSWORD")? signingConfigs.release : null + signingConfig signingConfigs.release buildConfigField "String", "BACKTRACE_URL", "\"" + (System.getenv("CMAKE_BACKTRACE_URL") ? System.getenv("CMAKE_BACKTRACE_URL") : '') + "\"" buildConfigField "String", "BACKTRACE_TOKEN", "\"" + (System.getenv("CMAKE_BACKTRACE_TOKEN") ? System.getenv("CMAKE_BACKTRACE_TOKEN") : '') + "\"" buildConfigField "String", "OAUTH_CLIENT_ID", "\"" + (System.getenv("OAUTH_CLIENT_ID") ? System.getenv("OAUTH_CLIENT_ID") : '') + "\"" diff --git a/android/apps/questInterface/keystore.jks b/android/apps/keystore.jks similarity index 100% rename from android/apps/questInterface/keystore.jks rename to android/apps/keystore.jks diff --git a/android/apps/questInterface/build.gradle b/android/apps/questInterface/build.gradle index 43ce0c0c37..6f4f6b7441 100644 --- a/android/apps/questInterface/build.gradle +++ b/android/apps/questInterface/build.gradle @@ -44,10 +44,10 @@ android { } signingConfigs { release { - storeFile project.hasProperty("HIFI_ANDROID_KEYSTORE") ? file(HIFI_ANDROID_KEYSTORE) : null - storePassword project.hasProperty("HIFI_ANDROID_KEYSTORE_PASSWORD") ? HIFI_ANDROID_KEYSTORE_PASSWORD : '' - keyAlias project.hasProperty("HIFI_ANDROID_KEY_ALIAS") ? HIFI_ANDROID_KEY_ALIAS : '' - keyPassword project.hasProperty("HIFI_ANDROID_KEY_PASSWORD") ? HIFI_ANDROID_KEY_PASSWORD : '' + storeFile project.hasProperty("HIFI_ANDROID_KEYSTORE") ? file(HIFI_ANDROID_KEYSTORE) : file('../keystore.jks') + storePassword project.hasProperty("HIFI_ANDROID_KEYSTORE_PASSWORD") ? HIFI_ANDROID_KEYSTORE_PASSWORD : 'password' + keyAlias project.hasProperty("HIFI_ANDROID_KEY_ALIAS") ? HIFI_ANDROID_KEY_ALIAS : 'key0' + keyPassword project.hasProperty("HIFI_ANDROID_KEY_PASSWORD") ? HIFI_ANDROID_KEY_PASSWORD : 'password' v2SigningEnabled false } } diff --git a/android/build_android.sh b/android/build_android.sh index 106a295750..e9c69b09de 100755 --- a/android/build_android.sh +++ b/android/build_android.sh @@ -4,16 +4,19 @@ set -xeuo pipefail ANDROID_BUILD_TYPE=release ANDROID_BUILD_TARGET=assembleRelease -case "$RELEASE_TYPE" in - PR) ANDROID_APK_SUFFIX=PR${RELEASE_NUMBER}-${SHA7}.apk ;; - *) ANDROID_APK_SUFFIX=${RELEASE_NUMBER}-${SHA7}.apk ;; -esac +if [[ "$RELEASE_TYPE" == "PR" ]]; then +ANDROID_APK_SUFFIX=PR${RELEASE_NUMBER}-${SHA7}.apk ; +elif [[ "${STABLE_BUILD}" == "1" ]]; then +ANDROID_APK_SUFFIX=${RELEASE_NUMBER}.apk ; +else +ANDROID_APK_SUFFIX=${RELEASE_NUMBER}-${SHA7}.apk ; +fi # Interface build ANDROID_APP=interface ANDROID_OUTPUT_DIR=./apps/${ANDROID_APP}/build/outputs/apk/${ANDROID_BUILD_TYPE} -ANDROID_OUTPUT_FILE=${ANDROID_APP}-${ANDROID_BUILD_TYPE}-unsigned.apk +ANDROID_OUTPUT_FILE=${ANDROID_APP}-${ANDROID_BUILD_TYPE}.apk ANDROID_APK_NAME=HighFidelity-Beta-${ANDROID_APK_SUFFIX} ./gradlew -PHIFI_ANDROID_PRECOMPILED=${HIFI_ANDROID_PRECOMPILED} -PVERSION_CODE=${VERSION_CODE} -PRELEASE_NUMBER=${RELEASE_NUMBER} -PRELEASE_TYPE=${RELEASE_TYPE} ${ANDROID_APP}:${ANDROID_BUILD_TARGET} cp ${ANDROID_OUTPUT_DIR}/${ANDROID_OUTPUT_FILE} ./${ANDROID_APK_NAME} @@ -23,8 +26,8 @@ ANDROID_APP=questInterface ANDROID_OUTPUT_DIR=./apps/${ANDROID_APP}/build/outputs/apk/${ANDROID_BUILD_TYPE} ANDROID_OUTPUT_FILE=${ANDROID_APP}-${ANDROID_BUILD_TYPE}.apk ANDROID_APK_NAME=HighFidelity-Quest-Beta-${ANDROID_APK_SUFFIX} -./gradlew -PHIFI_ANDROID_PRECOMPILED=${HIFI_ANDROID_PRECOMPILED} -PVERSION_CODE=${VERSION_CODE} -PRELEASE_NUMBER=${RELEASE_NUMBER} -PRELEASE_TYPE=${RELEASE_TYPE} ${ANDROID_APP}:${ANDROID_BUILD_TARGET} -cp ${ANDROID_OUTPUT_DIR}/${ANDROID_OUTPUT_FILE} ./${ANDROID_APK_NAME} +./gradlew -PHIFI_ANDROID_PRECOMPILED=${HIFI_ANDROID_PRECOMPILED} -PVERSION_CODE=${VERSION_CODE} -PRELEASE_NUMBER=${RELEASE_NUMBER} -PRELEASE_TYPE=${RELEASE_TYPE} ${ANDROID_APP}:${ANDROID_BUILD_TARGET} || true +cp ${ANDROID_OUTPUT_DIR}/${ANDROID_OUTPUT_FILE} ./${ANDROID_APK_NAME} || true diff --git a/android/docker/Dockerfile b/android/docker/Dockerfile index fe3a83950a..105bcb7cb0 100644 --- a/android/docker/Dockerfile +++ b/android/docker/Dockerfile @@ -73,7 +73,7 @@ RUN mkdir "$HIFI_BASE" && \ RUN git clone https://github.com/jherico/hifi.git && \ cd ~/hifi && \ - git checkout feature/quest_frame_player + git checkout quest/build WORKDIR /home/jenkins/hifi