summaryrefslogtreecommitdiffstats
path: root/dev/a4-dance/pose.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dev/a4-dance/pose.cc')
-rw-r--r--dev/a4-dance/pose.cc84
1 files changed, 84 insertions, 0 deletions
diff --git a/dev/a4-dance/pose.cc b/dev/a4-dance/pose.cc
new file mode 100644
index 0000000..e23d655
--- /dev/null
+++ b/dev/a4-dance/pose.cc
@@ -0,0 +1,84 @@
+
+#include "pose.h"
+
+
+Pose::Pose() {}
+
+Pose::~Pose() {}
+
+Matrix4 Pose::RootTransform() const {
+ return root_translation_ * root_rotation_;
+}
+
+Matrix4 Pose::JointRotation(const std::string &bone) const {
+ std::map<std::string, Matrix4>::const_iterator it = joint_rotations_.find(bone);
+ if (it == joint_rotations_.end()) {
+ return Matrix4();
+ }
+ else {
+ return it->second;
+ }
+}
+
+Pose Pose::Lerp(const Pose &other, float alpha) const {
+ if (alpha == 0.0) {
+ return *this;
+ }
+ else if (alpha == 1.0) {
+ return other;
+ }
+ else {
+ Pose new_pose;
+ new_pose.set_frame_number(GfxMath::iLerp(frame_num_, other.frame_num_, alpha));
+ new_pose.set_root_position(root_position_.Lerp(other.root_position_, alpha));
+ Vector3 t1 = root_rel_translation_.ColumnToVector3(3);
+ Vector3 t2 = other.root_rel_translation_.ColumnToVector3(3);
+ new_pose.set_root_relative_translation(t1.Lerp(t2, alpha));
+
+ Quaternion q_root_this = Quaternion::FromEulerAnglesZYX(GfxMath::ToRadians(root_orientation_));
+ Quaternion q_root_other = Quaternion::FromEulerAnglesZYX(GfxMath::ToRadians(other.root_orientation_));
+ Quaternion q_root = q_root_this.Slerp(q_root_other, alpha);
+ Vector3 root_angles = GfxMath::ToDegrees(q_root.ToEulerAnglesZYX());
+ new_pose.set_root_orientation(root_angles);
+
+ for (std::map<std::string, Vector3>::const_iterator it = joint_angles_.begin(); it != joint_angles_.end(); ++it) {
+
+ Quaternion q_joint_this = Quaternion::FromEulerAnglesZYX(GfxMath::ToRadians(it->second));
+ Quaternion q_joint_other = Quaternion::FromEulerAnglesZYX(GfxMath::ToRadians(other.joint_angles_.find(it->first)->second));
+ Quaternion q_joint = q_joint_this.Slerp(q_joint_other, alpha);
+ Vector3 joint_angles = GfxMath::ToDegrees(q_joint.ToEulerAnglesZYX());
+ new_pose.set_joint_angles(it->first, joint_angles);
+ }
+ return new_pose;
+ }
+}
+
+
+void Pose::Pose::set_frame_number(int frame_num) {
+ frame_num_ = frame_num;
+}
+
+void Pose::set_root_position(const Point3 &position) {
+ root_position_ = position;
+ root_translation_ = Matrix4::Translation(root_position_ - Point3::Origin());
+}
+
+void Pose::set_root_relative_translation(const Vector3 &delta_since_last_frame) {
+ root_rel_translation_ = Matrix4::Translation(delta_since_last_frame);
+}
+
+
+void Pose::set_root_orientation(const Vector3 &angles) {
+ root_orientation_ = angles;
+ root_rotation_ = Matrix4::RotationZ(GfxMath::ToRadians(root_orientation_[2])) *
+ Matrix4::RotationY(GfxMath::ToRadians(root_orientation_[1])) *
+ Matrix4::RotationX(GfxMath::ToRadians(root_orientation_[0]));
+}
+
+void Pose::set_joint_angles(const std::string &bone, const Vector3 &angles) {
+ joint_angles_[bone] = angles;
+ joint_rotations_[bone] = Matrix4::RotationZ(GfxMath::ToRadians(angles[2])) *
+ Matrix4::RotationY(GfxMath::ToRadians(angles[1])) *
+ Matrix4::RotationX(GfxMath::ToRadians(angles[0]));
+}
+