diff --git a/src/esp/bindings/PhysicsObjectBindings.cpp b/src/esp/bindings/PhysicsObjectBindings.cpp index ad644b65b7..5515a8b2e8 100644 --- a/src/esp/bindings/PhysicsObjectBindings.cpp +++ b/src/esp/bindings/PhysicsObjectBindings.cpp @@ -207,8 +207,19 @@ void declareBasePhysicsObjectWrapper(py::module& m, .def_property_readonly( "marker_sets", &PhysObjWrapper::getMarkerSets, py::return_value_policy::reference_internal, - ("The MarkerSets defined for " + objType + " this object.").c_str()) - + ("The MarkerSets defined for this " + objType + ".").c_str()) + .def("marker_points_local", &PhysObjWrapper::getMarkerPointsLocal, + ("A nested dict structure holding all the marker" + "points defined for this " + + objType + + " in object-local space. Same result as " + ".marker_sets.get_all_marker_points.") + .c_str()) + .def("marker_points_global", &PhysObjWrapper::getMarkerPointsGlobal, + ("A nested dict structure holding all the marker" + "points defined for this " + + objType + " transformed to world space.") + .c_str()) .def_property_readonly( "csv_info", &PhysObjWrapper::getObjectInfo, ("Comma-separated informational string describing this " + objType + @@ -663,8 +674,8 @@ void initPhysicsObjectBindings(py::module& m) { // create bindings for ArticulatedObjects // physics object base instance for articulated object - declareBasePhysicsObjectWrapper(m, "Articulated Object", - "ArticulatedObject"); + declareBasePhysicsObjectWrapper( + m, "Articulated Object", "ManagedArticulatedObject"); // ==== ManagedArticulatedObject ==== declareArticulatedObjectWrapper(m, "Articulated Object", diff --git a/src/esp/physics/ArticulatedObject.h b/src/esp/physics/ArticulatedObject.h index e17913453e..51e0b48326 100644 --- a/src/esp/physics/ArticulatedObject.h +++ b/src/esp/physics/ArticulatedObject.h @@ -506,6 +506,56 @@ class ArticulatedObject : public esp::physics::PhysicsObjectBase { return linkIter->second->transformWorldPointsToLocal(points, linkId); } + /** + * @brief Retrieves the hierarchical map-of-map-of-maps containing + * the @ref MarkerSets constituent marker points, in local space + * (which is the space they are given in). + */ + std::unordered_map< + std::string, + std::unordered_map< + std::string, + std::unordered_map>>> + getMarkerPointsGlobal() const override { + const auto lclPoints = markerSets_->getAllMarkerPoints(); + std::unordered_map< + std::string, + std::unordered_map< + std::string, + std::unordered_map>>> + res{}; + // for each task + for (const auto& taskEntry : lclPoints) { + const std::string taskName = taskEntry.first; + std::unordered_map< + std::string, + std::unordered_map>> + perTaskMap; + // for each link + for (const auto& linkEntry : taskEntry.second) { + const std::string linkName = linkEntry.first; + int linkId = getLinkIdFromName(linkName); + auto linkIter = links_.find(linkId); + ESP_CHECK( + linkIter != links_.end(), + "ArticulatedObject::getMarkerPointsGlobal - no link found with " + "linkId =" + << linkId); + std::unordered_map> perLinkMap; + // for each set in link + for (const auto& markersEntry : linkEntry.second) { + const std::string markersName = markersEntry.first; + perLinkMap[markersName] = + linkIter->second->transformLocalPointsToWorld(markersEntry.second, + linkId); + } + perTaskMap[linkName] = perLinkMap; + } + res[taskName] = perTaskMap; + } + return res; + } // getMarkerPointsGlobal + /** * @brief Set forces/torques for all joints indexed by degrees of freedom. * diff --git a/src/esp/physics/PhysicsObjectBase.h b/src/esp/physics/PhysicsObjectBase.h index 0519e61f77..fb8400a988 100644 --- a/src/esp/physics/PhysicsObjectBase.h +++ b/src/esp/physics/PhysicsObjectBase.h @@ -537,6 +537,62 @@ class PhysicsObjectBase : public Magnum::SceneGraph::AbstractFeature3D { markerSets_->overwriteWithConfig(attr); } + /** + * @brief Retrieves the hierarchical map-of-map-of-maps containing + * the @ref MarkerSets constituent marker points, in local space + * (which is the space they are given in). + */ + std::unordered_map< + std::string, + std::unordered_map< + std::string, + std::unordered_map>>> + getMarkerPointsLocal() const { + return markerSets_->getAllMarkerPoints(); + } + + /** + * @brief Retrieves the hierarchical map-of-map-of-maps containing + * the @ref MarkerSets constituent marker points, in local space + * (which is the space they are given in). + */ + virtual std::unordered_map< + std::string, + std::unordered_map< + std::string, + std::unordered_map>>> + getMarkerPointsGlobal() const { + const auto lclPoints = markerSets_->getAllMarkerPoints(); + std::unordered_map< + std::string, + std::unordered_map< + std::string, + std::unordered_map>>> + res{}; + // for each task + for (const auto& taskEntry : lclPoints) { + const std::string taskName = taskEntry.first; + std::unordered_map< + std::string, + std::unordered_map>> + perTaskMap; + // for each link - should only have 1 link in rigids + for (const auto& linkEntry : taskEntry.second) { + const std::string linkName = linkEntry.first; + std::unordered_map> perLinkMap; + // for each set in link + for (const auto& markersEntry : linkEntry.second) { + const std::string markersName = markersEntry.first; + perLinkMap[markersName] = + transformLocalPointsToWorld(markersEntry.second, -1); + } + perTaskMap[linkName] = perLinkMap; + } + res[taskName] = perTaskMap; + } + return res; + } // getMarkerPointsGlobal + /** @brief Get the scale of the object set during initialization. * @return The scaling for the object relative to its initially loaded meshes. */ diff --git a/src/esp/physics/objectWrappers/ManagedPhysicsObjectBase.h b/src/esp/physics/objectWrappers/ManagedPhysicsObjectBase.h index b26ebce997..cb360a940e 100644 --- a/src/esp/physics/objectWrappers/ManagedPhysicsObjectBase.h +++ b/src/esp/physics/objectWrappers/ManagedPhysicsObjectBase.h @@ -203,6 +203,40 @@ class AbstractManagedPhysicsObject return {}; } + /** + * @brief Retrieves the hierarchical map-of-map-of-maps containing + * the @ref MarkerSets constituent marker points, in local space + * (which is the space they are given in). + */ + std::unordered_map< + std::string, + std::unordered_map< + std::string, + std::unordered_map>>> + getMarkerPointsLocal() const { + if (auto sp = this->getObjectReference()) { + return sp->getMarkerPointsLocal(); + } + return {}; + } + + /** + * @brief Retrieves the hierarchical map-of-map-of-maps containing + * the @ref MarkerSets constituent marker points, in local space + * (which is the space they are given in). + */ + std::unordered_map< + std::string, + std::unordered_map< + std::string, + std::unordered_map>>> + getMarkerPointsGlobal() const { + if (auto sp = this->getObjectReference()) { + return sp->getMarkerPointsGlobal(); + } + return {}; + } + Magnum::Quaternion getRotation() const { if (auto sp = this->getObjectReference()) { return sp->getRotation();