From 38f539e432d76febd565d0bbec1700c5bf770589 Mon Sep 17 00:00:00 2001 From: Jamie Greunbaum Date: Sat, 19 Sep 2026 02:03:49 -0400 Subject: [PATCH] Added a CharacterSkeleton3D class, for standardising skeleton builds. --- .../character_nodes/character_skeleton3d.cpp | 32 +++++++++ .../character_nodes/character_skeleton3d.h | 68 +++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 src/liborng/nodes/character_nodes/character_skeleton3d.cpp create mode 100644 src/liborng/nodes/character_nodes/character_skeleton3d.h diff --git a/src/liborng/nodes/character_nodes/character_skeleton3d.cpp b/src/liborng/nodes/character_nodes/character_skeleton3d.cpp new file mode 100644 index 0000000..75d2a30 --- /dev/null +++ b/src/liborng/nodes/character_nodes/character_skeleton3d.cpp @@ -0,0 +1,32 @@ +/* + * ©2026 Batty Bovine Productions, LLC. All Rights Reserved. + * + * If this source code makes it to the public internet, this software can be + * considered to be protected by the MIT licence. Have fun with it. + */ + +#include "character_skeleton3d.h" + +#include "orng_macros.h" + +#include +#include +using namespace godot; + + +void CharacterSkeleton3D::_activate_ragdoll() +{ + if (this->physical_bone_simulator) + { + const TypedArray &physical_bones = this->physical_bone_simulator->get_children(); + const uint32_t num_physical_bones = physical_bones.size(); + for (uint32_t i = 0; i < num_physical_bones; i++) + { + if (PhysicalBone3D *bone = cast_to(physical_bones[i])) + { + bone->set_collision_layer(0); + } + } + this->physical_bone_simulator->physical_bones_start_simulation(); + } +} diff --git a/src/liborng/nodes/character_nodes/character_skeleton3d.h b/src/liborng/nodes/character_nodes/character_skeleton3d.h new file mode 100644 index 0000000..a16f7f4 --- /dev/null +++ b/src/liborng/nodes/character_nodes/character_skeleton3d.h @@ -0,0 +1,68 @@ +/* + * ©2026 Batty Bovine Productions, LLC. All Rights Reserved. + * + * If this source code makes it to the public internet, this software can be + * considered to be protected by the MIT licence. Have fun with it. + */ + +#pragma once + +#include "orng_macros.h" + +#include +#include +#include +#include +#include +using namespace godot; + +#define CHARACTER_SKELETON3D_TAG "CharacterSkeleton3D" + + +class CharacterSkeleton3D : public Node3D +{ + GDCLASS(CharacterSkeleton3D, Node3D); + +public: + Skeleton3D *get_skeleton() const { return this->skeleton; } + PhysicalBoneSimulator3D *get_physical_bone_simulator() const { return this->physical_bone_simulator; } + AnimationPlayer *get_animation_player() const { return this->animation_player; } + AnimationTree *get_animation_tree() const { return this->animation_tree; } + +protected: + void set_skeleton(Skeleton3D *s) { this->skeleton = s; } + void set_physical_bone_simulator(PhysicalBoneSimulator3D *pbs) { this->physical_bone_simulator = pbs; } + void set_animation_player(AnimationPlayer *ap) { this->animation_player = ap; } + void set_animation_tree(AnimationTree *at) { this->animation_tree = at; } + +private: + void _refresh_skins_and_meshes(); + + void _activate_ragdoll(); + + Skeleton3D *skeleton = nullptr; + PhysicalBoneSimulator3D *physical_bone_simulator = nullptr; + AnimationPlayer *animation_player = nullptr; + AnimationTree *animation_tree = nullptr; + +// Godot boilerplate below +protected: + static void _bind_methods() + { + ClassDB::bind_method(D_METHOD("get_skeleton"), &CharacterSkeleton3D::get_skeleton); + ClassDB::bind_method(D_METHOD("set_skeleton", "skeleton"), &CharacterSkeleton3D::set_skeleton); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "skeleton", PROPERTY_HINT_NODE_TYPE, "Skeleton3D"), "set_skeleton", "get_skeleton"); + + ClassDB::bind_method(D_METHOD("get_physical_bone_simulator"), &CharacterSkeleton3D::get_physical_bone_simulator); + ClassDB::bind_method(D_METHOD("set_physical_bone_simulator", "physical_bone_simulator"), &CharacterSkeleton3D::set_physical_bone_simulator); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "physical_bone_simulator", PROPERTY_HINT_NODE_TYPE, "PhysicalBoneSimulator3D"), "set_physical_bone_simulator", "get_physical_bone_simulator"); + + ClassDB::bind_method(D_METHOD("get_animation_player"), &CharacterSkeleton3D::get_animation_player); + ClassDB::bind_method(D_METHOD("set_animation_player", "animation_player"), &CharacterSkeleton3D::set_animation_player); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "animation_player", PROPERTY_HINT_NODE_TYPE, "AnimationPlayer"), "set_animation_player", "get_animation_player"); + + ClassDB::bind_method(D_METHOD("get_animation_tree"), &CharacterSkeleton3D::get_animation_tree); + ClassDB::bind_method(D_METHOD("set_animation_tree", "animation_tree"), &CharacterSkeleton3D::set_animation_tree); + ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "animation_tree", PROPERTY_HINT_NODE_TYPE, "AnimationTree"), "set_animation_tree", "get_animation_tree"); + } +};