Pārlūkot izejas kodu

Add bone name/idx matching validation & virtual func to skel Modifier

Silc Lizard (Tokage) Renew 4 mēneši atpakaļ
vecāks
revīzija
17d068963f

+ 14 - 0
doc/classes/SkeletonModifier3D.xml

@@ -28,6 +28,20 @@
 				[param delta] is passed from parent [Skeleton3D]. See also [method Skeleton3D.advance].
 				[param delta] is passed from parent [Skeleton3D]. See also [method Skeleton3D.advance].
 			</description>
 			</description>
 		</method>
 		</method>
+		<method name="_skeleton_changed" qualifiers="virtual">
+			<return type="void" />
+			<param index="0" name="old_skeleton" type="Skeleton3D" />
+			<param index="1" name="new_skeleton" type="Skeleton3D" />
+			<description>
+				Called when the skeleton is changed.
+			</description>
+		</method>
+		<method name="_validate_bone_names" qualifiers="virtual">
+			<return type="void" />
+			<description>
+				Called when bone name and index need to be validated such as the timing of the entering tree or changing skeleton.
+			</description>
+		</method>
 		<method name="get_skeleton" qualifiers="const">
 		<method name="get_skeleton" qualifiers="const">
 			<return type="Skeleton3D" />
 			<return type="Skeleton3D" />
 			<description>
 			<description>

+ 15 - 1
scene/3d/look_at_modifier_3d.cpp

@@ -75,6 +75,20 @@ PackedStringArray LookAtModifier3D::get_configuration_warnings() const {
 	return warnings;
 	return warnings;
 }
 }
 
 
+void LookAtModifier3D::_validate_bone_names() {
+	// Prior bone name.
+	if (!bone_name.is_empty()) {
+		set_bone_name(bone_name);
+	} else if (bone != -1) {
+		set_bone(bone);
+	}
+	if (!origin_bone_name.is_empty()) {
+		set_origin_bone_name(origin_bone_name);
+	} else if (origin_bone != -1) {
+		set_origin_bone(origin_bone);
+	}
+}
+
 void LookAtModifier3D::set_bone_name(const String &p_bone_name) {
 void LookAtModifier3D::set_bone_name(const String &p_bone_name) {
 	bone_name = p_bone_name;
 	bone_name = p_bone_name;
 	Skeleton3D *sk = get_skeleton();
 	Skeleton3D *sk = get_skeleton();
@@ -529,7 +543,7 @@ void LookAtModifier3D::_process_modification(double p_delta) {
 		} else {
 		} else {
 			origin_tr = bone_rest_space;
 			origin_tr = bone_rest_space;
 		}
 		}
-		forward_vector = bone_rest_space.orthonormalized().basis.xform_inv((target->get_global_position() - origin_tr.translated_local(origin_offset).origin));
+		forward_vector = bone_rest_space.orthonormalized().basis.xform_inv(target->get_global_position() - origin_tr.translated_local(origin_offset).origin);
 		forward_vector_nrm = forward_vector.normalized();
 		forward_vector_nrm = forward_vector.normalized();
 		if (forward_vector_nrm.abs().is_equal_approx(get_vector_from_axis(primary_rotation_axis))) {
 		if (forward_vector_nrm.abs().is_equal_approx(get_vector_from_axis(primary_rotation_axis))) {
 			destination = skeleton->get_bone_pose_rotation(bone);
 			destination = skeleton->get_bone_pose_rotation(bone);

+ 2 - 0
scene/3d/look_at_modifier_3d.h

@@ -105,6 +105,8 @@ protected:
 	virtual PackedStringArray get_configuration_warnings() const override;
 	virtual PackedStringArray get_configuration_warnings() const override;
 	void _validate_property(PropertyInfo &p_property) const;
 	void _validate_property(PropertyInfo &p_property) const;
 
 
+	virtual void _validate_bone_names() override;
+
 	static void _bind_methods();
 	static void _bind_methods();
 
 
 	virtual void _process_modification(double p_delta) override;
 	virtual void _process_modification(double p_delta) override;

+ 11 - 1
scene/3d/skeleton_modifier_3d.cpp

@@ -68,11 +68,18 @@ void SkeletonModifier3D::_update_skeleton() {
 	if (old_sk != new_sk) {
 	if (old_sk != new_sk) {
 		_skeleton_changed(old_sk, new_sk);
 		_skeleton_changed(old_sk, new_sk);
 	}
 	}
+	if (new_sk) {
+		_validate_bone_names();
+	}
 	update_configuration_warnings();
 	update_configuration_warnings();
 }
 }
 
 
 void SkeletonModifier3D::_skeleton_changed(Skeleton3D *p_old, Skeleton3D *p_new) {
 void SkeletonModifier3D::_skeleton_changed(Skeleton3D *p_old, Skeleton3D *p_new) {
-	//
+	GDVIRTUAL_CALL(_skeleton_changed, p_old, p_new);
+}
+
+void SkeletonModifier3D::_validate_bone_names() {
+	GDVIRTUAL_CALL(_validate_bone_names);
 }
 }
 
 
 void SkeletonModifier3D::_force_update_skeleton_skin() {
 void SkeletonModifier3D::_force_update_skeleton_skin() {
@@ -163,6 +170,9 @@ void SkeletonModifier3D::_bind_methods() {
 	GDVIRTUAL_BIND(_process_modification);
 	GDVIRTUAL_BIND(_process_modification);
 #endif
 #endif
 
 
+	GDVIRTUAL_BIND(_skeleton_changed, "old_skeleton", "new_skeleton");
+	GDVIRTUAL_BIND(_validate_bone_names);
+
 	BIND_ENUM_CONSTANT(BONE_AXIS_PLUS_X);
 	BIND_ENUM_CONSTANT(BONE_AXIS_PLUS_X);
 	BIND_ENUM_CONSTANT(BONE_AXIS_MINUS_X);
 	BIND_ENUM_CONSTANT(BONE_AXIS_MINUS_X);
 	BIND_ENUM_CONSTANT(BONE_AXIS_PLUS_Y);
 	BIND_ENUM_CONSTANT(BONE_AXIS_PLUS_Y);

+ 3 - 0
scene/3d/skeleton_modifier_3d.h

@@ -61,6 +61,9 @@ protected:
 	void _force_update_skeleton_skin();
 	void _force_update_skeleton_skin();
 
 
 	virtual void _skeleton_changed(Skeleton3D *p_old, Skeleton3D *p_new);
 	virtual void _skeleton_changed(Skeleton3D *p_old, Skeleton3D *p_new);
+	virtual void _validate_bone_names();
+	GDVIRTUAL2(_skeleton_changed, Skeleton3D *, Skeleton3D *);
+	GDVIRTUAL0(_validate_bone_names);
 
 
 	void _validate_property(PropertyInfo &p_property) const;
 	void _validate_property(PropertyInfo &p_property) const;
 	void _notification(int p_what);
 	void _notification(int p_what);

+ 18 - 0
scene/3d/spring_bone_collision_3d.cpp

@@ -58,6 +58,15 @@ void SpringBoneCollision3D::_validate_property(PropertyInfo &p_property) const {
 	}
 	}
 }
 }
 
 
+void SpringBoneCollision3D::_validate_bone_name() {
+	// Prior bone name.
+	if (!bone_name.is_empty()) {
+		set_bone_name(bone_name);
+	} else if (bone != -1) {
+		set_bone(bone);
+	}
+}
+
 Skeleton3D *SpringBoneCollision3D::get_skeleton() const {
 Skeleton3D *SpringBoneCollision3D::get_skeleton() const {
 	SpringBoneSimulator3D *parent = Object::cast_to<SpringBoneSimulator3D>(get_parent());
 	SpringBoneSimulator3D *parent = Object::cast_to<SpringBoneSimulator3D>(get_parent());
 	if (!parent) {
 	if (!parent) {
@@ -173,6 +182,15 @@ void SpringBoneCollision3D::_bind_methods() {
 	ADD_PROPERTY(PropertyInfo(Variant::QUATERNION, "rotation_offset"), "set_rotation_offset", "get_rotation_offset");
 	ADD_PROPERTY(PropertyInfo(Variant::QUATERNION, "rotation_offset"), "set_rotation_offset", "get_rotation_offset");
 }
 }
 
 
+void SpringBoneCollision3D::_notification(int p_what) {
+	switch (p_what) {
+		case NOTIFICATION_ENTER_TREE:
+		case NOTIFICATION_PARENTED: {
+			_validate_bone_name();
+		} break;
+	}
+}
+
 Vector3 SpringBoneCollision3D::collide(const Transform3D &p_center, float p_bone_radius, float p_bone_length, const Vector3 &p_current) const {
 Vector3 SpringBoneCollision3D::collide(const Transform3D &p_center, float p_bone_radius, float p_bone_length, const Vector3 &p_current) const {
 	return _collide(p_center, p_bone_radius, p_bone_length, p_current);
 	return _collide(p_center, p_bone_radius, p_bone_length, p_current);
 }
 }

+ 3 - 0
scene/3d/spring_bone_collision_3d.h

@@ -41,10 +41,13 @@ class SpringBoneCollision3D : public Node3D {
 	Vector3 position_offset;
 	Vector3 position_offset;
 	Quaternion rotation_offset;
 	Quaternion rotation_offset;
 
 
+	void _validate_bone_name();
+
 protected:
 protected:
 	PackedStringArray get_configuration_warnings() const override;
 	PackedStringArray get_configuration_warnings() const override;
 
 
 	void _validate_property(PropertyInfo &p_property) const;
 	void _validate_property(PropertyInfo &p_property) const;
+	void _notification(int p_what);
 	static void _bind_methods();
 	static void _bind_methods();
 
 
 	virtual Vector3 _collide(const Transform3D &p_center, float p_bone_radius, float p_bone_length, const Vector3 &p_current) const;
 	virtual Vector3 _collide(const Transform3D &p_center, float p_bone_radius, float p_bone_length, const Vector3 &p_current) const;

+ 17 - 0
scene/3d/spring_bone_simulator_3d.cpp

@@ -1240,6 +1240,23 @@ void SpringBoneSimulator3D::_bind_methods() {
 	BIND_ENUM_CONSTANT(ROTATION_AXIS_ALL);
 	BIND_ENUM_CONSTANT(ROTATION_AXIS_ALL);
 }
 }
 
 
+void SpringBoneSimulator3D::_validate_bone_names() {
+	for (int i = 0; i < settings.size(); i++) {
+		// Prior bone name.
+		if (!settings[i]->root_bone_name.is_empty()) {
+			set_root_bone_name(i, settings[i]->root_bone_name);
+		} else if (settings[i]->root_bone != -1) {
+			set_root_bone(i, settings[i]->root_bone);
+		}
+		// Prior bone name.
+		if (!settings[i]->end_bone_name.is_empty()) {
+			set_end_bone_name(i, settings[i]->end_bone_name);
+		} else if (settings[i]->end_bone != -1) {
+			set_end_bone(i, settings[i]->end_bone);
+		}
+	}
+}
+
 void SpringBoneSimulator3D::_make_joints_dirty(int p_index) {
 void SpringBoneSimulator3D::_make_joints_dirty(int p_index) {
 	ERR_FAIL_INDEX(p_index, settings.size());
 	ERR_FAIL_INDEX(p_index, settings.size());
 	settings[p_index]->joints_dirty = true;
 	settings[p_index]->joints_dirty = true;

+ 2 - 0
scene/3d/spring_bone_simulator_3d.h

@@ -150,6 +150,8 @@ protected:
 
 
 	void _notification(int p_what);
 	void _notification(int p_what);
 
 
+	virtual void _validate_bone_names() override;
+
 	static void _bind_methods();
 	static void _bind_methods();
 
 
 	virtual void _set_active(bool p_active) override;
 	virtual void _set_active(bool p_active) override;