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

@@ -36,10 +36,12 @@ bool BoneConstraint3D::_set(const StringName &p_path, const Variant &p_value) {
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 == "amount") {
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") {
set_apply_bone_name(which, p_value);
} 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);
} else if (what == "reference_bone") {
set_reference_bone(which, p_value);
} else if (what == "reference_node") {
set_reference_node(which, p_value);
} else {
return false;
}
@@ -61,10 +65,12 @@ bool BoneConstraint3D::_get(const StringName &p_path, Variant &r_ret) const {
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 == "amount") {
r_ret = get_amount(which);
} else if (what == "reference_type") {
r_ret = (int)get_reference_type(which);
} else if (what == "apply_bone_name") {
r_ret = get_apply_bone_name(which);
} 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);
} else if (what == "reference_bone") {
r_ret = get_reference_bone(which);
} else if (what == "reference_node") {
r_ret = get_reference_node(which);
} else {
return false;
}
@@ -87,23 +95,46 @@ void BoneConstraint3D::get_property_list(List<PropertyInfo> *p_list) const {
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) + "/";
p_list->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));
p_list->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));
p_list->push_back(PropertyInfo(Variant::INT, path + "reference_bone", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
props.push_back(PropertyInfo(Variant::FLOAT, path + "amount", PROPERTY_HINT_RANGE, "0,1,0.001"));
props.push_back(PropertyInfo(Variant::STRING, path + "apply_bone_name", PROPERTY_HINT_ENUM_SUGGESTION, enum_hint));
props.push_back(PropertyInfo(Variant::INT, path + "apply_bone", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
props.push_back(PropertyInfo(Variant::INT, path + "reference_type", PROPERTY_HINT_ENUM, "Bone,Node"));
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) {
ERR_FAIL_COND(p_count < 0);
int delta = p_count - settings.size();
int delta = p_count - (int)settings.size();
if (delta < 0) {
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);
@@ -119,11 +150,11 @@ void BoneConstraint3D::set_setting_count(int p_count) {
}
int BoneConstraint3D::get_setting_count() const {
return settings.size();
return (int)settings.size();
}
void BoneConstraint3D::_validate_setting(int p_index) {
settings.write[p_index] = memnew(BoneConstraint3DSetting);
settings[p_index] = memnew(BoneConstraint3DSetting);
}
void BoneConstraint3D::clear_settings() {
@@ -131,17 +162,17 @@ void BoneConstraint3D::clear_settings() {
}
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;
}
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;
}
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;
Skeleton3D *sk = get_skeleton();
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 {
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;
}
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;
Skeleton3D *sk = get_skeleton();
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 {
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;
}
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) {
ERR_FAIL_INDEX(p_index, settings.size());
ERR_FAIL_INDEX(p_index, (int)settings.size());
settings[p_index]->reference_bone_name = p_bone_name;
Skeleton3D *sk = get_skeleton();
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 {
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;
}
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;
Skeleton3D *sk = get_skeleton();
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 {
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;
}
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() {
ClassDB::bind_method(D_METHOD("set_amount", "index", "amount"), &BoneConstraint3D::set_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("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("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("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("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("get_setting_count"), &BoneConstraint3D::get_setting_count);
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() {
for (int i = 0; i < settings.size(); i++) {
for (int i = 0; i < (int)settings.size(); i++) {
// Prior bone name.
if (!settings[i]->apply_bone_name.is_empty()) {
set_apply_bone_name(i, settings[i]->apply_bone_name);
@@ -246,27 +305,38 @@ void BoneConstraint3D::_process_modification(double p_delta) {
return;
}
for (int i = 0; i < 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;
}
for (int i = 0; i < (int)settings.size(); i++) {
float amount = settings[i]->amount;
if (amount <= 0) {
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) {
//
}