Skip to content

Commit

Permalink
Try to fix opengl issue. Added feature "Remove face"
Browse files Browse the repository at this point in the history
  • Loading branch information
UnrealKaraulov committed Dec 28, 2023
1 parent a2de2a1 commit 7e25506
Show file tree
Hide file tree
Showing 9 changed files with 290 additions and 115 deletions.
145 changes: 130 additions & 15 deletions src/bsp/Bsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2114,7 +2114,7 @@ STRUCTCOUNT Bsp::remove_unused_model_structures(unsigned int target)
{
nodes[i].iPlane = remap.planes[nodes[i].iPlane];
if (nodes[i].nFaces > 0)
nodes[i].firstFace = remap.faces[nodes[i].firstFace];
nodes[i].iFirstFace = remap.faces[nodes[i].iFirstFace];
for (int k = 0; k < 2; k++)
{
if (nodes[i].iChildren[k] >= 0)
Expand Down Expand Up @@ -2882,7 +2882,7 @@ void Bsp::write(const std::string& path)
freenodes16[n].iChildren[1] = (short)nodes[n].iChildren[1];
freenodes16[n].iPlane = nodes[n].iPlane;

freenodes16[n].firstFace = (unsigned short)nodes[n].firstFace;
freenodes16[n].firstFace = (unsigned short)nodes[n].iFirstFace;
freenodes16[n].nFaces = (unsigned short)nodes[n].nFaces;
for (int m = 0; m < 3; m++)
{
Expand All @@ -2902,7 +2902,7 @@ void Bsp::write(const std::string& path)
freenodes32a[n].iChildren[1] = nodes[n].iChildren[1];
freenodes32a[n].iPlane = nodes[n].iPlane;

freenodes32a[n].firstFace = nodes[n].firstFace;
freenodes32a[n].firstFace = nodes[n].iFirstFace;
freenodes32a[n].nFaces = nodes[n].nFaces;
for (int m = 0; m < 3; m++)
{
Expand Down Expand Up @@ -3385,7 +3385,7 @@ bool Bsp::load_lumps(std::string fpath)

for (int n = 0; n < nodeCount; n++)
{
tmpnodes[n].firstFace = nodes16[n].firstFace;
tmpnodes[n].iFirstFace = nodes16[n].firstFace;
tmpnodes[n].iChildren[0] = nodes16[n].iChildren[0];
tmpnodes[n].iChildren[1] = nodes16[n].iChildren[1];
tmpnodes[n].iPlane = nodes16[n].iPlane;
Expand Down Expand Up @@ -3426,7 +3426,7 @@ bool Bsp::load_lumps(std::string fpath)

for (int n = 0; n < nodeCount; n++)
{
tmpnodes[n].firstFace = nodes16[n].firstFace;
tmpnodes[n].iFirstFace = nodes16[n].firstFace;
tmpnodes[n].iChildren[0] = nodes16[n].iChildren[0];
tmpnodes[n].iChildren[1] = nodes16[n].iChildren[1];
tmpnodes[n].iPlane = nodes16[n].iPlane;
Expand Down Expand Up @@ -4090,7 +4090,7 @@ bool Bsp::validate()
}
for (int i = 0; i < leafCount; i++)
{
if (leaves[i].nMarkSurfaces > 0 && leaves[i].iFirstMarkSurface >= marksurfCount)
if (leaves[i].nMarkSurfaces > 0 && leaves[i].iFirstMarkSurface + leaves[i].nMarkSurfaces > marksurfCount)
{
print_log(PRINT_RED | PRINT_INTENSITY, get_localized_string(LANG_0117), i, leaves[i].iFirstMarkSurface, marksurfCount);
isValid = false;
Expand Down Expand Up @@ -4125,9 +4125,9 @@ bool Bsp::validate()
}
for (int i = 0; i < nodeCount; i++)
{
if (nodes[i].nFaces > 0 && nodes[i].firstFace >= faceCount)
if (nodes[i].nFaces > 0 && nodes[i].iFirstFace >= faceCount)
{
print_log(PRINT_RED | PRINT_INTENSITY, get_localized_string(LANG_0120), i, nodes[i].firstFace, faceCount);
print_log(PRINT_RED | PRINT_INTENSITY, get_localized_string(LANG_0120), i, nodes[i].iFirstFace, faceCount);
isValid = false;
}
if (nodes[i].iPlane >= planeCount)
Expand Down Expand Up @@ -4738,7 +4738,7 @@ void Bsp::mark_node_structures(int iNode, STRUCTUSAGE* usage, bool skipLeaves)

for (int i = 0; i < node.nFaces; i++)
{
mark_face_structures(node.firstFace + i, usage);
mark_face_structures(node.iFirstFace + i, usage);
}

for (int i = 0; i < 2; i++)
Expand Down Expand Up @@ -4844,7 +4844,7 @@ void Bsp::remap_node_structures(int iNode, STRUCTREMAP* remap)

for (int i = 0; i < node.nFaces; i++)
{
remap_face_structures(node.firstFace + i, remap);
remap_face_structures(node.iFirstFace + i, remap);
}

for (int i = 0; i < 2; i++)
Expand Down Expand Up @@ -5796,7 +5796,7 @@ void Bsp::create_node_box(const vec3& min, const vec3& max, BSPMODEL* targetMode
{
BSPNODE32& node = newNodes[nodeCount + k];

node.firstFace = (startFace + k); // face required for decals
node.iFirstFace = (startFace + k); // face required for decals
node.nFaces = 1;
node.iPlane = startPlane + k;
// node mins/maxs don't matter for submodels. Leave them at 0.
Expand Down Expand Up @@ -5979,7 +5979,7 @@ void Bsp::create_nodes(Solid& solid, BSPMODEL* targetModel)
{
BSPNODE32& node = newNodes[nodeCount + k];

node.firstFace = (startFace + k); // face required for decals
node.iFirstFace = (startFace + k); // face required for decals
node.nFaces = 1;
node.iPlane = startPlane + k;
// node mins/maxs don't matter for submodels. Leave them at 0.
Expand Down Expand Up @@ -6320,7 +6320,7 @@ void Bsp::copy_bsp_model(int modelIdx, Bsp* targetMap, STRUCTREMAP& remap, std::
for (size_t i = 0; i < newNodes.size(); i++)
{
BSPNODE32& node = newNodes[i];
node.firstFace = remap.faces[node.firstFace];
node.iFirstFace = remap.faces[node.iFirstFace];
node.iPlane = remap.planes[node.iPlane];

for (int k = 0; k < 2; k++)
Expand Down Expand Up @@ -6486,6 +6486,121 @@ int Bsp::duplicate_model(int modelIdx)
return newModelIdx;
}

bool Bsp::remove_face(int faceIdx, bool onlyleafs)
{
// Check if face is valid
if (faceIdx < 0 || faceIdx >= faceCount)
{
return false;
}

int leafFaceTarget = -1;

if (onlyleafs)
{
leafFaceTarget = faceIdx;
}
else
{
print_log("Remove face with id:{}\n", faceIdx);
std::vector<BSPFACE32> all_faces;
for (int f = 0; f < faceCount; f++)
{
if (f != faceIdx)
{
all_faces.push_back(faces[f]);
}
else
{
// Shift face count in models
for (int m = 0; m < modelCount; m++)
{
if (models[m].nFaces == 0)
continue;
if (faceIdx >= models[m].iFirstFace && faceIdx < models[m].iFirstFace + models[m].nFaces)
{
print_log("Remove face from {} model\n", m);
models[m].nFaces--;
}
else if (models[m].iFirstFace != 0 && models[m].iFirstFace > faceIdx)
{
models[m].iFirstFace--;
}
}

// Shift face count in nodes
for (int n = 0; n < nodeCount; n++)
{
if (nodes[n].nFaces == 0)
continue;
if (faceIdx >= nodes[n].iFirstFace && faceIdx < nodes[n].iFirstFace + nodes[n].nFaces)
{
print_log("Remove face from {} node\n", n);
nodes[n].nFaces--;
}
else if (nodes[n].iFirstFace != 0 && nodes[n].iFirstFace > faceIdx)
{
nodes[n].iFirstFace--;
}
}

//Shift face count in marksurfs
for (int s = 0; s < marksurfCount; s++)
{
if (marksurfs[s] == 0)
continue;

if (faceIdx == marksurfs[s])
{
print_log("Remove face from {} surface\n", s);
marksurfs[s] = leafFaceTarget;
}
else if (marksurfs[s] != 0 && marksurfs[s] > faceIdx)
{
marksurfs[s]--;
}
}
}
}

// Update faces array
unsigned char* newLump = new unsigned char[sizeof(BSPFACE32) * all_faces.size()];
memcpy(newLump, &all_faces[0], sizeof(BSPFACE32) * all_faces.size());
replace_lump(LUMP_FACES, newLump, sizeof(BSPFACE32) * all_faces.size());
}

std::vector<int> all_mark_surfaces;
for (int s = 0; s < marksurfCount; s++)
{
if (marksurfs[s] != leafFaceTarget)
{
all_mark_surfaces.push_back(marksurfs[s]);
}
else
{
for (int m = 0; m < leafCount; m++)
{
if (leaves[m].nMarkSurfaces == 0)
continue;
if (s >= leaves[m].iFirstMarkSurface && s < leaves[m].iFirstMarkSurface + leaves[m].nMarkSurfaces)
{
print_log("Remove face {} from {} leaf\n", faceIdx, m);
leaves[m].nMarkSurfaces--;
}
else if (leaves[m].iFirstMarkSurface != 0 && leaves[m].iFirstMarkSurface > s)
{
leaves[m].iFirstMarkSurface--;
}
}
}
}

unsigned char *newLump = new unsigned char[sizeof(int) * all_mark_surfaces.size()];
memcpy(newLump, &all_mark_surfaces[0], sizeof(int) * all_mark_surfaces.size());
replace_lump(LUMP_MARKSURFACES, newLump, sizeof(int) * all_mark_surfaces.size());
return true;
}

int Bsp::merge_two_models(int src_model, int dst_model)
{
if (models[dst_model].iFirstFace > models[src_model].iFirstFace)
Expand Down Expand Up @@ -6517,9 +6632,9 @@ int Bsp::merge_two_models(int src_model, int dst_model)

for (int m = 0; m < nodeCount; m++)
{
if (nodes[m].firstFace >= models[dst_model].iFirstFace + models[dst_model].nFaces)
if (nodes[m].iFirstFace >= models[dst_model].iFirstFace + models[dst_model].nFaces)
{
nodes[m].firstFace += newfaces;
nodes[m].iFirstFace += newfaces;
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/bsp/Bsp.h
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,8 @@ class Bsp

int duplicate_model(int modelIdx);
void duplicate_model_structures(int modelIdx);

bool remove_face(int faceid, bool onlyleafs = false);
int merge_two_models(int src_model, int dst_model);

// if the face's texinfo is not unique, a new one is created and returned. Otherwise, it's current texinfo is returned
Expand Down
6 changes: 3 additions & 3 deletions src/bsp/BspMerger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1566,9 +1566,9 @@ void BspMerger::merge_nodes(Bsp& mapA, Bsp& mapB)
}
}
}
if (node.nFaces && node.firstFace >= thisWorldFaceCount)
if (node.nFaces && node.iFirstFace >= thisWorldFaceCount)
{
node.firstFace += otherFaceCount;
node.iFirstFace += otherFaceCount;
}

mergedNodes.push_back(node);
Expand All @@ -1593,7 +1593,7 @@ void BspMerger::merge_nodes(Bsp& mapA, Bsp& mapB)
node.iPlane = planeRemap[node.iPlane];
if (node.nFaces)
{
node.firstFace += thisWorldFaceCount;
node.iFirstFace += thisWorldFaceCount;
}

mergedNodes.push_back(node);
Expand Down
Loading

0 comments on commit 7e25506

Please sign in to comment.