Skip to content

Commit

Permalink
GameMap|Blockmap|Gridmap|Refactor: Enforce data hiding - GameMap's us…
Browse files Browse the repository at this point in the history
…e of Blockmap is now invisible
  • Loading branch information
danij-deng committed Mar 11, 2012
1 parent 0ea1e50 commit a72f302
Show file tree
Hide file tree
Showing 11 changed files with 431 additions and 363 deletions.
95 changes: 68 additions & 27 deletions doomsday/engine/portable/include/blockmap.h
Expand Up @@ -25,112 +25,153 @@

#include "dd_types.h"
#include "m_vector.h"
#include "p_mapdata.h"

/// @todo It should not be necessary to expose the Gridmap implementation.
#include "gridmap.h"

struct blockmap_s; // The Blockmap instance (opaque).
typedef struct blockmap_s Blockmap;

typedef GridmapCoord BlockmapCoord;
typedef GridmapCell BlockmapCell;
typedef const_GridmapCell const_BlockmapCell;

typedef GridmapCellBlock BlockmapCellBlock;

Blockmap* Blockmap_New(const pvec2_t min, const pvec2_t max, uint cellWidth, uint cellHeight);

/**
* @param blockmap Blockmap instance.
* @return "Origin" map space point for the Blockmap (minimal [x,y]).
*/
const pvec2_t Blockmap_Origin(Blockmap* blockmap);

/**
* Retrieve the extremal map space points covered by the Blockmap.
*
* @param blockmap Blockmap instance.
*/
const AABoxf* Blockmap_Bounds(Blockmap* blockmap);

/// @return Width of the Blockmap in cells.
uint Blockmap_Width(Blockmap* blockmap);
/**
* @param blockmap Blockmap instance.
* @return Width of the Blockmap in cells.
*/
BlockmapCoord Blockmap_Width(Blockmap* blockmap);

/// @return Height of the Blockmap in cells.
uint Blockmap_Height(Blockmap* blockmap);
/**
* @param blockmap Blockmap instance.
* @return Height of the Blockmap in cells.
*/
BlockmapCoord Blockmap_Height(Blockmap* blockmap);

/**
* Retrieve the size of the Blockmap in cells.
*
* @param widthHeight Size of the Blockmap [width,height] written here.
*/
void Blockmap_Size(Blockmap* blockmap, uint widthHeight[2]);
void Blockmap_Size(Blockmap* blockmap, BlockmapCoord widthHeight[2]);

/// @return Width of a Blockmap cell in map space units.
/**
* @param blockmap Blockmap instance.
* @return Width of a Blockmap cell in map space units.
*/
float Blockmap_CellWidth(Blockmap* blockmap);

/// @return Height of a Blockmap cell in map space units.
/**
* @param blockmap Blockmap instance.
* @return Height of a Blockmap cell in map space units.
*/
float Blockmap_CellHeight(Blockmap* blockmap);

/// @return Size [width,height] of a Blockmap cell in map space units.
/**
* @param blockmap Blockmap instance.
* @return Size [width,height] of a Blockmap cell in map space units.
*/
const pvec2_t Blockmap_CellSize(Blockmap* blockmap);

/**
* Given map space X coordinate @a x, return the corresponding cell coordinate.
* If @a x is outside the Blockmap it will be clamped to the nearest edge on
* the X axis.
*
* @param blockmap Blockmap instance.
* @param x Map space X coordinate to be translated.
*
* @return Translated Blockmap cell X coordinate.
*/
uint Blockmap_CellX(Blockmap* blockmap, float x);
BlockmapCoord Blockmap_CellX(Blockmap* blockmap, float x);

/**
* Given map space Y coordinate @a y, return the corresponding cell coordinate.
* If @a y is outside the Blockmap it will be clamped to the nearest edge on
* the Y axis.
*
* @param outY Blockmap cell X coordinate written here.
* @param y Map space X coordinate to be translated.
* @return @c true iff clamping was necessary.
* @param blockmap Blockmap instance.
* @param y Map space Y coordinate to be translated.
*
* @return Translated Blockmap cell Y coordinate.
*/
uint Blockmap_CellY(Blockmap* blockmap, float y);
BlockmapCoord Blockmap_CellY(Blockmap* blockmap, float y);

/**
* Same as @a Blockmap::CellX with alternative semantics for when the caller
* needs to know if the coordinate specified was inside/outside the Blockmap.
*/
boolean Blockmap_ClipCellX(Blockmap* bm, uint* outX, float x);
boolean Blockmap_ClipCellX(Blockmap* blockmap, BlockmapCoord* outX, float x);

/**
* Same as @a Blockmap::CellY with alternative semantics for when the caller
* needs to know if the coordinate specified was inside/outside the Blockmap.
*
* @param outY Blockmap cell Y coordinate written here.
* @param y Map space Y coordinate to be translated.
* @param blockmap Blockmap instance.
* @param outY Blockmap cell Y coordinate written here.
* @param y Map space Y coordinate to be translated.
*
* @return @c true iff clamping was necessary.
*/
boolean Blockmap_ClipCellY(Blockmap* bm, uint* outY, float y);
boolean Blockmap_ClipCellY(Blockmap* blockmap, BlockmapCoord* outY, float y);

/**
* Given map space XY coordinates @a pos, output the Blockmap cell[x, y] it
* resides in. If @a pos is outside the Blockmap it will be clamped to the
* nearest edge on one or more axes as necessary.
*
* @param blockmap Blockmap instance.
* @param cell Blockmap cell coordinates will be written here.
* @param pos Map space coordinates to translate.
*
* @return @c true iff clamping was necessary.
*/
boolean Blockmap_CellCoords(Blockmap* blockmap, uint coords[2], float const pos[2]);
boolean Blockmap_Cell(Blockmap* blockmap, BlockmapCell cell, float const pos[2]);

/**
* Given map space box XY coordinates @a box, output the blockmap cells[x, y]
* they reside in. If any point defined by @a box lies outside the blockmap
* it will be clamped to the nearest edge on one or more axes as necessary.
*
* @param blockmap Blockmap instance.
* @param cellBlock Blockmap cell coordinates will be written here.
* @param box Map space coordinates to translate.
*
* @return @c true iff Clamping was necessary.
*/
boolean Blockmap_CellBlockCoords(Blockmap* blockmap, GridmapBlock* blockCoords, const AABoxf* box);
boolean Blockmap_CellBlock(Blockmap* blockmap, BlockmapCellBlock* cellBlock, const AABoxf* box);

boolean Blockmap_CreateCellAndLinkObject(Blockmap* blockmap, uint const coords[2], void* object);
boolean Blockmap_CreateCellAndLinkObject(Blockmap* blockmap, const_BlockmapCell cell, void* object);

boolean Blockmap_CreateCellAndLinkObjectXY(Blockmap* blockmap, uint x, uint y, void* object);
boolean Blockmap_CreateCellAndLinkObjectXY(Blockmap* blockmap, BlockmapCoord x, BlockmapCoord y, void* object);

boolean Blockmap_UnlinkObjectInCell(Blockmap* blockmap, uint const coords[2], void* object);
boolean Blockmap_UnlinkObjectInCell(Blockmap* blockmap, const_BlockmapCell cell, void* object);

boolean Blockmap_UnlinkObjectInCellXY(Blockmap* blockmap, uint x, uint y, void* object);
boolean Blockmap_UnlinkObjectInCellXY(Blockmap* blockmap, BlockmapCoord x, BlockmapCoord y, void* object);

void Blockmap_UnlinkObjectInCellBlock(Blockmap* blockmap, const GridmapBlock* blockCoords, void* object);
void Blockmap_UnlinkObjectInCellBlock(Blockmap* blockmap, const BlockmapCellBlock* blockCoords, void* object);

int Blockmap_IterateCellObjects(Blockmap* blockmap, uint const coords[2],
int Blockmap_IterateCellObjects(Blockmap* blockmap, const_BlockmapCell cell,
int (*callback) (void* object, void* context), void* context);

int Blockmap_IterateCellBlockObjects(Blockmap* blockmap, const GridmapBlock* blockCoords,
int Blockmap_IterateCellBlockObjects(Blockmap* blockmap, const BlockmapCellBlock* blockCoords,
int (*callback) (void* object, void* context), void* context);

#endif /// LIBDENG_MAP_BLOCKMAP_H
141 changes: 78 additions & 63 deletions doomsday/engine/portable/include/gamemap.h
Expand Up @@ -29,11 +29,8 @@ struct thinkerlist_s;
struct clmoinfo_s;
struct generators_s;

/// Size of Blockmap blocks in map units. Must be an integer power of two.
#define MAPBLOCKUNITS (128)

/// @todo Remove me.
struct blockmap_s;
struct gridmapblock_s;

/**
* The client mobjs are stored into a hash for quickly locating a ClMobj by its identifier.
Expand Down Expand Up @@ -506,8 +503,7 @@ void GameMap_SetMobjID(GameMap* map, thid_t id, boolean state);
void GameMap_InitClMobjs(GameMap* map);

/**
* Called when the client is shut down. Unlinks everything from the
* sectors and the blockmap and clears the clmobj list.
* To be called when the client is shut down.
*/
void GameMap_DestroyClMobjs(GameMap* map);

Expand Down Expand Up @@ -601,46 +597,36 @@ void GameMap_InitPolyobjs(GameMap* map);
void GameMap_InitNodePiles(GameMap* map);

/**
* Construct an initial (empty) Mobj Blockmap for this map.
* Link the specified @a mobj in any internal data structures for bookkeeping purposes.
* Should be called AFTER mobj translation to (re-)insert the mobj.
*
* @param min Minimal coordinates for the map.
* @param max Maximal coordinates for the map.
* @param map GameMap instance.
* @param mobj Mobj to be linked.
*/
void GameMap_InitMobjBlockmap(GameMap* map, const_pvec2_t min, const_pvec2_t max);

void GameMap_LinkMobjInBlockmap(GameMap* map, struct mobj_s* mo);
boolean GameMap_UnlinkMobjInBlockmap(GameMap* map, struct mobj_s* mo);
void GameMap_LinkMobj(GameMap* map, struct mobj_s* mobj);

int GameMap_IterateCellMobjs(GameMap* map, const uint coords[2],
int (*callback) (struct mobj_s*, void*), void* parameters);
int GameMap_IterateCellBlockMobjs(GameMap* map, const struct gridmapblock_s* blockCoords,
int (*callback) (struct mobj_s*, void*), void* parameters);
/**
* Unlink the specified @a mobj from any internal data structures for bookkeeping purposes.
* Should be called BEFORE mobj translation to extract the mobj.
*
* @param map GameMap instance.
* @param mobj Mobj to be unlinked.
*/
boolean GameMap_UnlinkMobj(GameMap* map, struct mobj_s* mobj);

int GameMap_MobjsBoxIterator(GameMap* map, const AABoxf* box,
int (*callback) (struct mobj_s*, void*), void* parameters);

/**
* Construct an initial (empty) LineDef Blockmap for this map.
* Link the specified @a lineDef in any internal data structures for bookkeeping purposes.
*
* @param min Minimal coordinates for the map.
* @param max Maximal coordinates for the map.
* @param map GameMap instance.
* @param lineDef LineDef to be linked.
*/
void GameMap_InitLineDefBlockmap(GameMap* map, const_pvec2_t min, const_pvec2_t max);

void GameMap_LinkLineDefInBlockmap(GameMap* map, LineDef* lineDef);

int GameMap_IterateCellLineDefs(GameMap* map, const uint coords[2],
int (*callback) (LineDef*, void*), void* parameters);
int GameMap_IterateCellBlockLineDefs(GameMap* map, const struct gridmapblock_s* blockCoords,
int (*callback) (LineDef*, void*), void* parameters);
void GameMap_LinkLineDef(GameMap* map, LineDef* lineDef);

int GameMap_LineDefIterator(GameMap* map, int (*callback) (LineDef*, void*), void* parameters);

int GameMap_IterateCellPolyobjLineDefs(GameMap* map, const uint coords[2],
int (*callback) (LineDef*, void*), void* parameters);
int GameMap_IterateCellBlockPolyobjLineDefs(GameMap* map, const struct gridmapblock_s* blockCoords,
int (*callback) (LineDef*, void*), void* parameters);

int GameMap_LineDefsBoxIterator(GameMap* map, const AABoxf* box,
int (*callback) (LineDef*, void*), void* parameters);

Expand All @@ -650,55 +636,48 @@ int GameMap_PolyobjLinesBoxIterator(GameMap* map, const AABoxf* box,
/**
* LineDefs and Polyobj LineDefs (note Polyobj LineDefs are iterated first).
*
* The validCount flags are used to avoid checking lines that are marked
* in multiple mapblocks, so increment validCount before the first call
* to GameMap_IterateCellLineDefs(), then make one or more calls to it.
* @note validCount should be incremented before calling this to begin a new logical traversal.
* Otherwise LineDefs marked with a validCount equal to this will be skipped over (can
* be used to avoid processing a LineDef multiple times during complex / non-linear traversals.
*/
int GameMap_AllLineDefsBoxIterator(GameMap* map, const AABoxf* box,
int (*callback) (LineDef*, void*), void* parameters);

/**
* Construct an initial (empty) BspLeaf Blockmap for this map.
* Link the specified @a bspLeaf in internal data structures for bookkeeping purposes.
*
* @param min Minimal coordinates for the map.
* @param max Maximal coordinates for the map.
* @param map GameMap instance.
* @param bspLeaf BspLeaf to be linked.
*/
void GameMap_InitBspLeafBlockmap(GameMap* map, const_pvec2_t min, const_pvec2_t max);

void GameMap_LinkBspLeafInBlockmap(GameMap* map, BspLeaf* bspLeaf);

int GameMap_IterateCellBspLeafs(GameMap* map, const uint coords[2],
Sector* sector, const AABoxf* box, int localValidCount,
int (*callback) (BspLeaf*, void*), void* parameters);
int GameMap_IterateCellBlockBspLeafs(GameMap* map, const struct gridmapblock_s* blockCoords,
Sector* sector, const AABoxf* box, int localValidCount,
int (*callback) (BspLeaf*, void*), void* parameters);
void GameMap_LinkBspLeaf(GameMap* map, BspLeaf* bspLeaf);

int GameMap_BspLeafsBoxIterator(GameMap* map, const AABoxf* box, Sector* sector,
int (*callback) (BspLeaf*, void*), void* parameters);

int GameMap_BspLeafIterator(GameMap* map, int (*callback) (BspLeaf*, void*), void* parameters);

/**
* Construct an initial (empty) Polyobj Blockmap for this map.
* Link the specified @a polyobj in any internal data structures for bookkeeping purposes.
* Should be called AFTER Polyobj rotation and/or translation to (re-)insert the polyobj.
*
* @param min Minimal coordinates for the map.
* @param max Maximal coordinates for the map.
* @param map GameMap instance.
* @param polyobj Polyobj to be linked.
*/
void GameMap_InitPolyobjBlockmap(GameMap* map, const_pvec2_t min, const_pvec2_t max);

void GameMap_LinkPolyobjInBlockmap(GameMap* map, Polyobj* po);
void GameMap_UnlinkPolyobjInBlockmap(GameMap* map, Polyobj* po);
void GameMap_LinkPolyobj(GameMap* map, Polyobj* polyobj);

int GameMap_IterateCellPolyobjs(GameMap* map, const uint coords[2],
int (*callback) (Polyobj*, void*), void* parameters);
int GameMap_IterateCellBlockPolyobjs(GameMap* map, const struct gridmapblock_s* blockCoords,
int (*callback) (Polyobj*, void*), void* parameters);
/**
* Unlink the specified @a polyobj from any internal data structures for bookkeeping purposes.
* Should be called BEFORE Polyobj rotation and/or translation to extract the polyobj.
*
* @param map GameMap instance.
* @param polyobj Polyobj to be unlinked.
*/
void GameMap_UnlinkPolyobj(GameMap* map, Polyobj* polyobj);

/**
* The validCount flags are used to avoid checking polys that are marked in
* multiple mapblocks, so increment validCount before the first call, then
* make one or more calls to it.
* @note validCount should be incremented before calling this to begin a new logical traversal.
* Otherwise LineDefs marked with a validCount equal to this will be skipped over (can
* be used to avoid processing a LineDef multiple times during complex / non-linear traversals.
*/
int GameMap_PolyobjsBoxIterator(GameMap* map, const AABoxf* box,
int (*callback) (struct polyobj_s*, void*), void* parameters);
Expand Down Expand Up @@ -745,4 +724,40 @@ int GameMap_PathXYTraverse(GameMap* map, float fromX, float fromY, float toX, fl
BspLeaf* GameMap_BspLeafAtPoint(GameMap* map, float point[2]);
BspLeaf* GameMap_BspLeafAtPointXY(GameMap* map, float x, float y);

/**
* Private member functions:
*/

/**
* Construct an initial (empty) Mobj Blockmap for this map.
*
* @param min Minimal coordinates for the map.
* @param max Maximal coordinates for the map.
*/
void GameMap_InitMobjBlockmap(GameMap* map, const_pvec2_t min, const_pvec2_t max);

/**
* Construct an initial (empty) LineDef Blockmap for this map.
*
* @param min Minimal coordinates for the map.
* @param max Maximal coordinates for the map.
*/
void GameMap_InitLineDefBlockmap(GameMap* map, const_pvec2_t min, const_pvec2_t max);

/**
* Construct an initial (empty) BspLeaf Blockmap for this map.
*
* @param min Minimal coordinates for the map.
* @param max Maximal coordinates for the map.
*/
void GameMap_InitBspLeafBlockmap(GameMap* map, const_pvec2_t min, const_pvec2_t max);

/**
* Construct an initial (empty) Polyobj Blockmap for this map.
*
* @param min Minimal coordinates for the map.
* @param max Maximal coordinates for the map.
*/
void GameMap_InitPolyobjBlockmap(GameMap* map, const_pvec2_t min, const_pvec2_t max);

#endif /// LIBDENG_GAMEMAP_H

0 comments on commit a72f302

Please sign in to comment.