From 0e4abbd90d67afaa595321948f1b7290061adbae Mon Sep 17 00:00:00 2001 From: InvalidArgument3 Date: Sun, 2 Mar 2025 04:52:48 -0600 Subject: [PATCH 1/5] Update CastSpectator.cs --- .../Scripts/CastSpectator/CastSpectator.cs | 97 ++++++++++++++++--- 1 file changed, 86 insertions(+), 11 deletions(-) diff --git a/Utility Mods/Cast Spectator - StarCore/Data/Scripts/CastSpectator/CastSpectator.cs b/Utility Mods/Cast Spectator - StarCore/Data/Scripts/CastSpectator/CastSpectator.cs index 06505e23f..f38eeea79 100644 --- a/Utility Mods/Cast Spectator - StarCore/Data/Scripts/CastSpectator/CastSpectator.cs +++ b/Utility Mods/Cast Spectator - StarCore/Data/Scripts/CastSpectator/CastSpectator.cs @@ -123,6 +123,9 @@ public class CastSpectator : MySessionComponentBase public float InQuint(float t) => t * t * t * t * t; public float OutQuint(float t) => 1 - InQuint(1 - t); + private MatrixD freeModeMatrix = MatrixD.Identity; + private bool freeModeInitialized = false; + private bool HideHud { get @@ -264,6 +267,17 @@ public override void UpdateAfterSimulation() if (m_Pref.FreeMode.IsKeybindPressed()) { ObsCameraState.lockmode = CameraMode.Free; + if (ObsCameraState.lockEntity != null) + { + Vector3D targetPos = ObsCameraState.lockEntity.WorldVolume.Center; + // Compute the offset from the target. + Vector3D offset = m_specCam.Position - targetPos; + // Use the current camera orientation, but zero out its translation. + MatrixD currentOrientation = m_specCam.Orientation; + currentOrientation.Translation = offset; + freeModeMatrix = currentOrientation; + freeModeInitialized = true; + } } if (m_Pref.FollowMode.IsKeybindPressed()) @@ -533,11 +547,55 @@ public override void UpdateAfterSimulation() switch (ObsCameraState.lockmode) { case CameraMode.Free: - Vector3D WorldMoveFree = mi.X * m_playerCamera.WorldMatrix.Right - + mi.Y * m_playerCamera.WorldMatrix.Up - + mi.Z * m_playerCamera.WorldMatrix.Backward; - m_specCam.Position = ObsCameraState.lockEntity.WorldVolume.Center + ObsCameraState.localVector + WorldMoveFree; + { + if (!freeModeInitialized && ObsCameraState.lockEntity != null) + { + // Fallback initialization if needed: + Vector3D targetPos = ObsCameraState.lockEntity.WorldVolume.Center; + Vector3D offset = m_specCam.Position - targetPos; + MatrixD currentOrientation = m_specCam.Orientation; + currentOrientation.Translation = offset; + freeModeMatrix = currentOrientation; + freeModeInitialized = true; + } + + // Update freeModeMatrix translation with smoothed movement: + Vector3D freeMovement = mi.X * freeModeMatrix.Right + + mi.Y * freeModeMatrix.Up + + mi.Z * freeModeMatrix.Backward; + freeModeMatrix.Translation += freeMovement; + + // Update freeModeMatrix rotation with smoothed mouse input: + if (mouse.Y != 0) + { + Vector3D newRight, newForward; + MyUtils.VectorPlaneRotation(freeModeMatrix.Right, freeModeMatrix.Forward, out newRight, out newForward, -mouse.Y); + freeModeMatrix.Right = newRight; + freeModeMatrix.Forward = newForward; + } + if (mouse.X != 0) + { + Vector3D newUp, newForward; + MyUtils.VectorPlaneRotation(freeModeMatrix.Up, freeModeMatrix.Forward, out newUp, out newForward, mouse.X); + freeModeMatrix.Up = newUp; + freeModeMatrix.Forward = newForward; + } + if (ri != 0) + { + Vector3D newUp, newRight; + MyUtils.VectorPlaneRotation(freeModeMatrix.Up, freeModeMatrix.Right, out newUp, out newRight, ri); + freeModeMatrix.Up = newUp; + freeModeMatrix.Right = newRight; + } + + // Compute camera position as target's center + stored free-mode offset. + Vector3D targetCenter = ObsCameraState.lockEntity.WorldVolume.Center; + m_specCam.Position = targetCenter + freeModeMatrix.Translation; + // Use freeModeMatrix rotation for the view. + m_specCam.SetTarget(m_specCam.Position + freeModeMatrix.Forward, freeModeMatrix.Up); + } break; + case CameraMode.Follow: Vector3D WorldMoveFollow = mi.X * ObsCameraState.localMatrix.Right + mi.Y * ObsCameraState.localMatrix.Up @@ -586,14 +644,16 @@ public override void UpdateAfterSimulation() } - var reconstruct = ObsCameraState.lastOrientation = m_specCam.Orientation; - reconstruct.Translation = m_specCam.Position; - ObsCameraState.localMatrix = WorldToLocalNI(reconstruct, ObsCameraState.lockEntity.WorldMatrixNormalizedInv); - - ObsCameraState.localVector = m_specCam.Position - ObsCameraState.lockEntity.WorldVolume.Center; - if (ObsCameraState.lockmode != CameraMode.Orbit) + if (ObsCameraState.lockmode != CameraMode.Free) { - ObsCameraState.localDistance = ObsCameraState.localVector.Length(); + var reconstruct = ObsCameraState.lastOrientation = m_specCam.Orientation; + reconstruct.Translation = m_specCam.Position; + ObsCameraState.localMatrix = WorldToLocalNI(reconstruct, ObsCameraState.lockEntity.WorldMatrixNormalizedInv); + ObsCameraState.localVector = m_specCam.Position - ObsCameraState.lockEntity.WorldVolume.Center; + if (ObsCameraState.lockmode != CameraMode.Orbit) + { + ObsCameraState.localDistance = ObsCameraState.localVector.Length(); + } } } @@ -1145,6 +1205,21 @@ private MatrixD LocalToWorld(MatrixD local, MatrixD worldMatrix) return local * worldMatrix; } + private void InitFreeMode() + { + if (m_playerCamera != null && ObsCameraState.lockEntity != null) + { + // Capture the current camera orientation (without translation) + MatrixD currentOrientation = m_specCam.Orientation; + currentOrientation.Translation = Vector3D.Zero; + // Calculate the offset from the target's center + Vector3D offset = m_specCam.Position - ObsCameraState.lockEntity.WorldVolume.Center; + // Set the free mode state to start from the current camera state + ObsCameraState.localMatrix = currentOrientation; + ObsCameraState.localMatrix.Translation = offset; + } + } + public IMyGridGroupData GetConeFocus() { IMyCamera camera = MyAPIGateway.Session.Camera; From 041948a17278bdccc14fa0ef2a24b088da768882 Mon Sep 17 00:00:00 2001 From: InvalidArgument3 Date: Sun, 2 Mar 2025 05:12:37 -0600 Subject: [PATCH 2/5] almost --- .../Scripts/CastSpectator/CastSpectator.cs | 106 ++++++++++-------- 1 file changed, 62 insertions(+), 44 deletions(-) diff --git a/Utility Mods/Cast Spectator - StarCore/Data/Scripts/CastSpectator/CastSpectator.cs b/Utility Mods/Cast Spectator - StarCore/Data/Scripts/CastSpectator/CastSpectator.cs index f38eeea79..c179167fb 100644 --- a/Utility Mods/Cast Spectator - StarCore/Data/Scripts/CastSpectator/CastSpectator.cs +++ b/Utility Mods/Cast Spectator - StarCore/Data/Scripts/CastSpectator/CastSpectator.cs @@ -245,6 +245,7 @@ public override void UpdateAfterSimulation() { case CameraMode.Free: ObsCameraState.lockmode = CameraMode.Follow; + InitializeFollowFromFree(); // Preserve Free mode state break; case CameraMode.Follow: ObsCameraState.lockmode = CameraMode.Orbit; @@ -255,6 +256,7 @@ public override void UpdateAfterSimulation() break; case CameraMode.Track: ObsCameraState.lockmode = CameraMode.Free; + InitializeFreeMode(); break; } } @@ -267,21 +269,15 @@ public override void UpdateAfterSimulation() if (m_Pref.FreeMode.IsKeybindPressed()) { ObsCameraState.lockmode = CameraMode.Free; - if (ObsCameraState.lockEntity != null) - { - Vector3D targetPos = ObsCameraState.lockEntity.WorldVolume.Center; - // Compute the offset from the target. - Vector3D offset = m_specCam.Position - targetPos; - // Use the current camera orientation, but zero out its translation. - MatrixD currentOrientation = m_specCam.Orientation; - currentOrientation.Translation = offset; - freeModeMatrix = currentOrientation; - freeModeInitialized = true; - } + InitializeFreeMode(); } if (m_Pref.FollowMode.IsKeybindPressed()) { + if (ObsCameraState.lockmode == CameraMode.Free) + { + InitializeFollowFromFree(); + } ObsCameraState.lockmode = CameraMode.Follow; } @@ -548,24 +544,18 @@ public override void UpdateAfterSimulation() { case CameraMode.Free: { - if (!freeModeInitialized && ObsCameraState.lockEntity != null) + if (!freeModeInitialized) { - // Fallback initialization if needed: - Vector3D targetPos = ObsCameraState.lockEntity.WorldVolume.Center; - Vector3D offset = m_specCam.Position - targetPos; - MatrixD currentOrientation = m_specCam.Orientation; - currentOrientation.Translation = offset; - freeModeMatrix = currentOrientation; - freeModeInitialized = true; + InitializeFreeMode(); } - // Update freeModeMatrix translation with smoothed movement: + // Apply smoothed movement Vector3D freeMovement = mi.X * freeModeMatrix.Right + mi.Y * freeModeMatrix.Up + mi.Z * freeModeMatrix.Backward; freeModeMatrix.Translation += freeMovement; - // Update freeModeMatrix rotation with smoothed mouse input: + // Apply smoothed rotation if (mouse.Y != 0) { Vector3D newRight, newForward; @@ -588,25 +578,34 @@ public override void UpdateAfterSimulation() freeModeMatrix.Right = newRight; } - // Compute camera position as target's center + stored free-mode offset. - Vector3D targetCenter = ObsCameraState.lockEntity.WorldVolume.Center; - m_specCam.Position = targetCenter + freeModeMatrix.Translation; - // Use freeModeMatrix rotation for the view. + // Set camera position and orientation + Vector3D basePos = ObsCameraState.lockEntity?.WorldVolume.Center ?? Vector3D.Zero; + m_specCam.Position = basePos + freeModeMatrix.Translation; m_specCam.SetTarget(m_specCam.Position + freeModeMatrix.Forward, freeModeMatrix.Up); } break; case CameraMode.Follow: - Vector3D WorldMoveFollow = mi.X * ObsCameraState.localMatrix.Right - + mi.Y * ObsCameraState.localMatrix.Up - + mi.Z * ObsCameraState.localMatrix.Backward; - var move = ObsCameraState.localMatrix.Translation + WorldMoveFollow; - ObsCameraState.localMatrix.Translation = move; - var fworldmatrix = ObsCameraState.lockEntity.WorldMatrix; - var targetm = LocalToWorld(ObsCameraState.localMatrix, fworldmatrix); - m_specCam.Position = targetm.Translation; - m_specCam.SetTarget(m_specCam.Position + targetm.Forward, targetm.Up); + { + if (ObsCameraState.localMatrix == MatrixD.Identity && ObsCameraState.lockEntity != null) + { + // Fallback initialization if localMatrix wasn’t set (e.g., no prior mode) + Vector3D offset = m_specCam.Position - ObsCameraState.lockEntity.WorldVolume.Center; + MatrixD worldMatrix = m_specCam.Orientation; + worldMatrix.Translation = offset; + ObsCameraState.localMatrix = WorldToLocalNI(worldMatrix, ObsCameraState.lockEntity.WorldMatrixNormalizedInv); + } + Vector3D WorldMoveFollow = mi.X * ObsCameraState.localMatrix.Right + + mi.Y * ObsCameraState.localMatrix.Up + + mi.Z * ObsCameraState.localMatrix.Backward; + var move = ObsCameraState.localMatrix.Translation + WorldMoveFollow; + ObsCameraState.localMatrix.Translation = move; + var fworldmatrix = ObsCameraState.lockEntity.WorldMatrix; + var targetm = LocalToWorld(ObsCameraState.localMatrix, fworldmatrix); + m_specCam.Position = targetm.Translation; + m_specCam.SetTarget(m_specCam.Position + targetm.Forward, targetm.Up); + } break; case CameraMode.Orbit: var lookAt = ObsCameraState.lockEntity.WorldVolume.Center; @@ -1205,18 +1204,37 @@ private MatrixD LocalToWorld(MatrixD local, MatrixD worldMatrix) return local * worldMatrix; } - private void InitFreeMode() + private void InitializeFreeMode() + { + if (m_specCam != null) + { + // Capture current orientation (rotation only) + freeModeMatrix = m_specCam.Orientation; + // Set translation as offset from target (if locked) or absolute position + if (ObsCameraState.lockEntity != null) + { + Vector3D targetPos = ObsCameraState.lockEntity.WorldVolume.Center; + freeModeMatrix.Translation = m_specCam.Position - targetPos; + } + else + { + freeModeMatrix.Translation = m_specCam.Position; // Absolute position if no target + } + freeModeInitialized = true; + } + } + + private void InitializeFollowFromFree() { - if (m_playerCamera != null && ObsCameraState.lockEntity != null) + if (m_specCam != null && ObsCameraState.lockEntity != null) { - // Capture the current camera orientation (without translation) - MatrixD currentOrientation = m_specCam.Orientation; - currentOrientation.Translation = Vector3D.Zero; - // Calculate the offset from the target's center - Vector3D offset = m_specCam.Position - ObsCameraState.lockEntity.WorldVolume.Center; - // Set the free mode state to start from the current camera state - ObsCameraState.localMatrix = currentOrientation; - ObsCameraState.localMatrix.Translation = offset; + // Convert freeModeMatrix (world relative to target) to localMatrix (relative to entity's world matrix) + Vector3D worldPosition = ObsCameraState.lockEntity.WorldVolume.Center + freeModeMatrix.Translation; + MatrixD worldMatrix = freeModeMatrix; + worldMatrix.Translation = worldPosition; + ObsCameraState.localMatrix = WorldToLocalNI(worldMatrix, ObsCameraState.lockEntity.WorldMatrixNormalizedInv); + // Reset free mode state + freeModeInitialized = false; } } From 27c1a9defe8382db6925c9803762426d98e6c230 Mon Sep 17 00:00:00 2001 From: InvalidArgument3 Date: Sun, 2 Mar 2025 05:33:15 -0600 Subject: [PATCH 3/5] Update CastSpectator.cs --- .../Scripts/CastSpectator/CastSpectator.cs | 104 ++++++++++++------ 1 file changed, 68 insertions(+), 36 deletions(-) diff --git a/Utility Mods/Cast Spectator - StarCore/Data/Scripts/CastSpectator/CastSpectator.cs b/Utility Mods/Cast Spectator - StarCore/Data/Scripts/CastSpectator/CastSpectator.cs index c179167fb..ee55a16f3 100644 --- a/Utility Mods/Cast Spectator - StarCore/Data/Scripts/CastSpectator/CastSpectator.cs +++ b/Utility Mods/Cast Spectator - StarCore/Data/Scripts/CastSpectator/CastSpectator.cs @@ -224,9 +224,11 @@ public override void UpdateAfterSimulation() { Clear(); } - + // Keep current position, just look at target + Vector3D targetPos = tempHIt.HitEntity.WorldVolume.Center; + m_specCam.SetTarget(targetPos, m_specCam.Orientation.Up); // Use current Up vector SetTarget(tempHIt.HitEntity); - SetMode(1); + ObsCameraState.lockmode = CameraMode.Follow; // Default to Follow } } } @@ -696,7 +698,7 @@ public override void UpdateAfterSimulation() if (m_FindAndMoveState == FindAndMoveState.GoToMove) { - Clear(); + // Don’t Clear() immediately to preserve mode state until animation ends origStart = m_specCam.Position; origFor = m_specCam.Orientation.Forward; origUp = m_specCam.Orientation.Up; @@ -714,7 +716,6 @@ public override void UpdateAfterSimulation() if (m_FindAndMoveState == FindAndMoveState.InMove) { bool complete = false; - if (moveGrid == null || moveGrid.Physics == null || MyAPIGateway.Session.IsCameraControlledObject) { m_FindAndMoveState = FindAndMoveState.GoToIdle; @@ -724,9 +725,7 @@ public override void UpdateAfterSimulation() Vector3D currentStartPosition = m_specCam.Position; Vector3D focusCentralPosition = moveGrid.WorldAABB.Center; Vector3D direction = Vector3D.Normalize(focusCentralPosition - currentStartPosition); - double pullbackDist = moveGrid.PositionComp.WorldVolume.Radius; - pullbackDist *= 1.5; - + double pullbackDist = moveGrid.PositionComp.WorldVolume.Radius * 1.5; double travelDist = (focusCentralPosition - currentStartPosition).Length() - pullbackDist; Vector3D endPosition = currentStartPosition + (direction * travelDist); @@ -740,6 +739,7 @@ public override void UpdateAfterSimulation() var realRatio = (double)viewAnimFrame / maxViewAnimFrame; var easingRatio = OutQuint((float)realRatio); m_specCam.Position = Vector3D.Lerp(origStart, endPosition, easingRatio); + m_specCam.SetTarget(focusCentralPosition, m_specCam.Orientation.Up); viewAnimFrame += 1; } else @@ -749,11 +749,39 @@ public override void UpdateAfterSimulation() if (complete) { + // Set final animation position and orientation + m_specCam.Position = endPosition; + Vector3D targetPos = moveGrid.WorldVolume.Center; + m_specCam.SetTarget(targetPos, m_specCam.Orientation.Up); + + // Lock onto the grid + if (ObsCameraState.lockEntity != null) + { + Clear(); // Clear previous lock + } SetTarget(moveGrid); + ObsCameraState.islocked = true; + + // Update mode-specific state to match final position/orientation + switch (ObsCameraState.lockmode) + { + case CameraMode.Free: + freeModeMatrix = m_specCam.Orientation; + freeModeMatrix.Translation = m_specCam.Position - moveGrid.WorldVolume.Center; + freeModeInitialized = true; + break; + case CameraMode.Follow: + case CameraMode.Orbit: + case CameraMode.Track: + MatrixD worldMatrix = m_specCam.Orientation; + worldMatrix.Translation = m_specCam.Position; + ObsCameraState.localMatrix = WorldToLocalNI(worldMatrix, moveGrid.WorldMatrixNormalizedInv); + break; + } + m_FindAndMoveState = FindAndMoveState.GoToIdle; } } - if (m_FindAndMoveState == FindAndMoveState.InMoveLookback) { bool complete = false; @@ -809,10 +837,9 @@ public override void UpdateAfterSimulation() if (m_FindAndMoveState == FindAndMoveState.GoToIdle) { - moveGrid = null; + moveGrid = null; // Clear animation state viewAnimFrame = 0; rotationAnimFrame = 0; - origStart = Vector3D.Zero; origFor = Vector3D.Zero; origUp = Vector3D.Zero; @@ -851,9 +878,10 @@ private void UpdateLockEntity(IMyEntity lockEntity) ObsCameraState.lockEntity = lockEntity; ObsCameraState.islocked = true; + // Only set a default mode if none exists if (ObsCameraState.lockmode == CameraMode.None) { - SetMode(1); + ObsCameraState.lockmode = CameraMode.Follow; // Default to Follow only if no mode is set } if (ObsCameraState.lockmode == CameraMode.Track) @@ -863,6 +891,7 @@ private void UpdateLockEntity(IMyEntity lockEntity) if (ObsCameraState.lockEntity != null && m_specCam != null) { + // Use current spectator camera state var reconstruct = m_specCam.Orientation; reconstruct.Translation = m_specCam.Position; ObsCameraState.localMatrix = WorldToLocalNI(reconstruct, ObsCameraState.lockEntity.WorldMatrixNormalizedInv); @@ -961,31 +990,34 @@ private void onRegistered() private void UpdateMenu() { - LockTargetInput.Text = "Lock Target - " + m_Pref.ToggleLock.ToString(); - NextModeInput.Text = "Next Mode - " + m_Pref.SwitchMode.ToString(); - FindAndMoveInput.Text = "Find and Move - " + m_Pref.FindAndMove.ToString(); - FindAndMoveSpinInput.Text = "Find and Move Spin - " + m_Pref.FindAndMoveSpin.ToString(); - ModeFreeInput.Text = "Mode Free - " + m_Pref.FreeMode.ToString(); - ModeFollowInput.Text = "Mode Follow - " + m_Pref.FollowMode.ToString(); - ModeOrbitInput.Text = "Mode Orbit - " + m_Pref.OrbitMode.ToString(); - ModeTrackInput.Text = "Mode Track - " + m_Pref.TrackMode.ToString(); - - CameraSmoothKeybind.Text = "Toggle Smooth Camera - " + m_Pref.ToggleSmoothCamera.ToString(); - CameraSmoothOnOff.Text = m_SmoothCamera ? "Smooth Camera On" : "Smooth Camera Off"; - CameraSmoothRate.Text = string.Format("Camera Smooth Rate {0:N0}", SmoothSenseToValue(m_Pref.SmoothCameraLERP).ToString()); - - CameraSmoothRate.InitialPercent = m_Pref.SmoothCameraLERP; - - // Remove updates for Cycle Player Up and Cycle Player Down - // CyclePlayerUp.Text = "Cycle Player Up - " + m_Pref.CyclePlayerUp.ToString(); - // CyclePlayerDown.Text = "Cycle Player Down - " + m_Pref.CyclePlayerDown.ToString(); - - PeriodicSwitchInput.Text = "Periodic Switch - " + m_Pref.PeriodicSwitch.ToString(); - PeriodicSwitchIntervalSlider.Text = "Switch Interval: " + m_PeriodicSwitchInterval + "s"; - PeriodicSwitchIntervalSlider.InitialPercent = m_PeriodicSwitchInterval / 30f; - PeriodicSwitchRandomToggle.Text = m_PeriodicSwitchRandom ? "Random Switch: On" : "Random Switch: Off"; - - HideHudOnOff.Text = m_Pref.HideHud ? "Hud Hidden" : "HUD Always Visible"; + if (TextHUD == null || !m_init) return; // Skip if HUD isn’t initialized + + if (LockTargetInput != null) LockTargetInput.Text = "Lock Target - " + m_Pref.ToggleLock.ToString(); + if (NextModeInput != null) NextModeInput.Text = "Next Mode - " + m_Pref.SwitchMode.ToString(); + if (FindAndMoveInput != null) FindAndMoveInput.Text = "Find and Move - " + m_Pref.FindAndMove.ToString(); + if (FindAndMoveSpinInput != null) FindAndMoveSpinInput.Text = "Find and Move Spin - " + m_Pref.FindAndMoveSpin.ToString(); + if (ModeFreeInput != null) ModeFreeInput.Text = "Mode Free - " + m_Pref.FreeMode.ToString(); + if (ModeFollowInput != null) ModeFollowInput.Text = "Mode Follow - " + m_Pref.FollowMode.ToString(); + if (ModeOrbitInput != null) ModeOrbitInput.Text = "Mode Orbit - " + m_Pref.OrbitMode.ToString(); + if (ModeTrackInput != null) ModeTrackInput.Text = "Mode Track - " + m_Pref.TrackMode.ToString(); + + if (CameraSmoothKeybind != null) CameraSmoothKeybind.Text = "Toggle Smooth Camera - " + m_Pref.ToggleSmoothCamera.ToString(); + if (CameraSmoothOnOff != null) CameraSmoothOnOff.Text = m_SmoothCamera ? "Smooth Camera On" : "Smooth Camera Off"; + if (CameraSmoothRate != null) + { + CameraSmoothRate.Text = string.Format("Camera Smooth Rate {0:N0}", SmoothSenseToValue(m_Pref.SmoothCameraLERP)); + CameraSmoothRate.InitialPercent = m_Pref.SmoothCameraLERP; + } + + if (PeriodicSwitchInput != null) PeriodicSwitchInput.Text = "Periodic Switch - " + m_Pref.PeriodicSwitch.ToString(); + if (PeriodicSwitchIntervalSlider != null) + { + PeriodicSwitchIntervalSlider.Text = "Switch Interval: " + m_PeriodicSwitchInterval + "s"; + PeriodicSwitchIntervalSlider.InitialPercent = m_PeriodicSwitchInterval / 30f; + } + if (PeriodicSwitchRandomToggle != null) PeriodicSwitchRandomToggle.Text = m_PeriodicSwitchRandom ? "Random Switch: On" : "Random Switch: Off"; + + if (HideHudOnOff != null) HideHudOnOff.Text = m_Pref.HideHud ? "Hud Hidden" : "HUD Always Visible"; } private void ToggleHideHud() From d358daf74780bf63ce7b06de6d881b9eca85351f Mon Sep 17 00:00:00 2001 From: InvalidArgument3 Date: Sun, 2 Mar 2025 05:36:29 -0600 Subject: [PATCH 4/5] Update CastSpectator.cs --- .../Scripts/CastSpectator/CastSpectator.cs | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/Utility Mods/Cast Spectator - StarCore/Data/Scripts/CastSpectator/CastSpectator.cs b/Utility Mods/Cast Spectator - StarCore/Data/Scripts/CastSpectator/CastSpectator.cs index ee55a16f3..dc035dd28 100644 --- a/Utility Mods/Cast Spectator - StarCore/Data/Scripts/CastSpectator/CastSpectator.cs +++ b/Utility Mods/Cast Spectator - StarCore/Data/Scripts/CastSpectator/CastSpectator.cs @@ -800,7 +800,7 @@ public override void UpdateAfterSimulation() var moveRatio = (double)viewAnimFrame / maxViewAnimFrame; var moveEaseRatio = OutQuint((float)moveRatio); - var rotateRatio = (double)rotationAnimFrame/ maxRotationAnimFrame; + var rotateRatio = (double)rotationAnimFrame / maxRotationAnimFrame; var rotateEaseRatio = OutQuint((float)rotateRatio); if (viewAnimFrame < maxViewAnimFrame + 1) @@ -830,11 +830,41 @@ public override void UpdateAfterSimulation() if (complete) { + // Set final position and orientation + m_specCam.Position = endPosition; + var lerpedRotation = Math.PI; // Final rotation value + MatrixD rotMat = MatrixD.CreateFromAxisAngle(origUp, lerpedRotation); + var finalFor = Vector3D.Rotate(origFor, rotMat); + m_specCam.SetTarget(m_specCam.Position + finalFor, m_specCam.Orientation.Up); + + // Lock onto the grid, preserving current mode + if (ObsCameraState.lockEntity != null) + { + Clear(); // Clear previous lock + } SetTarget(moveGrid); + ObsCameraState.islocked = true; + + // Update mode-specific state to match final position/orientation + switch (ObsCameraState.lockmode) + { + case CameraMode.Free: + freeModeMatrix = m_specCam.Orientation; + freeModeMatrix.Translation = m_specCam.Position - moveGrid.WorldVolume.Center; + freeModeInitialized = true; + break; + case CameraMode.Follow: + case CameraMode.Orbit: + case CameraMode.Track: + MatrixD worldMatrix = m_specCam.Orientation; + worldMatrix.Translation = m_specCam.Position; + ObsCameraState.localMatrix = WorldToLocalNI(worldMatrix, moveGrid.WorldMatrixNormalizedInv); + break; + } + m_FindAndMoveState = FindAndMoveState.GoToIdle; } } - if (m_FindAndMoveState == FindAndMoveState.GoToIdle) { moveGrid = null; // Clear animation state From b69a1bd17542ef5fa54d64157347c5011cb2778f Mon Sep 17 00:00:00 2001 From: InvalidArgument3 Date: Sun, 2 Mar 2025 05:40:39 -0600 Subject: [PATCH 5/5] no lock when moveto --- .../Scripts/CastSpectator/CastSpectator.cs | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/Utility Mods/Cast Spectator - StarCore/Data/Scripts/CastSpectator/CastSpectator.cs b/Utility Mods/Cast Spectator - StarCore/Data/Scripts/CastSpectator/CastSpectator.cs index dc035dd28..ddccc3169 100644 --- a/Utility Mods/Cast Spectator - StarCore/Data/Scripts/CastSpectator/CastSpectator.cs +++ b/Utility Mods/Cast Spectator - StarCore/Data/Scripts/CastSpectator/CastSpectator.cs @@ -739,7 +739,7 @@ public override void UpdateAfterSimulation() var realRatio = (double)viewAnimFrame / maxViewAnimFrame; var easingRatio = OutQuint((float)realRatio); m_specCam.Position = Vector3D.Lerp(origStart, endPosition, easingRatio); - m_specCam.SetTarget(focusCentralPosition, m_specCam.Orientation.Up); + // Remove SetTarget during animation to preserve orientation viewAnimFrame += 1; } else @@ -749,12 +749,10 @@ public override void UpdateAfterSimulation() if (complete) { - // Set final animation position and orientation + // Set final animation position, keep existing orientation m_specCam.Position = endPosition; - Vector3D targetPos = moveGrid.WorldVolume.Center; - m_specCam.SetTarget(targetPos, m_specCam.Orientation.Up); - // Lock onto the grid + // Lock onto the grid, preserving current mode and orientation if (ObsCameraState.lockEntity != null) { Clear(); // Clear previous lock @@ -762,18 +760,18 @@ public override void UpdateAfterSimulation() SetTarget(moveGrid); ObsCameraState.islocked = true; - // Update mode-specific state to match final position/orientation + // Update mode-specific state with current orientation switch (ObsCameraState.lockmode) { case CameraMode.Free: - freeModeMatrix = m_specCam.Orientation; + freeModeMatrix = m_specCam.Orientation; // Use current orientation freeModeMatrix.Translation = m_specCam.Position - moveGrid.WorldVolume.Center; freeModeInitialized = true; break; case CameraMode.Follow: case CameraMode.Orbit: case CameraMode.Track: - MatrixD worldMatrix = m_specCam.Orientation; + MatrixD worldMatrix = m_specCam.Orientation; // Preserve current orientation worldMatrix.Translation = m_specCam.Position; ObsCameraState.localMatrix = WorldToLocalNI(worldMatrix, moveGrid.WorldMatrixNormalizedInv); break; @@ -813,7 +811,7 @@ public override void UpdateAfterSimulation() var lerpedRotation = MathHelper.Lerp(0, Math.PI, rotateEaseRatio); MatrixD rotMat = MatrixD.CreateFromAxisAngle(origUp, lerpedRotation); var finalFor = Vector3D.Rotate(origFor, rotMat); - m_specCam.SetTarget(m_specCam.Position + finalFor, m_specCam.Orientation.Up); + m_specCam.SetTarget(m_specCam.Position + finalFor, m_specCam.Orientation.Up); // Keep spin animation } if (moveRatio > 0.1) @@ -830,14 +828,10 @@ public override void UpdateAfterSimulation() if (complete) { - // Set final position and orientation + // Set final position, preserve orientation with spin applied m_specCam.Position = endPosition; - var lerpedRotation = Math.PI; // Final rotation value - MatrixD rotMat = MatrixD.CreateFromAxisAngle(origUp, lerpedRotation); - var finalFor = Vector3D.Rotate(origFor, rotMat); - m_specCam.SetTarget(m_specCam.Position + finalFor, m_specCam.Orientation.Up); - // Lock onto the grid, preserving current mode + // Lock onto the grid, preserving current mode and orientation if (ObsCameraState.lockEntity != null) { Clear(); // Clear previous lock @@ -845,18 +839,18 @@ public override void UpdateAfterSimulation() SetTarget(moveGrid); ObsCameraState.islocked = true; - // Update mode-specific state to match final position/orientation + // Update mode-specific state with current orientation switch (ObsCameraState.lockmode) { case CameraMode.Free: - freeModeMatrix = m_specCam.Orientation; + freeModeMatrix = m_specCam.Orientation; // Use current orientation (post-spin) freeModeMatrix.Translation = m_specCam.Position - moveGrid.WorldVolume.Center; freeModeInitialized = true; break; case CameraMode.Follow: case CameraMode.Orbit: case CameraMode.Track: - MatrixD worldMatrix = m_specCam.Orientation; + MatrixD worldMatrix = m_specCam.Orientation; // Preserve current orientation (post-spin) worldMatrix.Translation = m_specCam.Position; ObsCameraState.localMatrix = WorldToLocalNI(worldMatrix, moveGrid.WorldMatrixNormalizedInv); break;