0
\$\begingroup\$

I want to generate a simplified mesh from cubes placed in a GridMap in Godot. I came up with the following code, however, the resulting ArrayMesh appears so be invalid, as surface_get_arrays(0).size() will always evaluate to 0. Can anyone point me in the right direction what the issue might be?

func create_combined_cube_mesh(gridmap: GridMap) -> ArrayMesh:
    print("Create combined cube mesh...")
    var start = Time.get_ticks_msec()
    
    var array_mesh = ArrayMesh.new()
    var box_mesh = BoxMesh.new()
    box_mesh.size = gridmap.cell_size

    var arrays = box_mesh.surface_get_arrays(0)
    var vertices = arrays[Mesh.ARRAY_VERTEX]
    var indices = arrays[Mesh.ARRAY_INDEX]

    var mesh_data = []
    mesh_data.resize(Mesh.ARRAY_MAX)
    mesh_data[Mesh.ARRAY_VERTEX] = []
    mesh_data[Mesh.ARRAY_INDEX] = []

    var vertex_offset = 0
    
    for cell in gridmap.get_used_cells():
        
        var transform = gridmap.map_to_local(cell)
        for v in vertices:
            mesh_data[Mesh.ARRAY_VERTEX].append(v + transform)

        for i in indices:
            mesh_data[Mesh.ARRAY_INDEX].append(i + vertex_offset)

        vertex_offset += vertices.size()
    

    array_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, mesh_data)
    
    print(array_mesh.surface_get_arrays(0).size()) // prints 0, but should contain a surface at index 0, as per 1 line above, huh!?
    
    return array_mesh if mesh_data[Mesh.ARRAY_VERTEX].size() > 0 else null
```
\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

I also had to include the normals and uv arrays, now it works:

func create_combined_cube_mesh(gridmap: GridMap) -> ArrayMesh:
    print("Create combined cube mesh...")
    var start = Time.get_ticks_msec()
    var array_mesh = ArrayMesh.new()
    var box_mesh = BoxMesh.new()
    box_mesh.size = gridmap.cell_size

    var box_arrays = box_mesh.surface_get_arrays(0)
    var box_vertices = box_arrays[Mesh.ARRAY_VERTEX]
    var box_uvs = box_arrays[Mesh.ARRAY_TEX_UV]
    var box_indices = box_arrays[Mesh.ARRAY_INDEX]
    var box_normals = box_arrays[Mesh.ARRAY_NORMAL]
    
    var verts = PackedVector3Array()
    var uvs = PackedVector2Array()
    var normals = PackedVector3Array()
    var indices = PackedInt32Array()

    var vertex_offset = 0
    var cell_times = []
    
    for cell in gridmap.get_used_cells():
        var cell_start = Time.get_ticks_msec()
        
        var transform = gridmap.map_to_local(cell)
        for v in box_vertices:
            verts.append(v + transform)
            
        for uv in box_uvs:
            uvs.append(uv)
            
        for normal in box_normals:
            normals.append(normal)

        for i in box_indices:
            indices.append(i + vertex_offset)

        vertex_offset += box_vertices.size()
        
        cell_times.append(Time.get_ticks_msec() - cell_start)

    var mesh_data = []
    mesh_data.resize(Mesh.ARRAY_MAX)
    mesh_data[Mesh.ARRAY_VERTEX] = verts
    mesh_data[Mesh.ARRAY_TEX_UV] = uvs
    mesh_data[Mesh.ARRAY_INDEX] = indices
    mesh_data[Mesh.ARRAY_NORMAL] = normals

    array_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, mesh_data)
    var res = array_mesh if mesh_data[Mesh.ARRAY_VERTEX].size() > 0 else null
    
    var cell_times_total = cell_times.reduce(sum, 0)
    print("cell_times total: " + str(cell_times_total) + " ms, samples: " + str(len(cell_times)) + ", average: " + str( cell_times_total * 1.0 / len(cell_times)) + " ms")
    print("Creating combined cube mesh done, took " + str(Time.get_ticks_msec() - start) + "ms")
    
    return res
```
\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.