00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "oculus_rviz_plugins/ogre_oculus.h"
00015 #include "OVR.h"
00016 #include "OGRE/OgreSceneManager.h"
00017 #include "OGRE/OgreRenderWindow.h"
00018 #include "OGRE/OgreCompositorManager.h"
00019 #include "OGRE/OgreCompositorInstance.h"
00020 #include "OGRE/OgreCompositionTargetPass.h"
00021 #include "OGRE/OgreCompositionPass.h"
00022
00023 using namespace OVR;
00024
00025 namespace
00026 {
00027 const float g_defaultNearClip = 0.01f;
00028 const float g_defaultFarClip = 10000.0f;
00029 const float g_defaultIPD = 0.064f;
00030 const Ogre::ColourValue g_defaultViewportColour(97 / 255.0f, 97 / 255.0f, 200 / 255.0f);
00031 const float g_defaultProjectionCentreOffset = 0.14529906f;
00032 const float g_defaultDistortion[4] = {1.0f, 0.22f, 0.24f, 0.0f};
00033 const float g_defaultChromAb[4] = {0.996, -0.004, 1.014, 0.0f};
00034 }
00035
00036 namespace oculus_rviz_plugins
00037 {
00038
00039 Oculus::Oculus(void) :
00040 m_sensorFusion(0), m_stereoConfig(0), m_hmd(0), m_deviceManager(0), m_oculusReady(false), m_ogreReady(false), m_sensor(
00041 0), m_centreOffset(g_defaultProjectionCentreOffset), m_window(0), m_sceneManager(0), m_cameraNode(0)
00042 {
00043 for (int i = 0; i < 2; ++i)
00044 {
00045 m_cameras[i] = 0;
00046 m_viewports[i] = 0;
00047 m_compositors[i] = 0;
00048 }
00049 }
00050
00051 Oculus::~Oculus(void)
00052 {
00053 shutDownOgre();
00054 shutDownOculus();
00055 }
00056
00057 void Oculus::shutDownOculus()
00058 {
00059 delete m_stereoConfig;
00060 m_stereoConfig = 0;
00061 delete m_sensorFusion;
00062 m_sensorFusion = 0;
00063
00064 if (m_sensor)
00065 {
00066 m_sensor->Release();
00067 }
00068 if (m_hmd)
00069 {
00070 m_hmd->Release();
00071 m_hmd = 0;
00072 }
00073 if (m_deviceManager)
00074 {
00075 m_deviceManager->Release();
00076 m_deviceManager = 0;
00077 }
00078
00079 if ( m_oculusReady)
00080 {
00081
00082 }
00083
00084 m_oculusReady = false;
00085 System::Destroy();
00086 }
00087
00088 void Oculus::shutDownOgre()
00089 {
00090 m_ogreReady = false;
00091 for (int i = 0; i < 2; ++i)
00092 {
00093 if (m_compositors[i])
00094 {
00095 Ogre::CompositorManager::getSingleton().removeCompositor(m_viewports[i], "Oculus");
00096 m_compositors[i] = 0;
00097 }
00098 if (m_viewports[i])
00099 {
00100 m_window->removeViewport(i);
00101 m_viewports[i] = 0;
00102 }
00103 if (m_cameras[i])
00104 {
00105 m_cameras[i]->getParentSceneNode()->detachObject(m_cameras[i]);
00106 m_sceneManager->destroyCamera(m_cameras[i]);
00107 m_cameras[i] = 0;
00108 }
00109 }
00110 if (m_cameraNode)
00111 {
00112 m_cameraNode->getParentSceneNode()->removeChild(m_cameraNode);
00113 m_sceneManager->destroySceneNode(m_cameraNode);
00114 m_cameraNode = 0;
00115 }
00116 m_window = 0;
00117 m_sceneManager = 0;
00118 }
00119
00120 bool Oculus::isOculusReady() const
00121 {
00122 return m_oculusReady;
00123 }
00124
00125 bool Oculus::isOgreReady() const
00126 {
00127 return m_ogreReady;
00128 }
00129
00130 bool Oculus::setupOculus()
00131 {
00132 if (m_oculusReady)
00133 {
00134 Ogre::LogManager::getSingleton().logMessage("Oculus: Already Initialised");
00135 return true;
00136 }
00137 Ogre::LogManager::getSingleton().logMessage("Oculus: Initialising system");
00138 System::Init(Log::ConfigureDefaultLog(LogMask_All));
00139 m_deviceManager = DeviceManager::Create();
00140 if (!m_deviceManager)
00141 {
00142 Ogre::LogManager::getSingleton().logMessage("Oculus: Failed to create Device Manager");
00143 return false;
00144 }
00145 Ogre::LogManager::getSingleton().logMessage("Oculus: Created Device Manager");
00146 m_stereoConfig = new Util::Render::StereoConfig();
00147 if (!m_stereoConfig)
00148 {
00149 Ogre::LogManager::getSingleton().logMessage("Oculus: Failed to create StereoConfig");
00150 return false;
00151 }
00152 m_centreOffset = m_stereoConfig->GetProjectionCenterOffset();
00153 Ogre::LogManager::getSingleton().logMessage("Oculus: Created StereoConfig");
00154 m_hmd = m_deviceManager->EnumerateDevices<HMDDevice>().CreateDevice();
00155 if (!m_hmd)
00156 {
00157 Ogre::LogManager::getSingleton().logMessage("Oculus: Failed to create HMD");
00158 return false;
00159 }
00160 Ogre::LogManager::getSingleton().logMessage("Oculus: Created HMD");
00161 HMDInfo devinfo;
00162 m_hmd->GetDeviceInfo(&devinfo);
00163 m_stereoConfig->SetHMDInfo(devinfo);
00164
00165 m_sensor = m_hmd->GetSensor();
00166 if (!m_sensor)
00167 {
00168 Ogre::LogManager::getSingleton().logMessage("Oculus: Failed to create sensor");
00169 return false;
00170 }
00171 Ogre::LogManager::getSingleton().logMessage("Oculus: Created sensor");
00172
00173 m_sensorFusion = new SensorFusion();
00174 m_sensorFusion->AttachToSensor(m_sensor);
00175 Ogre::LogManager::getSingleton().logMessage("Oculus: Created SensorFusion");
00176
00177 m_magCalibration = new Util::MagCalibration();
00178 m_magCalibration->BeginAutoCalibration( *m_sensorFusion );
00179 Ogre::LogManager::getSingleton().logMessage("Oculus: Created MagCalibration");
00180
00181 m_oculusReady = true;
00182 Ogre::LogManager::getSingleton().logMessage("Oculus: Oculus setup completed successfully");
00183 return true;
00184 }
00185
00186 bool Oculus::setupOgre(Ogre::SceneManager *sm, Ogre::RenderWindow *win, Ogre::SceneNode *parent)
00187 {
00188 m_window = win;
00189 m_sceneManager = sm;
00190 Ogre::LogManager::getSingleton().logMessage("Oculus: Setting up Ogre");
00191 if (parent)
00192 m_cameraNode = parent->createChildSceneNode("StereoCameraNode");
00193 else
00194 m_cameraNode = sm->getRootSceneNode()->createChildSceneNode("StereoCameraNode");
00195
00196 m_cameras[0] = sm->createCamera("CameraLeft");
00197 m_cameras[1] = sm->createCamera("CameraRight");
00198
00199 Ogre::MaterialPtr matLeft = Ogre::MaterialManager::getSingleton().getByName("Ogre/Compositor/Oculus");
00200 Ogre::MaterialPtr matRight = matLeft->clone("Ogre/Compositor/Oculus/Right");
00201 Ogre::GpuProgramParametersSharedPtr pParamsLeft =
00202 matLeft->getTechnique(0)->getPass(0)->getFragmentProgramParameters();
00203 Ogre::GpuProgramParametersSharedPtr pParamsRight =
00204 matRight->getTechnique(0)->getPass(0)->getFragmentProgramParameters();
00205 Ogre::Vector4 hmdwarp;
00206 if (m_stereoConfig)
00207 {
00208 hmdwarp = Ogre::Vector4(m_stereoConfig->GetDistortionK(0), m_stereoConfig->GetDistortionK(1),
00209 m_stereoConfig->GetDistortionK(2), m_stereoConfig->GetDistortionK(3));
00210 }
00211 else
00212 {
00213 hmdwarp = Ogre::Vector4(g_defaultDistortion[0], g_defaultDistortion[1], g_defaultDistortion[2],
00214 g_defaultDistortion[3]);
00215 }
00216 pParamsLeft->setNamedConstant("HmdWarpParam", hmdwarp);
00217 pParamsRight->setNamedConstant("HmdWarpParam", hmdwarp);
00218
00219 Ogre::Vector4 hmdchrom;
00220 if (m_stereoConfig)
00221 {
00222 hmdchrom = Ogre::Vector4(m_stereoConfig->GetHMDInfo().ChromaAbCorrection);
00223 }
00224 else
00225 {
00226 hmdchrom = Ogre::Vector4(g_defaultChromAb);
00227 }
00228 pParamsLeft->setNamedConstant("ChromAbParam", hmdchrom);
00229 pParamsRight->setNamedConstant("ChromAbParam", hmdchrom);
00230
00231 pParamsLeft->setNamedConstant("LensCenter", 0.5f + (m_stereoConfig->GetProjectionCenterOffset() / 2.0f));
00232 pParamsRight->setNamedConstant("LensCenter", 0.5f - (m_stereoConfig->GetProjectionCenterOffset() / 2.0f));
00233
00234 Ogre::CompositorPtr comp = Ogre::CompositorManager::getSingleton().getByName("OculusRight");
00235 comp->getTechnique(0)->getOutputTargetPass()->getPass(0)->setMaterialName("Ogre/Compositor/Oculus/Right");
00236
00237 for (int i = 0; i < 2; ++i)
00238 {
00239 m_cameraNode->attachObject(m_cameras[i]);
00240 if (m_stereoConfig)
00241 {
00242
00243 m_cameras[i]->setNearClipDistance(m_stereoConfig->GetEyeToScreenDistance());
00244 m_cameras[i]->setFarClipDistance(g_defaultFarClip);
00245 m_cameras[i]->setPosition((i * 2 - 1) * m_stereoConfig->GetIPD() * 0.5f, 0, 0);
00246 m_cameras[i]->setAspectRatio(m_stereoConfig->GetAspect());
00247 m_cameras[i]->setFOVy(Ogre::Radian(m_stereoConfig->GetYFOVRadians()));
00248 }
00249 else
00250 {
00251 m_cameras[i]->setNearClipDistance(g_defaultNearClip);
00252 m_cameras[i]->setFarClipDistance(g_defaultFarClip);
00253 m_cameras[i]->setPosition((i * 2 - 1) * g_defaultIPD * 0.5f, 0, 0);
00254 }
00255 m_viewports[i] = win->addViewport(m_cameras[i], i, 0.5f * i, 0, 0.5f, 1.0f);
00256 m_viewports[i]->setBackgroundColour(g_defaultViewportColour);
00257 m_compositors[i] = Ogre::CompositorManager::getSingleton().addCompositor(m_viewports[i],
00258 i == 0 ? "OculusLeft" : "OculusRight");
00259 m_compositors[i]->setEnabled(true);
00260 }
00261
00262 updateProjectionMatrices();
00263
00264 m_ogreReady = true;
00265 Ogre::LogManager::getSingleton().logMessage("Oculus: Oculus setup completed successfully");
00266 return true;
00267 }
00268
00269 void Oculus::updateProjectionMatrices()
00270 {
00271 if (m_stereoConfig)
00272 {
00273 for (int i = 0; i < 2; ++i)
00274 {
00275 m_cameras[i]->setCustomProjectionMatrix(false);
00276 Ogre::Matrix4 proj = Ogre::Matrix4::IDENTITY;
00277 float temp = m_stereoConfig->GetProjectionCenterOffset();
00278 proj.setTrans(Ogre::Vector3(-m_stereoConfig->GetProjectionCenterOffset() * (2 * i - 1), 0, 0));
00279 m_cameras[i]->setCustomProjectionMatrix(true, proj * m_cameras[i]->getProjectionMatrix());
00280 }
00281 }
00282 }
00283
00284 void Oculus::update()
00285 {
00286 if (m_ogreReady)
00287 {
00288 m_cameraNode->setOrientation(getOrientation());
00289
00290 if (m_magCalibration->IsAutoCalibrating())
00291 {
00292 m_magCalibration->UpdateAutoCalibration( *m_sensorFusion );
00293 if (m_magCalibration->IsCalibrated())
00294 {
00295 m_sensorFusion->SetYawCorrectionEnabled(true);
00296 }
00297 }
00298 }
00299 }
00300
00301 bool Oculus::isMagCalibrated()
00302 {
00303 return m_oculusReady && m_magCalibration->IsCalibrated();
00304 }
00305
00306 Ogre::SceneNode* Oculus::getCameraNode()
00307 {
00308 return m_cameraNode;
00309 }
00310
00311 void Oculus::setPredictionDt(float dt)
00312 {
00313 if (m_oculusReady)
00314 {
00315 m_sensorFusion->SetPrediction( dt, dt > 0.0f );
00316 }
00317 }
00318
00319 Ogre::Quaternion Oculus::getOrientation() const
00320 {
00321 if (m_oculusReady)
00322 {
00323 Quatf q = m_sensorFusion->GetPredictedOrientation();
00324 return Ogre::Quaternion(q.w, q.x, q.y, q.z);
00325 }
00326 else
00327 {
00328 return Ogre::Quaternion::IDENTITY;
00329 }
00330 }
00331
00332 Ogre::CompositorInstance *Oculus::getCompositor(unsigned int i)
00333 {
00334 return m_compositors[i];
00335 }
00336
00337 float Oculus::getCentreOffset() const
00338 {
00339 return m_centreOffset;
00340 }
00341
00342 void Oculus::resetOrientation()
00343 {
00344 if (m_sensorFusion)
00345 m_sensorFusion->Reset();
00346 }
00347
00348 }