godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.16k stars 97 forks source link

SurfaceTool: Add a method to generate a surface based on vertices and index arrays #3344

Open ghsoares opened 3 years ago

ghsoares commented 3 years ago

Describe the project you are working on

Infinite runner with procedural terrain

Describe the problem or limitation you are having in your project

In my runner game, I'm generating the terrain procedurally with noise, and using SurfaceTool to generate the mesh in C#. I'm using csharp's arrays for the vertices, normals, uvs, indexes, etc. And using SurfaceTool's add_triangle_fan to add the triangles to commit. But this method don't take a index array, so it takes that every three vertices there's a triangle, but in my case I'm not adding duplicated vertices, so the result is something like this: image And the rest of the triangles are upside down: image I need to use SurfaceTool to be able to generate tangents, which I don't know how to calculate, if I generate a ArrayMesh then use SurfaceTool just for the tangent generation part it would impact the performance.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

The feature is to add a method to SurfaceTool to add vertices, indexes, uvs (optional), colors (optional), uv2s (optional), normals (optional) and tangents (optional), similar to add_triangle_fan. The signature could be something like this:

add_surface_from_arrays(
    vertices: PoolVector3Array, indexes: PoolIntArray, uvs: PoolVector2Array = PoolVector2Array(  ),
    colors: PoolColorArray = PoolColorArray(  ), uv2s: PoolVector2Array = PoolVector2Array(  ),
    normals: PoolVector3Array = PoolVector3Array(  ), tangents: Array = [  ]
)

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

It would work similar to add_triangle_fan, but taking into account the index array instead of three vertices for a triangle.

If this enhancement will not be used often, can it be worked around with a few lines of script?

Not so simple, it would be possible but would require complex knowledge of vector mathematics.

Is there a reason why this should be core and not an add-on in the asset library?

Because it makes more sense to be implemented into SurfaceTool, as the standard for mesh generation is to use a index array along with the vertices array.

fire commented 3 years ago

I looked at the master source. The surface tool is either adding per vertex or per index.

Exposing create_from_triangle_arrays(Array arrays) solves your proposal.

Note that this is not the proposed api of add_surface_from_arrays( vertices: PoolVector3Array, indexes: PoolIntArray, uvs: PoolVector2Array = PoolVector2Array( ), colors: PoolColorArray = PoolColorArray( ), uv2s: PoolVector2Array = PoolVector2Array( ), normals: PoolVector3Array = PoolVector3Array( ), tangents: Array = [ ] )

void create_from_triangle_arrays(const Array &p_arrays);

https://github.com/godotengine/godot/blob/8aedcfced7462f19d3e341ca593a415165f36a0f/scene/resources/surface_tool.h#L184

ghsoares commented 3 years ago

@fire This seems to do, I wasn't finding the line that gets the provided index array, but I found it in this line: https://github.com/godotengine/godot/blob/8aedcfced7462f19d3e341ca593a415165f36a0f/scene/resources/surface_tool.cpp#L821 I guess that this is the correct line?

fire commented 2 years ago

Is this resolved?

I'm currently investigating the winged edge representation for edges. https://github.com/jarneson/godot-ply