mirror of
https://github.com/amwatson/CitraVR.git
synced 2024-09-20 03:11:40 +02:00
Hacky setup for adjusting position of upper and lower panels from menu (partial, toggle doesn't work)
This commit is contained in:
parent
e9eb4a30fd
commit
9f57f8530e
6 changed files with 159 additions and 105 deletions
|
@ -436,6 +436,30 @@ void GameSurfaceLayer::SetTopPanelFromController(const XrVector3f& controllerPos
|
||||||
mTopPanel.mPanelFromWorld = XrPosef{windowRotation, windowPosition};
|
mTopPanel.mPanelFromWorld = XrPosef{windowRotation, windowPosition};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GameSurfaceLayer::SetTopPanelFromThumbstick(const float thumbstickY) {
|
||||||
|
static constexpr float kDepthSpeed = 0.05f;
|
||||||
|
static constexpr float kMaxDepth = -10.0f;
|
||||||
|
|
||||||
|
mTopPanel.mPanelFromWorld.position.z -= (thumbstickY * kDepthSpeed);
|
||||||
|
mTopPanel.mPanelFromWorld.position.z =
|
||||||
|
std::min(mTopPanel.mPanelFromWorld.position.z, mLowerPanel.mPanelFromWorld.position.z);
|
||||||
|
mTopPanel.mPanelFromWorld.position.z =
|
||||||
|
std::max(mTopPanel.mPanelFromWorld.position.z, kMaxDepth);
|
||||||
|
}
|
||||||
|
|
||||||
|
XrPosef GameSurfaceLayer::SetLowerPanelFromThumbstick(const float thumbstickY) {
|
||||||
|
static constexpr float kDepthSpeed = 0.05f;
|
||||||
|
static constexpr float kMaxDepth = -10.0f;
|
||||||
|
|
||||||
|
mLowerPanel.mPanelFromWorld.position.y += (thumbstickY * kDepthSpeed);
|
||||||
|
mLowerPanel.mPanelFromWorld.position.y =
|
||||||
|
std::min(mLowerPanel.mPanelFromWorld.position.y, mTopPanel.mPanelFromWorld.position.y);
|
||||||
|
mLowerPanel.mPanelFromWorld.position.y =
|
||||||
|
std::max(mLowerPanel.mPanelFromWorld.position.y, kMaxDepth);
|
||||||
|
|
||||||
|
return mLowerPanel.mPanelFromWorld;
|
||||||
|
}
|
||||||
|
|
||||||
XrPosef GameSurfaceLayer::GetTopPanelFromHeadPose(uint32_t eye, const XrPosef& headPose) {
|
XrPosef GameSurfaceLayer::GetTopPanelFromHeadPose(uint32_t eye, const XrPosef& headPose) {
|
||||||
XrVector3f panelPosition = headPose.position;
|
XrVector3f panelPosition = headPose.position;
|
||||||
|
|
||||||
|
@ -460,17 +484,6 @@ XrPosef GameSurfaceLayer::GetTopPanelFromHeadPose(uint32_t eye, const XrPosef& h
|
||||||
}
|
}
|
||||||
|
|
||||||
// based on thumbstick, modify the depth of the top panel
|
// based on thumbstick, modify the depth of the top panel
|
||||||
void GameSurfaceLayer::SetTopPanelFromThumbstick(const float thumbstickY) {
|
|
||||||
static constexpr float kDepthSpeed = 0.05f;
|
|
||||||
static constexpr float kMaxDepth = -10.0f;
|
|
||||||
|
|
||||||
mTopPanel.mPanelFromWorld.position.z -= (thumbstickY * kDepthSpeed);
|
|
||||||
mTopPanel.mPanelFromWorld.position.z =
|
|
||||||
std::min(mTopPanel.mPanelFromWorld.position.z, mLowerPanel.mPanelFromWorld.position.z);
|
|
||||||
mTopPanel.mPanelFromWorld.position.z =
|
|
||||||
std::max(mTopPanel.mPanelFromWorld.position.z, kMaxDepth);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Next error code: -2
|
// Next error code: -2
|
||||||
int32_t GameSurfaceLayer::Init(const XrSession& session, const jobject activityObject) {
|
int32_t GameSurfaceLayer::Init(const XrSession& session, const jobject activityObject) {
|
||||||
if (mImmersiveMode > 0) {
|
if (mImmersiveMode > 0) {
|
||||||
|
|
|
@ -167,9 +167,10 @@ public:
|
||||||
XrVector2f& result2d,
|
XrVector2f& result2d,
|
||||||
XrPosef& result3d) const;
|
XrPosef& result3d) const;
|
||||||
void SetTopPanelFromController(const XrVector3f& controllerPosition);
|
void SetTopPanelFromController(const XrVector3f& controllerPosition);
|
||||||
XrPosef GetTopPanelFromHeadPose(uint32_t eye, const XrPosef& headPose);
|
|
||||||
|
|
||||||
void SetTopPanelFromThumbstick(const float thumbstickY);
|
void SetTopPanelFromThumbstick(const float thumbstickY);
|
||||||
|
XrPosef SetLowerPanelFromThumbstick(const float thumbstickY);
|
||||||
|
|
||||||
|
XrPosef GetTopPanelFromHeadPose(uint32_t eye, const XrPosef& headPose);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int Init(const XrSession& session, const jobject activityObject);
|
int Init(const XrSession& session, const jobject activityObject);
|
||||||
|
|
|
@ -325,3 +325,5 @@ int UILayer::CreateSwapchain() {
|
||||||
void UILayer::SendClickToUI(const XrVector2f& pos2d, const int type) {
|
void UILayer::SendClickToUI(const XrVector2f& pos2d, const int type) {
|
||||||
mEnv->CallIntMethod(mVrUILayerObject, mSendClickToUIMethodID, pos2d.x, pos2d.y, type);
|
mEnv->CallIntMethod(mVrUILayerObject, mSendClickToUIMethodID, pos2d.x, pos2d.y, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UILayer::SetPanelWithPose(const XrPosef& pose) { mPanelFromWorld = pose; }
|
||||||
|
|
|
@ -123,6 +123,8 @@ public:
|
||||||
*/
|
*/
|
||||||
void SendClickToUI(const XrVector2f& pos2d, const int type);
|
void SendClickToUI(const XrVector2f& pos2d, const int type);
|
||||||
|
|
||||||
|
void SetPanelWithPose(const XrPosef& pose);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int Init(const std::string& className, const jobject activityObject, const XrVector3f& position,
|
int Init(const std::string& className, const jobject activityObject, const XrVector3f& position,
|
||||||
const XrSession& session);
|
const XrSession& session);
|
||||||
|
|
|
@ -650,7 +650,7 @@ private:
|
||||||
XrPosef cursorPose3d = XrMath::Posef::Identity();
|
XrPosef cursorPose3d = XrMath::Posef::Identity();
|
||||||
XrVector2f cursorPos2d = {0, 0};
|
XrVector2f cursorPos2d = {0, 0};
|
||||||
float scaleFactor = 0.01f;
|
float scaleFactor = 0.01f;
|
||||||
CursorLayer::CursorType cursorType = CursorLayer::CursorType::CURSOR_TYPE_NORMAL;
|
CursorLayer::CursorType cursorType = appState.mLowerMenuType == LowerMenuType::POSITIONAL_MENU ? CursorLayer::CursorType::CURSOR_TYPE_TOP_PANEL : CursorLayer::CursorType::CURSOR_TYPE_NORMAL;
|
||||||
|
|
||||||
[[maybe_unused]] const auto nonPreferredController =
|
[[maybe_unused]] const auto nonPreferredController =
|
||||||
mInputStateFrame.mPreferredHand == InputStateFrame::LEFT_CONTROLLER
|
mInputStateFrame.mPreferredHand == InputStateFrame::LEFT_CONTROLLER
|
||||||
|
@ -685,16 +685,18 @@ private:
|
||||||
if (triggerState.changedSinceLastSync) {
|
if (triggerState.changedSinceLastSync) {
|
||||||
mErrorMessageLayer->SendClickToUI(cursorPos2d, triggerState.currentState);
|
mErrorMessageLayer->SendClickToUI(cursorPos2d, triggerState.currentState);
|
||||||
}
|
}
|
||||||
} else { // Don't test for cursor intersection if error message is shown
|
}
|
||||||
if (appState.mIsKeyboardActive) {
|
// Don't test for cursor intersection if error message is shown
|
||||||
|
if (!shouldRenderCursor && appState.mIsKeyboardActive) {
|
||||||
shouldRenderCursor = mKeyboardLayer->GetRayIntersectionWithPanel(
|
shouldRenderCursor = mKeyboardLayer->GetRayIntersectionWithPanel(
|
||||||
start, end, cursorPos2d, cursorPose3d);
|
start, end, cursorPos2d, cursorPose3d);
|
||||||
if (triggerState.changedSinceLastSync) {
|
if (triggerState.changedSinceLastSync) {
|
||||||
mKeyboardLayer->SendClickToUI(cursorPos2d, triggerState.currentState);
|
mKeyboardLayer->SendClickToUI(cursorPos2d, triggerState.currentState);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
// No dialogs/popups that should impede normal cursor interaction with
|
// No dialogs/popups that should impede normal cursor interaction with
|
||||||
// applicable panels
|
// applicable panels
|
||||||
|
if (!shouldRenderCursor && appState.ShouldShowLowerPanel()) {
|
||||||
shouldRenderCursor = mGameSurfaceLayer->GetRayIntersectionWithPanel(
|
shouldRenderCursor = mGameSurfaceLayer->GetRayIntersectionWithPanel(
|
||||||
start, end, cursorPos2d, cursorPose3d);
|
start, end, cursorPos2d, cursorPose3d);
|
||||||
if (triggerState.currentState == 0 && triggerState.changedSinceLastSync) {
|
if (triggerState.currentState == 0 && triggerState.changedSinceLastSync) {
|
||||||
|
@ -710,12 +712,29 @@ private:
|
||||||
jni->CallVoidMethod(mActivityObject, mSendClickToWindowMethodID,
|
jni->CallVoidMethod(mActivityObject, mSendClickToWindowMethodID,
|
||||||
cursorPos2d.x, cursorPos2d.y, 2);
|
cursorPos2d.x, cursorPos2d.y, 2);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (!shouldRenderCursor) {
|
if (!shouldRenderCursor) {
|
||||||
shouldRenderCursor = mRibbonLayer->GetRayIntersectionWithPanel(
|
shouldRenderCursor = mRibbonLayer->GetRayIntersectionWithPanel(
|
||||||
start, end, cursorPos2d, cursorPose3d);
|
start, end, cursorPos2d, cursorPose3d);
|
||||||
if (triggerState.changedSinceLastSync) {
|
if (shouldRenderCursor && triggerState.changedSinceLastSync) {
|
||||||
mRibbonLayer->SendClickToUI(cursorPos2d, triggerState.currentState);
|
mRibbonLayer->SendClickToUI(cursorPos2d, triggerState.currentState);
|
||||||
}
|
}
|
||||||
|
if (shouldRenderCursor &&
|
||||||
|
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 (!shouldRenderCursor) {
|
if (!shouldRenderCursor) {
|
||||||
|
@ -726,19 +745,17 @@ private:
|
||||||
// a problem for any games.
|
// a problem for any games.
|
||||||
ForwardButtonStateIfNeeded(
|
ForwardButtonStateIfNeeded(
|
||||||
jni, mActivityObject, mForwardVRInputMethodID, 104 /* BUTTON_L2 */,
|
jni, mActivityObject, mForwardVRInputMethodID, 104 /* BUTTON_L2 */,
|
||||||
mInputStateFrame
|
mInputStateFrame.mIndexTriggerState[InputStateFrame::LEFT_CONTROLLER],
|
||||||
.mIndexTriggerState[InputStateFrame::LEFT_CONTROLLER],
|
|
||||||
"l2");
|
"l2");
|
||||||
ForwardButtonStateIfNeeded(
|
ForwardButtonStateIfNeeded(
|
||||||
jni, mActivityObject, mForwardVRInputMethodID, 105 /* BUTTON_R2 */,
|
jni, mActivityObject, mForwardVRInputMethodID, 105 /* BUTTON_R2 */,
|
||||||
mInputStateFrame
|
mInputStateFrame.mIndexTriggerState[InputStateFrame::RIGHT_CONTROLLER],
|
||||||
.mIndexTriggerState[InputStateFrame::RIGHT_CONTROLLER],
|
|
||||||
"r2");
|
"r2");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Hit test the top panel
|
// Hit test the top panel if positional menu is active.
|
||||||
if (!shouldRenderCursor) {
|
if (!shouldRenderCursor &&
|
||||||
|
appState.mLowerMenuType == LowerMenuType::POSITIONAL_MENU) {
|
||||||
shouldRenderCursor = mGameSurfaceLayer->GetRayIntersectionWithPanelTopPanel(
|
shouldRenderCursor = mGameSurfaceLayer->GetRayIntersectionWithPanelTopPanel(
|
||||||
start, end, cursorPos2d, cursorPose3d);
|
start, end, cursorPos2d, cursorPose3d);
|
||||||
// If top panel is hit, trigger controls the
|
// If top panel is hit, trigger controls the
|
||||||
|
@ -760,11 +777,8 @@ private:
|
||||||
thumbstickState.currentState.y);
|
thumbstickState.currentState.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (shouldRenderCursor) {
|
|
||||||
cursorType = CursorLayer::CursorType::CURSOR_TYPE_TOP_PANEL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a scale factor so the cursor doesn't scale as
|
// Add a scale factor so the cursor doesn't scale as
|
||||||
// quickly as the panel(s) with distance. This may be
|
// quickly as the panel(s) with distance. This may be
|
||||||
// mildly unsettling, but it helps to ensure the cursor
|
// mildly unsettling, but it helps to ensure the cursor
|
||||||
|
@ -1065,9 +1079,7 @@ private:
|
||||||
|
|
||||||
class AppState {
|
class AppState {
|
||||||
public:
|
public:
|
||||||
bool ShouldShowLowerPanel() const {
|
bool ShouldShowLowerPanel() const { return mLowerMenuType == LowerMenuType::MAIN_MENU; }
|
||||||
return mLowerMenuType == LowerMenuType::MAIN_MENU;
|
|
||||||
}
|
|
||||||
|
|
||||||
LowerMenuType mLowerMenuType = LowerMenuType::MAIN_MENU;
|
LowerMenuType mLowerMenuType = LowerMenuType::MAIN_MENU;
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,39 @@
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:id="@+id/position_panel"
|
android:id="@+id/position_panel"
|
||||||
android:layout_width="wrap_content"
|
android:gravity="center"
|
||||||
android:layout_height="wrap_content">
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<FrameLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/linearLayout"
|
||||||
android:layout_width="1000dp"
|
android:layout_width="1000dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<com.google.android.material.textview.MaterialTextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Press and hold trigger on panel to move it"
|
||||||
|
android:textAlignment="center"
|
||||||
|
android:textColor="@color/citra_onBackground" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatToggleButton
|
||||||
|
android:id="@+id/toggle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="Lock Horizontal Axis"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
Loading…
Reference in a new issue