Skeleton tests
This commit is contained in:
parent
3d00ece41d
commit
ca018300a1
4 changed files with 226 additions and 49 deletions
BIN
4-intro.pdf
Normal file
BIN
4-intro.pdf
Normal file
Binary file not shown.
|
@ -1,5 +1,5 @@
|
||||||
// This source code is property of the Computer Graphics and Visualization
|
// This source code is property of the Computer Graphics and Visualization
|
||||||
// chair of the TU Dresden. Do not distribute!
|
// chair of the TU Dresden. Do not distribute!
|
||||||
// Copyright (C) CGV TU Dresden - All Rights Reserved
|
// Copyright (C) CGV TU Dresden - All Rights Reserved
|
||||||
//
|
//
|
||||||
#include "Skeleton.h"
|
#include "Skeleton.h"
|
||||||
|
@ -22,11 +22,11 @@ Skeleton::~Skeleton()
|
||||||
delete root;
|
delete root;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bone* Skeleton::get_root() const { return root; }
|
Bone *Skeleton::get_root() const { return root; }
|
||||||
const Mat4& Skeleton::get_origin() const { return origin; }
|
const Mat4 &Skeleton::get_origin() const { return origin; }
|
||||||
Vec3 Skeleton::get_origin_vec() const { return Vec3(origin(0, 3), origin(1, 3), origin(2,3)); }
|
Vec3 Skeleton::get_origin_vec() const { return Vec3(origin(0, 3), origin(1, 3), origin(2, 3)); }
|
||||||
void Skeleton::set_origin(const Vec3& v) { origin = translate(v); }
|
void Skeleton::set_origin(const Vec3 &v) { origin = translate(v); }
|
||||||
void Skeleton::set_origin(const Mat4& m) { origin = m; }
|
void Skeleton::set_origin(const Mat4 &m) { origin = m; }
|
||||||
|
|
||||||
enum ParseState
|
enum ParseState
|
||||||
{
|
{
|
||||||
|
@ -36,7 +36,7 @@ enum ParseState
|
||||||
Hierarchy,
|
Hierarchy,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool Skeleton::fromASFFile(const std::string& filename)
|
bool Skeleton::fromASFFile(const std::string &filename)
|
||||||
{
|
{
|
||||||
origin.identity();
|
origin.identity();
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@ bool Skeleton::fromASFFile(const std::string& filename)
|
||||||
reset_bounding_box();
|
reset_bounding_box();
|
||||||
ParseState state = Ignore;
|
ParseState state = Ignore;
|
||||||
|
|
||||||
Bone* current_node = nullptr;
|
Bone *current_node = nullptr;
|
||||||
|
|
||||||
bones.clear();
|
bones.clear();
|
||||||
|
|
||||||
|
@ -86,7 +86,8 @@ bool Skeleton::fromASFFile(const std::string& filename)
|
||||||
state = BoneData;
|
state = BoneData;
|
||||||
else if (str.find(":hierarchy") == 0)
|
else if (str.find(":hierarchy") == 0)
|
||||||
state = Hierarchy;
|
state = Hierarchy;
|
||||||
else state = Ignore;
|
else
|
||||||
|
state = Ignore;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
switch (state)
|
switch (state)
|
||||||
|
@ -104,7 +105,7 @@ bool Skeleton::fromASFFile(const std::string& filename)
|
||||||
while (!ss.eof())
|
while (!ss.eof())
|
||||||
{
|
{
|
||||||
ss >> dofstr;
|
ss >> dofstr;
|
||||||
AtomicTransform* dof;
|
AtomicTransform *dof;
|
||||||
if (dofstr.find("RX") == 0)
|
if (dofstr.find("RX") == 0)
|
||||||
dof = new AtomicXRotationTransform();
|
dof = new AtomicXRotationTransform();
|
||||||
else if (dofstr.find("RY") == 0)
|
else if (dofstr.find("RY") == 0)
|
||||||
|
@ -121,7 +122,7 @@ bool Skeleton::fromASFFile(const std::string& filename)
|
||||||
current_node->add_dof(dof);
|
current_node->add_dof(dof);
|
||||||
++n_dofs;
|
++n_dofs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BoneData:
|
case BoneData:
|
||||||
if (str.find("begin") == 0)
|
if (str.find("begin") == 0)
|
||||||
|
@ -157,7 +158,7 @@ bool Skeleton::fromASFFile(const std::string& filename)
|
||||||
ss >> a[0] >> a[1] >> a[2] >> order;
|
ss >> a[0] >> a[1] >> a[2] >> order;
|
||||||
for (int i = 0; i < 3; ++i)
|
for (int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
AtomicTransform* t;
|
AtomicTransform *t;
|
||||||
if (order.at(i) == 'X')
|
if (order.at(i) == 'X')
|
||||||
t = new AtomicXRotationTransform();
|
t = new AtomicXRotationTransform();
|
||||||
else if (order.at(i) == 'Y')
|
else if (order.at(i) == 'Y')
|
||||||
|
@ -177,7 +178,7 @@ bool Skeleton::fromASFFile(const std::string& filename)
|
||||||
while (!ss.eof())
|
while (!ss.eof())
|
||||||
{
|
{
|
||||||
ss >> dofstr;
|
ss >> dofstr;
|
||||||
AtomicTransform* dof;
|
AtomicTransform *dof;
|
||||||
if (dofstr.find("rx") == 0)
|
if (dofstr.find("rx") == 0)
|
||||||
dof = new AtomicXRotationTransform();
|
dof = new AtomicXRotationTransform();
|
||||||
else if (dofstr.find("ry") == 0)
|
else if (dofstr.find("ry") == 0)
|
||||||
|
@ -206,7 +207,6 @@ bool Skeleton::fromASFFile(const std::string& filename)
|
||||||
ss >> lower >> upper;
|
ss >> lower >> upper;
|
||||||
current_node->get_dof(n_dofs - i - 1)->set_limits(lower, upper);
|
current_node->get_dof(n_dofs - i - 1)->set_limits(lower, upper);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Hierarchy:
|
case Hierarchy:
|
||||||
|
@ -215,12 +215,12 @@ bool Skeleton::fromASFFile(const std::string& filename)
|
||||||
std::stringstream ss(str);
|
std::stringstream ss(str);
|
||||||
std::string parentstr;
|
std::string parentstr;
|
||||||
ss >> parentstr;
|
ss >> parentstr;
|
||||||
Bone* parent = bones[parentstr];
|
Bone *parent = bones[parentstr];
|
||||||
std::string childstr;
|
std::string childstr;
|
||||||
while (!ss.eof())
|
while (!ss.eof())
|
||||||
{
|
{
|
||||||
ss >> childstr;
|
ss >> childstr;
|
||||||
Bone* child = bones[childstr];
|
Bone *child = bones[childstr];
|
||||||
parent->add_child(child);
|
parent->add_child(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,7 +241,7 @@ bool Skeleton::fromASFFile(const std::string& filename)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Skeleton::postprocess(Bone* node, const Vec3& global_position)
|
void Skeleton::postprocess(Bone *node, const Vec3 &global_position)
|
||||||
{
|
{
|
||||||
//For display adaptation
|
//For display adaptation
|
||||||
auto bone_offset_in_global_system = node->get_direction_in_world_space() * node->get_length();
|
auto bone_offset_in_global_system = node->get_direction_in_world_space() * node->get_length();
|
||||||
|
@ -256,7 +256,77 @@ void Skeleton::postprocess(Bone* node, const Vec3& global_position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Skeleton::write_pinocchio_file(const std::string& filename)
|
Vec3 into_vec3(const Vec4 &v)
|
||||||
|
{
|
||||||
|
return Vec3(v.x(), v.y(), v.z());
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_vec3(const Vec3 &v)
|
||||||
|
{
|
||||||
|
std::cout << "(" << v.x() << ", " << v.y() << ", " << v.z() << ")" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Skeleton::get_bones(Bone *bone, std::vector<Bone *> &bone_list)
|
||||||
|
{
|
||||||
|
float len = length(bone->get_bone_local_root_position() - bone->get_bone_local_tip_position());
|
||||||
|
|
||||||
|
if (len > 0.0f)
|
||||||
|
bone_list.emplace_back(bone);
|
||||||
|
|
||||||
|
for (int i = 0; i < bone->childCount(); i++)
|
||||||
|
{
|
||||||
|
get_bones(bone->child_at(i), bone_list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Skeleton::find_bone(Bone *bone, std::vector<Bone *> &bone_list)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < bone_list.size(); i++)
|
||||||
|
{
|
||||||
|
if (bone == bone_list[i])
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void calc_points(Bone *bone, std::vector<Vec3> &points, Vec3 parent_pos)
|
||||||
|
{
|
||||||
|
Vec3 new_pos = parent_pos + into_vec3(bone->get_bone_local_tip_position());
|
||||||
|
|
||||||
|
points.emplace_back(new_pos);
|
||||||
|
|
||||||
|
for (int i = 0; i < bone->childCount(); i++)
|
||||||
|
{
|
||||||
|
calc_points(bone->child_at(i), points, new_pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void calc_points(Bone *bone, std::vector<Vec3> &points, Vec3 parent_pos, float correction)
|
||||||
|
{
|
||||||
|
Vec3 new_pos = parent_pos + (into_vec3(bone->get_bone_local_tip_position()) / correction);
|
||||||
|
|
||||||
|
points.emplace_back(new_pos);
|
||||||
|
|
||||||
|
for (int i = 0; i < bone->childCount(); i++)
|
||||||
|
{
|
||||||
|
calc_points(bone->child_at(i), points, new_pos, correction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float abs(float &v)
|
||||||
|
{
|
||||||
|
if (v < 0.0f)
|
||||||
|
{
|
||||||
|
return -v;
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Skeleton::write_pinocchio_file(const std::string &filename)
|
||||||
{
|
{
|
||||||
std::ofstream o;
|
std::ofstream o;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -264,17 +334,100 @@ void Skeleton::write_pinocchio_file(const std::string& filename)
|
||||||
o.open(wfilename, std::ios::out);
|
o.open(wfilename, std::ios::out);
|
||||||
#else
|
#else
|
||||||
o.open(filename, std::ios::out);
|
o.open(filename, std::ios::out);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (o)
|
if (o)
|
||||||
{
|
{
|
||||||
/*Task 4.1: Write Pinocchio file into o */
|
/*Task 4.1: Write Pinocchio file into o */
|
||||||
|
|
||||||
|
std::vector<Bone *> bone_list;
|
||||||
|
get_bones(root, bone_list);
|
||||||
|
|
||||||
|
// gather all points
|
||||||
|
std::vector<Vec3> points;
|
||||||
|
calc_points(root, points, Vec3(0.0f, 0.0f, 0.0f));
|
||||||
|
|
||||||
|
Vec3 min(0.0f, 0.0f, 0.0f);
|
||||||
|
Vec3 max(0.0f, 0.0f, 0.0f);
|
||||||
|
|
||||||
|
for (auto &point : points)
|
||||||
|
{
|
||||||
|
//print_vec3(point);
|
||||||
|
|
||||||
|
if (point.x() < min.x())
|
||||||
|
{
|
||||||
|
min.x() = point.x();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (point.y() < min.y())
|
||||||
|
{
|
||||||
|
min.y() = point.y();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (point.z() < min.z())
|
||||||
|
{
|
||||||
|
min.z() = point.z();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (point.x() > max.x())
|
||||||
|
{
|
||||||
|
max.x() = point.x();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (point.y() > max.y())
|
||||||
|
{
|
||||||
|
max.y() = point.y();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (point.z() > max.z())
|
||||||
|
{
|
||||||
|
max.z() = point.z();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//std::cout << "min: ";
|
||||||
|
//print_vec3(min);
|
||||||
|
|
||||||
|
//std::cout << "max: ";
|
||||||
|
//print_vec3(max);
|
||||||
|
|
||||||
|
float x_diff = abs(min.x()) + abs(max.x());
|
||||||
|
float y_diff = abs(min.y()) + abs(max.y());
|
||||||
|
float z_diff = abs(min.z()) + abs(max.z());
|
||||||
|
|
||||||
|
float max_diff = std::max(x_diff, std::max(y_diff, z_diff));
|
||||||
|
|
||||||
|
std::vector<Vec3> points2;
|
||||||
|
calc_points(root, points2, Vec3(0.0f, 0.0f, 0.0f), max_diff);
|
||||||
|
|
||||||
|
for (auto p : points2)
|
||||||
|
{
|
||||||
|
print_vec3(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
//std::cout << "max_diff: " << max_diff << std::endl;
|
||||||
|
|
||||||
|
// ---------------------------- info ----------------------------
|
||||||
|
int i = 0;
|
||||||
|
for (Bone *bone : bone_list)
|
||||||
|
{
|
||||||
|
//float len = length(bone->get_bone_local_tip_position());
|
||||||
|
|
||||||
|
int parent_index = find_bone(bone->get_parent(), bone_list);
|
||||||
|
|
||||||
|
//std::cout << i++ << ": " << bone->get_name() << ": " << len << " parent: " << parent_index << std::endl;
|
||||||
|
|
||||||
|
Vec3 c = into_vec3(bone->get_bone_local_tip_position()) / max_diff;
|
||||||
|
|
||||||
|
o << i++ << " " << c.x() << " " << c.y() << " " << c.z() << " " << parent_index << std::endl;
|
||||||
|
}
|
||||||
|
//std::cout << std::endl
|
||||||
|
// << "---------------------------" << std::endl
|
||||||
|
// << std::endl;
|
||||||
}
|
}
|
||||||
o.close();
|
o.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Skeleton::read_pinocchio_file(std::string filename)
|
void Skeleton::read_pinocchio_file(std::string filename)
|
||||||
{
|
{
|
||||||
std::ifstream o;
|
std::ifstream o;
|
||||||
|
@ -294,18 +447,14 @@ void Skeleton::read_pinocchio_file(std::string filename)
|
||||||
postprocess(root, get_origin_vec());
|
postprocess(root, get_origin_vec());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Skeleton::get_skinning_matrices(std::vector<Mat4> &matrices)
|
||||||
|
|
||||||
void Skeleton::get_skinning_matrices(std::vector<Mat4>& matrices)
|
|
||||||
{
|
{
|
||||||
/*Task 4.6: Calculate skinning matrices */
|
/*Task 4.6: Calculate skinning matrices */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bone *Skeleton::find_bone(const std::string &name) const
|
||||||
|
{
|
||||||
Bone* Skeleton::find_bone(const std::string& name) const
|
auto it = bones.find(name);
|
||||||
{
|
|
||||||
auto it = bones.find(name);
|
|
||||||
if (it == bones.end())
|
if (it == bones.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// This source code is property of the Computer Graphics and Visualization
|
// This source code is property of the Computer Graphics and Visualization
|
||||||
// chair of the TU Dresden. Do not distribute!
|
// chair of the TU Dresden. Do not distribute!
|
||||||
// Copyright (C) CGV TU Dresden - All Rights Reserved
|
// Copyright (C) CGV TU Dresden - All Rights Reserved
|
||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
|
@ -10,45 +10,43 @@
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
class Skeleton : public IHasBoundingBox
|
class Skeleton : public IHasBoundingBox
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Skeleton();
|
Skeleton();
|
||||||
~Skeleton();
|
~Skeleton();
|
||||||
|
|
||||||
//Loads skeleton data from an ASF file.
|
//Loads skeleton data from an ASF file.
|
||||||
bool fromASFFile(const std::string& filename);
|
bool fromASFFile(const std::string &filename);
|
||||||
|
|
||||||
//Writes the current skeleton to a Pinocchio file.
|
//Writes the current skeleton to a Pinocchio file.
|
||||||
void write_pinocchio_file(const std::string& filename);
|
void write_pinocchio_file(const std::string &filename);
|
||||||
|
|
||||||
//Loads a Pinocchio skeleton file and adapts the current skeleton according to this file.
|
//Loads a Pinocchio skeleton file and adapts the current skeleton according to this file.
|
||||||
void read_pinocchio_file(std::string filename);
|
void read_pinocchio_file(std::string filename);
|
||||||
|
|
||||||
//Fille the matrices vector with the skinning matrices for all bones in DFS order
|
//Fille the matrices vector with the skinning matrices for all bones in DFS order
|
||||||
void get_skinning_matrices(std::vector<Mat4>& matrices);
|
void get_skinning_matrices(std::vector<Mat4> &matrices);
|
||||||
|
|
||||||
//Returns the skeleton's root bone
|
//Returns the skeleton's root bone
|
||||||
Bone* get_root() const;
|
Bone *get_root() const;
|
||||||
|
|
||||||
const Mat4& get_origin() const;
|
const Mat4 &get_origin() const;
|
||||||
Vec3 get_origin_vec() const;
|
Vec3 get_origin_vec() const;
|
||||||
void set_origin(const Vec3&);
|
void set_origin(const Vec3 &);
|
||||||
void set_origin(const Mat4&);
|
void set_origin(const Mat4 &);
|
||||||
|
|
||||||
Bone* find_bone(const std::string& name) const;
|
Bone *find_bone(const std::string &name) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Mat4 origin;
|
Mat4 origin;
|
||||||
std::string version;
|
std::string version;
|
||||||
std::string name;
|
std::string name;
|
||||||
Bone* root;
|
Bone *root;
|
||||||
void postprocess(Bone* node, const Vec3& global_position);
|
void postprocess(Bone *node, const Vec3 &global_position);
|
||||||
|
|
||||||
|
void get_bones(Bone *bone, std::vector<Bone *> &bone_list);
|
||||||
|
int find_bone(Bone *bone, std::vector<Bone *> &bone_list);
|
||||||
|
|
||||||
|
|
||||||
std::map<const std::string, Bone*> bones;
|
std::map<const std::string, Bone *> bones;
|
||||||
};
|
};
|
30
penis.txt
Normal file
30
penis.txt
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
0 0.0429472 -0.0565452 0.0264444 -1
|
||||||
|
1 -7.5121e-09 -0.225528 0 0
|
||||||
|
2 0 -0.236038 0 1
|
||||||
|
3 8.92062e-09 -0.073179 -0.014522 2
|
||||||
|
4 -5.48289e-17 -0.0374839 4.69168e-08 3
|
||||||
|
5 -0.0411343 -0.0565452 0.0264444 -1
|
||||||
|
6 0 -0.234226 0 5
|
||||||
|
7 -7.5121e-09 -0.236596 0 6
|
||||||
|
8 4.69506e-09 -0.0744582 -0.0151752 7
|
||||||
|
9 2.00063e-16 -0.0381506 4.77513e-08 8
|
||||||
|
10 0.000890649 0.0641375 -0.00609295 -1
|
||||||
|
11 0.00178704 0.0645553 -0.00134698 10
|
||||||
|
12 0.00128702 0.0650298 0.00152129 11
|
||||||
|
13 -0.00170664 0.0550206 0.00542001 12
|
||||||
|
14 0.00327919 0.0554969 -0.00390619 13
|
||||||
|
15 0.00117224 0.0557831 -0.00196647 14
|
||||||
|
16 0.105943 0.0378376 -0.00980558 12
|
||||||
|
17 1.68454e-07 -0.157005 -2.90101e-07 16
|
||||||
|
18 1.17764e-07 -0.10976 -2.02806e-07 17
|
||||||
|
19 -3.12333e-18 -0.0548801 7.10897e-08 18
|
||||||
|
20 -1.28279e-18 -0.0225364 2.91929e-08 19
|
||||||
|
21 -1.0339e-18 -0.0181695 2.35361e-08 20
|
||||||
|
22 1.78412e-08 -0.0260878 3.10974e-08 19
|
||||||
|
23 -0.0988282 0.0432937 -0.0127496 12
|
||||||
|
24 -1.77206e-07 -0.165162 -3.05173e-07 23
|
||||||
|
25 -1.16433e-07 -0.108519 -2.00513e-07 24
|
||||||
|
26 3.08802e-18 -0.0542597 6.70519e-08 25
|
||||||
|
27 1.11643e-18 -0.0196147 2.4239e-08 26
|
||||||
|
28 8.99718e-19 -0.0158139 1.95421e-08 27
|
||||||
|
29 -1.50242e-08 -0.0227056 2.70658e-08 26
|
Loading…
Reference in a new issue