#if USE_SIMD import simd #endif #if USE_SIMD public typealias Matrix3x3 = simd_float3x3 public extension Matrix3x3 { typealias T = Float } #else public struct Matrix3x3: Equatable { public var m00: T, m01: T, m02: T public var m10: T, m11: T, m12: T public var m20: T, m21: T, m22: T public init() { self.m00 = 1; self.m01 = 0; self.m02 = 0 self.m10 = 0; self.m11 = 1; self.m12 = 0 self.m20 = 0; self.m21 = 0; self.m22 = 1 } public init( _ a00: T, _ a01: T, _ a02: T, _ a10: T, _ a11: T, _ a12: T, _ a20: T, _ a21: T, _ a22: T) { self.m00 = a00; self.m01 = a01; self.m02 = a02 self.m10 = a10; self.m11 = a11; self.m12 = a12 self.m20 = a20; self.m21 = a21; self.m22 = a22 } } public extension Matrix3x3 { init(_ row0: Vector3, _ row1: Vector3, _ row2: Vector3) { self.m00 = row0.x; self.m01 = row0.y; self.m02 = row0.z self.m10 = row1.x; self.m11 = row1.y; self.m12 = row1.z self.m20 = row2.x; self.m21 = row2.y; self.m22 = row2.z } @inline(__always) var identity: Self { Self( 1, 0, 0, 0, 1, 0, 0, 0, 1) } @inline(__always) var transpose: Self { Self( m00, m10, m20, m01, m11, m21, m02, m12, m22) } static func * (lhs: Self, rhs: Self) -> Self { Self( lhs.m00 * rhs.m00 + lhs.m01 * rhs.m10 + lhs.m02 * rhs.m20, lhs.m00 * rhs.m01 + lhs.m01 * rhs.m11 + lhs.m02 * rhs.m21, lhs.m00 * rhs.m02 + lhs.m01 * rhs.m12 + lhs.m02 * rhs.m22, lhs.m10 * rhs.m00 + lhs.m11 * rhs.m10 + lhs.m12 * rhs.m20, lhs.m10 * rhs.m01 + lhs.m11 * rhs.m11 + lhs.m12 * rhs.m21, lhs.m10 * rhs.m02 + lhs.m11 * rhs.m12 + lhs.m12 * rhs.m22, lhs.m20 * rhs.m00 + lhs.m21 * rhs.m10 + lhs.m22 * rhs.m20, lhs.m20 * rhs.m01 + lhs.m21 * rhs.m11 + lhs.m22 * rhs.m21, lhs.m20 * rhs.m02 + lhs.m21 * rhs.m12 + lhs.m22 * rhs.m22) } } #endif public extension Matrix3x3 { @inline(__always) static func lookAt(from: Vector3 = .zero, to: Vector3, up: Vector3 = .up) -> Self { let direction = (to - from).normalised let normal = -direction let bitangent = up.cross(normal).normalised let tangent = normal.cross(bitangent).normalised return Self( .init(bitangent.x, tangent.x, normal.x), .init(bitangent.y, tangent.y, normal.y), .init(bitangent.z, tangent.z, normal.z)) } } #if USE_SIMD public typealias Mat3f = Matrix3x3 #else public typealias Mat3f = Matrix3x3 public typealias Mat3d = Matrix3x3 #endif