parent
addf621074
commit
25cbbd42aa
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue