-
Notifications
You must be signed in to change notification settings - Fork 32
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
Added Transform multiplication and Quaternion::mul_direction #78
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -417,6 +417,13 @@ macro_rules! quaternion_complete_mod { | |
pub fn into_vec3(self) -> Vec3<T> { | ||
self.into() | ||
} | ||
|
||
/// Shortcut for `self * Vec4::from_point(rhs)`. | ||
pub fn mul_direction<V: Into<Vec3<T>> + From<Vec4<T>>>(self, rhs: V) -> V | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would make sense to add |
||
where T: Real + MulAdd<T,T,Output=T> | ||
{ | ||
(self * Vec4::from_direction(rhs.into())).into() | ||
} | ||
} | ||
|
||
#[cfg(feature = "mint")] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,7 @@ macro_rules! transform_complete_mod { | |
// look_at | ||
// rotate_around | ||
|
||
use std::ops::Add; | ||
use std::ops::{Add, Mul}; | ||
use $crate::num_traits::{Zero, One, real::Real}; | ||
use $crate::ops::*; | ||
use crate::vec::$mod::*; | ||
|
@@ -26,7 +26,7 @@ macro_rules! transform_complete_mod { | |
/// let (p, rz, s) = (Vec3::unit_x(), 3.0_f32, 5.0_f32); | ||
/// let a = Mat4::scaling_3d(s).rotated_z(rz).translated_3d(p); | ||
/// let b = Mat4::from(Transform { | ||
/// position: p, | ||
/// position: p, | ||
/// orientation: Quaternion::rotation_z(rz), | ||
/// scale: Vec3::broadcast(s), | ||
/// }); | ||
|
@@ -68,9 +68,24 @@ macro_rules! transform_complete_mod { | |
} | ||
} | ||
|
||
/// LERP on a `Transform` is defined as LERP-ing between the positions and scales, | ||
impl<T> Mul for Transform<T,T,T> | ||
where T: Real + MulAdd<T,T,Output=T> | ||
{ | ||
type Output = Self; | ||
fn mul(self, rhs: Self) -> Self { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with the idea to allow Transform to be multiplied by another, just like matrices!
So the plan for 3. would be :
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This is the implementation used by In hindsight, I don't think that my application of scaling is correct under rotation when the scale is non-scalar: I'll correct that. Edit: Actually, I don't think that I can even determine the correct code without the order of application being made explicit. What order are the translation/orientation/scaling operations supposed to be made in? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think it's safe to look at Unreal's void FTransform::Multiply(FTransform* OutTransform, const FTransform* A, const FTransform* B). Their implementation is very similar to your initial impl, except they compute We should note that when they write A * B, it means "B applied over A, so A transformed by B". But, when we write A * B, we will want to mean "A applied over B, so B transformed by A". |
||
let shift = self.orientation.mul_direction(rhs.position) * self.scale; | ||
|
||
Self { | ||
position: self.position + shift, | ||
orientation: self.orientation * rhs.orientation, | ||
scale: self.scale * rhs.scale, | ||
} | ||
} | ||
} | ||
|
||
/// LERP on a `Transform` is defined as LERP-ing between the positions and scales, | ||
/// and performing SLERP between the orientations. | ||
impl<P,O,S,Factor> Lerp<Factor> for Transform<P,O,S> | ||
impl<P,O,S,Factor> Lerp<Factor> for Transform<P,O,S> | ||
where Factor: Copy + Into<O>, | ||
P: Lerp<Factor,Output=P>, | ||
S: Lerp<Factor,Output=S>, | ||
|
@@ -93,9 +108,9 @@ macro_rules! transform_complete_mod { | |
} | ||
} | ||
|
||
/// LERP on a `Transform` is defined as LERP-ing between the positions and scales, | ||
/// LERP on a `Transform` is defined as LERP-ing between the positions and scales, | ||
/// and performing SLERP between the orientations. | ||
impl<'a,P,O,S,Factor> Lerp<Factor> for &'a Transform<P,O,S> | ||
impl<'a,P,O,S,Factor> Lerp<Factor> for &'a Transform<P,O,S> | ||
where Factor: Copy + Into<O>, | ||
&'a P: Lerp<Factor,Output=P>, | ||
&'a S: Lerp<Factor,Output=S>, | ||
|
@@ -117,8 +132,8 @@ macro_rules! transform_complete_mod { | |
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
#[cfg(all(nightly, feature="repr_simd"))] | ||
pub mod repr_simd { | ||
|
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.
The comment should mention Vec4::from_direction instead :)