21#include <osgXR/Settings>
23#include <simgear/scene/util/RenderConstants.hxx>
24#include <simgear/scene/viewer/Compositor.hxx>
25#include <simgear/scene/viewer/CompositorPass.hxx>
32using namespace simgear;
33using namespace compositor;
40VRManager::VRManager() :
41 _reloadCompositorCallback(new ReloadCompositorCallback(this)),
42 _propXrLayersValidation(
"/sim/vr/openxr/layers/validation"),
43 _propXrExtensionsDepthInfo(
"/sim/vr/openxr/extensions/depth-info"),
44 _propXrExtensionsVisibilityMask(
"/sim/vr/openxr/extensions/visibility-mask"),
45 _propXrRuntimeName(
"/sim/vr/openxr/runtime/name"),
46 _propXrSystemName(
"/sim/vr/openxr/system/name"),
47 _propStateString(
"/sim/vr/state-string"),
48 _propPresent(
"/sim/vr/present"),
49 _propRunning(
"/sim/vr/running"),
50 _propEnabled(
"/sim/vr/enabled"),
51 _propDepthInfo(
"/sim/vr/depth-info"),
52 _propVisibilityMask(
"/sim/vr/visibility-mask"),
53 _propValidationLayer(
"/sim/vr/validation-layer"),
54 _propMode(
"/sim/vr/mode"),
55 _propSwapchainMode(
"/sim/vr/swapchain-mode"),
56 _propMirrorEnabled(
"/sim/vr/mirror-enabled"),
57 _propMirrorMode(
"/sim/vr/mirror-mode"),
58 _listenerEnabled(this, &osgXR::Manager::setEnabled),
59 _listenerDepthInfo(this, &VRManager::setDepthInfo),
60 _listenerVisibilityMask(this, &VRManager::setVisibilityMask),
61 _listenerValidationLayer(this, &VRManager::setValidationLayer),
62 _listenerMode(this, &VRManager::setVRMode),
63 _listenerSwapchainMode(this, &VRManager::setSwapchainMode),
64 _listenerMirrorMode(this, &VRManager::setMirrorMode)
66 uint32_t fgVersion = (FLIGHTGEAR_MAJOR_VERSION << 16 |
67 FLIGHTGEAR_MINOR_VERSION << 8 |
68 FLIGHTGEAR_PATCH_VERSION);
69 _settings->setApp(
"FlightGear", fgVersion);
70 _settings->preferEnvBlendMode(osgXR::Settings::BLEND_MODE_OPAQUE);
73 setVisibilityMaskNodeMasks(simgear::NodeMask::LEFT_BIT,
74 simgear::NodeMask::RIGHT_BIT);
77 osgViewer::View *view =
globals->get_renderer()->getView();
79 setViewer(
globals->get_renderer()->getViewerBase());
83 syncReadOnlyProperties();
85 _propEnabled.node(
true)->addChangeListener(&_listenerEnabled,
true);
86 _propDepthInfo.node(
true)->addChangeListener(&_listenerDepthInfo,
true);
87 _propVisibilityMask.node(
true)->addChangeListener(&_listenerVisibilityMask,
true);
88 _propValidationLayer.node(
true)->addChangeListener(&_listenerValidationLayer,
true);
89 _propMode.node(
true)->addChangeListener(&_listenerMode,
true);
90 _propSwapchainMode.node(
true)->addChangeListener(&_listenerSwapchainMode,
true);
91 _propMirrorMode.node(
true)->addChangeListener(&_listenerMirrorMode,
true);
94 _propMirrorEnabled.node(
true);
97 std::string compositorPath =
fgGetString(
"/sim/rendering/default-compositor",
98 "Compositor/default");
99 SGPropertyNode_ptr compositorProps = Compositor::loadPropertyList(compositorPath);
100 if (compositorProps.valid()) {
101 _settings->setViewAlignmentMask(compositorProps->getIntValue(
"multiview/view-align-mask", 0));
103 _settings->allowVRMode(osgXR::Settings::VRMODE_SLAVE_CAMERAS);
104 if (compositorProps->getBoolValue(
"multiview/sceneview",
false))
105 _settings->allowVRMode(osgXR::Settings::VRMODE_SCENE_VIEW);
107 _settings->allowSwapchainMode(osgXR::Settings::SWAPCHAIN_MULTIPLE);
108 if (compositorProps->getBoolValue(
"multiview/intermediates-tiled",
false))
109 _settings->allowSwapchainMode(osgXR::Settings::SWAPCHAIN_SINGLE);
113VRManager *VRManager::instance()
115 static bool initialised =
false;
117 managerInstance =
new VRManager;
123void VRManager::syncProperties()
126 if (checkAndResetStateChanged()) {
127 syncReadOnlyProperties();
128 syncSettingProperties();
132void VRManager::syncReadOnlyProperties()
134 _propXrLayersValidation = hasValidationLayer();
135 _propXrExtensionsDepthInfo = hasDepthInfoExtension();
136 _propXrExtensionsVisibilityMask = hasVisibilityMaskExtension();
137 _propXrRuntimeName = getRuntimeName();
138 _propXrSystemName = getSystemName();
140 _propStateString = getStateString();
141 _propPresent = getPresent();
142 _propRunning = isRunning();
145void VRManager::syncSettingProperties()
147 bool enabled = getEnabled();
148 if (_propEnabled != enabled)
149 _propEnabled = enabled;
152bool VRManager::getUseMirror()
const
154 return _propMirrorEnabled && isRunning();
157void VRManager::setValidationLayer(
bool validationLayer)
159 _settings->setValidationLayer(validationLayer);
163void VRManager::setDepthInfo(
bool depthInfo)
165 _settings->setDepthInfo(depthInfo);
169void VRManager::setVisibilityMask(
bool visibilityMask)
171 _settings->setVisibilityMask(visibilityMask);
175void VRManager::setVRMode(
const std::string& mode)
177 osgXR::Settings::VRMode vrMode = osgXR::Settings::VRMODE_AUTOMATIC;
179 if (mode ==
"AUTOMATIC") {
180 vrMode = osgXR::Settings::VRMODE_AUTOMATIC;
181 }
else if (mode ==
"SLAVE_CAMERAS") {
182 vrMode = osgXR::Settings::VRMODE_SLAVE_CAMERAS;
183 }
else if (mode ==
"SCENE_VIEW") {
184 vrMode = osgXR::Settings::VRMODE_SCENE_VIEW;
187 _settings->setVRMode(vrMode);
191void VRManager::setSwapchainMode(
const std::string& mode)
193 osgXR::Settings::SwapchainMode swapchainMode = osgXR::Settings::SWAPCHAIN_AUTOMATIC;
195 if (mode ==
"AUTOMATIC") {
196 swapchainMode = osgXR::Settings::SWAPCHAIN_AUTOMATIC;
197 }
else if (mode ==
"MULTIPLE") {
198 swapchainMode = osgXR::Settings::SWAPCHAIN_MULTIPLE;
199 }
else if (mode ==
"SINGLE") {
200 swapchainMode = osgXR::Settings::SWAPCHAIN_SINGLE;
203 _settings->setSwapchainMode(swapchainMode);
207void VRManager::setMirrorMode(
const std::string& mode)
209 osgXR::MirrorSettings::MirrorMode mirrorMode = osgXR::MirrorSettings::MIRROR_AUTOMATIC;
212 if (mode ==
"AUTOMATIC") {
213 mirrorMode = osgXR::MirrorSettings::MIRROR_AUTOMATIC;
214 }
else if (mode ==
"NONE") {
215 mirrorMode = osgXR::MirrorSettings::MIRROR_NONE;
216 }
else if (mode ==
"LEFT") {
217 mirrorMode = osgXR::MirrorSettings::MIRROR_SINGLE;
219 }
else if (mode ==
"RIGHT") {
220 mirrorMode = osgXR::MirrorSettings::MIRROR_SINGLE;
222 }
else if (mode ==
"LEFT_RIGHT") {
223 mirrorMode = osgXR::MirrorSettings::MIRROR_LEFT_RIGHT;
226 _settings->getMirrorSettings().setMirror(mirrorMode, viewIndex);
229void VRManager::update()
231 osgXR::Manager::update();
235void VRManager::doCreateView(osgXR::View *xrView)
238 _viewer->stopThreading();
241 SGPropertyNode_ptr camNode =
new SGPropertyNode;
242 setValue(camNode->getNode(
"window/name",
true),
244 setValue(camNode->getNode(
"viewport/width",
true), (
int)xrView->getMVRWidth());
245 setValue(camNode->getNode(
"viewport/height",
true), (
int)xrView->getMVRHeight());
246 setValue(camNode->getNode(
"mvr-views",
true), (
int)xrView->getMVRViews());
247 setValue(camNode->getNode(
"mvr-view-id-global",
true), xrView->getMVRViewIdGlobalStr());
248 setValue(camNode->getNode(
"mvr-view-id-vert",
true), xrView->getMVRViewIdStr(GL_VERTEX_SHADER));
249 setValue(camNode->getNode(
"mvr-view-id-geom",
true), xrView->getMVRViewIdStr(GL_GEOMETRY_SHADER));
250 setValue(camNode->getNode(
"mvr-view-id-frag",
true), xrView->getMVRViewIdStr(GL_FRAGMENT_SHADER));
251 setValue(camNode->getNode(
"mvr-cells",
true), (
int)xrView->getMVRCells());
254 CameraGroup *cgroup = CameraGroup::getDefault();
255 CameraInfo *info = cgroup->buildCamera(camNode);
259 _camInfos[xrView] = info;
260 _xrViews[info] = xrView;
261 info->reloadCompositorCallback = _reloadCompositorCallback;
263 postReloadCompositor(cgroup, info);
267 xrView->setCallback(
new ViewCallback(
this));
270void VRManager::doDestroyView(osgXR::View *xrView)
273 _viewer->stopThreading();
275 CameraGroup *cgroup = CameraGroup::getDefault();
276 auto it = _camInfos.find(xrView);
277 if (it != _camInfos.end()) {
278 osg::ref_ptr<CameraInfo> info = (*it).second;
281 auto it2 = _xrViews.find(info.get());
282 if (it2 != _xrViews.end())
285 cgroup->removeCamera(info.get());
289void VRManager::onRunning()
292 CameraGroup *cgroup = CameraGroup::getDefault();
296void VRManager::onStopped()
302 CameraGroup *cgroup = CameraGroup::getDefault();
309 bool isScene = (pass->type ==
"scene");
310 bool isMultiviewQuad = (pass->type ==
"quad" && pass->multiview ==
"true");
311 bool isWidthScaled = (pass->viewport_width_scale != 0.0f);
312 bool isHeightScaled = (pass->viewport_height_scale != 0.0f);
315 bool isToFb = (pass->camera->getRenderTargetImplementation() == osg::Camera::FRAME_BUFFER);
317 osgXR::View::Flags flags = osgXR::View::CAM_NO_BITS;
320 if ((isScene || isMultiviewQuad) && isToFb)
321 flags |= osgXR::View::CAM_TOXR_BIT;
323 if (isScene && (isToFb || (isWidthScaled && isHeightScaled))) {
326 flags |= osgXR::View::CAM_MVR_SCENE_BIT;
327 flags |= osgXR::View::CAM_MVR_SHADING_BIT;
328 }
else if (isMultiviewQuad) {
330 flags |= osgXR::View::CAM_MVR_SHADING_BIT;
332 if (!(flags & osgXR::View::CAM_TOXR_BIT)) {
335 flags |= osgXR::View::CAM_MVR_FIXED_WIDTH_BIT;
337 flags |= osgXR::View::CAM_MVR_FIXED_HEIGHT_BIT;
344void VRManager::preReloadCompositor(CameraGroup *cgroup, CameraInfo *info)
346 osgXR::View *xrView = _xrViews[info];
348 auto& passes = info->compositor->getPassList();
349 for (
auto& pass: passes) {
352 auto flags = getPassVRFlags(pass);
354 xrView->removeSlave(pass->camera);
358void VRManager::postReloadCompositor(CameraGroup *cgroup, CameraInfo *info)
360 osgXR::View *xrView = _xrViews[info];
362 auto& passes = info->compositor->getPassList();
363 for (
auto& pass: passes) {
366 xrView->addSlave(pass->camera, flags);
370void VRManager::updateSubView(osgXR::View *view,
unsigned int subviewIndex,
371 const osgXR::View::SubView &subview)
373 auto it = _camInfos.find(view);
374 if (it == _camInfos.end())
377 osg::ref_ptr<CameraInfo> info = (*it).second;
379 osg::Matrix viewMatrix = subview.getViewMatrix();
380 osg::Matrix projMatrix = subview.getProjectionMatrix();
383 viewMatrix = info->viewOffset * viewMatrix;
384 if ((info->flags & CameraInfo::VIEW_ABSOLUTE) == 0) {
385 auto *masterCam = CameraGroup::getDefault()->getView()->getCamera();
386 viewMatrix = masterCam->getViewMatrix() * viewMatrix;
389 auto vp = subview.getViewport();
390 info->compositor->updateSubView(subviewIndex, viewMatrix, projMatrix,
391 osg::Vec4(vp.x, vp.y, vp.w, vp.h));
std::string fgGetString(const char *name, const char *defaultValue)
Get a string value for a property.
FlightPlan.hxx - defines a full flight-plan object, including departure, cruise, arrival information ...
static osg::ref_ptr< VRManager > managerInstance
void reloadCompositors(CameraGroup *cgroup)
Force a reload of all Compositor instances in the CameraGroup, except the one used by the GUI camera.
const char DEFAULT_WINDOW_NAME[]
static osgXR::View::Flags getPassVRFlags(const simgear::compositor::Pass *pass)