mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
map generation framework under development... not quite operational at this point.
This commit is contained in:
parent
8788fffec0
commit
be851871cd
13 changed files with 965 additions and 372 deletions
370
src/mapblock.h
370
src/mapblock.h
|
@ -70,6 +70,74 @@ struct NodeMod
|
|||
u16 param;
|
||||
};
|
||||
|
||||
class NodeModMap
|
||||
{
|
||||
public:
|
||||
/*
|
||||
returns true if the mod was different last time
|
||||
*/
|
||||
bool set(v3s16 p, const NodeMod &mod)
|
||||
{
|
||||
// See if old is different, cancel if it is not different.
|
||||
core::map<v3s16, NodeMod>::Node *n = m_mods.find(p);
|
||||
if(n)
|
||||
{
|
||||
NodeMod old = n->getValue();
|
||||
if(old == mod)
|
||||
return false;
|
||||
|
||||
n->setValue(mod);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mods.insert(p, mod);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
// Returns true if there was one
|
||||
bool get(v3s16 p, NodeMod *mod)
|
||||
{
|
||||
core::map<v3s16, NodeMod>::Node *n;
|
||||
n = m_mods.find(p);
|
||||
if(n == NULL)
|
||||
return false;
|
||||
if(mod)
|
||||
*mod = n->getValue();
|
||||
return true;
|
||||
}
|
||||
bool clear(v3s16 p)
|
||||
{
|
||||
if(m_mods.find(p))
|
||||
{
|
||||
m_mods.remove(p);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool clear()
|
||||
{
|
||||
if(m_mods.size() == 0)
|
||||
return false;
|
||||
m_mods.clear();
|
||||
return true;
|
||||
}
|
||||
void copy(NodeModMap &dest)
|
||||
{
|
||||
dest.m_mods.clear();
|
||||
|
||||
for(core::map<v3s16, NodeMod>::Iterator
|
||||
i = m_mods.getIterator();
|
||||
i.atEnd() == false; i++)
|
||||
{
|
||||
dest.m_mods.insert(i.getNode()->getKey(), i.getNode()->getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
core::map<v3s16, NodeMod> m_mods;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
NODECONTAINER_ID_MAPBLOCK,
|
||||
|
@ -104,71 +172,6 @@ public:
|
|||
return m_parent;
|
||||
}
|
||||
|
||||
bool isDummy()
|
||||
{
|
||||
return (data == NULL);
|
||||
}
|
||||
|
||||
void unDummify()
|
||||
{
|
||||
assert(isDummy());
|
||||
reallocate();
|
||||
}
|
||||
|
||||
bool getChangedFlag()
|
||||
{
|
||||
return changed;
|
||||
}
|
||||
|
||||
void resetChangedFlag()
|
||||
{
|
||||
changed = false;
|
||||
}
|
||||
|
||||
void setChangedFlag()
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
#ifndef SERVER
|
||||
void setMeshExpired(bool expired)
|
||||
{
|
||||
m_mesh_expired = expired;
|
||||
}
|
||||
|
||||
bool getMeshExpired()
|
||||
{
|
||||
return m_mesh_expired;
|
||||
}
|
||||
#endif
|
||||
v3s16 getPos()
|
||||
{
|
||||
return m_pos;
|
||||
}
|
||||
|
||||
v3s16 getPosRelative()
|
||||
{
|
||||
return m_pos * MAP_BLOCKSIZE;
|
||||
}
|
||||
|
||||
bool getIsUnderground()
|
||||
{
|
||||
return is_underground;
|
||||
}
|
||||
|
||||
void setIsUnderground(bool a_is_underground)
|
||||
{
|
||||
is_underground = a_is_underground;
|
||||
setChangedFlag();
|
||||
}
|
||||
|
||||
core::aabbox3d<s16> getBox()
|
||||
{
|
||||
return core::aabbox3d<s16>(getPosRelative(),
|
||||
getPosRelative()
|
||||
+ v3s16(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE)
|
||||
- v3s16(1,1,1));
|
||||
}
|
||||
|
||||
void reallocate()
|
||||
{
|
||||
if(data != NULL)
|
||||
|
@ -181,6 +184,101 @@ public:
|
|||
setChangedFlag();
|
||||
}
|
||||
|
||||
/*
|
||||
Flags
|
||||
*/
|
||||
|
||||
bool isDummy()
|
||||
{
|
||||
return (data == NULL);
|
||||
}
|
||||
void unDummify()
|
||||
{
|
||||
assert(isDummy());
|
||||
reallocate();
|
||||
}
|
||||
|
||||
bool getChangedFlag()
|
||||
{
|
||||
return changed;
|
||||
}
|
||||
void resetChangedFlag()
|
||||
{
|
||||
changed = false;
|
||||
}
|
||||
void setChangedFlag()
|
||||
{
|
||||
changed = true;
|
||||
}
|
||||
|
||||
bool getIsUnderground()
|
||||
{
|
||||
return is_underground;
|
||||
}
|
||||
|
||||
void setIsUnderground(bool a_is_underground)
|
||||
{
|
||||
is_underground = a_is_underground;
|
||||
setChangedFlag();
|
||||
}
|
||||
|
||||
#ifndef SERVER
|
||||
void setMeshExpired(bool expired)
|
||||
{
|
||||
m_mesh_expired = expired;
|
||||
}
|
||||
|
||||
bool getMeshExpired()
|
||||
{
|
||||
return m_mesh_expired;
|
||||
}
|
||||
#endif
|
||||
|
||||
void setLightingExpired(bool expired)
|
||||
{
|
||||
m_lighting_expired = expired;
|
||||
setChangedFlag();
|
||||
}
|
||||
bool getLightingExpired()
|
||||
{
|
||||
return m_lighting_expired;
|
||||
}
|
||||
|
||||
bool isValid()
|
||||
{
|
||||
if(m_lighting_expired)
|
||||
return false;
|
||||
if(data == NULL)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
Position stuff
|
||||
*/
|
||||
|
||||
v3s16 getPos()
|
||||
{
|
||||
return m_pos;
|
||||
}
|
||||
|
||||
v3s16 getPosRelative()
|
||||
{
|
||||
return m_pos * MAP_BLOCKSIZE;
|
||||
}
|
||||
|
||||
core::aabbox3d<s16> getBox()
|
||||
{
|
||||
return core::aabbox3d<s16>(getPosRelative(),
|
||||
getPosRelative()
|
||||
+ v3s16(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE)
|
||||
- v3s16(1,1,1));
|
||||
}
|
||||
|
||||
/*
|
||||
Regular MapNode get-setters
|
||||
*/
|
||||
|
||||
bool isValidPosition(v3s16 p)
|
||||
{
|
||||
if(data == NULL)
|
||||
|
@ -190,10 +288,6 @@ public:
|
|||
&& p.Z >= 0 && p.Z < MAP_BLOCKSIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
Regular MapNode get-setters
|
||||
*/
|
||||
|
||||
MapNode getNode(s16 x, s16 y, s16 z)
|
||||
{
|
||||
if(data == NULL)
|
||||
|
@ -271,9 +365,14 @@ public:
|
|||
setNode(x0+x, y0+y, z0+z, node);
|
||||
}
|
||||
|
||||
/*
|
||||
Graphics-related methods
|
||||
*/
|
||||
|
||||
// A quick version with nodes passed as parameters
|
||||
u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2,
|
||||
v3s16 face_dir);
|
||||
|
||||
// A more convenient version
|
||||
u8 getFaceLight(u32 daynight_ratio, v3s16 p, v3s16 face_dir)
|
||||
{
|
||||
return getFaceLight(daynight_ratio,
|
||||
|
@ -288,11 +387,16 @@ public:
|
|||
v3s16 dir, v3f scale, v3f posRelative_f,
|
||||
core::array<FastFace> &dest);
|
||||
|
||||
TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir);
|
||||
u8 getNodeContent(v3s16 p, MapNode mn);
|
||||
TileSpec getNodeTile(MapNode mn, v3s16 p, v3s16 face_dir,
|
||||
NodeModMap &temp_mods);
|
||||
u8 getNodeContent(v3s16 p, MapNode mn,
|
||||
NodeModMap &temp_mods);
|
||||
|
||||
/*
|
||||
startpos:
|
||||
Generates the FastFaces of a node row. This has a
|
||||
ridiculous amount of parameters because that way they
|
||||
can be precalculated by the caller.
|
||||
|
||||
translate_dir: unit vector with only one of x, y or z
|
||||
face_dir: unit vector with only one of x, y or z
|
||||
*/
|
||||
|
@ -305,12 +409,14 @@ public:
|
|||
v3f translate_dir_f,
|
||||
v3s16 face_dir,
|
||||
v3f face_dir_f,
|
||||
core::array<FastFace> &dest);
|
||||
|
||||
core::array<FastFace> &dest,
|
||||
NodeModMap &temp_mods);
|
||||
|
||||
/*
|
||||
Thread-safely updates the whole mesh of the mapblock.
|
||||
*/
|
||||
void updateMesh(u32 daynight_ratio);
|
||||
/*void updateMesh(s32 daynight_i);
|
||||
// Updates all DAYNIGHT_CACHE_COUNT meshes
|
||||
void updateMeshes(s32 first_i=0);*/
|
||||
|
||||
#endif // !SERVER
|
||||
|
||||
// See comments in mapblock.cpp
|
||||
|
@ -322,7 +428,7 @@ public:
|
|||
void copyTo(VoxelManipulator &dst);
|
||||
|
||||
/*
|
||||
Object stuff
|
||||
MapBlockObject stuff
|
||||
*/
|
||||
|
||||
void serializeObjects(std::ostream &os, u8 version)
|
||||
|
@ -384,9 +490,6 @@ public:
|
|||
m_objects.getObjects(origin, max_d, dest);
|
||||
}
|
||||
|
||||
/*void getPseudoObjects(v3f origin, f32 max_d,
|
||||
core::array<DistanceSortedObject> &dest);*/
|
||||
|
||||
s32 getObjectCount()
|
||||
{
|
||||
return m_objects.getCount();
|
||||
|
@ -399,7 +502,7 @@ public:
|
|||
|
||||
returns true if the mod was different last time
|
||||
*/
|
||||
bool setTempMod(v3s16 p, NodeMod mod)
|
||||
bool setTempMod(v3s16 p, const NodeMod &mod)
|
||||
{
|
||||
/*dstream<<"setTempMod called on block"
|
||||
<<" ("<<p.X<<","<<p.Y<<","<<p.Z<<")"
|
||||
|
@ -408,52 +511,33 @@ public:
|
|||
<<std::endl;*/
|
||||
JMutexAutoLock lock(m_temp_mods_mutex);
|
||||
|
||||
// See if old is different, cancel if it is not different.
|
||||
core::map<v3s16, NodeMod>::Node *n = m_temp_mods.find(p);
|
||||
if(n)
|
||||
{
|
||||
NodeMod old = n->getValue();
|
||||
if(old == mod)
|
||||
return false;
|
||||
}
|
||||
|
||||
m_temp_mods[p] = mod;
|
||||
return true;
|
||||
return m_temp_mods.set(p, mod);
|
||||
}
|
||||
// Returns true if there was one
|
||||
bool getTempMod(v3s16 p, struct NodeMod *mod)
|
||||
bool getTempMod(v3s16 p, NodeMod *mod)
|
||||
{
|
||||
JMutexAutoLock lock(m_temp_mods_mutex);
|
||||
core::map<v3s16, NodeMod>::Node *n;
|
||||
n = m_temp_mods.find(p);
|
||||
if(n == NULL)
|
||||
return false;
|
||||
if(mod)
|
||||
*mod = n->getValue();
|
||||
return true;
|
||||
|
||||
return m_temp_mods.get(p, mod);
|
||||
}
|
||||
bool clearTempMod(v3s16 p)
|
||||
{
|
||||
JMutexAutoLock lock(m_temp_mods_mutex);
|
||||
if(m_temp_mods.find(p))
|
||||
{
|
||||
m_temp_mods.remove(p);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
return m_temp_mods.clear(p);
|
||||
}
|
||||
bool clearTempMods()
|
||||
{
|
||||
JMutexAutoLock lock(m_temp_mods_mutex);
|
||||
if(m_temp_mods.size() == 0)
|
||||
return false;
|
||||
m_temp_mods.clear();
|
||||
return true;
|
||||
|
||||
return m_temp_mods.clear();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
Day-night lighting difference
|
||||
Update day-night lighting difference flag.
|
||||
|
||||
Sets m_day_night_differs to appropriate value.
|
||||
|
||||
These methods don't care about neighboring blocks.
|
||||
It means that to know if a block really doesn't need a mesh
|
||||
|
@ -490,17 +574,10 @@ public:
|
|||
|
||||
void deSerialize(std::istream &is, u8 version);
|
||||
|
||||
/*
|
||||
Public member variables
|
||||
*/
|
||||
|
||||
#ifndef SERVER
|
||||
//scene::SMesh *mesh[DAYNIGHT_CACHE_COUNT];
|
||||
scene::SMesh *mesh;
|
||||
JMutex mesh_mutex;
|
||||
#endif
|
||||
|
||||
private:
|
||||
/*
|
||||
Private methods
|
||||
*/
|
||||
|
||||
/*
|
||||
Used only internally, because changes can't be tracked
|
||||
|
@ -520,28 +597,58 @@ private:
|
|||
return getNodeRef(p.X, p.Y, p.Z);
|
||||
}
|
||||
|
||||
public:
|
||||
/*
|
||||
Public member variables
|
||||
*/
|
||||
|
||||
#ifndef SERVER
|
||||
scene::SMesh *mesh;
|
||||
JMutex mesh_mutex;
|
||||
#endif
|
||||
|
||||
private:
|
||||
/*
|
||||
Private member variables
|
||||
*/
|
||||
|
||||
// Parent container (practically the Map)
|
||||
// Not a MapSector, it is just a structural element.
|
||||
NodeContainer *m_parent;
|
||||
// Position in blocks on parent
|
||||
v3s16 m_pos;
|
||||
|
||||
/*
|
||||
If NULL, block is a dummy block.
|
||||
Dummy blocks are used for caching not-found-on-disk blocks.
|
||||
*/
|
||||
MapNode * data;
|
||||
|
||||
/*
|
||||
- On the client, this is used for checking whether to
|
||||
recalculate the face cache. (Is it anymore?)
|
||||
- On the server, this is used for telling whether the
|
||||
block has been changed from the one on disk.
|
||||
- On the client, this is used for nothing.
|
||||
*/
|
||||
bool changed;
|
||||
|
||||
/*
|
||||
Used for some initial lighting stuff.
|
||||
At least /has been/ used. 8)
|
||||
It's probably useless now.
|
||||
When propagating sunlight and the above block doesn't exist,
|
||||
sunlight is assumed if this is false.
|
||||
|
||||
In practice this is set to true if the block is completely
|
||||
undeground with nothing visible above the ground except
|
||||
caves.
|
||||
*/
|
||||
bool is_underground;
|
||||
|
||||
/*
|
||||
Set to true if changes has been made that make the old lighting
|
||||
values wrong but the lighting hasn't been actually updated.
|
||||
|
||||
If this is false, lighting is exactly right.
|
||||
If this is true, lighting might be wrong or right.
|
||||
*/
|
||||
bool m_lighting_expired;
|
||||
|
||||
// Whether day and night lighting differs
|
||||
bool m_day_night_differs;
|
||||
|
@ -552,11 +659,16 @@ private:
|
|||
float m_spawn_timer;
|
||||
|
||||
#ifndef SERVER
|
||||
/*
|
||||
Set to true if the mesh has been ordered to be updated
|
||||
sometime in the background.
|
||||
In practice this is set when the day/night lighting switches.
|
||||
*/
|
||||
bool m_mesh_expired;
|
||||
|
||||
// Temporary modifications to nodes
|
||||
// These are only used when drawing
|
||||
core::map<v3s16, NodeMod> m_temp_mods;
|
||||
NodeModMap m_temp_mods;
|
||||
JMutex m_temp_mods_mutex;
|
||||
#endif
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue