diff --git a/main.cpp b/main.cpp index 0c04fcd..ed7ab0e 100644 --- a/main.cpp +++ b/main.cpp @@ -112,7 +112,6 @@ int process_faces(const world_t* world, const std::vector& tex std::vector outFaces; std::vector outFaceVertices; FaceBounds faceBounds; - VertexFaces vertexFaces; for (int faceIdx = 0; faceIdx < world->numFaces; ++faceIdx) { face_t* face = &world->faces[faceIdx]; @@ -126,6 +125,9 @@ int process_faces(const world_t* world, const std::vector& tex outFace.firstFaceVertex = (unsigned short)outFaceVertices.size(); outFace.textureId = (unsigned char)texinfo->texture_id; + float minS = FLT_MAX, minT = FLT_MAX; + float maxS = FLT_MIN, maxT = FLT_MIN; + // Traverse the list of face edges to collect all of the face's vertices Vec3 vertexSum; BoundBox bounds; @@ -140,19 +142,11 @@ int process_faces(const world_t* world, const std::vector& tex const vertex_t* vertex = &world->vertices[vertIndex]; Vec3 vertexPoint = vertex->toVec(); - ps1bsp_facevertex_t faceVertex = { 0 }; - faceVertex.index = vertIndex; - faceVertex.light = 0; - - // Calculate texture UVs + // Calculate texture UV bounds float s = (vertexPoint.dotProduct(texinfo->vectorS) + texinfo->distS) / miptex->width; float t = (vertexPoint.dotProduct(texinfo->vectorT) + texinfo->distT) / miptex->height; - - // Rescale the UVs to the dimensions of the mipmap we've selected for our texture atlas - faceVertex.u = (unsigned char)(fmodf(s * ps1tex.w, ps1tex.w)); // TODO: fmodf is a nasty fudge to deal with the lack of texture tiling on PS1 hardware - faceVertex.v = (unsigned char)(fmodf(t * ps1tex.h, ps1tex.h)); // We'll need to break up the faces and manually tile I guess... - - outFaceVertices.push_back(faceVertex); + if (s > maxS) maxS = s; if (s < minS) minS = s; + if (t > maxT) maxT = t; if (t < minT) minT = t; // Calculate bounding box of this face if (edgeListIdx == 0) @@ -160,16 +154,39 @@ int process_faces(const world_t* world, const std::vector& tex else bounds.includePoint(vertexPoint); - auto vertexIter = vertexFaces.find(vertex); - if (vertexIter == vertexFaces.end()) - vertexFaces[vertex] = std::unordered_set{ face }; - else - vertexIter->second.insert(face); - // Sum all vertices to calculate an average center point vertexSum = vertexSum + vertexPoint; } + // Go over the edges again to fudge some UVs for the vertices (this second pass is only necessary because we don't have texture tiling yet) + for (int edgeListIdx = 0; edgeListIdx < face->ledge_num; ++edgeListIdx) + { + int edgeIdx = world->edgeList[face->ledge_id + edgeListIdx]; + + unsigned short vertIndex = edgeIdx > 0 ? + world->edges[edgeIdx].vertex0 : + world->edges[-edgeIdx].vertex1; + + const vertex_t* vertex = &world->vertices[vertIndex]; + Vec3 vertexPoint = vertex->toVec(); + + ps1bsp_facevertex_t faceVertex = { 0 }; + faceVertex.index = vertIndex; + faceVertex.light = 0; + + // Calculate texture UVs + float s = (vertexPoint.dotProduct(texinfo->vectorS) + texinfo->distS) / miptex->width; + float t = (vertexPoint.dotProduct(texinfo->vectorT) + texinfo->distT) / miptex->height; + s = (s - minS) / (maxS - minS); + t = (t - minT) / (maxT - minT); + + // Rescale the UVs to the dimensions of the mipmap we've selected for our texture atlas + faceVertex.u = (unsigned char)(s * ps1tex.w); + faceVertex.v = (unsigned char)(t * ps1tex.h); + + outFaceVertices.push_back(faceVertex); + } + faceBounds[face] = bounds; // For visualizing and debugging lightmaps @@ -183,8 +200,6 @@ int process_faces(const world_t* world, const std::vector& tex outFaces.push_back(outFace); } - SurfaceList surfaces = group_surfaces(world, vertexFaces); - // Iterate over all faces again; now that we know the bounds of each face, we can calculate lighting for all of them for (int faceIdx = 0; faceIdx < world->numFaces; ++faceIdx) { @@ -197,6 +212,9 @@ int process_faces(const world_t* world, const std::vector& tex ps1bsp_facevertex_t& faceVertex = outFaceVertices[outFace.firstFaceVertex + faceVertIdx]; const vertex_t* vertex = &world->vertices[faceVertex.index]; faceVertex.light = compute_faceVertex_light4(world, face, faceBounds, vertex->toVec()); + faceVertex.light <<= 1; + if (faceVertex.light > 255) + faceVertex.light = 255; } }