|
|
@ -1850,6 +1850,104 @@ bool ExportMesh(Mesh mesh, const char *fileName) |
|
|
|
return success; |
|
|
|
} |
|
|
|
|
|
|
|
// Export mesh as code file (.h) defining multiple arrays of vertex attributes |
|
|
|
bool ExportMeshAsCode(Mesh mesh, const char *fileName) |
|
|
|
{ |
|
|
|
bool success = false; |
|
|
|
|
|
|
|
#ifndef TEXT_BYTES_PER_LINE |
|
|
|
#define TEXT_BYTES_PER_LINE 20 |
|
|
|
#endif |
|
|
|
|
|
|
|
// NOTE: Text data buffer size is fixed to 64MB |
|
|
|
char *txtData = (char *)RL_CALLOC(64*1024*1024, sizeof(char)); // 64 MB |
|
|
|
|
|
|
|
int byteCount = 0; |
|
|
|
byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n"); |
|
|
|
byteCount += sprintf(txtData + byteCount, "// //\n"); |
|
|
|
byteCount += sprintf(txtData + byteCount, "// MeshAsCode exporter v1.0 - Mesh vertex data exported as arrays //\n"); |
|
|
|
byteCount += sprintf(txtData + byteCount, "// //\n"); |
|
|
|
byteCount += sprintf(txtData + byteCount, "// more info and bugs-report: github.com/raysan5/raylib //\n"); |
|
|
|
byteCount += sprintf(txtData + byteCount, "// feedback and support: ray[at]raylib.com //\n"); |
|
|
|
byteCount += sprintf(txtData + byteCount, "// //\n"); |
|
|
|
byteCount += sprintf(txtData + byteCount, "// Copyright (c) 2023 Ramon Santamaria (@raysan5) //\n"); |
|
|
|
byteCount += sprintf(txtData + byteCount, "// //\n"); |
|
|
|
byteCount += sprintf(txtData + byteCount, "////////////////////////////////////////////////////////////////////////////////////////\n\n"); |
|
|
|
|
|
|
|
// Get file name from path and convert variable name to uppercase |
|
|
|
char varFileName[256] = { 0 }; |
|
|
|
strcpy(varFileName, GetFileNameWithoutExt(fileName)); |
|
|
|
for (int i = 0; varFileName[i] != '\0'; i++) if ((varFileName[i] >= 'a') && (varFileName[i] <= 'z')) { varFileName[i] = varFileName[i] - 32; } |
|
|
|
|
|
|
|
// Add image information |
|
|
|
byteCount += sprintf(txtData + byteCount, "// Mesh basic information\n"); |
|
|
|
byteCount += sprintf(txtData + byteCount, "#define %s_VERTEX_COUNT %i\n", varFileName, mesh.vertexCount); |
|
|
|
byteCount += sprintf(txtData + byteCount, "#define %s_TRIANGLE_COUNT %i\n\n", varFileName, mesh.triangleCount); |
|
|
|
|
|
|
|
// Define vertex attributes data as separate arrays |
|
|
|
//----------------------------------------------------------------------------------------- |
|
|
|
if (mesh.vertices != NULL) // Vertex position (XYZ - 3 components per vertex - float) |
|
|
|
{ |
|
|
|
byteCount += sprintf(txtData + byteCount, "static float %s_VERTEX_DATA[%i] = { ", varFileName, mesh.vertexCount*3); |
|
|
|
for (int i = 0; i < mesh.vertexCount*3 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%.3ff,\n" : "%.3ff, "), mesh.vertices[i]); |
|
|
|
byteCount += sprintf(txtData + byteCount, "%.3ff };\n\n", mesh.vertices[mesh.vertexCount*3 - 1]); |
|
|
|
} |
|
|
|
|
|
|
|
if (mesh.texcoords != NULL) // Vertex texture coordinates (UV - 2 components per vertex - float) |
|
|
|
{ |
|
|
|
byteCount += sprintf(txtData + byteCount, "static float %s_TEXCOORD_DATA[%i] = { ", varFileName, mesh.vertexCount*2); |
|
|
|
for (int i = 0; i < mesh.vertexCount*2 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%.3ff,\n" : "%.3ff, "), mesh.texcoords[i]); |
|
|
|
byteCount += sprintf(txtData + byteCount, "%.3ff };\n\n", mesh.texcoords[mesh.vertexCount*2 - 1]); |
|
|
|
} |
|
|
|
|
|
|
|
if (mesh.texcoords2 != NULL) // Vertex texture coordinates (UV - 2 components per vertex - float) |
|
|
|
{ |
|
|
|
byteCount += sprintf(txtData + byteCount, "static float %s_TEXCOORD2_DATA[%i] = { ", varFileName, mesh.vertexCount*2); |
|
|
|
for (int i = 0; i < mesh.vertexCount*2 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%.3ff,\n" : "%.3ff, "), mesh.texcoords2[i]); |
|
|
|
byteCount += sprintf(txtData + byteCount, "%.3ff };\n\n", mesh.texcoords2[mesh.vertexCount*2 - 1]); |
|
|
|
} |
|
|
|
|
|
|
|
if (mesh.normals != NULL) // Vertex normals (XYZ - 3 components per vertex - float) |
|
|
|
{ |
|
|
|
byteCount += sprintf(txtData + byteCount, "static float %s_NORMAL_DATA[%i] = { ", varFileName, mesh.vertexCount*3); |
|
|
|
for (int i = 0; i < mesh.vertexCount*3 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%.3ff,\n" : "%.3ff, "), mesh.normals[i]); |
|
|
|
byteCount += sprintf(txtData + byteCount, "%.3ff };\n\n", mesh.normals[mesh.vertexCount*3 - 1]); |
|
|
|
} |
|
|
|
|
|
|
|
if (mesh.tangents != NULL) // Vertex tangents (XYZW - 4 components per vertex - float) |
|
|
|
{ |
|
|
|
byteCount += sprintf(txtData + byteCount, "static float %s_TANGENT_DATA[%i] = { ", varFileName, mesh.vertexCount*4); |
|
|
|
for (int i = 0; i < mesh.vertexCount*4 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%.3ff,\n" : "%.3ff, "), mesh.tangents[i]); |
|
|
|
byteCount += sprintf(txtData + byteCount, "%.3ff };\n\n", mesh.tangents[mesh.vertexCount*4 - 1]); |
|
|
|
} |
|
|
|
|
|
|
|
if (mesh.colors != NULL) // Vertex colors (RGBA - 4 components per vertex - unsigned char) |
|
|
|
{ |
|
|
|
byteCount += sprintf(txtData + byteCount, "static unsigned char %s_COLOR_DATA[%i] = { ", varFileName, mesh.vertexCount*4); |
|
|
|
for (int i = 0; i < mesh.vertexCount*4 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "0x%x,\n" : "0x%x, "), mesh.colors[i]); |
|
|
|
byteCount += sprintf(txtData + byteCount, "0x%x };\n\n", mesh.colors[mesh.vertexCount*4 - 1]); |
|
|
|
} |
|
|
|
|
|
|
|
if (mesh.indices != NULL) // Vertex indices (3 index per triangle - unsigned short) |
|
|
|
{ |
|
|
|
byteCount += sprintf(txtData + byteCount, "static unsigned short %s_INDEX_DATA[%i] = { ", varFileName, mesh.triangleCount*3); |
|
|
|
for (int i = 0; i < mesh.triangleCount*3 - 1; i++) byteCount += sprintf(txtData + byteCount, ((i%TEXT_BYTES_PER_LINE == 0)? "%i,\n" : "%i, "), mesh.indices[i]); |
|
|
|
byteCount += sprintf(txtData + byteCount, "%i };\n", mesh.indices[mesh.triangleCount*3 - 1]); |
|
|
|
} |
|
|
|
//----------------------------------------------------------------------------------------- |
|
|
|
|
|
|
|
// NOTE: Text data size exported is determined by '\0' (NULL) character |
|
|
|
success = SaveFileText(fileName, txtData); |
|
|
|
|
|
|
|
RL_FREE(txtData); |
|
|
|
|
|
|
|
//if (success != 0) TRACELOG(LOG_INFO, "FILEIO: [%s] Image as code exported successfully", fileName); |
|
|
|
//else TRACELOG(LOG_WARNING, "FILEIO: [%s] Failed to export image as code", fileName); |
|
|
|
|
|
|
|
return success; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#if defined(SUPPORT_FILEFORMAT_OBJ) || defined(SUPPORT_FILEFORMAT_MTL) |
|
|
|
// Process obj materials |
|
|
|
static void ProcessMaterialsOBJ(Material *materials, tinyobj_material_t *mats, int materialCount) |
|
|
|