Mesh Generation From Code Acts Odd

When Generating a mesh’s vertices and triangles trough code, all triangles and vertices seem correct, but after applying the mesh to mesh Filter, the faces render completely random and inverted.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using Unity.Burst;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Entities;
using Unity.Mathematics;
using Unity.VisualScripting;
using UnityEngine;

[RequireComponent(typeof(MeshRenderer))]
[RequireComponent(typeof(MeshFilter))]
[BurstCompile]
public class MeshCalculator : MonoBehaviour
{
    public static MeshCalculator Instance;
    private void Awake()
    {
        Instance = this;
    }




    public float cubeSize = 1;

    private MeshRenderer meshRenderer;
    private MeshFilter meshFilter;


    public int atlasSize;

    public int randomSpawnAmount;
    public Vector3Int spawnBounds;

    public bool drawBoundsGizmos;
    public bool drawGridGizmos;
    public Color gridGizmoColor;





    private void Start()
    {
        meshRenderer = GetComponent<MeshRenderer>();
        meshFilter = GetComponent<MeshFilter>();
        stopwatch = Stopwatch.StartNew();


        NativeList<float3> blockPositions = new NativeList<float3>(Allocator.Persistent);

        if (randomSpawnAmount > 0)
        {
            List<float3> possiblePositions = new List<float3>();

            for (int x = 0; x < spawnBounds.x + 1; x++)
            {
                for (int y = 0; y < spawnBounds.y + 1; y++)
                {
                    for (int z = 0; z < spawnBounds.z + 1; z++)
                    {
                        possiblePositions.Add(new float3((x - spawnBounds.x * 0.5f) * cubeSize, (y - spawnBounds.y * 0.5f) * cubeSize, (z - spawnBounds.z * 0.5f) * cubeSize));
                    }
                }
            }


            int calculatedAmount = Mathf.Min(randomSpawnAmount, possiblePositions.Count);

            for (int i = 0; i < calculatedAmount; i++)
            {
                int r = UnityEngine.Random.Range(0, possiblePositions.Count);
                blockPositions.Add(possiblePositions[r]);
                possiblePositions.RemoveAt(r);
            }
        }

        print("Preperation Done In: " + stopwatch.ElapsedMilliseconds + "ms");

        MeshCalculatorJob.CallGenerateMeshJob(blockPositions, cubeSize, atlasSize);

        blockPositions.Dispose();
    }





    #region Performance ANTI Local Variables

    private float3 halfCubeSize;

    private Stopwatch stopwatch;
    #endregion



    public Vector3[] debugVerts;
    public int[] debugTris;

    public void ApplyMeshToObject(NativeList<float3> vertices, NativeList<int> triangles, NativeArray<byte> cubeFacesActiveState, NativeArray<int> textureIndexs)
    {
        print("Started Applying mesh at: " + stopwatch.ElapsedMilliseconds + "ms");

        // Create a new mesh and assign the vertices, triangles, and normals
        Mesh mesh = new Mesh();

        if (vertices.Length > 65535)
        {
            mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
        }



        Vector3[] verticesVectors = new Vector3[vertices.Length];

        int loopIndex = 0;
        foreach (float3 vertex in vertices)
        {
            verticesVectors[loopIndex] = new Vector3(vertex.x, vertex.y, vertex.z);
            loopIndex += 1;
        }


        int[] trianglesVectors = new int[triangles.Length];

        loopIndex = 0;
        foreach (int triangle in triangles)
        {
            print(triangle);

            trianglesVectors[loopIndex] = triangle;
            loopIndex += 1;
        }
        print(trianglesVectors.Length);



        mesh.vertices = verticesVectors;
        mesh.triangles = trianglesVectors;


        //NativeArray<float2> uvs = new NativeArray<float2>(vertices.Length, Allocator.Persistent);
        //TextureCalculator.ScheduleUVGeneration(uvs, vertices.Length, cubeFacesActiveState, textureIndexs, atlasSize);

        //Vector2[] vectorUvs = new Vector2[vertices.Length];
        //for (int i = 0; i < vectorUvs.Length; i++)
        //{
        //    vectorUvs[i] = new Vector2(uvs[i].x, uvs[i].y);
        //}


        debugVerts = verticesVectors;
        debugTris = mesh.triangles;

        //mesh.uv = vectorUvs;

        mesh.RecalculateNormals();
        mesh.RecalculateBounds();

        meshFilter.mesh = mesh;

        //uvs.Dispose();

        stopwatch.Stop();

        print("Generated Mesh After " + stopwatch.ElapsedMilliseconds + "ms, With " + triangles.Length + " Tris And " + vertices.Length + " Vertices.");
    }






    //public Vector3Int chunkPosition; // Position of the chunk in the chunk grid (chunk coordinates)

    //public List<Vector3Int> GetConnectedEdge(Chunk neighbor)
    //{
    //    List<Vector3Int> edgePositions = new List<Vector3Int>();

    //    // Determine which side is connected to the current chunk based on relative position
    //    if (neighbor.chunkPosition.x < this.chunkPosition.x)
    //    {
    //        // Neighbor is on the left (West), return right edge
    //        edgePositions = GetEdgePositionsRight();
    //    }
    //    else if (neighbor.chunkPosition.x > this.chunkPosition.x)
    //    {
    //        // Neighbor is on the right (East), return left edge
    //        edgePositions = GetEdgePositionsLeft();
    //    }
    //    else if (neighbor.chunkPosition.z > this.chunkPosition.z)
    //    {
    //        // Neighbor is in front (North), return back edge
    //        edgePositions = GetEdgePositionsBack();
    //    }
    //    else if (neighbor.chunkPosition.z < this.chunkPosition.z)
    //    {
    //        // Neighbor is behind (South), return front edge
    //        edgePositions = GetEdgePositionsFront();
    //    }

    //    return edgePositions;
    //}


    ////
    ////
    ////
    ////
    ////
    ////
    ////
    ////DELETE FLOAT
    ////
    ////
    //public Vector3Int chunkSize;
    ////
    ////
    ////DELETE FLOAT
    ////
    ////
    ////
    ////
    ////
    ////
    ////
    ////
    ////


    //// Get the right edge (x = 15) of this chunk
    //private List<Vector3Int> GetEdgePositionsRight()
    //{
    //    List<Vector3Int> edgePositions = new List<Vector3Int>();
    //    for (int y = 0; y < chunkSize.y; y++)
    //    {
    //        for (int z = 0; z < chunkSize.z; z++)
    //        {
    //            edgePositions.Add(new Vector3Int(chunkSize.x - 1, y, z));
    //        }
    //    }
    //    return edgePositions;
    //}

    //// Get the left edge (x = 0) of this chunk
    //private List<Vector3Int> GetEdgePositionsLeft()
    //{
    //    List<Vector3Int> edgePositions = new List<Vector3Int>();
    //    for (int y = 0; y < chunkSize.y; y++)
    //    {
    //        for (int z = 0; z < chunkSize.z; z++)
    //        {
    //            edgePositions.Add(new Vector3Int(0, y, z));
    //        }
    //    }
    //    return edgePositions;
    //}

    //// Get the back edge (z = 15) of this chunk
    //private List<Vector3Int> GetEdgePositionsBack()
    //{
    //    List<Vector3Int> edgePositions = new List<Vector3Int>();
    //    for (int y = 0; y < chunkSize.y; y++)
    //    {
    //        for (int x = 0; x < chunkSize.x; x++)
    //        {
    //            edgePositions.Add(new Vector3Int(x, y, chunkSize.z - 1));
    //        }
    //    }
    //    return edgePositions;
    //}

    //// Get the front edge (z = 0) of this chunk
    //private List<Vector3Int> GetEdgePositionsFront()
    //{
    //    List<Vector3Int> edgePositions = new List<Vector3Int>();
    //    for (int y = 0; y < chunkSize.y; y++)
    //    {
    //        for (int x = 0; x < chunkSize.x; x++)
    //        {
    //            edgePositions.Add(new Vector3Int(x, y, 0));
    //        }
    //    }
    //    return edgePositions;
    //}



    private void OnDrawGizmos()
    {
        if (spawnBounds.x != 0 && spawnBounds.y != 0 && spawnBounds.z != 0)
        {
            if (drawGridGizmos)
            {
                Gizmos.color = gridGizmoColor;

                for (int x = 0; x < spawnBounds.x + 1; x++)
                {
                    for (int y = 0; y < spawnBounds.y + 1; y++)
                    {
                        for (int z = 0; z < spawnBounds.z + 1; z++)
                        {
                            Gizmos.DrawWireCube(transform.position + new Vector3((x - spawnBounds.x * 0.5f) * cubeSize, (y - spawnBounds.y * 0.5f) * cubeSize, (z - spawnBounds.z * 0.5f) * cubeSize), Vector3.one * cubeSize);
                        }
                    }
                }
            }

            if (drawBoundsGizmos)
            {
                Gizmos.color = Color.white;

                Gizmos.DrawWireCube(transform.position, spawnBounds + cubeSize * Vector3.one);
            }
        }
    }
}

script under here soesnt format?

using System;
using System.Collections;
using System.Collections.Generic;
using Unity.Burst;
using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;


[BurstCompile]
public class MeshCalculatorJob : MonoBehaviour
{
    public int debugMathComplexity;

    public int jobGroupAmount;
    public int jobTotalAmount;

    public int batchSize;

    public int completions;
    public float elapsed;

    public float timeCheck;

    public bool paused;



    public static void CallGenerateMeshJob(NativeList<float3> blockPositions, float cubeSize, int atlasSize)
    {
        int blockPositionsLength = blockPositions.Length;

        NativeList<float3> vertices = new NativeList<float3>(blockPositionsLength * 24, Allocator.TempJob);
        NativeArray<float3> sortedFaceVertices = new NativeArray<float3>(blockPositionsLength * 24, Allocator.TempJob);
        for (int i = 0; i < sortedFaceVertices.Length; i++)
        {
            sortedFaceVertices[i] = new float3(0.1f, 0, 0);
        }

        NativeList<int> triangles = new NativeList<int>(blockPositionsLength * 36, Allocator.TempJob);
        NativeArray<int> sortedFaceTriangles = new NativeArray<int>(blockPositionsLength * 36, Allocator.TempJob);
        for (int i = 0; i < sortedFaceTriangles.Length; i++)
        {
            sortedFaceTriangles[i] = -1;
        }

        NativeArray<int> textureIndexs = new NativeArray<int>(blockPositionsLength, Allocator.TempJob);

        NativeArray<byte> cubeFacesActiveState = new NativeArray<byte>(blockPositionsLength * 6, Allocator.TempJob);

        NativeArray<float3> faceVerticesOffsets = new NativeArray<float3>(24, Allocator.TempJob);

        #region faceVerticesOffsets Data Setup

        float3 halfCubeSize = 0.5f * cubeSize * Vector3.one;

        faceVerticesOffsets[0] = new float3(-halfCubeSize.x, -halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[1] = new float3(halfCubeSize.x, -halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[2] = new float3(halfCubeSize.x, halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[3] = new float3(-halfCubeSize.x, halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[4] = new float3(-halfCubeSize.x, -halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[5] = new float3(halfCubeSize.x, -halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[6] = new float3(halfCubeSize.x, halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[7] = new float3(-halfCubeSize.x, halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[8] = new float3(halfCubeSize.x, -halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[9] = new float3(halfCubeSize.x, -halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[10] = new float3(halfCubeSize.x, halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[11] = new float3(halfCubeSize.x, halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[12] = new float3(-halfCubeSize.x, -halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[13] = new float3(-halfCubeSize.x, -halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[14] = new float3(-halfCubeSize.x, halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[15] = new float3(-halfCubeSize.x, halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[16] = new float3(-halfCubeSize.x, halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[17] = new float3(halfCubeSize.x, halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[18] = new float3(halfCubeSize.x, halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[19] = new float3(-halfCubeSize.x, halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[20] = new float3(-halfCubeSize.x, -halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[21] = new float3(halfCubeSize.x, -halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[22] = new float3(halfCubeSize.x, -halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[23] = new float3(-halfCubeSize.x, -halfCubeSize.y, halfCubeSize.z);
        #endregion

        NativeArray<float3> gridNeighbourOffsets = new NativeArray<float3>(6, Allocator.TempJob);

        #region gridNeighbourOffsets Data Setup

        gridNeighbourOffsets[0] = new float3(0, 0, cubeSize);     // Z+
        gridNeighbourOffsets[1] = new float3(0, 0, -cubeSize);    // Z-
        gridNeighbourOffsets[2] = new float3(-cubeSize, 0, 0);    // X-
        gridNeighbourOffsets[3] = new float3(cubeSize, 0, 0);     // X+
        gridNeighbourOffsets[4] = new float3(0, cubeSize, 0);     // Y+
        gridNeighbourOffsets[5] = new float3(0, -cubeSize, 0);    // Y-
        #endregion

        NativeArray<float3> faceVertices = new NativeArray<float3>(24, Allocator.Persistent);

        for (int i = 0; i < 6; i++) // 6 faces
        {
            // Calculate the index offsets for each face's vertices
            int baseIndex = i * 4; // 4 vertices per face
            faceVertices[baseIndex + 0] = faceVerticesOffsets[baseIndex + 0];
            faceVertices[baseIndex + 1] = faceVerticesOffsets[baseIndex + 1];
            faceVertices[baseIndex + 2] = faceVerticesOffsets[baseIndex + 2];
            faceVertices[baseIndex + 3] = faceVerticesOffsets[baseIndex + 3];
        }





        /*GenerateMeshJob job = new GenerateMeshJob
        {
            blockPositions = blockPositions,

            // 24 vertices per cube
            vertices = vertices,
            sortedFaceVertices = sortedFaceVertices,

            // 36 triangles per cube
            triangles = triangles,
            sortedFaceTriangles = sortedFaceTriangles,

            textureIndexs = textureIndexs,

            cubeFacesActiveState = cubeFacesActiveState,

            faceVerticesOffsets = faceVerticesOffsets,

            gridNeighbourOffsets = gridNeighbourOffsets,

            faceVertices = faceVertices,

            cubeSize = cubeSize,

            atlasSize = atlasSize,
        };*/



        GenerateMeshJobParallel job = new GenerateMeshJobParallel
        {
            blockPositions = blockPositions,

            sortedFaceVertices = sortedFaceVertices,

            sortedFaceTriangles = sortedFaceTriangles,

            textureIndexs = textureIndexs,

            cubeFacesActiveState = cubeFacesActiveState,

            faceVerticesOffsets = faceVerticesOffsets,

            gridNeighbourOffsets = gridNeighbourOffsets,

            faceVertices = faceVertices,
        };

        // Schedule the job
        JobHandle jobHandle = job.Schedule(blockPositionsLength, 2048);
        jobHandle.Complete();



        NativeList<float3> filteredVertices = new NativeList<float3>(sortedFaceVertices.Length, Allocator.Temp);
        for (int i = 0; i < sortedFaceVertices.Length; i++)
        {
            if (sortedFaceVertices[i].x == 0.1f)
            {
                continue;
            }

            filteredVertices.Add(sortedFaceVertices[i]);
        }

        NativeList<int> filteredTriangles = new NativeList<int>(sortedFaceTriangles.Length, Allocator.Temp);
        for (int i = 0; i < sortedFaceTriangles.Length; i++)
        {
            if (sortedFaceTriangles[i] == -1)
            {
                continue;
            }

            filteredTriangles.Add(sortedFaceTriangles[i]);
        }


        MeshCalculator.Instance.ApplyMeshToObject(filteredVertices, filteredTriangles, cubeFacesActiveState, textureIndexs);


        //Dispose All Native Containers
        vertices.Dispose();
        sortedFaceVertices.Dispose();

        triangles.Dispose();
        sortedFaceTriangles.Dispose();

        textureIndexs.Dispose();

        cubeFacesActiveState.Dispose();

        faceVerticesOffsets.Dispose();

        gridNeighbourOffsets.Dispose();

        faceVertices.Dispose();

        filteredVertices.Dispose();
        filteredTriangles.Dispose();
    }
}



[BurstCompile]
public struct GenerateMeshJob : IJob
{
    [ReadOnly] public NativeList<float3> blockPositions;

    public NativeList<float3> vertices;
    public NativeList<float3> sortedFaceVertices;

    public NativeList<int> triangles;
    public NativeList<int> sortedFaceTriangles;

    [ReadOnly] public NativeArray<int> textureIndexs;

    public NativeArray<byte> cubeFacesActiveState;

    public NativeArray<float3> faceVerticesOffsets;
    public NativeArray<float3> gridNeighbourOffsets;

    public NativeArray<float3> faceVertices;


    [ReadOnly] public float cubeSize;

    [ReadOnly] public int atlasSize;



    [BurstCompile]
    public void Execute()
    {
        float3 halfCubeSize = 0.5f * cubeSize * Vector3.one;

        #region faceVerticesOffsets Data Setup

        faceVerticesOffsets[0] = new float3(-halfCubeSize.x, -halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[1] = new float3(halfCubeSize.x, -halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[2] = new float3(halfCubeSize.x, halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[3] = new float3(-halfCubeSize.x, halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[4] = new float3(-halfCubeSize.x, -halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[5] = new float3(halfCubeSize.x, -halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[6] = new float3(halfCubeSize.x, halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[7] = new float3(-halfCubeSize.x, halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[8] = new float3(halfCubeSize.x, -halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[9] = new float3(halfCubeSize.x, -halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[10] = new float3(halfCubeSize.x, halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[11] = new float3(halfCubeSize.x, halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[12] = new float3(-halfCubeSize.x, -halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[13] = new float3(-halfCubeSize.x, -halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[14] = new float3(-halfCubeSize.x, halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[15] = new float3(-halfCubeSize.x, halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[16] = new float3(-halfCubeSize.x, halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[17] = new float3(halfCubeSize.x, halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[18] = new float3(halfCubeSize.x, halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[19] = new float3(-halfCubeSize.x, halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[20] = new float3(-halfCubeSize.x, -halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[21] = new float3(halfCubeSize.x, -halfCubeSize.y, -halfCubeSize.z);
        faceVerticesOffsets[22] = new float3(halfCubeSize.x, -halfCubeSize.y, halfCubeSize.z);
        faceVerticesOffsets[23] = new float3(-halfCubeSize.x, -halfCubeSize.y, halfCubeSize.z);
        #endregion

        #region gridNeighbourOffsets Data Setup

        gridNeighbourOffsets[0] = new float3(0, 0, cubeSize);     // Z+
        gridNeighbourOffsets[1] = new float3(0, 0, -cubeSize);    // Z-
        gridNeighbourOffsets[2] = new float3(-cubeSize, 0, 0);    // X-
        gridNeighbourOffsets[3] = new float3(cubeSize, 0, 0);     // X+
        gridNeighbourOffsets[4] = new float3(0, cubeSize, 0);     // Y+
        gridNeighbourOffsets[5] = new float3(0, -cubeSize, 0);    // Y-
        #endregion



        int vertexOffset = 0;

        int frontFaceVisible, backFaceVisible, leftFaceVisible, rightFaceVisible, topFaceVisible, bottomFaceVisible;

        for (int cubeIndex = 0; cubeIndex < blockPositions.Length; cubeIndex++)
        {
            float3 gridPosition = blockPositions[cubeIndex];
            

            // Define the 6 faces with separate vertices for flat shading
            for (int i = 0; i < 6; i++) // 6 faces
            {
                // Calculate the index offsets for each face's vertices
                int baseIndex = i * 4; // 4 vertices per face
                faceVertices[baseIndex + 0] = gridPosition + faceVerticesOffsets[baseIndex + 0];
                faceVertices[baseIndex + 1] = gridPosition + faceVerticesOffsets[baseIndex + 1];
                faceVertices[baseIndex + 2] = gridPosition + faceVerticesOffsets[baseIndex + 2];
                faceVertices[baseIndex + 3] = gridPosition + faceVerticesOffsets[baseIndex + 3];
            }



            float3 neighborPositionZPlus = gridPosition + gridNeighbourOffsets[0];
            float3 neighborPositionZMinus = gridPosition + gridNeighbourOffsets[1];
            float3 neighborPositionXMinus = gridPosition + gridNeighbourOffsets[2];
            float3 neighborPositionXPlus = gridPosition + gridNeighbourOffsets[3];
            float3 neighborPositionYPlus = gridPosition + gridNeighbourOffsets[4];
            float3 neighborPositionYMinus = gridPosition + gridNeighbourOffsets[5];

            // Check face visibility
            frontFaceVisible = !blockPositions.Contains(neighborPositionZPlus) ? 1 : 0;
            backFaceVisible = !blockPositions.Contains(neighborPositionZMinus) ? 1 : 0;
            leftFaceVisible = !blockPositions.Contains(neighborPositionXMinus) ? 1 : 0;
            rightFaceVisible = !blockPositions.Contains(neighborPositionXPlus) ? 1 : 0;
            topFaceVisible = !blockPositions.Contains(neighborPositionYPlus) ? 1 : 0;
            bottomFaceVisible = !blockPositions.Contains(neighborPositionYMinus) ? 1 : 0;


            sortedFaceVertices.Clear();
            sortedFaceTriangles.Clear();

            int faceMissedVertOffset = 0;



            #region Add face vertices and triangles if the face is visible

            if (backFaceVisible == 1)
            {
                cubeFacesActiveState[cubeIndex * 6 + 0] = 1;

                sortedFaceVertices.Add(faceVertices[0]);
                sortedFaceVertices.Add(faceVertices[1]);
                sortedFaceVertices.Add(faceVertices[2]);
                sortedFaceVertices.Add(faceVertices[3]);

                sortedFaceTriangles.Add(vertexOffset + 2 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 1 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 0 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 3 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 2 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 0 - faceMissedVertOffset);
            }
            else
            {
                faceMissedVertOffset += 4;
            }

            if (frontFaceVisible == 1)
            {
                cubeFacesActiveState[cubeIndex * 6 + 1] = 1;

                sortedFaceVertices.Add(faceVertices[4]);
                sortedFaceVertices.Add(faceVertices[5]);
                sortedFaceVertices.Add(faceVertices[6]);
                sortedFaceVertices.Add(faceVertices[7]);

                sortedFaceTriangles.Add(vertexOffset + 5 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 6 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 4 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 6 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 7 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 4 - faceMissedVertOffset);
            }
            else
            {
                faceMissedVertOffset += 4;
            }

            if (rightFaceVisible == 1)
            {
                cubeFacesActiveState[cubeIndex * 6 + 2] = 1;

                sortedFaceVertices.Add(faceVertices[8]);
                sortedFaceVertices.Add(faceVertices[9]);
                sortedFaceVertices.Add(faceVertices[10]);
                sortedFaceVertices.Add(faceVertices[11]);

                sortedFaceTriangles.Add(vertexOffset + 10 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 9 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 8 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 11 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 10 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 8 - faceMissedVertOffset);
            }
            else
            {
                faceMissedVertOffset += 4;
            }

            if (leftFaceVisible == 1)
            {
                cubeFacesActiveState[cubeIndex * 6 + 3] = 1;

                sortedFaceVertices.Add(faceVertices[12]);
                sortedFaceVertices.Add(faceVertices[13]);
                sortedFaceVertices.Add(faceVertices[14]);
                sortedFaceVertices.Add(faceVertices[15]);

                sortedFaceTriangles.Add(vertexOffset + 13 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 14 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 12 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 14 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 15 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 12 - faceMissedVertOffset);
            }
            else
            {
                faceMissedVertOffset += 4;
            }

            if (topFaceVisible == 1)
            {
                cubeFacesActiveState[cubeIndex * 6 + 4] = 1;

                sortedFaceVertices.Add(faceVertices[16]);
                sortedFaceVertices.Add(faceVertices[17]);
                sortedFaceVertices.Add(faceVertices[18]);
                sortedFaceVertices.Add(faceVertices[19]);

                // Adding face triangles one by one
                sortedFaceTriangles.Add(vertexOffset + 16 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 18 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 17 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 16 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 19 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 18 - faceMissedVertOffset);
            }
            else
            {
                faceMissedVertOffset += 4;
            }

            if (bottomFaceVisible == 1)
            {
                cubeFacesActiveState[cubeIndex * 6 + 5] = 1;

                sortedFaceVertices.Add(faceVertices[20]);
                sortedFaceVertices.Add(faceVertices[21]);
                sortedFaceVertices.Add(faceVertices[22]);
                sortedFaceVertices.Add(faceVertices[23]);

                sortedFaceTriangles.Add(vertexOffset + 20 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 21 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 22 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 20 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 22 - faceMissedVertOffset);
                sortedFaceTriangles.Add(vertexOffset + 23 - faceMissedVertOffset);
            }
            else
            {
                faceMissedVertOffset += 4;
            }
            #endregion


            vertices.AddRange(sortedFaceVertices.AsArray());
            triangles.AddRange(sortedFaceTriangles.AsArray());

            vertexOffset += 24 - faceMissedVertOffset;
        }
    }
}



[BurstCompile]
public struct GenerateMeshJobParallel : IJobParallelFor
{
    [ReadOnly] public NativeList<float3> blockPositions;

    [NativeDisableParallelForRestriction]
    [WriteOnly] public NativeArray<float3> sortedFaceVertices;

    [NativeDisableParallelForRestriction]
    [WriteOnly] public NativeArray<int> sortedFaceTriangles;

    [ReadOnly] public NativeArray<int> textureIndexs;

    [NativeDisableParallelForRestriction]
    [WriteOnly] public NativeArray<byte> cubeFacesActiveState;

    [ReadOnly] public NativeArray<float3> faceVerticesOffsets;
    [ReadOnly] public NativeArray<float3> gridNeighbourOffsets;

    [ReadOnly] public NativeArray<float3> faceVertices;



    [BurstCompile]
    public void Execute(int cubeIndex)
    {
        int frontFaceVisible, backFaceVisible, leftFaceVisible, rightFaceVisible, topFaceVisible, bottomFaceVisible;

        float3 cubePosition = blockPositions[cubeIndex];


        float3 neighborPositionZPlus = cubePosition + gridNeighbourOffsets[0];
        float3 neighborPositionZMinus = cubePosition + gridNeighbourOffsets[1];
        float3 neighborPositionXMinus = cubePosition + gridNeighbourOffsets[2];
        float3 neighborPositionXPlus = cubePosition + gridNeighbourOffsets[3];
        float3 neighborPositionYPlus = cubePosition + gridNeighbourOffsets[4];
        float3 neighborPositionYMinus = cubePosition + gridNeighbourOffsets[5];

        // Check face visibility
        frontFaceVisible = !blockPositions.Contains(neighborPositionZPlus) ? 1 : 0;
        backFaceVisible = !blockPositions.Contains(neighborPositionZMinus) ? 1 : 0;
        leftFaceVisible = !blockPositions.Contains(neighborPositionXMinus) ? 1 : 0;
        rightFaceVisible = !blockPositions.Contains(neighborPositionXPlus) ? 1 : 0;
        topFaceVisible = !blockPositions.Contains(neighborPositionYPlus) ? 1 : 0;
        bottomFaceVisible = !blockPositions.Contains(neighborPositionYMinus) ? 1 : 0;




        #region Add face vertices and triangles if the face is visible

        if (backFaceVisible == 1)
        {
            cubeFacesActiveState[cubeIndex * 6 + 0] = 1;

            sortedFaceVertices[cubeIndex * 24 + 0] = faceVertices[0] + cubePosition;
            sortedFaceVertices[cubeIndex * 24 + 1] = faceVertices[1] + cubePosition;
            sortedFaceVertices[cubeIndex * 24 + 2] = faceVertices[2] + cubePosition;
            sortedFaceVertices[cubeIndex * 24 + 3] = faceVertices[3] + cubePosition;

            sortedFaceTriangles[cubeIndex * 36 + 0] = 2;
            sortedFaceTriangles[cubeIndex * 36 + 1] = 1;
            sortedFaceTriangles[cubeIndex * 36 + 2] = 0; 
            sortedFaceTriangles[cubeIndex * 36 + 3] = 3;
            sortedFaceTriangles[cubeIndex * 36 + 4] = 2;
            sortedFaceTriangles[cubeIndex * 36 + 5] = 0;
        }

        if (frontFaceVisible == 1)
        {
            cubeFacesActiveState[cubeIndex * 6 + 1] = 1;

            sortedFaceVertices[cubeIndex * 24 + 4] = faceVertices[4] + cubePosition;
            sortedFaceVertices[cubeIndex * 24 + 5] = faceVertices[5] + cubePosition;
            sortedFaceVertices[cubeIndex * 24 + 6] = faceVertices[6] + cubePosition;
            sortedFaceVertices[cubeIndex * 24 + 7] = faceVertices[7] + cubePosition;

            sortedFaceTriangles[cubeIndex * 36 + 6] = 5;
            sortedFaceTriangles[cubeIndex * 36 + 7] = 6;
            sortedFaceTriangles[cubeIndex * 36 + 8] = 4;
            sortedFaceTriangles[cubeIndex * 36 + 9] = 6;
            sortedFaceTriangles[cubeIndex * 36 + 10] = 7;
            sortedFaceTriangles[cubeIndex * 36 + 11] = 4;
        }

        if (rightFaceVisible == 1)
        {
            cubeFacesActiveState[cubeIndex * 6 + 2] = 1;

            sortedFaceVertices[cubeIndex * 24 + 8] = faceVertices[8] + cubePosition;
            sortedFaceVertices[cubeIndex * 24 + 9] = faceVertices[9] + cubePosition;
            sortedFaceVertices[cubeIndex * 24 + 10] = faceVertices[10] + cubePosition;
            sortedFaceVertices[cubeIndex * 24 + 11] = faceVertices[11] + cubePosition;

            sortedFaceTriangles[cubeIndex * 36 + 12] = 10;
            sortedFaceTriangles[cubeIndex * 36 + 13] = 9;
            sortedFaceTriangles[cubeIndex * 36 + 14] = 8;
            sortedFaceTriangles[cubeIndex * 36 + 15] = 11;
            sortedFaceTriangles[cubeIndex * 36 + 16] = 10;
            sortedFaceTriangles[cubeIndex * 36 + 17] = 8;
        }

        if (leftFaceVisible == 1)
        {
            cubeFacesActiveState[cubeIndex * 6 + 3] = 1;

            sortedFaceVertices[cubeIndex * 24 + 12] = faceVertices[12] + cubePosition;
            sortedFaceVertices[cubeIndex * 24 + 13] = faceVertices[13] + cubePosition;
            sortedFaceVertices[cubeIndex * 24 + 14] = faceVertices[14] + cubePosition;
            sortedFaceVertices[cubeIndex * 24 + 15] = faceVertices[15] + cubePosition;

            sortedFaceTriangles[cubeIndex * 36 + 18] = 13;
            sortedFaceTriangles[cubeIndex * 36 + 19] = 14;
            sortedFaceTriangles[cubeIndex * 36 + 20] = 12;
            sortedFaceTriangles[cubeIndex * 36 + 21] = 14;
            sortedFaceTriangles[cubeIndex * 36 + 22] = 15;
            sortedFaceTriangles[cubeIndex * 36 + 23] = 12;
        }

        if (topFaceVisible == 1)
        {
            cubeFacesActiveState[cubeIndex * 6 + 4] = 1;

            sortedFaceVertices[cubeIndex * 24 + 16] = faceVertices[16] + cubePosition;
            sortedFaceVertices[cubeIndex * 24 + 17] = faceVertices[17] + cubePosition;
            sortedFaceVertices[cubeIndex * 24 + 18] = faceVertices[18] + cubePosition;
            sortedFaceVertices[cubeIndex * 24 + 19] = faceVertices[19] + cubePosition;

            sortedFaceTriangles[cubeIndex * 36 + 24] = 16;
            sortedFaceTriangles[cubeIndex * 36 + 25] = 18;
            sortedFaceTriangles[cubeIndex * 36 + 26] = 17;
            sortedFaceTriangles[cubeIndex * 36 + 27] = 16;
            sortedFaceTriangles[cubeIndex * 36 + 28] = 19;
            sortedFaceTriangles[cubeIndex * 36 + 29] = 18;
        }

        if (bottomFaceVisible == 1)
        {
            cubeFacesActiveState[cubeIndex * 6 + 5] = 1;

            sortedFaceVertices[cubeIndex * 24 + 20] = faceVertices[20] + cubePosition;
            sortedFaceVertices[cubeIndex * 24 + 21] = faceVertices[21] + cubePosition;
            sortedFaceVertices[cubeIndex * 24 + 22] = faceVertices[22] + cubePosition;
            sortedFaceVertices[cubeIndex * 24 + 23] = faceVertices[23] + cubePosition;

            sortedFaceTriangles[cubeIndex * 36 + 30] = 20;
            sortedFaceTriangles[cubeIndex * 36 + 31] = 21;
            sortedFaceTriangles[cubeIndex * 36 + 32] = 22;
            sortedFaceTriangles[cubeIndex * 36 + 33] = 20;
            sortedFaceTriangles[cubeIndex * 36 + 34] = 22;
            sortedFaceTriangles[cubeIndex * 36 + 35] = 23;
        }
        #endregion
    }
}

I see you asserting this:

By what means are you confident the above is the case?

I recommend stripping it down to the simplest form, a single triangle over three verts, and prove that it is correct before going into the jobbify thingy, and prove it is wrong coming out.

Otherwise, the most likely explanation is that your triangle faces are just wound the wrong way. Unity uses left-hand-rule of course. If “left hand rule” doesn’t mean anything to you, hurry to some docs on face normals / vertex windings.

1 Like

The Mesh is created from a list of positions which all represent a cube, then all cubes get combined with triangles and vertices being deleted from the Data Arrays if the are not visible from any direction (coverd by another cube)
The interesting thing is, is that the when making a simple simulation with 1 cube, it spawns as normal. But the moment more cubes are made at the same time (more Positions are fed to the function) every Cube BUT the first in the list is all messed up.
Im aware of how unity treats normals and that the way your triangles are created (clockwise or counterClockwise) decides which way the normal is, but the triangles just dont show up at all.

And regarding how confident I am, I wouldnt be surprised if there is a mistake in the code, the question is where, because its currently really hard to debug, because everything “seems” right

Disclaimer: I am way out of my depth on the jobs / parallelization API, I have not used it at all yet. But I have run plenty of things in parallel in other contexts. :slight_smile:

Given this:

… it smells like maybe some part of this is being parallelized despite your “Disable Parallel” decorators?? What if you feed these jobs in one at a time, waiting until each is complete? That would be a fast gross way to prove that it is some kind of data contention…

I also note that your decorators are not on all data blocks…

It would immensely help if you would format your code block properly
Use 3 backticks like this

```cs
your code goes here
in however many
lines you need
```

You can specify csharp instead of cs, it works the same. This is used so that syntax highlighter can tell how to colorize the code.

1 Like

What exactly do you mean?

Whatever this stuff is:

Like I said, I have only a little bit of time using this API, but you should know your code and why that’s in there, and what fields it is decorating.

Oh that field, it is required.
I needed a way to have nestedArrays in the job, but since thats not possible, i made an Array that gives every job Xpieces of it. (now every job has X elements of the array, kindof letting it act as an array in an array)
But because Jobs force you to only modify arrays in the job at an index equal to the jobsIndex, you can use that field to force it anyway.

This problem has been solved, thanks to everyone trying to help!

The problem occured because the vertices Array had a bunch of 0’s (default values) in it.
Altough no triangles referenced these vertices, later code caused some weird issues because of that, so removing the 0’s fixed it.