Skip to main content

AffineMatrix

Struct AffineMatrix 

Source
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 × BB × 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: T

Implementations§

Source§

impl<T: SignedNumber> AffineMatrix<T>

Source

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.

Source

pub fn from_translation(position: Vector2D<T>) -> Self

Generates the matrix that represents a translation by the position

Source

pub fn position(&self) -> Vector2D<T>

The position fields of the matrix

Source

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.

Source

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>>

Source

pub fn from_rotation(angle: Num<I, N>) -> Self

Generates the matrix that represents a rotation

Source

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>

Source§

fn clone(&self) -> AffineMatrix<T>

Returns a duplicate of the value. Read more
1.0.0§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug> Debug for AffineMatrix<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: SignedNumber> Default for AffineMatrix<T>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl From<AffineMatrix> for AffineMatrixBackground

Source§

fn from(value: AffineMatrix) -> Self

Converts to this type from the input type.
Source§

impl From<AffineMatrix> for AffineMatrixObject

Source§

fn from(value: AffineMatrix) -> Self

Converts to this type from the input type.
Source§

impl From<AffineMatrixBackground> for AffineMatrix

Source§

fn from(mat: AffineMatrixBackground) -> Self

Converts to this type from the input type.
Source§

impl<T: SignedNumber> Mul<Vector2D<T>> for AffineMatrix<T>

Source§

type Output = Vector2D<T>

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: Vector2D<T>) -> Self::Output

Performs the * operation. Read more
Source§

impl<T: SignedNumber> Mul for AffineMatrix<T>

Source§

type Output = AffineMatrix<T>

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: Self) -> Self::Output

Performs the * operation. Read more
Source§

impl<T: SignedNumber> MulAssign for AffineMatrix<T>

Source§

fn mul_assign(&mut self, rhs: Self)

Performs the *= operation. Read more
Source§

impl<T: PartialEq> PartialEq for AffineMatrix<T>

Source§

fn eq(&self, other: &AffineMatrix<T>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T: Copy> Copy for AffineMatrix<T>

Source§

impl<T: Eq> Eq for AffineMatrix<T>

Source§

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 T
where T: 'static + ?Sized,

§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<T> Borrow<T> for T
where T: ?Sized,

§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
§

impl<T> BorrowMut<T> for T
where T: ?Sized,

§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> CloneToUninit for T
where T: Clone,

§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> From<T> for T

§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, W> HasTypeWitness<W> for T
where W: MakeTypeWitness<Arg = T>, T: ?Sized,

Source§

const WITNESS: W = W::MAKE

A constant of the type witness
Source§

impl<T> Identity for T
where T: ?Sized,

Source§

const TYPE_EQ: TypeEq<T, <T as Identity>::Type> = TypeEq::NEW

Proof that Self is the same type as Self::Type, provides methods for casting between Self and Self::Type.
Source§

type Type = T

The same type as Self, used to emulate type equality bounds (T == U) with associated type equality constraints (T: Identity<Type = U>).
§

impl<T, U> Into<U> for T
where U: From<T>,

§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of [From]<T> for U chooses to do.

§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.