-
-
Notifications
You must be signed in to change notification settings - Fork 21.6k
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
Make is_equal_approx separate and make == exact again #32477
Make is_equal_approx separate and make == exact again #32477
Conversation
320e902
to
0a3315b
Compare
0a3315b
to
726faa2
Compare
I would really prefer a PR that only addresses the issues raised in #18992. It's unclear whether many of the added approximation checks are necessary, and as mentioned by @reduz, they might impair the compiler's ability to perform optimizations. AFAICT reverting the changes to operators in |
@@ -557,28 +557,9 @@ void Basis::set_euler_yxz(const Vector3 &p_euler) { | |||
*this = ymat * xmat * zmat; | |||
} | |||
|
|||
bool Basis::is_equal_approx(const Basis &a, const Basis &b, real_t p_epsilon) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The epsilon is needed afaik because it can be used with different values for different use cases, when matrix is not of unit size. Check those that use is_equal_approx_ratio and leave them alone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the matrix is not of unit size, is_equal_approx
now handles such cases, since is_equal_approx
is called on each component Vector3.
The epsilon override for the pre-existing is_equal_approx
is not actually used anywhere in the code base.
I undid changes to is_equal_approx_ratio
for Basis, but it's also not actually used anywhere in the code base.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
leave == comparisons alone if they did not use is_equal_approx originally.
@@ -80,11 +80,11 @@ class Delaunay2D { | |||
} | |||
|
|||
static bool edge_compare(const Vector<Vector2> &p_vertices, const Edge &p_a, const Edge &p_b) { | |||
if (p_vertices[p_a.edge[0]] == p_vertices[p_b.edge[0]] && p_vertices[p_a.edge[1]] == p_vertices[p_b.edge[1]]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In many cases there is a good reason for this to have equal signs. When dealing with geometry, vertices may be very close but not be the same one, or sometimes they may be hashed, and this will break it.
Please do not replace == comparisons by is_equal_approx if they did not originally do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They were not originally like this. This is a reversion of https://github.com/godotengine/godot/pull/31395/files#diff-1c96941701be95512a1964a0e4e5c5c4L83
@@ -156,11 +153,6 @@ bool Plane::intersects_segment(const Vector3 &p_begin, const Vector3 &p_end, Vec | |||
|
|||
/* misc */ | |||
|
|||
bool Plane::is_almost_like(const Plane &p_plane) const { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please do not break compatibility, leave the old function with a deprecate warning.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only used internally, @akien-mga told me to remove it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah it's ok to remove this one.
@@ -242,7 +242,7 @@ void CSGBrushOperation::BuildPoly::_clip_segment(const CSGBrush *p_brush, int p_ | |||
//check if edge and poly share a vertex, of so, assign it to segment_idx | |||
for (int i = 0; i < points.size(); i++) { | |||
for (int j = 0; j < 2; j++) { | |||
if (segment[j] == points[i].point) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
again, I dont remember how this was originally, but if it did not use is_equal_approx, then dont replace it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They were originally is_zero_approx(a.distance_to(b))
which is functionally identical to checking for approximate equality except that the old code doesn't work with large vectors. This is necessary to keep #22988 fixed.
@@ -310,7 +310,7 @@ void CSGBrushOperation::BuildPoly::_clip_segment(const CSGBrush *p_brush, int p_ | |||
Vector2 edgeseg[2] = { points[edges[i].points[0]].point, points[edges[i].points[1]].point }; | |||
Vector2 closest = Geometry::get_closest_point_to_segment_2d(segment[j], edgeseg); | |||
|
|||
if (closest == segment[j]) { | |||
if (closest.is_equal_approx(segment[j])) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as always, check what this was originally.
ack stupid github, dont merge this, i only approved the last commit. |
This commit adds exposed behavior for C#
Internal changes only
This commit changes behavior for GDScript and C#. Also did some organizing of the order to logically group related methods, mostly for Rect2 and AABB.
726faa2
to
218f38c
Compare
As mentioned, I would really have preferred a PR only addressing the necessary bug fixes, i.e. undoing approximate equality checks added where exact checks are meant to be used. This PR does that, and adds more utility methods, some cleanup, some refactoring... it makes it big and quite inappropriate to merge at such a late stage in development. Still, the bug fixes are important and I don't feel like doing a slimmed down version of the PR with only fixes myself. After the last revision and discussing it with @reduz, we agree that the extra enhancements should likely be fine, so let's merge. |
Thanks! |
@akien-mga For the record, having only the changes to the If any further issues are discovered due to merging such a large PR I'll get on it immediately. |
This PR fixes the concerns @reduz has about #18992, and fixes #32604
My initial reasoning is that end-user code would almost always want to have equality checks be safe, so that would make sense to have as the default behavior of
==
for vectors. One concern about this is with performance, but if that was the only concern, performance-critical code could have a separate method for checking this (and some code could also switch to integer vectors later on, too).This PR restores the old (3.1) functionality of
==
for vectors etc, and instead introduces someis_equal_approx
methods for comparing them. The main reason I think this is the best course of action is that, as @reduz mentioned, we don't want to hide this functionality from the user. It makes sense to require users to be aware of approximate equality and consciously choose it, instead of it just being the default choice for==
. Aside from that, it does also have the advantage of allowing code to run as fast as before.The first commit adds
is_equal_approx
internally (exposed in C#) to the types (so, nothing breaking). There is a pre-existing exposedis_equal_approx
inBasis
that should be replaced in 4.0, I've placed TODO notes in there. The second commit switches internal code that depends on approximate vector equality (such as the lines in #31395) to use theis_equal_approx
methods (so, nothing breaking). The third commit exposesis_equal_approx
methods and reverts==
to check for exact equality again (same behavior as 3.1, so 3.1 projects will still work the same).One thing I wasn't sure about is with
>
and>=
etc. I think it's desirable to leave these as they currently are, but I could be wrong.As a side note, this is my 100th pull request on GitHub (and my 51st to the Godot repo). 🎉