X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fmapblock.h;h=22b3b7db6189d986c947d9ac50c393f4f53fe909;hb=fe98fe342a65c995bbc59470549417f38311366b;hp=48f8775519fe8e47b713dba47e43beda4a6c9b2e;hpb=c707e00195f1035ae535f3fc8697af42e73190c0;p=minetest.git diff --git a/src/mapblock.h b/src/mapblock.h index 48f877551..22b3b7db6 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 @@ -14,11 +29,19 @@ #include "exceptions.h" #include "serialization.h" #include "constants.h" -#include "mapblockobject.h" +#include "voxel.h" +#include "nodemetadata.h" +#include "staticobject.h" +#include "mapblock_nodemod.h" +#ifndef SERVER + #include "mapblock_mesh.h" +#endif + +class Map; -#define MAP_BLOCKSIZE 16 +#define BLOCK_TIMESTAMP_UNDEFINED 0xffffffff -// Named by looking towards z+ +/*// Named by looking towards z+ enum{ FACE_BACK=0, FACE_TOP, @@ -26,14 +49,39 @@ enum{ FACE_FRONT, FACE_BOTTOM, FACE_LEFT -}; +};*/ -struct FastFace +enum ModifiedState { - u8 material; - video::S3DVertex vertices[4]; // Precalculated vertices + // Has not been modified. + MOD_STATE_CLEAN = 0, + MOD_RESERVED1 = 1, + // Has been modified, and will be saved when being unloaded. + MOD_STATE_WRITE_AT_UNLOAD = 2, + MOD_RESERVED3 = 3, + // Has been modified, and will be saved as soon as possible. + MOD_STATE_WRITE_NEEDED = 4, + MOD_RESERVED5 = 5, }; +// NOTE: If this is enabled, set MapBlock to be initialized with +// CONTENT_IGNORE. +/*enum BlockGenerationStatus +{ + // Completely non-generated (filled with CONTENT_IGNORE). + BLOCKGEN_UNTOUCHED=0, + // Trees or similar might have been blitted from other blocks to here. + // Otherwise, the block contains CONTENT_IGNORE + BLOCKGEN_FROM_NEIGHBORS=2, + // Has been generated, but some neighbors might put some stuff in here + // when they are generated. + // Does not contain any CONTENT_IGNORE + BLOCKGEN_SELF_GENERATED=4, + // The block and all its neighbors have been generated + BLOCKGEN_FULLY_GENERATED=6 +};*/ + +#if 0 enum { NODECONTAINER_ID_MAPBLOCK, @@ -50,139 +98,177 @@ 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); + } + } }; +#endif -class MapBlock : public NodeContainer -{ -private: +/* + MapBlock itself +*/ - 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; - +class MapBlock /*: public NodeContainer*/ +{ public: - - /* - This used by Server's block creation stuff for not sending - blocks that are waiting a lighting update. - - If true, the block needs some work by the one who set this - to true. - - While true, nobody else should touch the block. - */ - //bool is_incomplete; - - scene::SMesh *mesh; - JMutex mesh_mutex; - - 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; - } - - ~MapBlock() - { - { - JMutexAutoLock lock(mesh_mutex); - - if(mesh != NULL) - { - mesh->drop(); - mesh = NULL; - } - } - - if(data) - delete[] data; - } + MapBlock(Map *parent, v3s16 pos, bool dummy=false); + ~MapBlock(); - virtual u16 nodeContainerId() const + /*virtual u16 nodeContainerId() const { return NODECONTAINER_ID_MAPBLOCK; + }*/ + + Map * getParent() + { + return m_parent; } - NodeContainer * getParent() + void reallocate() { - return m_parent; + 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 +276,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) @@ -231,6 +305,15 @@ class MapBlock : public NodeContainer return getNode(p.X, p.Y, p.Z); } + MapNode getNodeNoEx(v3s16 p) + { + try{ + return getNode(p.X, p.Y, p.Z); + }catch(InvalidPositionException &e){ + return MapNode(CONTENT_IGNORE); + } + } + void setNode(s16 x, s16 y, s16 z, MapNode & n) { if(data == NULL) @@ -239,7 +322,7 @@ class MapBlock : public NodeContainer if(y < 0 || y >= MAP_BLOCKSIZE) throw InvalidPositionException(); if(z < 0 || z >= MAP_BLOCKSIZE) throw InvalidPositionException(); data[z*MAP_BLOCKSIZE*MAP_BLOCKSIZE + y*MAP_BLOCKSIZE + x] = n; - setChangedFlag(); + raiseModified(MOD_STATE_WRITE_NEEDED); } void setNode(v3s16 p, MapNode & n) @@ -268,7 +351,7 @@ class MapBlock : public NodeContainer if(data == NULL) throw InvalidPositionException(); data[z*MAP_BLOCKSIZE*MAP_BLOCKSIZE + y*MAP_BLOCKSIZE + x] = n; - setChangedFlag(); + raiseModified(MOD_STATE_WRITE_NEEDED); } void setNodeNoCheck(v3s16 p, MapNode & n) @@ -283,6 +366,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,103 +376,176 @@ 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 // Only on client +#if 1 /* - startpos: - translate_dir: unit vector with only one of x, y or z - face_dir: unit vector with only one of x, y or z + Thread-safely updates the whole mesh of the mapblock. + NOTE: Prefer generating the mesh separately and then using + replaceMesh(). */ - void updateFastFaceRow(v3s16 startpos, - u16 length, - v3s16 translate_dir, - v3s16 face_dir, - core::list &dest); - - void updateMesh(); - - bool propagateSunlight(core::map & light_sources); + void updateMesh(u32 daynight_ratio); +#endif + // Replace the mesh with a new one + void replaceMesh(scene::SMesh *mesh_new); +#endif - // Doesn't write version by itself - void serialize(std::ostream &os, u8 version); - - void deSerialize(std::istream &is, u8 version); + // See comments in mapblock.cpp + bool propagateSunlight(core::map & light_sources, + bool remove_light=false, bool *black_air_left=NULL); - void serializeObjects(std::ostream &os, u8 version) + // Copies data to VoxelManipulator to getPosRelative() + void copyTo(VoxelManipulator &dst); + // Copies data from VoxelManipulator getPosRelative() + void copyFrom(VoxelManipulator &dst); + +#ifndef SERVER // Only on client + /* + 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) { - m_objects.serialize(os, version); + /*dstream<<"setTempMod called on block" + <<" ("<