Skip to content

Commit

Permalink
Refactor|Surface: Ensure Surface's owner link is never invalidated
Browse files Browse the repository at this point in the history
  • Loading branch information
danij-deng committed Mar 15, 2013
1 parent 4cca36a commit cb7151e
Show file tree
Hide file tree
Showing 19 changed files with 432 additions and 254 deletions.
12 changes: 6 additions & 6 deletions doomsday/client/include/map/gamemap.h
Expand Up @@ -301,24 +301,24 @@ SideDef* GameMap_SideDef(GameMap* map, uint idx);
Sector* GameMap_Sector(GameMap* map, uint idx);

/**
* Lookup a Sector in the map by origin.
* Lookup a Sector in the map by it's sound emitter.
*
* @param map GameMap instance.
* @param ddMobjBase ddmobj_base_t to search for.
* @param soundEmitter ddmobj_base_t to search for.
*
* @return Found Sector instance else @c NULL.
*/
Sector* GameMap_SectorByBase(GameMap* map, const void* ddMobjBase);
Sector *GameMap_SectorBySoundEmitter(GameMap *map, void const *soundEmitter);

/**
* Lookup a Surface in the map by origin.
* Lookup a Surface in the map by it's sound emitter.
*
* @param map GameMap instance.
* @param ddMobjBase ddmobj_base_t to search for.
* @param soundEmitter ddmobj_base_t to search for.
*
* @return Found Surface instance else @c NULL.
*/
Surface* GameMap_SurfaceByBase(GameMap* map, const void* ddMobjBase);
Surface *GameMap_SurfaceBySoundEmitter(GameMap* map, void const *soundEmitter);

/**
* Lookup a BspLeaf by its unique index.
Expand Down
2 changes: 1 addition & 1 deletion doomsday/client/include/map/plane.h
Expand Up @@ -71,8 +71,8 @@ class Plane : public de::MapElement
};

public: /// @todo Make private:
Sector *_sector; ///< Owner of the plane.
Surface _surface;
Sector *_sector; ///< Owner of the plane.
coord_t _height; ///< Current height.
coord_t _oldHeight[2];
coord_t _targetHeight; ///< Target height.
Expand Down
48 changes: 45 additions & 3 deletions doomsday/client/include/map/sidedef.h
Expand Up @@ -30,11 +30,11 @@
class LineDef;

/*
* Helper macros for accessing sidedef top/middle/bottom section data elements:
* Helper macros for accessing sidedef surface data elements:
*/
/// @addtogroup map
///@{
#define SW_surface(n) sections[(n)]
#define SW_surface(n) surface(n)
#define SW_surfaceflags(n) SW_surface(n).flags
#define SW_surfaceinflags(n) SW_surface(n).inFlags
#define SW_surfacematerial(n) SW_surface(n).material
Expand Down Expand Up @@ -126,14 +126,19 @@ struct msidedef_t
class SideDef : public de::MapElement
{
public:
/// The given surface section reference is invalid. @ingroup errors
DENG2_ERROR(InvalidSectionError);

/// The referenced property does not exist. @ingroup errors
DENG2_ERROR(UnknownPropertyError);

/// The referenced property is not writeable. @ingroup errors
DENG2_ERROR(WritePropertyError);

public:
Surface sections[3];
Surface _middleSurface;
Surface _bottomSurface;
Surface _topSurface;

LineDef *line;

Expand All @@ -157,6 +162,43 @@ class SideDef : public de::MapElement
SideDef();
~SideDef();

/// @todo Refactor away.
SideDef &operator = (SideDef const &other);

/**
* Returns the specified surface of the sidedef.
*
* @param surface Identifier of the surface to return.
*/
Surface &surface(int surface);

/// @copydoc section()
Surface const &surface(int surface) const;

/**
* Returns the middle surface of the sidedef.
*/
inline Surface &middle() { return surface(SS_MIDDLE); }

/// @copydoc middle()
inline Surface const &middle() const { return surface(SS_MIDDLE); }

/**
* Returns the bottom surface of the sidedef.
*/
inline Surface &bottom() { return surface(SS_BOTTOM); }

/// @copydoc middle()
inline Surface const &bottom() const { return surface(SS_BOTTOM); }

/**
* Returns the middle surface of the sidedef.
*/
inline Surface &top() { return surface(SS_TOP); }

/// @copydoc middle()
inline Surface const &top() const { return surface(SS_TOP); }

/**
* Update the side's map space surface base origins according to the points
* defined by the associated LineDef's vertices and the plane heights of the
Expand Down
101 changes: 75 additions & 26 deletions doomsday/client/include/map/surface.h
Expand Up @@ -28,15 +28,21 @@
#ifdef __CLIENT__
# include "MaterialSnapshot"
#endif
#include <de/vector1.h>
#include <QSet>

// Internal surface flags:
/**
* @defgroup surfaceInternalFlags Surface Internal Flags
* @ingroup map
*/
///@{
#define SUIF_FIX_MISSING_MATERIAL 0x0001 ///< Current material is a fix replacement
/// (not sent to clients, returned via DMU etc).
#define SUIF_NO_RADIO 0x0002 ///< No fakeradio for this surface.

#define SUIF_UPDATE_FLAG_MASK 0xff00
#define SUIF_UPDATE_DECORATIONS 0x8000
///@}

/**
* @ingroup map
Expand All @@ -55,33 +61,79 @@ class Surface : public de::MapElement
#endif // __CLIENT__

public:
ddmobj_base_t base;
de::MapElement *owner; ///< Either @c DMU_SIDEDEF, or @c DMU_PLANE
int flags; ///< SUF_ flags
int oldFlags;
/// Owning map element, either @c DMU_SIDEDEF, or @c DMU_PLANE.
de::MapElement &_owner;

/// Sound emitter.
ddmobj_base_t _soundEmitter;

/// @ref sufFlags
int flags;

// Bound material.
Material *material;

// Blending mode, for rendering.
blendmode_t blendMode;
float tangent[3];
float bitangent[3];
float normal[3];
float offset[2]; ///< [X, Y] Planar offset to surface material origin.
float oldOffset[2][2];
float visOffset[2];
float visOffsetDelta[2];
float rgba[4]; ///< Surface color tint
short inFlags; ///< SUIF_* flags

// Tangent space vectors:
vec3f_t tangent;
vec3f_t bitangent;
vec3f_t normal;

/// [X, Y] Planar offset to surface material origin.
vec2f_t offset;

/// Old [X, Y] Planar material origin offset. For smoothing.
vec2f_t _oldOffset[2];

/// Smoothed [X, Y] Planar material origin offset.
vec2f_t visOffset;

/// Smoother [X, Y] Planar material origin offset delta.
vec2f_t visOffsetDelta;

/// Surface color tint.
float rgba[4];

/// @ref surfaceInternalFlags
short inFlags;

/// Old @ref surfaceInternalFlags, for tracking changes.
short oldInFlags;

uint numDecorations;

struct surfacedecorsource_s *decorations;

public:
Surface();
Surface(de::MapElement &owner);
~Surface();

/// @todo Refactor away.
Surface &operator = (Surface const &other);

/// @return @c true= is drawable (i.e., a drawable Material is bound).
bool isDrawable() const;

/// @return @c true= is sky-masked (i.e., a sky-masked Material is bound).
bool isSkyMasked() const;

/// @return @c true= is owned by some element of the Map geometry.
bool isAttachedToMap() const;

/**
* Mark the surface as requiring a full update. To be called during an
* engine reset.
* Returns the owning map element. Either @c DMU_SIDEDEF, or @c DMU_PLANE.
*/
void update();
de::MapElement &owner() const;

/**
* Returns the sound emitter for the surface.
*/
ddmobj_base_t &soundEmitter();

/// @copydoc soundEmitter()
ddmobj_base_t const &soundEmitter() const;

/**
* Update the Surface's map space base origin according to relevant points in
Expand All @@ -99,14 +151,11 @@ class Surface : public de::MapElement
*/
void updateSoundEmitterOrigin();

/// @return @c true= is drawable (i.e., a drawable Material is bound).
bool isDrawable() const;

/// @return @c true= is sky-masked (i.e., a sky-masked Material is bound).
bool isSkyMasked() const;

/// @return @c true= is owned by some element of the Map geometry.
bool isAttachedToMap() const;
/**
* Mark the surface as requiring a full update. To be called during an
* engine reset.
*/
void update();

/**
* Change Material bound to this surface.
Expand Down
10 changes: 5 additions & 5 deletions doomsday/client/src/client/cl_sound.cpp
Expand Up @@ -148,19 +148,19 @@ void Cl_ReadSoundDelta2(deltatype_t type, boolean skip)
{
// Select the origin for the sound.
if(flags & SNDDF_PLANE_FLOOR)
emitter = (mobj_t*) &sector->floorSurface().base;
emitter = (mobj_t *) &sector->floorSurface().soundEmitter();
else if(flags & SNDDF_PLANE_CEILING)
emitter = (mobj_t*) &sector->ceilingSurface().base;
emitter = (mobj_t *) &sector->ceilingSurface().soundEmitter();
}

if(type == DT_SIDE_SOUND)
{
if(flags & SNDDF_SIDE_MIDDLE)
emitter = (mobj_t*) &side->SW_middlesurface.base;
emitter = (mobj_t *) &side->SW_middlesurface.soundEmitter();
else if(flags & SNDDF_SIDE_TOP)
emitter = (mobj_t*) &side->SW_topsurface.base;
emitter = (mobj_t *) &side->SW_topsurface.soundEmitter();
else if(flags & SNDDF_SIDE_BOTTOM)
emitter = (mobj_t*) &side->SW_bottomsurface.base;
emitter = (mobj_t *) &side->SW_bottomsurface.soundEmitter();
}

if(flags & SNDDF_VOLUME)
Expand Down

0 comments on commit cb7151e

Please sign in to comment.