1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-07-02 16:38:41 +00:00

Initial commit of mapgen v.2. Lacks configuration and saving to disk.

This commit is contained in:
Perttu Ahola 2011-01-16 19:32:14 +02:00
parent 69e7cd9b5b
commit 7068bc90af
13 changed files with 1197 additions and 187 deletions

View file

@ -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
*/
@ -258,59 +261,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)
*/
@ -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);
}
@ -697,6 +669,148 @@ void UnlimitedHeightmap::serialize(std::ostream &os, u8 version)
throw VersionMismatchException
("ERROR: UnlimitedHeightmap format not supported");
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")
{
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
@ -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,16 +979,16 @@ UnlimitedHeightmap * UnlimitedHeightmap::deSerialize(std::istream &is)
}
return hm;
}
else
else if(version <= 11)
{
u8 buf[4];
is.read((char*)buf, 2);
s16 blocksize = readU16(buf);
ValueGenerator *maxgen = ValueGenerator::deSerialize(is);
ValueGenerator *factorgen = ValueGenerator::deSerialize(is);
ValueGenerator *basegen = ValueGenerator::deSerialize(is);
// Dummy-read three lines (generators)
std::string templine;
std::getline(is, templine, '\n');
is.read((char*)buf, 4);
u32 heightmap_count = readU32(buf);
@ -880,7 +997,45 @@ 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++)
{
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];
is.read((char*)buf, 2);
s16 blocksize = readU16(buf);
/*ValueGenerator *maxgen = ValueGenerator::deSerialize(is);
ValueGenerator *factorgen = ValueGenerator::deSerialize(is);
ValueGenerator *basegen = ValueGenerator::deSerialize(is);*/
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++)
{