Godot Version
4.6 Stable
Question
I’m trying to add origin to circle , so then I could create indices to render it triangles ( sliced pizza )
but something I don’t understand is how can I add this start_vector / point to PackedVector3Array() after loop , as debugger is complain no matter what I tried with push_back() append()
here is error
E 0:00:00:245 circle_mesh_array.gd:23 @ _ready(): Condition "array.size() != p_vertex_array_len" is true. Returning: ERR_INVALID_PARAMETER
<C++ Source> servers/rendering/rendering_server.cpp:612 @ _surface_set_data()
<Stack Trace> circle_mesh_array.gd:23 @ _ready()
E 0:00:00:245 circle_mesh_array.gd:23 @ _ready(): Invalid array format for surface.
<C++ Error> Condition "err != OK" is true. Returning: ERR_INVALID_DATA
<C++ Source> servers/rendering/rendering_server.cpp:1310 @ mesh_create_surface_data_from_arrays()
<Stack Trace> circle_mesh_array.gd:23 @ _ready()
E 0:00:00:245 circle_mesh_array.gd:23 @ _ready(): Condition "err != OK" is true.
<C++ Source> scene/resources/mesh.cpp:1825 @ add_surface_from_arrays()
<Stack Trace> circle_mesh_array.gd:23 @ _ready()
Does this mean the .resize() need to be executed after loop again to resize or something else ?
current code
extends MeshInstance3D
func _ready() -> void:
var surface_array = []
surface_array.resize(Mesh.ARRAY_MAX)
var my_vertices = PackedVector3Array()
var my_uvs = PackedVector2Array()
var my_normals = PackedVector3Array()
var point := Vector3.RIGHT
var steps := 32
var angle_step := TAU / steps
my_vertices.append(point)
for i in steps:
my_vertices.append(point)
point = point.rotated(Vector3.UP, angle_step)
my_uvs.push_back(Vector2(0,0))
my_normals.push_back(Vector3.UP)
surface_array[Mesh.ARRAY_VERTEX] = my_vertices
surface_array[Mesh.ARRAY_TEX_UV] = my_uvs
surface_array[Mesh.ARRAY_NORMAL] = my_normals
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_POINTS, surface_array)
I tried before and after loop same error.
You need to append an uv and a normal as well. The number of all vertex attributes must match.
If you’re just drawing lines though, you can completely disregards uv and normal arrays, and only use the vertex array
Btw append() and push_back() do the same thing. So use either one or the other throughout the code for the sake of stylistic consistency.
Tried that
nothing on screen, and Debugger going crazy
E 0:00:00:249 draw_list_draw: Vertex amount (33) must be a multiple of the amount of vertices required by the render primitive (2).
<C++ Error> Condition "(to_draw % draw_list.validation.pipeline_primitive_divisor) != 0" is true.
<C++ Source> servers/rendering/rendering_device.cpp:5145 @ draw_list_draw()
extends MeshInstance3D
func _ready() -> void:
var surface_array = []
surface_array.resize(Mesh.ARRAY_MAX)
var my_vertices = PackedVector3Array()
var point := Vector3.RIGHT
var steps := 32
var angle_step := TAU / steps
for i in steps:
my_vertices.append(point)
point = point.rotated(Vector3.UP, angle_step)
my_vertices.append(point)
surface_array[Mesh.ARRAY_VERTEX] = my_vertices
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_LINES, surface_array)
ok 31 + 1
but for POINTS its still showing nothing
For start, use the point primitve, not line. Line requires a pair of vertices for each line, so the total number of vertices must be even.
for points nothing is rendered now .
but also if I want to make for example indices for triangles pizza does it mean I need to add origin twice to keep count happy to be able make triangles/ lines ?
Show the code.
For triangle primitive, you’ll need 3 vertices per triangle. So the total number must be a multiple of 3. Otherwise the engine will complain.
1 Like
for points code
extends MeshInstance3D
func _ready() -> void:
var surface_array = []
surface_array.resize(Mesh.ARRAY_MAX)
var my_vertices = PackedVector3Array()
var point := Vector3.RIGHT
var steps := 32
var angle_step := TAU / steps
for i in steps:
my_vertices.append(point)
point = point.rotated(Vector3.UP, angle_step)
my_vertices.append(point)
surface_array[Mesh.ARRAY_VERTEX] = my_vertices
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_POINTS, surface_array)
nothing on screen
Go back to last working version.
right so uv and normals to be added right ?
extends MeshInstance3D
func _ready() -> void:
var surface_array = []
surface_array.resize(Mesh.ARRAY_MAX)
var my_vertices = PackedVector3Array()
var my_uvs = PackedVector2Array()
var my_normals = PackedVector3Array()
var point := Vector3.RIGHT
var steps := 32
var angle_step := TAU / steps
my_vertices.append(point)
my_uvs.append(Vector2(0,0))
my_normals.append(Vector3.UP)
for i in steps:
my_vertices.append(point)
point = point.rotated(Vector3.UP, angle_step)
my_uvs.append(Vector2(0,0))
my_normals.append(Vector3.UP)
surface_array[Mesh.ARRAY_VERTEX] = my_vertices
surface_array[Mesh.ARRAY_TEX_UV] = my_uvs
surface_array[Mesh.ARRAY_NORMAL] = my_normals
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_POINTS, surface_array)
but just find out the point is not actually origin , I will need to take some opposite 2 vertices and find middle
could I get it by some formula from my_vertices take array index 0 and steps/2 and minus those two Vector3 values - , instead of hardcode Vector3(0,0,0) ?
print(my_vertices.get(0), my_vertices.get(steps/2))
(1.0, 0.0, 0.0)(-0.999999, 0.0, 0.0)
Why? The way you calculate your circle points imply that the center is at 0,0. The center is a given, the points are relative to the center, not the other way around.
Always start with defining the center. If you want center at some position other than zero, you’ll need to add the center position to the point positions.
Although having a center other than zero is typically not needed.
Starting point can be anything you like. Whatever you use it will do full TAU rotation around the origin.
1 Like
in case I change variable
var point := Vector3.RIGHT
to something else
current code
extends MeshInstance3D
func _ready() -> void:
var surface_array = []
surface_array.resize(Mesh.ARRAY_MAX)
var my_vertices = PackedVector3Array()
var my_uvs = PackedVector2Array()
var my_normals = PackedVector3Array()
var point := Vector3.RIGHT
var steps := 32
var angle_step := TAU / steps
for i in steps:
my_vertices.append(point)
point = point.rotated(Vector3.UP, angle_step)
my_uvs.append(Vector2(0,0))
my_normals.append(Vector3.UP)
my_vertices.append(my_vertices.get(0) + my_vertices.get(steps/2))
my_uvs.append(Vector2(0,0))
my_normals.append(Vector3.UP)
surface_array[Mesh.ARRAY_VERTEX] = my_vertices
surface_array[Mesh.ARRAY_TEX_UV] = my_uvs
surface_array[Mesh.ARRAY_NORMAL] = my_normals
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_POINTS, surface_array)
I’m just not sure why removing the uvs and normals causes problems. It should work with vertex positions only.
not sure, but it didn’t worked for me .
Have you tried it yourself ?
It’s probably shading making it black. Try setting unshaded flag for the material and then remove uvs and normals.
No, the origin is Vector3(0, 0, 0). You can use Vector3.ZERO
1 Like
it doesn’t have any material option only override , shall I create override and set it there ?
Yes, assign a new material to material_override and set it there.