From 0a1172b75f571685c264a8b9d8ee224bbf11381f Mon Sep 17 00:00:00 2001 From: xolatile Date: Wed, 6 Aug 2025 22:54:55 +0200 Subject: Please do not hate me, it makes sense... --- src/engine/lightmap.cpp | 849 +++++++++++++++--------------------------------- 1 file changed, 264 insertions(+), 585 deletions(-) (limited to 'src/engine/lightmap.cpp') diff --git a/src/engine/lightmap.cpp b/src/engine/lightmap.cpp index a317dd5..1481de9 100644 --- a/src/engine/lightmap.cpp +++ b/src/engine/lightmap.cpp @@ -6,8 +6,7 @@ struct lightmapinfo; struct lightmaptask; -struct lightmapworker -{ +struct lightmapworker { uchar *buf; int bufstart, bufused; lightmapinfo *firstlightmap, *lastlightmap, *curlightmaps; @@ -25,19 +24,15 @@ struct lightmapworker bool needspace, doneworking; SDL_cond *spacecond; SDL_Thread *thread; - lightmapworker(); ~lightmapworker(); - void reset(); bool setupthread(); void cleanupthread(); - static int work(void *data); }; -struct lightmapinfo -{ +struct lightmapinfo { lightmapinfo *next; cube *c; uchar *colorbuf; @@ -46,8 +41,7 @@ struct lightmapinfo int type, w, h, bpp, bufsize, surface, layers; }; -struct lightmaptask -{ +struct lightmaptask { ivec o; int size, usefaces, progress; cube *c; @@ -56,8 +50,7 @@ struct lightmaptask lightmapworker *worker; }; -struct lightmapext -{ +struct lightmapext { cube *c; cubeext *ext; }; @@ -78,14 +71,12 @@ VARR(lighterror, 1, 8, 16); VARR(bumperror, 1, 3, 16); VARR(lightlod, 0, 0, 10); bvec ambientcolor(36, 24, 12); -HVARFR(ambient, 1, 0x191919, 0xFFFFFF, -{ +HVARFR(ambient, 1, 0x191919, 0xFFFFFF, { if(ambient <= 255) ambient |= (ambient<<8) | (ambient<<16); ambientcolor = bvec((ambient>>16)&0xFF, (ambient>>8)&0xFF, ambient&0xFF); }); -static const surfaceinfo brightsurfaces[6] = -{ +static const surfaceinfo brightsurfaces[6] = { brightsurface, brightsurface, brightsurface, @@ -94,28 +85,23 @@ static const surfaceinfo brightsurfaces[6] = brightsurface }; -void brightencube(cube &c) -{ +void brightencube(cube &c) { if(!c.ext) newcubeext(c, 0, false); memcpy(c.ext->surfaces, brightsurfaces, sizeof(brightsurfaces)); } -void setsurfaces(cube &c, const surfaceinfo *surfs, const vertinfo *verts, int numverts) -{ +void setsurfaces(cube &c, const surfaceinfo *surfs, const vertinfo *verts, int numverts) { if(!c.ext || c.ext->maxverts < numverts) newcubeext(c, numverts, false); memcpy(c.ext->surfaces, surfs, sizeof(c.ext->surfaces)); memcpy(c.ext->verts(), verts, numverts*sizeof(vertinfo)); } -void setsurface(cube &c, int orient, const surfaceinfo &src, const vertinfo *srcverts, int numsrcverts) -{ +void setsurface(cube &c, int orient, const surfaceinfo &src, const vertinfo *srcverts, int numsrcverts) { int dstoffset = 0; if(!c.ext) newcubeext(c, numsrcverts, true); - else - { + else { int numbefore = 0, beforeoffset = 0; - loopi(orient) - { + loopi(orient) { surfaceinfo &surf = c.ext->surfaces[i]; int numverts = surf.totalverts(); if(!numverts) continue; @@ -123,8 +109,7 @@ void setsurface(cube &c, int orient, const surfaceinfo &src, const vertinfo *src beforeoffset = surf.verts + numverts; } int numafter = 0, afteroffset = c.ext->maxverts; - for(int i = 5; i > orient; i--) - { + for(int i = 5; i > orient; i--) { surfaceinfo &surf = c.ext->surfaces[i]; int numverts = surf.totalverts(); if(!numverts) continue; @@ -132,22 +117,18 @@ void setsurface(cube &c, int orient, const surfaceinfo &src, const vertinfo *src afteroffset = surf.verts; } if(afteroffset - beforeoffset >= numsrcverts) dstoffset = beforeoffset; - else - { + else { cubeext *ext = c.ext; - if(numbefore + numsrcverts + numafter > c.ext->maxverts) - { + if(numbefore + numsrcverts + numafter > c.ext->maxverts) { ext = growcubeext(c.ext, numbefore + numsrcverts + numafter); memcpy(ext->surfaces, c.ext->surfaces, sizeof(ext->surfaces)); } int offset = 0; - if(numbefore == beforeoffset) - { + if(numbefore == beforeoffset) { if(numbefore && c.ext != ext) memcpy(ext->verts(), c.ext->verts(), numbefore*sizeof(vertinfo)); offset = numbefore; } - else loopi(orient) - { + else loopi(orient) { surfaceinfo &surf = ext->surfaces[i]; int numverts = surf.totalverts(); if(!numverts) continue; @@ -157,11 +138,9 @@ void setsurface(cube &c, int orient, const surfaceinfo &src, const vertinfo *src } dstoffset = offset; offset += numsrcverts; - if(numafter && offset > afteroffset) - { + if(numafter && offset > afteroffset) { offset += numafter; - for(int i = 5; i > orient; i--) - { + for(int i = 5; i > orient; i--) { surfaceinfo &surf = ext->surfaces[i]; int numverts = surf.totalverts(); if(!numverts) continue; @@ -192,30 +171,23 @@ static int progresstexticks = 0, progresslightmap = -1; bool calclight_canceled = false; volatile bool check_calclight_progress = false; -void check_calclight_canceled() -{ - if(interceptkey(SDLK_ESCAPE)) - { +void check_calclight_canceled() { + if(interceptkey(SDLK_ESCAPE)) { calclight_canceled = true; loopv(lightmapworkers) lightmapworkers[i]->doneworking = true; } if(!calclight_canceled) check_calclight_progress = false; } -void show_calclight_progress() -{ +void show_calclight_progress() { float bar1 = float(progress) / float(allocnodes); defformatstring(text1, "%d%% using %d textures", int(bar1 * 100), lightmaps.length()); - - if(LM_PACKW <= hwtexsize && !progresstex) - { + if(LM_PACKW <= hwtexsize && !progresstex) { glGenTextures(1, &progresstex); createtexture(progresstex, LM_PACKW, LM_PACKH, NULL, 3, 1, GL_RGB); } - // only update once a sec (4 * 250 ms ticks) to not kill performance - if(progresstex && !calclight_canceled && progresslightmap >= 0 && !(progresstexticks++ % 4)) - { + if(progresstex && !calclight_canceled && progresslightmap >= 0 && !(progresstexticks++ % 4)) { if(tasklock) SDL_LockMutex(tasklock); LightMap &lm = lightmaps[progresslightmap]; uchar *data = lm.data; @@ -231,56 +203,45 @@ void show_calclight_progress() #define CHECK_PROGRESS_LOCKED(exit, before, after) CHECK_CALCLIGHT_PROGRESS_LOCKED(exit, show_calclight_progress, before, after) #define CHECK_PROGRESS(exit) CHECK_PROGRESS_LOCKED(exit, , ) -bool PackNode::insert(ushort &tx, ushort &ty, ushort tw, ushort th) -{ +bool PackNode::insert(ushort &tx, ushort &ty, ushort tw, ushort th) { if((available < tw && available < th) || w < tw || h < th) return false; - if(child1) - { + if(child1) { bool inserted = child1->insert(tx, ty, tw, th) || child2->insert(tx, ty, tw, th); available = max(child1->available, child2->available); if(!available) clear(); return inserted; } - if(w == tw && h == th) - { + if(w == tw && h == th) { available = 0; tx = x; ty = y; return true; } - - if(w - tw > h - th) - { + if(w - tw > h - th) { child1 = new PackNode(x, y, tw, h); child2 = new PackNode(x + tw, y, w - tw, h); } - else - { + else { child1 = new PackNode(x, y, w, th); child2 = new PackNode(x, y + th, w, h - th); } - bool inserted = child1->insert(tx, ty, tw, th); available = max(child1->available, child2->available); return inserted; } -bool LightMap::insert(ushort &tx, ushort &ty, uchar *src, ushort tw, ushort th) -{ +bool LightMap::insert(ushort &tx, ushort &ty, uchar *src, ushort tw, ushort th) { if((type&LM_TYPE) != LM_BUMPMAP1 && !packroot.insert(tx, ty, tw, th)) return false; - copy(tx, ty, src, tw, th); return true; } -void LightMap::copy(ushort tx, ushort ty, uchar *src, ushort tw, ushort th) -{ +void LightMap::copy(ushort tx, ushort ty, uchar *src, ushort tw, ushort th) { uchar *dst = data + bpp * tx + ty * bpp * LM_PACKW; - loopi(th) - { + loopi(th) { memcpy(dst, src, bpp * tw); dst += bpp * LM_PACKW; src += bpp * tw; @@ -289,20 +250,16 @@ void LightMap::copy(ushort tx, ushort ty, uchar *src, ushort tw, ushort th) lumels += tw * th; } -static void insertunlit(int i) -{ +static void insertunlit(int i) { LightMap &l = lightmaps[i]; - if((l.type&LM_TYPE) == LM_BUMPMAP1) - { + if((l.type&LM_TYPE) == LM_BUMPMAP1) { l.unlitx = l.unlity = -1; return; } ushort x, y; uchar unlit[4] = { ambientcolor[0], ambientcolor[1], ambientcolor[2], 255 }; - if(l.insert(x, y, unlit, 1, 1)) - { - if((l.type&LM_TYPE) == LM_BUMPMAP0) - { + if(l.insert(x, y, unlit, 1, 1)) { + if((l.type&LM_TYPE) == LM_BUMPMAP0) { bvec front(128, 128, 255); ASSERT(lightmaps[i+1].insert(x, y, front.v, 1, 1)); } @@ -311,26 +268,20 @@ static void insertunlit(int i) } } -struct layoutinfo -{ +struct layoutinfo { ushort x, y, lmid; uchar w, h; }; -static void insertlightmap(lightmapinfo &li, layoutinfo &si) -{ - loopv(lightmaps) - { - if(lightmaps[i].type == li.type && lightmaps[i].insert(si.x, si.y, li.colorbuf, si.w, si.h)) - { +static void insertlightmap(lightmapinfo &li, layoutinfo &si) { + loopv(lightmaps) { + if(lightmaps[i].type == li.type && lightmaps[i].insert(si.x, si.y, li.colorbuf, si.w, si.h)) { si.lmid = i + LMID_RESERVED; if((li.type&LM_TYPE) == LM_BUMPMAP0) ASSERT(lightmaps[i+1].insert(si.x, si.y, (uchar *)li.raybuf, si.w, si.h)); return; } } - progresslightmap = lightmaps.length(); - si.lmid = lightmaps.length() + LMID_RESERVED; LightMap &l = lightmaps.add(); l.type = li.type; @@ -338,8 +289,7 @@ static void insertlightmap(lightmapinfo &li, layoutinfo &si) l.data = new uchar[li.bpp*LM_PACKW*LM_PACKH]; memset(l.data, 0, li.bpp*LM_PACKW*LM_PACKH); ASSERT(l.insert(si.x, si.y, li.colorbuf, si.w, si.h)); - if((li.type&LM_TYPE) == LM_BUMPMAP0) - { + if((li.type&LM_TYPE) == LM_BUMPMAP0) { LightMap &r = lightmaps.add(); r.type = LM_BUMPMAP1 | (li.type&~LM_TYPE); r.bpp = 3; @@ -349,8 +299,7 @@ static void insertlightmap(lightmapinfo &li, layoutinfo &si) } } -static inline bool htcmp(const lightmapinfo &k, const layoutinfo &v) -{ +static inline bool htcmp(const lightmapinfo &k, const layoutinfo &v) { int kw = k.w, kh = k.h; if(kw != v.w || kh != v.h) return false; LightMap &vlm = lightmaps[v.lmid - LMID_RESERVED]; @@ -358,16 +307,14 @@ static inline bool htcmp(const lightmapinfo &k, const layoutinfo &v) if(ktype != vlm.type) return false; int kbpp = k.bpp; const uchar *kcolor = k.colorbuf, *vcolor = vlm.data + kbpp*(v.x + v.y*LM_PACKW); - loopi(kh) - { + loopi(kh) { if(memcmp(kcolor, vcolor, kbpp*kw)) return false; kcolor += kbpp*kw; vcolor += kbpp*LM_PACKW; } if((ktype&LM_TYPE) != LM_BUMPMAP0) return true; const bvec *kdir = k.raybuf, *vdir = (const bvec *)lightmaps[v.lmid+1 - LMID_RESERVED].data + (v.x + v.y*LM_PACKW); - loopi(kh) - { + loopi(kh) { if(memcmp(kdir, vdir, kw*sizeof(bvec))) return false; kdir += kw; vdir += LM_PACKW; @@ -375,13 +322,11 @@ static inline bool htcmp(const lightmapinfo &k, const layoutinfo &v) return true; } -static inline uint hthash(const lightmapinfo &k) -{ +static inline uint hthash(const lightmapinfo &k) { int kw = k.w, kh = k.h, kbpp = k.bpp; uint hash = kw + (kh<<8); const uchar *color = k.colorbuf; - loopi(kw*kh) - { + loopi(kw*kh) { hash ^= color[0] + (color[1] << 4) + (color[2] << 8); color += kbpp; } @@ -392,20 +337,16 @@ static hashset compressed; VAR(lightcompress, 0, 3, 6); -static bool packlightmap(lightmapinfo &l, layoutinfo &surface) -{ +static bool packlightmap(lightmapinfo &l, layoutinfo &surface) { surface.w = l.w; surface.h = l.h; - if((int)l.w <= lightcompress && (int)l.h <= lightcompress) - { + if((int)l.w <= lightcompress && (int)l.h <= lightcompress) { layoutinfo *val = compressed.access(l); - if(!val) - { + if(!val) { insertlightmap(l, surface); compressed[l] = surface; } - else - { + else { surface.x = val->x; surface.y = val->y; surface.lmid = val->lmid; @@ -416,13 +357,11 @@ static bool packlightmap(lightmapinfo &l, layoutinfo &surface) return true; } -static uint generatelumel(lightmapworker *w, const float tolerance, uint lightmask, const vector &lights, const vec &target, const vec &normal, vec &sample, int x, int y) -{ +static uint generatelumel(lightmapworker *w, const float tolerance, uint lightmask, const vector &lights, const vec &target, const vec &normal, vec &sample, int x, int y) { vec avgray(0, 0, 0); float r = 0, g = 0, b = 0; uint lightused = 0; - loopv(lights) - { + loopv(lights) { if(lightmask&(1<type==ET_SPOTLIGHT) - { + if(light.attached && light.attached->type==ET_SPOTLIGHT) { vec spot = vec(light.attached->o).sub(light.o).normalize(); float maxatten = sincos360[clamp(int(light.attached->attr1), 1, 89)].x, spotatten = (ray.dot(spot) - maxatten) / (1 - maxatten); if(spotatten <= 0) continue; attenuation *= spotatten; } - if(lmshadows && mag) - { + if(lmshadows && mag) { float dist = shadowray(w->shadowraycache, light.o, ray, mag - tolerance, RAY_SHADOW | (lmshadows > 1 ? RAY_ALPHAPOLY : 0)); if(dist < mag - tolerance) continue; } lightused |= 1<type&LM_TYPE) - { + switch(w->type&LM_TYPE) { case LM_BUMPMAP0: intensity = attenuation; avgray.add(ray.mul(-attenuation)); @@ -466,8 +401,7 @@ static uint generatelumel(lightmapworker *w, const float tolerance, uint lightma g += intensity * float(light.attr3); b += intensity * float(light.attr4); } - switch(w->type&LM_TYPE) - { + switch(w->type&LM_TYPE) { case LM_BUMPMAP0: if(avgray.iszero()) break; // transform to tangent space @@ -486,8 +420,7 @@ static uint generatelumel(lightmapworker *w, const float tolerance, uint lightma return lightused; } -static bool lumelsample(const vec &sample, int aasample, int stride) -{ +static bool lumelsample(const vec &sample, int aasample, int stride) { if(sample.x >= int(ambientcolor[0])+1 || sample.y >= int(ambientcolor[1])+1 || sample.z >= int(ambientcolor[2])+1) return true; #define NCHECK(n) \ if((n).x >= int(ambientcolor[0])+1 || (n).y >= int(ambientcolor[1])+1 || (n).z >= int(ambientcolor[2])+1) \ @@ -501,11 +434,9 @@ static bool lumelsample(const vec &sample, int aasample, int stride) return false; } -static inline void generatealpha(lightmapworker *w, float tolerance, const vec &pos, uchar &alpha) -{ +static inline void generatealpha(lightmapworker *w, float tolerance, const vec &pos, uchar &alpha) { alpha = 0; - if(w->slot->layermask) - { + if(w->slot->layermask) { static const int sdim[] = { 1, 0, 0 }, tdim[] = { 2, 2, 1 }; int dim = dimension(w->orient); float k = 8.0f/w->vslot->scale, @@ -520,8 +451,7 @@ static inline void generatealpha(lightmapworker *w, float tolerance, const vec & if(mx < 0) mx += mask.w; if(my < 0) my += mask.h; uchar maskval = mask.data[mask.bpp*(mx + 1) - 1 + mask.pitch*my]; - switch(w->slot->layermaskmode) - { + switch(w->slot->layermaskmode) { case 2: alpha = min(alpha, maskval); break; case 3: alpha = max(alpha, maskval); break; case 4: alpha = min(alpha, uchar(0xFF - maskval)); break; @@ -534,8 +464,7 @@ static inline void generatealpha(lightmapworker *w, float tolerance, const vec & VAR(edgetolerance, 1, 4, 64); VAR(adaptivesample, 0, 2, 2); -enum -{ +enum { NO_SURFACE = 0, SURFACE_AMBIENT_BOTTOM, SURFACE_AMBIENT_TOP, @@ -547,33 +476,29 @@ enum #define SURFACE_AMBIENT SURFACE_AMBIENT_BOTTOM #define SURFACE_LIGHTMAP SURFACE_LIGHTMAP_BOTTOM -static bool generatelightmap(lightmapworker *w, float lpu, const lerpvert *lv, int numv, vec origin1, const vec &xstep1, const vec &ystep1, vec origin2, const vec &xstep2, const vec &ystep2, float side0, float sidestep) -{ - static const float aacoords[8][2] = - { - {0.0f, 0.0f}, - {-0.5f, -0.5f}, - {0.0f, -0.5f}, - {-0.5f, 0.0f}, - - {0.3f, -0.6f}, - {0.6f, 0.3f}, - {-0.3f, 0.6f}, - {-0.6f, -0.3f}, +static bool generatelightmap(lightmapworker *w, float lpu, const lerpvert *lv, int numv, vec origin1, const vec &xstep1, const vec &ystep1, vec origin2, const vec &xstep2, const vec &ystep2, float side0, float sidestep) { + static const float aacoords[8][2] = { + { + 0.0f, 0.0f}, { + -0.5f, -0.5f}, { + 0.0f, -0.5f}, { + -0.5f, 0.0f}, + { + 0.3f, -0.6f}, { + 0.6f, 0.3f}, { + -0.3f, 0.6f}, { + -0.6f, -0.3f}, }; float tolerance = 0.5 / lpu; uint lightmask = 0, lightused = 0; vec offsets1[8], offsets2[8]; - loopi(8) - { + loopi(8) { offsets1[i] = vec(xstep1).mul(aacoords[i][0]).add(vec(ystep1).mul(aacoords[i][1])); offsets2[i] = vec(xstep2).mul(aacoords[i][0]).add(vec(ystep2).mul(aacoords[i][1])); } if((w->type&LM_TYPE) == LM_BUMPMAP0) memclear(w->raydata, (LM_MAXW + 4)*(LM_MAXH + 4)); - origin1.sub(vec(ystep1).add(xstep1).mul(0)); origin2.sub(vec(ystep2).add(xstep2).mul(0)); - int aasample = min(1 << lmaa, 4); int stride = aasample*(w->w+1); vec *sample = w->colordata; @@ -581,13 +506,10 @@ static bool generatelightmap(lightmapworker *w, float lpu, const lerpvert *lv, i lerpbounds start, end; initlerpbounds(-0, -0, lv, numv, start, end); float sidex = side0 + 0*sidestep; - for(int y = 0; y < w->h; ++y, sidex += sidestep) - { + for(int y = 0; y < w->h; ++y, sidex += sidestep) { vec normal, nstep; lerpnormal(-0, y - 0, lv, numv, start, end, normal, nstep); - - for(int x = 0; x < w->w; ++x, normal.add(nstep), amb += w->bpp) - { + for(int x = 0; x < w->w; ++x, normal.add(nstep), amb += w->bpp) { #define EDGE_TOLERANCE(x, y) \ (x < 0 \ || x+1 > w->w - 0 \ @@ -605,28 +527,22 @@ static bool generatelightmap(lightmapworker *w, float lpu, const lerpvert *lv, i sample = w->colordata; initlerpbounds(-0, -0, lv, numv, start, end); sidex = side0 + 0*sidestep; - for(int y = 0; y < w->h; ++y, sidex += sidestep) - { + for(int y = 0; y < w->h; ++y, sidex += sidestep) { vec normal, nstep; lerpnormal(-0, y - 0, lv, numv, start, end, normal, nstep); - - for(int x = 0; x < w->w; ++x, normal.add(nstep)) - { + for(int x = 0; x < w->w; ++x, normal.add(nstep)) { vec ¢er = *sample++; if(adaptivesample && x > 0 && x+1 < w->w && y > 0 && y+1 < w->h && !lumelsample(center, aasample, stride)) loopi(aasample-1) *sample++ = center; - else - { + else { #define AA_EDGE_TOLERANCE(x, y, i) EDGE_TOLERANCE(x + aacoords[i][0], y + aacoords[i][1]) vec u = x < sidex ? vec(xstep1).mul(x).add(vec(ystep1).mul(y)).add(origin1) : vec(xstep2).mul(x).add(vec(ystep2).mul(y)).add(origin2); const vec *offsets = x < sidex ? offsets1 : offsets2; vec n = vec(normal).normalize(); loopi(aasample-1) generatelumel(w, AA_EDGE_TOLERANCE(x, y, i+1) * tolerance, lightmask, w->lights, vec(u).add(offsets[i+1]), n, *sample++, x, y); - if(lmaa == 3) - { - loopi(4) - { + if(lmaa == 3) { + loopi(4) { vec s; generatelumel(w, AA_EDGE_TOLERANCE(x, y, i+4) * tolerance, lightmask, w->lights, vec(u).add(offsets[i+4]), n, s, x, y); center.add(s); @@ -635,8 +551,7 @@ static bool generatelightmap(lightmapworker *w, float lpu, const lerpvert *lv, i } } } - if(aasample > 1) - { + if(aasample > 1) { vec u = w->w < sidex ? vec(xstep1).mul(w->w).add(vec(ystep1).mul(y)).add(origin1) : vec(xstep2).mul(w->w).add(vec(ystep2).mul(y)).add(origin2); const vec *offsets = w->w < sidex ? offsets1 : offsets2; vec n = vec(normal).normalize(); @@ -646,14 +561,10 @@ static bool generatelightmap(lightmapworker *w, float lpu, const lerpvert *lv, i } sample += aasample; } - - if(aasample > 1) - { + if(aasample > 1) { vec normal, nstep; lerpnormal(-0, w->h - 0, lv, numv, start, end, normal, nstep); - - for(int x = 0; x <= w->w; ++x, normal.add(nstep)) - { + for(int x = 0; x <= w->w; ++x, normal.add(nstep)) { vec u = x < sidex ? vec(xstep1).mul(x).add(vec(ystep1).mul(w->h)).add(origin1) : vec(xstep2).mul(x).add(vec(ystep2).mul(w->h)).add(origin2); const vec *offsets = x < sidex ? offsets1 : offsets2; vec n = vec(normal).normalize(); @@ -666,8 +577,7 @@ static bool generatelightmap(lightmapworker *w, float lpu, const lerpvert *lv, i return true; } -static int finishlightmap(lightmapworker *w) -{ +static int finishlightmap(lightmapworker *w) { vec *sample = w->colordata; int aasample = min(1 << lmaa, 4), stride = aasample*(w->w+1); float weight = 1.0f / (1.0f + 4.0f*lmaa), @@ -677,26 +587,21 @@ static int finishlightmap(lightmapworker *w) uchar mincolor[4] = { 255, 255, 255, 255 }, maxcolor[4] = { 0, 0, 0, 0 }; bvec *dstray = 0 && (w->w > 1 || w->h > 1) ? (bvec *)w->raydata : w->raybuf; bvec minray(255, 255, 255), maxray(0, 0, 0); - loop(y, w->h) - { - loop(x, w->w) - { + loop(y, w->h) { + loop(x, w->w) { vec l(0, 0, 0); const vec ¢er = *sample++; loopi(aasample-1) l.add(*sample++); - if(aasample > 1) - { + if(aasample > 1) { l.add(sample[1]); if(aasample > 2) l.add(sample[3]); } vec *next = sample + stride - aasample; - if(aasample > 1) - { + if(aasample > 1) { l.add(next[1]); if(aasample > 2) l.add(next[2]); l.add(next[aasample+1]); } - int r = int(center.x*cweight + l.x*weight), g = int(center.y*cweight + l.y*weight), b = int(center.z*cweight + l.z*weight), @@ -704,30 +609,25 @@ static int finishlightmap(lightmapworker *w) dstcolor[0] = max(ar, r); dstcolor[1] = max(ag, g); dstcolor[2] = max(ab, b); - loopk(3) - { + loopk(3) { mincolor[k] = min(mincolor[k], dstcolor[k]); maxcolor[k] = max(maxcolor[k], dstcolor[k]); } - if(w->type&LM_ALPHA) - { + if(w->type&LM_ALPHA) { dstcolor[3] = 127;///TODO mincolor[3] = min(mincolor[3], dstcolor[3]); maxcolor[3] = max(maxcolor[3], dstcolor[3]); } - if((w->type&LM_TYPE) == LM_BUMPMAP0) - { + if((w->type&LM_TYPE) == LM_BUMPMAP0) { if(ray->iszero()) dstray[0] = bvec(128, 128, 255); - else - { + else { ray->normalize(); int l = max(r, max(g, b)), a = max(ar, max(ag, ab)); ray->mul(max(l-a, 0)); ray->z += a; dstray[0] = bvec(ray->normalize()); } - loopk(3) - { + loopk(3) { minray[k] = min(minray[k], dstray[0][k]); maxray[k] = max(maxray[k], dstray[0][k]); } @@ -741,8 +641,7 @@ static int finishlightmap(lightmapworker *w) if(int(maxcolor[0]) - int(mincolor[0]) <= lighterror && int(maxcolor[1]) - int(mincolor[1]) <= lighterror && int(maxcolor[2]) - int(mincolor[2]) <= lighterror && - mincolor[3] >= maxcolor[3]) - { + mincolor[3] >= maxcolor[3]) { uchar color[3]; loopk(3) color[k] = (int(maxcolor[k]) + int(mincolor[k])) / 2; if(color[0] <= int(ambientcolor[0]) + lighterror && @@ -754,12 +653,10 @@ static int finishlightmap(lightmapworker *w) (int(maxray.x) - int(minray.x) <= bumperror && int(maxray.y) - int(minray.z) <= bumperror && int(maxray.z) - int(minray.z) <= bumperror)) - - { + { memcpy(w->colorbuf, color, 3); if(w->type&LM_ALPHA) w->colorbuf[3] = mincolor[3]; - if((w->type&LM_TYPE) == LM_BUMPMAP0) - { + if((w->type&LM_TYPE) == LM_BUMPMAP0) { loopk(3) w->raybuf[0][k] = uchar((int(maxray[k])+int(minray[k]))/2); } w->lastlightmap->w = w->w = 1; @@ -771,17 +668,14 @@ static int finishlightmap(lightmapworker *w) else return SURFACE_LIGHTMAP_BLEND; } -static int previewlightmapalpha(lightmapworker *w, float lpu, const vec &origin1, const vec &xstep1, const vec &ystep1, const vec &origin2, const vec &xstep2, const vec &ystep2, float side0, float sidestep) -{ +static int previewlightmapalpha(lightmapworker *w, float lpu, const vec &origin1, const vec &xstep1, const vec &ystep1, const vec &origin2, const vec &xstep2, const vec &ystep2, float side0, float sidestep) { extern int fullbrightlevel; float tolerance = 0.5 / lpu; uchar *dst = w->colorbuf; uchar minalpha = 255, maxalpha = 0; float sidex = side0; - for(int y = 0; y < w->h; ++y, sidex += sidestep) - { - for(int x = 0; x < w->w; ++x, dst += 4) - { + for(int y = 0; y < w->h; ++y, sidex += sidestep) { + for(int x = 0; x < w->w; ++x, dst += 4) { vec u = x < sidex ? vec(xstep1).mul(x).add(vec(ystep1).mul(y)).add(origin1) : vec(xstep2).mul(x).add(vec(ystep2).mul(y)).add(origin2); @@ -798,25 +692,18 @@ static int previewlightmapalpha(lightmapworker *w, float lpu, const vec &origin1 return SURFACE_LIGHTMAP_BLEND; } -static void clearsurfaces(cube *c) -{ - loopi(8) - { - if(c[i].ext) - { - loopj(6) - { +static void clearsurfaces(cube *c) { + loopi(8) { + if(c[i].ext) { + loopj(6) { surfaceinfo &surf = c[i].ext->surfaces[j]; if(!surf.used()) continue; surf.clear(); int numverts = surf.numverts&MAXFACEVERTS; - if(numverts) - { + if(numverts) { if(!(c[i].merged&(1<verts() + surf.verts; - loopk(numverts) - { + loopk(numverts) { vertinfo &v = verts[k]; v.u = 0; v.v = 0; @@ -831,8 +718,7 @@ static void clearsurfaces(cube *c) #define LIGHTCACHESIZE 1024 -static struct lightcacheentry -{ +static struct lightcacheentry { int x, y; vector lights; } lightcache[LIGHTCACHESIZE]; @@ -841,17 +727,13 @@ static struct lightcacheentry VARF(lightcachesize, 4, 6, 12, clearlightcache()); -void clearlightcache(int id) -{ - if(id >= 0) - { +void clearlightcache(int id) { + if(id >= 0) { const extentity &light = *entities::getents()[id]; int radius = light.attr1; - if(radius) - { + if(radius) { for(int x = int(max(light.o.x-radius, 0.0f))>>lightcachesize, ex = int(min(light.o.x+radius, worldsize-1.0f))>>lightcachesize; x <= ex; x++) - for(int y = int(max(light.o.y-radius, 0.0f))>>lightcachesize, ey = int(min(light.o.y+radius, worldsize-1.0f))>>lightcachesize; y <= ey; y++) - { + for(int y = int(max(light.o.y-radius, 0.0f))>>lightcachesize, ey = int(min(light.o.y+radius, worldsize-1.0f))>>lightcachesize; y <= ey; y++) { lightcacheentry &lce = lightcache[LIGHTCACHEHASH(x, y)]; if(lce.x != x || lce.y != y) continue; lce.x = -1; @@ -860,34 +742,26 @@ void clearlightcache(int id) return; } } - - for(lightcacheentry *lce = lightcache; lce < &lightcache[LIGHTCACHESIZE]; lce++) - { + for(lightcacheentry *lce = lightcache; lce < &lightcache[LIGHTCACHESIZE]; lce++) { lce->x = -1; lce->lights.setsize(0); } } -const vector &checklightcache(int x, int y) -{ +const vector &checklightcache(int x, int y) { x >>= lightcachesize; y >>= lightcachesize; lightcacheentry &lce = lightcache[LIGHTCACHEHASH(x, y)]; if(lce.x == x && lce.y == y) return lce.lights; - lce.lights.setsize(0); int csize = 1< &ents = entities::getents(); - loopv(ents) - { + loopv(ents) { const extentity &light = *ents[i]; - switch(light.type) - { - case ET_LIGHT: - { + switch(light.type) { + case ET_LIGHT: { int radius = light.attr1; - if(radius > 0) - { + if(radius > 0) { if(light.o.x + radius < cx || light.o.x - radius > cx + csize || light.o.y + radius < cy || light.o.y - radius > cy + csize) continue; @@ -898,60 +772,48 @@ const vector &checklightcache(int x, int y) } lce.lights.add(i); } - lce.x = x; lce.y = y; return lce.lights; } -static inline void addlight(lightmapworker *w, const extentity &light, int cx, int cy, int cz, int size, const vec *v, const vec *n, int numv) -{ +static inline void addlight(lightmapworker *w, const extentity &light, int cx, int cy, int cz, int size, const vec *v, const vec *n, int numv) { int radius = light.attr1; - if(radius > 0) - { + if(radius > 0) { if(light.o.x + radius < cx || light.o.x - radius > cx + size || light.o.y + radius < cy || light.o.y - radius > cy + size || light.o.z + radius < cz || light.o.z - radius > cz + size) return; } - - loopi(4) - { + loopi(4) { vec p(light.o); p.sub(v[i]); float dist = p.dot(n[i]); - if(dist >= 0 && (!radius || dist < radius)) - { + if(dist >= 0 && (!radius || dist < radius)) { w->lights.add(&light); break; } } } -static bool findlights(lightmapworker *w, int cx, int cy, int cz, int size, const vec *v, const vec *n, int numv, const Slot &slot, const VSlot &vslot) -{ +static bool findlights(lightmapworker *w, int cx, int cy, int cz, int size, const vec *v, const vec *n, int numv, const Slot &slot, const VSlot &vslot) { w->lights.setsize(0); const vector &ents = entities::getents(); static volatile bool usinglightcache = false; - if(size <= 1< &lights = checklightcache(cx, cy); - loopv(lights) - { + loopv(lights) { const extentity &light = *ents[lights[i]]; - switch(light.type) - { + switch(light.type) { case ET_LIGHT: addlight(w, light, cx, cy, cz, size, v, n, numv); break; } } if(lightlock) { usinglightcache = false; SDL_UnlockMutex(lightlock); } } - else loopv(ents) - { + else loopv(ents) { const extentity &light = *ents[i]; - switch(light.type) - { + switch(light.type) { case ET_LIGHT: addlight(w, light, cx, cy, cz, size, v, n, numv); break; } } @@ -959,15 +821,12 @@ static bool findlights(lightmapworker *w, int cx, int cy, int cz, int size, cons return w->lights.length(); } -static int packlightmaps(lightmapworker *w = NULL) -{ +static int packlightmaps(lightmapworker *w = NULL) { int numpacked = 0; - for(; packidx < lightmaptasks[0].length(); packidx++, numpacked++) - { + for(; packidx < lightmaptasks[0].length(); packidx++, numpacked++) { lightmaptask &t = lightmaptasks[0][packidx]; if(!t.lightmaps) break; - if(t.ext && t.c->ext != t.ext) - { + if(t.ext && t.c->ext != t.ext) { lightmapext &e = lightmapexts.add(); e.c = t.c; e.ext = t.ext; @@ -976,8 +835,7 @@ static int packlightmaps(lightmapworker *w = NULL) lightmapinfo *l = t.lightmaps; if(l == (lightmapinfo *)-1) continue; int space = 0; - for(; l && l->c == t.c; l = l->next) - { + for(; l && l->c == t.c; l = l->next) { l->packed = true; space += l->bufsize; if(l->surface < 0 || !t.ext) continue; @@ -986,31 +844,26 @@ static int packlightmaps(lightmapworker *w = NULL) packlightmap(*l, layout); int numverts = surf.numverts&MAXFACEVERTS; vertinfo *verts = t.ext->verts() + surf.verts; - if(l->layers&LAYER_DUP) - { + if(l->layers&LAYER_DUP) { if(l->type&LM_ALPHA) surf.lmid[0] = layout.lmid; else { surf.lmid[1] = layout.lmid; verts += numverts; } } - else - { + else { if(l->layers&LAYER_TOP) surf.lmid[0] = layout.lmid; if(l->layers&LAYER_BOTTOM) surf.lmid[1] = layout.lmid; } ushort offsetx = layout.x*((USHRT_MAX+1)/LM_PACKW), offsety = layout.y*((USHRT_MAX+1)/LM_PACKH); - loopk(numverts) - { + loopk(numverts) { vertinfo &v = verts[k]; v.u += offsetx; v.v += offsety; } } - if(t.worker == w) - { + if(t.worker == w) { w->bufused -= space; w->bufstart = (w->bufstart + space)%LIGHTMAPBUFSIZE; w->firstlightmap = l; - if(!l) - { + if(!l) { w->lastlightmap = NULL; w->bufstart = w->bufused = 0; } @@ -1020,8 +873,7 @@ static int packlightmaps(lightmapworker *w = NULL) return numpacked; } -static lightmapinfo *alloclightmap(lightmapworker *w) -{ +static lightmapinfo *alloclightmap(lightmapworker *w) { int needspace1 = sizeof(lightmapinfo) + w->w*w->h*w->bpp, needspace2 = (w->type&LM_TYPE) == LM_BUMPMAP0 ? w->w*w->h*3 : 0, needspace = needspace1 + needspace2, @@ -1029,20 +881,16 @@ static lightmapinfo *alloclightmap(lightmapworker *w) availspace = LIGHTMAPBUFSIZE - w->bufused, availspace1 = min(availspace, LIGHTMAPBUFSIZE - bufend), availspace2 = min(availspace, w->bufstart); - if(availspace < needspace || (max(availspace1, availspace2) < needspace && (availspace1 < needspace1 || availspace2 < needspace2))) - { + if(availspace < needspace || (max(availspace1, availspace2) < needspace && (availspace1 < needspace1 || availspace2 < needspace2))) { if(tasklock) SDL_LockMutex(tasklock); - while(!w->doneworking) - { + while(!w->doneworking) { lightmapinfo *l = w->firstlightmap; - for(; l && l->packed; l = l->next) - { + for(; l && l->packed; l = l->next) { w->bufused -= l->bufsize; w->bufstart = (w->bufstart + l->bufsize)%LIGHTMAPBUFSIZE; } w->firstlightmap = l; - if(!l) - { + if(!l) { w->lastlightmap = NULL; w->bufstart = w->bufused = 0; } @@ -1061,20 +909,17 @@ static lightmapinfo *alloclightmap(lightmapworker *w) } int usedspace = needspace; lightmapinfo *l = NULL; - if(availspace1 >= needspace1) - { + if(availspace1 >= needspace1) { l = (lightmapinfo *)&w->buf[bufend]; w->colorbuf = (uchar *)(l + 1); if((w->type&LM_TYPE) != LM_BUMPMAP0) w->raybuf = NULL; else if(availspace1 >= needspace) w->raybuf = (bvec *)&w->buf[bufend + needspace1]; - else - { + else { w->raybuf = (bvec *)w->buf; usedspace += availspace1 - needspace1; } } - else if(availspace2 >= needspace) - { + else if(availspace2 >= needspace) { usedspace += availspace1; l = (lightmapinfo *)w->buf; w->colorbuf = (uchar *)(l + 1); @@ -1101,17 +946,14 @@ static lightmapinfo *alloclightmap(lightmapworker *w) return l; } -static void freelightmap(lightmapworker *w) -{ +static void freelightmap(lightmapworker *w) { lightmapinfo *l = w->lastlightmap; if(!l || l->surface >= 0) return; - if(w->firstlightmap == w->lastlightmap) - { + if(w->firstlightmap == w->lastlightmap) { w->firstlightmap = w->lastlightmap = w->curlightmaps = NULL; w->bufstart = w->bufused = 0; } - else - { + else { w->bufused -= l->bufsize - sizeof(lightmapinfo); l->bufsize = sizeof(lightmapinfo); l->packed = true; @@ -1119,11 +961,9 @@ static void freelightmap(lightmapworker *w) if(w->curlightmaps == l) w->curlightmaps = NULL; } -static int setupsurface(lightmapworker *w, plane planes[2], int numplanes, const vec *p, const vec *n, int numverts, vertinfo *litverts, bool preview = false) -{ +static int setupsurface(lightmapworker *w, plane planes[2], int numplanes, const vec *p, const vec *n, int numverts, vertinfo *litverts, bool preview = false) { vec u, v, t; vec2 c[MAXFACEVERTS]; - u = vec(p[2]).sub(p[0]).normalize(); v.cross(planes[0], u); c[0] = vec2(0, 0); @@ -1131,24 +971,20 @@ static int setupsurface(lightmapworker *w, plane planes[2], int numplanes, const vec r1 = vec(p[1]).sub(p[0]); c[1] = vec2(r1.dot(u), min(r1.dot(v), 0.0f)); c[2] = vec2(vec(p[2]).sub(p[0]).dot(u), 0); - for(int i = 3; i < numverts; i++) - { + for(int i = 3; i < numverts; i++) { vec r = vec(p[i]).sub(p[0]); c[i] = vec2(r.dot(u), max(r.dot(t), 0.0f)); } - float carea = 1e16f; vec2 cx(0, 0), cy(0, 0), co(0, 0), cmin(0, 0), cmax(0, 0); - loopi(numverts) - { + loopi(numverts) { vec2 px = vec2(c[i+1 < numverts ? i+1 : 0]).sub(c[i]); float len = px.squaredlen(); if(!len) continue; px.mul(1/sqrtf(len)); vec2 py(-px.y, px.x), pmin(0, 0), pmax(0, 0); if(numplanes >= 2 && (i == 0 || i >= 3)) px.neg(); - loopj(numverts) - { + loopj(numverts) { vec2 rj = vec2(c[j]).sub(c[i]), pj(rj.dot(px), rj.dot(py)); pmin.x = min(pmin.x, pj.x); pmin.y = min(pmin.y, pj.y); @@ -1158,29 +994,24 @@ static int setupsurface(lightmapworker *w, plane planes[2], int numplanes, const float area = (pmax.x-pmin.x)*(pmax.y-pmin.y); if(area < carea) { carea = area; cx = px; cy = py; co = c[i]; cmin = pmin; cmax = pmax; } } - int scale = int(min(cmax.x - cmin.x, cmax.y - cmin.y)); float lpu = 16.0f / float(lightlod && scale < (1 << lightlod) ? max(lightprecision / 2, 1) : lightprecision); int lw = clamp(int(ceil((cmax.x - cmin.x + 1)*lpu)), LM_MINW, LM_MAXW), lh = clamp(int(ceil((cmax.y - cmin.y + 1)*lpu)), LM_MINH, LM_MAXH); w->w = lw; w->h = lh; if(!alloclightmap(w)) return NO_SURFACE; - vec2 cscale = vec2(cmax).sub(cmin).div(vec2(lw-1, lh-1)), comin = vec2(cx).mul(cmin.x).add(vec2(cy).mul(cmin.y)).add(co); - loopi(numverts) - { + loopi(numverts) { vec2 ri = vec2(c[i]).sub(comin); c[i] = vec2(ri.dot(cx)/cscale.x, ri.dot(cy)/cscale.y); } - vec xstep1 = vec(v).mul(cx.y).add(vec(u).mul(cx.x)).mul(cscale.x), ystep1 = vec(v).mul(cy.y).add(vec(u).mul(cy.x)).mul(cscale.y), origin1 = vec(v).mul(comin.y).add(vec(u).mul(comin.x)).add(p[0]), xstep2 = xstep1, ystep2 = ystep1, origin2 = origin1; float side0 = LM_MAXW + 1, sidestep = 0; - if(numplanes >= 2) - { + if(numplanes >= 2) { xstep2 = vec(t).mul(cx.y).add(vec(u).mul(cx.x)).mul(cscale.x); ystep2 = vec(t).mul(cy.y).add(vec(u).mul(cy.x)).mul(cscale.y); origin2 = vec(t).mul(comin.y).add(vec(u).mul(comin.x)).add(p[0]); @@ -1188,41 +1019,33 @@ static int setupsurface(lightmapworker *w, plane planes[2], int numplanes, const else if(cy.y) { side0 = ceil(comin.y/-(cy.y*cscale.y))*(LM_MAXW + 1); sidestep = -(LM_MAXW + 1); if(cy.y < 0) { side0 = (LM_MAXW + 1) - side0; sidestep = -sidestep; } } else side0 = comin.y <= 0 ? LM_MAXW + 1 : -1; } - int surftype = NO_SURFACE; - if(preview) - { + if(preview) { surftype = previewlightmapalpha(w, lpu, origin1, xstep1, ystep1, origin2, xstep2, ystep2, side0, sidestep); } - else - { + else { lerpvert lv[MAXFACEVERTS]; int numv = numverts; calclerpverts(c, n, lv, numv); - if(!generatelightmap(w, lpu, lv, numv, origin1, xstep1, ystep1, origin2, xstep2, ystep2, side0, sidestep)) return NO_SURFACE; surftype = finishlightmap(w); } if(surftypew) texscale.x *= float(w->w - 1) / (lw - 1); if(lh != w->h) texscale.y *= float(w->h - 1) / (lh - 1); - loopk(numverts) - { + loopk(numverts) { litverts[k].u = ushort(floor(clamp(c[k].x*texscale.x, 0.0f, float(USHRT_MAX)))); litverts[k].v = ushort(floor(clamp(c[k].y*texscale.y, 0.0f, float(USHRT_MAX)))); } return surftype; } -static void removelmalpha(lightmapworker *w) -{ +static void removelmalpha(lightmapworker *w) { if(!(w->type&LM_ALPHA)) return; for(uchar *dst = w->colorbuf, *src = w->colorbuf, *end = &src[w->w*w->h*4]; src < end; - dst += 3, src += 4) - { + dst += 3, src += 4) { dst[0] = src[0]; dst[1] = src[1]; dst[2] = src[2]; @@ -1233,60 +1056,48 @@ static void removelmalpha(lightmapworker *w) w->lastlightmap->bpp = w->bpp; } -static lightmapinfo *setupsurfaces(lightmapworker *w, lightmaptask &task) -{ +static lightmapinfo *setupsurfaces(lightmapworker *w, lightmaptask &task) { cube &c = *task.c; const ivec &co = task.o; int size = task.size, usefacemask = task.usefaces; - w->curlightmaps = NULL; w->c = &c; - surfaceinfo surfaces[6]; vertinfo litverts[6*2*MAXFACEVERTS]; int numlitverts = 0; memclear(surfaces); - loopi(6) - { + loopi(6) { int usefaces = usefacemask&0xF; usefacemask >>= 4; - if(!usefaces) - { + if(!usefaces) { if(!c.ext) continue; surfaceinfo &surf = surfaces[i]; surf = c.ext->surfaces[i]; int numverts = surf.totalverts(); - if(numverts) - { + if(numverts) { memcpy(&litverts[numlitverts], c.ext->verts() + surf.verts, numverts*sizeof(vertinfo)); surf.verts = numlitverts; numlitverts += numverts; } continue; } - VSlot &vslot = lookupvslot(c.texture[i], false), *layer = vslot.layer && !(c.material&MAT_ALPHA) ? &lookupvslot(vslot.layer, false) : NULL; Shader *shader = vslot.slot->shader; int shadertype = shader->type; if(layer) shadertype |= layer->slot->shader->type; - surfaceinfo &surf = surfaces[i]; vertinfo *curlitverts = &litverts[numlitverts]; int numverts = c.ext ? c.ext->surfaces[i].numverts&MAXFACEVERTS : 0; ivec mo(co); int msz = size, convex = 0; - if(numverts) - { + if(numverts) { vertinfo *verts = c.ext->verts() + c.ext->surfaces[i].verts; loopj(numverts) curlitverts[j].set(verts[j].getxyz()); - if(c.merged&(1<slot = vslot.slot; w->vslot = &vslot; w->type = shader->type&SHADER_NORMALSLMS ? LM_BUMPMAP0 : LM_DIFFUSE; @@ -1349,30 +1150,24 @@ static lightmapinfo *setupsurfaces(lightmapworker *w, lightmaptask &task) w->orient = i; w->rotate = vslot.rotation; int surftype = setupsurface(w, planes, numplanes, pos, n, numverts, curlitverts); - switch(surftype) - { + switch(surftype) { case SURFACE_LIGHTMAP_BOTTOM: if((shader->type^layer->slot->shader->type)&SHADER_NORMALSLMS || - (shader->type&SHADER_NORMALSLMS && vslot.rotation!=layer->rotation)) - { + (shader->type&SHADER_NORMALSLMS && vslot.rotation!=layer->rotation)) { freelightmap(w); break; } // fall through case SURFACE_LIGHTMAP_BLEND: - case SURFACE_LIGHTMAP_TOP: - { - if(!(surf.numverts&MAXFACEVERTS)) - { + case SURFACE_LIGHTMAP_TOP: { + if(!(surf.numverts&MAXFACEVERTS)) { surf.verts = numlitverts; surf.numverts |= numverts; numlitverts += numverts; } - w->lastlightmap->surface = i; w->lastlightmap->layers = (surftype==SURFACE_LIGHTMAP_BOTTOM ? LAYER_BOTTOM : LAYER_TOP); - if(surftype==SURFACE_LIGHTMAP_BLEND) - { + if(surftype==SURFACE_LIGHTMAP_BLEND) { surf.numverts |= LAYER_BLEND; w->lastlightmap->layers = LAYER_TOP; if((shader->type^layer->slot->shader->type)&SHADER_NORMALSLMS || @@ -1380,15 +1175,12 @@ static lightmapinfo *setupsurfaces(lightmapworker *w, lightmaptask &task) break; w->lastlightmap->layers |= LAYER_BOTTOM; } - else - { - if(surftype==SURFACE_LIGHTMAP_BOTTOM) - { + else { + if(surftype==SURFACE_LIGHTMAP_BOTTOM) { surf.numverts |= LAYER_BOTTOM; w->lastlightmap->layers = LAYER_BOTTOM; } - else - { + else { surf.numverts |= LAYER_TOP; w->lastlightmap->layers = LAYER_TOP; } @@ -1396,44 +1188,35 @@ static lightmapinfo *setupsurfaces(lightmapworker *w, lightmaptask &task) } continue; } - case SURFACE_AMBIENT_BOTTOM: freelightmap(w); surf.numverts |= layer ? LAYER_BOTTOM : LAYER_TOP; continue; - case SURFACE_AMBIENT_TOP: freelightmap(w); surf.numverts |= LAYER_TOP; continue; - default: freelightmap(w); continue; } - w->slot = layer->slot; w->vslot = layer; w->type = layer->slot->shader->type&SHADER_NORMALSLMS ? LM_BUMPMAP0 : LM_DIFFUSE; w->bpp = 3; w->rotate = layer->rotation; vertinfo *blendverts = surf.numverts&MAXFACEVERTS ? &curlitverts[numverts] : curlitverts; - switch(setupsurface(w, planes, numplanes, pos, n, numverts, blendverts)) - { - case SURFACE_LIGHTMAP_TOP: - { - if(!(surf.numverts&MAXFACEVERTS)) - { + switch(setupsurface(w, planes, numplanes, pos, n, numverts, blendverts)) { + case SURFACE_LIGHTMAP_TOP: { + if(!(surf.numverts&MAXFACEVERTS)) { surf.verts = numlitverts; surf.numverts |= numverts; numlitverts += numverts; } - else if(!(surf.numverts&LAYER_DUP)) - { + else if(!(surf.numverts&LAYER_DUP)) { surf.numverts |= LAYER_DUP; w->lastlightmap->layers |= LAYER_DUP; - loopk(numverts) - { + loopk(numverts) { vertinfo &src = curlitverts[k]; vertinfo &dst = blendverts[k]; dst.setxyz(src.getxyz()); @@ -1443,26 +1226,20 @@ static lightmapinfo *setupsurfaces(lightmapworker *w, lightmaptask &task) } surf.numverts |= LAYER_BOTTOM; w->lastlightmap->layers |= LAYER_BOTTOM; - w->lastlightmap->surface = i; break; } - - case SURFACE_AMBIENT_TOP: - { + case SURFACE_AMBIENT_TOP: { freelightmap(w); surf.numverts |= LAYER_BOTTOM; break; } - default: freelightmap(w); break; } } - loopk(6) - { + loopk(6) { surfaceinfo &surf = surfaces[k]; - if(surf.used()) - { + if(surf.used()) { cubeext *ext = c.ext && c.ext->maxverts >= numlitverts ? c.ext : growcubeext(c.ext, numlitverts); memcpy(ext->surfaces, surfaces, sizeof(ext->surfaces)); memcpy(ext->verts(), litverts, numlitverts*sizeof(vertinfo)); @@ -1473,14 +1250,11 @@ static lightmapinfo *setupsurfaces(lightmapworker *w, lightmaptask &task) return w->curlightmaps ? w->curlightmaps : (lightmapinfo *)-1; } -int lightmapworker::work(void *data) -{ +int lightmapworker::work(void *data) { lightmapworker *w = (lightmapworker *)data; SDL_LockMutex(tasklock); - while(!w->doneworking) - { - if(allocidx < lightmaptasks[0].length()) - { + while(!w->doneworking) { + if(allocidx < lightmaptasks[0].length()) { lightmaptask &t = lightmaptasks[0][allocidx++]; t.worker = w; SDL_UnlockMutex(tasklock); @@ -1489,8 +1263,7 @@ int lightmapworker::work(void *data) t.lightmaps = l; packlightmaps(w); } - else - { + else { if(packidx >= lightmaptasks[0].length()) SDL_CondSignal(emptycond); SDL_CondWait(fullcond, tasklock); } @@ -1499,28 +1272,22 @@ int lightmapworker::work(void *data) return 0; } -static bool processtasks(bool finish = false) -{ +static bool processtasks(bool finish = false) { if(tasklock) SDL_LockMutex(tasklock); - while(finish || lightmaptasks[1].length()) - { - if(packidx >= lightmaptasks[0].length()) - { + while(finish || lightmaptasks[1].length()) { + if(packidx >= lightmaptasks[0].length()) { if(lightmaptasks[1].empty()) break; lightmaptasks[0].setsize(0); lightmaptasks[0].move(lightmaptasks[1]); packidx = allocidx = 0; if(fullcond) SDL_CondBroadcast(fullcond); } - else if(lightmapping > 1) - { + else if(lightmapping > 1) { SDL_CondWaitTimeout(emptycond, tasklock, 250); CHECK_PROGRESS_LOCKED({ SDL_UnlockMutex(tasklock); return false; }, SDL_UnlockMutex(tasklock), SDL_LockMutex(tasklock)); } - else - { - while(allocidx < lightmaptasks[0].length()) - { + else { + while(allocidx < lightmaptasks[0].length()) { lightmaptask &t = lightmaptasks[0][allocidx++]; t.worker = lightmapworkers[0]; t.lightmaps = setupsurfaces(lightmapworkers[0], t); @@ -1533,35 +1300,26 @@ static bool processtasks(bool finish = false) return true; } -static void generatelightmaps(cube *c, const ivec &co, int size) -{ +static void generatelightmaps(cube *c, const ivec &co, int size) { CHECK_PROGRESS(return); - taskprogress++; - - loopi(8) - { + loopi(8) { ivec o(i, co, size); if(c[i].children) generatelightmaps(c[i].children, o, size >> 1); - else if(!isempty(c[i])) - { - if(c[i].ext) - { - loopj(6) - { + else if(!isempty(c[i])) { + if(c[i].ext) { + loopj(6) { surfaceinfo &surf = c[i].ext->surfaces[j]; if(surf.lmid[0] >= LMID_RESERVED || surf.lmid[1] >= LMID_RESERVED) goto nextcube; surf.clear(); } } int usefacemask = 0; - loopj(6) if(!(c[i].merged&(1<surfaces[j].numverts&MAXFACEVERTS)) - { + loopj(6) if(!(c[i].merged&(1<surfaces[j].numverts&MAXFACEVERTS)) { usefacemask |= visibletris(c[i], j, o, size)<<(4*j); } - if(usefacemask) - { + if(usefacemask) { lightmaptask &t = lightmaptasks[1].add(); t.o = o; t.size = size; @@ -1577,10 +1335,8 @@ static void generatelightmaps(cube *c, const ivec &co, int size) } } -void cleanuplightmaps() -{ - loopv(lightmaps) - { +void cleanuplightmaps() { + loopv(lightmaps) { LightMap &lm = lightmaps[i]; lm.tex = lm.offsetx = lm.offsety = -1; } @@ -1589,8 +1345,7 @@ void cleanuplightmaps() if(progresstex) { glDeleteTextures(1, &progresstex); progresstex = 0; } } -void resetlightmaps(bool fullclean) -{ +void resetlightmaps(bool fullclean) { cleanuplightmaps(); lightmaps.shrink(0); compressed.clear(); @@ -1598,8 +1353,7 @@ void resetlightmaps(bool fullclean) if(fullclean) while(lightmapworkers.length()) delete lightmapworkers.pop(); } -lightmapworker::lightmapworker() -{ +lightmapworker::lightmapworker() { buf = new uchar[LIGHTMAPBUFSIZE]; bufstart = bufused = 0; firstlightmap = lastlightmap = curlightmaps = NULL; @@ -1613,8 +1367,7 @@ lightmapworker::lightmapworker() thread = NULL; } -lightmapworker::~lightmapworker() -{ +lightmapworker::~lightmapworker() { cleanupthread(); delete[] buf; delete[] ambient; @@ -1624,38 +1377,32 @@ lightmapworker::~lightmapworker() freeshadowraycache(shadowraycache); } -void lightmapworker::cleanupthread() -{ +void lightmapworker::cleanupthread() { if(spacecond) { SDL_DestroyCond(spacecond); spacecond = NULL; } thread = NULL; } -void lightmapworker::reset() -{ +void lightmapworker::reset() { bufstart = bufused = 0; firstlightmap = lastlightmap = curlightmaps = NULL; needspace = doneworking = false; resetshadowraycache(shadowraycache); } -bool lightmapworker::setupthread() -{ +bool lightmapworker::setupthread() { if(!spacecond) spacecond = SDL_CreateCond(); if(!spacecond) return false; thread = SDL_CreateThread(work, "lightmap worker", this); return thread!=NULL; } -static Uint32 calclighttimer(Uint32 interval, void *param) -{ +static Uint32 calclighttimer(Uint32 interval, void *param) { check_calclight_progress = true; return interval; } -bool setlightmapquality(int quality) -{ - switch(quality) - { +bool setlightmapquality(int quality) { + switch(quality) { case 1: lmshadows = 2; lmaa = 3; lerptjoints = 1; break; case 0: lmshadows = lmshadows_; lmaa = lmaa_; lerptjoints = lerptjoints_; break; case -1: lmshadows = 1; lmaa = 0; lerptjoints = 0; break; @@ -1669,30 +1416,26 @@ VARP(lightthreads, 0, 0, 16); #define ALLOCLOCK(name, init) { if(lightmapping > 1) name = init(); if(!name) lightmapping = 1; } #define FREELOCK(name, destroy) { if(name) { destroy(name); name = NULL; } } -static void cleanuplocks() -{ +static void cleanuplocks() { FREELOCK(lightlock, SDL_DestroyMutex); FREELOCK(tasklock, SDL_DestroyMutex); FREELOCK(fullcond, SDL_DestroyCond); FREELOCK(emptycond, SDL_DestroyCond); } -static void setupthreads(int numthreads) -{ +static void setupthreads(int numthreads) { loopi(2) lightmaptasks[i].setsize(0); lightmapexts.setsize(0); packidx = allocidx = 0; lightmapping = numthreads; - if(lightmapping > 1) - { + if(lightmapping > 1) { ALLOCLOCK(lightlock, SDL_CreateMutex); ALLOCLOCK(tasklock, SDL_CreateMutex); ALLOCLOCK(fullcond, SDL_CreateCond); ALLOCLOCK(emptycond, SDL_CreateCond); } while(lightmapworkers.length() < lightmapping) lightmapworkers.add(new lightmapworker); - loopi(lightmapping) - { + loopi(lightmapping) { lightmapworker *w = lightmapworkers[i]; w->reset(); if(lightmapping <= 1 || w->setupthread()) continue; @@ -1703,28 +1446,23 @@ static void setupthreads(int numthreads) if(lightmapping <= 1) cleanuplocks(); } -static void cleanupthreads() -{ +static void cleanupthreads() { processtasks(true); - if(lightmapping > 1) - { + if(lightmapping > 1) { SDL_LockMutex(tasklock); loopv(lightmapworkers) lightmapworkers[i]->doneworking = true; SDL_CondBroadcast(fullcond); - loopv(lightmapworkers) - { + loopv(lightmapworkers) { lightmapworker *w = lightmapworkers[i]; if(w->needspace && w->spacecond) SDL_CondSignal(w->spacecond); } SDL_UnlockMutex(tasklock); - loopv(lightmapworkers) - { + loopv(lightmapworkers) { lightmapworker *w = lightmapworkers[i]; if(w->thread) SDL_WaitThread(w->thread, NULL); } } - loopv(lightmapexts) - { + loopv(lightmapexts) { lightmapext &e = lightmapexts[i]; setcubeext(*e.c, e.ext); } @@ -1733,10 +1471,8 @@ static void cleanupthreads() lightmapping = 0; } -void calclight(int *quality) -{ - if(!setlightmapquality(*quality)) - { +void calclight(int *quality) { + if(!setlightmapquality(*quality)) { conoutf(CON_ERROR, "valid range for calclight quality is -1..1"); return; } @@ -1763,8 +1499,7 @@ void calclight(int *quality) Uint32 end = SDL_GetTicks(); if(timer) SDL_RemoveTimer(timer); uint total = 0, lumels = 0; - loopv(lightmaps) - { + loopv(lightmaps) { insertunlit(i); if(!editmode) lightmaps[i].finalize(); total += lightmaps[i].lightmaps; @@ -1786,8 +1521,7 @@ void calclight(int *quality) COMMAND(calclight, "i"); -void clearlightmaps() -{ +void clearlightmaps() { if(noedit(true)) return; renderprogress(0, "clearing lightmaps..."); resetlightmaps(false); @@ -1798,10 +1532,8 @@ void clearlightmaps() COMMAND(clearlightmaps, ""); -void setfullbrightlevel(int fullbrightlevel) -{ - if(lightmaptexs.length() > LMID_BRIGHT) - { +void setfullbrightlevel(int fullbrightlevel) { + if(lightmaptexs.length() > LMID_BRIGHT) { uchar bright[3] = { uchar(fullbrightlevel), uchar(fullbrightlevel), uchar(fullbrightlevel) }; createtexture(lightmaptexs[LMID_BRIGHT].id, 1, 1, bright, 0, 1); } @@ -1813,21 +1545,17 @@ VARF(fullbrightlevel, 0, 128, 255, setfullbrightlevel(fullbrightlevel)); vector lightmaptexs; -static void copylightmap(LightMap &lm, uchar *dst, size_t stride) -{ +static void copylightmap(LightMap &lm, uchar *dst, size_t stride) { const uchar *c = lm.data; - loopi(LM_PACKH) - { + loopi(LM_PACKH) { memcpy(dst, c, lm.bpp*LM_PACKW); c += lm.bpp*LM_PACKW; dst += stride; } } -void genreservedlightmaptexs() -{ - while(lightmaptexs.length() < LMID_RESERVED) - { +void genreservedlightmaptexs() { + while(lightmaptexs.length() < LMID_RESERVED) { LightMapTexture &tex = lightmaptexs.add(); tex.type = lightmaptexs.length()&1 ? LM_DIFFUSE : LM_BUMPMAP1; glGenTextures(1, &tex.id); @@ -1844,30 +1572,24 @@ void genreservedlightmaptexs() createtexture(lightmaptexs[LMID_DARK1].id, 1, 1, &front, 0, 1); } -static void findunlit(int i) -{ +static void findunlit(int i) { LightMap &lm = lightmaps[i]; if(lm.unlitx>=0) return; - else if((lm.type&LM_TYPE)==LM_BUMPMAP0) - { + else if((lm.type&LM_TYPE)==LM_BUMPMAP0) { if(i+1>=lightmaps.length() || (lightmaps[i+1].type&LM_TYPE)!=LM_BUMPMAP1) return; } else if((lm.type&LM_TYPE)!=LM_DIFFUSE) return; uchar *data = lm.data; - loop(y, 2) loop(x, LM_PACKW) - { - if(!data[0] && !data[1] && !data[2]) - { + loop(y, 2) loop(x, LM_PACKW) { + if(!data[0] && !data[1] && !data[2]) { memcpy(data, ambientcolor.v, 3); if((lm.type&LM_TYPE)==LM_BUMPMAP0) ((bvec *)lightmaps[i+1].data)[y*LM_PACKW + x] = bvec(128, 128, 255); lm.unlitx = x; lm.unlity = y; return; } - if(data[0]==ambientcolor[0] && data[1]==ambientcolor[1] && data[2]==ambientcolor[2]) - { - if((lm.type&LM_TYPE)!=LM_BUMPMAP0 || ((bvec *)lightmaps[i+1].data)[y*LM_PACKW + x] == bvec(128, 128, 255)) - { + if(data[0]==ambientcolor[0] && data[1]==ambientcolor[1] && data[2]==ambientcolor[2]) { + if((lm.type&LM_TYPE)!=LM_BUMPMAP0 || ((bvec *)lightmaps[i+1].data)[y*LM_PACKW + x] == bvec(128, 128, 255)) { lm.unlitx = x; lm.unlity = y; return; @@ -1880,13 +1602,10 @@ static void findunlit(int i) VARF(roundlightmaptex, 0, 4, 16, { cleanuplightmaps(); initlights(); allchanged(); }); VARF(batchlightmaps, 0, 4, 256, { cleanuplightmaps(); initlights(); allchanged(); }); -void genlightmaptexs(int flagmask, int flagval) -{ +void genlightmaptexs(int flagmask, int flagval) { if(lightmaptexs.length() < LMID_RESERVED) genreservedlightmaptexs(); - int remaining[LM_TYPE+1] = { 0 }, total = 0; - loopv(lightmaps) - { + loopv(lightmaps) { LightMap &lm = lightmaps[i]; if(lm.tex >= 0 || (lm.type&flagmask)!=flagval) continue; int type = lm.type&LM_TYPE; @@ -1894,15 +1613,12 @@ void genlightmaptexs(int flagmask, int flagval) total++; if(lm.unlitx < 0) findunlit(i); } - int sizelimit = (maxtexsize ? min(maxtexsize, hwtexsize) : hwtexsize)/max(LM_PACKW, LM_PACKH); sizelimit = min(batchlightmaps, sizelimit*sizelimit); - while(total) - { + while(total) { int type = LM_DIFFUSE; LightMap *firstlm = NULL; - loopv(lightmaps) - { + loopv(lightmaps) { LightMap &lm = lightmaps[i]; if(lm.tex >= 0 || (lm.type&flagmask) != flagval) continue; type = lm.type&LM_TYPE; @@ -1915,8 +1631,7 @@ void genlightmaptexs(int flagmask, int flagval) used--; int oldval = remaining[type]; remaining[type] -= 1<bpp; uchar *data = used ? new uchar[bpp*tex.w*tex.h] : NULL; int offsetx = 0, offsety = 0; - loopv(lightmaps) - { + loopv(lightmaps) { LightMap &lm = lightmaps[i]; if(lm.tex >= 0 || (lm.type&flagmask) != flagval || (lm.type&LM_TYPE) != type) continue; - lm.tex = lightmaptexs.length()-1; lm.offsetx = offsetx; lm.offsety = offsety; - if(tex.unlitx < 0 && lm.unlitx >= 0) - { + if(tex.unlitx < 0 && lm.unlitx >= 0) { tex.unlitx = offsetx + lm.unlitx; tex.unlity = offsety + lm.unlity; } - if(data) copylightmap(lm, &data[bpp*(offsety*tex.w + offsetx)], bpp*tex.w); - offsetx += LM_PACKW; if(offsetx >= tex.w) { offsetx = 0; offsety += LM_PACKH; } if(offsety >= tex.h) break; } - glGenTextures(1, &tex.id); createtexture(tex.id, tex.w, tex.h, data ? data : firstlm->data, 3, 1, bpp==4 ? GL_RGBA : GL_RGB); if(data) delete[] data; @@ -1957,29 +1666,24 @@ void genlightmaptexs(int flagmask, int flagval) bool brightengeom = false, shouldlightents = false; -void clearlights() -{ +void clearlights() { clearlightcache(); const vector &ents = entities::getents(); - loopv(ents) - { + loopv(ents) { extentity &e = *ents[i]; e.light.color = vec(1, 1, 1); e.light.dir = vec(0, 0, 1); } shouldlightents = false; - genlightmaptexs(LM_ALPHA, 0); genlightmaptexs(LM_ALPHA, LM_ALPHA); brightengeom = true; } -void lightent(extentity &e, float height) -{ +void lightent(extentity &e, float height) { if(e.type==ET_LIGHT) return; float ambient = 0.0f; - if(e.type==ET_MAPMODEL) - { + if(e.type==ET_MAPMODEL) { model *m = loadmodel(NULL, e.attr2); if(m) height = m->above()*0.75f; } @@ -1988,24 +1692,18 @@ void lightent(extentity &e, float height) lightreaching(target, e.light.color, e.light.dir, false, &e, ambient); } -void lightents(bool force) -{ +void lightents(bool force) { if(!force && !shouldlightents) return; - const vector &ents = entities::getents(); loopv(ents) lightent(*ents[i]); - shouldlightents = false; } -void initlights() -{ - if((fullbright && editmode) || lightmaps.empty()) - { +void initlights() { + if((fullbright && editmode) || lightmaps.empty()) { clearlights(); return; } - clearlightcache(); genlightmaptexs(LM_ALPHA, 0); genlightmaptexs(LM_ALPHA, LM_ALPHA); @@ -2013,49 +1711,39 @@ void initlights() shouldlightents = true; } -void lightreaching(const vec &target, vec &color, vec &dir, bool fast, extentity *t, float ambient) -{ - if((fullbright && editmode) || lightmaps.empty()) - { +void lightreaching(const vec &target, vec &color, vec &dir, bool fast, extentity *t, float ambient) { + if((fullbright && editmode) || lightmaps.empty()) { color = vec(1, 1, 1); dir = vec(0, 0, 1); return; } - color = dir = vec(0, 0, 0); const vector &ents = entities::getents(); const vector &lights = checklightcache(int(target.x), int(target.y)); - loopv(lights) - { + loopv(lights) { extentity &e = *ents[lights[i]]; if(e.type != ET_LIGHT) continue; - vec ray(target); ray.sub(e.o); float mag = ray.magnitude(); if(e.attr1 && mag >= float(e.attr1)) continue; - if(mag < 1e-4f) ray = vec(0, 0, -1); - else - { + else { ray.div(mag); if(shadowray(e.o, ray, mag, RAY_SHADOW | RAY_POLY, t) < mag) continue; } - float intensity = 1; if(e.attr1) intensity -= mag / float(e.attr1); - if(e.attached && e.attached->type==ET_SPOTLIGHT) - { + if(e.attached && e.attached->type==ET_SPOTLIGHT) { vec spot = vec(e.attached->o).sub(e.o).normalize(); float maxatten = sincos360[clamp(int(e.attached->attr1), 1, 89)].x, spotatten = (ray.dot(spot) - maxatten) / (1 - maxatten); if(spotatten <= 0) continue; intensity *= spotatten; } - vec lightcol = vec(e.attr2, e.attr3, e.attr4).mul(1.0f/255); color.add(vec(lightcol).mul(intensity)); dir.add(vec(ray).mul(-intensity*lightcol.x*lightcol.y*lightcol.z)); @@ -2065,40 +1753,33 @@ void lightreaching(const vec &target, vec &color, vec &dir, bool fast, extentity else dir.normalize(); } -entity *brightestlight(const vec &target, const vec &dir) -{ +entity *brightestlight(const vec &target, const vec &dir) { const vector &ents = entities::getents(); const vector &lights = checklightcache(int(target.x), int(target.y)); extentity *brightest = NULL; float bintensity = 0; - loopv(lights) - { + loopv(lights) { extentity &e = *ents[lights[i]]; if(e.type != ET_LIGHT || vec(e.o).sub(target).dot(dir)<0) continue; - vec ray(target); ray.sub(e.o); float mag = ray.magnitude(); if(e.attr1 && mag >= float(e.attr1)) continue; - ray.div(mag); if(shadowray(e.o, ray, mag, RAY_SHADOW | RAY_POLY) < mag) continue; float intensity = 1; if(e.attr1) intensity -= mag / float(e.attr1); - if(e.attached && e.attached->type==ET_SPOTLIGHT) - { + if(e.attached && e.attached->type==ET_SPOTLIGHT) { vec spot = vec(e.attached->o).sub(e.o).normalize(); float maxatten = sincos360[clamp(int(e.attached->attr1), 1, 89)].x, spotatten = (ray.dot(spot) - maxatten) / (1 - maxatten); if(spotatten <= 0) continue; intensity *= spotatten; } - - if(!brightest || intensity > bintensity) - { + if(!brightest || intensity > bintensity) { brightest = &e; bintensity = intensity; } @@ -2106,10 +1787,8 @@ entity *brightestlight(const vec &target, const vec &dir) return brightest; } -void dumplms() -{ - loopv(lightmaps) - { +void dumplms() { + loopv(lightmaps) { ImageData temp(LM_PACKW, LM_PACKH, lightmaps[i].bpp, lightmaps[i].data); const char *map = game::getclientmap(), *name = strrchr(map, '/'); defformatstring(buf, "lightmap_%s_%d.png", name ? name+1 : map, i); -- cgit v1.2.3