Program Listing for File heightmap.hpp

Return to documentation for file (libtcod/heightmap.hpp)

/* BSD 3-Clause License
 *
 * Copyright © 2008-2026, Jice and the libtcod contributors.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#pragma once
#ifndef TCOD_HEIGHTMAP_HPP_
#define TCOD_HEIGHTMAP_HPP_

#include <stddef.h>

#include <vector>

#include "heightmap.h"
#include "noise.hpp"

// clang-format off
class TCODLIB_API TCODHeightMap {
 public:
  TCODHeightMap() = default;

  TCODHeightMap(int width, int height) : w{width}, h{height}, values{new float[width * height]{}} {}

  // clang-format on

  TCODHeightMap(const TCODHeightMap& rhs) : TCODHeightMap{rhs.w, rhs.h} { *this = rhs; }
  TCODHeightMap& operator=(const TCODHeightMap& rhs) {
    if (w == rhs.w && h == rhs.h) {
      for (ptrdiff_t i = 0; i < w * h; ++i) values[i] = rhs.values[i];
    } else {
      *this = TCODHeightMap(rhs);
    }
    return *this;
  }
  TCODHeightMap(TCODHeightMap&& rhs) { swap(rhs); }
  TCODHeightMap& operator=(TCODHeightMap&& rhs) {
    swap(rhs);
    return *this;
  }

  ~TCODHeightMap() { delete[] values; }

  void swap(TCODHeightMap& rhs) noexcept {
    std::swap(w, rhs.w);
    std::swap(h, rhs.h);
    std::swap(values, rhs.values);
  }
  // clang-format off
  inline void setValue(int x, int y, float v) {
    values[w * y + x] = v;
  }

  void add(float f);

  void scale(float f);

  void clear(); // resets all values to 0.0

  void clamp(float min, float max);

  [[deprecated("Copy by value instead: 'x = y;'")]]
  void copy(const TCODHeightMap *source) {
    if (source) *this = *source;
  }

  void normalize(float newMin=0.0f, float newMax=1.0f); // scales the values to the range [newMin;newMax]

  void lerp(const TCODHeightMap *a, const TCODHeightMap *b,float coef);

  void add(const TCODHeightMap *a, const TCODHeightMap *b);

  void multiply(const TCODHeightMap *a, const TCODHeightMap *b);

  void addHill(float x, float y, float radius, float height); // adds a hill (half sphere) at given position

  void digHill(float hx, float hy, float h_radius, float height);

  void rainErosion(int nbDrops,float erosionCoef,float sedimentationCoef,TCODRandom *rnd);

  void kernelTransform(int kernelSize, const int *dx, const int *dy, const float *weight, float minLevel,float maxLevel);

  void addVoronoi(int nbPoints, int nbCoef, const float *coef,TCODRandom *rnd);

  void addFbm(TCODNoise *noise,float mul_x, float mul_y, float add_x, float add_y, float octaves, float delta, float scale);

  void scaleFbm(TCODNoise *noise,float mul_x, float mul_y, float add_x, float add_y, float octaves, float delta, float scale);

  void digBezier(int px[4], int py[4], float startRadius, float startDepth, float endRadius, float endDepth);

  inline float getValue(int x, int y) const {
    return values[w * y + x];
  }

  float getInterpolatedValue(float x, float y) const;

  float getSlope(int x, int y) const; // returns the slope in radian between 0 and PI/2

  void getNormal(float x, float y,float n[3], float waterLevel=0.0f) const; // returns the surface normal or (0,0,1) if beyond water level.

  int countCells(float min,float max) const;

  bool hasLandOnBorder(float waterLevel) const;

  void getMinMax(float *min, float *max) const;

//  void heatErosion(int nbPass,float minSlope,float erosionCoef,float sedimentationCoef,TCODRandom *rnd);
  void midPointDisplacement(TCODRandom *rnd = NULL, float roughness=0.45f);
  void islandify(float seaLevel,TCODRandom *rnd); // lowers the terrain near the heightmap borders
  // TODO : checks island connectivity with floodfill

  // clang-format on

  int w{};
  int h{};
  float* values{};

 private:
};

#endif  // TCOD_HEIGHTMAP_HPP_