📄 tepatch.cpp
字号:
//##################################################//# $Id: TePatch.cpp 28 2005-08-28 10:37:47Z peciva $/*****************************************************************************\ * * TePatch.cpp * * 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. *\*****************************************************************************/#include <Inventor/nodes/SoCoordinate3.h>#include <Inventor/nodes/SoIndexedTriangleStripSet.h>#include <Inventor/nodes/SoMaterial.h>#include <Inventor/nodes/SoMaterialBinding.h>#include <Inventor/nodes/SoNormal.h>#include <Inventor/nodes/SoNormalBinding.h>#include <Inventor/nodes/SoSeparator.h>#include <Inventor/nodes/SoTranslation.h>#include <Inventor/errors/SoDebugError.h>#include <ctime>#include "TePatch.h"#include "TeHeightMap.h"#include "TeEngine.h"//-----------------------------------------------------------------------------/** * Simple default constructor. * * It does not specify the engine that manages this patch and therefore is * private and shoul be \b never called. Documented only to explain the * reason. */TePatch::TePatch(){ assert(0 && "Default constructor of TePatch is private and should be never called.");}//-----------------------------------------------------------------------------/** * Constructor. * * \param aengine Engine in which patch hierarchy this patch belongs. */TePatch::TePatch(TeEngine *aengine) : hmap(NULL), engine(aengine), parent(NULL), graph(NULL){ assert(engine && "Engine parameter can not be NULL."); int i; for (i=0;i<8;i++) seamMap[i] = NULL; for (i=0;i<4;i++) buildMap[i] = NULL; for (i=0;i<4;i++) detail[i] = NULL; for (i=0;i<8;i++) neighbour[i] = NULL; for (i=0;i<8;i++) seamGraph[i] = NULL;}//-----------------------------------------------------------------------------/** * Destructor. * * Releases memory. * * \todo Cancel scheduled tasks at engine. ??? */TePatch::~TePatch(){ int i; // TODO: cancel scheduled tasks at engine // delete more detail patches for (i=0; i<4; i++) delete detail[i]; // delete buildMaps if (!neighbour[SOUTH_WEST] && !neighbour[SOUTH] && !neighbour[WEST]) delete buildMap[SOUTH_WEST]; if (!neighbour[SOUTH_EAST] && !neighbour[SOUTH] && !neighbour[EAST]) delete buildMap[SOUTH_EAST]; if (!neighbour[NORTH_WEST] && !neighbour[NORTH] && !neighbour[WEST]) delete buildMap[NORTH_WEST]; if (!neighbour[NORTH_EAST] && !neighbour[NORTH] && !neighbour[EAST]) delete buildMap[NORTH_EAST]; // release heightmap delete hmap; // release seam height maps for (i=0; i<8; i++) delete seamMap[i]; // release scene graphs if (graph) graph->unref(); for (i=0; i<8; i++) if (seamGraph[i]) seamGraph[i]->unref(); // remove self from neighbours references for (i=0; i<8; i++) if (neighbour[i]) { neighbour[i]->neighbour[getOppositeDirection(i)] = NULL; } // remove parent reference if (parent) { // this is always true if we are not root node for (i=0; i<4; i++) { if (parent->detail[i] == this) { parent->detail[i] = NULL; break; } } assert(i<4 && "This patch was not found in the parent patch!"); } else if (engine->getRootPatch() == this) engine->onRootDestroy();}//-----------------------------------------------------------------------------/** * Private attribute accessor. * * \return Const pointer to the patch heightmap. * * \sa hmap, setHMap() */const TeHeightMap* TePatch::getHMap() const{ return hmap;}//-----------------------------------------------------------------------------/** * Private attribute accessor. * * \return Pointer to the patch heightmap. * * \sa hmap, setHMap() */TeHeightMap* TePatch::getHMap(){ return hmap;}//-----------------------------------------------------------------------------/** * Sets private hmap attribute. * * This function checks if the resolution of the heightmap \a hmap is the same * as the one set in the engine. If it is not so, nothing happens and the * warning is post. If there is already some heightmap set, it is deleted. * * \param hmap Pointer to the heightmap. * * \todo When the heightmap is being deleted, we probably should unref all * scene graphs and delete the seam maps too. * * \sa hmap, getHMap() */void TePatch::setHMap(TeHeightMap *hmap){ if (hmap->getResolution() != engine->getHMapResolution()) { SoDebugError::post("TePatch:setHMap", "HMap resolution must be the same as the one set in TeEngine constructor,\n" "that usually defaults to 65x65. The problem is handled by ignoring of this call."); return; } if (this->hmap) delete this->hmap; this->hmap = hmap;}//-----------------------------------------------------------------------------/** * Private attribute accessor. * * \param which Seam map selector. * \return Const pointer to the specified seam map. * * \sa seamMap, setSeamMap() */const TeHeightMap* TePatch::getSeamMap(const Direction which) const{ assert(which>=0 && which<8 && "Wrong which parameter."); return seamMap[which];}//-----------------------------------------------------------------------------/** * Private attribute accessor. * * \param which Seam map selector. * \return Pointer to the specified seam map. * * \sa seamMap, setSeamMap() */TeHeightMap* TePatch::getSeamMap(const Direction which){ assert(which>=0 && which<8 && "Wrong which parameter."); return seamMap[which];}//-----------------------------------------------------------------------------/** * Sets private seam map attribute. * * This function checks if the resolution of the heightmap \a map corresponds * with the one set in the engine and the selected seam. If it is not so, * nothing happens and the warning is post. * * \param which Seam map selector. * \param map Pointer to the heightmap. * * \sa seamMap, getSeamMap() * * \todo If there is already some seam map set, it should be deleted. It is * similar to the TePatch::setHMap() function. */void TePatch::setSeamMap(const Direction which, TeHeightMap *map){ assert(which>=0 && which<8 && "Wrong which parameter."); int rx,ry; map->getResolution(rx,ry); if (which < 4) { if (rx != 5 || ry != 5) goto bad_res; } else { const SbVec2s &res = engine->getHMapResolution(); if (which == WEST || which == EAST) { if (rx != 5 || ry != res[1]) goto bad_res; } else { if (ry != 5 || rx != res[0]) goto bad_res; } } seamMap[which] = map; return;bad_res: SoDebugError::post("TePatch:setSeamMap", "Wrong seam height maps resolution. It must be [5,TeEngine::\n" "getHMapResolution()[1], or [TeEngine::getHMapResolution()[0],5],\n" "or [5,5], depending of which parameter. Setting of the height map is ignored.");}//-----------------------------------------------------------------------------/** * Private attribute accessor. * * \return Pointer to the attached engine. * * \sa engine, setEngine() */TeEngine* TePatch::getEngine() const{ return engine;}//-----------------------------------------------------------------------------/** * Should set the private engine attribute. * * This function is not implemented yet, it looks like we don't need it... * * \sa engine, getEngine() * * \todo Not implemented yet. Consider removing it completely, because its * work is done in constructor and changing attached engines at * run-time will be strange hack. */void TePatch::setEngine(){ assert(0 && "Not implemented yet.");}//-----------------------------------------------------------------------------/** * Private attribute accessor. * * \return Rectangle area occupied by the scene graph. * * \sa area */const SbBox2f& TePatch::getArea() const{ return area;}//-----------------------------------------------------------------------------/** * Gets level of the patch in the hierarchy. * * \return Patch level in the hierarchy. * * \todo More detailed documentation. */int TePatch::getLevel() const{ if (parent) return parent->getLevel() - 1; else if (engine->getRootPatch() == this) return engine->getRootLevel(); else { SoDebugError::post("TePatch::getLevel", "It is forbidden to call getLevel() until TePatch is made part of the\n" "TePatch hierarchy headed by an TeEngine."); return 0; }}//-----------------------------------------------------------------------------/** * Private attribute accessor. * * \return Parent patch in the hierarchy. * * \sa parent * * \todo More detailed documentation. */TePatch* TePatch::getParent() const{ return parent;}//-----------------------------------------------------------------------------/** * Documentation not available. * * \todo More detailed documentation. */TePatch* TePatch::getPatchHierarch(const SbVec2f &pos, const int level, PatchMissedPolicy policy){ return getPatchHierarchRelative(pos, level - this->getLevel(), policy);}//-----------------------------------------------------------------------------/** * Documentation not available. * * \todo More detailed documentation. */TePatch* TePatch::getPatchHierarchRelative(const SbVec2f &pos, const int relativeLevel, PatchMissedPolicy policy){ // policy works like this: // - DONT_CREATE - return NULL // - CREATE - create all necesary patches // - LOWER_DETAIL - 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. // handle requests for higher level if (relativeLevel > 0) if (parent) return parent->getPatchHierarchRelative(pos, relativeLevel-1, policy); else { if (!engine) { SoDebugError::post("TePatch::getPatchHierarchRelative", "The patch must be appended to the TePatch tree\n" "before the call of this function."); return NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -