RMath: implement transforms for Vector, Point, and Normal.
This commit is contained in:
parent
d8e1437db1
commit
42cd282c47
|
@ -3,13 +3,14 @@
|
|||
use std::ops::{Add, Div, Mul, Neg, Sub};
|
||||
|
||||
use crate::wide4::Float4;
|
||||
use crate::xform::XformFull;
|
||||
use crate::DotProduct;
|
||||
use crate::Vector;
|
||||
|
||||
/// A surface normal in 3D space.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[repr(transparent)]
|
||||
pub struct Normal(pub(crate) Float4);
|
||||
pub struct Normal(pub Float4);
|
||||
|
||||
impl Normal {
|
||||
#[inline(always)]
|
||||
|
@ -71,6 +72,25 @@ impl Normal {
|
|||
pub fn set_z(self, z: f32) -> Self {
|
||||
Self(self.0.set_c(z))
|
||||
}
|
||||
|
||||
//-------------
|
||||
// Transforms.
|
||||
|
||||
pub fn xform(self, xform: &XformFull) -> Self {
|
||||
Self(self.0.vec_mul_3x3(&Float4::transpose_3x3(xform.m_inv)))
|
||||
}
|
||||
|
||||
pub fn xform_inv(self, xform: &XformFull) -> Self {
|
||||
Self(self.0.vec_mul_3x3(&Float4::transpose_3x3(xform.m)))
|
||||
}
|
||||
|
||||
pub fn xform_fast(self, xform: &XformFull) -> Self {
|
||||
Self(self.0.vec_mul_3x3_fast(&Float4::transpose_3x3(xform.m_inv)))
|
||||
}
|
||||
|
||||
pub fn xform_inv_fast(self, xform: &XformFull) -> Self {
|
||||
Self(self.0.vec_mul_3x3_fast(&Float4::transpose_3x3(xform.m)))
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for Normal {
|
||||
|
|
|
@ -3,11 +3,12 @@ use std::ops::{Add, Sub};
|
|||
|
||||
use crate::vector::Vector;
|
||||
use crate::wide4::Float4;
|
||||
use crate::xform::XformFull;
|
||||
|
||||
/// A position in 3D space.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[repr(transparent)]
|
||||
pub struct Point(pub(crate) Float4);
|
||||
pub struct Point(pub Float4);
|
||||
|
||||
impl Point {
|
||||
#[inline(always)]
|
||||
|
@ -62,6 +63,25 @@ impl Point {
|
|||
pub fn set_z(self, z: f32) -> Self {
|
||||
Self(self.0.set_c(z))
|
||||
}
|
||||
|
||||
//-------------
|
||||
// Transforms.
|
||||
|
||||
pub fn xform(self, xform: &XformFull) -> Self {
|
||||
Self(self.0.vec_mul_affine(&xform.m, xform.t))
|
||||
}
|
||||
|
||||
pub fn xform_inv(self, xform: &XformFull) -> Self {
|
||||
Self(self.0.vec_mul_affine_rev(&xform.m_inv, -xform.t))
|
||||
}
|
||||
|
||||
pub fn xform_fast(self, xform: &XformFull) -> Self {
|
||||
Self(self.0.vec_mul_affine_fast(&xform.m, xform.t))
|
||||
}
|
||||
|
||||
pub fn xform_inv_fast(self, xform: &XformFull) -> Self {
|
||||
Self(self.0.vec_mul_affine_rev_fast(&xform.m_inv, -xform.t))
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<Vector> for Point {
|
||||
|
|
|
@ -5,12 +5,13 @@ use std::ops::{Add, Div, Mul, Neg, Sub};
|
|||
use crate::normal::Normal;
|
||||
use crate::point::Point;
|
||||
use crate::wide4::Float4;
|
||||
use crate::xform::XformFull;
|
||||
use crate::DotProduct;
|
||||
|
||||
/// A direction vector in 3D space.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[repr(transparent)]
|
||||
pub struct Vector(pub(crate) Float4);
|
||||
pub struct Vector(pub Float4);
|
||||
|
||||
impl Vector {
|
||||
#[inline(always)]
|
||||
|
@ -77,6 +78,25 @@ impl Vector {
|
|||
pub fn set_z(self, z: f32) -> Self {
|
||||
Self(self.0.set_c(z))
|
||||
}
|
||||
|
||||
//-------------
|
||||
// Transforms.
|
||||
|
||||
pub fn xform(self, xform: &XformFull) -> Self {
|
||||
Self(self.0.vec_mul_3x3(&xform.m))
|
||||
}
|
||||
|
||||
pub fn xform_inv(self, xform: &XformFull) -> Self {
|
||||
Self(self.0.vec_mul_3x3(&xform.m_inv))
|
||||
}
|
||||
|
||||
pub fn xform_fast(self, xform: &XformFull) -> Self {
|
||||
Self(self.0.vec_mul_3x3_fast(&xform.m))
|
||||
}
|
||||
|
||||
pub fn xform_inv_fast(self, xform: &XformFull) -> Self {
|
||||
Self(self.0.vec_mul_3x3_fast(&xform.m_inv))
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for Vector {
|
||||
|
|
|
@ -10,7 +10,6 @@ mod fallback {
|
|||
|
||||
use crate::FMulAdd;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[repr(C, align(16))]
|
||||
pub struct Float4 {
|
||||
|
@ -463,6 +462,18 @@ impl Float4 {
|
|||
s3 + err3
|
||||
}
|
||||
|
||||
/// Transforms a 3d point by an affine transform.
|
||||
///
|
||||
/// Faster but less precise version.
|
||||
#[inline]
|
||||
pub fn vec_mul_affine_fast(self, m: &[Self; 3], t: Self) -> Self {
|
||||
let x = self.aaaa();
|
||||
let y = self.bbbb();
|
||||
let z = self.cccc();
|
||||
|
||||
(x * m[0]) + (y * m[1]) + (z * m[2]) + t
|
||||
}
|
||||
|
||||
/// Transforms a 3d point by an affine transform, except it applies
|
||||
/// the translation part before the 3x3 part.
|
||||
///
|
||||
|
@ -499,6 +510,21 @@ impl Float4 {
|
|||
s3 + err3
|
||||
}
|
||||
|
||||
/// Transforms a 3d point by an affine transform, except it applies
|
||||
/// the translation part before the 3x3 part.
|
||||
///
|
||||
/// Faster but less precise version.
|
||||
#[inline]
|
||||
pub fn vec_mul_affine_rev_fast(self, m: &[Self; 3], t: Self) -> Self {
|
||||
let v = self + t;
|
||||
|
||||
let x = v.aaaa();
|
||||
let y = v.bbbb();
|
||||
let z = v.cccc();
|
||||
|
||||
(x * m[0]) + (y * m[1]) + (z * m[2])
|
||||
}
|
||||
|
||||
/// Returns whether the `Float4`s are approximately equal to each
|
||||
/// other.
|
||||
///
|
||||
|
|
|
@ -9,8 +9,8 @@ use crate::wide4::Float4;
|
|||
#[derive(Debug, Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct Xform {
|
||||
pub(crate) m: [Float4; 3], // Linear matrix.
|
||||
pub(crate) t: Float4, // Translation.
|
||||
pub m: [Float4; 3], // Linear matrix.
|
||||
pub t: Float4, // Translation.
|
||||
}
|
||||
|
||||
impl Xform {
|
||||
|
@ -170,9 +170,9 @@ impl Add for Xform {
|
|||
#[derive(Debug, Copy, Clone)]
|
||||
#[repr(C)]
|
||||
pub struct XformFull {
|
||||
pub(crate) m: [Float4; 3], // Linear matrix.
|
||||
pub(crate) m_inv: [Float4; 3], // Inverse of linear matrix.
|
||||
pub(crate) t: Float4, // Forward translation.
|
||||
pub m: [Float4; 3], // Forward linear matrix.
|
||||
pub m_inv: [Float4; 3], // Inverse linear matrix.
|
||||
pub t: Float4, // Forward translation.
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue
Block a user