-
-
Notifications
You must be signed in to change notification settings - Fork 21.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
world_to_map() and map_to_world() are not inverse functions #23250
Comments
To be on the safe side, it's advised to add the half extents of your tile size to the But yeah, in this situation I would expect that This should be investigated in Lines 1429 to 1449 in b902a2f
affine_inverse might not do exactly what we want here - or maybe it's an issue of precision and the ret.floor() is the problem. CC @bojidar-bg
|
Fixing this would likely break compat, but I think it's an acceptable change even for 3.1, as long as we document it in release notes. |
Probably related to #2884 |
I would suspect a precision issue, affine_inverse should properly invert all commonly-found transformations just fine. |
Has anyone tested this? I ran the example code and I'm getting (8,2) back, instead of (7,1) that is the author getting. |
I have a reproduction project here: |
Well, this is weird indeed. When running your reproduction project, I am getting yet another result - (5,2). I won't have time to work on this issue this week, but I might be able to look into it the following week. |
Sorry, I used different coordinates on the project above, but I forgot to remove the old comments
If you're getting (5, 2) this confirms the bug. |
A Friend and me are trying to look into it. |
I suggest trying the other options before suspecting the matrix code. The reason is that the matrix code has been tested for multiple years, unlike the tilemap code which is much newer than that. |
ok, we'll look into the tilemap-code first. Thanks. |
changed in tile_map.cpp in function world_to_map The test inputs leading to expected results. This includes the bug-case. Pull Request incoming. Tested on Fedora and Majora by two diffrent users. |
I think the variable idet in affine_inverse is causing the unexpected behaviour. |
Continuing conversation here from #23315: A hacky fix would be: diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 67e25ec50..a7ac2bb98 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -1445,6 +1445,11 @@ Vector2 TileMap::world_to_map(const Vector2 &p_pos) const {
default: {}
}
+ // Account for precision errors on the border (GH-23250).
+ // 0.00005 is 5*CMP_EPSILON, results would start being unpredictible if
+ // cell size is > 15,000, but we can hardly have more precision anyway with
+ // floating point.
+ ret += Vector2(0.00005, 0.00005);
return ret.floor();
} But @Zylann proposes a better fix making integer calculations in pixel (world) space (thus without floating point precision errors), see #23315 (comment). |
Or we could just forego the whole transform stuff and just do:
I guess? (+ the offset calculations before that with |
One use case that could be affected would be collision contacts: If we apply an offset before
Another thing I thought about when reading this issue was, the fact that Unfortunately even my solution of two-step transform could break compat due to the fact users can specify a custom cell transform, which has to be directly world-to-cell (at best we won't be able to do the round trick when it is active). It would work only on square tiles. |
So should I just push my hack from #23250 (comment)? It should work fine as long as you don't have 16k tile sizes - which should be hopefully be safe for the near future :) |
Godot version:
3.0.6
OS/device including version:
Windows 7 - 64 bits
Issue description:
I needed to do some conversions between map and world coordinates in a Tilemap, but I always get incorrect values.
Steps to reproduce:
It should give me (8,2) again, right? But instead I get (7,1).
The text was updated successfully, but these errors were encountered: