X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fvoxel.h;h=52274ac19d4479960005ead8e9c8d5628aae4466;hb=5b55deb1ebfd55562a6a57fbdbf5dce86015ca86;hp=411cf4376e3e1ce45f57faf7ff10771caebd4823;hpb=47a593b5197393d8f8cdfe18b1aa46b8bc1f3fb6;p=dragonfireclient.git diff --git a/src/voxel.h b/src/voxel.h index 411cf4376..52274ac19 100644 --- a/src/voxel.h +++ b/src/voxel.h @@ -1,18 +1,18 @@ /* -Minetest-c55 -Copyright (C) 2010 celeron55, Perttu Ahola +Minetest +Copyright (C) 2013 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 +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 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. +GNU Lesser General Public License for more details. -You should have received a copy of the GNU General Public License along +You should have received a copy of the GNU Lesser 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. */ @@ -20,13 +20,28 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifndef VOXEL_HEADER #define VOXEL_HEADER -#include "common_irrlicht.h" +#include "irrlichttypes.h" +#include "irr_v3d.h" #include #include "debug.h" +#include "exceptions.h" #include "mapnode.h" +#include +#include +#include + +class INodeDefManager; + +// For VC++ +#undef min +#undef max /* - A fast voxel manipulator class + A fast voxel manipulator class. + + In normal operation, it fetches more map when it is requested. + It can also be used so that all allowed area is fetched at the + start, using ManualMapVoxelManipulator. Not thread-safe. */ @@ -60,14 +75,14 @@ class VoxelArea MaxEdge(p) { } - + /* Modifying methods */ - void addArea(VoxelArea &a) + void addArea(const VoxelArea &a) { - if(getExtent() == v3s16(0,0,0)) + if (hasEmptyExtent()) { *this = a; return; @@ -79,9 +94,9 @@ class VoxelArea if(a.MaxEdge.Y > MaxEdge.Y) MaxEdge.Y = a.MaxEdge.Y; if(a.MaxEdge.Z > MaxEdge.Z) MaxEdge.Z = a.MaxEdge.Z; } - void addPoint(v3s16 p) + void addPoint(const v3s16 &p) { - if(getExtent() == v3s16(0,0,0)) + if(hasEmptyExtent()) { MinEdge = p; MaxEdge = p; @@ -94,14 +109,14 @@ class VoxelArea if(p.Y > MaxEdge.Y) MaxEdge.Y = p.Y; if(p.Z > MaxEdge.Z) MaxEdge.Z = p.Z; } - + // Pad with d nodes - void pad(v3s16 d) + void pad(const v3s16 &d) { MinEdge -= d; MaxEdge += d; } - + /*void operator+=(v3s16 off) { MinEdge += off; @@ -122,6 +137,15 @@ class VoxelArea { return MaxEdge - MinEdge + v3s16(1,1,1); } + + /* Because MaxEdge and MinEdge are included in the voxel area an empty extent + * is not represented by (0, 0, 0), but instead (-1, -1, -1) + */ + bool hasEmptyExtent() const + { + return MaxEdge - MinEdge == v3s16(-1, -1, -1); + } + s32 getVolume() const { v3s16 e = getExtent(); @@ -131,7 +155,7 @@ class VoxelArea { // No area contains an empty area // NOTE: Algorithms depend on this, so do not change. - if(a.getExtent() == v3s16(0,0,0)) + if(a.hasEmptyExtent()) return false; return( @@ -148,6 +172,10 @@ class VoxelArea p.Z >= MinEdge.Z && p.Z <= MaxEdge.Z ); } + bool contains(s32 i) const + { + return (i >= 0 && i < getVolume()); + } bool operator==(const VoxelArea &other) const { return (MinEdge == other.MinEdge @@ -170,7 +198,7 @@ class VoxelArea a: area inside *this */ - void diff(const VoxelArea &a, core::list &result) + void diff(const VoxelArea &a, std::list &result) { /* This can result in a maximum of 6 areas @@ -186,7 +214,7 @@ class VoxelArea } assert(contains(a)); - + // Take back area, XY inclusive { v3s16 min(MinEdge.X, MinEdge.Y, a.MaxEdge.Z+1); @@ -242,7 +270,7 @@ class VoxelArea } } - + /* Translates position from virtual coordinates to array index */ @@ -259,6 +287,30 @@ class VoxelArea return index(p.X, p.Y, p.Z); } + // Translate index in the X coordinate + void add_x(const v3s16 &extent, u32 &i, s16 a) + { + i += a; + } + // Translate index in the Y coordinate + void add_y(const v3s16 &extent, u32 &i, s16 a) + { + i += a * extent.X; + } + // Translate index in the Z coordinate + void add_z(const v3s16 &extent, u32 &i, s16 a) + { + i += a * extent.X*extent.Y; + } + // Translate index in space + void add_p(const v3s16 &extent, u32 &i, v3s16 a) + { + i += a.Z*extent.X*extent.Y + a.Y*extent.X + a.X; + } + + /* + Print method for debugging + */ void print(std::ostream &o) const { v3s16 e = getExtent(); @@ -277,21 +329,17 @@ class VoxelArea v3s16 MaxEdge; }; -// Hasn't been copied from source (emerged) -#define VOXELFLAG_NOT_LOADED (1<<0) -// Checked as being inexistent in source -#define VOXELFLAG_INEXISTENT (1<<1) +// unused +#define VOXELFLAG_UNUSED (1<<0) +// no data about that node +#define VOXELFLAG_NO_DATA (1<<1) // Algorithm-dependent -// flowWater: "visited" -#define VOXELFLAG_CHECKED (1<<2) +#define VOXELFLAG_CHECKED1 (1<<2) // Algorithm-dependent -// getWaterPressure: "visited" #define VOXELFLAG_CHECKED2 (1<<3) // Algorithm-dependent -// spreadWaterPressure: "visited" #define VOXELFLAG_CHECKED3 (1<<4) // Algorithm-dependent -// water: "pressure check route node" #define VOXELFLAG_CHECKED4 (1<<5) enum VoxelPrintMode @@ -299,6 +347,7 @@ enum VoxelPrintMode VOXELPRINT_NOTHING, VOXELPRINT_MATERIAL, VOXELPRINT_WATERPRESSURE, + VOXELPRINT_LIGHT_DAY, }; class VoxelManipulator /*: public NodeContainer*/ @@ -306,7 +355,7 @@ class VoxelManipulator /*: public NodeContainer*/ public: VoxelManipulator(); virtual ~VoxelManipulator(); - + /* Virtuals from NodeContainer */ @@ -316,48 +365,105 @@ class VoxelManipulator /*: public NodeContainer*/ } bool isValidPosition(v3s16 p) { - emerge(p); - return !(m_flags[m_area.index(p)] & VOXELFLAG_INEXISTENT); + addArea(p); + return !(m_flags[m_area.index(p)] & VOXELFLAG_NO_DATA); }*/ - // These are a bit slow and shouldn't be used internally + + /* + These are a bit slow and shouldn't be used internally. + Use m_data[m_area.index(p)] instead. + */ MapNode getNode(v3s16 p) { - emerge(p); + VoxelArea voxel_area(p); + addArea(voxel_area); - if(m_flags[m_area.index(p)] & VOXELFLAG_INEXISTENT) + if(m_flags[m_area.index(p)] & VOXELFLAG_NO_DATA) { - dstream<<"EXCEPT: VoxelManipulator::getNode(): " + /*dstream<<"EXCEPT: VoxelManipulator::getNode(): " <<"p=("< &active_nodes, - int recur_count); - - /* - VOXELFLAG_CHECKED3s must usually be cleared before calling. - */ - void updateAreaWaterPressure(VoxelArea a, - core::map &active_nodes, - bool checked3_is_clear=false); - - /* - Returns true if moved something - */ - bool flowWater(v3s16 removed_pos, - core::map &active_nodes, - int recursion_depth=0, - bool debugprint=false, - u32 stoptime=0 - ); + void unspreadLight(enum LightBank bank, v3s16 p, u8 oldlight, + std::set & light_sources, INodeDefManager *nodemgr); + void unspreadLight(enum LightBank bank, + std::map & from_nodes, + std::set & light_sources, INodeDefManager *nodemgr); - /* - To flow some water, call this with the target node in - active_nodes - TODO: Make the active_nodes map to contain some vectors - that are properly sorted according to water flow order. - The current order makes water flow strangely if the - first one is always taken. - No, active_nodes should preserve the order stuff is - added to it, in addition to adhering the water flow - order. - */ - void flowWater(core::map &active_nodes, - int recursion_depth=0, - bool debugprint=false, - u32 timelimit=50 - ); + void spreadLight(enum LightBank bank, v3s16 p, INodeDefManager *nodemgr); + void spreadLight(enum LightBank bank, + std::set & from_nodes, INodeDefManager *nodemgr); /* Virtual functions */ - - /* - Get the contents of the requested area from somewhere. - Shall touch only nodes that have VOXELFLAG_NOT_LOADED - Shall reset VOXELFLAG_NOT_LOADED - - If not found from source, add with VOXELFLAG_INEXISTENT - */ - virtual void emerge(VoxelArea a, s32 caller_id=-1) - { - //dstream<<"emerge p=("<