1
0
mirror of https://github.com/godotengine/godot.git synced 2025-12-02 16:48:55 +00:00

Add option to BoneConstraint3D to make reference target allow node

This commit is contained in:
Silc Lizard (Tokage) Renew
2025-09-08 09:35:49 +09:00
parent a6e7084b40
commit a57f96110a
11 changed files with 383 additions and 140 deletions

View File

@@ -52,6 +52,21 @@
This bone will be only referenced and not modified by this modifier. This bone will be only referenced and not modified by this modifier.
</description> </description>
</method> </method>
<method name="get_reference_node" qualifiers="const">
<return type="NodePath" />
<param index="0" name="index" type="int" />
<description>
Returns the reference node path of the setting at [param index].
This node will be only referenced and not modified by this modifier.
</description>
</method>
<method name="get_reference_type" qualifiers="const">
<return type="int" enum="BoneConstraint3D.ReferenceType" />
<param index="0" name="index" type="int" />
<description>
Returns the reference target type of the setting at [param index]. See also [enum ReferenceType].
</description>
</method>
<method name="get_setting_count" qualifiers="const"> <method name="get_setting_count" qualifiers="const">
<return type="int" /> <return type="int" />
<description> <description>
@@ -100,6 +115,23 @@
This bone will be only referenced and not modified by this modifier. This bone will be only referenced and not modified by this modifier.
</description> </description>
</method> </method>
<method name="set_reference_node">
<return type="void" />
<param index="0" name="index" type="int" />
<param index="1" name="node" type="NodePath" />
<description>
Sets the reference node path of the setting at [param index] to [param node].
This node will be only referenced and not modified by this modifier.
</description>
</method>
<method name="set_reference_type">
<return type="void" />
<param index="0" name="index" type="int" />
<param index="1" name="type" type="int" enum="BoneConstraint3D.ReferenceType" />
<description>
Sets the reference target type of the setting at [param index] to [param type]. See also [enum ReferenceType].
</description>
</method>
<method name="set_setting_count"> <method name="set_setting_count">
<return type="void" /> <return type="void" />
<param index="0" name="count" type="int" /> <param index="0" name="count" type="int" />
@@ -108,4 +140,13 @@
</description> </description>
</method> </method>
</methods> </methods>
<constants>
<constant name="REFERENCE_TYPE_BONE" value="0" enum="ReferenceType">
The reference target is a bone. In this case, the reference target spaces is local space.
</constant>
<constant name="REFERENCE_TYPE_NODE" value="1" enum="ReferenceType">
The reference target is a [Node3D]. In this case, the reference target spaces is model space.
In other words, the reference target's coordinates are treated as if it were placed directly under [Skeleton3D] which parent of the [BoneConstraint3D].
</constant>
</constants>
</class> </class>

View File

@@ -14,6 +14,7 @@
- Extract reference pose absolutely and add it to the apply bone's pose. - Extract reference pose absolutely and add it to the apply bone's pose.
[b]Not Relative + Not Additive:[/b] [b]Not Relative + Not Additive:[/b]
- Extract reference pose absolutely and the apply bone's pose is replaced with it. - Extract reference pose absolutely and the apply bone's pose is replaced with it.
[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].
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>

View File

@@ -14,6 +14,7 @@
- Extract reference pose absolutely and add it to the apply bone's pose. - Extract reference pose absolutely and add it to the apply bone's pose.
[b]Not Relative + Not Additive:[/b] [b]Not Relative + Not Additive:[/b]
- Extract reference pose absolutely and the apply bone's pose is replaced with it. - Extract reference pose absolutely and the apply bone's pose is replaced with it.
[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].
</description> </description>
<tutorials> <tutorials>
</tutorials> </tutorials>

View File

@@ -37,7 +37,7 @@ bool AimModifier3D::_set(const StringName &p_path, const Variant &p_value) {
if (path.begins_with("settings/")) { if (path.begins_with("settings/")) {
int which = path.get_slicec('/', 1).to_int(); int which = path.get_slicec('/', 1).to_int();
String what = path.get_slicec('/', 2); String what = path.get_slicec('/', 2);
ERR_FAIL_INDEX_V(which, settings.size(), false); ERR_FAIL_INDEX_V(which, (int)settings.size(), false);
if (what == "forward_axis") { if (what == "forward_axis") {
set_forward_axis(which, static_cast<BoneAxis>((int)p_value)); 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 {
if (path.begins_with("settings/")) { if (path.begins_with("settings/")) {
int which = path.get_slicec('/', 1).to_int(); int which = path.get_slicec('/', 1).to_int();
String what = path.get_slicec('/', 2); String what = path.get_slicec('/', 2);
ERR_FAIL_INDEX_V(which, settings.size(), false); ERR_FAIL_INDEX_V(which, (int)settings.size(), false);
if (what == "forward_axis") { if (what == "forward_axis") {
r_ret = (int)get_forward_axis(which); r_ret = (int)get_forward_axis(which);
@@ -80,7 +80,7 @@ bool AimModifier3D::_get(const StringName &p_path, Variant &r_ret) const {
void AimModifier3D::_get_property_list(List<PropertyInfo> *p_list) const { void AimModifier3D::_get_property_list(List<PropertyInfo> *p_list) const {
BoneConstraint3D::get_property_list(p_list); BoneConstraint3D::get_property_list(p_list);
for (int i = 0; i < settings.size(); i++) { for (uint32_t i = 0; i < settings.size(); i++) {
String path = "settings/" + itos(i) + "/"; String path = "settings/" + itos(i) + "/";
int rotation_usage = is_using_euler(i) ? PROPERTY_USAGE_DEFAULT : PROPERTY_USAGE_NONE; int rotation_usage = is_using_euler(i) ? PROPERTY_USAGE_DEFAULT : PROPERTY_USAGE_NONE;
@@ -93,7 +93,7 @@ void AimModifier3D::_get_property_list(List<PropertyInfo> *p_list) const {
PackedStringArray AimModifier3D::get_configuration_warnings() const { PackedStringArray AimModifier3D::get_configuration_warnings() const {
PackedStringArray warnings = BoneConstraint3D::get_configuration_warnings(); PackedStringArray warnings = BoneConstraint3D::get_configuration_warnings();
for (int i = 0; i < settings.size(); i++) { for (uint32_t i = 0; i < settings.size(); i++) {
if (is_using_euler(i) && get_axis_from_bone_axis(get_forward_axis(i)) == get_primary_rotation_axis(i)) { if (is_using_euler(i) && get_axis_from_bone_axis(get_forward_axis(i)) == get_primary_rotation_axis(i)) {
warnings.push_back(vformat(RTR("Forward axis and primary rotation axis must not be parallel in setting %s."), itos(i))); warnings.push_back(vformat(RTR("Forward axis and primary rotation axis must not be parallel in setting %s."), itos(i)));
} }
@@ -103,24 +103,24 @@ PackedStringArray AimModifier3D::get_configuration_warnings() const {
} }
void AimModifier3D::_validate_setting(int p_index) { void AimModifier3D::_validate_setting(int p_index) {
settings.write[p_index] = memnew(AimModifier3DSetting); settings[p_index] = memnew(AimModifier3DSetting);
} }
void AimModifier3D::set_forward_axis(int p_index, BoneAxis p_axis) { void AimModifier3D::set_forward_axis(int p_index, BoneAxis p_axis) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]); AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]);
setting->forward_axis = p_axis; setting->forward_axis = p_axis;
update_configuration_warnings(); update_configuration_warnings();
} }
SkeletonModifier3D::BoneAxis AimModifier3D::get_forward_axis(int p_index) const { SkeletonModifier3D::BoneAxis AimModifier3D::get_forward_axis(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), BONE_AXIS_PLUS_Y); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), BONE_AXIS_PLUS_Y);
AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]); AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]);
return setting->forward_axis; return setting->forward_axis;
} }
void AimModifier3D::set_use_euler(int p_index, bool p_enabled) { void AimModifier3D::set_use_euler(int p_index, bool p_enabled) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]); AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]);
setting->use_euler = p_enabled; setting->use_euler = p_enabled;
notify_property_list_changed(); notify_property_list_changed();
@@ -128,32 +128,32 @@ void AimModifier3D::set_use_euler(int p_index, bool p_enabled) {
} }
bool AimModifier3D::is_using_euler(int p_index) const { bool AimModifier3D::is_using_euler(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), false); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), false);
AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]); AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]);
return setting->use_euler; return setting->use_euler;
} }
void AimModifier3D::set_primary_rotation_axis(int p_index, Vector3::Axis p_axis) { void AimModifier3D::set_primary_rotation_axis(int p_index, Vector3::Axis p_axis) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]); AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]);
setting->primary_rotation_axis = p_axis; setting->primary_rotation_axis = p_axis;
update_configuration_warnings(); update_configuration_warnings();
} }
Vector3::Axis AimModifier3D::get_primary_rotation_axis(int p_index) const { Vector3::Axis AimModifier3D::get_primary_rotation_axis(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), Vector3::AXIS_X); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), Vector3::AXIS_X);
AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]); AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]);
return setting->primary_rotation_axis; return setting->primary_rotation_axis;
} }
void AimModifier3D::set_use_secondary_rotation(int p_index, bool p_enabled) { void AimModifier3D::set_use_secondary_rotation(int p_index, bool p_enabled) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]); AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]);
setting->use_secondary_rotation = p_enabled; setting->use_secondary_rotation = p_enabled;
} }
bool AimModifier3D::is_using_secondary_rotation(int p_index) const { bool AimModifier3D::is_using_secondary_rotation(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), false); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), false);
AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]); AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]);
return setting->use_secondary_rotation; return setting->use_secondary_rotation;
} }
@@ -171,16 +171,28 @@ void AimModifier3D::_bind_methods() {
ADD_ARRAY_COUNT("Settings", "setting_count", "set_setting_count", "get_setting_count", "settings/"); ADD_ARRAY_COUNT("Settings", "setting_count", "set_setting_count", "get_setting_count", "settings/");
} }
void AimModifier3D::_process_constraint(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, int p_reference_bone, float p_amount) { void AimModifier3D::_process_constraint_by_bone(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, int p_reference_bone, float p_amount) {
if (p_apply_bone == p_reference_bone) { if (p_apply_bone == p_reference_bone) {
ERR_PRINT_ONCE_ED(vformat("In setting %s, the reference bone must not be same with the apply bone.", itos(p_index))); ERR_PRINT_ONCE_ED(vformat("In setting %s, the reference bone must not be same with the apply bone.", itos(p_index)));
return; return;
} }
Vector3 reference_origin = p_skeleton->get_bone_global_pose(p_reference_bone).origin;
_process_aim(p_index, p_skeleton, p_apply_bone, reference_origin, p_amount);
}
void AimModifier3D::_process_constraint_by_node(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, const NodePath &p_reference_node, float p_amount) {
Node3D *nd = Object::cast_to<Node3D>(get_node_or_null(p_reference_node));
if (!nd) {
return;
}
Vector3 reference_origin = nd->get_global_transform_interpolated().origin - p_skeleton->get_global_transform_interpolated().origin;
_process_aim(p_index, p_skeleton, p_apply_bone, reference_origin, p_amount);
}
void AimModifier3D::_process_aim(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, Vector3 p_target, float p_amount) {
AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]); AimModifier3DSetting *setting = static_cast<AimModifier3DSetting *>(settings[p_index]);
// Prepare forward_vector and rest. // Prepare forward_vector and rest.
Vector3 reference_origin = p_skeleton->get_bone_global_pose(p_reference_bone).origin;
Transform3D src_bone_rest = p_skeleton->get_bone_rest(p_apply_bone); Transform3D src_bone_rest = p_skeleton->get_bone_rest(p_apply_bone);
Transform3D bone_rest_space; Transform3D bone_rest_space;
int parent_bone = p_skeleton->get_bone_parent(p_apply_bone); 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
bone_rest_space = p_skeleton->get_bone_global_pose(parent_bone); bone_rest_space = p_skeleton->get_bone_global_pose(parent_bone);
bone_rest_space.translate_local(src_bone_rest.origin); bone_rest_space.translate_local(src_bone_rest.origin);
} }
Vector3 forward_vector = bone_rest_space.basis.get_rotation_quaternion().xform_inv(reference_origin - bone_rest_space.origin); Vector3 forward_vector = bone_rest_space.basis.get_rotation_quaternion().xform_inv(p_target - bone_rest_space.origin);
if (forward_vector.is_zero_approx()) { if (forward_vector.is_zero_approx()) {
return; return;
} }

View File

@@ -51,7 +51,9 @@ protected:
static void _bind_methods(); static void _bind_methods();
virtual void _process_constraint(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, int p_reference_bone, float p_amount) override; virtual void _process_constraint_by_bone(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, int p_reference_bone, float p_amount) override;
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;
virtual void _process_aim(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, Vector3 p_target, float p_amount);
virtual void _validate_setting(int p_index) override; virtual void _validate_setting(int p_index) override;
public: public:

View File

@@ -36,10 +36,12 @@ bool BoneConstraint3D::_set(const StringName &p_path, const Variant &p_value) {
if (path.begins_with("settings/")) { if (path.begins_with("settings/")) {
int which = path.get_slicec('/', 1).to_int(); int which = path.get_slicec('/', 1).to_int();
String what = path.get_slicec('/', 2); String what = path.get_slicec('/', 2);
ERR_FAIL_INDEX_V(which, settings.size(), false); ERR_FAIL_INDEX_V(which, (int)settings.size(), false);
if (what == "amount") { if (what == "amount") {
set_amount(which, p_value); set_amount(which, p_value);
} else if (what == "reference_type") {
set_reference_type(which, static_cast<ReferenceType>((int)p_value));
} else if (what == "apply_bone_name") { } else if (what == "apply_bone_name") {
set_apply_bone_name(which, p_value); set_apply_bone_name(which, p_value);
} else if (what == "reference_bone_name") { } else if (what == "reference_bone_name") {
@@ -48,6 +50,8 @@ bool BoneConstraint3D::_set(const StringName &p_path, const Variant &p_value) {
set_apply_bone(which, p_value); set_apply_bone(which, p_value);
} else if (what == "reference_bone") { } else if (what == "reference_bone") {
set_reference_bone(which, p_value); set_reference_bone(which, p_value);
} else if (what == "reference_node") {
set_reference_node(which, p_value);
} else { } else {
return false; return false;
} }
@@ -61,10 +65,12 @@ bool BoneConstraint3D::_get(const StringName &p_path, Variant &r_ret) const {
if (path.begins_with("settings/")) { if (path.begins_with("settings/")) {
int which = path.get_slicec('/', 1).to_int(); int which = path.get_slicec('/', 1).to_int();
String what = path.get_slicec('/', 2); String what = path.get_slicec('/', 2);
ERR_FAIL_INDEX_V(which, settings.size(), false); ERR_FAIL_INDEX_V(which, (int)settings.size(), false);
if (what == "amount") { if (what == "amount") {
r_ret = get_amount(which); r_ret = get_amount(which);
} else if (what == "reference_type") {
r_ret = (int)get_reference_type(which);
} else if (what == "apply_bone_name") { } else if (what == "apply_bone_name") {
r_ret = get_apply_bone_name(which); r_ret = get_apply_bone_name(which);
} else if (what == "reference_bone_name") { } else if (what == "reference_bone_name") {
@@ -73,6 +79,8 @@ bool BoneConstraint3D::_get(const StringName &p_path, Variant &r_ret) const {
r_ret = get_apply_bone(which); r_ret = get_apply_bone(which);
} else if (what == "reference_bone") { } else if (what == "reference_bone") {
r_ret = get_reference_bone(which); r_ret = get_reference_bone(which);
} else if (what == "reference_node") {
r_ret = get_reference_node(which);
} else { } else {
return false; return false;
} }
@@ -87,23 +95,46 @@ void BoneConstraint3D::get_property_list(List<PropertyInfo> *p_list) const {
enum_hint = skeleton->get_concatenated_bone_names(); enum_hint = skeleton->get_concatenated_bone_names();
} }
for (int i = 0; i < settings.size(); i++) { LocalVector<PropertyInfo> props;
for (uint32_t i = 0; i < settings.size(); i++) {
String path = "settings/" + itos(i) + "/"; String path = "settings/" + itos(i) + "/";
p_list->push_back(PropertyInfo(Variant::FLOAT, path + "amount", PROPERTY_HINT_RANGE, "0,1,0.001")); props.push_back(PropertyInfo(Variant::FLOAT, path + "amount", PROPERTY_HINT_RANGE, "0,1,0.001"));
p_list->push_back(PropertyInfo(Variant::STRING, path + "apply_bone_name", PROPERTY_HINT_ENUM_SUGGESTION, enum_hint)); props.push_back(PropertyInfo(Variant::STRING, path + "apply_bone_name", PROPERTY_HINT_ENUM_SUGGESTION, enum_hint));
p_list->push_back(PropertyInfo(Variant::INT, path + "apply_bone", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); props.push_back(PropertyInfo(Variant::INT, path + "apply_bone", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
p_list->push_back(PropertyInfo(Variant::STRING, path + "reference_bone_name", PROPERTY_HINT_ENUM_SUGGESTION, enum_hint)); props.push_back(PropertyInfo(Variant::INT, path + "reference_type", PROPERTY_HINT_ENUM, "Bone,Node"));
p_list->push_back(PropertyInfo(Variant::INT, path + "reference_bone", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR)); props.push_back(PropertyInfo(Variant::STRING, path + "reference_bone_name", PROPERTY_HINT_ENUM_SUGGESTION, enum_hint));
props.push_back(PropertyInfo(Variant::INT, path + "reference_bone", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
props.push_back(PropertyInfo(Variant::NODE_PATH, path + "reference_node", PROPERTY_HINT_NODE_PATH_VALID_TYPES, "Node3D"));
}
for (PropertyInfo &p : props) {
_validate_dynamic_prop(p);
p_list->push_back(p);
}
}
void BoneConstraint3D::_validate_dynamic_prop(PropertyInfo &p_property) const {
PackedStringArray split = p_property.name.split("/");
if (split.size() > 2 && split[0] == "settings") {
int which = split[1].to_int();
if (split[2].begins_with("reference_bone") && get_reference_type(which) != REFERENCE_TYPE_BONE) {
p_property.usage = PROPERTY_USAGE_NONE;
}
if (split[2].begins_with("reference_node") && get_reference_type(which) != REFERENCE_TYPE_NODE) {
p_property.usage = PROPERTY_USAGE_NONE;
}
} }
} }
void BoneConstraint3D::set_setting_count(int p_count) { void BoneConstraint3D::set_setting_count(int p_count) {
ERR_FAIL_COND(p_count < 0); ERR_FAIL_COND(p_count < 0);
int delta = p_count - settings.size(); int delta = p_count - (int)settings.size();
if (delta < 0) { if (delta < 0) {
for (int i = delta; i < 0; i++) { for (int i = delta; i < 0; i++) {
memdelete(settings[settings.size() + i]); memdelete(settings[(int)settings.size() + i]);
settings[(int)settings.size() + i] = nullptr;
} }
} }
settings.resize(p_count); settings.resize(p_count);
@@ -119,11 +150,11 @@ void BoneConstraint3D::set_setting_count(int p_count) {
} }
int BoneConstraint3D::get_setting_count() const { int BoneConstraint3D::get_setting_count() const {
return settings.size(); return (int)settings.size();
} }
void BoneConstraint3D::_validate_setting(int p_index) { void BoneConstraint3D::_validate_setting(int p_index) {
settings.write[p_index] = memnew(BoneConstraint3DSetting); settings[p_index] = memnew(BoneConstraint3DSetting);
} }
void BoneConstraint3D::clear_settings() { void BoneConstraint3D::clear_settings() {
@@ -131,17 +162,17 @@ void BoneConstraint3D::clear_settings() {
} }
void BoneConstraint3D::set_amount(int p_index, float p_amount) { void BoneConstraint3D::set_amount(int p_index, float p_amount) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
settings[p_index]->amount = p_amount; settings[p_index]->amount = p_amount;
} }
float BoneConstraint3D::get_amount(int p_index) const { float BoneConstraint3D::get_amount(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), 0.0); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), 0.0);
return settings[p_index]->amount; return settings[p_index]->amount;
} }
void BoneConstraint3D::set_apply_bone_name(int p_index, const String &p_bone_name) { void BoneConstraint3D::set_apply_bone_name(int p_index, const String &p_bone_name) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
settings[p_index]->apply_bone_name = p_bone_name; settings[p_index]->apply_bone_name = p_bone_name;
Skeleton3D *sk = get_skeleton(); Skeleton3D *sk = get_skeleton();
if (sk) { if (sk) {
@@ -150,12 +181,12 @@ void BoneConstraint3D::set_apply_bone_name(int p_index, const String &p_bone_nam
} }
String BoneConstraint3D::get_apply_bone_name(int p_index) const { String BoneConstraint3D::get_apply_bone_name(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), String()); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), String());
return settings[p_index]->apply_bone_name; return settings[p_index]->apply_bone_name;
} }
void BoneConstraint3D::set_apply_bone(int p_index, int p_bone) { void BoneConstraint3D::set_apply_bone(int p_index, int p_bone) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
settings[p_index]->apply_bone = p_bone; settings[p_index]->apply_bone = p_bone;
Skeleton3D *sk = get_skeleton(); Skeleton3D *sk = get_skeleton();
if (sk) { if (sk) {
@@ -169,12 +200,23 @@ void BoneConstraint3D::set_apply_bone(int p_index, int p_bone) {
} }
int BoneConstraint3D::get_apply_bone(int p_index) const { int BoneConstraint3D::get_apply_bone(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), -1); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), -1);
return settings[p_index]->apply_bone; return settings[p_index]->apply_bone;
} }
void BoneConstraint3D::set_reference_type(int p_index, ReferenceType p_type) {
ERR_FAIL_INDEX(p_index, (int)settings.size());
settings[p_index]->reference_type = p_type;
notify_property_list_changed();
}
BoneConstraint3D::ReferenceType BoneConstraint3D::get_reference_type(int p_index) const {
ERR_FAIL_INDEX_V(p_index, (int)settings.size(), REFERENCE_TYPE_BONE);
return settings[p_index]->reference_type;
}
void BoneConstraint3D::set_reference_bone_name(int p_index, const String &p_bone_name) { void BoneConstraint3D::set_reference_bone_name(int p_index, const String &p_bone_name) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
settings[p_index]->reference_bone_name = p_bone_name; settings[p_index]->reference_bone_name = p_bone_name;
Skeleton3D *sk = get_skeleton(); Skeleton3D *sk = get_skeleton();
if (sk) { if (sk) {
@@ -183,12 +225,12 @@ void BoneConstraint3D::set_reference_bone_name(int p_index, const String &p_bone
} }
String BoneConstraint3D::get_reference_bone_name(int p_index) const { String BoneConstraint3D::get_reference_bone_name(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), String()); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), String());
return settings[p_index]->reference_bone_name; return settings[p_index]->reference_bone_name;
} }
void BoneConstraint3D::set_reference_bone(int p_index, int p_bone) { void BoneConstraint3D::set_reference_bone(int p_index, int p_bone) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
settings[p_index]->reference_bone = p_bone; settings[p_index]->reference_bone = p_bone;
Skeleton3D *sk = get_skeleton(); Skeleton3D *sk = get_skeleton();
if (sk) { if (sk) {
@@ -202,10 +244,20 @@ void BoneConstraint3D::set_reference_bone(int p_index, int p_bone) {
} }
int BoneConstraint3D::get_reference_bone(int p_index) const { int BoneConstraint3D::get_reference_bone(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), -1); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), -1);
return settings[p_index]->reference_bone; return settings[p_index]->reference_bone;
} }
void BoneConstraint3D::set_reference_node(int p_index, const NodePath &p_node) {
ERR_FAIL_INDEX(p_index, (int)settings.size());
settings[p_index]->reference_node = p_node;
}
NodePath BoneConstraint3D::get_reference_node(int p_index) const {
ERR_FAIL_INDEX_V(p_index, (int)settings.size(), NodePath());
return settings[p_index]->reference_node;
}
void BoneConstraint3D::_bind_methods() { void BoneConstraint3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_amount", "index", "amount"), &BoneConstraint3D::set_amount); ClassDB::bind_method(D_METHOD("set_amount", "index", "amount"), &BoneConstraint3D::set_amount);
ClassDB::bind_method(D_METHOD("get_amount", "index"), &BoneConstraint3D::get_amount); ClassDB::bind_method(D_METHOD("get_amount", "index"), &BoneConstraint3D::get_amount);
@@ -213,18 +265,25 @@ void BoneConstraint3D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_apply_bone_name", "index"), &BoneConstraint3D::get_apply_bone_name); ClassDB::bind_method(D_METHOD("get_apply_bone_name", "index"), &BoneConstraint3D::get_apply_bone_name);
ClassDB::bind_method(D_METHOD("set_apply_bone", "index", "bone"), &BoneConstraint3D::set_apply_bone); ClassDB::bind_method(D_METHOD("set_apply_bone", "index", "bone"), &BoneConstraint3D::set_apply_bone);
ClassDB::bind_method(D_METHOD("get_apply_bone", "index"), &BoneConstraint3D::get_apply_bone); ClassDB::bind_method(D_METHOD("get_apply_bone", "index"), &BoneConstraint3D::get_apply_bone);
ClassDB::bind_method(D_METHOD("set_reference_type", "index", "type"), &BoneConstraint3D::set_reference_type);
ClassDB::bind_method(D_METHOD("get_reference_type", "index"), &BoneConstraint3D::get_reference_type);
ClassDB::bind_method(D_METHOD("set_reference_bone_name", "index", "bone_name"), &BoneConstraint3D::set_reference_bone_name); ClassDB::bind_method(D_METHOD("set_reference_bone_name", "index", "bone_name"), &BoneConstraint3D::set_reference_bone_name);
ClassDB::bind_method(D_METHOD("get_reference_bone_name", "index"), &BoneConstraint3D::get_reference_bone_name); ClassDB::bind_method(D_METHOD("get_reference_bone_name", "index"), &BoneConstraint3D::get_reference_bone_name);
ClassDB::bind_method(D_METHOD("set_reference_bone", "index", "bone"), &BoneConstraint3D::set_reference_bone); ClassDB::bind_method(D_METHOD("set_reference_bone", "index", "bone"), &BoneConstraint3D::set_reference_bone);
ClassDB::bind_method(D_METHOD("get_reference_bone", "index"), &BoneConstraint3D::get_reference_bone); ClassDB::bind_method(D_METHOD("get_reference_bone", "index"), &BoneConstraint3D::get_reference_bone);
ClassDB::bind_method(D_METHOD("set_reference_node", "index", "node"), &BoneConstraint3D::set_reference_node);
ClassDB::bind_method(D_METHOD("get_reference_node", "index"), &BoneConstraint3D::get_reference_node);
ClassDB::bind_method(D_METHOD("set_setting_count", "count"), &BoneConstraint3D::set_setting_count); ClassDB::bind_method(D_METHOD("set_setting_count", "count"), &BoneConstraint3D::set_setting_count);
ClassDB::bind_method(D_METHOD("get_setting_count"), &BoneConstraint3D::get_setting_count); ClassDB::bind_method(D_METHOD("get_setting_count"), &BoneConstraint3D::get_setting_count);
ClassDB::bind_method(D_METHOD("clear_setting"), &BoneConstraint3D::clear_settings); ClassDB::bind_method(D_METHOD("clear_setting"), &BoneConstraint3D::clear_settings);
BIND_ENUM_CONSTANT(REFERENCE_TYPE_BONE);
BIND_ENUM_CONSTANT(REFERENCE_TYPE_NODE);
} }
void BoneConstraint3D::_validate_bone_names() { void BoneConstraint3D::_validate_bone_names() {
for (int i = 0; i < settings.size(); i++) { for (int i = 0; i < (int)settings.size(); i++) {
// Prior bone name. // Prior bone name.
if (!settings[i]->apply_bone_name.is_empty()) { if (!settings[i]->apply_bone_name.is_empty()) {
set_apply_bone_name(i, settings[i]->apply_bone_name); set_apply_bone_name(i, settings[i]->apply_bone_name);
@@ -246,27 +305,38 @@ void BoneConstraint3D::_process_modification(double p_delta) {
return; return;
} }
for (int i = 0; i < settings.size(); i++) { for (int i = 0; i < (int)settings.size(); i++) {
int apply_bone = settings[i]->apply_bone;
if (apply_bone < 0) {
continue;
}
int reference_bone = settings[i]->reference_bone;
if (reference_bone < 0) {
continue;
}
float amount = settings[i]->amount; float amount = settings[i]->amount;
if (amount <= 0) { if (amount <= 0) {
continue; continue;
} }
_process_constraint(i, skeleton, apply_bone, reference_bone, amount); int apply_bone = settings[i]->apply_bone;
if (apply_bone < 0) {
continue;
}
if (settings[i]->reference_type == REFERENCE_TYPE_BONE) {
int reference_bone = settings[i]->reference_bone;
if (reference_bone < 0) {
continue;
}
_process_constraint_by_bone(i, skeleton, apply_bone, reference_bone, amount);
} else {
NodePath pt = settings[i]->reference_node;
if (pt.is_empty()) {
continue;
}
_process_constraint_by_node(i, skeleton, apply_bone, pt, amount);
}
} }
} }
void BoneConstraint3D::_process_constraint(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, int p_reference_bone, float p_amount) { void BoneConstraint3D::_process_constraint_by_bone(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, int p_reference_bone, float p_amount) {
//
}
void BoneConstraint3D::_process_constraint_by_node(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, const NodePath &p_reference_node, float p_amount) {
// //
} }

View File

@@ -36,18 +36,27 @@ class BoneConstraint3D : public SkeletonModifier3D {
GDCLASS(BoneConstraint3D, SkeletonModifier3D); GDCLASS(BoneConstraint3D, SkeletonModifier3D);
public: public:
enum ReferenceType {
REFERENCE_TYPE_BONE,
REFERENCE_TYPE_NODE,
};
struct BoneConstraint3DSetting { struct BoneConstraint3DSetting {
float amount = 1.0; float amount = 1.0;
String apply_bone_name; String apply_bone_name;
int apply_bone = -1; int apply_bone = -1;
ReferenceType reference_type = REFERENCE_TYPE_BONE;
String reference_bone_name; String reference_bone_name;
int reference_bone = -1; int reference_bone = -1;
NodePath reference_node;
}; };
protected: protected:
Vector<BoneConstraint3DSetting *> settings; LocalVector<BoneConstraint3DSetting *> settings;
bool _get(const StringName &p_path, Variant &r_ret) const; bool _get(const StringName &p_path, Variant &r_ret) const;
bool _set(const StringName &p_path, const Variant &p_value); bool _set(const StringName &p_path, const Variant &p_value);
@@ -55,13 +64,15 @@ protected:
// Define get_property_list() instead of _get_property_list() // Define get_property_list() instead of _get_property_list()
// to merge child class properties into parent class array inspector. // to merge child class properties into parent class array inspector.
void get_property_list(List<PropertyInfo> *p_list) const; // Will be called by child classes. void get_property_list(List<PropertyInfo> *p_list) const; // Will be called by child classes.
void _validate_dynamic_prop(PropertyInfo &p_property) const;
virtual void _validate_bone_names() override; 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;
virtual void _process_constraint(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, int p_reference_bone, float p_amount); virtual void _process_constraint_by_bone(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, int p_reference_bone, float p_amount);
virtual void _process_constraint_by_node(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, const NodePath &p_reference_node, float p_amount);
virtual void _validate_setting(int p_index); virtual void _validate_setting(int p_index);
public: public:
@@ -73,11 +84,17 @@ public:
void set_apply_bone(int p_index, int p_bone); void set_apply_bone(int p_index, int p_bone);
int get_apply_bone(int p_index) const; int get_apply_bone(int p_index) const;
void set_reference_type(int p_index, ReferenceType p_type);
ReferenceType get_reference_type(int p_index) const;
void set_reference_bone_name(int p_index, const String &p_bone_name); void set_reference_bone_name(int p_index, const String &p_bone_name);
String get_reference_bone_name(int p_index) const; String get_reference_bone_name(int p_index) const;
void set_reference_bone(int p_index, int p_bone); void set_reference_bone(int p_index, int p_bone);
int get_reference_bone(int p_index) const; int get_reference_bone(int p_index) const;
void set_reference_node(int p_index, const NodePath &p_node);
NodePath get_reference_node(int p_index) const;
void set_setting_count(int p_count); void set_setting_count(int p_count);
int get_setting_count() const; int get_setting_count() const;
@@ -85,3 +102,5 @@ public:
~BoneConstraint3D(); ~BoneConstraint3D();
}; };
VARIANT_ENUM_CAST(BoneConstraint3D::ReferenceType);

View File

@@ -40,7 +40,7 @@ bool ConvertTransformModifier3D::_set(const StringName &p_path, const Variant &p
if (path.begins_with("settings/")) { if (path.begins_with("settings/")) {
int which = path.get_slicec('/', 1).to_int(); int which = path.get_slicec('/', 1).to_int();
String where = path.get_slicec('/', 2); String where = path.get_slicec('/', 2);
ERR_FAIL_INDEX_V(which, settings.size(), false); ERR_FAIL_INDEX_V(which, (int)settings.size(), false);
String what = path.get_slicec('/', 3); String what = path.get_slicec('/', 3);
if (where == "apply") { if (where == "apply") {
@@ -84,7 +84,7 @@ bool ConvertTransformModifier3D::_get(const StringName &p_path, Variant &r_ret)
if (path.begins_with("settings/")) { if (path.begins_with("settings/")) {
int which = path.get_slicec('/', 1).to_int(); int which = path.get_slicec('/', 1).to_int();
String where = path.get_slicec('/', 2); String where = path.get_slicec('/', 2);
ERR_FAIL_INDEX_V(which, settings.size(), false); ERR_FAIL_INDEX_V(which, (int)settings.size(), false);
String what = path.get_slicec('/', 3); String what = path.get_slicec('/', 3);
if (where == "apply") { if (where == "apply") {
@@ -125,7 +125,9 @@ bool ConvertTransformModifier3D::_get(const StringName &p_path, Variant &r_ret)
void ConvertTransformModifier3D::_get_property_list(List<PropertyInfo> *p_list) const { void ConvertTransformModifier3D::_get_property_list(List<PropertyInfo> *p_list) const {
BoneConstraint3D::get_property_list(p_list); BoneConstraint3D::get_property_list(p_list);
for (int i = 0; i < settings.size(); i++) { LocalVector<PropertyInfo> props;
for (uint32_t i = 0; i < settings.size(); i++) {
String path = "settings/" + itos(i) + "/"; String path = "settings/" + itos(i) + "/";
String hint_apply_range; String hint_apply_range;
@@ -136,10 +138,10 @@ void ConvertTransformModifier3D::_get_property_list(List<PropertyInfo> *p_list)
} else { } else {
hint_apply_range = HINT_SCALE; hint_apply_range = HINT_SCALE;
} }
p_list->push_back(PropertyInfo(Variant::INT, path + "apply/transform_mode", PROPERTY_HINT_ENUM, "Position,Rotation,Scale")); props.push_back(PropertyInfo(Variant::INT, path + "apply/transform_mode", PROPERTY_HINT_ENUM, "Position,Rotation,Scale"));
p_list->push_back(PropertyInfo(Variant::INT, path + "apply/axis", PROPERTY_HINT_ENUM, "X,Y,Z")); props.push_back(PropertyInfo(Variant::INT, path + "apply/axis", PROPERTY_HINT_ENUM, "X,Y,Z"));
p_list->push_back(PropertyInfo(Variant::FLOAT, path + "apply/range_min", PROPERTY_HINT_RANGE, hint_apply_range)); props.push_back(PropertyInfo(Variant::FLOAT, path + "apply/range_min", PROPERTY_HINT_RANGE, hint_apply_range));
p_list->push_back(PropertyInfo(Variant::FLOAT, path + "apply/range_max", PROPERTY_HINT_RANGE, hint_apply_range)); props.push_back(PropertyInfo(Variant::FLOAT, path + "apply/range_max", PROPERTY_HINT_RANGE, hint_apply_range));
String hint_reference_range; String hint_reference_range;
if (get_reference_transform_mode(i) == TRANSFORM_MODE_POSITION) { if (get_reference_transform_mode(i) == TRANSFORM_MODE_POSITION) {
@@ -149,138 +151,153 @@ void ConvertTransformModifier3D::_get_property_list(List<PropertyInfo> *p_list)
} else { } else {
hint_reference_range = HINT_SCALE; hint_reference_range = HINT_SCALE;
} }
p_list->push_back(PropertyInfo(Variant::INT, path + "reference/transform_mode", PROPERTY_HINT_ENUM, "Position,Rotation,Scale")); props.push_back(PropertyInfo(Variant::INT, path + "reference/transform_mode", PROPERTY_HINT_ENUM, "Position,Rotation,Scale"));
p_list->push_back(PropertyInfo(Variant::INT, path + "reference/axis", PROPERTY_HINT_ENUM, "X,Y,Z")); props.push_back(PropertyInfo(Variant::INT, path + "reference/axis", PROPERTY_HINT_ENUM, "X,Y,Z"));
p_list->push_back(PropertyInfo(Variant::FLOAT, path + "reference/range_min", PROPERTY_HINT_RANGE, hint_reference_range)); props.push_back(PropertyInfo(Variant::FLOAT, path + "reference/range_min", PROPERTY_HINT_RANGE, hint_reference_range));
p_list->push_back(PropertyInfo(Variant::FLOAT, path + "reference/range_max", PROPERTY_HINT_RANGE, hint_reference_range)); props.push_back(PropertyInfo(Variant::FLOAT, path + "reference/range_max", PROPERTY_HINT_RANGE, hint_reference_range));
p_list->push_back(PropertyInfo(Variant::BOOL, path + "relative")); props.push_back(PropertyInfo(Variant::BOOL, path + "relative"));
p_list->push_back(PropertyInfo(Variant::BOOL, path + "additive")); props.push_back(PropertyInfo(Variant::BOOL, path + "additive"));
}
for (PropertyInfo &p : props) {
_validate_dynamic_prop(p);
p_list->push_back(p);
}
}
void ConvertTransformModifier3D::_validate_dynamic_prop(PropertyInfo &p_property) const {
PackedStringArray split = p_property.name.split("/");
if (split.size() > 2 && split[0] == "settings") {
int which = split[1].to_int();
if (split[2].begins_with("relative") && get_reference_type(which) != REFERENCE_TYPE_BONE) {
p_property.usage = PROPERTY_USAGE_NONE;
}
} }
} }
void ConvertTransformModifier3D::_validate_setting(int p_index) { void ConvertTransformModifier3D::_validate_setting(int p_index) {
settings.write[p_index] = memnew(ConvertTransform3DSetting); settings[p_index] = memnew(ConvertTransform3DSetting);
} }
void ConvertTransformModifier3D::set_apply_transform_mode(int p_index, TransformMode p_transform_mode) { void ConvertTransformModifier3D::set_apply_transform_mode(int p_index, TransformMode p_transform_mode) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]); ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
setting->apply_transform_mode = p_transform_mode; setting->apply_transform_mode = p_transform_mode;
notify_property_list_changed(); notify_property_list_changed();
} }
ConvertTransformModifier3D::TransformMode ConvertTransformModifier3D::get_apply_transform_mode(int p_index) const { ConvertTransformModifier3D::TransformMode ConvertTransformModifier3D::get_apply_transform_mode(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), TRANSFORM_MODE_POSITION); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), TRANSFORM_MODE_POSITION);
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]); ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
return setting->apply_transform_mode; return setting->apply_transform_mode;
} }
void ConvertTransformModifier3D::set_apply_axis(int p_index, Vector3::Axis p_axis) { void ConvertTransformModifier3D::set_apply_axis(int p_index, Vector3::Axis p_axis) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]); ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
setting->apply_axis = p_axis; setting->apply_axis = p_axis;
} }
Vector3::Axis ConvertTransformModifier3D::get_apply_axis(int p_index) const { Vector3::Axis ConvertTransformModifier3D::get_apply_axis(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), Vector3::AXIS_X); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), Vector3::AXIS_X);
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]); ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
return setting->apply_axis; return setting->apply_axis;
} }
void ConvertTransformModifier3D::set_apply_range_min(int p_index, float p_range_min) { void ConvertTransformModifier3D::set_apply_range_min(int p_index, float p_range_min) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]); ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
setting->apply_range_min = p_range_min; setting->apply_range_min = p_range_min;
} }
float ConvertTransformModifier3D::get_apply_range_min(int p_index) const { float ConvertTransformModifier3D::get_apply_range_min(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), 0); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), 0);
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]); ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
return setting->apply_range_min; return setting->apply_range_min;
} }
void ConvertTransformModifier3D::set_apply_range_max(int p_index, float p_range_max) { void ConvertTransformModifier3D::set_apply_range_max(int p_index, float p_range_max) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]); ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
setting->apply_range_max = p_range_max; setting->apply_range_max = p_range_max;
} }
float ConvertTransformModifier3D::get_apply_range_max(int p_index) const { float ConvertTransformModifier3D::get_apply_range_max(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), 0); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), 0);
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]); ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
return setting->apply_range_max; return setting->apply_range_max;
} }
void ConvertTransformModifier3D::set_reference_transform_mode(int p_index, TransformMode p_transform_mode) { void ConvertTransformModifier3D::set_reference_transform_mode(int p_index, TransformMode p_transform_mode) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]); ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
setting->reference_transform_mode = p_transform_mode; setting->reference_transform_mode = p_transform_mode;
notify_property_list_changed(); notify_property_list_changed();
} }
ConvertTransformModifier3D::TransformMode ConvertTransformModifier3D::get_reference_transform_mode(int p_index) const { ConvertTransformModifier3D::TransformMode ConvertTransformModifier3D::get_reference_transform_mode(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), TRANSFORM_MODE_POSITION); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), TRANSFORM_MODE_POSITION);
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]); ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
return setting->reference_transform_mode; return setting->reference_transform_mode;
} }
void ConvertTransformModifier3D::set_reference_axis(int p_index, Vector3::Axis p_axis) { void ConvertTransformModifier3D::set_reference_axis(int p_index, Vector3::Axis p_axis) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]); ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
setting->reference_axis = p_axis; setting->reference_axis = p_axis;
} }
Vector3::Axis ConvertTransformModifier3D::get_reference_axis(int p_index) const { Vector3::Axis ConvertTransformModifier3D::get_reference_axis(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), Vector3::AXIS_X); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), Vector3::AXIS_X);
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]); ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
return setting->reference_axis; return setting->reference_axis;
} }
void ConvertTransformModifier3D::set_reference_range_min(int p_index, float p_range_min) { void ConvertTransformModifier3D::set_reference_range_min(int p_index, float p_range_min) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]); ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
setting->reference_range_min = p_range_min; setting->reference_range_min = p_range_min;
} }
float ConvertTransformModifier3D::get_reference_range_min(int p_index) const { float ConvertTransformModifier3D::get_reference_range_min(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), 0); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), 0);
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]); ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
return setting->reference_range_min; return setting->reference_range_min;
} }
void ConvertTransformModifier3D::set_reference_range_max(int p_index, float p_range_max) { void ConvertTransformModifier3D::set_reference_range_max(int p_index, float p_range_max) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]); ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
setting->reference_range_max = p_range_max; setting->reference_range_max = p_range_max;
} }
float ConvertTransformModifier3D::get_reference_range_max(int p_index) const { float ConvertTransformModifier3D::get_reference_range_max(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), 0); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), 0);
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]); ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
return setting->reference_range_max; return setting->reference_range_max;
} }
void ConvertTransformModifier3D::set_relative(int p_index, bool p_enabled) { void ConvertTransformModifier3D::set_relative(int p_index, bool p_enabled) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]); ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
setting->relative = p_enabled; setting->relative = p_enabled;
} }
bool ConvertTransformModifier3D::is_relative(int p_index) const { bool ConvertTransformModifier3D::is_relative(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), 0); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), 0);
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]); ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
return setting->relative; return setting->is_relative();
} }
void ConvertTransformModifier3D::set_additive(int p_index, bool p_enabled) { void ConvertTransformModifier3D::set_additive(int p_index, bool p_enabled) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]); ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
setting->additive = p_enabled; setting->additive = p_enabled;
} }
bool ConvertTransformModifier3D::is_additive(int p_index) const { bool ConvertTransformModifier3D::is_additive(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), 0); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), 0);
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]); ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
return setting->additive; return setting->additive;
} }
@@ -316,16 +333,37 @@ void ConvertTransformModifier3D::_bind_methods() {
BIND_ENUM_CONSTANT(TRANSFORM_MODE_SCALE); BIND_ENUM_CONSTANT(TRANSFORM_MODE_SCALE);
} }
void ConvertTransformModifier3D::_process_constraint(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, int p_reference_bone, float p_amount) { void ConvertTransformModifier3D::_process_constraint_by_bone(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, int p_reference_bone, float p_amount) {
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]); ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
Transform3D destination = p_skeleton->get_bone_pose(p_reference_bone); Transform3D destination = p_skeleton->get_bone_pose(p_reference_bone);
if (setting->relative) { if (setting->is_relative()) {
Vector3 scl_relative = destination.basis.get_scale() / p_skeleton->get_bone_rest(p_reference_bone).basis.get_scale(); Vector3 scl_relative = destination.basis.get_scale() / p_skeleton->get_bone_rest(p_reference_bone).basis.get_scale();
destination.basis = p_skeleton->get_bone_rest(p_reference_bone).basis.get_rotation_quaternion().inverse() * destination.basis.get_rotation_quaternion(); destination.basis = p_skeleton->get_bone_rest(p_reference_bone).basis.get_rotation_quaternion().inverse() * destination.basis.get_rotation_quaternion();
destination.basis.scale_local(scl_relative); destination.basis.scale_local(scl_relative);
destination.origin = destination.origin - p_skeleton->get_bone_rest(p_reference_bone).origin; destination.origin = destination.origin - p_skeleton->get_bone_rest(p_reference_bone).origin;
} }
_process_convert(p_index, p_skeleton, p_apply_bone, destination, p_amount);
}
void ConvertTransformModifier3D::_process_constraint_by_node(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, const NodePath &p_reference_node, float p_amount) {
Node3D *nd = Object::cast_to<Node3D>(get_node_or_null(p_reference_node));
if (!nd) {
return;
}
Transform3D skel_tr = p_skeleton->get_global_transform_interpolated();
int parent = p_skeleton->get_bone_parent(p_apply_bone);
if (parent >= 0) {
skel_tr = skel_tr * p_skeleton->get_bone_global_pose(parent);
}
Transform3D dest_tr = nd->get_global_transform_interpolated();
Transform3D reference_dest = skel_tr.affine_inverse() * dest_tr;
_process_convert(p_index, p_skeleton, p_apply_bone, reference_dest, p_amount);
}
void ConvertTransformModifier3D::_process_convert(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, const Transform3D &p_destination, float p_amount) {
ConvertTransform3DSetting *setting = static_cast<ConvertTransform3DSetting *>(settings[p_index]);
Transform3D destination = p_destination;
// Retrieve point from reference. // Retrieve point from reference.
double point = 0.0; double point = 0.0;
@@ -355,7 +393,7 @@ void ConvertTransformModifier3D::_process_constraint(int p_index, Skeleton3D *p_
case TRANSFORM_MODE_POSITION: { case TRANSFORM_MODE_POSITION: {
if (setting->additive) { if (setting->additive) {
point = p_skeleton->get_bone_pose(p_apply_bone).origin[axis] + point; point = p_skeleton->get_bone_pose(p_apply_bone).origin[axis] + point;
} else if (setting->relative) { } else if (setting->is_relative()) {
point = p_skeleton->get_bone_rest(p_apply_bone).origin[axis] + point; point = p_skeleton->get_bone_rest(p_apply_bone).origin[axis] + point;
} }
destination.origin[axis] = point; destination.origin[axis] = point;
@@ -369,7 +407,7 @@ void ConvertTransformModifier3D::_process_constraint(int p_index, Skeleton3D *p_
Quaternion rot = Quaternion(rot_axis, point); Quaternion rot = Quaternion(rot_axis, point);
if (setting->additive) { if (setting->additive) {
destination.basis = p_skeleton->get_bone_pose(p_apply_bone).basis.get_rotation_quaternion() * rot; destination.basis = p_skeleton->get_bone_pose(p_apply_bone).basis.get_rotation_quaternion() * rot;
} else if (setting->relative) { } else if (setting->is_relative()) {
destination.basis = p_skeleton->get_bone_rest(p_apply_bone).basis.get_rotation_quaternion() * rot; destination.basis = p_skeleton->get_bone_rest(p_apply_bone).basis.get_rotation_quaternion() * rot;
} else { } else {
destination.basis = rot; destination.basis = rot;
@@ -382,7 +420,7 @@ void ConvertTransformModifier3D::_process_constraint(int p_index, Skeleton3D *p_
if (setting->additive) { if (setting->additive) {
dest_scl = p_skeleton->get_bone_pose(p_apply_bone).basis.get_scale(); dest_scl = p_skeleton->get_bone_pose(p_apply_bone).basis.get_scale();
dest_scl[axis] = dest_scl[axis] * point; dest_scl[axis] = dest_scl[axis] * point;
} else if (setting->relative) { } else if (setting->is_relative()) {
dest_scl = p_skeleton->get_bone_rest(p_apply_bone).basis.get_scale(); dest_scl = p_skeleton->get_bone_rest(p_apply_bone).basis.get_scale();
dest_scl[axis] = dest_scl[axis] * point; dest_scl[axis] = dest_scl[axis] * point;
} else { } else {

View File

@@ -55,16 +55,26 @@ public:
bool relative = true; bool relative = true;
bool additive = false; bool additive = false;
bool is_relative() {
if (reference_type == REFERENCE_TYPE_NODE) {
return false;
}
return relative;
}
}; };
protected: protected:
bool _get(const StringName &p_path, Variant &r_ret) const; bool _get(const StringName &p_path, Variant &r_ret) const;
bool _set(const StringName &p_path, const Variant &p_value); bool _set(const StringName &p_path, const Variant &p_value);
void _get_property_list(List<PropertyInfo> *p_list) const; void _get_property_list(List<PropertyInfo> *p_list) const;
void _validate_dynamic_prop(PropertyInfo &p_property) const;
static void _bind_methods(); static void _bind_methods();
virtual void _process_constraint(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, int p_reference_bone, float p_amount) override; virtual void _process_constraint_by_bone(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, int p_reference_bone, float p_amount) override;
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;
virtual void _process_convert(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, const Transform3D &p_destination, float p_amount);
virtual void _validate_setting(int p_index) override; virtual void _validate_setting(int p_index) override;
public: public:

View File

@@ -36,7 +36,7 @@ bool CopyTransformModifier3D::_set(const StringName &p_path, const Variant &p_va
if (path.begins_with("settings/")) { if (path.begins_with("settings/")) {
int which = path.get_slicec('/', 1).to_int(); int which = path.get_slicec('/', 1).to_int();
String what = path.get_slicec('/', 2); String what = path.get_slicec('/', 2);
ERR_FAIL_INDEX_V(which, settings.size(), false); ERR_FAIL_INDEX_V(which, (int)settings.size(), false);
if (what == "copy") { if (what == "copy") {
set_copy_flags(which, static_cast<BitField<TransformFlag>>((int)p_value)); set_copy_flags(which, static_cast<BitField<TransformFlag>>((int)p_value));
@@ -61,7 +61,7 @@ bool CopyTransformModifier3D::_get(const StringName &p_path, Variant &r_ret) con
if (path.begins_with("settings/")) { if (path.begins_with("settings/")) {
int which = path.get_slicec('/', 1).to_int(); int which = path.get_slicec('/', 1).to_int();
String what = path.get_slicec('/', 2); String what = path.get_slicec('/', 2);
ERR_FAIL_INDEX_V(which, settings.size(), false); ERR_FAIL_INDEX_V(which, (int)settings.size(), false);
if (what == "copy") { if (what == "copy") {
r_ret = (int)get_copy_flags(which); r_ret = (int)get_copy_flags(which);
@@ -83,61 +83,78 @@ bool CopyTransformModifier3D::_get(const StringName &p_path, Variant &r_ret) con
void CopyTransformModifier3D::_get_property_list(List<PropertyInfo> *p_list) const { void CopyTransformModifier3D::_get_property_list(List<PropertyInfo> *p_list) const {
BoneConstraint3D::get_property_list(p_list); BoneConstraint3D::get_property_list(p_list);
for (int i = 0; i < settings.size(); i++) { LocalVector<PropertyInfo> props;
for (uint32_t i = 0; i < settings.size(); i++) {
String path = "settings/" + itos(i) + "/"; String path = "settings/" + itos(i) + "/";
p_list->push_back(PropertyInfo(Variant::INT, path + "copy", PROPERTY_HINT_FLAGS, "Position,Rotation,Scale")); props.push_back(PropertyInfo(Variant::INT, path + "copy", PROPERTY_HINT_FLAGS, "Position,Rotation,Scale"));
p_list->push_back(PropertyInfo(Variant::INT, path + "axes", PROPERTY_HINT_FLAGS, "X,Y,Z")); props.push_back(PropertyInfo(Variant::INT, path + "axes", PROPERTY_HINT_FLAGS, "X,Y,Z"));
p_list->push_back(PropertyInfo(Variant::INT, path + "invert", PROPERTY_HINT_FLAGS, "X,Y,Z")); props.push_back(PropertyInfo(Variant::INT, path + "invert", PROPERTY_HINT_FLAGS, "X,Y,Z"));
p_list->push_back(PropertyInfo(Variant::BOOL, path + "relative")); props.push_back(PropertyInfo(Variant::BOOL, path + "relative"));
p_list->push_back(PropertyInfo(Variant::BOOL, path + "additive")); props.push_back(PropertyInfo(Variant::BOOL, path + "additive"));
}
for (PropertyInfo &p : props) {
_validate_dynamic_prop(p);
p_list->push_back(p);
}
}
void CopyTransformModifier3D::_validate_dynamic_prop(PropertyInfo &p_property) const {
PackedStringArray split = p_property.name.split("/");
if (split.size() > 2 && split[0] == "settings") {
int which = split[1].to_int();
if (split[2].begins_with("relative") && get_reference_type(which) != REFERENCE_TYPE_BONE) {
p_property.usage = PROPERTY_USAGE_NONE;
}
} }
} }
void CopyTransformModifier3D::_validate_setting(int p_index) { void CopyTransformModifier3D::_validate_setting(int p_index) {
settings.write[p_index] = memnew(CopyTransform3DSetting); settings[p_index] = memnew(CopyTransform3DSetting);
} }
void CopyTransformModifier3D::set_copy_flags(int p_index, BitField<TransformFlag> p_copy_flags) { void CopyTransformModifier3D::set_copy_flags(int p_index, BitField<TransformFlag> p_copy_flags) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
setting->copy_flags = p_copy_flags; setting->copy_flags = p_copy_flags;
notify_property_list_changed(); notify_property_list_changed();
} }
BitField<CopyTransformModifier3D::TransformFlag> CopyTransformModifier3D::get_copy_flags(int p_index) const { BitField<CopyTransformModifier3D::TransformFlag> CopyTransformModifier3D::get_copy_flags(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), 0); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), 0);
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
return setting->copy_flags; return setting->copy_flags;
} }
void CopyTransformModifier3D::set_axis_flags(int p_index, BitField<AxisFlag> p_axis_flags) { void CopyTransformModifier3D::set_axis_flags(int p_index, BitField<AxisFlag> p_axis_flags) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
setting->axis_flags = p_axis_flags; setting->axis_flags = p_axis_flags;
notify_property_list_changed(); notify_property_list_changed();
} }
BitField<CopyTransformModifier3D::AxisFlag> CopyTransformModifier3D::get_axis_flags(int p_index) const { BitField<CopyTransformModifier3D::AxisFlag> CopyTransformModifier3D::get_axis_flags(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), 0); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), 0);
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
return setting->axis_flags; return setting->axis_flags;
} }
void CopyTransformModifier3D::set_invert_flags(int p_index, BitField<AxisFlag> p_axis_flags) { void CopyTransformModifier3D::set_invert_flags(int p_index, BitField<AxisFlag> p_axis_flags) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
setting->invert_flags = p_axis_flags; setting->invert_flags = p_axis_flags;
notify_property_list_changed(); notify_property_list_changed();
} }
BitField<CopyTransformModifier3D::AxisFlag> CopyTransformModifier3D::get_invert_flags(int p_index) const { BitField<CopyTransformModifier3D::AxisFlag> CopyTransformModifier3D::get_invert_flags(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), false); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), false);
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
return setting->invert_flags; return setting->invert_flags;
} }
void CopyTransformModifier3D::set_copy_position(int p_index, bool p_enabled) { void CopyTransformModifier3D::set_copy_position(int p_index, bool p_enabled) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
if (p_enabled) { if (p_enabled) {
setting->copy_flags.set_flag(TRANSFORM_FLAG_POSITION); setting->copy_flags.set_flag(TRANSFORM_FLAG_POSITION);
@@ -147,13 +164,13 @@ void CopyTransformModifier3D::set_copy_position(int p_index, bool p_enabled) {
} }
bool CopyTransformModifier3D::is_position_copying(int p_index) const { bool CopyTransformModifier3D::is_position_copying(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), false); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), false);
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
return setting->copy_flags.has_flag(TRANSFORM_FLAG_POSITION); return setting->copy_flags.has_flag(TRANSFORM_FLAG_POSITION);
} }
void CopyTransformModifier3D::set_copy_rotation(int p_index, bool p_enabled) { void CopyTransformModifier3D::set_copy_rotation(int p_index, bool p_enabled) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
if (p_enabled) { if (p_enabled) {
setting->copy_flags.set_flag(TRANSFORM_FLAG_ROTATION); setting->copy_flags.set_flag(TRANSFORM_FLAG_ROTATION);
@@ -163,13 +180,13 @@ void CopyTransformModifier3D::set_copy_rotation(int p_index, bool p_enabled) {
} }
bool CopyTransformModifier3D::is_rotation_copying(int p_index) const { bool CopyTransformModifier3D::is_rotation_copying(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), false); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), false);
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
return setting->copy_flags.has_flag(TRANSFORM_FLAG_ROTATION); return setting->copy_flags.has_flag(TRANSFORM_FLAG_ROTATION);
} }
void CopyTransformModifier3D::set_copy_scale(int p_index, bool p_enabled) { void CopyTransformModifier3D::set_copy_scale(int p_index, bool p_enabled) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
if (p_enabled) { if (p_enabled) {
setting->copy_flags.set_flag(TRANSFORM_FLAG_SCALE); setting->copy_flags.set_flag(TRANSFORM_FLAG_SCALE);
@@ -179,13 +196,13 @@ void CopyTransformModifier3D::set_copy_scale(int p_index, bool p_enabled) {
} }
bool CopyTransformModifier3D::is_scale_copying(int p_index) const { bool CopyTransformModifier3D::is_scale_copying(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), false); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), false);
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
return setting->copy_flags.has_flag(TRANSFORM_FLAG_SCALE); return setting->copy_flags.has_flag(TRANSFORM_FLAG_SCALE);
} }
void CopyTransformModifier3D::set_axis_x_enabled(int p_index, bool p_enabled) { void CopyTransformModifier3D::set_axis_x_enabled(int p_index, bool p_enabled) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
if (p_enabled) { if (p_enabled) {
setting->axis_flags.set_flag(AXIS_FLAG_X); setting->axis_flags.set_flag(AXIS_FLAG_X);
@@ -195,13 +212,13 @@ void CopyTransformModifier3D::set_axis_x_enabled(int p_index, bool p_enabled) {
} }
bool CopyTransformModifier3D::is_axis_x_enabled(int p_index) const { bool CopyTransformModifier3D::is_axis_x_enabled(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), false); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), false);
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
return setting->axis_flags.has_flag(AXIS_FLAG_X); return setting->axis_flags.has_flag(AXIS_FLAG_X);
} }
void CopyTransformModifier3D::set_axis_y_enabled(int p_index, bool p_enabled) { void CopyTransformModifier3D::set_axis_y_enabled(int p_index, bool p_enabled) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
if (p_enabled) { if (p_enabled) {
setting->axis_flags.set_flag(AXIS_FLAG_Y); setting->axis_flags.set_flag(AXIS_FLAG_Y);
@@ -211,13 +228,13 @@ void CopyTransformModifier3D::set_axis_y_enabled(int p_index, bool p_enabled) {
} }
bool CopyTransformModifier3D::is_axis_y_enabled(int p_index) const { bool CopyTransformModifier3D::is_axis_y_enabled(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), false); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), false);
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
return setting->axis_flags.has_flag(AXIS_FLAG_Y); return setting->axis_flags.has_flag(AXIS_FLAG_Y);
} }
void CopyTransformModifier3D::set_axis_z_enabled(int p_index, bool p_enabled) { void CopyTransformModifier3D::set_axis_z_enabled(int p_index, bool p_enabled) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
if (p_enabled) { if (p_enabled) {
setting->axis_flags.set_flag(AXIS_FLAG_Z); setting->axis_flags.set_flag(AXIS_FLAG_Z);
@@ -227,13 +244,13 @@ void CopyTransformModifier3D::set_axis_z_enabled(int p_index, bool p_enabled) {
} }
bool CopyTransformModifier3D::is_axis_z_enabled(int p_index) const { bool CopyTransformModifier3D::is_axis_z_enabled(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), false); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), false);
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
return setting->axis_flags.has_flag(AXIS_FLAG_Z); return setting->axis_flags.has_flag(AXIS_FLAG_Z);
} }
void CopyTransformModifier3D::set_axis_x_inverted(int p_index, bool p_enabled) { void CopyTransformModifier3D::set_axis_x_inverted(int p_index, bool p_enabled) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
if (p_enabled) { if (p_enabled) {
setting->invert_flags.set_flag(AXIS_FLAG_X); setting->invert_flags.set_flag(AXIS_FLAG_X);
@@ -243,13 +260,13 @@ void CopyTransformModifier3D::set_axis_x_inverted(int p_index, bool p_enabled) {
} }
bool CopyTransformModifier3D::is_axis_x_inverted(int p_index) const { bool CopyTransformModifier3D::is_axis_x_inverted(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), false); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), false);
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
return setting->invert_flags.has_flag(AXIS_FLAG_X); return setting->invert_flags.has_flag(AXIS_FLAG_X);
} }
void CopyTransformModifier3D::set_axis_y_inverted(int p_index, bool p_enabled) { void CopyTransformModifier3D::set_axis_y_inverted(int p_index, bool p_enabled) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
if (p_enabled) { if (p_enabled) {
setting->invert_flags.set_flag(AXIS_FLAG_Y); setting->invert_flags.set_flag(AXIS_FLAG_Y);
@@ -259,13 +276,13 @@ void CopyTransformModifier3D::set_axis_y_inverted(int p_index, bool p_enabled) {
} }
bool CopyTransformModifier3D::is_axis_y_inverted(int p_index) const { bool CopyTransformModifier3D::is_axis_y_inverted(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), false); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), false);
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
return setting->invert_flags.has_flag(AXIS_FLAG_Y); return setting->invert_flags.has_flag(AXIS_FLAG_Y);
} }
void CopyTransformModifier3D::set_axis_z_inverted(int p_index, bool p_enabled) { void CopyTransformModifier3D::set_axis_z_inverted(int p_index, bool p_enabled) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
if (p_enabled) { if (p_enabled) {
setting->invert_flags.set_flag(AXIS_FLAG_Z); setting->invert_flags.set_flag(AXIS_FLAG_Z);
@@ -275,31 +292,31 @@ void CopyTransformModifier3D::set_axis_z_inverted(int p_index, bool p_enabled) {
} }
bool CopyTransformModifier3D::is_axis_z_inverted(int p_index) const { bool CopyTransformModifier3D::is_axis_z_inverted(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), false); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), false);
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
return setting->invert_flags.has_flag(AXIS_FLAG_Z); return setting->invert_flags.has_flag(AXIS_FLAG_Z);
} }
void CopyTransformModifier3D::set_relative(int p_index, bool p_enabled) { void CopyTransformModifier3D::set_relative(int p_index, bool p_enabled) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
setting->relative = p_enabled; setting->relative = p_enabled;
} }
bool CopyTransformModifier3D::is_relative(int p_index) const { bool CopyTransformModifier3D::is_relative(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), 0); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), 0);
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
return setting->relative; return setting->is_relative();
} }
void CopyTransformModifier3D::set_additive(int p_index, bool p_enabled) { void CopyTransformModifier3D::set_additive(int p_index, bool p_enabled) {
ERR_FAIL_INDEX(p_index, settings.size()); ERR_FAIL_INDEX(p_index, (int)settings.size());
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
setting->additive = p_enabled; setting->additive = p_enabled;
} }
bool CopyTransformModifier3D::is_additive(int p_index) const { bool CopyTransformModifier3D::is_additive(int p_index) const {
ERR_FAIL_INDEX_V(p_index, settings.size(), 0); ERR_FAIL_INDEX_V(p_index, (int)settings.size(), 0);
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
return setting->additive; return setting->additive;
} }
@@ -351,16 +368,37 @@ void CopyTransformModifier3D::_bind_methods() {
BIND_BITFIELD_FLAG(AXIS_FLAG_ALL); BIND_BITFIELD_FLAG(AXIS_FLAG_ALL);
} }
void CopyTransformModifier3D::_process_constraint(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, int p_reference_bone, float p_amount) { void CopyTransformModifier3D::_process_constraint_by_bone(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, int p_reference_bone, float p_amount) {
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]); CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
Transform3D destination = p_skeleton->get_bone_pose(p_reference_bone); Transform3D destination = p_skeleton->get_bone_pose(p_reference_bone);
if (setting->relative) { if (setting->is_relative()) {
Vector3 scl_relative = destination.basis.get_scale() / p_skeleton->get_bone_rest(p_reference_bone).basis.get_scale(); Vector3 scl_relative = destination.basis.get_scale() / p_skeleton->get_bone_rest(p_reference_bone).basis.get_scale();
destination.basis = p_skeleton->get_bone_rest(p_reference_bone).basis.get_rotation_quaternion().inverse() * destination.basis.get_rotation_quaternion(); destination.basis = p_skeleton->get_bone_rest(p_reference_bone).basis.get_rotation_quaternion().inverse() * destination.basis.get_rotation_quaternion();
destination.basis.scale_local(scl_relative); destination.basis.scale_local(scl_relative);
destination.origin = destination.origin - p_skeleton->get_bone_rest(p_reference_bone).origin; destination.origin = destination.origin - p_skeleton->get_bone_rest(p_reference_bone).origin;
} }
_process_copy(p_index, p_skeleton, p_apply_bone, destination, p_amount);
}
void CopyTransformModifier3D::_process_constraint_by_node(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, const NodePath &p_reference_node, float p_amount) {
Node3D *nd = Object::cast_to<Node3D>(get_node_or_null(p_reference_node));
if (!nd) {
return;
}
Transform3D skel_tr = p_skeleton->get_global_transform_interpolated();
int parent = p_skeleton->get_bone_parent(p_apply_bone);
if (parent >= 0) {
skel_tr = skel_tr * p_skeleton->get_bone_global_pose(parent);
}
Transform3D dest_tr = nd->get_global_transform_interpolated();
Transform3D reference_dest = skel_tr.affine_inverse() * dest_tr;
_process_copy(p_index, p_skeleton, p_apply_bone, reference_dest, p_amount);
}
void CopyTransformModifier3D::_process_copy(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, const Transform3D &p_destination, float p_amount) {
CopyTransform3DSetting *setting = static_cast<CopyTransform3DSetting *>(settings[p_index]);
Transform3D destination = p_destination;
Vector3 dest_pos = destination.origin; Vector3 dest_pos = destination.origin;
Quaternion dest_rot = destination.basis.get_rotation_quaternion(); Quaternion dest_rot = destination.basis.get_rotation_quaternion();
Vector3 dest_scl = destination.basis.get_scale(); Vector3 dest_scl = destination.basis.get_scale();
@@ -421,7 +459,7 @@ void CopyTransformModifier3D::_process_constraint(int p_index, Skeleton3D *p_ske
destination.origin = p_skeleton->get_bone_pose_position(p_apply_bone) + dest_pos; destination.origin = p_skeleton->get_bone_pose_position(p_apply_bone) + dest_pos;
destination.basis = p_skeleton->get_bone_pose_rotation(p_apply_bone) * Basis(dest_rot); destination.basis = p_skeleton->get_bone_pose_rotation(p_apply_bone) * Basis(dest_rot);
destination.basis.scale_local(p_skeleton->get_bone_pose_scale(p_apply_bone) * dest_scl); destination.basis.scale_local(p_skeleton->get_bone_pose_scale(p_apply_bone) * dest_scl);
} else if (setting->relative) { } else if (setting->is_relative()) {
Transform3D rest = p_skeleton->get_bone_rest(p_apply_bone); Transform3D rest = p_skeleton->get_bone_rest(p_apply_bone);
destination.origin = rest.origin + dest_pos; destination.origin = rest.origin + dest_pos;
destination.basis = rest.basis.get_rotation_quaternion() * Basis(dest_rot); destination.basis = rest.basis.get_rotation_quaternion() * Basis(dest_rot);

View File

@@ -54,18 +54,29 @@ public:
BitField<TransformFlag> copy_flags = TRANSFORM_FLAG_ALL; BitField<TransformFlag> copy_flags = TRANSFORM_FLAG_ALL;
BitField<AxisFlag> axis_flags = AXIS_FLAG_ALL; BitField<AxisFlag> axis_flags = AXIS_FLAG_ALL;
BitField<AxisFlag> invert_flags = 0; BitField<AxisFlag> invert_flags = 0;
bool relative = true; bool relative = true;
bool additive = false; bool additive = false;
bool is_relative() {
if (reference_type == REFERENCE_TYPE_NODE) {
return false;
}
return relative;
}
}; };
protected: protected:
bool _get(const StringName &p_path, Variant &r_ret) const; bool _get(const StringName &p_path, Variant &r_ret) const;
bool _set(const StringName &p_path, const Variant &p_value); bool _set(const StringName &p_path, const Variant &p_value);
void _get_property_list(List<PropertyInfo> *p_list) const; void _get_property_list(List<PropertyInfo> *p_list) const;
void _validate_dynamic_prop(PropertyInfo &p_property) const;
static void _bind_methods(); static void _bind_methods();
virtual void _process_constraint(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, int p_reference_bone, float p_amount) override; virtual void _process_constraint_by_bone(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, int p_reference_bone, float p_amount) override;
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;
virtual void _process_copy(int p_index, Skeleton3D *p_skeleton, int p_apply_bone, const Transform3D &p_destination, float p_amount);
virtual void _validate_setting(int p_index) override; virtual void _validate_setting(int p_index) override;
public: public: