summaryrefslogtreecommitdiff
path: root/scene/3d/skeleton_3d.h
diff options
context:
space:
mode:
Diffstat (limited to 'scene/3d/skeleton_3d.h')
-rw-r--r--scene/3d/skeleton_3d.h171
1 files changed, 104 insertions, 67 deletions
diff --git a/scene/3d/skeleton_3d.h b/scene/3d/skeleton_3d.h
index 08b8691658..c8a19db813 100644
--- a/scene/3d/skeleton_3d.h
+++ b/scene/3d/skeleton_3d.h
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,20 +31,17 @@
#ifndef SKELETON_3D_H
#define SKELETON_3D_H
-#include "core/rid.h"
#include "scene/3d/node_3d.h"
+#include "scene/resources/skeleton_modification_3d.h"
#include "scene/resources/skin.h"
-#ifndef _3D_DISABLED
typedef int BoneId;
class PhysicalBone3D;
-#endif // _3D_DISABLED
-
class Skeleton3D;
-class SkinReference : public Reference {
- GDCLASS(SkinReference, Reference)
+class SkinReference : public RefCounted {
+ GDCLASS(SkinReference, RefCounted)
friend class Skeleton3D;
Skeleton3D *skeleton_node;
@@ -65,44 +62,47 @@ public:
~SkinReference();
};
-class Skeleton3D : public Node3D {
+class SkeletonModificationStack3D;
+class Skeleton3D : public Node3D {
GDCLASS(Skeleton3D, Node3D);
private:
friend class SkinReference;
- Set<SkinReference *> skin_bindings;
-
- void _skin_changed();
-
struct Bone {
-
String name;
bool enabled;
int parent;
- int sort_index; //used for re-sorting process order
- bool disable_rest;
- Transform rest;
+ bool disable_rest = false;
+ Transform3D rest;
- Transform pose;
- Transform pose_global;
+ Transform3D pose;
+ Transform3D pose_global;
+ Transform3D pose_global_no_override;
- bool custom_pose_enable;
- Transform custom_pose;
+ bool custom_pose_enable = false;
+ Transform3D custom_pose;
- float global_pose_override_amount;
- bool global_pose_override_reset;
- Transform global_pose_override;
+ real_t global_pose_override_amount = 0.0;
+ bool global_pose_override_reset = false;
+ Transform3D global_pose_override;
-#ifndef _3D_DISABLED
- PhysicalBone3D *physical_bone;
- PhysicalBone3D *cache_parent_physical_bone;
-#endif // _3D_DISABLED
+ PhysicalBone3D *physical_bone = nullptr;
+ PhysicalBone3D *cache_parent_physical_bone = nullptr;
- List<ObjectID> nodes_bound;
+ real_t local_pose_override_amount;
+ bool local_pose_override_reset;
+ Transform3D local_pose_override;
+
+ Vector<int> child_bones;
+
+ // The forward direction vector and rest bone forward axis are cached because they do not change
+ // 99% of the time, but recalculating them can be expensive on models with many bones.
+ Vector3 rest_bone_forward_vector;
+ int rest_bone_forward_axis = -1;
Bone() {
parent = -1;
@@ -115,32 +115,29 @@ private:
physical_bone = nullptr;
cache_parent_physical_bone = nullptr;
#endif // _3D_DISABLED
+ local_pose_override_amount = 0;
+ local_pose_override_reset = false;
+ child_bones = Vector<int>();
+
+ rest_bone_forward_vector = Vector3(0, 0, 0);
+ rest_bone_forward_axis = -1;
}
};
- bool animate_physical_bones;
- Vector<Bone> bones;
- Vector<int> process_order;
- bool process_order_dirty;
-
- void _make_dirty();
- bool dirty;
+ Set<SkinReference *> skin_bindings;
- uint64_t version;
+ void _skin_changed();
- // bind helpers
- Array _get_bound_child_nodes_to_bone(int p_bone) const {
+ bool animate_physical_bones = true;
+ Vector<Bone> bones;
+ bool process_order_dirty;
- Array bound;
- List<Node *> children;
- get_bound_child_nodes_to_bone(p_bone, &children);
+ Vector<int> parentless_bones;
- for (int i = 0; i < children.size(); i++) {
+ void _make_dirty();
+ bool dirty = false;
- bound.push_back(children[i]);
- }
- return bound;
- }
+ uint64_t version = 1;
void _update_process_order();
@@ -151,9 +148,21 @@ protected:
void _notification(int p_what);
static void _bind_methods();
+#ifndef _3D_DISABLED
+ Ref<SkeletonModificationStack3D> modification_stack;
+#endif // _3D_DISABLED
+
public:
- enum {
+ enum Bone_Forward_Axis {
+ BONE_AXIS_X_FORWARD = 0,
+ BONE_AXIS_Y_FORWARD = 1,
+ BONE_AXIS_Z_FORWARD = 2,
+ BONE_AXIS_NEGATIVE_X_FORWARD = 3,
+ BONE_AXIS_NEGATIVE_Y_FORWARD = 4,
+ BONE_AXIS_NEGATIVE_Z_FORWARD = 5,
+ };
+ enum {
NOTIFICATION_UPDATE_SKELETON = 50
};
@@ -161,6 +170,7 @@ public:
void add_bone(const String &p_name);
int find_bone(const String &p_name) const;
String get_bone_name(int p_bone) const;
+ void set_bone_name(int p_bone, const String &p_name);
bool is_bone_parent_of(int p_bone_id, int p_parent_bone_id) const;
@@ -169,41 +179,69 @@ public:
void unparent_bone_and_rest(int p_bone);
+ Vector<int> get_bone_children(int p_bone);
+ void set_bone_children(int p_bone, Vector<int> p_children);
+ void add_bone_child(int p_bone, int p_child);
+ void remove_bone_child(int p_bone, int p_child);
+ Vector<int> get_parentless_bones();
+
void set_bone_disable_rest(int p_bone, bool p_disable);
bool is_bone_rest_disabled(int p_bone) const;
int get_bone_count() const;
- void set_bone_rest(int p_bone, const Transform &p_rest);
- Transform get_bone_rest(int p_bone) const;
- Transform get_bone_global_pose(int p_bone) const;
-
- void clear_bones_global_pose_override();
- void set_bone_global_pose_override(int p_bone, const Transform &p_pose, float p_amount, bool p_persistent = false);
+ void set_bone_rest(int p_bone, const Transform3D &p_rest);
+ Transform3D get_bone_rest(int p_bone) const;
+ Transform3D get_bone_global_pose(int p_bone) const;
+ Transform3D get_bone_global_pose_no_override(int p_bone) const;
void set_bone_enabled(int p_bone, bool p_enabled);
bool is_bone_enabled(int p_bone) const;
-
- void bind_child_node_to_bone(int p_bone, Node *p_node);
- void unbind_child_node_from_bone(int p_bone, Node *p_node);
- void get_bound_child_nodes_to_bone(int p_bone, List<Node *> *p_bound) const;
-
void clear_bones();
// posing api
- void set_bone_pose(int p_bone, const Transform &p_pose);
- Transform get_bone_pose(int p_bone) const;
+ void set_bone_pose(int p_bone, const Transform3D &p_pose);
+ Transform3D get_bone_pose(int p_bone) const;
+
+ void set_bone_custom_pose(int p_bone, const Transform3D &p_custom_pose);
+ Transform3D get_bone_custom_pose(int p_bone) const;
+
+ void clear_bones_global_pose_override();
+ Transform3D get_bone_global_pose_override(int p_bone) const;
+ void set_bone_global_pose_override(int p_bone, const Transform3D &p_pose, real_t p_amount, bool p_persistent = false);
- void set_bone_custom_pose(int p_bone, const Transform &p_custom_pose);
- Transform get_bone_custom_pose(int p_bone) const;
+ void clear_bones_local_pose_override();
+ Transform3D get_bone_local_pose_override(int p_bone) const;
+ void set_bone_local_pose_override(int p_bone, const Transform3D &p_pose, real_t p_amount, bool p_persistent = false);
void localize_rests(); // used for loaders and tools
- int get_process_order(int p_idx);
Ref<SkinReference> register_skin(const Ref<Skin> &p_skin);
+ void force_update_all_bone_transforms();
+ void force_update_bone_children_transforms(int bone_idx);
+
+ void update_bone_rest_forward_vector(int p_bone, bool p_force_update = false);
+ void update_bone_rest_forward_axis(int p_bone, bool p_force_update = false);
+ Vector3 get_bone_axis_forward_vector(int p_bone);
+ int get_bone_axis_forward_enum(int p_bone);
+
+ // Helper functions
+ Transform3D global_pose_to_world_transform(Transform3D p_global_pose);
+ Transform3D world_transform_to_global_pose(Transform3D p_transform);
+ Transform3D global_pose_to_local_pose(int p_bone_idx, Transform3D p_global_pose);
+ Transform3D local_pose_to_global_pose(int p_bone_idx, Transform3D p_local_pose);
+
+ Basis global_pose_z_forward_to_bone_forward(int p_bone_idx, Basis p_basis);
+
+ // Modifications
#ifndef _3D_DISABLED
+ Ref<SkeletonModificationStack3D> get_modification_stack();
+ void set_modification_stack(Ref<SkeletonModificationStack3D> p_stack);
+ void execute_modifications(real_t p_delta, int p_execution_mode);
+#endif // _3D_DISABLED
+
// Physical bone API
void set_animate_physical_bones(bool p_animate);
@@ -216,16 +254,15 @@ public:
PhysicalBone3D *get_physical_bone_parent(int p_bone);
private:
- /// This is a slow API os it's cached
+ /// This is a slow API, so it's cached
PhysicalBone3D *_get_physical_bone_parent(int p_bone);
void _rebuild_physical_bones_cache();
public:
void physical_bones_stop_simulation();
- void physical_bones_start_simulation_on(const Array &p_bones);
+ void physical_bones_start_simulation_on(const TypedArray<StringName> &p_bones);
void physical_bones_add_collision_exception(RID p_exception);
void physical_bones_remove_collision_exception(RID p_exception);
-#endif // _3D_DISABLED
public:
Skeleton3D();