Skip to content

Commit

Permalink
Refactor: Relocated more code from r_world.h to better homes
Browse files Browse the repository at this point in the history
  • Loading branch information
danij-deng committed May 8, 2013
1 parent fb2ccc3 commit 6aefce7
Show file tree
Hide file tree
Showing 16 changed files with 276 additions and 277 deletions.
3 changes: 3 additions & 0 deletions doomsday/client/include/def_data.h
Expand Up @@ -283,6 +283,9 @@ typedef struct ded_skymodel_s {
#define NUM_SKY_LAYERS 2
#define NUM_SKY_MODELS 32

// Sky flags.
#define SIF_DRAW_SPHERE 0x1 ///< Always draw the sky sphere.

typedef struct ded_sky_s {
ded_stringid_t id;
ded_flags_t flags; // Flags.
Expand Down
9 changes: 9 additions & 0 deletions doomsday/client/include/map/gamemap.h
Expand Up @@ -615,6 +615,15 @@ class GameMap
*/
void updateSurfacesOnMaterialChange(Material &material);

#ifdef __CLIENT__

/**
* @todo Replace with a de::Observers-based mechanism.
*/
void updateMissingMaterialsForLinesOfSector(Sector const &sec);

#endif // __CLIENT__

private:
DENG2_PRIVATE(d)
};
Expand Down
11 changes: 11 additions & 0 deletions doomsday/client/include/map/line.h
Expand Up @@ -829,6 +829,17 @@ class Line : public de::MapElement
*/
LineOwner *vertexOwner(int to) const;

/**
* Returns a pointer to the line owner for the specified edge @a vertex
* of the line. If the vertex is not an edge vertex for the line then
* @c 0 will be returned.
*/
inline LineOwner *vertexOwner(Vertex const &vertex) const {
if(&vertex == &from()) return v1Owner();
if(&vertex == &to()) return v2Owner();
return 0;
}

/**
* Returns a pointer to the line owner node for the From/Start vertex of the line.
*
Expand Down
23 changes: 0 additions & 23 deletions doomsday/client/include/map/r_world.h
Expand Up @@ -33,30 +33,7 @@
DENG2_DECLARE_AUDIENCE(MapChange, void currentMapChanged())
DENG2_EXTERN_AUDIENCE(MapChange)

extern float rendSkyLight; // cvar
extern byte rendSkyLightAuto; // cvar
extern float rendLightWallAngle;
extern byte rendLightWallAngleSmooth;
extern boolean ddMapSetup;
extern boolean firstFrameAfterLoad;

// Sky flags.
#define SIF_DRAW_SPHERE 0x1 ///< Always draw the sky sphere.

LineOwner *R_GetVtxLineOwner(Vertex const *vtx, Line const *line);

void R_UpdateSector(Sector &sector, bool forceUpdate = false);

/**
* @return @c > 0 if @a lightlevel passes the min max limit condition.
*/
float R_CheckSectorLight(float lightlevel, float min, float max);

#ifdef __CLIENT__

void R_UpdateMissingMaterialsForLinesOfSector(Sector const &sec);

#endif // __CLIENT__

/**
* Determine the map space Z coordinates of a wall section.
Expand Down
2 changes: 2 additions & 0 deletions doomsday/client/include/render/r_main.h
Expand Up @@ -67,6 +67,8 @@ DENG_EXTERN_C int validCount;
DENG_EXTERN_C int frameCount;
DENG_EXTERN_C int rendInfoTris;

DENG_EXTERN_C boolean firstFrameAfterLoad;

DENG_EXTERN_C byte precacheMapMaterials, precacheSprites, precacheSkins;

DENG_EXTERN_C fontid_t fontFixed, fontVariable[FONTSTYLE_COUNT];
Expand Down
4 changes: 4 additions & 0 deletions doomsday/client/include/render/rend_main.h
Expand Up @@ -51,6 +51,10 @@ DENG_EXTERN_C boolean usingFog;
DENG_EXTERN_C int rAmbient;
DENG_EXTERN_C float rendLightDistanceAttenuation;
DENG_EXTERN_C int rendLightAttenuateFixedColormap;
DENG_EXTERN_C float rendLightWallAngle;
DENG_EXTERN_C byte rendLightWallAngleSmooth;
DENG_EXTERN_C float rendSkyLight; // cvar
DENG_EXTERN_C byte rendSkyLightAuto; // cvar
DENG_EXTERN_C float lightModRange[255];
DENG_EXTERN_C int extraLight;
DENG_EXTERN_C float extraLightDelta;
Expand Down
184 changes: 184 additions & 0 deletions doomsday/client/src/map/gamemap.cpp
Expand Up @@ -1844,3 +1844,187 @@ void GameMap::updateSurfacesOnMaterialChange(Material &material)
}
#endif
}

#ifdef __CLIENT__

/**
* Given a side section, look at the neighbouring surfaces and pick the
* best choice of material used on those surfaces to be applied to "this"
* surface.
*
* Material on back neighbour plane has priority.
* Non-animated materials are preferred.
* Sky materials are ignored.
*/
static Material *chooseFixMaterial(Line::Side &side, int section)
{
Material *choice1 = 0, *choice2 = 0;

Sector *frontSec = side.sectorPtr();
Sector *backSec = side.back().hasSections()? side.back().sectorPtr() : 0;

if(backSec)
{
// Our first choice is a material in the other sector.
if(section == Line::Side::Bottom)
{
if(frontSec->floor().height() < backSec->floor().height())
{
choice1 = backSec->floorSurface().materialPtr();
}
}
else if(section == Line::Side::Top)
{
if(frontSec->ceiling().height() > backSec->ceiling().height())
{
choice1 = backSec->ceilingSurface().materialPtr();
}
}

// In the special case of sky mask on the back plane, our best
// choice is always this material.
if(choice1 && choice1->isSkyMasked())
{
return choice1;
}
}
else
{
// Our first choice is a material on an adjacent wall section.
// Try the left neighbor first.
Line *other = R_FindLineNeighbor(frontSec, &side.line(), side.line().vertexOwner(side.lineSideId()),
false /*next clockwise*/);
if(!other)
// Try the right neighbor.
other = R_FindLineNeighbor(frontSec, &side.line(), side.line().vertexOwner(side.lineSideId()^1),
true /*next anti-clockwise*/);

if(other)
{
if(!other->hasBackSections())
{
// Our choice is clear - the middle material.
choice1 = other->front().middle().materialPtr();
}
else
{
// Compare the relative heights to decide.
Line::Side &otherSide = other->side(&other->frontSector() == frontSec? Line::Front : Line::Back);
Sector &otherSec = other->sector(&other->frontSector() == frontSec? Line::Back : Line::Front);

if(otherSec.ceiling().height() <= frontSec->floor().height())
choice1 = otherSide.top().materialPtr();
else if(otherSec.floor().height() >= frontSec->ceiling().height())
choice1 = otherSide.bottom().materialPtr();
else if(otherSec.ceiling().height() < frontSec->ceiling().height())
choice1 = otherSide.top().materialPtr();
else if(otherSec.floor().height() > frontSec->floor().height())
choice1 = otherSide.bottom().materialPtr();
// else we'll settle for a plane material.
}
}
}

// Our second choice is a material from this sector.
choice2 = frontSec->planeSurface(section == Line::Side::Bottom? Plane::Floor : Plane::Ceiling).materialPtr();

// Prefer a non-animated, non-masked material.
if(choice1 && !choice1->isAnimated() && !choice1->isSkyMasked())
return choice1;
if(choice2 && !choice2->isAnimated() && !choice2->isSkyMasked())
return choice2;

// Prefer a non-masked material.
if(choice1 && !choice1->isSkyMasked())
return choice1;
if(choice2 && !choice2->isSkyMasked())
return choice2;

// At this point we'll accept anything if it means avoiding HOM.
if(choice1) return choice1;
if(choice2) return choice2;

// We'll assign the special "missing" material...
return &App_Materials().find(de::Uri("System", Path("missing"))).material();
}

static void addMissingMaterial(Line::Side &side, int section)
{
// Sides without sections need no fixing.
if(!side.hasSections()) return;
// ...nor those of self-referencing lines.
if(side.line().isSelfReferencing()) return;
// ...nor those of "one-way window" lines.
if(!side.back().hasSections() && side.back().hasSector()) return;

// A material must actually be missing to qualify for fixing.
Surface &surface = side.surface(section);
if(surface.hasMaterial()) return;

// Look for and apply a suitable replacement if found.
surface.setMaterial(chooseFixMaterial(side, section), true/* is missing fix */);

// During map load we log missing materials.
if(ddMapSetup && verbose)
{
String path = surface.hasMaterial()? surface.material().manifest().composeUri().asText() : "<null>";

LOG_WARNING("%s of Line #%d is missing a material for the %s section.\n"
" %s was chosen to complete the definition.")
<< (side.isBack()? "Back" : "Front") << side.line().indexInMap()
<< (section == Line::Side::Middle? "middle" : section == Line::Side::Top? "top" : "bottom")
<< path;
}
}

void GameMap::updateMissingMaterialsForLinesOfSector(Sector const &sec)
{
foreach(Line *line, sec.lines())
{
/**
* Do as in the original Doom if the texture has not been defined -
* extend the floor/ceiling to fill the space (unless it is skymasked),
* or if there is a midtexture use that instead.
*/
if(line->hasBackSector())
{
Sector const &frontSec = line->frontSector();
Sector const &backSec = line->backSector();

// A potential bottom section fix?
if(!(frontSec.floorSurface().hasSkyMaskedMaterial() &&
backSec.floorSurface().hasSkyMaskedMaterial()))
{
if(frontSec.floor().height() < backSec.floor().height())
{
addMissingMaterial(line->front(), Line::Side::Bottom);
}
else if(frontSec.floor().height() > backSec.floor().height())
{
addMissingMaterial(line->back(), Line::Side::Bottom);
}
}

// A potential top section fix?
if(!(frontSec.ceilingSurface().hasSkyMaskedMaterial() &&
backSec.ceilingSurface().hasSkyMaskedMaterial()))
{
if(backSec.ceiling().height() < frontSec.ceiling().height())
{
addMissingMaterial(line->front(), Line::Side::Top);
}
else if(backSec.ceiling().height() > frontSec.ceiling().height())
{
addMissingMaterial(line->back(), Line::Side::Top);
}
}
}
else
{
// A potential middle section fix.
addMissingMaterial(line->front(), Line::Side::Middle);
}
}
}

#endif // __CLIENT__
34 changes: 31 additions & 3 deletions doomsday/client/src/map/p_dmu.cpp
Expand Up @@ -30,9 +30,14 @@
#include "de_base.h"
#include "de_play.h"
#include "de_audio.h"
#include "Materials"

#include "Materials"
#include "api_map.h"

#ifdef __CLIENT__
# include "render/r_lgrid.h"
#endif

#include "map/p_dmu.h"

using namespace de;
Expand Down Expand Up @@ -818,6 +823,29 @@ void DMU_SetValue(valuetype_t valueType, void *dst, setargs_t const *args,
}
}

static void updateSector(Sector &sector, bool forceUpdate = false)
{
#ifdef __CLIENT__
// Check if there are any lightlevel or color changes.
if(forceUpdate ||
(sector._lightLevel != sector._oldLightLevel ||
sector._lightColor[0] != sector._oldLightColor[0] ||
sector._lightColor[1] != sector._oldLightColor[1] ||
sector._lightColor[2] != sector._oldLightColor[2]))
{
sector._frameFlags |= SIF_LIGHT_CHANGED;
sector._oldLightLevel = sector._lightLevel;
sector._oldLightColor = sector._lightColor;

LG_SectorChanged(&sector);
}
else
{
sector._frameFlags &= ~SIF_LIGHT_CHANGED;
}
#endif
}

/**
* Only those properties that are writable by outside parties (such as games)
* are included here. Attempting to set a non-writable property causes a
Expand Down Expand Up @@ -961,10 +989,10 @@ static void setProperty(MapElement *elem, setargs_t &args)
updateSector1 = &updatePlane->sector();

if(updateSector1)
R_UpdateSector(*updateSector1);
updateSector(*updateSector1);

if(updateSector2)
R_UpdateSector(*updateSector2);
updateSector(*updateSector2);
}

void DMU_GetValue(valuetype_t valueType, void const *src, setargs_t *args, uint index)
Expand Down

0 comments on commit 6aefce7

Please sign in to comment.