diff --git a/main.cpp b/main.cpp index d61f768..545b7e3 100644 --- a/main.cpp +++ b/main.cpp @@ -225,20 +225,20 @@ static void export_lightmap(const world_t* world, const face_t* face, const Boun case 0: case 3: // Towards X - width = ceil(bounds.max.y / 16) - floor(bounds.min.y / 16); - height = ceil(bounds.max.z / 16) - floor(bounds.min.z / 16); + width = (int)(ceil(bounds.max.y / 16) - floor(bounds.min.y / 16)); + height = (int)(ceil(bounds.max.z / 16) - floor(bounds.min.z / 16)); break; case 1: case 4: // Towards Y - width = ceil(bounds.max.x / 16) - floor(bounds.min.x / 16); - height = ceil(bounds.max.z / 16) - floor(bounds.min.z / 16); + width = (int)(ceil(bounds.max.x / 16) - floor(bounds.min.x / 16)); + height = (int)(ceil(bounds.max.z / 16) - floor(bounds.min.z / 16)); break; case 2: case 5: // Towards Z - width = ceil(bounds.max.x / 16) - floor(bounds.min.x / 16); - height = ceil(bounds.max.y / 16) - floor(bounds.min.y / 16); + width = (int)(ceil(bounds.max.x / 16) - floor(bounds.min.x / 16)); + height = (int)(ceil(bounds.max.y / 16) - floor(bounds.min.y / 16)); break; default: printf("Error: unknown plane type %d\n", plane->type); @@ -297,23 +297,18 @@ int process_faces(const world_t* world) outVertex.y = (short)(inVertex->Y * 4); outVertex.z = (short)(inVertex->Z * 4); } - outVertex.baseLight = 0; - outVertex.finalLight = 0; - outVertex.r = 0; outVertices.push_back(outVertex); } - std::vector outTriangles; std::vector outFaces; - - std::vector faceVertIndices; + std::vector outFaceVertices; for (int faceIdx = 0; faceIdx < world->numFaces; ++faceIdx) { face_t* face = &world->faces[faceIdx]; ps1bsp_face_t outFace = { 0 }; - outFace.firstVertexIndex = faceVertIndices.size(); + outFace.firstFaceVertex = (unsigned short)outFaceVertices.size(); // Traverse the list of face edges to collect all of the face's vertices BoundBox bounds; @@ -325,7 +320,10 @@ int process_faces(const world_t* world) world->edges[edgeIdx].vertex0 : world->edges[-edgeIdx].vertex1; - faceVertIndices.push_back(vertIndex); + ps1bsp_facevertex_t faceVertex; + faceVertex.index = vertIndex; + faceVertex.light = 0; + outFaceVertices.push_back(faceVertex); // Calculate bounding box of this face const vertex_t* vertex = &world->vertices[vertIndex]; @@ -335,15 +333,18 @@ int process_faces(const world_t* world) bounds.includePoint(vertex->toVec()); } - // Accumulate lightmap contribution of this face on each vertex - if (face->lightmap >= 0) + // Sample lightmap contribution of this face on each vertex + for (size_t faceVertIdx = outFace.firstFaceVertex; faceVertIdx < outFaceVertices.size(); ++faceVertIdx) { - for (int indexIdx = outFace.firstVertexIndex; indexIdx < faceVertIndices.size(); ++indexIdx) + ps1bsp_facevertex_t& faceVertex = outFaceVertices[faceVertIdx]; + unsigned char lightmap = sample_lightmap(world, face, bounds, world->vertices[faceVertex.index].toVec()); + faceVertex.light = lightmap + (0xFF - face->baselight); + + if (face->lightmap >= 0) { - int vertIndex = faceVertIndices[indexIdx]; - unsigned char light = sample_lightmap(world, face, bounds, world->vertices[vertIndex].toVec()); - *(unsigned short*)(&outVertices[vertIndex].baseLight) += light + (0xFF - face->baselight); - outVertices[vertIndex].r++; + ps1bsp_vertex_t& vertex = outVertices[faceVertex.index]; + *(unsigned short*)(&vertex.baseLight) += faceVertex.light; + vertex.r++; } } @@ -351,11 +352,11 @@ int process_faces(const world_t* world) //if (face->ledge_num >= 10) // export_lightmap(world, face, bounds, faceIdx); - outFace.numVertices = faceVertIndices.size() - outFace.firstVertexIndex; + outFace.numFaceVertices = (unsigned short)(outFaceVertices.size() - outFace.firstFaceVertex); outFaces.push_back(outFace); } - // Average the lightmap values for this vertex + // Average the lightmap values for each vertex for (auto iter = outVertices.begin(); iter != outVertices.end(); ++iter) { unsigned char count = (*iter).r; @@ -369,20 +370,20 @@ int process_faces(const world_t* world) // Write triangle and face data to file fwrite(outVertices.data(), sizeof(ps1bsp_vertex_t), outVertices.size(), fbsp); - fwrite(faceVertIndices.data(), sizeof(unsigned short), faceVertIndices.size(), fbsp); + fwrite(outFaceVertices.data(), sizeof(ps1bsp_facevertex_t), outFaceVertices.size(), fbsp); fwrite(outFaces.data(), sizeof(ps1bsp_face_t), outFaces.size(), fbsp); // Update header information - outHeader.numVertices = outVertices.size(); - outHeader.numFaceVertIndices = faceVertIndices.size(); - outHeader.numFaces = outFaces.size(); + outHeader.numVertices = (unsigned short)outVertices.size(); + outHeader.numFaceVertices = (unsigned short)outFaceVertices.size(); + outHeader.numFaces = (unsigned short)outFaces.size(); // Write final header fseek(fbsp, 0, SEEK_SET); fwrite(&outHeader, sizeof(ps1bsp_header_t), 1, fbsp); fclose(fbsp); - printf("PS1BSP: wrote %d vertices, %d indices, %d faces\n", outHeader.numVertices, outHeader.numFaceVertIndices, outHeader.numFaces); + printf("PS1BSP: wrote %d vertices, %d indices, %d faces\n", outHeader.numVertices, outHeader.numFaceVertices, outHeader.numFaces); return 1; } diff --git a/ps1bsp.h b/ps1bsp.h index eafbc55..b1e27d3 100644 --- a/ps1bsp.h +++ b/ps1bsp.h @@ -22,7 +22,7 @@ Probable rendering process: typedef struct { unsigned short numVertices; - unsigned short numFaceVertIndices; + unsigned short numFaceVertices; unsigned short numFaces; } ps1bsp_header_t; @@ -51,19 +51,16 @@ typedef struct unsigned char b : 5; } ps1bsp_vertex_t; -// Instead of edges as in the original BSP format, we store triangles for easy consumption by the PS1 -// Note: it may actually be more efficient to render quads for faces with 4+ vertices typedef struct { - unsigned short vertex0; - unsigned short vertex1; - unsigned short vertex2; -} ps1bsp_triangle_t; + unsigned short index; + unsigned char light; +} ps1bsp_facevertex_t; typedef struct { - unsigned short firstVertexIndex; - unsigned short numVertices; + unsigned short firstFaceVertex; + unsigned short numFaceVertices; } ps1bsp_face_t; // Pre-parsed and encoded entity data (this runs the risk of becoming too bloated)