Would it be possible to get access to a thread safe version of the actual mesh data of a mesh collider (vertices and triangles)? I was glad to learn that in 1.2.0-pre.6 this PhysicCollider.ToMesh method was added, allowing me to have a convex mesh baker to use, but I have just realized something obvious I did not think about (from error “Internal_Create can only be called from the main thread.”) : UnityEngine.Mesh is a class and cannot be initialized from a thread.

So, while I can make use of this method in my old main thread code (instead of using DesignEngrLab.MIConvexHull), this is useless in my attempt to multithread my current code. As I never need more than the vertices and triangles arrays of the convex mesh, an exentension like PhysicCollider.GetVertices and PhysicCollider.GetTriangles returning NativeArrays (allocator could be as parameter of method) would help me a lot.

This requires the ConvexCollider.Create to also be thread safe, but I believe it is, as I did not get any error in the trace before the call to Internal_Create.

For my use case, I got what I wanted with an Assembly definition reference asset. I have done like this (got the code from the actual ToMesh method, but just took the data I needed instead of returning a mesh) :

public unsafe struct TempMesh
{
public uint VerticesCount;
public uint IndicesCount;
public void* Vertices;
public void* Indices;
}
internal static float3 ComputeHullCentroid(ref ConvexHull hull)
{
float3 centroid = float3.zero;
for (int i = 0; i < hull.NumVertices; i++)
{
centroid += hull.Vertices[i];
}
centroid /= hull.NumVertices;
return centroid;
}
public static TempMesh CreateTempMeshFromCollider(in Collider collider)
{
var tempMesh = new TempMesh();
unsafe
{
fixed(Collider* colliderPtr = &collider)
{
if (colliderPtr->Type != ColliderType.Convex)
{
return tempMesh;
}
GetConvexHullData(ref tempMesh, ref ((ConvexCollider*)colliderPtr)->ConvexHull);
}
}
return tempMesh;
}
private static void GetConvexHullData(ref TempMesh result, ref ConvexHull hull)
{
int totalNumVertices = 0;
for (int f = 0; f < hull.NumFaces; f++)
{
totalNumVertices += hull.Faces[f].NumVertices + 1;
}
Vector3[] vertices = new Vector3[totalNumVertices];
Vector3[] normals = new Vector3[totalNumVertices];
int[] triangles = new int[(totalNumVertices - hull.NumFaces) * 3];
// Calculate centroid to approximately render convex radius effect
Vector3 hullCentroid = ComputeHullCentroid(ref hull);
int startVertexIndex = 0;
int curTri = 0;
for (int f = 0; f < hull.NumFaces; f++)
{
Vector3 avgFace = Vector3.zero;
Vector3 faceNormal = hull.Planes[f].Normal;
for (int fv = 0; fv < hull.Faces[f].NumVertices; fv++)
{
int origVIndex = hull.FaceVertexIndices[hull.Faces[f].FirstIndex + fv];
Vector3 origV = hull.Vertices[origVIndex];
// find the direction from centroid to the vertex
Vector3 dir = origV - hullCentroid;
Vector3 dirNormalized = math.normalize(dir);
Vector3 vertexWithConvexRadius = origV + dirNormalized * hull.ConvexRadius;
vertices[startVertexIndex + fv] = vertexWithConvexRadius;
normals[startVertexIndex + fv] = faceNormal;
avgFace += vertexWithConvexRadius;
triangles[curTri * 3 + 0] = startVertexIndex + fv;
triangles[curTri * 3 + 1] = startVertexIndex + (fv + 1) % hull.Faces[f].NumVertices;
triangles[curTri * 3 + 2] = startVertexIndex + hull.Faces[f].NumVertices;
curTri++;
}
avgFace *= 1.0f / hull.Faces[f].NumVertices;
vertices[startVertexIndex + hull.Faces[f].NumVertices] = avgFace;
normals[startVertexIndex + hull.Faces[f].NumVertices] = faceNormal;
startVertexIndex += hull.Faces[f].NumVertices + 1;
}
result.Vertices = new NativeArray<Vector3>(vertices, Allocator.Temp).GetUnsafePtr();
result.VerticesCount = (uint)totalNumVertices;
result.Indices = new NativeArray<int>(triangles, Allocator.Temp).GetUnsafePtr();
result.IndicesCount = (uint)triangles.Length;
}