Add AffineTransform
This commit is contained in:
parent
900fe532b5
commit
e16a916413
3 changed files with 219 additions and 0 deletions
209
ray-tracing-core/src/affine_transform.rs
Normal file
209
ray-tracing-core/src/affine_transform.rs
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
use std::ops::{Mul, MulAssign};
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct AffineTransform {
|
||||
mat: [[Float; 4]; 3],
|
||||
inv: [[Float; 3]; 3],
|
||||
}
|
||||
|
||||
impl AffineTransform {
|
||||
pub fn identity() -> Self {
|
||||
Self {
|
||||
mat: [
|
||||
[1.0, 0.0, 0.0, 0.0],
|
||||
[0.0, 1.0, 0.0, 0.0],
|
||||
[0.0, 0.0, 1.0, 0.0],
|
||||
],
|
||||
inv: [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn translation(pos: Pos3) -> Self {
|
||||
Self {
|
||||
mat: [
|
||||
[1.0, 0.0, 0.0, pos.x()],
|
||||
[0.0, 1.0, 0.0, pos.y()],
|
||||
[0.0, 0.0, 1.0, pos.z()],
|
||||
],
|
||||
inv: [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scale(sx: Float, sy: Float, sz: Float) -> Self {
|
||||
Self {
|
||||
mat: [
|
||||
[sx, 0.0, 0.0, 0.0],
|
||||
[0.0, sy, 0.0, 0.0],
|
||||
[0.0, 0.0, sz, 0.0],
|
||||
],
|
||||
inv: [
|
||||
[1.0 / sx, 0.0, 0.0],
|
||||
[0.0, 1.0 / sy, 0.0],
|
||||
[0.0, 0.0, 1.0 / sz],
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn rotation(angle: Float, dir: Dir3) -> Self {
|
||||
let mat = [
|
||||
[
|
||||
dir.x() * dir.x() * (1.0 - angle.cos()) + angle.cos(),
|
||||
dir.x() * dir.y() * (1.0 - angle.cos()) - dir.z() * angle.sin(),
|
||||
dir.x() * dir.z() * (1.0 - angle.cos()) + dir.y() * angle.sin(),
|
||||
0.0,
|
||||
],
|
||||
[
|
||||
dir.x() * dir.y() * (1.0 - angle.cos()) + dir.z() * angle.sin(),
|
||||
dir.y() * dir.y() * (1.0 - angle.cos()) + angle.cos(),
|
||||
dir.y() * dir.z() * (1.0 - angle.cos()) - dir.x() * angle.sin(),
|
||||
0.0,
|
||||
],
|
||||
[
|
||||
dir.x() * dir.z() * (1.0 - angle.cos()) - dir.y() * angle.sin(),
|
||||
dir.y() * dir.z() * (1.0 - angle.cos()) + dir.x() * angle.sin(),
|
||||
dir.z() * dir.z() * (1.0 - angle.cos()) + angle.cos(),
|
||||
0.0,
|
||||
],
|
||||
];
|
||||
Self {
|
||||
mat,
|
||||
inv: [
|
||||
[mat[0][0], mat[1][0], mat[2][0]],
|
||||
[mat[0][1], mat[1][1], mat[2][1]],
|
||||
[mat[0][2], mat[1][2], mat[2][2]],
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn transform_pos(&self, pos: Pos3) -> Pos3 {
|
||||
Pos3::new(
|
||||
self.mat[0][0] * pos.x()
|
||||
+ self.mat[0][1] * pos.y()
|
||||
+ self.mat[0][2] * pos.z()
|
||||
+ self.mat[0][3],
|
||||
self.mat[1][0] * pos.x()
|
||||
+ self.mat[1][1] * pos.y()
|
||||
+ self.mat[1][2] * pos.z()
|
||||
+ self.mat[1][3],
|
||||
self.mat[2][0] * pos.x()
|
||||
+ self.mat[2][1] * pos.y()
|
||||
+ self.mat[2][2] * pos.z()
|
||||
+ self.mat[2][3],
|
||||
)
|
||||
}
|
||||
pub fn transform_normal(&self, pos: Pos3) -> Pos3 {
|
||||
Pos3::new(
|
||||
self.inv[0][0] * pos.x() + self.inv[0][1] * pos.y() + self.inv[0][2] * pos.z(),
|
||||
self.inv[1][0] * pos.x() + self.inv[1][1] * pos.y() + self.inv[1][2] * pos.z(),
|
||||
self.inv[2][0] * pos.x() + self.inv[2][1] * pos.y() + self.inv[2][2] * pos.z(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<AffineTransform> for AffineTransform {
|
||||
type Output = AffineTransform;
|
||||
|
||||
fn mul(self, rhs: Self) -> Self::Output {
|
||||
Self {
|
||||
mat: [
|
||||
[
|
||||
self.mat[0][0] * rhs.mat[0][0]
|
||||
+ self.mat[0][1] * rhs.mat[1][0]
|
||||
+ self.mat[0][2] * rhs.mat[2][0]
|
||||
+ self.mat[0][3],
|
||||
self.mat[0][0] * rhs.mat[0][1]
|
||||
+ self.mat[0][1] * rhs.mat[1][1]
|
||||
+ self.mat[0][2] * rhs.mat[2][1]
|
||||
+ self.mat[0][3],
|
||||
self.mat[0][0] * rhs.mat[0][2]
|
||||
+ self.mat[0][1] * rhs.mat[1][2]
|
||||
+ self.mat[0][2] * rhs.mat[2][2]
|
||||
+ self.mat[0][3],
|
||||
self.mat[0][0] * rhs.mat[0][3]
|
||||
+ self.mat[0][1] * rhs.mat[1][3]
|
||||
+ self.mat[0][2] * rhs.mat[2][3]
|
||||
+ self.mat[0][3],
|
||||
],
|
||||
[
|
||||
self.mat[1][0] * rhs.mat[0][0]
|
||||
+ self.mat[1][1] * rhs.mat[1][0]
|
||||
+ self.mat[1][2] * rhs.mat[2][0]
|
||||
+ self.mat[1][3],
|
||||
self.mat[1][0] * rhs.mat[0][1]
|
||||
+ self.mat[1][1] * rhs.mat[1][1]
|
||||
+ self.mat[1][2] * rhs.mat[2][1]
|
||||
+ self.mat[1][3],
|
||||
self.mat[1][0] * rhs.mat[0][2]
|
||||
+ self.mat[1][1] * rhs.mat[1][2]
|
||||
+ self.mat[1][2] * rhs.mat[2][2]
|
||||
+ self.mat[1][3],
|
||||
self.mat[1][0] * rhs.mat[0][3]
|
||||
+ self.mat[1][1] * rhs.mat[1][3]
|
||||
+ self.mat[1][2] * rhs.mat[2][3]
|
||||
+ self.mat[1][3],
|
||||
],
|
||||
[
|
||||
self.mat[2][0] * rhs.mat[0][0]
|
||||
+ self.mat[2][1] * rhs.mat[1][0]
|
||||
+ self.mat[2][2] * rhs.mat[2][0]
|
||||
+ self.mat[2][3],
|
||||
self.mat[2][0] * rhs.mat[0][1]
|
||||
+ self.mat[2][1] * rhs.mat[1][1]
|
||||
+ self.mat[2][2] * rhs.mat[2][1]
|
||||
+ self.mat[2][3],
|
||||
self.mat[2][0] * rhs.mat[0][2]
|
||||
+ self.mat[2][1] * rhs.mat[1][2]
|
||||
+ self.mat[2][2] * rhs.mat[2][2]
|
||||
+ self.mat[2][3],
|
||||
self.mat[2][0] * rhs.mat[0][3]
|
||||
+ self.mat[2][1] * rhs.mat[1][3]
|
||||
+ self.mat[2][2] * rhs.mat[2][3]
|
||||
+ self.mat[2][3],
|
||||
],
|
||||
],
|
||||
inv: [
|
||||
[
|
||||
rhs.inv[0][0] * self.inv[0][0]
|
||||
+ rhs.inv[0][1] * self.inv[1][0]
|
||||
+ rhs.inv[0][2] * self.inv[2][0],
|
||||
rhs.inv[0][0] * self.inv[0][1]
|
||||
+ rhs.inv[0][1] * self.inv[1][1]
|
||||
+ rhs.inv[0][2] * self.inv[2][1],
|
||||
rhs.inv[0][0] * self.inv[0][2]
|
||||
+ rhs.inv[0][1] * self.inv[1][2]
|
||||
+ rhs.inv[0][2] * self.inv[2][2],
|
||||
],
|
||||
[
|
||||
rhs.inv[1][0] * self.inv[0][0]
|
||||
+ rhs.inv[1][1] * self.inv[1][0]
|
||||
+ rhs.inv[1][2] * self.inv[2][0],
|
||||
rhs.inv[1][0] * self.inv[0][1]
|
||||
+ rhs.inv[1][1] * self.inv[1][1]
|
||||
+ rhs.inv[1][2] * self.inv[2][1],
|
||||
rhs.inv[1][0] * self.inv[0][2]
|
||||
+ rhs.inv[1][1] * self.inv[1][2]
|
||||
+ rhs.inv[1][2] * self.inv[2][2],
|
||||
],
|
||||
[
|
||||
rhs.inv[2][0] * self.inv[0][0]
|
||||
+ rhs.inv[2][1] * self.inv[1][0]
|
||||
+ rhs.inv[2][2] * self.inv[2][0],
|
||||
rhs.inv[2][0] * self.inv[0][1]
|
||||
+ rhs.inv[2][1] * self.inv[1][1]
|
||||
+ rhs.inv[2][2] * self.inv[2][1],
|
||||
rhs.inv[2][0] * self.inv[0][2]
|
||||
+ rhs.inv[2][1] * self.inv[1][2]
|
||||
+ rhs.inv[2][2] * self.inv[2][2],
|
||||
],
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MulAssign<AffineTransform> for AffineTransform {
|
||||
fn mul_assign(&mut self, rhs: AffineTransform) {
|
||||
*self = *self * rhs
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
pub mod aabb;
|
||||
pub mod affine_transform;
|
||||
pub mod camera;
|
||||
pub mod color;
|
||||
pub mod light;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue