/* Copyright (C) 1997, 1998, 1999 by Alex Pfaffe (Digital Dawn Graphics Inc) This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef _ddgMesh_Class_ #define _ddgMesh_Class_ #include "math/ddgvec.h" #include "math/ddgbbox.h" #include "struct/ddghemap.h" #include "struct/ddgcache.h" class ddgTBinTree; class ddgTBinMesh; class ddgContext; // Block size of bintrees within a binmesh. #define ddgTBinMesh_size 32 #define ddgPriorityResolution 1024 typedef unsigned int ddgTriIndex; typedef unsigned int ddgTreeIndex; typedef unsigned short ddgPriority; typedef enum { eINNER = 0, eTOP = 1, eLEFT = 2, eDIAG = 3} Edge; class WEXP ddgMSTri { public: unsigned int row, col; // Maybe possible to calculate. ddgTriIndex v0, v1; ddgTriIndex neighbour; inline Edge edge(void) { if (row == 0) return eTOP; if (col == 0) return eLEFT; if (row + col == ddgTBinMesh_size) return eDIAG; return eINNER; } }; class WEXP ddgTNode : public ddgLNode { friend class ddgTCache; private: ddgTriIndex _tindex; ddgPriority _priority; ddgVisState _vis; ddgCacheIndex _qscacheIndex; ddgCacheIndex _qmcacheIndex; float _priorityFactor; public: void qscacheIndex( ddgCacheIndex ci ) { _qscacheIndex = ci; } ddgCacheIndex qscacheIndex( void ) { return _qscacheIndex; } void qmcacheIndex( ddgCacheIndex ci ) { _qmcacheIndex = ci; } ddgCacheIndex qmcacheIndex( void ) { return _qmcacheIndex; } inline ddgTriIndex tindex(void) { return _tindex; } inline void tindex(ddgTriIndex ti) { _tindex = ti; } inline void priority(int p ) { _priority = p; } inline int priority(void) { return _priority; } inline void vis(float v ) { _vis = ddgVisState(v); } inline ddgVisState vis(void) { return _vis; } inline void priorityFactor(float pf) { _priorityFactor = pf; } inline float priorityFactor(void) { return _priorityFactor; } }; class WEXP ddgTCache : public ddgLCache { typedef ddgLCache super; public: inline void init (unsigned int size ) { super::init(size,sizeof(ddgTNode)); } inline ddgTNode* get(ddgCacheIndex n) { return (ddgTNode*) ddgLCache::get(n); } }; class WEXP ddgQNode : public ddgSNode { friend class ddgQTCache; private: ddgTriIndex _tindex; ddgTreeIndex _tree; public: inline ddgTriIndex tindex(void) { return _tindex; } inline void tindex(ddgTriIndex ti) { _tindex = ti; } inline ddgTreeIndex tree(void) { return _tree; } inline void tree(ddgTreeIndex t) { _tree = t; } }; class WEXP ddgQCache : public ddgSCache { typedef ddgSCache super; public: void init (unsigned int size, unsigned int bn, bool r = false ) { super::init(size,sizeof(ddgQNode),bn,r); } inline ddgQNode* get(unsigned short index) { return (ddgQNode*) ddgCache::get(index); } inline ddgCacheIndex insert(ddgTreeIndex t, ddgTriIndex ti, short b) { ddgCacheIndex ci = super::insert(b); // Initialize the new node. ddgQNode *qn = get(ci); qn->tree(t); qn->tindex(ti); return ci; } inline void move(ddgCacheIndex ci, short b) { super::remove(ci); super::insert(b); } }; class WEXP ddgTBinMesh { unsigned int _maxLevel; unsigned int _triNo; unsigned int _leafTriNo; unsigned int _bintreeMax; ddgTBinTree ** _bintree; ddgTCache _tcache; bool _merge; bool _splitRun; ddgQCache _qscache; ddgQCache _qmcache; unsigned int _nr; unsigned int _nc; unsigned int _minDetail; unsigned int _maxDetail; unsigned int _absMaxDetail; float _farClip; float _farClipSQ; float _nearClip; ddgHeightMap *_heightMap; float _scale; float _base; int _absMinHeight; int _absMaxHeight; int _absDiffHeight; unsigned int _triVis; unsigned int _triCount; unsigned int _priCount; unsigned int _insCount; unsigned int _remCount; unsigned int _movCount; unsigned int _visCount; unsigned int _balCount; ddgTriIndex *_indexLUT; ddgBBox3 _bbox; public: ddgTBinMesh( ddgHeightMap *i); ~ddgTBinMesh(void); ddgMSTri* stri; bool init( ddgContext *ctx ); void initNeighbours( void ); void initVertex( unsigned int level, ddgTriIndex va, ddgTriIndex v1, ddgTriIndex v0, ddgTriIndex vc); inline void incrTriVis(void) { _triVis++; } inline void decrTriVis(void) { _triVis--; } unsigned int countTriVis(void) { return _triVis; } inline unsigned int edge(ddgTriIndex i) { return stri[i].edge(); } ddgTriIndex *indexLUT(void) { return _indexLUT; } inline ddgTriIndex v0(ddgTriIndex i) { ddgAssert(i < triNo()); return stri[i].v0; } inline ddgTriIndex v1(ddgTriIndex i) { ddgAssert(i < triNo()); return stri[i].v1; } ddgTCache *tcache(void) { return &_tcache; } bool merge(void) { return _merge; } void merge(bool m) { _merge = m; } bool splitRun(void) { return _splitRun; } ddgQCache *qscache(void) { return &_qscache; } ddgQCache *qmcache(void) { return &_qmcache; } inline ddgTriIndex lookupIndex( unsigned short row, unsigned short col ) { ddgAsserts(row >= 0 && row <= ddgTBinMesh_size &&col >= 0 && col <= ddgTBinMesh_size,"Invalid coord"); ddgAssert(_indexLUT[row * (ddgTBinMesh_size+1) + col] < _triNo+2); return _indexLUT[row * (ddgTBinMesh_size+1) + col]; } ddgHeightMap *heightMap(void) { return _heightMap; } inline float wheight(short rh) { return ddgHeightMap::sconvert(rh,_base,_scale); } unsigned int minDetail( void ) { return _minDetail; } void minDetail( unsigned int d ) { _minDetail = d; } unsigned int maxDetail( void ) { return _maxDetail; } void maxDetail( unsigned int d ) { _maxDetail = d; } unsigned int absMaxDetail( void ) { return _absMaxDetail; } void absMaxDetail( unsigned int d ) { _absMaxDetail = d; } unsigned int triNo(void) { return _triNo; } unsigned int leafTriNo(void) { return _leafTriNo; } unsigned int maxLevel( void ) { return _maxLevel; } bool calculate(ddgContext *ctx); void addBinTree( ddgTBinTree *bt ); void removeBinTree( ddgTBinTree *bt ); ddgTBinTree *getBinTree( ddgTreeIndex i) { ddgAssert(i < _bintreeMax && i >= 0); return _bintree[i]; } unsigned int getBinTreeNo(void) { return _bintreeMax; } float farClip(void) { return _farClip; } float farClipSQ(void) { return _farClipSQ; } float nearClip(void) { return _nearClip; } inline void farClip(float f) { _farClip = f; _farClipSQ = f * f; } inline void nearClip(float n) { _nearClip = n; } bool mapPosToTree(float *x, float *z, ddgTBinTree **bt, unsigned int *r, unsigned int *c); float height(float x, float z); int absDiffHeight(void) { return _absDiffHeight; } int absMinHeight(void) { return _absMinHeight; } int absMaxHeight(void) { return _absMaxHeight; } ddgBBox3* bbox(void) { return &_bbox; } void triCountIncr(void) { _triCount++; } #ifdef _DEBUG void priCountIncr(void) { _priCount++; } void insCountIncr(void) { _insCount++; } void remCountIncr(void) { _remCount++; } void movCountIncr(void) { _movCount++; } void visCountIncr(void) { _visCount++; } #endif unsigned int triCount(void) { return _triCount; } unsigned int priCount(void) { return _priCount; } unsigned int insCount(void) { return _insCount; } unsigned int remCount(void) { return _remCount; } unsigned int movCount(void) { return _movCount; } unsigned int visCount(void) { return _visCount; } unsigned int balCount(void) { return _balCount; } }; #endif