ofxOpenNI ofxLimb position and orientation


I wonder how can I get the ofxLimb positions in 3D, the struct have 2 ofVec2f properties begin and end, but it also have 2 XnSkeletonJoint properties start_joint and end_joint, I look into XnSkeletonJoint but from there I got lost, any ideas how can I get the 3d position vectors of the limbs?


  • rS

in ofxLimb, each limb has

XnSkeletonJoint start_joint;
XnSkeletonJoint end_joint;

(their storage format)

in function updateLimb() in ofxLimb this gets the limb data if its found

	XnSkeletonJointPosition a,b;  
	xn_user_generator->GetSkeletonCap().GetSkeletonJointPosition(id, rLimb.start_joint, a);  
	xn_user_generator->GetSkeletonCap().GetSkeletonJointPosition(id, rLimb.end_joint, b);  
	if(a.fConfidence < 0.3f || b.fConfidence < 0.3f) {  
		rLimb.found = false;   

Then it updates them in the addon like this

	XnPoint3D pos[2];  
	pos[0] = a.position;  
	pos[1] = b.position;  
		.ConvertRealWorldToProjective(2, pos, pos);  

So its storing the real world perspective x,y.

I agree it would be better if we could store the xyz in the addon easily too. Am playing around with is unless someone beats me to it.

Thanks I will try it out over the weekend

  • rS

Hey if that can help I put some code on github that allow control of an ofNode armature with ofxOpenNI ( I couldn’t push it to the point I could control an actual collada armature though )


AWESOME!!! I will play with this tonight

Thanks a lot for sharing

  • rS

Hi kikko,

I got it working, but the legs are not rotating, they do get to the right positions but no orientation is apply to them, any ideas what could be the problem? I am still studying your code


  • rS

oups I’ve commited the wrong version! should be fixed this evening

Yesterday I fix it, not sure if this is the best approach.

All I did was, check if the limb is different than the hips or knees, if so do
else if they are hips and knees do

Maybe this could also be fix by initializing the bindPoseOrientation in the setup method like you did for the neck, and arms, I will jump back into it over the weekend.


  • rS

hey nardove, actually the code was the good one!
I didn’t set any specific orientation for the bind pose of the legs because OpenNI expect them to have no rotation.
So testNodes[nodeNum].bindPoseOrientation*q is equal to q because testNodes[nodeNum].bindPoseOrientation is (0, 0, 0, 1) for the bones of the legs. Not sure why it’s not working in you project.
It’s should work correcly with the latest master/origin version on github!

:frowning: arrgg! i’m just too stupid, i dont get this rotation/quaternitaion/openGl-stuff!
could someone help me out with a code snippet where i can put in two points and get the resulting openGLrotate ?


ofxVec3f normal = end - begin;  
	float length = normal.length();  
	ofxVec3f forward(0, -1, 0);  
	ofxVec3f axis   = forward.crossed(normal);  
	float angle      = forward.angle(normal);  
	glTranslatef(begin.x, begin.y, begin.z);  
	ofRotate( angle,axis.x,axis.y,axis.z);  


I tinkered a bit with kikkos example code and now i want to draw the stickman on the actual person from the kinect camera (similar to ascorbins video)… not as a small stickfigure in the corner.

can anyone tell me how to do that?

void testApp::setup()   
    for(int i=0; i< 11; i++)   
		testNodes[i].setPosition(ofRandomf()*10-5, ofRandomf()*10-5, ofRandomf()*10-5);  
		// setup a traditional humanoid bind pose  
		// LEFT ARM  
			testNodes[i].bindPoseOrientation.makeRotate(-90.0, ofVec3f(0.0f, 0.0f, 1.0f));  
        // RIGHT ARM  
		} else if(i==3||i==5){  
			testNodes[i].bindPoseOrientation.makeRotate(90.0, ofVec3f(0.0f, 0.0f, 1.0f));  
        // NECK  
		} else if(i==10){  
			testNodes[i].bindPoseOrientation.makeRotate(180.0, ofVec3f(0.0f, 0.0f, 1.0f));  
		} else {  
			testNodes[i].bindPoseOrientation.set(0, 0, 0, 1);  
void testApp::update()  
    if (isTracking) recordUser.update();  
	cam.orbit(180, 0, 10, ofVec3f(0,0,10));  
    if( recordUser.getNumberOfTrackedUsers() > 0 )  
        headRotation = atan2( recordUser.getTrackedUser(1)->neck.position[1].Y - recordUser.getTrackedUser(1)->neck.position[0].Y , recordUser.getTrackedUser(1)->neck.position[1].X - recordUser.getTrackedUser(1)->neck.position[0].X ) *180/PI - 90;  
        winkel = ofToString( headRotation );  
        transformObject(0, XN_SKEL_TORSO);  
		transformObject(1, XN_SKEL_WAIST);  
		transformObject(2, XN_SKEL_LEFT_SHOULDER);  
		transformObject(3, XN_SKEL_RIGHT_SHOULDER);  
		transformObject(4, XN_SKEL_LEFT_ELBOW);  
		transformObject(5, XN_SKEL_RIGHT_ELBOW);  
		transformObject(6, XN_SKEL_LEFT_HIP);  
		transformObject(7, XN_SKEL_RIGHT_HIP);  
		transformObject(8, XN_SKEL_LEFT_KNEE);  
		transformObject(9, XN_SKEL_RIGHT_KNEE);  
		transformObject(10, XN_SKEL_NECK);  
void testApp::transformObject(int nodeNum,XnSkeletonJoint skelJoint)  
    XnUserID userId = recordUser.getTrackedUser(1)->id;  
    //get openni bone info  
    xn::SkeletonCapability pUserSkel = recordUser.getXnUserGenerator().GetSkeletonCap();  
    XnSkeletonJointOrientation jointOri;  
    pUserSkel.GetSkeletonJointOrientation(userId, skelJoint, jointOri);  
    XnSkeletonJointPosition jointPos;  
    pUserSkel.GetSkeletonJointPosition(userId, skelJoint, jointPos);  
    if( jointOri.fConfidence > 0)  
        float * oriM = jointOri.orientation.elements;  
        ofMatrix4x4 rotMatrix;  
        rotMatrix.set(   oriM[0], oriM[3], oriM[6], 0.0f,  
                         oriM[1], oriM[4], oriM[7], 0.0f,  
                         oriM[2], oriM[5], oriM[8], 0.0f,  
                         0.0f, 0.0f, 0.0f, 1.0f );  
        ofQuaternion q = rotMatrix.getRotate();  
        testNodes[nodeNum].setPosition(jointPos.position.X, jointPos.position.Y, jointPos.position.Z);