aboutsummaryrefslogtreecommitdiff
path: root/src/heightmap.h
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2011-02-05 14:55:16 +0200
committerPerttu Ahola <celeron55@gmail.com>2011-02-05 14:55:16 +0200
commitea6740e9002839f79053cf9d8cd78eb3fcae1b47 (patch)
treedc8a6c8c0df0ef2d50a0874a74549ccd2022e874 /src/heightmap.h
parent7f2aa30bf29ed1c8b363bd948916d4c027b0192f (diff)
downloadminetest-ea6740e9002839f79053cf9d8cd78eb3fcae1b47.tar.gz
minetest-ea6740e9002839f79053cf9d8cd78eb3fcae1b47.tar.bz2
minetest-ea6740e9002839f79053cf9d8cd78eb3fcae1b47.zip
mapgen stuff
Diffstat (limited to 'src/heightmap.h')
-rw-r--r--src/heightmap.h572
1 files changed, 0 insertions, 572 deletions
diff --git a/src/heightmap.h b/src/heightmap.h
deleted file mode 100644
index aba3b050d..000000000
--- a/src/heightmap.h
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
-Minetest-c55
-Copyright (C) 2010 celeron55, Perttu Ahola <celeron55@gmail.com>
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License along
-with this program; if not, write to the Free Software Foundation, Inc.,
-51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-*/
-
-#ifndef HEIGHTMAP_HEADER
-#define HEIGHTMAP_HEADER
-
-#include <iostream>
-#include <time.h>
-#include <sstream>
-
-#include "debug.h"
-#include "common_irrlicht.h"
-#include "exceptions.h"
-#include "utility.h"
-#include "serialization.h"
-
-#define GROUNDHEIGHT_NOTFOUND_SETVALUE (-10e6)
-#define GROUNDHEIGHT_VALID_MINVALUE ( -9e6)
-
-class Heightmappish
-{
-public:
- virtual f32 getGroundHeight(v2s16 p, bool generate=true) = 0;
- virtual void setGroundHeight(v2s16 p, f32 y, bool generate=true) = 0;
-
- v2f32 getSlope(v2s16 p)
- {
- f32 y0 = getGroundHeight(p, false);
-
- v2s16 dirs[] = {
- v2s16(1,0),
- v2s16(0,1),
- };
-
- v2f32 fdirs[] = {
- v2f32(1,0),
- v2f32(0,1),
- };
-
- v2f32 slopevector(0.0, 0.0);
-
- for(u16 i=0; i<2; i++){
- f32 y1 = 0.0;
- f32 y2 = 0.0;
- f32 count = 0.0;
-
- v2s16 p1 = p - dirs[i];
- y1 = getGroundHeight(p1, false);
- if(y1 > GROUNDHEIGHT_VALID_MINVALUE){
- y1 -= y0;
- count += 1.0;
- }
- else
- y1 = 0;
-
- v2s16 p2 = p + dirs[i];
- y2 = getGroundHeight(p2, false);
- if(y2 > GROUNDHEIGHT_VALID_MINVALUE){
- y2 -= y0;
- count += 1.0;
- }
- else
- y2 = 0;
-
- if(count < 0.001)
- return v2f32(0.0, 0.0);
-
- /*
- If y2 is higher than y1, slope is positive
- */
- f32 slope = (y2 - y1)/count;
-
- slopevector += fdirs[i] * slope;
- }
-
- return slopevector;
- }
-
-};
-
-// TODO: Get rid of this dummy wrapper
-class Heightmap : public Heightmappish /*, public ReferenceCounted*/
-{
-};
-
-class WrapperHeightmap : public Heightmap
-{
- Heightmappish *m_target;
-public:
-
- WrapperHeightmap(Heightmappish *target):
- m_target(target)
- {
- if(target == NULL)
- throw NullPointerException();
- }
-
- f32 getGroundHeight(v2s16 p, bool generate=true)
- {
- return m_target->getGroundHeight(p, generate);
- }
- void setGroundHeight(v2s16 p, f32 y, bool generate=true)
- {
- m_target->setGroundHeight(p, y, generate);
- }
-};
-
-/*
- Base class that defines a generator that gives out values at
- positions in 2-dimensional space.
- Can be given to UnlimitedHeightmap to feed stuff.
-
- These are always serialized as readable text ending in "\n"
-*/
-class ValueGenerator
-{
-public:
- ValueGenerator(){}
- virtual ~ValueGenerator(){}
-
- static ValueGenerator* deSerialize(std::string line);
-
- static ValueGenerator* deSerialize(std::istream &is)
- {
- std::string line;
- std::getline(is, line, '\n');
- return deSerialize(line);
- }
-
- void serializeBase(std::ostream &os)
- {
- os<<getName()<<" ";
- }
-
- // Virtual methods
- virtual const char * getName() const = 0;
- virtual f32 getValue(v2s16 p) = 0;
- virtual void serialize(std::ostream &os) = 0;
-};
-
-class ConstantGenerator : public ValueGenerator
-{
-public:
- f32 m_value;
-
- ConstantGenerator(f32 value)
- {
- m_value = value;
- }
-
- const char * getName() const
- {
- return "constant";
- }
-
- f32 getValue(v2s16 p)
- {
- return m_value;
- }
-
- void serialize(std::ostream &os)
- {
- serializeBase(os);
-
- std::ostringstream ss;
- //ss.imbue(std::locale("C"));
-
- ss<<m_value<<"\n";
-
- os<<ss.str();
- }
-};
-
-class LinearGenerator : public ValueGenerator
-{
-public:
- f32 m_height;
- v2f m_slope;
-
- LinearGenerator(f32 height, v2f slope)
- {
- m_height = height;
- m_slope = slope;
- }
-
- const char * getName() const
- {
- return "linear";
- }
-
- f32 getValue(v2s16 p)
- {
- return m_height + m_slope.X * p.X + m_slope.Y * p.Y;
- }
-
- void serialize(std::ostream &os)
- {
- serializeBase(os);
-
- std::ostringstream ss;
- //ss.imbue(std::locale("C"));
-
- ss<<m_height<<" "<<m_slope.X<<" "<<m_slope.Y<<"\n";
-
- os<<ss.str();
- }
-};
-
-class PowerGenerator : public ValueGenerator
-{
-public:
- f32 m_height;
- v2f m_slope;
- f32 m_power;
-
- PowerGenerator(f32 height, v2f slope, f32 power)
- {
- m_height = height;
- m_slope = slope;
- m_power = power;
- }
-
- const char * getName() const
- {
- return "power";
- }
-
- f32 getValue(v2s16 p)
- {
- return m_height
- + m_slope.X * pow((f32)p.X, m_power)
- + m_slope.Y * pow((f32)p.Y, m_power);
- }
-
- void serialize(std::ostream &os)
- {
- serializeBase(os);
-
- std::ostringstream ss;
- //ss.imbue(std::locale("C"));
-
- ss<<m_height<<" "
- <<m_slope.X<<" "
- <<m_slope.Y<<" "
- <<m_power<<"\n";
-
- os<<ss.str();
- }
-};
-
-class FixedHeightmap : public Heightmap
-{
- // A meta-heightmap on which this heightmap is located
- // (at m_pos_on_master * m_blocksize)
- Heightmap * m_master;
- // Position on master heightmap (in blocks)
- v2s16 m_pos_on_master;
- s32 m_blocksize; // This is (W-1) = (H-1)
- // These are the actual size of the data
- s32 W;
- s32 H;
- f32 *m_data;
-
-public:
-
- FixedHeightmap(Heightmap * master,
- v2s16 pos_on_master, s32 blocksize):
- m_master(master),
- m_pos_on_master(pos_on_master),
- m_blocksize(blocksize)
- {
- W = m_blocksize+1;
- H = m_blocksize+1;
- m_data = NULL;
- m_data = new f32[(blocksize+1)*(blocksize+1)];
-
- for(s32 i=0; i<(blocksize+1)*(blocksize+1); i++){
- m_data[i] = GROUNDHEIGHT_NOTFOUND_SETVALUE;
- }
- }
-
- ~FixedHeightmap()
- {
- if(m_data)
- delete[] m_data;
- }
-
- v2s16 getPosOnMaster()
- {
- return m_pos_on_master;
- }
-
- /*
- TODO: BorderWrapper class or something to allow defining
- borders that wrap to an another heightmap. The algorithm
- should be allowed to edit stuff over the border and on
- the border in that case, too.
- This will allow non-square heightmaps, too. (probably)
- */
-
- void print()
- {
- printf("FixedHeightmap::print(): size is %ix%i\n", W, H);
- for(s32 y=0; y<H; y++){
- for(s32 x=0; x<W; x++){
- /*if(getSeeded(v2s16(x,y)))
- printf("S");*/
- f32 n = getGroundHeight(v2s16(x,y));
- if(n < GROUNDHEIGHT_VALID_MINVALUE)
- printf(" - ");
- else
- printf("% -5.1f ", getGroundHeight(v2s16(x,y)));
- }
- printf("\n");
- }
- }
-
- bool overborder(v2s16 p)
- {
- return (p.X < 0 || p.X >= W || p.Y < 0 || p.Y >= H);
- }
-
- bool atborder(v2s16 p)
- {
- if(overborder(p))
- return false;
- return (p.X == 0 || p.X == W-1 || p.Y == 0 || p.Y == H-1);
- }
-
- void setGroundHeight(v2s16 p, f32 y, bool generate=false)
- {
- /*dstream<<"FixedHeightmap::setGroundHeight(("
- <<p.X<<","<<p.Y
- <<"), "<<y<<")"<<std::endl;*/
- if(overborder(p))
- throw InvalidPositionException();
- m_data[p.Y*W + p.X] = y;
- }
-
- // Returns true on success, false on railure.
- bool setGroundHeightParent(v2s16 p, f32 y, bool generate=false)
- {
- /*// Position on master
- v2s16 blockpos_nodes = m_pos_on_master * m_blocksize;
- v2s16 nodepos_master = blockpos_nodes + p;
- dstream<<"FixedHeightmap::setGroundHeightParent(("
- <<p.X<<","<<p.Y
- <<"), "<<y<<"): nodepos_master=("
- <<nodepos_master.X<<","
- <<nodepos_master.Y<<")"<<std::endl;
- m_master->setGroundHeight(nodepos_master, y, false);*/
-
- // Try to set on master
- bool master_got_it = false;
- if(overborder(p) || atborder(p))
- {
- try{
- // Position on master
- v2s16 blockpos_nodes = m_pos_on_master * m_blocksize;
- v2s16 nodepos_master = blockpos_nodes + p;
- m_master->setGroundHeight(nodepos_master, y, false);
-
- master_got_it = true;
- }
- catch(InvalidPositionException &e)
- {
- }
- }
-
- if(overborder(p))
- return master_got_it;
-
- setGroundHeight(p, y);
-
- return true;
- }
-
- f32 getGroundHeight(v2s16 p, bool generate=false)
- {
- if(overborder(p))
- return GROUNDHEIGHT_NOTFOUND_SETVALUE;
- return m_data[p.Y*W + p.X];
- }
-
- f32 getGroundHeightParent(v2s16 p)
- {
- /*v2s16 blockpos_nodes = m_pos_on_master * m_blocksize;
- return m_master->getGroundHeight(blockpos_nodes + p, false);*/
-
- if(overborder(p) == false){
- f32 h = getGroundHeight(p);
- if(h > GROUNDHEIGHT_VALID_MINVALUE)
- return h;
- }
-
- // Position on master
- v2s16 blockpos_nodes = m_pos_on_master * m_blocksize;
- f32 h = m_master->getGroundHeight(blockpos_nodes + p, false);
- return h;
- }
-
- f32 avgNeighbours(v2s16 p, s16 d);
-
- f32 avgDiagNeighbours(v2s16 p, s16 d);
-
- void makeDiamond(
- v2s16 center,
- s16 a,
- f32 randmax,
- core::map<v2s16, bool> &next_squares);
-
- void makeSquare(
- v2s16 center,
- s16 a,
- f32 randmax,
- core::map<v2s16, bool> &next_diamonds);
-
- void DiamondSquare(f32 randmax, f32 randfactor);
-
- /*
- corners: [i]=XY: [0]=00, [1]=10, [2]=11, [3]=10
- */
- void generateContinued(f32 randmax, f32 randfactor, f32 *corners);
-
-
- static u32 serializedLength(u8 version, u16 blocksize);
- u32 serializedLength(u8 version);
- void serialize(u8 *dest, u8 version);
- void deSerialize(u8 *source, u8 version);
- /*static FixedHeightmap * deSerialize(u8 *source, u32 size,
- u32 &usedsize, Heightmap *master, u8 version);*/
-};
-
-class OneChildHeightmap : public Heightmap
-{
- s16 m_blocksize;
-
-public:
-
- FixedHeightmap m_child;
-
- OneChildHeightmap(s16 blocksize):
- m_blocksize(blocksize),
- m_child(this, v2s16(0,0), blocksize)
- {
- }
-
- f32 getGroundHeight(v2s16 p, bool generate=true)
- {
- if(p.X < 0 || p.X > m_blocksize
- || p.Y < 0 || p.Y > m_blocksize)
- return GROUNDHEIGHT_NOTFOUND_SETVALUE;
- return m_child.getGroundHeight(p);
- }
- void setGroundHeight(v2s16 p, f32 y, bool generate=true)
- {
- //dstream<<"OneChildHeightmap::setGroundHeight()"<<std::endl;
- if(p.X < 0 || p.X > m_blocksize
- || p.Y < 0 || p.Y > m_blocksize)
- throw InvalidPositionException();
- m_child.setGroundHeight(p, y);
- }
-};
-
-
-/*
- This is a dynamic container of an arbitrary number of heightmaps
- at arbitrary positions.
-
- It is able to redirect queries to the corresponding heightmaps and
- it generates new heightmaps on-the-fly according to the relevant
- parameters.
-
- It doesn't have a master heightmap because it is meant to be used
- as such itself.
-
- Child heightmaps are spaced at m_blocksize distances, and are of
- size (m_blocksize+1)*(m_blocksize+1)
-
- This is used as the master heightmap of a Map object.
-*/
-class UnlimitedHeightmap: public Heightmap
-{
-private:
-
- core::map<v2s16, FixedHeightmap*> m_heightmaps;
- s16 m_blocksize;
-
- // TODO: Remove ValueGenerators
- /*ValueGenerator *m_randmax_generator;
- ValueGenerator *m_randfactor_generator;
- ValueGenerator *m_base_generator;*/
-
- PointAttributeDatabase *m_padb;
-
-public:
-
- UnlimitedHeightmap(
- s16 blocksize,
- /*ValueGenerator *randmax_generator,
- ValueGenerator *randfactor_generator,
- ValueGenerator *base_generator,*/
- PointAttributeDatabase *padb
- ):
- m_blocksize(blocksize),
- /*m_randmax_generator(randmax_generator),
- m_randfactor_generator(randfactor_generator),
- m_base_generator(base_generator),*/
- m_padb(padb)
- {
- /*assert(m_randmax_generator != NULL);
- assert(m_randfactor_generator != NULL);
- assert(m_base_generator != NULL);*/
- assert(m_padb);
- }
-
- ~UnlimitedHeightmap()
- {
- core::map<v2s16, FixedHeightmap*>::Iterator i;
- i = m_heightmaps.getIterator();
- for(; i.atEnd() == false; i++)
- {
- delete i.getNode()->getValue();
- }
-
- /*delete m_randmax_generator;
- delete m_randfactor_generator;
- delete m_base_generator;*/
- }
-
- void print();
-
- v2s16 getNodeHeightmapPos(v2s16 p)
- {
- return v2s16(
- (p.X>=0 ? p.X : p.X-m_blocksize+1) / m_blocksize,
- (p.Y>=0 ? p.Y : p.Y-m_blocksize+1) / m_blocksize);
- }
-
- // Can throw an InvalidPositionException
- FixedHeightmap * getHeightmap(v2s16 p, bool generate=true);
-
- f32 getGroundHeight(v2s16 p, bool generate=true);
- void setGroundHeight(v2s16 p, f32 y, bool generate=true);
-
- /*static UnlimitedHeightmap * deSerialize(u8 *source, u32 maxsize,
- u32 &usedsize, u8 version);*/
-
- //SharedBuffer<u8> serialize(u8 version);
- void serialize(std::ostream &os, u8 version);
- static UnlimitedHeightmap * deSerialize(std::istream &istr,
- PointAttributeDatabase *padb);
-};
-
-#endif
-