A game about forced loneliness, made by TACStudios
1using UnityEditor.AnimatedValues;
2using UnityEngine;
3
4namespace UnityEditor.Rendering.LookDev
5{
6 /// <summary>
7 /// Interface to comunicate with simple <see cref="Renderer"/>
8 /// </summary>
9 public interface ICameraUpdater
10 {
11 /// <summary>Method called To update the LookDev camera position</summary>
12 /// <param name="camera">The camera</param>
13 void UpdateCamera(Camera camera);
14 }
15
16 /// <summary>
17 /// Class containing data regarding position, rotation and viewport size of a camera
18 /// </summary>
19 [System.Serializable]
20 public class CameraState : ICameraUpdater
21 {
22 private static readonly Quaternion k_DefaultRotation = Quaternion.LookRotation(new Vector3(0.0f, 0.0f, 1.0f));
23 private const float k_DefaultViewSize = 10f;
24 private static readonly Vector3 k_DefaultPivot = Vector3.zero;
25 private const float k_DefaultFoV = 90f;
26 private const float k_NearFactor = 0.000005f;
27 private const float k_MaxFar = 1000;
28
29 /// <summary>The position of the camera pivot</summary>
30 [field: SerializeField]
31 public Vector3 pivot { get; set; } = k_DefaultPivot;
32
33 /// <summary>The rotation of the camera arround the pivot</summary>
34 [field: SerializeField]
35 public Quaternion rotation { get; set; } = k_DefaultRotation;
36
37 /// <summary>The size of the view</summary>
38 [field: SerializeField]
39 public float viewSize { get; set; } = k_DefaultViewSize;
40
41 /// <summary>The distance from pivot</summary>
42 public float distanceFromPivot
43 // distance coeficient from vertical FOV should be
44 // 1f / Mathf.Tan(kDefaultFoV * 0.5f * Mathf.Deg2Rad)
45 // but with fixed FoV of 90, this coef is always equal to 1f
46 => viewSize;
47
48 /// <summary>The position of the camera</summary>
49 public Vector3 position
50 => pivot + rotation * new Vector3(0, 0, -distanceFromPivot);
51
52 /// <summary>The field of view of the camera</summary>
53 public float fieldOfView => k_DefaultFoV;
54
55 /// <summary>The far clip distance from camera</summary>
56 public float farClip => Mathf.Max(k_MaxFar, 2 * k_MaxFar * viewSize);
57
58 /// <summary>The near clip distance from camera</summary>
59 public float nearClip => farClip * k_NearFactor;
60
61 /// <summary>The Forward vector in world space</summary>
62 public Vector3 forward => rotation * Vector3.forward;
63
64 /// <summary>The Up vector in world space</summary>
65 public Vector3 up => rotation * Vector3.up;
66
67 /// <summary>The Right vector in world space</summary>
68 public Vector3 right => rotation * Vector3.right;
69
70 internal Vector3 QuickReprojectionWithFixedFOVOnPivotPlane(Rect screen, Vector2 screenPoint)
71 {
72 if (screen.height == 0)
73 return Vector3.zero;
74 float aspect = screen.width / screen.height;
75 //Note: verticalDistance is same than distance from pivot with fixed FoV 90°
76 float verticalDistance = distanceFromPivot;
77 Vector2 normalizedScreenPoint = new Vector2(
78 screenPoint.x * 2f / screen.width - 1f,
79 screenPoint.y * 2f / screen.height - 1f);
80 return pivot
81 - up * verticalDistance * normalizedScreenPoint.y
82 - right * verticalDistance * aspect * normalizedScreenPoint.x;
83 }
84
85 //Pivot is always on center axis by construction
86 internal Vector3 QuickProjectPivotInScreen(Rect screen)
87 => new Vector3(screen.width * .5f, screen.height * .5f, distanceFromPivot);
88
89 /// <summary>
90 /// Update a Camera component and its transform with this state values
91 /// </summary>
92 /// <param name="camera">The camera to update</param>
93 public void UpdateCamera(Camera camera)
94 {
95 camera.transform.rotation = rotation;
96 camera.transform.position = position;
97 camera.nearClipPlane = nearClip;
98 camera.farClipPlane = farClip;
99 camera.fieldOfView = fieldOfView;
100 }
101
102 /// <summary>
103 /// Reset the State to its default values
104 /// </summary>
105 public void Reset()
106 {
107 pivot = k_DefaultPivot;
108 rotation = k_DefaultRotation;
109 viewSize = k_DefaultViewSize;
110 }
111
112 internal void SynchronizeFrom(CameraState other)
113 {
114 pivot = other.pivot;
115 rotation = other.rotation;
116 viewSize = other.viewSize;
117 }
118 }
119}