Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions Sources/FirebladeMath/Matrix/Matrices.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ public typealias Mat2x2d = Matrix2x2<Storage2x2<Double>>
/// - row: The row (zero based).
/// - width: The width of a column.
/// - Returns: The flat index into the matrix storage.
/// - Important: This computes a **row-major** index, which does not match the column-major
/// storage of FirebladeMath matrices (see ``columnRow(index:width:)``).
@available(*, deprecated, message: "Computes a row-major index that does not match FirebladeMath's column-major storage. Use the matrix's subscript(column:row:) instead.")
@inlinable
public func index(column: Int, row: Int, width: Int) -> Int {
(row * width) + column
Expand All @@ -53,9 +56,19 @@ public func index(column: Int, row: Int, width: Int) -> Int {
/// - index: The index into the matrix.
/// - width: The width of a column.
/// - Returns: A tuple containing the column and row indices.
@available(*, deprecated, message: "Implementation detail of matrix storage. Use the matrix's subscript(column:row:) or subscript(index:) instead.")
@inlinable
public func columnRow(index: Int, width: Int) -> (column: Int, row: Int) {
let row: Int = index % width
let column: Int = index / width
return (column, row)
columnMajorPosition(of: index, rows: width)
}

/// Splits a flat column-major index into its column and row.
/// - Parameters:
/// - index: The flat index into the matrix storage.
/// - rows: The number of rows, i.e. the length of a column.
/// - Returns: A tuple containing the column and row indices.
@inlinable
@inline(__always)
func columnMajorPosition(of index: Int, rows: Int) -> (column: Int, row: Int) { // swiftlint:disable:this explicit_top_level_acl
(index / rows, index % rows)
}
12 changes: 7 additions & 5 deletions Sources/FirebladeMath/Matrix/Matrix2x2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public struct Matrix2x2<Storage: Storage2x2Protocol>: RandomAccessCollection, Mu
@inlinable
public init(_ columns: [Vector]) {
precondition(columns.count == 2, "Matrix needs exactly 2 Vector vectors")
storage = Storage(columns)
self.init(columns[0], columns[1])
}

/// Creates a new 2x2 matrix from two column vectors.
Expand All @@ -74,16 +74,18 @@ public struct Matrix2x2<Storage: Storage2x2Protocol>: RandomAccessCollection, Mu
/// - column1: The second column vector.
@inlinable
public init(_ column0: Vector, _ column1: Vector) {
self.init([column0, column1])
storage = Storage(column0, column1)
}

/// Creates a new 2x2 matrix from an array of values in column-major order.
/// - Parameter values: An array of 4 values.
@inlinable
public init(_ values: [Storage.Value]) {
precondition(values.count == 4, "Matrix needs exactly 4 values")
self.init([Vector(values[0...1]),
Vector(values[2...3])])
self.init(
Vector(values[0], values[1]),
Vector(values[2], values[3])
)
}

/// Accesses the value at the specified flat index in column-major order.
Expand Down Expand Up @@ -117,7 +119,7 @@ public struct Matrix2x2<Storage: Storage2x2Protocol>: RandomAccessCollection, Mu

/// An array containing the elements of the matrix in column-major order.
@inlinable public var elements: [Value] {
[Value](AnyIterator(storage.makeIterator()))
Array(storage)
}

/// Provides access to the underlying memory as a contiguous buffer.
Expand Down
14 changes: 8 additions & 6 deletions Sources/FirebladeMath/Matrix/Matrix3x3.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public struct Matrix3x3<Storage: Storage3x3Protocol>: RandomAccessCollection, Mu
@inlinable
public init(_ columns: [Vector]) {
precondition(columns.count == 3, "Matrix needs exactly 3 Vector vectors")
storage = Storage(columns)
self.init(columns[0], columns[1], columns[2])
}

/// Creates a new 3x3 matrix from three column vectors.
Expand All @@ -75,17 +75,19 @@ public struct Matrix3x3<Storage: Storage3x3Protocol>: RandomAccessCollection, Mu
/// - column2: The third column vector.
@inlinable
public init(_ column0: Vector, _ column1: Vector, _ column2: Vector) {
self.init([column0, column1, column2])
storage = Storage(column0, column1, column2)
}

/// Creates a new 3x3 matrix from an array of values in column-major order.
/// - Parameter values: An array of 9 values.
@inlinable
public init(_ values: [Storage.Value]) {
precondition(values.count == 9, "Matrix needs exactly 9 values")
self.init([Vector(values[0...2]),
Vector(values[3...5]),
Vector(values[6...8])])
self.init(
Vector(values[0], values[1], values[2]),
Vector(values[3], values[4], values[5]),
Vector(values[6], values[7], values[8])
)
}

/// Accesses the value at the specified flat index in column-major order.
Expand Down Expand Up @@ -119,7 +121,7 @@ public struct Matrix3x3<Storage: Storage3x3Protocol>: RandomAccessCollection, Mu

/// An array containing the elements of the matrix in column-major order.
@inlinable public var elements: [Value] {
[Value](AnyIterator(storage.makeIterator()))
Array(storage)
}

/// Provides access to the underlying memory as a contiguous buffer.
Expand Down
16 changes: 9 additions & 7 deletions Sources/FirebladeMath/Matrix/Matrix4x4.swift
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public struct Matrix4x4<Storage: Storage4x4Protocol>: RandomAccessCollection, Mu
@inlinable
public init(_ columns: [Vector]) {
precondition(columns.count == 4, "Matrix needs exactly 4 Column vectors")
storage = Storage(columns)
self.init(columns[0], columns[1], columns[2], columns[3])
}

/// Creates a new 4x4 matrix from four column vectors.
Expand All @@ -76,18 +76,20 @@ public struct Matrix4x4<Storage: Storage4x4Protocol>: RandomAccessCollection, Mu
/// - column3: The fourth column vector.
@inlinable
public init(_ column0: Vector, _ column1: Vector, _ column2: Vector, _ column3: Vector) {
self.init([column0, column1, column2, column3])
storage = Storage(column0, column1, column2, column3)
}

/// Creates a new 4x4 matrix from an array of values in column-major order.
/// - Parameter values: An array of 16 values.
@inlinable
public init(_ values: [Value]) {
precondition(values.count == 16, "Matrix needs exactly 16 values")
self.init([Vector(values[0...3]),
Vector(values[4...7]),
Vector(values[8...11]),
Vector(values[12...15])])
self.init(
Vector(values[0], values[1], values[2], values[3]),
Vector(values[4], values[5], values[6], values[7]),
Vector(values[8], values[9], values[10], values[11]),
Vector(values[12], values[13], values[14], values[15])
)
}

/// Accesses the value at the specified flat index in column-major order.
Expand Down Expand Up @@ -121,7 +123,7 @@ public struct Matrix4x4<Storage: Storage4x4Protocol>: RandomAccessCollection, Mu

/// An array containing the elements of the matrix in column-major order.
@inlinable public var elements: [Value] {
[Value](AnyIterator(storage.makeIterator()))
Array(storage)
}

/// Provides access to the underlying memory as a contiguous buffer.
Expand Down
63 changes: 30 additions & 33 deletions Sources/FirebladeMath/Matrix/MatrixStorage+NO_SIMD.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,13 @@ public struct Storage2x2<Value: StorageScalar>: Storage2x2Protocol {
@inlinable
public init(_ columns: [Column]) {
precondition(columns.count == 2, "Storage needs exactly 2 column vectors")
column0 = columns[0]
column1 = columns[1]
self.init(columns[0], columns[1])
}

@inlinable
public init(_ column0: Column, _ column1: Column) {
self.column0 = column0
self.column1 = column1
}

@inlinable
Expand All @@ -35,12 +40,6 @@ public struct Storage2x2<Value: StorageScalar>: Storage2x2Protocol {
self.init(diagonal: Column(zero, zero))
}

@inlinable
@inline(__always)
public func makeIterator() -> IndexingIterator<[Value]> {
[column0, column1].flatMap { $0 }.makeIterator()
}

@inlinable
public subscript(column: Int, row: Int) -> Value {
get {
Expand Down Expand Up @@ -72,11 +71,11 @@ public struct Storage2x2<Value: StorageScalar>: Storage2x2Protocol {
@inlinable
public subscript(index: Int) -> Value {
get {
let (column, row) = columnRow(index: index, width: 2)
let (column, row) = columnMajorPosition(of: index, rows: 2)
return self[column, row]
}
set {
let (column, row) = columnRow(index: index, width: 2)
let (column, row) = columnMajorPosition(of: index, rows: 2)
self[column, row] = newValue
}
}
Expand Down Expand Up @@ -113,9 +112,14 @@ public struct Storage3x3<Value: StorageScalar>: Storage3x3Protocol {
@inlinable
public init(_ columns: [Column]) {
precondition(columns.count == 3, "Storage needs exactly 3 column vectors")
column0 = columns[0]
column1 = columns[1]
column2 = columns[2]
self.init(columns[0], columns[1], columns[2])
}

@inlinable
public init(_ column0: Column, _ column1: Column, _ column2: Column) {
self.column0 = column0
self.column1 = column1
self.column2 = column2
}

@inlinable
Expand All @@ -132,12 +136,6 @@ public struct Storage3x3<Value: StorageScalar>: Storage3x3Protocol {
self.init(diagonal: Column(zero, zero, zero))
}

@inlinable
@inline(__always)
public func makeIterator() -> IndexingIterator<[Value]> {
[column0, column1, column2].flatMap { $0 }.makeIterator()
}

@inlinable
public subscript(column: Int, row: Int) -> Value {
get {
Expand Down Expand Up @@ -175,11 +173,11 @@ public struct Storage3x3<Value: StorageScalar>: Storage3x3Protocol {
@inlinable
public subscript(index: Int) -> Value {
get {
let (column, row) = columnRow(index: index, width: 3)
let (column, row) = columnMajorPosition(of: index, rows: 3)
return self[column, row]
}
set {
let (column, row) = columnRow(index: index, width: 3)
let (column, row) = columnMajorPosition(of: index, rows: 3)
self[column, row] = newValue
}
}
Expand Down Expand Up @@ -220,10 +218,15 @@ public struct Storage4x4<Value: StorageScalar>: Storage4x4Protocol {
@inlinable
public init(_ columns: [Column]) {
precondition(columns.count == 4, "Storage needs exactly 4 column vectors")
column0 = columns[0]
column1 = columns[1]
column2 = columns[2]
column3 = columns[3]
self.init(columns[0], columns[1], columns[2], columns[3])
}

@inlinable
public init(_ column0: Column, _ column1: Column, _ column2: Column, _ column3: Column) {
self.column0 = column0
self.column1 = column1
self.column2 = column2
self.column3 = column3
}

@inlinable
Expand All @@ -241,12 +244,6 @@ public struct Storage4x4<Value: StorageScalar>: Storage4x4Protocol {
self.init(diagonal: Column(zero, zero, zero, zero))
}

@inlinable
@inline(__always)
public func makeIterator() -> IndexingIterator<[Value]> {
[column0, column1, column2, column3].flatMap { $0 }.makeIterator()
}

@inlinable
public subscript(column: Int, row: Int) -> Value {
get {
Expand Down Expand Up @@ -290,11 +287,11 @@ public struct Storage4x4<Value: StorageScalar>: Storage4x4Protocol {
@inlinable
public subscript(index: Int) -> Value {
get {
let (column, row) = columnRow(index: index, width: 4)
let (column, row) = columnMajorPosition(of: index, rows: 4)
return self[column, row]
}
set {
let (column, row) = columnRow(index: index, width: 4)
let (column, row) = columnMajorPosition(of: index, rows: 4)
self[column, row] = newValue
}
}
Expand Down
Loading
Loading