Merge pull request #107666 from Sch1nken/add-physics-interpolation-multimesh2d

Add MultiMesh physics interpolation for 2D transforms (MultiMeshInstance2D)
This commit is contained in:
Thaddeus Crews 2025-10-03 12:01:07 -05:00
commit fb572aff53
No known key found for this signature in database
GPG key ID: 8C6E5FEB5FC03CCC
4 changed files with 53 additions and 2 deletions

View file

@ -42,8 +42,24 @@
Callable MultiMeshInstance2D::_navmesh_source_geometry_parsing_callback; Callable MultiMeshInstance2D::_navmesh_source_geometry_parsing_callback;
RID MultiMeshInstance2D::_navmesh_source_geometry_parser; 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) { void MultiMeshInstance2D::_notification(int p_what) {
switch (p_what) { switch (p_what) {
case NOTIFICATION_ENTER_TREE: {
_refresh_interpolated();
break;
}
case NOTIFICATION_DRAW: { case NOTIFICATION_DRAW: {
if (multimesh.is_valid()) { if (multimesh.is_valid()) {
draw_multimesh(multimesh, texture); draw_multimesh(multimesh, texture);
@ -75,6 +91,7 @@ void MultiMeshInstance2D::set_multimesh(const Ref<MultiMesh> &p_multimesh) {
// Connect to the multimesh so the AABB can update when instance transforms are changed. // Connect to the multimesh so the AABB can update when instance transforms are changed.
if (multimesh.is_valid()) { if (multimesh.is_valid()) {
multimesh->connect_changed(callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw)); multimesh->connect_changed(callable_mp((CanvasItem *)this, &CanvasItem::queue_redraw));
_refresh_interpolated();
} }
queue_redraw(); queue_redraw();
} }

View file

@ -43,7 +43,10 @@ class MultiMeshInstance2D : public Node2D {
Ref<Texture2D> texture; Ref<Texture2D> texture;
void _refresh_interpolated();
protected: protected:
virtual void _physics_interpolated_changed() override;
void _notification(int p_what); void _notification(int p_what);
static void _bind_methods(); static void _bind_methods();

View file

@ -147,8 +147,6 @@ private:
void _notify_transform(CanvasItem *p_node); void _notify_transform(CanvasItem *p_node);
virtual void _physics_interpolated_changed() override;
static CanvasItem *current_item_drawn; static CanvasItem *current_item_drawn;
friend class Viewport; friend class Viewport;
void _refresh_texture_repeat_cache() const; void _refresh_texture_repeat_cache() const;
@ -164,6 +162,8 @@ protected:
bool _get(const StringName &p_name, Variant &r_ret) const; bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const; void _get_property_list(List<PropertyInfo> *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_repeat(RS::CanvasItemTextureRepeat p_texture_repeat);
virtual void _update_self_texture_filter(RS::CanvasItemTextureFilter p_texture_filter); virtual void _update_self_texture_filter(RS::CanvasItemTextureFilter p_texture_filter);

View file

@ -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) { 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); _multimesh_instance_set_transform_2d(p_multimesh, p_index, p_transform);
} }