#ifndef AZONE_H #define AZONE_H //pull in datatypes from zone's map.h #include "../../zone/map.h" #include "file_loader.hpp" /* Father Nitwit's zone to map file converter. */ #include #include #include using namespace std; #define COUNT_MACTHES 1 //this is the version number to put in the map header #undef MAP_VERSION //override this from map.h with our version #define MAP_VERSION 0x01000000 //quadtree stopping criteria, comment any to disable them #define MAX_QUADRENT_FACES 50 //if box has fewer than this, stop #define MIN_QUADRENT_SIZE 100.0f //if box has a dimention smaller than this, stop #define MIN_QUADRENT_GAIN 0.3f //minimum split ratio before stopping #define MAX_QUADRENT_MISSES 2 //maximum number of quads which can miss their gains //1 or 2 make sense, others are less useful //attepmt to trim the data a little #define MAX_Z 3000.0 //seems to be a lot of points above this //if all points on poly are, kill it. /* This is used for the recursive node structure unsigned shorts are adequate because, worst case even in a zone that is 6000x6000 with a small node size of 30x30, there are only 40000 nodes. quadrent definitions: quad 1 (nodes[0]): x>=0, y>=0 quad 2 (nodes[1]): x<0, y>=0 quad 3 (nodes[2]): x<0, y<0 quad 4 (nodes[3]): x>=0, y<0 */ #define MAX_POLY_VTX 24 //arbitrary, im too lazy to figure it out //cut a triangle at most 6 times.... enum EQFileType { S3D, EQG, UNKNOWN }; struct POLYGON { VERTEX /*w[MAX_POLY_VTX], */c[MAX_POLY_VTX]; int count; // w is world points, c is for camera points }; class GPoint { public: GPoint(); GPoint(VERTEX &v); GPoint(float x, float y, float z); inline void operator()(float nx, float ny, float nz) { x = nx; y = ny; z = nz; } GPoint cross(const GPoint &them) const; float dot3(const GPoint &them) const; float x; float y; float z; }; GPoint operator-(const GPoint &v1, const GPoint &v2); class GVector : public GPoint { public: GVector(); GVector(const GPoint &them); GVector(float x, float y, float z, float w = 1.0f); inline void operator()(float nx, float ny, float nz, float nw) { x = nx; y = ny; z = nz; W = nw; } float dot4(const GVector &them) const; float dot4(const GPoint &them) const; void normalize(); float length(); float W; }; struct FaceRecord { FACE *face; unsigned long index; }; class QTNode; class QTBuilder { public: QTBuilder(); ~QTBuilder(); bool build(const char *shortname); bool build_eqg(const char *shortname); void AddPlaceable(FileLoader *fileloader, char *ZoneFileName, bool ListPlaceable=false); void AddPlaceableV4(FileLoader *fileloader, char *ZoneFileName, bool ListPlaceable=false); void RotateVertex(VERTEX &v, float XRotation, float YRotation, float ZRotation); void ScaleVertex(VERTEX &v, float XScale, float YScale, float ZScale); void TranslateVertex(VERTEX &v, float XOffset, float YOffset, float ZOffset); bool writeMap(const char *file); bool FaceInNode(const QTNode *q, const FACE *f); protected: void AddFace(VERTEX &v1, VERTEX &v2, VERTEX &v3); int ClipPolygon(POLYGON *poly, GVector *plane); //dynamic during load // vector _VertexList; vector _FaceList; //static once loaded // unsigned long vertexCount; unsigned long faceCount; // VERTEX * vertexBlock; FACE * faceBlock; VERTEX tempvtx[MAX_POLY_VTX]; QTNode *_root; static void NormalizeN(FACE *p); #ifdef COUNT_MACTHES unsigned long gEasyMatches; unsigned long gEasyExcludes; unsigned long gHardMatches; unsigned long gHardExcludes; #endif }; //quadtree node container class QTNode { public: QTNode(QTBuilder *builder, float Tminx, float Tmaxx, float Tminy, float Tmaxy); ~QTNode(); void clearNodes(); void doSplit(); void divideYourself(int depth); void buildVertexes(); // bool writeFile(FILE *out); unsigned long countNodes() const; unsigned long countFacelists() const; void fillBlocks(nodeHeader *heads, unsigned long *flist, unsigned long &hindex, unsigned long &findex); float minx; float miny; float maxx; float maxy; unsigned long nfaces; vector faces; /* quadrent definitions: quad 1 (node1): x>=0, y>=0 quad 2 (node2): x<0, y>=0 quad 3 (node3): x<0, y<0 quad 4 (node4): x>=0, y<0 */ QTNode *node1; QTNode *node2; QTNode *node3; QTNode *node4; GPoint v[8]; bool final; protected: QTBuilder *builder; }; #endif