Skip to content

Commit 2f80bab

Browse files
committed
Added OnPreCull and EndOfFrame coroutine, which previously in VRViewer.
1 parent a76c00b commit 2f80bab

1 file changed

Lines changed: 75 additions & 101 deletions

File tree

OSVR-Unity/Assets/OSVRUnity/src/DisplayController.cs

Lines changed: 75 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -32,33 +32,40 @@ namespace Unity
3232
//Rendering parameters are obtained from ClientKit.
3333
//DisplayController creates VRViewer and VREyes as children. Each eye has a VRSurface child with a camera.
3434
//In this implementation, we are assuming that there is exactly one viewer and one surface per eye.
35+
[RequireComponent(typeof(Camera))] //requires a "dummy" camera
3536
public class DisplayController : MonoBehaviour
3637
{
37-
public const uint DEFAULT_VIEWER = 0; //assume exactly one viewer in this Unity implementation
38-
public const uint DEFAULT_SURFACE = 0; //assume exactly one viewer in this Unity implementation
38+
3939
public const uint NUM_VIEWERS = 1;
40-
public const uint NUM_SURFACE_PER_EYE = 1;
4140

4241
private ClientKit _clientKit;
4342
private OSVR.ClientKit.DisplayConfig _displayConfig;
4443
private VRViewer[] _viewers;
45-
private VREye[] _eyes;
46-
private uint _eyeCount;
4744
private uint _viewerCount;
4845
private bool _renderedStereo = false;
4946
private bool _displayConfigInitialized = false;
47+
private Camera _camera;
48+
private bool _disabledCamera = true;
5049

50+
public Camera Camera
51+
{
52+
get
53+
{
54+
if (_camera == null)
55+
{
56+
_camera = GetComponent<Camera>();
57+
}
58+
return _camera;
59+
}
60+
set { _camera = value; }
61+
}
5162
public OSVR.ClientKit.DisplayConfig DisplayConfig
5263
{
5364
get { return _displayConfig; }
5465
set { _displayConfig = value; }
5566
}
5667
public VRViewer[] Viewers { get { return _viewers; } }
57-
public VREye[] Eyes { get { return _eyes; } }
58-
public uint EyeCount { get { return _eyeCount; } }
5968
public uint ViewerCount { get { return _viewerCount; } }
60-
public float nearClippingPlane = 0.01f;
61-
public float farClippingPlane = 1000f;
6269

6370
void Awake()
6471
{
@@ -67,12 +74,23 @@ void Awake()
6774
{
6875
Debug.LogError("DisplayController requires a ClientKit object in the scene.");
6976
}
77+
_camera = GetComponent<Camera>(); //get the "dummy" camera
7078
SetupApplicationSettings();
7179
}
7280
void Start()
7381
{
7482
SetupDisplay();
75-
}
83+
}
84+
85+
void OnEnable()
86+
{
87+
StartCoroutine("EndOfFrame");
88+
}
89+
90+
void OnDisable()
91+
{
92+
StopCoroutine("EndOfFrame");
93+
}
7694

7795
void SetupApplicationSettings()
7896
{
@@ -96,7 +114,7 @@ void SetupDisplay()
96114
{
97115
return;
98116
}
99-
_displayConfigInitialized = true;
117+
_displayConfigInitialized = true;
100118

101119
//get the number of viewers, bail if there isn't exactly one viewer for now
102120
_viewerCount = _displayConfig.GetNumViewers();
@@ -106,10 +124,10 @@ void SetupDisplay()
106124
return;
107125
}
108126
//create scene objects
109-
CreateHeadAndEyes();
110-
127+
CreateHeadAndEyes();
111128
}
112129

130+
113131
//Creates a head and eyes as configured in clientKit
114132
//Viewers and Eyes are siblings, children of DisplayController
115133
//Each eye has one child Surface which has a camera
@@ -124,124 +142,80 @@ private void CreateHeadAndEyes()
124142
return;
125143
}
126144
_viewers = new VRViewer[_viewerCount];
145+
//loop through viewers because at some point we could support multiple viewers
146+
//but this implementation currently supports exactly one
127147
for (uint viewerIndex = 0; viewerIndex < _viewerCount; viewerIndex++)
128148
{
129149
//create a VRViewer
130150
GameObject vrViewer = new GameObject("VRViewer" + viewerIndex);
131151
vrViewer.AddComponent<AudioListener>(); //add an audio listener
132152
VRViewer vrViewerComponent = vrViewer.AddComponent<VRViewer>();
133-
vrViewerComponent.Camera = vrViewer.GetComponent<Camera>(); //add a dummy camera, VRViewer requires that it has a camera already
134-
vrViewerComponent.Camera.nearClipPlane = nearClippingPlane;
135-
vrViewerComponent.Camera.farClipPlane = farClippingPlane;
136153
vrViewerComponent.DisplayController = this; //pass DisplayController to Viewers
137-
if(viewerIndex == 0)
138-
{
139-
vrViewer.tag = "MainCamera"; //tag a VRViewer as the MainCamera so other gameobjects can reference it
140-
}
154+
vrViewerComponent.ViewerIndex = viewerIndex; //set the viewer's index
141155
vrViewer.transform.parent = this.transform; //child of DisplayController
142156
vrViewer.transform.localPosition = Vector3.zero;
143157
_viewers[viewerIndex] = vrViewerComponent;
144158

145159
//create Viewer's VREyes
146-
_eyeCount = (uint)_displayConfig.GetNumEyesForViewer(viewerIndex); //get the number of eyes
147-
_eyes = new VREye[_eyeCount];
148-
for (uint eyeIndex = 0; eyeIndex < _eyeCount; eyeIndex++)
149-
{
150-
GameObject eyeGameObject = new GameObject("Eye" + eyeIndex); //add an eye gameobject to the scene
151-
VREye eye = eyeGameObject.AddComponent<VREye>(); //add the VReye component
152-
eye.Viewer = _viewers[viewerIndex]; //ASSUME THERE IS ONLY ONE VIEWER
153-
eye.EyeIndex = eyeIndex; //set the eye's index
154-
eyeGameObject.transform.parent = this.transform; //child of DisplayController
155-
eyeGameObject.transform.localPosition = Vector3.zero;
156-
_eyes[eyeIndex] = eye;
157-
CreateEyeSurface(eyeIndex);
158-
SetDistortion(eyeIndex);
159-
}
160+
uint eyeCount = (uint)_displayConfig.GetNumEyesForViewer(viewerIndex); //get the number of eyes for this viewer
161+
vrViewerComponent.CreateEyes(eyeCount);
160162
}
161-
}
163+
}
162164

163-
//Creates a Surface for a given Eye
164-
//bail if there isn't exactly one surface per eye
165-
private void CreateEyeSurface(uint eyeIndex)
165+
void Update()
166166
{
167-
uint surfaceCount = _displayConfig.GetNumSurfacesForViewerEye(DEFAULT_VIEWER, (byte)eyeIndex);
168-
if(surfaceCount != 1)
167+
//sometimes it takes a few frames to get a DisplayConfig from ClientKit
168+
//keep trying until we have initialized
169+
if(!_displayConfigInitialized)
169170
{
170-
Debug.LogError("Eye" + eyeIndex + " has " + surfaceCount + " surfaces, but "+
171-
"this implementation requires exactly one surface per eye.");
172-
return;
171+
SetupDisplay();
173172
}
174-
GameObject surfaceGameObject = new GameObject("Surface");
175-
VRSurface surface = surfaceGameObject.AddComponent<VRSurface>();
176-
surface.Camera = surfaceGameObject.AddComponent<Camera>();
177-
surface.Camera.nearClipPlane = nearClippingPlane;
178-
surface.Camera.farClipPlane = farClippingPlane;
179-
surface.Camera.enabled = false;
180-
surfaceGameObject.transform.parent = _eyes[eyeIndex].transform; //surface is child of Eye
181-
surfaceGameObject.transform.localPosition = Vector3.zero;
182-
_eyes[eyeIndex].Surface = surface;
183173
}
184174

185-
//determines if distortion will be used, and what type of distortion will be used
186-
//set distortion parameters accordingly for the given eye.
187-
private void SetDistortion(uint eyeIndex)
175+
//helper method for updating the client context
176+
public void UpdateClient()
188177
{
189-
bool useDistortion = _displayConfig.DoesViewerEyeSurfaceWantDistortion(DEFAULT_VIEWER, (byte)eyeIndex, DEFAULT_SURFACE);
190-
if (!useDistortion)
191-
{ //return if we do not want distortion
192-
return;
193-
}
194-
195-
//@todo figure out which type of distortion to use
196-
//right now, there is only one option
197-
OSVR.ClientKit.RadialDistortionParameters distortionParameters =
198-
_displayConfig.GetViewerEyeSurfaceRadialDistortion(DEFAULT_VIEWER, (byte)eyeIndex, DEFAULT_SURFACE);
199-
float k1Red = (float)distortionParameters.k1.x;
200-
float k1Green = (float)distortionParameters.k1.y;
201-
float k1Blue = (float)distortionParameters.k1.z;
202-
Vector2 center = new Vector2((float)distortionParameters.centerOfProjection.x,
203-
(float)distortionParameters.centerOfProjection.y);
204-
SetK1RadialDistortion(eyeIndex, k1Red, k1Green, k1Blue, center);
178+
_clientKit.context.update(); //update the client
205179
}
206180

207-
//set distortion parameters for K1 Radial Distortion method
208-
private void SetK1RadialDistortion(uint eyeIndex, float k1Red, float k1Green, float k1Blue, Vector2 center)
181+
//Culling determines which objects are visible to the camera. OnPreCull is called just before this process.
182+
void OnPreCull()
209183
{
210-
VREye eye = _eyes[eyeIndex];
211-
// disable distortion if there is no distortion for this HMD
212-
if (k1Red == 0 && k1Green == 0 && k1Blue == 0)
213-
{
214-
if (eye.Surface.DistortionEffect)
215-
{
216-
eye.Surface.DistortionEffect.enabled = false;
217-
}
218-
return;
219-
}
220-
// Otherwise try to create distortion and set its parameters
221-
var distortionFactory = new K1RadialDistortionFactory();
222-
var effect = distortionFactory.GetOrCreateDistortion(eye.Surface);
223-
if (effect)
184+
//update the client
185+
UpdateClient();
186+
187+
// Disable dummy camera during rendering
188+
// Enable after frame ends
189+
_camera.enabled = false;
190+
191+
//for each viewer, update each eye, which will update each surface
192+
for (uint viewerIndex = 0; viewerIndex < _viewerCount; viewerIndex++)
224193
{
225-
effect.k1Red = k1Red;
226-
effect.k1Green = k1Green;
227-
effect.k1Blue = k1Blue;
228-
effect.center = center;
229-
}
194+
VRViewer viewer = Viewers[viewerIndex];
195+
//update the viewer's head pose
196+
viewer.UpdateViewerHeadPose(DisplayConfig.GetViewerPose(viewerIndex));
197+
198+
//have each viewer update its eyes
199+
viewer.UpdateEyes();
200+
}
201+
202+
// Remember to reenable.
203+
_disabledCamera = true;
230204
}
231205

232-
void Update()
206+
IEnumerator EndOfFrame()
233207
{
234-
if(!_displayConfigInitialized)
208+
while (true)
235209
{
236-
SetupDisplay();
210+
//if we disabled the dummy camera, enable it here
211+
if (_disabledCamera)
212+
{
213+
Camera.enabled = true;
214+
_disabledCamera = false;
215+
}
216+
yield return new WaitForEndOfFrame();
237217
}
238218
}
239-
240-
//helper method for updating the client context
241-
public void UpdateClient()
242-
{
243-
_clientKit.context.update(); //update the client
244-
}
245219
}
246220
}
247221
}

0 commit comments

Comments
 (0)