#ifndef ANDROID_DVR_POSE_H_ #define ANDROID_DVR_POSE_H_ #include <private/dvr/eigen.h> namespace android { namespace dvr { // Encapsulates a 3D pose (rotation and position). // // @tparam T Data type for storing the position coordinate and rotation // quaternion. template <typename T> class Pose { public: // Creates identity pose. Pose() : rotation_(Eigen::Quaternion<T>::Identity()), position_(Eigen::Vector3<T>::Zero()) {} // Initializes a pose with given rotation and position. // // rotation Initial rotation. // position Initial position. Pose(Eigen::Quaternion<T> rotation, Eigen::Vector3<T> position) : rotation_(rotation), position_(position) {} void Invert() { rotation_ = rotation_.inverse(); position_ = rotation_ * -position_; } Pose Inverse() const { Pose result(*this); result.Invert(); return result; } // Compute the composition of this pose with another, storing the result // in the current object void ComposeInPlace(const Pose& other) { position_ = position_ + rotation_ * other.position_; rotation_ = rotation_ * other.rotation_; } // Computes the composition of this pose with another, and returns the result Pose Compose(const Pose& other) const { Pose result(*this); result.ComposeInPlace(other); return result; } Eigen::Vector3<T> TransformPoint(const Eigen::Vector3<T>& v) const { return rotation_ * v + position_; } Eigen::Vector3<T> Transform(const Eigen::Vector3<T>& v) const { return rotation_ * v; } Pose& operator*=(const Pose& other) { ComposeInPlace(other); return *this; } Pose operator*(const Pose& other) const { return Compose(other); } // Gets the rotation of the 3D pose. Eigen::Quaternion<T> GetRotation() const { return rotation_; } // Gets the position of the 3D pose. Eigen::Vector3<T> GetPosition() const { return position_; } // Sets the rotation of the 3D pose. void SetRotation(Eigen::Quaternion<T> rotation) { rotation_ = rotation; } // Sets the position of the 3D pose. void SetPosition(Eigen::Vector3<T> position) { position_ = position; } // Gets a 4x4 matrix representing a transform from the reference space (that // the rotation and position of the pose are relative to) to the object space. Eigen::AffineMatrix<T, 4> GetObjectFromReferenceMatrix() const; // Gets a 4x4 matrix representing a transform from the object space to the // reference space (that the rotation and position of the pose are relative // to). Eigen::AffineMatrix<T, 4> GetReferenceFromObjectMatrix() const; private: Eigen::Quaternion<T> rotation_; Eigen::Vector3<T> position_; }; template <typename T> Eigen::AffineMatrix<T, 4> Pose<T>::GetObjectFromReferenceMatrix() const { // The transfrom from the reference is the inverse of the pose. Eigen::AffineMatrix<T, 4> matrix(rotation_.inverse().toRotationMatrix()); return matrix.translate(-position_); } template <typename T> Eigen::AffineMatrix<T, 4> Pose<T>::GetReferenceFromObjectMatrix() const { // The transfrom to the reference. Eigen::AffineMatrix<T, 4> matrix(rotation_.toRotationMatrix()); return matrix.pretranslate(position_); } //------------------------------------------------------------------------------ // Type-specific typedefs. //------------------------------------------------------------------------------ using Posef = Pose<float>; using Posed = Pose<double>; } // namespace dvr } // namespace android #endif // ANDROID_DVR_POSE_H_