Here’s cut’n’pasted ASE loader, should help, though its has some engine specific structs/macros.
bool Builder_c::ReadASE()
{
int i, j;
int NumFaces, NumVerts, NumTVerts;
int NumObjects;
int Flags, ShaderID;
Vec3_t *TmpVerts;
Vec2_t *TmpTVerts;
Parser_c Parser;
if (!Parser.Open(“Base/Data/Maps_in/ASE/%s”, FileName))
{
LOL_WARN(“Couldn’t open map file "%s" in "%s"”, Parser.GetFileName());
return false;
}
// Extract name without extension
Name = LOL_ALLOC char[strlen(FileName) - 3];
memcpy(Name, FileName, sizeof(char) * (strlen(FileName) - 4));
Name[strlen(FileName) - 4] = ‘\0’;
LOL_PRINT(“$>Building map from "%s" (%.2f kB)…”, FileName, (float) Parser.FileSize() / 1024);
LOL_REFRESH;
// Materials
//----------
Parser.Next(“*MATERIAL_COUNT”);
LOL_FOR(i = Parser.NextInt(), i > 0, i–)
{
Parser.Next(“*BITMAP”);
ShaderRefs.Alloc();
strcpy(ShaderRefs.Get().Name, Parser.Next());
}
// Objects
//--------
NumObjects = 0;
NumVerts = 1;
NumTVerts = 1;
TmpVerts = LOL_ALLOC Vec3_t[NumVerts];
TmpTVerts = LOL_ALLOC Vec2_t[NumTVerts];
while (!Parser.EOFile())
{
LOL_REFRESH;
if (!Parser.Next2(“*GEOMOBJECT”, “*LIGHTOBJECT”))
{
break;
}
// Light object
//-------------
if (!stricmp("*LIGHTOBJECT", Parser.Curr()))
{
Lights.Alloc();
// Default Flags
Lights.Get().Flags = LIGHT_SHADOWS | LIGHT_CORONA;
// Position
Parser.Next("*TM_POS");
Lights.Get().Origin[0] = -Parser.NextFloat();
Lights.Get().Origin[2] = Parser.NextFloat();
Lights.Get().Origin[1] = Parser.NextFloat();
// Color (Alpha == 1 by default)
Parser.Next("*LIGHT_COLOR");
Lights.Get().Color[0] = Parser.NextFloat();
Lights.Get().Color[1] = Parser.NextFloat();
Lights.Get().Color[2] = Parser.NextFloat();
Lights.Get().Color[3] = 1.0f;
continue;
}
// Geometric object
//-----------------
NumObjects++;
// Face Flags
Parser.Next("*NODE_NAME");
if (stristr(Parser.Next(), "INVISIBLE"))
{
Flags = FACE_INVISIBLE | FACE_SEETHROUGH | FACE_NOTSOLID;
}
else if (stristr(Parser.Next(), "SEETHROUGH"))
{
Flags = FACE_SEETHROUGH | FACE_NOTSOLID;
}
else
{
Flags = 0;
}
Parser.Next("*MESH_NUMVERTEX");
i = Parser.NextInt();
Parser.Next("*MESH_NUMFACES");
NumFaces = Parser.NextInt();
// Verts
if (i > NumVerts)
{
NumVerts = i;
LOL_FREE1D( TmpVerts );
TmpVerts = LOL_ALLOC Vec3_t[NumVerts];
}
else
{
NumVerts = i;
}
LOL_FOR(i = 0, i < NumVerts, i++)
{
Parser.Next("*MESH_VERTEX");
Parser.Next(); // Skip int
// Exchange Y with Z, negate X
TmpVerts[i][0] = -Parser.NextFloat();
TmpVerts[i][2] = Parser.NextFloat();
TmpVerts[i][1] = Parser.NextFloat();
}
// Verts to Faces associations
LOL_FOR(i = 0, i < NumFaces, i++)
{
Parser.Next("*MESH_FACE");
Parser.Next(); // Skip "int:"
Parser.Next(); // Skip "A:"
Faces.Alloc();
Faces.Get().FirstVert = Verts.GetNum();
Faces.Get().NumVerts = 3;
// Inverse order to clockwise
j = Verts.Alloc();
Verts.Alloc();
Verts.Alloc();
Verts.Get(j).Pos = TmpVerts[ Parser.NextInt() ];
Parser.Next(); // Skip "B:"
Verts.Get(j + 2).Pos = TmpVerts[ Parser.NextInt() ];
Parser.Next(); // Skip "C:"
Verts.Get(j + 1).Pos = TmpVerts[ Parser.NextInt() ];
// Set to NULL for Kill() reasons
Faces.Get().EdgesID = NULL;
}
if (!(Flags & FACE_INVISIBLE))
{
// Texture coords
Parser.Next("*MESH_NUMTVERTEX");
i = Parser.NextInt();
if (i > NumTVerts)
{
NumTVerts = i;
LOL_FREE1D( TmpTVerts );
TmpTVerts = LOL_ALLOC Vec2_t[NumTVerts];
}
else
{
NumTVerts = i;
}
LOL_FOR(i = 0, i < NumTVerts, i++)
{
Parser.Next("*MESH_TVERT");
Parser.Next(); // Skip int
TmpTVerts[i][0] = Parser.NextFloat();
TmpTVerts[i][1] = Parser.NextFloat();
}
// Texture coords to faces associations
j = Faces.GetNum() - NumFaces;
LOL_FOR(i = 0, i < NumFaces, (i++, j++))
{
Parser.Next("*MESH_TFACE");
Parser.Next(); // Skip int
// Inverse order to clockwise
Verts.Get( Faces.Get(j).FirstVert ).Tex0 = TmpTVerts[ Parser.NextInt() ];
Verts.Get( Faces.Get(j).FirstVert + 2 ).Tex0 = TmpTVerts[ Parser.NextInt() ];
Verts.Get( Faces.Get(j).FirstVert + 1 ).Tex0 = TmpTVerts[ Parser.NextInt() ];
}
}
// Material reference
Parser.Next("*MATERIAL_REF");
ShaderID = Parser.NextInt();
// Assign common features for Faces
j = Faces.GetNum() - NumFaces;
LOL_FOR(i = 0, i < NumFaces, (i++, j++))
{
Faces.Get(j).Flags = Flags;
Faces.Get(j).ShaderID = ShaderID;
}
}
LOL_FREE1D( TmpVerts );
LOL_FREE1D( TmpTVerts );
LOL_PRINT(“ASE File "%s" read [%d msec]”, FileName, Clock->TestTime());
LOL_PRINT(" - Verts %d", Verts.GetNum());
LOL_PRINT(" - Faces %d", Faces.GetNum());
LOL_PRINT(" - Shaders %d", ShaderRefs.GetNum());
LOL_PRINT(" - Lights %d", Lights.GetNum());
LOL_PRINT(" - Geometric objects %d", NumObjects);
LOL_REFRESH;
return true;
}