WARNING: this spec is for G3Dv3 Glest now uses G3Dv4, please take a look to model_header.h and model.h/cpp to know about G3Dv4. I will probabbly update this spec soon for G3Dv4.
Many people is asking us for plugins/converters for non-3dsmax platforms. We don't have the time to spend in this task, so that's we decided to publish the G3D spec. That way anyone can make its own plugins/converters. If anyone needs further explainations use this board, or mail us to: theproject 'at' glest 'dot' org
This is a spec for G3D (Glest 3D) file format, this spec will be included in future versions of the Glest Editor Pack.
G3D (Glest 3D) version 3 file format specificacion. v0.1.
1. DATA TYPES
================
G3D files use the following data types:
uint8: 8 bit unsigned int
uint32: 32 bit unsigned int
float32: 32 bit float
2. MODEL HEADER
===============
Every g3d file starts by a model header:
struct ModelHeader{
uint8 id[3];
uint8 version;
uint32 meshCount;
};
id: identifier, must be be "g3d"
version: g3d file version, must be 3 (not '3')
meshCount: the number of meshes in the model
3. MESHES
===============
After the model header they come the meshes, each mesh has it's own header:
struct MeshHeader{
uint32 vertexFrameCount;
uint32 normalFrameCount;
uint32 texCoordFrameCount;
uint32 colorFrameCount;
uint32 pointCount;
uint32 indexCount;
uint32 properties;
uint8 texName[64];
};
vertexFrameCount: number of vertex frames in the mesh
normalFrameCount: number of normal frames in the mesh, this value has to be 0, 1, or the same as vertexFrameCount
texCoordFrameCount: number of texture coordinate frames in the mesh, this value has to be 0, 1, or the same as vertexFrameCount
colorFrameCount: number of color frames in the mesh, this value has to be 1, or the same as vertexFrameCount
pointCount: number of vertices per frame
indexCount: number of indices in the mesh
properties: additional properties of the mesh:
enum MeshProperty{
mpNoTexture= 1,
mpTwoSided= 2,
mpCustomTexture= 4
};
mpNotexture: this mesh has not a texture
mpTwoSided: this mesh is two sided
mpCustomTexture: replace alpha in the texture by a custom texture (user for faction colors)
texName: texture file (in tga format), path is relative to this file path
After each mesh is comes the mesh data:
vertices: vertexFrameCount * pointCount * 3, float32 values representing the x, y, z vertex coords for all frames
normals: normalFrameCount * pointCount * 3, float32 values representing the x, y, z normal coords for all frames
texture coords: texCoordFrameCount * pointCount * 2, float32 values representing the s, t tex coords for all frames
colors: colorFrameCount * 4, float32 valuesrepresenting the r, g, b, a coords for all frames
indices: indexCount, uint32 values representing the indices
4. EXAMPLES
===============
Here is the C++ code for saving a G3D file:
//save a model to a g3d file
void Model::saveG3d(const string &path){
FILE *f= fopen(path.c_str(), "wb");
if(f==NULL){
throw runtime_error("Can't open file for writting: "+path);
}
ModelHeader modelHeader;
modelHeader.id[0]= 'G';
modelHeader.id[1]= '3';
modelHeader.id[2]= 'D';
modelHeader.version= 3;
modelHeader.meshCount= meshCount;
string dir= cutLastFile(path);
fwrite(&modelHeader, sizeof(ModelHeader), 1, f);
for(int i=0; i<meshCount; ++i){
meshes.save(dir, f);
}
fclose(f);
}
void Mesh::save(const string &dir, FILE *f){
MeshHeader meshHeader;
meshHeader.vertexFrameCount= vertexFrameCount;
meshHeader.normalFrameCount= normalFrameCount;
meshHeader.texCoordFrameCount= texCoordFrameCount;
meshHeader.colorFrameCount= colorFrameCount;
meshHeader.pointCount= pointCount;
meshHeader.indexCount= indexCount;
meshHeader.properties= 0;
if(twoSided) meshHeader.properties|= mpTwoSided;
if(customTexture) meshHeader.properties|= mpCustomTexture;
if(texture==NULL){
meshHeader.properties|= mpNoTexture;
meshHeader.texName[0]= '\0';
}
else{
strcpy(reinterpret_cast<char*>(meshHeader.texName), texName.c_str());
texture->getPixmap()->saveTga(dir+"/"+texName);
}
fwrite(&meshHeader, sizeof(MeshHeader), 1, f);
fwrite(vertices, sizeof(Vec3f)*vertexFrameCount*pointCount, 1, f);
fwrite(normals, sizeof(Vec3f)*normalFrameCount*pointCount, 1, f);
fwrite(texCoords, sizeof(Vec2f)*texCoordFrameCount*pointCount, 1, f);
fwrite(colors, sizeof(Vec4f)*colorFrameCount, 1, f);
fwrite(indices, sizeof(uint32)*indexCount, 1, f);
}