-
-
Notifications
You must be signed in to change notification settings - Fork 268
Tweaks to glamconv and indexing for vectors #128
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
Conversation
Bromeon
left a comment
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.
Thanks for the split!
Are the Index<usize> and IndexMut<usize> traits really necessary? We have already Index<Vector2Axis>, and the regular .x/.y/.z access. I don't want to provide 3 ways to achieve the same thing unless there's a very good reason.
If this is truly needed, we should look at the concrete use case. E.g. if it's for a for loop, we could provide something like Vector2Axis::values() instead.
| ($(,)?) => {}; | ||
| ($($T:ty),+ $(,)?) => {$( |
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.
What's the reason behind this? I'd rather repeat the macro invocation than making the macro more complex.
Repetition patterns are mostly useful for token ranges inside the macro body, not for repeating the entire macro.
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.
i can change it if you want, but it's not that uncommon afaik. the standard library does it a fair bit, see for instance https://doc.rust-lang.org/src/core/cmp.rs.html#1370.
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.
Interesting, thanks for that link! 👍
I think it's easier if we use separate calls though, as we do that already in several other places (the impl macros for vectors, From/ToVariant, etc)
godot-core/src/builtin/math.rs
Outdated
| let difference = (to - from) % (2.0 * PI); | ||
| let distance = (2.0 * difference) % (2.0 * PI) - difference; |
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.
See TAU
| impl GlamType for Vec3A { | ||
| type Mapped = Vector3; | ||
|
|
||
| fn to_front(&self) -> Self::Mapped { | ||
| Vector3::new(self.x, self.y, self.z) | ||
| } | ||
|
|
||
| fn from_front(mapped: &Self::Mapped) -> Self { | ||
| Vec3A::new(mapped.x, mapped.y, mapped.z) | ||
| } | ||
| } |
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.
We are not using Vec3A at the moment, so this is dead code.
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.
we will be because the Transform3D will use Affine3A, since there is no Affine3, which uses Vec3A internally
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.
Ok, we then need to see if Vec3A <-> Vector3 conversions are not necessary all over the place 🤔 otherwise we might not gain much from using glam. But I guess it's a good start.
godot-core/src/builtin/vector3.rs
Outdated
| } | ||
| } | ||
|
|
||
| impl super::glam_helpers::GlamConv for Vector3 { |
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.
GlamConv could be imported.
godot-core/src/builtin/vector4.rs
Outdated
| use std::{ | ||
| fmt, | ||
| ops::{Index, IndexMut}, | ||
| }; |
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.
IIRC we don't use this import style elsewhere, maybe keep it flat for now (i.e. two use statements).
I think there are nightly rustfmt configs to tweak that, but so far we don't have automation on 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.
i didn't do this manually so i think this is something rust-analyzer + rustfmt concocted
The main usecase is to index into matrices like As an example: pub fn transposed(self) -> Self {
Self {
rows: [
Vector3::new(self[0][0], self[1][0], self[2][0]),
Vector3::new(self[0][1], self[1][1], self[2][1]),
Vector3::new(self[0][2], self[1][2], self[2][2]),
],
}
} |
In this case you only use literals, so you don't benefit from having the numbers (except for syntactical reasons). For example, the code you showed adds 9 extra bound checks -- which might be optimized away, or might not. If we really need random access syntax later, we can still consider something at the matrix level. But a general philosophy I'd like to follow is to start with a slim, non-redundant API and only expand when there is a significant use case that cannot be easily solved with existing APIs🙂 Regarding pub fn transposed(self) -> Self {
Self {
rows: [self.a(), self.b(), self.c()]
}
} |
|
I think i just find myself often getting frustrated when i'm not able to just index normally into things that are just lists of homogeneous values. Like i can't really think of a case from the std where something that is mentally just a list of values doesn't have a way to index into them without a good reason. Closest are probably tuples, but there it's just I'll remove them for now but that's where it comes from i think. For matrices at least i think we should have indexing though, mainly because godot does it. |
293fe3f to
e1aaa3f
Compare
But a 2D/3D vector is not just a list of values -- it's a geometric object. Slices in Rust are located at a much lower abstraction level. Nothing would prevent us from modeling And there is a good reason. I mentioned two of them already, but there are more:
I understand the desire to have that syntax, but for the use case described it seems to be based mostly on syntactical preference. * Edit: we conducted some further analysis on performance in this Godbolt example. With |
Bromeon
left a comment
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.
Thanks for the update!
bors try
| pub fn lerp_angle(from: f32, to: f32, weight: f32) -> f32 { | ||
| let difference = (to - from) % TAU; | ||
| let distance = (2.0 * difference) % TAU - difference; | ||
| from + distance * weight | ||
| } |
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.
Is this wrapping correctly?
Is the output in [0, TAU] or [-PI, PI] range or something else?
Some docs would be nice 🙂
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.
i just copied the code from godot, so i didn't super look into it closely.
https://github.com/godotengine/godot/blob/master/core/math/math_funcs.h#L389
tryBuild succeeded: |
Add glamconv/glamtype for Vector2/3/4 Add lerp_angle Add assert_eq_approx/assert_ne_approx
e1aaa3f to
91cc0a3
Compare
|
Thanks for the docs! Is it necessary to always pass |
If not it wont know what function to use. We could make it use the one for floats by default, but i decided not to. The main alternative would be to create a trait for |
But it's only about the name, no? As long as an |
Not really, because the |
|
Thanks! bors r+ |
|
Build succeeded: |
124: Implement the matrix types r=Bromeon a=sayaks Implement the four matrix types godot has: `Basis`, `Transform2D`, `Transform3D`, `Projection`. `Transform2D` in godot consists of an array of 3 `Vector2`s, where the first two are the basis. This means godot has some methods named `Transform2D::basis_<something>()`. I decided to instead make a struct `Basis2D`. so now any method like the above would be called `trans.basis.<something>()` instead. `Projection` has a lot of intricate math for many of its functions so it is largely a wrapper around `InnerProjection`, except for some methods that were easy to reimplement. Depends on #128 Co-authored-by: Lili Zoey <[email protected]>
Add bool as glam type
Add glamconv/glamtype for Vector2/3/4
Add assert_eq/ne_approx
Add lerp_angle
Split from #124