📄 tepatch.h
字号:
//##################################################//# $Id: TePatch.h 28 2005-08-28 10:37:47Z peciva $#ifndef TE_PATCH_H#define TE_PATCH_H/*****************************************************************************\ * * TePatch.h * * TePatch - terrain patch class * * Author: PCJohn (peciva AT fit.vutbr.cz) * Contributors: Martin Havl龛ek (xhavli15 AT stud.fit.vutbr.cz) * * ---------------------------------------------------------------------------- * * THIS SOFTWARE IS NOT COPYRIGHTED * * This source code is offered for use in the public domain. * You may use, modify or distribute it freely. * * This source code is distributed in the hope that it will be useful but * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY * DISCLAIMED. This includes but is not limited to warranties of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * If you find the source code useful, authors will kindly welcome * if you give them credit and keep their names with their source code. *\*****************************************************************************//** * TePatch class header file. * * \file TePatch.h * \author PCJohn (peciva AT fit.vutbr.cz) * \author Martin Havl龛ek (martyn AT seznam.cz) */#include <Inventor/SbLinear.h>#include <Inventor/SbBox2f.h>class SoSeparator;class TeHeightMap;class TeEngine;/** * Single rectangular terrain patch. * * This class is used as a representation of the terrain patches database * needed by our engine. It also implements the algorithm that computes * final patch heihtmap hmap using 4 so-called build maps. This method * produces continuous terrain generated from separatedly computed patches. * * The class provides scene graph generation too. Using getPatchGraph() * and getSeamGraph() methods the landscape can be easily rendered. * These methods use caching, so scene graphs are generated only once and * are ready to use quickly next time they are needed. * * Each patch has to be managed by the TeEngine object and is strongly * recommended to use TeEngine::getPatch() method instead of hacking the * patch hierarchy in another way. * * \todo Detailed explanation of the patch hierarchy structure. */class TePatch { friend class TeEngine;public: // Direction mapping to the axis: // // N +y // ^ ^ // | | // W<-- -->E corresponds with -x<-- -->+x // | | // \/ \/ // S -y // // axis z is going "up" /** Enumerates all 8 possible directions, ASCII-art picture of axis mapping is in the TePatch.h source. */ enum Direction { SOUTH_WEST = 0, /**< Axis mapping: -x, -y */ SOUTH_EAST = 1, /**< Axis mapping: +x, -y */ NORTH_WEST = 2, /**< Axis mapping: -x, +y */ NORTH_EAST = 3, /**< Axis mapping: +x, +y */ SOUTH = 4, /**< Axis mapping: 0, -y */ WEST = 5, /**< Axis mapping: -x, 0 */ EAST = 6, /**< Axis mapping: +x, 0 */ NORTH = 7 /**< Axis mapping: 0, +y */ }; /** Determines what to do when desired patch is not found in the patch-tree. */ enum PatchMissedPolicy { DONT_CREATE, /**< Do not create a new one, we're just checking it, return NULL. */ CREATE, /**< We need it, create a new one and all necessary patches too. */ LOWER_DETAIL /**< We need it, return patch matching pos, but possible with lower detail than specified; if pos falls outside the current patch root, new nodes are appended to the top of patch tree to match pos. */ }; // WhichMap to index mapping: // // y ^ y ^ // | | // | NW NE | 2 3 // | corresponds with indices | // | SW SE | 0 1 // --------> x -------> x // /** Enumeration used to determine which heightmap should be used at the moment, ASCII-art picture is in the TePatch.h source. */ enum WhichHMap { HMAP_PATCH = 4, /**< Patch heightmap. */ HMAP_SOUTH_WEST = 0, /**< South-west buildmap. */ HMAP_SOUTH_EAST = 1, /**< South-east buildmap. */ HMAP_NORTH_WEST = 2, /**< North-west buildmap. */ HMAP_NORTH_EAST = 3 /**< South-east buildmap. */ }; static inline int getOppositeDirection(const int d); static inline Direction getDirectionXFromVec(const SbVec2f &vec);private: /** Patch area. Defines its rectangle on the surface in the world-space coordinates. \sa getArea() */ SbBox2f area; /** Pointer to the patch height map. This map will be used when creating scene graph. \sa getHMap(), setHMap(), buildHMapFromBuildMaps() */ TeHeightMap *hmap; /** Pointers to all 8 possible seam height maps. These maps can be computed when all necessary neighbours' maps are available. These are used when creating seam scene graph. \sa getSeamMap(), setSeamMap(), generateSeamMap() */ TeHeightMap* seamMap[8]; /** Pointers to 4 build-maps used to create final heightmap. \sa getBuildMap(), setBuildMap(), prepareBuildMaps(), buildHMapFromBuildMaps() */ TeHeightMap* buildMap[4]; /** Pointer to the engine that manages this patch. \sa getEngine(), setEngine() */ TeEngine *engine; /** Pointer to the parent patch in the patch hierarchy. \todo More detailed documentation. */ TePatch *parent; /** Pointers to the detail patches. \todo More detailed documentation. */ TePatch* detail[4]; /** Pointers to all 8 possible neighbour of this patch. These are used to obtain seam maps and to find already existing build maps. */ TePatch* neighbour[8]; /** Patch scene graph cache. \sa getPatchGraph() */ SoSeparator *graph; /** Seam graphs cache. \sa getSeamGraph() */ SoSeparator* seamGraph[8]; TePatch* getPatchHierarch(const SbVec2f &pos, const int level, PatchMissedPolicy policy = CREATE); TePatch* getPatchHierarchRelative(const SbVec2f &pos, const int relativeLevel, PatchMissedPolicy policy = CREATE); void updateNeighbours(); static SbVec3f calculateNormal(const TeHeightMap *map, const int x, const int y, const float sx, const float sy); static unsigned short selectMaterial(float value); static SoSeparator* generateGraphFromSubMap(const TeHeightMap *map, const SbVec2s &min, const SbVec2s &max, const SbBox2f &area); SoSeparator* generateGraph(); SoSeparator* generatePatchGraph(); SoSeparator* generateSeamGraph(const Direction which); TePatch();public: TePatch(TeEngine *engine); ~TePatch(); const TeHeightMap* getHMap() const; TeHeightMap* getHMap(); void setHMap(TeHeightMap *hmap); const TeHeightMap* getSeamMap(const Direction which) const; TeHeightMap* getSeamMap(const Direction which); void setSeamMap(const Direction which, TeHeightMap *map); SbBool generateSeamMap(const Direction which); TeEngine* getEngine() const; void setEngine(); // read-only attributes const SbBox2f& getArea() const; int getLevel() const; TePatch* getParent() const; TePatch* getPatch(const SbVec2f &pos, const int level, PatchMissedPolicy policy = CREATE); TePatch* getPatchRelative(const SbVec2f &pos, const int relativeLevel, PatchMissedPolicy policy = CREATE); TePatch* getDetail(const Direction which); void setDetail(const Direction which, TePatch *patch); void removeDetail(TePatch *patch); Direction getDirectionWithinParent() const; Direction getDetailDirection(const SbVec2f &point) const; const TeHeightMap* getBuildMap(const int i) const; TeHeightMap* getBuildMap(const int i); void setBuildMap(const int i, TeHeightMap *hmap); void setBuildMaps(TeHeightMap *nw, TeHeightMap *ne, TeHeightMap *sw, TeHeightMap *se); void findBuildMap(const int i); void prepareBuildMaps(); void buildHMapFromBuildMaps(); void generateHMapFF(WhichHMap which, const unsigned int seed, const int num_faults, const float min_delta, const float max_delta); // internal functions void makeRoot(const SbBox2f &area, TeEngine *engine); // high-level graph requests SoSeparator *getGraph(); // raw SoSeparator *getPatchGraph(); SoSeparator *getSeamGraph(const Direction which);};/** * Computes opposite direction to the one in \a d parameter. * * When called with NORTH as an argument, returns SOUTH, when called with * SOUTH_EAST returns NORTH_WEST etc., complies with TePatch::Direction enum * values. * * \param d Given direction. * \return Opposite direction to \a d. */inline int TePatch::getOppositeDirection(const int d){ if (d<4) return 3-d; else return 11-d;}/** * Computes the direction from the given vector. * * \param vec Given vector. * \return Direction the vector is pointing. */inline TePatch::Direction TePatch::getDirectionXFromVec(const SbVec2f &vec){ if (vec[1] < 0.f) if (vec[0] < 0.f) return SOUTH_WEST; else return SOUTH_EAST; else if (vec[0] < 0.f) return NORTH_WEST; else return NORTH_EAST;}#endif /* TE_PATCH_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -