joeylib3d/obj2j3d/main.c
2019-08-27 21:19:57 -05:00

166 lines
4.1 KiB
C

/*
* JoeyLib 3D
* Copyright (C) 2019 Scott Duensing <scott@kangaroopunch.com>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
// OBJ format: http://paulbourke.net/dataformats/obj/
#include <stdio.h>
#include <string.h>
#include "stretchy_buffer.h"
#include "joey.h"
#include "j3d.h"
int main(int argc, char *argv[]) {
char *nameIn;
char *nameOut;
jint16 r;
juint16 x;
juint16 y;
char token[1024];
char *c;
FILE *f;
j3CoordinatesT v;
j3ObjectT o;
j3TriangleT t;
j3WorldT world;
if (argc < 3) {
printf("Usage: %s [infile] [outfile]\n", argv[0]);
return 1;
}
nameIn = argv[1];
nameOut = argv[2];
f = fopen(nameIn, "rt");
// Did we find the file?
if (f == NULL) {
// Nope.
printf("Unable to open %s\n", nameIn);
return 1;
}
world.objectCount = 0;
world.objects = NULL;
o.vertexCount = 0;
o.triangleCount = 0;
o.verticies = NULL;
o.triangles = NULL;
while (true) {
// Read next token
r = (jint16)fscanf(f, "%s", token);
// End of file?
if (r == EOF) {
break;
}
// Vertex?
if (strcmp(token, "v" ) == 0) {
r = (jint16)fscanf(f, "%f %f %f\n", &v.local.x, &v.local.y, &v.local.z);
sb_push(o.verticies, v);
o.vertexCount++;
}
// Face?
if (strcmp(token, "f" ) == 0) {
for (x=0; x<3; x++) {
// Fetch 'x'th vertex index
r = (jint16)fscanf(f, "%s", token);
c = strstr(token, "/");
if (c) c[0] = 0;
r = (jint16)atoi(token);
t.index[x] = (juint16)r - 1; // obj indicies start at 1
}
fscanf(f, "\n");
sb_push(o.triangles, t);
o.triangleCount++;
}
}
//***TODO*** support multiple objects - not sure how I want to do this yet
sb_push(world.objects, o);
world.objectCount++;
// Finished reading
fclose(f);
printf("Objects: %d\n", world.objectCount);
for (x=0; x<world.objectCount; x++) {
printf("Object %d:\n", x);
printf(" Verticies: %d\n", world.objects[x].vertexCount);
printf(" Triangles: %d\n", world.objects[x].triangleCount);
}
// Create output file
f = fopen(nameOut, "wb");
if (f == NULL) {
// Nope.
printf("Unable to create %s\n", nameOut);
return 1;
}
// Write header
fputc('J', f);
fputc('3', f);
fputc('D', f);
// Version
fputc(0, f);
// Number of objects in file
fwrite(&world.objectCount, sizeof(juint16), 1, f);
// Iterate over objects
for (x=0; x<world.objectCount; x++) {
// Number of verticies
fwrite(&world.objects[x].vertexCount, sizeof(juint16), 1, f);
// Vertex list
for (y=0; y<world.objects[x].vertexCount; y++) {
// Write one at a time in case the struct gets padded
fwrite(&world.objects[x].verticies[y].local.x, sizeof(float), 1, f);
fwrite(&world.objects[x].verticies[y].local.y, sizeof(float), 1, f);
fwrite(&world.objects[x].verticies[y].local.z, sizeof(float), 1, f);
}
// Number of triangles
fwrite(&world.objects[x].triangleCount, sizeof(juint16), 1, f);
// Triangle list
for (y=0; y<world.objects[x].triangleCount; y++) {
// Write one at a time in case the struct gets padded
fwrite(&world.objects[x].triangles[y].index[0], sizeof(juint16), 1, f);
fwrite(&world.objects[x].triangles[y].index[1], sizeof(juint16), 1, f);
fwrite(&world.objects[x].triangles[y].index[2], sizeof(juint16), 1, f);
}
}
// Finished writing
fclose(f);
return 0;
}