This could help a bit, it doesnt load every map file but somehow i managed to load few basic maps with it
inline void LoadStdGTKRadiantMapFile(AnsiString fname, TachoGLModel<float> * output_model_tree, int & len)
{
TStringList * s = new TStringList();
s->LoadFromFile(fname);
ALOG("loaded file: "+fname+" lines: "+IntToStr(s->Count));
//begin with counting worlspawns or func_groups //since we treat them as worldspawn too
bool inEntity = false;
bool inBrush = false;
//First: count brushes in entities and func_groups so we can size output_model_tree, int & len
int EntityLen = 0;
int BracketDepth = 0;
for (int i=0; i < s->Count; i++)
{
AnsiString line = LowerCase(s->Strings[i]);
if ( (Pos("classname", line) > 0 ) &&
((Pos("worldspawn", line) > 0 ) || (Pos("func_group", line) > 0 )) )
{
BracketDepth = 0;
ALOG("FOUND WORLDSPAWN OR FUNC_GROUP at line: "+IntToStr(i));
for (int j=i+1; j < s->Count; j++)
{
line = LowerCase(s->Strings[j]);
// ALOG("j = "+IntToStr(j) +" line: "+line);
if (Pos("{", line) > 0 )
{
BracketDepth = BracketDepth + 1;
ALOG("FOUND Bracket: depth: "+IntToStr(BracketDepth));
if (BracketDepth > 0){ ALOG("FOUND BRUSH");EntityLen = EntityLen + 1; }
}
if (Pos("}", line) > 0 )
{
BracketDepth = BracketDepth - 1;
ALOG("Closing brush: bracket depth: "+IntToStr(BracketDepth));
}
if (BracketDepth < 0) {ALOG("Entity closed"); i = j + 1; break; }
}
}
}
if (EntityLen == 0) { delete s; return; }
output_model_tree = new TachoGLModel<float>[EntityLen];
len = EntityLen;
int EntityIndex = -1;
/*
* Through all lines in file check if we found { sign and are not in brush
*/
for (int i=0; i < s->Count; i++)
{
AnsiString line = LowerCase(s->Strings[i]);
if ( (Pos("classname", line) > 0 ) &&
((Pos("worldspawn", line) > 0 ) || (Pos("func_group", line) > 0 )) )
{
BracketDepth = 0;
for (int j=i+1; j < s->Count; j++) //to zakonczyc i = j+1;
{
bool found_brush = false;
line = LowerCase(s->Strings[j]);
if (Pos("{", line) > 0 )
{
BracketDepth = BracketDepth + 1;
found_brush = true;
if (BracketDepth > 0) EntityIndex = EntityIndex + 1;
}
if (Pos("}", line) > 0 )
BracketDepth = BracketDepth - 1;
if (BracketDepth < 0) continue;
if (Pos("{", line) > 0) continue;
if (Pos("(", line) <= 0) continue;
//we are definetly at (
inBrush = true;
//finally we have our polygon definition ffs
int NumOfFaces = 0;
TPlane<float> * Faces;
TPolygon<float> * Polys;
//count how many faces object has/consists
for (int p=j; p < s->Count; p++)
{
AnsiString str2 = s->Strings[p];
if (Pos("}", str2) > 0) break;
if (Pos("(", str2) > 0) NumOfFaces = NumOfFaces + 1;
}
ALOG("OBJECT CONSISTS OF: "+IntToStr(NumOfFaces));
Faces = new TPlane<float>[ NumOfFaces ];
Polys = new TPolygon<float>[ NumOfFaces ];
int FaceIndex = -1;
for (int p=j; p < s->Count; p++)
{
AnsiString str2 = s->Strings[p];
if (Pos("}", str2) > 0) break;
FaceIndex = FaceIndex + 1;
/*
* Receive data from 3 ( x, y, z )
*/
vec3 points[3];
AnsiString VertexStr = get_text_between2("(", ")", str2);
for (int iterations=0; iterations < 3; iterations++)
{
get_all_in_nawias(VertexStr, " ", 0);
points[iterations].x = (float)pstrtoint(w_nawiasie[0][0]);
points[iterations].y = (float)pstrtoint(w_nawiasie[0][1]);
points[iterations].z = (float)pstrtoint(w_nawiasie[0][2]);
// Swap the y and z values, and negate the new z so Y points up.
float tmp = points[iterations].y;
points[iterations].y = points[iterations].z;
points[iterations].z = -tmp;
//Reminder: Ax+By+Cz+D=0 => D = -(Ax+By+Cz) => D = -Ax-By-Cz
}
/*
* ===============================================================================================
* //eof retreiving data from (x y z) (x y z) (x y z) uselesss/text we now have plane definition [3] points
*/
Faces[FaceIndex].calc_plane(points[0], points[1], points[2], false);
}
TPolygon<float> output_polygon;
std::vector<TPolygon<float> > OutputModel;
//Test each face against another face then find intersection
for (int n1=0; n1 < NumOfFaces; n1++)
{
for (int n2=0; n2 < NumOfFaces; n2++)
for (int n3=0; n3 < NumOfFaces; n3++)
if ( (n1 != n2) && (n1 != n3) && (n2 != n3) )
{
bool illegal = false;
vec3 vertex_result;
bool newVertex = Get3PlaneIntersection(Faces[n1].n, Faces[n2].n, Faces[n3].n, Faces[n1].D, Faces[n2].D, Faces[n3].D, vertex_result);
if (newVertex)
for (int n4=0; n4 < NumOfFaces; n4++)
if (Faces[n4].ClassifyPoint(vertex_result) == isFront) illegal = true;
if (!illegal) output_polygon.AddVertex( vertex_result );
}
OutputModel.push_back(output_polygon);
}
int model_vlen = 0;
int model_flen = OutputModel.size();
for (int p1=0; p1 < model_flen; p1++)
model_vlen = model_vlen + OutputModel[p1].Count;
for (int p1=0; p1 < model_flen; p1++)
OutputModel[p1].CalcPlane();
output_model_tree[ EntityIndex ].header.LENGTH = model_vlen;
output_model_tree[ EntityIndex ].AOS = new TTGLVertex<float,float,float>[model_vlen];
output_model_tree[ EntityIndex ].FaceLength = model_flen;
output_model_tree[ EntityIndex ].Matrixarr = new tmatrixtype[model_flen];
output_model_tree[ EntityIndex ].VBO_BE = new tvbofacenfo[model_flen];
output_model_tree[ EntityIndex ].Textureindex = new int[model_flen];
for (int fa=0; fa < model_flen; fa++)
{
output_model_tree[ EntityIndex ].Matrixarr[fa] = mtTriangleFan;
output_model_tree[ EntityIndex ].Textureindex[fa] = 0;
}
int findex = -1;
int vindex = 0;
for (int p1=0; p1 < model_flen; p1++)
{
findex = findex + 1;
output_model_tree[ EntityIndex ].VBO_BE[findex].INDEX_START = vindex;
for (int p2=0; p2 < OutputModel[p1].Count; p2++)
{
output_model_tree[ EntityIndex ].AOS[vindex].v = OutputModel[p1].V[p2];
output_model_tree[ EntityIndex ].AOS[vindex].n = OutputModel[p1].normal;
vindex = vindex + 1;
}
}
i = j + 1; //skip to next line
if (i >= s->Count) {delete s; return;}//reached end of file way ago
}//eof for j
}//eof if classname worldspawn of func_group
}//eof for i
delete s;
} //end of function
template <class T> bool Get3PlaneIntersection(t3dpoint<T> n1, t3dpoint<T> n2, t3dpoint<T> n3,
T d1, T d2, T d3, t3dpoint<T> &p , T &den)
{
double denom = Dot(n1, vectorcross(n2, n3) );
den = T(denom);
if (betweenorequal(-epsilona,epsilona, denom)) return false; //check if denominator is equal or close to 0
t3dpoint<T> tmp = vectorcross(n2, n3) * -d1;
t3dpoint<T> tmp2 = vectorcross(n3, n1) * -d2;
t3dpoint<T> tmp3 = vectorcross(n1, n2) * -d3;
p = (tmp+tmp2+tmp3) / denom;
return true;
}
get_all_in_nawias is a function that separates a string given a key
Means: if we have a string "88, 66, 33"
And call that func with key ","
It will return a std::vector<std::string> with values
88
66
33
Lol just found that i nowhere store how many vertices each face has, and even with this it loaded data normally... Maybe i was setting it earlier but cant remember its an old code btw