⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tepatch.cpp

📁 海量地形数据漫游系统,对于OPENGL开发人员具有一定的参考
💻 CPP
📖 第 1 页 / 共 3 页
字号:
 * \sa WhichHMap, hmap, buildMap */void TePatch::generateHMapFF(WhichHMap which,                             const unsigned int seed, const int num_faults,                             const float min_delta, const float max_delta){  assert(which>=0 && which<5 && "Wrong which parameter.");  TeHeightMap* &p = (which == 4) ? hmap : buildMap[which];  if (!p)    p = new TeHeightMap;  p->setResolution(engine->getHMapResolution());  p->generate_FaultFormation(seed, num_faults, min_delta, max_delta);}//-----------------------------------------------------------------------------/** * Tries to find build map by looking in the neighbours. * * We suppose that correct info is in all of them, therefore we grab the * first one. Info propagation is assured by setBuildMap() method. * * The function returns void, the effect is visible right inside the * buildMap attribute. * * \param i Buildmap selector (TePatch::WhichHMap should be used here). * * \sa WhichHMap, buildMap, buildHMapFromBuildMaps() */void TePatch::findBuildMap(const int i){  switch (i) {    case 0: if (!buildMap[0]) {              if (neighbour[WEST] && neighbour[WEST]->getBuildMap(1)) this->setBuildMap(0, neighbour[WEST]->getBuildMap(1));              else if (neighbour[SOUTH_WEST] && neighbour[SOUTH_WEST]->getBuildMap(3)) this->setBuildMap(0, neighbour[SOUTH_WEST]->getBuildMap(3));              else if (neighbour[SOUTH] && neighbour[SOUTH]->getBuildMap(2)) this->setBuildMap(0, neighbour[SOUTH]->getBuildMap(2));            }            break;    case 1: if (!buildMap[1]) {              if (neighbour[SOUTH] && neighbour[SOUTH]->getBuildMap(3)) this->setBuildMap(1, neighbour[SOUTH]->getBuildMap(3));              else if (neighbour[SOUTH_EAST] && neighbour[SOUTH_EAST]->getBuildMap(2)) this->setBuildMap(1, neighbour[SOUTH_EAST]->getBuildMap(2));              else if (neighbour[EAST] && neighbour[EAST]->getBuildMap(0)) this->setBuildMap(1, neighbour[EAST]->getBuildMap(0));            }            break;    case 2: if (!buildMap[2]) {              if (neighbour[WEST] && neighbour[WEST]->getBuildMap(3)) this->setBuildMap(2, neighbour[WEST]->getBuildMap(3));              else if (neighbour[NORTH_WEST] && neighbour[NORTH_WEST]->getBuildMap(1)) this->setBuildMap(2, neighbour[NORTH_WEST]->getBuildMap(1));              else if (neighbour[NORTH] && neighbour[NORTH]->getBuildMap(0)) this->setBuildMap(2, neighbour[NORTH]->getBuildMap(0));            }            break;    case 3: if (!buildMap[3]) {              if (neighbour[NORTH] && neighbour[NORTH]->getBuildMap(1)) this->setBuildMap(3, neighbour[NORTH]->getBuildMap(1));              else if (neighbour[NORTH_EAST] && neighbour[NORTH_EAST]->getBuildMap(0)) this->setBuildMap(3, neighbour[NORTH_EAST]->getBuildMap(0));              else if (neighbour[EAST] && neighbour[EAST]->getBuildMap(2)) this->setBuildMap(3, neighbour[EAST]->getBuildMap(2));            }            break;  }}//-----------------------------------------------------------------------------/** * High-level function that prepares all build maps. * * Tries to find build maps in the neighbours. If map is not found, asks * engine to generate new one. * * \sa buildMap, TeEngine::generateHMap(), buildHMapFromBuildMaps() */void TePatch::prepareBuildMaps(){  for (int i=0; i<4; i++) {    this->findBuildMap(i);    if (!buildMap[i]) {      engine->faultFormation.seed = (unsigned int)time(NULL)+(rand()%10000);      this->setBuildMap(i, engine->generateHMap(engine->getBuildMapResolution()));    }  }}//-----------------------------------------------------------------------------/** * Computes patch height map from four build maps. * * All build maps have to be set before calling this method. * * \sa buildMap, setBuildMap() * * \todo More detailed documentation. */void TePatch::buildHMapFromBuildMaps(){  if (!buildMap[0] || !buildMap[1] || !buildMap[2] || !buildMap[3]) {    SoDebugError::post("TePatch::buildHMapFromBuildMaps",                       "Not all build maps were set. Can not build HeightMap.");    return;  }  SbVec2s h_res = engine->getHMapResolution();      // height map resolution  SbVec2s b_res = engine->getBuildMapResolution();  // build map resolution  assert((buildMap[0]->getResolution() == b_res) && (buildMap[1]->getResolution() == b_res) &&         (buildMap[2]->getResolution() == b_res) && (buildMap[3]->getResolution() == b_res) &&         "buildMaps resolutions are not the same.");  int shift = b_res[0] - h_res[0];  if (hmap)    delete hmap;  hmap = new TeHeightMap(h_res);  float *dest = hmap->startEditing();  const float *m1 = &buildMap[0]->getValues()[b_res[0]*(h_res[1]-1) + h_res[0]-1];  const float *m2 = &buildMap[1]->getValues()[b_res[0]*(h_res[1]-1)];  const float *m3 = &buildMap[2]->getValues()[h_res[0]-1];  const float *m4 = &buildMap[3]->getValues()[0];  int x,y;  int index;  float qf; // koeficient "going forward" - increasing from 0 on the first row to 1 on the last row  float qb; // koeficient "going backward" - decreasing from 1 on the first row to 0 on the last row  float q1; // koeficient decreasing from qb to 0 on each row  float q2; // koeficient increasing from 0 to qb on each row  float q3; // koeficient decreasing from qf to 0 on each row  float q4; // koeficient increasing from 0 to qf on each row  float dy = 1.f/float(h_res[1]-1);  float dxf,dxb; // size of q1,q2,q3, and q4 step  qf = 0.f;  qb = 1.f;  index = 0;  for (y=0; y<h_res[1]; y++) {    q1 = qb;    q2 = 0.f;    q3 = qf;    q4 = 0.f;    dxf = qf / (h_res[0]-1);    dxb = qb / (h_res[0]-1);    for (x=0; x<h_res[0]; x++) {      *dest++ = (*m1++)*q1 + (*m2++)*q2 + (*m3++)*q3 + (*m4++)*q4;      q1 -= dxb;      q2 += dxb;      q3 -= dxf;      q4 += dxf;    }    m1 += shift;    m2 += shift;    m3 += shift;    m4 += shift;    qf += dy;    qb -= dy;  }  hmap->finishEditing();}//-----------------------------------------------------------------------------/** * Validates seamMap pointer in desired direction if possible. * * Tries to look for the desired map in the neighbours. If not found, tries * to compute it and propagate the info to all interested neighbours. This * assures that each seam map will be computed only once. User does not * need to worry about the way how the data are obtained. This function * says if the private seam map pointer is valid or not. * * Note that properly set hmap attributes of all necessary neighbours are * needed to succesfully complete this task. * * \param which Seam map selector. * \return TRUE if the seam map pointer is valid and the graph can be created. * * \sa seamMap, getSeamMap() */SbBool TePatch::generateSeamMap(const Direction which){  // map already set  if (seamMap[which]) return TRUE;  // do we have all neighbours and hmaps ready?  if (!this->hmap) return FALSE;  if (which == SOUTH || which == WEST || which == EAST || which == NORTH) {    if (!neighbour[which]) return FALSE;    else if (!neighbour[which]->hmap) return FALSE;  }  else {    if (!neighbour[which]) return FALSE;    else if (!neighbour[which]->hmap) return FALSE;    switch (which) {      case SOUTH_WEST: if (!neighbour[SOUTH] || !neighbour[WEST]) return FALSE;                       else if (!neighbour[SOUTH]->hmap || !neighbour[WEST]->hmap) return FALSE;                       break;      case SOUTH_EAST: if (!neighbour[SOUTH] || !neighbour[EAST]) return FALSE;                       else if (!neighbour[SOUTH]->hmap || !neighbour[EAST]->hmap) return FALSE;                       break;      case NORTH_WEST: if (!neighbour[NORTH] || !neighbour[WEST]) return FALSE;                       else if (!neighbour[NORTH]->hmap || !neighbour[WEST]->hmap) return FALSE;                       break;      case NORTH_EAST: if (!neighbour[NORTH] || !neighbour[EAST]) return FALSE;                       else if (!neighbour[NORTH]->hmap || !neighbour[EAST]->hmap) return FALSE;                       break;    }  }  // if yes, try to look for the map in one of the neighbours (we rely on  // correct info to be in all of them)  TeHeightMap *tmp = neighbour[which]->seamMap[getOppositeDirection(which)];  if (tmp) {    seamMap[which] = tmp;    return TRUE;  }  int x, y = 0;  int resx = engine->getHMapResolution()[0];  int resy = engine->getHMapResolution()[1];  // if not found, compute map from neighbour data and update neighbour's  // seamMap-pointer  switch (which) {    case SOUTH_WEST: tmp = new TeHeightMap(5, 5);                     for (y=2; y<5; y++)                       for (x=0; x<3; x++)                         tmp->setValue(x, y, neighbour[WEST]->hmap->getValue(resx-3+x, y-2));                     for (y=2; y<5; y++)                       for (x=3; x<5; x++)                         tmp->setValue(x, y, this->hmap->getValue(x-2, y-2));                     for (y=0; y<2; y++)                       for (x=0; x<3; x++)                         tmp->setValue(x, y, neighbour[SOUTH_WEST]->hmap->getValue(resx-3+x, resy-3+y));                     for (y=0; y<2; y++)                       for (x=3; x<5; x++)                         tmp->setValue(x, y, neighbour[SOUTH]->hmap->getValue(x-2, resy-3+y));                     neighbour[WEST]->setSeamMap(SOUTH_EAST, tmp);                     neighbour[SOUTH]->setSeamMap(NORTH_WEST, tmp);                     break;    case SOUTH_EAST: tmp = new TeHeightMap(5, 5);                     for (y=2; y<5; y++)                       for (x=0; x<3; x++)                         tmp->setValue(x, y, this->hmap->getValue(resx-3+x, y-2));                     for (y=2; y<5; y++)                       for (x=3; x<5; x++)                         tmp->setValue(x, y, neighbour[EAST]->hmap->getValue(x-2, y-2));                     for (y=0; y<2; y++)                       for (x=0; x<3; x++)                         tmp->setValue(x, y, neighbour[SOUTH]->hmap->getValue(resx-3+x, resy-3+y));                     for (y=0; y<2; y++)                       for (x=3; x<5; x++)                         tmp->setValue(x, y, neighbour[SOUTH_EAST]->hmap->getValue(x-2, resy-3+y));                     neighbour[EAST]->setSeamMap(SOUTH_WEST, tmp);                     neighbour[SOUTH]->setSeamMap(NORTH_EAST, tmp);                     break;    case NORTH_WEST: tmp = new TeHeightMap(5, 5);                     for (y=2; y<5; y++)                       for (x=0; x<3; x++)                         tmp->setValue(x, y, neighbour[NORTH_WEST]->hmap->getValue(resx-3+x, y-2));                     for (y=2; y<5; y++)                       for (x=3; x<5; x++)                         tmp->setValue(x, y, neighbour[NORTH]->hmap->getValue(x-2, y-2));                     for (y=0; y<2; y++)                       for (x=0; x<3; x++)                         tmp->setValue(x, y, neighbour[WEST]->hmap->getValue(resx-3+x, resy-3+y));                     for (y=0; y<2; y++)                       for (x=3; x<5; x++)                         tmp->setValue(x, y, this->hmap->getValue(x-2, resy-3+y));                     neighbour[NORTH]->setSeamMap(SOUTH_WEST, tmp);                     neighbour[WEST]->setSeamMap(NORTH_EAST, tmp);                     break;    case NORTH_EAST: tmp = new TeHeightMap(5, 5);                     for (y=2; y<5; y++)                       for (x=0; x<3; x++)                         tmp->setValue(x, y, neighbour[NORTH]->hmap->getValue(resx-3+x, y-2));                     for (y=2; y<5; y++)                       for (x=3; x<5; x++)                         tmp->setValue(x, y, neighbour[NORTH_EAST]->hmap->getValue(x-2, y-2));                     for (y=0; y<2; y++)                       for (x=0; x<3; x++)                         tmp->setValue(x, y, this->hmap->getValue(resx-3+x, resy-3+y));                     for (y=0; y<2; y++)                       for (x=3; x<5; x++)                         tmp->setValue(x, y, neighbour[EAST]->hmap->getValue(x-2, resy-3+y));                     neighbour[NORTH]->setSeamMap(SOUTH_EAST, tmp);                     neighbour[EAST]->setSeamMap(NORTH_WEST, tmp);                     break;         case SOUTH: tmp = new TeHeightMap(SbVec2s(engine->getHMapResolution()[0], 5));                     tmp->copyFrom(neighbour[which]->hmap,                                   SbVec2s(0, engine->getHMapResolution()[1]-3),                                   SbVec2s(engine->getHMapResolution()[0], 3));                     tmp->copyFrom(this->hmap,                                   SbVec2s(0, 1),                                   SbVec2s(engine->getHMapResolution()[0], 2),                                   SbVec2s(0, 3));                     break;          case WEST: tmp = new TeHeightMap(SbVec2s(5, engine->getHMapResolution()[1]));                     tmp->copyFrom(neighbour[which]->hmap,                                   SbVec2s(engine->getHMapResolution()[0]-3, 0),                                   SbVec2s(3, engine->getHMapResolution()[1]));                     tmp->copyFrom(this->hmap,                                   SbVec2s(1, 0),                                   SbVec2s(2, engine->getHMapResolution()[1]),                                   SbVec2s(3, 0));                     break;          case EAST: tmp = new TeHeightMap(SbVec2s(5, engine->getHMapResolution()[1]));                     tmp->copyFrom(this->hmap,                                   SbVec2s(engine->getHMapResolution()[0]-3, 0),                                   SbVec2s(3, engine->getHMapResolution()[1]));                     tmp->copyFrom(neighbour[which]->hmap,                                   SbVec2s(1, 0),                                   SbVec2s(2, engine->getHMapResolution()[1]),                                   SbVec2s(3, 0));                     break;         case NORTH: tmp = new TeHeightMap(SbVec2s(engine->getHMapResolution()[0], 5));                     tmp->copyFrom(this->hmap,                                   SbVec2s(0, engine->getHMapResolution()[1]-3),                                   SbVec2s(engine->getHMapResolution()[0], 3));                     tmp->copyFrom( neighbour[which]->hmap,                                   SbVec2s(0, 1),                                   SbVec2s(engine->getHMapResolution()[0], 2),                                   SbVec2s(0, 3));                     break;  }  // always  this->setSeamMap(which, tmp);  neighbour[which]->setSeamMap(Direction(getOppositeDirection(which)), tmp);  // more inside the switch above  return TRUE;}//-----------------------------------------------------------------------------/** * Calculates normal at the specified point in the heightmap. * * \param map Pointer to the height map. * \param x X-coordinate of the point. * \param y Y-coordinate of the point. * \param sx ??? * \param sy ??? * \return Normal at the specified point (\a x, \a y). * * \todo More detailed documentation. Parameters sx, sy ??? */SbVec3f TePatch::calculateNormal(const TeHeightMap *map, const int x,                                 const int y, const float sx, const float sy){  float dx,dy;  int resx,resy;  map->getResolution(resx,resy);  const float *values = map->getValues();  // 趆el v ose X  if (x>=1 && x<=resx-2)    // V齪o鑕t ze dvou sousedn韈h bod

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -