From 015efc89e056f86b9b0401df80476f0419c9ca89 Mon Sep 17 00:00:00 2001 From: Karaulov Date: Tue, 22 Nov 2022 23:27:04 +0300 Subject: [PATCH] Now can open multiple maps Remove old code. Now use only filesystem. Added Windows menu item. Now support multiple maps. --- CMakeLists.txt | 1 - src/bsp/Bsp.cpp | 55 +++++++++------- src/bsp/Bsp.h | 6 ++ src/bsp/remap.h | 2 +- src/editor/BspRenderer.cpp | 64 ++++++++++-------- src/editor/Gui.cpp | 132 ++++++++++++++++++++++--------------- src/editor/Renderer.cpp | 48 ++++++++++---- src/main.cpp | 6 +- src/util/util.cpp | 71 -------------------- src/util/util.h | 12 ---- vs-project/bspguy.vcxproj | 6 +- 11 files changed, 194 insertions(+), 209 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e56fa27..104aa4e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -205,7 +205,6 @@ else() set (CMAKE_CXX_STANDARD 17) set (CMAKE_CXX_STANDARD_REQUIRED ON) endif () - add_definitions(-DUSE_FILESYSTEM) set(CMAKE_CXX_FLAGS "-Wall -std=c++17") set(CMAKE_CXX_FLAGS_DEBUG "-g -O0") set(CMAKE_CXX_FLAGS_RELEASE "-Os -fno-exceptions -w -Wfatal-errors") diff --git a/src/bsp/Bsp.cpp b/src/bsp/Bsp.cpp index 4919a82b..daa6bbb7 100644 --- a/src/bsp/Bsp.cpp +++ b/src/bsp/Bsp.cpp @@ -2703,7 +2703,7 @@ bool Bsp::validate() isValid = false; } if (visDataLength > 0 && - leaves[i].nVisOffset != (unsigned int)-1 && (leaves[i].nVisOffset < 0 || (unsigned int)leaves[i].nVisOffset >= visDataLength)) + leaves[i].nVisOffset != -1 && (leaves[i].nVisOffset < 0 || leaves[i].nVisOffset >= visDataLength)) { logf("Bad vis offset in leaf %d: %d / %d\n", i, leaves[i].nVisOffset, visDataLength); isValid = false; @@ -2734,12 +2734,12 @@ bool Bsp::validate() } for (unsigned int k = 0; k < 2; k++) { - if (nodes[i].iChildren[k] != (unsigned int)-1 && nodes[i].iChildren[k] > 0 && (unsigned int)nodes[i].iChildren[k] >= nodeCount) + if (nodes[i].iChildren[k] != -1 && nodes[i].iChildren[k] > 0 && nodes[i].iChildren[k] >= nodeCount) { logf("Bad node reference in node %d child %d: %d / %d\n", i, k, nodes[i].iChildren[k], nodeCount); isValid = false; } - else if (~nodes[i].iChildren[k] != (unsigned int)-1 && nodes[i].iChildren[k] < 0 && (unsigned int)~nodes[i].iChildren[k] >= leafCount) + else if (~nodes[i].iChildren[k] != -1 && nodes[i].iChildren[k] < 0 && ~nodes[i].iChildren[k] >= leafCount) { logf("Bad leaf reference in ~node %d child %d: %d / %d\n", i, k, ~nodes[i].iChildren[k], leafCount); isValid = false; @@ -2748,14 +2748,14 @@ bool Bsp::validate() } for (unsigned int i = 0; i < clipnodeCount; i++) { - if (clipnodes[i].iPlane < 0 || (unsigned int)clipnodes[i].iPlane >= planeCount) + if (clipnodes[i].iPlane < 0 || clipnodes[i].iPlane >= planeCount) { logf("Bad plane reference in clipnode %d: %d / %d\n", i, clipnodes[i].iPlane, planeCount); isValid = false; } for (unsigned int k = 0; k < 2; k++) { - if (clipnodes[i].iChildren[k] > 0 && (unsigned int)clipnodes[i].iChildren[k] >= clipnodeCount) + if (clipnodes[i].iChildren[k] > 0 && clipnodes[i].iChildren[k] >= clipnodeCount) { logf("Bad clipnode reference in clipnode %d child %d: %d / %d\n", i, k, clipnodes[i].iChildren[k], clipnodeCount); isValid = false; @@ -2764,7 +2764,7 @@ bool Bsp::validate() } for (unsigned int i = 0; i < ents.size(); i++) { - if (ents[i]->getBspModelIdxForce() > 0 && (unsigned int)ents[i]->getBspModelIdxForce() >= modelCount) + if (ents[i]->getBspModelIdxForce() > 0 && ents[i]->getBspModelIdxForce() >= modelCount) { logf("Bad model reference in entity %d: %d / %d\n", i, ents[i]->getBspModelIdxForce(), modelCount); isValid = false; @@ -2891,7 +2891,7 @@ std::vector Bsp::get_sorted_model_infos(int sortMode) void Bsp::print_info(bool perModelStats, int perModelLimit, int sortMode) { - size_t entCount = ents.size(); + unsigned int entCount = (unsigned int)ents.size(); if (perModelStats) { @@ -2923,7 +2923,7 @@ void Bsp::print_info(bool perModelStats, int perModelLimit, int sortMode) logf(" Classname Targetname Model %-10s Usage\n", countName); logf("------------------------- ------------------------- ----- ---------- --------\n"); - for (unsigned int i = 0; i < modelCount && i < (unsigned int)perModelLimit; i++) + for (int i = 0; i < modelCount && i < perModelLimit; i++) { int val = 0; @@ -2959,7 +2959,7 @@ void Bsp::print_info(bool perModelStats, int perModelLimit, int sortMode) print_stat("textures", textureCount, MAX_MAP_TEXTURES, false); print_stat("lightdata", lightDataLength, MAX_MAP_LIGHTDATA, true); print_stat("visdata", visDataLength, MAX_MAP_VISDATA, true); - print_stat("entities", (unsigned int)entCount, MAX_MAP_ENTS, false); + print_stat("entities", entCount, MAX_MAP_ENTS, false); } } @@ -3392,7 +3392,7 @@ void Bsp::delete_hull(int hull_number, int redirect) void Bsp::delete_hull(int hull_number, int modelIdx, int redirect) { - if (modelIdx < 0 || (unsigned int)modelIdx >= modelCount) + if (modelIdx < 0 || modelIdx >= modelCount) { logf("Invalid model index %d. Must be 0-%d\n", modelIdx); return; @@ -4216,7 +4216,7 @@ int Bsp::create_clipnode_box(const vec3& mins, const vec3& maxs, BSPMODEL* targe void Bsp::simplify_model_collision(int modelIdx, int hullIdx) { - if (modelIdx < 0 || (unsigned int)modelIdx >= modelCount) + if (modelIdx < 0 || modelIdx >= modelCount) { logf("Invalid model index %d. Must be 0-%d\n", modelIdx); return; @@ -4308,14 +4308,16 @@ int Bsp::create_texinfo() return texinfoCount - 1; } -int Bsp::duplicate_model(int modelIdx) +void Bsp::copy_bsp_model(int modelIdx, STRUCTREMAP& remap, std::vector& newPlanes, std::vector& newVerts, + std::vector& newEdges, std::vector& newSurfedges, std::vector& newTexinfo, + std::vector& newFaces, std::vector& newLightmaps, std::vector& newNodes, + std::vector& newClipnodes) { STRUCTUSAGE usage(this); mark_model_structures(modelIdx, &usage, true); - STRUCTREMAP remap(this); + remap = STRUCTREMAP(this); - std::vector newPlanes; for (unsigned int i = 0; i < usage.count.planes; i++) { if (usage.planes[i]) @@ -4325,7 +4327,6 @@ int Bsp::duplicate_model(int modelIdx) } } - std::vector newVerts; for (unsigned int i = 0; i < usage.count.verts; i++) { if (usage.verts[i]) @@ -4335,7 +4336,6 @@ int Bsp::duplicate_model(int modelIdx) } } - std::vector newEdges; for (unsigned int i = 0; i < usage.count.edges; i++) { if (usage.edges[i]) @@ -4349,7 +4349,6 @@ int Bsp::duplicate_model(int modelIdx) } } - std::vector newSurfedges; for (unsigned int i = 0; i < usage.count.surfEdges; i++) { if (usage.surfEdges[i]) @@ -4363,7 +4362,6 @@ int Bsp::duplicate_model(int modelIdx) } } - std::vector newTexinfo; for (unsigned int i = 0; i < usage.count.texInfos; i++) { if (usage.texInfo[i]) @@ -4373,8 +4371,6 @@ int Bsp::duplicate_model(int modelIdx) } } - std::vector newFaces; - std::vector newLightmaps; int lightmapAppendSz = 0; for (unsigned int i = 0; i < usage.count.faces; i++) { @@ -4410,7 +4406,6 @@ int Bsp::duplicate_model(int modelIdx) } } - std::vector newNodes; for (unsigned int i = 0; i < usage.count.nodes; i++) { if (usage.nodes[i]) @@ -4434,7 +4429,6 @@ int Bsp::duplicate_model(int modelIdx) } } - std::vector newClipnodes; for (unsigned int i = 0; i < usage.count.clipnodes; i++) { if (usage.clipnodes[i]) @@ -4456,8 +4450,23 @@ int Bsp::duplicate_model(int modelIdx) } } } +} + +int Bsp::duplicate_model(int modelIdx) +{ + std::vector newPlanes; + std::vector newVerts; + std::vector newEdges; + std::vector newSurfedges; + std::vector newTexinfo; + std::vector newFaces; + std::vector newLightmaps; + std::vector newNodes; + std::vector newClipnodes; + + STRUCTREMAP remap = STRUCTREMAP(); - // MAYBE TODO: duplicate leaves(?) + marksurfs + recacl vis + update undo command lumps + copy_bsp_model(modelIdx, remap, newPlanes, newVerts, newEdges, newSurfedges, newTexinfo, newFaces, newLightmaps, newNodes, newClipnodes); if (newClipnodes.size()) append_lump(LUMP_CLIPNODES, &newClipnodes[0], sizeof(BSPCLIPNODE) * newClipnodes.size()); diff --git a/src/bsp/Bsp.h b/src/bsp/Bsp.h index 06da2b48..607b6bf2 100644 --- a/src/bsp/Bsp.h +++ b/src/bsp/Bsp.h @@ -53,6 +53,7 @@ class Bsp bool is_model = false; + Bsp* parentMap = NULL; void selectModelEnt(); int planeCount; @@ -198,6 +199,11 @@ class Bsp int create_model(); int create_texinfo(); + void copy_bsp_model(int modelIdx, STRUCTREMAP& remap, std::vector& newPlanes, std::vector& newVerts, + std::vector& newEdges, std::vector& newSurfedges, std::vector& newTexinfo, + std::vector& newFaces, std::vector& newLightmaps, std::vector& newNodes, + std::vector& newClipnodes); + int duplicate_model(int modelIdx); // if the face's texinfo is not unique, a new one is created and returned. Otherwise, it's current texinfo is returned diff --git a/src/bsp/remap.h b/src/bsp/remap.h index c830bad6..2bc78a81 100644 --- a/src/bsp/remap.h +++ b/src/bsp/remap.h @@ -76,7 +76,7 @@ struct STRUCTREMAP bool* visitedFaces; STRUCTCOUNT count; // size of each array - + STRUCTREMAP() = default; STRUCTREMAP(Bsp* map); ~STRUCTREMAP(); }; diff --git a/src/editor/BspRenderer.cpp b/src/editor/BspRenderer.cpp index 09cbc6c5..ea6111b1 100644 --- a/src/editor/BspRenderer.cpp +++ b/src/editor/BspRenderer.cpp @@ -837,7 +837,7 @@ bool BspRenderer::refreshModelClipnodes(int modelIdx) { return false; } - if (modelIdx < 0 || (unsigned int)modelIdx >= numRenderClipnodes) + if (modelIdx < 0 || modelIdx >= numRenderClipnodes) { logf("Bad model idx\n"); return false; @@ -1515,7 +1515,7 @@ void BspRenderer::render(int highlightEnt, bool highlightAlwaysOnTop, int clipno // draw highlighted ent first so other ent edges don't overlap the highlighted edges if (highlightEnt > 0 && !highlightAlwaysOnTop) { - if (renderEnts[highlightEnt].modelIdx >= 0 && (unsigned int)renderEnts[highlightEnt].modelIdx < map->modelCount) + if (renderEnts[highlightEnt].modelIdx >= 0 && renderEnts[highlightEnt].modelIdx < map->modelCount) { activeShader->pushMatrix(MAT_MODEL); *activeShader->modelMat = renderEnts[highlightEnt].modelMat; @@ -1537,7 +1537,7 @@ void BspRenderer::render(int highlightEnt, bool highlightAlwaysOnTop, int clipno for (size_t i = 0, sz = map->ents.size(); i < sz; i++) { - if (renderEnts[i].modelIdx >= 0 && (unsigned int)renderEnts[i].modelIdx < map->modelCount) + if (renderEnts[i].modelIdx >= 0 && renderEnts[i].modelIdx < map->modelCount) { activeShader->pushMatrix(MAT_MODEL); *activeShader->modelMat = renderEnts[i].modelMat; @@ -1570,7 +1570,7 @@ void BspRenderer::render(int highlightEnt, bool highlightAlwaysOnTop, int clipno { for (size_t i = 0, sz = map->ents.size(); i < sz; i++) { - if (renderEnts[i].modelIdx >= 0 && (unsigned int)renderEnts[i].modelIdx < map->modelCount) + if (renderEnts[i].modelIdx >= 0 && renderEnts[i].modelIdx < map->modelCount) { if (clipnodeHull == -1 && renderModels[renderEnts[i].modelIdx].groupCount > 0) { @@ -1605,7 +1605,7 @@ void BspRenderer::render(int highlightEnt, bool highlightAlwaysOnTop, int clipno { activeShader->bind(); - if (renderEnts[highlightEnt].modelIdx >= 0 && (unsigned int)renderEnts[highlightEnt].modelIdx < map->modelCount) + if (renderEnts[highlightEnt].modelIdx >= 0 && renderEnts[highlightEnt].modelIdx < map->modelCount) { activeShader->pushMatrix(MAT_MODEL); *activeShader->modelMat = renderEnts[highlightEnt].modelMat; @@ -1627,7 +1627,7 @@ void BspRenderer::render(int highlightEnt, bool highlightAlwaysOnTop, int clipno void BspRenderer::drawModel(RenderEnt* ent, bool transparent, bool highlight, bool edgesOnly) { int modelIdx = ent ? ent->modelIdx : 0; - if (modelIdx < 0 || (unsigned int)modelIdx >= numRenderModels) + if (modelIdx < 0 || modelIdx >= numRenderModels) { return; } @@ -1827,7 +1827,7 @@ void BspRenderer::drawPointEntities(int highlightEnt) colorShader->popMatrix(MAT_MODEL); } -bool BspRenderer::pickPoly(vec3 start, const vec3& dir, int hullIdx, PickInfo& pickInfo) +bool BspRenderer::pickPoly(vec3 start, const vec3& dir, int hullIdx, PickInfo& tempPickInfo) { bool foundBetterPick = false; @@ -1838,21 +1838,23 @@ bool BspRenderer::pickPoly(vec3 start, const vec3& dir, int hullIdx, PickInfo& p start -= mapOffset; - if (pickModelPoly(start, dir, vec3(0, 0, 0), 0, hullIdx, pickInfo)) + if (pickModelPoly(start, dir, vec3(0, 0, 0), 0, hullIdx, tempPickInfo)) { - pickInfo.entIdx = 0; - pickInfo.modelIdx = 0; - pickInfo.map = map; - pickInfo.ent = map->ents[0]; - foundBetterPick = true; + if (tempPickInfo.map || (tempPickInfo.map && map && tempPickInfo.map == map)) + { + tempPickInfo.entIdx = 0; + tempPickInfo.modelIdx = 0; + tempPickInfo.map = map; + tempPickInfo.ent = map->ents[0]; + foundBetterPick = true; + } } int sz = (int)map->ents.size(); for (int i = 0; i < sz; i++) { - if (renderEnts[i].modelIdx >= 0 && (unsigned int)renderEnts[i].modelIdx < map->modelCount) + if (renderEnts[i].modelIdx >= 0 && renderEnts[i].modelIdx < map->modelCount) { - bool isSpecial = false; for (int k = 0; k < renderModels[renderEnts[i].modelIdx].groupCount; k++) { @@ -1872,27 +1874,33 @@ bool BspRenderer::pickPoly(vec3 start, const vec3& dir, int hullIdx, PickInfo& p continue; } - if (pickModelPoly(start, dir, renderEnts[i].offset, renderEnts[i].modelIdx, hullIdx, pickInfo)) + if (pickModelPoly(start, dir, renderEnts[i].offset, renderEnts[i].modelIdx, hullIdx, tempPickInfo)) { - pickInfo.entIdx = i; - pickInfo.modelIdx = renderEnts[i].modelIdx; - pickInfo.map = map; - pickInfo.ent = map->ents[i]; - foundBetterPick = true; + if (!tempPickInfo.map || (tempPickInfo.map && map && tempPickInfo.map == map)) + { + tempPickInfo.entIdx = i; + tempPickInfo.modelIdx = renderEnts[i].modelIdx; + tempPickInfo.map = map; + tempPickInfo.ent = map->ents[i]; + foundBetterPick = true; + } } } else if (i > 0 && g_render_flags & RENDER_POINT_ENTS) { vec3 mins = renderEnts[i].offset + renderEnts[i].pointEntCube->mins; vec3 maxs = renderEnts[i].offset + renderEnts[i].pointEntCube->maxs; - if (pickAABB(start, dir, mins, maxs, pickInfo.bestDist)) + if (pickAABB(start, dir, mins, maxs, tempPickInfo.bestDist)) { - pickInfo.entIdx = i; - pickInfo.modelIdx = -1; - pickInfo.faceIdx = -1; - pickInfo.map = map; - pickInfo.ent = map->ents[i]; - foundBetterPick = true; + if (!tempPickInfo.map || (tempPickInfo.map && map && tempPickInfo.map == map)) + { + tempPickInfo.entIdx = i; + tempPickInfo.modelIdx = -1; + tempPickInfo.faceIdx = -1; + tempPickInfo.map = map; + tempPickInfo.ent = map->ents[i]; + foundBetterPick = true; + } }; } } diff --git a/src/editor/Gui.cpp b/src/editor/Gui.cpp index 01dc3f8b..71726ad5 100644 --- a/src/editor/Gui.cpp +++ b/src/editor/Gui.cpp @@ -302,6 +302,7 @@ void ExportModel(Bsp* map, int id, int ExportType) Bsp* tmpMap = new Bsp(map->bsp_path); tmpMap->is_model = true; + tmpMap->parentMap = map; BSPMODEL tmpModel = map->models[id]; @@ -730,7 +731,7 @@ void Gui::draw3dContextMenus() { copyTexture(); } - if (ImGui::MenuItem("Paste texture", "Ctrl+V", false, copiedMiptex >= 0 && (unsigned int)copiedMiptex < map->textureCount)) + if (ImGui::MenuItem("Paste texture", "Ctrl+V", false, copiedMiptex >= 0 && copiedMiptex < map->textureCount)) { pasteTexture(); } @@ -748,7 +749,7 @@ void Gui::draw3dContextMenus() ImGui::EndTooltip(); } - if (ImGui::MenuItem("Paste lightmap", "", false, copiedLightmapFace >= 0 && (unsigned int)copiedLightmapFace < map->faceCount)) + if (ImGui::MenuItem("Paste lightmap", "", false, copiedLightmapFace >= 0 && copiedLightmapFace < map->faceCount)) { pasteLightmap(); } @@ -882,8 +883,7 @@ void Gui::drawMenuBar() if (ifd::FileDialog::Instance().HasResult()) { std::filesystem::path res = ifd::FileDialog::Instance().GetResult(); - this->app->clearMaps(); - this->app->addMap(new Bsp(res.string())); + app->addMap(new Bsp(res.string())); g_settings.lastdir = res.parent_path().string(); } ifd::FileDialog::Instance().Close(); @@ -1426,6 +1426,23 @@ void Gui::drawMenuBar() ImGui::EndMenu(); } + if (ImGui::BeginMenu("Windows")) + { + for (BspRenderer* bspRend : app->mapRenderers) + { + Bsp* selectedMap = app->getSelectedMap(); + if (bspRend->map && !bspRend->map->is_model) + { + if (ImGui::MenuItem(bspRend->map->bsp_name.c_str(), NULL, selectedMap == bspRend->map)) + { + app->clearSelection(); + app->selectMap(bspRend->map); + } + } + } + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Help")) { if (ImGui::MenuItem("View help")) @@ -1696,67 +1713,74 @@ void Gui::drawDebugWidget() } Bsp* map = app->getSelectedMap(); - Entity* ent = app->pickInfo.ent; - if (!map || !ent) - { - ImGui::Text("No map selected"); - } - else + + if (ImGui::CollapsingHeader("Map", ImGuiTreeNodeFlags_DefaultOpen)) { - if (ImGui::CollapsingHeader("Map", ImGuiTreeNodeFlags_DefaultOpen)) + if (!map) { - ImGui::Text("Name: %s", map->bsp_name.c_str()); + ImGui::Text("No map selected."); } - - if (ImGui::CollapsingHeader("Selection", ImGuiTreeNodeFlags_DefaultOpen)) + else { - ImGui::Text("Entity ID: %d", app->pickInfo.entIdx); + ImGui::Text("Name: %s", map->bsp_name.c_str()); - if (app->pickInfo.modelIdx > 0) + if (ImGui::CollapsingHeader("Selection", ImGuiTreeNodeFlags_DefaultOpen)) { - ImGui::Checkbox("Debug clipnodes", &app->debugClipnodes); - ImGui::SliderInt("Clipnode", &app->debugInt, 0, app->debugIntMax); + if (app->pickInfo.entIdx) + { + ImGui::Text("Entity ID: %d", app->pickInfo.entIdx); + } - ImGui::Checkbox("Debug nodes", &app->debugNodes); - ImGui::SliderInt("Node", &app->debugNode, 0, app->debugNodeMax); - } + if (app->pickInfo.modelIdx > 0) + { + ImGui::Checkbox("Debug clipnodes", &app->debugClipnodes); + ImGui::SliderInt("Clipnode", &app->debugInt, 0, app->debugIntMax); - if (app->pickInfo.faceIdx != -1) - { - BSPMODEL& model = map->models[app->pickInfo.modelIdx]; - BSPFACE& face = map->faces[app->pickInfo.faceIdx]; + ImGui::Checkbox("Debug nodes", &app->debugNodes); + ImGui::SliderInt("Node", &app->debugNode, 0, app->debugNodeMax); + } - ImGui::Text("Model ID: %d", app->pickInfo.modelIdx); - ImGui::Text("Model polies: %d", model.nFaces); + if (app->pickInfo.faceIdx >= 0 && app->pickInfo.faceIdx < map->faceCount) + { + BSPFACE& face = map->faces[app->pickInfo.faceIdx]; - ImGui::Text("Face ID: %d", app->pickInfo.faceIdx); - ImGui::Text("Plane ID: %d", face.iPlane); + if (app->pickInfo.modelIdx > 0) + { + BSPMODEL& model = map->models[app->pickInfo.modelIdx]; + ImGui::Text("Model ID: %d", app->pickInfo.modelIdx); - if (face.iTextureInfo < map->texinfoCount) - { - BSPTEXTUREINFO& info = map->texinfos[face.iTextureInfo]; - int texOffset = ((int*)map->textures)[info.iMiptex + 1]; - BSPMIPTEX& tex = *((BSPMIPTEX*)(map->textures + texOffset)); - ImGui::Text("Texinfo ID: %d", face.iTextureInfo); - ImGui::Text("Texture ID: %d", info.iMiptex); - ImGui::Text("Texture: %s (%dx%d)", tex.szName, tex.nWidth, tex.nHeight); - BSPPLANE& plane = map->planes[face.iPlane]; - BSPTEXTUREINFO& texinfo = map->texinfos[face.iTextureInfo]; - float anglex, angley; - vec3 xv, yv; - int val = TextureAxisFromPlane(plane, xv, yv); - ImGui::Text("Plane type %d : axis (%fx%f)", val, anglex = AngleFromTextureAxis(texinfo.vS, true, val), angley = AngleFromTextureAxis(texinfo.vT, false, val)); - ImGui::Text("Texinfo: %f/%f/%f + %f / %f/%f/%f + %f ", texinfo.vS.x, texinfo.vS.y, texinfo.vS.z, texinfo.shiftS, - texinfo.vT.x, texinfo.vT.y, texinfo.vT.z, texinfo.shiftT); - - xv = AxisFromTextureAngle(anglex, true, val); - yv = AxisFromTextureAngle(angley, false, val); - - ImGui::Text("AxisBack: %f/%f/%f + %f / %f/%f/%f + %f ", xv.x, xv.y, xv.z, texinfo.shiftS, - yv.x, yv.y, yv.z, texinfo.shiftT); + ImGui::Text("Model polies: %d", model.nFaces); + } + + ImGui::Text("Face ID: %d", app->pickInfo.faceIdx); + ImGui::Text("Plane ID: %d", face.iPlane); + if (face.iTextureInfo < map->texinfoCount) + { + BSPTEXTUREINFO& info = map->texinfos[face.iTextureInfo]; + int texOffset = ((int*)map->textures)[info.iMiptex + 1]; + BSPMIPTEX& tex = *((BSPMIPTEX*)(map->textures + texOffset)); + ImGui::Text("Texinfo ID: %d", face.iTextureInfo); + ImGui::Text("Texture ID: %d", info.iMiptex); + ImGui::Text("Texture: %s (%dx%d)", tex.szName, tex.nWidth, tex.nHeight); + BSPPLANE& plane = map->planes[face.iPlane]; + BSPTEXTUREINFO& texinfo = map->texinfos[face.iTextureInfo]; + float anglex, angley; + vec3 xv, yv; + int val = TextureAxisFromPlane(plane, xv, yv); + ImGui::Text("Plane type %d : axis (%fx%f)", val, anglex = AngleFromTextureAxis(texinfo.vS, true, val), angley = AngleFromTextureAxis(texinfo.vT, false, val)); + ImGui::Text("Texinfo: %f/%f/%f + %f / %f/%f/%f + %f ", texinfo.vS.x, texinfo.vS.y, texinfo.vS.z, texinfo.shiftS, + texinfo.vT.x, texinfo.vT.y, texinfo.vT.z, texinfo.shiftT); + + xv = AxisFromTextureAngle(anglex, true, val); + yv = AxisFromTextureAngle(angley, false, val); + + ImGui::Text("AxisBack: %f/%f/%f + %f / %f/%f/%f + %f ", xv.x, xv.y, xv.z, texinfo.shiftS, + yv.x, yv.y, yv.z, texinfo.shiftT); + + } + ImGui::Text("Lightmap Offset: %d", face.nLightmapOffset); } - ImGui::Text("Lightmap Offset: %d", face.nLightmapOffset); } } } @@ -3810,7 +3834,8 @@ void Gui::drawImportMapWidget() } else { - if (g_app->mapRenderers.size() && g_app->mapRenderers[0]->map) + Bsp* map = g_app->getSelectedMap(); + if (map) { Bsp* model = new Bsp(mapPath); if (!model->ents.size()) @@ -3819,7 +3844,6 @@ void Gui::drawImportMapWidget() } else { - Bsp* map = g_app->getSelectedMap(); logf("Binding .bsp model to func_breakable.\n"); Entity* tmpEnt = new Entity("func_breakable"); tmpEnt->setOrAddKeyvalue("gibmodel", std::string("models/") + basename(mapPath)); diff --git a/src/editor/Renderer.cpp b/src/editor/Renderer.cpp index ed96e59c..d0eadaa4 100644 --- a/src/editor/Renderer.cpp +++ b/src/editor/Renderer.cpp @@ -755,6 +755,8 @@ void Renderer::renderLoop() isLoading = reloading; + Bsp* selectedMap = getSelectedMap(); + std::set modelidskip; for (size_t i = 0; i < mapRenderers.size(); i++) { @@ -768,6 +770,11 @@ void Renderer::renderLoop() highlightEnt = pickInfo.entIdx; } + if (selectedMap && getSelectedMap() != curMap && !curMap->is_model) + { + continue; + } + if (curMap->ents.size() && !isLoading) { if (curMap->is_model) @@ -1730,17 +1737,24 @@ void Renderer::cameraContextMenus() PickInfo tempPick = PickInfo(); tempPick.bestDist = FLT_MAX_COORD; - for (int i = 0; i < mapRenderers.size(); i++) + + Bsp* map = getSelectedMap(); + + map->getBspRender()->pickPoly(pickStart, pickDir, clipnodeRenderHull, tempPick); + + if (tempPick.entIdx < 0) { - if (mapRenderers[i]->pickPoly(pickStart, pickDir, clipnodeRenderHull, tempPick)) + for (int i = 0; i < mapRenderers.size(); i++) { - + if (getSelectedMap() == mapRenderers[i]->map->parentMap && mapRenderers[i]->pickPoly(pickStart, pickDir, clipnodeRenderHull, tempPick) && tempPick.entIdx > 0) + { + break; + } } } if (tempPick.entIdx != 0 && tempPick.entIdx == pickInfo.entIdx) { - selectMap(tempPick.map); gui->openContextMenu(pickInfo.entIdx); } else @@ -1861,23 +1875,34 @@ void Renderer::globalShortcutControls() void Renderer::pickObject() { + if (!getSelectedMap()) + return; bool pointEntWasSelected = pickInfo.ent && !pickInfo.ent->isBspModel(); int oldSelectedEntIdx = pickInfo.entIdx; + Bsp* map = getSelectedMap(); vec3 pickStart, pickDir; getPickRay(pickStart, pickDir); - clearSelection(); + int oldEntIdx = pickInfo.entIdx; + clearSelection(); + selectMap(map); + pickInfo.bestDist = FLT_MAX_COORD; + map->getBspRender()->preRenderEnts(); + map->getBspRender()->pickPoly(pickStart, pickDir, clipnodeRenderHull, pickInfo); + for (int i = 0; i < mapRenderers.size(); i++) { - mapRenderers[i]->preRenderEnts(); - mapRenderers[i]->pickPoly(pickStart, pickDir, clipnodeRenderHull, pickInfo); + if (map == mapRenderers[i]->map->parentMap) + { + mapRenderers[i]->preRenderEnts(); + mapRenderers[i]->pickPoly(pickStart, pickDir, clipnodeRenderHull, pickInfo); + } } - Bsp* map = pickInfo.map; if (movingEnt && oldEntIdx != pickInfo.entIdx) { @@ -1897,7 +1922,6 @@ void Renderer::pickObject() isTransformableSolid = pickInfo.modelIdx > 0 || pickInfo.entIdx > 0; - if ((pickMode == PICK_OBJECT || !anyCtrlPressed)) { deselectFaces(); @@ -2166,7 +2190,7 @@ int Renderer::getSelectedMapId() for (int i = 0; i < mapRenderers.size(); i++) { BspRenderer* s = mapRenderers[i]; - if (s->map && s->map == pickInfo.map) + if (s->map && s->map == getSelectedMap()) { return i; } @@ -2200,7 +2224,6 @@ void Renderer::deselectMap(Bsp* map) void Renderer::clearSelection() { - pickInfo = PickInfo(); } @@ -2305,6 +2328,7 @@ void Renderer::reloadBspModels() { Bsp* tmpBsp = new Bsp(tryPath); tmpBsp->is_model = true; + tmpBsp->parentMap = bsprend->map; if (tmpBsp->bsp_valid) { BspRenderer* mapRenderer = new BspRenderer(tmpBsp, bspShader, fullBrightBspShader, colorShader, pointEntRenderer); @@ -2324,7 +2348,6 @@ void Renderer::reloadBspModels() void Renderer::addMap(Bsp* map) { - if (!map->bsp_valid) { logf("Invalid map!\n"); @@ -3632,6 +3655,7 @@ void Renderer::pasteEnt(bool noModifyOrigin) pushUndoCommand(createCommand); clearSelection(); + selectMap(map); selectEnt(map, map->ents.size() > 1 ? ((int)map->ents.size() - 1) : 0); } diff --git a/src/main.cpp b/src/main.cpp index f20b9266..eda835af 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -358,7 +358,7 @@ int noclip(CommandLine& cli) { model = cli.getOptionInt("-model"); - if (model < 0 || (unsigned int)model >= map->modelCount) + if (model < 0 || model >= map->modelCount) { logf("ERROR: model number must be 0 - %d\n", map->modelCount); return 1; @@ -465,7 +465,7 @@ int simplify(CommandLine& cli) STRUCTCOUNT oldCounts(map); - if (modelIdx < 0 || (unsigned int)modelIdx >= map->modelCount) + if (modelIdx < 0 || modelIdx >= map->modelCount) { logf("ERROR: model number must be 0 - %d\n", map->modelCount); return 1; @@ -762,13 +762,11 @@ int main(int argc, char* argv[]) ::ShowWindow(::GetConsoleWindow(), SW_SHOW); #endif -#ifdef USE_FILESYSTEM if (strlen(argv[0])) { fs::path ph = argv[0]; fs::current_path(ph.parent_path()); } -#endif g_settings_path = fileExists(GetCurrentWorkingDir() + "bspguy.cfg") ? GetCurrentWorkingDir() + "bspguy.cfg" : getConfigDir() + "bspguy.cfg"; g_config_dir = fileExists(GetCurrentWorkingDir() + "bspguy.cfg") ? GetCurrentWorkingDir() : getConfigDir(); diff --git a/src/util/util.cpp b/src/util/util.cpp index b977f4d8..dd8c6026 100644 --- a/src/util/util.cpp +++ b/src/util/util.cpp @@ -78,16 +78,7 @@ void debugf(const char* format, ...) bool fileExists(const std::string& fileName) { -#ifdef USE_FILESYSTEM return fs::exists(fileName) && !fs::is_directory(fileName); -#else - if (FILE* file = fopen(fileName.c_str(), "r")) - { - fclose(file); - return true; - } - return false; -#endif } char* loadFile(const std::string& fileName, int& length) @@ -131,13 +122,7 @@ bool writeFile(const std::string& fileName, const std::string& data) bool removeFile(const std::string& fileName) { -#ifdef USE_FILESYSTEM return fs::exists(fileName) && fs::remove(fileName); -#elif WIN32 - return DeleteFile(fileName.c_str()); -#else - return remove(fileName.c_str()); -#endif } std::streampos fileSize(const std::string& filePath) @@ -961,23 +946,7 @@ void WriteBMP(const std::string& fileName, unsigned char* pixels, int width, int bool dirExists(const std::string& dirName) { -#ifdef USE_FILESYSTEM return fs::exists(dirName) && fs::is_directory(dirName); -#else -#ifdef WIN32 - DWORD ftyp = GetFileAttributesA(dirName.c_str()); - if (ftyp == INVALID_FILE_ATTRIBUTES) - return false; //something is wrong with your path! - - if (ftyp & FILE_ATTRIBUTE_DIRECTORY) - return true; // this is a directory! - - return false; // this is not a directory! -#else - struct stat sb; - return stat(dirName.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode); -#endif -#endif } #ifndef WIN32 @@ -1057,7 +1026,6 @@ int mkdir_p(const char* dir, const mode_t mode) bool createDir(const std::string& dirName) { -#ifdef USE_FILESYSTEM std::string fixDirName = dirName; fixupPath(fixDirName, FIXUPPATH_SLASH::FIXUPPATH_SLASH_SKIP, FIXUPPATH_SLASH::FIXUPPATH_SLASH_REMOVE); if (dirExists(dirName)) @@ -1066,40 +1034,12 @@ bool createDir(const std::string& dirName) if (dirExists(dirName)) return true; return false; -#else -#ifdef WIN32 - std::string fixDirName = dirName; - fixupPath(fixDirName, FIXUPPATH_SLASH_SKIP, FIXUPPATH_SLASH_REMOVE); - if (dirExists(dirName)) - return true; - int ret = SHCreateDirectoryExA(NULL, dirName.c_str(), NULL); - if (ret != ERROR_SUCCESS) - { - logf("Could not create directory: %s. Error: %i", dirName.c_str(), ret); - return false; - } - return true; -#else - if (dirExists(dirName)) - return true; - - int ret = mkdir_p(dirName.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); - if (ret != 0) - { - logf("Could not create directory: %s", dirName.c_str()); - return false; - } - return true; -#endif -#endif } void removeDir(const std::string& dirName) { -#ifdef USE_FILESYSTEM std::error_code e; fs::remove_all(dirName, e); -#endif } @@ -1186,22 +1126,11 @@ void fixupPath(std::string& path, FIXUPPATH_SLASH startslash, FIXUPPATH_SLASH en std::string GetCurrentWorkingDir() { -#ifdef USE_FILESYSTEM #ifdef WIN32 return fs::current_path().string() + "\\"; #else return fs::current_path().string() + "/"; #endif -#else - - char buff[FILENAME_MAX]; - GetCurrentDir(buff, FILENAME_MAX); -#ifdef WIN32 - return std::string(buff) + "\\"; -#else - return std::string(buff) + "/"; -#endif -#endif } #ifdef WIN32 diff --git a/src/util/util.h b/src/util/util.h index c80c48ef..4e6f2e21 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -1,19 +1,7 @@ #pragma once - -#if defined(__cpp_lib_filesystem) || defined(USE_FILESYSTEM) || ((defined(__GNUC__) && (7 <= __GNUC_MAJOR__))) #include namespace fs = std::filesystem; -#ifndef USE_FILESYSTEM -#define USE_FILESYSTEM -#endif -#elif _MSC_VER > 1920 || defined(USE_EXPERIMENTAL_FILESYSTEM) -#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING -#include -namespace fs = std::experimental::filesystem; -#define USE_FILESYSTEM -#endif - #include #include diff --git a/vs-project/bspguy.vcxproj b/vs-project/bspguy.vcxproj index 6276dba7..241a7bd4 100644 --- a/vs-project/bspguy.vcxproj +++ b/vs-project/bspguy.vcxproj @@ -70,7 +70,7 @@ true false Level4 - %(PreprocessorDefinitions);WIN32;_WINDOWS;GLEW_STATIC;USE_FILESYSTEM;NOMINMAX; + %(PreprocessorDefinitions);WIN32;_WINDOWS;GLEW_STATIC;NOMINMAX; $(IntDir) stdcpplatest true @@ -79,7 +79,7 @@ true - %(PreprocessorDefinitions);WIN32;_DEBUG;_WINDOWS;GLEW_STATIC;USE_FILESYSTEM; + %(PreprocessorDefinitions);WIN32;_DEBUG;_WINDOWS;GLEW_STATIC; .\..\src;.\..\src\bsp;.\..\src\cli;.\..\src\data;.\..\src\editor;.\..\src\filedialog;.\..\src\gl;.\..\src\qtools;.\..\src\util;.\..\src\mdlviewer;.\..\imgui;.\..\imgui\examples;.\..\imgui\backends;.\..\imgui\misc\cpp;.\..\glew\include;.\..\glfw\include;%(AdditionalIncludeDirectories) @@ -141,7 +141,7 @@ true - %(PreprocessorDefinitions);WIN32;_WINDOWS;NDEBUG;GLEW_STATIC;USE_FILESYSTEM; + %(PreprocessorDefinitions);WIN32;_WINDOWS;NDEBUG;GLEW_STATIC; .\..\src;.\..\src\bsp;.\..\src\cli;.\..\src\data;.\..\src\editor;.\..\src\filedialog;.\..\src\gl;.\..\src\qtools;.\..\src\util;.\..\src\mdlviewer;.\..\imgui;.\..\imgui\examples;.\..\imgui\backends;.\..\imgui\misc\cpp;.\..\glew\include;.\..\glfw\include;%(AdditionalIncludeDirectories)