mirror of
https://github.com/amwatson/CitraVR.git
synced 2024-09-19 19:01:38 +02:00
remove thumbstick code (for now) and use main menu layout for traditional menu (temporary)
This commit is contained in:
parent
a5dcfc0e37
commit
5fe11a8be5
5 changed files with 83 additions and 77 deletions
|
@ -37,7 +37,7 @@ public:
|
|||
/** The type of cursor to render.
|
||||
* Determines the color of the cursor.
|
||||
**/
|
||||
enum class CursorType { CURSOR_TYPE_NORMAL, CURSOR_TYPE_TOP_PANEL, NUM_CURSOR_TYPES };
|
||||
enum class CursorType { CURSOR_TYPE_NORMAL, CURSOR_TYPE_POSITIONAL_MENU, NUM_CURSOR_TYPES };
|
||||
/**
|
||||
* @param session a valid XR Session
|
||||
*/
|
||||
|
|
|
@ -31,7 +31,6 @@ License : Licensed under GPLv3 or any later version.
|
|||
namespace {
|
||||
|
||||
constexpr float kSuperImmersiveRadius = 0.5f;
|
||||
constexpr float kDistanceBetweenPanelsInMeters = 0.75f;
|
||||
constexpr float kInitialLowerPanelPitchInRadians = -MATH_FLOAT_PI / 4.0f; // -45 degrees in radians
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
@ -485,7 +484,7 @@ void GameSurfaceLayer::SetLowerPanelFromController(const XrVector3f& controllerP
|
|||
|
||||
// Construct a quaternion for the pitch adjustment
|
||||
const XrQuaternionf pitchAdjustmentQuat =
|
||||
XrMath::FromAxisAngle({1.0f, 0.0f, 0.0f}, newPitchRadians / 2.0f);
|
||||
XrMath::Quatf::FromAxisAngle({1.0f, 0.0f, 0.0f}, newPitchRadians / 2.0f);
|
||||
|
||||
// Combine the base rotation with the pitch adjustment
|
||||
mLowerPanel.mPanelFromWorld = {baseRotation * pitchAdjustmentQuat, windowPosition};
|
||||
|
@ -503,19 +502,6 @@ void GameSurfaceLayer::SetTopPanelFromThumbstick(const float thumbstickY) {
|
|||
std::max(mTopPanel.mPanelFromWorld.position.z, kMaxDepth);
|
||||
}
|
||||
|
||||
XrPosef GameSurfaceLayer::SetLowerPanelFromThumbstick(const float thumbstickY) {
|
||||
static constexpr float kMinY = -3.0f;
|
||||
|
||||
mLowerPanel.mPanelFromWorld.position.y += (thumbstickY * kThumbstickSpeed);
|
||||
mLowerPanel.mPanelFromWorld.position.y =
|
||||
std::min(mLowerPanel.mPanelFromWorld.position.y,
|
||||
mTopPanel.mPanelFromWorld.position.y - kDistanceBetweenPanelsInMeters);
|
||||
mLowerPanel.mPanelFromWorld.position.y =
|
||||
std::max(mLowerPanel.mPanelFromWorld.position.y, kMinY);
|
||||
|
||||
return mLowerPanel.mPanelFromWorld;
|
||||
}
|
||||
|
||||
XrPosef GameSurfaceLayer::GetTopPanelFromHeadPose(uint32_t eye, const XrPosef& headPose) {
|
||||
XrVector3f panelPosition = headPose.position;
|
||||
|
||||
|
|
|
@ -98,6 +98,22 @@ void ForwardButtonStateIfNeeded(JNIEnv* jni, jobject activityObject,
|
|||
}
|
||||
}
|
||||
|
||||
void SendTriggerStateToWindow(JNIEnv* jni, jobject activityObject,
|
||||
jmethodID sendClickToWindowMethodID,
|
||||
const XrActionStateBoolean& triggerState,
|
||||
const XrVector2f& cursorPos2d) {
|
||||
if (triggerState.currentState == 0 && triggerState.changedSinceLastSync) {
|
||||
jni->CallVoidMethod(activityObject, sendClickToWindowMethodID, cursorPos2d.x, cursorPos2d.y,
|
||||
0);
|
||||
} else if (triggerState.changedSinceLastSync && triggerState.currentState == 1) {
|
||||
jni->CallVoidMethod(activityObject, sendClickToWindowMethodID, cursorPos2d.x, cursorPos2d.y,
|
||||
1);
|
||||
} else if (triggerState.currentState == 1 && !triggerState.changedSinceLastSync) {
|
||||
jni->CallVoidMethod(activityObject, sendClickToWindowMethodID, cursorPos2d.x, cursorPos2d.y,
|
||||
2);
|
||||
}
|
||||
}
|
||||
|
||||
[[maybe_unused]] const char* XrSessionStateToString(const XrSessionState state) {
|
||||
switch (state) {
|
||||
case XR_SESSION_STATE_UNKNOWN:
|
||||
|
@ -652,7 +668,7 @@ private:
|
|||
float scaleFactor = 0.01f;
|
||||
CursorLayer::CursorType cursorType =
|
||||
appState.mLowerMenuType == LowerMenuType::POSITIONAL_MENU
|
||||
? CursorLayer::CursorType::CURSOR_TYPE_TOP_PANEL
|
||||
? CursorLayer::CursorType::CURSOR_TYPE_POSITIONAL_MENU
|
||||
: CursorLayer::CursorType::CURSOR_TYPE_NORMAL;
|
||||
|
||||
[[maybe_unused]] const auto nonPreferredController =
|
||||
|
@ -690,6 +706,7 @@ private:
|
|||
|
||||
// Hit-test panels in order of priority (and known depth)
|
||||
|
||||
// 1. Error message layer
|
||||
if (appState.mShouldShowErrorMessage) {
|
||||
shouldRenderCursor = mErrorMessageLayer->GetRayIntersectionWithPanel(
|
||||
start, end, cursorPos2d, cursorPose3d);
|
||||
|
@ -697,7 +714,8 @@ private:
|
|||
mErrorMessageLayer->SendClickToUI(cursorPos2d, triggerState.currentState);
|
||||
}
|
||||
}
|
||||
// Don't test for cursor intersection if error message is shown
|
||||
|
||||
// 2. Keyboard layer
|
||||
if (!shouldRenderCursor && appState.mIsKeyboardActive) {
|
||||
shouldRenderCursor = mKeyboardLayer->GetRayIntersectionWithPanel(
|
||||
start, end, cursorPos2d, cursorPose3d);
|
||||
|
@ -715,6 +733,7 @@ private:
|
|||
mRibbonLayer->SetPanelWithPose(mGameSurfaceLayer->GetLowerPanelPose());
|
||||
}
|
||||
|
||||
// 3. Lower panel
|
||||
if (!shouldRenderCursor) {
|
||||
shouldRenderCursor = mGameSurfaceLayer->GetRayIntersectionWithPanel(
|
||||
start, end, cursorPos2d, cursorPose3d);
|
||||
|
@ -726,50 +745,21 @@ private:
|
|||
|
||||
sIsLowerPanelBeingPositioned = true;
|
||||
} else if (appState.mLowerMenuType == LowerMenuType::MAIN_MENU) {
|
||||
if (triggerState.currentState == 0 && triggerState.changedSinceLastSync) {
|
||||
jni->CallVoidMethod(mActivityObject, mSendClickToWindowMethodID,
|
||||
cursorPos2d.x, cursorPos2d.y, 0);
|
||||
} else if (triggerState.changedSinceLastSync &&
|
||||
triggerState.currentState == 1) {
|
||||
jni->CallVoidMethod(mActivityObject, mSendClickToWindowMethodID,
|
||||
cursorPos2d.x, cursorPos2d.y, 1);
|
||||
} else if (triggerState.currentState == 1 &&
|
||||
!triggerState.changedSinceLastSync) {
|
||||
|
||||
jni->CallVoidMethod(mActivityObject, mSendClickToWindowMethodID,
|
||||
cursorPos2d.x, cursorPos2d.y, 2);
|
||||
}
|
||||
SendTriggerStateToWindow(jni, mActivityObject, mSendClickToWindowMethodID,
|
||||
triggerState, cursorPos2d);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Ribbon layer
|
||||
if (!shouldRenderCursor) {
|
||||
shouldRenderCursor = mRibbonLayer->GetRayIntersectionWithPanel(
|
||||
start, end, cursorPos2d, cursorPose3d);
|
||||
if (shouldRenderCursor && triggerState.changedSinceLastSync) {
|
||||
mRibbonLayer->SendClickToUI(cursorPos2d, triggerState.currentState);
|
||||
}
|
||||
if ((shouldRenderCursor || sIsLowerPanelBeingPositioned) &&
|
||||
appState.mLowerMenuType == LowerMenuType::POSITIONAL_MENU &&
|
||||
triggerState.currentState) {
|
||||
|
||||
static constexpr float kThumbStickDirectionThreshold = 0.5f;
|
||||
// If trigger is pressed, thumbstick controls
|
||||
// the depth
|
||||
const XrActionStateVector2f& thumbstickState =
|
||||
mInputStateFrame.mThumbStickState[mInputStateFrame.mPreferredHand];
|
||||
|
||||
if (std::abs(thumbstickState.currentState.y) >
|
||||
kThumbStickDirectionThreshold) {
|
||||
const XrPosef lowerPanelPose =
|
||||
mGameSurfaceLayer->SetLowerPanelFromThumbstick(
|
||||
thumbstickState.currentState.y);
|
||||
mRibbonLayer->SetPanelWithPose(lowerPanelPose);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sIsLowerPanelBeingPositioned) { shouldRenderCursor = true; }
|
||||
|
||||
// Hit test the top panel if positional menu is active.
|
||||
// 5. Hit test the top panel if positional menu is active.
|
||||
if (!shouldRenderCursor &&
|
||||
appState.mLowerMenuType == LowerMenuType::POSITIONAL_MENU) {
|
||||
shouldRenderCursor = mGameSurfaceLayer->GetRayIntersectionWithPanelTopPanel(
|
||||
|
@ -822,6 +812,7 @@ private:
|
|||
scaleFactor = 0.01f + 0.003f * distance;
|
||||
}
|
||||
}
|
||||
if (sIsLowerPanelBeingPositioned) { shouldRenderCursor = true; }
|
||||
}
|
||||
|
||||
if (shouldRenderCursor) {
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
android:layout_weight="1"
|
||||
android:minHeight="0dp"
|
||||
android:padding="0dp"
|
||||
android:paddingVertical="12dp"
|
||||
android:paddingVertical="20dp"
|
||||
android:text="<" />
|
||||
|
||||
<Button
|
||||
|
@ -83,7 +83,7 @@
|
|||
android:layout_weight="1"
|
||||
android:minHeight="0dp"
|
||||
android:padding="0dp"
|
||||
android:paddingVertical="12dp"
|
||||
android:paddingVertical="20dp"
|
||||
android:text=">" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
|
|
@ -2,39 +2,68 @@
|
|||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/position_panel"
|
||||
android:gravity="center"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/linearLayout"
|
||||
<FrameLayout
|
||||
android:layout_width="1000dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<com.google.android.material.textview.MaterialTextView
|
||||
android:layout_width="wrap_content"
|
||||
<FrameLayout
|
||||
android:id="@+id/lowerPanelPlaceHolder"
|
||||
android:layout_width="900dp"
|
||||
android:layout_height="675dp"
|
||||
android:layout_marginTop="18dp"
|
||||
android:background="#093A60"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="400dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="50dp"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/lowerPanelPlaceHolder"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/lowerPanelPlaceHolder"
|
||||
app:layout_constraintTop_toTopOf="@+id/lowerPanelPlaceHolder">
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttonSelect"
|
||||
style="@style/VrRibbonButtonStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Press and hold trigger on panel to move it"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@color/citra_onBackground" />
|
||||
android:layout_marginBottom="10dp"
|
||||
android:text="@string/button_select" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatToggleButton
|
||||
android:id="@+id/toggle"
|
||||
android:layout_width="wrap_content"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttonStart"
|
||||
style="@style/VrRibbonButtonStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Lock Horizontal Axis"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
android:text="@string/button_start" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/buttonExit"
|
||||
style="@style/VrRibbonButtonStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/emulation_close_game" />
|
||||
</LinearLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
Loading…
Reference in a new issue