@@ -135,13 +135,18 @@ Ref<ArrayMesh> ChainIK3DGizmoPlugin::get_joints_mesh(Skeleton3D *p_skeleton, Cha
135135 int current_bone = -1 ;
136136 int prev_bone = -1 ;
137137 int joint_end = p_ik->get_joint_count (i) - 1 ;
138+ float prev_length = INFINITY;
138139 bool is_extended = p_ik->is_end_bone_extended (i) && p_ik->get_end_bone_length (i) > 0 ;
140+ Transform3D anc_global_pose = p_ik->get_chain_root_global_rest (i);
139141 for (int j = 0 ; j <= joint_end; j++) {
140142 current_bone = p_ik->get_joint_bone (i, j);
141- Transform3D global_pose = p_skeleton->get_bone_global_rest (current_bone);
142143 if (j > 0 ) {
144+ int prev_joint = j - 1 ;
143145 Transform3D parent_global_pose = p_skeleton->get_bone_global_rest (prev_bone);
144- draw_line (surface_tool, parent_global_pose.origin , global_pose.origin , bone_color);
146+ Vector3 bone_vector = p_ik->get_bone_vector (i, prev_joint);
147+ float current_length = bone_vector.length ();
148+ Vector3 center = parent_global_pose.translated_local (bone_vector).origin ;
149+ draw_line (surface_tool, parent_global_pose.origin , center, bone_color);
145150
146151 if (it_ik) {
147152 // Draw rotation axis vector if not ROTATION_AXIS_ALL.
@@ -150,15 +155,14 @@ Ref<ArrayMesh> ChainIK3DGizmoPlugin::get_joints_mesh(Skeleton3D *p_skeleton, Cha
150155 if (rotation_axis != SkeletonModifier3D::ROTATION_AXIS_ALL) {
151156 Vector3 axis_vector = it_ik->get_joint_rotation_axis_vector (i, j);
152157 if (!axis_vector.is_zero_approx ()) {
153- float rot_axis_length = (global_pose. origin - parent_global_pose. origin ) .length () * 0.2 ; // Use 20% of the bone length for the rotation axis vector.
154- Vector3 axis = global_pose .basis .xform (axis_vector.normalized ()) * rot_axis_length;
155- draw_line (surface_tool, global_pose. origin - axis, global_pose. origin + axis, bone_color);
158+ float rot_axis_length = bone_vector .length () * 0.2 ; // Use 20% of the bone length for the rotation axis vector.
159+ Vector3 axis = parent_global_pose .basis .xform (axis_vector.normalized ()) * rot_axis_length;
160+ draw_line (surface_tool, center - axis, center + axis, bone_color);
156161 }
157162 }
158163 }
159164
160165 // Draw parent limitation shape.
161- int prev_joint = j - 1 ;
162166 Ref<JointLimitation3D> lim = it_ik->get_joint_limitation (i, prev_joint);
163167 if (lim.is_valid ()) {
164168 // Limitation space should bind parent bone rest.
@@ -170,28 +174,36 @@ Ref<ArrayMesh> ChainIK3DGizmoPlugin::get_joints_mesh(Skeleton3D *p_skeleton, Cha
170174 surface_tool->set_weights (weights);
171175 }
172176 }
173- Transform3D tr = parent_global_pose;
174- Vector3 forward = p_skeleton->get_bone_rest (current_bone).origin ;
175- tr.basis *= it_ik->get_joint_limitation_space (i, prev_joint, forward);
176- lim->draw_shape (surface_tool, tr, forward.length (), bone_color);
177- Vector3 x_axis = tr.basis .get_column (Vector3::AXIS_X).normalized () * forward.length () * 0.1 ;
178- Vector3 z_axis = tr.basis .get_column (Vector3::AXIS_Z).normalized () * forward.length () * 0.1 ;
177+ Transform3D tr = anc_global_pose;
178+ tr.basis *= it_ik->get_joint_limitation_space (i, prev_joint, bone_vector.normalized ());
179+ float sl = MIN (current_length, prev_length);
180+ lim->draw_shape (surface_tool, tr, sl, bone_color);
181+ sl *= 0.1 ;
182+ Vector3 x_axis = tr.basis .get_column (Vector3::AXIS_X).normalized () * sl;
183+ Vector3 z_axis = tr.basis .get_column (Vector3::AXIS_Z).normalized () * sl;
179184 draw_line (surface_tool, tr.origin + x_axis * 2 , tr.origin + x_axis * 3 , limitation_x_axis_color); // Offset 20%.
180185 draw_line (surface_tool, tr.origin + z_axis * 2 , tr.origin + z_axis * 3 , limitation_z_axis_color); // Offset 20%.
181186 }
182187 }
188+ prev_length = current_length;
189+ Transform3D tr = p_skeleton->get_bone_rest (current_bone);
190+ tr.origin = bone_vector;
191+ parent_global_pose *= tr;
192+ anc_global_pose = parent_global_pose;
183193 }
184194 if (j == joint_end && is_extended) {
185- Vector3 axis = p_ik->get_bone_axis (current_bone, p_ik->get_end_bone_direction (i));
186- if (axis.is_zero_approx ()) {
195+ Transform3D current_global_pose = p_skeleton->get_bone_global_rest (current_bone);
196+ Vector3 bone_vector = p_ik->get_bone_vector (i, j);
197+ if (bone_vector.is_zero_approx ()) {
187198 continue ;
188199 }
200+ float current_length = bone_vector.length ();
189201 bones.write [0 ] = current_bone;
190202 surface_tool->set_bones (bones);
191203 surface_tool->set_weights (weights);
192- float length = p_ik-> get_end_bone_length (i) ;
193- axis = global_pose. xform (axis * length );
194- draw_line (surface_tool, global_pose. origin , axis, bone_color);
204+ Vector3 center = current_global_pose. translated_local (bone_vector). origin ;
205+ draw_line (surface_tool, current_global_pose. origin , center, bone_color );
206+
195207 if (it_ik) {
196208 // Draw limitation shape.
197209 Ref<JointLimitation3D> lim = it_ik->get_joint_limitation (i, j);
@@ -205,12 +217,13 @@ Ref<ArrayMesh> ChainIK3DGizmoPlugin::get_joints_mesh(Skeleton3D *p_skeleton, Cha
205217 surface_tool->set_weights (weights);
206218 }
207219 }
208- Vector3 forward = it_ik->get_bone_axis (current_bone, it_ik->get_end_bone_direction (i));
209- Transform3D tr = global_pose;
210- tr.basis *= it_ik->get_joint_limitation_space (i, j, forward);
211- lim->draw_shape (surface_tool, tr, length, bone_color);
212- Vector3 x_axis = tr.basis .get_column (Vector3::AXIS_X).normalized () * length * 0.1 ;
213- Vector3 z_axis = tr.basis .get_column (Vector3::AXIS_Z).normalized () * length * 0.1 ;
220+ Transform3D tr = anc_global_pose;
221+ tr.basis *= it_ik->get_joint_limitation_space (i, j, bone_vector.normalized ());
222+ float sl = MIN (current_length, prev_length);
223+ lim->draw_shape (surface_tool, tr, sl, bone_color);
224+ sl *= 0.1 ;
225+ Vector3 x_axis = tr.basis .get_column (Vector3::AXIS_X).normalized () * sl;
226+ Vector3 z_axis = tr.basis .get_column (Vector3::AXIS_Z).normalized () * sl;
214227 draw_line (surface_tool, tr.origin + x_axis * 2 , tr.origin + x_axis * 3 , limitation_x_axis_color); // Offset 20%.
215228 draw_line (surface_tool, tr.origin + z_axis * 2 , tr.origin + z_axis * 3 , limitation_z_axis_color); // Offset 20%.
216229 }
@@ -231,10 +244,10 @@ Ref<ArrayMesh> ChainIK3DGizmoPlugin::get_joints_mesh(Skeleton3D *p_skeleton, Cha
231244 if (rotation_axis != SkeletonModifier3D::ROTATION_AXIS_ALL) {
232245 Vector3 axis_vector = it_ik->get_joint_rotation_axis_vector (i, j);
233246 if (!axis_vector.is_zero_approx ()) {
234- Transform3D next_bone_global_pose = p_skeleton-> get_bone_global_rest (it_ik-> get_joint_bone ( i, 1 ) );
235- float rot_axis_length = (next_bone_global_pose. origin - global_pose. origin ) .length () * 0.2 ; // Use 20% of the bone length for the rotation axis vector.
236- Vector3 axis = global_pose .basis .xform (axis_vector.normalized ()) * rot_axis_length;
237- draw_line (surface_tool, global_pose .origin - axis, global_pose .origin + axis, bone_color);
247+ Vector3 bone_vector = p_ik-> get_bone_vector ( i, j );
248+ float rot_axis_length = bone_vector .length () * 0.2 ; // Use 20% of the bone length for the rotation axis vector.
249+ Vector3 axis = anc_global_pose .basis .xform (axis_vector.normalized ()) * rot_axis_length;
250+ draw_line (surface_tool, anc_global_pose .origin - axis, anc_global_pose .origin + axis, bone_color);
238251 }
239252 }
240253 }
0 commit comments