Skip to content

Commit

Permalink
misc tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
Invertex committed Jan 20, 2024
1 parent d76c1d0 commit 62a98c4
Show file tree
Hide file tree
Showing 5 changed files with 248 additions and 1 deletion.
11 changes: 11 additions & 0 deletions editor/import/post_import_plugin_skeleton_renamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "scene/3d/skeleton_3d.h"
#include "scene/animation/animation_player.h"
#include "scene/resources/bone_map.h"
#include <scene/resources/bindpose_data.h>

void PostImportPluginSkeletonRenamer::get_internal_import_options(InternalImportCategory p_category, List<ResourceImporter::ImportOption> *r_options) {
if (p_category == INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE) {
Expand All @@ -53,6 +54,16 @@ void PostImportPluginSkeletonRenamer::_internal_process(InternalImportCategory p
}
Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_node);

// Store Skeleton's bind-pose in this file's .import data, and potentially load a Bindpose to use from another file.
{
Object *bindpose_data = p_options["import/bindpose_data"].get_validated_object();
if (bindpose_data && bindpose_data->is_class("BindposeData")) {
print_line("set bindpose");
BindposeData *bpose = Object::cast_to<BindposeData>(bindpose_data);
bpose->process_skeleton(p_base_scene, skeleton);
}
}

// Rename bones in Skeleton3D.
{
int len = skeleton->get_bone_count();
Expand Down
2 changes: 2 additions & 0 deletions editor/import/resource_importer_scene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "scene/3d/vehicle_body_3d.h"
#include "scene/animation/animation_player.h"
#include "scene/resources/animation.h"
#include "scene/resources/bindpose_data.h"
#include "scene/resources/box_shape_3d.h"
#include "scene/resources/importer_mesh.h"
#include "scene/resources/packed_scene.h"
Expand Down Expand Up @@ -1742,6 +1743,7 @@ void ResourceImporterScene::get_internal_import_options(InternalImportCategory p
} break;
case INTERNAL_IMPORT_CATEGORY_SKELETON_3D_NODE: {
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "import/skip_import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::OBJECT, "import/bindpose_data", PROPERTY_HINT_RESOURCE_TYPE, "BindposeData", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), Variant()));
r_options->push_back(ImportOption(PropertyInfo(Variant::OBJECT, "retarget/bone_map", PROPERTY_HINT_RESOURCE_TYPE, "BoneMap", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), Variant()));
} break;
default: {
Expand Down
3 changes: 2 additions & 1 deletion scene/register_scene_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@
#include "scene/resources/atlas_texture.h"
#include "scene/resources/audio_stream_polyphonic.h"
#include "scene/resources/audio_stream_wav.h"
#include "scene/resources/bindpose_data.h"
#include "scene/resources/bit_map.h"
#include "scene/resources/bone_map.h"
#include "scene/resources/box_shape_3d.h"
Expand Down Expand Up @@ -930,7 +931,7 @@ void register_scene_types() {
GDREGISTER_CLASS(SkeletonProfile);
GDREGISTER_CLASS(SkeletonProfileHumanoid);
GDREGISTER_CLASS(BoneMap);

GDREGISTER_CLASS(BindposeData);
OS::get_singleton()->yield(); // may take time to init

GDREGISTER_CLASS(AudioStreamPlayer);
Expand Down
176 changes: 176 additions & 0 deletions scene/resources/bindpose_data.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
/**************************************************************************/
/* bindpose_data.cpp */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#include "bindpose_data.h"
#include "scene/3d/skeleton_3d.h"
#include <core/io/config_file.h>

bool BindposeData::_set(const StringName &p_path, const Variant &p_value) {
String path = p_path;
if (path == "source_pose") {
source_pose = p_value;
return true;
}
if (path == "store_source_bindpose") {
store_source_bindpose = p_value;
return true;
}
if (path == "load_source_bindpose_from_other") {
load_source_bindpose_from_other = p_value;
return true;
}
return false;
}

bool BindposeData::_get(const StringName &p_path, Variant &r_ret) const {
String path = p_path;
if (path == "source_pose") {
r_ret = source_pose;
return true;
}
if (path == "store_source_bindpose") {
r_ret = store_source_bindpose;
return true;
}
if (path == "load_source_bindpose_from_other") {
r_ret = load_source_bindpose_from_other;
return true;
}
return false;
}

void BindposeData::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::BOOL, "store_source_bindpose", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED));
if (!store_source_bindpose) {
p_list->push_back(PropertyInfo(Variant::STRING, "load_source_bindpose_from_other", PROPERTY_HINT_FILE, "*.import, *.res", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED));
}
p_list->push_back(PropertyInfo(Variant::DICTIONARY, "source_pose", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR));
}


Dictionary BindposeData::get_referenced_pose(Node *p_root, Node *p_skeleton) {
Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_skeleton);
Dictionary empty;
print_line("get ref pose");
if (!skeleton) {
print_error("Value passed in that was not a Skeleton3D.");
return empty;
}
String target_import_path = load_source_bindpose_from_other;
if (!load_source_bindpose_from_other.is_empty()) {
if (!FileAccess::exists(target_import_path)) {
print_error("Could find file at: " + target_import_path);
} else {
Ref<ConfigFile> cf;
cf.instantiate();
Error err = cf->load(target_import_path);
if (err == OK && cf->has_section_key("params", "_subresources")) {
Dictionary subresources = cf->get_value("params", "_subresources");
print_line("get params");
Dictionary nodes;
if (subresources.has("nodes")) {
nodes = subresources["nodes"];
String skeleton_path = "PATH:" + p_root->get_path_to(p_skeleton);
print_line("found skel");
print_line(skeleton_path);

if (nodes.has(skeleton_path)) {
print_line("has skelly path");
Dictionary skeleton_data = nodes[skeleton_path];
if (skeleton_data.has("import/bindpose_data")) {
print_line("skelly has bindpose");
BindposeData *bindpose_data = Object::cast_to<BindposeData>(skeleton_data["import/bindpose_data"]);
print_line(bindpose_data->store_source_bindpose);
return bindpose_data->source_pose;
}

}
}
}
}
}
return empty;
}

void BindposeData::process_skeleton(Node *p_root, Node *p_skeleton) {
Skeleton3D *skeleton = Object::cast_to<Skeleton3D>(p_skeleton);
if (!skeleton) {
print_error("Value passed in that was not a Skeleton3D.");
return;
}
if (store_source_bindpose) {
source_pose["basis"] = skeleton->get_basis();

int bone_count = skeleton->get_bone_count();
for (int i = 0; i < bone_count; i++) {
source_pose[skeleton->get_bone_name(i)] = skeleton->get_bone_rest(i);
}
}
Dictionary &referenced_pose = get_referenced_pose(p_root, p_skeleton);

Check failure on line 136 in scene/resources/bindpose_data.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor w/ Mono (target=editor)

cannot bind non-const lvalue reference of type 'Dictionary&' to an rvalue of type 'Dictionary'

Check failure on line 136 in scene/resources/bindpose_data.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor with doubles and GCC sanitizers (target=editor, tests=yes, dev_build=yes, scu_build=yes, precision=double, use_asan=yes, use_ubsan=yes, linker=gold)

cannot bind non-const lvalue reference of type 'Dictionary&' to an rvalue of type 'Dictionary'

Check failure on line 136 in scene/resources/bindpose_data.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor with clang sanitizers (target=editor, tests=yes, dev_build=yes, use_asan=yes, use_ubsan=yes, use_llvm=yes, linker=lld)

non-const lvalue reference to type 'Dictionary' cannot bind to a temporary of type 'Dictionary'

Check failure on line 136 in scene/resources/bindpose_data.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Editor with ThreadSanitizer (target=editor, tests=yes, dev_build=yes, use_tsan=yes, use_llvm=yes, linker=lld)

non-const lvalue reference to type 'Dictionary' cannot bind to a temporary of type 'Dictionary'

Check failure on line 136 in scene/resources/bindpose_data.cpp

View workflow job for this annotation

GitHub Actions / 🏁 Windows / Template (target=template_release)

the following warning is treated as an error

Check warning on line 136 in scene/resources/bindpose_data.cpp

View workflow job for this annotation

GitHub Actions / 🏁 Windows / Template (target=template_release)

nonstandard extension used: 'initializing': conversion from 'Dictionary' to 'Dictionary &'

Check failure on line 136 in scene/resources/bindpose_data.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Template w/ Mono (target=template_release)

cannot bind non-const lvalue reference of type 'Dictionary&' to an rvalue of type 'Dictionary'

Check failure on line 136 in scene/resources/bindpose_data.cpp

View workflow job for this annotation

GitHub Actions / 🐧 Linux / Minimal template (target=template_release, everything disabled)

cannot bind non-const lvalue reference of type 'Dictionary&' to an rvalue of type 'Dictionary'
if (!referenced_pose.is_empty()) {
Basis skeleton_basis = referenced_pose["basis"];
skeleton->set_basis(skeleton_basis);

int bone_count = skeleton->get_bone_count();
for (int b = 0; b < bone_count; b++) {
String bone_name = skeleton->get_bone_name(b);
if (referenced_pose.has(bone_name)) {
print_line("Changed bone: " + bone_name);
Transform3D pose = referenced_pose[bone_name];
skeleton->set_bone_rest(b, pose);
skeleton->set_bone_pose_rotation(b, pose.basis.get_quaternion());
skeleton->set_bone_global_pose_override(b, pose, true);
}
}
//skeleton->reset_bone_poses();
}
notify_property_list_changed();
}

void BindposeData::_bind_methods() {
ClassDB::bind_method(D_METHOD("process_skeleton", "p_root", "skeleton"), &BindposeData::process_skeleton);
ClassDB::bind_method(D_METHOD("get_referenced_pose", "p_root", "skeleton"), &BindposeData::get_referenced_pose);
ADD_SIGNAL(MethodInfo("source_bindpose_updated"));
}

void BindposeData::_validate_property(PropertyInfo &property) const {
if (property.name == "import/bindpose_data") {
property.usage = PROPERTY_USAGE_NO_EDITOR;
}
}

BindposeData::BindposeData() {
store_source_bindpose = false;
}

BindposeData::~BindposeData() {
}

//////////////////////////////////////
57 changes: 57 additions & 0 deletions scene/resources/bindpose_data.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**************************************************************************/
/* bindpose_data.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#ifndef BINDPOSE_DATA_H
#define BINDPOSE_DATA_H

#include "core/io/resource.h"

class BindposeData : public Resource {
GDCLASS(BindposeData, Resource);
bool store_source_bindpose;
String load_source_bindpose_from_other;
Dictionary source_pose;

protected:
bool _get(const StringName &p_path, Variant &r_ret) const;
bool _set(const StringName &p_path, const Variant &p_value);
void _validate_property(PropertyInfo &p_property) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
static void _bind_methods();

public:
void process_skeleton(Node *p_root, Node *p_skeleton);
Dictionary get_referenced_pose(Node *p_root, Node *p_skeleton);

BindposeData();
~BindposeData();
};

#endif // BINDPOSE_DATA_H

0 comments on commit 62a98c4

Please sign in to comment.