mirror of
https://github.com/glest/glest-source.git
synced 2025-02-24 19:52:25 +01:00
371 lines
8.8 KiB
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;
|
|
|
|
}
|
|
|