1
0
mirror of https://github.com/godotengine/godot.git synced 2025-12-04 17:04:49 +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

@@ -36,7 +36,7 @@ bool CopyTransformModifier3D::_set(const StringName &p_path, const Variant &p_va
if (path.begins_with("settings/")) {
int which = path.get_slicec('/', 1).to_int();
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") {
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/")) {
int which = path.get_slicec('/', 1).to_int();
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") {
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 {
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) + "/";
p_list->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"));
p_list->push_back(PropertyInfo(Variant::INT, path + "invert", PROPERTY_HINT_FLAGS, "X,Y,Z"));
p_list->push_back(PropertyInfo(Variant::BOOL, path + "relative"));
p_list->push_back(PropertyInfo(Variant::BOOL, path + "additive"));
props.push_back(PropertyInfo(Variant::INT, path + "copy", PROPERTY_HINT_FLAGS, "Position,Rotation,Scale"));
props.push_back(PropertyInfo(Variant::INT, path + "axes", PROPERTY_HINT_FLAGS, "X,Y,Z"));
props.push_back(PropertyInfo(Variant::INT, path + "invert", PROPERTY_HINT_FLAGS, "X,Y,Z"));
props.push_back(PropertyInfo(Variant::BOOL, path + "relative"));
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) {
settings.write[p_index] = memnew(CopyTransform3DSetting);
settings[p_index] = memnew(CopyTransform3DSetting);
}
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]);
setting->copy_flags = p_copy_flags;
notify_property_list_changed();
}
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]);
return setting->copy_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]);
setting->axis_flags = p_axis_flags;
notify_property_list_changed();
}
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]);
return setting->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]);
setting->invert_flags = p_axis_flags;
notify_property_list_changed();
}
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]);
return setting->invert_flags;
}
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]);
if (p_enabled) {
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 {
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]);
return setting->copy_flags.has_flag(TRANSFORM_FLAG_POSITION);
}
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]);
if (p_enabled) {
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 {
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]);
return setting->copy_flags.has_flag(TRANSFORM_FLAG_ROTATION);
}
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]);
if (p_enabled) {
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 {
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]);
return setting->copy_flags.has_flag(TRANSFORM_FLAG_SCALE);
}
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]);
if (p_enabled) {
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 {
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]);
return setting->axis_flags.has_flag(AXIS_FLAG_X);
}
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]);
if (p_enabled) {
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 {
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]);
return setting->axis_flags.has_flag(AXIS_FLAG_Y);
}
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]);
if (p_enabled) {
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 {
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]);
return setting->axis_flags.has_flag(AXIS_FLAG_Z);
}
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]);
if (p_enabled) {
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 {
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]);
return setting->invert_flags.has_flag(AXIS_FLAG_X);
}
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]);
if (p_enabled) {
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 {
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]);
return setting->invert_flags.has_flag(AXIS_FLAG_Y);
}
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]);
if (p_enabled) {
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 {
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]);
return setting->invert_flags.has_flag(AXIS_FLAG_Z);
}
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]);
setting->relative = p_enabled;
}
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]);
return setting->relative;
return setting->is_relative();
}
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]);
setting->additive = p_enabled;
}
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]);
return setting->additive;
}
@@ -351,16 +368,37 @@ void CopyTransformModifier3D::_bind_methods() {
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]);
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();
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.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;
Quaternion dest_rot = destination.basis.get_rotation_quaternion();
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.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);
} else if (setting->relative) {
} else if (setting->is_relative()) {
Transform3D rest = p_skeleton->get_bone_rest(p_apply_bone);
destination.origin = rest.origin + dest_pos;
destination.basis = rest.basis.get_rotation_quaternion() * Basis(dest_rot);