fix phong calculation

obj output adjustment
This commit is contained in:
Jonathan 2022-09-21 05:35:11 -04:00
parent addf621074
commit 25cbbd42aa
2 changed files with 28 additions and 25 deletions

View File

@ -200,7 +200,7 @@ static faceextents_t get_face_extents(const mbsp_t &bsp, const bspxentries_t &bs
(float)nth_bit(reinterpret_cast<const char *>(bspx.at("LMSHIFT").data())[&face - bsp.dfaces.data()])}; (float)nth_bit(reinterpret_cast<const char *>(bspx.at("LMSHIFT").data())[&face - bsp.dfaces.data()])};
} }
static json generate_lightmap_atlases(const mbsp_t &bsp, const bspxentries_t &bspx, bool use_bspx) static void export_obj_and_lightmaps(const mbsp_t &bsp, const bspxentries_t &bspx, bool use_bspx, fs::path obj_path, fs::path lightmaps_path)
{ {
struct face_rect struct face_rect
{ {
@ -249,7 +249,7 @@ static json generate_lightmap_atlases(const mbsp_t &bsp, const bspxentries_t &bs
} }
if (!rectangles.size()) { if (!rectangles.size()) {
return nullptr; return;
} }
// sort faces // sort faces
@ -326,8 +326,6 @@ static json generate_lightmap_atlases(const mbsp_t &bsp, const bspxentries_t &bs
full_atlas.height = full_atlas.meta.height = trimmed_height; full_atlas.height = full_atlas.meta.height = trimmed_height;
full_atlas.pixels.resize(full_atlas.width * full_atlas.height); full_atlas.pixels.resize(full_atlas.width * full_atlas.height);
json obj = json::object();
// compile all of the styles that are available // compile all of the styles that are available
// TODO: LMSTYLE16 // TODO: LMSTYLE16
for (size_t i = 0; i < INVALID_LIGHTSTYLE_OLD - 1; i++) { for (size_t i = 0; i < INVALID_LIGHTSTYLE_OLD - 1; i++) {
@ -375,11 +373,16 @@ static json generate_lightmap_atlases(const mbsp_t &bsp, const bspxentries_t &bs
continue; continue;
} }
obj.emplace(std::to_string(i), serialize_image(full_atlas)); lightmaps_path.replace_filename(lightmaps_path.stem().string() + "_" + std::to_string(i) + ".png");
std::ofstream strm(lightmaps_path, std::ofstream::out | std::ofstream::binary);
stbi_write_png_to_func([](void *context, void *data, int size) {
std::ofstream &strm = *((std::ofstream *) context);
strm.write((const char *) data, size);
}, &strm, full_atlas.width, full_atlas.height, 4, full_atlas.pixels.data(), full_atlas.width * 4);
memset(full_atlas.pixels.data(), 0, sizeof(*full_atlas.pixels.data()) * full_atlas.pixels.size()); memset(full_atlas.pixels.data(), 0, sizeof(*full_atlas.pixels.data()) * full_atlas.pixels.size());
} }
auto ExportObjFace = [&full_atlas](std::iostream &f, const mbsp_t *bsp, const face_rect &face, int &vertcount) { auto ExportObjFace = [&full_atlas](std::ostream &f, const mbsp_t *bsp, const face_rect &face, int &vertcount) {
// export the vertices and uvs // export the vertices and uvs
for (int i = 0; i < face.face->numedges; i++) { for (int i = 0; i < face.face->numedges; i++) {
const int vertnum = Face_VertexAtIndex(bsp, face.face, i); const int vertnum = Face_VertexAtIndex(bsp, face.face, i);
@ -412,20 +415,16 @@ static json generate_lightmap_atlases(const mbsp_t &bsp, const bspxentries_t &bs
vertcount += face.face->numedges; vertcount += face.face->numedges;
}; };
auto ExportObj = [&ExportObjFace, &rectangles](const mbsp_t *bsp) { auto ExportObj = [&ExportObjFace, &rectangles, &obj_path](const mbsp_t *bsp) {
std::stringstream objfile; std::ofstream objstream(obj_path, std::ofstream::out);
int vertcount = 0; int vertcount = 0;
for (auto &rect : rectangles) { for (auto &rect : rectangles) {
ExportObjFace(objfile, bsp, rect, vertcount); ExportObjFace(objstream, bsp, rect, vertcount);
} }
return objfile.str();
}; };
obj.emplace("obj", ExportObj(&bsp)); ExportObj(&bsp);
return obj;
} }
void serialize_bsp(const bspdata_t &bspdata, const mbsp_t &bsp, const fs::path &name) void serialize_bsp(const bspdata_t &bspdata, const mbsp_t &bsp, const fs::path &name)
@ -684,6 +683,7 @@ void serialize_bsp(const bspdata_t &bspdata, const mbsp_t &bsp, const fs::path &
} }
// lightmap atlas // lightmap atlas
#if 0
for (int32_t i = 0; i < MAXLIGHTMAPS; i++) { for (int32_t i = 0; i < MAXLIGHTMAPS; i++) {
if (auto lm = generate_lightmap_atlases(bsp, bspdata.bspx.entries, false); !lm.empty()) { if (auto lm = generate_lightmap_atlases(bsp, bspdata.bspx.entries, false); !lm.empty()) {
j.emplace("lightmaps", std::move(lm)); j.emplace("lightmaps", std::move(lm));
@ -695,6 +695,8 @@ void serialize_bsp(const bspdata_t &bspdata, const mbsp_t &bsp, const fs::path &
} }
} }
} }
#endif
export_obj_and_lightmaps(bsp, bspdata.bspx.entries, false, fs::path(name).replace_extension(".geometry.obj"), fs::path(name).replace_extension(".lm.png"));
std::ofstream(name, std::fstream::out | std::fstream::trunc) << std::setw(4) << j; std::ofstream(name, std::fstream::out | std::fstream::trunc) << std::setw(4) << j;
} }

View File

@ -525,13 +525,6 @@ void CalculateVertexNormals(const mbsp_t *bsp)
return; return;
} }
auto neighboursIt = smoothFaces.find(&f);
if (neighboursIt == smoothFaces.end()) {
return;
}
const auto &neighboursToSmooth = neighboursIt->second;
const qvec3f f_norm = Face_Normal(bsp, &f); // get the face normal const qvec3f f_norm = Face_Normal(bsp, &f); // get the face normal
// face tangent // face tangent
@ -541,7 +534,12 @@ void CalculateVertexNormals(const mbsp_t *bsp)
// gather up f and neighboursToSmooth // gather up f and neighboursToSmooth
std::vector<const mface_t *> fPlusNeighbours; std::vector<const mface_t *> fPlusNeighbours;
fPlusNeighbours.push_back(&f); fPlusNeighbours.push_back(&f);
std::copy(neighboursToSmooth.begin(), neighboursToSmooth.end(), std::back_inserter(fPlusNeighbours)); auto neighboursIt = smoothFaces.find(&f);
if (neighboursIt != smoothFaces.end()) {
const auto &neighboursToSmooth = neighboursIt->second;
std::copy(neighboursToSmooth.begin(), neighboursToSmooth.end(), std::back_inserter(fPlusNeighbours));
}
// global vertex index -> smoothed normal // global vertex index -> smoothed normal
std::unordered_map<int, face_normal_t> smoothedNormals; std::unordered_map<int, face_normal_t> smoothedNormals;
@ -618,9 +616,12 @@ void CalculateVertexNormals(const mbsp_t *bsp)
} }
// sanity check // sanity check
if (!neighboursToSmooth.size()) { if (neighboursIt != smoothFaces.end()) {
for (auto &vertIndexNormalPair : smoothedNormals) { const auto &neighboursToSmooth = neighboursIt->second;
Q_assert(qv::epsilonEqual(vertIndexNormalPair.second.normal, f_norm, (float)EQUAL_EPSILON)); if (!neighboursToSmooth.size()) {
for (auto &vertIndexNormalPair : smoothedNormals) {
Q_assert(qv::epsilonEqual(vertIndexNormalPair.second.normal, f_norm, (float)EQUAL_EPSILON));
}
} }
} }