Created
August 14, 2024 15:02
-
-
Save N-Carter/373b655e9f5c9de4f2c4a4db60c26464 to your computer and use it in GitHub Desktop.
How to use ArrayMesh.surface_update_vertex_region() in Godot 4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extends MeshInstance3D | |
@export var _grid_size := 2 | |
# Which of the array of quads to change (must be between 0 and _grid_size * _grid_size): | |
@export var _quad_to_change := 1 | |
var _array_mesh : ArrayMesh | |
func _ready() -> void: | |
_array_mesh = ArrayMesh.new() | |
var vertices = PackedVector3Array() | |
# Fill the vertex array with quads arranged in a grid. The quads are made out of two triangles: | |
for y in _grid_size: | |
for x in _grid_size: | |
vertices.append_array(_create_quad_vertices(Vector3(x, y, 0), 0.9)) | |
# Just using the vertex array here for simplicity: | |
var arrays = [] | |
arrays.resize(Mesh.ARRAY_MAX) | |
arrays[Mesh.ARRAY_VERTEX] = vertices | |
# Calling this function once puts the new surface in index 0, and each subsequent call will | |
# increase the new surface number by one: | |
_array_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays) | |
mesh = _array_mesh | |
func _process(delta: float) -> void: | |
# We're going to randomly change the size of one of the quads every frame. | |
# We have to work out its position again, but that's not part of the example: | |
var quad_origin := Vector3(_quad_to_change % _grid_size, _quad_to_change / _grid_size, 0.0) | |
# Make a new set of vertices for that quad: | |
var new_vertices := _create_quad_vertices(quad_origin, randf() * 0.5) | |
# Convert it into something which surface_update_vertex_region() will accept: | |
var byte_array := new_vertices.to_byte_array() | |
# We have to pass an offset in byte indices, not in vertex indices. We have 6 vertices per | |
# quad, 3 elements per vertex (x, y, z) and each element is 4 bytes (a float): | |
var byte_offset := 6 * 3 * 4 | |
# We're editing surface index 0 because that's the only one we have: | |
_array_mesh.surface_update_vertex_region(0, _quad_to_change * byte_offset, byte_array) | |
func _create_quad_vertices(origin : Vector3, scale : float) -> PackedVector3Array: | |
# Create a quad out of two triangles: | |
var vertices = PackedVector3Array() | |
vertices.push_back(origin + Vector3(0.0, 0.0, 0.0) * scale) | |
vertices.push_back(origin + Vector3(0.0, 1.0, 0.0) * scale) | |
vertices.push_back(origin + Vector3(1.0, 1.0, 0.0) * scale) | |
vertices.push_back(origin + Vector3(0.0, 0.0, 0.0) * scale) | |
vertices.push_back(origin + Vector3(1.0, 1.0, 0.0) * scale) | |
vertices.push_back(origin + Vector3(1.0, 0.0, 0.0) * scale) | |
return vertices |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment