Skip to content

Commit 05b1ba9

Browse files
committed
Implement swapAt for improved sorting performance
1 parent c1022cc commit 05b1ba9

File tree

1 file changed

+25
-9
lines changed

1 file changed

+25
-9
lines changed

Sources/GateEngine/Resources/Geometry/Raw/RawGeometry.swift

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import GameMath
1010
/// An element array object formatted as triangle primitives
1111
public struct RawGeometry: Codable, Sendable, Equatable, Hashable {
1212
public var vertices: VertexView
13-
13+
1414
@usableFromInline
1515
internal func triangle(at index: Index) -> Element {
1616
assert(self.indices.contains(index), "Index \(index) out of range \(self.indices)")
@@ -31,7 +31,7 @@ public struct RawGeometry: Codable, Sendable, Equatable, Hashable {
3131
self.vertices.setVertex(triangle.v2, at: index + 1)
3232
self.vertices.setVertex(triangle.v3, at: index + 2)
3333
}
34-
34+
3535
public func flipped() -> RawGeometry {
3636
var copy = self
3737
for index in self.indices {
@@ -53,7 +53,7 @@ public struct RawGeometry: Codable, Sendable, Equatable, Hashable {
5353
copy.optimize()
5454
return copy
5555
}
56-
56+
5757
/// Creates a new `Geometry` from element array values.
5858
public init(
5959
positions: [Float],
@@ -84,7 +84,7 @@ public struct RawGeometry: Codable, Sendable, Equatable, Hashable {
8484
/// Checks the result of the provided comparator. If true, the vertices will be folded into a single vertex. The vertex kept is always lhs.
8585
case usingComparator(_ comparator: (_ lhs: Vertex, _ rhs: Vertex) -> Bool)
8686
}
87-
87+
8888
/// Create `Geometry` from counter-clockwise wound `Triangles` and optionanly attempts to optimize the arrays by distance.
8989
/// Optimization is extremely slow and may result in loss of data. It should be used to pre-optimize assets and should not be used at runtime.
9090
public init(triangles: [Triangle], optimization: Optimization = .dontOptimize) {
@@ -99,7 +99,7 @@ public struct RawGeometry: Codable, Sendable, Equatable, Hashable {
9999
}
100100

101101
var inVertices = triangles.vertices
102-
102+
103103
var optimizedIndicies: [UInt16]
104104
switch optimization {
105105
case .dontOptimize:
@@ -154,7 +154,7 @@ public struct RawGeometry: Codable, Sendable, Equatable, Hashable {
154154
uvSet2.append(contentsOf: vertex.uv2.valuesArray())
155155
self.tangents.append(contentsOf: vertex.tangent.valuesArray())
156156
self.colors.append(contentsOf: vertex.color.valuesArray())
157-
157+
158158
self.vertexIndicies.append(UInt16(nextIndex))
159159
// Increment the next real indicies index
160160
nextIndex += 1
@@ -193,7 +193,7 @@ public struct RawGeometry: Codable, Sendable, Equatable, Hashable {
193193
}
194194
self.uvSets = [uvSet1, uvSet2]
195195
}
196-
196+
197197
/// Creates a new `Geometry` by merging multiple geometry. This is usful for loading files that store geometry speretly base don material if you intend to only use a single material for them all.
198198
public init(byCombining geometries: [RawGeometry], withOptimization optimization: Optimization = .dontOptimize) {
199199
self.init(triangles: geometries.reduce(into: []) {$0.append(contentsOf: $1)}, optimization: optimization)
@@ -272,7 +272,7 @@ extension RawGeometry {
272272
internal var tangents: Deque<Float>
273273
internal var colors: Deque<Float>
274274
internal var vertexIndicies: Deque<UInt16>
275-
275+
276276
nonmutating func uvSet(_ index: Int) -> Deque<Float>? {
277277
guard index < uvSets.count else { return nil }
278278
return uvSets[index]
@@ -427,7 +427,7 @@ extension RawGeometry.VertexView: RandomAccessCollection, MutableCollection, Ran
427427
public var endIndex: Index {
428428
return self.vertexIndicies.endIndex
429429
}
430-
430+
431431
public func index(before i: Index) -> Index {
432432
return self.vertexIndicies.index(before: i)
433433
}
@@ -509,6 +509,11 @@ extension RawGeometry.VertexView: RandomAccessCollection, MutableCollection, Ran
509509
}
510510
}
511511

512+
public mutating func swapAt(_ i: Int, _ j: Int) {
513+
// Swap only the vertexIndicies value for performance
514+
self.vertexIndicies.swapAt(i, j)
515+
}
516+
512517
public subscript (index: Index) -> Element {
513518
nonmutating get {
514519
assert(self.indices.contains(index), "Index \(index) out of range \(self.indices)")
@@ -614,6 +619,17 @@ extension RawGeometry: RandomAccessCollection, MutableCollection, RangeReplaceab
614619
return Triangle(v1: v1, v2: v2, v3: v3, repairIfNeeded: false)
615620
}
616621

622+
@inlinable
623+
public mutating func swapAt(_ i: Index, _ j: Index) {
624+
let baseIndexI = i * 3
625+
let baseIndexJ = j * 3
626+
627+
self.vertices.swapAt(baseIndexI + 0, baseIndexJ + 0)
628+
self.vertices.swapAt(baseIndexI + 1, baseIndexJ + 1)
629+
self.vertices.swapAt(baseIndexI + 2, baseIndexJ + 2)
630+
}
631+
632+
@inlinable
617633
public subscript (index: Index) -> Element {
618634
get {
619635
assert(self.indices.contains(index), "Index \(index) out of range \(self.indices)")

0 commit comments

Comments
 (0)