private void DoUpdate(CameraUpdate update) { { bool wasEnabled = this.IsEnabled; bool isEnabled = this.CalculateEnabled(update); if (wasEnabled != isEnabled) { if (!isEnabled) { this.Stack.DisableAll(update); } this.IsEnabled = isEnabled; if (isEnabled) { this.OnEnabled(update); } else { this.OnDisabled(update); } } } if (this.IsEnabled) { this.OnUpdating(0); } if (this.IsEnabled) { if (this.Stabilize == null || this.Stabilize.ShouldRecreate(update.Target)) { this.Stabilize = new CameraStabilize(this, update.Target); } if (this.Stabilize != null) { this.Stabilize.Update(update.Target.StabilizeRootNode, update.Target.HeadNode, update); } } this.Stack.Check(update); this.Stack.Update(update); update.Values.Update(this.Plugin.Time, this.IsEnabled); this.Hide.Update(update); { bool isFpArms = this.IsEnabled && update.Values.Show1stPersonArms.CurrentValue >= 0.5; if (isFpArms != this.WasUsingFirstPersonArms) { this.WasUsingFirstPersonArms = isFpArms; } } if (this.IsEnabled) { double mode = update.Values.SkeletonMode.CurrentValue; bool wantThird = true; if (mode <= -0.5) { wantThird = !this.WasUsingFirstPersonArms; } else if (mode >= 0.5) { wantThird = false; } //else wantThird = true; bool showFirst = this.WasUsingFirstPersonArms; bool showThird = true; if (this.DidCollideLastUpdate && Settings.Instance.HidePlayerWhenColliding == 2) { showThird = false; } this.UpdateSkeleton(showFirst, showThird, wantThird); } if (this.IsEnabled) { if (this.Stabilize == null || !this.Stabilize.Get(update.Target.StabilizeRootNode, this.BaseRoot.Transform)) { this.BaseRoot.Transform.CopyFrom(update.Target.HeadNode.WorldTransform); } this.BaseHead.Transform.CopyFrom(update.Target.HeadNode.WorldTransform); CameraResult cur = null; // Calculate base position. { double posRatio = update.Values.PositionFromHead.CurrentValue; if (posRatio == 0.0) { this.BaseResult.Transform.Position.CopyFrom(this.BaseRoot.Transform.Position); } else if (posRatio == 1.0) { this.BaseResult.Transform.Position.CopyFrom(this.BaseHead.Transform.Position); } else { var pos = this.BaseResult.Transform.Position; var rootPos = this.BaseRoot.Transform.Position; var headPos = this.BaseHead.Transform.Position; pos.X = (float)((headPos.X - rootPos.X) * posRatio + rootPos.X); pos.Y = (float)((headPos.Y - rootPos.Y) * posRatio + rootPos.Y); pos.Z = (float)((headPos.Z - rootPos.Z) * posRatio + rootPos.Z); } } // Calculate base rotation. { double rotRatio = update.Values.RotationFromHead.CurrentValue; if (rotRatio == 0.0) { this.BaseResult.Transform.Rotation.CopyFrom(this.BaseRoot.Transform.Rotation); } else if (rotRatio == 1.0) { this.BaseResult.Transform.Rotation.CopyFrom(this.BaseHead.Transform.Rotation); } else { var rot = this.BaseResult.Transform.Rotation; var rootRot = this.BaseRoot.Transform.Rotation; var headRot = this.BaseHead.Transform.Rotation; rootRot.Interpolate(headRot, (float)rotRatio, rot); } } cur = this.BaseResult; // Calculate offset based on object rotation itself. { var root = update.Target.RootNode; if (root != null) { double x = this.Values.OffsetObjectPositionX.CurrentValue; double y = this.Values.OffsetObjectPositionY.CurrentValue; double z = this.Values.OffsetObjectPositionZ.CurrentValue; if (x != 0.0 || y != 0.0 || z != 0.0) { this.Offset1Result.Transform.Position.CopyFrom(this.BaseResult.Transform.Position); this.Offset1Result.Transform.Rotation.CopyFrom(root.WorldTransform.Rotation); this.ApplyPositionOffset(this.Offset1Result.Transform, (float)x, (float)y, (float)z, this.BaseResult.Transform.Position); } } } // Look down offset. if (States.Default._look_downoffset_ratio > 0.0f || States.Default._look_downoffset_ratio_leftrightmove > 0.0f) { float ratio = States.Default._look_downoffset_ratio; var root = update.Target.RootNode; if (root != null) { float x = Settings.Instance.DownOffsetX * ratio; float y = Settings.Instance.DownOffsetY * ratio; float z = Settings.Instance.DownOffsetZ * ratio; y += Settings.Instance.TryFixLeftRightMovementClipping * States.Default._look_downoffset_ratio_leftrightmove; if (x != 0.0f || y != 0.0f || z != 0.0f) { this.Offset1Result.Transform.Position.CopyFrom(this.BaseResult.Transform.Position); this.Offset1Result.Transform.Rotation.CopyFrom(root.WorldTransform.Rotation); this.ApplyPositionOffset(this.Offset1Result.Transform, x, y, z, this.BaseResult.Transform.Position); } } } // Calculate offset #1. { float rx = (float)this.Values.Offset1RotationX.CurrentValue; float ry = (float)this.Values.Offset1RotationY.CurrentValue; float px = (float)this.Values.Offset1PositionX.CurrentValue; float py = (float)this.Values.Offset1PositionY.CurrentValue; float pz = (float)this.Values.Offset1PositionZ.CurrentValue; bool hasRot = rx != 0.0f || ry != 0.0f; bool hasPos = px != 0.0f || py != 0.0f || pz != 0.0f; if (hasRot || hasPos) { this.Offset1Result.Transform.CopyFrom(cur.Transform); if (hasRot) { this.ApplyRotationOffset(this.Offset1Result.Transform.Rotation, rx, ry, this.Offset1Result.Transform.Rotation); } if (hasPos) { this.ApplyPositionOffset(this.Offset1Result.Transform, px, py, pz, this.Offset1Result.Transform.Position); } cur = this.Offset1Result; } } // Calculate input. { float extraX = 0.0f; float extraY = 0.0f; if (this.LastActorTurnFrames > 0) { this.LastActorTurnFrames--; extraX = this.LastActorTurnX; //extraY = this.LastActorTurnY; } float rx = (float)(this.Values.InputRotationX.CurrentValue + extraX) * (float)this.Values.InputRotationXMultiplier.CurrentValue; float ry = (float)(this.Values.InputRotationY.CurrentValue + extraY) * (float)this.Values.InputRotationYMultiplier.CurrentValue; if (rx != 0.0f || ry != 0.0f) { this.InputResult.Transform.CopyFrom(cur.Transform); this.ApplyRotationOffset(this.InputResult.Transform.Rotation, rx, ry, this.InputResult.Transform.Rotation); cur = this.InputResult; } } // Calculate offset #2. { float rx = (float)this.Values.Offset2RotationX.CurrentValue; float ry = (float)this.Values.Offset2RotationY.CurrentValue; float px = (float)this.Values.Offset2PositionX.CurrentValue; float py = (float)this.Values.Offset2PositionY.CurrentValue; float pz = (float)this.Values.Offset2PositionZ.CurrentValue; bool hasRot = rx != 0.0f || ry != 0.0f; bool hasPos = px != 0.0f || py != 0.0f || pz != 0.0f; if (hasRot || hasPos) { this.Offset2Result.Transform.CopyFrom(cur.Transform); if (hasRot) { this.ApplyRotationOffset(this.Offset2Result.Transform.Rotation, rx, ry, this.Offset2Result.Transform.Rotation); } if (hasPos) { this.ApplyPositionOffset(this.Offset2Result.Transform, px, py, pz, this.Offset2Result.Transform.Position); } cur = this.Offset2Result; } } // Apply tween from stabilize. { if (this.Stabilize != null) { this.Stabilize.ApplyTween(cur.Transform.Position, this.Plugin.Time); } } // Apply collision of camera so we don't go inside walls, this can be done within the same transform. { this.DidCollideLastUpdate = CameraCollision.Apply(update, cur.Transform, cur.Transform.Position); } // Calculate final result. { this.FinalResult.Transform.CopyFrom(cur.Transform); } update.GameCameraNode.LocalTransform.CopyFrom(this.FinalResult.Transform); update.GameCameraNode.Update(0.0f); this.Hide.UpdateFirstPersonSkeletonRotation(update); var third = update.GameCameraState.As <ThirdPersonState>(); if (third != null) { third.Position.CopyFrom(update.GameCameraNode.LocalTransform.Position); } if (this.WasUsingFirstPersonArms) { this.UpdateMagicNodePosition(update); } } else { this.DidCollideLastUpdate = false; } if (this.IsEnabled) { this.OnUpdating(1); } if (!this.IsEnabled && Settings.Instance.ReplaceDefaultCamera && update.GameCameraState.Id == TESCameraStates.FirstPerson && this.IsGameCameraSwitchControlsEnabled()) { update.GameCamera.EnterThirdPerson(); this.SetWantState(WantStates.EnabledFromTogglePOV); } this.FixSensitivityMode = this.IsEnabled && update.GameCameraState.Id == TESCameraStates.ThirdPerson2 && Memory.ReadUInt8(update.GameCameraState.Address + 0xDC) != 0; }
private void DoUpdate(CameraUpdate update) { { var wasEnabled = IsEnabled; var isEnabled = CalculateEnabled(update); if (wasEnabled != isEnabled) { if (!isEnabled) { Stack.DisableAll(update); } IsEnabled = isEnabled; if (isEnabled) { OnEnabled(update); } else { OnDisabled(update); } } } if (IsEnabled) { OnUpdating(0); } if (IsEnabled) { if (Stabilize == null || Stabilize.ShouldRecreate(update.Target)) { Stabilize = new CameraStabilize(this, update.Target); } Stabilize?.Update(update.Target.StabilizeRootNode, update.Target.HeadNode, update); } Stack.Check(update); Stack.Update(update); update.Values.Update(Plugin.Time, IsEnabled); Hide.Update(update); { var isFpArms = IsEnabled && update.Values.Show1stPersonArms.CurrentValue >= 0.5; if (isFpArms != WasUsingFirstPersonArms) { WasUsingFirstPersonArms = isFpArms; } } if (IsEnabled) { var mode = update.Values.SkeletonMode.CurrentValue; var wantThird = true; if (mode <= -0.5) { wantThird = !WasUsingFirstPersonArms; } else if (mode >= 0.5) { wantThird = false; } //else wantThird = true; var showFirst = WasUsingFirstPersonArms; var showThird = !(DidCollideLastUpdate && Settings.Instance.HidePlayerWhenColliding == 2); UpdateSkeleton(showFirst, showThird, wantThird); } if (IsEnabled) { if (Stabilize == null || !Stabilize.Get(update.Target.StabilizeRootNode, BaseRoot.Transform)) { BaseRoot.Transform.CopyFrom(update.Target.HeadNode.WorldTransform); } BaseHead.Transform.CopyFrom(update.Target.HeadNode.WorldTransform); CameraResult cur = null; using (cur) { { var posRatio = update.Values.PositionFromHead.CurrentValue; switch (posRatio) { case 0.0: BaseResult.Transform.Position.CopyFrom(BaseRoot.Transform.Position); break; case 1.0: BaseResult.Transform.Position.CopyFrom(BaseHead.Transform.Position); break; default: { var pos = BaseResult.Transform.Position; var rootPos = BaseRoot.Transform.Position; var headPos = BaseHead.Transform.Position; pos.X = (float)((headPos.X - rootPos.X) * posRatio + rootPos.X); pos.Y = (float)((headPos.Y - rootPos.Y) * posRatio + rootPos.Y); pos.Z = (float)((headPos.Z - rootPos.Z) * posRatio + rootPos.Z); break; } } } // Calculate base rotation. { var rotRatio = update.Values.RotationFromHead.CurrentValue; switch (rotRatio) { case 0.0: BaseResult.Transform.Rotation.CopyFrom(BaseRoot.Transform.Rotation); break; case 1.0: BaseResult.Transform.Rotation.CopyFrom(BaseHead.Transform.Rotation); break; default: { var rot = BaseResult.Transform.Rotation; var rootRot = BaseRoot.Transform.Rotation; var headRot = BaseHead.Transform.Rotation; rootRot.Interpolate(headRot, (float)rotRatio, rot); break; } } } cur = BaseResult; // Calculate offset based on object rotation itself. { var root = update.Target.RootNode; if (root != null) { var x = Values.OffsetObjectPositionX.CurrentValue; var y = Values.OffsetObjectPositionY.CurrentValue; var z = Values.OffsetObjectPositionZ.CurrentValue; if (x != 0.0 || y != 0.0 || z != 0.0) { Offset1Result.Transform.Position.CopyFrom(BaseResult.Transform.Position); Offset1Result.Transform.Rotation.CopyFrom(root.WorldTransform.Rotation); ApplyPositionOffset(Offset1Result.Transform, (float)x, (float)y, (float)z, BaseResult.Transform.Position); } } } // Look down offset. if (Default._look_downoffset_ratio > 0.0f || Default._look_downoffset_ratio_leftrightmove > 0.0f) { var ratio = Default._look_downoffset_ratio; var root = update.Target.RootNode; if (root != null) { var x = Settings.Instance.DownOffsetX * ratio; var y = Settings.Instance.DownOffsetY * ratio; var z = Settings.Instance.DownOffsetZ * ratio; y += Settings.Instance.TryFixLeftRightMovementClipping * Default._look_downoffset_ratio_leftrightmove; if (x != 0.0f || y != 0.0f || z != 0.0f) { Offset1Result.Transform.Position.CopyFrom(BaseResult.Transform.Position); Offset1Result.Transform.Rotation.CopyFrom(root.WorldTransform.Rotation); ApplyPositionOffset(Offset1Result.Transform, x, y, z, BaseResult.Transform.Position); } } } // Calculate offset #1. { var rx = (float)Values.Offset1RotationX.CurrentValue; var ry = (float)Values.Offset1RotationY.CurrentValue; var px = (float)Values.Offset1PositionX.CurrentValue; var py = (float)Values.Offset1PositionY.CurrentValue; var pz = (float)Values.Offset1PositionZ.CurrentValue; var hasRot = rx != 0.0f || ry != 0.0f; var hasPos = px != 0.0f || py != 0.0f || pz != 0.0f; if (hasRot || hasPos) { Offset1Result.Transform.CopyFrom(cur.Transform); if (hasRot) { ApplyRotationOffset(Offset1Result.Transform.Rotation, rx, ry, Offset1Result.Transform.Rotation); } if (hasPos) { ApplyPositionOffset(Offset1Result.Transform, px, py, pz, Offset1Result.Transform.Position); } cur = Offset1Result; } } // Calculate input. { var extraX = 0.0f; var extraY = 0.0f; if (LastActorTurnFrames > 0) { LastActorTurnFrames--; extraX = LastActorTurnX; //extraY = this.LastActorTurnY; } var rx = (float)(Values.InputRotationX.CurrentValue + extraX) * (float)Values.InputRotationXMultiplier.CurrentValue; var ry = (float)(Values.InputRotationY.CurrentValue + extraY) * (float)Values.InputRotationYMultiplier.CurrentValue; if (rx != 0.0f || ry != 0.0f) { InputResult.Transform.CopyFrom(cur.Transform); ApplyRotationOffset(InputResult.Transform.Rotation, rx, ry, InputResult.Transform.Rotation); cur = InputResult; } } // Calculate offset #2. { var rx = (float)Values.Offset2RotationX.CurrentValue; var ry = (float)Values.Offset2RotationY.CurrentValue; var px = (float)Values.Offset2PositionX.CurrentValue; var py = (float)Values.Offset2PositionY.CurrentValue; var pz = (float)Values.Offset2PositionZ.CurrentValue; var hasRot = rx != 0.0f || ry != 0.0f; var hasPos = px != 0.0f || py != 0.0f || pz != 0.0f; if (hasRot || hasPos) { Offset2Result.Transform.CopyFrom(cur.Transform); if (hasRot) { ApplyRotationOffset(Offset2Result.Transform.Rotation, rx, ry, Offset2Result.Transform.Rotation); } if (hasPos) { ApplyPositionOffset(Offset2Result.Transform, px, py, pz, Offset2Result.Transform.Position); } cur = Offset2Result; } } // Apply tween from stabilize. { Stabilize?.ApplyTween(cur.Transform.Position, Plugin.Time); } // Apply collision of camera so we don't go inside walls, this can be done within the same transform. { DidCollideLastUpdate = CameraCollision.Apply(update, cur.Transform, cur.Transform.Position); } // Calculate final result. { FinalResult.Transform.CopyFrom(cur.Transform); } } update.GameCameraNode.LocalTransform.CopyFrom(FinalResult.Transform); update.GameCameraNode.Update(0.0f); Hide.UpdateFirstPersonSkeletonRotation(update); if (update.GameCameraState is ThirdPersonState third) { third.Position.CopyFrom(update.GameCameraNode.LocalTransform.Position); } if (WasUsingFirstPersonArms) { UpdateMagicNodePosition(update); } } else { DidCollideLastUpdate = false; } if (IsEnabled) { OnUpdating(1); } if (!IsEnabled && Settings.Instance.ReplaceDefaultCamera && update.GameCameraState.Id == TESCameraStates.FirstPerson && IsGameCameraSwitchControlsEnabled()) { update.GameCamera.EnterThirdPerson(); SetWantState(WantStates.EnabledFromTogglePOV); } FixSensitivityMode = IsEnabled && update.GameCameraState.Id == TESCameraStates.ThirdPerson2 && Memory.ReadUInt8(update.GameCameraState.Address + 0xDC) != 0; }