Skip to content

Commit 0f3cd9f

Browse files
committed
Make CollisionMesh a cached Resource
Allows loading and hot reloading CollisionMesh from ResourceImporters
1 parent e306531 commit 0f3cd9f

File tree

9 files changed

+625
-73
lines changed

9 files changed

+625
-73
lines changed

Sources/GameMath/3D Types/3D Physics/3D Colliders/Triangles/CollisionAttributes.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public struct CollisionAttributeUVs {
3030
}
3131
}
3232

33-
public protocol CollisionAttributesType: RawRepresentable where RawValue == UInt32 {
33+
public protocol CollisionAttributesType: RawRepresentable, Equatable, Sendable where RawValue == UInt32 {
3434
var rawValue: RawValue { get }
3535
init(rawValue: RawValue)
3636

@@ -57,7 +57,7 @@ public extension CollisionAttributesType {
5757
}
5858
}
5959

60-
public protocol CollisionAttributesGroup: RawRepresentable where RawValue == UInt64 {
60+
public protocol CollisionAttributesGroup: RawRepresentable, Equatable, Sendable where RawValue == UInt64 {
6161
associatedtype Group1: CollisionAttributesType
6262
associatedtype Group2: CollisionAttributesType
6363
var group1: Group1 {get set}

Sources/GameMath/3D Types/3D Physics/3D Colliders/Triangles/CollisionTriangle.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,3 +395,13 @@ extension CollisionTriangle: Codable {
395395
self.init(p1: positions[0], p2: positions[1], p3: positions[2], normal: normal, rawAttributes: attributes)
396396
}
397397
}
398+
399+
extension Array where Element == CollisionTriangle {
400+
public func generatePositions() -> [Position3] {
401+
return self.map(\.positions).flatMap(\.self)
402+
}
403+
404+
public func generateBoundingBox() -> AxisAlignedBoundingBox3D {
405+
return AxisAlignedBoundingBox3D(generatePositions())
406+
}
407+
}

Sources/GameMath/3D Types/3D Physics/3D Colliders/Triangles/MeshCollider.swift renamed to Sources/GateEngine/Physics/MeshCollider.swift

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* http://stregasgate.com
66
*/
77

8+
@MainActor
89
public final class MeshCollider: Collider3D {
910
public var center: Position3 {
1011
return transform.position
@@ -17,11 +18,11 @@ public final class MeshCollider: Collider3D {
1718
}
1819
}
1920

20-
private let originalTriangles: [CollisionTriangle]
21+
private let collisionMesh: CollisionMesh
2122
/// Triangles as they were provided to the collider
2223
/// These triangles are not moved, rotated, or scaled to match its entity
2324
public func untransformedTriangles() -> [CollisionTriangle] {
24-
return originalTriangles
25+
return collisionMesh.generateCollisionTriangles()
2526
}
2627
private var transformedTriangles: [CollisionTriangle]
2728
/// Triangles as they were provided to the collider
@@ -35,16 +36,10 @@ public final class MeshCollider: Collider3D {
3536
}
3637

3738
private func update() {
38-
needsUpdate = false
39-
let matrix = transform.matrix()
40-
transformedTriangles = originalTriangles.map({$0 * matrix})
41-
var positions: [Position3] = []
42-
positions.reserveCapacity(transformedTriangles.count * 3)
43-
for triangle in transformedTriangles {
44-
positions.append(contentsOf: triangle.positions)
45-
}
46-
47-
_boundingBox = AxisAlignedBoundingBox3D(positions)
39+
self.needsUpdate = false
40+
let matrix = self.transform.matrix()
41+
transformedTriangles = self.untransformedTriangles().map({$0 * matrix})
42+
_boundingBox = transformedTriangles.generateBoundingBox()
4843
}
4944

5045
private var transform: Transform3 = .default {
@@ -55,7 +50,22 @@ public final class MeshCollider: Collider3D {
5550
}
5651
}
5752

58-
private var needsUpdate: Bool = true
53+
private var _needsUpdate: Bool = true
54+
private var previousReadyStateReceipt: UInt8 = 0
55+
private var needsUpdate: Bool {
56+
get {
57+
guard self.collisionMesh.isReady else { return false }
58+
let receipt = self.collisionMesh.receipt
59+
if receipt != self.previousReadyStateReceipt {
60+
previousReadyStateReceipt = receipt
61+
_needsUpdate = true
62+
}
63+
return _needsUpdate
64+
}
65+
set {
66+
_needsUpdate = newValue
67+
}
68+
}
5969

6070
private var _boundingBox: AxisAlignedBoundingBox3D = AxisAlignedBoundingBox3D()
6171
public var boundingBox: AxisAlignedBoundingBox3D {
@@ -122,10 +132,11 @@ public final class MeshCollider: Collider3D {
122132
return hits
123133
}
124134

125-
public init(transform: Transform3, offset: Position3, triangles: [CollisionTriangle]) {
126-
self.originalTriangles = triangles
127-
self.transformedTriangles = triangles
135+
public init(offset: Position3, transform: Transform3, collisionMesh: CollisionMesh) {
136+
self.collisionMesh = collisionMesh
137+
self.transformedTriangles = []
128138
self.offset = offset
129139
self.transform = transform
140+
self.needsUpdate = true
130141
}
131142
}

0 commit comments

Comments
 (0)