2121#include " Fgd.h"
2222#include " Texture.h"
2323#include " LeafNavMeshGenerator.h"
24+ #include " NavMeshGenerator.h"
25+ #include " PolyOctree.h"
2426
2527typedef map< string, vec3 > mapStringToVector;
2628
@@ -4291,53 +4293,102 @@ bool Bsp::rename_texture(const char* oldName, const char* newName) {
42914293 return false ;
42924294}
42934295
4294- unordered_set<int > Bsp::selectConnected (int modelId, int faceId , unordered_set<int >& ignoreFaces, bool planarTextureOnly) {
4296+ unordered_set<int > Bsp::selectConnected (vector< int >& srcFaces , unordered_set<int >& ignoreFaces, bool planarTextureOnly) {
42954297 unordered_set<int > selected;
4296- const float epsilon = 1 .0f ;
4298+ vector<Polygon3D*> selectedFaces;
4299+ queue<Polygon3D*> testPolys;
4300+ unordered_set<int > validMiptex;
4301+ vector<vec3> validNormals;
4302+ vector<Polygon3D*> polys;
4303+ vector<int > polyModels; // maps a polygon index to a model index
4304+
4305+ for (int idx : srcFaces) {
4306+ BSPFACE & face = faces[idx];
4307+ BSPTEXTUREINFO & info = texinfos[face.iTextureInfo ];
4308+ BSPPLANE & plane = planes[face.iPlane ];
42974309
4298- BSPMODEL & model = models[modelId];
4310+ vector<vec3> selectedVerts;
4311+ for (int e = 0 ; e < face.nEdges ; e++) {
4312+ int32_t edgeIdx = surfedges[face.iFirstEdge + e];
4313+ BSPEDGE & edge = edges[abs (edgeIdx)];
4314+ int vertIdx = edgeIdx >= 0 ? edge.iVertex [1 ] : edge.iVertex [0 ];
4315+ selectedVerts.push_back (verts[vertIdx]);
4316+ }
42994317
4300- BSPFACE & face = faces[faceId];
4301- BSPTEXTUREINFO & info = texinfos[face.iTextureInfo ];
4302- BSPPLANE & plane = planes[face.iPlane ];
4318+ Polygon3D* poly = new Polygon3D (selectedVerts, idx, true );
4319+ selectedFaces.push_back (poly);
4320+ testPolys.push (poly);
4321+ validMiptex.insert (info.iMiptex );
4322+ push_unique_vec3 (validNormals, plane.vNormal , 0 .0001f );
4323+ }
43034324
4304- vector<vec3> selectedVerts;
4305- for (int e = 0 ; e < face.nEdges ; e++) {
4306- int32_t edgeIdx = surfedges[face.iFirstEdge + e];
4307- BSPEDGE & edge = edges[abs (edgeIdx)];
4308- int vertIdx = edgeIdx >= 0 ? edge.iVertex [1 ] : edge.iVertex [0 ];
4309- selectedVerts.push_back (verts[vertIdx]);
4325+ for (int fa = 0 ; fa < faceCount; fa++) {
4326+ polyModels.push_back (get_model_from_face (fa));
4327+
4328+ BSPFACE & face = faces[fa];
4329+
4330+ vector<vec3> faceVerts;
4331+
4332+ for (int e = 0 ; e < face.nEdges ; e++) {
4333+ int32_t edgeIdx = surfedges[face.iFirstEdge + e];
4334+ BSPEDGE & edge = edges[abs (edgeIdx)];
4335+ int vertIdx = edgeIdx >= 0 ? edge.iVertex [1 ] : edge.iVertex [0 ];
4336+ faceVerts.push_back (verts[vertIdx]);
4337+ }
4338+
4339+ Polygon3D* poly = new Polygon3D (faceVerts, polys.size (), true );
4340+
4341+ polys.push_back (poly);
43104342 }
43114343
4312- bool anyNewFaces = true ;
4313- while (anyNewFaces) {
4314- anyNewFaces = false ;
4344+ PolygonOctree* octree = NavMeshGenerator::createPolyOctree (this , polys, 6 );
43154345
4316- for (int fa = 0 ; fa < model.nFaces ; fa++) {
4317- int testFaceIdx = model.iFirstFace + fa;
4318- BSPFACE & faceA = faces[testFaceIdx];
4319- BSPTEXTUREINFO & infoA = texinfos[faceA.iTextureInfo ];
4320- BSPPLANE & planeA = planes[faceA.iPlane ];
4346+ while (testPolys.size ()) {
4347+ Polygon3D* poly = testPolys.front ();
4348+ testPolys.pop ();
43214349
4322- if (selected.count (testFaceIdx) || ignoreFaces.count (fa)) {
4350+ int srcModel = polyModels[poly->idx ];
4351+ unordered_set<int > regionPolys = octree->getPolysInRegion (poly);
4352+
4353+ for (int ridx : regionPolys) {
4354+ int idx = polys[ridx]->idx ;
4355+ BSPFACE & faceA = faces[idx];
4356+
4357+ if (polyModels[idx] != srcModel)
43234358 continue ;
4324- }
43254359
4326- if (planarTextureOnly && (planeA. vNormal != plane. vNormal || info. iMiptex != infoA. iMiptex )) {
4360+ if (selected. count (idx) || ignoreFaces. count (idx))
43274361 continue ;
4362+
4363+ if (planarTextureOnly) {
4364+ BSPTEXTUREINFO & info = texinfos[faceA.iTextureInfo ];
4365+ BSPPLANE & plane = planes[faceA.iPlane ];
4366+
4367+ if (!validMiptex.count (info.iMiptex ))
4368+ continue ;
4369+
4370+ bool isPlanar = false ;
4371+ for (const vec3& norm : validNormals) {
4372+ if (plane.vNormal == norm) {
4373+ isPlanar = true ;
4374+ break ;
4375+ }
4376+ }
4377+
4378+ if (!isPlanar)
4379+ continue ;
43284380 }
43294381
4330- vector<vec3> uniqueVerts;
43314382 bool isConnected = false ;
43324383
43334384 for (int e = 0 ; e < faceA.nEdges && !isConnected; e++) {
43344385 int32_t edgeIdx = surfedges[faceA.iFirstEdge + e];
43354386 BSPEDGE & edge = edges[abs (edgeIdx)];
43364387 int vertIdx = edgeIdx >= 0 ? edge.iVertex [1 ] : edge.iVertex [0 ];
4388+ const float epsilon = 1 .0f ;
43374389
4338- bool isUnique = true ;
4339- vec3 v2 = verts[vertIdx];
4340- for (vec3 v1 : selectedVerts) {
4390+ vec3& v2 = verts[vertIdx];
4391+ for (const vec3& v1 : poly->verts ) {
43414392 if ((v1 - v2).length () < epsilon) {
43424393 isConnected = true ;
43434394 break ;
@@ -4351,15 +4402,22 @@ unordered_set<int> Bsp::selectConnected(int modelId, int faceId, unordered_set<i
43514402 int32_t edgeIdx = surfedges[faceA.iFirstEdge + e];
43524403 BSPEDGE & edge = edges[abs (edgeIdx)];
43534404 int vertIdx = edgeIdx >= 0 ? edge.iVertex [1 ] : edge.iVertex [0 ];
4354- selectedVerts.push_back (verts[vertIdx]);
43554405 }
43564406
4357- selected.insert (testFaceIdx );
4358- anyNewFaces = true ;
4407+ selected.insert (idx );
4408+ testPolys. push (polys[ridx]) ;
43594409 }
43604410 }
43614411 }
43624412
4413+ for (Polygon3D* poly : polys) {
4414+ delete poly;
4415+ }
4416+ for (Polygon3D* poly : selectedFaces) {
4417+ delete poly;
4418+ }
4419+ delete octree;
4420+
43634421 return selected;
43644422}
43654423
0 commit comments