Closed douglyuckling closed 1 month ago
Invoking queue_redraw() whenever the mesh changes shape avoids the problem because it causes the node's bounding rect to be marked as dirty.
May I ask where did you add the queue_redraw()
draw? I can reproduce the issue but adding queue_redraw()
to _update_immediatemesh
does not solve the issue.
@jsjtxietian Apologies, you're right I wan't specific about the queue_redraw()
workaround. You need to invoke it on the MeshInstance2D
whose mesh was updated.
So in my MRP project, you can apply the workaround by adding the line white_mesh.queue_redraw()
in the _process()
function.
I'll update my description above to be clearer about that.
Tested versions
ImmediateMesh
doesn't exist yet, andImmediateGeometry
is aSpatial
node.System information
Godot v4.2.2.stable - macOS 14.5.0 - GLES3 (Compatibility) - Apple M2 Max - Apple M2 Max (12 Threads)
Issue description
Problem
When using
ImmediateMesh
withMeshInstance2D
, the node's bounding rect is not automatically updated when the mesh's surfaces are cleared and re-generated in a different shape. SinceCanvasItem
nodes are culled when their bounding rect is entirely outside of the viewport, this can cause the mesh to "disappear" in cases where it should actually be visible.The animation below demonstrates the problem. The white rectangle is a
MeshInstance2D
whoseposition
is animated to move around the viewport. It has anImmediateMesh
that is re-generated each frame with its vertices in a different location with respect to its own origin. The blue rectangle is identical except that its mesh is never updated after the first frame, so it shows the initial pose of the white rectangle's mesh for reference.Notice how whenever the blue rectangle is fully outside the viewport (meaning the cached bounding rect for the white rectangle is outside the viewport), the white rectangle is culled from the view:
Obviously this is a contrived example, but the real-world situation where I ran into this problem was creating a Snake-style game where the snake's body is a procedurally-generated mesh. In order to allow the player's snake to leave one side of the screen and enter from the opposite side, I need to render snake meshes that are partly outside the viewport. In most cases this means the snake mesh's initial bounding rect fully leaves the viewport before the mesh does, causing the mesh to suddenly disappear.
Workaround
Invoking
queue_redraw()
on theMeshInstance2D
node whenever its mesh changes shape avoids the problem because that causes the node's bounding rect to be marked as dirty. But this is awkward since there are no drawing commands, and perhaps also inefficient due to causing additional work that otherwise would not need to be done.Expected behavior
The expected behavior is that the node's bounding rect would be marked as dirty whenever the ImmediateMesh changes shape, i.e. whenever a surface is added or the surfaces are cleared.
Alternatively, if the
queue_redraw()
workaround is the intended way get the bounding rect to be updated, then that should be mentioned in the documentation.Other notes
ArrayMesh
withMeshInstance2D
, but I haven't tried it yet.ImmediateMesh
withMeshInstance3D
. But I cannot be sure that my test was valid.Steps to reproduce
MeshInstance2D
and set its mesh to anImmediateMesh
.ImmediateMesh
and allow it to be rendered for at least one frame.MeshInstance2D
node such that it's initial bounding rect is outside of the viewport, but part of the mesh should still be visible inside the viewport. Observe that the mesh disappears as soon as it's initial bounding rect is fully outside the viewport.The attached MRP demonstrates these steps.
Minimal reproduction project (MRP)
immediatemesh_bug_mrp.zip