I know this is probably quite trivial but I am not getting anywhere with it. I am using ofxKinectV2-OSC to send skeleton joints to my OF app. Instead of displaying those joints, I want to use them to control another skeleton (this is because I want all skeletons in my app to be the same height/size and this way seemed easier than scaling all the skeletons).
To do this, I am thinking that the easiest way would be to calculate the angles of the joints on the skeleton coming in through OSC and rotate the joints in my avatar skeleton.
I’ve tried using the rotate method from ofVec2f to rotate around another point. For example, if I want to rotate the elbow around the shoulder I do this:
This kind of works but it rotates the joint by 45 degree instead of to 45 degrees. Maybe I am going about it the wrong way?
Are there any examples around of this being done?
You can use the kinect2 addon directly and get the real rotation instead of using the positions from kinectV2-OSC to calculate the rotation, it should give you the correct results.
Thanks fresla but calculating the angles is not my problem, it rotating my avatar skeleton joints based on the angles that I am struggling with.
The reason I suggest this is that getting the rotation from plain old angles (kinectV2-OSC only gives coordinates not rotations) is quite inaccurate, rotation order is not taken care of and you will also see gimbal lock using this method. If you use the addon and get the rotation you will get a matrix or quaternion for the rotation of each joint, this will allow you to apply rotation without these issues.
This has worked better and led to simpler code for me from the time of the first kinect. I never found a reliable solution to deal with rotations from calculated angles derived from the positions of the joints (I also have problems with angle wrap which was a royal pain to overcome).
There may be a way to solve this with your method, I am not sure, I never found a good one, this is why I suggested the addon.
I am curious to see if there is a way through from your approach though.
I should probably have mentioned that I’m only concerned with 2D so gimbal lock is not an issue. Think, I’m halfway there now anyway (very rough code below). Was getting confused with atan2. Thanks for your help though!
//get user joint positions
ofVec2f userShoulderLeftPoint = skeletons->at(i).getShoulderLeft().getPoint();
ofVec2f userElbowLeftPoint = skeletons->at(i).getElbowLeft().getPoint();
ofVec2f userHandLeftPoint = skeletons->at(i).getHandLeft().getPoint();
//get avatar joint positions
ofVec2f avatarShoulderLeftPoint = shoulderLeft.point;
ofVec2f avatarElbowLeftPoint = elbowLeft.point;
ofVec2f avatarHandLeftPoint = handLeft.point;
//work out angles
float leftShoulderAngle = ofRadToDeg(atan2(userElbowLeftPoint .y - userShoulderLeftPoint .y, userElbowLeftPoint .x - userShoulderLeftPoint .x));
float leftElbowAngle = ofRadToDeg(atan2(userHandLeftPoint .y - userElbowLeftPoint .y, userHandLeftPoint .x - userElbowLeftPoint .x));
//set new avatar joint point based on user angle
float angle = ofDegToRad(leftShoulderAngle);
elbowLeft.point.set(avatarShoulderLeftPoint.x + cos(angle)* 150, avatarShoulderLeftPoint.y + sin(angle)* 150); //150 is shoulder to elbow length
angle = ofDegToRad(leftElbowAngle);
handLeft.point.set(avatarElbowLeftPoint.x + cos(angle) * 150, avatarElbowLeftPoint.y + sin(angle)* 150); //150 is elbow to elbow hand