Browse Source

Use the node and leaf data to traverse the entire BSP tree and draw all attached faces.

This already gets rid of all the collision volumes that were being drawn before.
tess_experiment
Nico de Poel 3 years ago
parent
commit
337406c03f
  1. 9
      ps1bsp.h
  2. BIN
      test.ps1bsp
  3. 51
      world.c

9
ps1bsp.h

@ -85,10 +85,13 @@ typedef struct
typedef struct typedef struct
{ {
int planeId; int planeId;
u_short front;
u_short back;
short front;
short back;
// TODO: add bounding box for frustum culling // TODO: add bounding box for frustum culling
// TODO: not sure if face list is needed here
u_short firstFace;
u_short numFaces;
} ps1bsp_node_t; } ps1bsp_node_t;
typedef struct typedef struct

BIN
test.ps1bsp

51
world.c

@ -237,36 +237,61 @@ static void world_drawface(const world_t *world, const ps1bsp_face_t *face, char
vecs[vertIdx].pad = vert->baseLight; vecs[vertIdx].pad = vert->baseLight;
} }
if (face->numFaceVertices == 3)
if (face->numFaceVertices == 3) // Special case: draw single triangles using the simplest method
drawface_triangle_fan(face, vecs); drawface_triangle_fan(face, vecs);
else else
drawface_quad_strip(face, vecs); drawface_quad_strip(face, vecs);
} }
void world_draw(const world_t *world)
static void world_drawnode(const world_t *world, short nodeIdx, char *scratchptr)
{ {
int p;
// The world doesn't move, so we just set the camera view-projection matrix
gte_SetRotMatrix(&vp_matrix);
gte_SetTransMatrix(&vp_matrix);
u_long frameNum = time_getFrameNumber(); u_long frameNum = time_getFrameNumber();
const ps1bsp_leaf_t *leaf = &world->leaves[0];
for (u_short leafIdx = 0; leafIdx < world->numLeaves; ++leafIdx, ++leaf)
if (nodeIdx < 0) // Leaf node
{ {
u_short *leafFace = &world->leafFaces[leaf->firstLeafFace];
const ps1bsp_leaf_t *leaf = &world->leaves[~nodeIdx];
const u_short *leafFace = &world->leafFaces[leaf->firstLeafFace];
for (u_short leafFaceIdx = 0; leafFaceIdx < leaf->numLeafFaces; ++leafFaceIdx, ++leafFace) for (u_short leafFaceIdx = 0; leafFaceIdx < leaf->numLeafFaces; ++leafFaceIdx, ++leafFace)
{ {
ps1bsp_face_t *face = &world->faces[*leafFace]; ps1bsp_face_t *face = &world->faces[*leafFace];
// Check if we've already drawn this face
// Check if we've already drawn this face on the current frame
if (face->drawFrame == frameNum) if (face->drawFrame == frameNum)
continue; continue;
world_drawface(world, face, scratchpad);
world_drawface(world, face, scratchptr);
face->drawFrame = frameNum; face->drawFrame = frameNum;
} }
return;
}
const ps1bsp_node_t *node = &world->nodes[nodeIdx];
// Still not sure why we have faces attached to nodes... Try to remove this and see what happens
ps1bsp_face_t *face = &world->faces[node->firstFace];
for (u_short faceIdx = 0; faceIdx < node->numFaces; ++faceIdx, ++face)
{
// Check if we've already drawn this face on the current frame
if (face->drawFrame == frameNum)
continue;
world_drawface(world, face, scratchptr);
face->drawFrame = frameNum;
} }
world_drawnode(world, node->front, scratchptr);
world_drawnode(world, node->back, scratchptr);
}
void world_draw(const world_t *world)
{
int p;
// The world doesn't move, so we just set the camera view-projection matrix
gte_SetRotMatrix(&vp_matrix);
gte_SetTransMatrix(&vp_matrix);
world_drawnode(world, 0, scratchpad);
} }
Loading…
Cancel
Save