Skip to content
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

Improve physics body/shape scale warnings, check shear/global, add to 2D #79364

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

aaronfranke
Copy link
Member

@aaronfranke aaronfranke commented Jul 12, 2023

Fixes #88415, fixes #92205

Previously, the body/shape scale warning code did not handle these cases:

  • If an ancestor node had a non-uniform scale.
  • If the node or an ancestor had a shear/skew.

This PR changes the code to check if the Basis is conformal, which handles all these cases. It actually does this twice, another time for the global transform, to ensure that there is no invalid transform inherited from ancestors (we also want the node's local transform to be validated in addition to global).

Also, this PR adds the same checks to 2D, since it was missing before.

Note: Negative scale is allowed in master and still allowed in this PR.

Note: Zero scale is invalid but is not validated in master or in this PR. I don't know if that's worth checking for since it's kinda obvious that it's invalid because most things in 3D are considered invalid if they have an zero scale.

@aaronfranke aaronfranke added this to the 4.x milestone Jul 12, 2023
@aaronfranke aaronfranke requested a review from a team as a code owner July 12, 2023 08:34
@fire fire requested review from a team July 14, 2023 04:39
@aaronfranke aaronfranke requested review from a team as code owners July 15, 2023 05:52
@aaronfranke aaronfranke marked this pull request as draft July 16, 2023 00:21
@aaronfranke aaronfranke changed the title Improve physics body/shape scale warnings, check shear and global Improve physics body/shape scale warnings, check shear/global, add to 2D Jul 16, 2023
@aaronfranke aaronfranke marked this pull request as ready for review September 26, 2023 15:45
@aaronfranke aaronfranke requested a review from a team as a code owner September 26, 2023 15:45
@rburing
Copy link
Member

rburing commented Dec 23, 2023

In #67847 I did not add the warnings to 2D because I could not reproduce the issues there. I did see some issues later with CCD when using non-uniform scale. Are there any open issues except for #12335?

If you can reproduce issues with 2D, that would justify adding the warnings, but otherwise we maybe should wait with adding those to avoid annoying users unnecessarily (even if it may be teaching good practice).

The code changes look good.

@aaronfranke
Copy link
Member Author

@rburing I do not use 2D physics so I'm not sure, but many physics calculations don't quite work the same with non-conformal transforms. For example, circles would become ellipses. If it really works with Godot's physics I could remove it I suppose, however, I think it's still best to keep this check because 1) It's a good practice for physics objects to have conformal transforms and 2) What about third-party 2D physics engines like Box2D or Rapier2D, wouldn't it be a bad idea to assume all 2D physics engines support non-conformally transformed physics objects?

@mihe
Copy link
Contributor

mihe commented Feb 27, 2024

What about third-party 2D physics engines like Box2D or Rapier2D, wouldn't it be a bad idea to assume all 2D physics engines support non-conformally transformed physics objects?

I guess I'll paraphrase myself from #88914 seeing as how there's a good amount of overlap here.

I can't speak for 2D, but I would prefer to see these is_conformal() checks done in the physics server instead, so as to allow other physics engines to use non-uniform scaling and whatever else they might want to allow.

With Jolt you can non-uniformly scale boxes, cylinders (so long as X and Z stays the same), convex polygons and concave polygons without any issues. I don't know if the same holds true for Godot Physics.

You can also scale physics bodies with Jolt to some degree as well.

Seeing as how this PR (unlike #88914) also checks to see that the basis is orthogonal I guess the method name proposed in #88914 of PhysicsServer*D::shape_is_valid_scale isn't as good of a fit, but maybe some PhysicsServer*D::shape_is_valid_transform and PhysicsServer*D::body_is_valid_transform? I'm not sure what the error message would be in that case though, given that the physics server could then reject it based on any part of it.

@geekley
Copy link

geekley commented May 21, 2024

many physics calculations don't quite work the same with non-conformal transforms. For example, circles would become ellipses. If it really works with Godot's physics I could remove it I suppose, however, I think it's still best to keep this check

If the approach of "all non-uniform scaling is bad" is taken, then there should be primitive shapes for things like ellipses. Or even better some more generic "oval" shape (like eggs).

@mihe
Copy link
Contributor

mihe commented Jan 16, 2025

Just as an FYI, there are runtime scaling checks happening server-side in the newly added Jolt module, which is a somewhat crude carry-over from the extension. See these methods, these macros and their usage.

Jolt provides a JPH::Shape::IsValidScale method that checks to see whether a given scale is valid (within a tight tolerance) for that particular shape instance, allowing for things like non-uniform scaling for certain shapes (even compound shapes). Ideally this would have been used through a configuration warning I guess, similar to what this PR does, but I wasn't able to add to that from the extension for the default physics nodes, so I went with the runtime checks.

However, just relying on JPH::Shape::IsValid for these runtime checks quickly became a point of friction, as I also support scaling all physics bodies, and doing something as simple as rotating a CharacterBody3D over a few thousand frames without orthonormalizing meant you'd end up with a slightly non-uniformly scaled transform and trigger these runtime checks.

As a result, a new method was added to Jolt, called JPH::Shape::MakeScaleValid, which changes the scale just enough to be valid for that given shape instance. So what I do instead is always call this method, and in DEBUG_ENABLED builds emit an error if the valid scale differs from the given scale within a tolerance that's greater than the one in JPH::Shape::IsValidScale (0.01 instead of 0.0001). That way you end up with Jolt always receiving a valid scale on its end, but we only emit an error if the user is deliberately scaling things the wrong way, or when they have a very dire precision problem.

With that said, there are still some people who find this behavior annoying, since it results in significant error spam in situations where you might not necessarily care about that particular problem, so there might be some argument for just ditching these runtime checks altogether and solely rely on node configuration warnings instead, but I would still like to see that these checks be deferred to the physics server in some way, so that we can allow for Jolt's more relaxed requirements around scaling.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants