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鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement some methods of the Transform API #821
Conversation
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.
Thank you!
This actually made me notice that we have quite a few inconsistencies in our geometric APIs:
Transform2D
andQuat
have anIDENTITY
constant, whileBasis
has anidentity()
function. We should probably go for the constant.Default
is implemented for some geometric types but not all. Do we have a good use case for generic programming?Self
vs. struct name insideimpl
.
No need to fix anything outside Transform
here, I can gladly take care of that.
bors try
/// fully aligned to the target by a further rotation around an axis | ||
/// perpendicular to both the target and up vectors. | ||
#[inline] | ||
pub fn looking_at(eye: Vector3, target: Vector3, up: Vector3) -> Transform { |
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.
Any particular reason why this deviates from the GDScript method signature? In particular, using eye
instead of &self
. Probably it's more intuitive when one is mostly interested creating a new coordinate system from scratch (including translation + rotation, but not scale)? In that case, a constructor name like from_position_direction()
or so might be more appropriate.
But generally it seems to me that in Godot, it's more idiomatic to construct custom transforms by chaining operations, rather than specialized constructors. Would this method be equivalent to the following?
Transform::IDENTITY
.translated(eye)
.looking_at(target, up) // assuming canonical impl
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 decision would also affect the already present translate(origin)
vs. translated(&self, origin)
.
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.
Any particular reason why this deviates from the GDScript method signature?
The main reason is that I copied this from a utility method in my code that used these arguments. But I think it makes more sense to make it consistent with the API 馃憤
Same decision would also affect the already present translate(origin) vs. translated(&self, origin)
Indeed. I didn't want to change that because it was already there so it would become a breaking change. But since you're mentioning it I went ahead and created the following methods:
from_position
, renamed from the oldtranslate
.translate
, which takes&mut self
and modifies in-placetranslated
, which takes&self
and returns a modified transform
I think this is closer to the other APIs.
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.
translated, which takes &self and returns a modified transform
This one definitely makes sense.
I'm not 100% sure about the others -- I would tend to go for the minimal API (close to Godot). Because if we have translate()
, we would also need rotate()
and scale()
, and do the same for Transform2D
. The same applies to from_position()
, which can currently be expressed as IDENTITY.translated(v)
.
I'm not categorically against convenience functions, but for now I'd stay with the building blocks and encourage the "chain different transforms" pattern.
tryBuild succeeded: |
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.
Looks good to me. I have nothing to add that bromeon hasn't already mentioned.
Most looks good, see comment above. Maybe we could add a constructor |
@Bromeon I removed some of the redundant constructors to simplify the API and added a new Let me know when this is ready to merge and I'll squash all those commits on my branch. |
Thanks, looks good now! Also thanks for the multiplication! If you squash the commits, it should be ready 馃檪 |
tryBuild succeeded: |
a955235
to
3363986
Compare
Thank you 馃檪 bors r+ |
Build succeeded: |
Here are some more Transform methods. I followed the same strategy as for #791, where the implementation was done by translating the C++ code to Rust.
I can also add some tests similar to the ones from the previous PR if you'd like 馃憤 Although the code for Transform is far simpler, because it delegates most of the implementation to
Vector3
andBasis
.