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

📄 t3dloader.h

📁 一个类似QUAKE的CSG关卡编辑器
💻 H
字号:
#ifndef _T3DLOADER_H_
#define _T3DLOADER_H_

#include "Common/Tokenizer.h"
#include "Common/Stack.h"

#define PF_Invisible        1
#define PF_Masked           2
#define PF_Translucent      4
#define PF_NotSolid         8
#define PF_Environment      16
#define PF_ForceViewZone    16
#define PF_Semisolid        32
#define PF_Modulated        64
#define PF_FakeBackdrop     128
#define PF_TwoSided         256
#define PF_AutoUPan         512
#define PF_AutoVPan         1024
#define PF_NoSmooth         2048
#define PF_BigWavy          4096
#define PF_SpecialPoly      4096
#define PF_SmallWavy        8192
#define PF_Flat             16384
#define PF_LowShadowDetail  32768
#define PF_NoMerge          65536
#define PF_CloudWavy        131072
#define PF_DirtyShadows     262144
#define PF_BrightCorners    524288
#define PF_SpecialLit       1048576
#define PF_Gouraud          2097152
#define PF_NoBoundRejection 2097152
#define PF_Unlit            4194304
#define PF_HighShadowDetail 8388608
#define PF_Portal           67108864
#define PF_Mirrored         134217728

#define PF_NoOcclude (PF_Masked | PF_Translucent | PF_Invisible | PF_Modulated)
#define PF_NoShadows (PF_Unlit | PF_Invisible | PF_Environment | PF_FakeBackdrop)

enum STATE {
	NONE,
	MAP,
	BRUSH,
	POLYGON,
	POLYGONLIST,
	ACTOR
};

/* ########################################################################################################### */

struct TexName {
    char *name;
    TextureID baseTexture;
    TextureID bumpMap;
    unsigned int sizeU, sizeV;
    unsigned int flags;
};

class TextureTable {
private:
    Set <TexName *> textureNames;
public:
    TextureTable(){}
    ~TextureTable(){
        TexName *texName;
        int i, len = textureNames.getSize();

        for (i = 0; i < len; i++){
            texName = textureNames[i];
            delete texName->name;
            delete texName;
        }
    }

    void addTextureName(char *name, unsigned int sizeU, unsigned int sizeV, TextureID baseTexture, TextureID bumpMap, unsigned int flags){
        TexName *texName = new TexName;

        texName->name        = new char[strlen(name) + 1];
        strcpy(texName->name, name);
        texName->sizeU       = sizeU;
        texName->sizeV       = sizeV;
        texName->baseTexture = baseTexture;
        texName->bumpMap     = bumpMap;
        texName->flags       = flags;
        textureNames.add(texName);        
    }

    bool getTexturesFromName(char *name, unsigned int &sizeU, unsigned int &sizeV, TextureID &baseTexture, TextureID &bumpMap, unsigned int &flags){
        TexName *texName;
        int i, len = textureNames.getSize();

        for (i = 0; i < len; i++){
            texName = textureNames[i];

            if (stricmp(name, texName->name) == 0){
                sizeU       = texName->sizeU;
                sizeV       = texName->sizeV;
                baseTexture = texName->baseTexture;
                bumpMap     = texName->bumpMap;
                flags       = texName->flags;
                return true;
            }
        }

        texName = textureNames[0];
        sizeU       = texName->sizeU;
        sizeV       = texName->sizeV;
        baseTexture = texName->baseTexture;
        bumpMap     = texName->bumpMap;
        flags       = texName->flags;
        return false;
    }
        
};

/* ----------------------------------- */

class T3dLoader {
private:
	Tokenizer tok;

	Vertex fix(Vertex &v){
//		return Vertex(v.x, -v.z, -v.y);
		return Vertex(v.x, v.z, -v.y);
	}

	Vertex readVertex(){
		char str[256];
		float x,y,z;
		
		tok.next(str);  // sign
		x = (*str == '+')? 1.0f : -1.0f;
		tok.next(str);  // number
		x *= (float) atof(str);
		
		tok.next(NULL); // ,
		tok.next(str);  // sign
		y = (*str == '+')? 1.0f : -1.0f;
		tok.next(str);  // number
		y *= (float) atof(str);
		
		tok.next(NULL); // ,
		tok.next(str);  // sign
		z = (*str == '+')? 1.0f : -1.0f;
		tok.next(str);  // number
		z *= (float) atof(str);

		return Vertex(x,y,z);
	}
public:
	T3dLoader();
	~T3dLoader();

	bool loadFromFile(char *fileName, Set <class Polygon *> &polygons, TextureTable &textureTable);

};

/* ------------------------------------------------------------------- */


T3dLoader::T3dLoader(){

}

T3dLoader::~T3dLoader(){

}

bool T3dLoader::loadFromFile(char *fileName, Set <class Polygon *> &polygons, TextureTable &textureTable){
	char str[256];
	Stack <STATE> states;
	STATE state = NONE;
	int i,len;

	// Polygon variables
	class Polygon *poly;
	//class Polygon *poly;
	Set <Vertex> vertices;
	unsigned int flags, pflags;
	Vertex normal;
	Vertex origo, textureU, textureV;
    float panU, panV;
    TextureID baseTexture, bumpMap;
    unsigned int sizeU, sizeV;

	// Actor variables
	bool usePolygons = true;
	Vertex location(0,0,0);
	int vertexComponent;




	tok.setFile(fileName);

	while (tok.next(str)){
		if (stricmp(str, "Begin") == 0){
			tok.next(str);
			states.push(state);

			if (stricmp(str, "Map") == 0){
				state = MAP;
			} else if (stricmp(str, "Polygon") == 0){
				state = POLYGON;
				if (usePolygons){
					vertices.clear();
					flags = pflags = 0;
                    panU = panV = 0.0f;
				}
			} else if (stricmp(str, "Actor") == 0){
				state = ACTOR;
				location = Vertex(0,0,0);
				usePolygons = true;
			} else {
				state = NONE;
			}
		} else if (stricmp(str, "End") == 0){
			tok.next(NULL);

			switch(state){
			case POLYGON:
				if (usePolygons){
					if ((flags & PF_Invisible) == 0){
						len = vertices.getSize();
						poly = new class Polygon(len);
						for (i = 0; i < len; i++){
							//poly->setVertex(i, vertices[i]);
                            poly->setVertex(len - i - 1, vertices[i]);
						}
						if (flags & PF_TwoSided){
							poly->setFlags(PF_DOUBLESIDED, true);
						}
						if (flags & PF_Unlit){
							poly->setFlags(PF_UNLIT, true);
						}
						if (flags & PF_Translucent){
							poly->setFlags(PF_TRANSLUCENT, true);
						}

                        /*if (flags & PF_SpecialPoly){
                            poly->setFlags(PF_FOGVOLUME | PF_NONBLOCKING, true);
                        }*/

                        

                        poly->setFlags(pflags, true);

                        //origo -= (panU * (textureU / length(textureU)) + panV * (textureV / length(textureV)));
                        //origo += ((-panU - 2) * textureU * 2 + panV * textureV * 2);

                        origo -= (panU * textureU) / lengthSqr(textureU);
                        origo -= (panV * textureV) / lengthSqr(textureV);

                        textureU = fix(textureU);
                        textureV = fix(textureV);

						poly->setTexCoordSystem(fix(origo), textureU / (float) sizeU, textureV / (float) sizeV);
                        poly->setTextures(baseTexture,bumpMap);
						poly->finalize();
						//poly->setNormal(normal);
						polygons.add(poly);

					}
				}
				break;
			}

			state = states.pop();
		} else {


			switch(state){
			case POLYGON:
				if (usePolygons){
					if (stricmp(str, "Flags") == 0){
						tok.next(NULL); // =
						tok.next(str);  // flags
						flags = atoi(str);
												
					} else if ((flags & PF_Invisible) == 0){
						if (stricmp(str, "Vertex") == 0){
							Vertex v = readVertex();
							vertices.add(fix(v + location));
						} else if (stricmp(str, "Normal") == 0){
							normal = fix(readVertex());
						} else if (stricmp(str, "Texture") == 0){
    						tok.next(NULL); // =
	    					tok.next(str);  // texture name
                            textureTable.getTexturesFromName(str, sizeU, sizeV, baseTexture, bumpMap, pflags);
						} else if (stricmp(str, "TextureU") == 0){
							textureU = readVertex();
						} else if (stricmp(str, "TextureV") == 0){
							textureV = readVertex();
						} else if (stricmp(str, "Origin") == 0){
							origo = readVertex();
						} else if (stricmp(str, "Pan") == 0){
    						tok.next(NULL); // U
    						tok.next(NULL); // =
	    					tok.next(str);  // U pan or -
                            if (str[0] == '-'){
    	    					tok.next(str);  // U pan
		    				    panU = -(float) atof(str);
                            } else panU = (float) atof(str);

    						tok.next(NULL); // V
    						tok.next(NULL); // =
	    					tok.next(str);  // V pan or -
                            if (str[0] == '-'){
    	    					tok.next(str);  // V pan
		    				    panV = -(float) atof(str);
                            } else panV = (float) atof(str);
						}
					}
				}
				break;
			case ACTOR:
				if (stricmp(str, "Group") == 0){
					usePolygons = false;
				} else if (stricmp(str, "Location") == 0){
					float value;
					tok.next(NULL); // =
					tok.next(NULL); // (
					do {
						tok.next(str);
						vertexComponent = (*str - 'X');
						tok.next(NULL); // =
						tok.next(str);  // sign/value
						if (*str == '-'){
							tok.next(str);  // number
							value = -(float) atof(str);
						} else {
							value = (float) atof(str);
						}
						location[vertexComponent] = value;

						tok.next(str);
					} while (*str == ',');
				}
				break;
			}
		}
	}
	
	return true;
}

/* ########################################################################################################### */

#endif // _T3DLOADER_H_

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -