Libprimis
Imprimis' 3D destroyable world engine
Loading...
Searching...
No Matches
octa.h
Go to the documentation of this file.
1
10
11#ifndef OCTA_H_
12#define OCTA_H_
13
14const int Face_MaxVerts = 15;
15
16struct cubeext;
17
18constexpr uint faceempty = 0;
19constexpr uint facesolid = 0x80808080;
20
99class cube
100{
101 public:
102 std::array<cube, 8> *children;
103 cubeext *ext;
104 union
105 {
106 uchar edges[12];
108 uint faces[3];
109 };
110 ushort texture[6];
111 ushort material;
112 uchar merged;
113 union
114 {
115 uchar escaped;
116 uchar visible;
117 };
118 bool valid;
125 bool isempty() const
126 {
127 return faces[0]==faceempty;
128 }
129
133 bool issolid() const
134 {
135 return faces[0]==facesolid &&
136 faces[1]==facesolid &&
137 faces[2]==facesolid; //check all three
138 }
139
153 void setmat(ushort mat, ushort matmask, ushort filtermat, ushort filtermask, int filtergeom);
154
161 void discardchildren(bool fixtex = false, int depth = 0);
162
177
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 pvert() {}
202 pvert(ushort x, ushort y) : x(x), y(y) {}
203
204 bool operator==(const pvert &o) const
205 {
206 return x == o.x && y == o.y;
207 }
208 bool operator!=(const pvert &o) const
209 {
210 return x != o.x || y != o.y;
211 }
212 };
213
214 struct pedge
215 {
216 pvert from, to;
217
218 pedge() {}
219 pedge(const pvert &from, const pvert &to) : from(from), to(to) {}
220
221 bool operator==(const pedge &o) const
222 {
223 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 plink()
237 {
238 clear();
239 }
240
241 plink(const pedge &p) : pedge(p)
242 {
243 clear();
244 }
245 private:
246 void clear()
247 {
248 polys[0] = polys[1] = -1;
249 }
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
296struct selinfo
297{
298 int corner;
299 int cx, cxs, cy, cys;
302 int grid,
304 selinfo() : corner(0), cx(0), cxs(0), cy(0), cys(0), o(0, 0, 0), s(0, 0, 0), grid(8), orient(0) {}
305
315 int size() const
316 {
317 return s.x*s.y*s.z;
318 }
319
327 int us(int d) const
328 {
329 return s[d]*grid;
330 }
331
339 bool operator==(const selinfo &sel) const
340 {
341 return o==sel.o && s==sel.s && grid==sel.grid && orient==sel.orient;
342 }
343
349 bool validate();
350};
351
357struct block3
358{
359 ivec o, s;
360 int grid, orient;
361 block3() {}
362 block3(const selinfo &sel) : o(sel.o), s(sel.s), grid(sel.grid), orient(sel.orient) {}
363
364 const cube *getcube() const
365 {
366 return reinterpret_cast<const cube *>(this+1);
367 }
368
369 cube *c()
370 {
371 return reinterpret_cast<cube *>(this+1);
372 }
373
374 int size() const
375 {
376 return s.x*s.y*s.z;
377 }
378};
379
380struct editinfo
381{
382 block3 *copy;
383 editinfo() : copy(nullptr) {}
384};
385
387{
388 size_t i;
389 entity e;
390};
391
393{
394 undoblock *prev, *next;
395 int size,
398
399 block3 *block()
400 {
401 return reinterpret_cast<block3 *>(this + 1);
402 }
403
404 uchar *gridmap()
405 {
406 block3 *ub = block();
407 return reinterpret_cast<uchar *>(ub->c() + ub->size());
408 }
409
410 undoent *ents()
411 {
412 return reinterpret_cast<undoent *>(this + 1);
413 }
414};
415
416extern int selchildcount, selchildmat;
417
421inline void setcubefaces(cube &c, uint face)
422{
423 c.faces[0] = c.faces[1] = c.faces[2] = face;
424}
425
426inline int octadim(int d)
427{
428 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
443extern ivec lu;
444extern int lusize;
445struct prefab;
446struct clipplanes;
447
456{
457 public:
458 std::array<cube, 8> *worldroot;
459
470 int lookupmaterial(const vec &v);
471
483 bool emptymap(int factor, bool force, bool usecfg = true);
484
494 bool modifyoctaent(int flags, int id, extentity &e);
495
502 void shrinkmap();
503
518 bool load_world(const char *mname, const char *gameident, const char *gameinfo = nullptr, const char *cname = nullptr);
519
529 bool save_world(const char *mname, const char *gameident);
530
537 int compactvslots(bool cull = false);
538 void genprefabmesh(prefab &p);
539
546 void cleanupva();
547
558 float raycube (const vec &o, const vec &ray, float radius = 0, int mode = 3, int size = 0, const extentity *t = 0) const;
559
568 cube &lookupcube(const ivec &to, int tsize = 0, ivec &ro = lu, int &rsize = lusize);
569 bool bboccluded(const ivec &bo, const ivec &br) const;
570 void findtjoints();
571 void allchanged(bool load = false);
572 const cube &neighborcube(int orient, const ivec &co, int size, ivec &ro, int &rsize);
573
580 void calclight();
581 float shadowray(const vec &o, const vec &ray, float radius, int mode, const extentity *t = nullptr);
582 void changed(const ivec &bbmin, const ivec &bbmax, bool commit = true);
583 void changed(const block3 &sel, bool commit = true);
584 clipplanes &getclipbounds(const cube &c, const ivec &o, int size, int offset);
585 void calcnormals(bool lerptjoints);
586
594 void remip();
604 uint getmapcrc() const;
605
613
614 void entitiesinoctanodes();
615 void commitchanges(bool force = false);
616 void updateparticles();
617
627 int mapscale() const;
628
638 int mapsize() const;
639 private:
640 uint mapcrc;
641 bool haschanged;
642 string ogzname, bakname, cfgname, picname;
643 int worldscale;
644
645
647 struct emptycube : cube
648 {
649 emptycube()
650 {
651 children = nullptr;
652 ext = nullptr;
653 visible = 0;
654 merged = 0;
655 material = 0;
656 setcubefaces(*this, faceempty);
657 for(int i = 0; i < 6; ++i)
658 {
659 texture[i] = 0;
660 }
661 }
662 } emptycube;
663
664 struct mapheader
665 {
666 char magic[4]; // "TMAP"
667 int version; // any >8bit quantity is little endian
668 int headersize; // sizeof(header)
669 int worldsize;
670 int numents;
671 int numpvs; // no longer used, kept for backwards compatibility
672 int blendmap; // also no longer used
673 int numvars;
674 int numvslots;
675 };
676
677 struct octaheader
678 {
679 char magic[4]; // "OCTA"
680 int version; // any >8bit quantity is little endian
681 int headersize; // sizeof(header)
682 int worldsize;
683 int numents;
684 int numvars;
685 int numvslots;
686 };
693 void octarender();
694 void seedparticles();
695 void makeparticles(const entity &e);
696
701 void resetmap();
702 void resetclipplanes();
703
715 void savec(const std::array<cube, 8> &c, const ivec &o, int size, stream * const f);
716
727 bool loadmapheader(stream *f, const char *ogzname, mapheader &hdr, octaheader &ohdr) const;
728
737 void setmapfilenames(const char *fname, const char *cname = nullptr);
738
739 bool upoctree(const vec& v, int& x, int& y, int& z, const ivec& lo, int& lshift) const;
740 bool checkinsideworld(const vec &invray, float radius, float &outrad, const vec &o, vec &v, const vec &ray, float &dist) const;
741
742};
743
744extern cubeworld rootworld;
745
746#endif /* OCTA_H_ */
The fundemental building block of the octree world, representing a 3D cube.
Definition octa.h:100
std::array< cube, 8 > * children
Definition octa.h:102
uint faces[3]
Definition octa.h:108
void calcmerges()
Merges adjacent faces that can be losslessly merged.
bool issolid() const
returns if the cube passed is entirely solid (no distortions)
Definition octa.h:133
uchar escaped
Definition octa.h:115
bool valid
Definition octa.h:118
cubeext * ext
Definition octa.h:103
bool isvalidcube() const
Returns whether the cube is valid.
uchar merged
Definition octa.h:112
uchar visible
Definition octa.h:116
void setmat(ushort mat, ushort matmask, ushort filtermat, ushort filtermask, int filtergeom)
Sets a cube's materials, given a material & filter to use.
bool isempty() const
returns if the cube is empty (face 0 does not exist)
Definition octa.h:125
void discardchildren(bool fixtex=false, int depth=0)
discards children
ushort material
Definition octa.h:111
uchar edges[12]
Definition octa.h:106
ushort texture[6]
Definition octa.h:110
An object representing the entirety of an octree world.
Definition octa.h:456
int mapsize() const
Returns the linear dimensions of the world.
bool emptymap(int factor, bool force, bool usecfg=true)
Clears the old level and creates a new one.
void clearmapcrc()
sets the CRC field variable to 0
void remip()
Reduces the number of cubes on the level losslessly.
void shrinkmap()
attempts to reduce the mapsize by 1 (halves all linear dimensions)
uint getmapcrc() const
Returns the CRC code for the map currently loaded.
void cleanupva()
Destroys vertex arrays for the octree world.
int lookupmaterial(const vec &v)
Returns the material bitmask value at the given location.
void calclight()
Calculates normals and re-calculates geometry.
bool enlargemap()
Grows the map to an additional gridsize.
int mapscale() const
Returns the gridpower scale of the world.
int compactvslots(bool cull=false)
Removes unnecessary virtual texture slots.
bool save_world(const char *mname, const char *gameident)
Saves the current map to an ogz file.
cube & lookupcube(const ivec &to, int tsize=0, ivec &ro=lu, int &rsize=lusize)
Returns a reference to the cube at the specified world coordinates.
float raycube(const vec &o, const vec &ray, float radius=0, int mode=3, int size=0, const extentity *t=0) const
Returns the distance before a ray hits a cube.
bool load_world(const char *mname, const char *gameident, const char *gameinfo=nullptr, const char *cname=nullptr)
Loads a map file into the octaworld object.
constexpr uint facesolid
Definition octa.h:19
void setcubefaces(cube &c, uint face)
sets the faces to a given value face given
Definition octa.h:421
constexpr uint faceempty
Definition octa.h:18
A representation of a rectangular volume of cubes, with less metadata.
Definition octa.h:358
Entity data capable of being saved to disk.
Definition ents.h:82
Extended entity data not of the subset which is saved to disk.
Definition ents.h:93
Definition geom.h:2530
A representation of a rectangular volume of cubes.
Definition octa.h:297
bool operator==(const selinfo &sel) const
Returns whether the two selections occupy the same space.
Definition octa.h:339
int size() const
Returns the volume of the selection.
Definition octa.h:315
int orient
Definition octa.h:303
bool validate()
Keeps the selection within the world.
int grid
Definition octa.h:302
ivec s
Definition octa.h:301
ivec o
Definition octa.h:300
int us(int d) const
Returns the absolute size of the selection along the specified axis.
Definition octa.h:327
Definition octa.h:393
int size
Definition octa.h:395
int numents
Definition octa.h:397
int timestamp
Definition octa.h:396
Definition octa.h:387
size_t i
Definition octa.h:388
three dimensional Cartesian vector object
Definition geom.h:207