MegaGlest/source/tools/glexemel/g2xml.c

371 lines
8.8 KiB
C

/**
* File: g2xml.c
* Written: Jonathan Merritt <jmerritt@warpax.com>
*
* Description:
* Converts G3D format files into an XML representation.
*
* Copyright (C) Jonathan Merritt 2005.
* This file may be distributed under the terms of the GNU General Public
* License.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "g3dv4.h"
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
/**
* Forward function declarations.
*/
int g3d2xml(FILE *infile, FILE *outfile);
void usage(char *execname);
/**
* Program entry point.
*
* @param argc: Number of arguments passed to the program.
* @param argv: Array of string arguments.
*
* @returns: EXIT_SUCCESS or EXIT_FAILURE depending upon success or failure
* of the conversion to XML.
*/
int main(int argc, char **argv)
{
char *infilename, *outfilename;
FILE *infile, *outfile;
int successFlag;
/* parse command line arguments */
if (argc != 3)
{
usage(argv[0]);
return (EXIT_FAILURE);
}
else
{
infilename = argv[1];
outfilename = argv[2];
}
/* attempt to open the input and output files */
//#ifdef WIN32
// infile = _wfopen(utf8_decode(infilename).c_str(), L"rb");
//#else
infile = fopen(infilename, "rb");
//#endif
if (infile == NULL) {
printf("Could not open file \"%s\" for binary reading.\n",
infilename);
return (EXIT_FAILURE);
}
//#ifdef WIN32
// outfile = _wfopen(utf8_decode(outfilename).c_str(), L"w");
//#else
outfile = fopen(outfilename, "w");
//#endif
if (outfile == NULL)
{
printf("Could not open file \"%s\" for writing.\n",
outfilename);
fclose(infile);
return (EXIT_FAILURE);
}
/* perform the XML conversion */
successFlag = g3d2xml(infile, outfile);
/* close the two files */
fclose(infile);
fclose(outfile);
/* return a success or failure flag */
if (successFlag)
return (EXIT_SUCCESS);
else
return (EXIT_FAILURE);
}
/**
* Prints a "Usage:" string for the program.
*
* @param execname: Executable name of the program.
*/
void usage(char *execname)
{
printf("Usage:\n");
printf(" %s infile.g3d outfile.xml\n", execname);
return;
}
/**
* Performs the conversion from the G3D file format to XML.
*
* @param infile: G3D binary file, opened as "rb", for input.
* @param outfile: Text file, opened as "w", for XML output.
*
* @returns: TRUE if conversion to XML was successful, and FALSE otherwise.
*/
int g3d2xml(FILE *infile, FILE *outfile)
{
struct FileHeader fileHeader;
struct ModelHeader modelHeader;
struct MeshHeader meshHeader;
size_t nBytes;
uint8 textureName[NAMESIZE+1];
float32 *fdata;
uint32 *idata;
unsigned int ii, jj, kk;
/* read in the FileHeader */
nBytes = sizeof(struct FileHeader);
if (fread(&fileHeader, nBytes, 1, infile) != 1)
{
printf("Could not read file header!\n");
return FALSE;
}
if (strncmp((char*)fileHeader.id, "G3D", 3) != 0)
{
printf("Expected \"G3D\" id was not found!\n");
return FALSE;
}
if (fileHeader.version != 4)
{
printf("Version 4 expected, but version %d found!\n",
fileHeader.version);
return FALSE;
}
fprintf(outfile, "<?xml version=\"1.0\" encoding=\"ASCII\" ?>\n");
fprintf(outfile, "<!DOCTYPE G3D SYSTEM \"g3d.dtd\">\n");
fprintf(outfile, "<!--\n");
fprintf(outfile, "\tThis file is an XML encoding of a G3D binary\n");
fprintf(outfile, "\tfile. The XML format is by Jonathan Merritt\n");
fprintf(outfile, "\t(not yet accepted as part of Glest!).\n");
fprintf(outfile, "-->\n");
fprintf(outfile, "<G3D version=\"%d\">\n", fileHeader.version);
/* read in the ModelHeader */
nBytes = sizeof(struct ModelHeader);
if (fread(&modelHeader, nBytes, 1, infile) != 1)
{
printf("Could not read model header!\n");
return FALSE;
}
if (modelHeader.type != mtMorphMesh)
{
printf("Unrecognized mesh type!\n");
return FALSE;
}
/* read in the meshes */
for (ii = 0; ii < modelHeader.meshCount; ii++)
{
/* read in the MeshHeader */
nBytes = sizeof(struct MeshHeader);
if (fread(&meshHeader, nBytes, 1, infile) != 1)
{
printf("Could not read mesh header!\n");
return FALSE;
}
meshHeader.name[NAMESIZE-1] = 0;
/* write out XML mesh header */
fprintf(outfile, "\t<Mesh name=\"%s\" ", meshHeader.name);
fprintf(outfile, "frameCount=\"%u\" ", meshHeader.frameCount);
fprintf(outfile, "vertexCount=\"%u\" ",
meshHeader.vertexCount);
fprintf(outfile, "indexCount=\"%u\" ", meshHeader.indexCount);
fprintf(outfile, "specularPower=\"%f\" ",
meshHeader.specularPower);
fprintf(outfile, "opacity=\"%f\" ", meshHeader.opacity);
if (meshHeader.properties & (0x1 << mpfTwoSided))
fprintf(outfile, "twoSided=\"true\" ");
else
fprintf(outfile, "twoSided=\"false\" ");
if (meshHeader.properties & (0x1 << mpfCustomColor))
fprintf(outfile, "customColor=\"true\" ");
else
fprintf(outfile, "customColor=\"false\" ");
if (meshHeader.textures)
fprintf(outfile, "diffuseTexture=\"true\"");
else
fprintf(outfile, "diffuseTexture=\"false\"");
fprintf(outfile, ">\n");
/* write out diffuse and specular colors */
fprintf(outfile, "\t\t<Diffuse>\n");
fprintf(outfile, "\t\t\t<Color r=\"%f\" g=\"%f\" b=\"%f\"/>\n",
meshHeader.diffuseColor[0],
meshHeader.diffuseColor[1],
meshHeader.diffuseColor[2]);
fprintf(outfile, "\t\t</Diffuse>\n");
fprintf(outfile, "\t\t<Specular>\n");
fprintf(outfile, "\t\t\t<Color r=\"%f\" g=\"%f\" b=\"%f\"/>\n",
meshHeader.specularColor[0],
meshHeader.specularColor[1],
meshHeader.specularColor[2]);
fprintf(outfile, "\t\t</Specular>\n");
/* read / write the texture name if present */
if (meshHeader.textures)
{
memset(&textureName[0],0,NAMESIZE+1);
nBytes = NAMESIZE;
if (fread(&textureName, nBytes, 1, infile) != 1) {
printf("Could not read texture name!\n");
return FALSE;
}
textureName[NAMESIZE] = 0;
fprintf(outfile, "\t\t<Texture name=\"%s\"/>\n",
textureName);
}
/* read / write each set of vertex data */
for (jj=0; jj < meshHeader.frameCount; jj++)
{
nBytes = sizeof(float32)*meshHeader.vertexCount*3;
fdata = malloc(nBytes);
if (fdata == NULL)
{
printf("Could not allocate buffer!\n");
return FALSE;
}
if (fread(fdata, nBytes, 1, infile) != 1)
{
printf("Could not read vertex data!\n");
free(fdata);
return FALSE;
}
fprintf(outfile, "\t\t<Vertices frame=\"%u\">\n",
jj);
for (kk=0; kk < meshHeader.vertexCount; kk++)
{
fprintf(outfile, "\t\t\t<Vertex ");
/*fprintf(outfile, "i=\"%d\" ",
kk);*/
fprintf(outfile, "x=\"%f\" ",
fdata[3*kk]);
fprintf(outfile, "y=\"%f\" ",
fdata[3*kk+1]);
fprintf(outfile, "z=\"%f\"/>\n",
fdata[3*kk+2]);
}
fprintf(outfile, "\t\t</Vertices>\n");
free(fdata);
}
/* read / write each set of normal data */
for (jj=0; jj < meshHeader.frameCount; jj++)
{
nBytes = sizeof(float32)*meshHeader.vertexCount*3;
fdata = malloc(nBytes);
if (fdata == NULL)
{
printf("Could not allocate buffer!\n");
return FALSE;
}
if (fread(fdata, nBytes, 1, infile) != 1)
{
printf("Could not read normal data!\n");
free(fdata);
return FALSE;
}
fprintf(outfile, "\t\t<Normals frame=\"%u\">\n",
jj);
for (kk=0; kk < meshHeader.vertexCount; kk++)
{
fprintf(outfile, "\t\t\t<Normal ");
/*fprintf(outfile, "i=\"%d\" ",
kk);*/
fprintf(outfile, "x=\"%f\" ",
fdata[3*kk]);
fprintf(outfile, "y=\"%f\" ",
fdata[3*kk+1]);
fprintf(outfile, "z=\"%f\"/>\n",
fdata[3*kk+2]);
}
fprintf(outfile, "\t\t</Normals>\n");
free(fdata);
}
/* read / write texture coordinates */
if (meshHeader.textures)
{
nBytes = sizeof(float32)*meshHeader.vertexCount*2;
fdata = malloc(nBytes);
if (fdata == NULL)
{
printf("Could not allocate buffer!\n");
return FALSE;
}
if (fread(fdata, nBytes, 1, infile) != 1)
{
printf("Could not read texture coords!\n");
free(fdata);
return FALSE;
}
fprintf(outfile, "\t\t<TexCoords>\n");
for (kk=0; kk < meshHeader.vertexCount; kk++)
{
fprintf(outfile, "\t\t\t<ST ");
/*fprintf(outfile, "i=\"%d\" ",
kk);*/
fprintf(outfile, "s=\"%f\" ",
fdata[2*kk]);
fprintf(outfile, "t=\"%f\"/>\n",
fdata[2*kk+1]);
}
fprintf(outfile, "\t\t</TexCoords>\n");
free(fdata);
}
/* read / write face indices */
nBytes = sizeof(uint32)*meshHeader.indexCount;
idata = malloc(nBytes);
if (idata == NULL)
{
printf("Could not allocate buffer!\n");
return FALSE;
}
if (fread(idata, nBytes, 1, infile) != 1)
{
printf("Could not read indexes!\n");
free(idata);
return FALSE;
}
fprintf(outfile, "\t\t<Indices>\n");
for (kk=0; kk < meshHeader.indexCount; kk++)
{
fprintf(outfile, "\t\t\t<Ix i=\"%u\"/>\n",
idata[kk]);
}
fprintf(outfile, "\t\t</Indices>\n");
free(idata);
fprintf(outfile, "\t</Mesh>\n");
}
fprintf(outfile, "</G3D>\n");
return TRUE;
}