Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
World|Sector: Extend dynamic plane mapping to those with sky-masked m…
…aterials

With the plane mapping algorithm now finalized and the map renderer
updated accordingly we can extend support to planes with a sky-masked
material, also.

Back to Saturn X: Episode 1 uses such constructs frequently.
  • Loading branch information
danij-deng committed Sep 22, 2013
1 parent a38943b commit 90eff11
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 103 deletions.
8 changes: 8 additions & 0 deletions doomsday/client/include/render/rend_main.h
Expand Up @@ -28,6 +28,8 @@

#include "dd_types.h"

#include "Sector"

#include "MaterialVariantSpec"
#include "WallEdge"

Expand Down Expand Up @@ -156,6 +158,12 @@ void Rend_DrawLightModMatrix();
/**
* Sector light color may be affected by the sky light color.
*/
de::Vector3f const &Rend_SectorLightColor(SectorCluster const &cluster);

/**
* @copydoc Rend_SectorLightColor()
* @deprecated Caller should work at cluster level.
*/
de::Vector3f const &Rend_SectorLightColor(Sector const &sector);

/**
Expand Down
14 changes: 0 additions & 14 deletions doomsday/client/include/world/bspleaf.h
Expand Up @@ -361,20 +361,6 @@ class BspLeaf : public de::MapElement

#ifdef __CLIENT__

/**
* Determines whether the BSP leaf has a positive world volume. For this
* to be true the following criteria must be met:
*
* - The polygon geometry is @em not degenerate (see @ref isDegenerate()).
* - A sector is attributed (see @ref hasSector())
* - The height of floor is lower than that of the ceiling plane for the
* attributed sector.
*
* @param useSmoothedHeights @c true= use the @em smoothed plane heights
* instead of the @em sharp heights.
*/
bool hasWorldVolume(bool useSmoothedHeights = true) const;

/**
* Returns a pointer to the face geometry half-edge which has been chosen
* for use as the base for a triangle fan GL primitive. May return @c 0 if
Expand Down
25 changes: 17 additions & 8 deletions doomsday/client/include/world/sector.h
Expand Up @@ -154,6 +154,14 @@ class Sector : public de::MapElement
*/
void markVisPlanesDirty();

/**
* Returns @c true iff at least one of the mapped visual planes of the
* cluster presently has a sky-masked material bound.
*
* @see Surface::hasSkyMaskedMaterial()
*/
bool hasSkyMaskedPlane() const;

/**
* Provides access to the list of all BSP leafs in the cluster, for
* efficient traversal.
Expand All @@ -180,6 +188,15 @@ class Sector : public de::MapElement

#ifdef __CLIENT__

/**
* Determines whether the cluster has a positive world volume, i.e., the
* height of floor is lower than that of the ceiling plane.
*
* @param useSmoothedHeights @c true= use the @em smoothed plane heights
* instead of the @em sharp heights.
*/
bool hasWorldVolume(bool useSmoothedHeights = true) const;

/**
* Returns a rough approximation of the total combined area of the geometry
* for all BSP leafs which define the cluster (map units squared).
Expand Down Expand Up @@ -284,14 +301,6 @@ class Sector : public de::MapElement
*/
inline int planeCount() const { return planes().count(); }

/**
* Returns @c true iff at least one of the surfaces of a plane in/owned
* by the sector presently has a sky-masked material bound.
*
* @see Surface::hasSkyMaskedMaterial()
*/
bool hasSkyMaskedPlane() const;

/**
* Convenient accessor method for returning the surface of the specified
* plane of the sector.
Expand Down
3 changes: 2 additions & 1 deletion doomsday/client/src/render/lightgrid.cpp
Expand Up @@ -923,7 +923,8 @@ void LightGrid::update()
continue;

// Determine the ambient light properties of the sector at this block.
Sector &sector = block.sector();
/// @todo fixme: Should work with sector clusters instead.
Sector &sector = block.sector();
Vector3f const &color = Rend_SectorLightColor(sector);
float const level = sector.lightLevel();
int const bias = biasForSector(sector);
Expand Down
9 changes: 5 additions & 4 deletions doomsday/client/src/render/r_things.cpp
Expand Up @@ -60,10 +60,10 @@ static void evaluateLighting(Vector3d const &origin, BspLeaf *bspLeafAtOrigin,
}
else
{
Sector const &sec = bspLeafAtOrigin->sector();
Vector3f const &secColor = Rend_SectorLightColor(sec);
SectorCluster const &cluster = bspLeafAtOrigin->cluster();
Vector3f const &secColor = Rend_SectorLightColor(cluster);

float lightLevel = sec.lightLevel();
float lightLevel = cluster.sector().lightLevel();
/* if(spr->type == VSPR_DECORATION)
{
// Wall decorations receive an additional light delta.
Expand Down Expand Up @@ -186,7 +186,8 @@ void R_ProjectSprite(mobj_t *mo)
float const alpha = Mobj_Alpha(mo);
if(alpha <= 0) return;
// ...origin lies in a sector with no volume?
if(!mo->bspLeaf->hasWorldVolume()) return;
if(!mo->bspLeaf->hasCluster()) return;
if(!mo->bspLeaf->cluster().hasWorldVolume()) return;

// Determine distance to object.
Vector3d const moPos = mobjOriginSmoothed(mo);
Expand Down
6 changes: 4 additions & 2 deletions doomsday/client/src/render/rend_fakeradio.cpp
Expand Up @@ -1262,8 +1262,10 @@ static void writeShadowSection(int planeIndex, LineSide &side, float shadowDark)
// If the sector containing the shadowing line section is fully closed (i.e., volume
// is not positive) then skip shadow drawing entirely.
/// @todo Encapsulate this logic in ShadowEdge -ds
if(!leftHEdge->hasFace() ||
!leftHEdge->face().mapElement()->as<BspLeaf>().hasWorldVolume())
if(!leftHEdge->hasFace()) return;

BspLeaf &frontLeaf = leftHEdge->face().mapElement()->as<BspLeaf>();
if(!frontLeaf.hasCluster() || !frontLeaf.cluster().hasWorldVolume())
return;

ShadowEdge leftEdge(*leftHEdge, Line::From);
Expand Down
63 changes: 54 additions & 9 deletions doomsday/client/src/render/rend_main.cpp
Expand Up @@ -329,7 +329,7 @@ static void reportWallSectionDrawn(Line &line)

static inline bool isNullLeaf(BspLeaf const *leaf)
{
return !leaf || !leaf->hasWorldVolume();
return !leaf || !leaf->hasCluster() || !leaf->cluster().hasWorldVolume();
}

void Rend_Init()
Expand Down Expand Up @@ -483,13 +483,58 @@ float Rend_ShadowAttenuationFactor(coord_t distance)
return 1;
}

Vector3f const &Rend_SectorLightColor(Sector const &sector)
static Vector3f skyLightColor;
static Vector3f oldSkyAmbientColor(-1.f, -1.f, -1.f);
static float oldRendSkyLight = -1;

Vector3f const &Rend_SectorLightColor(SectorCluster const &cluster)
{
static Vector3f skyLightColor;
static Vector3f oldSkyAmbientColor(-1.f, -1.f, -1.f);
static float oldRendSkyLight = -1;
if(rendSkyLight > .001f && cluster.hasSkyMaskedPlane())
{
ColorRawf const *ambientColor = Sky_AmbientColor();

if(rendSkyLight != oldRendSkyLight ||
!INRANGE_OF(ambientColor->red, oldSkyAmbientColor.x, .001f) ||
!INRANGE_OF(ambientColor->green, oldSkyAmbientColor.y, .001f) ||
!INRANGE_OF(ambientColor->blue, oldSkyAmbientColor.z, .001f))
{
skyLightColor = Vector3f(ambientColor->rgb);
R_AmplifyColor(skyLightColor);

// Apply the intensity factor cvar.
for(int i = 0; i < 3; ++i)
{
skyLightColor[i] = skyLightColor[i] + (1 - rendSkyLight) * (1.f - skyLightColor[i]);
}

if(rendSkyLight > .001f && sector.hasSkyMaskedPlane())
// When the sky light color changes we must update the light grid.
markLightGridForFullUpdate();
oldSkyAmbientColor = Vector3f(ambientColor->rgb);
}

oldRendSkyLight = rendSkyLight;
return skyLightColor;
}

// A non-skylight sector (i.e., everything else!)
// Return the sector's ambient light color.
return cluster.sector().lightColor();
}

static bool sectorHasSkyMaskedPlane(Sector const &sector)
{
foreach(Plane *plane, sector.planes())
{
if(plane->surface().hasSkyMaskedMaterial())
return true;
}
return false;
}

/// @todo refactor away.
Vector3f const &Rend_SectorLightColor(Sector const &sector)
{
if(rendSkyLight > .001f && sectorHasSkyMaskedPlane(sector))
{
ColorRawf const *ambientColor = Sky_AmbientColor();

Expand Down Expand Up @@ -1609,7 +1654,7 @@ static void writeWallSection(HEdge &hedge, int section,
if(twoSidedMiddle && side.sectorPtr() != leaf->sectorPtr())
{
// Undo temporary draw state changes.
currentSectorLightColor = Rend_SectorLightColor(leaf->sector());
currentSectorLightColor = Rend_SectorLightColor(leaf->cluster());
currentSectorLightLevel = leaf->sector().lightLevel();
}

Expand Down Expand Up @@ -1811,7 +1856,7 @@ static void writeLeafPlane(Plane &plane)
if(&plane.sector() != leaf->sectorPtr())
{
// Undo temporary draw state changes.
currentSectorLightColor = Rend_SectorLightColor(leaf->sector());
currentSectorLightColor = Rend_SectorLightColor(leaf->cluster());
currentSectorLightLevel = leaf->sector().lightLevel();
}

Expand Down Expand Up @@ -2529,7 +2574,7 @@ static void makeCurrent(BspLeaf *bspLeaf)
// Update draw state.
if(sectorChanged)
{
currentSectorLightColor = Rend_SectorLightColor(bspLeaf->sector());
currentSectorLightColor = Rend_SectorLightColor(bspLeaf->cluster());
currentSectorLightLevel = bspLeaf->sector().lightLevel();
}
}
Expand Down
6 changes: 3 additions & 3 deletions doomsday/client/src/render/rend_particle.cpp
Expand Up @@ -471,9 +471,9 @@ static void setupModelParamsForParticle(rendmodelparams_t* params,
}
else
{
Sector &sector = pt->bspLeaf->sector();
float lightLevel = sector.lightLevel();
Vector3f const &secColor = Rend_SectorLightColor(sector);
SectorCluster &cluster = pt->bspLeaf->cluster();
float lightLevel = cluster.sector().lightLevel();
Vector3f const &secColor = Rend_SectorLightColor(cluster);

// Apply distance attenuation.
lightLevel = Rend_AttenuateLightLevel(params->distance, lightLevel);
Expand Down
12 changes: 6 additions & 6 deletions doomsday/client/src/render/sprite.cpp
Expand Up @@ -324,11 +324,11 @@ static void setupPSpriteParams(rendpspriteparams_t *params, vispsprite_t *spr)
}
else
{
Sector &sector = spr->data.sprite.bspLeaf->sector();
Vector3f const &secColor = Rend_SectorLightColor(sector);
SectorCluster &cluster = spr->data.sprite.bspLeaf->cluster();
Vector3f const &secColor = Rend_SectorLightColor(cluster);

// No need for distance attentuation.
float lightLevel = sector.lightLevel();
float lightLevel = cluster.sector().lightLevel();

// Add extra light plus bonus.
lightLevel += Rend_ExtraLightDelta();
Expand Down Expand Up @@ -711,11 +711,11 @@ static void setupModelParamsForVisPSprite(rendmodelparams_t *params, vispsprite_
}
else
{
Sector &sector = spr->data.model.bspLeaf->sector();
Vector3f const &secColor = Rend_SectorLightColor(sector);
SectorCluster &cluster = spr->data.model.bspLeaf->cluster();
Vector3f const &secColor = Rend_SectorLightColor(cluster);

// Diminished light (with compression).
float lightLevel = sector.lightLevel();
float lightLevel = cluster.sector().lightLevel();

// No need for distance attentuation.

Expand Down
14 changes: 0 additions & 14 deletions doomsday/client/src/world/bspleaf.cpp
Expand Up @@ -424,20 +424,6 @@ bool BspLeaf::polyContains(Vector2d const &point) const

#ifdef __CLIENT__

bool BspLeaf::hasWorldVolume(bool useSmoothedHeights) const
{
if(!hasCluster()) return false;

if(useSmoothedHeights)
{
return visCeilingHeightSmoothed() - visFloorHeightSmoothed() > 0;
}
else
{
return ceilingHeight() - floorHeight() > 0;
}
}

HEdge *BspLeaf::fanBase() const
{
if(d->needUpdateFanBase)
Expand Down
10 changes: 0 additions & 10 deletions doomsday/client/src/world/sector.cpp
Expand Up @@ -396,16 +396,6 @@ Sector::Planes const &Sector::planes() const
return d->planes;
}

bool Sector::hasSkyMaskedPlane() const
{
foreach(Plane *plane, d->planes)
{
if(plane->surface().hasSkyMaskedMaterial())
return true;
}
return false;
}

Sector::Clusters const &Sector::clusters() const
{
return d->clusters;
Expand Down

0 comments on commit 90eff11

Please sign in to comment.