LCOV - code coverage report
Current view: top level - engine/world - light.cpp (source / functions) Hit Total Coverage
Test: Libprimis Test Coverage Lines: 23 358 6.4 %
Date: 2024-11-22 05:07:59 Functions: 1 21 4.8 %

          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(i, 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 1.14