Skip to content

Commit 76e974d

Browse files
committed
Merge pull request #110336 from TokageItLab/constraint-mod-node
Add option to `BoneConstraint3D` to make reference target allow to set `Node3D`
2 parents aa248bf + a57f961 commit 76e974d

11 files changed

+381
-138
lines changed

doc/classes/BoneConstraint3D.xml

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,21 @@
5252
This bone will be only referenced and not modified by this modifier.
5353
</description>
5454
</method>
55+
<method name="get_reference_node" qualifiers="const">
56+
<return type="NodePath" />
57+
<param index="0" name="index" type="int" />
58+
<description>
59+
Returns the reference node path of the setting at [param index].
60+
This node will be only referenced and not modified by this modifier.
61+
</description>
62+
</method>
63+
<method name="get_reference_type" qualifiers="const">
64+
<return type="int" enum="BoneConstraint3D.ReferenceType" />
65+
<param index="0" name="index" type="int" />
66+
<description>
67+
Returns the reference target type of the setting at [param index]. See also [enum ReferenceType].
68+
</description>
69+
</method>
5570
<method name="get_setting_count" qualifiers="const">
5671
<return type="int" />
5772
<description>
@@ -100,6 +115,23 @@
100115
This bone will be only referenced and not modified by this modifier.
101116
</description>
102117
</method>
118+
<method name="set_reference_node">
119+
<return type="void" />
120+
<param index="0" name="index" type="int" />
121+
<param index="1" name="node" type="NodePath" />
122+
<description>
123+
Sets the reference node path of the setting at [param index] to [param node].
124+
This node will be only referenced and not modified by this modifier.
125+
</description>
126+
</method>
127+
<method name="set_reference_type">
128+
<return type="void" />
129+
<param index="0" name="index" type="int" />
130+
<param index="1" name="type" type="int" enum="BoneConstraint3D.ReferenceType" />
131+
<description>
132+
Sets the reference target type of the setting at [param index] to [param type]. See also [enum ReferenceType].
133+
</description>
134+
</method>
103135
<method name="set_setting_count">
104136
<return type="void" />
105137
<param index="0" name="count" type="int" />
@@ -108,4 +140,13 @@
108140
</description>
109141
</method>
110142
</methods>
143+
<constants>
144+
<constant name="REFERENCE_TYPE_BONE" value="0" enum="ReferenceType">
145+
The reference target is a bone. In this case, the reference target spaces is local space.
146+
</constant>
147+
<constant name="REFERENCE_TYPE_NODE" value="1" enum="ReferenceType">
148+
The reference target is a [Node3D]. In this case, the reference target spaces is model space.
149+
In other words, the reference target's coordinates are treated as if it were placed directly under [Skeleton3D] which parent of the [BoneConstraint3D].
150+
</constant>
151+
</constants>
111152
</class>

doc/classes/ConvertTransformModifier3D.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
- Extract reference pose absolutely and add it to the apply bone's pose.
1515
[b]Not Relative + Not Additive:[/b]
1616
- Extract reference pose absolutely and the apply bone's pose is replaced with it.
17+
[b]Note:[/b] Relative option is available only in the case [method BoneConstraint3D.get_reference_type] is [constant BoneConstraint3D.REFERENCE_TYPE_BONE]. See also [enum BoneConstraint3D.ReferenceType].
1718
</description>
1819
<tutorials>
1920
</tutorials>

doc/classes/CopyTransformModifier3D.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
- Extract reference pose absolutely and add it to the apply bone's pose.
1515
[b]Not Relative + Not Additive:[/b]
1616
- Extract reference pose absolutely and the apply bone's pose is replaced with it.
17+
[b]Note:[/b] Relative option is available only in the case [method BoneConstraint3D.get_reference_type] is [constant BoneConstraint3D.REFERENCE_TYPE_BONE]. See also [enum BoneConstraint3D.ReferenceType].
1718
</description>
1819
<tutorials>
1920
</tutorials>

scene/3d/aim_modifier_3d.cpp

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ bool AimModifier3D::_set(const StringName &p_path, const Variant &p_value) {
3737
if (path.begins_with("settings/")) {
3838
int which = path.get_slicec('/', 1).to_int();
3939
String what = path.get_slicec('/', 2);
40-
ERR_FAIL_INDEX_V(which, settings.size(), false);
40+
ERR_FAIL_INDEX_V(which, (int)settings.size(), false);
4141

4242
if (what == "forward_axis") {
4343
set_forward_axis(which, static_cast<BoneAxis>((int)p_value));
@@ -60,7 +60,7 @@ bool AimModifier3D::_get(const StringName &p_path, Variant &r_ret) const {
6060
if (path.begins_with("settings/")) {
6161
int which = path.get_slicec('/', 1).to_int();
6262
String what = path.get_slicec('/', 2);
63-
ERR_FAIL_INDEX_V(which, settings.size(), false);
63+
ERR_FAIL_INDEX_V(which, (int)settings.size(), false);
6464

6565
if (what == "forward_axis") {
6666
r_ret = (int)get_forward_axis(which);
@@ -80,7 +80,7 @@ bool AimModifier3D::_get(const StringName &p_path, Variant &r_ret) const {
8080
void AimModifier3D::_get_property_list(List<PropertyInfo> *p_list) const {
8181
BoneConstraint3D::get_property_list(p_list);
8282

83-
for (int i = 0; i < settings.size(); i++) {
83+
for (uint32_t i = 0; i < settings.size(); i++) {
8484
String path = "settings/" + itos(i) + "/";
8585
int rotation_usage = is_using_euler(i) ? PROPERTY_USAGE_DEFAULT : PROPERTY_USAGE_NONE;
8686

@@ -93,7 +93,7 @@ void AimModifier3D::_get_property_list(List<PropertyInfo> *p_list) const {
9393

9494
PackedStringArray AimModifier3D::get_configuration_warnings() const {
9595
PackedStringArray warnings = BoneConstraint3D::get_configuration_warnings();
96-
for (int i = 0; i < settings.size(); i++) {
96+
for (uint32_t i = 0; i < settings.size(); i++) {
9797
if (is_using_euler(i) && get_axis_from_bone_axis(get_forward_axis(i)) == get_primary_rotation_axis(i)) {
9898
warnings.push_back(vformat(RTR("Forward axis and primary rotation axis must not be parallel in setting %s."), itos(i)));
9999
}
@@ -103,57 +103,57 @@ PackedStringArray AimModifier3D::get_configuration_warnings() const {
103103
}
104104

105105
void AimModifier3D::_validate_setting(int p_index) {
106-
settings.write[p_index] = memnew(AimModifier3DSetting);
106+
settings[p_index] = memnew(AimModifier3DSetting);
107107
}
108108

109109
void AimModifier3D::set_forward_axis(int p_index, BoneAxis p_axis) {
110-
ERR_FAIL_INDEX(p_index, settings.size());
110+
ERR_FAIL_INDEX(p_index, (int)settings.size());
111111
AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]);
112112
setting->forward_axis = p_axis;
113113
update_configuration_warnings();
114114
}
115115

116116
SkeletonModifier3D::BoneAxis AimModifier3D::get_forward_axis(int p_index) const {
117-
ERR_FAIL_INDEX_V(p_index, settings.size(), BONE_AXIS_PLUS_Y);
117+
ERR_FAIL_INDEX_V(p_index, (int)settings.size(), BONE_AXIS_PLUS_Y);
118118
AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]);
119119
return setting->forward_axis;
120120
}
121121

122122
void AimModifier3D::set_use_euler(int p_index, bool p_enabled) {
123-
ERR_FAIL_INDEX(p_index, settings.size());
123+
ERR_FAIL_INDEX(p_index, (int)settings.size());
124124
AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]);
125125
setting->use_euler = p_enabled;
126126
notify_property_list_changed();
127127
update_configuration_warnings();
128128
}
129129

130130
bool AimModifier3D::is_using_euler(int p_index) const {
131-
ERR_FAIL_INDEX_V(p_index, settings.size(), false);
131+
ERR_FAIL_INDEX_V(p_index, (int)settings.size(), false);
132132
AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]);
133133
return setting->use_euler;
134134
}
135135

136136
void AimModifier3D::set_primary_rotation_axis(int p_index, Vector3::Axis p_axis) {
137-
ERR_FAIL_INDEX(p_index, settings.size());
137+
ERR_FAIL_INDEX(p_index, (int)settings.size());
138138
AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]);
139139
setting->primary_rotation_axis = p_axis;
140140
update_configuration_warnings();
141141
}
142142

143143
Vector3::Axis AimModifier3D::get_primary_rotation_axis(int p_index) const {
144-
ERR_FAIL_INDEX_V(p_index, settings.size(), Vector3::AXIS_X);
144+
ERR_FAIL_INDEX_V(p_index, (int)settings.size(), Vector3::AXIS_X);
145145
AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]);
146146
return setting->primary_rotation_axis;
147147
}
148148

149149
void AimModifier3D::set_use_secondary_rotation(int p_index, bool p_enabled) {
150-
ERR_FAIL_INDEX(p_index, settings.size());
150+
ERR_FAIL_INDEX(p_index, (int)settings.size());
151151
AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]);
152152
setting->use_secondary_rotation = p_enabled;
153153
}
154154

155155
bool AimModifier3D::is_using_secondary_rotation(int p_index) const {
156-
ERR_FAIL_INDEX_V(p_index, settings.size(), false);
156+
ERR_FAIL_INDEX_V(p_index, (int)settings.size(), false);
157157
AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]);
158158
return setting->use_secondary_rotation;
159159
}
@@ -171,16 +171,28 @@ void AimModifier3D::_bind_methods() {
171171
ADD_ARRAY_COUNT("Settings", "setting_count", "set_setting_count", "get_setting_count", "settings/");
172172
}
173173

174-
void AimModifier3D::_process_constraint(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, int p_reference_bone, float p_amount) {
174+
void AimModifier3D::_process_constraint_by_bone(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, int p_reference_bone, float p_amount) {
175175
if (p_apply_bone == p_reference_bone) {
176176
ERR_PRINT_ONCE_ED(vformat("In setting %s, the reference bone must not be same with the apply bone.", itos(p_index)));
177177
return;
178178
}
179+
Vector3 reference_origin = p_skeleton->get_bone_global_pose(p_reference_bone).origin;
180+
_process_aim(p_index, p_skeleton, p_apply_bone, reference_origin, p_amount);
181+
}
179182

183+
void AimModifier3D::_process_constraint_by_node(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, const NodePath &p_reference_node, float p_amount) {
184+
Node3D *nd = Object::cast_to<Node3D>(get_node_or_null(p_reference_node));
185+
if (!nd) {
186+
return;
187+
}
188+
Vector3 reference_origin = nd->get_global_transform_interpolated().origin - p_skeleton->get_global_transform_interpolated().origin;
189+
_process_aim(p_index, p_skeleton, p_apply_bone, reference_origin, p_amount);
190+
}
191+
192+
void AimModifier3D::_process_aim(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, Vector3 p_target, float p_amount) {
180193
AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]);
181194

182195
// Prepare forward_vector and rest.
183-
Vector3 reference_origin = p_skeleton->get_bone_global_pose(p_reference_bone).origin;
184196
Transform3D src_bone_rest = p_skeleton->get_bone_rest(p_apply_bone);
185197
Transform3D bone_rest_space;
186198
int parent_bone = p_skeleton->get_bone_parent(p_apply_bone);
@@ -190,7 +202,7 @@ void AimModifier3D::_process_constraint(int p_index, Skeleton3D *p_skeleton, int
190202
bone_rest_space = p_skeleton->get_bone_global_pose(parent_bone);
191203
bone_rest_space.translate_local(src_bone_rest.origin);
192204
}
193-
Vector3 forward_vector = bone_rest_space.basis.get_rotation_quaternion().xform_inv(reference_origin - bone_rest_space.origin);
205+
Vector3 forward_vector = bone_rest_space.basis.get_rotation_quaternion().xform_inv(p_target - bone_rest_space.origin);
194206
if (forward_vector.is_zero_approx()) {
195207
return;
196208
}

scene/3d/aim_modifier_3d.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ class AimModifier3D : public BoneConstraint3D {
5151

5252
static void _bind_methods();
5353

54-
virtual void _process_constraint(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, int p_reference_bone, float p_amount) override;
54+
virtual void _process_constraint_by_bone(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, int p_reference_bone, float p_amount) override;
55+
virtual void _process_constraint_by_node(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, const NodePath &p_reference_node, float p_amount) override;
56+
virtual void _process_aim(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, Vector3 p_target, float p_amount);
5557
virtual void _validate_setting(int p_index) override;
5658

5759
public:

0 commit comments

Comments
 (0)