Create raw bone hierarchy
This commit is contained in:
parent
3b55561ce2
commit
6d2fbf0421
4 changed files with 100 additions and 46 deletions
9
.vscode/settings.json
vendored
9
.vscode/settings.json
vendored
|
@ -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
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -25,15 +25,15 @@ 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
|
||||||
|
|
||||||
|
@ -41,24 +41,21 @@ private:
|
||||||
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;
|
||||||
|
|
||||||
std::list<std::shared_ptr<Transform>> kinematic_chain;
|
std::list<std::shared_ptr<Transform>> kinematic_chain;
|
||||||
|
|
||||||
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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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)), "");*/
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue