|
@@ -4190,39 +4190,36 @@ static void BuildPoseFromParentJoints(BoneInfo *bones, int boneCount, Transform
|
|
static Model LoadOBJ(const char *fileName)
|
|
static Model LoadOBJ(const char *fileName)
|
|
{
|
|
{
|
|
tinyobj_attrib_t objAttributes = { 0 };
|
|
tinyobj_attrib_t objAttributes = { 0 };
|
|
- tinyobj_shape_t* objShapes = NULL;
|
|
|
|
|
|
+ tinyobj_shape_t *objShapes = NULL;
|
|
unsigned int objShapeCount = 0;
|
|
unsigned int objShapeCount = 0;
|
|
|
|
|
|
- tinyobj_material_t* objMaterials = NULL;
|
|
|
|
|
|
+ tinyobj_material_t *objMaterials = NULL;
|
|
unsigned int objMaterialCount = 0;
|
|
unsigned int objMaterialCount = 0;
|
|
|
|
|
|
Model model = { 0 };
|
|
Model model = { 0 };
|
|
model.transform = MatrixIdentity();
|
|
model.transform = MatrixIdentity();
|
|
|
|
|
|
- char* fileText = LoadFileText(fileName);
|
|
|
|
|
|
+ char *fileText = LoadFileText(fileName);
|
|
|
|
|
|
if (fileText == NULL)
|
|
if (fileText == NULL)
|
|
{
|
|
{
|
|
- TRACELOG(LOG_ERROR, "MODEL Unable to read obj file %s", fileName);
|
|
|
|
|
|
+ TRACELOG(LOG_ERROR, "MODEL: [%s] Unable to read obj file", fileName);
|
|
return model;
|
|
return model;
|
|
}
|
|
}
|
|
|
|
|
|
char currentDir[1024] = { 0 };
|
|
char currentDir[1024] = { 0 };
|
|
strcpy(currentDir, GetWorkingDirectory()); // Save current working directory
|
|
strcpy(currentDir, GetWorkingDirectory()); // Save current working directory
|
|
- const char* workingDir = GetDirectoryPath(fileName); // Switch to OBJ directory for material path correctness
|
|
|
|
- if (CHDIR(workingDir) != 0)
|
|
|
|
- {
|
|
|
|
- TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to change working directory", workingDir);
|
|
|
|
- }
|
|
|
|
|
|
+ const char *workingDir = GetDirectoryPath(fileName); // Switch to OBJ directory for material path correctness
|
|
|
|
+ if (CHDIR(workingDir) != 0) TRACELOG(LOG_WARNING, "MODEL: [%s] Failed to change working directory", workingDir);
|
|
|
|
|
|
unsigned int dataSize = (unsigned int)strlen(fileText);
|
|
unsigned int dataSize = (unsigned int)strlen(fileText);
|
|
-
|
|
|
|
|
|
+
|
|
unsigned int flags = TINYOBJ_FLAG_TRIANGULATE;
|
|
unsigned int flags = TINYOBJ_FLAG_TRIANGULATE;
|
|
int ret = tinyobj_parse_obj(&objAttributes, &objShapes, &objShapeCount, &objMaterials, &objMaterialCount, fileText, dataSize, flags);
|
|
int ret = tinyobj_parse_obj(&objAttributes, &objShapes, &objShapeCount, &objMaterials, &objMaterialCount, fileText, dataSize, flags);
|
|
|
|
|
|
if (ret != TINYOBJ_SUCCESS)
|
|
if (ret != TINYOBJ_SUCCESS)
|
|
{
|
|
{
|
|
- TRACELOG(LOG_ERROR, "MODEL Unable to read obj data %s", fileName);
|
|
|
|
|
|
+ TRACELOG(LOG_ERROR, "MODEL: Unable to read obj data %s", fileName);
|
|
return model;
|
|
return model;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -4233,52 +4230,51 @@ static Model LoadOBJ(const char *fileName)
|
|
int lastMaterial = -1;
|
|
int lastMaterial = -1;
|
|
unsigned int meshIndex = 0;
|
|
unsigned int meshIndex = 0;
|
|
|
|
|
|
- // count meshes
|
|
|
|
|
|
+ // Count meshes
|
|
unsigned int nextShapeEnd = objAttributes.num_face_num_verts;
|
|
unsigned int nextShapeEnd = objAttributes.num_face_num_verts;
|
|
|
|
|
|
- // see how many verts till the next shape
|
|
|
|
-
|
|
|
|
|
|
+ // See how many verts till the next shape
|
|
if (objShapeCount > 1) nextShapeEnd = objShapes[nextShape].face_offset;
|
|
if (objShapeCount > 1) nextShapeEnd = objShapes[nextShape].face_offset;
|
|
|
|
|
|
- // walk all the faces
|
|
|
|
|
|
+ // Walk all the faces
|
|
for (unsigned int faceId = 0; faceId < objAttributes.num_faces; faceId++)
|
|
for (unsigned int faceId = 0; faceId < objAttributes.num_faces; faceId++)
|
|
{
|
|
{
|
|
if (faceId >= nextShapeEnd)
|
|
if (faceId >= nextShapeEnd)
|
|
{
|
|
{
|
|
- // try to find the last vert in the next shape
|
|
|
|
|
|
+ // Try to find the last vert in the next shape
|
|
nextShape++;
|
|
nextShape++;
|
|
if (nextShape < objShapeCount) nextShapeEnd = objShapes[nextShape].face_offset;
|
|
if (nextShape < objShapeCount) nextShapeEnd = objShapes[nextShape].face_offset;
|
|
- else nextShapeEnd = objAttributes.num_face_num_verts; // this is actually the total number of face verts in the file, not faces
|
|
|
|
|
|
+ else nextShapeEnd = objAttributes.num_face_num_verts; // This is actually the total number of face verts in the file, not faces
|
|
meshIndex++;
|
|
meshIndex++;
|
|
}
|
|
}
|
|
- else if (lastMaterial != -1 && objAttributes.material_ids[faceId] != lastMaterial)
|
|
|
|
|
|
+ else if ((lastMaterial != -1) && (objAttributes.material_ids[faceId] != lastMaterial))
|
|
{
|
|
{
|
|
- meshIndex++;// if this is a new material, we need to allocate a new mesh
|
|
|
|
|
|
+ meshIndex++; // If this is a new material, we need to allocate a new mesh
|
|
}
|
|
}
|
|
|
|
|
|
lastMaterial = objAttributes.material_ids[faceId];
|
|
lastMaterial = objAttributes.material_ids[faceId];
|
|
faceVertIndex += objAttributes.face_num_verts[faceId];
|
|
faceVertIndex += objAttributes.face_num_verts[faceId];
|
|
}
|
|
}
|
|
|
|
|
|
- // allocate the base meshes and materials
|
|
|
|
|
|
+ // Allocate the base meshes and materials
|
|
model.meshCount = meshIndex + 1;
|
|
model.meshCount = meshIndex + 1;
|
|
- model.meshes = (Mesh*)MemAlloc(sizeof(Mesh) * model.meshCount);
|
|
|
|
|
|
+ model.meshes = (Mesh *)MemAlloc(sizeof(Mesh)*model.meshCount);
|
|
|
|
|
|
if (objMaterialCount > 0)
|
|
if (objMaterialCount > 0)
|
|
{
|
|
{
|
|
model.materialCount = objMaterialCount;
|
|
model.materialCount = objMaterialCount;
|
|
- model.materials = (Material*)MemAlloc(sizeof(Material) * objMaterialCount);
|
|
|
|
|
|
+ model.materials = (Material *)MemAlloc(sizeof(Material)*objMaterialCount);
|
|
}
|
|
}
|
|
- else // we must allocate at least one material
|
|
|
|
|
|
+ else // We must allocate at least one material
|
|
{
|
|
{
|
|
model.materialCount = 1;
|
|
model.materialCount = 1;
|
|
- model.materials = (Material*)MemAlloc(sizeof(Material) * 1);
|
|
|
|
|
|
+ model.materials = (Material *)MemAlloc(sizeof(Material)*1);
|
|
}
|
|
}
|
|
|
|
|
|
- model.meshMaterial = (int*)MemAlloc(sizeof(int) * model.meshCount);
|
|
|
|
|
|
+ model.meshMaterial = (int *)MemAlloc(sizeof(int)*model.meshCount);
|
|
|
|
|
|
- // see how many verts are in each mesh
|
|
|
|
- unsigned int* localMeshVertexCounts = (unsigned int*)MemAlloc(sizeof(unsigned int) * model.meshCount);
|
|
|
|
|
|
+ // See how many verts are in each mesh
|
|
|
|
+ unsigned int *localMeshVertexCounts = (unsigned int *)MemAlloc(sizeof(unsigned int)*model.meshCount);
|
|
|
|
|
|
faceVertIndex = 0;
|
|
faceVertIndex = 0;
|
|
nextShapeEnd = objAttributes.num_face_num_verts;
|
|
nextShapeEnd = objAttributes.num_face_num_verts;
|
|
@@ -4287,23 +4283,22 @@ static Model LoadOBJ(const char *fileName)
|
|
unsigned int localMeshVertexCount = 0;
|
|
unsigned int localMeshVertexCount = 0;
|
|
|
|
|
|
nextShape = 1;
|
|
nextShape = 1;
|
|
- if (objShapeCount > 1)
|
|
|
|
- nextShapeEnd = objShapes[nextShape].face_offset;
|
|
|
|
|
|
+ if (objShapeCount > 1) nextShapeEnd = objShapes[nextShape].face_offset;
|
|
|
|
|
|
- // walk all the faces
|
|
|
|
|
|
+ // Walk all the faces
|
|
for (unsigned int faceId = 0; faceId < objAttributes.num_faces; faceId++)
|
|
for (unsigned int faceId = 0; faceId < objAttributes.num_faces; faceId++)
|
|
{
|
|
{
|
|
- bool newMesh = false; // do we need a new mesh?
|
|
|
|
|
|
+ bool newMesh = false; // Do we need a new mesh?
|
|
if (faceId >= nextShapeEnd)
|
|
if (faceId >= nextShapeEnd)
|
|
{
|
|
{
|
|
- // try to find the last vert in the next shape
|
|
|
|
|
|
+ // Try to find the last vert in the next shape
|
|
nextShape++;
|
|
nextShape++;
|
|
if (nextShape < objShapeCount) nextShapeEnd = objShapes[nextShape].face_offset;
|
|
if (nextShape < objShapeCount) nextShapeEnd = objShapes[nextShape].face_offset;
|
|
else nextShapeEnd = objAttributes.num_face_num_verts; // this is actually the total number of face verts in the file, not faces
|
|
else nextShapeEnd = objAttributes.num_face_num_verts; // this is actually the total number of face verts in the file, not faces
|
|
|
|
|
|
newMesh = true;
|
|
newMesh = true;
|
|
}
|
|
}
|
|
- else if (lastMaterial != -1 && objAttributes.material_ids[faceId] != lastMaterial)
|
|
|
|
|
|
+ else if ((lastMaterial != -1) && (objAttributes.material_ids[faceId] != lastMaterial))
|
|
{
|
|
{
|
|
newMesh = true;
|
|
newMesh = true;
|
|
}
|
|
}
|
|
@@ -4321,50 +4316,52 @@ static Model LoadOBJ(const char *fileName)
|
|
faceVertIndex += objAttributes.face_num_verts[faceId];
|
|
faceVertIndex += objAttributes.face_num_verts[faceId];
|
|
localMeshVertexCount += objAttributes.face_num_verts[faceId];
|
|
localMeshVertexCount += objAttributes.face_num_verts[faceId];
|
|
}
|
|
}
|
|
|
|
+
|
|
localMeshVertexCounts[meshIndex] = localMeshVertexCount;
|
|
localMeshVertexCounts[meshIndex] = localMeshVertexCount;
|
|
|
|
|
|
for (int i = 0; i < model.meshCount; i++)
|
|
for (int i = 0; i < model.meshCount; i++)
|
|
{
|
|
{
|
|
- // allocate the buffers for each mesh
|
|
|
|
|
|
+ // Allocate the buffers for each mesh
|
|
unsigned int vertexCount = localMeshVertexCounts[i];
|
|
unsigned int vertexCount = localMeshVertexCounts[i];
|
|
|
|
|
|
model.meshes[i].vertexCount = vertexCount;
|
|
model.meshes[i].vertexCount = vertexCount;
|
|
model.meshes[i].triangleCount = vertexCount / 3;
|
|
model.meshes[i].triangleCount = vertexCount / 3;
|
|
|
|
|
|
- model.meshes[i].vertices = (float*)MemAlloc(sizeof(float) * vertexCount * 3);
|
|
|
|
- model.meshes[i].normals = (float*)MemAlloc(sizeof(float) * vertexCount * 3);
|
|
|
|
- model.meshes[i].texcoords = (float*)MemAlloc(sizeof(float) * vertexCount * 2);
|
|
|
|
- model.meshes[i].colors = (unsigned char*)MemAlloc(sizeof(unsigned char) * vertexCount * 4);
|
|
|
|
|
|
+ model.meshes[i].vertices = (float *)MemAlloc(sizeof(float)*vertexCount*3);
|
|
|
|
+ model.meshes[i].normals = (float *)MemAlloc(sizeof(float)*vertexCount*3);
|
|
|
|
+ model.meshes[i].texcoords = (float *)MemAlloc(sizeof(float)*vertexCount*2);
|
|
|
|
+ model.meshes[i].colors = (unsigned char *)MemAlloc(sizeof(unsigned char)*vertexCount*4);
|
|
}
|
|
}
|
|
|
|
|
|
MemFree(localMeshVertexCounts);
|
|
MemFree(localMeshVertexCounts);
|
|
localMeshVertexCounts = NULL;
|
|
localMeshVertexCounts = NULL;
|
|
|
|
|
|
- // fill meshes
|
|
|
|
|
|
+ // Fill meshes
|
|
faceVertIndex = 0;
|
|
faceVertIndex = 0;
|
|
|
|
|
|
nextShapeEnd = objAttributes.num_face_num_verts;
|
|
nextShapeEnd = objAttributes.num_face_num_verts;
|
|
|
|
|
|
- // see how many verts till the next shape
|
|
|
|
|
|
+ // See how many verts till the next shape
|
|
nextShape = 1;
|
|
nextShape = 1;
|
|
if (objShapeCount > 1) nextShapeEnd = objShapes[nextShape].face_offset;
|
|
if (objShapeCount > 1) nextShapeEnd = objShapes[nextShape].face_offset;
|
|
lastMaterial = -1;
|
|
lastMaterial = -1;
|
|
meshIndex = 0;
|
|
meshIndex = 0;
|
|
localMeshVertexCount = 0;
|
|
localMeshVertexCount = 0;
|
|
|
|
|
|
- // walk all the faces
|
|
|
|
|
|
+ // Walk all the faces
|
|
for (unsigned int faceId = 0; faceId < objAttributes.num_faces; faceId++)
|
|
for (unsigned int faceId = 0; faceId < objAttributes.num_faces; faceId++)
|
|
{
|
|
{
|
|
- bool newMesh = false; // do we need a new mesh?
|
|
|
|
|
|
+ bool newMesh = false; // Do we need a new mesh?
|
|
if (faceId >= nextShapeEnd)
|
|
if (faceId >= nextShapeEnd)
|
|
{
|
|
{
|
|
- // try to find the last vert in the next shape
|
|
|
|
|
|
+ // Try to find the last vert in the next shape
|
|
nextShape++;
|
|
nextShape++;
|
|
if (nextShape < objShapeCount) nextShapeEnd = objShapes[nextShape].face_offset;
|
|
if (nextShape < objShapeCount) nextShapeEnd = objShapes[nextShape].face_offset;
|
|
- else nextShapeEnd = objAttributes.num_face_num_verts; // this is actually the total number of face verts in the file, not faces
|
|
|
|
|
|
+ else nextShapeEnd = objAttributes.num_face_num_verts; // This is actually the total number of face verts in the file, not faces
|
|
newMesh = true;
|
|
newMesh = true;
|
|
}
|
|
}
|
|
- // if this is a new material, we need to allocate a new mesh
|
|
|
|
|
|
+
|
|
|
|
+ // If this is a new material, we need to allocate a new mesh
|
|
if (lastMaterial != -1 && objAttributes.material_ids[faceId] != lastMaterial) newMesh = true;
|
|
if (lastMaterial != -1 && objAttributes.material_ids[faceId] != lastMaterial) newMesh = true;
|
|
lastMaterial = objAttributes.material_ids[faceId];
|
|
lastMaterial = objAttributes.material_ids[faceId];
|
|
|
|
|
|
@@ -4375,8 +4372,7 @@ static Model LoadOBJ(const char *fileName)
|
|
}
|
|
}
|
|
|
|
|
|
int matId = 0;
|
|
int matId = 0;
|
|
- if (lastMaterial >= 0 && lastMaterial < (int)objMaterialCount)
|
|
|
|
- matId = lastMaterial;
|
|
|
|
|
|
+ if ((lastMaterial >= 0) && (lastMaterial < (int)objMaterialCount)) matId = lastMaterial;
|
|
|
|
|
|
model.meshMaterial[meshIndex] = matId;
|
|
model.meshMaterial[meshIndex] = matId;
|
|
|
|
|
|
@@ -4386,19 +4382,15 @@ static Model LoadOBJ(const char *fileName)
|
|
int normalIndex = objAttributes.faces[faceVertIndex].vn_idx;
|
|
int normalIndex = objAttributes.faces[faceVertIndex].vn_idx;
|
|
int texcordIndex = objAttributes.faces[faceVertIndex].vt_idx;
|
|
int texcordIndex = objAttributes.faces[faceVertIndex].vt_idx;
|
|
|
|
|
|
- for (int i = 0; i < 3; i++)
|
|
|
|
- model.meshes[meshIndex].vertices[localMeshVertexCount * 3 + i] = objAttributes.vertices[vertIndex * 3 + i];
|
|
|
|
|
|
+ for (int i = 0; i < 3; i++) model.meshes[meshIndex].vertices[localMeshVertexCount*3 + i] = objAttributes.vertices[vertIndex*3 + i];
|
|
|
|
|
|
- for (int i = 0; i < 3; i++)
|
|
|
|
- model.meshes[meshIndex].normals[localMeshVertexCount * 3 + i] = objAttributes.normals[normalIndex * 3 + i];
|
|
|
|
|
|
+ for (int i = 0; i < 3; i++) model.meshes[meshIndex].normals[localMeshVertexCount*3 + i] = objAttributes.normals[normalIndex*3 + i];
|
|
|
|
|
|
- for (int i = 0; i < 2; i++)
|
|
|
|
- model.meshes[meshIndex].texcoords[localMeshVertexCount * 2 + i] = objAttributes.texcoords[texcordIndex * 2 + i];
|
|
|
|
|
|
+ for (int i = 0; i < 2; i++) model.meshes[meshIndex].texcoords[localMeshVertexCount*2 + i] = objAttributes.texcoords[texcordIndex*2 + i];
|
|
|
|
|
|
- model.meshes[meshIndex].texcoords[localMeshVertexCount * 2 + 1] = 1.0f - model.meshes[meshIndex].texcoords[localMeshVertexCount * 2 + 1];
|
|
|
|
|
|
+ model.meshes[meshIndex].texcoords[localMeshVertexCount*2 + 1] = 1.0f - model.meshes[meshIndex].texcoords[localMeshVertexCount*2 + 1];
|
|
|
|
|
|
- for (int i = 0; i < 4; i++)
|
|
|
|
- model.meshes[meshIndex].colors[localMeshVertexCount * 4 + i] = 255;
|
|
|
|
|
|
+ for (int i = 0; i < 4; i++) model.meshes[meshIndex].colors[localMeshVertexCount*4 + i] = 255;
|
|
|
|
|
|
faceVertIndex++;
|
|
faceVertIndex++;
|
|
localMeshVertexCount++;
|
|
localMeshVertexCount++;
|
|
@@ -4412,8 +4404,7 @@ static Model LoadOBJ(const char *fileName)
|
|
tinyobj_shapes_free(objShapes, objShapeCount);
|
|
tinyobj_shapes_free(objShapes, objShapeCount);
|
|
tinyobj_materials_free(objMaterials, objMaterialCount);
|
|
tinyobj_materials_free(objMaterials, objMaterialCount);
|
|
|
|
|
|
- for (int i = 0; i < model.meshCount; i++)
|
|
|
|
- UploadMesh(model.meshes + i, true);
|
|
|
|
|
|
+ for (int i = 0; i < model.meshCount; i++) UploadMesh(model.meshes + i, true);
|
|
|
|
|
|
// Restore current working directory
|
|
// Restore current working directory
|
|
if (CHDIR(currentDir) != 0)
|
|
if (CHDIR(currentDir) != 0)
|