Licar/assets/encodeCarModel.c

154 lines
3.2 KiB
C
Raw Normal View History

2024-08-29 23:59:54 +02:00
/**
Converts car 3D model in obj format to the game's internal C arrays. The model
is to be passed on stdin.
A specific subset of obj format is assumed. UVs must be present but not
normals or other such things.
The following materials must be set for model triangles: "a" for body, "b"
2024-09-10 20:11:31 +02:00
for front wheels, "c" and "d" for back wheels.
2024-08-29 23:59:54 +02:00
*/
#include <stdio.h>
#define UNIT 512
#define ARRAY_MAX 1024
2024-09-20 15:22:18 +02:00
#define UV_OFFSET -0.01
2024-08-29 23:59:54 +02:00
int vertices[ARRAY_MAX * 3];
int vertexTypes[ARRAY_MAX];
int vertexCount;
int uvs[ARRAY_MAX * 2];
int uvCount;
int triangles[ARRAY_MAX * 3];
int triangleUvs[ARRAY_MAX * 3];
int triangleCount;
char line[128];
void error(int n)
{
printf("ERROR %d\n",n);
exit(1);
}
void writeArray(int *array, unsigned int len, const char *name,
unsigned int align)
{
printf("%s[] =\n{",name);
for (int i = 0; i < len; ++i)
{
if (i != 0)
printf(", ");
if (i % align == 0)
printf("\n ");
printf("%d",array[i]);
}
puts("\n};\n");
}
int main(void)
{
unsigned char vertexType = 0;
while (1)
{
if (gets(line) == NULL)
break;
if (line[0] == 'f') // face
{
unsigned int n[6];
if (sscanf(line + 1,"%u/%u %u/%u %u/%u",
n,n + 1,n + 2,n + 3,n + 4,n + 5) != 6)
error(0);
2024-09-01 14:06:24 +02:00
for (int i = 0; i < 6; ++i)
n[i]--; // obj indices are 1-based
2024-08-29 23:59:54 +02:00
2024-09-01 14:06:24 +02:00
triangles[triangleCount * 3] = n[0];
triangles[triangleCount * 3 + 1] = n[4];
triangles[triangleCount * 3 + 2] = n[2];
2024-08-29 23:59:54 +02:00
2024-09-01 14:06:24 +02:00
triangleUvs[triangleCount * 3] = n[1];
triangleUvs[triangleCount * 3 + 1] = n[5];
triangleUvs[triangleCount * 3 + 2] = n[3];
vertexTypes[n[0]] = vertexType;
vertexTypes[n[2]] = vertexType;
vertexTypes[n[4]] = vertexType;
2024-08-29 23:59:54 +02:00
triangleCount++;
if (triangleCount >= ARRAY_MAX)
error(1);
}
else if (line[0] == 'v' && line[1] != 't') // vertex
{
float a, b, c;
if (sscanf(line + 1,"%f %f %f",&a,&b,&c) != 3)
error(2);
vertices[3 * vertexCount] = a * UNIT;
vertices[3 * vertexCount + 1] = b * UNIT;
vertices[3 * vertexCount + 2] = c * UNIT;
vertexCount++;
if (vertexCount >= ARRAY_MAX)
error(3);
}
else if (line[0] == 'v' && line[1] == 't') // texture vertex
{
float a, b;
if (sscanf(line + 2,"%f %f",&a,&b) != 2)
error(4);
2024-09-20 15:22:18 +02:00
a += UV_OFFSET;
b += UV_OFFSET;
2024-08-29 23:59:54 +02:00
uvs[2 * uvCount] = a * UNIT;
2024-09-01 14:06:24 +02:00
uvs[2 * uvCount + 1] = (1 - b) * UNIT;
2024-08-29 23:59:54 +02:00
uvCount++;
if (uvCount >= ARRAY_MAX)
error(5);
}
else if (line[0] == 'u' && line[1] == 's') // material
{
vertexType = line[7] - 'a';
}
}
2024-08-30 01:04:07 +02:00
printf("#define LCR_CAR_VERTEX_COUNT %d\n"
"#define LCR_CAR_TRIANGLE_COUNT %d\n\n",vertexCount,triangleCount);
2024-08-29 23:59:54 +02:00
writeArray(vertices,vertexCount * 3,
2024-08-30 01:04:07 +02:00
"static const int32_t LCR_carVertices",10);
2024-08-29 23:59:54 +02:00
writeArray(triangles,triangleCount * 3,
2024-08-30 01:04:07 +02:00
"static const uint16_t LCR_carTriangles",13);
2024-08-29 23:59:54 +02:00
writeArray(uvs,uvCount * 2,
2024-08-30 01:04:07 +02:00
"static const uint16_t LCR_carUvs",10);
2024-08-29 23:59:54 +02:00
writeArray(triangleUvs,triangleCount * 3,
2024-08-30 01:04:07 +02:00
"static const uint16_t LCR_carTriangleUvs",13);
2024-08-29 23:59:54 +02:00
writeArray(vertexTypes,vertexCount,
2024-08-30 01:04:07 +02:00
"static const uint8_t LCR_carVertexTypes",18);
2024-08-29 23:59:54 +02:00
return 0;
}