LCOV - code coverage report
Current view: top level - libprimis-headers - octa.h (source / functions) Hit Total Coverage
Test: Libprimis Test Coverage Lines: 60 65 92.3 %
Date: 2024-11-22 05:07:59 Functions: 26 28 92.9 %

          Line data    Source code
       1             : /**
       2             :  * @file octa.h
       3             :  * @brief Objects representing the octree and its manipulation methods.
       4             :  *
       5             :  * This file describes objects that build the octal tree structure of the world
       6             :  * (a `cubeworld` containing `cube` objects) as well as convenient representations
       7             :  * of selections of cubes (in a Cartesian sense) that allow simpler reasoning about
       8             :  * spatial relationships between nodes.
       9             :  */
      10             : 
      11             : #ifndef OCTA_H_
      12             : #define OCTA_H_
      13             : 
      14             : const int Face_MaxVerts = 15;
      15             : 
      16             : struct cubeext; /** internal engine data for the cube object, not accessible via external API*/
      17             : 
      18             : constexpr uint faceempty = 0;             /**< all edges in the range (0,0) */
      19             : constexpr uint facesolid = 0x80808080;    /**< all edges in the range (0,8) */
      20             : 
      21             : /**
      22             :  * @brief The fundemental building block of the octree world, representing a 3D cube.
      23             :  *
      24             :  * The main rendered object in the world is an octree (8-leaf tree) comprising of
      25             :  * objects of this type. Each cube object has its own deformation information,
      26             :  * texture information, and a handful of utility functions as well as pointing to
      27             :  * up to eight children in a fractal manner.
      28             :  *
      29             :  * Cube objects are the game-facing abstraction which the renderer itself does not
      30             :  * use; they are converted to `vertex arrays` by the engine which requires calculation
      31             :  * by itself. However, the octree structure is capable of a relatively simple and
      32             :  * effective representation of detail over several orders of magnitude.
      33             :  *
      34             :  * The integer indices for the textures are shown below.
      35             :  * ```
      36             :  *  +z
      37             :  *   |  /+x
      38             :  *   | /
      39             :  *   |/___+y
      40             :  *      ______
      41             :  *     /.    /|
      42             :  *    / . 5 / |
      43             :  *   /__.__/  |
      44             :  *   |  ...|3./
      45             :  *   | .0  | /
      46             :  *   |.    |/
      47             :  *   .-----/
      48             :  *      ______
      49             :  *     /|    .|
      50             :  *    / |  1. |
      51             :  *   /..|...  |
      52             :  *   |2 |-----/
      53             :  *   | /   . /
      54             :  *   |/   4./
      55             :  *   .-----/
      56             :  * ```
      57             :  *
      58             :  * The integer indices of the 8 children are shown below.
      59             :  * ```
      60             :  *              ^ +z
      61             :  *              |
      62             :  *            __________
      63             :  *           /  4 /  5 /
      64             :  *          /____/____/.
      65             :  *         /  6 /  7 / .
      66             :  *        /____/____/  .
      67             :  *       .    _____.___.
      68             :  *       .   /  0 /. 1 /     +x
      69             :  *       .  /____/_.__/    ->
      70             :  *       . /  2 / 3. /
      71             :  *       ./____/___./
      72             :  *
      73             :  *
      74             :  *           / +y
      75             :  *          |/
      76             :  * ```
      77             :  *
      78             :  * The integer indices of the 12 edges are shown below.
      79             :  * ```
      80             :  *              ^ +z
      81             :  *              |
      82             :  *              |
      83             :  *            _____2____
      84             :  *           /         /
      85             :  *        5 /.8      7/.
      86             :  *         / .       / .
      87             :  *        /_____3___/  .9
      88             :  *       . . ._____.___.
      89             :  *     10.   /  0  .   /     +x
      90             :  *       . 4/    11.  /    ->
      91             :  *       . /       . /6
      92             :  *       ./________./
      93             :  *            1
      94             :  *
      95             :  *           / +y
      96             :  *          |/
      97             :  * ```
      98             :  */
      99             : class cube
     100             : {
     101             :     public:
     102             :         std::array<cube, 8> *children; /**< points to 8 cube structures which are its children, or nullptr. -Z first, then -Y, -X. If children[0] == nullptr, assume there are no children.*/
     103             :         cubeext *ext;            /**< extended info for the cube */
     104             :         union
     105             :         {
     106             :             uchar edges[12];     /**< edges of the cube, each uchar is 2 4bit values denoting the range. */
     107             :                                  /**< see documentation jpgs for more info. */
     108             :             uint faces[3];       /**< 4 edges of each dimension together representing 2 perpendicular faces */
     109             :         };
     110             :         ushort texture[6];       /**< one for each face. same order as orient. */
     111             :         ushort material;         /**< empty-space material, bitmask created from available mats */
     112             :         uchar merged;            /**< merged faces of the cube */
     113             :         union
     114             :         {
     115             :             uchar escaped;       /**< mask of which children have escaped merges */
     116             :             uchar visible;       /**< visibility info for faces */
     117             :         };
     118             :         bool valid;              /**< status of the cube: */
     119             :         /**
     120             :          * @brief returns if the cube is empty (face 0 does not exist)
     121             :          *
     122             :          * note that a non-empty (but distorted) cube missing faces for an axis is impossible
     123             :          * unless there are no faces at all (impossible to construct a 3d cube otherwise)
     124             :          */
     125         122 :         bool isempty() const
     126             :         {
     127         122 :             return faces[0]==faceempty;
     128             :         }
     129             : 
     130             :         /**
     131             :          * @brief returns if the cube passed is entirely solid (no distortions)
     132             :          */
     133           2 :         bool issolid() const
     134             :         {
     135           3 :             return faces[0]==facesolid &&
     136           3 :                    faces[1]==facesolid &&
     137           3 :                    faces[2]==facesolid; //check all three
     138             :         }
     139             : 
     140             :         /**
     141             :          * @brief Sets a cube's materials, given a material & filter to use
     142             :          *
     143             :          * Modifies the material properties of a cube object, given the various
     144             :          * filtering parameters.
     145             :          *
     146             :          * @param c the cube object to use
     147             :          * @param mat material index to apply
     148             :          * @param matmask material mask
     149             :          * @param filtermat if nonzero, determines what existing mats to apply to
     150             :          * @param filtermask filter material mask
     151             :          * @param filtergeom type of geometry inside the cube (empty, solid, partially solid)
     152             :          */
     153             :         void setmat(ushort mat, ushort matmask, ushort filtermat, ushort filtermask, int filtergeom);
     154             : 
     155             :         /**
     156             :          * @brief discards children
     157             :          *
     158             :          * @param fixtex toggles fixing the texture of the resulting cube
     159             :          * @param depth at which to stop discarding
     160             :          */
     161             :         void discardchildren(bool fixtex = false, int depth = 0);
     162             : 
     163             :         /**
     164             :          * @brief Merges adjacent faces that can be losslessly merged.
     165             :          *
     166             :          * Merges adjacent faces, provided that the resulting cube created
     167             :          * is no larger than the `maxmerge` gridpower size. Faces resulting from
     168             :          * the merge process are always lossless; therefore the previously
     169             :          * existing cubes must be coplanar prior to the merge request.
     170             :          *
     171             :          * Applies to all children of this cube, and also all adjacent cubes at
     172             :          * the same level as this cube. This function is assumed to be called from
     173             :          * the first element of an octree (eight element) array and will fail
     174             :          * ungracefully if this condition is not satisfied.
     175             :          */
     176             :         void calcmerges();
     177             : 
     178             :         /**
     179             :          * @brief Returns whether the cube is valid.
     180             :          *
     181             :          * If the cube is not convex, this function returns true, otherwise it
     182             :          * returns false.
     183             :          */
     184             :         bool isvalidcube() const;
     185             : 
     186             :     private:
     187             : 
     188             :         struct facebounds
     189             :         {
     190             :             ushort u1, u2, v1, v2;
     191             : 
     192             :             bool empty() const
     193             :             {
     194             :                 return u1 >= u2 || v1 >= v2;
     195             :             }
     196             :         };
     197             :         struct pvert
     198             :         {
     199             :             ushort x, y;
     200             : 
     201        1734 :             pvert() {}
     202         192 :             pvert(ushort x, ushort y) : x(x), y(y) {}
     203             : 
     204         360 :             bool operator==(const pvert &o) const
     205             :             {
     206         360 :                 return x == o.x && y == o.y;
     207             :             }
     208           0 :             bool operator!=(const pvert &o) const
     209             :             {
     210           0 :                 return x != o.x || y != o.y;
     211             :             }
     212             :         };
     213             : 
     214             :         struct pedge
     215             :         {
     216             :             pvert from, to;
     217             : 
     218         192 :             pedge() {}
     219         192 :             pedge(const pvert &from, const pvert &to) : from(from), to(to) {}
     220             : 
     221         180 :             bool operator==(const pedge &o) const
     222             :             {
     223         180 :                 return from == o.from && to == o.to;
     224             :             }
     225             :             bool operator!=(const pedge &o) const
     226             :             {
     227             :                 return from != o.from || to != o.to;
     228             :             }
     229             :         };
     230             : 
     231             :         class plink : public pedge
     232             :         {
     233             :             public:
     234             :                 int polys[2];
     235             : 
     236         192 :                 plink()
     237         192 :                 {
     238         192 :                     clear();
     239         192 :                 }
     240             : 
     241         192 :                 plink(const pedge &p) : pedge(p)
     242             :                 {
     243         192 :                     clear();
     244         192 :                 }
     245             :             private:
     246         384 :                 void clear()
     247             :                 {
     248         384 :                     polys[0] = polys[1] = -1;
     249         384 :                 }
     250             :         };
     251             : 
     252             :         struct poly
     253             :         {
     254             :             cube *c;
     255             :             int numverts;
     256             :             bool merged;
     257             :             pvert verts[Face_MaxVerts];
     258             : 
     259             :             bool clippoly(const facebounds &b);
     260             :             bool mergepolys(std::unordered_set<plink> &links, std::deque<const plink *> &queue, int owner, poly &q, const pedge &e);
     261             :         };
     262             : 
     263             :         bool mincubeface(const cube &cu, int orient, const ivec &co, int size, facebounds &orig) const;
     264             :         void mincubeface(const cube &cu, int orient, const ivec &o, int size, const facebounds &orig, facebounds &cf, ushort nmat, ushort matmask) const;
     265             : 
     266             :         void freecubeext(cube &c);
     267             :         void genmerges(cube * root, const ivec &o = ivec(0, 0, 0), int size = 9);
     268             :         bool genpoly(int orient, const ivec &o, int size, int vis, ivec &n, int &offset, poly &p);
     269             :         void clearmerge(int orient);
     270             :         void addmerge(int orient, const ivec &n, int offset, poly &p);
     271             :         void addmerges(int orient, const ivec &n, int offset, std::deque<poly> &polys);
     272             :         void mergepolys(int orient, const ivec &n, int offset, std::deque<poly> &polys);
     273             : 
     274             :         struct cfpolys
     275             :         {
     276             :             std::deque<poly> polys;
     277             :         };
     278             : 
     279             :         struct cfkey
     280             :         {
     281             :             uchar orient;
     282             :             ushort material, tex;
     283             :             ivec n;
     284             :             int offset;
     285             :         };
     286             : 
     287             :         //for unordered_map
     288             :         friend std::hash<plink>;
     289             :         friend std::hash<cfkey>;
     290             :         friend bool operator==(const cfkey &x, const cfkey &y);
     291             : };
     292             : 
     293             : /**
     294             :  * @brief A representation of a rectangular volume of cubes.
     295             :  */
     296             : struct selinfo
     297             : {
     298             :     int corner;
     299             :     int cx, cxs, cy, cys;
     300             :     ivec o, /**< the coordinates from which the selection starts */
     301             :          s; /**< the offset vector conveying the size of the  selection*/
     302             :     int grid, /**< the gridscale of the selection */
     303             :         orient; /**< the orientation of the selection */
     304          12 :     selinfo() : corner(0), cx(0), cxs(0), cy(0), cys(0), o(0, 0, 0), s(0, 0, 0), grid(8), orient(0) {}
     305             : 
     306             :     /**
     307             :      * @brief Returns the volume of the selection.
     308             :      *
     309             :      * The volume returned is in the units of the gridpower being used, so selections
     310             :      * with the same cube dimensions but different gridpowers will have the same
     311             :      * volume.
     312             :      *
     313             :      * @return the volume of the selection (l*w*h)
     314             :      */
     315           3 :     int size() const
     316             :     {
     317           3 :         return s.x*s.y*s.z;
     318             :     }
     319             : 
     320             :     /**
     321             :      * @brief Returns the absolute size of the selection along the specified axis.
     322             :      *
     323             :      * @param d the dimension to query (0 for x, 1 for y, 2 for z)
     324             :      *
     325             :      * @return the absolute size of the selection along that axis
     326             :      */
     327           6 :     int us(int d) const
     328             :     {
     329           6 :         return s[d]*grid;
     330             :     }
     331             : 
     332             :     /**
     333             :      * @brief Returns whether the two selections occupy the same space.
     334             :      *
     335             :      * Requires that the two selections are occupying the same volume in the
     336             :      * world space, and both are of the same gridpower and orientation (selected
     337             :      * face). Otherwise, false is returned.
     338             :      */
     339           2 :     bool operator==(const selinfo &sel) const
     340             :     {
     341           2 :         return o==sel.o && s==sel.s && grid==sel.grid && orient==sel.orient;
     342             :     }
     343             : 
     344             :     /**
     345             :      * @brief Keeps the selection within the world.
     346             :      *
     347             :      * @return false if the selection attempts to leave the bounds of the world
     348             :      */
     349             :     bool validate();
     350             : };
     351             : 
     352             : /**
     353             :  * @brief A representation of a rectangular volume of cubes, with less metadata.
     354             :  *
     355             :  * A rectangular volume of cubes.
     356             :  */
     357             : struct block3
     358             : {
     359             :     ivec o, s;
     360             :     int grid, orient;
     361           5 :     block3() {}
     362           1 :     block3(const selinfo &sel) : o(sel.o), s(sel.s), grid(sel.grid), orient(sel.orient) {}
     363             : 
     364           1 :     const cube *getcube() const
     365             :     {
     366           1 :         return reinterpret_cast<const cube *>(this+1);
     367             :     }
     368             : 
     369           1 :     cube *c()
     370             :     {
     371           1 :         return reinterpret_cast<cube *>(this+1);
     372             :     }
     373             : 
     374           3 :     int size() const
     375             :     {
     376           3 :         return s.x*s.y*s.z;
     377             :     }
     378             : };
     379             : 
     380             : struct editinfo
     381             : {
     382             :     block3 *copy;
     383           1 :     editinfo() : copy(nullptr) {}
     384             : };
     385             : 
     386             : struct undoent
     387             : {
     388             :     size_t i; /**< an index in entgroup*/
     389             :     entity e;
     390             : };
     391             : 
     392             : struct undoblock /**< undo header, all data sits in payload */
     393             : {
     394             :     undoblock *prev, *next;
     395             :     int size,       /**< size of undo block */
     396             :         timestamp,  /**< time of creation */
     397             :         numents;    /**< if numents is 0, is a cube undo record, otherwise an entity undo record */
     398             : 
     399           1 :     block3 *block()
     400             :     {
     401           1 :         return reinterpret_cast<block3 *>(this + 1);
     402             :     }
     403             : 
     404           0 :     uchar *gridmap()
     405             :     {
     406           0 :         block3 *ub = block();
     407           0 :         return reinterpret_cast<uchar *>(ub->c() + ub->size());
     408             :     }
     409             : 
     410           1 :     undoent *ents()
     411             :     {
     412           1 :         return reinterpret_cast<undoent *>(this + 1);
     413             :     }
     414             : };
     415             : 
     416             : extern int selchildcount, selchildmat;
     417             : 
     418             : /**
     419             :  * @brief sets the faces to a given value `face` given
     420             :  */
     421          49 : inline void setcubefaces(cube &c, uint face)
     422             : {
     423          49 :     c.faces[0] = c.faces[1] = c.faces[2] = face;
     424          49 : }
     425             : 
     426           4 : inline int octadim(int d)
     427             : {
     428           4 :     return 1<<d;
     429             : }
     430             : 
     431             : //note that these macros actually loop in the opposite order: e.g. loopxy runs a for loop of x inside y
     432             : #define LOOP_XY(b)        for(int y = 0; y < (b).s[C[DIMENSION((b).orient)]]; ++y) for(int x = 0; x < (b).s[R[DIMENSION((b).orient)]]; ++x)
     433             : #define LOOP_XYZ(b, r, f) { for(int z = 0; z < (b).s[D[DIMENSION((b).orient)]]; ++z) LOOP_XY((b)) { cube &c = blockcube(x,y,z,b,r); f; } }
     434             : #define LOOP_SEL_XYZ(f)    { if(local) makeundo(); LOOP_XYZ(sel, sel.grid, f); rootworld.changed(sel); }
     435             : #define SELECT_CUBE(x, y, z) blockcube(x, y, z, sel, sel.grid)
     436             : 
     437             : // guard against subdivision
     438             : #define PROTECT_SEL(f) { undoblock *_u = newundocube(sel); f; if(_u) { pasteundoblock(_u->block(), _u->gridmap()); freeundo(_u); } }
     439             : 
     440             : #define DIMENSION(orient)  ((orient)>>1)
     441             : #define DIM_COORD(orient)  ((orient)&1)
     442             : 
     443             : extern ivec lu;
     444             : extern int lusize;
     445             : struct prefab;
     446             : struct clipplanes;
     447             : 
     448             : /**
     449             :  * @brief An object representing the entirety of an octree world.
     450             :  *
     451             :  * A `cubeworld` is an object storing an entire octree structure and its data;
     452             :  *  the octree is made up of `cube` objects, the topmost of which is pointed to
     453             :  * by `worldroot`.
     454             :  */
     455             : class cubeworld
     456             : {
     457             :     public:
     458             :         std::array<cube, 8> *worldroot;
     459             : 
     460             :         /**
     461             :          * @brief Returns the material bitmask value at the given location.
     462             :          *
     463             :          * Given a world location, returns the material bitmask at the specified location.
     464             :          * This bitmask may be the sum of multiple materials if present.
     465             :          * Returns 0 (air) if the location specified has no material or is outside the
     466             :          * world.
     467             :          *
     468             :          * @return an integer corresponding to the material(s) at the specified location
     469             :          */
     470             :         int lookupmaterial(const vec &v);
     471             : 
     472             :         /**
     473             :          * @brief Clears the old level and creates a new one.
     474             :          *
     475             :          * This function unloads the old map, including textures, and creates a new level
     476             :          * of the size specified.
     477             :          *
     478             :          * @param factor sets the gridscale (power of 2 size) of the map; limit 10 to 15
     479             :          * @param force if true, creates map regardless of check variables
     480             :          * @param usecfg if true, uses the default map config path
     481             :          *
     482             :          */
     483             :         bool emptymap(int factor, bool force, bool usecfg = true);
     484             : 
     485             :         /**
     486             :          * @brief Grows the map to an additional gridsize.
     487             :          *
     488             :          * Expands the map by placing the old map in the corner nearest the origin and
     489             :          * adding 7 old-map sized cubes to create a new largest cube.
     490             :          *
     491             :          * This moves the worldroot cube to the new parent cube of the old map.
     492             :          */
     493             :         bool enlargemap(bool force);
     494             :         bool modifyoctaent(int flags, int id, extentity &e);
     495             : 
     496             :         /**
     497             :          * @brief attempts to reduce the mapsize by 1 (halves all linear dimensions)
     498             :          *
     499             :          * Fails if the 7 octants not at the origin are not empty.
     500             :          * On success, the resulting map will have its maximum gridsize reduced by 1.
     501             :          */
     502             :         void shrinkmap();
     503             : 
     504             :         /**
     505             :          * @brief Loads a map file into the octaworld object.
     506             :          *
     507             :          * Loads a map that has been saved in .ogz format.
     508             :          * Will load the configuration file of the same name, unless cname is specified.
     509             :          *
     510             :          * @param mname the name of the map to load (the ogz)
     511             :          * @param gameident the name of the game calling (this is saved in the map)
     512             :          * @param gameinfo the string to render while the map is loading
     513             :          * @param the name of the map's configuration file (if different than the octree)
     514             :          *
     515             :          * @return true if the map was loaded
     516             :          * @return false if the map failed to load or was not found
     517             :          */
     518             :         bool load_world(const char *mname, const char *gameident, const char *gameinfo = nullptr, const char *cname = nullptr);
     519             : 
     520             :         /**
     521             :          * @brief Saves the current map to an ogz file.
     522             :          *
     523             :          * @param mname the name of the map file once saved
     524             :          * @param gameident the name of the game saving the file
     525             :          *
     526             :          * @return true if the map was saved
     527             :          * @return false if the map failed to save
     528             :          */
     529             :         bool save_world(const char *mname, const char *gameident);
     530             : 
     531             :         /**
     532             :          * @brief Removes unnecessary virtual texture slots.
     533             :          *
     534             :          * Checks and removes unused virtual texture slots (vslots) from the octree
     535             :          * world.
     536             :          */
     537             :         int compactvslots(bool cull = false);
     538             :         void genprefabmesh(prefab &p);
     539             : 
     540             :         /**
     541             :          * @brief Destroys vertex arrays for the octree world.
     542             :          *
     543             :          * Cleans up the geometry objects used by the renderer to render the octree
     544             :          * world.
     545             :          */
     546             :         void cleanupva();
     547             : 
     548             :         /**
     549             :          * @brief Returns the distance before a ray hits a cube.
     550             :          *
     551             :          * @param o      the starting location of the ray to be drawn
     552             :          * @param ray    normalized direction vector for the ray to point
     553             :          * @param radius region around ray that counts as a hit
     554             :          * @param mode   flags which determine what counts as a hit
     555             :          * @param size   size of cube which registers a hit
     556             :          * @param t      entity to check against
     557             :          */
     558             :         float raycube   (const vec &o, const vec &ray, float radius = 0, int mode = 3, int size = 0, const extentity *t = 0) const;
     559             : 
     560             :         /**
     561             :          * @brief Returns whether the entity passed has collided with this octaworld.
     562             :          *
     563             :          * @param d the physent to check
     564             :          * @param dir the direction at which to check for a collision
     565             :          * @param cutoff the model cutoff factor
     566             :          * @param bo the vector for the minimum position of the model
     567             :          * @param bs the vector for the maximum position of the model
     568             :          */
     569             :         bool octacollide(const physent *d, const vec &dir, float cutoff, const ivec &bo, const ivec &bs) const;
     570             : 
     571             :         /**
     572             :          * @brief Returns a reference to the cube at the specified world coordinates
     573             :          *
     574             :          * @param to the location to look in
     575             :          * @param tsize the size of cube to find (by gridpower)
     576             :          * @param ro the found location to be assigned by reference
     577             :          * @param rsize the found size (gridpower) of the cube to be assigned by reference
     578             :          */
     579             :         cube &lookupcube(const ivec &to, int tsize = 0, ivec &ro = lu, int &rsize = lusize);
     580             :         bool bboccluded(const ivec &bo, const ivec &br) const;
     581             :         void findtjoints();
     582             :         void allchanged(bool load = false);
     583             :         const cube &neighborcube(int orient, const ivec &co, int size, ivec &ro, int &rsize);
     584             : 
     585             :         /**
     586             :          * @brief Calculates normals and re-calculates geometry.
     587             :          *
     588             :          * Re-mips the cube structure of the level to remove unnecessary nodes, then
     589             :          * calculates normal maps for corners.
     590             :          */
     591             :         void calclight();
     592             :         float shadowray(const vec &o, const vec &ray, float radius, int mode, const extentity *t = nullptr);
     593             :         void changed(const ivec &bbmin, const ivec &bbmax, bool commit = true);
     594             :         void changed(const block3 &sel, bool commit = true);
     595             :         clipplanes &getclipbounds(const cube &c, const ivec &o, int size, int offset);
     596             :         void calcnormals(bool lerptjoints);
     597             : 
     598             :         /**
     599             :          * @brief Reduces the number of cubes on the level losslessly.
     600             :          *
     601             :          * Loops through all cube objects, dissolving child nodes where it is possible
     602             :          * to convert them to their parent nodes. The largest gridpower that can be
     603             :          * optimizied can be controlled by the maxmerge variable.
     604             :          */
     605             :         void remip();
     606             :         /**
     607             :          * @brief Returns the CRC code for the map currently loaded.
     608             :          *
     609             :          * Returns the cyclic redundancy checksum for the file currently loaded. This
     610             :          * value is unique for every revision of a map binary, and is useful to make
     611             :          * sure multiple clients have the same binary.
     612             :          *
     613             :          * @return the cyclic redundancy code of the map file currently loaded
     614             :          */
     615             :         uint getmapcrc() const;
     616             : 
     617             :         /**
     618             :          * @brief sets the CRC field variable to 0
     619             :          *
     620             :          * Invalidates the CRC code saved as a cubeworld field for the world, usually
     621             :          * to indicate that the CRC has become invalid as a result of modification.
     622             :          */
     623             :         void clearmapcrc();
     624             : 
     625             :         void entitiesinoctanodes();
     626             :         void commitchanges(bool force = false);
     627             :         void updateparticles();
     628             : 
     629             :         /**
     630             :          * @brief Returns the gridpower scale of the world
     631             :          *
     632             :          * Returns the size of the worldroot cube, in terms of the number of
     633             :          * half-linear-size cubes it has as descendents in the octree. This value
     634             :          * is generally between 10 and 15.
     635             :          *
     636             :          * @return the scale of the world
     637             :          */
     638             :         int mapscale() const;
     639             : 
     640             :         /**
     641             :          * @brief Returns the linear dimensions of the world
     642             :          *
     643             :          * Returns the size of the worldroot cube, in terms of the number of size
     644             :          * 0 cubes on each linear axis. This value is generally between 2^10 and
     645             :          * 2^15.
     646             :          *
     647             :          * @return the size of the world
     648             :          */
     649             :         int mapsize() const;
     650             :     private:
     651             :         uint mapcrc; /**< the cyclic redundancy checksum of the entire world*/
     652             :         bool haschanged;
     653             :         string ogzname, bakname, cfgname, picname;
     654             :         int worldscale; /**< should only be set at map creation/load **/
     655             : 
     656             : 
     657             :         ///@brief This is a cube() object but with a constructor that indicates nothing is in it
     658             :         struct emptycube : cube
     659             :         {
     660           1 :             emptycube()
     661           1 :             {
     662           1 :                 children = nullptr;
     663           1 :                 ext = nullptr;
     664           1 :                 visible = 0;
     665           1 :                 merged = 0;
     666           1 :                 material = 0;
     667           1 :                 setcubefaces(*this, faceempty);
     668           7 :                 for(int i = 0; i < 6; ++i)
     669             :                 {
     670           6 :                     texture[i] = 0;
     671             :                 }
     672           1 :             }
     673             :         } emptycube;
     674             : 
     675             :         struct mapheader
     676             :         {
     677             :             char magic[4];              // "TMAP"
     678             :             int version;                // any >8bit quantity is little endian
     679             :             int headersize;             // sizeof(header)
     680             :             int worldsize;
     681             :             int numents;
     682             :             int numpvs;                 // no longer used, kept for backwards compatibility
     683             :             int blendmap;               // also no longer used
     684             :             int numvars;
     685             :             int numvslots;
     686             :         };
     687             : 
     688             :         struct octaheader
     689             :         {
     690             :             char magic[4];              // "OCTA"
     691             :             int version;                // any >8bit quantity is little endian
     692             :             int headersize;             // sizeof(header)
     693             :             int worldsize;
     694             :             int numents;
     695             :             int numvars;
     696             :             int numvslots;
     697             :         };
     698             :         /**
     699             :          * @brief Creates vertex arrays for the octree world.
     700             :          *
     701             :          * Creates vertex arrays, geometry objects used by the renderer to render
     702             :          * the world.
     703             :          */
     704             :         void octarender();
     705             :         void seedparticles();
     706             :         void makeparticles(const entity &e);
     707             : 
     708             :         /**
     709             :          * @brief Resets the metadata associated with a map.
     710             :          *
     711             :          */
     712             :         void resetmap();
     713             :         void resetclipplanes();
     714             : 
     715             :         /**
     716             :          * @brief Saves a cube and its children to the specified stream.
     717             :          *
     718             :          * Recursively saves a cube and all of its information (materials, textures, etc.) by writing it to the
     719             :          * stream object passed by const pointer.
     720             :          *
     721             :          * @param c the cube to save (usually the world root)
     722             :          * @param o the location of the cube in the world
     723             :          * @param size the gridpower of the cube to save
     724             :          * @param f the stream to save to
     725             :          */
     726             :         void savec(const std::array<cube, 8> &c, const ivec &o, int size, stream * const f);
     727             : 
     728             :         /**
     729             :          * @brief Loads a map header given the input stream.
     730             :          *
     731             :          * @param f the stream to decode into a map header
     732             :          * @param ogzname the name of the map file, for debug message purposes
     733             :          * @param hdr the mapheader object to be set with values from f
     734             :          * @param ohdr the octaheader object to be set with values from f
     735             :          *
     736             :          * @return true if the input stream is well formed, false otherwise
     737             :          */
     738             :         bool loadmapheader(stream *f, const char *ogzname, mapheader &hdr, octaheader &ohdr) const;
     739             : 
     740             :         /**
     741             :          * @brief Sets the map's save file names
     742             :          *
     743             :          * Also sets the backup names of the file in anology with `fname`.
     744             :          *
     745             :          * @param fname the octree map file (ogz) name to set
     746             :          * @param cname the config file (cfg) name to set
     747             :          */
     748             :         void setmapfilenames(const char *fname, const char *cname = nullptr);
     749             : 
     750             :         bool upoctree(const vec& v, int& x, int& y, int& z, const ivec& lo, int& lshift) const;
     751             :         bool checkinsideworld(const vec &invray, float radius, float &outrad, const vec &o, vec &v, const vec &ray, float &dist) const;
     752             : 
     753             : };
     754             : 
     755             : extern cubeworld rootworld;
     756             : 
     757             : #endif /* OCTA_H_ */

Generated by: LCOV version 1.14