diff options
Diffstat (limited to 'scene/3d/skeleton.cpp')
-rw-r--r-- | scene/3d/skeleton.cpp | 99 |
1 files changed, 82 insertions, 17 deletions
diff --git a/scene/3d/skeleton.cpp b/scene/3d/skeleton.cpp index 9df29f70ec..4712ba308a 100644 --- a/scene/3d/skeleton.cpp +++ b/scene/3d/skeleton.cpp @@ -187,30 +187,59 @@ void Skeleton::_notification(int p_what) { Bone &b=bonesptr[i]; - if (b.enabled) { + if (b.disable_rest) { + if (b.enabled) { - Transform pose=b.pose; - if (b.custom_pose_enable) { + Transform pose=b.pose; + if (b.custom_pose_enable) { - pose = b.custom_pose * pose; - } + pose = b.custom_pose * pose; + } + + if (b.parent>=0) { + + b.pose_global=bonesptr[b.parent].pose_global * pose; + } else { - if (b.parent>=0) { - - b.pose_global=bonesptr[b.parent].pose_global * (b.rest * pose); + b.pose_global=pose; + } } else { - - b.pose_global=b.rest * pose; + + if (b.parent>=0) { + + b.pose_global=bonesptr[b.parent].pose_global; + } else { + + b.pose_global=Transform(); + } } + } else { - - if (b.parent>=0) { - - b.pose_global=bonesptr[b.parent].pose_global * b.rest; + if (b.enabled) { + + Transform pose=b.pose; + if (b.custom_pose_enable) { + + pose = b.custom_pose * pose; + } + + if (b.parent>=0) { + + b.pose_global=bonesptr[b.parent].pose_global * (b.rest * pose); + } else { + + b.pose_global=b.rest * pose; + } } else { - - b.pose_global=b.rest; - } + + if (b.parent>=0) { + + b.pose_global=bonesptr[b.parent].pose_global * b.rest; + } else { + + b.pose_global=b.rest; + } + } } vs->skeleton_bone_set_transform( skeleton, i, b.pose_global * b.rest_global_inverse ); @@ -315,6 +344,37 @@ void Skeleton::set_bone_parent(int p_bone, int p_parent) { _make_dirty(); } +void Skeleton::unparent_bone_and_rest(int p_bone) { + + ERR_FAIL_INDEX( p_bone, bones.size() ); + + int parent=bones[p_bone].parent; + while(parent>=0) { + bones[p_bone].rest = bones[parent].rest * bones[p_bone].rest; + parent=bones[parent].parent; + } + + bones[p_bone].parent=-1; + bones[p_bone].rest_global_inverse=bones[p_bone].rest.affine_inverse(); //same thing + + _make_dirty(); + +} + +void Skeleton::set_bone_disable_rest(int p_bone, bool p_disable) { + + ERR_FAIL_INDEX( p_bone, bones.size() ); + bones[p_bone].disable_rest=p_disable; + +} + +bool Skeleton::is_bone_rest_disabled(int p_bone) const { + + ERR_FAIL_INDEX_V( p_bone, bones.size(), false ); + return bones[p_bone].disable_rest; +} + + int Skeleton::get_bone_parent(int p_bone) const { ERR_FAIL_INDEX_V( p_bone, bones.size(), -1 ); @@ -522,9 +582,14 @@ void Skeleton::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_bone_count"),&Skeleton::get_bone_count); + ObjectTypeDB::bind_method(_MD("unparent_bone_and_rest","bone_idx"),&Skeleton::unparent_bone_and_rest); + ObjectTypeDB::bind_method(_MD("get_bone_rest","bone_idx"),&Skeleton::get_bone_rest); ObjectTypeDB::bind_method(_MD("set_bone_rest","bone_idx","rest"),&Skeleton::set_bone_rest); + ObjectTypeDB::bind_method(_MD("set_bone_disable_rest","bone_idx","disable"),&Skeleton::set_bone_disable_rest); + ObjectTypeDB::bind_method(_MD("is_bone_rest_disabled","bone_idx"),&Skeleton::is_bone_rest_disabled); + ObjectTypeDB::bind_method(_MD("bind_child_node_to_bone","bone_idx","node:Node"),&Skeleton::bind_child_node_to_bone); ObjectTypeDB::bind_method(_MD("unbind_child_node_from_bone","bone_idx","node:Node"),&Skeleton::unbind_child_node_from_bone); ObjectTypeDB::bind_method(_MD("get_bound_child_nodes_to_bone","bone_idx"),&Skeleton::_get_bound_child_nodes_to_bone); |