Unwanted chunks rendered outside defined limits with limit visibility enabled
gmfamily opened this issue · 13 comments
template is bold
sample data is italicized
Issue Description: *Some unwanted chunks are rendered outside defined limits with limit visibility enabled. The unwanted chunk are located only around two visible limits defined near to x=20000 z=-20000. We have *
- Dynmap Version: 3.4
- Server Version: paper 1.19 build 81
- Pastebin of Configuration.txt: https://pastebin.com/8drbHTJa
- Server Host (if applicable): MineStrator
- Pastebin of crashlogs or other relevant logs: https://pastebin.com/crashcausedbydynmap
- Other Relevant Data/Screenshots: No specific texture pack / Plugins (29): ArmorStandTools, AsyncWorldEdit, AsyncWorldEditBossBar, Chunky, CoreProtect, dynmap, Essentials, EssentialsAntiBuild, EssentialsDiscord, EssentialsProtect, EssentialsSpawn, HeadDatabase, HolographicDisplays, LuckPerms, MessageAnnouncer, Multiverse-Core, NoMobGriefing, PlaceholderAPI, ProtocolLib, Skript, spark, SurvivalInvisiframes, TerredesHorizons, Vault, VaultChatFormatter, WorldEdit, WorldEditSelectionVisualizer, WorldGuard, WorldGuardExtraFlags / Current worlds.txt file : https://pastebin.com/4UAU0UiT / Current dmap worldgetlimits world results : https://pastebin.com/AJE0dwA4 / Online dynmap scoped on problematic limits rendered with unwanted chunks : http://137.74.100.108:25575/?worldname=world&mapname=flat&zoom=1&x=19976&y=64&z=-19994
- Steps to Replicate: dynmap cancelrender world ; dynmap purgeworld world ; dynmap fullrender world -> this sequence repeated 2 times produced exactly the same result with unwanted chunks rendered outside defined limits.
[X ] I have looked at all other issues and this is not a duplicate
[X ] I have been able to replicate this
you have a lot of areas defined, maybe some are overlapping, you can check by visualising the areas with circlemarkers: dmarker addcircle "label" radius:150 world:world x:-801 y:64 z:975
for example. dynmap sets the areas defined last as the most important ones, so whatever is on top is how it is getting rendered.
Thank you for your feedback, I'll try to reproduce keeping only suspicious limits.
I think I got the trick!
In the method doIntersectChunk of the class RoundVisibilityLimit there is a formula computing the distance between a block and the center of a limit to be compared with the radius. The part of the formula computing the distance is executed in ‘int’ context.
Indeed, taking our own defined limites, the « unwanted rendered blocks » are all at more than 46341 blocks (in our case it is on the z axis) of the center of the limit defined at the opposite of the map.
Then the distance computing formula exceed the capacity of ‘int’ representation (square root of 2^31 = 46 340,95).
Ok, so I followed a strict methodolody adding / removing limits and checking when the rendering problem occurs.
The conclusion is indeed very simple : as soon as I add the following visibility limits I reproduce the problem, with or without all the others and/or with or without hiddenlimits :
visibilitylimits:
- x: 19939
z: -20043
r: 150
- x: 19783
z: -19932
r: 150
- x: 13167
z: 29432
r: 150
Another curiousity is that the "unwanted rendering" seems to stop near a circular frontier centered on x=0/z=0 and ~30000 block radius (I need further analysis to confirm that fact). This can be observed a these coordinates: http://137.74.100.108:25575/?worldname=world&mapname=flat&zoom=0&x=12280&y=64&z=27484
In conclusion:
- The problem is reproductible, not related to number of visibility limits behing defined and hidden limits have also no impact.
- The problem occurs only when some visibility limits are defined outside a certain "frontier".
I have recompiled locally the spigot (1.19-R0.1-SNAPSHOT) artefact with the following code (casting to long all return formula operands) and the problem seems to be solved. I will test further to ensure there is no significative impact on performance before suggesting a merge request.
@Override
public boolean doIntersectChunk(int chunk_x, int chunk_z) {
int chunk_center_x = chunk_x * 16 + 8;
int chunk_center_z = chunk_z * 16 + 8;
int chunk_corner_x, chunk_corner_z;
if (chunk_center_x >= x_center)
chunk_corner_x = chunk_x * 16;
else
chunk_corner_x = chunk_x * 16 + 15;
if (chunk_center_z >= z_center)
chunk_corner_z = chunk_z * 16;
else
chunk_corner_z = chunk_z * 16 + 15;
return (long)(chunk_corner_x - x_center) * (long)(chunk_corner_x - x_center) + (long)(chunk_corner_z - z_center) * (long)(chunk_corner_z - z_center) < (long)(radius * radius);
}
The fixed version has been deployed on our server with no regression on runtime with several players connected (fullrender still running). I'll propose pull request asap.
Thanks for investigating! code looks good from what I can see, you can create a pr on the github to address this issue.
how is the PR going? I don't see a repo on your github account, do you need help with creating the PR?
It is ok. I was focused on another subjects at work. Please review the PR below 😊
Is there any problem with the PR ? I'm not very familiar with github delivery process...
Mike is very busy, PRs take weeks to merge. This one looks good, so all that's needed now is patience :)