in doom_py/src/vizdoom/src/r_bsp.cpp [1013:1363]
void R_Subsector (subsector_t *sub)
{
int count;
seg_t* line;
sector_t tempsec; // killough 3/7/98: deep water hack
int floorlightlevel; // killough 3/16/98: set floor lightlevel
int ceilinglightlevel; // killough 4/11/98
bool outersubsector;
int fll, cll, position;
ASkyViewpoint *skybox;
// kg3D - fake floor stuff
visplane_t *backupfp;
visplane_t *backupcp;
//secplane_t templane;
lightlist_t *light;
if (InSubsector != NULL)
{ // InSubsector is not NULL. This means we are rendering from a mini-BSP.
outersubsector = false;
}
else
{
outersubsector = true;
InSubsector = sub;
}
#ifdef RANGECHECK
if (outersubsector && sub - subsectors >= (ptrdiff_t)numsubsectors)
I_Error ("R_Subsector: ss %ti with numss = %i", sub - subsectors, numsubsectors);
#endif
assert(sub->sector != NULL);
if (sub->polys)
{ // Render the polyobjs in the subsector first
R_AddPolyobjs(sub);
if (outersubsector)
{
InSubsector = NULL;
}
return;
}
frontsector = sub->sector;
frontsector->MoreFlags |= SECF_DRAWN;
count = sub->numlines;
line = sub->firstline;
// killough 3/8/98, 4/4/98: Deep water / fake ceiling effect
frontsector = R_FakeFlat(frontsector, &tempsec, &floorlightlevel,
&ceilinglightlevel, false); // killough 4/11/98
fll = floorlightlevel;
cll = ceilinglightlevel;
// [RH] set foggy flag
foggy = level.fadeto || frontsector->ColorMap->Fade || (level.flags & LEVEL_HASFADETABLE);
r_actualextralight = foggy ? 0 : extralight << 4;
// kg3D - fake lights
if (fixedlightlev < 0 && frontsector->e && frontsector->e->XFloor.lightlist.Size())
{
light = P_GetPlaneLight(frontsector, &frontsector->ceilingplane, false);
basecolormap = light->extra_colormap;
// If this is the real ceiling, don't discard plane lighting R_FakeFlat()
// accounted for.
if (light->p_lightlevel != &frontsector->lightlevel)
{
ceilinglightlevel = *light->p_lightlevel;
}
}
else
{
basecolormap = frontsector->ColorMap;
}
skybox = frontsector->GetSkyBox(sector_t::ceiling);
ceilingplane = frontsector->ceilingplane.PointOnSide(viewx, viewy, viewz) > 0 ||
frontsector->GetTexture(sector_t::ceiling) == skyflatnum ||
(skybox != NULL && skybox->bAlways) ||
(frontsector->heightsec &&
!(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) &&
frontsector->heightsec->GetTexture(sector_t::floor) == skyflatnum) ?
R_FindPlane(frontsector->ceilingplane, // killough 3/8/98
frontsector->GetTexture(sector_t::ceiling),
ceilinglightlevel + r_actualextralight, // killough 4/11/98
frontsector->GetAlpha(sector_t::ceiling),
!!(frontsector->GetFlags(sector_t::ceiling) & PLANEF_ADDITIVE),
frontsector->GetXOffset(sector_t::ceiling), // killough 3/7/98
frontsector->GetYOffset(sector_t::ceiling), // killough 3/7/98
frontsector->GetXScale(sector_t::ceiling),
frontsector->GetYScale(sector_t::ceiling),
frontsector->GetAngle(sector_t::ceiling),
frontsector->sky,
skybox
) : NULL;
if (fixedlightlev < 0 && frontsector->e && frontsector->e->XFloor.lightlist.Size())
{
light = P_GetPlaneLight(frontsector, &frontsector->floorplane, false);
basecolormap = light->extra_colormap;
// If this is the real floor, don't discard plane lighting R_FakeFlat()
// accounted for.
if (light->p_lightlevel != &frontsector->lightlevel)
{
floorlightlevel = *light->p_lightlevel;
}
}
else
{
basecolormap = frontsector->ColorMap;
}
// killough 3/7/98: Add (x,y) offsets to flats, add deep water check
// killough 3/16/98: add floorlightlevel
// killough 10/98: add support for skies transferred from sidedefs
skybox = frontsector->GetSkyBox(sector_t::floor);
floorplane = frontsector->floorplane.PointOnSide(viewx, viewy, viewz) > 0 || // killough 3/7/98
frontsector->GetTexture(sector_t::floor) == skyflatnum ||
(skybox != NULL && skybox->bAlways) ||
(frontsector->heightsec &&
!(frontsector->heightsec->MoreFlags & SECF_IGNOREHEIGHTSEC) &&
frontsector->heightsec->GetTexture(sector_t::ceiling) == skyflatnum) ?
R_FindPlane(frontsector->floorplane,
frontsector->GetTexture(sector_t::floor),
floorlightlevel + r_actualextralight, // killough 3/16/98
frontsector->GetAlpha(sector_t::floor),
!!(frontsector->GetFlags(sector_t::floor) & PLANEF_ADDITIVE),
frontsector->GetXOffset(sector_t::floor), // killough 3/7/98
frontsector->GetYOffset(sector_t::floor), // killough 3/7/98
frontsector->GetXScale(sector_t::floor),
frontsector->GetYScale(sector_t::floor),
frontsector->GetAngle(sector_t::floor),
frontsector->sky,
skybox
) : NULL;
// kg3D - fake planes rendering
if (r_3dfloors && frontsector->e && frontsector->e->XFloor.ffloors.Size())
{
backupfp = floorplane;
backupcp = ceilingplane;
// first check all floors
for (int i = 0; i < (int)frontsector->e->XFloor.ffloors.Size(); i++)
{
fakeFloor = frontsector->e->XFloor.ffloors[i];
if (!(fakeFloor->flags & FF_EXISTS)) continue;
if (!fakeFloor->model) continue;
if (fakeFloor->bottom.plane->a || fakeFloor->bottom.plane->b) continue;
if (!(fakeFloor->flags & FF_NOSHADE) || (fakeFloor->flags & (FF_RENDERPLANES|FF_RENDERSIDES)))
{
R_3D_AddHeight(fakeFloor->top.plane, frontsector);
}
if (!(fakeFloor->flags & FF_RENDERPLANES)) continue;
if (fakeFloor->alpha == 0) continue;
if (fakeFloor->flags & FF_THISINSIDE && fakeFloor->flags & FF_INVERTSECTOR) continue;
fakeAlpha = MIN(Scale(fakeFloor->alpha, OPAQUE, 255), OPAQUE);
if (fakeFloor->validcount != validcount)
{
fakeFloor->validcount = validcount;
R_3D_NewClip();
}
fakeHeight = fakeFloor->top.plane->ZatPoint(frontsector->soundorg[0], frontsector->soundorg[0]);
if (fakeHeight < viewz &&
fakeHeight > frontsector->floorplane.ZatPoint(frontsector->soundorg[0], frontsector->soundorg[1]))
{
fake3D = FAKE3D_FAKEFLOOR;
tempsec = *fakeFloor->model;
tempsec.floorplane = *fakeFloor->top.plane;
tempsec.ceilingplane = *fakeFloor->bottom.plane;
if (!(fakeFloor->flags & FF_THISINSIDE) && !(fakeFloor->flags & FF_INVERTSECTOR))
{
tempsec.SetTexture(sector_t::floor, tempsec.GetTexture(sector_t::ceiling));
position = sector_t::ceiling;
} else position = sector_t::floor;
frontsector = &tempsec;
if (fixedlightlev < 0 && sub->sector->e->XFloor.lightlist.Size())
{
light = P_GetPlaneLight(sub->sector, &frontsector->floorplane, false);
basecolormap = light->extra_colormap;
floorlightlevel = *light->p_lightlevel;
}
ceilingplane = NULL;
floorplane = R_FindPlane(frontsector->floorplane,
frontsector->GetTexture(sector_t::floor),
floorlightlevel + r_actualextralight, // killough 3/16/98
frontsector->GetAlpha(sector_t::floor),
!!(fakeFloor->flags & FF_ADDITIVETRANS),
frontsector->GetXOffset(position), // killough 3/7/98
frontsector->GetYOffset(position), // killough 3/7/98
frontsector->GetXScale(position),
frontsector->GetYScale(position),
frontsector->GetAngle(position),
frontsector->sky,
NULL);
R_FakeDrawLoop(sub);
fake3D = 0;
frontsector = sub->sector;
}
}
// and now ceilings
for (unsigned int i = 0; i < frontsector->e->XFloor.ffloors.Size(); i++)
{
fakeFloor = frontsector->e->XFloor.ffloors[i];
if (!(fakeFloor->flags & FF_EXISTS)) continue;
if (!fakeFloor->model) continue;
if (fakeFloor->top.plane->a || fakeFloor->top.plane->b) continue;
if (!(fakeFloor->flags & FF_NOSHADE) || (fakeFloor->flags & (FF_RENDERPLANES|FF_RENDERSIDES)))
{
R_3D_AddHeight(fakeFloor->bottom.plane, frontsector);
}
if (!(fakeFloor->flags & FF_RENDERPLANES)) continue;
if (fakeFloor->alpha == 0) continue;
if (!(fakeFloor->flags & FF_THISINSIDE) && (fakeFloor->flags & (FF_SWIMMABLE|FF_INVERTSECTOR)) == (FF_SWIMMABLE|FF_INVERTSECTOR)) continue;
fakeAlpha = MIN(Scale(fakeFloor->alpha, OPAQUE, 255), OPAQUE);
if (fakeFloor->validcount != validcount)
{
fakeFloor->validcount = validcount;
R_3D_NewClip();
}
fakeHeight = fakeFloor->bottom.plane->ZatPoint(frontsector->soundorg[0], frontsector->soundorg[1]);
if (fakeHeight > viewz &&
fakeHeight < frontsector->ceilingplane.ZatPoint(frontsector->soundorg[0], frontsector->soundorg[1]))
{
fake3D = FAKE3D_FAKECEILING;
tempsec = *fakeFloor->model;
tempsec.floorplane = *fakeFloor->top.plane;
tempsec.ceilingplane = *fakeFloor->bottom.plane;
if ((!(fakeFloor->flags & FF_THISINSIDE) && !(fakeFloor->flags & FF_INVERTSECTOR)) ||
(fakeFloor->flags & FF_THISINSIDE && fakeFloor->flags & FF_INVERTSECTOR))
{
tempsec.SetTexture(sector_t::ceiling, tempsec.GetTexture(sector_t::floor));
position = sector_t::floor;
} else position = sector_t::ceiling;
frontsector = &tempsec;
tempsec.ceilingplane.ChangeHeight(-1);
if (fixedlightlev < 0 && sub->sector->e->XFloor.lightlist.Size())
{
light = P_GetPlaneLight(sub->sector, &frontsector->ceilingplane, false);
basecolormap = light->extra_colormap;
ceilinglightlevel = *light->p_lightlevel;
}
tempsec.ceilingplane.ChangeHeight(1);
floorplane = NULL;
ceilingplane = R_FindPlane(frontsector->ceilingplane, // killough 3/8/98
frontsector->GetTexture(sector_t::ceiling),
ceilinglightlevel + r_actualextralight, // killough 4/11/98
frontsector->GetAlpha(sector_t::ceiling),
!!(fakeFloor->flags & FF_ADDITIVETRANS),
frontsector->GetXOffset(position), // killough 3/7/98
frontsector->GetYOffset(position), // killough 3/7/98
frontsector->GetXScale(position),
frontsector->GetYScale(position),
frontsector->GetAngle(position),
frontsector->sky,
NULL);
R_FakeDrawLoop(sub);
fake3D = 0;
frontsector = sub->sector;
}
}
fakeFloor = NULL;
floorplane = backupfp;
ceilingplane = backupcp;
}
basecolormap = frontsector->ColorMap;
floorlightlevel = fll;
ceilinglightlevel = cll;
// killough 9/18/98: Fix underwater slowdown, by passing real sector
// instead of fake one. Improve sprite lighting by basing sprite
// lightlevels on floor & ceiling lightlevels in the surrounding area.
// [RH] Handle sprite lighting like Duke 3D: If the ceiling is a sky, sprites are lit by
// it, otherwise they are lit by the floor.
R_AddSprites (sub->sector, frontsector->GetTexture(sector_t::ceiling) == skyflatnum ?
ceilinglightlevel : floorlightlevel, FakeSide);
// [RH] Add particles
if ((unsigned int)(sub - subsectors) < (unsigned int)numsubsectors)
{ // Only do it for the main BSP.
int shade = LIGHT2SHADE((floorlightlevel + ceilinglightlevel)/2 + r_actualextralight);
for (WORD i = ParticlesInSubsec[(unsigned int)(sub-subsectors)]; i != NO_PARTICLE; i = Particles[i].snext)
{
R_ProjectParticle (Particles + i, subsectors[sub-subsectors].sector, shade, FakeSide);
}
}
count = sub->numlines;
line = sub->firstline;
while (count--)
{
if (!outersubsector || line->sidedef == NULL || !(line->sidedef->Flags & WALLF_POLYOBJ))
{
// kg3D - fake planes bounding calculation
if (r_3dfloors && line->backsector && frontsector->e && line->backsector->e->XFloor.ffloors.Size())
{
backupfp = floorplane;
backupcp = ceilingplane;
floorplane = NULL;
ceilingplane = NULL;
for (unsigned int i = 0; i < line->backsector->e->XFloor.ffloors.Size(); i++)
{
fakeFloor = line->backsector->e->XFloor.ffloors[i];
if (!(fakeFloor->flags & FF_EXISTS)) continue;
if (!(fakeFloor->flags & FF_RENDERPLANES)) continue;
if (!fakeFloor->model) continue;
fake3D = FAKE3D_FAKEBACK;
tempsec = *fakeFloor->model;
tempsec.floorplane = *fakeFloor->top.plane;
tempsec.ceilingplane = *fakeFloor->bottom.plane;
backsector = &tempsec;
if (fakeFloor->validcount != validcount)
{
fakeFloor->validcount = validcount;
R_3D_NewClip();
}
if (frontsector->CenterFloor() >= backsector->CenterFloor())
{
fake3D |= FAKE3D_CLIPBOTFRONT;
}
if (frontsector->CenterCeiling() <= backsector->CenterCeiling())
{
fake3D |= FAKE3D_CLIPTOPFRONT;
}
R_AddLine(line); // fake
}
fakeFloor = NULL;
fake3D = 0;
floorplane = backupfp;
ceilingplane = backupcp;
}
R_AddLine (line); // now real
}
line++;
}
if (outersubsector)
{
InSubsector = NULL;
}
}