-
-
Notifications
You must be signed in to change notification settings - Fork 21k
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
Prevent setting a bad Node3D scale or transform #39980
Conversation
Just wanted to indicate that with a change like this, making a 3D node to "despawn" with a shrinking animation is no longer possible without thinking about the case of zero. |
Was this possible? I'm on master and it looks like it would segfault if you set any scale dimension to 0 (unless you compiled with extra runtime math checks). I think with this change it should stay at the last valid value, so it might be near-infinitely small depending on your animation step
I was a bit worried about performance.. I didn't see that many calls to set_transform, but I only have a simple test case with a bunch of non-moving meshes and a flying camera. Perhaps it's better to put a check in the editor GUI instead? I suppose one could see entering a transform manually as an advanced operation, and put less protections on it, but IMHO the editor should avoid crashing at all costs. I have to admit I don't remember much from matrix algebra, but based on when the program crashes I think the limitation is that no transform.basis row or column may be all zeroes. A zero diagonal seems to work fine as long as the other elements are filled in with something. Perhaps it would be faster to check for this condition using only boolean operators instead of multiplication.. I think all the ERR checks are enabled from all builds, I can't see any mechanism that disables them in the code |
It probably wasnt possible already, just saying I've seen shrinking animations being a thing in games.
It's not about the amount of times
|
An alternative could be to hide the object if scale is set to 0, but I think that might add a bit of complexity.
Yea, I meant I put a debug print every time it was called to get a feeling for how often it happens. But now I tried adding some physics objects and it's called much more often as you said. Perhaps it's better to move this check to the GUI, and let people crash if they set bad values through script :) With a large number of moving objects the overhead might be too much, even if it's only done when running through the editor and not in exported projects. What do you think about keeping the check in set_scale, since that one is used more rarely and the test is trivial, and finding a different solution for set_transform? Would that be too inconsistent?
No idea.. Maybe that's only valid when you have no rotation and translation? I just played around with setting different translations, scales and rotations and looked for what caused problems. |
@Zylann For a shrinking animation, you can just have it shrink to 0.001 or something.
Nope, that is not the case. You can't really make general statements about any specific part of the matrix meaning anything specific about the decomposed transform, except for the last column (wrongly displayed as a row, but it shouldn't be displayed anyway). The only case where the diagonal alone determines the scale is if all the other Basis elements are zero.
I think it's better to throw an error for the user to look at. |
Setting scale to 0 or a transform with 0-determinant will later lead to a division by 0, or in best case error message spam if MATH_CHECKS is defined.
817e64a
to
a14b198
Compare
Updated with some feedback from @aaronfranke (on discord). The check is kept in Node3D::set_transform but wrapped in #ifdef DEBUG_ENABLED to avoid the performance hit on release builds. I think if this pull request is accepted a similar check in Node2D would be a good idea, but I couldn't test if that is necessary since it seems like 2D rendering isn't ported to 4.0 yet (getting this message if I try to create a 2D scene for testing: "ERROR: FIXME: Mesh, MultiMesh and Particles render commands are unimplemented currently, they need to be ported to the 4.0 rendering architecture.") One minor issue with this change is that when it blocks setting an invalid transform or scale from the editor, the operation is still put in the undo history. I.e. the first time you press undo after this it will appear as if nothing changed. I don't know if this is acceptable, but fixing it I think requires a more complex change. |
I also made an experiment where I added a Node3D::safe_set_transform, which is regular set_transform plus the param check, and used that one with Node3D's ADD_PROPERTY. I didn't dig that much deeper into it, so I don't know if it would have any unexpected side effects, but it looked like it was working and only affecting changes made in the editor. |
@akien-mga In that case, what about adding an editor check in |
Superseded by #41426. |
Setting a scale to 0 or a transform with 0-determinant in Node3D will later lead to a division by 0 when the basis is inverted, or in best case error message spam if MATH_CHECKS is defined.
Fixes #32405