📄 teheightmap.cpp
字号:
//##################################################//# $Id: TeHeightMap.cpp 28 2005-08-28 10:37:47Z peciva $/*****************************************************************************\ * * TeHeightMap.cpp * * TeHeightMap class implementation * * Author: Martin Havl龛ek (xhavli15 AT stud.fit.vutbr.cz) * Contributors: PCJohn (peciva AT 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 "TeHeightMap.h"#include <cstdlib> // NULL, malloc, free, rand#include <cstring> // memcpy#include <cmath> // floor//----------------------------------------------------------------------------/** * Resets TeHeightMap::flags to zero, marks all stored statistics as invalid. * * \sa minValue, maxValue, averageValue */void TeHeightMap::resetFlags(){ flags.minUpdated = flags.maxUpdated = flags.averageUpdated = 0;}//----------------------------------------------------------------------------/** * Simple default constructor. * * Creates empty object (zero dimensions, no allocated memory). */TeHeightMap::TeHeightMap() : resx(0), resy(0), values(NULL), minValue(0), maxValue(0), averageValue(0){ resetFlags();}//----------------------------------------------------------------------------/** * Constructor that sets dimensions and allocates memory. * * Creates initialized object with known dimensions and allocated memory * to store generated values. * * \param resolution Desired heightmap resolution. */TeHeightMap::TeHeightMap(const SbVec2s resolution) : resx(resolution[0]), resy(resolution[1]), minValue(0), maxValue(0), averageValue(0){ values = (float *)malloc(resx*resy*sizeof(float)); resetFlags();}//----------------------------------------------------------------------------/** * Constructor that sets dimensions and allocates memory. * * Creates initialized object with known dimensions and allocated memory * to store generated values. * * \param rx Desired resolution in X-axis direction. * \param ry Desired resolution in Y-axis direction. */TeHeightMap::TeHeightMap(const int rx, const int ry) : resx(rx), resy(ry), minValue(0), maxValue(0), averageValue(0){ values = (float *)malloc(resx*resy*sizeof(float)); resetFlags();}//----------------------------------------------------------------------------/** * Copy-constructor. * * Creates new heightmap as a copy of source heightmap. * * \param hmap Reference to source heightmap. */TeHeightMap::TeHeightMap(const TeHeightMap &hmap) : resx(hmap.resx), resy(hmap.resy), minValue(hmap.minValue), maxValue(hmap.maxValue), averageValue(hmap.averageValue), flags(hmap.flags){ values = (float *)malloc(resx*resy*sizeof(float)); memcpy((void*)values, (const void*)hmap.values, resx*resy*sizeof(float));}//----------------------------------------------------------------------------/** * Constructor that copies only specified part of source heightmap. * * New heightmap will have the same resolution as the source \a hmap. * Values are copied from the source \a hmap. The rectangular area of values * being copied is defined by \a origin and \a asize parameters. The values * are pasted at (0,0) coordinates. * * \param hmap Pointer to source heightmap. * \param origin Top-left corner of the copied area in the source heightmap. * \param asize Size of copied area. */TeHeightMap::TeHeightMap(const TeHeightMap *hmap, const SbVec2s origin, const SbVec2s asize) : resx(hmap->resx), resy(hmap->resy), minValue(0), maxValue(0), averageValue(0){ values = (float *)malloc(resx*resy*sizeof(float)); copyFrom(hmap, origin, asize);}//----------------------------------------------------------------------------/** * Destructor. * * Releases memory. */TeHeightMap::~TeHeightMap(){ free((void *)values);}//----------------------------------------------------------------------------/** * Assignment operator * * \param hmap Reference to source heightmap. * \return Reference to itself. */TeHeightMap& TeHeightMap::operator= (const TeHeightMap &hmap){ if(&hmap != this) { resx = hmap.resx; resy = hmap.resy; if (values!=NULL) free((void *)values); values = (float *)malloc(resx*resy*sizeof(float)); memcpy((void*)values, (const void*)hmap.values, resx*resy*sizeof(float)); minValue = hmap.minValue; maxValue = hmap.maxValue; averageValue = hmap.averageValue; flags = hmap.flags; } return *this;}//----------------------------------------------------------------------------/** * Returns size. * * \return Vector representing resolution of heightmap. */SbVec2s TeHeightMap::getResolution() const{ return SbVec2s(resx, resy);}//----------------------------------------------------------------------------/** * Returns size. * * \param x Reference to the output variable for x-resolution. * \param y Reference to the output variable for y-resolution. */void TeHeightMap::getResolution(int &x, int &y) const{ x = resx; y = resy;}//----------------------------------------------------------------------------/** * Sets new resolution. * * If map was larger cut off previous values, if map was smaller set new * points to zero, old will be in the top-left corner. * * \param newRes Desired heightmap size. */void TeHeightMap::setResolution(const SbVec2s &newRes){ if (resx!=newRes[0] && resy != newRes[1]) { float *new_values = (float *)calloc(newRes[0]*newRes[1], sizeof(float)); for (int i=0; i<((newRes[1]<resx) ? newRes[1] : resy); i++) { memcpy((void*)(new_values+i*newRes[0]), (const void*)(values+i*resx), (newRes[0]<resx) ? newRes[0]*sizeof(float) : resx*sizeof(float)); } free((void *)values); values = new_values; resx = newRes[0]; resy = newRes[1]; resetFlags(); }}//----------------------------------------------------------------------------/** * Sets one heightmap value. * * Sets value at (\a x, \a y) to \a value. If (\a x, \a y) is out of bounds * does nothing. * * \param x X coordinate of the point. * \param y Y coordinate of the point. * \param value Value to be placed at that point. */void TeHeightMap::setValue(const int x, const int y, const float value){ if ((x<resx) && (x>=0) && (y<resy) && (y>=0)) values[(y*resx)+x] = value; resetFlags();}//----------------------------------------------------------------------------/** * Sets all heightmap values to specified \a value. * * \param value Float number to be set everywhere. * * \todo Consider implementing this using memset. Memset wants int argument, * but for zero it should be fine too and it should be faster. */void TeHeightMap::setAllValues(const float value){ for (int i=0; i<resx*resy; i++) values[i] = value; flags.maxUpdated = flags.minUpdated = flags.averageUpdated = 1; maxValue = value; minValue = value; averageValue = value;}//----------------------------------------------------------------------------/** * Returns value at specified coordinates. * * \param x X coordinate of the point. * \param y Y coordinate of the point. * \return Value at specified coordinates */float TeHeightMap::getValue(const int x, const int y) const{ return values[(y*resx)+x];}//----------------------------------------------------------------------------/** * Returns values array. * * \return Pointer to memory location, where heightmap values are stored. */const float *TeHeightMap::getValues() const{ return values;}//----------------------------------------------------------------------------/** * One row getting operator. * * Useful for coding like height=hmap[y][x]. * * \param i Row index * \return Pointer to memory location of specified row. */const float* TeHeightMap::operator[] (int i) const{ return &values[resx*i];}//----------------------------------------------------------------------------/** * Starts editing. * * \return Pointer to memory location, where heightmap values are stored. */float* TeHeightMap::startEditing(){ return values;}//----------------------------------------------------------------------------/** * Finishes editing. * * It performs resetFlags(). */void TeHeightMap::finishEditing(){ resetFlags();}//----------------------------------------------------------------------------/** * Statistics gathering (fast single-pass) * * Returns stats faster than when calling standalone routines, uses * TeHeightMap::flags so we can save even more time. * * If you do not need all the values, pass NULL as no-wanted args when * calling this function. * * \param min Pointer to the output variable for minimal value. * \param max Pointer to the output variable for maximal value. * \param average Pointer the to output variable for average value. * * \sa minValue, maxValue, averageValue, getMinValue(), getMaxValue(), getAverageValue() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -