我想在OpenGL中绘制一个人体骨架(姿势估计项目),使用任何可能有用的工具包。 我已经有一些简单的工作,用
绘制关节glvertex3d // and/or
glutWireSphere
和骨头
glBbegin(GL_Lines)
glvertex3d // coordinates of starting point
glvertex3d // coordinates of ending point
glEnd()
这看起来与下一张照片非常相似,但是这种骨骼描绘并没有给出任何关于骨骼旋转的直觉。
我希望看到更类似于下图的内容,将骨骼绘制成细长的金字塔。
Glut似乎没有帮助。
glutWireCone // better than simple line, but still no intuition about rotation
glutWireTetrahedron // not really useful / parametrizable
是否有可用的工具或是否应该是自定义解决方案?
答案 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 :(得分: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();
结果: