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

📄 teheightmap.cpp

📁 海量地形数据漫游系统,对于OPENGL开发人员具有一定的参考
💻 CPP
📖 第 1 页 / 共 3 页
字号:
}//----------------------------------------------------------------------------/** * Two heightmaps specified-values subtracting. * * Values from source heightmap will be subtracted from "this" heightmap * according to a "blend-rate" \a rate. This should be greater than 0.0f. All * source values are multiplied by \a rate before subtracting from target * values. * * Selected source area is specified by its top-left corner \a sorogin and its * \a size. Target area is specified by its top-left corner \a dorogin. * * \param hmap Pointer to the source heightmap. * \param sorigin Top-left corner of selected area in source heightmap. * \param size Size of selected area. * \param dorigin Top-left corner of area in target heightmap. * \param rate Blend-rate showing how much of source heightmap to be subtracted *             from the target. */void TeHeightMap::subtractFrom(const TeHeightMap *hmap, const SbVec2s &sorigin,                               const SbVec2s &size, const SbVec2s &dorigin,                               const float rate){  if (sorigin[0]<hmap->resx && sorigin[1]<hmap->resy && size[0]>0 && size[1]>0 && rate>0) {    // dimension-check in source    int sizex = ((sorigin[0]+size[0]<=hmap->resx) ? size[0] : hmap->resx-sorigin[0] );    int sizey = ((sorigin[1]+size[1]<=hmap->resy) ? size[1] : hmap->resy-sorigin[1] );        // dimension-check in target    if (sizex>this->resx-dorigin[0]) sizex = this->resx-dorigin[0];    if (sizey>this->resy-dorigin[1]) sizey = this->resy-dorigin[1];    if (sizex>0 && sizey>0) {      // adding      for (int y=0; y<sizey; y++) {        for (int x=0; x<sizex; x++) {          values[(y*this->resx)+(dorigin[1]*this->resx)+dorigin[0]+x] -=            hmap->values[(y*hmap->resx)+(sorigin[1]*hmap->resx)+sorigin[0]+x]*rate;        }      }      resetFlags();    }  }}//----------------------------------------------------------------------------/** * Subtracts constant from all heightmap values. * * Same as shift(-value). * * \param value Constant to be subtracted from all heightmap values. * * \sa shift() */void TeHeightMap::subtractAll(const float value){  shift(-value);}//----------------------------------------------------------------------------/** * Two heightmaps all-values multiplying. * * Values in target heightmap will be multiplied by values in the source * heightmap according to a "blend-rate" \a rate. This should be greater than * 0.0f. All source values are multiplied by \a rate before multiplying the * target values. * * All possible values will be multiplied, both source and target top-left * corners are in (0,0) coordinates. * * \param hmap Pointer to the source heightmap. * \param rate Blend-rate showing how much of source heightmap to be *             multiplied with. */void TeHeightMap::multiplyFrom(const TeHeightMap *hmap, const float rate){  multiplyFrom(hmap, SbVec2s(0,0), getResolution(), SbVec2s(0,0), rate);}//----------------------------------------------------------------------------/** * Two heightmaps specified-values multiplying. * * Values in target heightmap will be multiplied by values in the source * heightmap according to a "blend-rate" \a rate. This should be greater than * 0.0f. All source values are multiplied by \a rate before multiplying the * target values. * * Selected source area is specified by its top-left corner \a sorogin and its * \a size. Target area is specified by its top-left corner \a dorogin. * * \param hmap Pointer to the source heightmap. * \param sorigin Top-left corner of selected area in source heightmap. * \param size Size of selected area. * \param dorigin Top-left corner of area in target heightmap. * \param rate Blend-rate showing how much of source heightmap to be *             multiplied with. */void TeHeightMap::multiplyFrom(const TeHeightMap *hmap, const SbVec2s &sorigin,                               const SbVec2s &size, const SbVec2s &dorigin,                               const float rate){  if (sorigin[0]<hmap->resx && sorigin[1]<hmap->resy && size[0]>0 && size[1]>0 && rate>0) {    // dimension-check in source    int sizex = ((sorigin[0]+size[0]<=hmap->resx) ? size[0] : hmap->resx-sorigin[0] );    int sizey = ((sorigin[1]+size[1]<=hmap->resy) ? size[1] : hmap->resy-sorigin[1] );    // dimension-check in target    if (sizex>this->resx-dorigin[0]) sizex = this->resx-dorigin[0];    if (sizey>this->resy-dorigin[1]) sizey = this->resy-dorigin[1];    if (sizex>0 && sizey>0) {      // adding      for (int y=0; y<sizey; y++) {        for (int x=0; x<sizex; x++) {          values[(y*this->resx)+(dorigin[1]*this->resx)+dorigin[0]+x] *=            hmap->values[(y*hmap->resx)+(sorigin[1]*hmap->resx)+sorigin[0]+x]*rate;        }      }      resetFlags();    }  }}//----------------------------------------------------------------------------/** * Multiplies all heightmap values by a constant. * * \param value All heightmap values will be multiplied by this constant. */void TeHeightMap::multiplyAll(const float value){  for (int i=0; i<resx*resy; i++)    values[i] *= value;  resetFlags();}//----------------------------------------------------------------------------/** * Linear filtering of heightmap values * * In one cycle, the filter goes through the data in all rows and columns * in both directions and changes the values according to the neighbours and * filtration coefficient \a coef. This value should be between * (0.0f-1.0f). When large - smaller changes, when small - huge filtering will * be done. This cycle will be done \a times -times. * * \param coef Filtration coefficient, when large - little change, when small -               huge filtering. * \param times Filtering will be done times -times * * \sa TeLinearFilter */void TeHeightMap::filter_Linear(const float coef, const int times){  if (coef<1.0 && coef>0.0) {    int x = 0;    int y = 0;    for (int i=0; i<times; i++) {      // rows      for (y=0; y<resy; y++) {        // from left to right        x = 1;        while (x < resx-1) {          values[(y*resx)+x] = values[(y*resx)+x-1]*(1-coef)+values[(y*resx)+x]*coef;          x++;        }        // from right to left        x = resx-2;        while (x > -1) {          values[(y*resx)+x] = values[(y*resx)+x+1]*(1-coef)+values[(y*resx)+x]*coef;          x--;        }      }      // columns      for(x=0; x<resx; x++) {        // columns top to bottom        y = 1;        while (y < resy) {          values[(y*resx)+x] = values[((y-1)*resx)+x]*(1-coef)+values[(y*resx)+x]*coef;          y++;        }        // columns bottom to top        y = resy-2;        while (y > -1) {          values[(y*resx)+x] = values[((y+1)*resx)+x]*(1-coef)+values[(y*resx)+x]*coef;          y--;        }      }    } // for    resetFlags();  } // if}//----------------------------------------------------------------------------/** * Generates mask that can used when building heightmap from 4 others. * * Heightmaps have to be squares sized (2^x)+1 !!! * * \todo This method is obsolete and should be removed. */void TeHeightMap::generate_4HMOverlap_Mask(){  int size = resx; // square !!!  float step = (float)(1.0/floor(size/2));  int base = (int)(floor(size/2));  int center = base*size + base;  int idx1 = center;  int idx2 = idx1;  int idx3 = idx1;  int idx4 = idx1;  int i, j = 0;  float value;  // init  values[idx1] = 1.0;  // center cross  for (i=1; i<base; i++) {    idx1--;    idx2 -= size;    idx3++;    idx4 += size;    value = (float)(1.0 - i*step);    values[idx1] = values[idx2] = values[idx3] = values[idx4] = value;  }  // remaining values (the same for 4 quadrants do it "in parallel")  for (i=1; i<base; i++) {    for (j=1; j<base; j++) {      idx1 = center - i*size - j;      idx2 = center - i*size + j;      idx3 = center + i*size - j;      idx4 = center + i*size + j;      value = values[center+j]*values[center+i*size];      values[idx1] = values[idx2] = values[idx3] = values[idx4] = value;    }  }}//----------------------------------------------------------------------------/** * Generates heightmap values using fault-formation algorithm. * * The algorithm works as follows: * \li Two points in the heightmap are selected. These points define the fault *     vector. The selection is done randomly (the generator is initialized *     with \a seed as random seed). * \li According to current iteration number, \a min_delta and *     \a max_delta, the height of the fault is computed. * \li All values in one half-plane specified by the fault are increased *     by computed value. Rest of values is left unchanged. * \li This cycle is done \a num_faults -times. * * \param seed Random seed that defines terrain shape. * \param num_faults Number of faults to be generated (number of iterations). * \param min_delta Minimal fault height. * \param max_delta Maximal fault height. * * \sa TeFaultFormation */void TeHeightMap::generate_FaultFormation(const unsigned int seed,                                          const int num_faults,                                          const float min_delta,                                          const float max_delta){  // init  setAllValues(0);  float Delta = 0;  unsigned int Rand1X, Rand1Y, Rand2X, Rand2Y;  int FaultVectorX, FaultVectorY;  int ToPointVectorX, ToPointVectorY;  for (int i = 0; i < num_faults; i++) {    Rand1X = rand() % resx;    Rand1Y = rand() % resy;    Rand2X = rand() % resx;    Rand2Y = rand() % resy;    // fault vector    FaultVectorX = Rand2X - Rand1X;    FaultVectorY = Rand2Y - Rand1Y;    // value to be added to one side of the fault    Delta = static_cast<float>            (max_delta - ((max_delta-min_delta) * i) / num_faults);    int idx=0;    for (int y = 0; y < resy; y++) {      for (int x = 0; x < resx; x++) {        // vector to the current map position        ToPointVectorX = x - Rand1X;        ToPointVectorY = y - Rand1Y;        if ((ToPointVectorX*FaultVectorY-FaultVectorX*ToPointVectorY) > 0)          values[idx] += Delta;        idx++;      }    }  }  resetFlags();}//----------------------------------------------------------------------------// FOR DEBUGGING ONLY//----------------------------------------------------------------------------#include <cstdio>/** * Dumps itself to stdout. * * This method is meant to be for DEBUGGING only and can be removed at any * time. */void TeHeightMap::dump(){  printf("\n\n----- TeHeightMap::dump() ---------------------------------\n\n");  printf(" Width: %d\n", resx);  printf("Height: %d\n\n", resy);    printf("Memory: %d B\n\n", sizeof(TeHeightMap)+(resx*resy*sizeof(float)));  printf("    minValue: %6.2f (flag: %d)\n", minValue, flags.minUpdated);  printf("    maxValue: %6.2f (flag: %d)\n", maxValue, flags.maxUpdated);  printf("averageValue: %6.2f (flag: %d)\n\n", averageValue, flags.averageUpdated);  if (values!=NULL) {    printf(" Values: ");    for (int i=0; i<resx*resy; i++) {      if ((i%resx)==0 && (i!=0)) printf("\n         ");      printf("%6.2f, ", values[i]);    }  }  else printf(" Values: NULL");  printf("\n\n-----------------------------------------------------------\n\n");}

⌨️ 快捷键说明

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