Errors generating a plane with ArrayMesh ("array.size() != p_vertex_array_len")

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By MaxwellDexter

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 = []
	arr.resize(Mesh.ARRAY_MAX)
	# 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()
	norms.resize(verts.size())
	for vert in verts:
		norms.append(vert.normalized())
	return norms

func get_uvs(verts):
	var uvs = PoolVector2Array()
	uvs.resize(verts.size())
	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 :slight_smile:

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

Andrea | 2021-01-19 13:13

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 :slight_smile:

MaxwellDexter | 2021-01-19 22:09