quaternion.rs (2434B)
1 use crate::Vec3; 2 3 // A simple quaternion implementation 4 pub struct Quaternion { 5 pub x: f32, 6 pub y: f32, 7 pub z: f32, 8 pub w: f32, 9 } 10 11 impl Quaternion { 12 // Create identity quaternion 13 pub fn identity() -> Self { 14 Self { 15 x: 0.0, 16 y: 0.0, 17 z: 0.0, 18 w: 1.0, 19 } 20 } 21 22 // Create from axis-angle representation 23 pub fn from_axis_angle(axis: &Vec3, angle: f32) -> Self { 24 let half_angle = angle * 0.5; 25 let s = half_angle.sin(); 26 Self { 27 x: axis.x * s, 28 y: axis.y * s, 29 z: axis.z * s, 30 w: half_angle.cos(), 31 } 32 } 33 34 // Multiply two quaternions (combines rotations) 35 pub fn multiply(&self, other: &Self) -> Self { 36 Self { 37 x: self.w * other.x + self.x * other.w + self.y * other.z - self.z * other.y, 38 y: self.w * other.y - self.x * other.z + self.y * other.w + self.z * other.x, 39 z: self.w * other.z + self.x * other.y - self.y * other.x + self.z * other.w, 40 w: self.w * other.w - self.x * other.x - self.y * other.y - self.z * other.z, 41 } 42 } 43 44 // Convert quaternion to 4x4 matrix (for 3D transformation with homogeneous coordinates) 45 pub fn to_matrix4(&self) -> [f32; 16] { 46 // Normalize quaternion 47 let magnitude = 48 (self.x * self.x + self.y * self.y + self.z * self.z + self.w * self.w).sqrt(); 49 let x = self.x / magnitude; 50 let y = self.y / magnitude; 51 let z = self.z / magnitude; 52 let w = self.w / magnitude; 53 54 let x2 = x * x; 55 let y2 = y * y; 56 let z2 = z * z; 57 let xy = x * y; 58 let xz = x * z; 59 let yz = y * z; 60 let wx = w * x; 61 let wy = w * y; 62 let wz = w * z; 63 64 // Row-major 3x3 rotation matrix components 65 let m00 = 1.0 - 2.0 * (y2 + z2); 66 let m01 = 2.0 * (xy - wz); 67 let m02 = 2.0 * (xz + wy); 68 69 let m10 = 2.0 * (xy + wz); 70 let m11 = 1.0 - 2.0 * (x2 + z2); 71 let m12 = 2.0 * (yz - wx); 72 73 let m20 = 2.0 * (xz - wy); 74 let m21 = 2.0 * (yz + wx); 75 let m22 = 1.0 - 2.0 * (x2 + y2); 76 77 // Convert 3x3 rotation matrix to 4x4 transformation matrix 78 // Note: This is column-major for WGPU 79 [ 80 m00, m10, m20, 0.0, m01, m11, m21, 0.0, m02, m12, m22, 0.0, 0.0, 0.0, 0.0, 1.0, 81 ] 82 } 83 }