Skip to content

Commit e60cff6

Browse files
committed
Fix rig driven collider update bug
1 parent cf8ec94 commit e60cff6

File tree

3 files changed

+28
-21
lines changed

3 files changed

+28
-21
lines changed

Sources/GameMath/3D Types/3D Physics/3D Colliders/OrientedBoundingBox3D.swift

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@ public struct OrientedBoundingBox3D: Collider3D, Sendable {
1212
public private(set) var radius: Size3 // Positive halfwidth extents of OBB along each axis
1313
internal var _radius: Size3
1414
internal var _offset: Position3
15+
internal var _rotation: Quaternion
1516

1617
public var size: Size3 {return radius * 2}
1718

1819
public init(center: Position3 = .zero, offset: Position3 = .zero, radius: Size3, rotation: Quaternion) {
1920
self.center = center
2021
self.rotation = rotation
22+
self._rotation = rotation
2123
self.offset = offset
2224
self._offset = offset
2325
self._radius = radius
@@ -38,16 +40,17 @@ public struct OrientedBoundingBox3D: Collider3D, Sendable {
3840
public private(set) var boundingBox: AxisAlignedBoundingBox3D
3941

4042
mutating public func update(transform: Transform3) {
41-
rotation = transform.rotation
4243
center = transform.position
4344
offset = _offset * transform.scale
4445
radius = _radius * transform.scale
46+
rotation = _rotation * transform.rotation.conjugate
4547
self.boundingBox.update(transform: transform)
4648
}
4749

4850
public mutating func update(sizeAndOffsetUsingTransform transform: Transform3) {
4951
_offset = transform.position
5052
_radius = transform.scale / 2
53+
_rotation = transform.rotation
5154
self.boundingBox.update(sizeAndOffsetUsingTransform: transform)
5255
}
5356
}
@@ -75,6 +78,7 @@ public extension OrientedBoundingBox3D {
7578
self._radius = Size3(width: (x.y - x.x) / 2.0, height: (y.y - y.x) / 2.0, depth: (z.y - z.x) / 2.0)
7679
self.radius = _radius
7780
self.rotation = .zero
81+
self._rotation = .zero
7882
self.boundingBox = AxisAlignedBoundingBox3D(center: center, offset: offset, radius: radius)
7983
}
8084
}

Sources/GateEngine/ECS/3D Specific/Physics/Collision3DComponent.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,21 @@ public final class Collision3DComponent: Component {
7272
self.collider.update(transform: transform)
7373
self.rayCastCollider?.update(transform: transform)
7474
}
75+
76+
@MainActor
77+
@inlinable
78+
internal func updateColliders(_ rigComponent: Rig3DComponent) {
79+
// Update collider from animation
80+
if let colliderJointName = rigComponent.updateColliderFromBoneNamed {
81+
if let joint = rigComponent.skeleton.jointNamed(colliderJointName) {
82+
let matrix = joint.modelSpace
83+
self.update(sizeAndOffsetUsingTransform: matrix.transform)
84+
self.rayCastCollider?.update(sizeAndOffsetUsingTransform: matrix.transform)
85+
} else {
86+
fatalError("Failed to find joint \(colliderJointName).")
87+
}
88+
}
89+
}
7590

7691
@inlinable
7792
public func update(sizeAndOffsetUsingTransform transform: Transform3) {

Sources/GateEngine/ECS/3D Specific/Physics/Collision3DSystem.swift

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@ public final class Collision3DSystem: System {
1515
return false
1616
})
1717
for entity in staticEntities {
18-
entity.collision3DComponent.updateColliders(entity.transform3)
18+
let collisionComponent = entity.collision3DComponent
19+
// Update collider from animation
20+
if let rigComponent = entity.component(ofType: Rig3DComponent.self) {
21+
collisionComponent.updateColliders(rigComponent)
22+
}
23+
collisionComponent.updateColliders(entity.transform3)
1924
}
2025
let dynamicEntities = context.entities.filter({
2126
guard let collisionComponenet = $0.component(ofType: Collision3DComponent.self) else {return false}
@@ -50,27 +55,10 @@ public final class Collision3DSystem: System {
5055
func updateCollider() {
5156
collisionComponent.updateColliders(transformComponent.transform)
5257
}
53-
58+
5459
// Update collider from animation
5560
if let rigComponent = dynamicEntity.component(ofType: Rig3DComponent.self) {
56-
if let colliderJointName = rigComponent.updateColliderFromBoneNamed {
57-
if let joint = rigComponent.skeleton.jointNamed(colliderJointName) {
58-
let position =
59-
(transformComponent.transform.matrix() * joint.modelSpace).position
60-
- transformComponent.position
61-
let rotation =
62-
transformComponent.rotation * joint.modelSpace.rotation.conjugate
63-
let scale = joint.modelSpace.scale
64-
let transform = Transform3(
65-
position: position,
66-
rotation: rotation,
67-
scale: scale
68-
)
69-
collisionComponent.update(sizeAndOffsetUsingTransform: transform)
70-
} else {
71-
fatalError("Failed to find joint \(colliderJointName).")
72-
}
73-
}
61+
collisionComponent.updateColliders(rigComponent)
7462
}
7563

7664
collisionComponent.touching.removeAll(keepingCapacity: true)

0 commit comments

Comments
 (0)