pub struct AffineMatrix<T = Num<i32, 8>> {
pub a: T,
pub b: T,
pub c: T,
pub d: T,
pub x: T,
pub y: T,
}Expand description
An affine matrix stored in a way that is efficient for the GBA to perform operations on. This implements multiplication.
a b x
c d y
0 0 0§Affine matrices for the Game Boy Advance
An affine matrix represents an affine transformation, an affine transformation being one which preserves parallel lines (note that this therefore cannot represent perspective seen in games like Super Mario Kart). Affine matrices are used in two places on the GBA, for affine backgrounds and for affine objects.
§Linear Algebra
As a matrix, they can be manipulated using linear algebra. The short version of this section is to beware that the matrix is the inverse of the normal transformation matrices.
One quick thing to point out at the start as it will become very relevant is that matrix-matrix multiplication is not commutative, meaning swapping the order changes the result, or A × B ≢ B × A. However, matrices are, at least in the case they are used here, associative, meaning (AB)C = A(BC).
§Normal (wrong on GBA!) transformation matrices
As a start, normal transformation matrices will transform a shape from it’s original position to it’s new position. Generally when people talk about transformation matrices they are talking about them in this sense.
If A and B are transformation matrices, then matrix C = A × B represents the transformation A performed on B, or alternatively C is transformation B followed by transformation A.
This is not what they represent on the GBA! If you are looking up more information about transformation matrices bear this in mind.
§Correct (on GBA) transformation matrices
On the GBA, the affine matrix works the other way around. The GBA wants to know for each pixel what colour it should render, to do this it applies the affine transformation matrix to the pixel it is rendering to lookup correct pixel in the texture.
This describes the inverse of the previously given transformation matrices.
Above I described the matrix C = A × B, but what the GBA wants is the inverse of C, or C-1 = (AB)-1 = B-1 × A-1. This means that if we have the matrices I and J in the form the GBA expects then
Transformation K = I × J is the transformation I followed by the transformation J.
Beware if you are used to the other way around!
§Example, rotation around the centre
To rotate something around its centre, you will need to move the thing such that the centre is at (0, 0) and then you can rotate it. After that you can move it where you actually want it.
These can be done in the order I stated, A = Move To Origin × Rotate × Move to Final Position. Or in code,
use agb::fixnum::{Vector2D, Num, num};
use agb::display::AffineMatrix;
// size of our thing is 10 pixels by 10 pixels
let size_of_thing: Vector2D<Num<i32, 8>> = (10, 10).into();
// rotation by a quarter turn
let rotation: Num<i32, 8> = num!(0.25);
// the final position
let position: Vector2D<Num<i32, 8>> = (100, 100).into();
// now lets calculate the final transformation matrix!
let a = AffineMatrix::from_translation(-size_of_thing / 2)
* AffineMatrix::from_rotation(rotation)
* AffineMatrix::from_translation(position);Fields§
§a: T§b: T§c: T§d: T§x: T§y: TImplementations§
Source§impl<T: SignedNumber> AffineMatrix<T>
impl<T: SignedNumber> AffineMatrix<T>
Sourcepub fn identity() -> Self
pub fn identity() -> Self
The Identity matrix. The identity matrix can be thought of as 1 and is
represented by I. For a matrix A, A ≡ A * I ≡ I * A.
Sourcepub fn from_translation(position: Vector2D<T>) -> Self
pub fn from_translation(position: Vector2D<T>) -> Self
Generates the matrix that represents a translation by the position
Sourcepub fn from_scale(scale: Vector2D<T>) -> Self
pub fn from_scale(scale: Vector2D<T>) -> Self
Creates an affine matrix from a given (x, y) scaling. This will scale by the inverse, ie (2, 2) will produce half the size.
Sourcepub fn from_shear(shear: Vector2D<T>) -> AffineMatrix<T>
pub fn from_shear(shear: Vector2D<T>) -> AffineMatrix<T>
Creates an affine matrix from a given (λ, μ) shearing.
Source§impl<I, const N: usize> AffineMatrix<Num<I, N>>where
I: FixedWidthSignedInteger,
impl<I, const N: usize> AffineMatrix<Num<I, N>>where
I: FixedWidthSignedInteger,
Sourcepub fn from_rotation(angle: Num<I, N>) -> Self
pub fn from_rotation(angle: Num<I, N>) -> Self
Generates the matrix that represents a rotation
Sourcepub fn change_base<J, const M: usize>(self) -> AffineMatrix<Num<J, M>>where
J: FixedWidthSignedInteger + From<I>,
pub fn change_base<J, const M: usize>(self) -> AffineMatrix<Num<J, M>>where
J: FixedWidthSignedInteger + From<I>,
Change from one Num kind to another where the conversion is loss-less
Trait Implementations§
Source§impl<T: Clone> Clone for AffineMatrix<T>
impl<T: Clone> Clone for AffineMatrix<T>
Source§fn clone(&self) -> AffineMatrix<T>
fn clone(&self) -> AffineMatrix<T>
1.0.0§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<T: Debug> Debug for AffineMatrix<T>
impl<T: Debug> Debug for AffineMatrix<T>
Source§impl<T: SignedNumber> Default for AffineMatrix<T>
impl<T: SignedNumber> Default for AffineMatrix<T>
Source§impl From<AffineMatrix> for AffineMatrixBackground
impl From<AffineMatrix> for AffineMatrixBackground
Source§fn from(value: AffineMatrix) -> Self
fn from(value: AffineMatrix) -> Self
Source§impl From<AffineMatrix> for AffineMatrixObject
impl From<AffineMatrix> for AffineMatrixObject
Source§fn from(value: AffineMatrix) -> Self
fn from(value: AffineMatrix) -> Self
Source§impl From<AffineMatrixBackground> for AffineMatrix
impl From<AffineMatrixBackground> for AffineMatrix
Source§fn from(mat: AffineMatrixBackground) -> Self
fn from(mat: AffineMatrixBackground) -> Self
Source§impl<T: SignedNumber> Mul<Vector2D<T>> for AffineMatrix<T>
impl<T: SignedNumber> Mul<Vector2D<T>> for AffineMatrix<T>
Source§impl<T: SignedNumber> Mul for AffineMatrix<T>
impl<T: SignedNumber> Mul for AffineMatrix<T>
Source§impl<T: SignedNumber> MulAssign for AffineMatrix<T>
impl<T: SignedNumber> MulAssign for AffineMatrix<T>
Source§fn mul_assign(&mut self, rhs: Self)
fn mul_assign(&mut self, rhs: Self)
*= operation. Read moreSource§impl<T: PartialEq> PartialEq for AffineMatrix<T>
impl<T: PartialEq> PartialEq for AffineMatrix<T>
impl<T: Copy> Copy for AffineMatrix<T>
impl<T: Eq> Eq for AffineMatrix<T>
impl<T> StructuralPartialEq for AffineMatrix<T>
Auto Trait Implementations§
impl<T> Freeze for AffineMatrix<T>where
T: Freeze,
impl<T> RefUnwindSafe for AffineMatrix<T>where
T: RefUnwindSafe,
impl<T> Send for AffineMatrix<T>where
T: Send,
impl<T> Sync for AffineMatrix<T>where
T: Sync,
impl<T> Unpin for AffineMatrix<T>where
T: Unpin,
impl<T> UnwindSafe for AffineMatrix<T>where
T: UnwindSafe,
Blanket Implementations§
§impl<T> Any for Twhere
T: 'static + ?Sized,
impl<T> Any for Twhere
T: 'static + ?Sized,
§impl<T> Borrow<T> for Twhere
T: ?Sized,
impl<T> Borrow<T> for Twhere
T: ?Sized,
§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§unsafe fn clone_to_uninit(&self, dest: *mut u8)
unsafe fn clone_to_uninit(&self, dest: *mut u8)
clone_to_uninit)