Restore LooksMenu camera state
Capture the pre-LooksMenu third-person camera settings and restore them when character customization closes, so first-time customization returns to the normal over-the-shoulder view and movement controls. Also clear the saved snapshot during reset paths so cleanup still runs if the menu flow exits early.
This commit is contained in:
@@ -33,6 +33,24 @@ namespace
|
||||
constexpr float kPi = 3.14159265358979323846F;
|
||||
constexpr float kLooksMenuFaceCameraZoomOffset = -90.0F;
|
||||
|
||||
struct ThirdPersonCameraSnapshot
|
||||
{
|
||||
RE::NiPoint3 targetShoulderOffset;
|
||||
RE::NiPoint3 currentShoulderOffset;
|
||||
RE::NiPoint3 sideOffsetCollisionBlend;
|
||||
RE::NiPoint2 freeRotation;
|
||||
float targetZoomOffset;
|
||||
float currentZoomOffset;
|
||||
float targetYaw;
|
||||
float currentYaw;
|
||||
float cameraHeightAdjust;
|
||||
bool freeRotationEnabled;
|
||||
bool zoomingInto1st;
|
||||
bool show3rdPersonModel;
|
||||
bool preserveRotation;
|
||||
bool applyOffsets;
|
||||
};
|
||||
|
||||
enum class CharGenPhase
|
||||
{
|
||||
None,
|
||||
@@ -54,6 +72,7 @@ namespace
|
||||
bool g_sawSpecialMenuOpen = false;
|
||||
bool g_looksMenuFallbackIssued = false;
|
||||
bool g_looksMenuCameraContextApplied = false;
|
||||
std::optional<ThirdPersonCameraSnapshot> g_preLooksCameraSnapshot;
|
||||
int g_spawnPollFrameCounter = 0;
|
||||
int g_spawnWaitAttempts = 0;
|
||||
int g_worldReadyPolls = 0;
|
||||
@@ -266,6 +285,81 @@ namespace
|
||||
return a_angle;
|
||||
}
|
||||
|
||||
RE::ThirdPersonState* GetThirdPersonCameraState()
|
||||
{
|
||||
auto* camera = RE::PlayerCamera::GetSingleton();
|
||||
if (!camera) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto thirdPersonState = camera->GetState(RE::CameraState::k3rdPerson);
|
||||
return thirdPersonState ? static_cast<RE::ThirdPersonState*>(thirdPersonState.get()) : nullptr;
|
||||
}
|
||||
|
||||
void CapturePreLooksCameraState()
|
||||
{
|
||||
if (g_preLooksCameraSnapshot) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* state = GetThirdPersonCameraState();
|
||||
if (!state) {
|
||||
LogWarning("Third-person camera state unavailable while capturing pre-Looks camera state.");
|
||||
return;
|
||||
}
|
||||
|
||||
g_preLooksCameraSnapshot = ThirdPersonCameraSnapshot{
|
||||
state->targetShoulderOffset,
|
||||
state->currentShoulderOffset,
|
||||
state->sideOffsetCollisionBlend,
|
||||
state->freeRotation,
|
||||
state->targetZoomOffset,
|
||||
state->currentZoomOffset,
|
||||
state->targetYaw,
|
||||
state->currentYaw,
|
||||
state->cameraHeightAdjust,
|
||||
state->freeRotationEnabled,
|
||||
state->zoomingInto1st,
|
||||
state->show3rdPersonModel,
|
||||
state->preserveRotation,
|
||||
state->applyOffsets
|
||||
};
|
||||
}
|
||||
|
||||
void RestorePreLooksCameraState()
|
||||
{
|
||||
if (!g_preLooksCameraSnapshot) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto* state = GetThirdPersonCameraState();
|
||||
if (!state) {
|
||||
LogWarning("Third-person camera state unavailable while restoring pre-Looks camera state.");
|
||||
g_preLooksCameraSnapshot.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
const auto snapshot = *g_preLooksCameraSnapshot;
|
||||
state->SetFreeRotationMode(snapshot.freeRotationEnabled, false);
|
||||
state->targetShoulderOffset = snapshot.targetShoulderOffset;
|
||||
state->currentShoulderOffset = snapshot.currentShoulderOffset;
|
||||
state->sideOffsetCollisionBlend = snapshot.sideOffsetCollisionBlend;
|
||||
state->freeRotation = snapshot.freeRotation;
|
||||
state->targetZoomOffset = snapshot.targetZoomOffset;
|
||||
state->currentZoomOffset = snapshot.currentZoomOffset;
|
||||
state->targetYaw = snapshot.targetYaw;
|
||||
state->currentYaw = snapshot.currentYaw;
|
||||
state->cameraHeightAdjust = snapshot.cameraHeightAdjust;
|
||||
state->freeRotationEnabled = snapshot.freeRotationEnabled;
|
||||
state->zoomingInto1st = snapshot.zoomingInto1st;
|
||||
state->show3rdPersonModel = snapshot.show3rdPersonModel;
|
||||
state->preserveRotation = snapshot.preserveRotation;
|
||||
state->applyOffsets = snapshot.applyOffsets;
|
||||
|
||||
g_preLooksCameraSnapshot.reset();
|
||||
LogInfo("Restored third-person camera state after Looks menu.");
|
||||
}
|
||||
|
||||
bool ForcePlayerThirdPersonCamera()
|
||||
{
|
||||
auto* camera = RE::PlayerCamera::GetSingleton();
|
||||
@@ -307,6 +401,7 @@ namespace
|
||||
|
||||
void PrepareCharGenCameraContext()
|
||||
{
|
||||
CapturePreLooksCameraState();
|
||||
ForcePlayerThirdPersonCamera();
|
||||
RE::Console::ExecuteCommand("ForceThirdPerson");
|
||||
LogInfo("Prepared camera context before Looks menu.");
|
||||
@@ -319,6 +414,7 @@ namespace
|
||||
}
|
||||
|
||||
RE::Console::ExecuteCommand("SetInChargen 1");
|
||||
CapturePreLooksCameraState();
|
||||
ForcePlayerThirdPersonCamera();
|
||||
RE::Console::ExecuteCommand("ForceThirdPerson");
|
||||
g_looksMenuCameraContextApplied = true;
|
||||
@@ -328,11 +424,14 @@ namespace
|
||||
|
||||
void RestoreCharGenCameraContext()
|
||||
{
|
||||
if (!g_looksMenuCameraContextApplied) {
|
||||
if (!g_looksMenuCameraContextApplied && !g_preLooksCameraSnapshot) {
|
||||
return;
|
||||
}
|
||||
|
||||
RE::Console::ExecuteCommand("SetInChargen 0");
|
||||
if (g_looksMenuCameraContextApplied) {
|
||||
RE::Console::ExecuteCommand("SetInChargen 0");
|
||||
}
|
||||
RestorePreLooksCameraState();
|
||||
g_looksMenuCameraContextApplied = false;
|
||||
g_looksMenuCameraNudgePolls = 0;
|
||||
LogInfo("Restored chargen camera context after Looks menu.");
|
||||
@@ -350,6 +449,7 @@ namespace
|
||||
g_sawSpecialMenuOpen = false;
|
||||
g_looksMenuFallbackIssued = false;
|
||||
g_looksMenuCameraContextApplied = false;
|
||||
g_preLooksCameraSnapshot.reset();
|
||||
g_spawnPollFrameCounter = 0;
|
||||
g_spawnWaitAttempts = 0;
|
||||
g_worldReadyPolls = 0;
|
||||
@@ -369,6 +469,7 @@ namespace
|
||||
g_sawSpecialMenuOpen = false;
|
||||
g_looksMenuFallbackIssued = false;
|
||||
g_looksMenuCameraContextApplied = false;
|
||||
g_preLooksCameraSnapshot.reset();
|
||||
g_spawnPollFrameCounter = 0;
|
||||
g_spawnWaitAttempts = 0;
|
||||
g_worldReadyPolls = 0;
|
||||
|
||||
Reference in New Issue
Block a user