142 lines
4.7 KiB
C++
142 lines
4.7 KiB
C++
/* --------------------------------------------------------------------
|
|
Author of the quadtree algorithm is Ulrich Thatcher. To get the code running
|
|
in Tuxracer it was modified by Jasmin F. Patry. I've modified the code
|
|
again for Bunny Hill (old version). With this modification it was possible
|
|
to use more terrains than the 3 standard terrains (snow, rock and ice). For
|
|
the current version of ETR I've rearranged the modules. The
|
|
quadgeom.cpp ist not required because all needed mathematical functions are
|
|
available in the mathlib unit (now called "mathlib"). Furthermore the functions
|
|
of "course_quad.cpp" are integrated in quadtree.cpp. These functions were
|
|
purposed to acess the C++ quadtree from the other modules which were completely
|
|
written in C. The new Bunny Hill code or ETR code is C++-orientated though
|
|
not rigorously adapted to C++.
|
|
|
|
The quadtree algorithm works well but has some disadvantages. One disadvantage
|
|
ist the kind of blurring at adjacent terrain tiles, detailed terrain texturing
|
|
is not possible in this way. Another, more weightly disadvantage is the
|
|
performance that depends on the count of different terrains. Many terrains on
|
|
a course slow down the race appreciably. It's not urgent but anytime this
|
|
algorithm should be replaced with a more convenient quadtree algorithm.
|
|
--------------------------------------------------------------------- */
|
|
|
|
#ifndef QUADTREE_H
|
|
#define QUADTREE_H
|
|
|
|
#include "bh.h"
|
|
#include "view.h"
|
|
|
|
|
|
enum vertex_loc_t {
|
|
East,
|
|
South,
|
|
Center
|
|
};
|
|
|
|
struct HeightMapInfo {
|
|
double *Data;
|
|
int XOrigin, ZOrigin;
|
|
int XSize, ZSize;
|
|
int RowWidth;
|
|
int Scale;
|
|
float Sample(int x, int z) const;
|
|
};
|
|
|
|
struct VertInfo { float Y; };
|
|
struct quadsquare;
|
|
|
|
class quadcornerdata {
|
|
public:
|
|
const quadcornerdata* Parent;
|
|
quadsquare* Square;
|
|
int ChildIndex;
|
|
int Level;
|
|
int xorg, zorg;
|
|
VertInfo Verts[4];
|
|
};
|
|
|
|
struct quadsquare {
|
|
quadsquare* Child[4];
|
|
|
|
VertInfo Vertex[5];
|
|
float Error[6];
|
|
float MinY, MaxY;
|
|
unsigned char EnabledFlags;
|
|
unsigned char SubEnabledCount[2];
|
|
bool Static;
|
|
bool Dirty;
|
|
|
|
bool ForceEastVert;
|
|
bool ForceSouthVert;
|
|
|
|
static double ScaleX, ScaleZ;
|
|
static int RowSize, NumRows;
|
|
static char *Terrain;
|
|
|
|
static GLuint *VertexArrayIndices;
|
|
static GLuint VertexArrayCounter;
|
|
static GLuint VertexArrayMinIdx;
|
|
static GLuint VertexArrayMaxIdx;
|
|
|
|
static void MakeTri(int a, int b, int c, int terrain);
|
|
static void MakeSpecialTri(int a, int b, int c, int terrain);
|
|
static void MakeNoBlendTri(int a, int b, int c, int terrain);
|
|
|
|
static void DrawTris();
|
|
static void InitArrayCounters();
|
|
|
|
quadsquare(quadcornerdata* pcd);
|
|
~quadsquare();
|
|
|
|
void AddHeightMap(const quadcornerdata& cd, const HeightMapInfo& hm);
|
|
void StaticCullData(const quadcornerdata& cd, float ThresholdDetail);
|
|
float RecomputeError(const quadcornerdata& cd);
|
|
int CountNodes();
|
|
void Update(const quadcornerdata& cd, const TVector3d& ViewerLocation, float Detail);
|
|
void Render(const quadcornerdata& cd, GLubyte *vnc_array);
|
|
float GetHeight(const quadcornerdata& cd, float x, float z);
|
|
void SetScale(double x, double z);
|
|
void SetTerrain(char *terrain);
|
|
|
|
private:
|
|
quadsquare* EnableDescendant(int count, int stack[],
|
|
const quadcornerdata& cd);
|
|
quadsquare* GetNeighbor(int dir, const quadcornerdata &cd);
|
|
clip_result_t ClipSquare(const quadcornerdata &cd);
|
|
|
|
void EnableEdgeVertex(int index, bool IncrementCount,
|
|
const quadcornerdata &cd);
|
|
void EnableChild(int index, const quadcornerdata &cd);
|
|
void NotifyChildDisable(const quadcornerdata& cd, int index);
|
|
void ResetTree();
|
|
void StaticCullAux(const quadcornerdata &cd, float ThresholdDetail,
|
|
int TargetLevel);
|
|
void CreateChild(int index, const quadcornerdata &cd);
|
|
void SetupCornerData(quadcornerdata *q, const quadcornerdata &pd,
|
|
int ChildIndex);
|
|
void UpdateAux(const quadcornerdata &cd, const float ViewerLocation[3],
|
|
float CenterError, clip_result_t vis);
|
|
void RenderAux(const quadcornerdata &cd, clip_result_t vis,
|
|
int terrain);
|
|
void SetStatic(const quadcornerdata &cd);
|
|
void InitVert(int i, int x, int z);
|
|
bool VertexTest(int x, float y, int z, float error, const float Viewer[3],
|
|
int level, vertex_loc_t vertex_loc);
|
|
bool BoxTest(int x, int z, float size, float miny, float maxy,
|
|
float error, const float Viewer[3]);
|
|
};
|
|
|
|
// --------------------------------------------------------------------
|
|
// global calls
|
|
// --------------------------------------------------------------------
|
|
|
|
void ResetQuadtree();
|
|
void InitQuadtree(double *elevation, int nx, int nz,
|
|
double scalex, double scalez,
|
|
const TVector3d& view_pos, double detail);
|
|
|
|
void UpdateQuadtree(const TVector3d& view_pos, float detail);
|
|
void RenderQuadtree();
|
|
|
|
|
|
#endif
|