53 #define ACG_SKELETONNODET_C 57 #include "SkeletonNodeT.hh" 58 #include <ACG/GL/gl.hh> 59 #include <ACG/GL/IRenderer.hh> 74 template <
class SkeletonType>
77 bCoordFramesVisible_(false),
84 this->multipassNodeSetActive(3,
true);
87 cone_ =
new ACG::GLCone(slices_, stacks_, 1.0f, 0.0f,
false,
false);
97 template <
class SkeletonType>
116 template <
class SkeletonType>
128 template <
class SkeletonType>
131 if(skeleton_.jointCount() == 0)
134 Pose *pose = skeleton_.pose(hAni_);
135 typename SkeletonType::Iterator it;
136 for(it = skeleton_.begin(); it != skeleton_.end(); ++it)
138 _bbMin.
minimize( (
Vec3d)pose->globalTranslation((*it)->id()) );
139 _bbMax.
maximize( (
Vec3d)pose->globalTranslation((*it)->id()) );
143 fFrameSize_ = (_bbMin - _bbMax).norm() * 0.07;
152 template <
class SkeletonType>
155 return (DrawModes::WIREFRAME | DrawModes::POINTS | DrawModes::SOLID_FLAT_SHADED
156 | DrawModes::SOLID_FACES_COLORED | DrawModes::SOLID_FACES_COLORED_FLAT_SHADED);
163 template <
class SkeletonType>
175 template <
class SkeletonType>
179 for(
int i = 0; i < 3; ++i)
181 for(
int x = 0; x < 3; ++x)
184 for(
int x = 0; x < 3; ++x)
200 template <
class SkeletonType>
205 h = int(floor(_HSV[0] / 60.0));
206 f = _HSV[0] / 60.0 - float(h);
207 p = _HSV[2] * (1 - _HSV[1]);
208 q = _HSV[2] * (1 - _HSV[1] * f);
209 t = _HSV[2] * (1 - _HSV[1] * (1 - f));
261 template <
class SkeletonType>
264 double maxC = _RGB[2];
269 double minC = _RGB[2];
275 double delta = maxC - minC;
287 double dR = 60 * (maxC - _RGB[0]) / delta + 180;
288 double dG = 60 * (maxC - _RGB[1]) / delta + 180;
289 double dB = 60 * (maxC - _RGB[2]) / delta + 180;
292 else if (_RGB[1] == maxC)
313 template <
class SkeletonType>
319 glPushAttrib(GL_ENABLE_BIT);
321 Pose *pose = skeleton_.pose(hAni_);
322 typename SkeletonType::Iterator it;
328 if (_drawMode & DrawModes::POINTS)
340 for(it = skeleton_.begin(); it != skeleton_.end(); ++it)
344 if ( (*it)->selected() )
353 if ( (*it)->isRoot() )
371 const double sphereSize = unprojectPointSize((
double)_state.
point_size(),
372 pose->globalTranslation( (*it)->id() ), _state);
374 sphere_->draw(_state,sphereSize,
ACG::Vec3f(pose->globalTranslation( (*it)->id() )));
383 if(bCoordFramesVisible_)
388 for(it = skeleton_.begin(); it != skeleton_.end(); ++it)
390 typename SkeletonType::Matrix global = pose->globalMatrix( (*it)->id() );
391 NormalizeCoordinateFrame(global);
392 glColor3f(0.8f, 0.2f, 0.2f);
393 glVertex( global.transform_point(Point(fFrameSize_, 0, 0)) );
394 glColor3f(0.2f, 0.8f, 0.2f);
395 glVertex( global.transform_point(Point(0, fFrameSize_, 0)) );
396 glColor3f(0.2f, 0.2f, 0.8f);
397 glVertex( global.transform_point(Point(0, 0, fFrameSize_)) );
407 if ( (_drawMode & DrawModes::WIREFRAME)
408 || (_drawMode & DrawModes::SOLID_FLAT_SHADED)
409 || (_drawMode & DrawModes::SOLID_FACES_COLORED)
410 || (_drawMode & DrawModes::SOLID_FACES_COLORED_FLAT_SHADED) )
413 if ( (_drawMode & DrawModes::SOLID_FLAT_SHADED)
414 || (_drawMode & DrawModes::SOLID_FACES_COLORED_FLAT_SHADED) ){
420 if (_drawMode & DrawModes::SOLID_FACES_COLORED)
427 for(it = skeleton_.begin(); it != skeleton_.end(); ++it) {
440 glColor4fv( &baseColor[0] );
442 Vec3d parentPos = pose->globalTranslation(parent->
id());
443 Vec3d jointPos = pose->globalTranslation(joint->
id());
445 Vec3d boneVector = (jointPos - parentPos);
447 draw_bone(_state, _drawMode, parentPos, boneVector);
452 if(bCoordFramesVisible_)
459 for(it = skeleton_.begin(); it != skeleton_.end(); ++it)
461 unsigned int index = (*it)->id();
462 typename SkeletonType::Matrix global = pose->globalMatrix(index);
463 NormalizeCoordinateFrame(global);
464 glColor3f(0.8f, 0.2f, 0.2f);
465 glVertex( pose->globalTranslation(index));
466 glVertex( global.transform_point(Point(fFrameSize_, 0, 0)) );
467 glColor3f(0.2f, 0.8f, 0.2f);
468 glVertex( pose->globalTranslation(index));
469 glVertex( global.transform_point(Point(0, fFrameSize_, 0)) );
470 glColor3f(0.2f, 0.2f, 0.8f);
471 glVertex( pose->globalTranslation(index));
472 glVertex( global.transform_point(Point(0, 0, fFrameSize_)) );
490 template <
class SkeletonType>
494 RGBtoHSV(_baseColor, hsv);
497 if (hsv[0] > 1.0) hsv[0] -= 1.0;
500 if (hsv[1] > 1.0) hsv[1] = 1.0;
502 HSVtoRGB(hsv, _result);
511 template <
class SkeletonType>
514 unsigned int n_of_vertices = skeleton_.jointCount();
520 pick_vertices(_state);
530 pick_vertices(_state);
545 template <
class SkeletonType>
549 typename SkeletonType::Pose* pose = skeleton_.pose(hAni_);
550 for(
typename SkeletonType::Iterator it = skeleton_.begin(); it != skeleton_.end(); ++it)
552 typename SkeletonType::Joint *joint = *it;
555 Vec3d p = pose->globalTranslation(joint->id());
569 template <
class SkeletonType>
573 typename SkeletonType::Pose* pose = skeleton_.pose(hAni_);
574 for(
typename SkeletonType::Iterator it = skeleton_.begin(); it != skeleton_.end(); ++it)
577 for(
typename Joint::ChildIter it_ch = joint->
begin(); it_ch != joint->
end(); ++it_ch)
579 Joint *child = *it_ch;
583 Vec3d p0 = pose->globalTranslation(joint->
id()),
584 p1 = pose->globalTranslation(child->
id());
600 template <
class SkeletonType>
609 computeConeMatrices(_state.
modelview(), _parent, _axis, &mv0, &mv1);
613 cone_->draw_primitive();
616 cone_->draw_primitive();
628 template <
class SkeletonType>
634 _base.glDrawArrays(GL_TRIANGLES, 0, cone_->getNumTriangles() * 3);
641 computeConeMatrices(prevTransform, _parent, _axis, &mv0, &mv1);
655 template <
class SkeletonType>
658 Point midPoint = _parent + 0.1 * _axis;
660 *_outCone0 = _modelView;
662 _outCone0->
translate(midPoint[0], midPoint[1], midPoint[2]);
664 Point direction = _axis;
669 direction.normalize();
670 rot_angle = acos((z_axis | direction))*180/M_PI;
671 rot_normal = ((z_axis % direction).normalize());
674 if(fabs(rot_angle) > 0.0001 && fabs(180-rot_angle) > 0.0001)
675 _outCone0->
rotate(rot_angle, rot_normal[0], rot_normal[1], rot_normal[2]);
677 _outCone0->
rotate(rot_angle, 1, 0, 0);
679 double boneLength = _axis.norm();
680 double radius = boneLength * 0.07;
682 *_outCone1 = *_outCone0;
685 _outCone0->
scale(radius, radius, boneLength*0.9);
688 _outCone1->
scale(radius, radius, boneLength*0.1);
707 template <
class SkeletonType>
719 template <
class SkeletonType>
731 template <
class SkeletonType>
734 bCoordFramesVisible_ = _bVisible;
737 template <
class SkeletonType>
740 return bCoordFramesVisible_;
748 template <
class SkeletonType>
757 shifted[0] = shifted[0] + _pointSize / 2.0 ;
763 ACG::Vec3d difference = unProjectedShifted - _point;
765 return difference.
norm();
775 template <
class SkeletonType>
786 ro.depthWrite =
true;
792 Pose *pose = skeleton_.pose(hAni_);
793 typename SkeletonType::Iterator it;
799 const int numJoints = skeleton_.jointCount();
802 for (
unsigned int i = 0; i < _drawMode.
getNumLayers(); ++i)
806 switch (props->primitive())
809 case DrawModes::PRIMITIVE_POINT:
811 ro.debugName =
"SkeletonNode.point";
814 if (VertexDeclaration::supportsInstancedArrays())
823 const int instanceDataSize = 4*3*4 + 4;
824 const int instanceBufSize = numJoints * instanceDataSize;
827 const int numFloats = instanceBufSize/4;
828 std::vector<float> instanceData(numFloats);
831 int instanceDataOffset = 0;
833 for(it = skeleton_.begin(); it != skeleton_.end(); ++it)
839 if ( (*it)->selected() )
840 vcolor =
Vec4f(1.0f, 0.0f, 0.0f, 1.0f);
844 if ( (*it)->isRoot() )
845 vcolor =
Vec4f(1.0f,0.66f, 0.0f, 1.0f);
850 Vec3d globalPosD = pose->globalTranslation( (*it)->id() );
852 float sphereSize = float(unprojectPointSize((
double)_state.
point_size(),
857 modelview.
translate(static_cast<float>(globalPosD[0]), static_cast<float>(globalPosD[1]), static_cast<float>(globalPosD[2]));
858 modelview.
scale(sphereSize, sphereSize, sphereSize);
861 for (
int r = 0; r < 3; ++r)
862 for (
int c = 0; c < 4; ++c)
863 instanceData[instanceDataOffset++] = modelview(r,c);
866 unsigned int uicolor = 0xff000000;
867 uicolor |= (
unsigned int)(vcolor[0] * 255.0f) & 0x000000ff;
868 uicolor |= ((
unsigned int)(vcolor[1] * 255.0f) << 8) & 0x0000ff00;
869 uicolor |= ((
unsigned int)(vcolor[2] * 255.0f) << 16) & 0x00ff0000;
878 uitofloat.u = uicolor;
880 instanceData[instanceDataOffset++] = uitofloat.f;
884 pointInstanceData_.bind();
885 pointInstanceData_.upload(instanceBufSize, &instanceData[0], GL_DYNAMIC_DRAW);
886 pointInstanceData_.unbind();
890 if (!pointInstanceDecl_.getNumElements())
892 pointInstanceDecl_ = *sphere_->getVertexDecl();
894 pointInstanceDecl_.addElement(GL_FLOAT, 4,
VERTEX_USAGE_SHADER_INPUT,
size_t(0),
"inModelView0", 1, pointInstanceData_.id());
895 pointInstanceDecl_.addElement(GL_FLOAT, 4,
VERTEX_USAGE_SHADER_INPUT,
size_t(0),
"inModelView1", 1, pointInstanceData_.id());
896 pointInstanceDecl_.addElement(GL_FLOAT, 4,
VERTEX_USAGE_SHADER_INPUT,
size_t(0),
"inModelView2", 1, pointInstanceData_.id());
897 pointInstanceDecl_.addElement(GL_UNSIGNED_BYTE, 4,
VERTEX_USAGE_COLOR,
size_t(0), 0, 1, pointInstanceData_.id());
901 ro.
shaderDesc.vertexTemplateFile =
"Skeleton/instanced_vs.glsl";
905 ro.glDrawInstancedArrays(GL_TRIANGLES, 0, sphere_->getNumTriangles() * 3, numJoints);
918 for(it = skeleton_.begin(); it != skeleton_.end(); ++it)
922 if ( (*it)->selected() )
923 ro.emissive =
Vec3f(1.0f, 0.0f, 0.0f);
927 if ( (*it)->isRoot() )
928 ro.emissive =
Vec3f(1.0f,0.66f, 0.0f);
930 ro.emissive =
Vec3f(jointColor[0], jointColor[1] , jointColor[2]);
936 const double sphereSize = unprojectPointSize((
double)_state.
point_size(), pose->globalTranslation( (*it)->id() ), _state);
938 sphere_->addToRenderer(_renderer, &ro, sphereSize,
ACG::Vec3f(pose->globalTranslation( (*it)->id() )));
946 case DrawModes::PRIMITIVE_POLYGON:
948 ro.debugName =
"SkeletonNode.bone";
952 ro.setMaterial(_mat);
954 ro.emissive =
ACG::Vec3f(baseColor[0],baseColor[1],baseColor[2]);
958 if (VertexDeclaration::supportsInstancedArrays())
967 const int instanceDataFloats = 3*4 + 3*3;
968 const int instanceDataSize = instanceDataFloats * 4;
969 const int instanceBufSize = 2 * numJoints * instanceDataSize;
972 const int numFloats = instanceBufSize/4;
973 std::vector<float> instanceData(numFloats);
976 int instanceDataOffset = 0;
977 GLMatrixf cone0, cone1, cone0IT, cone1IT;
979 for(it = skeleton_.begin(); it != skeleton_.end(); ++it)
990 Vec3d parentPos = pose->globalTranslation(parent->
id());
991 Vec3d jointPos = pose->globalTranslation(joint->
id());
993 Vec3d boneVector = (jointPos - parentPos);
996 computeConeMatrices(ro.
modelview, parentPos, boneVector, &cone0, &cone1);
1005 for (
int r = 0; r < 3; ++r)
1006 for (
int c = 0; c < 4; ++c)
1007 instanceData[instanceDataOffset++] = cone0(r,c);
1009 for (
int r = 0; r < 3; ++r)
1010 for (
int c = 0; c < 3; ++c)
1011 instanceData[instanceDataOffset++] = cone0IT(c,r);
1013 for (
int r = 0; r < 3; ++r)
1014 for (
int c = 0; c < 4; ++c)
1015 instanceData[instanceDataOffset++] = cone1(r,c);
1017 for (
int r = 0; r < 3; ++r)
1018 for (
int c = 0; c < 3; ++c)
1019 instanceData[instanceDataOffset++] = cone1IT(c,r);
1022 const int numBones = instanceDataOffset / instanceDataFloats;
1025 boneInstanceData_.bind();
1026 boneInstanceData_.upload(instanceDataOffset * 4, &instanceData[0], GL_DYNAMIC_DRAW);
1027 boneInstanceData_.unbind();
1032 if (!boneInstanceDecl_.getNumElements())
1034 boneInstanceDecl_ = *cone_->getVertexDecl();
1036 boneInstanceDecl_.addElement(GL_FLOAT, 4,
VERTEX_USAGE_SHADER_INPUT, static_cast<size_t>(0),
"inModelView0", 1, boneInstanceData_.id());
1037 boneInstanceDecl_.addElement(GL_FLOAT, 4,
VERTEX_USAGE_SHADER_INPUT, static_cast<size_t>(0),
"inModelView1", 1, boneInstanceData_.id());
1038 boneInstanceDecl_.addElement(GL_FLOAT, 4,
VERTEX_USAGE_SHADER_INPUT, static_cast<size_t>(0),
"inModelView2", 1, boneInstanceData_.id());
1039 boneInstanceDecl_.addElement(GL_FLOAT, 3,
VERTEX_USAGE_SHADER_INPUT, static_cast<size_t>(0),
"inModelViewIT0", 1, boneInstanceData_.id());
1040 boneInstanceDecl_.addElement(GL_FLOAT, 3,
VERTEX_USAGE_SHADER_INPUT, static_cast<size_t>(0),
"inModelViewIT1", 1, boneInstanceData_.id());
1041 boneInstanceDecl_.addElement(GL_FLOAT, 3,
VERTEX_USAGE_SHADER_INPUT, static_cast<size_t>(0),
"inModelViewIT2", 1, boneInstanceData_.id());
1046 ro.glDrawInstancedArrays(GL_TRIANGLES, 0, cone_->getNumTriangles() * 3, numBones);
1048 ro.
shaderDesc.vertexTemplateFile =
"Skeleton/instanced_wvit_vs.glsl";
1060 for(it = skeleton_.begin(); it != skeleton_.end(); ++it) {
1071 Vec3d parentPos = pose->globalTranslation(parent->
id());
1072 Vec3d jointPos = pose->globalTranslation(joint->
id());
1074 Vec3d boneVector = (jointPos - parentPos);
1076 addBoneToRenderer(_renderer, ro, parentPos, boneVector);
1089 if (bCoordFramesVisible_)
1093 for(it = skeleton_.begin(); it != skeleton_.end(); ++it)
1095 unsigned int index = (*it)->id();
1096 typename SkeletonType::Matrix global = pose->globalMatrix(index);
1097 NormalizeCoordinateFrame(global);
1101 Vec3f(0.8f, 0.2f, 0.2f),
1102 Vec3f(0.2f, 0.8f, 0.2f),
1103 Vec3f(0.2f, 0.2f, 0.8f)
1107 Point(fFrameSize_, 0, 0),
1108 Point(0, fFrameSize_, 0),
1109 Point(0, 0, fFrameSize_)
1114 float lineWidth = (float)unprojectPointSize(3.0f, pose->globalTranslation(index), _state);
1117 float sphereSize = (float)unprojectPointSize(6.0f, pose->globalTranslation(index), _state);
1120 for (
int i = 0; i < 3; ++i)
1122 ro.emissive = colors[i];
1125 Vec3f vstart = (
Vec3f)pose->globalTranslation(index);
1126 Vec3f vend = (
Vec3f)global.transform_point(points[i]);
1128 Vec3f vdir = vend - vstart;
1129 float height = vdir.
length();
1131 cylinder_->addToRenderer(_renderer, &ro, height, vstart, vdir, lineWidth);
1132 sphere_->addToRenderer(_renderer, &ro, sphereSize, vend);
void rotate(Scalar angle, Scalar x, Scalar y, Scalar z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
void glColor(const Vec3f &_v)
Wrapper: glColor for Vec3f.
void initFromState(GLState *_glState)
Initializes a RenderObject instance.
void pop_modelview_matrix()
pop modelview matrix
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
picks edges (may not be implemented for all nodes)
const Vec4f & specular_color() const
get specular color
size_t id() const
returns the joint id
defined by user via VertexElement::shaderInputName_
void set_diffuse_color(const Vec4f &_col)
set diffuse color
float point_size() const
get point size
void rotateX(Scalar _angle, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with a rotation matrix (angle in degree, x-axis)
Namespace providing different geometric functions concerning angles.
Vec3d project(const Vec3d &_point) const
project point in world coordinates to window coordinates
VectorT< float, 4 > Vec4f
const Vec4f & base_color() const
get base color (used when lighting is off)
ShaderGenDesc shaderDesc
Drawmode and other shader params.
void translate(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with translation matrix (x,y,z)
vector_type & maximize(const vector_type &_rhs)
maximize values: same as *this = max(*this, _rhs), but faster
GLuint vertexBuffer
VBO, IBO ids, ignored if VAO is provided.
const Vec4f & diffuse_color() const
get diffuse color
ChildIter end()
Returns the end iterator for the joints children.
PickTarget
What target to use for picking.
Vec3d unproject(const Vec3d &_winPoint) const
unproject point in window coordinates _winPoint to world coordinates
bool invert()
matrix inversion (returns true on success)
void push_modelview_matrix()
push modelview matrix
void set_modelview(const GLMatrixd &_m)
set modelview
void diffuseColor(const Vec4f &_d)
set the diffuse color.
Represents a single joint in the skeleton.
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
VectorT< float, 3 > Vec3f
pick any of the prior targets (should be implemented for all nodes)
void set_ambient_color(const Vec4f &_col)
set ambient color
bool pick_set_maximum(size_t _idx)
Set the maximal number of primitives/components of your object.
void scale(Scalar _x, Scalar _y, Scalar _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
multiply self with scaling matrix (x,y,z)
picks verices (may not be implemented for all nodes)
vector_type & minimize(const vector_type &_rhs)
minimize values: same as *this = min(*this, _rhs), but faster
const VertexDeclaration * vertexDecl
Defines the vertex buffer layout, ignored if VAO is provided.
auto norm() const -> decltype(std::sqrt(std::declval< VectorT< S, DIM >>().sqrnorm()))
compute euclidean norm
void glVertex(const Vec2i &_v)
Wrapper: glVertex for Vec2i.
void set_specular_color(const Vec4f &_col)
set specular color
DrawModeProperties stores a set of properties that defines, how to render an object.
void set_color(const Vec4f &_col)
set color
virtual void addRenderObject(RenderObject *_renderObject)
Callback for the scenegraph nodes, which send new render objects via this function.
auto length() const -> decltype(std::declval< VectorT< S, DIM >>().norm())
compute squared euclidean norm
Joint * parent()
Returns the parent joint.
void pick_set_name(size_t _idx)
sets the current name/color (like glLoadName(_idx))
void computeConeMatrices(const GLMatrixf &_modelView, const Point &_parent, const Point &_axis, GLMatrixf *_outCone0, GLMatrixf *_outCone1)
Helper function to compute modelview matrices for the two cones composing a bone. ...
const GLMatrixd & modelview() const
get modelview matrix
void setupShaderGenFromDrawmode(const SceneGraph::DrawModes::DrawModeProperties *_props)
Fills out ShaderGenDesc parameters based on Drawmode properties.
float line_width() const
get line width
const DrawModeProperties * getLayer(unsigned int _i) const
returns the property set at layer i
SkeletonNodeT(SkeletonType &_skeleton, BaseNode *_parent=nullptr, std::string _name="<SkeletonNode>")
Constructor.
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
Interface class between scenegraph and renderer.
size_t getNumLayers() const
returns the layer count
A handle used to refer to an animation or to a specific frame in an animation.
const Vec4f & ambient_color() const
get ambient color
GLMatrixd modelview
Modelview transform.
ChildIter begin()
Returns an iterator on the joints children.