Browse Source

Make transform elements BitField in RetargetModifier

Silc Lizard (Tokage) Renew 8 months ago
parent
commit
24f5361b8a
3 changed files with 120 additions and 32 deletions
  1. 57 8
      doc/classes/RetargetModifier3D.xml
  2. 48 21
      scene/3d/retarget_modifier_3d.cpp
  3. 15 3
      scene/3d/retarget_modifier_3d.h

+ 57 - 8
doc/classes/RetargetModifier3D.xml

@@ -10,19 +10,54 @@
 	</description>
 	<tutorials>
 	</tutorials>
+	<methods>
+		<method name="is_position_enabled" qualifiers="const">
+			<return type="bool" />
+			<description>
+				Returns [code]true[/code] if [member enable] has [constant TRANSFORM_FLAG_POSITION].
+			</description>
+		</method>
+		<method name="is_rotation_enabled" qualifiers="const">
+			<return type="bool" />
+			<description>
+				Returns [code]true[/code] if [member enable] has [constant TRANSFORM_FLAG_ROTATION].
+			</description>
+		</method>
+		<method name="is_scale_enabled" qualifiers="const">
+			<return type="bool" />
+			<description>
+				Returns [code]true[/code] if [member enable] has [constant TRANSFORM_FLAG_SCALE].
+			</description>
+		</method>
+		<method name="set_position_enabled">
+			<return type="void" />
+			<param index="0" name="enabled" type="bool" />
+			<description>
+				Sets [constant TRANSFORM_FLAG_POSITION] into [member enable].
+			</description>
+		</method>
+		<method name="set_rotation_enabled">
+			<return type="void" />
+			<param index="0" name="enabled" type="bool" />
+			<description>
+				Sets [constant TRANSFORM_FLAG_ROTATION] into [member enable].
+			</description>
+		</method>
+		<method name="set_scale_enabled">
+			<return type="void" />
+			<param index="0" name="enabled" type="bool" />
+			<description>
+				Sets [constant TRANSFORM_FLAG_SCALE] into [member enable].
+			</description>
+		</method>
+	</methods>
 	<members>
-		<member name="position_enabled" type="bool" setter="set_position_enabled" getter="is_position_enabled" default="true">
-			If [code]true[/code], allows to retarget the position.
+		<member name="enable" type="int" setter="set_enable_flags" getter="get_enable_flags" enum="RetargetModifier3D.TransformFlag" is_bitfield="true" default="7">
+			Flags to control the process of the transform elements individually when [member use_global_pose] is disabled.
 		</member>
 		<member name="profile" type="SkeletonProfile" setter="set_profile" getter="get_profile">
 			[SkeletonProfile] for retargeting bones with names matching the bone list.
 		</member>
-		<member name="rotation_enabled" type="bool" setter="set_rotation_enabled" getter="is_rotation_enabled" default="true">
-			If [code]true[/code], allows to retarget the rotation.
-		</member>
-		<member name="scale_enabled" type="bool" setter="set_scale_enabled" getter="is_scale_enabled" default="true">
-			If [code]true[/code], allows to retarget the scale.
-		</member>
 		<member name="use_global_pose" type="bool" setter="set_use_global_pose" getter="is_using_global_pose" default="false">
 			If [code]false[/code], in case the target skeleton has fewer bones than the source skeleton, the source bone parent's transform will be ignored.
 			Instead, it is possible to retarget between models with different body shapes, and position, rotation, and scale can be retargeted separately.
@@ -31,4 +66,18 @@
 			This is useful for using dummy bone with length [code]0[/code] to match postures when retargeting between models with different number of bones.
 		</member>
 	</members>
+	<constants>
+		<constant name="TRANSFORM_FLAG_POSITION" value="1" enum="TransformFlag" is_bitfield="true">
+			If set, allows to retarget the position.
+		</constant>
+		<constant name="TRANSFORM_FLAG_ROTATION" value="2" enum="TransformFlag" is_bitfield="true">
+			If set, allows to retarget the rotation.
+		</constant>
+		<constant name="TRANSFORM_FLAG_SCALE" value="4" enum="TransformFlag" is_bitfield="true">
+			If set, allows to retarget the scale.
+		</constant>
+		<constant name="TRANSFORM_FLAG_ALL" value="7" enum="TransformFlag" is_bitfield="true">
+			If set, allows to retarget the position/rotation/scale.
+		</constant>
+	</constants>
 </class>

+ 48 - 21
scene/3d/retarget_modifier_3d.cpp

@@ -236,7 +236,7 @@ void RetargetModifier3D::remove_child_notify(Node *p_child) {
 
 void RetargetModifier3D::_validate_property(PropertyInfo &p_property) const {
 	if (use_global_pose) {
-		if (p_property.name == "position_enabled" || p_property.name == "rotation_enabled" || p_property.name == "scale_enabled") {
+		if (p_property.name == "enable_flags") {
 			p_property.usage = PROPERTY_USAGE_NONE;
 		}
 	}
@@ -247,6 +247,9 @@ void RetargetModifier3D::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("get_profile"), &RetargetModifier3D::get_profile);
 	ClassDB::bind_method(D_METHOD("set_use_global_pose", "use_global_pose"), &RetargetModifier3D::set_use_global_pose);
 	ClassDB::bind_method(D_METHOD("is_using_global_pose"), &RetargetModifier3D::is_using_global_pose);
+	ClassDB::bind_method(D_METHOD("set_enable_flags", "enable_flags"), &RetargetModifier3D::set_enable_flags);
+	ClassDB::bind_method(D_METHOD("get_enable_flags"), &RetargetModifier3D::get_enable_flags);
+
 	ClassDB::bind_method(D_METHOD("set_position_enabled", "enabled"), &RetargetModifier3D::set_position_enabled);
 	ClassDB::bind_method(D_METHOD("is_position_enabled"), &RetargetModifier3D::is_position_enabled);
 	ClassDB::bind_method(D_METHOD("set_rotation_enabled", "enabled"), &RetargetModifier3D::set_rotation_enabled);
@@ -256,9 +259,12 @@ void RetargetModifier3D::_bind_methods() {
 
 	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "profile", PROPERTY_HINT_RESOURCE_TYPE, "SkeletonProfile"), "set_profile", "get_profile");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_global_pose"), "set_use_global_pose", "is_using_global_pose");
-	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "position_enabled"), "set_position_enabled", "is_position_enabled");
-	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "rotation_enabled"), "set_rotation_enabled", "is_rotation_enabled");
-	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "scale_enabled"), "set_scale_enabled", "is_scale_enabled");
+	ADD_PROPERTY(PropertyInfo(Variant::INT, "enable", PROPERTY_HINT_FLAGS, "Position,Rotation,Scale"), "set_enable_flags", "get_enable_flags");
+
+	BIND_BITFIELD_FLAG(TRANSFORM_FLAG_POSITION);
+	BIND_BITFIELD_FLAG(TRANSFORM_FLAG_ROTATION);
+	BIND_BITFIELD_FLAG(TRANSFORM_FLAG_SCALE);
+	BIND_BITFIELD_FLAG(TRANSFORM_FLAG_ALL);
 }
 
 void RetargetModifier3D::_set_active(bool p_active) {
@@ -338,17 +344,15 @@ void RetargetModifier3D::_retarget_pose() {
 			extracted_transform.basis = E.humanoid_bone_rests[i].pre_basis * extracted_transform.basis * E.humanoid_bone_rests[i].post_basis;
 			extracted_transform.origin = E.humanoid_bone_rests[i].pre_basis.xform((extracted_transform.origin - source_skeleton->get_bone_rest(source_bone_id).origin) * motion_scale_ratio) + target_skeleton->get_bone_rest(target_bone_id).origin;
 
-			Transform3D retarget_pose = target_skeleton->get_bone_pose(target_bone_id);
-			if (enable_position) {
-				retarget_pose.origin = extracted_transform.origin;
+			if (enable_flags.has_flag(TRANSFORM_FLAG_POSITION)) {
+				target_skeleton->set_bone_pose_position(target_bone_id, extracted_transform.origin);
 			}
-			if (enable_rotation) {
-				retarget_pose.basis = extracted_transform.basis.get_rotation_quaternion();
+			if (enable_flags.has_flag(TRANSFORM_FLAG_ROTATION)) {
+				target_skeleton->set_bone_pose_rotation(target_bone_id, extracted_transform.basis.get_rotation_quaternion());
 			}
-			if (enable_scale) {
-				retarget_pose.basis.scale_local(extracted_transform.basis.get_scale());
+			if (enable_flags.has_flag(TRANSFORM_FLAG_SCALE)) {
+				target_skeleton->set_bone_pose_scale(target_bone_id, extracted_transform.basis.get_scale());
 			}
-			target_skeleton->set_bone_pose(target_bone_id, retarget_pose);
 		}
 	}
 }
@@ -387,37 +391,60 @@ bool RetargetModifier3D::is_using_global_pose() const {
 	return use_global_pose;
 }
 
+void RetargetModifier3D::set_enable_flags(BitField<TransformFlag> p_enable_flag) {
+	if (enable_flags != p_enable_flag) {
+		_reset_child_skeleton_poses();
+	}
+	enable_flags = p_enable_flag;
+}
+
+BitField<RetargetModifier3D::TransformFlag> RetargetModifier3D::get_enable_flags() const {
+	return enable_flags;
+}
+
 void RetargetModifier3D::set_position_enabled(bool p_enabled) {
-	if (enable_position != p_enabled) {
+	if (enable_flags.has_flag(TRANSFORM_FLAG_POSITION) != p_enabled) {
 		_reset_child_skeleton_poses();
 	}
-	enable_position = p_enabled;
+	if (p_enabled) {
+		enable_flags.set_flag(TRANSFORM_FLAG_POSITION);
+	} else {
+		enable_flags.clear_flag(TRANSFORM_FLAG_POSITION);
+	}
 }
 
 bool RetargetModifier3D::is_position_enabled() const {
-	return enable_position;
+	return enable_flags.has_flag(TRANSFORM_FLAG_POSITION);
 }
 
 void RetargetModifier3D::set_rotation_enabled(bool p_enabled) {
-	if (enable_rotation != p_enabled) {
+	if (enable_flags.has_flag(TRANSFORM_FLAG_ROTATION) != p_enabled) {
 		_reset_child_skeleton_poses();
 	}
-	enable_rotation = p_enabled;
+	if (p_enabled) {
+		enable_flags.set_flag(TRANSFORM_FLAG_ROTATION);
+	} else {
+		enable_flags.clear_flag(TRANSFORM_FLAG_ROTATION);
+	}
 }
 
 bool RetargetModifier3D::is_rotation_enabled() const {
-	return enable_rotation;
+	return enable_flags.has_flag(TRANSFORM_FLAG_ROTATION);
 }
 
 void RetargetModifier3D::set_scale_enabled(bool p_enabled) {
-	if (enable_scale != p_enabled) {
+	if (enable_flags.has_flag(TRANSFORM_FLAG_SCALE) != p_enabled) {
 		_reset_child_skeleton_poses();
 	}
-	enable_scale = p_enabled;
+	if (p_enabled) {
+		enable_flags.set_flag(TRANSFORM_FLAG_SCALE);
+	} else {
+		enable_flags.clear_flag(TRANSFORM_FLAG_SCALE);
+	}
 }
 
 bool RetargetModifier3D::is_scale_enabled() const {
-	return enable_scale;
+	return enable_flags.has_flag(TRANSFORM_FLAG_SCALE);
 }
 
 void RetargetModifier3D::_notification(int p_what) {

+ 15 - 3
scene/3d/retarget_modifier_3d.h

@@ -37,12 +37,19 @@
 class RetargetModifier3D : public SkeletonModifier3D {
 	GDCLASS(RetargetModifier3D, SkeletonModifier3D);
 
+public:
+	enum TransformFlag {
+		TRANSFORM_FLAG_POSITION = 1,
+		TRANSFORM_FLAG_ROTATION = 2,
+		TRANSFORM_FLAG_SCALE = 4,
+		TRANSFORM_FLAG_ALL = TRANSFORM_FLAG_POSITION | TRANSFORM_FLAG_ROTATION | TRANSFORM_FLAG_SCALE,
+	};
+
+private:
 	Ref<SkeletonProfile> profile;
 
 	bool use_global_pose = false;
-	bool enable_position = true;
-	bool enable_rotation = true;
-	bool enable_scale = true;
+	BitField<TransformFlag> enable_flags = TRANSFORM_FLAG_ALL;
 
 	struct RetargetBoneInfo {
 		int bone_id = -1;
@@ -93,6 +100,9 @@ public:
 
 	void set_use_global_pose(bool p_use_global_pose);
 	bool is_using_global_pose() const;
+	void set_enable_flags(BitField<TransformFlag> p_enable_flags);
+	BitField<TransformFlag> get_enable_flags() const;
+
 	void set_position_enabled(bool p_enabled);
 	bool is_position_enabled() const;
 	void set_rotation_enabled(bool p_enabled);
@@ -107,4 +117,6 @@ public:
 	virtual ~RetargetModifier3D();
 };
 
+VARIANT_BITFIELD_CAST(RetargetModifier3D::TransformFlag);
+
 #endif // RETARGET_MODIFIER_3D_H