Skip to content

Commit

Permalink
Allow limiting position and range of FP Cameras / HMD position (Closes
Browse files Browse the repository at this point in the history
  • Loading branch information
kinsi55 committed Aug 19, 2022
1 parent 6d76136 commit 5ba4142
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 10 deletions.
58 changes: 58 additions & 0 deletions Configuration/CameraBoundsConfig.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace Camera2.Configuration {
[JsonObject(MemberSerialization.OptIn)]
class CameraBoundsConfig {
static IFormatProvider h = new CultureInfo("en-US").NumberFormat;

static void ParseInto(ref float min, ref float max, string val) {
min = float.NegativeInfinity;
max = float.PositiveInfinity;

if(val == null || val.Length == 0)
return;

var spl = val.Split(':');

if(!float.TryParse(spl[0], NumberStyles.Float, h, out min))
max = float.PositiveInfinity;

if(spl.Length == 1 || !float.TryParse(spl[1], NumberStyles.Float, h, out max))
max = float.PositiveInfinity;
}

static string GetInvariant(float val) => val.ToString(h);

[JsonProperty] public string pos_x { get => $"{GetInvariant(pos_x_min)}:{GetInvariant(pos_x_max)}"; set => ParseInto(ref pos_x_min, ref pos_x_max, value); }
[JsonProperty] public string pos_y { get => $"{GetInvariant(pos_y_min)}:{GetInvariant(pos_y_max)}"; set => ParseInto(ref pos_y_min, ref pos_y_max, value); }
[JsonProperty] public string pos_z { get => $"{GetInvariant(pos_z_min)}:{GetInvariant(pos_z_max)}"; set => ParseInto(ref pos_z_min, ref pos_z_max, value); }
[JsonProperty] public string rot_x { get => $"{GetInvariant(rot_x_min)}:{GetInvariant(rot_x_max)}"; set => ParseInto(ref rot_x_min, ref rot_x_max, value); }
[JsonProperty] public string rot_y { get => $"{GetInvariant(rot_y_min)}:{GetInvariant(rot_y_max)}"; set => ParseInto(ref rot_y_min, ref rot_y_max, value); }
[JsonProperty] public string rot_z { get => $"{GetInvariant(rot_z_min)}:{GetInvariant(rot_z_max)}"; set => ParseInto(ref rot_z_min, ref rot_z_max, value); }

public float rot_x_min = float.NegativeInfinity;
public float rot_x_max = float.PositiveInfinity;

public float rot_y_min = float.NegativeInfinity;
public float rot_y_max = float.PositiveInfinity;

public float rot_z_min = float.NegativeInfinity;
public float rot_z_max = float.PositiveInfinity;


public float pos_x_min = float.NegativeInfinity;
public float pos_x_max = float.PositiveInfinity;

public float pos_y_min = float.NegativeInfinity;
public float pos_y_max = float.PositiveInfinity;

public float pos_z_min = float.NegativeInfinity;
public float pos_z_max = float.PositiveInfinity;
}
}
34 changes: 30 additions & 4 deletions Middlewares/Smoothfollow.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Camera2.HarmonyPatches;
using System;
using Camera2.HarmonyPatches;
using Camera2.Interfaces;
using Camera2.Utils;
using Newtonsoft.Json;
Expand All @@ -10,7 +11,6 @@ class Settings_Smoothfollow : CameraSubSettings {
public float position = 10f;
public float rotation = 4f;

public bool forceUpright = false;
public bool followReplayPosition = true;

private bool _pivotingOffset = true;
Expand All @@ -27,6 +27,12 @@ public bool pivotingOffset {
}
}

public CameraBoundsConfig limits = new CameraBoundsConfig();

// TODO: Yeet this at some point
bool forceUpright { get => false; set => limits.rot_z_min = limits.rot_z_min = 0; }
public bool ShouldSerializeforceUpright() => false;

[JsonIgnore] internal bool useLocalPosition = true;
[JsonIgnore] internal Transform parent;

Expand Down Expand Up @@ -57,6 +63,15 @@ public void OnEnable() {
teleportOnNextFrame = true;
}

float ClampAngle(float angle, float from, float to) {
// accepts e.g. -80, 80
if(angle < 0f)
angle = 360 + angle;
if(angle > 180f)
return Math.Max(angle, 360 + from);
return Math.Min(angle, to);
}

new public bool Pre() {
if(settings.type == Configuration.CameraType.Positionable) {
if(settings.Smoothfollow.transformer != null) {
Expand Down Expand Up @@ -138,8 +153,19 @@ public void OnEnable() {
}
}

if(settings.Smoothfollow.forceUpright)
targetRotation *= Quaternion.Euler(0, 0, -parentToUse.transform.localEulerAngles.z);
targetPosition.x = Mathf.Clamp(targetPosition.x, settings.Smoothfollow.limits.pos_x_min, settings.Smoothfollow.limits.pos_x_max);
targetPosition.y = Mathf.Clamp(targetPosition.y, settings.Smoothfollow.limits.pos_y_min, settings.Smoothfollow.limits.pos_y_max);
targetPosition.z = Mathf.Clamp(targetPosition.z, settings.Smoothfollow.limits.pos_z_min, settings.Smoothfollow.limits.pos_z_max);

var E = targetRotation.eulerAngles;
var l = settings.Smoothfollow.limits;

E.x = ClampAngle(E.x, l.rot_x_min, l.rot_x_max);
E.y = ClampAngle(E.y, l.rot_y_min, l.rot_y_max);
E.z = ClampAngle(E.z, l.rot_z_min, l.rot_z_max);

targetRotation.eulerAngles = E;


if(!teleportOnNextFrame) {
teleportOnNextFrame =
Expand Down
15 changes: 10 additions & 5 deletions UI/SpaghettiUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,15 @@ internal bool multiplayer_followSpectatorPlattform {
}

internal bool smoothFollow_forceUpright {
get => cam.settings.Smoothfollow.forceUpright; set { cam.settings.Smoothfollow.forceUpright = value; }
get => cam.settings.Smoothfollow.limits.rot_z == "0:0";
set {
if(value) {
cam.settings.Smoothfollow.limits.rot_z = "0:0";
} else {
cam.settings.Smoothfollow.limits.rot_z_min = float.NegativeInfinity;
cam.settings.Smoothfollow.limits.rot_z_max = float.PositiveInfinity;
}
}
}
internal bool smoothFollow_followReplayPosition {
get => cam.settings.Smoothfollow.followReplayPosition; set { cam.settings.Smoothfollow.followReplayPosition = value; }
Expand Down Expand Up @@ -237,9 +245,6 @@ internal float postprocessing_transparencyThreshold {
internal bool postprocessing_forceDepthTexture {
get => cam.settings.PostProcessing.forceDepthTexture; set { cam.settings.PostProcessing.forceDepthTexture = value; }
}
internal float postprocessing_motionBlur {
get => cam.settings.PostProcessing.motionBlurBlend; set { cam.settings.PostProcessing.motionBlurBlend = value; }
}


internal float viewRect_x {
Expand Down Expand Up @@ -528,7 +533,7 @@ void AddCamAvatarFaceCam() {
cam.settings.targetRot = new UnityEngine.Vector3(0, 180f, 0);

cam.settings.Smoothfollow.followReplayPosition = false;
cam.settings.Smoothfollow.forceUpright = true;
cam.settings.Smoothfollow.limits.rot_z = "0:0";
cam.settings.Smoothfollow.position = 8f;
cam.settings.Smoothfollow.rotation = 3f;

Expand Down
1 change: 0 additions & 1 deletion UI/Views/camSettings.bsml
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@
hover-hint='Forces a Depthtexture to be rendered for this Camera, even if your Graphic settings dont need it (Only Smoke needs it). Used by Transparency to better decide what should be transparent'
/>
<slider-setting text='Transparency Threshold *' min='0' max='79.5' increment='0.5' value='postprocessing_transparencyThreshold' bind-value='true' apply-on-change='true'/>
<!--<slider-setting text='Motion Blur' min='0' max='0.4' increment='0.05' value='postprocessing_motionBlur' bind-value='true' apply-on-change='true'/>-->
</modifier-container>
<text text="* Higher = More Transparent, 0 = Off" color="#CCC" font-size="3" align="Center"/>
</vertical>
Expand Down

0 comments on commit 5ba4142

Please sign in to comment.