I was wondering, if it’s possible to force a skeleton on a certain height at the start. Let’s say it’s feet are always on the bottom of the screen. I don’t want to completely lock it since I want the user to be able to jump etc. But just at the start. Right now the starting height is different for each time you walk in screen. For example, I lock my Z pos always on -400;
Vector3 torsoPos = Quaternion.Euler(0f, 180f, 0f) * (0.8f * _data.GetJoint(JointType.Torso).
torsoPos.z = -400;
transform.position = torsoPos;
Can I do this for my height but only the first time the height gets calculated? Look at it like a calibration system. I just want the user to always start on the right height, no matter how the camera is angled or where the user comes in screen. This is probaply a hard one as Nuitrack updates this position each frame. I already tried calculating the offset etc. No luck…
You can see the sample project in our NuitrackSDK.unitypackage
(Tutorials/Avatar Animation(Advanced) (mobileVR)/RiggedModelAdvanced
). Please take a look at the script NuitrackSDK/Nuitrack/Advanced/RiggedAvatarAdvanced.cs
After calibration, the difference (offset) between the desired position and the current position is calculated. Then, each frame this offset is added to the position of the model.
I think you’re not taking into account the floor plane.
the floor plane comes with each frame, and with some math, you can transform all the points of the skeleton to be relative to the room, that is, after transforming, all skeletons will appear over the floor, regardless of where the camera is located. And no calibration required.
How would I get this floor plane out of the skeleton tracker?
public void ProcessSkeleton(Skeleton _mySkeleton)
{
_skeleton = _mySkeleton;
//change the model position(torso position) & rotate 180 degrees on the y axis, otherwise the model will move in the opposite direction.
//NOTE: For now we always put the Z axis on 0. This is to prevent any issues
Vector3 torsoPos = Quaternion.Euler(0f, 180f, 0f) * (0.8f * _mySkeleton.GetJoint(JointType.Torso).ToVector3());
torsoPos.z = 200;
transform.position = torsoPos;
//Get information about each joint. Calculate the rotation of the model bone: take the 'mirrored' joint orientation, add the base rotation of the model bone.
foreach (KeyValuePair<JointType, MoveModelJointBehaviour> riggedJoint in jointsRigged)
{
nuitrack.Joint joint = _mySkeleton.GetJoint(riggedJoint.Key);
if (joint.Confidence < .75) continue;
MoveModelJointBehaviour moveModelJoint = riggedJoint.Value;
Quaternion jointOrient = Quaternion.Inverse(CalibrationInfo.SensorOrientation) * (joint.ToQuaternionMirrored()) * moveModelJoint.baseRotOffset;
moveModelJoint.bone.rotation = jointOrient;
}
This is my current code. You can only get the floor plane from the usertracker right?
the floor plane can be retrieved with the .GetFloorPlane() of the UseFrame.
When you receive an Userframe, get and store the floor plane somewhere, then use the stored floor when you process the skeleton
That’s an option, altough not the nicest one, since it requires me to send the data all the way accros all my scripts to this one. I’ll take a look at it for sure though, thanks!
The floor plane returns with the position of 0. I want to get it relative to a joint. For example - I want to see if the user is sitting or squatting
Please see our reply here: Partial body tracking