Files
flightgear/3rdparty/osgXR/include/osgXR/Action
T
2022-10-20 20:29:11 +08:00

472 lines
16 KiB
C++

// -*-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