// // Transforms.swift // MetalSpectrograph // // Created by David Conner on 9/9/15. // Copyright © 2015 Voxxel. All rights reserved. // import simd // swiftlint:disable identifier_name extension simd_float4x4 { static let identity = matrix_identity_float4x4 // sx 0 0 0 // 0 sy 0 0 // 0 0 sz 0 // 0 0 0 1 init(scale x: Float, y: Float, z: Float) { self.init(diagonal: [x, y, z, 1.0]) } // 1 0 0 tx // 0 1 0 ty // 0 0 1 tz // 0 0 0 1 init(translate: SIMD3) { self.init([1, 0.0, 0.0, translate.x], [0.0, 1, 0.0, translate.y], [0.0, 0.0, 1, translate.z], [0.0, 0.0, 0, 1]) } init(rotationX radians: Float) { let cos = cosf(radians) let sin = sinf(radians) self.init([1, 0.0, 0.0, 0], [0.0, cos, sin, 0], [0.0, -sin, cos, 0], [0.0, 0.0, 0, 1]) } init(rotationY radians: Float) { let cos = cosf(radians) let sin = sinf(radians) self.init([cos, 0.0, -sin, 0], [0.0, 1, 0, 0], [sin, 0, cos, 0], [0.0, 0.0, 0, 1]) } init(rotationZ radians: Float) { let cos = cosf(radians) let sin = sinf(radians) self.init([cos, sin, 0.0, 0], [-sin, cos, 0, 0], [0.0, 0, 1, 0], [0.0, 0.0, 0, 1]) } public init(lookAt eye: SIMD3, center: SIMD3, up: SIMD3) { let N = normalize(eye - center) let U = normalize(cross(up, N)) let V = cross(N, U) self.init(rows: [[U.x, V.x, N.x, 0.0], [U.y, V.y, N.y, 0.0], [U.z, V.z, N.z, 0.0], [dot(-U, eye), dot(-V, eye), dot(-N, eye), 1.0]]) } public init(perspective fovyRadians: Float, aspect: Float, nearZ: Float, farZ: Float) { let cotan = 1.0 / tanf(fovyRadians / 2.0) self.init([cotan / aspect, 0.0, 0.0, 0.0], [0.0, cotan, 0.0, 0.0], [0.0, 0.0, (farZ + nearZ) / (nearZ - farZ), -1], [0.0, 0.0, (2.0 * farZ * nearZ) / (nearZ - farZ), 0]) } public init(euler x: Float, y: Float, z: Float) { let x = x * .pi / 180 let y = y * .pi / 180 let z = z * .pi / 180 let cx = cos(x) let sx = sin(x) let cy = cos(y) let sy = sin(y) let cz = cos(z) let sz = sin(z) let cxsy = cx * sy let sxsy = sx * sy self.init([cy * cz, -cy * sz, sy, 0.0], [cxsy * cz + cx * sz, -cxsy * sz + cx * cz, -sx * cy, 0.0], [-sxsy * cz + sx * sz, sxsy * sz + sx * cz, cx * cy, 0], [0.0, 0.0, 0, 1]) } func rotateX(radians: Float) -> simd_float4x4 { self * simd_float4x4(rotationX: radians) } func rotateY(radians: Float) -> simd_float4x4 { self * simd_float4x4(rotationY: radians) } func rotateZ(radians: Float) -> simd_float4x4 { self * simd_float4x4(rotationZ: radians) } } // swiftlint:enable identifier_name