There are no images on the basic primitives used in ModelIO that I've found so far. If these primitives are meant to be used by apps as starter content, then they should follow consistent modeling and uv wrapping rules.
- The sphere has uv coordinates where the u direction wraps counterclockwise. The capsule has the same problem. This is the opposite of the cube which fits u clockwise on each face. Solution was to flip x with 1-uv.x.
- The sphere reports 306 vertices on latest Big Sur, but after vertex 289 the rest of the vertex data is garbage data.
- The uv seam on the sphere is rotated by -45 degrees from the capsule.
- I had to flip the bitangent sign too in my app. This seemed to be reversed, but could be from shader issues.
- On my MBP 16" I'm getting uv's that are non-zero, but all zero derivatives. I don't know yet if this is from 2.
Here's part of what I did to fix the mesh. This doesn't include the call to generate tangents and bitangent sign, and then flip the sign.
mdlMesh = [MDLMesh newEllipsoidWithRadii:(vector_float3){0.5, 0.5, 0.5} radialSegments:16 verticalSegments:16 geometryType:MDLGeometryTypeTriangles inwardNormals:NO hemisphere:NO allocator:_metalAllocator];
float angle = M_PI * 0.5;
float2 cosSin = float2m(cos(angle), sin(angle));
{
mdlMesh.vertexDescriptor = _mdlVertexDescriptor;
id<MDLMeshBuffer> pos = mdlMesh.vertexBuffers[BufferIndexMeshPosition];
MDLMeshBufferMap *posMap = [pos map];
packed_float3* posData = (packed_float3*)posMap.bytes;
id<MDLMeshBuffer> normals = mdlMesh.vertexBuffers[BufferIndexMeshNormal];
MDLMeshBufferMap *normalsMap = [normals map];
packed_float3* normalData = (packed_float3*)normalsMap.bytes;
// vertexCount reports 306, but vertex 289+ are garbage
uint32_t numVertices = 289; // mdlMesh.vertexCount
for (uint32_t i = 0; i < numVertices; ++i) {
{
auto& pos = posData[i];
// dumb rotate about Y-axis
auto copy = pos;
pos.x = copy.x * cosSin.x - copy.z * cosSin.y;
pos.z = copy.x * cosSin.y + copy.z * cosSin.x;
}
{
auto& normal = normalData[i];
auto copy = normal;
normal.x = copy.x * cosSin.x - copy.z * cosSin.y;
normal.z = copy.x * cosSin.y + copy.z * cosSin.x;
}
}
// Hack - knock out all bogus vertices on the sphere
for (uint32_t i = numVertices; i < mdlMesh.vertexCount; ++i) {
auto& pos = posData[i];
pos.x = NAN;
}
}