OpenGL / Glut绘制金字塔 - 骨架骨骼

时间:2014-02-09 02:30:34

标签: opengl 3d glut freeglut

我想在OpenGL中绘制一个人体骨架(姿势估计项目),使用任何可能有用的工具包。 我已经有一些简单的工作,用

绘制关节
glvertex3d // and/or 
glutWireSphere

和骨头

glBbegin(GL_Lines)
glvertex3d // coordinates of starting point
glvertex3d // coordinates of ending point
glEnd()

这看起来与下一张照片非常相似,但是这种骨骼描绘并没有给出任何关于骨骼旋转的直觉。

enter image description here

我希望看到更类似于下图的内容,将骨骼绘制成细长的金字塔。

enter image description here

Glut似乎没有帮助。

glutWireCone // better than simple line, but still no intuition about rotation
glutWireTetrahedron // not really useful / parametrizable

是否有可用的工具或是否应该是自定义解决方案?

2 个答案:

答案 0 :(得分:3)

将使用当前的OpenGL模型视图矩阵绘制GLUT对象。这可用于控制渲染对象的位置,旋转甚至缩放。使用圆锥体,您首先将(使用glTranslate())平移到一个终点的位置,然后旋转(使用glRotate()glMultMatrix()),使圆锥指向另一个端点。最后,调用glutWireCone()方法,使高度等于从一个端点到另一个端点的距离。

棘手的一点是找到glRotate()参数。 GLUT默认沿Z轴绘制圆锥体,因此旋转需要将Z轴旋转到由终点减去起点定义的轴所需的旋转。 GLM数学库对于这种事情非常有用。它甚至有一个function

quat rotation(vec3 const & orig, vec3 const & dest)     

所以你可以这样做:

// these are filled in with your start and end points
glm::vec3 start, end; 
glm::vec3 direction = end - start;
glm::quat rotation = rotation(glm::vec3(0, 0, 1), direction);
glm::mat4 rotationMatrix = glm::mat4_cast(rotation);
glMultMatrixf(&rotationMatrix);

您可以通过为过剩锥体中的切片数量指定3来获得四面体效果。事实上,如果glutWireTetrahedron未按照glutWireCone

实施{{1}},我不会感到非常惊讶

答案 1 :(得分:0)

如上面的评论所述,Jherico的回答确实帮助我解决了这个问题。

这个答案在他的帖子中建立起来,只是为了让事情更加完整,以备将来参考。

请找到GLM库here,它只是一个标题库,所以您不需要构建它,只需链接到它并包含必要的头文件。它有一些很棒的工具,如下所示。

#define GLM_FORCE_RADIANS // for compatibility between GLM and OpenGL API legacy functions
#include <glm/glm.hpp>
#include <glm/gtc/type_ptr.hpp>    // for glm::mat4_cast // casting quaternion->mat4
#include <glm/gtx/quaternion.hpp>  // for glm::rotation
#include <glm/gtx/string_cast.hpp> // for glm::to_string
...
...
...
// _startBoneVec3 used below is Eigen::Vector3d
// _endddBoneVec3 used below is Eigen::Vector3d
...
...
...
//
// for JOINTS
//
glPushMatrix();
    glTranslated( _startBoneVec3(0),_startBoneVec3(1),_startBoneVec3(2) );
    glutWireSphere(1.0,30,30);
glPopMatrix();
...
...
//
// for BONES
//
glPushMatrix();
    float boneLength = ( _endddBoneVec3  - _startBoneVec3 ).norm();
    glTranslated(        _startBoneVec3(0),_startBoneVec3(1),_startBoneVec3(2) );
    glm::vec3 _glmStart( _startBoneVec3(0),_startBoneVec3(1),_startBoneVec3(2) );
    glm::vec3 _glmEnddd( _endddBoneVec3(0),_endddBoneVec3(1),_endddBoneVec3(2) );
    glm::vec3 _glmDirrr   = glm::normalize( _glmEnddd - _glmStart ); // super important to normalize!!!
    glm::quat _glmRotQuat = glm::rotation( glm::vec3(0,0,1),_glmDirrr); // calculates rotation quaternion between 2 normalized vectors
  //glm::mat4 _glmRotMat = glm::mat4_cast(_glmRotQuat); // quaternion -> mat4
    glm::mat4 _glmRotMat = glm::toMat4   (_glmRotQuat); // quaternion -> mat4
  //std::cout <<  glm::to_string(_glmDirrr) << std::endl;
    glMultMatrixf(glm::value_ptr(_glmRotMat));
    glutWireCone(4.2,boneLength,4,20); // cone with 4 slices = pyramid-like
glPopMatrix();

结果:

enter image description here