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
}
}