Upgraded to 0.9.9, minor physics improvements

This commit is contained in:
Brychan Dempsey 2021-06-12 12:54:54 +12:00
parent 4febf41721
commit bca92faa88
8 changed files with 48 additions and 43 deletions

View File

@ -38,7 +38,7 @@
<dependency>
<groupId>nz.ac.massey.javaecs</groupId>
<artifactId>javaecs</artifactId>
<version>0.9.2-PRERELEASE</version>
<version>0.9.9-RELEASE_CANDIDATE</version>
</dependency>
</dependencies>
<build>

View File

@ -145,11 +145,11 @@ public final class App {
long startTime = System.nanoTime();
while (!exit){
// Run system updates
collisionSystem.update();
collisionSystem.update(dt);
physicsSystem.update(dt);
existenceSystem.update(dt);
reportSystem.update();
renderSystem.update();
reportSystem.update(dt);
renderSystem.update(dt);
dt = (System.nanoTime() - startTime) / 1e9; // convert nanoseconds to seconds
startTime = System.nanoTime();

View File

@ -28,12 +28,12 @@ public class CollisionSystem extends ECSSystem {
public void init() {
}
// This is a quick & naive physics implementation. Not all collision states are accurately calculated
// I also expect it is highly inefficient, though I was able to run it with 500 subscribed entities
// This is a quick & naive physics implementation. Not all collision states are accurately calculated | I'm pretty sure one of the states is set wrong, and sends things flying in the wrong direction
// I also expect it is highly inefficient, though it is able to run it with 500 subscribed entities
// with no major performance issues
// Replace this with a proper system as required
// Replace this with a proper system as required - I.e. Box2D or etc.
@Override
public void update() {
public void update(double dt) {
Set<Entity> processed = new HashSet<>();
// Gets all items we have collided with
for (Entity entity : entities) {
@ -65,7 +65,8 @@ public class CollisionSystem extends ECSSystem {
&& pos.y + collider.y < otherPos.y + otherCollider.y;
// Evaluate a collision in the top-right
boolean trCollide = pos.x + collider.x > otherPos.x
&& pos.x + collider.x < otherPos.x + otherCollider.x && pos.y > otherPos.y
&& pos.x + collider.x < otherPos.x + otherCollider.x
&& pos.y > otherPos.y
&& pos.y < otherPos.y + otherCollider.y;
if (tlCollide || blCollide || brCollide || trCollide) {
// Get the vels
@ -79,31 +80,31 @@ public class CollisionSystem extends ECSSystem {
// left-hand collision
if (tlCollide && blCollide) {
fullEdge = true;
pos.x = otherPos.x + otherCollider.x;
pos.x = otherPos.x + otherCollider.x - .00001;
xMult = multTot;
}
// right-hand collision
else if (brCollide && trCollide) {
fullEdge = true;
pos.x = otherPos.x - collider.x;
pos.x = otherPos.x - collider.x + .00001;
xMult = -multTot;
}
// Bottom collision
else if (blCollide && brCollide) {
fullEdge = true;
//pos.y = otherPos.y + otherCollider.y;
pos.y = otherPos.y - collider.y;
pos.y = otherPos.y - collider.y + .00001;
yMult = -multTot;
}
// top collision
else if (trCollide && tlCollide) {
fullEdge = true;
//pos.y = otherPos.y - collider.y;
pos.y = otherPos.y + otherCollider.y;
pos.y = otherPos.y + otherCollider.y -.00001;
yMult = multTot;
}
if(!fullEdge){
// Not a full edge collision, must evaluate which edge it is
// Not a full edge collision, must evaluate which edge it is (it then gets treated as a full edge)
double deltaXVel = Math.abs(ridgidBody.xVel - otherRidgidBody.xVel);
double deltaYVel = Math.abs(ridgidBody.yVel - otherRidgidBody.yVel);
double deltaMin = 50.;
@ -206,24 +207,36 @@ public class CollisionSystem extends ECSSystem {
// entity 2 is immovable; full acceleration applied to the current entity
if (otherRidgidBody.mass >= 0){
ridgidBody.xVel += totalXVel * ((totalMass - ridgidBody.mass) / totalMass) * (xMult + (Math.abs(xMult) + (ridgidBody.bounciness * otherRidgidBody.bounciness)));
ridgidBody.yVel += totalYVel * ((totalMass - ridgidBody.mass) / totalMass) * (yMult + (Math.abs(yMult) + (ridgidBody.bounciness * otherRidgidBody.bounciness)));
otherRidgidBody.xVel -= totalXVel * ((totalMass - otherRidgidBody.mass) / totalMass) * (xMult + (Math.abs(xMult) + (ridgidBody.bounciness * otherRidgidBody.bounciness)));
otherRidgidBody.yVel -= totalYVel * ((totalMass - otherRidgidBody.mass) / totalMass) * (yMult + (Math.abs(yMult) + (ridgidBody.bounciness * otherRidgidBody.bounciness)));
// For collisions between dynamic objects, the restoring velocity [rv] is shared between both objects.
// Each object experiences a restoring velocity proportionate to its percentage of the total mass.
// They each recieve an additional force of 'bounce',
// which is the total velocity * total bounciness
// This force is then shared by the mass
double rvX1 = totalXVel * ((totalMass - ridgidBody.mass) / totalMass) * xMult;
double rvY1 = totalYVel * ((totalMass - ridgidBody.mass) / totalMass) * yMult;
double totalBounce = ridgidBody.bounciness * otherRidgidBody.bounciness;
// Restoring forces
ridgidBody.xVel += rvX1;
ridgidBody.yVel += rvY1;
// Additional forces; 'bounce'
double xBounce = rvX1 * ((totalBounce - ridgidBody.bounciness) / totalBounce);
double yBounce = rvY1 * ((totalBounce - ridgidBody.bounciness) / totalBounce);
rvX1 = xBounce * ((totalMass - ridgidBody.mass) / totalMass);// * xMult;
rvY1 = yBounce * ((totalMass - ridgidBody.mass) / totalMass);// * yMult;
// bounce forces
ridgidBody.xVel += rvX1;
ridgidBody.yVel += rvY1;
}
else{
double newXVel = totalXVel * (xMult * (Math.abs(xMult) + ridgidBody.bounciness));
double newYVel = totalYVel * (yMult * (Math.abs(yMult) + ridgidBody.bounciness));
// For collisions against a fixed object, the restoring velocity (velocity in the direction against the collision vector) [name it 'rv']
// is at least -1x. This would affix the cardinal velocity to zero, both objects would have a 'bounciness' of zero.
// The bounciness is combined (b = object1 * object2), which gives us the total percent of retained velocity,
// i.e. a factor >= 0 & <= 1. Multiply this factor by rv to get the total restoring velocity
double newXVel = totalXVel * (xMult * (Math.abs(xMult) + (ridgidBody.bounciness * otherRidgidBody.bounciness)));
double newYVel = totalYVel * (yMult * (Math.abs(yMult) + (ridgidBody.bounciness * otherRidgidBody.bounciness)));
ridgidBody.xVel += newXVel;
ridgidBody.yVel += newYVel;
}
Object grav = gameEngine.getComponentData(entity, Gravity.class);
if (grav != null && otherRidgidBody.mass < 0) {
// negate gravity while collided
Gravity gravity = (Gravity) grav;
ridgidBody.xAcc += gravity.x * -1.;
ridgidBody.yAcc += gravity.y * -1.;
}
}
}
}

View File

@ -34,9 +34,6 @@ public class ExistenceSystem extends ECSSystem{
}
@Override
public void update() {
}
public void update(double dt){
Queue<Entity> deletions = new LinkedList<>();
for (Entity entity : entities) {

View File

@ -24,7 +24,7 @@ public class LogUpdateSystem extends ECSSystem{
}
@Override
public void update() {
public void update(double dt) {
for (Entity entity : entities) {
Vec2D pos = (Vec2D)gameEngine.getComponentData(entity, Vec2D.class);
System.out.println(String.format("X: %.6g, Y: %.6g", pos.x, pos.y));

View File

@ -30,11 +30,6 @@ public class PhysicsSystem extends ECSSystem {
}
@Override
public void update() {
// TODO Auto-generated method stub
}
public void update(double dt){
for (Entity entity : entities) {
Vec2D pos = (Vec2D)gameEngine.getComponentData(entity, Vec2D.class);

View File

@ -44,7 +44,7 @@ public class RenderSystem extends ECSSystem{
}
@Override
public void update() {
public void update(double dt) {
Group renderScene = new Group();
for (Entity entity : entities) {
if (((Render)gameEngine.getComponentData(entity, Render.class)).renderType == BoxRender.class){

View File

@ -23,7 +23,7 @@ public class ReportSystem extends ECSSystem{
}
@Override
public void update() {
public void update(double dt) {
for (Entity entity : entities) {
TextRender text = (TextRender)gameEngine.getComponentData(entity, TextRender.class);
text.content = "Num Entities: " + gameEngine.getNumEntities();