From c110ea920b0bca90cff795440b57c3121b86435b Mon Sep 17 00:00:00 2001 From: danij Date: Mon, 19 Mar 2012 23:28:27 +0000 Subject: [PATCH] Refactor: Use DMU's RTTI mechanic to replace the BSP map data element 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. --- doomsday/engine/api/dd_maptypes.h | 2 +- doomsday/engine/portable/include/bsp_node.h | 2 +- doomsday/engine/portable/include/mapdata.hs | 2 +- doomsday/engine/portable/include/p_mapdata.h | 3 -- doomsday/engine/portable/include/p_maptypes.h | 2 +- doomsday/engine/portable/src/bsp_map.c | 14 ++++---- doomsday/engine/portable/src/gamemap.c | 20 +++++------ doomsday/engine/portable/src/p_sight.c | 25 +++++++------ doomsday/engine/portable/src/rend_main.c | 35 ++++++++++--------- 9 files changed, 52 insertions(+), 53 deletions(-) diff --git a/doomsday/engine/api/dd_maptypes.h b/doomsday/engine/api/dd_maptypes.h index 49e5e6678b..3ff7a5b60a 100644 --- a/doomsday/engine/api/dd_maptypes.h +++ b/doomsday/engine/api/dd_maptypes.h @@ -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 diff --git a/doomsday/engine/portable/include/bsp_node.h b/doomsday/engine/portable/include/bsp_node.h index b69723eb59..aac2a839a2 100644 --- a/doomsday/engine/portable/include/bsp_node.h +++ b/doomsday/engine/portable/include/bsp_node.h @@ -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); /** diff --git a/doomsday/engine/portable/include/mapdata.hs b/doomsday/engine/portable/include/mapdata.hs index d37ee6a29b..62c89b4da1 100644 --- a/doomsday/engine/portable/include/mapdata.hs +++ b/doomsday/engine/portable/include/mapdata.hs @@ -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 diff --git a/doomsday/engine/portable/include/p_mapdata.h b/doomsday/engine/portable/include/p_mapdata.h index c6eee8bdec..6fe3bafaa9 100644 --- a/doomsday/engine/portable/include/p_mapdata.h +++ b/doomsday/engine/portable/include/p_mapdata.h @@ -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 diff --git a/doomsday/engine/portable/include/p_maptypes.h b/doomsday/engine/portable/include/p_maptypes.h index 96b192fb47..e5d1616197 100644 --- a/doomsday/engine/portable/include/p_maptypes.h +++ b/doomsday/engine/portable/include/p_maptypes.h @@ -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; diff --git a/doomsday/engine/portable/src/bsp_map.c b/doomsday/engine/portable/src/bsp_map.c index 533155035b..54c9fe3ef1 100644 --- a/doomsday/engine/portable/src/bsp_map.c +++ b/doomsday/engine/portable/src/bsp_map.c @@ -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, ¶ms->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); } } @@ -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, ¶ms->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); } } diff --git a/doomsday/engine/portable/src/gamemap.c b/doomsday/engine/portable/src/gamemap.c index c1aac38f12..39472a2fab 100644 --- a/doomsday/engine/portable/src/gamemap.c +++ b/doomsday/engine/portable/src/gamemap.c @@ -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) diff --git a/doomsday/engine/portable/src/p_sight.c b/doomsday/engine/portable/src/p_sight.c index bf39e5d88b..b9ce038016 100644 --- a/doomsday/engine/portable/src/p_sight.c +++ b/doomsday/engine/portable/src/p_sight.c @@ -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. @@ -207,19 +207,19 @@ 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 { @@ -227,11 +227,11 @@ static boolean crossBspNode(GameMap* map, unsigned int bspNum, losdata_t* los) 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], @@ -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); } diff --git a/doomsday/engine/portable/src/rend_main.c b/doomsday/engine/portable/src/rend_main.c index a41173e727..04abaf2cb8 100644 --- a/doomsday/engine/portable/src/rend_main.c +++ b/doomsday/engine/portable/src/rend_main.c @@ -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? @@ -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); @@ -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. } } @@ -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; @@ -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())