⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pqmaploader.cpp

📁 一个类似QUAKE的CSG关卡编辑器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    V3  center;
    
    fprintf(fw._pf, "{\r\n");
    fprintf(fw._pf, "\"message\" \"%s\"\r\n", "scene");
    fprintf(fw._pf,"\"classname\" \"worldspawn\"\r\n");
    fprintf(fw._pf,"\"_color\" \"1 1 1\"\r\n"); // poly caries the color
    for(int i=0; i< pScene->nBrushes;i++)
    {
        Plg_Brush& b = pScene->pBrushes[i];

        if(b.flags & BRSH_CUT)

        for(int j=0; j< b.nPolys;j++)
        {
            Plg_Poly& p = b.pPolys[j];
            for(int x=0;x<p.nvXes;x++)
                p.vXes[x]._xyz/=2;
        }
	    for(int j=0; j< b.nPolys;j++)
	    {
            fprintf(fw._pf,"// brush %d\r\n", ++bn); // write a negative value for cut brush
            fprintf(fw._pf, "{\r\n");

            Plg_Poly& p = b.pPolys[j];

            
//            if(!GetWindingVertex(b.pPolys, b.nPolys, p, center))
            {
                center.reset();
                REAL exback = 8;
                
                
                for(int x=0; x < p.nvXes; x++)
                {
                    center+=p.vXes[x]._xyz;
                }
                center/=p.nvXes;
                
                

                Plane plan(p.vXes[0]._xyz, p.vXes[1]._xyz, p.vXes[2]._xyz);
                center += plan._n * (exback);
            }


            // put first 3 points of the poly. 
            // scale world by 4
            
            if(p.texIdx[0] < pScene->nTextures)
            {
                ::sprintf(texname,"%s/%s",_mapname.c_str(),pScene->pTextures[p.texIdx[0]].filename);

                
                CopyFile(MKSTR("%s/ged_textures/%s", installDir, pScene->pTextures[p.texIdx[0]].filename), texname,0);
            }
            else
            {
                ::strcpy(texname, "NULL");
            }
            
            fprintf(fw._pf, "( %f %f %f ) ( %f %f %f ) ( %f %f %f ) %s %f %f %f %f %f %f %f %f\r\n", //// %f %f
                            p.vXes[0]._xyz.x, p.vXes[0]._xyz.z, p.vXes[0]._xyz.y,
                            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)

            V3 a,b,c;
            for(int x=0;x<p.nvXes;x++)
            {
                a = p.vXes[x]._xyz;
                b = p.vXes[(x+1)%p.nvXes]._xyz;
                c = center;
                


                fprintf(fw._pf, "( %f %f %f ) ( %f %f %f ) ( %f %f %f ) %s %f %f %f %f %f %f %f %f\r\n", //// %f %f
                            a.x, a.z, a.y,
                            b.x, b.z, b.y,
                            c.x, c.z, c.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");

	    }
        
    }
    fprintf(fw._pf, "}\r\n");
    return 0;
}

//---------------------------------------------------------------------------------------
long PqmapLoader::GetMenuStringAndType(char* bsFileName, DWORD* type)
{
    //large enough
    _tcscpy(bsFileName,"Quake map files,map");
    *type = PLUG_IMPORTER|PLUG_EXPORTER;
    return 0;
}


//---------------------------------------------------------------------------------------
long PqmapLoader::ImportFile(IGeticEditor* pe, char* installDir, char* 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");
        append(_tokenspersect, tokens);
        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)
{
    _tokenspersect.clear();
    _pEntity = new QEntity(_pfw);
    TRACEX("New Entity\r\n");
    while(_pEntity->Step()>0);
    return 1;
}

//---------------------------------------------------------------------------------------
int Parser::Step()
{
    bool bok = false;
    char line[255]={0};
    char* pline = line;
    char* pend;  //= pline+strlen(line);
    do{
        pline = 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;
        if(T()==_BRUSH)
        {
            bok =  !(pline[0]=='(' || pline[0]==')' || pline[0]=='}');
            if(pline[0]=='{')
                _doubleopen                 = true;
            if(pline[0]=='}')
            {
                if(_doubleopen)
                {
                    _doubleopen=false;
                    bok=true;
                }
                else
                    bok=false;

            }
        }
    }while(bok);

    if(strlen(pline))
        return BaseParse(pline);
    return 0;
}

//---------------------------------------------------------------------------------------
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_Light(vvector<string>& tokens)
{
    if(tokens.size()>=2)
    {
        char* pc = (char*)tokens[1].c_str();
        if(*pc=='\"')pc++;
        _intensity = atoi(pc);
    }
    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 == 28) // new file
    {
        //( 1744 656 112 ) ( 1872 656 112 ) ( 1744 656 240 ) ( ( -0.00391 0.00000 -6.81640 ) ( 0.00000 0.00391 -0.56196 ) ) base_wall/basewall03
        ::sscanf(originalLine, "( %f %f %f ) ( %f %f %f ) ( %f %f %f ) ( ( %f %f %f ) ( %f %f %f ) ) %s" , 
                                 &a, &b,&c,    &d,&e,&f,    &g,&h,&i,     &u0,&u1,&u2, &v0, &v1, &v2, name);
    }
    else
    if(spacecount > 22) // new file
    {
        //( 93.750000 -91.500000 65.250000 ) ( -93.750000 91.500000 65.250000 ) ( 93.750000 91.500000 65.250000 ) qqq/bankmarble_offsq.jpg 0.000000 0.000000 1.000000 1.000000 1.000000 0.000000 0.000000 1.000000

        ::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                // 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*=3.0f; v22*=3.0f; v33*=3.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);

    // see if exitent plane is coplanar to already existent plane
    FOREACH(vvector<QBrushFace*>,  _pParent->_pbrshlines, ppBrLine)
    {
        QBrushFace* pLine = *ppBrLine;
        if(_plane == pLine->_plane)
        {
            return 1;
        }
    }
    _OK = TRUE;
    
    _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 + -