diff options
| author | Juan Linietsky <reduzio@gmail.com> | 2021-10-13 15:49:14 -0300 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-10-13 15:49:14 -0300 | 
| commit | 78cdfff0ec43a13406a7654eaf89aad50ddf8fde (patch) | |
| tree | 43014179b44fedcca852bc32ff13ac3cd6929b30 | |
| parent | c515fdd0fb480fe4e833ddd6cfe8c8162cd15e81 (diff) | |
| parent | 2dc823273e8d7d0eb92049c0d687f6a2c247ce13 (diff) | |
Merge pull request #53765 from reduz/skeleton-remove-rest-influence
Remove REST transform influence in skeleton bones
| -rw-r--r-- | doc/classes/Skeleton3D.xml | 36 | ||||
| -rw-r--r-- | editor/import/editor_import_collada.cpp | 19 | ||||
| -rw-r--r-- | editor/plugins/skeleton_3d_editor_plugin.cpp | 40 | ||||
| -rw-r--r-- | editor/plugins/skeleton_3d_editor_plugin.h | 4 | ||||
| -rw-r--r-- | modules/fbx/data/fbx_skeleton.cpp | 7 | ||||
| -rw-r--r-- | modules/fbx/editor_scene_importer_fbx.cpp | 14 | ||||
| -rw-r--r-- | modules/gltf/gltf_document.cpp | 33 | ||||
| -rw-r--r-- | scene/3d/bone_attachment_3d.cpp | 6 | ||||
| -rw-r--r-- | scene/3d/bone_attachment_3d.h | 1 | ||||
| -rw-r--r-- | scene/3d/mesh_instance_3d.cpp | 4 | ||||
| -rw-r--r-- | scene/3d/skeleton_3d.cpp | 197 | ||||
| -rw-r--r-- | scene/3d/skeleton_3d.h | 14 | ||||
| -rw-r--r-- | scene/animation/animation_tree.cpp | 3 | ||||
| -rw-r--r-- | scene/resources/skeleton_modification_3d_fabrik.cpp | 2 | ||||
| -rw-r--r-- | scene/resources/skeleton_modification_3d_twoboneik.cpp | 2 | 
15 files changed, 105 insertions, 277 deletions
diff --git a/doc/classes/Skeleton3D.xml b/doc/classes/Skeleton3D.xml index e046527b17..e804e7bf24 100644 --- a/doc/classes/Skeleton3D.xml +++ b/doc/classes/Skeleton3D.xml @@ -47,6 +47,11 @@  				Removes the local pose override on all bones in the skeleton.  			</description>  		</method> +		<method name="create_skin_from_rest_transforms"> +			<return type="Skin" /> +			<description> +			</description> +		</method>  		<method name="execute_modifications">  			<return type="void" />  			<argument index="0" name="delta" type="float" /> @@ -88,13 +93,6 @@  				Returns the amount of bones in the skeleton.  			</description>  		</method> -		<method name="get_bone_custom_pose" qualifiers="const"> -			<return type="Transform3D" /> -			<argument index="0" name="bone_idx" type="int" /> -			<description> -				Returns the custom pose of the specified bone. Custom pose is applied on top of the rest pose. -			</description> -		</method>  		<method name="get_bone_global_pose" qualifiers="const">  			<return type="Transform3D" />  			<argument index="0" name="bone_idx" type="int" /> @@ -214,13 +212,6 @@  				Returns whether the bone pose for the bone at [code]bone_idx[/code] is enabled.  			</description>  		</method> -		<method name="is_bone_rest_disabled" qualifiers="const"> -			<return type="bool" /> -			<argument index="0" name="bone_idx" type="int" /> -			<description> -				Returns whether the bone rest for the bone at [code]bone_idx[/code] is disabled. -			</description> -		</method>  		<method name="local_pose_to_global_pose">  			<return type="Transform3D" />  			<argument index="0" name="bone_idx" type="int" /> @@ -290,23 +281,6 @@  				Sets the children for the passed in bone, [code]bone_idx[/code], to the passed-in array of bone indexes, [code]bone_children[/code].  			</description>  		</method> -		<method name="set_bone_custom_pose"> -			<return type="void" /> -			<argument index="0" name="bone_idx" type="int" /> -			<argument index="1" name="custom_pose" type="Transform3D" /> -			<description> -				Sets the custom pose transform, [code]custom_pose[/code], for the bone at [code]bone_idx[/code]. This pose is an addition to the bone rest pose. -				[b]Note:[/b] The pose transform needs to be in bone space. Use [method world_transform_to_global_pose] to convert a world transform, like one you can get from a [Node3D], to bone space. -			</description> -		</method> -		<method name="set_bone_disable_rest"> -			<return type="void" /> -			<argument index="0" name="bone_idx" type="int" /> -			<argument index="1" name="disable" type="bool" /> -			<description> -				Disables the rest pose for the bone at [code]bone_idx[/code] if [code]true[/code], enables the bone rest if [code]false[/code]. -			</description> -		</method>  		<method name="set_bone_enabled">  			<return type="void" />  			<argument index="0" name="bone_idx" type="int" /> diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp index 022dc899da..d1bacf54de 100644 --- a/editor/import/editor_import_collada.cpp +++ b/editor/import/editor_import_collada.cpp @@ -120,6 +120,15 @@ Error ColladaImport::_populate_skeleton(Skeleton3D *p_skeleton, Collada::Node *p  	skeleton_bone_map[p_skeleton][joint->sid] = r_bone; +	{ +		Transform3D xform = joint->compute_transform(collada); +		collada.fix_transform(xform) * joint->post_transform; + +		p_skeleton->set_bone_pose_position(r_bone, xform.origin); +		p_skeleton->set_bone_pose_rotation(r_bone, xform.basis.get_rotation_quaternion()); +		p_skeleton->set_bone_pose_scale(r_bone, xform.basis.get_scale()); +	} +  	if (collada.state.bone_rest_map.has(joint->sid)) {  		p_skeleton->set_bone_rest(r_bone, collada.fix_transform(collada.state.bone_rest_map[joint->sid]));  		//should map this bone to something for animation? @@ -1639,16 +1648,6 @@ void ColladaImport::create_animation(int p_clip, bool p_import_value_tracks) {  			Transform3D xform = cn->compute_transform(collada);  			xform = collada.fix_transform(xform) * cn->post_transform; -			if (nm.bone >= 0) { -				//make bone transform relative to rest (in case of skeleton) -				Skeleton3D *sk = Object::cast_to<Skeleton3D>(nm.node); -				if (sk) { -					xform = sk->get_bone_rest(nm.bone).affine_inverse() * xform; -				} else { -					ERR_PRINT("Collada: Invalid skeleton"); -				} -			} -  			Vector3 s = xform.basis.get_scale();  			bool singular_matrix = Math::is_zero_approx(s.x) || Math::is_zero_approx(s.y) || Math::is_zero_approx(s.z);  			Quaternion q = singular_matrix ? Quaternion() : diff --git a/editor/plugins/skeleton_3d_editor_plugin.cpp b/editor/plugins/skeleton_3d_editor_plugin.cpp index 3a67c5415c..f9c46d35c4 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.cpp +++ b/editor/plugins/skeleton_3d_editor_plugin.cpp @@ -200,12 +200,7 @@ void BoneTransformEditor::_value_changed_transform(const String p_property_name,  }  void BoneTransformEditor::_change_transform(Transform3D p_new_transform) { -	if (property.get_slicec('/', 0) == "bones" && property.get_slicec('/', 2) == "custom_pose") { -		undo_redo->create_action(TTR("Set Custom Bone Pose Transform"), UndoRedo::MERGE_ENDS); -		undo_redo->add_undo_method(skeleton, "set_bone_custom_pose", property.get_slicec('/', 1).to_int(), skeleton->get_bone_custom_pose(property.get_slicec('/', 1).to_int())); -		undo_redo->add_do_method(skeleton, "set_bone_custom_pose", property.get_slicec('/', 1).to_int(), p_new_transform); -		undo_redo->commit_action(); -	} else if (property.get_slicec('/', 0) == "bones") { +	if (property.get_slicec('/', 0) == "bones") {  		undo_redo->create_action(TTR("Set Bone Transform"), UndoRedo::MERGE_ENDS);  		undo_redo->add_undo_property(skeleton, property, skeleton->get(property));  		undo_redo->add_do_property(skeleton, property, p_new_transform); @@ -236,21 +231,6 @@ void BoneTransformEditor::_update_properties() {  	_update_transform_properties(tform);  } -void BoneTransformEditor::_update_custom_pose_properties() { -	if (updating) { -		return; -	} - -	if (!skeleton) { -		return; -	} - -	updating = true; - -	Transform3D tform = skeleton->get_bone_custom_pose(property.to_int()); -	_update_transform_properties(tform); -} -  void BoneTransformEditor::_update_transform_properties(Transform3D tform) {  	Basis rotation_basis = tform.get_basis();  	Vector3 rotation_radians = rotation_basis.get_rotation_euler(); @@ -463,9 +443,7 @@ void Skeleton3DEditor::pose_to_rest() {  	ur->add_do_method(skeleton, "set_bone_pose", selected_bone, Transform3D());  	ur->add_undo_method(skeleton, "set_bone_pose", selected_bone, skeleton->get_bone_pose(selected_bone)); -	ur->add_do_method(skeleton, "set_bone_custom_pose", selected_bone, Transform3D()); -	ur->add_undo_method(skeleton, "set_bone_custom_pose", selected_bone, skeleton->get_bone_custom_pose(selected_bone)); -	ur->add_do_method(skeleton, "set_bone_rest", selected_bone, skeleton->get_bone_rest(selected_bone) * skeleton->get_bone_custom_pose(selected_bone) * skeleton->get_bone_pose(selected_bone)); +	ur->add_do_method(skeleton, "set_bone_rest", selected_bone, skeleton->get_bone_rest(selected_bone) * skeleton->get_bone_pose(selected_bone));  	ur->add_undo_method(skeleton, "set_bone_rest", selected_bone, skeleton->get_bone_rest(selected_bone));  	ur->commit_action(); @@ -654,11 +632,9 @@ void Skeleton3DEditor::_joint_tree_selection_changed() {  			pose_editor->set_target(bone_path + "pose");  			rest_editor->set_target(bone_path + "rest"); -			custom_pose_editor->set_target(bone_path + "custom_pose");  			pose_editor->set_visible(true);  			rest_editor->set_visible(true); -			custom_pose_editor->set_visible(true);  			selected_bone = b_idx;  		} @@ -679,9 +655,6 @@ void Skeleton3DEditor::_update_properties() {  	if (pose_editor) {  		pose_editor->_update_properties();  	} -	if (custom_pose_editor) { -		custom_pose_editor->_update_custom_pose_properties(); -	}  	_update_gizmo_transform();  } @@ -820,12 +793,6 @@ void Skeleton3DEditor::create_editors() {  	rest_editor->set_visible(false);  	add_child(rest_editor);  	rest_editor->set_transform_read_only(true); - -	custom_pose_editor = memnew(BoneTransformEditor(skeleton)); -	custom_pose_editor->set_label(TTR("Bone Custom Pose")); -	custom_pose_editor->set_visible(false); -	add_child(custom_pose_editor); -	custom_pose_editor->set_transform_read_only(true);  }  void Skeleton3DEditor::_notification(int p_what) { @@ -1289,7 +1256,6 @@ void Skeleton3DGizmoPlugin::set_subgizmo_transform(const EditorNode3DGizmo *p_gi  	if (parent_idx >= 0) {  		original_to_local = original_to_local * skeleton->get_bone_global_pose(parent_idx);  	} -	original_to_local = original_to_local * skeleton->get_bone_rest(p_id) * skeleton->get_bone_custom_pose(p_id);  	Basis to_local = original_to_local.get_basis().inverse();  	// Prepare transform. @@ -1518,5 +1484,5 @@ void Skeleton3DGizmoPlugin::redraw(EditorNode3DGizmo *p_gizmo) {  	}  	Ref<ArrayMesh> m = surface_tool->commit(); -	p_gizmo->add_mesh(m, Ref<Material>(), Transform3D(), skeleton->register_skin(Ref<Skin>())); +	p_gizmo->add_mesh(m, Ref<Material>(), Transform3D(), skeleton->register_skin(skeleton->create_skin_from_rest_transforms()));  } diff --git a/editor/plugins/skeleton_3d_editor_plugin.h b/editor/plugins/skeleton_3d_editor_plugin.h index e2a1d9a628..2c21aab739 100644 --- a/editor/plugins/skeleton_3d_editor_plugin.h +++ b/editor/plugins/skeleton_3d_editor_plugin.h @@ -102,13 +102,12 @@ public:  	void set_label(const String &p_label) { label = p_label; }  	void _update_properties(); -	void _update_custom_pose_properties();  	void _update_transform_properties(Transform3D p_transform);  	// Transform can be keyed, whether or not to show the button.  	void set_keyable(const bool p_keyable); -	// When rest mode, pose and custom_pose editor are diasbled. +	// When rest mode, pose editor are diasbled.  	void set_properties_read_only(const bool p_readonly);  	void set_transform_read_only(const bool p_readonly); @@ -151,7 +150,6 @@ class Skeleton3DEditor : public VBoxContainer {  	Tree *joint_tree = nullptr;  	BoneTransformEditor *rest_editor = nullptr;  	BoneTransformEditor *pose_editor = nullptr; -	BoneTransformEditor *custom_pose_editor = nullptr;  	VSeparator *separator;  	MenuButton *skeleton_options = nullptr; diff --git a/modules/fbx/data/fbx_skeleton.cpp b/modules/fbx/data/fbx_skeleton.cpp index 3dc163964c..11eed2576f 100644 --- a/modules/fbx/data/fbx_skeleton.cpp +++ b/modules/fbx/data/fbx_skeleton.cpp @@ -104,6 +104,13 @@ void FBXSkeleton::init_skeleton(const ImportState &state) {  		print_verbose("working on bone: " + itos(bone_index) + " bone name:" + bone->bone_name);  		skeleton->set_bone_rest(bone->godot_bone_id, get_unscaled_transform(bone->node->pivot_transform->LocalTransform, state.scale)); +		{ +			Transform3D base_xform = bone->node->pivot_transform->LocalTransform; + +			skeleton->set_bone_pose_position(bone_index, base_xform.origin); +			skeleton->set_bone_pose_rotation(bone_index, base_xform.basis.get_rotation_quaternion()); +			skeleton->set_bone_pose_scale(bone_index, base_xform.basis.get_scale()); +		}  		// lookup parent ID  		if (bone->valid_parent && state.fbx_bone_map.has(bone->parent_bone_id)) { diff --git a/modules/fbx/editor_scene_importer_fbx.cpp b/modules/fbx/editor_scene_importer_fbx.cpp index e90eab522f..879f281292 100644 --- a/modules/fbx/editor_scene_importer_fbx.cpp +++ b/modules/fbx/editor_scene_importer_fbx.cpp @@ -1227,20 +1227,6 @@ Node3D *EditorSceneImporterFBX::_generate_scene(  										AssetImportAnimation::INTERP_LINEAR);  							} -							// node animations must also include pivots -							if (skeleton_bone >= 0) { -								Transform3D xform = Transform3D(); -								xform.basis.set_quaternion_scale(rot, scale); -								xform.origin = pos; -								const Transform3D t = bone_rest.affine_inverse() * xform; - -								// populate	this again -								rot = t.basis.get_rotation_quaternion(); -								rot.normalize(); -								scale = t.basis.get_scale(); -								pos = t.origin; -							} -  							if (position_idx >= 0) {  								animation->position_track_insert_key(position_idx, time, pos);  							} diff --git a/modules/gltf/gltf_document.cpp b/modules/gltf/gltf_document.cpp index 32540e7a22..6fd542ca68 100644 --- a/modules/gltf/gltf_document.cpp +++ b/modules/gltf/gltf_document.cpp @@ -4319,6 +4319,9 @@ Error GLTFDocument::_create_skeletons(Ref<GLTFState> state) {  			skeleton->add_bone(node->get_name());  			skeleton->set_bone_rest(bone_index, node->xform); +			skeleton->set_bone_pose_position(bone_index, node->position); +			skeleton->set_bone_pose_rotation(bone_index, node->rotation.normalized()); +			skeleton->set_bone_pose_scale(bone_index, node->scale);  			if (node->parent >= 0 && state->nodes[node->parent]->skeleton == skel_i) {  				const int bone_parent = skeleton->find_bone(state->nodes[node->parent]->get_name()); @@ -5470,7 +5473,7 @@ void GLTFDocument::_convert_skeleton_to_gltf(Skeleton3D *p_skeleton3d, Ref<GLTFS  		// Note that we cannot use _gen_unique_bone_name here, because glTF spec requires all node  		// names to be unique regardless of whether or not they are used as joints.  		joint_node->set_name(_gen_unique_name(state, skeleton->get_bone_name(bone_i))); -		Transform3D xform = skeleton->get_bone_rest(bone_i) * skeleton->get_bone_pose(bone_i); +		Transform3D xform = skeleton->get_bone_pose(bone_i);  		joint_node->scale = xform.basis.get_scale();  		joint_node->rotation = xform.basis.get_rotation_quaternion();  		joint_node->position = xform.origin; @@ -5958,38 +5961,16 @@ void GLTFDocument::_import_animation(Ref<GLTFState> state, AnimationPlayer *ap,  				if (position_idx >= 0) {  					pos = _interpolate_track<Vector3>(track.position_track.times, track.position_track.values, time, track.position_track.interpolation); +					animation->position_track_insert_key(position_idx, time, pos);  				}  				if (rotation_idx >= 0) {  					rot = _interpolate_track<Quaternion>(track.rotation_track.times, track.rotation_track.values, time, track.rotation_track.interpolation); +					animation->rotation_track_insert_key(rotation_idx, time, rot);  				}  				if (scale_idx >= 0) {  					scale = _interpolate_track<Vector3>(track.scale_track.times, track.scale_track.values, time, track.scale_track.interpolation); -				} - -				if (gltf_node->skeleton >= 0) { -					Transform3D xform; -					xform.basis.set_quaternion_scale(rot, scale); -					xform.origin = pos; - -					const Skeleton3D *skeleton = state->skeletons[gltf_node->skeleton]->godot_skeleton; -					const int bone_idx = skeleton->find_bone(gltf_node->get_name()); -					xform = skeleton->get_bone_rest(bone_idx).affine_inverse() * xform; - -					rot = xform.basis.get_rotation_quaternion(); -					rot.normalize(); -					scale = xform.basis.get_scale(); -					pos = xform.origin; -				} - -				if (position_idx >= 0) { -					animation->position_track_insert_key(position_idx, time, pos); -				} -				if (rotation_idx >= 0) { -					animation->rotation_track_insert_key(rotation_idx, time, rot); -				} -				if (scale_idx >= 0) {  					animation->scale_track_insert_key(scale_idx, time, scale);  				} @@ -6108,7 +6089,7 @@ void GLTFDocument::_convert_mesh_instances(Ref<GLTFState> state) {  			} else {  				if (skin.is_null()) {  					// Note that gltf_skin_key should remain null, so these can share a reference. -					skin = skeleton->register_skin(nullptr)->get_skin(); +					skin = skeleton->create_skin_from_rest_transforms();  				}  				gltf_skin.instantiate();  				gltf_skin->godot_skin = skin; diff --git a/scene/3d/bone_attachment_3d.cpp b/scene/3d/bone_attachment_3d.cpp index afd11482e3..8e89f4fc54 100644 --- a/scene/3d/bone_attachment_3d.cpp +++ b/scene/3d/bone_attachment_3d.cpp @@ -215,8 +215,6 @@ void BoneAttachment3D::_transform_changed() {  			sk->set_bone_global_pose_override(bone_idx, our_trans, 1.0, true);  		} else if (override_mode == OVERRIDE_MODES::MODE_LOCAL_POSE) {  			sk->set_bone_local_pose_override(bone_idx, sk->global_pose_to_local_pose(bone_idx, our_trans), 1.0, true); -		} else if (override_mode == OVERRIDE_MODES::MODE_CUSTOM_POSE) { -			sk->set_bone_custom_pose(bone_idx, sk->global_pose_to_local_pose(bone_idx, our_trans));  		}  	}  } @@ -273,8 +271,6 @@ void BoneAttachment3D::set_override_pose(bool p_override) {  				sk->set_bone_global_pose_override(bone_idx, Transform3D(), 0.0, false);  			} else if (override_mode == OVERRIDE_MODES::MODE_LOCAL_POSE) {  				sk->set_bone_local_pose_override(bone_idx, Transform3D(), 0.0, false); -			} else if (override_mode == OVERRIDE_MODES::MODE_CUSTOM_POSE) { -				sk->set_bone_custom_pose(bone_idx, Transform3D());  			}  		}  		_transform_changed(); @@ -294,8 +290,6 @@ void BoneAttachment3D::set_override_mode(int p_mode) {  				sk->set_bone_global_pose_override(bone_idx, Transform3D(), 0.0, false);  			} else if (override_mode == OVERRIDE_MODES::MODE_LOCAL_POSE) {  				sk->set_bone_local_pose_override(bone_idx, Transform3D(), 0.0, false); -			} else if (override_mode == OVERRIDE_MODES::MODE_CUSTOM_POSE) { -				sk->set_bone_custom_pose(bone_idx, Transform3D());  			}  		}  		override_mode = p_mode; diff --git a/scene/3d/bone_attachment_3d.h b/scene/3d/bone_attachment_3d.h index cf681cace8..57b9854e0e 100644 --- a/scene/3d/bone_attachment_3d.h +++ b/scene/3d/bone_attachment_3d.h @@ -47,7 +47,6 @@ class BoneAttachment3D : public Node3D {  	enum OVERRIDE_MODES {  		MODE_GLOBAL_POSE,  		MODE_LOCAL_POSE, -		MODE_CUSTOM_POSE  	};  	bool use_external_skeleton = false; diff --git a/scene/3d/mesh_instance_3d.cpp b/scene/3d/mesh_instance_3d.cpp index 67f4a88228..cfd90e5da0 100644 --- a/scene/3d/mesh_instance_3d.cpp +++ b/scene/3d/mesh_instance_3d.cpp @@ -146,11 +146,13 @@ void MeshInstance3D::_resolve_skeleton_path() {  	if (!skeleton_path.is_empty()) {  		Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(get_node(skeleton_path));  		if (skeleton) { -			new_skin_reference = skeleton->register_skin(skin_internal);  			if (skin_internal.is_null()) { +				new_skin_reference = skeleton->register_skin(skeleton->create_skin_from_rest_transforms());  				//a skin was created for us  				skin_internal = new_skin_reference->get_skin();  				notify_property_list_changed(); +			} else { +				new_skin_reference = skeleton->register_skin(skin_internal);  			}  		}  	} diff --git a/scene/3d/skeleton_3d.cpp b/scene/3d/skeleton_3d.cpp index 79504b10bb..9b28d7aff8 100644 --- a/scene/3d/skeleton_3d.cpp +++ b/scene/3d/skeleton_3d.cpp @@ -557,18 +557,6 @@ void Skeleton3D::unparent_bone_and_rest(int p_bone) {  	_make_dirty();  } -void Skeleton3D::set_bone_disable_rest(int p_bone, bool p_disable) { -	const int bone_size = bones.size(); -	ERR_FAIL_INDEX(p_bone, bone_size); -	bones.write[p_bone].disable_rest = p_disable; -} - -bool Skeleton3D::is_bone_rest_disabled(int p_bone) const { -	const int bone_size = bones.size(); -	ERR_FAIL_INDEX_V(p_bone, bone_size, false); -	return bones[p_bone].disable_rest; -} -  int Skeleton3D::get_bone_parent(int p_bone) const {  	const int bone_size = bones.size();  	ERR_FAIL_INDEX_V(p_bone, bone_size, -1); @@ -723,23 +711,6 @@ Transform3D Skeleton3D::get_bone_pose(int p_bone) const {  	return bones[p_bone].pose_cache;  } -void Skeleton3D::set_bone_custom_pose(int p_bone, const Transform3D &p_custom_pose) { -	const int bone_size = bones.size(); -	ERR_FAIL_INDEX(p_bone, bone_size); -	//ERR_FAIL_COND( !is_inside_scene() ); - -	bones.write[p_bone].custom_pose_enable = (p_custom_pose != Transform3D()); -	bones.write[p_bone].custom_pose = p_custom_pose; - -	_make_dirty(); -} - -Transform3D Skeleton3D::get_bone_custom_pose(int p_bone) const { -	const int bone_size = bones.size(); -	ERR_FAIL_INDEX_V(p_bone, bone_size, Transform3D()); -	return bones[p_bone].custom_pose; -} -  void Skeleton3D::_make_dirty() {  	if (dirty) {  		return; @@ -938,59 +909,57 @@ void Skeleton3D::_skin_changed() {  	_make_dirty();  } -Ref<SkinReference> Skeleton3D::register_skin(const Ref<Skin> &p_skin) { -	for (Set<SkinReference *>::Element *E = skin_bindings.front(); E; E = E->next()) { -		if (E->get()->skin == p_skin) { -			return Ref<SkinReference>(E->get()); +Ref<Skin> Skeleton3D::create_skin_from_rest_transforms() { +	Ref<Skin> skin; + +	skin.instantiate(); +	skin->set_bind_count(bones.size()); +	_update_process_order(); // Just in case. + +	// Pose changed, rebuild cache of inverses. +	const Bone *bonesptr = bones.ptr(); +	int len = bones.size(); + +	// Calculate global rests and invert them. +	LocalVector<int> bones_to_process; +	bones_to_process = get_parentless_bones(); +	while (bones_to_process.size() > 0) { +		int current_bone_idx = bones_to_process[0]; +		const Bone &b = bonesptr[current_bone_idx]; +		bones_to_process.erase(current_bone_idx); +		LocalVector<int> child_bones_vector; +		child_bones_vector = get_bone_children(current_bone_idx); +		int child_bones_size = child_bones_vector.size(); +		if (b.parent < 0) { +			skin->set_bind_pose(current_bone_idx, b.rest); +		} +		for (int i = 0; i < child_bones_size; i++) { +			int child_bone_idx = child_bones_vector[i]; +			const Bone &cb = bonesptr[child_bone_idx]; +			skin->set_bind_pose(child_bone_idx, skin->get_bind_pose(current_bone_idx) * cb.rest); +			// Add the bone's children to the list of bones to be processed. +			bones_to_process.push_back(child_bones_vector[i]);  		}  	} -	Ref<Skin> skin = p_skin; - -	if (skin.is_null()) { -		// Need to create one from existing code, this is for compatibility only -		// when skeletons did not support skins. It is also used by gizmo -		// to display the skeleton. - -		skin.instantiate(); -		skin->set_bind_count(bones.size()); -		_update_process_order(); // Just in case. - -		// Pose changed, rebuild cache of inverses. -		const Bone *bonesptr = bones.ptr(); -		int len = bones.size(); - -		// Calculate global rests and invert them. -		LocalVector<int> bones_to_process; -		bones_to_process = get_parentless_bones(); -		while (bones_to_process.size() > 0) { -			int current_bone_idx = bones_to_process[0]; -			const Bone &b = bonesptr[current_bone_idx]; -			bones_to_process.erase(current_bone_idx); -			LocalVector<int> child_bones_vector; -			child_bones_vector = get_bone_children(current_bone_idx); -			int child_bones_size = child_bones_vector.size(); -			if (b.parent < 0) { -				skin->set_bind_pose(current_bone_idx, b.rest); -			} -			for (int i = 0; i < child_bones_size; i++) { -				int child_bone_idx = child_bones_vector[i]; -				const Bone &cb = bonesptr[child_bone_idx]; -				skin->set_bind_pose(child_bone_idx, skin->get_bind_pose(current_bone_idx) * cb.rest); -				// Add the bone's children to the list of bones to be processed. -				bones_to_process.push_back(child_bones_vector[i]); -			} -		} +	for (int i = 0; i < len; i++) { +		// The inverse is what is actually required. +		skin->set_bind_bone(i, i); +		skin->set_bind_pose(i, skin->get_bind_pose(i).affine_inverse()); +	} -		for (int i = 0; i < len; i++) { -			// The inverse is what is actually required. -			skin->set_bind_bone(i, i); -			skin->set_bind_pose(i, skin->get_bind_pose(i).affine_inverse()); +	return skin; +} + +Ref<SkinReference> Skeleton3D::register_skin(const Ref<Skin> &p_skin) { +	ERR_FAIL_COND_V(p_skin.is_null(), Ref<SkinReference>()); + +	for (Set<SkinReference *>::Element *E = skin_bindings.front(); E; E = E->next()) { +		if (E->get()->skin == p_skin) { +			return Ref<SkinReference>(E->get());  		}  	} -	ERR_FAIL_COND_V(skin.is_null(), Ref<SkinReference>()); -  	Ref<SkinReference> skin_ref;  	skin_ref.instantiate(); @@ -998,11 +967,11 @@ Ref<SkinReference> Skeleton3D::register_skin(const Ref<Skin> &p_skin) {  	skin_ref->bind_count = 0;  	skin_ref->skeleton = RenderingServer::get_singleton()->skeleton_create();  	skin_ref->skeleton_node = this; -	skin_ref->skin = skin; +	skin_ref->skin = p_skin;  	skin_bindings.insert(skin_ref.operator->()); -	skin->connect("changed", Callable(skin_ref.operator->(), "_skin_changed")); +	skin_ref->skin->connect("changed", Callable(skin_ref.operator->(), "_skin_changed"));  	_make_dirty(); // Skin needs to be updated, so update skeleton. @@ -1038,61 +1007,33 @@ void Skeleton3D::force_update_bone_children_transforms(int p_bone_idx) {  		Bone &b = bonesptr[current_bone_idx];  		bool bone_enabled = b.enabled && !show_rest_only; -		if (b.disable_rest) { -			if (bone_enabled) { -				b.update_pose_cache(); -				Transform3D pose = b.pose_cache; -				if (b.custom_pose_enable) { -					pose = b.custom_pose * pose; -				} -				if (b.parent >= 0) { -					b.pose_global = bonesptr[b.parent].pose_global * pose; -					b.pose_global_no_override = b.pose_global; -				} else { -					b.pose_global = pose; -					b.pose_global_no_override = b.pose_global; -				} +		if (bone_enabled) { +			b.update_pose_cache(); +			Transform3D pose = b.pose_cache; + +			if (b.parent >= 0) { +				b.pose_global = bonesptr[b.parent].pose_global * pose; +				b.pose_global_no_override = b.pose_global;  			} else { -				if (b.parent >= 0) { -					b.pose_global = bonesptr[b.parent].pose_global; -					b.pose_global_no_override = b.pose_global; -				} else { -					b.pose_global = Transform3D(); -					b.pose_global_no_override = b.pose_global; -				} +				b.pose_global = pose; +				b.pose_global_no_override = b.pose_global;  			} -  		} else { -			if (bone_enabled) { -				b.update_pose_cache(); -				Transform3D pose = b.pose_cache; -				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); -					b.pose_global_no_override = b.pose_global; -				} else { -					b.pose_global = b.rest * pose; -					b.pose_global_no_override = b.pose_global; -				} +			if (b.parent >= 0) { +				b.pose_global = bonesptr[b.parent].pose_global * b.rest; +				b.pose_global_no_override = b.pose_global;  			} else { -				if (b.parent >= 0) { -					b.pose_global = bonesptr[b.parent].pose_global * b.rest; -					b.pose_global_no_override = b.pose_global; -				} else { -					b.pose_global = b.rest; -					b.pose_global_no_override = b.pose_global; -				} +				b.pose_global = b.rest; +				b.pose_global_no_override = b.pose_global;  			}  		}  		if (b.local_pose_override_amount >= CMP_EPSILON) {  			Transform3D override_local_pose;  			if (b.parent >= 0) { -				override_local_pose = bonesptr[b.parent].pose_global * (b.rest * b.local_pose_override); +				override_local_pose = bonesptr[b.parent].pose_global * b.local_pose_override;  			} else { -				override_local_pose = (b.rest * b.local_pose_override); +				override_local_pose = b.local_pose_override;  			}  			b.pose_global = b.pose_global.interpolate_with(override_local_pose, b.local_pose_override_amount);  		} @@ -1133,8 +1074,8 @@ Transform3D Skeleton3D::global_pose_to_local_pose(int p_bone_idx, Transform3D p_  	ERR_FAIL_INDEX_V(p_bone_idx, bone_size, Transform3D());  	if (bones[p_bone_idx].parent >= 0) {  		int parent_bone_idx = bones[p_bone_idx].parent; -		Transform3D conversion_transform = (bones[parent_bone_idx].pose_global * bones[p_bone_idx].rest); -		return conversion_transform.affine_inverse() * p_global_pose; +		Transform3D conversion_transform = bones[parent_bone_idx].pose_global.affine_inverse(); +		return conversion_transform * p_global_pose;  	} else {  		return p_global_pose;  	} @@ -1145,8 +1086,7 @@ Transform3D Skeleton3D::local_pose_to_global_pose(int p_bone_idx, Transform3D p_  	ERR_FAIL_INDEX_V(p_bone_idx, bone_size, Transform3D());  	if (bones[p_bone_idx].parent >= 0) {  		int parent_bone_idx = bones[p_bone_idx].parent; -		Transform3D conversion_transform = (bones[parent_bone_idx].pose_global * bones[p_bone_idx].rest); -		return conversion_transform * p_local_pose; +		return bones[parent_bone_idx].pose_global * p_local_pose;  	} else {  		return p_local_pose;  	} @@ -1236,13 +1176,11 @@ void Skeleton3D::_bind_methods() {  	ClassDB::bind_method(D_METHOD("get_bone_rest", "bone_idx"), &Skeleton3D::get_bone_rest);  	ClassDB::bind_method(D_METHOD("set_bone_rest", "bone_idx", "rest"), &Skeleton3D::set_bone_rest); +	ClassDB::bind_method(D_METHOD("create_skin_from_rest_transforms"), &Skeleton3D::create_skin_from_rest_transforms);  	ClassDB::bind_method(D_METHOD("register_skin", "skin"), &Skeleton3D::register_skin);  	ClassDB::bind_method(D_METHOD("localize_rests"), &Skeleton3D::localize_rests); -	ClassDB::bind_method(D_METHOD("set_bone_disable_rest", "bone_idx", "disable"), &Skeleton3D::set_bone_disable_rest); -	ClassDB::bind_method(D_METHOD("is_bone_rest_disabled", "bone_idx"), &Skeleton3D::is_bone_rest_disabled); -  	ClassDB::bind_method(D_METHOD("clear_bones"), &Skeleton3D::clear_bones);  	ClassDB::bind_method(D_METHOD("get_bone_pose", "bone_idx"), &Skeleton3D::get_bone_pose); @@ -1267,9 +1205,6 @@ void Skeleton3D::_bind_methods() {  	ClassDB::bind_method(D_METHOD("set_bone_local_pose_override", "bone_idx", "pose", "amount", "persistent"), &Skeleton3D::set_bone_local_pose_override, DEFVAL(false));  	ClassDB::bind_method(D_METHOD("get_bone_local_pose_override", "bone_idx"), &Skeleton3D::get_bone_local_pose_override); -	ClassDB::bind_method(D_METHOD("get_bone_custom_pose", "bone_idx"), &Skeleton3D::get_bone_custom_pose); -	ClassDB::bind_method(D_METHOD("set_bone_custom_pose", "bone_idx", "custom_pose"), &Skeleton3D::set_bone_custom_pose); -  	ClassDB::bind_method(D_METHOD("force_update_all_bone_transforms"), &Skeleton3D::force_update_all_bone_transforms);  	ClassDB::bind_method(D_METHOD("force_update_bone_child_transform", "bone_idx"), &Skeleton3D::force_update_bone_children_transforms); diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h index aacee3da4e..f3cf551af7 100644 --- a/scene/3d/skeleton_3d.h +++ b/scene/3d/skeleton_3d.h @@ -76,7 +76,6 @@ private:  		bool enabled;  		int parent; -		bool disable_rest = false;  		Transform3D rest;  		_FORCE_INLINE_ void update_pose_cache() { @@ -95,9 +94,6 @@ private:  		Transform3D pose_global;  		Transform3D pose_global_no_override; -		bool custom_pose_enable = false; -		Transform3D custom_pose; -  		real_t global_pose_override_amount = 0.0;  		bool global_pose_override_reset = false;  		Transform3D global_pose_override; @@ -119,8 +115,6 @@ private:  		Bone() {  			parent = -1;  			enabled = true; -			disable_rest = false; -			custom_pose_enable = false;  			global_pose_override_amount = 0;  			global_pose_override_reset = false;  #ifndef _3D_DISABLED @@ -199,9 +193,6 @@ public:  	void remove_bone_child(int p_bone, int p_child);  	Vector<int> get_parentless_bones(); -	void set_bone_disable_rest(int p_bone, bool p_disable); -	bool is_bone_rest_disabled(int p_bone) const; -  	int get_bone_count() const;  	void set_bone_rest(int p_bone, const Transform3D &p_rest); @@ -228,9 +219,6 @@ public:  	Quaternion get_bone_pose_rotation(int p_bone) const;  	Vector3 get_bone_pose_scale(int p_bone) const; -	void set_bone_custom_pose(int p_bone, const Transform3D &p_custom_pose); -	Transform3D get_bone_custom_pose(int p_bone) const; -  	void clear_bones_global_pose_override();  	Transform3D get_bone_global_pose_override(int p_bone) const;  	void set_bone_global_pose_override(int p_bone, const Transform3D &p_pose, real_t p_amount, bool p_persistent = false); @@ -241,6 +229,8 @@ public:  	void localize_rests(); // used for loaders and tools +	Ref<Skin> create_skin_from_rest_transforms(); +  	Ref<SkinReference> register_skin(const Ref<Skin> &p_skin);  	void force_update_all_dirty_bones(); diff --git a/scene/animation/animation_tree.cpp b/scene/animation/animation_tree.cpp index 2ed8268289..dd5fe46223 100644 --- a/scene/animation/animation_tree.cpp +++ b/scene/animation/animation_tree.cpp @@ -1360,9 +1360,6 @@ void AnimationTree::_process_graph(real_t p_delta) {  						root_motion_transform = xform; -						if (t->skeleton && t->bone_idx >= 0) { -							root_motion_transform = (t->skeleton->get_bone_rest(t->bone_idx) * root_motion_transform) * t->skeleton->get_bone_rest(t->bone_idx).affine_inverse(); -						}  					} else if (t->skeleton && t->bone_idx >= 0) {  						if (t->loc_used) {  							t->skeleton->set_bone_pose_position(t->bone_idx, t->loc); diff --git a/scene/resources/skeleton_modification_3d_fabrik.cpp b/scene/resources/skeleton_modification_3d_fabrik.cpp index e615615924..20ebbda256 100644 --- a/scene/resources/skeleton_modification_3d_fabrik.cpp +++ b/scene/resources/skeleton_modification_3d_fabrik.cpp @@ -168,7 +168,7 @@ void SkeletonModification3DFABRIK::_execute(real_t p_delta) {  		// Apply magnet positions:  		if (stack->skeleton->get_bone_parent(fabrik_data_chain[i].bone_idx) >= 0) {  			int parent_bone_idx = stack->skeleton->get_bone_parent(fabrik_data_chain[i].bone_idx); -			Transform3D conversion_transform = (stack->skeleton->get_bone_global_pose(parent_bone_idx) * stack->skeleton->get_bone_rest(parent_bone_idx)); +			Transform3D conversion_transform = (stack->skeleton->get_bone_global_pose(parent_bone_idx));  			local_pose_override.origin += conversion_transform.basis.xform_inv(fabrik_data_chain[i].magnet_position);  		} else {  			local_pose_override.origin += fabrik_data_chain[i].magnet_position; diff --git a/scene/resources/skeleton_modification_3d_twoboneik.cpp b/scene/resources/skeleton_modification_3d_twoboneik.cpp index ae7a3bab7e..c1a71148a7 100644 --- a/scene/resources/skeleton_modification_3d_twoboneik.cpp +++ b/scene/resources/skeleton_modification_3d_twoboneik.cpp @@ -455,7 +455,7 @@ void SkeletonModification3DTwoBoneIK::calculate_joint_lengths() {  			joint_two_length = 0;  			for (int i = 0; i < bone_two_children.size(); i++) {  				joint_two_length += bone_two_rest_trans.origin.distance_to( -						stack->skeleton->local_pose_to_global_pose(bone_two_children[i], stack->skeleton->get_bone_rest(bone_two_children[i])).origin); +						stack->skeleton->get_bone_global_pose(bone_two_children[i]).origin);  			}  			joint_two_length = joint_two_length / bone_two_children.size();  		} else {  |