From 73228ed05a8d5522835bd85950f30d1ca6383f77 Mon Sep 17 00:00:00 2001 From: Brychan Dempsey Date: Fri, 11 Jun 2021 11:37:50 +1200 Subject: [PATCH] Improved the physics system --- .../examples/Systems/CollisionSystem.java | 107 +++++++++++++++++- 1 file changed, 104 insertions(+), 3 deletions(-) diff --git a/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/CollisionSystem.java b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/CollisionSystem.java index 484d69e..46634ab 100644 --- a/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/CollisionSystem.java +++ b/demo1/src/main/java/nz/ac/massey/javaecs/examples/Systems/CollisionSystem.java @@ -74,7 +74,7 @@ public class CollisionSystem extends ECSSystem { double totalYVel = Math.abs(ridgidBody.yVel) + Math.abs(otherRidgidBody.yVel); double xMult = 0; double yMult = 0; - double multTot = (1 + ridgidBody.bounciness); + double multTot = (1 + ridgidBody.bounciness); // reflect a force back 100%, (srtabilises) then add any extra in bounce double totalMass = ridgidBody.mass + otherRidgidBody.mass; boolean fullEdge = false; // left-hand collision @@ -103,11 +103,112 @@ public class CollisionSystem extends ECSSystem { pos.y = otherPos.y + otherCollider.y; yMult = multTot; } + if(!fullEdge){ + // Not a full edge collision, must evaluate which edge it is + double deltaXVel = Math.abs(ridgidBody.xVel - otherRidgidBody.xVel); + double deltaYVel = Math.abs(ridgidBody.yVel - otherRidgidBody.yVel); + double deltaMin = 50.; + double incidentThreshold = 0; // 10% of the sum of the velocity + if (trCollide){ + fullEdge = true; + // use the ratio i.e. the angle + // There are 3 cases, the incident angle is less than 45 + // The incident angle is more than 45 + // The incident angle is near 0 or 90 + if(deltaXVel < incidentThreshold || deltaYVel < incidentThreshold){ + // must use cover calc, as it is near stationary + if (otherPos.y - (pos.y + collider.y) >= otherPos.x - (pos.x + collider.x)){ + // vertical cover wins + yMult = multTot; + } + else{ + xMult = -multTot; + } + } + else if (deltaYVel > deltaXVel){ + // Top edge + if (deltaYVel > deltaMin) pos.y = otherPos.y + otherCollider.y; + yMult = multTot; + } + else{ + + if (deltaXVel > deltaMin) pos.x = otherPos.x + collider.x; + xMult = -multTot; + } + } + else if (brCollide){ + fullEdge = true; + if(deltaXVel < incidentThreshold || deltaYVel < incidentThreshold){ + // must use cover calc, as it is near stationary + if (pos.y - (otherPos.y + otherCollider.y) >= otherPos.x - (pos.x + collider.x)){ + // vertical cover wins + yMult = -multTot; + } + else{ + xMult = -multTot; + } + } + else if (deltaYVel < deltaXVel){ + //pos.y = otherPos.y + otherCollider.y; + if (deltaYVel > deltaMin) pos.y = otherPos.y - collider.y; + yMult = -multTot; + } + else{ + if (deltaXVel > deltaMin) pos.x = otherPos.x - collider.x; + xMult = -multTot; + } + } + else if (blCollide){ + fullEdge = true; + if(deltaXVel < incidentThreshold || deltaYVel < incidentThreshold){ + // must use cover calc, as it is near stationary + if (pos.y - (otherPos.y + otherCollider.y) >= pos.x - (otherPos.x + otherCollider.x)){ + // vertical cover wins + yMult = -multTot; + } + else{ + xMult = multTot; + } + } + else if (deltaYVel > deltaXVel){ + if (deltaYVel > deltaMin) pos.y = otherPos.y - collider.y; + yMult = -multTot; + } + else{ + if (deltaXVel > deltaMin) pos.x = otherPos.x + otherCollider.x; + xMult = multTot; + } + } + else{ // top left + fullEdge = true; + if(deltaXVel < incidentThreshold || deltaYVel < incidentThreshold){ + // must use cover calc, as it is near stationary + if (otherPos.y - (pos.y + collider.y) >= pos.x - (otherPos.x + otherCollider.x)){ + // vertical cover wins + yMult = multTot; + } + else{ + xMult = multTot; + } + } + else if (deltaYVel > deltaXVel){ + if (deltaYVel > deltaMin) pos.y = otherPos.y +otherCollider.y; + yMult = multTot; + } + else { + if (deltaXVel > deltaMin) pos.x = otherPos.x + otherCollider.x; + xMult = multTot; + } + } + + } if (fullEdge) { // Finally, actuate the calculation // entity 2 is immovable; full acceleration applied to the current entity - if (otherRidgidBody.mass > 0){ + if (otherRidgidBody.mass >= 0){ + yMult *= otherRidgidBody.bounciness; + xMult *= otherRidgidBody.bounciness; ridgidBody.xVel += totalXVel * xMult * ((totalMass - ridgidBody.mass) / totalMass); ridgidBody.yVel += totalYVel * yMult * ((totalMass - ridgidBody.mass) / totalMass); @@ -119,7 +220,7 @@ public class CollisionSystem extends ECSSystem { ridgidBody.yVel += totalYVel * yMult; } Object grav = gameEngine.getComponentData(entity, Gravity.class); - if (grav != null) { + if (grav != null && otherRidgidBody.mass < 0) { // negate gravity while collided Gravity gravity = (Gravity) grav; ridgidBody.xAcc += gravity.x * -1.;