Merge solution and next task
This commit is contained in:
parent
b5748c2902
commit
3b55561ce2
10 changed files with 225 additions and 364 deletions
BIN
03_IK.pdf
Normal file
BIN
03_IK.pdf
Normal file
Binary file not shown.
BIN
3-intro.pdf
Normal file
BIN
3-intro.pdf
Normal file
Binary file not shown.
|
@ -79,3 +79,13 @@ bool Animation::read_amc_file(std::string filename, Skeleton* s)
|
||||||
|
|
||||||
int Animation::frame_count() const { return frames.size(); }
|
int Animation::frame_count() const { return frames.size(); }
|
||||||
|
|
||||||
|
void Animation::apply_frame(int frame) const
|
||||||
|
{
|
||||||
|
for (auto& bone : frames.at(frame))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < bone.bone->dof_count(); ++i)
|
||||||
|
{
|
||||||
|
bone.bone->get_dof(i)->set_value(bone.dof_values[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,7 +16,7 @@ public:
|
||||||
bool read_amc_file(std::string filename, Skeleton*);
|
bool read_amc_file(std::string filename, Skeleton*);
|
||||||
int frame_count() const;
|
int frame_count() const;
|
||||||
|
|
||||||
|
void apply_frame(int frame) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//Contains a std::vector<AnimationFrameBone> for each frame, which contains animation data for a set of bones.
|
//Contains a std::vector<AnimationFrameBone> for each frame, which contains animation data for a set of bones.
|
||||||
|
|
|
@ -40,7 +40,45 @@ Mat4 AtomicRotationTransform::calculate_matrix()
|
||||||
return rotate(axis, (float)value);
|
return rotate(axis, (float)value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AtomicRotationTransform::drawIndicator(float size)
|
||||||
|
{
|
||||||
|
if (lower_limit == upper_limit)
|
||||||
|
return;
|
||||||
|
//Calculate rotation matrix from x-axis to current axis
|
||||||
|
Vec3 rot_axis = cgv::math::cross(Vec3(1, 0, 0), axis);
|
||||||
|
float angle = acosf(axis.x() / axis.length());
|
||||||
|
Mat4 t;
|
||||||
|
if (angle == 0)
|
||||||
|
t.identity();
|
||||||
|
else
|
||||||
|
t = rotate(rot_axis, angle * 180.0f / 3.1415926f);
|
||||||
|
glBegin(GL_TRIANGLE_FAN);
|
||||||
|
glVertex3f(0, 0, 0);
|
||||||
|
for (float v = (float)lower_limit; v <= upper_limit; v += 5)
|
||||||
|
{
|
||||||
|
auto p = t * size * Vec4(0, -cosf(v * PI / 180.0f), -sinf(v * PI / 180.0f), 0);
|
||||||
|
glVertex3f(p.x(), p.y(), p.z());
|
||||||
|
}
|
||||||
|
auto end = t * size * Vec4(0, -cosf((float)upper_limit * PI / 180.0f), -sinf((float)upper_limit * PI / 180.0f), 0);
|
||||||
|
glVertex3f(end.x(), end.y(), end.z());
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
void AtomicRotationTransform::drawActualIndicator(float size)
|
||||||
|
{
|
||||||
|
//Calculate rotation matrix from x-axis to current axis
|
||||||
|
Vec3 rot_axis = cgv::math::cross(Vec3(1, 0, 0), axis);
|
||||||
|
float angle = acosf(axis.x() / axis.length());
|
||||||
|
Mat4 t;
|
||||||
|
if (angle == 0)
|
||||||
|
t.identity();
|
||||||
|
else
|
||||||
|
t = rotate(rot_axis, angle * 180.0f / 3.1415926f);
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glVertex3f(0, 0, 0);
|
||||||
|
auto p = t * size * Vec4(0, -cosf((float)value * PI / 180.0f), -sinf((float)value * PI / 180.0f), 0);
|
||||||
|
glVertex3f(p.x(), p.y(), p.z());
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
void AtomicRotationTransform::optimize_value(const Vec3& local_vector, const Vec3& target, bool inverse)
|
void AtomicRotationTransform::optimize_value(const Vec3& local_vector, const Vec3& target, bool inverse)
|
||||||
{
|
{
|
||||||
|
|
|
@ -57,7 +57,10 @@ public:
|
||||||
virtual void optimize_value(const Vec3& local_vector, const Vec3& target, bool inverse = false) = 0;
|
virtual void optimize_value(const Vec3& local_vector, const Vec3& target, bool inverse = false) = 0;
|
||||||
virtual void optimize_value(const Vec3& local_vector, const Vec3& target) { optimize_value(local_vector, target, false); }
|
virtual void optimize_value(const Vec3& local_vector, const Vec3& target) { optimize_value(local_vector, target, false); }
|
||||||
|
|
||||||
|
//Draws an indicator that visualizes the transform, including its limits.
|
||||||
|
virtual void drawIndicator(float size) = 0;
|
||||||
|
//Draws an indicator that visualizes the current scalar parameter.
|
||||||
|
virtual void drawActualIndicator(float size) = 0;
|
||||||
|
|
||||||
std::string get_name() const;
|
std::string get_name() const;
|
||||||
|
|
||||||
|
@ -84,7 +87,8 @@ public:
|
||||||
virtual Mat4 calculate_matrix();
|
virtual Mat4 calculate_matrix();
|
||||||
virtual void optimize_value(const Vec3& local_vector, const Vec3& target, bool inverse = false);
|
virtual void optimize_value(const Vec3& local_vector, const Vec3& target, bool inverse = false);
|
||||||
|
|
||||||
|
virtual void drawIndicator(float size);
|
||||||
|
virtual void drawActualIndicator(float size);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Vec3 axis;
|
Vec3 axis;
|
||||||
|
@ -115,7 +119,8 @@ public:
|
||||||
virtual Mat4 calculate_matrix();
|
virtual Mat4 calculate_matrix();
|
||||||
virtual void optimize_value(const Vec3& local_vector, const Vec3& target, bool inverse = false);
|
virtual void optimize_value(const Vec3& local_vector, const Vec3& target, bool inverse = false);
|
||||||
|
|
||||||
|
virtual void drawIndicator(float size) { };
|
||||||
|
virtual void drawActualIndicator(float size) { };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int dim;
|
int dim;
|
||||||
|
|
|
@ -9,29 +9,9 @@
|
||||||
|
|
||||||
#include "math_helper.h"
|
#include "math_helper.h"
|
||||||
|
|
||||||
std::string from_Vec3(Vec3 &v)
|
|
||||||
{
|
|
||||||
std::stringstream is;
|
|
||||||
|
|
||||||
is << "(" << v.x() << ", " << v.y() << ", " << v.z() << ")";
|
|
||||||
|
|
||||||
return is.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
float calc_angle(Vec3 dir_vec, Vec3 axis)
|
|
||||||
{
|
|
||||||
float dot_result = dot(dir_vec, axis);
|
|
||||||
|
|
||||||
float length_v1 = length(dir_vec);
|
|
||||||
float length_v2 = length(axis);
|
|
||||||
|
|
||||||
return acos(dot_result / (length_v1 * length_v2));
|
|
||||||
}
|
|
||||||
|
|
||||||
Bone::Bone()
|
Bone::Bone()
|
||||||
: parent(nullptr), length(0.0f), direction_in_world_space(0.0, 0.0, 0.0), translationTransforms(0)
|
: parent(nullptr), length(0.0f), direction_in_world_space(0.0, 0.0, 0.0), translationTransforms(0)
|
||||||
{
|
{}
|
||||||
}
|
|
||||||
|
|
||||||
Bone::~Bone()
|
Bone::~Bone()
|
||||||
{
|
{
|
||||||
|
@ -50,45 +30,22 @@ void Bone::calculate_matrices()
|
||||||
{
|
{
|
||||||
orientationTransformGlobalToLocal.identity();
|
orientationTransformGlobalToLocal.identity();
|
||||||
std::for_each(orientation.begin(), orientation.end(), [&](AtomicTransform* t) {
|
std::for_each(orientation.begin(), orientation.end(), [&](AtomicTransform* t) {
|
||||||
//std::cout << name << " orientation " << t->get_name() << ": " << t->get_value() << std::endl;
|
|
||||||
|
|
||||||
orientationTransformGlobalToLocal = orientationTransformGlobalToLocal * t->calculate_matrix();
|
orientationTransformGlobalToLocal = orientationTransformGlobalToLocal * t->calculate_matrix();
|
||||||
});
|
});
|
||||||
|
|
||||||
orientationTransformLocalToGlobal = cgv::math::inv(orientationTransformGlobalToLocal);
|
orientationTransformLocalToGlobal = cgv::math::inv(orientationTransformGlobalToLocal);
|
||||||
|
|
||||||
//std::cout << name << " direction " << from_Vec3(direction_in_world_space) << std::endl;
|
Vec4 globalDirection = Vec4(direction_in_world_space.x() * length, direction_in_world_space.y() * length, direction_in_world_space.z() * length, 0);
|
||||||
//std::cout << name << " length " << length << std::endl;
|
Vec4 localDirection = orientationTransformLocalToGlobal * globalDirection;
|
||||||
|
translationTransformCurrentJointToNext = translate(localDirection.x(), localDirection.y(), localDirection.z());
|
||||||
/*Task 2.1: Implement matrix calculation */
|
if (parent != nullptr)
|
||||||
Vec3 vector = direction_in_world_space * length;
|
|
||||||
//translationTransformCurrentJointToNext = orientationTransformLocalToGlobal * translate(vector) * orientationTransformGlobalToLocal;
|
|
||||||
translationTransformCurrentJointToNext = translate(vector);
|
|
||||||
|
|
||||||
if (parent == nullptr)
|
|
||||||
{
|
{
|
||||||
orientationTransformPrevJointToCurrent.identity();
|
orientationTransformPrevJointToCurrent = parent->orientationTransformLocalToGlobal * orientationTransformGlobalToLocal;
|
||||||
|
translationTransformGlobalToLocal = parent->translationTransformGlobalToLocal * translate(parent->direction_in_world_space * parent->length);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Vec3 prev_dir = parent->get_direction_in_world_space();
|
orientationTransformPrevJointToCurrent = orientationTransformGlobalToLocal;
|
||||||
Vec3 &curr_dir = direction_in_world_space;
|
translationTransformGlobalToLocal.identity();
|
||||||
|
|
||||||
if (prev_dir.x() == 0.0f && prev_dir.y() == 0.0f && prev_dir.z() == 0.0f)
|
|
||||||
{
|
|
||||||
orientationTransformPrevJointToCurrent.identity();
|
|
||||||
}
|
|
||||||
else if (prev_dir == curr_dir)
|
|
||||||
{
|
|
||||||
orientationTransformPrevJointToCurrent.identity();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float angle = calc_angle(curr_dir, prev_dir);
|
|
||||||
Vec3 axis = cross(curr_dir, prev_dir);
|
|
||||||
|
|
||||||
orientationTransformPrevJointToCurrent = rotate(axis, angle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Task 4.6: Implement matrix calculation */
|
/*Task 4.6: Implement matrix calculation */
|
||||||
|
@ -96,40 +53,18 @@ void Bone::calculate_matrices()
|
||||||
|
|
||||||
Mat4 Bone::calculate_transform_prev_to_current_with_dofs()
|
Mat4 Bone::calculate_transform_prev_to_current_with_dofs()
|
||||||
{
|
{
|
||||||
//Task 2.1: Implement matrix calculation
|
Mat4 t = calculate_transform_prev_to_current_without_dofs();
|
||||||
if (parent == NULL)
|
for (unsigned int i = 0; i < dofs.size(); ++i)
|
||||||
{
|
t = t * dofs[i]->calculate_matrix();
|
||||||
Mat4 t;
|
|
||||||
t.identity();
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mat4 dofs_matrix;
|
|
||||||
dofs_matrix.identity();
|
|
||||||
|
|
||||||
std::for_each(dofs.begin(), dofs.end(), [&](std::shared_ptr<AtomicTransform> &t) {
|
|
||||||
dofs_matrix = dofs_matrix * t->calculate_matrix();
|
|
||||||
});
|
|
||||||
|
|
||||||
return parent->get_translation_transform_current_joint_to_next() * orientationTransformPrevJointToCurrent * dofs_matrix;
|
|
||||||
}
|
|
||||||
|
|
||||||
Mat4 Bone::calculate_transform_prev_to_current_without_dofs()
|
Mat4 Bone::calculate_transform_prev_to_current_without_dofs()
|
||||||
{
|
{
|
||||||
//Task 2.1: Implement matrix calculation
|
Mat4 t = orientationTransformPrevJointToCurrent;
|
||||||
return parent->get_translation_transform_current_joint_to_next() * orientationTransformPrevJointToCurrent;
|
if (parent != nullptr)
|
||||||
}
|
t = parent->translationTransformCurrentJointToNext * t;
|
||||||
|
return t;
|
||||||
Mat4 Bone::get_total_orientation()
|
|
||||||
{
|
|
||||||
Mat4 parent_orientation;
|
|
||||||
|
|
||||||
if (parent != NULL)
|
|
||||||
parent_orientation = parent->get_total_orientation();
|
|
||||||
else
|
|
||||||
parent_orientation.identity();
|
|
||||||
|
|
||||||
return orientationTransformPrevJointToCurrent * parent_orientation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Bone::add_dof(AtomicTransform* dof)
|
void Bone::add_dof(AtomicTransform* dof)
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#include <cgv/base/find_action.h>
|
#include <cgv/base/find_action.h>
|
||||||
|
|
||||||
#include "math_helper.h"
|
#include "math_helper.h"
|
||||||
#include <fstream>
|
|
||||||
|
|
||||||
using namespace cgv::utils;
|
using namespace cgv::utils;
|
||||||
|
|
||||||
|
@ -21,167 +20,76 @@ cgv::render::shader_program Mesh::prog;
|
||||||
// The constructor of this class
|
// The constructor of this class
|
||||||
SkeletonViewer::SkeletonViewer(DataStore* data)
|
SkeletonViewer::SkeletonViewer(DataStore* data)
|
||||||
: node("Skeleton Viewer"), data(data)
|
: node("Skeleton Viewer"), data(data)
|
||||||
|
, animation(nullptr), animationTime(0)
|
||||||
{
|
{
|
||||||
connect(data->skeleton_changed, this, &SkeletonViewer::skeleton_changed);
|
connect(data->skeleton_changed, this, &SkeletonViewer::skeleton_changed);
|
||||||
|
|
||||||
connect(get_animation_trigger().shoot, this, &SkeletonViewer::timer_event);
|
connect(get_animation_trigger().shoot, this, &SkeletonViewer::timer_event);
|
||||||
|
|
||||||
for (int i = 0; i < SKELETON_DEPTH; i++)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < 3; j++)
|
|
||||||
{
|
|
||||||
colors[i][j] = static_cast<float>(rand()) / static_cast<float>(RAND_MAX);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
frame = 0;
|
|
||||||
inc_frame = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
double winkel_to_bogenmass(float v)
|
|
||||||
{
|
|
||||||
return (v * 2 * PI) / 360;
|
|
||||||
}
|
|
||||||
|
|
||||||
void draw_dof(Bone *node, Vec4 start_point)
|
|
||||||
{
|
|
||||||
|
|
||||||
for (int i = 0; i < node->dof_count(); i++)
|
|
||||||
{
|
|
||||||
|
|
||||||
Vec3 point_joint = Vec3(start_point.x(), start_point.y(), start_point.z());
|
|
||||||
|
|
||||||
auto bonelength = node->get_length();
|
|
||||||
|
|
||||||
double lower_limit = node->get_dof(i)->get_lower_limit();
|
|
||||||
double upper_limit = node->get_dof(i)->get_upper_limit();
|
|
||||||
|
|
||||||
// lowerlimit
|
|
||||||
auto bog_lower_limit = winkel_to_bogenmass(lower_limit);
|
|
||||||
auto tan_lower_limit = std::tan(bog_lower_limit);
|
|
||||||
auto cos_lower_limit = std::cos(bog_lower_limit);
|
|
||||||
|
|
||||||
// upperlimit
|
|
||||||
auto bog_upper_limit = winkel_to_bogenmass(upper_limit);
|
|
||||||
auto tan_upper_limit = std::tan(bog_upper_limit);
|
|
||||||
auto cos_upper_limit = std::cos(bog_upper_limit);
|
|
||||||
|
|
||||||
auto pt_min = bonelength * cos_lower_limit;
|
|
||||||
auto pt_max = bonelength * cos_upper_limit;
|
|
||||||
|
|
||||||
glBegin(GL_TRIANGLE_STRIP);
|
|
||||||
|
|
||||||
if (node->get_dof(i)->get_name() == "X-Rotation")
|
|
||||||
{
|
|
||||||
|
|
||||||
// drawing x movement (local)
|
|
||||||
glColor4f(0, 128, 0, 128);
|
|
||||||
glVertex3f(point_joint.x(), point_joint.y(), point_joint.z());
|
|
||||||
glVertex3f(point_joint.x(), point_joint.y() - 5, point_joint.z() + pt_max);
|
|
||||||
glVertex3f(point_joint.x(), point_joint.y() - 5, point_joint.z() - pt_min);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
if(node->get_dof(i)->get_name() == "Y-Rotation") {
|
|
||||||
// drawing y movement (local)
|
|
||||||
glColor4f(0, 128, 0, 128);
|
|
||||||
glVertex3f(point_joint.x(), point_joint.y(), point_joint.z());
|
|
||||||
glVertex3f(point_joint.x(), point_joint.y()+pt_max, point_joint.z());
|
|
||||||
glVertex3f(point_joint.x(), point_joint.y()-pt_min, point_joint.z());
|
|
||||||
std::cout « "X:" « point_joint.x() « " Y:" « point_joint.y()+pt_max « " Z:" « point_joint.z() « std::endl;
|
|
||||||
std::cout « pt_max « std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(node->get_dof(i)->get_name() == "Z-Rotation") {
|
|
||||||
// drawing z movement (local)
|
|
||||||
glColor4f(0, 128, 0, 128);
|
|
||||||
glVertex3f(point_joint.x(), point_joint.y(), point_joint.z());
|
|
||||||
glVertex3f(point_joint.x(), point_joint.y(), point_joint.z()+pt_max);
|
|
||||||
glVertex3f(point_joint.x(), point_joint.y(), point_joint.z()-pt_min);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
// drawing y movement (local)
|
|
||||||
glColor4f(128, 0, 0, 128);
|
|
||||||
glVertex3f(start_point.x(), start_point.y(), start_point.z());
|
|
||||||
glVertex3f(end_point.x(), end_point.y() - 5, end_point.z());
|
|
||||||
glVertex3f(end_point.x(), end_point.y() + 5, end_point.z());
|
|
||||||
|
|
||||||
// drawing z movement (local)
|
|
||||||
glColor4f(0, 0, 128, 128);
|
|
||||||
glVertex3f(start_point.x(), start_point.y(), start_point.z());
|
|
||||||
glVertex3f(end_point.x(), end_point.y(), end_point.z() - 5);
|
|
||||||
glVertex3f(end_point.x() + 5, end_point.y(), end_point.z() + 5);
|
|
||||||
*/
|
|
||||||
glEnd();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//draws a part of a skeleton, represented by the given root node
|
//draws a part of a skeleton, represented by the given root node
|
||||||
void SkeletonViewer::draw_skeleton_subtree(Bone *node, const Mat4 &global_to_parent_local, context &c, int depth)
|
void SkeletonViewer::draw_skeleton_subtree(Bone* node, const Mat4& global_to_parent_local, context& c, int level, bool arrows, bool indicators)
|
||||||
{
|
{
|
||||||
//Task: Draw skeleton
|
auto global_to_current_local = global_to_parent_local * node->calculate_transform_prev_to_current_with_dofs();
|
||||||
if (frame < animations.size())
|
auto my_root_position = global_to_current_local * node->get_bone_local_root_position();
|
||||||
|
auto my_tip_position = global_to_current_local * node->get_bone_local_tip_position();
|
||||||
|
if (arrows)
|
||||||
{
|
{
|
||||||
auto ¤t_step = animations[frame];
|
const GLubyte colors[][3] =
|
||||||
auto it = current_step.find(node->get_name());
|
|
||||||
|
|
||||||
if (it != current_step.end())
|
|
||||||
{
|
{
|
||||||
std::vector<float> &values = it->second;
|
{ 27,158,119 },
|
||||||
|
{ 217,95,2 },
|
||||||
if (values.size() == node->dof_count())
|
{ 117,112,179 },
|
||||||
{
|
{ 231,41,138 },
|
||||||
for (int i = 0; i < values.size(); i++)
|
{ 102,166,30 },
|
||||||
{
|
{ 230,171,2 },
|
||||||
node->get_dof(i)->set_value(values[i]);
|
{ 166,118,29 },
|
||||||
|
};
|
||||||
|
glColor3ubv(colors[level % 7]);
|
||||||
|
c.tesselate_arrow(cgv::math::fvec<double, 3u>(my_root_position.x(), my_root_position.y(), my_root_position.z()),
|
||||||
|
cgv::math::fvec<double, 3u>(my_tip_position.x(), my_tip_position.y(), my_tip_position.z()), 0.1, 2.0, 0.5);
|
||||||
}
|
}
|
||||||
}
|
Mat4 dof_matrix = global_to_parent_local * node->calculate_transform_prev_to_current_without_dofs();
|
||||||
}
|
float indicatorSize = (data->get_skeleton()->getMax() - data->get_skeleton()->getMin()).length() * 0.05f;
|
||||||
}
|
//draw indicators for dofs
|
||||||
|
if (indicators)
|
||||||
Mat4 local_transform = global_to_parent_local * node->calculate_transform_prev_to_current_with_dofs();
|
|
||||||
|
|
||||||
Vec4 zero = Vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
|
||||||
|
|
||||||
Vec4 p1 = global_to_parent_local * zero;
|
|
||||||
Vec4 p2 = local_transform * zero;
|
|
||||||
|
|
||||||
Vec3 p1_v3 = Vec3(p1.x(), p1.y(), p1.z());
|
|
||||||
Vec3 p2_v3 = Vec3(p2.x(), p2.y(), p2.z());
|
|
||||||
|
|
||||||
glColor3f(colors[depth][0], colors[depth][1], colors[depth][2]);
|
|
||||||
c.tesselate_arrow(p1_v3, p2_v3);
|
|
||||||
|
|
||||||
draw_dof(node, p1);
|
|
||||||
|
|
||||||
depth++;
|
|
||||||
|
|
||||||
for (int i = 0; i < node->childCount(); i++)
|
|
||||||
{
|
{
|
||||||
draw_skeleton_subtree(node->child_at(i), local_transform, c, depth);
|
glDepthMask(false);
|
||||||
|
int i = 0;
|
||||||
|
for (int i = 0; i < node->dof_count(); ++i)
|
||||||
|
{
|
||||||
|
auto t = node->get_dof(i);
|
||||||
|
glPushMatrix();
|
||||||
|
glMultMatrixf(dof_matrix);
|
||||||
|
glColor4f(0, 1, 0, 0.2f);
|
||||||
|
t->drawIndicator(indicatorSize);
|
||||||
|
glColor4f(0.5f, 1, 0.5f, 1);
|
||||||
|
t->drawActualIndicator(indicatorSize);
|
||||||
|
glPopMatrix();
|
||||||
|
dof_matrix = dof_matrix * node->get_dof(i)->calculate_matrix();
|
||||||
|
}
|
||||||
|
glDepthMask(true);
|
||||||
|
}
|
||||||
|
int n = node->childCount();
|
||||||
|
for (int i = 0; i < n; ++i)
|
||||||
|
{
|
||||||
|
auto child = node->child_at(i);
|
||||||
|
draw_skeleton_subtree(child, global_to_current_local, c, level + 1, arrows, indicators);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonViewer::timer_event(double, double dt)
|
void SkeletonViewer::timer_event(double, double dt)
|
||||||
{
|
{
|
||||||
/*Task: Implement animation */
|
if (animation && playing)
|
||||||
|
{
|
||||||
|
animationTime += dt;
|
||||||
|
int frame = (int)std::round(animationTime * 120.0) % animation->frame_count();
|
||||||
|
animation->apply_frame(frame);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonViewer::start_animation()
|
void SkeletonViewer::start_animation() { playing = true; }
|
||||||
{
|
void SkeletonViewer::stop_animation() { playing = false; }
|
||||||
frame = 0;
|
|
||||||
inc_frame = true;
|
|
||||||
post_redraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SkeletonViewer::stop_animation()
|
|
||||||
{
|
|
||||||
inc_frame = false;
|
|
||||||
//Task: Implement animation
|
|
||||||
}
|
|
||||||
|
|
||||||
void SkeletonViewer::skeleton_changed(std::shared_ptr<Skeleton> s)
|
void SkeletonViewer::skeleton_changed(std::shared_ptr<Skeleton> s)
|
||||||
{
|
{
|
||||||
|
@ -194,8 +102,7 @@ void SkeletonViewer::skeleton_changed(std::shared_ptr<Skeleton> s)
|
||||||
//Fit view to skeleton
|
//Fit view to skeleton
|
||||||
std::vector<cgv::render::view*> view_ptrs;
|
std::vector<cgv::render::view*> view_ptrs;
|
||||||
cgv::base::find_interface<cgv::render::view>(get_node(), view_ptrs);
|
cgv::base::find_interface<cgv::render::view>(get_node(), view_ptrs);
|
||||||
if (view_ptrs.empty())
|
if (view_ptrs.empty()) {
|
||||||
{
|
|
||||||
// If there is no view, we cannot update it
|
// If there is no view, we cannot update it
|
||||||
cgv::gui::message("could not find a view to adjust!!");
|
cgv::gui::message("could not find a view to adjust!!");
|
||||||
}
|
}
|
||||||
|
@ -346,58 +253,22 @@ void SkeletonViewer::load_animation()
|
||||||
std::string filename = cgv::gui::file_open_dialog("Open", "Animation File (*.amc):*.amc");
|
std::string filename = cgv::gui::file_open_dialog("Open", "Animation File (*.amc):*.amc");
|
||||||
if (!filename.empty())
|
if (!filename.empty())
|
||||||
{
|
{
|
||||||
animations.clear();
|
if (animation)
|
||||||
|
|
||||||
std::ifstream file(filename);
|
|
||||||
|
|
||||||
std::string line;
|
|
||||||
int current_index = -1;
|
|
||||||
|
|
||||||
while (std::getline(file, line))
|
|
||||||
{
|
{
|
||||||
if (line[0] == '#' || line[0] == ':')
|
delete animation;
|
||||||
{
|
animation = nullptr;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
auto a = new Animation();
|
||||||
int number = 0;
|
if (a->read_amc_file(filename, data->get_skeleton().get()))
|
||||||
|
|
||||||
std::istringstream sline(line);
|
|
||||||
sline >> number;
|
|
||||||
|
|
||||||
if (number != 0)
|
|
||||||
{
|
{
|
||||||
current_index = number - 1;
|
animationTime = 0;
|
||||||
|
animation = a;
|
||||||
//std::map<std::string, std::vector<AtomicTransform *>> tmp;
|
playing = true;
|
||||||
std::map<std::string, std::vector<float>> tmp;
|
|
||||||
animations.emplace_back(tmp);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (current_index < 0)
|
delete a;
|
||||||
abort();
|
cgv::gui::message("Could not load specified AMC file.");
|
||||||
|
|
||||||
std::string bone_name;
|
|
||||||
std::vector<float> values;
|
|
||||||
|
|
||||||
int first_blank = line.find_first_of(" ");
|
|
||||||
bone_name = line.substr(0, first_blank);
|
|
||||||
|
|
||||||
auto ¤t_map = animations[current_index];
|
|
||||||
|
|
||||||
std::string rest = line.substr(first_blank + 1, line.size());
|
|
||||||
std::stringstream sstream(rest);
|
|
||||||
float value;
|
|
||||||
|
|
||||||
while (sstream >> value)
|
|
||||||
{
|
|
||||||
values.push_back(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
// test if values alone are enough
|
|
||||||
current_map[bone_name] = values;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -466,11 +337,16 @@ void SkeletonViewer::draw(context &c)
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||||
|
|
||||||
if (data->get_skeleton() != nullptr)
|
if (data->get_skeleton() != nullptr)
|
||||||
draw_skeleton_subtree(data->get_skeleton()->get_root(), data->get_skeleton()->get_origin(), c, 0);
|
{
|
||||||
|
glEnable(GL_LIGHTING);
|
||||||
if (inc_frame)
|
glEnable(GL_CULL_FACE);
|
||||||
frame++;
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
if (frame >= animations.size())
|
draw_skeleton_subtree(data->get_skeleton()->get_root(), data->get_skeleton()->get_origin(), c, 0, true, false);
|
||||||
frame = 0;
|
glDisable(GL_LIGHTING);
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||||
|
draw_skeleton_subtree(data->get_skeleton()->get_root(), data->get_skeleton()->get_origin(), c, 0, false, true);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -21,8 +21,6 @@ using namespace cgv::math;
|
||||||
using namespace cgv::render;
|
using namespace cgv::render;
|
||||||
using namespace cgv::utils;
|
using namespace cgv::utils;
|
||||||
|
|
||||||
#define SKELETON_DEPTH 10
|
|
||||||
|
|
||||||
class SkeletonViewer : public node, public drawable, public provider
|
class SkeletonViewer : public node, public drawable, public provider
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -30,15 +28,9 @@ class SkeletonViewer : public node, public drawable, public provider
|
||||||
gui_group_ptr tree_view;
|
gui_group_ptr tree_view;
|
||||||
gui_group_ptr bone_group;
|
gui_group_ptr bone_group;
|
||||||
|
|
||||||
std::vector<std::map<std::string, std::vector<float>>> animations;
|
|
||||||
float colors[SKELETON_DEPTH][3];
|
|
||||||
|
|
||||||
// Maps gui elements in the tree view to a specific bone
|
// Maps gui elements in the tree view to a specific bone
|
||||||
std::map<base_ptr, Bone*> gui_to_bone;
|
std::map<base_ptr, Bone*> gui_to_bone;
|
||||||
|
|
||||||
bool inc_frame;
|
|
||||||
int frame;
|
|
||||||
|
|
||||||
// slot for the signal
|
// slot for the signal
|
||||||
void timer_event(double, double dt);
|
void timer_event(double, double dt);
|
||||||
void skeleton_changed(std::shared_ptr<Skeleton>);
|
void skeleton_changed(std::shared_ptr<Skeleton>);
|
||||||
|
@ -55,11 +47,15 @@ class SkeletonViewer : public node, public drawable, public provider
|
||||||
void load_animation();
|
void load_animation();
|
||||||
void start_choose_base();
|
void start_choose_base();
|
||||||
|
|
||||||
void draw_skeleton_subtree(Bone *node, const Mat4 &global_to_parent_local, context &c, int depth);
|
void draw_skeleton_subtree(Bone* node, const Mat4& global_to_parent_local, context& c, int level, bool arrows, bool indicators);
|
||||||
|
|
||||||
void dof_changed(double new_value);
|
void dof_changed(double new_value);
|
||||||
void recursive_connect_signals(Bone* b);
|
void recursive_connect_signals(Bone* b);
|
||||||
|
|
||||||
|
Animation* animation;
|
||||||
|
double animationTime;
|
||||||
|
bool playing;
|
||||||
|
|
||||||
void start_animation();
|
void start_animation();
|
||||||
void stop_animation();
|
void stop_animation();
|
||||||
|
|
||||||
|
@ -74,3 +70,4 @@ class SkeletonViewer : public node, public drawable, public provider
|
||||||
|
|
||||||
std::string get_parent_type() const;
|
std::string get_parent_type() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ struct Initializer
|
||||||
|
|
||||||
Initializer()
|
Initializer()
|
||||||
{
|
{
|
||||||
//register_object(base_ptr(new CGVDemo()), "");
|
|
||||||
|
|
||||||
data = new DataStore();
|
data = new DataStore();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue