Merge pull request #89130 from Malcolmnixon/xr-hand-scaling
Fix XRHandModifier3D scaling
This commit is contained in:
commit
fcb0adf132
|
@ -5,6 +5,8 @@
|
||||||
</brief_description>
|
</brief_description>
|
||||||
<description>
|
<description>
|
||||||
This node uses hand tracking data from a [XRHandTracker] to animate the skeleton of a hand mesh.
|
This node uses hand tracking data from a [XRHandTracker] to animate the skeleton of a hand mesh.
|
||||||
|
This node positions itself at the [constant XRHandTracker.HAND_JOINT_PALM] position and scales itself to [member XRServer.world_scale]. Adding the hand model as a child of this node will result in the model being positioned and scaled correctly for XR experiences.
|
||||||
|
The hand tracking position-data is scaled by [member Skeleton3D.motion_scale] when applied to the skeleton, which can be used to adjust the tracked hand to match the scale of the hand model.
|
||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
<link title="XR documentation index">$DOCS_URL/tutorials/xr/index.html</link>
|
<link title="XR documentation index">$DOCS_URL/tutorials/xr/index.html</link>
|
||||||
|
|
|
@ -213,13 +213,15 @@ void XRHandModifier3D::_update_skeleton() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the world and skeleton scale.
|
||||||
|
const float ws = xr_server->get_world_scale();
|
||||||
|
const float ss = skeleton->get_motion_scale();
|
||||||
|
|
||||||
// We cache our transforms so we can quickly calculate local transforms.
|
// We cache our transforms so we can quickly calculate local transforms.
|
||||||
bool has_valid_data[XRHandTracker::HAND_JOINT_MAX];
|
bool has_valid_data[XRHandTracker::HAND_JOINT_MAX];
|
||||||
Transform3D transforms[XRHandTracker::HAND_JOINT_MAX];
|
Transform3D transforms[XRHandTracker::HAND_JOINT_MAX];
|
||||||
Transform3D inv_transforms[XRHandTracker::HAND_JOINT_MAX];
|
Transform3D inv_transforms[XRHandTracker::HAND_JOINT_MAX];
|
||||||
|
|
||||||
const float ws = xr_server->get_world_scale();
|
|
||||||
|
|
||||||
if (tracker->get_has_tracking_data()) {
|
if (tracker->get_has_tracking_data()) {
|
||||||
for (int joint = 0; joint < XRHandTracker::HAND_JOINT_MAX; joint++) {
|
for (int joint = 0; joint < XRHandTracker::HAND_JOINT_MAX; joint++) {
|
||||||
BitField<XRHandTracker::HandJointFlags> flags = tracker->get_hand_joint_flags((XRHandTracker::HandJoint)joint);
|
BitField<XRHandTracker::HandJointFlags> flags = tracker->get_hand_joint_flags((XRHandTracker::HandJoint)joint);
|
||||||
|
@ -227,7 +229,7 @@ void XRHandModifier3D::_update_skeleton() {
|
||||||
|
|
||||||
if (has_valid_data[joint]) {
|
if (has_valid_data[joint]) {
|
||||||
transforms[joint] = tracker->get_hand_joint_transform((XRHandTracker::HandJoint)joint);
|
transforms[joint] = tracker->get_hand_joint_transform((XRHandTracker::HandJoint)joint);
|
||||||
transforms[joint].origin *= ws;
|
transforms[joint].origin *= ss;
|
||||||
inv_transforms[joint] = transforms[joint].inverse();
|
inv_transforms[joint] = transforms[joint].inverse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -253,8 +255,11 @@ void XRHandModifier3D::_update_skeleton() {
|
||||||
skeleton->set_bone_pose_rotation(joints[joint].bone, Quaternion(relative_transform.basis));
|
skeleton->set_bone_pose_rotation(joints[joint].bone, Quaternion(relative_transform.basis));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transform to the skeleton pose.
|
// Transform to the skeleton pose. This uses the HAND_JOINT_PALM position without skeleton-scaling, as it
|
||||||
set_transform(transforms[XRHandTracker::HAND_JOINT_PALM]);
|
// must be positioned to match the physical hand location. It is scaled with the world space to match
|
||||||
|
// the scaling done to the camera and eyes.
|
||||||
|
set_transform(
|
||||||
|
tracker->get_hand_joint_transform(XRHandTracker::HAND_JOINT_PALM) * ws);
|
||||||
|
|
||||||
set_visible(true);
|
set_visible(true);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue