/* * quadtree.hpp -thatcher 9/15/1999 Copyright 1999-2000 Thatcher Ulrich * * Data structures for quadtree terrain storage. * * This code may be freely modified and redistributed. I make no * warrantees about it; use at your own risk. If you do incorporate * this code into a project, I'd appreciate a mention in the credits. * * Thatcher Ulrich * * Modified for use in Tux Racer by Jasmin Patry * * Modifications for use in ppracer by Volker Stroebel */ #ifndef _QUADTREE_H_ #define _QUADTREE_H_ #include "viewfrustum.h" enum VertexLoc { East, South, Center }; struct HeightMapInfo { const float *Data; int XOrigin, ZOrigin; int XSize, ZSize; int RowWidth; int Scale; inline float Sample(int x, int z) const { if ( x >= XSize ) { x = XSize - 1; } if ( z >= ZSize ) { z = ZSize - 1; } return Data[ x + z * RowWidth ]; } }; class quadsquare; // A structure used during recursive traversal of the tree to hold // relevant but transitory data. struct quadcornerdata { const quadcornerdata* Parent; quadsquare* Square; int ChildIndex; int Level; int xorg, zorg; float Verts[4]; }; class quadsquare { quadsquare* Child[4]; float Vertex[5]; // center, e, n, w, s float Error[6]; // e, s, children: ne, nw, sw, se float MinY, MaxY; // Bounds for frustum culling and error testing. unsigned char EnabledFlags; // bits 0-7: e, n, w, s, ne, nw, sw, se unsigned char SubEnabledCount[2]; // e, s enabled reference counts. bool Static; bool Dirty; // Set when vertex data has changed, but error/enabled data has not been recalculated. bool ForceEastVert; bool ForceSouthVert; static float ScaleX, ScaleZ; static int RowSize, NumRows; static int* Terrain; static GLuint *VertexArrayIndices[NUM_TERRAIN_TYPES]; static GLuint VertexArrayCounter[NUM_TERRAIN_TYPES]; static GLuint VertexArrayMinIdx[NUM_TERRAIN_TYPES]; static GLuint VertexArrayMaxIdx[NUM_TERRAIN_TYPES]; static void MakeTri( int a, int b, int c, int terrain ); static void MakeSpecialTri( int a, int b, int c); static void MakeNoBlendTri( int a, int b, int c, int terrain ); static void DrawTris(int terrain); static void DrawEnvmapTris(GLuint MapTexId, int terrain); static void InitArrayCounters(); public: quadsquare(quadcornerdata* pcd); ~quadsquare(); void AddHeightMap(const quadcornerdata& cd, const HeightMapInfo& hm); void StaticCullData(const quadcornerdata& cd, const float ThresholdDetail); float RecomputeError(const quadcornerdata& cd); int CountNodes(); void Update(const quadcornerdata& cd, const float ViewerLocation[3]); void Render(const quadcornerdata& cd, GLubyte *vnc_array); float GetHeight(const quadcornerdata& cd, const float x, const float z); inline void SetScale(const float x, const float z) { ScaleX = x; ScaleZ = z; }; inline void SetTerrain(int *terrain){Terrain = terrain;}; private: void EnableEdgeVertex(int index, const bool IncrementCount, const quadcornerdata& cd); quadsquare* EnableDescendant(int count, int stack[], const quadcornerdata& cd); void EnableChild(int index, const quadcornerdata& cd); void NotifyChildDisable(const quadcornerdata& cd, int index); void ResetTree(); void StaticCullAux(const quadcornerdata& cd, const float ThresholdDetail, const int TargetLevel); quadsquare* GetNeighbor(const int dir, const quadcornerdata& cd) const; void CreateChild(int index, const quadcornerdata& cd); void SetupCornerData(quadcornerdata* q, const quadcornerdata& pd, const int ChildIndex); void UpdateAux(const quadcornerdata& cd, const float ViewerLocation[3], const float CenterError, ClipResult vis); void RenderAux(const quadcornerdata& cd, ClipResult vi); void RenderAuxSpezial(const quadcornerdata& cd, ClipResult vis); void SetStatic(const quadcornerdata& cd); int InitVert(const int i, const int x, const int z); bool VertexTest(int x, float y, int z, float error, const float Viewer[3], VertexLoc vertex_loc ); bool BoxTest(int x, int z, float size, float miny, float maxy, float error, const float Viewer[3]); ClipResult ClipSquare( const quadcornerdata& cd ); }; #endif // _QUADTREE_H_