From 3fc19518b2881cff6a6c1b9dd29b04ea15eebaec Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Mon, 10 Aug 2026 21:22:31 -0400 Subject: Add lerp to orbital camera Signed-off-by: Andrew Opalach --- Plugin.cs | 55 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/Plugin.cs b/Plugin.cs index 6fd0d83..88ec14a 100755 --- a/Plugin.cs +++ b/Plugin.cs @@ -241,6 +241,7 @@ namespace NewCamera private float orbitDistance = 350.0f; private float orbitY = 150.0f; private float orbitRight = 0.0f; + private float orbitLerp = 0.25f; private int orbitJoint = -1; private bool enableOffsetPerspective = false; @@ -1749,7 +1750,7 @@ namespace NewCamera cameraYaw += 360.0f; } float pitchLimit = cameraPitchLimit; - if (orbitJoint >= 0 && pitchLimit == -1.0f) + if (orbitPlayer && pitchLimit == -1.0f) { pitchLimit = Config.Settings.MAX_PITCH_LIMIT; } @@ -1794,11 +1795,12 @@ namespace NewCamera if (orbitPlayer && player != null) { Quaternion rotation; + Vector3 target; bool targetJoint = orbitJoint >= 0 && orbitJoint < bodyJoints.Count; if (targetJoint) { nint jointAddr = bodyJoints[orbitJoint]; - cameraTarget = MemoryUtil.GetRef(jointAddr + 0x50); + target = MemoryUtil.GetRef(jointAddr + 0x50); rotation = new Quaternion(player.Rotation.X, player.Rotation.Y, player.Rotation.Z, player.Rotation.W); rotation *= MemoryUtil.GetRef(jointAddr + 0x70); rotation *= Quaternion.CreateFromYawPitchRoll( @@ -1808,26 +1810,37 @@ namespace NewCamera } else { - cameraTarget = player.Position; + target = player.Position; rotation = new Quaternion(player.Rotation.X, player.Rotation.Y, player.Rotation.Z, player.Rotation.W); } Vector3 up = Vector3.Transform(new Vector3(0.0f, 1.0f, 0.0f), rotation); Vector3 right = Vector3.Transform(new Vector3(1.0f, 0.0f, 0.0f), rotation); orbitY += cameraFrame.Y; - cameraTarget += orbitY * up; - cameraTarget.X += orbitRight * right.X; - cameraTarget.Z += orbitRight * right.Z; + target += orbitY * up; + target.X += orbitRight * right.X; + target.Z += orbitRight * right.Z; + Vector3 position; float dist = orbitDistance; if (targetJoint) { Vector3 forward = Vector3.Transform(new Vector3(0.0f, 0.0f, 1.0f), rotation); - cameraPosition = cameraTarget - forward * dist; + position = target - forward * dist; } else { - cameraPosition.X = cameraTarget.X - dist * MathF.Cos(Single.DegreesToRadians(cameraPitch)) * MathF.Cos(Single.DegreesToRadians(cameraYaw)); - cameraPosition.Y = cameraTarget.Y - dist * MathF.Sin(Single.DegreesToRadians(cameraPitch)); - cameraPosition.Z = cameraTarget.Z - dist * MathF.Cos(Single.DegreesToRadians(cameraPitch)) * MathF.Sin(Single.DegreesToRadians(cameraYaw)); + position.X = target.X - dist * MathF.Cos(Single.DegreesToRadians(cameraPitch)) * MathF.Cos(Single.DegreesToRadians(cameraYaw)); + position.Y = target.Y - dist * MathF.Sin(Single.DegreesToRadians(cameraPitch)); + position.Z = target.Z - dist * MathF.Cos(Single.DegreesToRadians(cameraPitch)) * MathF.Sin(Single.DegreesToRadians(cameraYaw)); + } + if (orbitLerp != 1.0f) + { + cameraTarget = Vector3.Lerp(cameraTarget, target, orbitLerp); + cameraPosition = Vector3.Lerp(cameraPosition, position, orbitLerp); + } + else + { + cameraTarget = target; + cameraPosition = position; } } else @@ -3418,9 +3431,9 @@ namespace NewCamera { nint armorAddr = next; next = MemoryUtil.Read(armorAddr + 0x30); - nint vtable = MemoryUtil.Read(armorAddr); + nint vTable = MemoryUtil.Read(armorAddr); // uWeaponParts: 0x1434D2400, uWeaponEmblem: 0x1434D1D58 - if (vtable == 0x1434A7560) // uPlCombineArmor + if (vTable == 0x1434A7560) // uPlCombineArmor { nint partsAddr = 0x0; nint childAddr = MemoryUtil.Read(armorAddr + 0x548); @@ -5504,6 +5517,12 @@ namespace NewCamera ImGui.Separator(); + ImGui.Checkbox("Only Toggle LOD 0", ref modelOnlyAddressLod0); + if (ImGui.BeginItemTooltip()) + { + ImGui.Text($"This can be used to check if a given model is showing LOD 0 or not.\nApplies when a part is toggled, meaning you should probably toggle all parts on before enabling this."); + ImGui.EndTooltip(); + } if (ImGui.CollapsingHeader("Loaded Models") && player != null) { ImGui.Text("Filter"); @@ -5570,8 +5589,8 @@ namespace NewCamera { ImGui.PushID(next); nint partsAddr = next + 0x40; - nint vtable = MemoryUtil.Read(partsAddr); - if (vtable == 0x143507A18) + nint vTable = MemoryUtil.Read(partsAddr); + if (vTable == 0x143507A18) { string fullString = Marshal.PtrToStringAnsi(partsAddr + 0xC)!; bool filterMatch = false; @@ -5605,12 +5624,6 @@ namespace NewCamera } } } - ImGui.Checkbox("Only Toggle LOD 0", ref modelOnlyAddressLod0); - if (ImGui.BeginItemTooltip()) - { - ImGui.Text($"This can be used to check if a given model is showing LOD 0 or not.\nApplies when a part is toggled, meaning you should probably toggle all parts on before enabling this."); - ImGui.EndTooltip(); - } ImGui.Separator(); @@ -5675,6 +5688,8 @@ namespace NewCamera ImGui.DragFloat("Target Y", ref orbitY, 1.0f); ImGui.SameLine(); ImGui.DragFloat("Target Right", ref orbitRight, 1.0f); + ImGui.DragFloat("Lerp", ref orbitLerp, 0.01f, 0.0f, 1.0f); + ImGui.Checkbox("Ignore Camera Direction", ref orbitIgnoreCamera); ImGui.DragFloat("Movement Rotation", ref orbitMovementRotation, 1.0f); ImGui.InputInt("Target Joint", ref orbitJoint); ImGui.PopItemWidth(); -- cgit v1.2.3-101-g0448