diff --git a/ps1bsp.h b/ps1bsp.h index 7dc494f..c8f5e0a 100755 --- a/ps1bsp.h +++ b/ps1bsp.h @@ -163,8 +163,8 @@ typedef struct ps1bsp_model_s u_short nodeId0; u_short nodeId1; - u_short nodeId2; - u_short nodeId3; + u_short firstFace; + u_short numFaces; // Run-time data const struct ps1bsp_model_s* nextModel; diff --git a/world.c b/world.c index b3f5f83..c7acaba 100644 --- a/world.c +++ b/world.c @@ -144,12 +144,12 @@ static void world_drawface_textured(const world_t *world, const ps1bsp_face_t *f const ps1bsp_texture_t *texture = &world->textures[face->textureId]; const ps1bsp_polygon_t* poly = &world->polygons[face->firstPolygon]; - u_char tess = face->flags & 3; - if (tess) - { - world_drawface_flat(world, face, &colors[tess - 1], ot); - return; - } + // u_char tess = face->flags & 3; + // if (tess) + // { + // world_drawface_flat(world, face, &colors[tess - 1], ot); + // return; + // } if (face->flags & SURF_DRAWLIQUID) { @@ -232,11 +232,56 @@ static ps1bsp_face_t *world_sortFaces(const world_t *world, const ps1bsp_leaf_t face->nextFace = firstFace; firstFace = face; } + + // Draw models in this leaf + for (const ps1bsp_model_t* model = leaf->models; model != NULL; model = model->nextModel) + { + // Hmmm... either just draw all the faces in this model, or do the whole BSP sorting thing + // Guess we could call sortLeafs from here + // If we don't, things like tech doors which are concave might render improperly + ps1bsp_face_t* face = &world->faces[model->firstFace]; + for (u_short faceIdx = 0; faceIdx < model->numFaces; ++faceIdx, ++face) + { + if (face->drawFrame == frameNum) + continue; + + face->drawFrame = frameNum; + + if (!world_cull_backface(world, face)) + continue; + + face->nextFace = firstFace; + firstFace = face; + } + } } return firstFace; } +static void world_sortModels(const world_t *world) +{ + for (u_short modelIdx = 1; modelIdx < world->numModels; ++modelIdx) + { + ps1bsp_model_t* model = (ps1bsp_model_t*)&world->models[modelIdx]; + + // TODO: refence leaf in model, update only when model moves + + VECTOR pos; + pos.vx = model->origin.vx + model->boundingSphere.vx; + pos.vy = model->origin.vy + model->boundingSphere.vy; + pos.vz = model->origin.vz + model->boundingSphere.vz; + + short leafIdx = world_leafAtPoint(world, &pos); + if (leafIdx >= 0) + { + ps1bsp_leaf_t *leaf = (ps1bsp_leaf_t*)&world->leaves[leafIdx]; + model->nextModel = leaf->models; + leaf->models = model; + } + } +} + 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 @@ -266,6 +311,7 @@ static ps1bsp_leaf_t *world_sortLeafs(const world_t *world, short startNode, u_c // 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]; leaf->nextLeaf = firstLeaf; + leaf->models = NULL; firstLeaf = leaf; continue; } @@ -333,21 +379,6 @@ static u_char *world_noVisData(const world_t *world, u_char **buffer) return head; } -static u_short world_leafAtPoint(const world_t *world, const VECTOR *point) -{ - short nodeIdx = 0; - while (nodeIdx >= 0) - { - const ps1bsp_node_t *node = &world->nodes[nodeIdx]; - const ps1bsp_plane_t *plane = &world->planes[node->planeId]; - - short dist = world_pointPlaneDist(point, plane); - nodeIdx = node->children[(dist > 0) ^ 1]; - } - - return ~nodeIdx; -} - void world_draw(const world_t *world) { // The world doesn't move, so we just set the camera view-projection matrix @@ -360,12 +391,14 @@ void world_draw(const world_t *world) u_char *pvs = world_loadVisData(world, cam_leaf, &pvsbuf); //u_char *pvs = world_noVisData(world, &pvsbuf); + ps1bsp_leaf_t *firstLeaf = world_sortLeafs(world, world->models[0].nodeId0, pvs); + world_sortModels(world); + ps1bsp_face_t *firstFace = world_sortFaces(world, firstLeaf); + if (enableTexturing) world_drawface = &world_drawface_textured; else world_drawface = &world_drawface_lit; - ps1bsp_leaf_t *firstLeaf = world_sortLeafs(world, world->models[0].nodeId0, pvs); - ps1bsp_face_t *firstFace = world_sortFaces(world, firstLeaf); world_drawFaces(world, firstFace); }