Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/game/terrain/StarDisplacementSelector.cpp
blob: 9047f3a5d53174fb4ebed9e608008f96c0f705f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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]));
}

}