@@ -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