Skip to content

Instantly share code, notes, and snippets.

@LukasFratzl
Last active November 14, 2022 17:20
Show Gist options
  • Select an option

  • Save LukasFratzl/b479a74087e17d729e8319edd4808757 to your computer and use it in GitHub Desktop.

Select an option

Save LukasFratzl/b479a74087e17d729e8319edd4808757 to your computer and use it in GitHub Desktop.
Apply a Unity Mesh with the Jobs System 2022
/*
LICENCE -> MIT License
AUTHOR -> Lukas Fratzl
GIT -> https://github.com/LukasFratzl
DESCRIPTION -> My implementation of "Marching Cubes" in Unity with Burst and Multithreaded with c# Jobs
the algorithm is smart enough to generate every "Grid Size" with every wanted "Resolution"
as extra with a "Smooth" or "Flat" normal generation
USAGE -> Assign all field and allocate the Native Containers, Schedule the Job and Complete it
When you don't know how the mesh is created just watch this Gist -> https://gist.github.com/LukasFratzl/988f1c9736b43684deb319880ac6c6fc
-> SEE EXAMPLE JOB DOWN BELOW!
EXAMPLE JOB -> // SCHEDULE THE APPLY JOB, WITH DEPENDENCIES
MeshApplyJob _apply = new MeshApplyJob();
_apply._indices = job._indices; // HERE WE STRAIGHT USE THE DATA OF THE MESH GENERATOR
_apply._vertexData = job._vertexData; // SAME HERE
_apply._meshDataArray = Mesh.AllocateWritableMeshData(1); // MESH ALLOCATOR
JobHandle _applyHandle = _apply.Schedule(_handle);
// COMPLETE IT
_applyHandle.Complete();
// DISPOSE AND ASSIGN MESH
Mesh mesh = _applyJob.ApplyMeshAndDispose(); // IT WILL DISPOSE THE DATA
*/
using System;
using Unity.Collections;
using Unity.Jobs;
using Unity.Mathematics;
using UnityEngine;
using UnityEngine.Rendering;
namespace flow____.Terrain
{
public struct MeshApplyJob : IJob
{
public struct VertexData
{
public float3 Position;
public float3 Normal;
public Color Color;
public float4 UV1;
}
public NativeList<VertexData> _vertexData;
public NativeList<ushort> _indices;
public Mesh.MeshDataArray _meshDataArray;
public void Execute()
{
if (_vertexData.Length >= UInt16.MaxValue) Debug.Log("Please use IndexFormat.<color=green>UInt32</color> instead of IndexFormat.<color=red>UInt16</color> on the mesh!");
if (_indices.Length > 0)
{
Mesh.MeshData _meshData = _meshDataArray[0];
_meshData.SetIndexBufferParams(_indices.Length, IndexFormat.UInt16);
_meshData.SetVertexBufferParams(_vertexData.Length, vertexAttributeDescriptor);
_meshData.GetIndexData<ushort>().CopyFrom(_indices.AsArray());
_meshData.GetVertexData<VertexData>().CopyFrom(_vertexData.AsArray());
_meshData.subMeshCount = 1;
_meshData.SetSubMesh(0, new SubMeshDescriptor(0, _indices.Length));
_meshData.subMeshCount = 1;
}
}
public Mesh ApplyMeshAndDispose()
{
if (_indices.Length == 0)
{
_indices.Dispose();
_vertexData.Dispose();
Debug.Log(1);
return null;
}
Mesh mesh = new Mesh();
mesh.indexFormat = IndexFormat.UInt16;
mesh.name = "Tetrahedron";
Mesh.ApplyAndDisposeWritableMeshData(_meshDataArray, mesh, MeshUpdateFlags.DontValidateIndices | MeshUpdateFlags.DontNotifyMeshUsers);
mesh.RecalculateBounds();
_indices.Dispose();
_vertexData.Dispose();
return mesh;
}
static readonly VertexAttributeDescriptor[] vertexAttributeDescriptor =
{
new VertexAttributeDescriptor(VertexAttribute.Position, VertexAttributeFormat.Float32, dimension: 3, stream: 0),
new VertexAttributeDescriptor(VertexAttribute.Normal, VertexAttributeFormat.Float32, dimension: 3, stream: 0),
new VertexAttributeDescriptor(VertexAttribute.Color, VertexAttributeFormat.Float32, dimension: 4, stream: 0),
new VertexAttributeDescriptor(VertexAttribute.TexCoord0, VertexAttributeFormat.Float32, dimension: 4, stream: 0)
};
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment