|
|
|
@ -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); |
|
|
|
} |