Skip to content

File hand_interaction_pose.hpp

File List > data_format > poses > hand_interaction_pose.hpp

Go to the documentation of this file

#pragma once
#ifdef USING_OPENXR
#    include "illixr/data_format/poses/pose_base.hpp"
#    include "illixr/switchboard.hpp"

#    include 

#    ifdef ENABLE_MONADO
#        define INTERACTION_POSE_TYPE xrt_pose
#    else
#        define INTERACTION_POSE_TYPE XrPosef
#    endif
namespace ILLIXR::data_format::pose {

enum interaction_pose_type : int {
    AIM   = 0, 
    GRIP  = 1, 
    PINCH = 2, 
    POKE  = 3, 
};

constexpr int NUM_INTERACTION_POSES = 4;

struct hand_interaction_pose : xrt_space_relation {
    float   value; 
    bool    ready; 
    int64_t predicted_time;

    hand_interaction_pose()
        : xrt_space_relation{}
        , value{0.f}
        , ready{false}
        , predicted_time{0} { }

    [[maybe_unused]] explicit hand_interaction_pose(INTERACTION_POSE_TYPE& in_pose, float val = 0.f, bool rdy = false,
                                                    int64_t p_time = 0)
        : xrt_space_relation{}
        , value{val}
        , ready{rdy}
        , predicted_time{p_time} {
        pose = in_pose;
    }

#    ifndef ENABLE_MONADO

    [[maybe_unused]] explicit hand_interaction_pose(XrSpaceLocation& location, float val = 0.f, bool rdy = false,
                                                    XrTime p_time = 0)
        : xrt_space_relation{}
        , value{val}
        , ready{rdy}
        , predicted_time{p_time} {
        pose = location.pose;
        set_flags(location.locationFlags);
    }

    /*
     * @brief Update the data with new values
     * @param location The new location of the gesture
     * @param val      Gesture-strength scalar in [0, 1], defaults to 0
     * @param rdy      Whether the gesture is activatable, defaults to false
     * @param p_time   The time the gesture was detected
     */
    void update(XrSpaceLocation location, float val, bool rdy, XrTime p_time) {
        pose  = location.pose;
        value = val;
        ready = rdy;
        set_flags(location.locationFlags);
        predicted_time = p_time;
    }
#    endif
    [[maybe_unused]] [[nodiscard]] bool valid() const {
        return (relation_flags & XRT_SPACE_RELATION_POSITION_VALID_BIT) != 0u &&
            (relation_flags & XRT_SPACE_RELATION_ORIENTATION_VALID_BIT) != 0u;
    }
};

struct hand_interaction_poses {
    std::map<interaction_pose_type, hand_interaction_pose> poses; 

    hand_interaction_poses()
        : poses{
              {AIM, hand_interaction_pose{}},
              {GRIP, hand_interaction_pose{}},
              {PINCH, hand_interaction_pose{}},
              {POKE, hand_interaction_pose{}},
          } { }

    explicit hand_interaction_poses(std::map<interaction_pose_type, hand_interaction_pose> poses_)
        : poses{std::move(poses_)} { }

    hand_interaction_pose& operator[](interaction_pose_type type) {
        return poses[type];
    }

    [[nodiscard]] const hand_interaction_pose& at(interaction_pose_type type) const {
        return poses.at(type);
    }

    [[nodiscard]] bool is_valid() const {
        return poses.at(AIM).valid() || poses.at(GRIP).valid() || poses.at(PINCH).valid() || poses.at(POKE).valid();
    }
};

struct hand_interaction_poses_pair : public switchboard::event {
    std::map<side, hand_interaction_poses> hands;       
    time_point                             sensor_time; 

    hand_interaction_poses_pair()
        : hands{{LEFT, hand_interaction_poses{}}, {RIGHT, hand_interaction_poses{}}}
        , sensor_time{time_point{}} { }

    hand_interaction_poses_pair(std::map<side, hand_interaction_poses> hands_, time_point sensor_time_)
        : hands{std::move(hands_)}
        , sensor_time{sensor_time_} { }

    [[nodiscard]] bool is_valid() const {
        return hands.at(LEFT).is_valid() || hands.at(RIGHT).is_valid();
    }

    hand_interaction_poses& operator[](side h) {
        return hands[h];
    }
};

} // namespace ILLIXR::data_format::pose
#endif