Search Unity

  1. Looking for a job or to hire someone for a project? Check out the re-opened job forums.
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Help Wanted How to define stride in Mesh.SetVertexBufferData with raw float[] array

Discussion in 'General Graphics' started by JimboJonesBL, Jan 15, 2021.

  1. JimboJonesBL

    JimboJonesBL

    Joined:
    Jul 16, 2020
    Posts:
    8
    Hey everyone,

    I hope this is the right thread for my problem.

    I receive (position) sensor data every frame from a C++ backend and want to insert it directly in the vertices property of a Mesh object. The received information is a simple float array, where 3 floats describe a vertex. The index list is just and ascending array of uint's, that doesn't change and therefore can be precomputed.

    My first idea was to loop over the array, create a Vector3 array and assign this to Mesh.vertices. This introduces a (hopefully) unnecessary step, though, that results in a strong performance hit.

    The other idea was to directly write to the vertex buffer of the mesh object with Mesh.SetVertexBufferData. The only problem is that I can't specify a stride to tell how many entries of this float array build an actual vertex position as I would in plane OpenGL for example.

    I already read about the Job system, yet I think that there has to be some way of defining a stride that I was unable to filter out from the documentation.

    The code below works only with lines 38/39 but not with 35/36.
    I'm working on Unity 2019.4.16f1 with URP 7.3.1.

    Code (CSharp):
    1. public class MeshFromRaw : MonoBehaviour
    2. {
    3.  
    4.     [SerializeField]
    5.     private Material MeshMaterial;
    6.     private Mesh _mesh;
    7.  
    8.     void Start()
    9.     {
    10.         gameObject.AddComponent<MeshFilter>();
    11.         gameObject.AddComponent<MeshRenderer>();
    12.         _mesh = GetComponent<MeshFilter>().mesh;
    13.  
    14.         FillMeshWFloat();
    15.  
    16.         MeshRenderer renderer = GetComponent<MeshRenderer>();
    17.         renderer.material = MeshMaterial;
    18.     }
    19.    
    20.     // For simplicity reasons, just builds a triangle and fills vertex and index buffers
    21.     private void FillMeshWFloat()
    22.     {
    23.         _mesh.Clear();
    24.         // simple float array with vertex data. DOES NOT WORK
    25.         float[] vertices = new float[] { 0.0f, 0.0f, 1.0f,
    26.                                         1.0f, 0.0f, 3.0f
    27.                                         2.0f, 0.0f, 1.0f,};
    28.  
    29.         // The "standard" way that works.
    30.         Vector3[] verticesVec3 = new Vector3[] { new Vector3(0, 0, 1),
    31.                                                  new Vector3(1, 0, 3),
    32.                                                  new Vector3(2, 0, 1) };
    33.  
    34.         uint[] indices = new uint[] { 0, 1, 2 };
    35.  
    36.         //_mesh.SetVertexBufferParams(vertices.Length/3, new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3));
    37.         //_mesh.SetVertexBufferData<float>(vertices, 0, 0, vertices.Length/3);
    38.  
    39.         _mesh.SetVertexBufferParams(verticesVec3.Length, new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, 3));
    40.         _mesh.SetVertexBufferData<Vector3>(verticesVec3, 0, 0, verticesVec3.Length);
    41.  
    42.         _mesh.SetIndexBufferParams(indices.Length, IndexFormat.UInt32);
    43.         _mesh.SetIndexBufferData<uint>(indices, 0, 0, indices.Length);
    44.  
    45.         _mesh.SetSubMesh(0, new SubMeshDescriptor(0, indices.Length));
    46.         _mesh.bounds = new Bounds(Vector3.zero, Vector3.one * 1000);
    47.         _mesh.RecalculateNormals();
    48.     }
    49. }
     
unityunity