godotengine / godotengine/godot-docs
Properly document Mesh.surface_update_region
- Dominant language
- reStructuredText
- Stars
- 5.7k
- Forks
- 3.8k
- Avg merge
- 1d 20h
- Merged PRs (30d)
- 25
Description
The documentation for [surface_update_region()](https://docs.godotengine.org/en/stable/classes/class_arraymesh.html#class-arraymesh-method-surface-update-region) currently says not to use it because it can be quite dangerous. While that is true, it would be a lot less dangerous to use if we actually documented how it works. The benefit of ``surface_update_region()`` is that it updates the OpenGL vertex buffer array directly. This saves a lot of overhead in the VisualServer, plus you don't have to delete and re-allocate buffers every frame. Accordingly, it is the fastest way to update meshes dynamically, but it is very complex and it is easy to completely break your mesh
Here I will lay out plans for updating the documentation appropriately. This is more for me than anyone else.
First: update [Mesh.surface_update_region()](https://docs.godotengine.org/en/stable/classes/class_arraymesh.html#class-arraymesh-method-surface-update-region) and the corresponding VisualServer Functions.
Next: Add a tutorial to the [Procedural Geometry](https://docs.godotengine.org/en/stable/tutorials/content/procedural_geometry/index.html) series using ``Mesh.surface_update_region()``. ``Mesh.surface_update_region()`` is the fastest way to have dynamic geometry. It is used internally by softbody meshes and Sprite3Ds. But it can be a real pain to work with. The tutorial will have to outline how to access the vertex buffer properly. As well as explain how each part of the buffer changes when mesh compression settings are used (since GDScript doesn't have ``half_float``'s this section will only be useful for GDNative and maybe C#).
Below is example code for the extreme basics.
```
extends MeshInstance
var array
var surface_format
var vertex_len
var index_len
var mesh_buffer
var mesh_stride
var vertex_offset
func _ready():
array = VisualServer.mesh_surface_get_array(mesh.get_rid(), 0)
surface_format = VisualServer.mesh_surface_get_format(mesh.get_rid(), 0)
vertex_len = VisualServer.mesh_surface_get_array_len(mesh.get_rid(), 0)
index_len = VisualServer.mesh_surface_get_array_index_len(mesh.get_rid(), 0)
mesh_buffer = VisualServer.mesh_surface_get_array(mesh.get_rid(), 0)
mesh_stride = VisualServer.mesh_surface_get_format_stride(surface_format, vertex_len, index_len)
vertex_offset = VisualServer.mesh_surface_get_format_offset(surface_format, vertex_len, index_len, VisualServer.ARRAY_VERTEX)
func _process(delta):
var pos = get_node("../Camera").project_position(get_viewport().get_mouse_position(), 1.5)
var a = PoolRealArray()
a.resize(3)
a[0] = pos.x
a[1] = pos.y
a[2] = pos.z
var c = var2bytes(a)
# Ignore the array type and the var type inside the array
for i in range(12):
array[vertex_offset + i] = c[i+8]
VisualServer.mesh_surface_update_region(mesh.get_rid(), 0, 0, array)
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.