diff options
Diffstat (limited to 'source/game/terrain/StarDisplacementSelector.cpp')
-rw-r--r-- | source/game/terrain/StarDisplacementSelector.cpp | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/source/game/terrain/StarDisplacementSelector.cpp b/source/game/terrain/StarDisplacementSelector.cpp new file mode 100644 index 0000000..9047f3a --- /dev/null +++ b/source/game/terrain/StarDisplacementSelector.cpp @@ -0,0 +1,69 @@ +#include "StarDisplacementSelector.hpp" +#include "StarRandom.hpp" +#include "StarJsonExtra.hpp" + +namespace Star { + +char const* const DisplacementSelector::Name = "displacement"; + +DisplacementSelector::DisplacementSelector( + Json const& config, TerrainSelectorParameters const& parameters, TerrainDatabase const* database) + : TerrainSelector(Name, config, parameters) { + RandomSource random(parameters.seed); + + auto xType = PerlinTypeNames.getLeft(config.getString("xType")); + auto xOctaves = config.getFloat("xOctaves"); + auto xFreq = config.getFloat("xFreq"); + auto xAmp = config.getFloat("xAmp"); + auto xBias = config.getFloat("xBias", 0.0f); + auto xAlpha = config.getFloat("xAlpha", 2.0f); + auto xBeta = config.getFloat("xBeta", 2.0f); + + xDisplacementFunction = PerlinF(xType, xOctaves, xFreq, xAmp, xBias, xAlpha, xBeta, random.randu64()); + + auto yType = PerlinTypeNames.getLeft(config.getString("yType")); + auto yOctaves = config.getFloat("yOctaves"); + auto yFreq = config.getFloat("yFreq"); + auto yAmp = config.getFloat("yAmp"); + auto yBias = config.getFloat("yBias", 0.0f); + auto yAlpha = config.getFloat("yAlpha", 2.0f); + auto yBeta = config.getFloat("yBeta", 2.0f); + + yDisplacementFunction = PerlinF(yType, yOctaves, yFreq, yAmp, yBias, yAlpha, yBeta, random.randu64()); + + xXInfluence = config.getFloat("xXInfluence", 1.0f); + xYInfluence = config.getFloat("xYInfluence", 1.0f); + yXInfluence = config.getFloat("yXInfluence", 1.0f); + yYInfluence = config.getFloat("yYInfluence", 1.0f); + + yClamp = config.contains("yClamp"); + if (yClamp) { + yClampRange = jsonToVec2F(config.get("yClamp")); + yClampSmoothing = config.getFloat("yClampSmoothing", 0); + } + + auto sourceConfig = config.get("source"); + String sourceType = sourceConfig.getString("type"); + m_source = database->createSelectorType(sourceType, sourceConfig, parameters); +} + +float DisplacementSelector::get(int x, int y) const { + auto x_ = x + xDisplacementFunction.get(x * xXInfluence, y * xYInfluence); + auto y_ = y + clampY(yDisplacementFunction.get(x * yXInfluence, y * yYInfluence)); + return m_source->get(x_, y_); +} + +float DisplacementSelector::clampY(float v) const { + if (!yClamp) + return v; + if (yClampSmoothing == 0) + return clamp(v, yClampRange[0], yClampRange[1]); + + return 0.2f * (clamp(v - yClampSmoothing, yClampRange[0], yClampRange[1]) + + clamp(v - 0.5f * yClampSmoothing, yClampRange[0], yClampRange[1]) + + clamp(v, yClampRange[0], yClampRange[1]) + + clamp(v + 0.5f * yClampSmoothing, yClampRange[0], yClampRange[1]) + + clamp(v + yClampSmoothing, yClampRange[0], yClampRange[1])); +} + +} |