#include "Contents/TerrainHeight.h" #include #include #include // OFFSET: 0x00AC8150 // FUNCTION: fn_17666 void TerrainHeight::CellOrigin(int column, int row, float& x, float& z) const { const auto dx = static_cast(column) - static_cast(this->width / 2); const auto first = dx * static_cast(this->cellSize); x = static_cast(std::bit_cast(first)); const auto dz = static_cast(row) - static_cast(this->height / 2); const auto second = dz * static_cast(this->cellSize); z = static_cast(std::bit_cast(second)); } // OFFSET: 0x00CD36E0 // FUNCTION: fn_21270 void TerrainHeight::CellCenter(int column, int row, float& x, float& z) const { const float size = static_cast(this->cellSize); const float offset = (size * 8.0f) * 0.0625f; x = ((static_cast(column) - static_cast(this->width) * 0.5f) * size) + offset; z = ((static_cast(row) - static_cast(this->height) * 0.5f) * static_cast(this->cellSize)) + offset; } // OFFSET: 0x00CD5230 // FUNCTION: fn_21278 void TerrainHeight::WorldCell(float x, float z, int& column, int& row) const { const float size = static_cast(this->cellSize); const float first = static_cast(this->width / 2) + x / size; const float flooredX = static_cast(std::floor(static_cast(first))); column = _mm_cvttss_si32(_mm_set_ss(flooredX)); const float second = static_cast(this->height / 2) + z / size; const float flooredZ = static_cast(std::floor(static_cast(second))); row = _mm_cvttss_si32(_mm_set_ss(flooredZ)); } // OFFSET: 0x00CD50A0 // FUNCTION: fn_21277 void TerrainHeight::WorldSubcell(float x, float z, int& column, int& row, int& subColumn, int& subRow) const { const float size = static_cast(this->cellSize); const float localX = x / size; const float gridX = static_cast(this->width / 2) + localX; const float flooredX = static_cast(std::floor(static_cast(gridX))); const float localZ = z / size; column = _mm_cvttss_si32(_mm_set_ss(flooredX)); const float gridZ = static_cast(this->height / 2) + localZ; const float flooredZ = static_cast(std::floor(static_cast(gridZ))); row = _mm_cvttss_si32(_mm_set_ss(flooredZ)); const float fractionX = (static_cast(this->width / 2) + localX) - static_cast(column); const float sixteenthsX = static_cast(std::floor(static_cast(fractionX * 16.0f))); subColumn = _mm_cvttss_si32(_mm_set_ss(sixteenthsX)) % 16; const float fractionZ = (static_cast(this->height / 2) + localZ) - static_cast(row); const float sixteenthsZ = static_cast(std::floor(static_cast(fractionZ * 16.0f))); subRow = _mm_cvttss_si32(_mm_set_ss(sixteenthsZ)) % 16; } // OFFSET: 0x00A8C790 // FUNCTION: fn_17135 void TerrainHeight::SpatialCell(float x, float z, int& column, int& row) const { const int halfRows = 2 * (this->height / 4); const float first = static_cast(std::floor(static_cast(x / static_cast(this->cellSize)))); const int firstCell = _mm_cvttss_si32(_mm_set_ss(first)); column = std::bit_cast(static_cast(firstCell) + static_cast(2 * (this->width / 4))); const float second = static_cast(std::floor(static_cast(z / static_cast(this->cellSize)))); row = std::bit_cast(static_cast(_mm_cvttss_si32(_mm_set_ss(second))) + static_cast(halfRows)); } // OFFSET: 0x00748E90 // FUNCTION: fn_07839 void TerrainHeight::HeightBounds(const int* rectangle, float& minimum, float& maximum) const { minimum = 999999.0f; maximum = -999999.0f; int column = rectangle[0]; while (column <= rectangle[2]) { int row = rectangle[1]; while (row <= rectangle[3]) { const TerrainHeightCell* cell = this->CellAt(column, row); if (cell) { // Maximum writes precede minimum reads, including aliased outputs. for (float value : cell->heights) { if (value > maximum) { maximum = value; } } for (float value : cell->heights) { if (minimum > value) { minimum = value; } } } row = std::bit_cast(static_cast(row) + 1u); } column = std::bit_cast(static_cast(column) + 1u); } }