Files
Michael Simard 872354b834 Initial commit: SimVision tvOS streaming app
Features:
- VOD library with movie grouping and version detection
- TV show library with season/episode organization
- TMDB integration for trending shows and recently aired episodes
- Recent releases section with TMDB release date sorting
- Watch history tracking with continue watching
- Playlist caching (12-hour TTL) for offline support
- M3U playlist parsing with XStream API support
- Authentication with credential storage

Technical:
- SwiftUI for tvOS
- Actor-based services for thread safety
- Persistent caching for playlists, TMDB data, and watch history
- KSPlayer integration for video playback

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-21 22:12:08 -06:00

111 lines
3.2 KiB
Swift

//
// 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<Float>) {
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<Float>, center: SIMD3<Float>, up: SIMD3<Float>) {
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