From 1827afba2e8fb2414e0609bccf8a6f44bf3b5070 Mon Sep 17 00:00:00 2001 From: Erik Onarheim Date: Fri, 27 Dec 2024 22:57:03 -0600 Subject: [PATCH] fix: CompositeCollider behavior affecting TileMap w/Realistic Solver (#3322) Fixes issue where the realistic solver gets confused with TileMaps mentioned in the discord https://discord.com/channels/1195771303215513671/1320140196372676692 The issue causes massive overcorrection because it _appears_ to the solver that the collider in a composite is further away from the contact than it actually is. https://github.com/user-attachments/assets/45bceff6-ab06-40b7-9c91-a4886505c124 In the fix we shift the collider local side by the offset (which is what is used in composites to position relative to the transform). This gives an accurate pos for the contact point https://github.com/user-attachments/assets/db83f756-8aa0-43a0-99da-72a7bebbb772 --- CHANGELOG.md | 1 + src/engine/Collision/Colliders/CollisionJumpTable.ts | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c11309405..3109989bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed +- Fixed issue with CompositeCollider where large TileMaps would sometimes causes odd collision behavior in the Realistic Solver when the body & collider components are far apart in a TileMap. - Fixed crash on Xiaomi Redmi Phones by lazy loading the GPU particle renderer, GPU particles still do not work on these phones - Add warning if World.add() falls through! This is caused by multiple versions of Excalibur usually - Fixed CollidePolygonPolygon crash with some defense against invalid separation diff --git a/src/engine/Collision/Colliders/CollisionJumpTable.ts b/src/engine/Collision/Colliders/CollisionJumpTable.ts index 8921d484a..3cb34ae7a 100644 --- a/src/engine/Collision/Colliders/CollisionJumpTable.ts +++ b/src/engine/Collision/Colliders/CollisionJumpTable.ts @@ -294,7 +294,7 @@ export const CollisionJumpTable = { return []; }, - FindContactSeparation(contact: CollisionContact, localPoint: Vector) { + FindContactSeparation(contact: CollisionContact, localPoint: Vector): number { const shapeA = contact.colliderA; const txA = contact.bodyA?.transform ?? new TransformComponent(); const shapeB = contact.colliderB; @@ -314,10 +314,16 @@ export const CollisionJumpTable = { let side: LineSegment; let worldPoint: Vector; if (contact.info.collider === shapeA) { - side = new LineSegment(txA.apply(contact.info.localSide.begin), txA.apply(contact.info.localSide.end)); + side = new LineSegment( + txA.apply(contact.info.localSide.begin).add(shapeA.offset), + txA.apply(contact.info.localSide.end).add(shapeA.offset) + ); worldPoint = txB.apply(localPoint); } else { - side = new LineSegment(txB.apply(contact.info.localSide.begin), txB.apply(contact.info.localSide.end)); + side = new LineSegment( + txB.apply(contact.info.localSide.begin).add(shapeB.offset), + txB.apply(contact.info.localSide.end).add(shapeB.offset) + ); worldPoint = txA.apply(localPoint); }