-
Notifications
You must be signed in to change notification settings - Fork 1
/
PupilCamera.cs
199 lines (165 loc) · 6.58 KB
/
PupilCamera.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;
using UnityEngine.Rendering.PostProcessing;
namespace Pupil
{
public class PupilCamera : MonoBehaviour
{
private float _ipd;
private Transform _camera;
[SerializeField]
private Transform _left;
[SerializeField]
private Transform _right;
private float _maxDistance;
private float _minDistanceIPD;
private float _maxDistanceIPD;
private bool _autoAdjustWarnings;
private PostProcessVolume _leftVolume;
private PostProcessVolume _rightVolume;
private DepthOfField _dof;
private DepthOfField _rightDOF;
[SerializeField]
private GameObject _nearest;
public void Start()
{
if (GameObject.Find("PupilInitializer") == null)
{
Debug.LogError("Error: No PupilInitializer GameObject found. Please add one to the hierarchy to properly load your VR device.");
}
// FindCameraRig();
_camera = transform;
// @todo(tdamron): Cover case for two MainCameras in the scene
/*
if (_camera == null)
{
Debug.LogError("Error: Camera not set. Please ensure that the PupilCameraRig is in the hierarchy and that there is only on camera with the MainCamera tag in the scene.");
}
*/
_leftVolume = _left.GetComponent<PostProcessVolume>();
if (_leftVolume == null)
{
Debug.LogError("Error: No post processing behaviour found on the left camera.");
}
_rightVolume = _right.GetComponent<PostProcessVolume>();
if (_rightVolume == null)
{
Debug.LogError("Error: No post processing behaviour found on the right camera.");
}
_leftVolume.sharedProfile.TryGetSettings<DepthOfField>(out _dof);
}
// DEPRECATED
public void FindCameraRig()
{
_camera = GameObject.FindGameObjectWithTag("MainCamera").transform;
_nearest = _camera.gameObject;
}
public float GetDistanceToGameObject(GameObject obj)
{
var distance = Vector3.Distance(_camera.position, obj.transform.position);
return distance;
}
public float GetDistanceToGameObject(GameObject obj, GameObject from)
{
var distance = Vector3.Distance(from.transform.localPosition, obj.transform.position);
return distance;
}
public void SetMinDistanceIPD(float ipd)
{
_minDistanceIPD = ipd;
}
public void SetMaxDistanceIPD(float distance, float ipd)
{
_maxDistance = distance;
_maxDistanceIPD = ipd;
}
public GameObject FindNearest()
{
RaycastHit hit;
var rot = InputTracking.GetLocalRotation(XRNode.Head);
#if UNITY_EDITOR
rot = _camera.transform.localRotation;
#endif
if (Physics.SphereCast(_camera.position, 1f, rot * _camera.forward, out hit))
{
_nearest = hit.transform.gameObject;
return hit.transform.gameObject;
}
return _camera.gameObject;
}
public GameObject FindNearest(int ignoreLayer)
{
RaycastHit hit;
var rot = InputTracking.GetLocalRotation(XRNode.Head);
#if UNITY_EDITOR
rot = _camera.transform.localRotation;
#endif
if (Physics.SphereCast(_camera.position, 1f, rot * _camera.forward, out hit))
{
if (hit.transform.gameObject.layer != ignoreLayer)
{
_nearest = hit.transform.gameObject;
return hit.transform.gameObject;
}
}
return _camera.gameObject;
}
public void DrawViewLines()
{
Debug.DrawLine(_left.position, _left.position + _left.forward * _maxDistance, Color.red);
Debug.DrawLine(_right.position, _right.position + _right.forward * _maxDistance, Color.green);
}
public void AutoAdjustDepthOfField()
{
if (_leftVolume == null || _rightVolume == null)
{
Debug.LogError("Error: Cannot adjust depth of field. PostProcessing profile(s) not found. Please attach a profile to the cameras' PostProcessingBehaviour.");
}
else
{
if (_leftVolume.sharedProfile.TryGetSettings<DepthOfField>(out var dof)) {
dof.SetAllOverridesTo(true);
_nearest = FindNearest();
var distance = GetDistanceToGameObject(_nearest, _camera.gameObject);
var lerp = 0f;
if (_nearest != _camera.gameObject)
{
lerp = Mathf.Lerp(dof.focusDistance, distance, Time.deltaTime * 30f);
}
if (_nearest == _camera.gameObject)
{
lerp = Mathf.Lerp(dof.focusDistance, 100f, Time.deltaTime);
}
dof.focusDistance.value = lerp;
}
}
}
public void AutoAdjustIPD()
{
if (!_autoAdjustWarnings && _maxDistance == 0f)
{
Debug.LogWarning("One or more distance variables are 0. Are you sure you want to do this?");
_autoAdjustWarnings = true;
}
_nearest = FindNearest();
//Default to max distance IPD
_ipd = _minDistanceIPD;
if (_nearest != _camera.gameObject)
{
var distance = GetDistanceToGameObject(_nearest);
if (distance > _maxDistance)
{
_ipd = _maxDistanceIPD;
}
}
_left.parent.localPosition = Vector3.Lerp(_left.parent.localPosition,
new Vector3(-_ipd + PupilDataHolder.left, _left.parent.localPosition.y, _left.parent.localPosition.z),
Time.deltaTime * 3f);
_right.parent.localPosition = Vector3.Lerp(_right.parent.localPosition,
new Vector3(_ipd + PupilDataHolder.right, _right.parent.localPosition.y, _right.parent.localPosition.z),
Time.deltaTime * 3f);
}
}
}