More work on ItemVisuals.

This commit is contained in:
Relintai 2019-10-26 03:38:09 +02:00
parent 5ea15ab1c9
commit 56a333bef5
6 changed files with 294 additions and 55 deletions

View File

@ -1,9 +1,31 @@
#include "character_skeleton.h"
void CharacterSkeleton::add_item_visual(Ref<ItemVisual> vis) {
}
void CharacterSkeleton::remove_item_visual(Ref<ItemVisual> vis) {
}
void CharacterSkeleton::remove_item_visual_index(int index) {
}
Ref<ItemVisual> CharacterSkeleton::get_item_visual(int index) {
return Ref<ItemVisual>();
}
int CharacterSkeleton::get_item_visual_count() {
return 0;
}
void CharacterSkeleton::clear_item_visuals() {
}
CharacterSkeleton::CharacterSkeleton() {
}
CharacterSkeleton::~CharacterSkeleton() {
}
void CharacterSkeleton::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_item_visual", "vis"), &CharacterSkeleton::add_item_visual);
ClassDB::bind_method(D_METHOD("remove_item_visual", "vis"), &CharacterSkeleton::remove_item_visual);
ClassDB::bind_method(D_METHOD("remove_item_visual_index", "index"), &CharacterSkeleton::remove_item_visual_index);
ClassDB::bind_method(D_METHOD("get_item_visual", "index"), &CharacterSkeleton::get_item_visual);
ClassDB::bind_method(D_METHOD("get_item_visual_count"), &CharacterSkeleton::get_item_visual_count);
ClassDB::bind_method(D_METHOD("clear_item_visuals"), &CharacterSkeleton::clear_item_visuals);
}

View File

@ -9,34 +9,30 @@
#include "core/node_path.h"
#include "core/ustring.h"
#include "scene/animation/animation_player.h"
#include "scene/animation/animation_tree.h"
#include "core/vector.h"
#include "../data/character_skeleton_visual_entry.h"
#include "../entity_enums.h"
#include "../data/item_visual.h"
#ifdef ENTITIES_2D
class CharacterSkeleton : public Node2D {
GDCLASS(CharacterSkeleton, Node2D);
#else
class CharacterSkeleton : public Spatial {
GDCLASS(CharacterSkeleton, Spatial);
#endif
public:
//virtual void add_item_visual(Ref<ItemVisual> vis);
//virtual void remove_item_visual(Ref<ItemVisual> vis);
//virtual Ref<ItemVisual> get_item_visual();
//virtual int get_item_visual_count();
//virtual void clear_item_visuals();
virtual void add_item_visual(Ref<ItemVisual> vis);
virtual void remove_item_visual(Ref<ItemVisual> vis);
virtual void remove_item_visual_index(int index);
virtual Ref<ItemVisual> get_item_visual(int index);
virtual int get_item_visual_count();
virtual void clear_item_visuals();
CharacterSkeleton();
~CharacterSkeleton();
protected:
static void _bind_methods();

View File

@ -2,14 +2,21 @@
#include "../data/item_visual.h"
bool CharacterSkeleton3D::get_model_dirty() const {
return _model_dirty;
}
void CharacterSkeleton3D::set_model_dirty(bool value) {
_model_dirty = value;
}
NodePath CharacterSkeleton3D::get_bone_path(int index) {
ERR_FAIL_INDEX_V(index, EntityEnums::SKELETON_POINTS_MAX, NodePath());
ERR_FAIL_INDEX_V(index, EntityEnums::SKELETON_POINTS_MAX, NodePath());
return _bone_paths[index];
}
void CharacterSkeleton3D::set_bone_path(int index, NodePath path) {
ERR_FAIL_INDEX(index, EntityEnums::SKELETON_POINTS_MAX);
ERR_FAIL_INDEX(index, EntityEnums::SKELETON_POINTS_MAX);
_bone_paths[index] = path;
_bone_nodes[index] = get_node_or_null(path);
@ -72,14 +79,151 @@ AnimationTree *CharacterSkeleton3D::get_animation_tree() {
void CharacterSkeleton3D::update_nodes() {
for (int i = 0; i < EntityEnums::SKELETON_POINTS_MAX; ++i) {
_bone_nodes[i] = get_node_or_null(_bone_paths[i]);
}
_bone_nodes[i] = get_node_or_null(_bone_paths[i]);
}
set_animation_player_path(_animation_player_path);
set_animation_tree_path(_animation_tree_path);
}
void CharacterSkeleton3D::add_item_visual(Ref<ItemVisual> vis) {
ERR_FAIL_COND(!vis.is_valid());
for (int i = 0; i < EntityEnums::SKELETON_POINTS_MAX; ++i) {
Ref<ItemVisualEntry> e = vis->get_visual(i);
if (e.is_valid())
add_item_visual_entry(vis, e);
}
_item_visuals.push_back(vis);
}
void CharacterSkeleton3D::remove_item_visual(Ref<ItemVisual> vis) {
ERR_FAIL_COND(!vis.is_valid());
int index = _item_visuals.find(vis);
if (index == -1)
return;
for (int i = 0; i < EntityEnums::SKELETON_POINTS_MAX; ++i) {
Ref<ItemVisualEntry> e = vis->get_visual(i);
if (e.is_valid())
remove_item_visual_entry(vis, e);
}
_item_visuals.remove(index);
}
void CharacterSkeleton3D::remove_item_visual_index(int index) {
ERR_FAIL_INDEX(index, _item_visuals.size());
_item_visuals.remove(index);
}
Ref<ItemVisual> CharacterSkeleton3D::get_item_visual(int index) {
ERR_FAIL_INDEX_V(index, _item_visuals.size(), Ref<ItemVisual>());
return _item_visuals.get(index);
}
int CharacterSkeleton3D::get_item_visual_count() {
return _item_visuals.size();
}
void CharacterSkeleton3D::clear_item_visuals() {
_item_visuals.clear();
for (int i = 0; i < EntityEnums::SKELETON_POINTS_MAX; ++i) {
_entries[i].clear();
}
_model_dirty = true;
set_process(true);
}
void CharacterSkeleton3D::add_item_visual_entry(Ref<ItemVisual> vis, Ref<ItemVisualEntry> ive) {
ERR_FAIL_COND(!vis.is_valid());
ERR_FAIL_COND(!ive.is_valid());
int target_bone_idx = static_cast<int>(ive->get_target_bone());
Vector<Ref<SkeletonModelEntry> > &entries = _entries[target_bone_idx];
for (int i = 0; i < entries.size(); ++i) {
Ref<SkeletonModelEntry> e = entries.get(i);
if (e->get_entry() == ive) {
e->set_count(e->get_count() + 1);
return;
}
}
Ref<SkeletonModelEntry> e;
e.instance();
e->set_priority(static_cast<int>(vis->get_layer()));
e->set_color(ive->get_color());
e->set_entry(ive);
entries.push_back(e);
_model_dirty = true;
set_process(true);
}
void CharacterSkeleton3D::remove_item_visual_entry(Ref<ItemVisual> vis, Ref<ItemVisualEntry> ive) {
ERR_FAIL_COND(!vis.is_valid());
ERR_FAIL_COND(!ive.is_valid());
int target_bone_idx = static_cast<int>(ive->get_target_bone());
Vector<Ref<SkeletonModelEntry> > &entries = _entries[target_bone_idx];
for (int i = 0; i < entries.size(); ++i) {
Ref<SkeletonModelEntry> e = entries.get(i);
if (e->get_entry() == ive) {
e->set_count(e->get_count() - 1);
if (e->get_count() <= 0) {
entries.remove(i);
_model_dirty = true;
set_process(true);
}
return;
}
}
}
Ref<SkeletonModelEntry> CharacterSkeleton3D::get_model_entry(const int bone_index, const int index) {
ERR_FAIL_INDEX_V(bone_index, EntityEnums::SKELETON_POINTS_MAX, Ref<SkeletonModelEntry>());
ERR_FAIL_INDEX_V(index, _entries[bone_index].size(), Ref<SkeletonModelEntry>());
return _entries[bone_index].get(index);
}
int CharacterSkeleton3D::get_model_entry_count(const int bone_index) {
ERR_FAIL_INDEX_V(bone_index, EntityEnums::SKELETON_POINTS_MAX, 0);
return _entries[bone_index].size();
}
void CharacterSkeleton3D::sort_layers() {
for (int i = 0; i < EntityEnums::SKELETON_POINTS_MAX; ++i) {
Vector<Ref<SkeletonModelEntry> > &entries = _entries[i];
entries.sort_custom<_ModelEntryComparator>();
}
}
void CharacterSkeleton3D::build_model() {
call("_build_model");
}
void CharacterSkeleton3D::_build_model() {
set_process(false);
}
CharacterSkeleton3D::CharacterSkeleton3D() {
_model_dirty = false;
for (int i = 0; i < EntityEnums::SKELETON_POINTS_MAX; ++i) {
_bone_nodes[i] = NULL;
}
@ -87,12 +231,24 @@ CharacterSkeleton3D::CharacterSkeleton3D() {
_animation_player = NULL;
}
CharacterSkeleton3D::~CharacterSkeleton3D() {
for (int i = 0; i < EntityEnums::SKELETON_POINTS_MAX; ++i) {
_entries[i].clear();
_visuals[i].unref();
}
_item_visuals.clear();
}
void CharacterSkeleton3D::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
update_nodes();
} break;
case NOTIFICATION_PROCESS: {
if (_model_dirty)
build_model();
} break;
case NOTIFICATION_EXIT_TREE: {
@ -101,13 +257,49 @@ void CharacterSkeleton3D::_notification(int p_what) {
}
void CharacterSkeleton3D::_bind_methods() {
BIND_VMETHOD(MethodInfo("_build_model"));
ClassDB::bind_method(D_METHOD("get_model_dirty"), &CharacterSkeleton3D::get_model_dirty);
ClassDB::bind_method(D_METHOD("set_model_dirty", "value"), &CharacterSkeleton3D::set_model_dirty);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "model_dirty"), "set_model_dirty", "get_model_dirty");
ClassDB::bind_method(D_METHOD("get_animation_player_path"), &CharacterSkeleton3D::get_animation_player_path);
ClassDB::bind_method(D_METHOD("set_animation_player_path", "path"), &CharacterSkeleton3D::set_animation_player_path);
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "animation_player_path"), "set_animation_player_path", "get_animation_player_path");
ClassDB::bind_method(D_METHOD("get_animation_tree_path"), &CharacterSkeleton3D::get_animation_tree_path);
ClassDB::bind_method(D_METHOD("set_animation_tree_path", "path"), &CharacterSkeleton3D::set_animation_tree_path);
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "animation_tree_path"), "set_animation_tree_path", "get_animation_tree_path");
ClassDB::bind_method(D_METHOD("add_item_visual_entry", "vis", "ive"), &CharacterSkeleton3D::add_item_visual_entry);
ClassDB::bind_method(D_METHOD("remove_item_visual_entry", "vis", "ive"), &CharacterSkeleton3D::remove_item_visual_entry);
ClassDB::bind_method(D_METHOD("get_model_entry", "bone_index", "index"), &CharacterSkeleton3D::get_model_entry);
ClassDB::bind_method(D_METHOD("get_model_entry_count", "bone_index"), &CharacterSkeleton3D::get_model_entry_count);
ClassDB::bind_method(D_METHOD("sort_layers"), &CharacterSkeleton3D::sort_layers);
ClassDB::bind_method(D_METHOD("build_model"), &CharacterSkeleton3D::build_model);
ClassDB::bind_method(D_METHOD("_build_model"), &CharacterSkeleton3D::_build_model);
//Bone Paths
ClassDB::bind_method(D_METHOD("get_bone_path", "index"), &CharacterSkeleton3D::get_bone_path);
ClassDB::bind_method(D_METHOD("set_bone_path", "index", "path"), &CharacterSkeleton3D::set_bone_path);
ADD_GROUP("Bone Paths", "bone_path_");
ADD_PROPERTYI(PropertyInfo(Variant::NODE_PATH, "bone_path_root"), "set_bone_path", "get_bone_path", EntityEnums::SKELETON_POINT_ROOT);
ClassDB::bind_method(D_METHOD("get_bone_node", "bone_idx"), &CharacterSkeleton3D::get_bone_node);
ClassDB::bind_method(D_METHOD("get_animation_player"), &CharacterSkeleton3D::get_animation_player);
ClassDB::bind_method(D_METHOD("get_animation_tree"), &CharacterSkeleton3D::get_animation_tree);
ClassDB::bind_method(D_METHOD("update_nodes"), &CharacterSkeleton3D::update_nodes);
//Visuals
ClassDB::bind_method(D_METHOD("get_visual", "index"), &CharacterSkeleton3D::get_visual);
ClassDB::bind_method(D_METHOD("set_visual", "index", "entry"), &CharacterSkeleton3D::set_visual);
ADD_GROUP("Visuals", "visual_");
ADD_GROUP("Visuals", "visual_");
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "visual_root", PROPERTY_HINT_RESOURCE_TYPE, "CharacterSkeletonVisualEntry"), "set_visual", "get_visual", EntityEnums::SKELETON_POINT_ROOT);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "visual_pelvis", PROPERTY_HINT_RESOURCE_TYPE, "CharacterSkeletonVisualEntry"), "set_visual", "get_visual", EntityEnums::SKELETON_POINT_PELVIS);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "visual_spine", PROPERTY_HINT_RESOURCE_TYPE, "CharacterSkeletonVisualEntry"), "set_visual", "get_visual", EntityEnums::SKELETON_POINT_SPINE);
@ -141,22 +333,4 @@ void CharacterSkeleton3D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "visual_right_thigh", PROPERTY_HINT_RESOURCE_TYPE, "CharacterSkeletonVisualEntry"), "set_visual", "get_visual", EntityEnums::SKELETON_POINT_RIGHT_THIGH);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "visual_right_calf", PROPERTY_HINT_RESOURCE_TYPE, "CharacterSkeletonVisualEntry"), "set_visual", "get_visual", EntityEnums::SKELETON_POINT_RIGHT_CALF);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "visual_right_foot", PROPERTY_HINT_RESOURCE_TYPE, "CharacterSkeletonVisualEntry"), "set_visual", "get_visual", EntityEnums::SKELETON_POINT_RIGHT_FOOT);
ADD_GROUP("Bone Paths", "bone_path_");
ADD_PROPERTYI(PropertyInfo(Variant::NODE_PATH, "bone_path_root"), "set_bone_path", "get_bone_path", EntityEnums::SKELETON_POINT_ROOT);
ClassDB::bind_method(D_METHOD("get_bone_node", "bone_idx"), &CharacterSkeleton3D::get_bone_node);
ClassDB::bind_method(D_METHOD("get_animation_player_path"), &CharacterSkeleton3D::get_animation_player_path);
ClassDB::bind_method(D_METHOD("set_animation_player_path", "path"), &CharacterSkeleton3D::set_animation_player_path);
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "animation_player_path"), "set_animation_player_path", "get_animation_player_path");
ClassDB::bind_method(D_METHOD("get_animation_tree_path"), &CharacterSkeleton3D::get_animation_tree_path);
ClassDB::bind_method(D_METHOD("set_animation_tree_path", "path"), &CharacterSkeleton3D::set_animation_tree_path);
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "animation_tree_path"), "set_animation_tree_path", "get_animation_tree_path");
ClassDB::bind_method(D_METHOD("get_animation_player"), &CharacterSkeleton3D::get_animation_player);
ClassDB::bind_method(D_METHOD("get_animation_tree"), &CharacterSkeleton3D::get_animation_tree);
ClassDB::bind_method(D_METHOD("update_nodes"), &CharacterSkeleton3D::update_nodes);
}

View File

@ -12,13 +12,20 @@
#include "../data/character_skeleton_visual_entry.h"
#include "../entity_enums.h"
#include "skeleton_model_entry.h"
#include "../data/item_visual_entry.h"
class ItemVisual;
//Rename to HumanoidCharSkeleton
class CharacterSkeleton3D : public CharacterSkeleton {
GDCLASS(CharacterSkeleton3D, CharacterSkeleton);
public:
bool get_model_dirty() const;
void set_model_dirty(bool value);
NodePath get_bone_path(int index);
void set_bone_path(int index, NodePath path);
@ -37,20 +44,44 @@ public:
AnimationTree *get_animation_tree();
//void add_item_visual(Ref<ItemVisual> vis);
//void remove_item_visual(Ref<ItemVisual> vis);
//Ref<ItemVisual> get_item_visual();
//int get_item_visual_count();
//void clear_item_visuals();
void update_nodes();
void add_item_visual(Ref<ItemVisual> vis);
void remove_item_visual(Ref<ItemVisual> vis);
void remove_item_visual_index(int index);
Ref<ItemVisual> get_item_visual(int index);
int get_item_visual_count();
void clear_item_visuals();
void add_item_visual_entry(Ref<ItemVisual> vis, Ref<ItemVisualEntry> ive);
void remove_item_visual_entry(Ref<ItemVisual> vis, Ref<ItemVisualEntry> ive);
Ref<SkeletonModelEntry> get_model_entry(const int bone_index, const int index);
int get_model_entry_count(const int bone_index);
void sort_layers();
void build_model();
void _build_model();
CharacterSkeleton3D();
~CharacterSkeleton3D();
protected:
static void _bind_methods();
virtual void _notification(int p_notification);
protected:
struct _ModelEntryComparator {
_FORCE_INLINE_ bool operator()(const Ref<SkeletonModelEntry> &a, const Ref<SkeletonModelEntry> &b) const {
if (!a.is_valid() || !b.is_valid()) {
return false;
}
return (a->get_priority() < b->get_priority());
}
};
private:
NodePath _animation_player_path;
NodePath _animation_tree_path;
@ -62,11 +93,11 @@ private:
Node *_bone_nodes[EntityEnums::SKELETON_POINTS_MAX];
Vector<Ref<ItemVisual> > _item_visuals;
Ref<CharacterSkeletonVisualEntry> _visuals[EntityEnums::SKELETON_POINTS_MAX];
Vector<Ref<CharacterSkeletonVisualEntry> > _entries[EntityEnums::SKELETON_POINTS_MAX];
bool _model_dirty;
Vector<Ref<ItemVisual> > _item_visuals;
Vector<Ref<SkeletonModelEntry> > _entries[EntityEnums::SKELETON_POINTS_MAX];
};

View File

@ -1,16 +1,23 @@
#include "skeleton_model_entry.h"
int SkeletonModelEntry::get_priority() {
int SkeletonModelEntry::get_count() const {
return _count;
}
void SkeletonModelEntry::set_count(const int value) {
_count = value;
}
int SkeletonModelEntry::get_priority() const {
return _priority;
}
void SkeletonModelEntry::set_priority(int value) {
void SkeletonModelEntry::set_priority(const int value) {
_priority = value;
}
Color SkeletonModelEntry::get_color() {
Color SkeletonModelEntry::get_color() const {
return _color;
}
void SkeletonModelEntry::set_color(Color value) {
void SkeletonModelEntry::set_color(const Color value) {
_color = value;
}
@ -22,6 +29,7 @@ void SkeletonModelEntry::set_entry(Ref<ItemVisualEntry> entry) {
}
SkeletonModelEntry::SkeletonModelEntry() {
_count = 1;
_priority = 0;
_color = Color(1, 1, 1, 1);
}
@ -31,6 +39,10 @@ SkeletonModelEntry::~SkeletonModelEntry() {
}
void SkeletonModelEntry::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_count"), &SkeletonModelEntry::get_count);
ClassDB::bind_method(D_METHOD("set_count", "value"), &SkeletonModelEntry::set_count);
ADD_PROPERTY(PropertyInfo(Variant::INT, "count"), "set_count", "get_count");
ClassDB::bind_method(D_METHOD("get_priority"), &SkeletonModelEntry::get_priority);
ClassDB::bind_method(D_METHOD("set_priority", "value"), &SkeletonModelEntry::set_priority);
ADD_PROPERTY(PropertyInfo(Variant::INT, "priority"), "set_priority", "get_priority");

View File

@ -8,11 +8,14 @@ class SkeletonModelEntry : public Reference {
GDCLASS(SkeletonModelEntry, Reference);
public:
int get_priority();
void set_priority(int value);
int get_count() const;
void set_count(const int value);
Color get_color();
void set_color(Color value);
int get_priority() const;
void set_priority(const int value);
Color get_color() const;
void set_color(const Color value);
Ref<ItemVisualEntry> get_entry();
void set_entry(Ref<ItemVisualEntry> entry);
@ -24,6 +27,7 @@ protected:
static void _bind_methods();
private:
int _count;
int _priority;
Color _color;
Ref<ItemVisualEntry> _entry;