Browse Source

Eliminated recursion from the BSP traversal, using fast RAM to hold the node stack. Yet another appreciable speed boost.

unrollquadloop
Nico de Poel 3 years ago
parent
commit
26d541e48f
  1. 36
      world.c

36
world.c

@ -202,39 +202,54 @@ static ps1bsp_face_t *world_sortFaces(const world_t *world, const ps1bsp_leaf_t
return firstFace; return firstFace;
} }
static void world_sortLeafs(const world_t *world, short nodeIdx, u_char *pvs, ps1bsp_leaf_t **firstLeaf)
static ps1bsp_leaf_t *world_sortLeafs(const world_t *world, short startNode, u_char *pvs)
{ {
short *nodeStack = (short*)(scratchpad + 256); // Place the node stack in fast RAM after the PVS data
u_char stackPtr = 0;
// Push the start node onto the stack
nodeStack[stackPtr++] = startNode;
ps1bsp_leaf_t *firstLeaf = NULL;
while (stackPtr > 0)
{
// Pop a node off the stack
short nodeIdx = nodeStack[--stackPtr];
if (nodeIdx < 0) // Leaf node if (nodeIdx < 0) // Leaf node
{ {
u_short leafIdx = ~nodeIdx; u_short leafIdx = ~nodeIdx;
if (leafIdx == 0) // Leaf 0 should not be drawn if (leafIdx == 0) // Leaf 0 should not be drawn
return;
continue;
// PVS culling // PVS culling
u_short test = leafIdx - 1; u_short test = leafIdx - 1;
if ((pvs[test >> 3] & (1 << (test & 0x7))) == 0) if ((pvs[test >> 3] & (1 << (test & 0x7))) == 0)
return;
continue;
// Add the leaf to the sorted linked list // Add the leaf to the sorted linked list
// Since we're traversing the BSP tree front-to-back, adding each leaf at the start sorts the list in back-to-front order // Since we're traversing the BSP tree front-to-back, adding each leaf at the start sorts the list in back-to-front order
ps1bsp_leaf_t *leaf = (ps1bsp_leaf_t*)&world->leaves[leafIdx]; ps1bsp_leaf_t *leaf = (ps1bsp_leaf_t*)&world->leaves[leafIdx];
leaf->nextLeaf = *firstLeaf;
*firstLeaf = leaf;
return;
leaf->nextLeaf = firstLeaf;
firstLeaf = leaf;
continue;
} }
// Perform frustum culling // Perform frustum culling
const ps1bsp_node_t *node = &world->nodes[nodeIdx]; const ps1bsp_node_t *node = &world->nodes[nodeIdx];
if (!frustum_sphereInside(&node->boundingSphere)) if (!frustum_sphereInside(&node->boundingSphere))
return;
continue;
const ps1bsp_plane_t *plane = &world->planes[node->planeId]; const ps1bsp_plane_t *plane = &world->planes[node->planeId];
short dist = world_pointPlaneDist(&cam_pos, plane); short dist = world_pointPlaneDist(&cam_pos, plane);
// Traverse the BSP tree in front-to-back order // Traverse the BSP tree in front-to-back order
char order = dist < 0; char order = dist < 0;
world_sortLeafs(world, node->children[order], pvs, firstLeaf);
world_sortLeafs(world, node->children[order ^ 1], pvs, firstLeaf);
nodeStack[stackPtr++] = node->children[order ^ 1];
nodeStack[stackPtr++] = node->children[order];
}
return firstLeaf;
} }
// Decompress PVS data for the given leaf ID and store it in RAM at the given buffer pointer location. // Decompress PVS data for the given leaf ID and store it in RAM at the given buffer pointer location.
@ -315,8 +330,7 @@ void world_draw(const world_t *world)
else else
world_drawface = &world_drawface_lit; world_drawface = &world_drawface_lit;
ps1bsp_leaf_t *firstLeaf = NULL;
world_sortLeafs(world, 0, pvs, &firstLeaf);
ps1bsp_leaf_t *firstLeaf = world_sortLeafs(world, 0, pvs);
ps1bsp_face_t *firstFace = world_sortFaces(world, firstLeaf); ps1bsp_face_t *firstFace = world_sortFaces(world, firstLeaf);
world_drawFaces(world, firstFace); world_drawFaces(world, firstFace);
} }
Loading…
Cancel
Save