Create raw bone hierarchy

This commit is contained in:
hodasemi 2018-06-09 10:16:18 +02:00
parent 3b55561ce2
commit 6d2fbf0421
4 changed files with 100 additions and 46 deletions

View file

@ -53,7 +53,14 @@
"utility": "cpp", "utility": "cpp",
"variant": "cpp", "variant": "cpp",
"algorithm": "cpp", "algorithm": "cpp",
"new": "cpp" "new": "cpp",
"deque": "cpp",
"list": "cpp",
"unordered_map": "cpp",
"unordered_set": "cpp",
"vector": "cpp",
"__config": "cpp",
"__nullptr": "cpp"
}, },
"editor.formatOnSave": true "editor.formatOnSave": true
} }

View file

@ -12,30 +12,79 @@
#include <cgv/math/inv.h> #include <cgv/math/inv.h>
#include <cgv/math/mat.h> #include <cgv/math/mat.h>
IKViewer::IKViewer(DataStore* data) IKViewer::IKViewer(DataStore *data)
: node("IK Viewer"), data(data), modifying(false), target_position(0, 0, 0, 1), max_iterations(20) : node("IK Viewer"), data(data), modifying(false), target_position(0, 0, 0, 1), max_iterations(20)
{ {
connect(data->endeffector_changed, this, &IKViewer::endeffector_changed); connect(data->endeffector_changed, this, &IKViewer::endeffector_changed);
connect(data->base_changed, this, &IKViewer::base_changed); connect(data->base_changed, this, &IKViewer::base_changed);
} }
void IKViewer::endeffector_changed(Bone* b) void IKViewer::endeffector_changed(Bone *b)
{ {
std::cout << "endeffector changed!" << std::endl;
calculate_kinematic_chain(data->get_base(), data->get_endeffector()); calculate_kinematic_chain(data->get_base(), data->get_endeffector());
post_redraw(); post_redraw();
} }
void IKViewer::base_changed(Bone* b) void IKViewer::base_changed(Bone *b)
{ {
std::cout << "base changed!" << std::endl;
calculate_kinematic_chain(data->get_base(), data->get_endeffector()); calculate_kinematic_chain(data->get_base(), data->get_endeffector());
post_redraw(); post_redraw();
} }
void IKViewer::calculate_kinematic_chain(Bone* base, Bone* endeffector) void IKViewer::calculate_kinematic_chain(Bone *base, Bone *endeffector)
{ {
std::cout << "calculate_kinematic_chain" << std::endl;
if (base)
std::cout << "Base bone: " << base->get_name() << std::endl;
else
{
std::cout << "no base set" << std::endl;
std::cout << std::endl;
return;
}
if (endeffector)
std::cout << "End bone: " << endeffector->get_name() << std::endl;
else
{
std::cout << "no endeffector set" << std::endl;
std::cout << std::endl;
return;
}
std::cout << std::endl;
/*Task 3.1: Calculate kinematic chain*/ /*Task 3.1: Calculate kinematic chain*/
// get list of bones in order of endeffector to base
std::vector<Bone *> bones;
Bone *current_bone = endeffector;
while (1)
{
bones.emplace_back(current_bone);
// break if we reached base bone
if (current_bone == base)
break;
// set next bone in hierarchy
current_bone = current_bone->get_parent();
}
for (Bone *bone : bones)
{
// TODO: calculate and add transforms to queue
std::shared_ptr<Transform> transform;
kinematic_chain.emplace_front(transform);
}
} }
void IKViewer::optimize() void IKViewer::optimize()
@ -44,7 +93,7 @@ void IKViewer::optimize()
data->dof_changed_by_ik = true; data->dof_changed_by_ik = true;
auto skeleton_size = (data->get_skeleton()->getMax() - data->get_skeleton()->getMin()); auto skeleton_size = (data->get_skeleton()->getMax() - data->get_skeleton()->getMin());
float distance_threshold = 0.0001f * std::max({ skeleton_size.x(), skeleton_size.y(), skeleton_size.z() }); float distance_threshold = 0.0001f * std::max({skeleton_size.x(), skeleton_size.y(), skeleton_size.z()});
//split the current matrix in: //split the current matrix in:
// before_dof -> dof -> after_dof // before_dof -> dof -> after_dof
@ -81,7 +130,7 @@ void IKViewer::set_target_position_2d(int x, int y)
int width = ctx->get_width(); int width = ctx->get_width();
int height = ctx->get_height(); int height = ctx->get_height();
float proj_position[4] = { (2.0f * x) / width - 1.0f, (-2.0f * y) / height + 1.0f, z, 1.0f }; float proj_position[4] = {(2.0f * x) / width - 1.0f, (-2.0f * y) / height + 1.0f, z, 1.0f};
auto unprojected = inv_mvp * cgv::math::vec<float>(4, proj_position); auto unprojected = inv_mvp * cgv::math::vec<float>(4, proj_position);
unprojected *= 1.0f / unprojected.w(); unprojected *= 1.0f / unprojected.w();
@ -95,15 +144,17 @@ void IKViewer::set_target_position_2d(int x, int y)
post_redraw(); post_redraw();
} }
bool IKViewer::handle(event &e)
bool IKViewer::handle(event& e)
{ {
if (e.get_kind() == EID_MOUSE) { if (e.get_kind() == EID_MOUSE)
cgv::gui::mouse_event me = (cgv::gui::mouse_event&) e; {
cgv::gui::mouse_event me = (cgv::gui::mouse_event &)e;
switch (me.get_action()) { switch (me.get_action())
{
case MA_PRESS: case MA_PRESS:
if (me.get_button() == MB_LEFT_BUTTON && me.get_modifiers() == EM_CTRL) { if (me.get_button() == MB_LEFT_BUTTON && me.get_modifiers() == EM_CTRL)
{
modifying = true; modifying = true;
set_target_position_2d(me.get_x(), me.get_y()); set_target_position_2d(me.get_x(), me.get_y());
return true; return true;
@ -119,23 +170,24 @@ bool IKViewer::handle(event& e)
return true; return true;
} }
break; break;
default: break; default:
break;
} }
} }
return false; return false;
} }
void IKViewer::stream_help(std::ostream& os) void IKViewer::stream_help(std::ostream &os)
{ {
} }
void IKViewer::draw(cgv::render::context& ctx) void IKViewer::draw(cgv::render::context &ctx)
{ {
if (!data->get_skeleton()) if (!data->get_skeleton())
return; return;
auto skeleton_size = (data->get_skeleton()->getMax() - data->get_skeleton()->getMin()); auto skeleton_size = (data->get_skeleton()->getMax() - data->get_skeleton()->getMin());
float scale = 0.2f * std::max({ skeleton_size.x(), skeleton_size.y(), skeleton_size.z() }); float scale = 0.2f * std::max({skeleton_size.x(), skeleton_size.y(), skeleton_size.z()});
glBegin(GL_LINES); glBegin(GL_LINES);

View file

@ -25,23 +25,21 @@ using namespace cgv::utils;
class IKViewer : public node, public drawable, public provider, public event_handler class IKViewer : public node, public drawable, public provider, public event_handler
{ {
private: private:
DataStore* data; DataStore *data;
void set_target_position_2d(int x, int y); void set_target_position_2d(int x, int y);
void endeffector_changed(Bone*); void endeffector_changed(Bone *);
void base_changed(Bone*); void base_changed(Bone *);
void calculate_kinematic_chain(Bone* base, Bone* endeffector); void calculate_kinematic_chain(Bone *base, Bone *endeffector);
bool modifying; //Specifies if the user is currently modifying the IK target position bool modifying; //Specifies if the user is currently modifying the IK target position
Vec4 target_position; Vec4 target_position;
Mat4 current_endeffector_matrix; //transform from base to endeffector Mat4 current_endeffector_matrix; //transform from base to endeffector
Mat4 current_base_matrix; //transform from global origin to base Mat4 current_base_matrix; //transform from global origin to base
unsigned int max_iterations; unsigned int max_iterations;
@ -49,16 +47,15 @@ private:
void optimize(); void optimize();
public: public:
// The constructor of this class // The constructor of this class
IKViewer(DataStore*); IKViewer(DataStore *);
bool handle(cgv::gui::event& e); bool handle(cgv::gui::event &e);
void stream_help(std::ostream& os); void stream_help(std::ostream &os);
// Create the gui elements // Create the gui elements
void create_gui(); void create_gui();
// Draw the scene // Draw the scene
void draw(context& c); void draw(context &c);
}; };

View file

@ -16,17 +16,15 @@ using namespace cgv::base;
struct Initializer struct Initializer
{ {
DataStore* data; DataStore *data;
Initializer() Initializer()
{ {
data = new DataStore(); data = new DataStore();
register_object(base_ptr(new SkeletonViewer(data)), ""); register_object(base_ptr(new SkeletonViewer(data)), "");
/*register_object(base_ptr(new IKViewer(data)), "");*/ register_object(base_ptr(new IKViewer(data)), "");
/*register_object(base_ptr(new SkinnedMeshViewer(data)), "");*/ /*register_object(base_ptr(new SkinnedMeshViewer(data)), "");*/
} }