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 aabb;
|
||||||
|
pub mod affine_transform;
|
||||||
pub mod camera;
|
pub mod camera;
|
||||||
pub mod color;
|
pub mod color;
|
||||||
pub mod light;
|
pub mod light;
|
||||||
|
|
|
||||||
9
ray-tracing-pbrt-scene/examples/transformation_test.rs
Normal file
9
ray-tracing-pbrt-scene/examples/transformation_test.rs
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
use ray_tracing_core::{affine_transform::AffineTransform, math::Dir3, prelude::*};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut t = AffineTransform::scale(1.0, 1.0, 2.0);
|
||||||
|
|
||||||
|
t *= AffineTransform::rotation(FloatConsts::PI, Dir3::up());
|
||||||
|
|
||||||
|
dbg!(t);
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue