Add mutable_bone_axes to IKs
This commit is contained in:
@@ -258,7 +258,7 @@ void ChainIK3D::set_extend_end_bone(int p_index, bool p_enabled) {
|
||||
}
|
||||
notify_property_list_changed();
|
||||
#ifdef TOOLS_ENABLED
|
||||
update_gizmos();
|
||||
_make_gizmo_dirty();
|
||||
#endif // TOOLS_ENABLED
|
||||
}
|
||||
|
||||
@@ -270,14 +270,17 @@ bool ChainIK3D::is_end_bone_extended(int p_index) const {
|
||||
void ChainIK3D::set_end_bone_direction(int p_index, BoneDirection p_bone_direction) {
|
||||
ERR_FAIL_INDEX(p_index, (int)settings.size());
|
||||
chain_settings[p_index]->end_bone_direction = p_bone_direction;
|
||||
_make_simulation_dirty(p_index);
|
||||
Skeleton3D *sk = get_skeleton();
|
||||
if (sk && !chain_settings[p_index]->joints.is_empty()) {
|
||||
_validate_axis(sk, p_index, chain_settings[p_index]->joints.size() - 1);
|
||||
}
|
||||
#ifdef TOOLS_ENABLED
|
||||
update_gizmos();
|
||||
_make_gizmo_dirty();
|
||||
#endif // TOOLS_ENABLED
|
||||
if (mutable_bone_axes) {
|
||||
return; // Chain dir will be recaluclated in _update_bone_axis().
|
||||
}
|
||||
_make_simulation_dirty(p_index);
|
||||
}
|
||||
|
||||
SkeletonModifier3D::BoneDirection ChainIK3D::get_end_bone_direction(int p_index) const {
|
||||
@@ -287,11 +290,15 @@ SkeletonModifier3D::BoneDirection ChainIK3D::get_end_bone_direction(int p_index)
|
||||
|
||||
void ChainIK3D::set_end_bone_length(int p_index, float p_length) {
|
||||
ERR_FAIL_INDEX(p_index, (int)settings.size());
|
||||
float old = chain_settings[p_index]->end_bone_length;
|
||||
chain_settings[p_index]->end_bone_length = p_length;
|
||||
_make_simulation_dirty(p_index);
|
||||
#ifdef TOOLS_ENABLED
|
||||
update_gizmos();
|
||||
_make_gizmo_dirty();
|
||||
#endif // TOOLS_ENABLED
|
||||
if (mutable_bone_axes && Math::is_zero_approx(old) == Math::is_zero_approx(p_length)) {
|
||||
return; // If chain size is not changed, length will be recaluclated in _update_bone_axis().
|
||||
}
|
||||
_make_simulation_dirty(p_index);
|
||||
}
|
||||
|
||||
float ChainIK3D::get_end_bone_length(int p_index) const {
|
||||
@@ -472,7 +479,7 @@ void ChainIK3D::_update_joints(int p_index) {
|
||||
}
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
update_gizmos();
|
||||
_make_gizmo_dirty();
|
||||
#endif // TOOLS_ENABLED
|
||||
}
|
||||
|
||||
@@ -480,6 +487,59 @@ void ChainIK3D::_process_ik(Skeleton3D *p_skeleton, double p_delta) {
|
||||
//
|
||||
}
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
void ChainIK3D::_update_mutable_info() {
|
||||
if (!is_inside_tree()) {
|
||||
return;
|
||||
}
|
||||
Skeleton3D *skeleton = get_skeleton();
|
||||
if (!skeleton) {
|
||||
for (uint32_t i = 0; i < settings.size(); i++) {
|
||||
chain_settings[i]->root_global_rest = Transform3D();
|
||||
}
|
||||
}
|
||||
bool changed = false;
|
||||
for (uint32_t i = 0; i < settings.size(); i++) {
|
||||
int root_bone = chain_settings[i]->root_bone.bone;
|
||||
if (root_bone < 0) {
|
||||
continue;
|
||||
}
|
||||
Transform3D new_tr = get_bone_global_rest_mutable(skeleton, root_bone);
|
||||
changed = changed || !chain_settings[i]->root_global_rest.is_equal_approx(new_tr);
|
||||
chain_settings[i]->root_global_rest = new_tr;
|
||||
}
|
||||
if (changed) {
|
||||
_make_gizmo_dirty();
|
||||
}
|
||||
}
|
||||
|
||||
Transform3D ChainIK3D::get_bone_global_rest_mutable(Skeleton3D *p_skeleton, int p_bone) {
|
||||
int current = p_bone;
|
||||
Transform3D accum;
|
||||
int parent = p_skeleton->get_bone_parent(current);
|
||||
if (parent >= 0) {
|
||||
accum = p_skeleton->get_bone_global_rest(parent);
|
||||
}
|
||||
Transform3D tr = p_skeleton->get_bone_rest(current);
|
||||
// Note:
|
||||
// Chain IK gizmo might not be able to retrieve this pose in SkeletonModifier update process.
|
||||
// So the gizmo uses bone_vector insteads but parent of root bone doesn't have bone_vector.
|
||||
// Then, we needs to cache this pose in IK node.
|
||||
tr.origin = p_skeleton->get_bone_pose_position(current);
|
||||
accum *= tr;
|
||||
return accum;
|
||||
}
|
||||
|
||||
Transform3D ChainIK3D::get_chain_root_global_rest(int p_index) {
|
||||
ERR_FAIL_INDEX_V(p_index, (int)settings.size(), Transform3D());
|
||||
return chain_settings[p_index]->root_global_rest;
|
||||
}
|
||||
|
||||
Vector3 ChainIK3D::get_bone_vector(int p_index, int p_joint) const {
|
||||
return Vector3();
|
||||
}
|
||||
#endif // TOOLS_ENABLED
|
||||
|
||||
ChainIK3D::~ChainIK3D() {
|
||||
clear_settings();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user