Skip to content

File hand_pose.hpp

File List > data_format > poses > hand_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 
#    include 
#    include 
#    include 

#    ifdef ENABLE_MONADO
#        define HAND_JOINT_COUNT XRT_HAND_JOINT_COUNT
#    else
#        define HAND_JOINT_COUNT XR_HAND_JOINT_COUNT_EXT
#        include "openxr_defines.hpp"
#    endif

namespace ILLIXR::data_format::pose {

enum joint : int {
    PALM [[maybe_unused]]                = 0,
    WRIST [[maybe_unused]]               = 1,
    THUMB_METACARPAL [[maybe_unused]]    = 2,
    THUMB_PROXIMAL [[maybe_unused]]      = 3,
    THUMB_DISTAL [[maybe_unused]]        = 4,
    THUMB_TIP [[maybe_unused]]           = 5,
    INDEX_METACARPAL [[maybe_unused]]    = 6,
    INDEX_PROXIMAL [[maybe_unused]]      = 7,
    INDEX_INTERMEDIATE [[maybe_unused]]  = 8,
    INDEX_DISTAL [[maybe_unused]]        = 9,
    INDEX_TIP [[maybe_unused]]           = 10,
    MIDDLE_METACARPAL [[maybe_unused]]   = 11,
    MIDDLE_PROXIMAL [[maybe_unused]]     = 12,
    MIDDLE_INTERMEDIATE [[maybe_unused]] = 13,
    MIDDLE_DISTAL [[maybe_unused]]       = 14,
    MIDDLE_TIP [[maybe_unused]]          = 15,
    RING_METACARPAL [[maybe_unused]]     = 16,
    RING_PROXIMAL [[maybe_unused]]       = 17,
    RING_INTERMEDIATE [[maybe_unused]]   = 18,
    RING_DISTAL [[maybe_unused]]         = 19,
    RING_TIP [[maybe_unused]]            = 20,
    LITTLE_METACARPAL [[maybe_unused]]   = 21,
    LITTLE_PROXIMAL [[maybe_unused]]     = 22,
    LITTLE_INTERMEDIATE [[maybe_unused]] = 23,
    LITTLE_DISTAL [[maybe_unused]]       = 24,
    LITTLE_TIP [[maybe_unused]]          = 25
};

#    ifdef ENABLE_MONADO
typedef xrt_hand_joint_value hand_joint_pose;

#    else
struct hand_joint_pose {
    xrt_space_relation relation; 
    float              radius;   

    hand_joint_pose()
        : radius{0.} { }

    hand_joint_pose(xrt_space_relation rel, float r)
        : relation{std::move(rel)}
        , radius{r} { }

    hand_joint_pose(XrHandJointLocationEXT pose, XrHandJointVelocityEXT vel) {
        radius                    = pose.radius;
        relation.pose             = pose.pose;
        relation.linear_velocity  = vel.linearVelocity;
        relation.angular_velocity = vel.angularVelocity;
        relation.set_flags(pose.locationFlags, vel.velocityFlags);
    }
};
#    endif

#    ifdef ENABLE_MONADO
typedef xrt_hand_joint_set hand_joint_poses;

#    else

struct hand_joint_poses {
    std::array<hand_joint_pose, XR_HAND_JOINT_COUNT_EXT> joints; 
    bool is_active = false; 

    hand_joint_poses()
        : joints{}
        , is_active{false} { }

    void update(std::array<XrHandJointLocationEXT, XR_HAND_JOINT_COUNT_EXT>& pose,
                std::array<XrHandJointVelocityEXT, XR_HAND_JOINT_COUNT_EXT>& velocity) {
        uint8_t tracked_count = 0;
        for (uint32_t j = 0; j < XR_HAND_JOINT_COUNT_EXT; j++) {
            joints[j] = {pose[j], velocity[j]};
            if (pose[j].locationFlags & XR_SPACE_LOCATION_ORIENTATION_VALID_BIT &&
                pose[j].locationFlags & XR_SPACE_LOCATION_POSITION_VALID_BIT)
                tracked_count++;
        }
        is_active = (static_cast<float>(tracked_count) / static_cast<float>(XR_HAND_JOINT_COUNT_EXT)) > 0.;
    }

    hand_joint_poses(std::array<XrHandJointLocationEXT, XR_HAND_JOINT_COUNT_EXT>& pose,
                     std::array<XrHandJointVelocityEXT, XR_HAND_JOINT_COUNT_EXT>& velocity) {
        update(pose, velocity);
    }

    hand_joint_pose& operator[](joint j) {
        return joints[static_cast<int>(j)];
    }

    const hand_joint_pose& operator[](joint j) const {
        return joints[static_cast<int>(j)];
    }
};
#    endif
struct hand_joint_poses_pair : public switchboard::event {
    std::map<side, hand_joint_poses> hands;       
    time_point                       sensor_time; 

    hand_joint_poses_pair()
        : hands{{LEFT, hand_joint_poses{}}, {RIGHT, hand_joint_poses{}}}
        , sensor_time{time_point{}} { }

    [[maybe_unused]] hand_joint_poses_pair(std::map<side, hand_joint_poses> hands_, time_point sensor_time_)
        : hands{std::move(hands_)}
        , sensor_time{sensor_time_} { }

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

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

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