diff --git a/doc/classes/MultiMesh.xml b/doc/classes/MultiMesh.xml
index e99694c3f0a..ae3963d8fab 100644
--- a/doc/classes/MultiMesh.xml
+++ b/doc/classes/MultiMesh.xml
@@ -59,6 +59,13 @@
This allows you to move instances instantaneously, and should usually be used when initially placing an instance such as a bullet to prevent graphical glitches.
+
+
+
+ When using [i]physics interpolation[/i], this function allows you to prevent interpolation for all instances in the current physics tick.
+ This allows you to move all instances instantaneously, and should usually be used when initially placing instances to prevent graphical glitches.
+
+
diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml
index b3f36e6e00e..5d00eca29e4 100644
--- a/doc/classes/RenderingServer.xml
+++ b/doc/classes/RenderingServer.xml
@@ -2772,6 +2772,14 @@
Sets the [Transform2D] for this instance. For use when multimesh is used in 2D. Equivalent to [method MultiMesh.set_instance_transform_2d].
+
+
+
+
+ Prevents physics interpolation for all instances during the current physics tick.
+ This is useful when moving all instances to new locations, to give instantaneous changes rather than interpolation from the previous locations.
+
+
diff --git a/scene/resources/multimesh.cpp b/scene/resources/multimesh.cpp
index 8cf68c1e61d..e3f0e120dd4 100644
--- a/scene/resources/multimesh.cpp
+++ b/scene/resources/multimesh.cpp
@@ -308,6 +308,10 @@ void MultiMesh::reset_instance_physics_interpolation(int p_instance) {
RenderingServer::get_singleton()->multimesh_instance_reset_physics_interpolation(multimesh, p_instance);
}
+void MultiMesh::reset_instances_physics_interpolation() {
+ RenderingServer::get_singleton()->multimesh_instances_reset_physics_interpolation(multimesh);
+}
+
void MultiMesh::set_physics_interpolated(bool p_interpolated) {
RenderingServer::get_singleton()->multimesh_set_physics_interpolated(multimesh, p_interpolated);
}
@@ -382,6 +386,7 @@ void MultiMesh::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_instance_custom_data", "instance", "custom_data"), &MultiMesh::set_instance_custom_data);
ClassDB::bind_method(D_METHOD("get_instance_custom_data", "instance"), &MultiMesh::get_instance_custom_data);
ClassDB::bind_method(D_METHOD("reset_instance_physics_interpolation", "instance"), &MultiMesh::reset_instance_physics_interpolation);
+ ClassDB::bind_method(D_METHOD("reset_instances_physics_interpolation"), &MultiMesh::reset_instances_physics_interpolation);
ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &MultiMesh::set_custom_aabb);
ClassDB::bind_method(D_METHOD("get_custom_aabb"), &MultiMesh::get_custom_aabb);
ClassDB::bind_method(D_METHOD("get_aabb"), &MultiMesh::get_aabb);
diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h
index 1545b454e63..a486bd6ef2f 100644
--- a/scene/resources/multimesh.h
+++ b/scene/resources/multimesh.h
@@ -115,6 +115,7 @@ public:
Color get_instance_custom_data(int p_instance) const;
void reset_instance_physics_interpolation(int p_instance);
+ void reset_instances_physics_interpolation();
void set_physics_interpolated(bool p_interpolated);
diff --git a/servers/rendering/rendering_server.cpp b/servers/rendering/rendering_server.cpp
index 8c02698ed5c..62f13bfc975 100644
--- a/servers/rendering/rendering_server.cpp
+++ b/servers/rendering/rendering_server.cpp
@@ -2543,6 +2543,7 @@ void RenderingServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("multimesh_set_physics_interpolated", "multimesh", "interpolated"), &RenderingServer::multimesh_set_physics_interpolated);
ClassDB::bind_method(D_METHOD("multimesh_set_physics_interpolation_quality", "multimesh", "quality"), &RenderingServer::multimesh_set_physics_interpolation_quality);
ClassDB::bind_method(D_METHOD("multimesh_instance_reset_physics_interpolation", "multimesh", "index"), &RenderingServer::multimesh_instance_reset_physics_interpolation);
+ ClassDB::bind_method(D_METHOD("multimesh_instances_reset_physics_interpolation", "multimesh"), &RenderingServer::multimesh_instances_reset_physics_interpolation);
BIND_ENUM_CONSTANT(MULTIMESH_TRANSFORM_2D);
BIND_ENUM_CONSTANT(MULTIMESH_TRANSFORM_3D);
diff --git a/servers/rendering/rendering_server.h b/servers/rendering/rendering_server.h
index 7fe0d3223c8..23f4b9d0cef 100644
--- a/servers/rendering/rendering_server.h
+++ b/servers/rendering/rendering_server.h
@@ -514,6 +514,7 @@ public:
virtual void multimesh_set_physics_interpolated(RID p_multimesh, bool p_interpolated) = 0;
virtual void multimesh_set_physics_interpolation_quality(RID p_multimesh, MultimeshPhysicsInterpolationQuality p_quality) = 0;
virtual void multimesh_instance_reset_physics_interpolation(RID p_multimesh, int p_index) = 0;
+ virtual void multimesh_instances_reset_physics_interpolation(RID p_multimesh) = 0;
virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible) = 0;
virtual int multimesh_get_visible_instances(RID p_multimesh) const = 0;
diff --git a/servers/rendering/rendering_server_default.h b/servers/rendering/rendering_server_default.h
index 62a155a534c..34faef662c4 100644
--- a/servers/rendering/rendering_server_default.h
+++ b/servers/rendering/rendering_server_default.h
@@ -424,6 +424,7 @@ public:
FUNC2(multimesh_set_physics_interpolated, RID, bool)
FUNC2(multimesh_set_physics_interpolation_quality, RID, MultimeshPhysicsInterpolationQuality)
FUNC2(multimesh_instance_reset_physics_interpolation, RID, int)
+ FUNC1(multimesh_instances_reset_physics_interpolation, RID)
FUNC2(multimesh_set_visible_instances, RID, int)
FUNC1RC(int, multimesh_get_visible_instances, RID)
diff --git a/servers/rendering/storage/mesh_storage.cpp b/servers/rendering/storage/mesh_storage.cpp
index 90f2def408a..c2829813834 100644
--- a/servers/rendering/storage/mesh_storage.cpp
+++ b/servers/rendering/storage/mesh_storage.cpp
@@ -329,6 +329,17 @@ void RendererMeshStorage::multimesh_instance_reset_physics_interpolation(RID p_m
}
}
+void RendererMeshStorage::multimesh_instances_reset_physics_interpolation(RID p_multimesh) {
+ MultiMeshInterpolator *mmi = _multimesh_get_interpolator(p_multimesh);
+ if (mmi && mmi->_data_curr.size()) {
+ // We don't want to invoke COW here, so copy the data directly.
+ ERR_FAIL_COND(mmi->_data_prev.size() != mmi->_data_curr.size());
+ float *w = mmi->_data_prev.ptrw();
+ const float *r = mmi->_data_curr.ptr();
+ memcpy(w, r, sizeof(float) * mmi->_data_curr.size());
+ }
+}
+
void RendererMeshStorage::multimesh_set_visible_instances(RID p_multimesh, int p_visible) {
return _multimesh_set_visible_instances(p_multimesh, p_visible);
}
diff --git a/servers/rendering/storage/mesh_storage.h b/servers/rendering/storage/mesh_storage.h
index 353d4cc9fc8..153750bfbd2 100644
--- a/servers/rendering/storage/mesh_storage.h
+++ b/servers/rendering/storage/mesh_storage.h
@@ -152,6 +152,7 @@ public:
virtual void multimesh_set_physics_interpolated(RID p_multimesh, bool p_interpolated);
virtual void multimesh_set_physics_interpolation_quality(RID p_multimesh, RS::MultimeshPhysicsInterpolationQuality p_quality);
virtual void multimesh_instance_reset_physics_interpolation(RID p_multimesh, int p_index);
+ virtual void multimesh_instances_reset_physics_interpolation(RID p_multimesh);
virtual void multimesh_set_visible_instances(RID p_multimesh, int p_visible);
virtual int multimesh_get_visible_instances(RID p_multimesh) const;