X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fvoxel.h;h=16540e5951b817849901770c1cec6476046f7992;hb=a69b7abe00fb818fd88f3cd04e7f9997ffd21072;hp=80d292891d61eac2e515f899eda2294644576352;hpb=3909e712a012c11793effc408fd348e438a9ac5b;p=dragonfireclient.git diff --git a/src/voxel.h b/src/voxel.h index 80d292891..16540e595 100644 --- a/src/voxel.h +++ b/src/voxel.h @@ -1,36 +1,46 @@ /* -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. */ -#ifndef VOXEL_HEADER -#define VOXEL_HEADER +#pragma once -#include "common_irrlicht.h" +#include "irrlichttypes.h" +#include "irr_v3d.h" #include -#include "debug.h" +#include +#include "exceptions.h" #include "mapnode.h" +#include +#include +#include "util/basic_macros.h" + +class NodeDefManager; // 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. */ @@ -38,8 +48,8 @@ with this program; if not, write to the Free Software Foundation, Inc., /* Debug stuff */ -extern u32 emerge_time; -extern u32 emerge_load_time; +extern u64 emerge_time; +extern u64 emerge_load_time; /* This class resembles aabbox3d a lot, but has inclusive @@ -49,29 +59,29 @@ class VoxelArea { public: // Starts as zero sized - VoxelArea(): - MinEdge(1,1,1), - MaxEdge(0,0,0) - { - } - VoxelArea(v3s16 min_edge, v3s16 max_edge): + VoxelArea() = default; + + VoxelArea(const v3s16 &min_edge, const v3s16 &max_edge): MinEdge(min_edge), MaxEdge(max_edge) { + cacheExtent(); } - VoxelArea(v3s16 p): + + VoxelArea(const v3s16 &p): MinEdge(p), MaxEdge(p) { + cacheExtent(); } - + /* Modifying methods */ - void addArea(VoxelArea &a) + void addArea(const VoxelArea &a) { - if(getExtent() == v3s16(0,0,0)) + if (hasEmptyExtent()) { *this = a; return; @@ -82,13 +92,16 @@ class VoxelArea if(a.MaxEdge.X > MaxEdge.X) MaxEdge.X = a.MaxEdge.X; if(a.MaxEdge.Y > MaxEdge.Y) MaxEdge.Y = a.MaxEdge.Y; if(a.MaxEdge.Z > MaxEdge.Z) MaxEdge.Z = a.MaxEdge.Z; + cacheExtent(); } - void addPoint(v3s16 p) + + void addPoint(const v3s16 &p) { - if(getExtent() == v3s16(0,0,0)) + if(hasEmptyExtent()) { MinEdge = p; MaxEdge = p; + cacheExtent(); return; } if(p.X < MinEdge.X) MinEdge.X = p.X; @@ -97,45 +110,43 @@ class VoxelArea if(p.X > MaxEdge.X) MaxEdge.X = p.X; if(p.Y > MaxEdge.Y) MaxEdge.Y = p.Y; if(p.Z > MaxEdge.Z) MaxEdge.Z = p.Z; + cacheExtent(); } - + // Pad with d nodes - void pad(v3s16 d) + void pad(const v3s16 &d) { MinEdge -= d; MaxEdge += d; } - - /*void operator+=(v3s16 off) - { - MinEdge += off; - MaxEdge += off; - } - - void operator-=(v3s16 off) - { - MinEdge -= off; - MaxEdge -= off; - }*/ /* const methods */ - v3s16 getExtent() const + const v3s16 &getExtent() const + { + return m_cache_extent; + } + + /* 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); + return MaxEdge - MinEdge == v3s16(-1, -1, -1); } + s32 getVolume() const { - v3s16 e = getExtent(); - return (s32)e.X * (s32)e.Y * (s32)e.Z; + return (s32)m_cache_extent.X * (s32)m_cache_extent.Y * (s32)m_cache_extent.Z; } + bool contains(const VoxelArea &a) const { // 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( @@ -152,20 +163,24 @@ 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 && MaxEdge == other.MaxEdge); } - VoxelArea operator+(v3s16 off) const + VoxelArea operator+(const v3s16 &off) const { - return VoxelArea(MinEdge+off, MaxEdge+off); + return {MinEdge+off, MaxEdge+off}; } - VoxelArea operator-(v3s16 off) const + VoxelArea operator-(const v3s16 &off) const { - return VoxelArea(MinEdge-off, MaxEdge-off); + return {MinEdge-off, MaxEdge-off}; } /* @@ -174,7 +189,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 @@ -189,8 +204,8 @@ class VoxelArea return; } - assert(contains(a)); - + assert(contains(a)); // pre-condition + // Take back area, XY inclusive { v3s16 min(MinEdge.X, MinEdge.Y, a.MaxEdge.Z+1); @@ -246,16 +261,15 @@ class VoxelArea } } - + /* Translates position from virtual coordinates to array index */ s32 index(s16 x, s16 y, s16 z) const { - v3s16 em = getExtent(); - v3s16 off = MinEdge; - s32 i = (s32)(z-off.Z)*em.Y*em.X + (y-off.Y)*em.X + (x-off.X); - //dstream<<" i("< & light_sources); - void unspreadLight(enum LightBank bank, - core::map & from_nodes, - core::map & light_sources); - - void spreadLight(enum LightBank bank, v3s16 p); - void spreadLight(enum LightBank bank, - core::map & from_nodes); - -#if 0 - // VOXELFLAG_CHECKED2s must usually be cleared before calling - // -1: dead end, 0-255: pressure - // highest_y: Highest found water y is stored here. - // Must be initialized to -32768 - int getWaterPressure(v3s16 p, s16 &highest_y, int recur_count); + virtual void clear(); - /* - VOXELFLAG_CHECKED3s must usually be cleared before calling. + void print(std::ostream &o, const NodeDefManager *nodemgr, + VoxelPrintMode mode=VOXELPRINT_MATERIAL); - active_nodes: surface-touching air nodes with flow-causing - pressure. set-like dummy map container. + void addArea(const VoxelArea &area); - Spreads pressure pr at node p to request_area or as far as - there is invalid pressure. - */ - void spreadWaterPressure(v3s16 p, int pr, - VoxelArea request_area, - core::map &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 + Copy data and set flags to 0 + dst_area.getExtent() <= src_area.getExtent() */ - bool flowWater(v3s16 removed_pos, - core::map &active_nodes, - int recursion_depth=0, - bool debugprint=false, - u32 stoptime=0 - ); + void copyFrom(MapNode *src, const VoxelArea& src_area, + v3s16 from_pos, v3s16 to_pos, const v3s16 &size); - /* - 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 - ); -#endif + // Copy data + void copyTo(MapNode *dst, const VoxelArea& dst_area, + v3s16 dst_pos, v3s16 from_pos, const v3s16 &size); /* - Virtual functions + Algorithms */ - - /* - 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=("<