瀏覽代碼

Fixed IK rotation issue

(cherry picked from commit 277696d6c50eba68ca11cf3c0988be0213e5c65d)
Andrea Catania 5 年之前
父節點
當前提交
a51e78528f
共有 4 個文件被更改,包括 15 次插入6 次删除
  1. 1 4
      editor/plugins/skeleton_ik_editor_plugin.cpp
  2. 8 0
      scene/3d/skeleton.cpp
  3. 1 0
      scene/3d/skeleton.h
  4. 5 2
      scene/animation/skeleton_ik.cpp

+ 1 - 4
editor/plugins/skeleton_ik_editor_plugin.cpp

@@ -44,10 +44,7 @@ void SkeletonIKEditorPlugin::_play() {
 		skeleton_ik->start();
 	} else {
 		skeleton_ik->stop();
-
-		for (int i = 0; i < skeleton_ik->get_parent_skeleton()->get_bone_count(); ++i) {
-			skeleton_ik->get_parent_skeleton()->set_bone_global_pose_override(i, Transform(), 0);
-		}
+		skeleton_ik->get_parent_skeleton()->clear_bones_global_pose_override();
 	}
 }
 

+ 8 - 0
scene/3d/skeleton.cpp

@@ -375,6 +375,13 @@ void Skeleton::_notification(int p_what) {
 	}
 }
 
+void Skeleton::clear_bones_global_pose_override() {
+	for (int i = 0; i < bones.size(); i += 1) {
+		bones.write[i].global_pose_override_amount = 0;
+	}
+	_make_dirty();
+}
+
 void Skeleton::set_bone_global_pose_override(int p_bone, const Transform &p_pose, float p_amount, bool p_persistent) {
 
 	ERR_FAIL_INDEX(p_bone, bones.size());
@@ -869,6 +876,7 @@ void Skeleton::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_bone_pose", "bone_idx"), &Skeleton::get_bone_pose);
 	ClassDB::bind_method(D_METHOD("set_bone_pose", "bone_idx", "pose"), &Skeleton::set_bone_pose);
 
+	ClassDB::bind_method(D_METHOD("clear_bones_global_pose_override"), &Skeleton::clear_bones_global_pose_override);
 	ClassDB::bind_method(D_METHOD("set_bone_global_pose_override", "bone_idx", "pose", "amount", "persistent"), &Skeleton::set_bone_global_pose_override, DEFVAL(false));
 	ClassDB::bind_method(D_METHOD("get_bone_global_pose", "bone_idx"), &Skeleton::get_bone_global_pose);
 

+ 1 - 0
scene/3d/skeleton.h

@@ -177,6 +177,7 @@ public:
 	Transform get_bone_rest(int p_bone) const;
 	Transform get_bone_global_pose(int p_bone) const;
 
+	void clear_bones_global_pose_override();
 	void set_bone_global_pose_override(int p_bone, const Transform &p_pose, float p_amount, bool p_persistent = false);
 
 	void set_bone_enabled(int p_bone, bool p_enabled);

+ 5 - 2
scene/animation/skeleton_ik.cpp

@@ -144,8 +144,9 @@ void FabrikInverseKinematic::update_chain(const Skeleton *p_sk, ChainItem *p_cha
 	p_chain_item->initial_transform = p_sk->get_bone_global_pose(p_chain_item->bone);
 	p_chain_item->current_pos = p_chain_item->initial_transform.origin;
 
-	for (int i = p_chain_item->children.size() - 1; 0 <= i; --i) {
-		update_chain(p_sk, &p_chain_item->children.write[i]);
+	ChainItem *items = p_chain_item->children.ptrw();
+	for (int i = 0; i < p_chain_item->children.size(); i += 1) {
+		update_chain(p_sk, items + i);
 	}
 }
 
@@ -286,6 +287,8 @@ void FabrikInverseKinematic::solve(Task *p_task, real_t blending_delta, bool ove
 		return; // Skip solving
 	}
 
+	p_task->skeleton->clear_bones_global_pose_override();
+
 	make_goal(p_task, p_task->skeleton->get_global_transform().affine_inverse().scaled(p_task->skeleton->get_global_transform().get_basis().get_scale()), blending_delta);
 
 	update_chain(p_task->skeleton, &p_task->chain.chain_root);