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