rest of animation coding
animation , animator , keyframe & quaterions compiling but not debuged at all
This commit is contained in:
@@ -6,7 +6,7 @@
|
|||||||
#define PI 3.14159265358979323846
|
#define PI 3.14159265358979323846
|
||||||
#define DEG2RAD PI/180
|
#define DEG2RAD PI/180
|
||||||
|
|
||||||
ColladaModel::ColladaModel(const char* filename) : faces_(), vertices_(), normals_(), rootjoint(rootindex, roottransform)
|
ColladaModel::ColladaModel(const char* filename) : faces_(), vertices_(), normals_(), rootjoint()
|
||||||
{
|
{
|
||||||
Transform = Matrix::identity();
|
Transform = Matrix::identity();
|
||||||
Rotation = Matrix::identity();
|
Rotation = Matrix::identity();
|
||||||
@@ -125,7 +125,57 @@ ColladaModel::ColladaModel(const char* filename) : faces_(), vertices_(), normal
|
|||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/*joint_count = 0;
|
||||||
|
tinyxml2::XMLElement* xml_joint = doc.FirstChildElement("COLLADA")->FirstChildElement("library_controllers")->FirstChildElement()->FirstChildElement()->FirstChildElement("source")->FirstChildElement();
|
||||||
|
xml_joint->QueryIntAttribute("count", &joint_count);
|
||||||
|
std::stringstream str_joint(xml_joint->GetText());
|
||||||
|
*/
|
||||||
|
/*for (int i = 0; i < joint_count; i++)
|
||||||
|
{
|
||||||
|
Vec2f temp;
|
||||||
|
str_texcoord >> temp.x;
|
||||||
|
str_texcoord >> temp.y;
|
||||||
|
texturecos_.push_back(temp);
|
||||||
|
}*/
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//tinyxml2::XMLElement* xml_hierachy = doc.FirstChildElement("COLLADA")->FirstChildElement("library_visual_scenes")->FirstChildElement("visual_scene")->FirstChildElement("node")->FirstChildElement("node");
|
||||||
|
//std::stringstream str_hierachy(xml_hierachy->GetText());
|
||||||
|
|
||||||
|
//ColladaModel::rootjoint = buildjoint(xml_hierachy);
|
||||||
|
joint_count = 0;
|
||||||
|
tinyxml2::XMLElement* xml_joint = doc.FirstChildElement("COLLADA")->FirstChildElement("library_controllers")->FirstChildElement("controller")->FirstChildElement("skin")->FirstChildElement("source")->FirstChildElement("Name_array");
|
||||||
|
xml_joint->QueryIntAttribute("count", &joint_count);
|
||||||
|
std::stringstream str_joint(xml_joint->GetText());
|
||||||
|
|
||||||
|
for (int i = 0; i < vertex_count / 3; i++)
|
||||||
|
{
|
||||||
|
std::string temp;
|
||||||
|
str_vertex >> temp;
|
||||||
|
|
||||||
|
jointIDs_.push_back(temp);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Joint buildjoint(tinyxml2::XMLElement* xml_hierachy)
|
||||||
|
//{
|
||||||
|
// const char* name;
|
||||||
|
// xml_hierachy->QueryStringAttribute("name", &name);
|
||||||
|
// std::stringstream str_transform(xml_hierachy->FirstChildElement("matrix")->GetText());
|
||||||
|
// Matrix transform;
|
||||||
|
//
|
||||||
|
// if (xml_hierachy->FirstChildElement("node") != NULL)
|
||||||
|
// {
|
||||||
|
// xml_hierachy = xml_hierachy->FirstChildElement("node");
|
||||||
|
// do
|
||||||
|
// {
|
||||||
|
//// buildjoint
|
||||||
|
// } while (xml_hierachy->NextSiblingElement() != NULL);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
ColladaModel::~ColladaModel() {
|
ColladaModel::~ColladaModel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,12 +270,12 @@ Joint ColladaModel::getrootjoint()
|
|||||||
|
|
||||||
void ColladaModel::doanimation(Animation animation)
|
void ColladaModel::doanimation(Animation animation)
|
||||||
{
|
{
|
||||||
animator.doanimation(animation);
|
//animator.doanimation(animation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaModel::updateanimator()
|
void ColladaModel::updateanimator()
|
||||||
{
|
{
|
||||||
animator.update();
|
//animator.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Matrix> ColladaModel::getjointtransforms()
|
std::vector<Matrix> ColladaModel::getjointtransforms()
|
||||||
|
|||||||
@@ -24,24 +24,40 @@ class ColladaModel {
|
|||||||
private:
|
private:
|
||||||
int face_count;
|
int face_count;
|
||||||
int vertex_count;
|
int vertex_count;
|
||||||
//int normal_count;
|
|
||||||
//int texcoord_count;
|
|
||||||
int joint_count;
|
int joint_count;
|
||||||
|
|
||||||
Joint rootjoint;
|
Joint rootjoint;
|
||||||
int rootindex=0;
|
int rootindex=0;
|
||||||
Matrix roottransform;
|
char* rootname;
|
||||||
|
Matrix root_transform;
|
||||||
|
|
||||||
Animator animator;
|
//Animator animator;
|
||||||
|
|
||||||
std::vector<std::vector<Vec3i> > faces_; //vertex/normal/uv
|
std::vector<std::vector<Vec3i> > faces_; //vertex/normal/uv
|
||||||
std::vector<Vec3f> vertices_;
|
std::vector<Vec3f> vertices_;
|
||||||
std::vector<Vec3f> normals_;
|
std::vector<Vec3f> normals_;
|
||||||
std::vector<Vec2f> texturecos_;
|
std::vector<Vec2f> texturecos_;
|
||||||
|
|
||||||
|
// #include <map>
|
||||||
|
// map<const char*, int> joint_names;
|
||||||
|
// joints.add(pair<const char*, int>("TORSO", 0));
|
||||||
|
|
||||||
|
// {TORSO, 0}
|
||||||
|
// {LEG, 1}
|
||||||
|
// {HAND, 2}
|
||||||
|
|
||||||
|
//joint_names.get("TORSO");
|
||||||
|
|
||||||
|
// 1. Get jointnames and map them to ids
|
||||||
|
// 2. get each joint and fill in the Joint class
|
||||||
|
// 3. get inversebindtransforms
|
||||||
|
|
||||||
|
// Vector -> Vectors -> (joint , weight)
|
||||||
std::vector<std::vector<Vec2i>> vertexweights_; //joint/weight
|
std::vector<std::vector<Vec2i>> vertexweights_; //joint/weight
|
||||||
std::vector<Vec3i> jointIDs_;
|
std::vector<std::string> jointIDs_;
|
||||||
|
// { TORSO , LEG, TEZ}
|
||||||
|
// { 0, 1, 2}
|
||||||
|
// jointIDs[0]
|
||||||
std::vector<float> weights_;
|
std::vector<float> weights_;
|
||||||
|
|
||||||
TGAImage diffusemap_;
|
TGAImage diffusemap_;
|
||||||
@@ -50,6 +66,7 @@ private:
|
|||||||
|
|
||||||
void load_texture(std::string filename, const char* suffix, TGAImage& img);
|
void load_texture(std::string filename, const char* suffix, TGAImage& img);
|
||||||
public:
|
public:
|
||||||
|
ColladaModel() = default;
|
||||||
ColladaModel(const char* filename);
|
ColladaModel(const char* filename);
|
||||||
~ColladaModel();
|
~ColladaModel();
|
||||||
|
|
||||||
@@ -65,6 +82,7 @@ public:
|
|||||||
Vec2f uv(int iface, int nthvert);
|
Vec2f uv(int iface, int nthvert);
|
||||||
|
|
||||||
Matrix Transform;
|
Matrix Transform;
|
||||||
|
|
||||||
Matrix Rotation;
|
Matrix Rotation;
|
||||||
Matrix Scale;
|
Matrix Scale;
|
||||||
Matrix Translation;
|
Matrix Translation;
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
#include "Joint.h"
|
#include "Joint.h"
|
||||||
|
|
||||||
Joint::Joint(int index, Matrix transform) {
|
Joint::Joint(int index, Matrix transform, char* name) {
|
||||||
Joint::index = index;
|
Joint::index = index;
|
||||||
_transform = transform;
|
_transform = transform;
|
||||||
|
Joint::name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
Joint::~Joint() {
|
Joint::~Joint() {
|
||||||
|
|||||||
+3
-1
@@ -10,9 +10,11 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
int index;
|
int index;
|
||||||
|
char* name;
|
||||||
std::vector<Joint> children;
|
std::vector<Joint> children;
|
||||||
|
|
||||||
Joint(int index,Matrix transform);
|
Joint() = default;
|
||||||
|
Joint(int index,Matrix transform,char* name);
|
||||||
~Joint();
|
~Joint();
|
||||||
|
|
||||||
void addChild(Joint child);
|
void addChild(Joint child);
|
||||||
|
|||||||
@@ -121,8 +121,11 @@
|
|||||||
<ClCompile Include="colladamodel.cpp" />
|
<ClCompile Include="colladamodel.cpp" />
|
||||||
<ClCompile Include="geometry.cpp" />
|
<ClCompile Include="geometry.cpp" />
|
||||||
<ClCompile Include="joint.cpp" />
|
<ClCompile Include="joint.cpp" />
|
||||||
|
<ClCompile Include="jointtransform.cpp" />
|
||||||
|
<ClCompile Include="keyframe.cpp" />
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
<ClCompile Include="model.cpp" />
|
<ClCompile Include="model.cpp" />
|
||||||
|
<ClCompile Include="quaternion.cpp" />
|
||||||
<ClCompile Include="renderer.cpp" />
|
<ClCompile Include="renderer.cpp" />
|
||||||
<ClCompile Include="tgaimage.cpp" />
|
<ClCompile Include="tgaimage.cpp" />
|
||||||
<ClCompile Include="tinyxml2.cpp" />
|
<ClCompile Include="tinyxml2.cpp" />
|
||||||
@@ -136,7 +139,10 @@
|
|||||||
<ClInclude Include="geometry.h" />
|
<ClInclude Include="geometry.h" />
|
||||||
<ClInclude Include="camera.h" />
|
<ClInclude Include="camera.h" />
|
||||||
<ClInclude Include="joint.h" />
|
<ClInclude Include="joint.h" />
|
||||||
|
<ClInclude Include="jointtransform.h" />
|
||||||
|
<ClInclude Include="keyframe.h" />
|
||||||
<ClInclude Include="model.h" />
|
<ClInclude Include="model.h" />
|
||||||
|
<ClInclude Include="quaternion.h" />
|
||||||
<ClInclude Include="renderer.h" />
|
<ClInclude Include="renderer.h" />
|
||||||
<ClInclude Include="tgaimage.h" />
|
<ClInclude Include="tgaimage.h" />
|
||||||
<ClInclude Include="tinyxml2.h" />
|
<ClInclude Include="tinyxml2.h" />
|
||||||
|
|||||||
@@ -54,6 +54,15 @@
|
|||||||
<ClCompile Include="animation.cpp">
|
<ClCompile Include="animation.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="keyframe.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="jointtransform.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="quaternion.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="util_window.h">
|
<ClInclude Include="util_window.h">
|
||||||
@@ -92,5 +101,14 @@
|
|||||||
<ClInclude Include="animation.h">
|
<ClInclude Include="animation.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="keyframe.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="jointtransform.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="quaternion.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@@ -1 +1,17 @@
|
|||||||
#include "animation.h"
|
#include "animation.h"
|
||||||
|
|
||||||
|
Animation::Animation(float seconds, std::vector<Keyframe> keyframes)
|
||||||
|
{
|
||||||
|
length = seconds;
|
||||||
|
keyframes_ = keyframes;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Animation::getlength()
|
||||||
|
{
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Keyframe> Animation::getkeyframe()
|
||||||
|
{
|
||||||
|
return keyframes_;
|
||||||
|
}
|
||||||
|
|||||||
+14
-3
@@ -1,5 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
class Animation
|
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
|
#include "keyframe.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class Animation {
|
||||||
|
private:
|
||||||
|
float length;
|
||||||
|
std::vector<Keyframe> keyframes_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Animation() = default;
|
||||||
|
Animation(float seconds, std::vector<Keyframe> keyframes);
|
||||||
|
float getlength();
|
||||||
|
std::vector<Keyframe>getkeyframe();
|
||||||
|
};
|
||||||
@@ -1,9 +1,108 @@
|
|||||||
#include "animator.h"
|
#include "animator.h"
|
||||||
|
#include "colladamodel.h"
|
||||||
|
|
||||||
|
void Animator::increaseAnimationTime()
|
||||||
|
{
|
||||||
|
animation_time_ += (1/60.f);
|
||||||
|
if (animation_time_ > current_animation_.getlength())
|
||||||
|
{
|
||||||
|
animation_time_ = (int)(animation_time_) % (int)(current_animation_.getlength());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Animator::applyPoseToJoints(std::map<std::string, Matrix> currentPose, Joint joint, Matrix parentTransform)
|
||||||
|
{
|
||||||
|
Matrix currentLocalTransform = currentPose.at(joint.name);
|
||||||
|
Matrix currentTransform = parentTransform * currentLocalTransform;
|
||||||
|
for (Joint childJoint : joint.children) {
|
||||||
|
applyPoseToJoints(currentPose, childJoint, currentTransform);
|
||||||
|
}
|
||||||
|
currentTransform = currentTransform * joint.getInverseBindTransform();
|
||||||
|
joint.setTransform(currentTransform);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Keyframe> Animator::getPreviousAndNextFrames()
|
||||||
|
{
|
||||||
|
std::vector<Keyframe> allFrames = current_animation_.getkeyframe();
|
||||||
|
Keyframe previousFrame = allFrames[0];
|
||||||
|
Keyframe nextFrame = allFrames[0];
|
||||||
|
for (int i = 1; i < allFrames.capacity(); i++) {
|
||||||
|
nextFrame = allFrames[i];
|
||||||
|
if (nextFrame.gettimestamp() > animation_time_) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
previousFrame = allFrames[i];
|
||||||
|
}
|
||||||
|
return std::vector<Keyframe>{ previousFrame, nextFrame };
|
||||||
|
}
|
||||||
|
|
||||||
|
float Animator::calculateProgression(Keyframe previousFrame, Keyframe nextFrame)
|
||||||
|
{
|
||||||
|
float totalTime = nextFrame.gettimestamp() - previousFrame.gettimestamp();
|
||||||
|
float currentTime = animation_time_ - previousFrame.gettimestamp();
|
||||||
|
return currentTime / totalTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, Matrix> Animator::interpolatePoses(Keyframe previousFrame, Keyframe nextFrame, float progression)
|
||||||
|
{
|
||||||
|
std::map<std::string, Matrix> currentPose ;
|
||||||
|
std::set<std::string> key_set;
|
||||||
|
make_key_set(previousFrame.getJointKeyFrames(), key_set);
|
||||||
|
for (std::string jointName : key_set)
|
||||||
|
{
|
||||||
|
JointTransform previousTransform = previousFrame.getJointKeyFrames().at(jointName);
|
||||||
|
JointTransform nextTransform = nextFrame.getJointKeyFrames().at(jointName);
|
||||||
|
JointTransform currentTransform = JointTransform::interpolate(previousTransform, nextTransform, progression);
|
||||||
|
currentPose.insert_or_assign(jointName, currentTransform.getlocationtransform());
|
||||||
|
make_key_set(previousFrame.getJointKeyFrames(), key_set);
|
||||||
|
}
|
||||||
|
return currentPose;
|
||||||
|
}
|
||||||
|
|
||||||
|
Animator::Animator(ColladaModel entity)
|
||||||
|
{
|
||||||
|
entity_ = &entity;
|
||||||
|
}
|
||||||
|
|
||||||
void Animator::doanimation(Animation animation)
|
void Animator::doanimation(Animation animation)
|
||||||
{
|
{
|
||||||
|
animation_time_ = 0;
|
||||||
|
current_animation_ = animation;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Animator::update()
|
void Animator::update()
|
||||||
{
|
{
|
||||||
|
if (¤t_animation_ == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
increaseAnimationTime();
|
||||||
|
std::map<std::string, Matrix> currentPose = calculateCurrentAnimationPose();
|
||||||
|
applyPoseToJoints(currentPose, entity_->getrootjoint(), Matrix());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, Matrix> Animator::calculateCurrentAnimationPose()
|
||||||
|
{
|
||||||
|
std::vector<Keyframe> frames = getPreviousAndNextFrames();
|
||||||
|
float progression = calculateProgression(frames[0], frames[1]);
|
||||||
|
return interpolatePoses(frames[0], frames[1], progression);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TK, typename TV>
|
||||||
|
std::vector<TK> extract_keys(std::map<TK, TV> const& input_map) {
|
||||||
|
std::vector<TK> retval;
|
||||||
|
for (auto const& element : input_map) {
|
||||||
|
retval.push_back(element.first);
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename TK, typename TV>
|
||||||
|
std::vector<TV> extract_values(std::map<TK, TV> const& input_map) {
|
||||||
|
std::vector<TV> retval;
|
||||||
|
for (auto const& element : input_map) {
|
||||||
|
retval.push_back(element.second);
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
+38
-3
@@ -1,11 +1,46 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "animator.h"
|
|
||||||
#include "animation.h"
|
#include "animation.h"
|
||||||
|
#include "geometry.h"
|
||||||
|
#include "keyframe.h"
|
||||||
|
#include "jointtransform.h"
|
||||||
|
#include "joint.h"
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
class ColladaModel;
|
||||||
|
|
||||||
|
class Animator {
|
||||||
|
private:
|
||||||
|
ColladaModel* entity_;
|
||||||
|
Animation current_animation_;
|
||||||
|
float animation_time_;
|
||||||
|
|
||||||
|
void increaseAnimationTime();
|
||||||
|
std::map<std::string,Matrix> calculateCurrentAnimationPose();
|
||||||
|
void applyPoseToJoints(std::map<std::string, Matrix> currentPose, Joint joint, Matrix parentTransform);
|
||||||
|
std::vector<Keyframe> getPreviousAndNextFrames();
|
||||||
|
float calculateProgression(Keyframe previousFrame, Keyframe nextFrame);
|
||||||
|
std::map<std::string, Matrix> interpolatePoses(Keyframe previousFrame, Keyframe nextFrame, float progression);
|
||||||
|
|
||||||
class Animator
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
Animator(ColladaModel entity);
|
||||||
void doanimation(Animation animation);
|
void doanimation(Animation animation);
|
||||||
void update();
|
void update();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template< class Key,
|
||||||
|
class T,
|
||||||
|
class Comparator,
|
||||||
|
class MapAllocator,
|
||||||
|
class SetAllocator>
|
||||||
|
void make_key_set(const std::map<Key, T, Comparator, MapAllocator>& map,
|
||||||
|
std::set<Key, Comparator, SetAllocator>& set)
|
||||||
|
{
|
||||||
|
set.clear();
|
||||||
|
typedef typename std::map<Key, T, Comparator, MapAllocator> map_type;
|
||||||
|
typename map_type::const_iterator itr = map.begin();
|
||||||
|
while (map.end() != itr)
|
||||||
|
{
|
||||||
|
set.insert((itr++)->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#include "jointtransform.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
JointTransform::JointTransform(Vec3f position, Quaternion rotation)
|
||||||
|
{
|
||||||
|
position_ = position;
|
||||||
|
rotation_ = rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix JointTransform::getlocationtransform()
|
||||||
|
{
|
||||||
|
Matrix matrix;
|
||||||
|
Vec4f column = Vec4f(position_.x, position_.y, position_.z, 1);
|
||||||
|
matrix.set_col(3, column);
|
||||||
|
matrix = matrix * rotation_.toRotationMatrix();
|
||||||
|
return matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
JointTransform JointTransform::interpolate(JointTransform frame1, JointTransform frame2, float progression)
|
||||||
|
{
|
||||||
|
Vec3f pos = interpolate(frame1.position_, frame2.position_, progression);
|
||||||
|
Quaternion rot = Quaternion::interpolate(frame1.rotation_, frame2.rotation_, progression);
|
||||||
|
return JointTransform(pos, rot);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3f JointTransform::interpolate(Vec3f start, Vec3f end, float progression)
|
||||||
|
{
|
||||||
|
float x = start.x + (end.x - start.x) * progression;
|
||||||
|
float y = start.y + (end.y - start.y) * progression;
|
||||||
|
float z = start.z + (end.z - start.z) * progression;
|
||||||
|
|
||||||
|
return Vec3f(x,y,z);
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "quaternion.h"
|
||||||
|
#include "geometry.h"
|
||||||
|
|
||||||
|
class JointTransform
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
Vec3f position_;
|
||||||
|
|
||||||
|
Quaternion rotation_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
JointTransform() = default;
|
||||||
|
JointTransform(Vec3f position,Quaternion rotation);
|
||||||
|
|
||||||
|
Matrix getlocationtransform();
|
||||||
|
|
||||||
|
static JointTransform interpolate(JointTransform frame1, JointTransform frame2, float progression);
|
||||||
|
|
||||||
|
static Vec3f interpolate(Vec3f start,Vec3f end, float progression);
|
||||||
|
};
|
||||||
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#include "keyframe.h"
|
||||||
|
|
||||||
|
Keyframe::Keyframe(float timestamp, std::map<std::string, JointTransform> pose)
|
||||||
|
{
|
||||||
|
timestamp_ = timestamp;
|
||||||
|
pose_ = pose;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Keyframe::gettimestamp()
|
||||||
|
{
|
||||||
|
return timestamp_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, JointTransform> Keyframe::getJointKeyFrames()
|
||||||
|
{
|
||||||
|
return pose_;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef HI
|
||||||
|
#define HI
|
||||||
|
|
||||||
|
// your declarations (and certain types of definitions) here
|
||||||
|
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include "jointtransform.h"
|
||||||
|
|
||||||
|
|
||||||
|
class Keyframe{
|
||||||
|
private:
|
||||||
|
float timestamp_;
|
||||||
|
std::map<std::string, JointTransform> pose_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Keyframe() = default;
|
||||||
|
Keyframe(float timestamp,std::map<std::string, JointTransform> pose);
|
||||||
|
float gettimestamp();
|
||||||
|
std::map<std::string, JointTransform> getJointKeyFrames();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
#include "quaternion.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
Quaternion::Quaternion(float x, float y, float z, float w)
|
||||||
|
{
|
||||||
|
x_ = x;
|
||||||
|
y_ = y;
|
||||||
|
z_ = z;
|
||||||
|
w_ = w;
|
||||||
|
normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Quaternion::normalize()
|
||||||
|
{
|
||||||
|
float mag = (float)sqrt(w_ * w_ + x_ * x_ + y_ * y_ + z_ * z_);
|
||||||
|
w_ /= mag;
|
||||||
|
x_ /= mag;
|
||||||
|
y_ /= mag;
|
||||||
|
z_ /= mag;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix Quaternion::toRotationMatrix()
|
||||||
|
{
|
||||||
|
Matrix matrix;
|
||||||
|
float xy = x_ * y_;
|
||||||
|
float xz = x_ * z_;
|
||||||
|
float xw = x_ * w_;
|
||||||
|
float yz = y_ * z_;
|
||||||
|
float yw = y_ * w_;
|
||||||
|
float zw = z_ * w_;
|
||||||
|
float xSquared = x_ * x_;
|
||||||
|
float ySquared = y_ * y_;
|
||||||
|
float zSquared = z_ * z_;
|
||||||
|
|
||||||
|
Vec4f c0 = Vec4f(1 - 2 * (ySquared + zSquared), 2 * (xy - zw), 2 * (xz + yw),0);
|
||||||
|
Vec4f c1 = Vec4f(2 * (xy + zw), 1 - 2 * (xSquared + zSquared), 2 * (yz - xw), 0);
|
||||||
|
Vec4f c2 = Vec4f(2 * (xz - yw), 2 * (yz + xw), 1 - 2 * (xSquared + ySquared), 0);
|
||||||
|
Vec4f c3 = Vec4f(0,0,0,1);
|
||||||
|
|
||||||
|
matrix.set_col(0,c0);
|
||||||
|
matrix.set_col(1, c1);
|
||||||
|
matrix.set_col(2, c2);
|
||||||
|
matrix.set_col(3, c3);
|
||||||
|
return matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion Quaternion::fromMatrix(Matrix matrix)
|
||||||
|
{
|
||||||
|
float w_, x_, y_, z_;
|
||||||
|
float diagonal = matrix[0][0] + matrix[1][1] + matrix[2][2];
|
||||||
|
if (diagonal > 0) {
|
||||||
|
float w4 = (float)(sqrt(diagonal + 1.f) * 2.f);
|
||||||
|
w_ = w4 / 4.f;
|
||||||
|
x_ = (matrix[2][1] - matrix[1][2]) / w4;
|
||||||
|
y_ = (matrix[0][2] - matrix[2][0]) / w4;
|
||||||
|
z_ = (matrix[1][0] - matrix[0][1]) / w4;
|
||||||
|
}
|
||||||
|
else if ((matrix[0][0] > matrix[1][1]) && (matrix[0][0] > matrix[2][2])) {
|
||||||
|
float x4 = (float)(sqrt(1.f + matrix[0][0] - matrix[1][1] - matrix[2][2]) * 2.f);
|
||||||
|
w_ = (matrix[2][1] - matrix[1][2]) / x4;
|
||||||
|
x_ = x4 / 4.f;
|
||||||
|
y_ = (matrix[0][1] + matrix[1][0]) / x4;
|
||||||
|
z_ = (matrix[0][2] + matrix[2][0]) / x4;
|
||||||
|
}
|
||||||
|
else if (matrix[1][1] > matrix[2][2]) {
|
||||||
|
float y4 = (float)(sqrt(1.f + matrix[1][1] - matrix[0][0] - matrix[2][2]) * 2.f);
|
||||||
|
w_ = (matrix[0][2] - matrix[2][0]) / y4;
|
||||||
|
x_ = (matrix[0][1] + matrix[1][0]) / y4;
|
||||||
|
y_ = y4 / 4.f;
|
||||||
|
z_ = (matrix[1][2] + matrix[2][1]) / y4;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
float z4 = (float)(sqrt(1.f + matrix[2][2] - matrix[0][0] - matrix[1][1]) * 2.f);
|
||||||
|
w_ = (matrix[1][0] - matrix[0][1]) / z4;
|
||||||
|
x_ = (matrix[0][2] + matrix[2][0]) / z4;
|
||||||
|
y_ = (matrix[1][2] + matrix[2][1]) / z4;
|
||||||
|
z_ = z4 / 4.f;
|
||||||
|
}
|
||||||
|
return Quaternion(x_, y_, z_, w_);
|
||||||
|
}
|
||||||
|
|
||||||
|
Quaternion Quaternion::interpolate(Quaternion a, Quaternion b, float blend)
|
||||||
|
{
|
||||||
|
Quaternion result(0, 0, 0, 1);
|
||||||
|
float dot = a.w_ * b.w_ + a.x_ * b.x_ + a.y_ * b.y_ + a.z_ * b.z_;
|
||||||
|
float blendI = 1.f - blend;
|
||||||
|
if (dot < 0) {
|
||||||
|
result.w_ = blendI * a.w_ + blend * -b.w_;
|
||||||
|
result.x_ = blendI * a.x_ + blend * -b.x_;
|
||||||
|
result.y_ = blendI * a.y_ + blend * -b.y_;
|
||||||
|
result.z_ = blendI * a.z_ + blend * -b.z_;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.w_ = blendI * a.w_ + blend * b.w_;
|
||||||
|
result.x_ = blendI * a.x_ + blend * b.x_;
|
||||||
|
result.y_ = blendI * a.y_ + blend * b.y_;
|
||||||
|
result.z_ = blendI * a.z_ + blend * b.z_;
|
||||||
|
}
|
||||||
|
result.normalize();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "geometry.h"
|
||||||
|
class Quaternion
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
float x_, y_, z_, w_;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
Quaternion() = default;
|
||||||
|
Quaternion(float x, float y, float z, float w);
|
||||||
|
void normalize();
|
||||||
|
Matrix toRotationMatrix();
|
||||||
|
static Quaternion fromMatrix(Matrix matrix);
|
||||||
|
static Quaternion interpolate(Quaternion a, Quaternion b, float blend);
|
||||||
|
};
|
||||||
|
|
||||||
Reference in New Issue
Block a user