// SPDX-License-Identifier: LGPL-2.1-only // Copyright (C) 2021 James Hogan <james@albanarts.com> #include <osgXR/Manager> #include <osgXR/Mirror> #include "XRState.h" #include "XRRealizeOperation.h" using namespace osgXR; Manager::Manager() : _settings(Settings::instance()), _destroying(false), _state(new XRState(_settings, const_cast<Manager *>(this))) { } Manager::~Manager() { } void Manager::setVisibilityMaskNodeMasks(osg::Node::NodeMask left, osg::Node::NodeMask right) const { _state->setVisibilityMaskNodeMasks(left, right); } void Manager::configure(osgViewer::View &view) const { osgViewer::ViewerBase *viewer = _viewer; if (!viewer) viewer = dynamic_cast<osgViewer::ViewerBase *>(&view); if (!viewer) return; _state->setViewer(viewer); // Its rather inconvenient that ViewConfig expects a const configure() // Just cheat and cast away the constness here osg::ref_ptr<XRRealizeOperation> realizeOp = new XRRealizeOperation(_state, &view); viewer->setRealizeOperation(realizeOp); if (viewer->isRealized()) { osgViewer::ViewerBase::Contexts contexts; viewer->getContexts(contexts, true); if (contexts.size() > 0) (*realizeOp)(contexts[0]); } } void Manager::update() { _state->update(); } bool Manager::checkAndResetStateChanged() { return _state->checkAndResetStateChanged(); } bool Manager::getPresent() const { return _state->getUpState() >= XRState::VRSTATE_SYSTEM; } bool Manager::getEnabled() const { return _state->getUpState() == XRState::VRSTATE_ACTIONS; } void Manager::setEnabled(bool enabled) { // Avoid needlessly discarding of the instance // SteamVR 1.15 and 1.16 have issues with xrDestroySession() hanging if (enabled) { _destroying = false; _state->setProbing(true); } else if (_destroying) { _state->setProbing(false); } _state->setDestState(enabled ? XRState::VRSTATE_ACTIONS : _state->getProbingState()); } void Manager::destroyAndWait() { _destroying = true; setEnabled(false); while (_state->isStateUpdateNeeded()) _state->update(); } bool Manager::isDestroying() const { return _destroying; } bool Manager::isRunning() const { return _state->isRunning(); } void Manager::syncSettings() { _state->syncSettings(); } void Manager::syncActionSetup() { _state->syncActionSetup(); } bool Manager::hasValidationLayer() const { return _state->hasValidationLayer(); } bool Manager::hasDepthInfoExtension() const { return _state->hasDepthInfoExtension(); } bool Manager::hasVisibilityMaskExtension() const { return _state->hasVisibilityMaskExtension(); } const char *Manager::getRuntimeName() const { return _state->getRuntimeName(); } const char *Manager::getSystemName() const { return _state->getSystemName(); } const char *Manager::getStateString() const { return _state->getStateString(); } void Manager::onRunning() { } void Manager::onStopped() { } void Manager::onFocus() { } void Manager::onUnfocus() { } void Manager::addMirror(Mirror *mirror) { if (!_state->valid()) { // handle this later, _state may not be created yet _mirrorQueue.push_back(mirror); } else { // init the mirror right away mirror->_init(); } } void Manager::setupMirrorCamera(osg::Camera *camera) { addMirror(new Mirror(this, camera)); } void Manager::_setupMirrors() { // init each mirror in the queue while (!_mirrorQueue.empty()) { _mirrorQueue.front()->_init(); _mirrorQueue.pop_front(); } }