namespace PoseConvertion
/// Represents 3D translation.
class Vector final {
public:
constexpr Vector(float x, float y, float z) noexcept
: m_data{x, y, z}
{ }
constexpr Vector() noexcept
: Vector{0, 0, 0}
{ }
constexpr const float &operator[](int index) const noexcept {return m_data[index];
}
/// @return The cross product of the instance with the given vector.
constexpr Vector cross(const Vector &other) const noexcept {
return {m_data[1] * other[2] - m_data[2] * other[1],
m_data[2] * other[0] - m_data[0] * other[2],
m_data[0] * other[1] - m_data[1] * other[0]};
}
friend constexpr Vector operator+(const Vector &a, const Vector &b) noexcept {return {a[0] + b[0], a[1] + b[1], a[2] + b[2]};
}
friend constexpr Vector operator-(const Vector &a, const Vector &b) noexcept {return {a[0] - b[0], a[1] - b[1], a[2] - b[2]};
}
/// @return The instance scaled by the given factor.
friend constexpr Vector operator*(float scale, const Vector &vec) noexcept {return {vec[0] * scale, vec[1] * scale, vec[2] * scale};
}
private:
std::array<float, 3> m_data;
};
/// Represents a rotational quaternion.
class Quat final {
public:
constexpr Quat(float x, float y, float z, float w) noexcept
: m_data{x, y, z, w}
{ }
constexpr Quat() noexcept
: Quat{0, 0, 0, 1.F}
{ }
constexpr const float &operator[](int index) const noexcept {return m_data[index];
}
/// @return The given translation rotated by the represented rotation.
constexpr Vector operator*(const Vector &trans) const noexcept {const Vector q_imag{m_data[0], m_data[1], m_data[2]};
const float q_real{m_data[3]};
Vector t = 2.F * q_imag.cross(trans);
return trans + q_real * t + q_imag.cross(t);
}
/// As this class is a normalized quaternion, conjugate for inverse.
constexpr Quat inversed() const noexcept {return {m_data[0], m_data[1], m_data[2], -m_data[3]};
}
};
class Transform final {
Each node has a unique name, an optional parent name, and a local pose made of a quaternion rotation and a 3D translation. Implement computeWorldPosesOf to return the world pose of every node in hierarchy order. The key is to build the parent-child relationship, then combine transforms along the path from the root to each node. Rotation composes with quaternion multiplication, and translation must be rotated by the parent before being added. Since quaternions are normalized, the inverse is the conjugate. A depth-first traversal or memoized recursion both work well for this kind of tree-based transform propagation.
This problem asks you to compute world-space poses in a hierarchical 3D transform tree. Each node stores a local quaternion rotation and a local translation, and the final pose must be accumulated from root to leaf. The main ideas are to build the parent-child structure, traverse the hierarchy, compose rotations with quaternion multiplication, and rotate each local translation by the parent before adding it to the parent translation. Since the quaternion is normalized, its inverse is the conjugate, which is useful if you need to reason about relative transforms.