View Issue Details

IDProjectCategoryView StatusLast Update
0005129The Dark ModCodingpublic18.01.2020 16:50
Reporterstgatilov Assigned Tostgatilov  
PrioritynormalSeverityfeatureReproducibilityhave not tried
Status resolvedResolutionfixed 
Product VersionTDM 2.07 
Target VersionTDM 2.08Fixed in VersionTDM 2.08 
Summary0005129: dmap: add diagnostics for visportal problems
DescriptionIt seems that mappers have a lot of problems with visportals.
Some of them are due to dmap bugs, some of them are simply because mapper errors are not reported in any way convenient for a mapper.
The goal of this task is to improve diagnostics of most visportal problems.
Additional InformationInternal discussion:
TagsNo tags attached.




15.01.2020 17:16

administrator   ~0012146

After a few preliminary commits, I have finally committed all the major changes in svn rev 8523.

They include two bugfixes, changing BSP, and two diagnostics.
Note that after this change dmap will work quite different from how it did previously.
It is possible to return to old behavior (and thus restore all the bugs) by setting:
  dmap_fixBrushOpacityFirstSide 0
  dmap_bspAllSidesOfVisportal 0
  dmap_fixVisportalOutOfBoundaryEffects 0
It can be used to dmap existing FMs in case you don't want to fix all the portal issues.


15.01.2020 17:31

administrator   ~0012147

Detailed description of fixes.

"dmap_fixBrushOpacityFirstSide": Due to stupid bug the first side of a brush was ignored when determining its opacity.
With this fix, dmap follows the rule: brush is opaque when all of its sides are opaque.
Before that, brush was detected as opaque also if its first side was non-opaque.
In rare cases, this change can break existing missions. For instance, "Behind Closed Doors" has one such brush on the world boundary, hence the map has become "leaky" now.

"dmap_fixVisportalOutOfBoundaryEffects": Sometimes visportalled side could block areas on its continuation (e.g. out of its winding).
When dmap determines areas, it runs flood-filling algorithm on the graph with vertices being BSP leaves (each such leaf is convex polyhedron) and edges being BSP portals (polygons shared by BSP leaves).
When checking if BSP portal is covered by any visportal, all visportalled sides of brushes in two incident BSP leaves were inspected.
If visportal side and BSP portal lie on same plane, the buggy code considered the BSP portal to be covered, regardless of mutual position of their windings on their common plane.
In order to fix it, I added a check that center of BSP portal winding is inside the winding of the visportalled side.

"dmap_bspAllSidesOfVisportal": Due to this change, ALL sides of a visportal brush are now inserted into BSP tree (previously, only the visportalled side was).
While the old behavior is not a bug, it caused problems with visportals.
The main problem is that sometimes non-sealed visportals survived into the final map, with ugly black areas being rendered where sealing was missing.
The correct behavior (and what the new code does) is to drop such visportals --- that's what usually happens when visportal has same area on both of its sides.
Unfortunately, mappers utilized old behavior a lot, even though it could not be relied on (whether portal survives or is dropped depends on BSP structure, i.e. on surrounding brushes).
As the result of this change, many visportals which survived old dmap will be dropped by the new one, so be attentive.


15.01.2020 17:53

administrator   ~0012148

Two diagnostic rules were added.

1) Portal "L"eak diagnostic.
After areas are assigned and all visportals between them are extracted, this diagnostic is triggered.
If finds all BSP portals, which 1) are covered by visportal, and 2) have same area on both of its sides --- these visportals are dropped by dmap (more precisely, they are NOT extracted to inter-area visportals).
For every such BSP portal, we start a Breadth-First-Search over BSP nodes. It is started from the node incident to the BSP portal. The search is forbidden to cross visportals. When it reaches the other node incident to the BSP portal, it is stopped. The resulting node-portal path leads from one side of the visportal to the other side, thus being a sample path which leaks.
Note that unlike the stupid heuristics of D3 outer leak path construction, the leak path detected by new code always crossed minimum number of BSP nodes/portals.
The leak path is reported to game console and saved to file "{mapname}_portalL_{coords}.lin", which can be loaded and inspected in DarkRadiant.
There is an additional hack to make leak path easier to see. Actually, two BFS searches are done in worst case. In the first one, it is forbidden to cross the nodraw sides of the dropped visportal brush, except for the "back"-side. This ensures that path is visible in DR even when looking from the back. If this search fails (it is possible), then another search without any limitations is done, which should find leak path for sure.
Final note is about duplicates. Since visportal can cover many BSP portals. We don't report (and don't even start BFS search) the cases having same visportalled side and area where it is located. If visportal spans several areas, then it can be reported many times (once in every area).

2) Portal "O"verlapping diagnostic.
Only done with dmap_bspAllSidesOfVisportal --- it makes such diagnostic trivial, because now every visportal either covers the whole BSP portal or does not cover it at all.
When detecting inter-area visportals and inspecting a BSP portal, we find ALL visportals. If there is more than one, then this is overlapping.
It is reported to game console, and also a "{mapname}_portalO_{coords}.lin" file is saved. The file contains winding of the BSP portal where overlapping is detected. It usually shows some part which belongs to both visportals at once.


18.01.2020 16:50

administrator   ~0012153

One more improvement in svn rev 8527.

All portals which did not made it to the resulting map but were not reported otherwise are useless. Now they are reported as "useless" =)
The most common case is when portal side is completely within/on-boundary of opaque brushes.

Issue History

Date Modified Username Field Change
14.01.2020 15:41 stgatilov New Issue
14.01.2020 15:41 stgatilov Status new => assigned
14.01.2020 15:41 stgatilov Assigned To => stgatilov
15.01.2020 17:16 stgatilov Note Added: 0012146
15.01.2020 17:31 stgatilov Note Added: 0012147
15.01.2020 17:53 stgatilov Note Added: 0012148
16.01.2020 04:00 stgatilov Additional Information Updated View Revisions
16.01.2020 16:15 stgatilov Status assigned => resolved
16.01.2020 16:15 stgatilov Resolution open => fixed
16.01.2020 16:15 stgatilov Fixed in Version => TDM 2.08
18.01.2020 16:50 stgatilov Note Added: 0012153