bitshifter / glam-rs

A simple and fast linear algebra library for games and graphics
Apache License 2.0
1.46k stars 145 forks source link

Add matrix transpose multiplication #494

Open bitshifter opened 4 months ago

bitshifter commented 4 months ago

Discussed in https://github.com/bitshifter/glam-rs/discussions/358

Originally posted by **dataphract** October 31, 2022 In collision detection, it's often useful to perform computations in the local space of one of the involved objects. For instance, given an OBB: ```rust struct Obb { half_extents: Vec3, orientation: Vec3, } ``` the closest point within the OBB to another point can be found like so: ```rust impl Obb { fn closest(&self, other: Vec3) -> Vec3 { let inv_orientation = self.orientation.transpose(); let local_other = inv_orientation * other; self.orientation * local_other.clamp(-self.half_extents, self.half_extents) } } ``` `other` is converted to the local space of `self` by premultiplying by the inverse of `self.orientation`, and since `self.orientation` is an orthonormal basis, its inverse is equivalent to its transpose. However, it's not necessary to actually construct the transposed matrix -- the multiplication can be performed by dotting the columns of the left-hand side with the columns of the right. Ideally, we could instead write: ```rust impl Obb { fn closest(&self, other: Vec3) -> Vec3 { let local_other = self.orientation.mul_transpose(other); // or transpose_mul(), if you like self.orientation * local_other.clamp(-self.half_extents, self.half_extents) } } ```