2D Skeletons WORK IN PROGRESS
This commit is contained in:
parent
612ab4bbc6
commit
7cd867c3fe
17 changed files with 488 additions and 26 deletions
|
@ -619,7 +619,7 @@ public:
|
|||
void canvas_begin(){};
|
||||
void canvas_end(){};
|
||||
|
||||
void canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light){};
|
||||
void canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light,const Transform2D& p_transform){};
|
||||
void canvas_debug_viewport_shadows(Light *p_lights_with_shadow){};
|
||||
|
||||
void canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache) {}
|
||||
|
|
|
@ -1042,7 +1042,7 @@ void RasterizerCanvasGLES3::_copy_texscreen(const Rect2 &p_rect) {
|
|||
glEnable(GL_BLEND);
|
||||
}
|
||||
|
||||
void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light) {
|
||||
void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_transform) {
|
||||
|
||||
Item *current_clip = NULL;
|
||||
RasterizerStorageGLES3::Shader *shader_cache = NULL;
|
||||
|
|
|
@ -129,7 +129,7 @@ public:
|
|||
_FORCE_INLINE_ void _canvas_item_render_commands(Item *p_item, Item *current_clip, bool &reclip);
|
||||
_FORCE_INLINE_ void _copy_texscreen(const Rect2 &p_rect);
|
||||
|
||||
virtual void canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light);
|
||||
virtual void canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_transform);
|
||||
virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow);
|
||||
|
||||
virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Transform2D &p_light_xform, int p_light_mask, float p_near, float p_far, LightOccluderInstance *p_occluders, CameraMatrix *p_xform_cache);
|
||||
|
|
|
@ -99,6 +99,7 @@
|
|||
#include "editor/plugins/script_text_editor.h"
|
||||
#include "editor/plugins/shader_editor_plugin.h"
|
||||
#include "editor/plugins/shader_graph_editor_plugin.h"
|
||||
#include "editor/plugins/skeleton_2d_editor_plugin.h"
|
||||
#include "editor/plugins/spatial_editor_plugin.h"
|
||||
#include "editor/plugins/sprite_editor_plugin.h"
|
||||
#include "editor/plugins/sprite_frames_editor_plugin.h"
|
||||
|
@ -5673,6 +5674,7 @@ EditorNode::EditorNode() {
|
|||
add_editor_plugin(memnew(MeshLibraryEditorPlugin(this)));
|
||||
add_editor_plugin(memnew(StyleBoxEditorPlugin(this)));
|
||||
add_editor_plugin(memnew(SpriteEditorPlugin(this)));
|
||||
add_editor_plugin(memnew(Skeleton2DEditorPlugin(this)));
|
||||
add_editor_plugin(memnew(ParticlesEditorPlugin(this)));
|
||||
add_editor_plugin(memnew(ResourcePreloaderEditorPlugin(this)));
|
||||
add_editor_plugin(memnew(ItemListEditorPlugin(this)));
|
||||
|
|
115
editor/plugins/skeleton_2d_editor_plugin.cpp
Normal file
115
editor/plugins/skeleton_2d_editor_plugin.cpp
Normal file
|
@ -0,0 +1,115 @@
|
|||
#include "skeleton_2d_editor_plugin.h"
|
||||
|
||||
#include "canvas_item_editor_plugin.h"
|
||||
#include "scene/2d/mesh_instance_2d.h"
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "thirdparty/misc/clipper.hpp"
|
||||
|
||||
void Skeleton2DEditor::_node_removed(Node *p_node) {
|
||||
|
||||
if (p_node == node) {
|
||||
node = NULL;
|
||||
options->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton2DEditor::edit(Skeleton2D *p_sprite) {
|
||||
|
||||
node = p_sprite;
|
||||
}
|
||||
|
||||
void Skeleton2DEditor::_menu_option(int p_option) {
|
||||
|
||||
switch (p_option) {
|
||||
case MENU_OPTION_MAKE_REST: {
|
||||
|
||||
if (node->get_bone_count() == 0) {
|
||||
err_dialog->set_text(TTR("This skeleton has no bones, create some children Bone2D nodes."));
|
||||
err_dialog->popup_centered_minsize();
|
||||
return;
|
||||
}
|
||||
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
|
||||
ur->create_action("Create Rest Pose from Bones");
|
||||
for (int i = 0; i < node->get_bone_count(); i++) {
|
||||
Bone2D *bone = node->get_bone(i);
|
||||
ur->add_do_method(bone, "set_rest", bone->get_transform());
|
||||
ur->add_undo_method(bone, "set_rest", bone->get_rest());
|
||||
}
|
||||
ur->commit_action();
|
||||
|
||||
} break;
|
||||
case MENU_OPTION_SET_REST: {
|
||||
if (node->get_bone_count() == 0) {
|
||||
err_dialog->set_text(TTR("This skeleton has no bones, create some children Bone2D nodes."));
|
||||
err_dialog->popup_centered_minsize();
|
||||
return;
|
||||
}
|
||||
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
|
||||
ur->create_action("Set Rest Pose to Bones");
|
||||
for (int i = 0; i < node->get_bone_count(); i++) {
|
||||
Bone2D *bone = node->get_bone(i);
|
||||
ur->add_do_method(bone, "set_transform", bone->get_rest());
|
||||
ur->add_undo_method(bone, "set_transform", bone->get_transform());
|
||||
}
|
||||
ur->commit_action();
|
||||
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton2DEditor::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method("_menu_option", &Skeleton2DEditor::_menu_option);
|
||||
}
|
||||
|
||||
Skeleton2DEditor::Skeleton2DEditor() {
|
||||
|
||||
options = memnew(MenuButton);
|
||||
|
||||
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(options);
|
||||
|
||||
options->set_text(TTR("Skeleton2D"));
|
||||
options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("Skeleton2D", "EditorIcons"));
|
||||
|
||||
options->get_popup()->add_item(TTR("Make Rest Pose (From Bones)"), MENU_OPTION_MAKE_REST);
|
||||
options->get_popup()->add_separator();
|
||||
options->get_popup()->add_item(TTR("Set Bones to Rest Pose"), MENU_OPTION_SET_REST);
|
||||
|
||||
options->get_popup()->connect("id_pressed", this, "_menu_option");
|
||||
|
||||
err_dialog = memnew(AcceptDialog);
|
||||
add_child(err_dialog);
|
||||
}
|
||||
|
||||
void Skeleton2DEditorPlugin::edit(Object *p_object) {
|
||||
|
||||
sprite_editor->edit(Object::cast_to<Skeleton2D>(p_object));
|
||||
}
|
||||
|
||||
bool Skeleton2DEditorPlugin::handles(Object *p_object) const {
|
||||
|
||||
return p_object->is_class("Skeleton2D");
|
||||
}
|
||||
|
||||
void Skeleton2DEditorPlugin::make_visible(bool p_visible) {
|
||||
|
||||
if (p_visible) {
|
||||
sprite_editor->options->show();
|
||||
} else {
|
||||
|
||||
sprite_editor->options->hide();
|
||||
sprite_editor->edit(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
Skeleton2DEditorPlugin::Skeleton2DEditorPlugin(EditorNode *p_node) {
|
||||
|
||||
editor = p_node;
|
||||
sprite_editor = memnew(Skeleton2DEditor);
|
||||
editor->get_viewport()->add_child(sprite_editor);
|
||||
|
||||
//sprite_editor->options->hide();
|
||||
}
|
||||
|
||||
Skeleton2DEditorPlugin::~Skeleton2DEditorPlugin() {
|
||||
}
|
55
editor/plugins/skeleton_2d_editor_plugin.h
Normal file
55
editor/plugins/skeleton_2d_editor_plugin.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
#ifndef SKELETON_2D_EDITOR_PLUGIN_H
|
||||
#define SKELETON_2D_EDITOR_PLUGIN_H
|
||||
|
||||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_plugin.h"
|
||||
#include "scene/2d/skeleton_2d.h"
|
||||
#include "scene/gui/spin_box.h"
|
||||
|
||||
class Skeleton2DEditor : public Control {
|
||||
|
||||
GDCLASS(Skeleton2DEditor, Control);
|
||||
|
||||
enum Menu {
|
||||
MENU_OPTION_MAKE_REST,
|
||||
MENU_OPTION_SET_REST,
|
||||
};
|
||||
|
||||
Skeleton2D *node;
|
||||
|
||||
MenuButton *options;
|
||||
AcceptDialog *err_dialog;
|
||||
|
||||
void _menu_option(int p_option);
|
||||
|
||||
//void _create_uv_lines();
|
||||
friend class Skeleton2DEditorPlugin;
|
||||
|
||||
protected:
|
||||
void _node_removed(Node *p_node);
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void edit(Skeleton2D *p_sprite);
|
||||
Skeleton2DEditor();
|
||||
};
|
||||
|
||||
class Skeleton2DEditorPlugin : public EditorPlugin {
|
||||
|
||||
GDCLASS(Skeleton2DEditorPlugin, EditorPlugin);
|
||||
|
||||
Skeleton2DEditor *sprite_editor;
|
||||
EditorNode *editor;
|
||||
|
||||
public:
|
||||
virtual String get_name() const { return "Skeleton2D"; }
|
||||
bool has_main_screen() const { return false; }
|
||||
virtual void edit(Object *p_object);
|
||||
virtual bool handles(Object *p_object) const;
|
||||
virtual void make_visible(bool p_visible);
|
||||
|
||||
Skeleton2DEditorPlugin(EditorNode *p_node);
|
||||
~Skeleton2DEditorPlugin();
|
||||
};
|
||||
|
||||
#endif // SKELETON_2D_EDITOR_PLUGIN_H
|
|
@ -779,13 +779,13 @@ void CanvasItem::draw_colored_polygon(const Vector<Point2> &p_points, const Colo
|
|||
VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, colors, p_uvs, rid, rid_normal, p_antialiased);
|
||||
}
|
||||
|
||||
void CanvasItem::draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map, RID p_skeleton) {
|
||||
void CanvasItem::draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map) {
|
||||
|
||||
ERR_FAIL_COND(p_mesh.is_null());
|
||||
RID texture_rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
|
||||
RID normal_map_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
|
||||
|
||||
VisualServer::get_singleton()->canvas_item_add_mesh(canvas_item, p_mesh->get_rid(), texture_rid, normal_map_rid, p_skeleton);
|
||||
VisualServer::get_singleton()->canvas_item_add_mesh(canvas_item, p_mesh->get_rid(), texture_rid, normal_map_rid);
|
||||
}
|
||||
void CanvasItem::draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map) {
|
||||
|
||||
|
@ -1032,7 +1032,7 @@ void CanvasItem::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("draw_colored_polygon", "points", "color", "uvs", "texture", "normal_map", "antialiased"), &CanvasItem::draw_colored_polygon, DEFVAL(PoolVector2Array()), DEFVAL(Variant()), DEFVAL(Variant()), DEFVAL(false));
|
||||
ClassDB::bind_method(D_METHOD("draw_string", "font", "position", "text", "modulate", "clip_w"), &CanvasItem::draw_string, DEFVAL(Color(1, 1, 1)), DEFVAL(-1));
|
||||
ClassDB::bind_method(D_METHOD("draw_char", "font", "position", "char", "next", "modulate"), &CanvasItem::draw_char, DEFVAL(Color(1, 1, 1)));
|
||||
ClassDB::bind_method(D_METHOD("draw_mesh", "mesh", "texture", "normal_map", "skeleton"), &CanvasItem::draw_mesh, DEFVAL(Ref<Texture>()), DEFVAL(RID()));
|
||||
ClassDB::bind_method(D_METHOD("draw_mesh", "mesh", "texture", "normal_map"), &CanvasItem::draw_mesh, DEFVAL(Ref<Texture>()));
|
||||
ClassDB::bind_method(D_METHOD("draw_multimesh", "mesh", "texture", "normal_map"), &CanvasItem::draw_mesh, DEFVAL(Ref<Texture>()));
|
||||
|
||||
ClassDB::bind_method(D_METHOD("draw_set_transform", "position", "rotation", "scale"), &CanvasItem::draw_set_transform);
|
||||
|
|
|
@ -283,7 +283,7 @@ public:
|
|||
void draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>(), const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_antialiased = false);
|
||||
void draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>(), const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_antialiased = false);
|
||||
|
||||
void draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map, RID p_skeleton);
|
||||
void draw_mesh(const Ref<Mesh> &p_mesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map);
|
||||
void draw_multimesh(const Ref<MultiMesh> &p_multimesh, const Ref<Texture> &p_texture, const Ref<Texture> &p_normal_map);
|
||||
|
||||
void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, const Color &p_modulate = Color(1, 1, 1), int p_clip_w = -1);
|
||||
|
|
|
@ -4,7 +4,7 @@ void MeshInstance2D::_notification(int p_what) {
|
|||
|
||||
if (p_what == NOTIFICATION_DRAW) {
|
||||
if (mesh.is_valid()) {
|
||||
draw_mesh(mesh, texture, normal_map, RID());
|
||||
draw_mesh(mesh, texture, normal_map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
210
scene/2d/skeleton_2d.cpp
Normal file
210
scene/2d/skeleton_2d.cpp
Normal file
|
@ -0,0 +1,210 @@
|
|||
#include "skeleton_2d.h"
|
||||
|
||||
void Bone2D::_notification(int p_what) {
|
||||
|
||||
if (p_what == NOTIFICATION_ENTER_TREE) {
|
||||
Node *parent = get_parent();
|
||||
parent_bone = Object::cast_to<Bone2D>(parent);
|
||||
skeleton = NULL;
|
||||
while (parent) {
|
||||
skeleton = Object::cast_to<Skeleton2D>(parent);
|
||||
if (skeleton)
|
||||
break;
|
||||
if (!Object::cast_to<Bone2D>(parent))
|
||||
break; //skeletons must be chained to Bone2Ds.
|
||||
}
|
||||
|
||||
if (skeleton) {
|
||||
Skeleton2D::Bone bone;
|
||||
bone.bone = this;
|
||||
skeleton->bones.push_back(bone);
|
||||
skeleton->_make_bone_setup_dirty();
|
||||
}
|
||||
}
|
||||
if (p_what == NOTIFICATION_LOCAL_TRANSFORM_CHANGED) {
|
||||
if (skeleton) {
|
||||
skeleton->_make_transform_dirty();
|
||||
}
|
||||
}
|
||||
|
||||
if (p_what == NOTIFICATION_EXIT_TREE) {
|
||||
if (skeleton) {
|
||||
for (int i = 0; i < skeleton->bones.size(); i++) {
|
||||
if (skeleton->bones[i].bone == this) {
|
||||
skeleton->bones.remove(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
skeleton->_make_bone_setup_dirty();
|
||||
skeleton = NULL;
|
||||
}
|
||||
parent_bone = NULL;
|
||||
}
|
||||
}
|
||||
void Bone2D::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_rest", "rest"), &Bone2D::set_rest);
|
||||
ClassDB::bind_method(D_METHOD("get_rest"), &Bone2D::get_rest);
|
||||
ClassDB::bind_method(D_METHOD("apply_rest"), &Bone2D::apply_rest);
|
||||
}
|
||||
|
||||
void Bone2D::set_rest(const Transform2D &p_rest) {
|
||||
rest = p_rest;
|
||||
if (skeleton)
|
||||
skeleton->_make_bone_setup_dirty();
|
||||
}
|
||||
|
||||
Transform2D Bone2D::get_rest() const {
|
||||
return rest;
|
||||
}
|
||||
|
||||
Transform2D Bone2D::get_skeleton_rest() const {
|
||||
|
||||
if (parent_bone) {
|
||||
return parent_bone->get_skeleton_rest() * rest;
|
||||
} else {
|
||||
return rest;
|
||||
}
|
||||
}
|
||||
|
||||
void Bone2D::apply_rest() {
|
||||
set_transform(rest);
|
||||
}
|
||||
|
||||
String Bone2D::get_configuration_warning() const {
|
||||
if (!skeleton) {
|
||||
if (parent_bone) {
|
||||
return TTR("This Bone2D chain should end at a Skeleton2D node.");
|
||||
} else {
|
||||
return TTR("A Bone2D only works with a Skeleton2D or another Bone2D as parent node.");
|
||||
}
|
||||
}
|
||||
|
||||
return Node2D::get_configuration_warning();
|
||||
}
|
||||
|
||||
Bone2D::Bone2D() {
|
||||
skeleton = NULL;
|
||||
parent_bone = NULL;
|
||||
set_notify_local_transform(true);
|
||||
}
|
||||
|
||||
//////////////////////////////////////
|
||||
|
||||
void Skeleton2D::_make_bone_setup_dirty() {
|
||||
|
||||
if (bone_setup_dirty)
|
||||
return;
|
||||
bone_setup_dirty = true;
|
||||
if (is_inside_tree()) {
|
||||
call_deferred("_update_bone_setup");
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton2D::_update_bone_setup() {
|
||||
|
||||
if (!bone_setup_dirty)
|
||||
return;
|
||||
|
||||
bone_setup_dirty = false;
|
||||
VS::get_singleton()->skeleton_allocate(skeleton, bones.size(), true);
|
||||
|
||||
bones.sort(); //sorty so they are always in the same order/index
|
||||
|
||||
for (int i = 0; i < bones.size(); i++) {
|
||||
bones[i].rest_inverse = bones[i].bone->get_skeleton_rest(); //bind pose
|
||||
}
|
||||
|
||||
transform_dirty = true;
|
||||
_update_transform();
|
||||
}
|
||||
|
||||
void Skeleton2D::_make_transform_dirty() {
|
||||
|
||||
if (transform_dirty)
|
||||
return;
|
||||
transform_dirty = true;
|
||||
if (is_inside_tree()) {
|
||||
call_deferred("_update_transform");
|
||||
}
|
||||
}
|
||||
|
||||
void Skeleton2D::_update_transform() {
|
||||
|
||||
if (bone_setup_dirty) {
|
||||
_update_bone_setup();
|
||||
return; //above will update transform anyway
|
||||
}
|
||||
if (!transform_dirty)
|
||||
return;
|
||||
|
||||
transform_dirty = false;
|
||||
|
||||
Transform2D global_xform = get_global_transform();
|
||||
Transform2D global_xform_inverse = global_xform.affine_inverse();
|
||||
|
||||
for (int i = 0; i < bones.size(); i++) {
|
||||
|
||||
Transform2D final_xform = bones[i].rest_inverse * bones[i].bone->get_relative_transform_to_parent(this);
|
||||
VS::get_singleton()->skeleton_bone_set_transform_2d(skeleton, i, global_xform * (final_xform * global_xform_inverse));
|
||||
}
|
||||
}
|
||||
|
||||
int Skeleton2D::get_bone_count() const {
|
||||
|
||||
ERR_FAIL_COND_V(!is_inside_tree(), 0);
|
||||
|
||||
if (bone_setup_dirty) {
|
||||
const_cast<Skeleton2D *>(this)->_update_bone_setup();
|
||||
}
|
||||
|
||||
return bones.size();
|
||||
}
|
||||
|
||||
Bone2D *Skeleton2D::get_bone(int p_idx) {
|
||||
|
||||
ERR_FAIL_COND_V(!is_inside_tree(), NULL);
|
||||
ERR_FAIL_INDEX_V(p_idx, bones.size(), NULL);
|
||||
|
||||
return bones[p_idx].bone;
|
||||
}
|
||||
|
||||
void Skeleton2D::_notification(int p_what) {
|
||||
|
||||
if (p_what == NOTIFICATION_READY) {
|
||||
|
||||
if (bone_setup_dirty)
|
||||
_update_bone_setup();
|
||||
if (transform_dirty)
|
||||
_update_transform();
|
||||
}
|
||||
|
||||
if (p_what == NOTIFICATION_TRANSFORM_CHANGED) {
|
||||
_make_transform_dirty();
|
||||
}
|
||||
}
|
||||
|
||||
RID Skeleton2D::get_skeleton() const {
|
||||
return skeleton;
|
||||
}
|
||||
void Skeleton2D::_bind_methods() {
|
||||
|
||||
ClassDB::bind_method(D_METHOD("_update_bone_setup"), &Skeleton2D::_update_bone_setup);
|
||||
ClassDB::bind_method(D_METHOD("_update_transform"), &Skeleton2D::_update_transform);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_bone_count"), &Skeleton2D::get_bone_count);
|
||||
ClassDB::bind_method(D_METHOD("get_bone"), &Skeleton2D::get_bone);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_skeleton"), &Skeleton2D::get_skeleton);
|
||||
}
|
||||
|
||||
Skeleton2D::Skeleton2D() {
|
||||
bone_setup_dirty = true;
|
||||
transform_dirty = true;
|
||||
skeleton = VS::get_singleton()->skeleton_create();
|
||||
}
|
||||
|
||||
Skeleton2D::~Skeleton2D() {
|
||||
|
||||
VS::get_singleton()->free(skeleton);
|
||||
}
|
68
scene/2d/skeleton_2d.h
Normal file
68
scene/2d/skeleton_2d.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
#ifndef SKELETON_2D_H
|
||||
#define SKELETON_2D_H
|
||||
|
||||
#include "scene/2d/node_2d.h"
|
||||
|
||||
class Skeleton2D;
|
||||
|
||||
class Bone2D : public Node2D {
|
||||
GDCLASS(Bone2D, Node2D)
|
||||
|
||||
Bone2D *parent_bone;
|
||||
Skeleton2D *skeleton;
|
||||
Transform2D rest;
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
void set_rest(const Transform2D &p_rest);
|
||||
Transform2D get_rest() const;
|
||||
void apply_rest();
|
||||
Transform2D get_skeleton_rest() const;
|
||||
|
||||
String get_configuration_warning() const;
|
||||
|
||||
Bone2D();
|
||||
};
|
||||
|
||||
class Skeleton2D : public Node2D {
|
||||
GDCLASS(Skeleton2D, Node2D);
|
||||
|
||||
friend class Bone2D;
|
||||
|
||||
struct Bone {
|
||||
bool operator<(const Bone &p_bone) const {
|
||||
p_bone.bone->is_greater_than(bone);
|
||||
}
|
||||
Bone2D *bone;
|
||||
Transform2D rest_inverse;
|
||||
};
|
||||
|
||||
Vector<Bone> bones;
|
||||
|
||||
bool bone_setup_dirty;
|
||||
void _make_bone_setup_dirty();
|
||||
void _update_bone_setup();
|
||||
|
||||
bool transform_dirty;
|
||||
void _make_transform_dirty();
|
||||
void _update_transform();
|
||||
|
||||
RID skeleton;
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
||||
public:
|
||||
int get_bone_count() const;
|
||||
Bone2D *get_bone(int p_idx);
|
||||
|
||||
RID get_skeleton() const;
|
||||
Skeleton2D();
|
||||
~Skeleton2D();
|
||||
};
|
||||
|
||||
#endif // SKELETON_2D_H
|
|
@ -749,7 +749,6 @@ public:
|
|||
struct CommandMesh : public Command {
|
||||
|
||||
RID mesh;
|
||||
RID skeleton;
|
||||
RID texture;
|
||||
RID normal_map;
|
||||
CommandMesh() { type = TYPE_MESH; }
|
||||
|
@ -758,7 +757,6 @@ public:
|
|||
struct CommandMultiMesh : public Command {
|
||||
|
||||
RID multimesh;
|
||||
RID skeleton;
|
||||
RID texture;
|
||||
RID normal_map;
|
||||
CommandMultiMesh() { type = TYPE_MULTIMESH; }
|
||||
|
@ -924,7 +922,7 @@ public:
|
|||
case Item::Command::TYPE_MESH: {
|
||||
|
||||
const Item::CommandMesh *mesh = static_cast<const Item::CommandMesh *>(c);
|
||||
AABB aabb = RasterizerStorage::base_singleton->mesh_get_aabb(mesh->mesh, mesh->skeleton);
|
||||
AABB aabb = RasterizerStorage::base_singleton->mesh_get_aabb(mesh->mesh, RID());
|
||||
|
||||
r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
|
||||
|
||||
|
@ -1016,7 +1014,7 @@ public:
|
|||
virtual void canvas_begin() = 0;
|
||||
virtual void canvas_end() = 0;
|
||||
|
||||
virtual void canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light) = 0;
|
||||
virtual void canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light, const Transform2D &p_base_transform) = 0;
|
||||
virtual void canvas_debug_viewport_shadows(Light *p_lights_with_shadow) = 0;
|
||||
|
||||
struct LightOccluderInstance : public RID_Data {
|
||||
|
|
|
@ -46,7 +46,7 @@ void VisualServerCanvas::_render_canvas_item_tree(Item *p_canvas_item, const Tra
|
|||
for (int i = 0; i < z_range; i++) {
|
||||
if (!z_list[i])
|
||||
continue;
|
||||
VSG::canvas_render->canvas_render_items(z_list[i], VS::CANVAS_ITEM_Z_MIN + i, p_modulate, p_lights);
|
||||
VSG::canvas_render->canvas_render_items(z_list[i], VS::CANVAS_ITEM_Z_MIN + i, p_modulate, p_lights, p_transform);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,7 +214,7 @@ void VisualServerCanvas::render_canvas(Canvas *p_canvas, const Transform2D &p_tr
|
|||
_light_mask_canvas_items(VS::CANVAS_ITEM_Z_MIN + i, z_list[i], p_masked_lights);
|
||||
}
|
||||
|
||||
VSG::canvas_render->canvas_render_items(z_list[i], VS::CANVAS_ITEM_Z_MIN + i, p_canvas->modulate, p_lights);
|
||||
VSG::canvas_render->canvas_render_items(z_list[i], VS::CANVAS_ITEM_Z_MIN + i, p_canvas->modulate, p_lights, p_transform);
|
||||
}
|
||||
} else {
|
||||
|
||||
|
@ -742,7 +742,7 @@ void VisualServerCanvas::canvas_item_add_set_transform(RID p_item, const Transfo
|
|||
canvas_item->commands.push_back(tr);
|
||||
}
|
||||
|
||||
void VisualServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_texture, RID p_normal_map, RID p_skeleton) {
|
||||
void VisualServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_texture, RID p_normal_map) {
|
||||
|
||||
Item *canvas_item = canvas_item_owner.getornull(p_item);
|
||||
ERR_FAIL_COND(!canvas_item);
|
||||
|
@ -752,7 +752,6 @@ void VisualServerCanvas::canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID
|
|||
m->mesh = p_mesh;
|
||||
m->texture = p_texture;
|
||||
m->normal_map = p_normal_map;
|
||||
m->skeleton = p_skeleton;
|
||||
|
||||
canvas_item->commands.push_back(m);
|
||||
}
|
||||
|
@ -776,7 +775,7 @@ void VisualServerCanvas::canvas_item_add_particles(RID p_item, RID p_particles,
|
|||
canvas_item->commands.push_back(part);
|
||||
}
|
||||
|
||||
void VisualServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture, RID p_normal_map, RID p_skeleton) {
|
||||
void VisualServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture, RID p_normal_map) {
|
||||
|
||||
Item *canvas_item = canvas_item_owner.getornull(p_item);
|
||||
ERR_FAIL_COND(!canvas_item);
|
||||
|
@ -784,7 +783,6 @@ void VisualServerCanvas::canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p
|
|||
Item::CommandMultiMesh *mm = memnew(Item::CommandMultiMesh);
|
||||
ERR_FAIL_COND(!mm);
|
||||
mm->multimesh = p_mesh;
|
||||
mm->skeleton = p_skeleton;
|
||||
mm->texture = p_texture;
|
||||
mm->normal_map = p_normal_map;
|
||||
|
||||
|
@ -826,6 +824,15 @@ void VisualServerCanvas::canvas_item_set_z_as_relative_to_parent(RID p_item, boo
|
|||
|
||||
canvas_item->z_relative = p_enable;
|
||||
}
|
||||
|
||||
void VisualServerCanvas::canvas_item_attach_skeleton(RID p_item, RID p_skeleton) {
|
||||
|
||||
Item *canvas_item = canvas_item_owner.getornull(p_item);
|
||||
ERR_FAIL_COND(!canvas_item);
|
||||
|
||||
canvas_item->skeleton = p_skeleton;
|
||||
}
|
||||
|
||||
void VisualServerCanvas::canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable, const Rect2 &p_rect) {
|
||||
|
||||
Item *canvas_item = canvas_item_owner.getornull(p_item);
|
||||
|
|
|
@ -51,6 +51,8 @@ public:
|
|||
|
||||
Vector<Item *> child_items;
|
||||
|
||||
RID skeleton;
|
||||
|
||||
Item() {
|
||||
children_order_dirty = true;
|
||||
E = NULL;
|
||||
|
@ -182,8 +184,8 @@ public:
|
|||
void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID());
|
||||
void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), RID p_normal_map = RID(), bool p_antialiased = false);
|
||||
void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID());
|
||||
void canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_texture = RID(), RID p_normal_map = RID(), RID p_skeleton = RID());
|
||||
void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID(), RID p_normal_map = RID(), RID p_skeleton = RID());
|
||||
void canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_texture = RID(), RID p_normal_map = RID());
|
||||
void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID(), RID p_normal_map = RID());
|
||||
void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal, int p_h_frames, int p_v_frames);
|
||||
void canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform);
|
||||
void canvas_item_add_clip_ignore(RID p_item, bool p_ignore);
|
||||
|
@ -191,6 +193,7 @@ public:
|
|||
void canvas_item_set_z_index(RID p_item, int p_z);
|
||||
void canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable);
|
||||
void canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable, const Rect2 &p_rect);
|
||||
void canvas_item_attach_skeleton(RID p_item, RID p_skeleton);
|
||||
|
||||
void canvas_item_clear(RID p_item);
|
||||
void canvas_item_set_draw_index(RID p_item, int p_index);
|
||||
|
|
|
@ -581,8 +581,8 @@ public:
|
|||
BIND7(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float, RID)
|
||||
BIND7(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, RID, bool)
|
||||
BIND8(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, int, RID)
|
||||
BIND5(canvas_item_add_mesh, RID, const RID &, RID, RID, RID)
|
||||
BIND5(canvas_item_add_multimesh, RID, RID, RID, RID, RID)
|
||||
BIND4(canvas_item_add_mesh, RID, const RID &, RID, RID)
|
||||
BIND4(canvas_item_add_multimesh, RID, RID, RID, RID)
|
||||
BIND6(canvas_item_add_particles, RID, RID, RID, RID, int, int)
|
||||
BIND2(canvas_item_add_set_transform, RID, const Transform2D &)
|
||||
BIND2(canvas_item_add_clip_ignore, RID, bool)
|
||||
|
@ -590,6 +590,7 @@ public:
|
|||
BIND2(canvas_item_set_z_index, RID, int)
|
||||
BIND2(canvas_item_set_z_as_relative_to_parent, RID, bool)
|
||||
BIND3(canvas_item_set_copy_to_backbuffer, RID, bool, const Rect2 &)
|
||||
BIND2(canvas_item_attach_skeleton, RID, RID)
|
||||
|
||||
BIND1(canvas_item_clear, RID)
|
||||
BIND2(canvas_item_set_draw_index, RID, int)
|
||||
|
|
|
@ -499,8 +499,8 @@ public:
|
|||
FUNC7(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float, RID)
|
||||
FUNC7(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, RID, bool)
|
||||
FUNC8(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, int, RID)
|
||||
FUNC5(canvas_item_add_mesh, RID, const RID &, RID, RID, RID)
|
||||
FUNC5(canvas_item_add_multimesh, RID, RID, RID, RID, RID)
|
||||
FUNC4(canvas_item_add_mesh, RID, const RID &, RID, RID)
|
||||
FUNC4(canvas_item_add_multimesh, RID, RID, RID, RID)
|
||||
FUNC6(canvas_item_add_particles, RID, RID, RID, RID, int, int)
|
||||
FUNC2(canvas_item_add_set_transform, RID, const Transform2D &)
|
||||
FUNC2(canvas_item_add_clip_ignore, RID, bool)
|
||||
|
@ -508,6 +508,7 @@ public:
|
|||
FUNC2(canvas_item_set_z_index, RID, int)
|
||||
FUNC2(canvas_item_set_z_as_relative_to_parent, RID, bool)
|
||||
FUNC3(canvas_item_set_copy_to_backbuffer, RID, bool, const Rect2 &)
|
||||
FUNC2(canvas_item_attach_skeleton, RID, RID)
|
||||
|
||||
FUNC1(canvas_item_clear, RID)
|
||||
FUNC2(canvas_item_set_draw_index, RID, int)
|
||||
|
|
|
@ -846,8 +846,8 @@ public:
|
|||
virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID()) = 0;
|
||||
virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), RID p_normal_map = RID(), bool p_antialiased = false) = 0;
|
||||
virtual void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID()) = 0;
|
||||
virtual void canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_texture = RID(), RID p_normal_map = RID(), RID p_skeleton = RID()) = 0;
|
||||
virtual void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID(), RID p_normal_map = RID(), RID p_skeleton = RID()) = 0;
|
||||
virtual void canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_texture = RID(), RID p_normal_map = RID()) = 0;
|
||||
virtual void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_texture = RID(), RID p_normal_map = RID()) = 0;
|
||||
virtual void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture, RID p_normal_map, int p_h_frames, int p_v_frames) = 0;
|
||||
virtual void canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform) = 0;
|
||||
virtual void canvas_item_add_clip_ignore(RID p_item, bool p_ignore) = 0;
|
||||
|
@ -856,6 +856,8 @@ public:
|
|||
virtual void canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable) = 0;
|
||||
virtual void canvas_item_set_copy_to_backbuffer(RID p_item, bool p_enable, const Rect2 &p_rect) = 0;
|
||||
|
||||
virtual void canvas_item_attach_skeleton(RID p_item, RID p_skeleton) = 0;
|
||||
|
||||
virtual void canvas_item_clear(RID p_item) = 0;
|
||||
virtual void canvas_item_set_draw_index(RID p_item, int p_index) = 0;
|
||||
|
||||
|
|
Loading…
Reference in a new issue