mirror of
https://github.com/godotengine/godot.git
synced 2024-11-23 20:53:15 +00:00
Merge pull request #49685 from reduz/implement-drawing-animation-slices-in-canvas
Implement animation slice drawing in CanvasItem
This commit is contained in:
commit
13c4796693
@ -24,6 +24,21 @@
|
||||
Overridable function called by the engine (if defined) to draw the canvas item.
|
||||
</description>
|
||||
</method>
|
||||
<method name="draw_animation_slice">
|
||||
<return type="void">
|
||||
</return>
|
||||
<argument index="0" name="animation_length" type="float">
|
||||
</argument>
|
||||
<argument index="1" name="slice_begin" type="float">
|
||||
</argument>
|
||||
<argument index="2" name="slice_end" type="float">
|
||||
</argument>
|
||||
<argument index="3" name="offset" type="float" default="0.0">
|
||||
</argument>
|
||||
<description>
|
||||
Subsequent drawing commands will be ignored unless they fall within the specified animation slice. This is a faster way to implement animations that loop on background rather than redrawing constantly.
|
||||
</description>
|
||||
</method>
|
||||
<method name="draw_arc">
|
||||
<return type="void">
|
||||
</return>
|
||||
@ -98,6 +113,13 @@
|
||||
Draws a colored polygon of any amount of points, convex or concave.
|
||||
</description>
|
||||
</method>
|
||||
<method name="draw_end_animation">
|
||||
<return type="void">
|
||||
</return>
|
||||
<description>
|
||||
After submitting all animations slices via [method draw_animation_slice], this function can be used to revert drawing to its default state (all subsequent drawing commands will be visible). If you don't care about this particular use case, usage of this function after submitting the slices is not required.
|
||||
</description>
|
||||
</method>
|
||||
<method name="draw_line">
|
||||
<return type="void">
|
||||
</return>
|
||||
|
@ -876,6 +876,17 @@ void CanvasItem::draw_set_transform_matrix(const Transform2D &p_matrix) {
|
||||
|
||||
RenderingServer::get_singleton()->canvas_item_add_set_transform(canvas_item, p_matrix);
|
||||
}
|
||||
void CanvasItem::draw_animation_slice(double p_animation_length, double p_slice_begin, double p_slice_end, double p_offset) {
|
||||
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
|
||||
|
||||
RenderingServer::get_singleton()->canvas_item_add_animation_slice(canvas_item, p_animation_length, p_slice_begin, p_slice_end, p_offset);
|
||||
}
|
||||
|
||||
void CanvasItem::draw_end_animation() {
|
||||
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
|
||||
|
||||
RenderingServer::get_singleton()->canvas_item_add_animation_slice(canvas_item, 1, 0, 2, 0);
|
||||
}
|
||||
|
||||
void CanvasItem::draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture2D> p_texture) {
|
||||
ERR_FAIL_COND_MSG(!drawing, "Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
|
||||
@ -1159,6 +1170,8 @@ void CanvasItem::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("draw_multimesh", "multimesh", "texture"), &CanvasItem::draw_multimesh);
|
||||
ClassDB::bind_method(D_METHOD("draw_set_transform", "position", "rotation", "scale"), &CanvasItem::draw_set_transform, DEFVAL(0.0), DEFVAL(Size2(1.0, 1.0)));
|
||||
ClassDB::bind_method(D_METHOD("draw_set_transform_matrix", "xform"), &CanvasItem::draw_set_transform_matrix);
|
||||
ClassDB::bind_method(D_METHOD("draw_animation_slice", "animation_length", "slice_begin", "slice_end", "offset"), &CanvasItem::draw_animation_slice, DEFVAL(0.0));
|
||||
ClassDB::bind_method(D_METHOD("draw_end_animation"), &CanvasItem::draw_end_animation);
|
||||
ClassDB::bind_method(D_METHOD("get_transform"), &CanvasItem::get_transform);
|
||||
ClassDB::bind_method(D_METHOD("get_global_transform"), &CanvasItem::get_global_transform);
|
||||
ClassDB::bind_method(D_METHOD("get_global_transform_with_canvas"), &CanvasItem::get_global_transform_with_canvas);
|
||||
|
@ -356,6 +356,8 @@ public:
|
||||
|
||||
void draw_set_transform(const Point2 &p_offset, real_t p_rot = 0.0, const Size2 &p_scale = Size2(1.0, 1.0));
|
||||
void draw_set_transform_matrix(const Transform2D &p_matrix);
|
||||
void draw_animation_slice(double p_animation_length, double p_slice_begin, double p_slice_end, double p_offset = 0);
|
||||
void draw_end_animation();
|
||||
|
||||
static CanvasItem *get_current_item_drawn();
|
||||
|
||||
|
@ -1003,6 +1003,18 @@ void RendererCanvasCull::canvas_item_add_clip_ignore(RID p_item, bool p_ignore)
|
||||
ci->ignore = p_ignore;
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_item_add_animation_slice(RID p_item, double p_animation_length, double p_slice_begin, double p_slice_end, double p_offset) {
|
||||
Item *canvas_item = canvas_item_owner.getornull(p_item);
|
||||
ERR_FAIL_COND(!canvas_item);
|
||||
|
||||
Item::CommandAnimationSlice *as = canvas_item->alloc_command<Item::CommandAnimationSlice>();
|
||||
ERR_FAIL_COND(!as);
|
||||
as->animation_length = p_animation_length;
|
||||
as->slice_begin = p_slice_begin;
|
||||
as->slice_end = p_slice_end;
|
||||
as->offset = p_offset;
|
||||
}
|
||||
|
||||
void RendererCanvasCull::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) {
|
||||
Item *canvas_item = canvas_item_owner.getornull(p_item);
|
||||
ERR_FAIL_COND(!canvas_item);
|
||||
|
@ -231,6 +231,8 @@ public:
|
||||
void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture);
|
||||
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);
|
||||
void canvas_item_add_animation_slice(RID p_item, double p_animation_length, double p_slice_begin, double p_slice_end, double p_offset);
|
||||
|
||||
void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable);
|
||||
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);
|
||||
|
@ -180,6 +180,7 @@ public:
|
||||
TYPE_PARTICLES,
|
||||
TYPE_TRANSFORM,
|
||||
TYPE_CLIP_IGNORE,
|
||||
TYPE_ANIMATION_SLICE,
|
||||
};
|
||||
|
||||
Command *next;
|
||||
@ -286,6 +287,17 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
struct CommandAnimationSlice : public Command {
|
||||
double animation_length = 0;
|
||||
double slice_begin = 0;
|
||||
double slice_end = 0;
|
||||
double offset = 0;
|
||||
|
||||
CommandAnimationSlice() {
|
||||
type = TYPE_ANIMATION_SLICE;
|
||||
}
|
||||
};
|
||||
|
||||
struct ViewportRender {
|
||||
RenderingServer *owner;
|
||||
void *udata;
|
||||
|
@ -464,8 +464,15 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
|
||||
RID last_texture;
|
||||
Size2 texpixel_size;
|
||||
|
||||
bool skipping = false;
|
||||
|
||||
const Item::Command *c = p_item->commands;
|
||||
while (c) {
|
||||
if (skipping && c->type != Item::Command::TYPE_ANIMATION_SLICE) {
|
||||
c = c->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
push_constant.flags = base_flags | (push_constant.flags & (FLAGS_DEFAULT_NORMAL_MAP_USED | FLAGS_DEFAULT_SPECULAR_MAP_USED)); //reset on each command for sanity, keep canvastexture binding config
|
||||
|
||||
switch (c->type) {
|
||||
@ -879,6 +886,14 @@ void RendererCanvasRenderRD::_render_item(RD::DrawListID p_draw_list, RID p_rend
|
||||
}
|
||||
|
||||
} break;
|
||||
case Item::Command::TYPE_ANIMATION_SLICE: {
|
||||
const Item::CommandAnimationSlice *as = static_cast<const Item::CommandAnimationSlice *>(c);
|
||||
double current_time = RendererCompositorRD::singleton->get_total_time();
|
||||
double local_time = Math::fposmod(current_time - as->offset, as->animation_length);
|
||||
skipping = !(local_time >= as->slice_begin && local_time < as->slice_end);
|
||||
|
||||
RenderingServerDefault::redraw_request(); // animation visible means redraw request
|
||||
} break;
|
||||
}
|
||||
|
||||
c = c->next;
|
||||
|
@ -813,6 +813,8 @@ public:
|
||||
FUNC3(canvas_item_add_particles, RID, RID, RID)
|
||||
FUNC2(canvas_item_add_set_transform, RID, const Transform2D &)
|
||||
FUNC2(canvas_item_add_clip_ignore, RID, bool)
|
||||
FUNC5(canvas_item_add_animation_slice, RID, double, double, double, double)
|
||||
|
||||
FUNC2(canvas_item_set_sort_children_by_y, RID, bool)
|
||||
FUNC2(canvas_item_set_z_index, RID, int)
|
||||
FUNC2(canvas_item_set_z_as_relative_to_parent, RID, bool)
|
||||
|
@ -1294,6 +1294,7 @@ public:
|
||||
virtual void canvas_item_add_particles(RID p_item, RID p_particles, RID p_texture) = 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;
|
||||
virtual void canvas_item_add_animation_slice(RID p_item, double p_animation_length, double p_slice_begin, double p_slice_end, double p_offset) = 0;
|
||||
virtual void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) = 0;
|
||||
virtual void canvas_item_set_z_index(RID p_item, int p_z) = 0;
|
||||
virtual void canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable) = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user