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

Generated by: LCOV version 2.0-1