本文整理汇总了C++中TerrainTile::setValue方法的典型用法代码示例。如果您正苦于以下问题:C++ TerrainTile::setValue方法的具体用法?C++ TerrainTile::setValue怎么用?C++ TerrainTile::setValue使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类TerrainTile
的用法示例。
在下文中一共展示了TerrainTile::setValue方法的2个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: setValue
float TerrainInteraction::setValue(TerrainTile & tile, unsigned row, unsigned column, float value, bool setToInteractionElement)
{
float stddev = tile.interactStdDeviation;
assert(stddev > 0);
/** clamp value */
if (value < tile.minValidValue) value = tile.minValidValue;
if (value > tile.maxValidValue) value = tile.maxValidValue;
// define the size of the affected interaction area, in grid coords
const float effectRadiusWorld = stddev * 3;
const uint32_t effectRadius = static_cast<uint32_t>(std::ceil(effectRadiusWorld * tile.samplesPerWorldCoord)); // = 0 means to change only the value at (row,column)
bool moveUp = (value - tile.valueAt(row, column)) > 0;
int invert = moveUp ? 1 : -1; // invert the curve if moving downwards
float norm0Inv = 1.0f / normalDist(0, 0, stddev);
float valueRange = std::abs(tile.maxValidValue - tile.minValidValue);
std::function<float(float)> interactHeight = [stddev, norm0Inv, value, valueRange, invert](float x) {
return normalDist(x, 0, stddev) // - normalize normDist to
* norm0Inv // normDist value at interaction center
* (valueRange + 10) // - scale to value range + offset to omit norm values near 0
* invert // - mirror the curve along the y axis if moving downward
+ value // - move along y so that value==0 => y==0
- (valueRange + 10) * invert;
};
unsigned int minRow, maxRow, minColumn, maxColumn;
{
// unchecked signed min/max values, possibly < 0 or > numRows/Column
int iMinRow = row - effectRadius, iMaxRow = row + effectRadius, iMinColumn = column - effectRadius, iMaxColumn = column + effectRadius;
// work on rows and column that are in range of the terrain tile settings and larger than 0
minRow = iMinRow < 0 ? 0 : (iMinRow >= static_cast<signed>(tile.samplesPerAxis) ? tile.samplesPerAxis - 1 : static_cast<unsigned int>(iMinRow));
maxRow = iMaxRow < 0 ? 0 : (iMaxRow >= static_cast<signed>(tile.samplesPerAxis) ? tile.samplesPerAxis - 1 : static_cast<unsigned int>(iMaxRow));
minColumn = iMinColumn < 0 ? 0 : (iMinColumn >= static_cast<signed>(tile.samplesPerAxis) ? tile.samplesPerAxis - 1 : static_cast<unsigned int>(iMinColumn));
maxColumn = iMaxColumn < 0 ? 0 : (iMaxColumn >= static_cast<signed>(tile.samplesPerAxis) ? tile.samplesPerAxis - 1 : static_cast<unsigned int>(iMaxColumn));
}
// also change element id's if requested and the tile supports it
PhysicalTile * physicalTile = dynamic_cast<PhysicalTile*>(&tile);
if (setToInteractionElement) {
assert(physicalTile);
}
uint8_t elementIndex = 0;
if (physicalTile)
elementIndex = physicalTile->elementIndex(m_interactElement);
for (unsigned int r = minRow; r <= maxRow; ++r) {
float relWorldX = (signed(r) - signed(row)) * tile.sampleInterval;
for (unsigned int c = minColumn; c <= maxColumn; ++c) {
float relWorldZ = (signed(c) - signed(column)) * tile.sampleInterval;
float localRadius = std::sqrt(relWorldX*relWorldX + relWorldZ*relWorldZ);
if (localRadius > effectRadiusWorld) // interaction in a circle, not square
continue;
float newLocalHeight = interactHeight(localRadius);
bool localMoveUp = newLocalHeight > tile.valueAt(r, c);
// don't do anything if we pull up the terrain but the local height point is already higher than its calculated height. (vice versa)
if (localMoveUp != moveUp)
continue;
tile.setValue(r, c, newLocalHeight);
if (setToInteractionElement)
physicalTile->setElement(r, c, elementIndex);
}
tile.addBufferUpdateRange(minColumn + r * tile.samplesPerAxis, 1u + effectRadius * 2u);
}
if (physicalTile)
physicalTile->addToPxUpdateBox(minRow, maxRow, minColumn, maxColumn);
return value;
}
示例2: diamondSquare
void TerrainGenerator::diamondSquare(TerrainTile & tile) const
{
// assuming the edge length of the field is a power of 2, + 1
// assuming the field is square
const unsigned fieldEdgeLength = tile.samplesPerAxis;
const float maxHeight = m_settings.maxHeight;
float randomMax = 50.0f;
std::function<float(float)> clampHeight = [maxHeight](float value) {
if (value > maxHeight)
value = maxHeight;
if (value < -maxHeight)
value = -maxHeight;
return value;
};
std::function<void(unsigned int, unsigned int, unsigned int, std::function<float(unsigned int, unsigned int)>&)> squareStep =
[&tile, fieldEdgeLength, &clampHeight](unsigned int diamondRadius, unsigned int diamondCenterRow, unsigned int diamondCenterColumn, std::function<float(unsigned int, unsigned int)>& heightRnd)
{
// get the existing data values first: if we get out of the valid range, wrap around, to the next existing value on the other field side
int upperRow = signed(diamondCenterRow) - signed(diamondRadius);
if (upperRow < 0)
upperRow = fieldEdgeLength - 1 - diamondRadius; // example: nbRows=5, centerRow=0, upperRow gets -1, we want the second last row (with existing value), so it's 3
int lowerRow = signed(diamondCenterRow) + signed(diamondRadius);
if (lowerRow >= signed(fieldEdgeLength))
lowerRow = diamondRadius; // this is easier: use the first row in our column, that is already set
int leftColumn = signed(diamondCenterColumn) - signed(diamondRadius);
if (leftColumn < 0)
leftColumn = fieldEdgeLength - 1 - diamondRadius;
int rightColumn = signed(diamondCenterColumn) + signed(diamondRadius);
if (rightColumn >= signed(fieldEdgeLength))
rightColumn = diamondRadius;
float value =
(tile.valueAt(upperRow, diamondCenterColumn)
+ tile.valueAt(lowerRow, diamondCenterColumn)
+ tile.valueAt(diamondCenterRow, leftColumn)
+ tile.valueAt(diamondCenterRow, rightColumn))
* 0.25f
+ heightRnd(diamondCenterRow, diamondCenterColumn);
float clampedHeight = clampHeight(value);
tile.setValue(diamondCenterRow, diamondCenterColumn, clampedHeight);
// in case we are at the borders of the tile: also set the value at the opposite border, to allow seamless tile wrapping
if (upperRow > signed(diamondCenterRow))
tile.setValue(fieldEdgeLength - 1, diamondCenterColumn, clampedHeight);
if (leftColumn > signed(diamondCenterColumn))
tile.setValue(diamondCenterRow, fieldEdgeLength - 1, clampedHeight);
};
unsigned nbSquareRows = 1; // number of squares in a row, doubles each time the current edge length increases [same for the columns]
for (unsigned int len = fieldEdgeLength; len > 2; len = (len / 2) + 1) // length: 9, 5, 3, finished
{
const unsigned int currentEdgeLength = len;
std::uniform_real_distribution<float> dist(-randomMax, randomMax);
std::function<float(unsigned int, unsigned int)> heightRndPos =
[fieldEdgeLength, &dist](unsigned int row, unsigned int column) {
glm::vec2 pos(row, column);
pos = pos / (fieldEdgeLength - 1.0f) * 2.0f - 1.0f;
return float(glm::length(pos)) * dist(rng);
//return std::abs(float(row + column) / float(2 * fieldEdgeLength - 2) * 2.0f - 1.0f) * dist(rng);
};
// create diamonds
for (unsigned int rowN = 0; rowN < nbSquareRows; ++rowN) {
const unsigned int row = rowN * (currentEdgeLength - 1);
const unsigned int midpointRow = row + (currentEdgeLength - 1) / 2; // this is always divisible, because of the edge length 2^n + 1
for (unsigned int columnN = 0; columnN < nbSquareRows; ++columnN) {
const unsigned int column = columnN * (currentEdgeLength - 1);
const unsigned int midpointColumn = column + (currentEdgeLength - 1) / 2;
float heightValue =
(tile.valueAt(row, column)
+ tile.valueAt(row + currentEdgeLength - 1, column)
+ tile.valueAt(row, column + currentEdgeLength - 1)
+ tile.valueAt(row + currentEdgeLength - 1, column + currentEdgeLength - 1))
* 0.25f
+ heightRndPos(midpointRow, midpointColumn);
tile.setValue(midpointRow, midpointColumn, clampHeight(heightValue));
}
}
// create squares
unsigned int diamondRadius = (currentEdgeLength - 1) / 2;
// don't iterate over the last row/column here. These values are set with the first row/column, to allow seamless tile wrapping
for (unsigned int rowN = 0; rowN < nbSquareRows; ++rowN) {
const unsigned int seedpointRow = rowN * (currentEdgeLength - 1);
for (unsigned int columnN = 0; columnN < nbSquareRows; ++columnN) {
const unsigned int seedpointColumn = columnN * (currentEdgeLength - 1);
unsigned int rightDiamondColumn = seedpointColumn + currentEdgeLength / 2;
if (rightDiamondColumn < tile.samplesPerAxis)
squareStep(diamondRadius, seedpointRow, rightDiamondColumn, heightRndPos);
unsigned int bottomDiamondRow = seedpointRow + currentEdgeLength / 2;
if (bottomDiamondRow < tile.samplesPerAxis)
squareStep(diamondRadius, bottomDiamondRow, seedpointColumn, heightRndPos);
}
}
//.........这里部分代码省略.........