1
0

Implemented faster upscaling using templates.

Fixes #819.
This commit is contained in:
madmaxoft 2014-03-21 22:53:46 +01:00
parent 20fc7d6aea
commit c9163d39f7
6 changed files with 38 additions and 36 deletions

View File

@ -371,8 +371,8 @@ void cBioGenDistortedVoronoi::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::B
Distort(BaseX + x * 4, BaseZ + z * 4, DistortX[4 * x][4 * z], DistortZ[4 * x][4 * z]); Distort(BaseX + x * 4, BaseZ + z * 4, DistortX[4 * x][4 * z], DistortZ[4 * x][4 * z]);
} }
LinearUpscale2DArrayInPlace(&DistortX[0][0], cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4); LinearUpscale2DArrayInPlace<cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4>(&DistortX[0][0]);
LinearUpscale2DArrayInPlace(&DistortZ[0][0], cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4); LinearUpscale2DArrayInPlace<cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4>(&DistortZ[0][0]);
for (int z = 0; z < cChunkDef::Width; z++) for (int z = 0; z < cChunkDef::Width; z++)
{ {
@ -477,8 +477,8 @@ void cBioGenMultiStepMap::DecideOceanLandMushroom(int a_ChunkX, int a_ChunkZ, cC
{ {
Distort(BaseX + x * 4, BaseZ + z * 4, DistortX[4 * x][4 * z], DistortZ[4 * x][4 * z], DistortSize); Distort(BaseX + x * 4, BaseZ + z * 4, DistortX[4 * x][4 * z], DistortZ[4 * x][4 * z], DistortSize);
} }
LinearUpscale2DArrayInPlace(&DistortX[0][0], cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4); LinearUpscale2DArrayInPlace<cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4>(&DistortX[0][0]);
LinearUpscale2DArrayInPlace(&DistortZ[0][0], cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4); LinearUpscale2DArrayInPlace<cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4>(&DistortZ[0][0]);
// Prepare a 9x9 area of neighboring cell seeds // Prepare a 9x9 area of neighboring cell seeds
// (assuming that 7x7 cell area is larger than a chunk being generated) // (assuming that 7x7 cell area is larger than a chunk being generated)
@ -651,8 +651,8 @@ void cBioGenMultiStepMap::BuildTemperatureHumidityMaps(int a_ChunkX, int a_Chunk
HumidityMap[x + 17 * z] = NoiseH; HumidityMap[x + 17 * z] = NoiseH;
} // for x } // for x
} // for z } // for z
LinearUpscale2DArrayInPlace(TemperatureMap, 17, 17, 8, 8); LinearUpscale2DArrayInPlace<17, 17, 8, 8>(TemperatureMap);
LinearUpscale2DArrayInPlace(HumidityMap, 17, 17, 8, 8); LinearUpscale2DArrayInPlace<17, 17, 8, 8>(HumidityMap);
// Re-map into integral values in [0 .. 255] range: // Re-map into integral values in [0 .. 255] range:
for (size_t idx = 0; idx < ARRAYCOUNT(a_TemperatureMap); idx++) for (size_t idx = 0; idx < ARRAYCOUNT(a_TemperatureMap); idx++)
@ -778,8 +778,8 @@ void cBioGenTwoLevel::GenBiomes(int a_ChunkX, int a_ChunkZ, cChunkDef::BiomeMap
DistortZ[4 * x][4 * z] = BlockZ + (int)(64 * NoiseZ); DistortZ[4 * x][4 * z] = BlockZ + (int)(64 * NoiseZ);
} }
LinearUpscale2DArrayInPlace(&DistortX[0][0], cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4); LinearUpscale2DArrayInPlace<cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4>(&DistortX[0][0]);
LinearUpscale2DArrayInPlace(&DistortZ[0][0], cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4); LinearUpscale2DArrayInPlace<cChunkDef::Width + 1, cChunkDef::Width + 1, 4, 4>(&DistortZ[0][0]);
// Apply distortion to each block coord, then query the voronoi maps for biome group and biome index and choose biome based on that: // Apply distortion to each block coord, then query the voronoi maps for biome group and biome index and choose biome based on that:
for (int z = 0; z < cChunkDef::Width; z++) for (int z = 0; z < cChunkDef::Width; z++)

View File

@ -566,7 +566,7 @@ void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc)
m_Noise2.IntNoise3DInt(BaseX + INTERPOL_X * x, 0, BaseZ + INTERPOL_Z * z) / m_Noise2.IntNoise3DInt(BaseX + INTERPOL_X * x, 0, BaseZ + INTERPOL_Z * z) /
256; 256;
} // for x, z - FloorLo[] } // for x, z - FloorLo[]
LinearUpscale2DArrayInPlace(FloorLo, 17, 17, INTERPOL_X, INTERPOL_Z); LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorLo);
// Interpolate segments: // Interpolate segments:
for (int Segment = 0; Segment < MaxHeight; Segment += SEGMENT_HEIGHT) for (int Segment = 0; Segment < MaxHeight; Segment += SEGMENT_HEIGHT)
@ -579,7 +579,7 @@ void cCompoGenNether::ComposeTerrain(cChunkDesc & a_ChunkDesc)
m_Noise2.IntNoise3DInt(BaseX + INTERPOL_Z * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) / m_Noise2.IntNoise3DInt(BaseX + INTERPOL_Z * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) /
256; 256;
} // for x, z - FloorLo[] } // for x, z - FloorLo[]
LinearUpscale2DArrayInPlace(FloorHi, 17, 17, INTERPOL_X, INTERPOL_Z); LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorHi);
// Interpolate between FloorLo and FloorHi: // Interpolate between FloorLo and FloorHi:
for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++) for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++)

View File

@ -428,7 +428,7 @@ void cHeiGenBiomal::GenHeightMap(int a_ChunkX, int a_ChunkZ, cChunkDef::HeightMa
Height[x + 17 * z] = GetHeightAt(x, z, a_ChunkX, a_ChunkZ, Biomes); Height[x + 17 * z] = GetHeightAt(x, z, a_ChunkX, a_ChunkZ, Biomes);
} }
} }
LinearUpscale2DArrayInPlace(Height, 17, 17, STEPX, STEPZ); LinearUpscale2DArrayInPlace<17, 17, STEPX, STEPZ>(Height);
// Copy into the heightmap // Copy into the heightmap
for (int z = 0; z < cChunkDef::Width; z++) for (int z = 0; z < cChunkDef::Width; z++)

View File

@ -420,7 +420,7 @@ void cNoise3DComposable::GenerateNoiseArrayIfNeeded(int a_ChunkX, int a_ChunkZ)
} }
} }
// Linear-interpolate this XZ floor: // Linear-interpolate this XZ floor:
LinearUpscale2DArrayInPlace(CurFloor, 17, 17, UPSCALE_X, UPSCALE_Z); LinearUpscale2DArrayInPlace<17, 17, UPSCALE_X, UPSCALE_Z>(CurFloor);
} }
// Finish the 3D linear interpolation by interpolating between each XZ-floors on the Y axis // Finish the 3D linear interpolation by interpolating between each XZ-floors on the Y axis

View File

@ -578,7 +578,7 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc)
m_Noise2.IntNoise3DInt(BaseX + INTERPOL_X * x, BaseY, BaseZ + INTERPOL_Z * z) / m_Noise2.IntNoise3DInt(BaseX + INTERPOL_X * x, BaseY, BaseZ + INTERPOL_Z * z) /
256; 256;
} // for x, z - FloorLo[] } // for x, z - FloorLo[]
LinearUpscale2DArrayInPlace(FloorLo, 17, 17, INTERPOL_X, INTERPOL_Z); LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorLo);
// Interpolate segments: // Interpolate segments:
for (int Segment = BaseY; Segment < MaxHeight; Segment += SEGMENT_HEIGHT) for (int Segment = BaseY; Segment < MaxHeight; Segment += SEGMENT_HEIGHT)
@ -591,7 +591,7 @@ void cStructGenDirectOverhangs::GenFinish(cChunkDesc & a_ChunkDesc)
m_Noise2.IntNoise3DInt(BaseX + INTERPOL_Z * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) / m_Noise2.IntNoise3DInt(BaseX + INTERPOL_Z * x, Segment + SEGMENT_HEIGHT, BaseZ + INTERPOL_Z * z) /
256; 256;
} // for x, z - FloorLo[] } // for x, z - FloorLo[]
LinearUpscale2DArrayInPlace(FloorHi, 17, 17, INTERPOL_X, INTERPOL_Z); LinearUpscale2DArrayInPlace<17, 17, INTERPOL_X, INTERPOL_Z>(FloorHi);
// Interpolate between FloorLo and FloorHi: // Interpolate between FloorLo and FloorHi:
for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++) for (int z = 0; z < 16; z++) for (int x = 0; x < 16; x++)

View File

@ -18,7 +18,7 @@ Therefore, there is no cpp file.
InPlace upscaling works on a single array and assumes that the values to work on have already InPlace upscaling works on a single array and assumes that the values to work on have already
been interspersed into the array to the cell boundaries. been interspersed into the array to the cell boundaries.
Specifically, a_Array[x * a_AnchorStepX + y * a_AnchorStepY] contains the anchor value. Specifically, a_Array[x * AnchorStepX + y * AnchorStepY] contains the anchor value.
Regular upscaling takes two arrays and "moves" the input from src to dst; src is expected packed. Regular upscaling takes two arrays and "moves" the input from src to dst; src is expected packed.
*/ */
@ -29,46 +29,48 @@ Regular upscaling takes two arrays and "moves" the input from src to dst; src is
/** /**
Linearly interpolates values in the array between the equidistant anchor points (upscales). Linearly interpolates values in the array between the equidistant anchor points (upscales).
Works in-place (input is already present at the correct output coords) Works in-place (input is already present at the correct output coords)
Uses templates to make it possible for the compiler to further optimizer the loops
*/ */
template<typename TYPE> void LinearUpscale2DArrayInPlace( template<
TYPE * a_Array, int SizeX, int SizeY, // Dimensions of the array
int a_SizeX, int a_SizeY, // Dimensions of the array int AnchorStepX, int AnchorStepY,
int a_AnchorStepX, int a_AnchorStepY // Distances between the anchor points in each direction typename TYPE
) >
void LinearUpscale2DArrayInPlace(TYPE * a_Array)
{ {
// First interpolate columns where the anchor points are: // First interpolate columns where the anchor points are:
int LastYCell = a_SizeY - a_AnchorStepY; int LastYCell = SizeY - AnchorStepY;
for (int y = 0; y < LastYCell; y += a_AnchorStepY) for (int y = 0; y < LastYCell; y += AnchorStepY)
{ {
int Idx = a_SizeX * y; int Idx = SizeX * y;
for (int x = 0; x < a_SizeX; x += a_AnchorStepX) for (int x = 0; x < SizeX; x += AnchorStepX)
{ {
TYPE StartValue = a_Array[Idx]; TYPE StartValue = a_Array[Idx];
TYPE EndValue = a_Array[Idx + a_SizeX * a_AnchorStepY]; TYPE EndValue = a_Array[Idx + SizeX * AnchorStepY];
TYPE Diff = EndValue - StartValue; TYPE Diff = EndValue - StartValue;
for (int CellY = 1; CellY < a_AnchorStepY; CellY++) for (int CellY = 1; CellY < AnchorStepY; CellY++)
{ {
a_Array[Idx + a_SizeX * CellY] = StartValue + Diff * CellY / a_AnchorStepY; a_Array[Idx + SizeX * CellY] = StartValue + Diff * CellY / AnchorStepY;
} // for CellY } // for CellY
Idx += a_AnchorStepX; Idx += AnchorStepX;
} // for x } // for x
} // for y } // for y
// Now interpolate in rows, each row has values in the anchor columns // Now interpolate in rows, each row has values in the anchor columns
int LastXCell = a_SizeX - a_AnchorStepX; int LastXCell = SizeX - AnchorStepX;
for (int y = 0; y < a_SizeY; y++) for (int y = 0; y < SizeY; y++)
{ {
int Idx = a_SizeX * y; int Idx = SizeX * y;
for (int x = 0; x < LastXCell; x += a_AnchorStepX) for (int x = 0; x < LastXCell; x += AnchorStepX)
{ {
TYPE StartValue = a_Array[Idx]; TYPE StartValue = a_Array[Idx];
TYPE EndValue = a_Array[Idx + a_AnchorStepX]; TYPE EndValue = a_Array[Idx + AnchorStepX];
TYPE Diff = EndValue - StartValue; TYPE Diff = EndValue - StartValue;
for (int CellX = 1; CellX < a_AnchorStepX; CellX++) for (int CellX = 1; CellX < AnchorStepX; CellX++)
{ {
a_Array[Idx + CellX] = StartValue + CellX * Diff / a_AnchorStepX; a_Array[Idx + CellX] = StartValue + CellX * Diff / AnchorStepX;
} // for CellY } // for CellY
Idx += a_AnchorStepX; Idx += AnchorStepX;
} }
} }
} }