diff --git a/ps1bsp.h b/ps1bsp.h index eead86a..a8ae1a0 100755 --- a/ps1bsp.h +++ b/ps1bsp.h @@ -85,10 +85,13 @@ typedef struct typedef struct { int planeId; - u_short front; - u_short back; + short front; + short back; + // 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; typedef struct diff --git a/test.ps1bsp b/test.ps1bsp index 3673abf..cc30168 100755 Binary files a/test.ps1bsp and b/test.ps1bsp differ diff --git a/world.c b/world.c index bc93d52..942df17 100644 --- a/world.c +++ b/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; } - if (face->numFaceVertices == 3) + if (face->numFaceVertices == 3) // Special case: draw single triangles using the simplest method drawface_triangle_fan(face, vecs); else 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(); - 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) { 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) continue; - world_drawface(world, face, scratchpad); + world_drawface(world, face, scratchptr); 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); }