first commit

This commit is contained in:
Your Name
2022-10-20 20:29:11 +08:00
commit 4d531f8044
3238 changed files with 1387862 additions and 0 deletions
+471
View File
@@ -0,0 +1,471 @@
// -*-c++-*-
// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2021 James Hogan <james@albanarts.com>
#ifndef OSGXR_Action
#define OSGXR_Action 1
#include <osgXR/Export>
#include <osg/Quat>
#include <osg/Referenced>
#include <osg/Vec2f>
#include <osg/Vec3f>
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
namespace osgXR {
class ActionSet;
class Subaction;
/**
* Represents an OpenXR action.
* OpenXR actions are inputs & outputs which are abstracted from the physical
* input sources. The OpenXR runtime is responsible for binding them to sources,
* using suggested bindings in interaction profiles.
*
* These Action objects can persist across multiple VR sessions, and changes can
* be made at any time, however some changes won't take effect while a session
* is running.
*/
class OSGXR_EXPORT Action : public osg::Referenced
{
public:
class Private;
protected:
/// Constructor (internal).
Action(Private *priv);
public:
/// Destructor.
~Action();
/**
* Add a subaction that may be later queried.
* Any subaction that is intended to be queried must be added to the
* action first.
* @param subaction Subaction that may be later queried.
*/
void addSubaction(Subaction *subaction);
// Accessors
/**
* Set the action's name and localized name.
* @param name New name for OpenXR action.
* @param localizedName A localized version of @p name.
*/
void setName(const std::string &name,
const std::string &localizedName);
/**
* Set the action's name.
* @param name New name for OpenXR action.
*/
void setName(const std::string &name);
/// Get the action's name.
const std::string &getName() const;
/**
* Set the action's localized name.
* @param localizedName The localized name for the action.
*/
void setLocalizedName(const std::string &localizedName);
/// Get the action's localized name.
const std::string &getLocalizedName() const;
/**
* Get a list of currently bound source paths for this action.
* @param sourcePaths[out] Vector of source paths to write into.
*/
void getBoundSources(std::vector<std::string> &sourcePaths) const;
typedef enum {
// Must match XR_INPUT_SOURCE_LOCALIZED_NAME_*
/// Include user path (e.g. "Left Hand").
USER_PATH_BIT = 1,
/// Include interaction profile (e.g. "Vive Controller").
INTERACTION_PROFILE_BIT = 2,
/// Include input component (e.g. "Trigger").
COMPONENT_BIT = 4,
} LocalizedNameFlags;
/**
* Get a list of currently bound source localized names for this action.
* @param whichComponents Which components to include.
* @param names[out] Vector of names to write into.
*/
void getBoundSourcesLocalizedNames(uint32_t whichComponents,
std::vector<std::string> &names) const;
private:
std::unique_ptr<Private> _private;
// Copying not permitted
Action(const Action &copy);
};
/// An action that can only have boolean values.
class OSGXR_EXPORT ActionBoolean : public Action
{
public:
/**
* Construct a boolean action.
* @param actionSet The action set the action should belong to.
*/
ActionBoolean(ActionSet *actionSet);
/**
* Construct a boolean action.
* @param actionSet The action set the action should belong to.
* @param name The name of the OpenXR action, also used as the
* localized name.
*/
ActionBoolean(ActionSet *actionSet,
const std::string &name);
/**
* Construct a boolean action.
* @param actionSet The action set the action should belong to.
* @param name The name of the OpenXR action.
* @param localizedName The localized name for the action.
*/
ActionBoolean(ActionSet *actionSet,
const std::string &name,
const std::string &localizedName);
/**
* Get the current value of the action as a bool.
* @param subaction The subaction to filter sources from, which must
* have been specified to Action::addSubaction().
* @return The current value of the action.
*/
bool getValue(Subaction *subaction = nullptr);
};
/// An action that can have floating point values.
class OSGXR_EXPORT ActionFloat : public Action
{
public:
/**
* Construct a floating-point action.
* @param actionSet The action set the action should belong to.
*/
ActionFloat(ActionSet *actionSet);
/**
* Construct a floating-point action.
* @param actionSet The action set the action should belong to.
* @param name The name of the OpenXR action, also used as the
* localized name.
*/
ActionFloat(ActionSet *actionSet,
const std::string &name);
/**
* Construct a floating-point action.
* @param actionSet The action set the action should belong to.
* @param name The name of the OpenXR action.
* @param localizedName The localized name for the action.
*/
ActionFloat(ActionSet *actionSet,
const std::string &name,
const std::string &localizedName);
/**
* Get the current value of the action as a float.
* @param subaction The subaction to filter sources from, which must
* have been specified to Action::addSubaction().
* @return The current value of the action.
*/
float getValue(Subaction *subaction = nullptr);
};
/// An action that can have 2 dimentional floating point vector values.
class OSGXR_EXPORT ActionVector2f : public Action
{
public:
/**
* Construct a 2d floating-point vector action.
* @param actionSet The action set the action should belong to.
*/
ActionVector2f(ActionSet *actionSet);
/**
* Construct a 2d floating-point vector action.
* @param actionSet The action set the action should belong to.
* @param name The name of the OpenXR action, also used as the
* localized name.
*/
ActionVector2f(ActionSet *actionSet,
const std::string &name);
/**
* Construct a 2d floating-point vector action.
* @param actionSet The action set the action should belong to.
* @param name The name of the OpenXR action.
* @param localizedName The localized name for the action.
*/
ActionVector2f(ActionSet *actionSet,
const std::string &name,
const std::string &localizedName);
/**
* Get the current value of the action as an OSG vector.
* @param subaction The subaction to filter sources from, which must
* have been specified to Action::addSubaction().
* @return The current value of the action.
*/
osg::Vec2f getValue(Subaction *subaction = nullptr);
};
/// An action that can have pose (position and orientation) values.
class OSGXR_EXPORT ActionPose : public Action
{
public:
/**
* Construct a pose action.
* @param actionSet The action set the action should belong to.
*/
ActionPose(ActionSet *actionSet);
/**
* Construct a pose action.
* @param actionSet The action set the action should belong to.
* @param name The name of the OpenXR action, also used as the
* localized name.
*/
ActionPose(ActionSet *actionSet,
const std::string &name);
/**
* Construct a pose action.
* @param actionSet The action set the action should belong to.
* @param name The name of the OpenXR action.
* @param localizedName The localized name for the action.
*/
ActionPose(ActionSet *actionSet,
const std::string &name,
const std::string &localizedName);
/**
* Represents a pose action's position and orientation.
* This represents a pose action's position and orientation, along with
* flags to indicate whether each of these are valid and whether they're
* currently tracked (as opposed to estimated based on recent tracking).
*/
class OSGXR_EXPORT Location
{
public:
typedef enum {
// Must match XR_SPACE_LOCATION_* */
ORIENTATION_VALID_BIT = 0x1,
POSITION_VALID_BIT = 0x2,
ORIENTATION_TRACKED_BIT = 0x4,
POSITION_TRACKED_BIT = 0x8,
} Flags;
// Constructors
/// Construct a pose action location.
Location();
/// Construct a pose action location.
Location(Flags flags,
const osg::Quat &orientation,
const osg::Vec3f &position);
// Accessors
/**
* Find whether the orientation is valid.
* If not, the orientation is undefined.
* @return Whether the orientation is valid.
*/
bool isOrientationValid() const
{
return _flags & ORIENTATION_VALID_BIT;
}
/**
* Find whether the position is valid.
* If not, the position is undefined.
* @return Whether the position is valid.
*/
bool isPositionValid() const
{
return _flags & POSITION_VALID_BIT;
}
/**
* Find whether the orientation is being tracked.
* If not, the orientation may only be an estimate.
* @return Whether the orientation is being tracked.
*/
bool isOrientationTracked() const
{
return _flags & ORIENTATION_TRACKED_BIT;
}
/**
* Find whether the position is being tracked.
* If not, the position may only be an estimate.
* @return Whether the position is being tracked.
*/
bool isPositionTracked() const
{
return _flags & POSITION_TRACKED_BIT;
}
/// Get the flags which indicate validity and tracking.
Flags getFlags() const
{
return _flags;
}
/**
* Get the pose action's orientation as a quaternion.
* Get the pose action's orientation relative to the default
* reference space as an OSG quaternion.
*
* The orientation is undefined if isOrientationValid() returns
* false.
*
* The orientation may only be an estimate if
* isOrientationTracked() returns false.
*/
const osg::Quat &getOrientation() const
{
return _orientation;
}
/**
* Get the pose action's position as a 3D vector.
* Get the pose action's position relative to the default
* reference space as an OSG 3D vector.
*
* The position is undefined if isPositionValid() returns false.
*
* The position may only be an estimate if isPositionTracked()
* returns false.
*/
const osg::Vec3f &getPosition() const
{
return _position;
}
// Comparison operators
bool operator != (const Location &other) const
{
return _flags != other._flags ||
(isOrientationValid() && _orientation != other._orientation) ||
(isPositionValid() && _position != other._position);
}
bool operator == (const Location &other) const
{
return !operator != (other);
}
protected:
Flags _flags;
osg::Quat _orientation;
osg::Vec3f _position;
};
/**
* Get the current pose of the action as a Location object.
* @param subaction The subaction to filter sources from, which must
* have been specified to Action::addSubaction().
* @return The current pose of the action.
*/
Location getValue(Subaction *subaction = nullptr);
};
/// An output action for vibration.
class OSGXR_EXPORT ActionVibration : public Action
{
public:
/**
* Construct a vibration output action.
* @param actionSet The action set the action should belong to.
*/
ActionVibration(ActionSet *actionSet);
/**
* Construct a vibration output action.
* @param actionSet The action set the action should belong to.
* @param name The name of the OpenXR action, also used as the
* localized name.
*/
ActionVibration(ActionSet *actionSet,
const std::string &name);
/**
* Construct a vibration output action.
* @param actionSet The action set the action should belong to.
* @param name The name of the OpenXR action.
* @param localizedName The localized name for the action.
*/
ActionVibration(ActionSet *actionSet,
const std::string &name,
const std::string &localizedName);
enum {
/// Indicates a minimum supported durection for a haptic device.
DURATION_MIN = -1,
/// Indicates an optimal frequency for a haptic pulse.
FREQUENCY_UNSPECIFIED = 0,
};
/**
* Apply haptic feedback.
* @param duration_ns Duration of vibration in nanoseconds.
* @param frequency Frequency of vibration in Hz.
* @param amplitude Amplitude of vibration between 0.0 and 1.0.
* @return true on success, false otherwise.
*/
bool applyHapticFeedback(int64_t duration_ns, float frequency,
float amplitude);
/**
* Apply haptic feedback.
* @param subaction The subaction to apply haptics to, which must
* have been specified to Action::addSubaction().
* @param duration_ns Duration of vibration in nanoseconds.
* @param frequency Frequency of vibration in Hz.
* @param amplitude Amplitude of vibration between 0.0 and 1.0.
* @return true on success, false otherwise.
*/
bool applyHapticFeedback(Subaction *subaction,
int64_t duration_ns, float frequency,
float amplitude);
/**
* Stop any in-progress haptic feedback.
* @param subaction The subaction to apply haptics to, which must
* have been specified to Action::addSubaction().
* @return true on success, false otherwise.
*/
bool stopHapticFeedback(Subaction *subaction = nullptr);
};
}
#endif
+138
View File
@@ -0,0 +1,138 @@
// -*-c++-*-
// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2021 James Hogan <james@albanarts.com>
#ifndef OSGXR_ActionSet
#define OSGXR_ActionSet 1
#include <osgXR/Export>
#include <osg/Referenced>
#include <cstdint>
#include <memory>
#include <string>
namespace osgXR {
class Manager;
class Subaction;
/**
* Represents a group of OpenXR actions.
* Action sets are attached to the OpenXR session, and can be dynamically
* activated and deactivated.
*/
class OSGXR_EXPORT ActionSet : public osg::Referenced
{
public:
/**
* Construct an action set.
* @param manager The VR manager object to add the action set to.
*/
ActionSet(Manager *manager);
/**
* Construct an action set.
* @param manager The VR manager object to add the action set to.
* @param name The name of the OpenXR action set, also used as the
* localized name.
*/
ActionSet(Manager *manager,
const std::string &name);
/**
* Construct an action set.
* @param manager The VR manager object to add the action set to.
* @param name The name of the OpenXR action set.
* @param localizedName The localized name for the action set.
*/
ActionSet(Manager *manager,
const std::string &name,
const std::string &localizedName);
/// Destructor.
~ActionSet();
// Accessors
/**
* Set the action set's name and localized name.
* @param name New name for OpenXR action set.
* @param localizedName A localized version of @p name.
*/
void setName(const std::string &name,
const std::string &localizedName);
/**
* Set the action set's name.
* @param name New name for OpenXR action set.
*/
void setName(const std::string &name);
/// Get the action's name.
const std::string &getName() const;
/**
* Set the action set's localized name.
* @param localizedName The localized name for the action set.
*/
void setLocalizedName(const std::string &localizedName);
/// Get the action set's localized name.
const std::string &getLocalizedName() const;
/**
* Set the priority of the action set.
* @param priority New priority of the action set. Larger priority
* action sets take precedence over smaller priority
* action sets.
*/
void setPriority(uint32_t priority);
/// Get the priority of the action set.
uint32_t getPriority() const;
// Activation of the action set
/**
* Activate the action set within a subaction.
* Set the action set as active so that its actions (filtered by
* subaction) are synchronised each frame. If @p subaction is nullptr,
* all subactions in the set will be synchronised, otherwise multiple
* subactions can be activated by multiple calls.
* @param subaction The subaction to activate this action set within.
* May be nullptr (default) in which case all
* subactions are activated.
*/
void activate(Subaction *subaction = nullptr);
/**
* Deactivate the action set within a subaction.
* Set the action set as inactive so that its actions (filtered by
* subaction) are no longer synchronised each frame. If @p subaction is
* nullptr, any full activation is removed, otherwise multiple
* subactions can be deactivated by multiple calls.
* @param subaction The subaction to deactivate this action set within.
* May be nullptr (default) in which case all
* subactions activations are removed.
*/
void deactivate(Subaction *subaction = nullptr);
/**
* Find whether the action set is activated for any subactions.
* @return Whether any subactions are activated for this action set.
*/
bool isActive();
class Private;
private:
std::unique_ptr<Private> _private;
// Copying not permitted
ActionSet(const ActionSet &copy);
};
}
#endif
+75
View File
@@ -0,0 +1,75 @@
// -*-c++-*-
// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2022 James Hogan <james@albanarts.com>
#ifndef OSGXR_CompositionLayer
#define OSGXR_CompositionLayer 1
#include <osgXR/Export>
#include <osg/Referenced>
#include <memory>
namespace osgXR {
/**
* Represents an OpenXR composition layer.
*/
class OSGXR_EXPORT CompositionLayer : public osg::Referenced
{
public:
class Private;
protected:
/// Constructor (internal).
CompositionLayer(Private *priv);
public:
/// Destructor.
~CompositionLayer();
// Accessors
/// Set whether the layer should be submitted to OpenXR.
void setVisible(bool visible);
/// Get whether the layer should be submitted to OpenXR (default: true).
bool getVisible() const;
/**
* Set ordering index.
* The default projection layer will have an order of 0, so layers with
* positive order indices will be composited in front, and negative
* behind.
*/
void setOrder(int order);
/// Get ordering index (default 1).
int getOrder() const;
typedef enum {
/// No blending, alpha treated as 1.
BLEND_NONE,
/// Per pixel alpha, with color values premultiplied by alpha.
BLEND_ALPHA_PREMULT,
/// Per pixel alpha, with color values unassociated with alpha.
BLEND_ALPHA_UNPREMULT,
} AlphaMode;
/// Set layer's alpha mode.
void setAlphaMode(AlphaMode mode);
/// Get layer's alpha mode (default: BLEND_NONE).
AlphaMode getAlphaMode() const;
private:
std::unique_ptr<Private> _private;
// Copying not permitted
CompositionLayer(const CompositionLayer &copy);
};
}
#endif
+76
View File
@@ -0,0 +1,76 @@
// -*-c++-*-
// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2022 James Hogan <james@albanarts.com>
#ifndef OSGXR_CompositionLayerQuad
#define OSGXR_CompositionLayerQuad 1
#include <osgXR/Export>
#include <osgXR/CompositionLayer>
#include <osg/Quat>
#include <osg/Referenced>
#include <osg/Vec2f>
#include <osg/Vec3f>
namespace osgXR {
class Manager;
class SubImage;
class Swapchain;
/**
* Represents an OpenXR quad composition layer.
*/
class OSGXR_EXPORT CompositionLayerQuad : public CompositionLayer
{
public:
/// Constructor.
CompositionLayerQuad(Manager *manager);
/// Destructor.
~CompositionLayerQuad();
// Accessors
typedef enum {
// Must match XR_EYE_VISIBILITY_*
/// Display layer to both eyes.
EYES_BOTH = 0,
/// Display layer only to left eye.
EYES_LEFT = 1,
/// Display layer only to right eye.
EYES_RIGHT = 2,
} EyeVisibility;
/// Set eye visibility.
void setEyeVisibility(EyeVisibility eyes);
/// Get eye visibility (default: EYES_BOTH).
EyeVisibility getEyeVisibility() const;
/// Set swapchain.
void setSubImage(Swapchain *swapchain);
/// Set swapchain subimage.
void setSubImage(const SubImage &subimage);
/// Get swapchain subimage.
const SubImage &getSubImage() const;
/// Set orientation of quad normal (+ve Z).
void setOrientation(const osg::Quat &quat);
/// Get orientation of quad normal (+ve Z).
const osg::Quat &getOrientation() const;
/// Set center position of quad.
void setPosition(const osg::Vec3f &pos);
/// Get center position of quad (default: 0, 0, -1m).
const osg::Vec3f &getPosition() const;
/// Set size of quad in meters.
void setSize(const osg::Vec2f &size);
/// Get size of quad in meters (default 1m*1m).
const osg::Vec2f &getSize() const;
};
}
#endif
+22
View File
@@ -0,0 +1,22 @@
// -*-c++-*-
// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2021 James Hogan <james@albanarts.com>
#ifndef OSGXR_Export
#define OSGXR_Export 1
#include <osgXR/Config>
#if defined(_MSC_VER) || defined(__CYGWIN__) || defined(__MINGW32__)
#if defined(OSGXR_STATIC_LIBRARY)
#define OSGXR_EXPORT
#elif defined(OSGXR_LIBRARY)
#define OSGXR_EXPORT __declspec(dllexport)
#else
#define OSGXR_EXPORT __declspec(dllimport)
#endif
#else
#define OSGXR_EXPORT
#endif
#endif
+74
View File
@@ -0,0 +1,74 @@
// -*-c++-*-
// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2021 James Hogan <james@albanarts.com>
#ifndef OSGXR_InteractionProfile
#define OSGXR_InteractionProfile 1
#include <osgXR/Export>
#include <osg/Referenced>
#include <memory>
#include <string>
namespace osgXR {
class Action;
class Manager;
/**
* Represents a group of suggested bindings for a specific interaction profile.
* This class allow the application to suggest bindings for actions to specific
* input paths for a given interaction profile. If the OpenXR runtime recognises
* the profile it may use the suggested bindings to bind actions to whichever
* input devices the user may have, even without a specific binding to that
* device.
*/
class OSGXR_EXPORT InteractionProfile : public osg::Referenced
{
public:
/**
* Construct an interaction profile.
* The OpenXR interaction profile path is constructed as
* "/interaction_profiles/@p vendor /@p type ".
* @param manager The VR manager object to add the action set to.
* @param vendor Vendor segment of OpenXR interaction profile path.
* @param type Type segment of OpenXR interaction profile path.
*/
InteractionProfile(Manager *manager,
const std::string &vendor,
const std::string &type);
/// Destructor
~InteractionProfile();
// Accessors
/// Get the vendor segment of the OpenXR interaction profile path.
const std::string &getVendor() const;
/// Get the type segment of the OpenXR interaction profile path.
const std::string &getType() const;
/**
* Suggest a binding for an action.
* @param action The action to bind.
* @param binding The OpenXR path to bind the action to.
*/
void suggestBinding(Action *action, const std::string &binding);
class Private;
private:
std::unique_ptr<Private> _private;
// Copying not permitted
InteractionProfile(const InteractionProfile &copy);
};
}
#endif
+237
View File
@@ -0,0 +1,237 @@
// -*-c++-*-
// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2021 James Hogan <james@albanarts.com>
#ifndef OSGXR_Manager
#define OSGXR_Manager 1
#include <osg/Camera>
#include <osg/Node>
#include <osg/ref_ptr>
#include <osgViewer/View>
#include <osgViewer/ViewerBase>
#include <osgXR/Export>
#include <osgXR/Mirror>
#include <osgXR/Settings>
#include <osgXR/View>
#include <list>
namespace osgXR {
// Internal state class
class XRState;
/**
* Public VR state manager class.
* Applications can extend this class to allow tighter integration with osgXR.
*/
class OSGXR_EXPORT Manager : public osgViewer::ViewConfig
{
public:
Manager();
virtual ~Manager();
/// Use if viewer is a CompositeViewer.
void setViewer(osgViewer::ViewerBase *viewer)
{
_viewer = viewer;
}
/// Set the NodeMasks to use for visibility masks.
void setVisibilityMaskNodeMasks(osg::Node::NodeMask left,
osg::Node::NodeMask right) const;
void configure(osgViewer::View& view) const override;
/**
* Perform a regular update.
* This will poll for OpenXR events, and handle any pending VR start /
* stop operations (possibly invoking the Manager's view callbacks).
* Some of these operations require threading on the viewer to be
* temporarily stopped, but in all cases it is started again.
*/
virtual void update();
/// Find whether state has changed since last call, and reset.
bool checkAndResetStateChanged();
/// Find whether VR seems to be present.
bool getPresent() const;
/**
* Get whether VR is currently set to be enabled.
* When enabled, osgXR will try to keep VR running.
* @return Whether VR is enabled
*/
bool getEnabled() const;
/**
* Set whether VR is currently set to be enabled.
* When enabled, osgXR will try to keep VR running.
* @param enabled Whether VR is enabled.
*/
void setEnabled(bool enabled);
/**
* Start destroying the VR state and wait for safe shutdown.
*/
void destroyAndWait();
/**
* Find whether this manager is in the process of being destroyed.
*/
bool isDestroying() const;
/**
* Get whether a VR session is currently running.
* @return Whether a VR session is currently running.
*/
bool isRunning() const;
/// Arrange reinit as needed for new settings.
void syncSettings();
/// Arrange reinit as needed of action setup.
void syncActionSetup();
/*
* OpenXR information.
*/
/**
* Find whether OpenXR's validation layer is supported.
* This looks to see whether the OpenXR validation API layer (i.e.
* XR_APILAYER_LUNARG_core_validation) is available.
*/
bool hasValidationLayer() const;
/**
* Find whether OpenXR supports the submission of depth information.
* This looks to see whether the OpenXR instance extension for
* submitting depth information to help the runtime perform better
* reprojection (i.e. XR_KHR_composition_layer_depth) is available.
*/
bool hasDepthInfoExtension() const;
/**
* Find whether OpenXR supports the visibility mask extension.
* This looks to see whether the OpenXR instance extension for getting
* visibility masks is available, which can be used to reduce fragment
* load.
*/
bool hasVisibilityMaskExtension() const;
/// Find the name of the OpenXR runtime.
const char *getRuntimeName() const;
/// Find the name of the OpenXR system in use.
const char *getSystemName() const;
/// Get a string describing the state (for user consumption).
const char *getStateString() const;
/*
* For implementation by derived classes.
*/
/**
* Callback telling the app to configure a new view.
* This callback allows osgXR to tell the app to configure a new view of
* the world. The application should notify osgXR of the addition and
* removal of slave cameras which osgXR should hook into using the
* osgXR::View parameter.
* The implementation may stop threading, and it will be started again
* before update() returns.
* @param xrView The new osgXR::View with a public API to allow the
* application to retrieve what it needs in relation to
* the view and to inform osgXR of changes.
*/
virtual void doCreateView(View *xrView) = 0;
/**
* Callback telling the app to destroy an existing view.
* This callback allows osgXR to tell the app to remove an existing view
* of the world that it had requested via doCreateView(). The
* application should notify osgXR of the removal of any slave cameras
* which it has already informed osgXR about.
* The implementation may stop threading, and it will be started again
* before update() returns.
*/
virtual void doDestroyView(View *xrView) = 0;
/**
* Callback telling the app that the VR session is now running.
* This happens after the OpenXR session has started running, and views
* have been configured (see doCreateView()). The app should start
* rendering the VR views, and may choose to reconfigure the desktop
* window to make a VR mirror visible.
*/
virtual void onRunning();
/**
* Callback telling the app that the VR session has now stopped.
* This happens after the OpenXR session has stopped, and views have
* been removed (see doDestroyView()). The app should stop rendering the
* VR views, and may choose to reconfigure the desktop window so as to
* no longer show a VR mirror.
*/
virtual void onStopped();
/**
* Callback telling the app that the VR session is in focus.
* This happens when the VR session enters focus and can get VR input
* from the user. The app may choose to resume the experience if it was
* previously paused due to onUnfocus().
*/
virtual void onFocus();
/**
* Callback telling the app that the VR session is no longer in focus.
* This happens when the VR session leaves focus and can no longer get
* VR input from the user. The VR runtime may be presenting a modal
* pop-up on top of the application's rendered frames. The app may
* choose to pause the experience.
*/
virtual void onUnfocus();
/// Add a custom mirror to the queue of mirrors to configure.
void addMirror(Mirror *mirror);
/// Set up a camera to render a VR mirror.
void setupMirrorCamera(osg::Camera *camera);
/*
* Internal
*/
inline Settings *_getSettings()
{
return _settings.get();
}
inline XRState *_getXrState()
{
return _state;
}
void _setupMirrors();
protected:
osg::ref_ptr<osgViewer::ViewerBase> _viewer;
osg::ref_ptr<Settings> _settings;
bool _destroying;
private:
std::list<osg::ref_ptr<Mirror> > _mirrorQueue;
osg::ref_ptr<XRState> _state;
};
}
#endif
+50
View File
@@ -0,0 +1,50 @@
// -*-c++-*-
// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2021 James Hogan <james@albanarts.com>
#ifndef OSGXR_Mirror
#define OSGXR_Mirror 1
#include <osg/Camera>
#include <osg/Referenced>
#include <osg/ref_ptr>
#include <osgXR/Export>
#include <osgXR/MirrorSettings>
namespace osgXR {
class Manager;
/**
* Public VR mirror class.
*/
class OSGXR_EXPORT Mirror : public osg::Referenced
{
public:
Mirror(Manager *manager, osg::Camera *camera);
virtual ~Mirror();
/*
* internal
*/
// Called when enough is known about OpenXR system
void _init();
private:
void setupQuad(unsigned int viewIndex,
float x, float w);
osg::observer_ptr<Manager> _manager;
osg::observer_ptr<osg::Camera> _camera;
MirrorSettings _mirrorSettings;
};
}
#endif
+72
View File
@@ -0,0 +1,72 @@
// -*-c++-*-
// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2021 James Hogan <james@albanarts.com>
#ifndef OSGXR_MirrorSettings
#define OSGXR_MirrorSettings 1
#include <osgXR/Export>
namespace osgXR {
class OSGXR_EXPORT MirrorSettings
{
public:
MirrorSettings();
/// Equality operator.
bool operator == (const MirrorSettings &other) const
{
return _mirrorMode == other._mirrorMode &&
(_mirrorMode != MIRROR_SINGLE ||
_mirrorViewIndex == other._mirrorViewIndex);
}
/// Inequality operator.
bool operator != (const MirrorSettings &other) const
{
return _mirrorMode != other._mirrorMode ||
(_mirrorMode == MIRROR_SINGLE &&
_mirrorViewIndex != other._mirrorViewIndex);
}
/// Type of VR mirror to show.
typedef enum MirrorMode
{
/// Choose automatically.
MIRROR_AUTOMATIC,
/// Render nothing to the mirror.
MIRROR_NONE,
/// Render a single view fullscreen to the mirror.
MIRROR_SINGLE,
/// Render left & right views side by side.
MIRROR_LEFT_RIGHT,
} MirrorMode;
/// Set the mirror mode to use.
void setMirror(MirrorMode mode, int viewIndex = -1)
{
_mirrorMode = mode;
_mirrorViewIndex = viewIndex;
}
/// Get the mirror mode to use.
MirrorMode getMirrorMode() const
{
return _mirrorMode;
}
/// Get the mirror view index.
int getMirrorViewIndex() const
{
return _mirrorViewIndex;
}
protected:
// Mirror mode
MirrorMode _mirrorMode;
int _mirrorViewIndex;
};
}
#endif
+49
View File
@@ -0,0 +1,49 @@
// -*-c++-*-
// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2021 James Hogan <james@albanarts.com>
#ifndef OSGXR_OpenXRDisplay
#define OSGXR_OpenXRDisplay 1
#include <osgXR/Export>
#include <osgXR/Settings>
#include <osg/Referenced>
#include <osg/ref_ptr>
#include <osgViewer/View>
#include <cinttypes>
#include <string>
namespace osgXR {
class XRState;
/** a camera for each OpenXR view.*/
class OSGXR_EXPORT OpenXRDisplay : public osgViewer::ViewConfig
{
public:
OpenXRDisplay();
OpenXRDisplay(Settings *settings);
OpenXRDisplay(const OpenXRDisplay& rhs,
const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY);
virtual ~OpenXRDisplay();
META_Object(osgXR, OpenXRDisplay);
void configure(osgViewer::View& view) const override;
protected:
osg::ref_ptr<Settings> _settings;
// Internal OpenXR state object
// FIXME this should probably belong elsewhere
mutable osg::ref_ptr<XRState> _state;
};
}
#endif
+529
View File
@@ -0,0 +1,529 @@
// -*-c++-*-
// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2021 James Hogan <james@albanarts.com>
#ifndef OSGXR_Settings
#define OSGXR_Settings 1
#include <osg/Referenced>
#include <osgXR/Export>
#include <osgXR/MirrorSettings>
#include <string>
namespace osgXR {
/// Encapsulates osgXR / OpenXR settings data.
class OSGXR_EXPORT Settings : public osg::Referenced
{
public:
/*
* Instance management.
*/
Settings();
virtual ~Settings();
/// Get the default/global instance of Settings.
static Settings *instance();
/*
* OpenXR application information.
*/
/**
* Set the application's name and version to expose to OpenXR.
* These will be used to create an OpenXR instance.
* @param appName Name of the application.
* @param appVersion 32-bit version number of the application.
*/
void setApp(const std::string &appName, uint32_t appVersion)
{
_appName = appName;
_appVersion = appVersion;
}
/**
* Set the application's name to expose to OpenXR.
* This will be used to create an OpenXR instance.
* @param appName Name of the application.
*/
void setAppName(const std::string &appName)
{
_appName = appName;
}
/// Get the application's name to expose to OpenXR.
const std::string &getAppName() const
{
return _appName;
}
/**
* Set the application's version to expose to OpenXR.
* This will be used to create an OpenXR instance.
* @param appVersion 32-bit version number of the application.
*/
void setAppVersion(uint32_t appVersion)
{
_appVersion = appVersion;
}
/// Get the application's 32-bit version number to expose to OpenXR.
uint32_t getAppVersion() const
{
return _appVersion;
}
/*
* osgXR configuration settings.
*/
/**
* Set whether to try enabling OpenXR's validation layer.
* This controls whether the OpenXR validation API layer (i.e.
* XR_APILAYER_LUNARG_core_validation) will be enabled when creating an
* OpenXR instance.
* By default this is disabled.
* @param validationLayer Whether to try enabling the validation layer.
*/
void setValidationLayer(bool validationLayer)
{
_validationLayer = validationLayer;
}
/// Get whether to try enabling OpenXR's validation layer.
bool getValidationLayer() const
{
return _validationLayer;
}
/**
* Set whether to enable submission of depth information to OpenXR.
* This controls whether the OpenXR instance depth information extension
* (i.e XR_KHR_composition_layer_depth) will be used to submit depth
* information to OpenXR to allow improved reprojection.
* This is currently disabled by default.
* @param depthInfo Whether to enable submission of depth information.
*/
void setDepthInfo(bool depthInfo)
{
_depthInfo = depthInfo;
}
/// Get whether to enable submission of depth information to OpenXR.
bool getDepthInfo() const
{
return _depthInfo;
}
/**
* Set whether to create visibility masks.
* This controls whether the OpenXR instance visibility mask extension
* (i.e. XR_KHR_visibility_mask) will be used to create and update
* visibility masks for each VR view in order to mask hidden fragments.
* This is enabled by default.
* @param visibilityMask Whether to create visibility masks.
*/
void setVisibilityMask(bool visibilityMask)
{
_visibilityMask = visibilityMask;
}
/// Get whether to create visibility masks.
bool getVisibilityMask() const
{
return _visibilityMask;
}
/// OpenXR system orm factors.
typedef enum FormFactor
{
/// A display mounted to the user's head.
HEAD_MOUNTED_DISPLAY,
/// A display held in the user's hands.
HANDHELD_DISPLAY,
} FormFactor;
/**
* Set which OpenXR form factor to use.
* This controls which OpenXR form factor to try to use. The default is
* HEAD_MOUNTED_DISPLAY.
* @param formFactor Form factor to use.
*/
void setFormFactor(FormFactor formFactor)
{
_formFactor = formFactor;
}
/// Get which OpenXR form factor to use.
FormFactor getFormFactor() const
{
return _formFactor;
}
/// Modes for blending layers onto the user's view of the real world.
typedef enum BlendMode
{
// Matches XrEnvironmentBlendMode
/// Display layers with no view of physical world behind.
BLEND_MODE_OPAQUE = 1,
/// Additively blend layers with view of physical world behind.
BLEND_MODE_ADDITIVE = 2,
/// Alpha blend layers with view of physical world behind.
BLEND_MODE_ALPHA_BLEND = 3,
} BlendMode;
/**
* Specify a preferred environment blend mode.
* The chosen environment blend mode is allowed for use, and will be
* chosen in preference to any other supported environment blend modes
* specified by allowEnvBlendMode() if supported by OpenXR.
* @param mode Environment blend mode to prefer.
*/
void preferEnvBlendMode(BlendMode mode)
{
uint32_t mask = (1u << (unsigned int)mode);
_preferredEnvBlendModeMask |= mask;
_allowedEnvBlendModeMask |= mask;
}
/**
* Specify an allowed environment blend mode.
* The chosen environment blend mode is allowed for use, and may be
* chosen if supported by OpenXR when none of the preferred environment
* blend modes specified by preferEnvBlendMode() are supported by
* OpenXR.
* @param mode Environment blend mode to prefer.
*/
void allowEnvBlendMode(BlendMode mode)
{
uint32_t mask = (1u << (unsigned int)mode);
_allowedEnvBlendModeMask |= mask;
}
/// Get the bitmask of preferred environment blend modes.
uint32_t getPreferredEnvBlendModeMask() const
{
return _preferredEnvBlendModeMask;
}
/// Set the bitmask of preferred environment blend modes.
void setPreferredEnvBlendModeMask(uint32_t preferredEnvBlendModeMask)
{
_preferredEnvBlendModeMask = preferredEnvBlendModeMask;
}
/// Get the bitmask of allowed environment blend modes.
uint32_t getAllowedEnvBlendModeMask() const
{
return _allowedEnvBlendModeMask;
}
/// Set the bitmask of allowed environment blend modes.
void setAllowedEnvBlendModeMask(uint32_t allowedEnvBlendModeMask)
{
_allowedEnvBlendModeMask = allowedEnvBlendModeMask;
}
/// Techniques for rendering multiple views.
typedef enum VRMode
{
/// Choose automatically.
VRMODE_AUTOMATIC,
/** Create a slave camera for each view.
* Either separate swapchains, or single with multiple viewports.
*/
VRMODE_SLAVE_CAMERAS,
/** Use the OSG SceneView stereo functionality.
* No extra slave cameras.
* Only supports SWAPCHAIN_SINGLE with stereo.
*/
VRMODE_SCENE_VIEW,
} VRMode;
/// Set the rendering technique to use.
void setVRMode(VRMode mode)
{
_vrMode = mode;
}
/// Get the rendering technique to use.
VRMode getVRMode() const
{
return _vrMode;
}
/// Techniques for managing swapchains.
typedef enum SwapchainMode
{
/// Choose automatically.
SWAPCHAIN_AUTOMATIC,
/// Create a 2D swapchain per view.
SWAPCHAIN_MULTIPLE,
/** Create a single 2D swapchain with a viewport per view.
* Stack them horizontally.
*/
SWAPCHAIN_SINGLE,
} SwapchainMode;
/// Set the swapchain management technique to use.
void setSwapchainMode(SwapchainMode mode)
{
_swapchainMode = mode;
}
/// Get the swapchain management technique to use.
SwapchainMode getSwapchainMode() const
{
return _swapchainMode;
}
/// RGB(A) / depth encodings.
typedef enum Encoding
{
/** Discrete linear encoding of RGB(A).
* The OpenXR runtime may perform its own conversion from RGB to
* sRGB for display on HMD, so the app should ensure it leaves RGB
* values linear to avoid an over-bright image.
*/
ENCODING_LINEAR = 0,
/** Floating-point linear encoding of RGB(A).
* The OpenXR runtime may perform its own conversion from RGB to
* sRGB for display on HMD, so the app should ensure it leaves RGB
* values linear to avoid an over-bright image.
*/
ENCODING_FLOAT = 1,
/** Discrete non-linear sRGB encoding with linear (A).
* Linear RGB values should be converted to sRGB, for example with
* GL_FRAMEBUFFER_SRGB or via fragment shader code, as the OpenXR
* runtime will treat them as non-linear.
* Not applicable to depth/stencil swapchains.
*/
ENCODING_SRGB = 2,
} Encoding;
/**
* Specify a preferred RGB(A) encoding.
* The chosen RGB(A) encoding is allowed for use, and a format with this
* encoding will be chosen in preference to other allowed encodings
* specified by allowRGBEncoding() if possible.
* @param encoding RGB(A) encoding to prefer.
*/
void preferRGBEncoding(Encoding encoding)
{
uint32_t mask = (1u << (unsigned int)encoding);
_preferredRGBEncodingMask |= mask;
_allowedRGBEncodingMask |= mask;
}
/**
* Specify an allowed RGB(A) encoding.
* The chosen RGB(A) encoding is allowed for use, and a format with this
* encoding may be chosen when none of the preferred color encodings
* specified by preferRGBEncoding() are useable.
* @param encoding RGB(A) encoding to permit.
*/
void allowRGBEncoding(Encoding encoding)
{
uint32_t mask = (1u << (unsigned int)encoding);
_allowedRGBEncodingMask |= mask;
}
/// Get the bitmask of preferred RGB(A) encodings.
uint32_t getPreferredRGBEncodingMask() const
{
return _preferredRGBEncodingMask;
}
/// Set the bitmask of preferred RGB(A) encodings.
void setPreferredRGBEncodingMask(uint32_t preferredRGBEncodingMask)
{
_preferredRGBEncodingMask = preferredRGBEncodingMask;
}
/// Get the bitmask of allowed RGB(A) encodings.
uint32_t getAllowedRGBEncodingMask() const
{
return _allowedRGBEncodingMask;
}
/// Set the bitmask of allowed RGB(A) encodings.
void setAllowedRGBEncodingMask(uint32_t allowedRGBEncodingMask)
{
_allowedRGBEncodingMask = allowedRGBEncodingMask;
}
/**
* Specify a preferred depth encoding.
* The chosen depth encoding is allowed for use, and a format with this
* encoding will be chosen in preference to other allowed encodings
* specified by allowDepthEncoding() if possible.
* @param encoding Depth encoding to prefer.
*/
void preferDepthEncoding(Encoding encoding)
{
uint32_t mask = (1u << (unsigned int)encoding);
_preferredDepthEncodingMask |= mask;
_allowedDepthEncodingMask |= mask;
}
/**
* Specify an allowed depth encoding.
* The chosen depth encoding is allowed for use, and a format with this
* encoding may be chosen when none of the preferred color encodings
* specified by preferDepthEncoding() are useable.
* @param encoding Depth encoding to permit.
*/
void allowDepthEncoding(Encoding encoding)
{
uint32_t mask = (1u << (unsigned int)encoding);
_allowedDepthEncodingMask |= mask;
}
/// Get the bitmask of preferred depth encodings.
uint32_t getPreferredDepthEncodingMask() const
{
return _preferredDepthEncodingMask;
}
/// Set the bitmask of preferred depth encodings.
void setPreferredDepthEncodingMask(uint32_t preferredDepthEncodingMask)
{
_preferredDepthEncodingMask = preferredDepthEncodingMask;
}
/// Get the bitmask of allowed depth encodings.
uint32_t getAllowedDepthEncodingMask() const
{
return _allowedDepthEncodingMask;
}
/// Set the bitmask of allowed depth encodings.
void setAllowedDepthEncodingMask(uint32_t allowedDepthEncodingMask)
{
_allowedDepthEncodingMask = allowedDepthEncodingMask;
}
/**
* Get number of desired bits for each RGB channel in RGB(A) swapchain.
* This only applies to linear RGB formats, not sRGB formats.
*/
int getRGBBits() const
{
return _rgbBits;
}
/**
* Set number of desired bits for each RGB channel in RGB(A) swapchain.
* This only applies to linear RGB formats, not sRGB formats.
*/
void setRGBBits(int rgbBits = -1)
{
_rgbBits = rgbBits;
}
/// Get number of desired alpha bits in RGB(A) swapchain.
int getAlphaBits() const
{
return _alphaBits;
}
/// Set the number of desired alpha bits in RGB(A) swapchain.
void setAlphaBits(int alphaBits = -1)
{
_alphaBits = alphaBits;
}
/// Get number of desired depth bits in depth/stencil swapchain.
int getDepthBits() const
{
return _depthBits;
}
/// Set the number of desired depth bits in depth/stencil swapchain.
void setDepthBits(int depthBits = -1)
{
_depthBits = depthBits;
}
/// Get number of desired stencil bits in depth/stencil swapchain.
int getStencilBits() const
{
return _stencilBits;
}
/// Set the number of desired stenil bits in depth/stencil swapchain.
void setStencilBits(int stencilBits = -1)
{
_stencilBits = stencilBits;
}
/// Get mirror settings.
MirrorSettings &getMirrorSettings()
{
return _mirrorSettings;
}
/// Get mirror settings.
const MirrorSettings &getMirrorSettings() const
{
return _mirrorSettings;
}
/**
* Set the number of virtual world units to fit per real world meter.
* This controls the size of the user relative to the virtual world, by
* scaling down the size of the world.
* @param unitsPerMeter The number of units per real world meter.
*/
void setUnitsPerMeter(float unitsPerMeter)
{
_unitsPerMeter = unitsPerMeter;
}
/// Get the number of virtual world units to fit per real world meter.
float getUnitsPerMeter() const
{
return _unitsPerMeter;
}
// Internal APIs
typedef enum {
DIFF_NONE = 0,
DIFF_APP_INFO = (1u << 0),
DIFF_VALIDATION_LAYER = (1u << 1),
DIFF_DEPTH_INFO = (1u << 2),
DIFF_VISIBILITY_MASK = (1u << 3),
DIFF_FORM_FACTOR = (1u << 4),
DIFF_BLEND_MODE = (1u << 5),
DIFF_VR_MODE = (1u << 6),
DIFF_SWAPCHAIN_MODE = (1u << 7),
DIFF_RGB_ENCODING = (1u << 8),
DIFF_DEPTH_ENCODING = (1u << 9),
DIFF_RGB_BITS = (1u << 10),
DIFF_ALPHA_BITS = (1u << 11),
DIFF_DEPTH_BITS = (1u << 12),
DIFF_STENCIL_BITS = (1u << 13),
DIFF_MIRROR = (1u << 14),
DIFF_SCALE = (1u << 15),
} _ChangeMask;
unsigned int _diff(const Settings &other) const;
private:
/*
* Internal data.
*/
// For XrInstance creation
std::string _appName;
uint32_t _appVersion;
bool _validationLayer;
bool _depthInfo;
bool _visibilityMask;
// To get XrSystem
FormFactor _formFactor;
// For choosing environment blend mode
uint32_t _preferredEnvBlendModeMask;
uint32_t _allowedEnvBlendModeMask;
// VR/swapchain modes to use
VRMode _vrMode;
SwapchainMode _swapchainMode;
// Swapchain requirements
uint32_t _preferredRGBEncodingMask;
uint32_t _allowedRGBEncodingMask;
uint32_t _preferredDepthEncodingMask;
uint32_t _allowedDepthEncodingMask;
// These default to -1: get bit depths from graphics window traits
int _rgbBits; // for linear RGB formats, per channel
int _alphaBits;
int _depthBits;
int _stencilBits;
// Mirror settings
MirrorSettings _mirrorSettings;
// How big the world
float _unitsPerMeter;
};
}
#endif
+116
View File
@@ -0,0 +1,116 @@
// -*-c++-*-
// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2022 James Hogan <james@albanarts.com>
#ifndef OSGXR_SubImage
#define OSGXR_SubImage 1
#include <osgXR/Swapchain>
#include <osg/ref_ptr>
namespace osgXR {
/**
* Represents an OpenXR swapchain subimage.
*/
class SubImage
{
public:
/**
* Construct a subimage representing entire swapchain image.
* @param swapchain The swapchain (optional).
*/
SubImage(Swapchain *swapchain = nullptr) :
_swapchain(swapchain),
_x(0),
_y(0),
_width(0),
_height(0),
_arrayIndex(0)
{
}
/**
* Construct a subimage representing part of a swapchain image.
* @param swapchain The swapchain.
* @param x X offset in pixels.
* @param y Y offset in pixels.
* @param width Width in pixels.
* @param height Height in pixels.
*/
SubImage(Swapchain *swapchain,
int32_t x, int32_t y,
uint32_t width, uint32_t height) :
_swapchain(swapchain),
_x(x),
_y(y),
_width(width),
_height(height),
_arrayIndex(0)
{
}
// Accessors
/// Get swapchain pointer.
Swapchain *getSwapchain() const
{
return _swapchain;
}
/// Set offset coordinates in pixels.
void setOffset(int32_t x, int32_t y)
{
_x = x;
_y = y;
}
/// Get X offset in pixels.
int32_t getX() const
{
return _x;
}
/// Get Y offset in pixels.
int32_t getY() const
{
return _y;
}
/// Set extent in pixels (0 means the whole image).
void setExtent(uint32_t width, uint32_t height)
{
_width = width;
_height = height;
}
/// Get width in pixels (0 means the whole image).
uint32_t getWidth() const
{
return _width;
}
/// Get height in pixels (0 means the whole image).
uint32_t getHeight() const
{
return _height;
}
protected:
/// The swapchain this subimage refers to.
osg::ref_ptr<Swapchain> _swapchain;
/// Offset into swapchain images in pixels.
int32_t _x;
int32_t _y;
/// Size in pixels (0 means the whole image).
uint32_t _width;
uint32_t _height;
/// Image array index (must be 0 for now).
uint32_t _arrayIndex;
};
}
#endif
+75
View File
@@ -0,0 +1,75 @@
// -*-c++-*-
// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2021 James Hogan <james@albanarts.com>
#ifndef OSGXR_Subaction
#define OSGXR_Subaction 1
#include <osgXR/Export>
#include <osg/Referenced>
#include <osg/ref_ptr>
#include <memory>
#include <string>
namespace osgXR {
class InteractionProfile;
class Manager;
/**
* Represents an OpenXR subaction path (a.k.a top level user path).
* This represents an OpenXR subaction path, also referred to in the OpenXR spec
* as a top level user path. These are the physical groupings of inputs, for
* example "/user/head" or "/user/hand/left". Actions and action sets can be
* filtered by subactions, so that the same action (e.g. "shoot") can be read
* separately for different hands.
*/
class OSGXR_EXPORT Subaction : public osg::Referenced
{
public:
/**
* Construct a subaction for a path.
* @param manager The VR manager object to add the action set to.
* @param path The subaction path, e.g. "/user/hand/left".
*/
Subaction(Manager *manager,
const std::string &path);
/// Destructor
virtual ~Subaction();
// Accessors
/// Get the subaction's path.
const std::string &getPath() const;
/// Find the interaction profile bound to the subaction.
InteractionProfile *getCurrentProfile();
class Private;
protected:
// Change handlers
/**
* Notification of change of interaction profile for subaction.
* This is called when the subaction's current interaction profile is
* changed. Derived classes can implement this to their own ends.
* @param newProfile The interaction profile object that is now
* current for the subaction indicated by @p
* subaction. May be nullptr.
*/
virtual void onProfileChanged(InteractionProfile *newProfile);
private:
std::shared_ptr<Private> _private;
};
}
#endif
+110
View File
@@ -0,0 +1,110 @@
// -*-c++-*-
// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2022 James Hogan <james@albanarts.com>
#ifndef OSGXR_Swapchain
#define OSGXR_Swapchain 1
#include <osgXR/Export>
#include <osgXR/Settings>
#include <osg/Camera>
#include <osg/Referenced>
#include <osg/StateSet>
#include <memory>
namespace osgXR {
/**
* Represents an OpenXR swapchain.
*/
class OSGXR_EXPORT Swapchain : public osg::Referenced
{
public:
/// Constructor.
Swapchain(uint32_t width, uint32_t height);
/// Destructor.
~Swapchain();
/// Attach the swapchain to a camera.
void attachToCamera(osg::Camera *camera);
/// Update a mirror texture each time the swapchain is rewritten.
void attachToMirror(osg::StateSet *stateSet);
// Accessors
typedef Settings::Encoding Encoding;
/**
* Specify a preferred RGB encoding.
* The chosen RGB encoding is allowed for use, and a format with this
* encoding will be chosen in preference to other allowed encodings
* specified by allowRGBEncoding() if possible.
* @param encoding RGB encoding to prefer.
*/
void preferRGBEncoding(Encoding encoding);
/**
* Specify an allowed RGB encoding.
* The chosen RGB encoding is allowed for use, and a format with this
* encoding may be chosen when none of the preferred color encodings
* specified by preferRGBEncoding() are useable.
* @param encoding RGB encoding to permit.
*/
void allowRGBEncoding(Encoding encoding);
/**
* Set number of desired bits for each RGB channel.
* This only applies to linear RGB formats, not sRGB formats.
*/
void setRGBBits(unsigned int rgbBits);
/**
* Get number of desired bits for each RGB channel.
* This only applies to linear RGB formats, not sRGB formats.
*/
unsigned int getRGBBits() const;
/// Set the number of desired alpha bits.
void setAlphaBits(unsigned int alphaBits);
/// Get number of desired alpha bits.
unsigned int getAlphaBits() const;
/// Set required size of swapchain images in pixels.
void setSize(uint32_t width, uint32_t height);
/// Set required width of swapchain images in pixels.
void setWidth(uint32_t width);
/// Get required width of swapchain images in pixels.
uint32_t getWidth() const;
/// Set required height of swapchain images in pixels.
void setHeight(uint32_t height);
/// Get required height of swapchain images in pixels.
uint32_t getHeight() const;
/**
* Force a particular alpha value before releasing images.
* This clears the alpha channel with a particular alpha value prior to
* releasing the images. This can be used in conjuction with an
* unpremultiplied alpha composition layer to implement alpha blending.
* @param alpha Alpha value to force [0..1].
*/
void setForcedAlpha(float alpha);
/// Disable forced alpha (default).
void disableForcedAlpha();
/// Get the forced alpha value or negative if disabled.
float getForcedAlpha() const;
class Private;
private:
std::shared_ptr<Private> _private;
// Copying not permitted
Swapchain(const Swapchain &copy);
};
}
#endif
+79
View File
@@ -0,0 +1,79 @@
// -*-c++-*-
// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2021 James Hogan <james@albanarts.com>
#ifndef OSGXR_View
#define OSGXR_View 1
#include <osgXR/Export>
#include <osg/Camera>
#include <osg/ref_ptr>
#include <osgViewer/GraphicsWindow>
#include <osgViewer/View>
namespace osgXR {
/**
* Representation of a view from an osgXR app point of view.
* This represents a render view that osgXR expects the application to set up.
* This may not directly correspond to OpenXR views, for example if using stereo
* SceneView mode there will be a single view set up for stereo rendering.
*/
class OSGXR_EXPORT View : public osg::Referenced
{
public:
/*
* Application -> osgXR notifications.
*/
/**
* Notify osgXR that a new slave camera has been added to the view.
* This tells osgXR that a new slave camera has been added to the view
* which it should hook into so that it renders to the appropriate
* texture and submits for XR display.
*/
virtual void addSlave(osg::Camera *slaveCamera) = 0;
/**
* Notify osgXR that a slave camera is being removed from the view.
* This tells osgXR when a slave camera previously notified with
* addSlave() is being removed.
*/
virtual void removeSlave(osg::Camera *slaveCamera) = 0;
/*
* Accessors.
*/
/// Get the OSG GraphicsWindow associated with this osgXR view.
inline const osgViewer::GraphicsWindow *getWindow() const
{
return _window;
}
/// Get the OSG View associated with this osgXR view.
inline const osgViewer::View *getView() const
{
return _osgView;
}
protected:
/*
* Internal
*/
View(osgViewer::GraphicsWindow *window, osgViewer::View *osgView);
virtual ~View();
osg::ref_ptr<osgViewer::GraphicsWindow> _window;
osg::ref_ptr<osgViewer::View> _osgView;
};
}
#endif
+22
View File
@@ -0,0 +1,22 @@
// -*-c++-*-
// SPDX-License-Identifier: LGPL-2.1-only
// Copyright (C) 2021 James Hogan <james@albanarts.com>
#ifndef OSGXR_osgXR
#define OSGXR_osgXR 1
#include <osgXR/Export>
#include <osgViewer/Viewer>
#include <string>
namespace osgXR {
void OSGXR_EXPORT setupViewerDefaults(osgViewer::Viewer *viewer,
const std::string &appName,
uint32_t appVersion);
}
#endif