Skip to content

Commit

Permalink
Refactor: Use DMU's RTTI mechanic to replace the BSP map data element…
Browse files Browse the repository at this point in the history
… references

Rather than using the object's index within the vector of these
owned by GameMap for references in BspNode (and using the NF_LEAF
value in the high byte to differentiate between leafs and nodes)
we now use the DMU type header to determine the object's type and
use pointers instead.
  • Loading branch information
danij-deng committed Mar 19, 2012
1 parent c5a68c2 commit c110ea9
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 53 deletions.
2 changes: 1 addition & 1 deletion doomsday/engine/api/dd_maptypes.h
Expand Up @@ -76,6 +76,6 @@

#define DMT_BSPNODE_AABOX DDVT_FLOAT

#define DMT_BSPNODE_CHILDREN DDVT_UINT // If NF_LEAF it's a BspLeaf.
#define DMT_BSPNODE_CHILDREN DDVT_PTR

#endif
2 changes: 1 addition & 1 deletion doomsday/engine/portable/include/bsp_node.h
Expand Up @@ -92,7 +92,7 @@ void BSP_PartitionHEdges(SuperBlock* hEdgeList, SuperBlock* rightList, SuperBloc
* @param hPlane HPlaneIntercept list for storing any new intersections.
* @return @c true iff successfull.
*/
boolean BuildNodes(struct superblock_s* hEdgeList, binarytree_t** parent, size_t depth,
boolean BuildNodes(SuperBlock* hEdgeList, binarytree_t** parent, size_t depth,
HPlane* hPlane);

/**
Expand Down
2 changes: 1 addition & 1 deletion doomsday/engine/portable/include/mapdata.hs
Expand Up @@ -521,6 +521,6 @@ end
struct BspNode
- partition_t partition
- AABoxf[2] aaBox // Bounding box for each child.
UINT uint[2] children // If NF_LEAF it's a BspLeaf.
PTR runtime_mapdata_header_t*[2] children
- mbspnode_t buildData
end
3 changes: 0 additions & 3 deletions doomsday/engine/portable/include/p_mapdata.h
Expand Up @@ -61,9 +61,6 @@

#define NUM_POLYOBJS GameMap_PolyobjCount(theMap)

// Node flags.
#define NF_LEAF 0x80000000

// Runtime map data objects, such as vertices, sectors, and BspLeafs all
// have this header as their first member. This makes it possible to treat
// an unknown map data pointer as a runtime_mapdata_header_t* and determine
Expand Down
2 changes: 1 addition & 1 deletion doomsday/engine/portable/include/p_maptypes.h
Expand Up @@ -482,7 +482,7 @@ typedef struct bspnode_s {
runtime_mapdata_header_t header;
partition_t partition;
AABoxf aaBox[2]; // Bounding box for each child.
unsigned int children[2]; // If NF_LEAF it's a BspLeaf.
runtime_mapdata_header_t* children[2];
mbspnode_t buildData;
} BspNode;

Expand Down
14 changes: 6 additions & 8 deletions doomsday/engine/portable/src/bsp_map.c
Expand Up @@ -328,14 +328,13 @@ static boolean C_DECL hardenNode(binarytree_t* tree, void* data)
bspleafdata_t* leaf = (bspleafdata_t*) BinaryTree_GetData(right);
uint idx = params->leafCurIndex++;

node->children[RIGHT] = idx | NF_LEAF;
hardenLeaf(params->dest, &params->dest->bspLeafs[idx], leaf);
node->children[RIGHT] = (runtime_mapdata_header_t*)(params->dest->bspLeafs + idx);
hardenLeaf(params->dest, (BspLeaf*)node->children[RIGHT], leaf);
}
else
{
BspNode* data = (BspNode*) BinaryTree_GetData(right);

node->children[RIGHT] = data->buildData.index;
node->children[RIGHT] = (runtime_mapdata_header_t*)(params->dest->bspNodes + data->buildData.index);
}
}

Expand All @@ -347,14 +346,13 @@ static boolean C_DECL hardenNode(binarytree_t* tree, void* data)
bspleafdata_t* leaf = (bspleafdata_t*) BinaryTree_GetData(left);
uint idx = params->leafCurIndex++;

node->children[LEFT] = idx | NF_LEAF;
hardenLeaf(params->dest, &params->dest->bspLeafs[idx], leaf);
node->children[LEFT] = (runtime_mapdata_header_t*)(params->dest->bspLeafs + idx);
hardenLeaf(params->dest, (BspLeaf*)node->children[LEFT], leaf);
}
else
{
BspNode* data = (BspNode*) BinaryTree_GetData(left);

node->children[LEFT] = data->buildData.index;
node->children[LEFT] = (runtime_mapdata_header_t*)(params->dest->bspNodes + data->buildData.index);
}
}

Expand Down
20 changes: 9 additions & 11 deletions doomsday/engine/portable/src/gamemap.c
Expand Up @@ -1404,28 +1404,26 @@ int GameMap_PathXYTraverse(GameMap* map, float fromX, float fromY, float toX, fl

BspLeaf* GameMap_BspLeafAtPoint(GameMap* map, float point_[2])
{
BspNode* node = 0;
uint nodenum = 0;
BspNode* node;
float point[2];

point[0] = point_? point_[0] : 0;
point[1] = point_? point_[1] : 0;

// A single BSP leaf is a special case
if(!map->numBspNodes)
{
return (BspLeaf*) map->bspLeafs;
}

nodenum = map->numBspNodes - 1;
while(!(nodenum & NF_LEAF))
point[0] = point_? point_[0] : 0;
point[1] = point_? point_[1] : 0;

node = map->bspNodes + (map->numBspNodes - 1);
do
{
node = map->bspNodes + nodenum;
ASSERT_DMU_TYPE(node, DMU_BSPNODE);
nodenum = node->children[P_PointOnPartitionSide(point[0], point[1], &node->partition)];
}
node = (BspNode*)node->children[P_PointOnPartitionSide(point[0], point[1], &node->partition)];
} while(((runtime_mapdata_header_t*) node)->type != DMU_BSPLEAF);

return map->bspLeafs + (nodenum & ~NF_LEAF);
return (BspLeaf*)node;
}

BspLeaf* GameMap_BspLeafAtPointXY(GameMap* map, float x, float y)
Expand Down
25 changes: 15 additions & 10 deletions doomsday/engine/portable/src/p_sight.c
Expand Up @@ -165,9 +165,9 @@ static boolean crossLineDef(const LineDef* li, byte side, losdata_t* los)
/**
* @return @c true iff trace crosses the given BSP leaf.
*/
static boolean crossBspLeaf(GameMap* map, uint bspLeafIdx, losdata_t* los)
static boolean crossBspLeaf(GameMap* map, const BspLeaf* bspLeaf, losdata_t* los)
{
const BspLeaf* bspLeaf = &map->bspLeafs[bspLeafIdx];
assert(bspLeaf);
if(bspLeaf->polyObj)
{
// Check polyobj lines.
Expand Down Expand Up @@ -207,31 +207,31 @@ static boolean crossBspLeaf(GameMap* map, uint bspLeafIdx, losdata_t* los)
/**
* @return @c true iff trace crosses the node.
*/
static boolean crossBspNode(GameMap* map, unsigned int bspNum, losdata_t* los)
static boolean crossBspNode(GameMap* map, runtime_mapdata_header_t* bspPtr, losdata_t* los)
{
while(!(bspNum & NF_LEAF))
while(bspPtr->type != DMU_BSPLEAF)
{
const BspNode* node = &map->bspNodes[bspNum];
const BspNode* node = (BspNode*)bspPtr;
int side = P_PointOnPartitionSide(FIX2FLT(los->trace.pos[VX]), FIX2FLT(los->trace.pos[VY]),
&node->partition);

// Would the trace completely cross this partition?
if(side == P_PointOnPartitionSide(los->to[VX], los->to[VY], &node->partition))
{
// Yes, decend!
bspNum = node->children[side];
// Yes, descend!
bspPtr = node->children[side];
}
else
{
// No.
if(!crossBspNode(map, node->children[side], los))
return 0; // Cross the starting side.

bspNum = node->children[side^1]; // Cross the ending side.
bspPtr = node->children[side^1]; // Cross the ending side.
}
}

return crossBspLeaf(map, bspNum & ~NF_LEAF, los);
return crossBspLeaf(map, (BspLeaf*)bspPtr, los);
}

boolean GameMap_CheckLineSight(GameMap* map, const float from[3], const float to[3],
Expand Down Expand Up @@ -275,5 +275,10 @@ boolean GameMap_CheckLineSight(GameMap* map, const float from[3], const float to
}

validCount++;
return crossBspNode(map, map->numBspNodes - 1, &los);
// A single leaf is a special case.
if(!map->numBspNodes)
{
return crossBspLeaf(map, map->bspLeafs, &los);
}
return crossBspNode(map, (runtime_mapdata_header_t*) (map->bspNodes + (map->numBspNodes - 1)), &los);
}
35 changes: 18 additions & 17 deletions doomsday/engine/portable/src/rend_main.c
Expand Up @@ -2725,13 +2725,12 @@ static void occludeBspLeaf(const BspLeaf* bspLeaf, boolean forwardFacing)
}
}

static void Rend_RenderBspLeaf(uint bspLeafIdx)
static void Rend_RenderBspLeaf(BspLeaf* bspLeaf)
{
uint i;
BspLeaf* bspLeaf = BSPLEAF_PTR(bspLeafIdx);
HEdge* hedge, **segIt;
Sector* sect;
float sceil, sfloor;
uint i, bspLeafIdx;
Sector* sect;

if(!bspLeaf->sector) return; // An orphan BSP leaf?

Expand Down Expand Up @@ -2764,6 +2763,7 @@ static void Rend_RenderBspLeaf(uint bspLeafIdx)
R_InitForBspLeaf(bspLeaf);
Rend_RadioBspLeafEdges(bspLeaf);

bspLeafIdx = GET_BSPLEAF_IDX(bspLeaf);
occludeBspLeaf(bspLeaf, false);
LO_ClipInBspLeaf(bspLeafIdx);
occludeBspLeaf(bspLeaf, true);
Expand Down Expand Up @@ -2895,33 +2895,31 @@ static void Rend_RenderBspLeaf(uint bspLeafIdx)
}
}

static void Rend_RenderNode(uint bspnum)
static void Rend_RenderNode(runtime_mapdata_header_t* bspPtr)
{
// If the clipper is full we're pretty much done. This means no geometry
// will be visible in the distance because every direction has already been
// fully covered by geometry.
if(C_IsFull()) return;

if(bspnum & NF_LEAF)
if(bspPtr->type == DMU_BSPLEAF)
{
// We've arrived at a leaf. Render it.
Rend_RenderBspLeaf(bspnum & ~NF_LEAF);
Rend_RenderBspLeaf((BspLeaf*)bspPtr);
}
else
{
// Descend deeper into the nodes.
const viewdata_t* viewData = R_ViewData(viewPlayer - ddPlayers);
BspNode* bsp;
BspNode* node = (BspNode*)bspPtr;
byte side;

// Descend deeper into the nodes.
bsp = BSPNODE_PTR(bspnum);

// Decide which side the view point is on.
side = P_PointOnPartitionSide(viewData->current.pos[VX], viewData->current.pos[VY],
&bsp->partition);
&node->partition);

Rend_RenderNode(bsp->children[side]); // Recursively divide front space.
Rend_RenderNode(bsp->children[side ^ 1]); // ...and back space.
Rend_RenderNode(node->children[side]); // Recursively divide front space.
Rend_RenderNode(node->children[side ^ 1]); // ...and back space.
}
}

Expand Down Expand Up @@ -3355,6 +3353,8 @@ void Rend_RenderMap(void)
{
binangle_t viewside;

if(!theMap) return;

// Set to true if dynlights are inited for this frame.
loInited = false;

Expand Down Expand Up @@ -3408,13 +3408,14 @@ void Rend_RenderMap(void)

// We don't want BSP clip checking for the first BSP leaf.
firstBspLeaf = true;
if(NUM_BSPNODES != 0)
if(NUM_BSPNODES)
{
Rend_RenderNode(NUM_BSPNODES - 1);
Rend_RenderNode((runtime_mapdata_header_t*) BSPNODE_PTR(NUM_BSPNODES - 1));
}
else
{
Rend_RenderBspLeaf(0);
// A single leaf is a special case.
Rend_RenderBspLeaf(BSPLEAF_PTR(0));
}

if(Rend_MobjShadowsEnabled())
Expand Down

0 comments on commit c110ea9

Please sign in to comment.