X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fmapblock.h;h=30e9e38f81e9cc9285995a51012ec4304e51d70e;hb=96e09703ba461923c2d8ffa3aeed8c6d0169b13f;hp=48f8775519fe8e47b713dba47e43beda4a6c9b2e;hpb=c707e00195f1035ae535f3fc8697af42e73190c0;p=dragonfireclient.git diff --git a/src/mapblock.h b/src/mapblock.h index 48f877551..30e9e38f8 100644 --- a/src/mapblock.h +++ b/src/mapblock.h @@ -1,5 +1,20 @@ /* -(c) 2010 Perttu Ahola +Minetest-c55 +Copyright (C) 2010 celeron55, Perttu Ahola + +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 MAPBLOCK_HEADER @@ -15,8 +30,10 @@ #include "serialization.h" #include "constants.h" #include "mapblockobject.h" +#include "voxel.h" +#include "nodemetadata.h" +#include "staticobject.h" -#define MAP_BLOCKSIZE 16 // Named by looking towards z+ enum{ @@ -30,10 +47,100 @@ enum{ struct FastFace { - u8 material; + TileSpec tile; video::S3DVertex vertices[4]; // Precalculated vertices }; +enum NodeModType +{ + NODEMOD_NONE, + NODEMOD_CHANGECONTENT, //param is content id + NODEMOD_CRACK // param is crack progression +}; + +struct NodeMod +{ + NodeMod(enum NodeModType a_type=NODEMOD_NONE, u16 a_param=0) + { + type = a_type; + param = a_param; + } + bool operator==(const NodeMod &other) + { + return (type == other.type && param == other.param); + } + enum NodeModType type; + 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::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::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::Iterator + i = m_mods.getIterator(); + i.atEnd() == false; i++) + { + dest.m_mods.insert(i.getNode()->getKey(), i.getNode()->getValue()); + } + } + +private: + core::map m_mods; +}; + enum { NODECONTAINER_ID_MAPBLOCK, @@ -50,97 +157,87 @@ class NodeContainer virtual MapNode getNode(v3s16 p) = 0; virtual void setNode(v3s16 p, MapNode & n) = 0; virtual u16 nodeContainerId() const = 0; + + MapNode getNodeNoEx(v3s16 p) + { + try{ + return getNode(p); + } + catch(InvalidPositionException &e){ + return MapNode(CONTENT_IGNORE); + } + } }; -class MapBlock : public NodeContainer -{ -private: +/* + Mesh making stuff +*/ - 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. - */ - bool changed; - /* - Used for some initial lighting stuff. - At least /has been/ used. 8) - */ - bool is_underground; - - MapBlockObjectList m_objects; - -public: +class MapBlock; +#ifndef SERVER + +struct MeshMakeData +{ + u32 m_daynight_ratio; + NodeModMap m_temp_mods; + VoxelManipulator m_vmanip; + v3s16 m_blockpos; + /* - This used by Server's block creation stuff for not sending - blocks that are waiting a lighting update. + Copy central data directly from block, and other data from + parent of block. + */ + void fill(u32 daynight_ratio, MapBlock *block); +}; - If true, the block needs some work by the one who set this - to true. +scene::SMesh* makeMapBlockMesh(MeshMakeData *data); - While true, nobody else should touch the block. - */ - //bool is_incomplete; - - scene::SMesh *mesh; - JMutex mesh_mutex; +#endif - MapBlock(NodeContainer *parent, v3s16 pos, bool dummy=false): - m_parent(parent), - m_pos(pos), - changed(true), - is_underground(false), - m_objects(this) - //is_incomplete(false) - { - data = NULL; - if(dummy == false) - reallocate(); - mesh_mutex.Init(); - mesh = NULL; - } +u8 getFaceLight(u32 daynight_ratio, MapNode n, MapNode n2, + v3s16 face_dir); - ~MapBlock() - { - { - JMutexAutoLock lock(mesh_mutex); - - if(mesh != NULL) - { - mesh->drop(); - mesh = NULL; - } - } +/* + MapBlock itself +*/ - if(data) - delete[] data; - } +class MapBlock : public NodeContainer +{ +public: + MapBlock(NodeContainer *parent, v3s16 pos, bool dummy=false); + ~MapBlock(); virtual u16 nodeContainerId() const { return NODECONTAINER_ID_MAPBLOCK; } - + NodeContainer * getParent() { return m_parent; } + void reallocate() + { + if(data != NULL) + delete[] data; + u32 l = MAP_BLOCKSIZE * MAP_BLOCKSIZE * MAP_BLOCKSIZE; + data = new MapNode[l]; + for(u32 i=0; i getBox() { return core::aabbox3d(getPosRelative(), @@ -190,19 +330,11 @@ class MapBlock : public NodeContainer + v3s16(MAP_BLOCKSIZE, MAP_BLOCKSIZE, MAP_BLOCKSIZE) - v3s16(1,1,1)); } - - void reallocate() - { - if(data != NULL) - delete[] data; - u32 l = MAP_BLOCKSIZE * MAP_BLOCKSIZE * MAP_BLOCKSIZE; - data = new MapNode[l]; - for(u32 i=0; i= 0 && p.Z < MAP_BLOCKSIZE); } - /* - Regular MapNode get-setters - */ - MapNode getNode(s16 x, s16 y, s16 z) { if(data == NULL) @@ -283,6 +411,7 @@ class MapBlock : public NodeContainer bool isValidPositionParent(v3s16 p); MapNode getNodeParent(v3s16 p); void setNodeParent(v3s16 p, MapNode & n); + MapNode getNodeParentNoEx(v3s16 p); void drawbox(s16 x0, s16 y0, s16 z0, s16 w, s16 h, s16 d, MapNode node) { @@ -292,36 +421,84 @@ class MapBlock : public NodeContainer setNode(x0+x, y0+y, z0+z, node); } - static FastFace * makeFastFace(u8 material, u8 light, v3f p, - v3f dir, v3f scale, v3f posRelative_f); - - u8 getFaceLight(v3s16 p, v3s16 face_dir); - /* - Gets node material from any place relative to block. - Returns MATERIAL_AIR if doesn't exist. + Graphics-related methods */ - u8 getNodeMaterial(v3s16 p); + + /*// 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, + getNodeParentNoEx(p), + getNodeParentNoEx(p + face_dir), + face_dir); + }*/ + u8 getFaceLight2(u32 daynight_ratio, v3s16 p, v3s16 face_dir) + { + return getFaceLight(daynight_ratio, + getNodeParentNoEx(p), + getNodeParentNoEx(p + face_dir), + face_dir); + } + +#ifndef SERVER + // light = 0...255 + /*static void makeFastFace(TileSpec tile, u8 light, v3f p, + v3s16 dir, v3f scale, v3f posRelative_f, + core::array &dest);*/ + + /*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 */ - void updateFastFaceRow(v3s16 startpos, + /*void updateFastFaceRow( + u32 daynight_ratio, + v3f posRelative_f, + v3s16 startpos, u16 length, v3s16 translate_dir, + v3f translate_dir_f, v3s16 face_dir, - core::list &dest); - - void updateMesh(); + v3f face_dir_f, + core::array &dest, + NodeModMap &temp_mods);*/ + + /* + Thread-safely updates the whole mesh of the mapblock. + */ +#if 1 + void updateMesh(u32 daynight_ratio); +#endif - bool propagateSunlight(core::map & light_sources); + void replaceMesh(scene::SMesh *mesh_new); - // Doesn't write version by itself - void serialize(std::ostream &os, u8 version); +#endif // !SERVER + + // See comments in mapblock.cpp + bool propagateSunlight(core::map & light_sources, + bool remove_light=false, bool *black_air_left=NULL, + bool grow_grass=false); + + // Copies data to VoxelManipulator to getPosRelative() + void copyTo(VoxelManipulator &dst); + // Copies data from VoxelManipulator getPosRelative() + void copyFrom(VoxelManipulator &dst); - void deSerialize(std::istream &is, u8 version); + /* + MapBlockObject stuff + */ void serializeObjects(std::ostream &os, u8 version) { @@ -329,9 +506,9 @@ class MapBlock : public NodeContainer } // If smgr!=NULL, new objects are added to the scene void updateObjects(std::istream &is, u8 version, - scene::ISceneManager *smgr) + scene::ISceneManager *smgr, u32 daynight_ratio) { - m_objects.update(is, version, smgr); + m_objects.update(is, version, smgr, daynight_ratio); setChangedFlag(); } @@ -362,12 +539,11 @@ class MapBlock : public NodeContainer { return m_objects.getLock(); } - void stepObjects(float dtime, bool server) - { - m_objects.step(dtime, server); - setChangedFlag(); - } + /* + Moves objects, deletes objects and spawns new objects + */ + void stepObjects(float dtime, bool server, u32 daynight_ratio); /*void wrapObject(MapBlockObject *object) { @@ -388,7 +564,94 @@ class MapBlock : public NodeContainer return m_objects.getCount(); } +#ifndef SERVER + /* + Methods for setting temporary modifications to nodes for + drawing + + returns true if the mod was different last time + */ + bool setTempMod(v3s16 p, const NodeMod &mod) + { + /*dstream<<"setTempMod called on block" + <<" ("<