Files
CavesOfSwift/Sources/Maths/Matrix3x3.swift

100 lines
2.4 KiB
Swift

#if USE_SIMD
import simd
#endif
#if USE_SIMD
public typealias Matrix3x3 = simd_float3x3
public extension Matrix3x3
{
typealias T = Float
}
#else
public struct Matrix3x3<T: FloatingPoint>: 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<T>, _ row1: Vector3<T>, _ row2: Vector3<T>)
{
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<T> = .zero, to: Vector3<T>, up: Vector3<T> = .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<Float>
public typealias Mat3d = Matrix3x3<Double>
#endif