Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Get mesh from sprite without allocations

Discussion in 'Scripting' started by palex-nx, Dec 9, 2019.

  1. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,745
    Hello Unity community!

    I'm experimenting with ecs now and Im trying to draw multiple sprites using their meshes as they defined in sprite importer. I'm asking my question here instead of experimental forum section because it is not directly related with Ecs, it is more about sprites and meshes vertex/index buffers.

    So far I've managed to extract sprite vertices and uvs, generate mesh, and push it to appopriate component, and it is drawn on screen. Everything works, no problem here, except I need to double copy vertex buffer because Sprite class retruns Vector2[] for vertices and Mesh class wants Vector3[].

    I discovered what that vertex buffer is a copy of sprite data. Therefore, my code instantiates 2 copies of vertex buffer and again copies it into Mesh instance. I see it as very poor design. I'd like to know if I able to extract mesh from sprite importer settings without allocations at all in runtime? Okay, I agree to copy my buffer to mesh is required, but is there anything to avoid creating two copies of vertext buffer and one copy of index buffer and uv buffer? Maybe Im missing something obvious?
    Thank you!
     
  2. palex-nx

    palex-nx

    Joined:
    Jul 23, 2018
    Posts:
    1,745
    Since there's no answer, i post some code to illustrate the problem

    Code (CSharp):
    1.    public class SpriteMeshExtractor
    2.    {
    3.       private readonly List<Vector3> _vertices = new List<Vector3>();
    4.    
    5.       public Mesh meshFromSprite(Sprite sprite)
    6.       {
    7.          var vertices = sprite.vertices; // first copy of vertex buffer occurs here, when it is marshalled from unmanaged to managed memory
    8.          var mesh = new Mesh();
    9.    
    10.          _vertices.Clear();  // this temporary buffer allows me to avoid one of those allocation, but i still do copy of data because Mesh.SetVertices can't accept Vector2[]
    11.  
    12.          for (var i = 0; i < vertices.Length; i++)
    13.          {
    14.             _vertices.Add(vertices[i]);
    15.          }
    16.    
    17.          mesh.SetVertices(_vertices);  // here's the third copy of vertex buffer is created and marshalled back to unmanaged memory
    18.          mesh.SetTriangles(sprite.triangles, 0);
    19.          mesh.SetUVs(0, sprite.uv);
    20.          mesh.RecalculateBounds();
    21.  
    22.          return mesh;
    23.       }
    24.    }
    Is there any way to avoid those pointless copying? For my demo game I need to create up to 4 * 9 * 11 = 396 sprites on scene load, not including characters. This leads to 3 * 396 = 1188 redundant copy operations for super simple 2d game.
     
    ZenTeapot likes this.
  3. ZenTeapot

    ZenTeapot

    Joined:
    Oct 19, 2014
    Posts:
    65
    Bump. No way to do this?
     
  4. weiner_monkey

    weiner_monkey

    Joined:
    Aug 1, 2022
    Posts:
    49
    Still no way to do this