LCOV - code coverage report
Current view: top level - engine/world - light.cpp (source / functions) Coverage Total Hit
Test: Libprimis Test Coverage Lines: 6.4 % 358 23
Test Date: 2025-02-18 06:21:28 Functions: 4.8 % 21 1

            Line data    Source code
       1              : /* light.cpp: world light interaction functions
       2              :  *
       3              :  * while renderlights in /render handles the deferred rendering of point lights
       4              :  * on the world, light.cpp handles how lights behave in the world
       5              :  *
       6              :  * includes sunlight variables (direction/color of no-parallax sun lighting)
       7              :  * world light entity packing for the renderer to use
       8              :  */
       9              : #include "../libprimis-headers/cube.h"
      10              : #include "../../shared/geomexts.h"
      11              : #include "../../shared/glexts.h"
      12              : 
      13              : #include "light.h"
      14              : #include "octaworld.h"
      15              : #include "raycube.h"
      16              : #include "world.h"
      17              : 
      18              : #include "interface/console.h"
      19              : #include "interface/input.h"
      20              : 
      21              : #include "render/radiancehints.h"
      22              : #include "render/renderlights.h"
      23              : #include "render/octarender.h"
      24              : #include "render/shaderparam.h"
      25              : #include "render/texture.h"
      26              : 
      27            0 : CVAR1R(ambient, 0x191919);
      28              : FVARR(ambientscale, 0, 1, 16);
      29              : 
      30            0 : CVAR1R(skylight, 0);
      31              : FVARR(skylightscale, 0, 1, 16);
      32              : 
      33            0 : CVAR1FR(sunlight, 0,
      34              : {
      35              :     clearradiancehintscache();
      36              :     cleardeferredlightshaders();
      37              :     clearshadowcache();
      38              : });
      39            0 : FVARFR(sunlightscale, 0, 1, 16, clearradiancehintscache(););
      40              : 
      41              : vec sunlightdir(0, 0, 1);
      42              : void setsunlightdir();
      43            0 : FVARFR(sunlightyaw, 0, 0, 360, setsunlightdir());
      44            0 : FVARFR(sunlightpitch, -90, 90, 90, setsunlightdir());
      45              : 
      46            0 : void setsunlightdir()
      47              : {
      48            0 :     sunlightdir = vec(sunlightyaw/RAD, sunlightpitch/RAD);
      49            0 :     for(int k = 0; k < 3; ++k)
      50              :     {
      51            0 :         if(std::fabs(sunlightdir[k]) < 1e-5f)
      52              :         {
      53            0 :             sunlightdir[k] = 0;
      54              :         }
      55              :     }
      56            0 :     sunlightdir.normalize();
      57            0 :     clearradiancehintscache();
      58            0 : }
      59              : 
      60            0 : void brightencube(cube &c)
      61              : {
      62            0 :     if(!c.ext)
      63              :     {
      64            0 :         newcubeext(c, 0, false);
      65              :     }
      66            0 :     c.ext->surfaces.fill(surfaceinfo());
      67            0 : }
      68              : 
      69            0 : void setsurfaces(cube &c, std::array<surfaceinfo, 6> surfs, const vertinfo *verts, int numverts)
      70              : {
      71            0 :     if(!c.ext || c.ext->maxverts < numverts)
      72              :     {
      73            0 :         newcubeext(c, numverts, false);
      74              :     }
      75            0 :     std::copy(c.ext->surfaces.begin(), c.ext->surfaces.end(), surfs.begin());
      76            0 :     std::memcpy(c.ext->verts(), verts, numverts*sizeof(vertinfo));
      77            0 : }
      78              : 
      79            0 : void setsurface(cube &c, int orient, const surfaceinfo &src, const vertinfo *srcverts, int numsrcverts)
      80              : {
      81            0 :     int dstoffset = 0;
      82            0 :     if(!c.ext)
      83              :     {
      84            0 :         newcubeext(c, numsrcverts, true);
      85              :     }
      86              :     else
      87              :     {
      88            0 :         int numbefore = 0,
      89            0 :             beforeoffset = 0;
      90            0 :         for(int i = 0; i < orient; ++i)
      91              :         {
      92            0 :             const surfaceinfo &surf = c.ext->surfaces[i];
      93            0 :             int numverts = surf.totalverts();
      94            0 :             if(!numverts)
      95              :             {
      96            0 :                 continue;
      97              :             }
      98            0 :             numbefore += numverts;
      99            0 :             beforeoffset = surf.verts + numverts;
     100              :         }
     101            0 :         int numafter = 0,
     102            0 :             afteroffset = c.ext->maxverts;
     103            0 :         for(int i = 5; i > orient; i--) //note reverse iteration
     104              :         {
     105            0 :             const surfaceinfo &surf = c.ext->surfaces[i];
     106            0 :             int numverts = surf.totalverts();
     107            0 :             if(!numverts)
     108              :             {
     109            0 :                 continue;
     110              :             }
     111            0 :             numafter += numverts;
     112            0 :             afteroffset = surf.verts;
     113              :         }
     114            0 :         if(afteroffset - beforeoffset >= numsrcverts)
     115              :         {
     116            0 :             dstoffset = beforeoffset;
     117              :         }
     118              :         else
     119              :         {
     120            0 :             cubeext *ext = c.ext;
     121            0 :             if(numbefore + numsrcverts + numafter > c.ext->maxverts)
     122              :             {
     123            0 :                 ext = growcubeext(c.ext, numbefore + numsrcverts + numafter);
     124            0 :                 std::copy(ext->surfaces.begin(), ext->surfaces.end(), c.ext->surfaces.begin());
     125              :             }
     126            0 :             int offset = 0;
     127            0 :             if(numbefore == beforeoffset)
     128              :             {
     129            0 :                 if(numbefore && c.ext != ext)
     130              :                 {
     131            0 :                     std::memcpy(ext->verts(), c.ext->verts(), numbefore*sizeof(vertinfo));
     132              :                 }
     133            0 :                 offset = numbefore;
     134              :             }
     135              :             else
     136              :             {
     137            0 :                 for(int i = 0; i < orient; ++i)
     138              :                 {
     139            0 :                     surfaceinfo &surf = ext->surfaces[i];
     140            0 :                     int numverts = surf.totalverts();
     141            0 :                     if(!numverts)
     142              :                     {
     143            0 :                         continue;
     144              :                     }
     145            0 :                     std::memmove(ext->verts() + offset, c.ext->verts() + surf.verts, numverts*sizeof(vertinfo));
     146            0 :                     surf.verts = offset;
     147            0 :                     offset += numverts;
     148              :                 }
     149              :             }
     150            0 :             dstoffset = offset;
     151            0 :             offset += numsrcverts;
     152            0 :             if(numafter && offset > afteroffset)
     153              :             {
     154            0 :                 offset += numafter;
     155            0 :                 for(int i = 5; i > orient; i--) //note reverse iteration
     156              :                 {
     157            0 :                     surfaceinfo &surf = ext->surfaces[i];
     158            0 :                     int numverts = surf.totalverts();
     159            0 :                     if(!numverts)
     160              :                     {
     161            0 :                         continue;
     162              :                     }
     163            0 :                     offset -= numverts;
     164            0 :                     std::memmove(ext->verts() + offset, c.ext->verts() + surf.verts, numverts*sizeof(vertinfo));
     165            0 :                     surf.verts = offset;
     166              :                 }
     167              :             }
     168            0 :             if(c.ext != ext)
     169              :             {
     170            0 :                 setcubeext(c, ext);
     171              :             }
     172              :         }
     173              :     }
     174            0 :     surfaceinfo &dst = c.ext->surfaces[orient];
     175            0 :     dst = src;
     176            0 :     dst.verts = dstoffset;
     177            0 :     if(srcverts)
     178              :     {
     179            0 :         std::memcpy(c.ext->verts() + dstoffset, srcverts, numsrcverts*sizeof(vertinfo));
     180              :     }
     181            0 : }
     182              : 
     183           33 : bool PackNode::insert(ushort &tx, ushort &ty, ushort tw, ushort th)
     184              : {
     185           33 :     if((available < tw && available < th) || w < tw || h < th)
     186              :     {
     187            9 :         return false;
     188              :     }
     189           24 :     if(child1)
     190              :     {
     191           21 :         bool inserted = child1->insert(tx, ty, tw, th) ||
     192            9 :                         child2->insert(tx, ty, tw, th);
     193           12 :         available = std::max(child1->available, child2->available);
     194           12 :         if(!available)
     195              :         {
     196            3 :             discardchildren();
     197              :         }
     198           12 :         return inserted;
     199              :     }
     200           12 :     if(w == tw && h == th)
     201              :     {
     202            6 :         available = 0;
     203            6 :         tx = x;
     204            6 :         ty = y;
     205            6 :         return true;
     206              :     }
     207              : 
     208            6 :     if(w - tw > h - th)
     209              :     {
     210            4 :         child1 = new PackNode(x, y, tw, h);
     211            4 :         child2 = new PackNode(x + tw, y, w - tw, h);
     212              :     }
     213              :     else
     214              :     {
     215            2 :         child1 = new PackNode(x, y, w, th);
     216            2 :         child2 = new PackNode(x, y + th, w, h - th);
     217              :     }
     218              : 
     219            6 :     bool inserted = child1->insert(tx, ty, tw, th);
     220            6 :     available = std::max(child1->available, child2->available);
     221            6 :     return inserted;
     222              : }
     223              : 
     224            0 : void PackNode::reserve(ushort tx, ushort ty, ushort tw, ushort th)
     225              : {
     226            0 :     if(tx + tw <= x || tx >= x + w || ty + th <= y || ty >= y + h)
     227              :     {
     228            0 :         return;
     229              :     }
     230            0 :     if(child1)
     231              :     {
     232            0 :         child1->reserve(tx, ty, tw, th);
     233            0 :         child2->reserve(tx, ty, tw, th);
     234            0 :         available = std::max(child1->available, child2->available);
     235            0 :         return;
     236              :     }
     237            0 :     int dx1 = tx - x,
     238            0 :         dx2 = x + w - tx - tw,
     239            0 :         dx = std::max(dx1, dx2),
     240            0 :         dy1 = ty - y,
     241            0 :         dy2 = y + h - ty - th,
     242            0 :         dy = std::max(dy1, dy2),
     243              :         split;
     244            0 :     if(dx > dy)
     245              :     {
     246            0 :         if(dx1 > dx2)
     247              :         {
     248            0 :             split = std::min(dx1, static_cast<int>(w));
     249              :         }
     250              :         else
     251              :         {
     252            0 :             split = w - std::max(dx2, 0);
     253              :         }
     254            0 :         if(w - split <= 0)
     255              :         {
     256            0 :             w = split;
     257            0 :             available = std::min(w, h);
     258            0 :             if(dy > 0)
     259              :             {
     260            0 :                 reserve(tx, ty, tw, th);
     261              :             }
     262            0 :             else if(tx <= x && tx + tw >= x + w)
     263              :             {
     264            0 :                 available = 0;
     265              :             }
     266            0 :             return;
     267              :         }
     268            0 :         if(split <= 0)
     269              :         {
     270            0 :             x += split;
     271            0 :             w -= split;
     272            0 :             available = std::min(w, h);
     273            0 :             if(dy > 0)
     274              :             {
     275            0 :                 reserve(tx, ty, tw, th);
     276              :             }
     277            0 :             else if(tx <= x && tx + tw >= x + w)
     278              :             {
     279            0 :                 available = 0;
     280              :             }
     281            0 :             return;
     282              :         }
     283            0 :         child1 = new PackNode(x, y, split, h);
     284            0 :         child2 = new PackNode(x + split, y, w - split, h);
     285              :     }
     286              :     else
     287              :     {
     288            0 :         if(dy1 > dy2)
     289              :         {
     290            0 :             split = std::min(dy1, static_cast<int>(h));
     291              :         }
     292              :         else
     293              :         {
     294            0 :             split = h - std::max(dy2, 0);
     295              :         }
     296            0 :         if(h - split <= 0)
     297              :         {
     298            0 :             h = split;
     299            0 :             available = std::min(w, h);
     300            0 :             if(dx > 0)
     301              :             {
     302            0 :                 reserve(tx, ty, tw, th);
     303              :             }
     304            0 :             else if(ty <= y && ty + th >= y + h)
     305              :             {
     306            0 :                 available = 0;
     307              :             }
     308            0 :             return;
     309              :         }
     310            0 :         if(split <= 0)
     311              :         {
     312            0 :             y += split;
     313            0 :             h -= split;
     314            0 :             available = std::min(w, h);
     315            0 :             if(dx > 0)
     316              :             {
     317            0 :                 reserve(tx, ty, tw, th);
     318              :             }
     319            0 :             else if(ty <= y && ty + th >= y + h)
     320              :             {
     321            0 :                 available = 0;
     322              :             }
     323            0 :             return;
     324              :         }
     325            0 :         child1 = new PackNode(x, y, w, split);
     326            0 :         child2 = new PackNode(x, y + split, w, h - split);
     327              :     }
     328            0 :     child1->reserve(tx, ty, tw, th);
     329            0 :     child2->reserve(tx, ty, tw, th);
     330            0 :     available = std::max(child1->available, child2->available);
     331              : }
     332              : 
     333            0 : static void clearsurfaces(std::array<cube, 8> &c)
     334              : {
     335            0 :     for(int i = 0; i < 8; ++i)
     336              :     {
     337            0 :         if(c[i].ext)
     338              :         {
     339            0 :             for(int j = 0; j < 6; ++j)
     340              :             {
     341            0 :                 surfaceinfo &surf = c[i].ext->surfaces[j];
     342            0 :                 if(!surf.used())
     343              :                 {
     344            0 :                     continue;
     345              :                 }
     346            0 :                 surf.clear();
     347            0 :                 int numverts = surf.numverts&Face_MaxVerts;
     348            0 :                 if(numverts)
     349              :                 {
     350            0 :                     if(!(c[i].merged&(1<<j)))
     351              :                     {
     352            0 :                         surf.numverts &= ~Face_MaxVerts;
     353            0 :                         continue;
     354              :                     }
     355            0 :                     vertinfo *verts = c[i].ext->verts() + surf.verts;
     356            0 :                     for(int k = 0; k < numverts; ++k)
     357              :                     {
     358            0 :                         vertinfo &v = verts[k];
     359            0 :                         v.norm = 0;
     360              :                     }
     361              :                 }
     362              :             }
     363              :         }
     364            0 :         if(c[i].children)
     365              :         {
     366            0 :             clearsurfaces(*(c[i].children));
     367              :         }
     368              :     }
     369            0 : }
     370              : 
     371              : 
     372              : static constexpr int lightcacheentries = 1024;
     373              : 
     374              : static struct lightcacheentry
     375              : {
     376              :     int x, y;
     377              : } lightcache[lightcacheentries];
     378              : 
     379            0 : static int lightcachehash(int x, int y)
     380              : {
     381            0 :     return (((((x)^(y))<<5) + (((x)^(y))>>5)) & (lightcacheentries - 1));
     382              : }
     383              : 
     384            0 : VARF(lightcachesize, 4, 6, 12, clearlightcache());
     385              : 
     386            0 : void clearlightcache(int id)
     387              : {
     388            0 :     if(id >= 0)
     389              :     {
     390            0 :         const extentity &light = *entities::getents()[id];
     391            0 :         int radius = light.attr1;
     392            0 :         if(radius <= 0)
     393              :         {
     394            0 :             return;
     395              :         }
     396            0 :         for(int x = static_cast<int>(std::max(light.o.x-radius, 0.0f))>>lightcachesize, ex = static_cast<int>(std::min(light.o.x+radius, rootworld.mapsize()-1.0f))>>lightcachesize; x <= ex; x++)
     397              :         {
     398            0 :             for(int y = static_cast<int>(std::max(light.o.y-radius, 0.0f))>>lightcachesize, ey = static_cast<int>(std::min(light.o.y+radius, rootworld.mapsize()-1.0f))>>lightcachesize; y <= ey; y++)
     399              :             {
     400            0 :                 lightcacheentry &lce = lightcache[lightcachehash(x, y)];
     401            0 :                 if(lce.x != x || lce.y != y)
     402              :                 {
     403            0 :                     continue;
     404              :                 }
     405            0 :                 lce.x = -1;
     406              :             }
     407              :         }
     408            0 :         return;
     409              :     }
     410              : 
     411            0 :     for(lightcacheentry *lce = lightcache; lce < &lightcache[lightcacheentries]; lce++)
     412              :     {
     413            0 :         lce->x = -1;
     414              :     }
     415              : }
     416              : 
     417            0 : static void calcsurfaces(cube &c, const ivec &co, int size, int usefacemask, int preview = 0)
     418              : {
     419            0 :     std::array<surfaceinfo, 6> surfaces;
     420              :     vertinfo litverts[6*2*Face_MaxVerts];
     421            0 :     int numlitverts = 0;
     422            0 :     surfaces.fill(surfaceinfo());
     423            0 :     for(int i = 0; i < 6; ++i) //for each face of the cube
     424              :     {
     425            0 :         int usefaces = usefacemask&0xF;
     426            0 :         usefacemask >>= 4;
     427            0 :         if(!usefaces)
     428              :         {
     429            0 :             if(!c.ext)
     430              :             {
     431            0 :                 continue;
     432              :             }
     433            0 :             surfaceinfo &surf = c.ext->surfaces[i];
     434            0 :             int numverts = surf.totalverts();
     435            0 :             if(numverts)
     436              :             {
     437            0 :                 std::memcpy(&litverts[numlitverts], c.ext->verts() + surf.verts, numverts*sizeof(vertinfo));
     438            0 :                 surf.verts = numlitverts;
     439            0 :                 numlitverts += numverts;
     440              :             }
     441            0 :             continue;
     442            0 :         }
     443              : 
     444            0 :         VSlot &vslot = lookupvslot(c.texture[i], false),
     445            0 :              *layer = vslot.layer && !(c.material&Mat_Alpha) ? &lookupvslot(vslot.layer, false) : nullptr;
     446            0 :         Shader *shader = vslot.slot->shader;
     447            0 :         int shadertype = shader->type;
     448            0 :         if(layer)
     449              :         {
     450            0 :             shadertype |= layer->slot->shader->type;
     451              :         }
     452            0 :         surfaceinfo &surf = surfaces[i];
     453            0 :         vertinfo *curlitverts = &litverts[numlitverts];
     454            0 :         int numverts = c.ext ? c.ext->surfaces[i].numverts&Face_MaxVerts : 0;
     455            0 :         ivec mo(co);
     456            0 :         int msz = size,
     457            0 :             convex = 0;
     458            0 :         if(numverts)
     459              :         {
     460            0 :             const vertinfo *verts = c.ext->verts() + c.ext->surfaces[i].verts;
     461            0 :             for(int j = 0; j < numverts; ++j)
     462              :             {
     463            0 :                 curlitverts[j].set(verts[j].getxyz());
     464              :             }
     465            0 :             if(c.merged&(1<<i))
     466              :             {
     467            0 :                 msz = 1<<calcmergedsize(mo, size, verts, numverts);
     468            0 :                 mo.mask(~(msz-1));
     469            0 :                 if(!(surf.numverts&Face_MaxVerts))
     470              :                 {
     471            0 :                     surf.verts = numlitverts;
     472            0 :                     surf.numverts |= numverts;
     473            0 :                     numlitverts += numverts;
     474              :                 }
     475              :             }
     476            0 :             else if(!flataxisface(c, i))
     477              :             {
     478            0 :                 convex = faceconvexity(verts, numverts, size);
     479              :             }
     480              :         }
     481              :         else
     482              :         {
     483            0 :             std::array<ivec, 4> v;
     484            0 :             genfaceverts(c, i, v);
     485            0 :             if(!flataxisface(c, i))
     486              :             {
     487            0 :                 convex = faceconvexity(v);
     488              :             }
     489            0 :             int order = usefaces&4 || convex < 0 ? 1 : 0;
     490            0 :             ivec vo = ivec(co).mask(0xFFF).shl(3);
     491            0 :             curlitverts[numverts++].set(v[order].mul(size).add(vo));
     492            0 :             if(usefaces&1)
     493              :             {
     494            0 :                 curlitverts[numverts++].set(v[order+1].mul(size).add(vo));
     495              :             }
     496            0 :             curlitverts[numverts++].set(v[order+2].mul(size).add(vo));
     497            0 :             if(usefaces&2)
     498              :             {
     499            0 :                 curlitverts[numverts++].set(v[(order+3)&3].mul(size).add(vo));
     500              :             }
     501              :         }
     502              : 
     503            0 :         vec pos[Face_MaxVerts],
     504            0 :             n[Face_MaxVerts],
     505            0 :             po(ivec(co).mask(~0xFFF));
     506            0 :         for(int j = 0; j < numverts; ++j)
     507              :         {
     508            0 :             pos[j] = vec(curlitverts[j].getxyz()).mul(1.0f/8).add(po);
     509              :         }
     510              : 
     511            0 :         int smooth = vslot.slot->smooth;
     512            0 :         plane planes[2];
     513            0 :         int numplanes = 0;
     514            0 :         planes[numplanes++].toplane(pos[0], pos[1], pos[2]);
     515            0 :         if(numverts < 4 || !convex)
     516              :         {
     517            0 :             for(int k = 0; k < numverts; ++k)
     518              :             {
     519            0 :                 findnormal(pos[k], smooth, planes[0], n[k]);
     520              :             }
     521            0 :         }
     522              :         else
     523              :         {
     524            0 :             planes[numplanes++].toplane(pos[0], pos[2], pos[3]);
     525            0 :             vec avg = vec(planes[0]).add(planes[1]).normalize();
     526            0 :             findnormal(pos[0], smooth, avg, n[0]);
     527            0 :             findnormal(pos[1], smooth, planes[0], n[1]);
     528            0 :             findnormal(pos[2], smooth, avg, n[2]);
     529            0 :             for(int k = 3; k < numverts; k++)
     530              :             {
     531            0 :                 findnormal(pos[k], smooth, planes[1], n[k]);
     532              :             }
     533              :         }
     534            0 :         for(int k = 0; k < numverts; ++k)
     535              :         {
     536            0 :             curlitverts[k].norm = encodenormal(n[k]);
     537              :         }
     538            0 :         if(!(surf.numverts&Face_MaxVerts))
     539              :         {
     540            0 :             surf.verts = numlitverts;
     541            0 :             surf.numverts |= numverts;
     542            0 :             numlitverts += numverts;
     543              :         }
     544            0 :         if(preview)
     545              :         {
     546            0 :             surf.numverts |= preview;
     547            0 :             continue;
     548              :         }
     549            0 :         int surflayer = BlendLayer_Top;
     550            0 :         if(vslot.layer)
     551              :         {
     552            0 :             int x1 = curlitverts[numverts-1].x,
     553            0 :                 y1 = curlitverts[numverts-1].y,
     554            0 :                 x2 = x1,
     555            0 :                 y2 = y1;
     556            0 :             for(int j = 0; j < numverts-1; ++j)
     557              :             {
     558            0 :                 const vertinfo &v = curlitverts[j];
     559            0 :                 x1 = std::min(x1, static_cast<int>(v.x));
     560            0 :                 y1 = std::min(y1, static_cast<int>(v.y));
     561            0 :                 x2 = std::max(x2, static_cast<int>(v.x));
     562            0 :                 y2 = std::max(y2, static_cast<int>(v.y));
     563              :             }
     564            0 :             x2 = std::max(x2, x1+1);
     565            0 :             y2 = std::max(y2, y1+1);
     566            0 :             x1 = (x1>>3) + (co.x&~0xFFF);
     567            0 :             y1 = (y1>>3) + (co.y&~0xFFF);
     568            0 :             x2 = ((x2+7)>>3) + (co.x&~0xFFF);
     569            0 :             y2 = ((y2+7)>>3) + (co.y&~0xFFF);
     570              :         }
     571            0 :         surf.numverts |= surflayer;
     572              :     }
     573            0 :     if(preview)
     574              :     {
     575            0 :         setsurfaces(c, surfaces, litverts, numlitverts);
     576              :     }
     577              :     else
     578              :     {
     579            0 :         for(const surfaceinfo &surf : surfaces)
     580              :         {
     581            0 :             if(surf.used())
     582              :             {
     583            0 :                 cubeext *ext = c.ext && c.ext->maxverts >= numlitverts ? c.ext : growcubeext(c.ext, numlitverts);
     584            0 :                 std::memcpy(ext->surfaces.data(), surfaces.data(), sizeof(ext->surfaces));
     585            0 :                 std::memcpy(ext->verts(), litverts, numlitverts*sizeof(vertinfo));
     586            0 :                 if(c.ext != ext)
     587              :                 {
     588            0 :                     setcubeext(c, ext);
     589              :                 }
     590            0 :                 break;
     591              :             }
     592              :         }
     593              :     }
     594            0 : }
     595              : 
     596            0 : static void calcsurfaces(std::array<cube, 8> &c, const ivec &co, int size)
     597              : {
     598            0 :     for(int i = 0; i < 8; ++i)
     599              :     {
     600            0 :         ivec o(i, co, size);
     601            0 :         if(c[i].children)
     602              :         {
     603            0 :             calcsurfaces(*(c[i].children), o, size >> 1);
     604              :         }
     605            0 :         else if(!(c[i].isempty()))
     606              :         {
     607            0 :             if(c[i].ext)
     608              :             {
     609            0 :                 for(surfaceinfo &s : c[i].ext->surfaces)
     610              :                 {
     611            0 :                     s.clear();
     612              :                 }
     613              :             }
     614            0 :             int usefacemask = 0;
     615            0 :             for(int j = 0; j < 6; ++j)
     616              :             {
     617            0 :                 if(c[i].texture[j] != Default_Sky && (!(c[i].merged & (1 << j)) || (c[i].ext && c[i].ext->surfaces[j].numverts & Face_MaxVerts)))
     618              :                 {
     619            0 :                     usefacemask |= visibletris(c[i], j, o, size)<<(4*j);
     620              :                 }
     621              :             }
     622            0 :             if(usefacemask)
     623              :             {
     624            0 :                 calcsurfaces(c[i], o, size, usefacemask);
     625              :             }
     626              :         }
     627              :     }
     628            0 : }
     629              : 
     630            0 : void cubeworld::calclight()
     631              : {
     632            0 :     remip();
     633            0 :     clearsurfaces(*worldroot);
     634            0 :     calcnormals(filltjoints > 0);
     635            0 :     calcsurfaces(*worldroot, ivec(0, 0, 0), rootworld.mapsize() >> 1);
     636            0 :     clearnormals();
     637            0 :     allchanged();
     638            0 : }
     639              : 
     640              : VAR(fullbright, 0, 0, 1);           //toggles rendering at fullbrightlevel light
     641              : VAR(fullbrightlevel, 0, 160, 255);  //grayscale shade for lighting when at fullbright
     642              : 
     643            0 : void clearlights()
     644              : {
     645            0 :     clearlightcache();
     646            0 :     clearshadowcache();
     647            0 :     cleardeferredlightshaders();
     648            0 :     resetsmoothgroups();
     649            0 : }
     650              : 
     651            0 : void initlights()
     652              : {
     653            0 :     clearlightcache();
     654            0 :     clearshadowcache();
     655            0 :     loaddeferredlightshaders();
     656            0 : }
        

Generated by: LCOV version 2.0-1