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 std::ops::{Add, Div, Mul, Neg, Sub};
|
||||||
|
|
||||||
use crate::wide4::Float4;
|
use crate::wide4::Float4;
|
||||||
|
use crate::xform::XformFull;
|
||||||
use crate::DotProduct;
|
use crate::DotProduct;
|
||||||
use crate::Vector;
|
use crate::Vector;
|
||||||
|
|
||||||
/// A surface normal in 3D space.
|
/// A surface normal in 3D space.
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct Normal(pub(crate) Float4);
|
pub struct Normal(pub Float4);
|
||||||
|
|
||||||
impl Normal {
|
impl Normal {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
@ -71,6 +72,25 @@ impl Normal {
|
||||||
pub fn set_z(self, z: f32) -> Self {
|
pub fn set_z(self, z: f32) -> Self {
|
||||||
Self(self.0.set_c(z))
|
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 {
|
impl Add for Normal {
|
||||||
|
|
|
@ -3,11 +3,12 @@ use std::ops::{Add, Sub};
|
||||||
|
|
||||||
use crate::vector::Vector;
|
use crate::vector::Vector;
|
||||||
use crate::wide4::Float4;
|
use crate::wide4::Float4;
|
||||||
|
use crate::xform::XformFull;
|
||||||
|
|
||||||
/// A position in 3D space.
|
/// A position in 3D space.
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct Point(pub(crate) Float4);
|
pub struct Point(pub Float4);
|
||||||
|
|
||||||
impl Point {
|
impl Point {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
@ -62,6 +63,25 @@ impl Point {
|
||||||
pub fn set_z(self, z: f32) -> Self {
|
pub fn set_z(self, z: f32) -> Self {
|
||||||
Self(self.0.set_c(z))
|
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 {
|
impl Add<Vector> for Point {
|
||||||
|
|
|
@ -5,12 +5,13 @@ use std::ops::{Add, Div, Mul, Neg, Sub};
|
||||||
use crate::normal::Normal;
|
use crate::normal::Normal;
|
||||||
use crate::point::Point;
|
use crate::point::Point;
|
||||||
use crate::wide4::Float4;
|
use crate::wide4::Float4;
|
||||||
|
use crate::xform::XformFull;
|
||||||
use crate::DotProduct;
|
use crate::DotProduct;
|
||||||
|
|
||||||
/// A direction vector in 3D space.
|
/// A direction vector in 3D space.
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct Vector(pub(crate) Float4);
|
pub struct Vector(pub Float4);
|
||||||
|
|
||||||
impl Vector {
|
impl Vector {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
@ -77,6 +78,25 @@ impl Vector {
|
||||||
pub fn set_z(self, z: f32) -> Self {
|
pub fn set_z(self, z: f32) -> Self {
|
||||||
Self(self.0.set_c(z))
|
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 {
|
impl Add for Vector {
|
||||||
|
|
|
@ -10,7 +10,6 @@ mod fallback {
|
||||||
|
|
||||||
use crate::FMulAdd;
|
use crate::FMulAdd;
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
#[repr(C, align(16))]
|
#[repr(C, align(16))]
|
||||||
pub struct Float4 {
|
pub struct Float4 {
|
||||||
|
@ -463,6 +462,18 @@ impl Float4 {
|
||||||
s3 + err3
|
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
|
/// Transforms a 3d point by an affine transform, except it applies
|
||||||
/// the translation part before the 3x3 part.
|
/// the translation part before the 3x3 part.
|
||||||
///
|
///
|
||||||
|
@ -499,6 +510,21 @@ impl Float4 {
|
||||||
s3 + err3
|
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
|
/// Returns whether the `Float4`s are approximately equal to each
|
||||||
/// other.
|
/// other.
|
||||||
///
|
///
|
||||||
|
|
|
@ -9,8 +9,8 @@ use crate::wide4::Float4;
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Xform {
|
pub struct Xform {
|
||||||
pub(crate) m: [Float4; 3], // Linear matrix.
|
pub m: [Float4; 3], // Linear matrix.
|
||||||
pub(crate) t: Float4, // Translation.
|
pub t: Float4, // Translation.
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Xform {
|
impl Xform {
|
||||||
|
@ -170,9 +170,9 @@ impl Add for Xform {
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct XformFull {
|
pub struct XformFull {
|
||||||
pub(crate) m: [Float4; 3], // Linear matrix.
|
pub m: [Float4; 3], // Forward linear matrix.
|
||||||
pub(crate) m_inv: [Float4; 3], // Inverse of linear matrix.
|
pub m_inv: [Float4; 3], // Inverse linear matrix.
|
||||||
pub(crate) t: Float4, // Forward translation.
|
pub t: Float4, // Forward translation.
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------
|
//-------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue
Block a user