diff --git a/scene/2d/multimesh_instance_2d.cpp b/scene/2d/multimesh_instance_2d.cpp index 479265225fc..1c42f1161ca 100644 --- a/scene/2d/multimesh_instance_2d.cpp +++ b/scene/2d/multimesh_instance_2d.cpp @@ -42,8 +42,24 @@ Callable MultiMeshInstance2D::_navmesh_source_geometry_parsing_callback; RID MultiMeshInstance2D::_navmesh_source_geometry_parser; +void MultiMeshInstance2D::_refresh_interpolated() { + if (is_inside_tree() && multimesh.is_valid()) { + bool interpolated = is_physics_interpolated_and_enabled(); + multimesh->set_physics_interpolated(interpolated); + } +} + +void MultiMeshInstance2D::_physics_interpolated_changed() { + CanvasItem::_physics_interpolated_changed(); + _refresh_interpolated(); +} + void MultiMeshInstance2D::_notification(int p_what) { switch (p_what) { + case NOTIFICATION_ENTER_TREE: { + _refresh_interpolated(); + break; + } case NOTIFICATION_DRAW: { if (multimesh.is_valid()) { draw_multimesh(multimesh, texture); @@ -75,6 +91,7 @@ void MultiMeshInstance2D::set_multimesh(const Ref &p_multimesh) { // Connect to the multimesh so the AABB can update when instance transforms are changed. if (multimesh.is_valid()) { multimesh->connect_changed(callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw)); + _refresh_interpolated(); } queue_redraw(); } diff --git a/scene/2d/multimesh_instance_2d.h b/scene/2d/multimesh_instance_2d.h index f3de5a9020a..1924982a3a0 100644 --- a/scene/2d/multimesh_instance_2d.h +++ b/scene/2d/multimesh_instance_2d.h @@ -43,7 +43,10 @@ class MultiMeshInstance2D : public Node2D { Ref texture; + void _refresh_interpolated(); + protected: + virtual void _physics_interpolated_changed() override; void _notification(int p_what); static void _bind_methods(); diff --git a/scene/main/canvas_item.h b/scene/main/canvas_item.h index 14e11a97686..0775d585ef4 100644 --- a/scene/main/canvas_item.h +++ b/scene/main/canvas_item.h @@ -140,8 +140,6 @@ private: void _notify_transform(CanvasItem *p_node); - virtual void _physics_interpolated_changed() override; - static CanvasItem *current_item_drawn; friend class Viewport; void _refresh_texture_repeat_cache() const; @@ -157,6 +155,8 @@ protected: bool _get(const StringName &p_name, Variant &r_ret) const; void _get_property_list(List *p_list) const; + virtual void _physics_interpolated_changed() override; + virtual void _update_self_texture_repeat(RS::CanvasItemTextureRepeat p_texture_repeat); virtual void _update_self_texture_filter(RS::CanvasItemTextureFilter p_texture_filter); diff --git a/servers/rendering/storage/mesh_storage.cpp b/servers/rendering/storage/mesh_storage.cpp index a495eac8b4e..f625cfae5f3 100644 --- a/servers/rendering/storage/mesh_storage.cpp +++ b/servers/rendering/storage/mesh_storage.cpp @@ -118,6 +118,37 @@ void RendererMeshStorage::multimesh_instance_set_transform(RID p_multimesh, int } void RendererMeshStorage::multimesh_instance_set_transform_2d(RID p_multimesh, int p_index, const Transform2D &p_transform) { + MultiMeshInterpolator *mmi = _multimesh_get_interpolator(p_multimesh); + if (mmi && mmi->interpolated) { + ERR_FAIL_COND(p_index >= mmi->_num_instances); + ERR_FAIL_COND(mmi->_vf_size_xform != 8); + + int start = p_index * mmi->_stride; + float *ptr = mmi->_data_curr.ptrw(); + ptr += start; + + const Transform2D &t = p_transform; + + ptr[0] = t.columns[0][0]; + ptr[1] = t.columns[1][0]; + ptr[2] = 0; + ptr[3] = t.columns[2][0]; + ptr[4] = t.columns[0][1]; + ptr[5] = t.columns[1][1]; + ptr[6] = 0; + ptr[7] = t.columns[2][1]; + + _multimesh_add_to_interpolation_lists(p_multimesh, *mmi); + +#if defined(DEBUG_ENABLED) && defined(TOOLS_ENABLED) + if (!Engine::get_singleton()->is_in_physics_frame()) { + PHYSICS_INTERPOLATION_WARNING("MultiMesh interpolation is being triggered from outside physics process, this might lead to issues"); + } +#endif + + return; + } + _multimesh_instance_set_transform_2d(p_multimesh, p_index, p_transform); }