-
-
Notifications
You must be signed in to change notification settings - Fork 220
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
Implement Mul<Transform...>
for Vector2
, Vector3
#1082
base: master
Are you sure you want to change the base?
Implement Mul<Transform...>
for Vector2
, Vector3
#1082
Conversation
API docs are being generated and will be shortly available at: https://godot-rust.github.io/docs/gdext/pr-1082 |
Godot supports it, but is it intuitive? Mathematically, you cannot multiply a 2x1 column vector with a 2x2 matrix. Since there is already the more explicit |
To elaborate a bit on my answer... The risk I see is in situations like these: let rotate: Transform3D = ...;
let rotate2: Transform3D = ...;
let rotated: Vector3 = ...;
let transform = rotate2 * rotate * rotated; Now someone wants to change order of rotations, but the refactor happens at 3:43am: let transform = rotate2 * rotated * rotate; Code compiles, everything seems fine. The developer commits, doesn't test... next day another developer spends 2h debugging because some object is in the wrong place, and that code looks fine at first. Of course it's an artificial scenario, and better variable names would help, but still, this class of issues doesn't exist with a named function. It's also much easier to recognize inverse-multiply if it doesn't look like regular matrix multiplication. There is also more nuance here. Godot docs:
So Maybe also noteworthy is that GDScript defines a lot of operators. Which is fine, with its focus on rapid prototyping and convenience rather than type-safety. For Rust, a lot of these operators would be considered weakly typed or straight unintuitive; I mean what's Point being, just because GDScript offers an operator doesn't mean we have to expose it as an operator, too. We should definitely expose the functionality for completeness. In obscure cases, In this case, we should probably add a named method, like it was the case in Godot 3 (I couldn't find why this was changed, might be interesting). Transform3D::xform_inv(self, v: Vector3) -> Vector3 This operation also exists for some other matrix-like types, such as Godot also uses an direct implementation and not |
I do agree, and I would be even more strict here – In general, I would propose creating methods
Methods has been removed with this PR, with comment stating that they are too complex and operators should be used instead 🤔 : godotengine/godot#42780 |
Why does it not make sense? There are also very practical reasons to support chaining of it: rotation * scale * vector
// vs.
(rotaton * scale).xform(vector)
Good call about I would definitely keep
Thanks for looking this up! (Note to self: need to expand It's interesting that they found |
Because it multiplies component of a transform – basis – with vector and adds origin afterwards. I.e. – it performs xform, instead of matrix multiplication, while docs state that both Transform2D and Transform3D are matrices. Transforms are ( therefore my_transform3d.basis * my_vector3 + my_transform3d.origin == my_transform3d * my_vector3;
my_transform2d.basis_xform(my_vector2) + my_transform2d.origin == my_transform2d * my_vector2; Godot docs explicitly state that I have no idea how common this kind of operator overload is outside Godot 🤔 RE: exposing
|
You're right, I glanced over this part. The mathematical operation that includes translation would be a 4x4 matrix, multiplied by a 4x1 vector: But since the last row are constant values, they don't need to be stored. So game developers usually use 3x4 matrices. This representation is indeed quite common in gamedev: |
I think most Rust libraries dont overload It'd be a breaking change but it may make sense to just remove them in our library too. |
Alright, then it would make sense to do the following:
|
Good point -- that's probably the reason why it doesn't exist in Godot for 3D transforms. Maybe we should briefly mention this in
Oh, interesting. I wonder if the design choice here was -- since those libraries offer many different matrix types -- to only implement
This one is interesting, I'm not sure about removing |
Implements
Mul<Transform...>
forVector2
,Vector3
.We already support
Transform * Vector
so the reverse should be supported as well. Tests are translated 1:1 from Godot (the implementation haven't really changed for 12 years and I don't expect to see any changes here anytime soon).Godot Impl
Multiplying Godot Vector x Transform results in performing XFormInv.
Initially I did it with macro, but it is not worth it.