0 votes

Hi I'm trying to generate a mesh (for testing water waves) and I'm following this tutorial which is made for Unity. The code for their plane generation (C#) is here.
I'm adapting it using the ArrayMesh tutorial. I get an error trying to add the surface to the mesh:

E 0:00:00.715   _surface_set_data: Condition "array.size() != p_vertex_array_len" is true. Returned: ERR_INVALID_PARAMETER
<C++ Source>  servers/visual_server.cpp:466 @ _surface_set_data()
<Stack Trace> MeshWave.gd:22 @ _ready()

so here's my GDScript version of the code (waveless, just want the plane for now).

extends MeshInstance

var dimension = 10

func _ready():
    # PoolVectorXXArrays for mesh construction.
    var verts = get_verts()
    var uvs = get_uvs(verts)
    var normals = get_normals(verts)
    var indices = get_tris(verts)

    var arr_mesh = ArrayMesh.new()
    var arr = []
    # Assign arrays to mesh array.
    arr[Mesh.ARRAY_VERTEX] = verts
    arr[Mesh.ARRAY_TEX_UV] = uvs
    arr[Mesh.ARRAY_NORMAL] = normals
    arr[Mesh.ARRAY_INDEX] = indices

    # Create mesh surface from mesh array.
    arr_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arr)
    mesh = arr_mesh
#   mesh.regen_normalmaps()

func get_verts():
    var verts = PoolVector3Array()
    verts.resize((dimension + 1) * (dimension + 1))
    for x in range(dimension+1):
        for z in range(dimension+1):
            print('verts: ' + str(Vector3(x, 0, z)))
            print('idx' + str(index(x, z)))
            verts.insert(index(x, z), Vector3(x, 0, z))
    return verts

func index(x, z):
    return x * (dimension + 1) + z

func get_tris(verts):
    var tris = PoolIntArray()
    tris.resize(verts.size() * 6)
    for x in range(dimension):
        for z in range(dimension):
            var idx = index(x, z)
            tris.insert(idx * 6 + 0, idx)
            tris.insert(idx * 6 + 1, index(x + 1, z + 1))
            tris.insert(idx * 6 + 2, index(x + 1, z))
            tris.insert(idx * 6 + 3, idx)
            tris.insert(idx * 6 + 4, index(x, z + 1))
            tris.insert(idx * 6 + 5, index(x + 1, z + 1))
    return tris

func get_normals(verts):
    var norms = PoolVector3Array()
    for vert in verts:
    return norms

func get_uvs(verts):
    var uvs = PoolVector2Array()
    for i in range(dimension):
        for j in range(dimension):
            uvs.append(Vector2(i/dimension, j/dimension))
    return uvs

Where am I going wrong with my mesh generating? The generate normals function also returns a bunch of errors. If generate with only the verts I don't get a plane, just some strange triangles.
If there are better ways to do this, then I would love to know haha. I'm kind of stumbling my way through learning this. Thanks :)

Godot version 3.2.1.stable
in Engine by (21 points)

i assume the mistake is in the varius get_vert/normal/uv, since the _ready() part is taken from the docs.
it seems the error is about some array size, are you sure you are not confusing yourself with dimension and dimension+1?
*eg: verts size is dimension+1, you set uv.size=verts.size, but then you only cyle up to dimension*

thank you! I had another look at the array sizes and I was iterating up to the wrong size in the UVs function, but more importantly I was using arr.insert() instead of arr.set() so my arrays were double the size that I needed them to be. I now have a janky looking plane, but a plane nonetheless :)

Please log in or register to answer this question.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.