|
|
@ -624,19 +624,19 @@ Model LoadModel(const char *fileName) |
|
|
|
#if defined(SUPPORT_FILEFORMAT_IQM) |
|
|
|
if (IsFileExtension(fileName, ".iqm")) model = LoadIQM(fileName); |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
// Make sure model transform is set to identity matrix! |
|
|
|
model.transform = MatrixIdentity(); |
|
|
|
|
|
|
|
if (model.meshCount == 0) |
|
|
|
if (model.meshCount == 0) |
|
|
|
{ |
|
|
|
TraceLog(LOG_WARNING, "[%s] No meshes can be loaded, default to cube mesh", fileName); |
|
|
|
|
|
|
|
|
|
|
|
model.meshCount = 1; |
|
|
|
model.meshes = (Mesh *)calloc(model.meshCount, sizeof(Mesh)); |
|
|
|
model.meshes[0] = GenMeshCube(1.0f, 1.0f, 1.0f); |
|
|
|
} |
|
|
|
else |
|
|
|
else |
|
|
|
{ |
|
|
|
// Upload vertex data to GPU (static mesh) |
|
|
|
for (int i = 0; i < model.meshCount; i++) rlLoadMesh(&model.meshes[i], false); |
|
|
@ -645,11 +645,11 @@ Model LoadModel(const char *fileName) |
|
|
|
if (model.materialCount == 0) |
|
|
|
{ |
|
|
|
TraceLog(LOG_WARNING, "[%s] No materials can be loaded, default to white material", fileName); |
|
|
|
|
|
|
|
|
|
|
|
model.materialCount = 1; |
|
|
|
model.materials = (Material *)calloc(model.materialCount, sizeof(Material)); |
|
|
|
model.materials[0] = LoadMaterialDefault(); |
|
|
|
|
|
|
|
|
|
|
|
model.meshMaterial = (int *)calloc(model.meshCount, sizeof(int)); |
|
|
|
} |
|
|
|
|
|
|
@ -665,15 +665,15 @@ Model LoadModelFromMesh(Mesh mesh) |
|
|
|
Model model = { 0 }; |
|
|
|
|
|
|
|
model.transform = MatrixIdentity(); |
|
|
|
|
|
|
|
|
|
|
|
model.meshCount = 1; |
|
|
|
model.meshes = (Mesh *)malloc(model.meshCount*sizeof(Mesh)); |
|
|
|
model.meshes[0] = mesh; |
|
|
|
|
|
|
|
|
|
|
|
model.materialCount = 1; |
|
|
|
model.materials = (Material *)malloc(model.materialCount*sizeof(Material)); |
|
|
|
model.materials[0] = LoadMaterialDefault(); |
|
|
|
|
|
|
|
|
|
|
|
model.meshMaterial = (int *)malloc(model.meshCount*sizeof(int)); |
|
|
|
model.meshMaterial[0] = 0; // First material index |
|
|
|
|
|
|
@ -685,11 +685,11 @@ void UnloadModel(Model model) |
|
|
|
{ |
|
|
|
for (int i = 0; i < model.meshCount; i++) UnloadMesh(&model.meshes[i]); |
|
|
|
for (int i = 0; i < model.materialCount; i++) UnloadMaterial(model.materials[i]); |
|
|
|
|
|
|
|
|
|
|
|
free(model.meshes); |
|
|
|
free(model.materials); |
|
|
|
free(model.meshMaterial); |
|
|
|
|
|
|
|
|
|
|
|
// Unload animation data |
|
|
|
free(model.bones); |
|
|
|
free(model.bindPose); |
|
|
@ -1817,11 +1817,11 @@ Material LoadMaterial(const char *fileName) |
|
|
|
{ |
|
|
|
tinyobj_material_t *materials; |
|
|
|
unsigned int materialCount = 0; |
|
|
|
|
|
|
|
|
|
|
|
int result = tinyobj_parse_mtl_file(&materials, &materialCount, fileName); |
|
|
|
|
|
|
|
|
|
|
|
// TODO: Process materials to return |
|
|
|
|
|
|
|
|
|
|
|
tinyobj_materials_free(materials, materialCount); |
|
|
|
} |
|
|
|
#else |
|
|
@ -1886,7 +1886,7 @@ void DrawModelEx(Model model, Vector3 position, Vector3 rotationAxis, float rota |
|
|
|
// Combine model transformation matrix (model.transform) with matrix generated by function parameters (matTransform) |
|
|
|
model.transform = MatrixMultiply(model.transform, matTransform); |
|
|
|
|
|
|
|
for (int i = 0; i < model.meshCount; i++) |
|
|
|
for (int i = 0; i < model.meshCount; i++) |
|
|
|
{ |
|
|
|
model.materials[model.meshMaterial[i]].maps[MAP_DIFFUSE].color = tint; |
|
|
|
rlDrawMesh(model.meshes[i], model.materials[model.meshMaterial[i]], model.transform); |
|
|
@ -2246,7 +2246,7 @@ BoundingBox MeshBoundingBox(Mesh mesh) |
|
|
|
// Get min and max vertex to construct bounds (AABB) |
|
|
|
Vector3 minVertex = { 0 }; |
|
|
|
Vector3 maxVertex = { 0 }; |
|
|
|
|
|
|
|
|
|
|
|
printf("Mesh vertex count: %i\n", mesh.vertexCount); |
|
|
|
|
|
|
|
if (mesh.vertices != NULL) |
|
|
@ -2402,20 +2402,20 @@ static Model LoadOBJ(const char *fileName) |
|
|
|
{ |
|
|
|
unsigned int flags = TINYOBJ_FLAG_TRIANGULATE; |
|
|
|
int ret = tinyobj_parse_obj(&attrib, &meshes, &meshCount, &materials, &materialCount, data, dataLength, flags); |
|
|
|
|
|
|
|
|
|
|
|
if (ret != TINYOBJ_SUCCESS) TraceLog(LOG_WARNING, "[%s] Model data could not be loaded", fileName); |
|
|
|
else TraceLog(LOG_INFO, "[%s] Model data loaded successfully: %i meshes / %i materials", fileName, meshCount, materialCount); |
|
|
|
|
|
|
|
|
|
|
|
// Init model meshes array |
|
|
|
model.meshCount = meshCount; |
|
|
|
model.meshes = (Mesh *)malloc(model.meshCount*sizeof(Mesh)); |
|
|
|
|
|
|
|
|
|
|
|
// Init model materials array |
|
|
|
model.materialCount = materialCount; |
|
|
|
model.materials = (Material *)malloc(model.materialCount*sizeof(Material)); |
|
|
|
model.meshMaterial = (int *)calloc(model.meshCount, sizeof(int)); |
|
|
|
|
|
|
|
/* |
|
|
|
|
|
|
|
/* |
|
|
|
// Multiple meshes data reference |
|
|
|
// NOTE: They are provided as a faces offset |
|
|
|
typedef struct { |
|
|
@ -2424,7 +2424,7 @@ static Model LoadOBJ(const char *fileName) |
|
|
|
unsigned int length; |
|
|
|
} tinyobj_shape_t; |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
// Init model meshes |
|
|
|
for (int m = 0; m < 1; m++) |
|
|
|
{ |
|
|
@ -2435,25 +2435,25 @@ static Model LoadOBJ(const char *fileName) |
|
|
|
mesh.vertices = (float *)malloc(mesh.vertexCount*3*sizeof(float)); |
|
|
|
mesh.texcoords = (float *)malloc(mesh.vertexCount*2*sizeof(float)); |
|
|
|
mesh.normals = (float *)malloc(mesh.vertexCount*3*sizeof(float)); |
|
|
|
|
|
|
|
|
|
|
|
int vCount = 0; |
|
|
|
int vtCount = 0; |
|
|
|
int vnCount = 0; |
|
|
|
|
|
|
|
|
|
|
|
for (int f = 0; f < attrib.num_faces; f++) |
|
|
|
{ |
|
|
|
// Get indices for the face |
|
|
|
tinyobj_vertex_index_t idx0 = attrib.faces[3*f + 0]; |
|
|
|
tinyobj_vertex_index_t idx1 = attrib.faces[3*f + 1]; |
|
|
|
tinyobj_vertex_index_t idx2 = attrib.faces[3*f + 2]; |
|
|
|
|
|
|
|
|
|
|
|
// TraceLog(LOG_DEBUG, "Face %i index: v %i/%i/%i . vt %i/%i/%i . vn %i/%i/%i\n", f, idx0.v_idx, idx1.v_idx, idx2.v_idx, idx0.vt_idx, idx1.vt_idx, idx2.vt_idx, idx0.vn_idx, idx1.vn_idx, idx2.vn_idx); |
|
|
|
|
|
|
|
|
|
|
|
// Fill vertices buffer (float) using vertex index of the face |
|
|
|
for (int v = 0; v < 3; v++) { mesh.vertices[vCount + v] = attrib.vertices[idx0.v_idx*3 + v]; } vCount +=3; |
|
|
|
for (int v = 0; v < 3; v++) { mesh.vertices[vCount + v] = attrib.vertices[idx1.v_idx*3 + v]; } vCount +=3; |
|
|
|
for (int v = 0; v < 3; v++) { mesh.vertices[vCount + v] = attrib.vertices[idx2.v_idx*3 + v]; } vCount +=3; |
|
|
|
|
|
|
|
|
|
|
|
// Fill texcoords buffer (float) using vertex index of the face |
|
|
|
// NOTE: Y-coordinate must be flipped upside-down |
|
|
|
mesh.texcoords[vtCount + 0] = attrib.texcoords[idx0.vt_idx*2 + 0]; |
|
|
@ -2462,7 +2462,7 @@ static Model LoadOBJ(const char *fileName) |
|
|
|
mesh.texcoords[vtCount + 1] = 1.0f - attrib.texcoords[idx1.vt_idx*2 + 1]; vtCount += 2; |
|
|
|
mesh.texcoords[vtCount + 0] = attrib.texcoords[idx2.vt_idx*2 + 0]; |
|
|
|
mesh.texcoords[vtCount + 1] = 1.0f - attrib.texcoords[idx2.vt_idx*2 + 1]; vtCount += 2; |
|
|
|
|
|
|
|
|
|
|
|
// Fill normals buffer (float) using vertex index of the face |
|
|
|
for (int v = 0; v < 3; v++) { mesh.normals[vnCount + v] = attrib.normals[idx0.vn_idx*3 + v]; } vnCount +=3; |
|
|
|
for (int v = 0; v < 3; v++) { mesh.normals[vnCount + v] = attrib.normals[idx1.vn_idx*3 + v]; } vnCount +=3; |
|
|
@ -2481,7 +2481,7 @@ static Model LoadOBJ(const char *fileName) |
|
|
|
// Init material to default |
|
|
|
// NOTE: Uses default shader, only MAP_DIFFUSE supported |
|
|
|
model.materials[m] = LoadMaterialDefault(); |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
typedef struct { |
|
|
|
char *name; |
|
|
@ -2508,19 +2508,19 @@ static Model LoadOBJ(const char *fileName) |
|
|
|
char *alpha_texname; // map_d |
|
|
|
} tinyobj_material_t; |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
model.materials[m].maps[MAP_DIFFUSE].texture = LoadTexture(materials[m].diffuse_texname); //char *diffuse_texname; // map_Kd |
|
|
|
model.materials[m].maps[MAP_DIFFUSE].color = (Color){ (float)(materials[m].diffuse[0]*255.0f), (float)(materials[m].diffuse[1]*255.0f), (float)(materials[m].diffuse[2]*255.0f), 255 }; //float diffuse[3]; |
|
|
|
model.materials[m].maps[MAP_DIFFUSE].value = 0.0f; |
|
|
|
|
|
|
|
|
|
|
|
model.materials[m].maps[MAP_SPECULAR].texture = LoadTexture(materials[m].specular_texname); //char *specular_texname; // map_Ks |
|
|
|
model.materials[m].maps[MAP_SPECULAR].color = (Color){ (float)(materials[m].specular[0]*255.0f), (float)(materials[m].specular[1]*255.0f), (float)(materials[m].specular[2]*255.0f), 255 }; //float specular[3]; |
|
|
|
model.materials[m].maps[MAP_SPECULAR].value = 0.0f; |
|
|
|
|
|
|
|
|
|
|
|
model.materials[m].maps[MAP_NORMAL].texture = LoadTexture(materials[m].bump_texname); //char *bump_texname; // map_bump, bump |
|
|
|
model.materials[m].maps[MAP_NORMAL].color = WHITE; |
|
|
|
model.materials[m].maps[MAP_NORMAL].value = materials[m].shininess; |
|
|
|
|
|
|
|
|
|
|
|
model.materials[m].maps[MAP_EMISSION].color = (Color){ (float)(materials[m].emission[0]*255.0f), (float)(materials[m].emission[1]*255.0f), (float)(materials[m].emission[2]*255.0f), 255 }; //float emission[3]; |
|
|
|
|
|
|
|
model.materials[m].maps[MAP_HEIGHT].texture = LoadTexture(materials[m].displacement_texname); //char *displacement_texname; // disp |
|
|
@ -2579,7 +2579,7 @@ static Model LoadIQM(const char *fileName) |
|
|
|
} IQMTriangle; |
|
|
|
|
|
|
|
// NOTE: Adjacency unused by default |
|
|
|
typedef struct IQMAdjacency { |
|
|
|
typedef struct IQMAdjacency { |
|
|
|
unsigned int triangle[3]; |
|
|
|
} IQMAdjacency; |
|
|
|
|
|
|
@ -2677,7 +2677,7 @@ static Model LoadIQM(const char *fileName) |
|
|
|
|
|
|
|
model.meshCount = iqm.num_meshes; |
|
|
|
model.meshes = malloc(sizeof(Mesh)*iqm.num_meshes); |
|
|
|
|
|
|
|
|
|
|
|
char name[MESH_NAME_LENGTH]; |
|
|
|
|
|
|
|
for (int i = 0; i < iqm.num_meshes; i++) |
|
|
@ -2685,17 +2685,17 @@ static Model LoadIQM(const char *fileName) |
|
|
|
fseek(iqmFile,iqm.ofs_text+imesh[i].name,SEEK_SET); |
|
|
|
fread(name, sizeof(char)*MESH_NAME_LENGTH, 1, iqmFile); // Mesh name not used... |
|
|
|
model.meshes[i].vertexCount = imesh[i].num_vertexes; |
|
|
|
|
|
|
|
|
|
|
|
model.meshes[i].vertices = malloc(sizeof(float)*imesh[i].num_vertexes*3); // Default vertex positions |
|
|
|
model.meshes[i].normals = malloc(sizeof(float)*imesh[i].num_vertexes*3); // Default vertex normals |
|
|
|
model.meshes[i].texcoords = malloc(sizeof(float)*imesh[i].num_vertexes*2); // Default vertex texcoords |
|
|
|
|
|
|
|
|
|
|
|
model.meshes[i].boneIds = malloc(sizeof(int)*imesh[i].num_vertexes*4); // Up-to 4 bones supported! |
|
|
|
model.meshes[i].boneWeights = malloc(sizeof(float)*imesh[i].num_vertexes*4); // Up-to 4 bones supported! |
|
|
|
|
|
|
|
|
|
|
|
model.meshes[i].triangleCount = imesh[i].num_triangles; |
|
|
|
model.meshes[i].indices = malloc(sizeof(unsigned short)*imesh[i].num_triangles*3); |
|
|
|
|
|
|
|
|
|
|
|
// Animated verted data, what we actually process for rendering |
|
|
|
// NOTE: Animated vertex should be re-uploaded to GPU (if not using GPU skinning) |
|
|
|
model.meshes[i].animVertices = malloc(sizeof(float)*imesh[i].num_vertexes*3); |
|
|
|