summaryrefslogtreecommitdiff
path: root/src/engine/octarender.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/octarender.cpp')
-rw-r--r--src/engine/octarender.cpp667
1 files changed, 204 insertions, 463 deletions
diff --git a/src/engine/octarender.cpp b/src/engine/octarender.cpp
index 6b8a5b5..afbc7b2 100644
--- a/src/engine/octarender.cpp
+++ b/src/engine/octarender.cpp
@@ -2,8 +2,7 @@
#include "engine.h"
-struct vboinfo
-{
+struct vboinfo {
int uses;
};
@@ -12,8 +11,7 @@ hashtable<GLuint, vboinfo> vbos;
VAR(printvbo, 0, 0, 1);
VARFN(vbosize, maxvbosize, 0, 1<<14, 1<<16, allchanged());
-enum
-{
+enum {
VBO_VBUF = 0,
VBO_EBUF,
NUMVBO
@@ -23,41 +21,32 @@ static vector<uchar> vbodata[NUMVBO];
static vector<vtxarray *> vbovas[NUMVBO];
static int vbosize[NUMVBO];
-void destroyvbo(GLuint vbo)
-{
+void destroyvbo(GLuint vbo) {
vboinfo *exists = vbos.access(vbo);
if(!exists) return;
vboinfo &vbi = *exists;
if(vbi.uses <= 0) return;
vbi.uses--;
- if(!vbi.uses)
- {
+ if(!vbi.uses) {
glDeleteBuffers_(1, &vbo);
vbos.remove(vbo);
}
}
-void genvbo(int type, void *buf, int len, vtxarray **vas, int numva)
-{
+void genvbo(int type, void *buf, int len, vtxarray **vas, int numva) {
gle::disable();
-
GLuint vbo;
glGenBuffers_(1, &vbo);
GLenum target = type==VBO_VBUF ? GL_ARRAY_BUFFER : GL_ELEMENT_ARRAY_BUFFER;
glBindBuffer_(target, vbo);
glBufferData_(target, len, buf, GL_STATIC_DRAW);
glBindBuffer_(target, 0);
-
vboinfo &vbi = vbos[vbo];
vbi.uses = numva;
-
if(printvbo) conoutf(CON_DEBUG, "vbo %d: type %d, size %d, %d uses", vbo, type, len, numva);
-
- loopi(numva)
- {
+ loopi(numva) {
vtxarray *va = vas[i];
- switch(type)
- {
+ switch(type) {
case VBO_VBUF:
va->vbuf = vbo;
break;
@@ -68,31 +57,24 @@ void genvbo(int type, void *buf, int len, vtxarray **vas, int numva)
}
}
-bool readva(vtxarray *va, ushort *&edata, vertex *&vdata)
-{
+bool readva(vtxarray *va, ushort *&edata, vertex *&vdata) {
if(!va->vbuf || !va->ebuf) return false;
-
edata = new ushort[3*va->tris];
vdata = new vertex[va->verts];
-
gle::bindebo(va->ebuf);
glGetBufferSubData_(GL_ELEMENT_ARRAY_BUFFER, (size_t)va->edata, 3*va->tris*sizeof(ushort), edata);
gle::clearebo();
-
gle::bindvbo(va->vbuf);
glGetBufferSubData_(GL_ARRAY_BUFFER, va->voffset*sizeof(vertex), va->verts*sizeof(vertex), vdata);
gle::clearvbo();
return true;
}
-void flushvbo(int type = -1)
-{
- if(type < 0)
- {
+void flushvbo(int type = -1) {
+ if(type < 0) {
loopi(NUMVBO) flushvbo(i);
return;
}
-
vector<uchar> &data = vbodata[type];
if(data.empty()) return;
vector<vtxarray *> &vas = vbovas[type];
@@ -102,42 +84,31 @@ void flushvbo(int type = -1)
vbosize[type] = 0;
}
-uchar *addvbo(vtxarray *va, int type, int numelems, int elemsize)
-{
+uchar *addvbo(vtxarray *va, int type, int numelems, int elemsize) {
vbosize[type] += numelems;
-
vector<uchar> &data = vbodata[type];
vector<vtxarray *> &vas = vbovas[type];
-
vas.add(va);
-
int len = numelems*elemsize;
uchar *buf = data.reserve(len).buf;
data.advance(len);
return buf;
}
-struct verthash
-{
+struct verthash {
static const int SIZE = 1<<13;
int table[SIZE];
vector<vertex> verts;
vector<int> chain;
-
verthash() { clearverts(); }
-
- void clearverts()
- {
+ void clearverts() {
memset(table, -1, sizeof(table));
chain.setsize(0);
verts.setsize(0);
}
-
- int addvert(const vertex &v)
- {
+ int addvert(const vertex &v) {
uint h = hthash(v.pos)&(SIZE-1);
- for(int i = table[h]; i>=0; i = chain[i])
- {
+ for(int i = table[h]; i>=0; i = chain[i]) {
const vertex &c = verts[i];
if(c.pos==v.pos && c.tc==v.tc && c.norm==v.norm && c.tangent==v.tangent && (v.lm.iszero() || c.lm==v.lm))
return i;
@@ -147,9 +118,7 @@ struct verthash
chain.add(table[h]);
return table[h] = verts.length()-1;
}
-
- int addvert(const vec &pos, const vec2 &tc = vec2(0, 0), const svec2 &lm = svec2(0, 0), const bvec &norm = bvec(128, 128, 128), const bvec4 &tangent = bvec4(128, 128, 128, 128))
- {
+ int addvert(const vec &pos, const vec2 &tc = vec2(0, 0), const svec2 &lm = svec2(0, 0), const bvec &norm = bvec(128, 128, 128), const bvec4 &tangent = bvec4(128, 128, 128, 128)) {
vertex vtx;
vtx.pos = pos;
vtx.tc = tc;
@@ -160,46 +129,37 @@ struct verthash
}
};
-enum
-{
+enum {
NO_ALPHA = 0,
ALPHA_BACK,
ALPHA_FRONT
};
-struct sortkey
-{
+struct sortkey {
ushort tex, lmid;
uchar dim, layer, alpha;
-
sortkey() {}
sortkey(ushort tex, ushort lmid, uchar dim, uchar layer = LAYER_TOP, uchar alpha = NO_ALPHA)
: tex(tex), lmid(lmid), dim(dim), layer(layer), alpha(alpha)
{}
-
bool operator==(const sortkey &o) const { return tex==o.tex && lmid==o.lmid && dim==o.dim && layer==o.layer && alpha==o.alpha; }
};
-struct sortval
-{
+struct sortval {
int unlit;
vector<ushort> tris[2];
-
sortval() : unlit(0) {}
};
-static inline bool htcmp(const sortkey &x, const sortkey &y)
-{
+static inline bool htcmp(const sortkey &x, const sortkey &y) {
return x == y;
}
-static inline uint hthash(const sortkey &k)
-{
+static inline uint hthash(const sortkey &k) {
return k.tex + k.lmid*9741;
}
-struct vacollect : verthash
-{
+struct vacollect : verthash {
ivec origin;
int size;
hashtable<sortkey, sortval> indices;
@@ -207,9 +167,7 @@ struct vacollect : verthash
vector<materialsurface> matsurfs;
vector<octaentities *> mapmodels;
int worldtris;
-
- void clear()
- {
+ void clear() {
clearverts();
worldtris = 0;
indices.clear();
@@ -217,47 +175,38 @@ struct vacollect : verthash
mapmodels.setsize(0);
texs.setsize(0);
}
-
- void remapunlit(vector<sortkey> &remap)
- {
+ void remapunlit(vector<sortkey> &remap) {
uint lastlmid[8] = { LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT },
firstlmid[8] = { LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT, LMID_AMBIENT };
int firstlit[8] = { -1, -1, -1, -1, -1, -1, -1, -1 };
- loopv(texs)
- {
+ loopv(texs) {
sortkey &k = texs[i];
- if(k.lmid>=LMID_RESERVED)
- {
+ if(k.lmid>=LMID_RESERVED) {
LightMapTexture &lmtex = lightmaptexs[k.lmid];
int type = lmtex.type&LM_TYPE;
if(k.layer==LAYER_BLEND) type += 2;
else if(k.alpha) type += 4 + 2*(k.alpha-1);
lastlmid[type] = lmtex.unlitx>=0 ? (int) k.lmid : (int) LMID_AMBIENT;
- if(firstlmid[type]==LMID_AMBIENT && lastlmid[type]!=LMID_AMBIENT)
- {
+ if(firstlmid[type]==LMID_AMBIENT && lastlmid[type]!=LMID_AMBIENT) {
firstlit[type] = i;
firstlmid[type] = lastlmid[type];
}
}
- else if(k.lmid==LMID_AMBIENT)
- {
+ else if(k.lmid==LMID_AMBIENT) {
Shader *s = lookupvslot(k.tex, false).slot->shader;
int type = s->type&SHADER_NORMALSLMS ? LM_BUMPMAP0 : LM_DIFFUSE;
if(k.layer==LAYER_BLEND) type += 2;
else if(k.alpha) type += 4 + 2*(k.alpha-1);
- if(lastlmid[type]!=LMID_AMBIENT)
- {
+ if(lastlmid[type]!=LMID_AMBIENT) {
sortval &t = indices[k];
if(t.unlit<=0) t.unlit = lastlmid[type];
}
}
}
- loopj(2)
- {
+ loopj(2) {
int offset = 2*j;
if(firstlmid[offset]==LMID_AMBIENT && firstlmid[offset+1]==LMID_AMBIENT) continue;
- loopi(max(firstlit[offset], firstlit[offset+1]))
- {
+ loopi(max(firstlit[offset], firstlit[offset+1])) {
sortkey &k = texs[i];
if((j ? k.layer!=LAYER_BLEND : k.layer==LAYER_BLEND) || k.alpha) continue;
if(k.lmid!=LMID_AMBIENT) continue;
@@ -267,12 +216,10 @@ struct vacollect : verthash
indices[k].unlit = firstlmid[type];
}
}
- loopj(2)
- {
+ loopj(2) {
int offset = 4 + 2*j;
if(firstlmid[offset]==LMID_AMBIENT && firstlmid[offset+1]==LMID_AMBIENT) continue;
- loopi(max(firstlit[offset], firstlit[offset+1]))
- {
+ loopi(max(firstlit[offset], firstlit[offset+1])) {
sortkey &k = texs[i];
if(k.alpha != j+1) continue;
if(k.lmid!=LMID_AMBIENT) continue;
@@ -282,20 +229,17 @@ struct vacollect : verthash
indices[k].unlit = firstlmid[type];
}
}
- loopv(remap)
- {
+ loopv(remap) {
sortkey &k = remap[i];
sortval &t = indices[k];
if(t.unlit<=0) continue;
LightMapTexture &lm = lightmaptexs[t.unlit];
svec2 lmtc(short(ceil((lm.unlitx + 0.5f) * SHRT_MAX/lm.w)),
short(ceil((lm.unlity + 0.5f) * SHRT_MAX/lm.h)));
- loopl(2) loopvj(t.tris[l])
- {
+ loopl(2) loopvj(t.tris[l]) {
vertex &vtx = verts[t.tris[l][j]];
if(vtx.lm.iszero()) vtx.lm = lmtc;
- else if(vtx.lm != lmtc)
- {
+ else if(vtx.lm != lmtc) {
vertex vtx2 = vtx;
vtx2.lm = lmtc;
t.tris[l][j] = addvert(vtx2);
@@ -305,26 +249,20 @@ struct vacollect : verthash
if(dst) loopl(2) loopvj(t.tris[l]) dst->tris[l].add(t.tris[l][j]);
}
}
-
- void optimize()
- {
+ void optimize() {
vector<sortkey> remap;
enumeratekt(indices, sortkey, k, sortval, t,
- loopl(2) if(t.tris[l].length() && t.unlit<=0)
- {
- if(k.lmid>=LMID_RESERVED && lightmaptexs[k.lmid].unlitx>=0)
- {
+ loopl(2) if(t.tris[l].length() && t.unlit<=0) {
+ if(k.lmid>=LMID_RESERVED && lightmaptexs[k.lmid].unlitx>=0) {
sortkey ukey(k.tex, LMID_AMBIENT, k.dim, k.layer, k.alpha);
sortval *uval = indices.access(ukey);
- if(uval && uval->unlit<=0)
- {
+ if(uval && uval->unlit<=0) {
if(uval->unlit<0) texs.removeobj(ukey);
else remap.add(ukey);
uval->unlit = k.lmid;
}
}
- else if(k.lmid==LMID_AMBIENT)
- {
+ else if(k.lmid==LMID_AMBIENT) {
remap.add(k);
t.unlit = -1;
}
@@ -333,20 +271,15 @@ struct vacollect : verthash
}
);
texs.sort(texsort);
-
remapunlit(remap);
-
matsurfs.shrink(optimizematsurfs(matsurfs.getbuf(), matsurfs.length()));
}
-
- static inline bool texsort(const sortkey &x, const sortkey &y)
- {
+ static inline bool texsort(const sortkey &x, const sortkey &y) {
if(x.alpha < y.alpha) return true;
if(x.alpha > y.alpha) return false;
if(x.layer < y.layer) return true;
if(x.layer > y.layer) return false;
- if(x.tex == y.tex)
- {
+ if(x.tex == y.tex) {
if(x.lmid < y.lmid) return true;
if(x.lmid > y.lmid) return false;
if(x.dim < y.dim) return true;
@@ -362,24 +295,20 @@ struct vacollect : verthash
else return false;
}
-#define GENVERTS(type, ptr, body) do \
- { \
+#define GENVERTS(type, ptr, body) do { \
+ \
type *f = (type *)ptr; \
- loopv(verts) \
- { \
+ loopv(verts) { \
+ \
const vertex &v = verts[i]; \
body; \
f++; \
} \
} while(0)
-
- void genverts(void *buf)
- {
+ void genverts(void *buf) {
GENVERTS(vertex, buf, { *f = v; f->norm.flip(); f->tangent.flip(); });
}
-
- void setupdata(vtxarray *va)
- {
+ void setupdata(vtxarray *va) {
va->verts = verts.length();
va->tris = worldtris/3;
va->vbuf = 0;
@@ -387,27 +316,22 @@ struct vacollect : verthash
va->minvert = 0;
va->maxvert = va->verts-1;
va->voffset = 0;
- if(va->verts)
- {
+ if(va->verts) {
if(vbosize[VBO_VBUF] + verts.length() > maxvbosize ||
vbosize[VBO_EBUF] + worldtris > USHRT_MAX)
flushvbo();
-
va->voffset = vbosize[VBO_VBUF];
uchar *vdata = addvbo(va, VBO_VBUF, va->verts, sizeof(vertex));
genverts(vdata);
va->minvert += va->voffset;
va->maxvert += va->voffset;
}
-
va->matbuf = NULL;
va->matsurfs = matsurfs.length();
- if(va->matsurfs)
- {
+ if(va->matsurfs) {
va->matbuf = new materialsurface[matsurfs.length()];
memcpy(va->matbuf, matsurfs.getbuf(), matsurfs.length()*sizeof(materialsurface));
}
-
va->eslist = NULL;
va->texs = texs.length();
va->blendtris = 0;
@@ -419,13 +343,11 @@ struct vacollect : verthash
va->ebuf = 0;
va->edata = 0;
va->texmask = 0;
- if(va->texs)
- {
+ if(va->texs) {
va->eslist = new elementset[va->texs];
va->edata += vbosize[VBO_EBUF];
ushort *edata = (ushort *)addvbo(va, VBO_EBUF, worldtris, sizeof(ushort)), *curbuf = edata;
- loopv(texs)
- {
+ loopv(texs) {
const sortkey &k = texs[i];
const sortval &t = indices[k];
elementset &e = va->eslist[i];
@@ -434,22 +356,16 @@ struct vacollect : verthash
e.dim = k.dim;
e.layer = k.layer;
ushort *startbuf = curbuf;
- loopl(2)
- {
+ loopl(2) {
e.minvert[l] = USHRT_MAX;
e.maxvert[l] = 0;
-
- if(t.tris[l].length())
- {
+ if(t.tris[l].length()) {
memcpy(curbuf, t.tris[l].getbuf(), t.tris[l].length() * sizeof(ushort));
-
- loopvj(t.tris[l])
- {
+ loopvj(t.tris[l]) {
curbuf[j] += va->voffset;
e.minvert[l] = min(e.minvert[l], curbuf[j]);
e.maxvert[l] = max(e.maxvert[l], curbuf[j]);
}
-
curbuf += t.tris[l].length();
}
e.length[l] = curbuf-startbuf;
@@ -457,19 +373,14 @@ struct vacollect : verthash
if(k.layer==LAYER_BLEND) { va->texs--; va->tris -= e.length[1]/3; va->blends++; va->blendtris += e.length[1]/3; }
else if(k.alpha==ALPHA_BACK) { va->texs--; va->tris -= e.length[1]/3; va->alphaback++; va->alphabacktris += e.length[1]/3; }
else if(k.alpha==ALPHA_FRONT) { va->texs--; va->tris -= e.length[1]/3; va->alphafront++; va->alphafronttris += e.length[1]/3; }
-
Slot &slot = *lookupvslot(k.tex, false).slot;
loopvj(slot.sts) va->texmask |= 1<<slot.sts[j].type;
}
}
-
va->alphatris = va->alphabacktris + va->alphafronttris;
-
if(mapmodels.length()) va->mapmodels.put(mapmodels.getbuf(), mapmodels.length());
}
-
- bool emptyva()
- {
+ bool emptyva() {
return verts.empty() && matsurfs.empty() && mapmodels.empty();
}
} vc;
@@ -481,24 +392,20 @@ vector<tjoint> tjoints;
vec shadowmapmin, shadowmapmax;
-int calcshadowmask(vec *pos, int numpos)
-{
+int calcshadowmask(vec *pos, int numpos) {
extern vec shadowdir;
int mask = 0, used = 1;
vec pe = vec(pos[1]).sub(pos[0]);
- loopk(numpos-2)
- {
+ loopk(numpos-2) {
vec e = vec(pos[k+2]).sub(pos[0]);
- if(vec().cross(pe, e).dot(shadowdir)>0)
- {
+ if(vec().cross(pe, e).dot(shadowdir)>0) {
mask |= 1<<k;
used |= 6<<k;
}
pe = e;
}
if(!mask) return 0;
- loopk(numpos) if(used&(1<<k))
- {
+ loopk(numpos) if(used&(1<<k)) {
const vec &v = pos[k];
shadowmapmin.min(v);
shadowmapmax.max(v);
@@ -508,14 +415,11 @@ int calcshadowmask(vec *pos, int numpos)
VARFP(filltjoints, 0, 1, 1, allchanged());
-void reduceslope(ivec &n)
-{
+void reduceslope(ivec &n) {
int mindim = -1, minval = 64;
- loopi(3) if(n[i])
- {
+ loopi(3) if(n[i]) {
int val = abs(n[i]);
- if(mindim < 0 || val < minval)
- {
+ if(mindim < 0 || val < minval) {
mindim = i;
minval = val;
}
@@ -525,49 +429,44 @@ void reduceslope(ivec &n)
}
// [rotation][dimension]
-extern const vec orientation_tangent[8][3] =
-{
- { vec(0, 1, 0), vec( 1, 0, 0), vec( 1, 0, 0) },
- { vec(0, 0, -1), vec( 0, 0, -1), vec( 0, 1, 0) },
- { vec(0, -1, 0), vec(-1, 0, 0), vec(-1, 0, 0) },
- { vec(0, 0, 1), vec( 0, 0, 1), vec( 0, -1, 0) },
- { vec(0, -1, 0), vec(-1, 0, 0), vec(-1, 0, 0) },
- { vec(0, 1, 0), vec( 1, 0, 0), vec( 1, 0, 0) },
- { vec(0, 0, -1), vec( 0, 0, -1), vec( 0, 1, 0) },
- { vec(0, 0, 1), vec( 0, 0, 1), vec( 0, -1, 0) },
+extern const vec orientation_tangent[8][3] = {
+ {
+ vec(0, 1, 0), vec( 1, 0, 0), vec( 1, 0, 0) }, {
+ vec(0, 0, -1), vec( 0, 0, -1), vec( 0, 1, 0) }, {
+ vec(0, -1, 0), vec(-1, 0, 0), vec(-1, 0, 0) }, {
+ vec(0, 0, 1), vec( 0, 0, 1), vec( 0, -1, 0) }, {
+ vec(0, -1, 0), vec(-1, 0, 0), vec(-1, 0, 0) }, {
+ vec(0, 1, 0), vec( 1, 0, 0), vec( 1, 0, 0) }, {
+ vec(0, 0, -1), vec( 0, 0, -1), vec( 0, 1, 0) }, {
+ vec(0, 0, 1), vec( 0, 0, 1), vec( 0, -1, 0) },
};
-extern const vec orientation_bitangent[8][3] =
-{
- { vec(0, 0, -1), vec( 0, 0, -1), vec( 0, 1, 0) },
- { vec(0, -1, 0), vec(-1, 0, 0), vec(-1, 0, 0) },
- { vec(0, 0, 1), vec( 0, 0, 1), vec( 0, -1, 0) },
- { vec(0, 1, 0), vec( 1, 0, 0), vec( 1, 0, 0) },
- { vec(0, 0, -1), vec( 0, 0, -1), vec( 0, 1, 0) },
- { vec(0, 0, 1), vec( 0, 0, 1), vec( 0, -1, 0) },
- { vec(0, 1, 0), vec( 1, 0, 0), vec( 1, 0, 0) },
- { vec(0, -1, 0), vec(-1, 0, 0), vec(-1, 0, 0) },
+extern const vec orientation_bitangent[8][3] = {
+ {
+ vec(0, 0, -1), vec( 0, 0, -1), vec( 0, 1, 0) }, {
+ vec(0, -1, 0), vec(-1, 0, 0), vec(-1, 0, 0) }, {
+ vec(0, 0, 1), vec( 0, 0, 1), vec( 0, -1, 0) }, {
+ vec(0, 1, 0), vec( 1, 0, 0), vec( 1, 0, 0) }, {
+ vec(0, 0, -1), vec( 0, 0, -1), vec( 0, 1, 0) }, {
+ vec(0, 0, 1), vec( 0, 0, 1), vec( 0, -1, 0) }, {
+ vec(0, 1, 0), vec( 1, 0, 0), vec( 1, 0, 0) }, {
+ vec(0, -1, 0), vec(-1, 0, 0), vec(-1, 0, 0) },
};
-void addtris(const sortkey &key, int orient, vertex *verts, int *index, int numverts, int convex, int shadowmask, int tj)
-{
+void addtris(const sortkey &key, int orient, vertex *verts, int *index, int numverts, int convex, int shadowmask, int tj) {
int &total = vc.worldtris;
int edge = orient*(MAXFACEVERTS+1);
- loopi(numverts-2) if(index[0]!=index[i+1] && index[i+1]!=index[i+2] && index[i+2]!=index[0])
- {
+ loopi(numverts-2) if(index[0]!=index[i+1] && index[i+1]!=index[i+2] && index[i+2]!=index[0]) {
vector<ushort> &idxs = vc.indices[key].tris[(shadowmask>>i)&1];
int left = index[0], mid = index[i+1], right = index[i+2], start = left, i0 = left, i1 = -1;
- loopk(4)
- {
+ loopk(4) {
int i2 = -1, ctj = -1, cedge = -1;
- switch(k)
- {
+ switch(k) {
case 1: i1 = i2 = mid; cedge = edge+i+1; break;
case 2: if(i1 != mid || i0 == left) { i0 = i1; i1 = right; } i2 = right; if(i+1 == numverts-2) cedge = edge+i+2; break;
case 3: if(i0 == start) { i0 = i1; i1 = left; } i2 = left; // fall-through
default: if(!i) cedge = edge; break;
}
- if(i1 != i2)
- {
+ if(i1 != i2) {
if(total + 3 > USHRT_MAX) return;
total += 3;
idxs.add(i0);
@@ -575,18 +474,15 @@ void addtris(const sortkey &key, int orient, vertex *verts, int *index, int numv
idxs.add(i2);
i1 = i2;
}
- if(cedge >= 0)
- {
- for(ctj = tj;;)
- {
+ if(cedge >= 0) {
+ for(ctj = tj;;) {
if(ctj < 0) break;
if(tjoints[ctj].edge < cedge) { ctj = tjoints[ctj].next; continue; }
if(tjoints[ctj].edge != cedge) ctj = -1;
break;
}
}
- if(ctj >= 0)
- {
+ if(ctj >= 0) {
int e1 = cedge%(MAXFACEVERTS+1), e2 = (e1+1)%numverts;
vertex &v1 = verts[e1], &v2 = verts[e2];
ivec d(vec(v2.pos).sub(v1.pos).mul(8));
@@ -598,15 +494,12 @@ void addtris(const sortkey &key, int orient, vertex *verts, int *index, int numv
offset2 = (int(v2.pos[axis]*8) - origin) / d[axis];
vec o = vec(v1.pos).sub(vec(d).mul(offset1/8.0f));
float doffset = 1.0f / (offset2 - offset1);
-
- if(i1 < 0) for(;;)
- {
+ if(i1 < 0) for(;;) {
tjoint &t = tjoints[ctj];
if(t.next < 0 || tjoints[t.next].edge != cedge) break;
ctj = t.next;
}
- while(ctj >= 0)
- {
+ while(ctj >= 0) {
tjoint &t = tjoints[ctj];
if(t.edge != cedge) break;
float offset = (t.offset - offset1) * doffset;
@@ -619,8 +512,7 @@ void addtris(const sortkey &key, int orient, vertex *verts, int *index, int numv
vt.tangent.lerp(v1.tangent, v2.tangent, offset);
int i2 = vc.addvert(vt);
if(i2 < 0) return;
- if(i1 >= 0)
- {
+ if(i1 >= 0) {
if(total + 3 > USHRT_MAX) return;
total += 3;
idxs.add(i0);
@@ -636,8 +528,7 @@ void addtris(const sortkey &key, int orient, vertex *verts, int *index, int numv
}
}
-static inline void calctexgen(VSlot &vslot, int dim, vec4 &sgen, vec4 &tgen)
-{
+static inline void calctexgen(VSlot &vslot, int dim, vec4 &sgen, vec4 &tgen) {
Texture *tex = vslot.slot->sts.empty() ? notexture : vslot.slot->sts[0].t;
const texrotation &r = texrotations[vslot.rotation];
float k = TEX_SCALE/vslot.scale,
@@ -650,53 +541,45 @@ static inline void calctexgen(VSlot &vslot, int dim, vec4 &sgen, vec4 &tgen)
int sdim = si[dim], tdim = ti[dim];
sgen = vec4(0, 0, 0, soff);
tgen = vec4(0, 0, 0, toff);
- if(r.swapxy)
- {
+ if(r.swapxy) {
sgen[tdim] = (dim <= 1 ? -sk : sk);
tgen[sdim] = tk;
}
- else
- {
+ else {
sgen[sdim] = sk;
tgen[tdim] = (dim <= 1 ? -tk : tk);
}
}
-ushort encodenormal(const vec &n)
-{
+ushort encodenormal(const vec &n) {
if(n.iszero()) return 0;
int yaw = int(-atan2(n.x, n.y)/RAD), pitch = int(asin(n.z)/RAD);
return ushort(clamp(pitch + 90, 0, 180)*360 + (yaw < 0 ? yaw%360 + 360 : yaw%360) + 1);
}
-vec decodenormal(ushort norm)
-{
+vec decodenormal(ushort norm) {
if(!norm) return vec(0, 0, 1);
norm--;
const vec2 &yaw = sincos360[norm%360], &pitch = sincos360[norm/360+270];
return vec(-yaw.y*pitch.x, yaw.x*pitch.x, pitch.y);
}
-void guessnormals(const vec *pos, int numverts, vec *normals)
-{
+void guessnormals(const vec *pos, int numverts, vec *normals) {
vec n1, n2;
n1.cross(pos[0], pos[1], pos[2]);
- if(numverts != 4)
- {
+ if(numverts != 4) {
n1.normalize();
loopk(numverts) normals[k] = n1;
return;
}
n2.cross(pos[0], pos[2], pos[3]);
- if(n1.iszero())
- {
+ if(n1.iszero()) {
n2.normalize();
loopk(4) normals[k] = n2;
return;
}
else n1.normalize();
- if(n2.iszero())
- {
+ if(n2.iszero()) {
loopk(4) normals[k] = n1;
return;
}
@@ -708,16 +591,13 @@ void guessnormals(const vec *pos, int numverts, vec *normals)
normals[3] = n2;
}
-void addcubeverts(VSlot &vslot, int orient, int size, vec *pos, int convex, ushort texture, ushort lmid, vertinfo *vinfo, int numverts, int tj = -1, int grassy = 0, bool alpha = false, int layer = LAYER_TOP)
-{
+void addcubeverts(VSlot &vslot, int orient, int size, vec *pos, int convex, ushort texture, ushort lmid, vertinfo *vinfo, int numverts, int tj = -1, int grassy = 0, bool alpha = false, int layer = LAYER_TOP) {
(void) grassy;
int dim = dimension(orient);
int shadowmask = alpha ? 0 : calcshadowmask(pos, numverts);
-
LightMap *lm = NULL;
LightMapTexture *lmtex = NULL;
- if(lightmaps.inrange(lmid-LMID_RESERVED))
- {
+ if(lightmaps.inrange(lmid-LMID_RESERVED)) {
lm = &lightmaps[lmid-LMID_RESERVED];
if((lm->type&LM_TYPE)==LM_DIFFUSE ||
((lm->type&LM_TYPE)==LM_BUMPMAP0 &&
@@ -726,70 +606,58 @@ void addcubeverts(VSlot &vslot, int orient, int size, vec *pos, int convex, usho
lmtex = &lightmaptexs[lm->tex];
else lm = NULL;
}
-
vec4 sgen, tgen;
calctexgen(vslot, dim, sgen, tgen);
vertex verts[MAXFACEVERTS];
int index[MAXFACEVERTS];
- loopk(numverts)
- {
+ loopk(numverts) {
vertex &v = verts[k];
v.pos = pos[k];
v.tc = vec2(sgen.dot(v.pos), tgen.dot(v.pos));
- if(lmtex)
- {
+ if(lmtex) {
v.lm = svec2(short(ceil((lm->offsetx + vinfo[k].u*(float(LM_PACKW)/float(USHRT_MAX+1)) + 0.5f) * float(SHRT_MAX)/lmtex->w)),
short(ceil((lm->offsety + vinfo[k].v*(float(LM_PACKH)/float(USHRT_MAX+1)) + 0.5f) * float(SHRT_MAX)/lmtex->h)));
}
else v.lm = svec2(0, 0);
- if(vinfo && vinfo[k].norm)
- {
+ if(vinfo && vinfo[k].norm) {
vec n = decodenormal(vinfo[k].norm), t = orientation_tangent[vslot.rotation][dim];
t.project(n).normalize();
v.norm = bvec(n);
v.tangent = bvec4(bvec(t), orientation_bitangent[vslot.rotation][dim].scalartriple(n, t) < 0 ? 0 : 255);
}
- else
- {
+ else {
v.norm = bvec(128, 128, 255);
v.tangent = bvec4(255, 128, 128, 255);
}
index[k] = vc.addvert(v);
if(index[k] < 0) return;
}
-
if(lmid >= LMID_RESERVED) lmid = lm ? lm->tex : LMID_AMBIENT;
-
sortkey key(texture, lmid, !vslot.scroll.iszero() ? dim : 3, layer == LAYER_BLEND ? LAYER_BLEND : LAYER_TOP, alpha ? (vslot.alphaback ? ALPHA_BACK : (vslot.alphafront ? ALPHA_FRONT : NO_ALPHA)) : NO_ALPHA);
addtris(key, orient, verts, index, numverts, convex, shadowmask, tj);
}
-struct edgegroup
-{
+struct edgegroup {
ivec slope, origin;
int axis;
};
-static uint hthash(const edgegroup &g)
-{
+static uint hthash(const edgegroup &g) {
return g.slope.x^(g.slope.y<<2)^(g.slope.z<<4)^g.origin.x^g.origin.y^g.origin.z;
}
-static bool htcmp(const edgegroup &x, const edgegroup &y)
-{
+static bool htcmp(const edgegroup &x, const edgegroup &y) {
return x.slope==y.slope && x.origin==y.origin;
}
-enum
-{
+enum {
CE_START = 1<<0,
CE_END = 1<<1,
CE_FLIP = 1<<2,
CE_DUP = 1<<3
};
-struct cubeedge
-{
+struct cubeedge {
cube *c;
int next, offset;
ushort size;
@@ -799,26 +667,21 @@ struct cubeedge
vector<cubeedge> cubeedges;
hashtable<edgegroup, int> edgegroups(1<<13);
-void gencubeedges(cube &c, const ivec &co, int size)
-{
+void gencubeedges(cube &c, const ivec &co, int size) {
ivec pos[MAXFACEVERTS];
int vis;
- loopi(6) if((vis = visibletris(c, i, co, size)))
- {
+ loopi(6) if((vis = visibletris(c, i, co, size))) {
int numverts = c.ext ? c.ext->surfaces[i].numverts&MAXFACEVERTS : 0;
- if(numverts)
- {
+ if(numverts) {
vertinfo *verts = c.ext->verts() + c.ext->surfaces[i].verts;
ivec vo = ivec(co).mask(~0xFFF).shl(3);
- loopj(numverts)
- {
+ loopj(numverts) {
vertinfo &v = verts[j];
pos[j] = ivec(v.x, v.y, v.z).add(vo);
}
}
else if(c.merged&(1<<i)) continue;
- else
- {
+ else {
ivec v[4];
genfaceverts(c, i, v);
int order = vis&4 || (!flataxisface(c, i) && faceconvexity(v) < 0) ? 1 : 0;
@@ -828,20 +691,17 @@ void gencubeedges(cube &c, const ivec &co, int size)
pos[numverts++] = v[order+2].mul(size).add(vo);
if(vis&2) pos[numverts++] = v[(order+3)&3].mul(size).add(vo);
}
- loopj(numverts)
- {
+ loopj(numverts) {
int e1 = j, e2 = j+1 < numverts ? j+1 : 0;
ivec d = pos[e2];
d.sub(pos[e1]);
if(d.iszero()) continue;
int axis = abs(d.x) > abs(d.y) ? (abs(d.x) > abs(d.z) ? 0 : 2) : (abs(d.y) > abs(d.z) ? 1 : 2);
- if(d[axis] < 0)
- {
+ if(d[axis] < 0) {
d.neg();
swap(e1, e2);
}
reduceslope(d);
-
int t1 = pos[e1][axis]/d[axis],
t2 = pos[e2][axis]/d[axis];
edgegroup g;
@@ -855,22 +715,17 @@ void gencubeedges(cube &c, const ivec &co, int size)
ce.index = i*(MAXFACEVERTS+1)+j;
ce.flags = CE_START | CE_END | (e1!=j ? CE_FLIP : 0);
ce.next = -1;
-
bool insert = true;
int *exists = edgegroups.access(g);
- if(exists)
- {
+ if(exists) {
int prev = -1, cur = *exists;
- while(cur >= 0)
- {
+ while(cur >= 0) {
cubeedge &p = cubeedges[cur];
- if(ce.offset <= p.offset+p.size)
- {
+ if(ce.offset <= p.offset+p.size) {
if(ce.offset < p.offset) break;
if(p.flags&CE_DUP ?
ce.offset+ce.size <= p.offset+p.size :
- ce.offset==p.offset && ce.size==p.size)
- {
+ ce.offset==p.offset && ce.size==p.size) {
p.flags |= CE_DUP;
insert = false;
break;
@@ -880,11 +735,9 @@ void gencubeedges(cube &c, const ivec &co, int size)
prev = cur;
cur = p.next;
}
- if(insert)
- {
+ if(insert) {
ce.next = cur;
- while(cur >= 0)
- {
+ while(cur >= 0) {
cubeedge &p = cubeedges[cur];
if(ce.offset+ce.size==p.offset) { ce.flags &= ~CE_END; break; }
cur = p.next;
@@ -894,18 +747,15 @@ void gencubeedges(cube &c, const ivec &co, int size)
}
}
else edgegroups[g] = cubeedges.length();
-
if(insert) cubeedges.add(ce);
}
}
}
-void gencubeedges(cube *c = worldroot, const ivec &co = ivec(0, 0, 0), int size = worldsize>>1)
-{
+void gencubeedges(cube *c = worldroot, const ivec &co = ivec(0, 0, 0), int size = worldsize>>1) {
progress("fixing t-joints...");
neighbourstack[++neighbourdepth] = c;
- loopi(8)
- {
+ loopi(8) {
ivec o(i, co, size);
if(c[i].ext) c[i].ext->tjoints = -1;
if(c[i].children) gencubeedges(c[i].children, o, size>>1);
@@ -914,29 +764,23 @@ void gencubeedges(cube *c = worldroot, const ivec &co = ivec(0, 0, 0), int size
--neighbourdepth;
}
-void gencubeverts(cube &c, const ivec &co, int size, int csi)
-{
+void gencubeverts(cube &c, const ivec &co, int size, int csi) {
if(!(c.visible&0xC0)) return;
-
int vismask = ~c.merged & 0x3F;
if(!(c.visible&0x80)) vismask &= c.visible;
if(!vismask) return;
-
int tj = filltjoints && c.ext ? c.ext->tjoints : -1, vis;
- loopi(6) if(vismask&(1<<i) && (vis = visibletris(c, i, co, size)))
- {
+ loopi(6) if(vismask&(1<<i) && (vis = visibletris(c, i, co, size))) {
vec pos[MAXFACEVERTS];
vertinfo *verts = NULL;
int numverts = c.ext ? c.ext->surfaces[i].numverts&MAXFACEVERTS : 0, convex = 0;
- if(numverts)
- {
+ if(numverts) {
verts = c.ext->verts() + c.ext->surfaces[i].verts;
vec vo(ivec(co).mask(~0xFFF));
loopj(numverts) pos[j] = vec(verts[j].getxyz()).mul(1.0f/8).add(vo);
if(!flataxisface(c, i)) convex = faceconvexity(verts, numverts, size);
}
- else
- {
+ else {
ivec v[4];
genfaceverts(c, i, v);
if(!flataxisface(c, i)) convex = faceconvexity(v);
@@ -947,15 +791,13 @@ void gencubeverts(cube &c, const ivec &co, int size, int csi)
pos[numverts++] = vec(v[order+2]).mul(size/8.0f).add(vo);
if(vis&2) pos[numverts++] = vec(v[(order+3)&3]).mul(size/8.0f).add(vo);
}
-
VSlot &vslot = lookupvslot(c.texture[i], true),
*layer = vslot.layer && !(c.material&MAT_ALPHA) ? &lookupvslot(vslot.layer, true) : NULL;
while(tj >= 0 && tjoints[tj].edge < i*(MAXFACEVERTS+1)) tj = tjoints[tj].next;
int hastj = tj >= 0 && tjoints[tj].edge < (i+1)*(MAXFACEVERTS+1) ? tj : -1;
if(!c.ext)
addcubeverts(vslot, i, size, pos, convex, c.texture[i], LMID_AMBIENT, NULL, numverts, hastj, 0, (c.material&MAT_ALPHA)!=0);
- else
- {
+ else {
const surfaceinfo &surf = c.ext->surfaces[i];
if(!surf.numverts || surf.numverts&LAYER_TOP)
addcubeverts(vslot, i, size, pos, convex, c.texture[i], surf.lmid[0], verts, numverts, hastj, 0, (c.material&MAT_ALPHA)!=0, LAYER_TOP|(surf.numverts&LAYER_BLEND));
@@ -971,10 +813,8 @@ int allocva = 0;
int wtris = 0, wverts = 0, vtris = 0, vverts = 0, glde = 0, gbatches = 0;
vector<vtxarray *> valist, varoot;
-vtxarray *newva(const ivec &co, int size)
-{
+vtxarray *newva(const ivec &co, int size) {
vc.optimize();
-
vtxarray *va = new vtxarray;
va->parent = NULL;
va->o = co;
@@ -986,29 +826,23 @@ vtxarray *newva(const ivec &co, int size)
va->bbmax = ivec(-1, -1, -1);
va->hasmerges = 0;
va->mergelevel = -1;
-
vc.setupdata(va);
-
wverts += va->verts;
wtris += va->tris + va->blends + va->alphatris;
allocva++;
valist.add(va);
-
return va;
}
-void destroyva(vtxarray *va, bool reparent)
-{
+void destroyva(vtxarray *va, bool reparent) {
wverts -= va->verts;
wtris -= va->tris + va->blends + va->alphatris;
allocva--;
valist.removeobj(va);
if(!va->parent) varoot.removeobj(va);
- if(reparent)
- {
+ if(reparent) {
if(va->parent) va->parent->children.removeobj(va);
- loopv(va->children)
- {
+ loopv(va->children) {
vtxarray *child = va->children[i];
child->parent = va->parent;
if(child->parent) child->parent->children.add(child);
@@ -1021,12 +855,9 @@ void destroyva(vtxarray *va, bool reparent)
delete va;
}
-void clearvas(cube *c)
-{
- loopi(8)
- {
- if(c[i].ext)
- {
+void clearvas(cube *c) {
+ loopi(8) {
+ if(c[i].ext) {
if(c[i].ext->va) destroyva(c[i].ext->va, false);
c[i].ext->va = NULL;
c[i].ext->tjoints = -1;
@@ -1035,23 +866,19 @@ void clearvas(cube *c)
}
}
-void updatevabb(vtxarray *va, bool force)
-{
+void updatevabb(vtxarray *va, bool force) {
if(!force && va->bbmin.x >= 0) return;
-
va->bbmin = va->geommin;
va->bbmax = va->geommax;
va->bbmin.min(va->matmin);
va->bbmax.max(va->matmax);
- loopv(va->children)
- {
+ loopv(va->children) {
vtxarray *child = va->children[i];
updatevabb(child, force);
va->bbmin.min(child->bbmin);
va->bbmax.max(child->bbmax);
}
- loopv(va->mapmodels)
- {
+ loopv(va->mapmodels) {
octaentities *oe = va->mapmodels[i];
va->bbmin.min(oe->bbmin);
va->bbmax.max(oe->bbmax);
@@ -1060,13 +887,11 @@ void updatevabb(vtxarray *va, bool force)
va->bbmax.min(ivec(va->o).add(va->size));
}
-void updatevabbs(bool force)
-{
+void updatevabbs(bool force) {
loopv(varoot) updatevabb(varoot[i], force);
}
-struct mergedface
-{
+struct mergedface {
uchar orient, lmid, numverts;
ushort mat, tex;
vertinfo *verts;
@@ -1077,16 +902,13 @@ struct mergedface
static int vahasmerges = 0, vamergemax = 0;
static vector<mergedface> vamerges[MAXMERGELEVEL+1];
-int genmergedfaces(cube &c, const ivec &co, int size, int minlevel = -1)
-{
+int genmergedfaces(cube &c, const ivec &co, int size, int minlevel = -1) {
if(!c.ext || isempty(c)) return -1;
int tj = c.ext->tjoints, maxlevel = -1;
- loopi(6) if(c.merged&(1<<i))
- {
+ loopi(6) if(c.merged&(1<<i)) {
surfaceinfo &surf = c.ext->surfaces[i];
int numverts = surf.numverts&MAXFACEVERTS;
- if(!numverts)
- {
+ if(!numverts) {
if(minlevel < 0) vahasmerges |= MERGE_PART;
continue;
}
@@ -1099,18 +921,13 @@ int genmergedfaces(cube &c, const ivec &co, int size, int minlevel = -1)
mf.verts = c.ext->verts() + surf.verts;
mf.tjoints = -1;
int level = calcmergedsize(i, co, size, mf.verts, mf.numverts&MAXFACEVERTS);
- if(level > minlevel)
- {
+ if(level > minlevel) {
maxlevel = max(maxlevel, level);
-
while(tj >= 0 && tjoints[tj].edge < i*(MAXFACEVERTS+1)) tj = tjoints[tj].next;
if(tj >= 0 && tjoints[tj].edge < (i+1)*(MAXFACEVERTS+1)) mf.tjoints = tj;
-
VSlot &vslot = lookupvslot(mf.tex, true);
-
if(surf.numverts&LAYER_TOP) vamerges[level].add(mf);
- if(surf.numverts&LAYER_BOTTOM)
- {
+ if(surf.numverts&LAYER_BOTTOM) {
mf.tex = vslot.layer;
mf.lmid = surf.lmid[1];
mf.numverts &= ~LAYER_TOP;
@@ -1119,22 +936,18 @@ int genmergedfaces(cube &c, const ivec &co, int size, int minlevel = -1)
}
}
}
- if(maxlevel >= 0)
- {
+ if(maxlevel >= 0) {
vamergemax = max(vamergemax, maxlevel);
vahasmerges |= MERGE_ORIGIN;
}
return maxlevel;
}
-int findmergedfaces(cube &c, const ivec &co, int size, int csi, int minlevel)
-{
+int findmergedfaces(cube &c, const ivec &co, int size, int csi, int minlevel) {
if(c.ext && c.ext->va && !(c.ext->va->hasmerges&MERGE_ORIGIN)) return c.ext->va->mergelevel;
- else if(c.children)
- {
+ else if(c.children) {
int maxlevel = -1;
- loopi(8)
- {
+ loopi(8) {
ivec o(i, co, size/2);
int level = findmergedfaces(c.children[i], o, size/2, csi-1, minlevel);
maxlevel = max(maxlevel, level);
@@ -1145,18 +958,15 @@ int findmergedfaces(cube &c, const ivec &co, int size, int csi, int minlevel)
else return -1;
}
-void addmergedverts(int level, const ivec &o)
-{
+void addmergedverts(int level, const ivec &o) {
vector<mergedface> &mfl = vamerges[level];
if(mfl.empty()) return;
vec vo(ivec(o).mask(~0xFFF));
vec pos[MAXFACEVERTS];
- loopv(mfl)
- {
+ loopv(mfl) {
mergedface &mf = mfl[i];
int numverts = mf.numverts&MAXFACEVERTS;
- loopi(numverts)
- {
+ loopi(numverts) {
vertinfo &v = mf.verts[i];
pos[i] = vec(v.x, v.y, v.z).mul(1.0f/8).add(vo);
}
@@ -1167,21 +977,16 @@ void addmergedverts(int level, const ivec &o)
mfl.setsize(0);
}
-void rendercube(cube &c, const ivec &co, int size, int csi, int &maxlevel) // creates vertices and indices ready to be put into a va
-{
+void rendercube(cube &c, const ivec &co, int size, int csi, int &maxlevel) { // creates vertices and indices ready to be put into a va {
//if(size<=16) return;
- if(c.ext && c.ext->va)
- {
+ if(c.ext && c.ext->va) {
maxlevel = max(maxlevel, c.ext->va->mergelevel);
return; // don't re-render
}
-
- if(c.children)
- {
+ if(c.children) {
neighbourstack[++neighbourdepth] = c.children;
c.escaped = 0;
- loopi(8)
- {
+ loopi(8) {
ivec o(i, co, size/2);
int level = -1;
rendercube(c.children[i], o, size/2, csi-1, level);
@@ -1190,91 +995,65 @@ void rendercube(cube &c, const ivec &co, int size, int csi, int &maxlevel) // c
maxlevel = max(maxlevel, level);
}
--neighbourdepth;
-
if(csi <= MAXMERGELEVEL && vamerges[csi].length()) addmergedverts(csi, co);
-
- if(c.ext)
- {
+ if(c.ext) {
if(c.ext->ents && c.ext->ents->mapmodels.length()) vc.mapmodels.add(c.ext->ents);
}
return;
}
-
- if(!isempty(c))
- {
+ if(!isempty(c)) {
gencubeverts(c, co, size, csi);
if(c.merged) maxlevel = max(maxlevel, genmergedfaces(c, co, size));
}
if(c.material != MAT_AIR) genmatsurfs(c, co, size, vc.matsurfs);
-
- if(c.ext)
- {
+ if(c.ext) {
if(c.ext->ents && c.ext->ents->mapmodels.length()) vc.mapmodels.add(c.ext->ents);
}
-
if(csi <= MAXMERGELEVEL && vamerges[csi].length()) addmergedverts(csi, co);
}
-void calcgeombb(const ivec &co, int size, ivec &bbmin, ivec &bbmax)
-{
+void calcgeombb(const ivec &co, int size, ivec &bbmin, ivec &bbmax) {
vec vmin(co), vmax = vmin;
vmin.add(size);
-
- loopv(vc.verts)
- {
+ loopv(vc.verts) {
const vec &v = vc.verts[i].pos;
vmin.min(v);
vmax.max(v);
}
-
bbmin = ivec(vmin.mul(8)).shr(3);
bbmax = ivec(vmax.mul(8)).add(7).shr(3);
}
-void calcmatbb(const ivec &co, int size, ivec &bbmin, ivec &bbmax)
-{
+void calcmatbb(const ivec &co, int size, ivec &bbmin, ivec &bbmax) {
bbmax = co;
(bbmin = bbmax).add(size);
- loopv(vc.matsurfs)
- {
+ loopv(vc.matsurfs) {
materialsurface &m = vc.matsurfs[i];
-
int dim = dimension(m.orient),
r = R[dim],
c = C[dim];
bbmin[dim] = min(bbmin[dim], m.o[dim]);
bbmax[dim] = max(bbmax[dim], m.o[dim]);
-
bbmin[r] = min(bbmin[r], m.o[r]);
bbmax[r] = max(bbmax[r], m.o[r] + m.rsize);
-
bbmin[c] = min(bbmin[c], m.o[c]);
bbmax[c] = max(bbmax[c], m.o[c] + m.csize);
}
}
-void setva(cube &c, const ivec &co, int size, int csi)
-{
+void setva(cube &c, const ivec &co, int size, int csi) {
ASSERT(size <= 0x1000);
-
int vamergeoffset[MAXMERGELEVEL+1];
loopi(MAXMERGELEVEL+1) vamergeoffset[i] = vamerges[i].length();
-
vc.origin = co;
vc.size = size;
-
shadowmapmin = vec(co).add(size);
shadowmapmax = vec(co);
-
int maxlevel = -1;
rendercube(c, co, size, csi, maxlevel);
-
ivec bbmin, bbmax;
-
calcgeombb(co, size, bbmin, bbmax);
-
- if(size == min(0x1000, worldsize/2) || !vc.emptyva())
- {
+ if(size == min(0x1000, worldsize/2) || !vc.emptyva()) {
vtxarray *va = newva(co, size);
ext(c).va = va;
va->geommin = bbmin;
@@ -1285,29 +1064,22 @@ void setva(cube &c, const ivec &co, int size, int csi)
va->hasmerges = vahasmerges;
va->mergelevel = vamergemax;
}
- else
- {
+ else {
loopi(MAXMERGELEVEL+1) vamerges[i].setsize(vamergeoffset[i]);
}
-
vc.clear();
}
-static inline int setcubevisibility(cube &c, const ivec &co, int size)
-{
+static inline int setcubevisibility(cube &c, const ivec &co, int size) {
int numvis = 0, vismask = 0, collidemask = 0, checkmask = 0;
- loopi(6)
- {
+ loopi(6) {
int facemask = classifyface(c, i, co, size);
- if(facemask&1)
- {
+ if(facemask&1) {
vismask |= 1<<i;
- if(c.merged&(1<<i))
- {
+ if(c.merged&(1<<i)) {
if(c.ext && c.ext->surfaces[i].numverts&MAXFACEVERTS) numvis++;
}
- else
- {
+ else {
numvis++;
if(!(c.ext && c.ext->surfaces[i].numverts&MAXFACEVERTS)) checkmask |= 1<<i;
}
@@ -1322,45 +1094,36 @@ VARF(vafacemax, 64, 384, 256*256, allchanged());
VARF(vafacemin, 0, 96, 256*256, allchanged());
VARF(vacubesize, 32, 128, 0x1000, allchanged());
-int updateva(cube *c, const ivec &co, int size, int csi)
-{
+int updateva(cube *c, const ivec &co, int size, int csi) {
progress("recalculating geometry...");
int ccount = 0, cmergemax = vamergemax, chasmerges = vahasmerges;
neighbourstack[++neighbourdepth] = c;
- loopi(8) // counting number of semi-solid/solid children cubes
- {
+ loopi(8) { // counting number of semi-solid/solid children cubes {
int count = 0, childpos = varoot.length();
ivec o(i, co, size);
vamergemax = 0;
vahasmerges = 0;
- if(c[i].ext && c[i].ext->va)
- {
+ if(c[i].ext && c[i].ext->va) {
varoot.add(c[i].ext->va);
if(c[i].ext->va->hasmerges&MERGE_ORIGIN) findmergedfaces(c[i], o, size, csi, csi);
}
- else
- {
+ else {
if(c[i].children) count += updateva(c[i].children, o, size/2, csi-1);
- else
- {
+ else {
if(!isempty(c[i])) count += setcubevisibility(c[i], o, size);
}
int tcount = count + (csi <= MAXMERGELEVEL ? vamerges[csi].length() : 0);
- if(tcount > vafacemax || (tcount >= vafacemin && size >= vacubesize) || size == min(0x1000, worldsize/2))
- {
+ if(tcount > vafacemax || (tcount >= vafacemin && size >= vacubesize) || size == min(0x1000, worldsize/2)) {
loadprogress = clamp(recalcprogress/float(allocnodes), 0.0f, 1.0f);
setva(c[i], o, size, csi);
- if(c[i].ext && c[i].ext->va)
- {
- while(varoot.length() > childpos)
- {
+ if(c[i].ext && c[i].ext->va) {
+ while(varoot.length() > childpos) {
vtxarray *child = varoot.pop();
c[i].ext->va->children.add(child);
child->parent = c[i].ext->va;
}
varoot.add(c[i].ext->va);
- if(vamergemax > size)
- {
+ if(vamergemax > size) {
cmergemax = max(cmergemax, vamergemax);
chasmerges |= vahasmerges&~MERGE_USE;
}
@@ -1377,58 +1140,46 @@ int updateva(cube *c, const ivec &co, int size, int csi)
--neighbourdepth;
vamergemax = cmergemax;
vahasmerges = chasmerges;
-
return ccount;
}
-void addtjoint(const edgegroup &g, const cubeedge &e, int offset)
-{
+void addtjoint(const edgegroup &g, const cubeedge &e, int offset) {
int vcoord = (g.slope[g.axis]*offset + g.origin[g.axis]) & 0x7FFF;
tjoint &tj = tjoints.add();
tj.offset = vcoord / g.slope[g.axis];
tj.edge = e.index;
-
int prev = -1, cur = ext(*e.c).tjoints;
- while(cur >= 0)
- {
+ while(cur >= 0) {
tjoint &o = tjoints[cur];
if(tj.edge < o.edge || (tj.edge==o.edge && (e.flags&CE_FLIP ? tj.offset > o.offset : tj.offset < o.offset))) break;
prev = cur;
cur = o.next;
}
-
tj.next = cur;
if(prev < 0) e.c->ext->tjoints = tjoints.length()-1;
else tjoints[prev].next = tjoints.length()-1;
}
-void findtjoints(int cur, const edgegroup &g)
-{
+void findtjoints(int cur, const edgegroup &g) {
int active = -1;
- while(cur >= 0)
- {
+ while(cur >= 0) {
cubeedge &e = cubeedges[cur];
int prevactive = -1, curactive = active;
- while(curactive >= 0)
- {
+ while(curactive >= 0) {
cubeedge &a = cubeedges[curactive];
- if(a.offset+a.size <= e.offset)
- {
+ if(a.offset+a.size <= e.offset) {
if(prevactive >= 0) cubeedges[prevactive].next = a.next;
else active = a.next;
}
- else
- {
+ else {
prevactive = curactive;
- if(!(a.flags&CE_DUP))
- {
+ if(!(a.flags&CE_DUP)) {
if(e.flags&CE_START && e.offset > a.offset && e.offset < a.offset+a.size)
addtjoint(g, a, e.offset);
if(e.flags&CE_END && e.offset+e.size > a.offset && e.offset+e.size < a.offset+a.size)
addtjoint(g, a, e.offset+e.size);
}
- if(!(e.flags&CE_DUP))
- {
+ if(!(e.flags&CE_DUP)) {
if(a.flags&CE_START && a.offset > e.offset && a.offset < e.offset+e.size)
addtjoint(g, e, a.offset);
if(a.flags&CE_END && a.offset+a.size > e.offset && a.offset+a.size < e.offset+e.size)
@@ -1444,8 +1195,7 @@ void findtjoints(int cur, const edgegroup &g)
}
}
-void findtjoints()
-{
+void findtjoints() {
recalcprogress = 0;
gencubeedges();
tjoints.setsize(0);
@@ -1454,38 +1204,31 @@ void findtjoints()
edgegroups.clear();
}
-void octarender() // creates va s for all leaf cubes that don't already have them
-{
+void octarender() { // creates va s for all leaf cubes that don't already have them {
int csi = 0;
while(1<<csi < worldsize) csi++;
-
recalcprogress = 0;
varoot.setsize(0);
updateva(worldroot, ivec(0, 0, 0), worldsize/2, csi-1);
loadprogress = 0;
flushvbo();
-
visibleva = NULL;
}
-void precachetextures()
-{
+void precachetextures() {
vector<int> texs;
- loopv(valist)
- {
+ loopv(valist) {
vtxarray *va = valist[i];
loopj(va->texs + va->blends) if(texs.find(va->eslist[j].texture) < 0) texs.add(va->eslist[j].texture);
}
- loopv(texs)
- {
+ loopv(texs) {
loadprogress = float(i+1)/texs.length();
lookupvslot(texs[i]);
}
loadprogress = 0;
}
-void allchanged(bool load)
-{
+void allchanged(bool load) {
renderprogress(0, "clearing vertex arrays...");
clearvas(worldroot);
resetqueries();
@@ -1499,15 +1242,13 @@ void allchanged(bool load)
setupmaterials();
updatevabbs(true);
lightents();
- if(load)
- {
+ if(load) {
seedparticles();
drawtextures();
}
}
-void recalc()
-{
+void recalc() {
allchanged(true);
}