2.3. Unity Mesh API¶
This is about how meshes are updated from C++ Eigen matrices to Unity, so that they can be rendered.
Since Unity 2019.3 there have been some updates to the mesh API. However, there are still various limitations and currently the older API (SetVertices
) is being used with NativeArray as it is much simpler and thus more reliable. The flowchart below shows the different copies of the mesh data (e.g. vertex position matrix V).
Indeed there are 4 copies of the mesh currently. Potentially, the ‘CPU Unity internal’ copy does not exist, but this is unclear. Libigl currently only reliably supports column-major, but Unity requires row-major data. A necessary transpose is required. In this case it is most efficient to have two copies.
Note that updates to the mesh only occur when a DirtyFlag
is set in the MeshState.DirtyState
. DirtyFlag
are propagated and cleared when processed. The native ApplyDirty()
is called by the managed ApplyDirty
in UMeshData
.
It is also important to note that the transposing in ApplyDirty()
is done on the worker thread. mesh.SetVertices()
must be called on the main thread (as it is a Unity API). It is called by the managed ApplyDirtyToMesh
function in UMeshData
.
Some useful points when working with Unity meshes:
Call
mesh.MarkDynamic()
on a readable mesh to keep a copy of the buffers on the managed CPU memory and makemesh.vertices
read/writable. This is required in order to be able to modify the vertices at runtime. The mesh must be marked as writable in the import settings in the Inspector.Call
mesh.SetVertexBufferParams()
to specify the layout on the GPU, attributes in the same stream are interleaved. Here you can specify the precision as well. SeeVertexBufferLayout
inNative.cs
.mesh.UploadData(false)
to copy themesh.vertices
‘CPU Unity internal’ managed data to the GPU immediately (else done pre-render), usingtrue
will delete the CPU copy and the mesh will no longer by dynamic/writable.mesh.GetNativeVertexBufferPtr()
gets the GPU (DirectX/OpenGL) pointerPotentially with this we can apply changes to the GPU copy directly, potentially gaining performance. This has been experimented with in the
source/CustomUploadMesh.cpp