summaryrefslogtreecommitdiff
path: root/src/heightmap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/heightmap.cpp')
-rw-r--r--src/heightmap.cpp313
1 files changed, 234 insertions, 79 deletions
diff --git a/src/heightmap.cpp b/src/heightmap.cpp
index 2f7ecc4dc..bb7f2a1d1 100644
--- a/src/heightmap.cpp
+++ b/src/heightmap.cpp
@@ -23,6 +23,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "heightmap.h"
+// For MAP_BLOCKSIZE
+#include "mapblock.h"
+
/*
ValueGenerator
*/
@@ -259,59 +262,6 @@ void FixedHeightmap::generateContinued(f32 randmax, f32 randfactor,
}
/*
- Seed borders from master heightmap
- NOTE: Does this actually have any effect on the output?
- */
- /*struct SeedSpec
- {
- v2s16 neighbour_start;
- v2s16 heightmap_start;
- v2s16 dir;
- };
-
- SeedSpec seeds[4] =
- {
- { // Z- edge on X-axis
- v2s16(0, -1), // neighbour_start
- v2s16(0, 0), // heightmap_start
- v2s16(1, 0) // dir
- },
- { // Z+ edge on X-axis
- v2s16(0, m_blocksize),
- v2s16(0, m_blocksize),
- v2s16(1, 0)
- },
- { // X- edge on Z-axis
- v2s16(-1, 0),
- v2s16(0, 0),
- v2s16(0, 1)
- },
- { // X+ edge on Z-axis
- v2s16(m_blocksize, 0),
- v2s16(m_blocksize, 0),
- v2s16(0, 1)
- },
- };
-
- for(s16 i=0; i<4; i++){
- v2s16 npos = seeds[i].neighbour_start + m_pos_on_master * m_blocksize;
- v2s16 hpos = seeds[i].heightmap_start;
- for(s16 s=0; s<m_blocksize+1; s++){
- f32 h = m_master->getGroundHeight(npos, false);
- //dstream<<"h="<<h<<std::endl;
- if(h < GROUNDHEIGHT_VALID_MINVALUE)
- continue;
- //break;
- setGroundHeight(hpos, h);
- hpos += seeds[i].dir;
- npos += seeds[i].dir;
- }
- }*/
-
- /*dstream<<"borders seeded:"<<std::endl;
- print();*/
-
- /*
Fill with corners[] (if not already set)
*/
v2s16 dirs[4] = {
@@ -549,29 +499,51 @@ FixedHeightmap * UnlimitedHeightmap::getHeightmap(v2s16 p_from, bool generate)
m_heightmaps.insert(p, heightmap);
f32 corners[4];
-
- if(m_palist)
+
+ s32 div = SECTOR_HEIGHTMAP_SPLIT * MAP_BLOCKSIZE;
+
{
- //TODO: palist must be taken into account in generateContinued.
- // It is almost useless in here.
- s32 div = 2 * 16;
- Settings *attr = m_palist->getNearAttr(p / div);
- assert(attr);
- corners[0] = attr->getFloat("baseheight");
- corners[1] = attr->getFloat("baseheight");
- corners[2] = attr->getFloat("baseheight");
- corners[3] = attr->getFloat("baseheight");
+ PointAttributeList *palist = m_padb->getList("hm_baseheight");
+
+ if(palist->empty())
+ {
+ corners[0] = 0;
+ corners[1] = 0;
+ corners[2] = 0;
+ corners[3] = 0;
+ }
+ else
+ {
+#if 0
+ corners[0] = palist->getNearAttr((p+v2s16(0,0)) * div).getFloat();
+ corners[1] = palist->getNearAttr((p+v2s16(1,0)) * div).getFloat();
+ corners[2] = palist->getNearAttr((p+v2s16(1,1)) * div).getFloat();
+ corners[3] = palist->getNearAttr((p+v2s16(0,1)) * div).getFloat();
+#endif
+#if 1
+ corners[0] = palist->getInterpolatedFloat((p+v2s16(0,0))*div);
+ corners[1] = palist->getInterpolatedFloat((p+v2s16(1,0))*div);
+ corners[2] = palist->getInterpolatedFloat((p+v2s16(1,1))*div);
+ corners[3] = palist->getInterpolatedFloat((p+v2s16(0,1))*div);
+#endif
+ }
}
- else
+ /*else
{
corners[0] = m_base_generator->getValue(p+v2s16(0,0));
corners[1] = m_base_generator->getValue(p+v2s16(1,0));
corners[2] = m_base_generator->getValue(p+v2s16(1,1));
corners[3] = m_base_generator->getValue(p+v2s16(0,1));
- }
+ }*/
+
+ /*f32 randmax = m_randmax_generator->getValue(p);
+ f32 randfactor = m_randfactor_generator->getValue(p);*/
- f32 randmax = m_randmax_generator->getValue(p);
- f32 randfactor = m_randfactor_generator->getValue(p);
+ f32 randmax = m_padb->getList("hm_randmax")
+ ->getInterpolatedFloat(p*div);
+ f32 randfactor = m_padb->getList("hm_randfactor")
+ ->getInterpolatedFloat(p*div);
+ //dstream<<"randmax="<<randmax<<" randfactor="<<randfactor<<std::endl;
heightmap->generateContinued(randmax, randfactor, corners);
}
@@ -702,6 +674,148 @@ void UnlimitedHeightmap::serialize(std::ostream &os, u8 version)
/*if(m_base_generator->getId() != VALUE_GENERATOR_ID_CONSTANT
|| m_randmax_generator->getId() != VALUE_GENERATOR_ID_CONSTANT
|| m_randfactor_generator->getId() != VALUE_GENERATOR_ID_CONSTANT)*/
+ /*if(std::string(m_base_generator->getName()) != "constant"
+ || std::string(m_randmax_generator->getName()) != "constant"
+ || std::string(m_randfactor_generator->getName()) != "constant")
+ {
+ throw SerializationError
+ ("Cannot write UnlimitedHeightmap in old version: "
+ "Generators are not ConstantGenerators.");
+ }*/
+
+ // Dummy values
+ f32 basevalue = 0.0;
+ f32 randmax = 0.0;
+ f32 randfactor = 0.0;
+
+ // Write version
+ os.write((char*)&version, 1);
+
+ /*
+ [0] u16 blocksize
+ [2] s32 randmax*1000
+ [6] s32 randfactor*1000
+ [10] s32 basevalue*1000
+ [14] u32 heightmap_count
+ [18] X * (v2s16 pos + heightmap)
+ */
+ u32 heightmap_size =
+ FixedHeightmap::serializedLength(version, m_blocksize);
+ u32 heightmap_count = m_heightmaps.size();
+
+ //dstream<<"heightmap_size="<<heightmap_size<<std::endl;
+
+ u32 datasize = 2+4+4+4+4+heightmap_count*(4+heightmap_size);
+ SharedBuffer<u8> data(datasize);
+
+ writeU16(&data[0], m_blocksize);
+ writeU32(&data[2], (s32)(randmax*1000.0));
+ writeU32(&data[6], (s32)(randfactor*1000.0));
+ writeU32(&data[10], (s32)(basevalue*1000.0));
+ writeU32(&data[14], heightmap_count);
+
+ core::map<v2s16, FixedHeightmap*>::Iterator j;
+ j = m_heightmaps.getIterator();
+ u32 i=0;
+ for(; j.atEnd() == false; j++)
+ {
+ FixedHeightmap *hm = j.getNode()->getValue();
+ v2s16 pos = j.getNode()->getKey();
+ writeV2S16(&data[18+i*(4+heightmap_size)], pos);
+ hm->serialize(&data[18+i*(4+heightmap_size)+4], version);
+ i++;
+ }
+
+ os.write((char*)*data, data.getSize());
+ }
+ else if(version <= 11)
+ {
+ // Write version
+ os.write((char*)&version, 1);
+
+ u8 buf[4];
+
+ writeU16(buf, m_blocksize);
+ os.write((char*)buf, 2);
+
+ /*m_randmax_generator->serialize(os);
+ m_randfactor_generator->serialize(os);
+ m_base_generator->serialize(os);*/
+ os<<"constant 0.0\n";
+ os<<"constant 0.0\n";
+ os<<"constant 0.0\n";
+
+ u32 heightmap_count = m_heightmaps.size();
+ writeU32(buf, heightmap_count);
+ os.write((char*)buf, 4);
+
+ u32 heightmap_size =
+ FixedHeightmap::serializedLength(version, m_blocksize);
+
+ SharedBuffer<u8> hmdata(heightmap_size);
+
+ core::map<v2s16, FixedHeightmap*>::Iterator j;
+ j = m_heightmaps.getIterator();
+ u32 i=0;
+ for(; j.atEnd() == false; j++)
+ {
+ v2s16 pos = j.getNode()->getKey();
+ writeV2S16(buf, pos);
+ os.write((char*)buf, 4);
+
+ FixedHeightmap *hm = j.getNode()->getValue();
+ hm->serialize(*hmdata, version);
+ os.write((char*)*hmdata, hmdata.getSize());
+
+ i++;
+ }
+ }
+ else
+ {
+ // Write version
+ os.write((char*)&version, 1);
+
+ u8 buf[4];
+
+ writeU16(buf, m_blocksize);
+ os.write((char*)buf, 2);
+
+ /*m_randmax_generator->serialize(os);
+ m_randfactor_generator->serialize(os);
+ m_base_generator->serialize(os);*/
+
+ u32 heightmap_count = m_heightmaps.size();
+ writeU32(buf, heightmap_count);
+ os.write((char*)buf, 4);
+
+ u32 heightmap_size =
+ FixedHeightmap::serializedLength(version, m_blocksize);
+
+ SharedBuffer<u8> hmdata(heightmap_size);
+
+ core::map<v2s16, FixedHeightmap*>::Iterator j;
+ j = m_heightmaps.getIterator();
+ u32 i=0;
+ for(; j.atEnd() == false; j++)
+ {
+ v2s16 pos = j.getNode()->getKey();
+ writeV2S16(buf, pos);
+ os.write((char*)buf, 4);
+
+ FixedHeightmap *hm = j.getNode()->getValue();
+ hm->serialize(*hmdata, version);
+ os.write((char*)*hmdata, hmdata.getSize());
+
+ i++;
+ }
+ }
+
+#if 0
+ if(version <= 7)
+ {
+ /*if(m_base_generator->getId() != VALUE_GENERATOR_ID_CONSTANT
+ || m_randmax_generator->getId() != VALUE_GENERATOR_ID_CONSTANT
+ || m_randfactor_generator->getId() != VALUE_GENERATOR_ID_CONSTANT)*/
if(std::string(m_base_generator->getName()) != "constant"
|| std::string(m_randmax_generator->getName()) != "constant"
|| std::string(m_randfactor_generator->getName()) != "constant")
@@ -797,9 +911,11 @@ void UnlimitedHeightmap::serialize(std::ostream &os, u8 version)
i++;
}
}
+#endif
}
-UnlimitedHeightmap * UnlimitedHeightmap::deSerialize(std::istream &is)
+UnlimitedHeightmap * UnlimitedHeightmap::deSerialize(std::istream &is,
+ PointAttributeDatabase *padb)
{
u8 version;
is.read((char*)&version, 1);
@@ -823,9 +939,10 @@ UnlimitedHeightmap * UnlimitedHeightmap::deSerialize(std::istream &is)
throw SerializationError
("UnlimitedHeightmap::deSerialize: no enough input data");
s16 blocksize = readU16(&data[0]);
- f32 randmax = (f32)readU32(&data[2]) / 1000.0;
- f32 randfactor = (f32)readU32(&data[6]) / 1000.0;
- f32 basevalue = (f32)readU32(&data[10]) / 1000.0;
+ // Dummy read randmax, randfactor, basevalue
+ /*f32 randmax = (f32)*/readU32(&data[2]) /*/ 1000.0*/;
+ /*f32 randfactor = (f32)*/readU32(&data[6]) /*/ 1000.0*/;
+ /*f32 basevalue = (f32)*/readU32(&data[10]) /*/ 1000.0*/;
u32 heightmap_count = readU32(&data[14]);
/*dstream<<"UnlimitedHeightmap::deSerialize():"
@@ -838,12 +955,12 @@ UnlimitedHeightmap * UnlimitedHeightmap::deSerialize(std::istream &is)
//dstream<<"heightmap_size="<<heightmap_size<<std::endl;
- ValueGenerator *maxgen = new ConstantGenerator(randmax);
+ /*ValueGenerator *maxgen = new ConstantGenerator(randmax);
ValueGenerator *factorgen = new ConstantGenerator(randfactor);
- ValueGenerator *basegen = new ConstantGenerator(basevalue);
-
+ ValueGenerator *basegen = new ConstantGenerator(basevalue);*/
+
UnlimitedHeightmap *hm = new UnlimitedHeightmap
- (blocksize, maxgen, factorgen, basegen, NULL);
+ (blocksize, padb);
for(u32 i=0; i<heightmap_count; i++)
{
@@ -862,6 +979,44 @@ UnlimitedHeightmap * UnlimitedHeightmap::deSerialize(std::istream &is)
}
return hm;
}
+ else if(version <= 11)
+ {
+ u8 buf[4];
+
+ is.read((char*)buf, 2);
+ s16 blocksize = readU16(buf);
+
+ // Dummy-read three lines (generators)
+ std::string templine;
+ std::getline(is, templine, '\n');
+
+ is.read((char*)buf, 4);
+ u32 heightmap_count = readU32(buf);
+
+ u32 heightmap_size =
+ FixedHeightmap::serializedLength(version, blocksize);
+
+ UnlimitedHeightmap *hm = new UnlimitedHeightmap
+ (blocksize, padb);
+
+ for(u32 i=0; i<heightmap_count; i++)
+ {
+ is.read((char*)buf, 4);
+ v2s16 pos = readV2S16(buf);
+
+ SharedBuffer<u8> data(heightmap_size);
+ is.read((char*)*data, heightmap_size);
+ if(is.gcount() != (s32)(heightmap_size)){
+ delete hm;
+ throw SerializationError
+ ("UnlimitedHeightmap::deSerialize: no enough input data");
+ }
+ FixedHeightmap *f = new FixedHeightmap(hm, pos, blocksize);
+ f->deSerialize(*data, version);
+ hm->m_heightmaps.insert(pos, f);
+ }
+ return hm;
+ }
else
{
u8 buf[4];
@@ -869,9 +1024,9 @@ UnlimitedHeightmap * UnlimitedHeightmap::deSerialize(std::istream &is)
is.read((char*)buf, 2);
s16 blocksize = readU16(buf);
- ValueGenerator *maxgen = ValueGenerator::deSerialize(is);
+ /*ValueGenerator *maxgen = ValueGenerator::deSerialize(is);
ValueGenerator *factorgen = ValueGenerator::deSerialize(is);
- ValueGenerator *basegen = ValueGenerator::deSerialize(is);
+ ValueGenerator *basegen = ValueGenerator::deSerialize(is);*/
is.read((char*)buf, 4);
u32 heightmap_count = readU32(buf);
@@ -880,7 +1035,7 @@ UnlimitedHeightmap * UnlimitedHeightmap::deSerialize(std::istream &is)
FixedHeightmap::serializedLength(version, blocksize);
UnlimitedHeightmap *hm = new UnlimitedHeightmap
- (blocksize, maxgen, factorgen, basegen, NULL);
+ (blocksize, padb);
for(u32 i=0; i<heightmap_count; i++)
{