Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

Bug ApplyAndDisposeWritableMeshData applies same data to all meshes.

Discussion in 'C# Job System' started by tonytopper, Nov 29, 2022.

  1. tonytopper

    tonytopper

    Joined:
    Jun 25, 2018
    Posts:
    229
    Code (CSharp):
    1. Mesh.ApplyAndDisposeWritableMeshData(
    2.    data: tangentJob.outputBranches,
    3.    meshes: meshes
    4. );
    Calling this version of the function.

    Code (CSharp):
    1. public static void ApplyAndDisposeWritableMeshData(MeshDataArray data, Mesh[] meshes, MeshUpdateFlags flags = MeshUpdateFlags.Default);
    I verified the data in the outputBranches MeshDataArray is different by outputing the vertexCount of outputBranches and the vertexCount of the meshes Mesh array. They do not match.

    The erroneous result is the Mesh instances in the meshes array have the same vertex and index count, which matches the first Mesh instance in the outputBranches MeshDataArray.

    It is also not recalculating bounds.

    Pretty sure there is a bug in ApplyAndDisposeWritableMeshData.

    Unity version 2022.1.23f1
    Jobs: 0.51.0-preview.32

    More complete code for further analysis:

    Code (CSharp):
    1. var tangentJob = new BuildMeshTangentsJob()
    2.             {
    3.                 inputBranches = meshBuilder.GetReadOnlyMeshDataArray(),
    4.                 outputBranches = AllocateWritableMeshData(meshBuilder.branchMeshes.Count)
    5.             };
    6.          
    7.             JobHandle handle = tangentJob.Schedule(meshBuilder.branchMeshes.Count, 1);
    8.  
    9.             Mesh[] meshes = new Mesh[meshBuilder.branchMeshes.Count];
    10.             Array.Fill(meshes, new Mesh());
    11.  
    12.             handle.Complete();
    13.  
    14.             for (int bN = 0; bN < 12; bN++)
    15.             {
    16.                 Debug.Log(
    17.                     $"i:{bN} of {tangentJob.outputBranches.Length} - Output: {tangentJob.outputBranches[bN].vertexCount} , indexes: , " +
    18.                     $"Input: {meshBuilder.branchMeshes[bN].vertexCount}, indexes: "
    19.                 );
    20.             }
    21.  
    22.             ApplyAndDisposeWritableMeshData(
    23.                 data: tangentJob.outputBranches,
    24.                 meshes: meshes
    25.             );
    26.  
    27.             for (int bN = 0; bN < meshes.Length; bN++)
    28.             {
    29.                 meshes[bN].RecalculateBounds();
    30.                 if (bN < 12)
    31.                 {
    32.                     Debug.Log(
    33.                         $"i:{bN} of {tangentJob.outputBranches.Length} - Output -- vertexes: {meshes[bN].vertexCount}, indexes: {meshes[bN].GetIndexCount(0)}, " +
    34.                         $"Input: {meshBuilder.branchMeshes[bN].vertexCount}, indexes: {meshBuilder.branchMeshes[bN].GetIndexCount(0)}\n" +
    35.                         $"{string.Join(", ", meshes[bN].vertices[0..5])}\n" +
    36.                         $"{string.Join(", ", meshes[bN].triangles[0..24])}"
    37.                     );
    38.                 }
    39.             }
    40.  
     
  2. tonytopper

    tonytopper

    Joined:
    Jun 25, 2018
    Posts:
    229
    Array Fill was the wrong call. It was filling the entire array with a reference to the same mesh.

    Code (CSharp):
    1. Array.Fill(meshes, new Mesh());
    Would be nice if ApplyAndDisposeWritableMeshData could handle null values.
     
  3. Trindenberg

    Trindenberg

    Joined:
    Dec 3, 2017
    Posts:
    416
    You could create your own MeshDataArray and add MeshData excluding nulls, then apply and dispose