📄 pqmaploader_new.cpp
字号:
p.vXes[2]._xyz.x, p.vXes[2]._xyz.z, p.vXes[2]._xyz.y,
p.vXes[1]._xyz.x, p.vXes[1]._xyz.z, p.vXes[1]._xyz.y,
texname,
p.texax[0].x, p.texax[0].y, p.texax[0].z, p.texShift.u,
p.texax[1].x, p.texax[1].y, p.texax[1].z, p.texShift.v); //texScale._u, texScale._v)
}
::fprintf(fw._pf, "}\r\n");
delete (*ppPlgBrush);
}
fragments.clear();
}
::fprintf(fw._pf, "}\r\n");
return 0;
}
//---------------------------------------------------------------------------------------
void PqmapLoader::MakeConvex(Plg_Brush& bf, vvector<Plg_Brush*> outs)
{
QBrCvx inbrush;
// use this for storage convenience.
// move them and pass the mem managemebt to stl.
for(int j=0; j < bf.nPolys;j++){
Plg_Poly& p = bf.pPolys[j];
QPoly qp;
qp._texIdx = bf.pPolys[j].texIdx[0];
qp._flags = bf.flags;
for(int v=0; v < p.nvXes;v++){
qp._vxes << p.vXes[v]._xyz;
qp._uvs << p.vXes[v]._uv[0];
}
cvxbr._flags = bf.flags;
cvxbr._polys << qp;
}
MakeConvex(inbrush, cvxbr);
}
//---------------------------------------------------------------------------------------
int PqmapLoader::IsConvex(QBrCvx& inbrush, QBrCvx& a, QBrCvx& b, QPoly* splPoly)
{
FOREACH(vvector<QPoly>, inbrush._polys, pp)
{
Plane pl(pp->_vxes[0], pp->_vxes[1], pp->_vxes[2]);
FOREACH(vvector<QPoly>, inbrush._polys, pp2)
{
if(pp2 == pp) continue;
QPoly pa;
QPoly pb;
pa._texIdx = pp2->._texIdx;
Split(pl, pp2->_vxes, pa._vxes, pb._vxes);
if(pa._vxes.size()>=3)
a._polys << pa;
if(pb._vxes.size()>=3)
b._polys << pb;
}
if(b._polys.size() && a._polys.size())
{
pp->_flags |= POLY_IS_SPLITTER;
splPoly = pp;
return HAS_BOTH;
}
}
return b._polys.size() ? HAS_BACKS : HAS_FRONTS;
}
//---------------------------------------------------------------------------------------
void PqmapLoader::MakeConvex(QBrCvx inbrush, vvector<QBrCvx>& cvx)
{
QBrCvx a;
QBrCvx b;
QPoly* pSlitter;
DWORD dwRez = IsConvex(inbrush, a, b, pSlitter);
switch(dwRez)
{
case HAS_BOTH:
MakeConvex(a, cvx);
MakeConvex(b, cvx);
break;
case HAS_BACKS:
cvx << b;
break;
case HAS_FRONTS:
//discard these
break;
}
}
//---------------------------------------------------------------------------------------
// pseudo code how to split the brush
/*
allocate out convex brushes
for each face plane
classify all brush vertexes.
if only front vertexex
is concave error
if only back vertexes
is convex store in out convex brushes and return
if back and front vertexes
split brush by this face plane
seal both fragment brush { build a bogus poly on this splitter
cut it with all faces that have been split or touched
add remainig polygon to both fragments. reverse one
face acordingly}
repeat for front and back fragments
save the out convex brushes
*/
//---------------------------------------------------------------------------------------
long PqmapLoader::GetMenuStringAndType(TCHAR* bsFileName, DWORD* type)
{
_tcscpy(bsFileName,"Quake map files,map");
*type = PLUG_IMPORTER|PLUG_EXPORTER;
return 0;
}
//---------------------------------------------------------------------------------------
long PqmapLoader::ImportFile(IGeticEditor* pe, TCHAR* bsFileName, Plg_Scene** pScene)
{
FileWrap fw;
if(!fw.Open(bsFileName, "rb"))
return -1;
Parser parser(&fw);
while(parser.Step()>=0);
fw.Close();
return PostProcess(pScene);
}
//---------------------------------------------------------------------------------------
long PqmapLoader::ReleaseScene(Plg_Scene* pScene)
{
RELEASE_SCENE(pScene);
return NO_ERROR;
}
//---------------------------------------------------------------------------------------
int Parser::Parse(vvector<string>& tokens)
{
map<string, PfHandler>::iterator fi = _classes.find(tokens[0]);
if(fi != _classes.end()){
return (this->*_classes[tokens[0]])(tokens);
}
return 1;
}
//---------------------------------------------------------------------------------------
int Parser::BaseParse(const char* pline)
{
vvector<string> tokens;
Explode(pline, tokens,' ');
if(tokens.size()){
TRACEX(pline);
TRACEX("\r\n");
return Parse(tokens);
}
return -1;
}
//---------------------------------------------------------------------------------------
void Parser::Explode(const char* pline, vvector<string>& tokens, char token)
{
char localline[256]= {0};
::strcpy(localline, pline);
char* pLocal = localline;
char pTok[2]= {token,'\0'};
char* pSubStr;
while(pSubStr = strtok(pLocal, pTok)){
pLocal = 0;
tokens << pSubStr;
}
}
//---------------------------------------------------------------------------------------
int Parser::Handle_Open(vvector<string>& tokens)
{
_pEntity = new QEntity(_pfw);
TRACEX("New Entity\r\n");
while(_pEntity->Step()>0);
return 1;
}
//---------------------------------------------------------------------------------------
int Parser::Step()
{
char line[255]={0};
char* pline = line;
char* pend; //= pline+strlen(line);
_pfw->ReadLine(line, 255);
if(feof(_pfw->_pf))
return -1;
// remove triling crlf
pend = pline+strlen(line)-1;
while(*pend=='\n'||*pend=='\r')
--pend;
*(pend+1)='\0';
// remove start spaces
while(*pline==' '||*pline=='\t')
++pline;
return BaseParse(pline);
}
//---------------------------------------------------------------------------------------
int QEntity::Handle_Open(vvector<string>& tokens)
{
if(_classname== "\"worldspawn\"")
{
TRACEX("New Brush\r\n");
QBrush* pBrush = new QBrush(_pfw, this);
while(pBrush->Step() > 0);
}
return 1;
}
//---------------------------------------------------------------------------------------
int QEntity::Handle_KeyVal(vvector<string>& tokens)
{
if(tokens.size() == 0)
return 1;
string values;
for(int i=1; i<tokens.size(); ++i){
values += tokens[i];
values += " ";
}
if(values.length())
_keyvals[tokens[0]] = values;
return 1;
}
//---------------------------------------------------------------------------------------
int QEntity::Handle_Comment(vvector<string>& tokens)
{
string values;
for(int i=1; i<tokens.size(); ++i){
values += tokens[i];
values += " ";
}
if(values.length())
_keyvals[tokens[0]] = values;
return 1;
}
//---------------------------------------------------------------------------------------
int QEntity::Handle_Close(vvector<string>& tokens)
{
if(_classname== "\"worldspawn\""){
TRACEX("Store entity brush in scene\r\n");
this->_flags = BRSH_SOLID;
__QLevel._entities << this;
}else{
TRACEX("Store entity in scene\r\n");
__QLevel._entities << this;
}
return 0;
}
//---------------------------------------------------------------------------------------
int QBrush::Handle_Line(vvector<string>& tokens)
{
QBrushFace* pLine = new QBrushFace(_pfw, this);
pLine->Handle_Line(tokens);
if(pLine->_OK)
_pbrshlines << pLine;
return 1;
}
//---------------------------------------------------------------------------------------
int QBrush::Handle_Close(vvector<string>& tokens)
{
if(this->_pbrshlines.size() &&_pParent->_classname=="\"worldspawn\""){
TRACEX("store Qbrush in entity");
_pParent->_brushes << this;
}
return 0; // end brush
}
//---------------------------------------------------------------------------------------
int QBrushFace::Handle_Line(vvector<string>& tokens)
{
float a,b,c,d,e,f,g,h,i;
float u0=0,u1=0,u2=0,u3=0,v0=0,v1=0,v2=0,v3=0;
char name[32];
char originalLine[255]={0};
if(_pParent->_pParent->_classname != "\"worldspawn\"")
return 1;
FOREACH(vvector<string>, tokens, pstring){
::strcat(originalLine, pstring->c_str());
::strcat(originalLine, " ");
}
int spacecount = tokens.size();
if(spacecount > 22){ // new file
::sscanf(originalLine, "( %f %f %f ) ( %f %f %f ) ( %f %f %f ) %s %f %f %f %f %f %f %f %f" , &a,&b,&c,&d,&e,&f,&g,&h,&i, name, &u0, &u1, &u2, &u3, &v0, &v1, &v2, &v3);
}
else{ // never tested (old file)
::sscanf(originalLine, "( %f %f %f ) ( %f %f %f ) ( %f %f %f ) %s %f %f %f" , &a,&b,&c,&d,&e,&f,&g,&h,&i, name, &u0, &u1, &u2);
}
// scale the world by 4
V3 v11(a,c,b);
V3 v22(d,f,e);
V3 v33(g,i,h);
v11*=4.0f; v22*=4.0f; v33*=4.0f;
_center = V3(0,0,0);
_center += v11;
_center += v22;
_center += v33;
_center /= 3.0f; // from wich we spawn the polygon
_plane.CalcNormal (v11,v22,v33);
// reject same planes in this brush
FOREACH(vvector<QBrushFace*>, _pParent->_pbrshlines, ppBrLine)
{
QBrushFace* pLine = *ppBrLine;
if(_plane == pLine->_plane){
return 1;
}
}
_OK = TRUE;
// save texture information
_indexTex = __QLevel.AddTex(name);
_ax[0] = V3(u0, u1, u2);
_shft.u = u3;
_ax[1] = V3(v0, v1, v2);
_shft.v = v3;
return 1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -