new Ribbon layer -- width is right, need height adjustment

This commit is contained in:
amwatson 2024-02-20 17:02:53 -06:00
parent 44d4c2d609
commit a558068642
7 changed files with 172 additions and 60 deletions

View file

@ -28,4 +28,5 @@
-keep class org.citra.citra_emu.vr.ui.VrUILayer { *; }
-keep class org.citra.citra_emu.vr.ui.VrKeyboardLayer { *; }
-keep class org.citra.citra_emu.vr.ui.VrErrorMessageLayer { *; }
-keep class org.citra.citra_emu.vr.ui.VrRibbonLayer { *; }
-keepattributes SourceFile,LineNumberTable

View file

@ -0,0 +1,13 @@
package org.citra.citra_emu.vr.ui
import org.citra.citra_emu.R
import org.citra.citra_emu.vr.VrActivity
class VrRibbonLayer(activity: VrActivity) : VrUILayer(activity, R.layout.vr_ribbon) {
override fun onSurfaceCreated() {
super.onSurfaceCreated()
}
}

View file

@ -163,7 +163,7 @@ UILayer::UILayer(const std::string& className, const XrVector3f&& position,
const XrQuaternionf&& orientation, JNIEnv* env, jobject activityObject,
const XrSession& session)
: mSession(session)
, mPanelFromWorld(XrPosef{XrMath::Quatf::Identity(), position})
, mPanelFromWorld(XrPosef{orientation, position})
, mEnv(env) {
const int32_t initializationStatus = Init(className, activityObject, position, session);
if (initializationStatus < 0) {

View file

@ -30,7 +30,7 @@ jclass JniUtils::GetGlobalClassReference(JNIEnv* env, jobject activityObject,
VR::JniGlobalRef::gClassLoader, VR::JniGlobalRef::gFindClassMethodID, classNameJString));
if (clazz == nullptr) {
// Class not found
ALOGE("Class not found: %s", correctedClassName.c_str());
ALOGE("Class not found: {}", correctedClassName.c_str());
return nullptr;
}

View file

@ -143,6 +143,40 @@ uint32_t GetDefaultGameResolutionFactorForHmd(const VRSettings::HMDType& hmdType
}
}
// Called whenever a session is started/resumed. Creates the head space based on the
// current pose of the HMD.
void CreateRuntimeInitatedReferenceSpaces(const XrTime predictedDisplayTime) {
// Create a reference space with the forward direction from the
// starting frame.
{
const XrReferenceSpaceCreateInfo sci = {XR_TYPE_REFERENCE_SPACE_CREATE_INFO, nullptr,
XR_REFERENCE_SPACE_TYPE_LOCAL,
XrMath::Posef::Identity()};
OXR(xrCreateReferenceSpace(gOpenXr->mSession, &sci, &gOpenXr->mForwardDirectionSpace));
}
{
const XrReferenceSpaceCreateInfo sci = {XR_TYPE_REFERENCE_SPACE_CREATE_INFO, nullptr,
XR_REFERENCE_SPACE_TYPE_VIEW,
XrMath::Posef::Identity()};
OXR(xrCreateReferenceSpace(gOpenXr->mSession, &sci, &gOpenXr->mViewSpace));
}
// Get the pose of the local space.
XrSpaceLocation lsl = {XR_TYPE_SPACE_LOCATION};
OXR(xrLocateSpace(gOpenXr->mForwardDirectionSpace, gOpenXr->mLocalSpace, predictedDisplayTime,
&lsl));
// Set the forward direction of the new space.
const XrPosef forwardDirectionPose = lsl.pose;
// Create a reference space with the same position and rotation as
// local.
const XrReferenceSpaceCreateInfo sci = {XR_TYPE_REFERENCE_SPACE_CREATE_INFO, nullptr,
XR_REFERENCE_SPACE_TYPE_LOCAL, forwardDirectionPose};
OXR(xrCreateReferenceSpace(gOpenXr->mSession, &sci, &gOpenXr->mHeadSpace));
}
} // anonymous namespace
//-----------------------------------------------------------------------------
@ -239,18 +273,22 @@ private:
XrVector3f{0, 0, -2.0f}, jni, mActivityObject, gOpenXr->mSession, resolutionFactor);
}
// Create the cursor layer.
mCursorLayer = std::make_unique<CursorLayer>(gOpenXr->mSession);
mErrorMessageLayer = std::make_unique<UILayer>(
"org/citra/citra_emu/vr/ui/VrErrorMessageLayer", XrVector3f{0, -0.1f, -1.0f},
XrQuaternionf{0, 0, 0, 1}, jni, mActivityObject, gOpenXr->mSession);
mRibbonLayer = std::make_unique<UILayer>(
"org/citra/citra_emu/vr/ui/VrRibbonLayer", XrVector3f{0, -0.75f, -1.51f},
XrMath::Quatf::FromEuler(0.0f, -MATH_FLOAT_PI / 4.0f, 0.0f), jni, mActivityObject, gOpenXr->mSession);
mKeyboardLayer = std::make_unique<UILayer>(
"org/citra/citra_emu/vr/ui/VrKeyboardLayer", XrVector3f{0, -0.4f, -0.5f},
XrMath::Quatf::FromEuler(0.0f, -MATH_FLOAT_PI / 4.0f, 0.0f), jni, mActivityObject,
gOpenXr->mSession);
mErrorMessageLayer = std::make_unique<UILayer>(
"org/citra/citra_emu/vr/ui/VrErrorMessageLayer", XrVector3f{0, -0.1f, -1.0f},
XrQuaternionf{0, 0, 0, 1}, jni, mActivityObject, gOpenXr->mSession);
// Create the cursor layer.
mCursorLayer = std::make_unique<CursorLayer>(gOpenXr->mSession);
//////////////////////////////////////////////////
// Intialize JNI methods
//////////////////////////////////////////////////
@ -451,6 +489,9 @@ private:
layers[layerCount++].mPassthrough = passthroughLayer;
}
mRibbonLayer->Frame(gOpenXr->mLocalSpace, layers, layerCount);
// Game surface (upper and lower panels) are in front of the passthrough layer.
mGameSurfaceLayer->Frame(gOpenXr->mLocalSpace, layers, layerCount,
gOpenXr->headLocation.pose, immersiveModeFactor,
@ -604,41 +645,6 @@ private:
}
}
// Called whenever a session is started/resumed. Creates the head space based on the
// current pose of the HMD.
void CreateRuntimeInitatedReferenceSpaces(const XrTime predictedDisplayTime) const {
// Create a reference space with the forward direction from the
// starting frame.
{
const XrReferenceSpaceCreateInfo sci = {XR_TYPE_REFERENCE_SPACE_CREATE_INFO, nullptr,
XR_REFERENCE_SPACE_TYPE_LOCAL,
XrMath::Posef::Identity()};
OXR(xrCreateReferenceSpace(gOpenXr->mSession, &sci, &gOpenXr->mForwardDirectionSpace));
}
{
const XrReferenceSpaceCreateInfo sci = {XR_TYPE_REFERENCE_SPACE_CREATE_INFO, nullptr,
XR_REFERENCE_SPACE_TYPE_VIEW,
XrMath::Posef::Identity()};
OXR(xrCreateReferenceSpace(gOpenXr->mSession, &sci, &gOpenXr->mViewSpace));
}
// Get the pose of the local space.
XrSpaceLocation lsl = {XR_TYPE_SPACE_LOCATION};
OXR(xrLocateSpace(gOpenXr->mForwardDirectionSpace, gOpenXr->mLocalSpace,
predictedDisplayTime, &lsl));
// Set the forward direction of the new space.
const XrPosef forwardDirectionPose = lsl.pose;
// Create a reference space with the same position and rotation as
// local.
const XrReferenceSpaceCreateInfo sci = {XR_TYPE_REFERENCE_SPACE_CREATE_INFO, nullptr,
XR_REFERENCE_SPACE_TYPE_LOCAL,
forwardDirectionPose};
OXR(xrCreateReferenceSpace(gOpenXr->mSession, &sci, &gOpenXr->mHeadSpace));
}
/** Handle the cursor and any hand-tracked/layer-dependent input
* interactions.
**/
@ -901,9 +907,7 @@ private:
break;
case XR_SESSION_STATE_VISIBLE:
ALOGV("{}(): Received XR_SESSION_STATE_VISIBLE event", __func__);
if (mLastAppState.mHasFocus) {
newAppState.mIsEmulationPaused = true;
}
if (mLastAppState.mHasFocus) { newAppState.mIsEmulationPaused = true; }
newAppState.mHasFocus = false;
break;
case XR_SESSION_STATE_READY:
@ -1066,6 +1070,7 @@ private:
std::unique_ptr<GameSurfaceLayer> mGameSurfaceLayer;
std::unique_ptr<PassthroughLayer> mPassthroughLayer;
std::unique_ptr<UILayer> mKeyboardLayer;
std::unique_ptr<UILayer> mRibbonLayer;
std::unique_ptr<InputStateStatic> mInputStateStatic;
InputStateFrame mInputStateFrame;

View file

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<FrameLayout
android:layout_width="1540dp"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/vr_menu_background"
android:padding="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<FrameLayout
android:layout_width="1200dp"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<FrameLayout
android:id="@+id/frameLayout"
android:layout_width="900dp"
android:layout_height="900dp"
android:background="@android:color/black"
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="20dp"
android:gravity="center"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="@+id/frameLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/frameLayout"
app:layout_constraintTop_toTopOf="@+id/frameLayout">
<Button
android:id="@+id/buttonSelect"
style="@style/VrRibbonButtonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="@string/button_select" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<ImageButton
android:id="@+id/buttonHome"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:background="@null"
android:src="@drawable/button_home" />
<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="@string/button_start" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -37,4 +37,10 @@
<item name="colorControlNormal">@color/citra_primary</item>
</style>
<style name="VrRibbonButtonStyle" parent="@style/VrKeyboardButtonStyle">
<item name="android:alpha">0.5</item>
<item name="android:background">#80eaeaea</item>
<item name="android:textColor">@android:color/black</item>
<item name="android:textAlignment">center</item>
</style>
</resources>