From 797729b799426f41006aa8a89176a41ca0ce80e1 Mon Sep 17 00:00:00 2001 From: Dmitry Chubrick Date: Sun, 14 Mar 2021 18:37:25 +0300 Subject: [PATCH] #94 Make all field in Body class protected --- .../broadphase/applier/MoveShapesAction.java | 2 +- .../applier/MoveShapesToPointAction.java | 10 +- .../com/github/introfog/pie/core/World.java | 26 ++--- .../pie/core/collisions/Manifold.java | 40 ++++---- .../impl/CircleCircleCollisionHandler.java | 6 +- .../impl/CirclePolygonCollisionHandler.java | 12 +-- .../impl/PolygonPolygonCollisionHandler.java | 12 +-- .../github/introfog/pie/core/shape/Body.java | 96 +++++++++++++------ .../introfog/pie/core/shape/Circle.java | 8 +- .../introfog/pie/core/shape/IShape.java | 17 ++-- .../introfog/pie/core/shape/Polygon.java | 10 +- .../introfog/pie/core/util/ShapeIOUtil.java | 6 +- .../github/introfog/pie/core/WorldTest.java | 12 +-- .../broadphase/aabbtree/AabbTreeNodeTest.java | 12 +-- .../introfog/pie/core/shape/BodyTest.java | 22 ++--- .../introfog/pie/core/shape/CircleTest.java | 6 +- .../introfog/pie/core/shape/IShapeTest.java | 17 +--- 17 files changed, 164 insertions(+), 150 deletions(-) diff --git a/assessment/src/main/java/com/github/introfog/pie/assessment/collisions/broadphase/applier/MoveShapesAction.java b/assessment/src/main/java/com/github/introfog/pie/assessment/collisions/broadphase/applier/MoveShapesAction.java index 2582f08..9688f05 100644 --- a/assessment/src/main/java/com/github/introfog/pie/assessment/collisions/broadphase/applier/MoveShapesAction.java +++ b/assessment/src/main/java/com/github/introfog/pie/assessment/collisions/broadphase/applier/MoveShapesAction.java @@ -54,7 +54,7 @@ protected void domesticApplyAction(List methods, Set method } IShape[] arrayMethodShapes = methodShapes.toArray(new IShape[] {}); for (int i = 0; i < arrayMethodShapes.length; i += oneMovingBodyOfBodies) { - arrayMethodShapes[i].getBody().position.add(offset, i % 2 == 0 ? -1 : 1); + arrayMethodShapes[i].getBody().getPosition().add(offset, i % 2 == 0 ? -1 : 1); } } } diff --git a/assessment/src/main/java/com/github/introfog/pie/assessment/collisions/broadphase/applier/MoveShapesToPointAction.java b/assessment/src/main/java/com/github/introfog/pie/assessment/collisions/broadphase/applier/MoveShapesToPointAction.java index da8236e..26a5029 100644 --- a/assessment/src/main/java/com/github/introfog/pie/assessment/collisions/broadphase/applier/MoveShapesToPointAction.java +++ b/assessment/src/main/java/com/github/introfog/pie/assessment/collisions/broadphase/applier/MoveShapesToPointAction.java @@ -38,21 +38,21 @@ protected void domesticApplyAction(List methods, Set method callCounter = -iterationOneWay; } - Vector2f center = methodShapes.stream().map(shape -> shape.getBody().position).collect(Collectors.toList()).stream(). + Vector2f center = methodShapes.stream().map(shape -> shape.getBody().getPosition()).collect(Collectors.toList()).stream(). reduce((sum, current) -> {sum.add(current); return sum;}).orElse(new Vector2f()); center.mul(1.0f / methodShapes.size()); for (IShape shape : methodShapes) { - float dist = (float) Math.sqrt(Vector2f.distanceWithoutSqrt(center, shape.getBody().position)); + float dist = (float) Math.sqrt(Vector2f.distanceWithoutSqrt(center, shape.getBody().getPosition())); float cos = 0; float sin = 0; if (dist != 0) { - cos = (shape.getBody().position.x - center.x) / dist; - sin = (shape.getBody().position.y - center.y) / dist; + cos = (shape.getBody().getPosition().x - center.x) / dist; + sin = (shape.getBody().getPosition().y - center.y) / dist; } Vector2f offset = new Vector2f(cos, sin); offset.mul(callCounter > 0 ? offsetValue : -offsetValue); - shape.getBody().position.add(offset); + shape.getBody().getPosition().add(offset); } } } diff --git a/core/src/main/java/com/github/introfog/pie/core/World.java b/core/src/main/java/com/github/introfog/pie/core/World.java index f1f625b..889df21 100644 --- a/core/src/main/java/com/github/introfog/pie/core/World.java +++ b/core/src/main/java/com/github/introfog/pie/core/World.java @@ -18,7 +18,6 @@ import com.github.introfog.pie.core.collisions.Manifold; import com.github.introfog.pie.core.collisions.narrowphase.IShapeCollisionHandler; import com.github.introfog.pie.core.math.MathPie; -import com.github.introfog.pie.core.shape.Body; import com.github.introfog.pie.core.shape.IShape; import com.github.introfog.pie.core.shape.ShapePair; @@ -151,7 +150,7 @@ private void step() { // Integrate forces // Hanna modification Euler's method is used! - shapes.forEach(this::integrateForces); + shapes.forEach(this::integrateForce); // Narrow phase manifolds.clear(); @@ -182,35 +181,26 @@ private void step() { // Integrate forces // Hanna modification Euler's method is used! - shapes.forEach(this::integrateForces); + shapes.forEach(this::integrateForce); // Correct positions manifolds.forEach(Manifold::correctPosition); // Clear all forces - shapes.forEach(shape -> shape.getBody().force.set(0f, 0f)); + shapes.forEach(shape -> shape.getBody().getForce().set(0f, 0f)); } - private void integrateForces(IShape shape) { - final Body body = shape.getBody(); - if (body.getInvertedMass() == 0.0f) { + private void integrateForce(IShape shape) { + if (shape.getBody().getInvertedMass() == 0.0f) { return; } - final float halfDeltaTime = context.getFixedDeltaTime() * 0.5f; - - body.velocity.add(body.force, body.getInvertedMass() * halfDeltaTime); - body.velocity.add(context.getGravity(), halfDeltaTime); - body.angularVelocity += body.torque * body.getInvertedInertia() * halfDeltaTime; + shape.integrateForce(context.getFixedDeltaTime() * 0.5f, context.getGravity()); } private void integrateVelocity(IShape shape) { - final Body body = shape.getBody(); - if (body.getInvertedMass() == 0.0f) { + if (shape.getBody().getInvertedMass() == 0.0f) { return; } - - body.position.add(body.velocity, context.getFixedDeltaTime()); - - shape.setOrientation(body.getOrientation() + body.angularVelocity * context.getFixedDeltaTime()); + shape.integrateVelocity(context.getFixedDeltaTime()); } } diff --git a/core/src/main/java/com/github/introfog/pie/core/collisions/Manifold.java b/core/src/main/java/com/github/introfog/pie/core/collisions/Manifold.java index f21bac6..8457f2a 100644 --- a/core/src/main/java/com/github/introfog/pie/core/collisions/Manifold.java +++ b/core/src/main/java/com/github/introfog/pie/core/collisions/Manifold.java @@ -55,16 +55,16 @@ public void solve() { for (int i = 0; i < contactCount; i++) { // Calculate the contact points regarding centers - Vector2f radA = Vector2f.sub(contacts[i], a.position); - Vector2f radB = Vector2f.sub(contacts[i], b.position); + Vector2f radA = Vector2f.sub(contacts[i], a.getPosition()); + Vector2f radB = Vector2f.sub(contacts[i], b.getPosition()); // Calculate the relative velocity // Vec2 rv = B->velocity + Cross( B->angularVelocity, rb ) - // A->velocity - Cross( A->angularVelocity, ra ); // relativeVelocity - Vector2f rv = Vector2f.sub(b.velocity, a.velocity); - rv.add(Vector2f.crossProduct(b.angularVelocity, radB)); - rv.sub(Vector2f.crossProduct(a.angularVelocity, radA)); + Vector2f rv = Vector2f.sub(b.getVelocity(), a.getVelocity()); + rv.add(Vector2f.crossProduct(b.getAngularVelocity(), radB)); + rv.sub(Vector2f.crossProduct(a.getAngularVelocity(), radA)); // Calculate the relative velocity relative to the normal direction float velAlongNormal = Vector2f.dotProduct(rv, normal); @@ -94,9 +94,9 @@ public void solve() { // Friction work // Recalculation relative speed after application of a normal impulse - rv = Vector2f.sub(b.velocity, a.velocity); //relativeVelocity - rv.add(Vector2f.crossProduct(b.angularVelocity, radB)); - rv.sub(Vector2f.crossProduct(a.angularVelocity, radA)); + rv = Vector2f.sub(b.getVelocity(), a.getVelocity()); //relativeVelocity + rv.add(Vector2f.crossProduct(b.getAngularVelocity(), radB)); + rv.sub(Vector2f.crossProduct(a.getAngularVelocity(), radA)); // Calculate the tangent vector: tangent = rb - dotProduct (rv, normal) * normal // Vec2 t = rv - (normal * Dot( rv, normal )); @@ -135,8 +135,8 @@ public void correctPosition() { } Vector2f correction = Vector2f.mul(normal, penetration * context.getCorrectPositionPercent() / (a.getInvertedMass() + b.getInvertedMass())); - a.position.sub(Vector2f.mul(correction, a.getInvertedMass())); - b.position.add(Vector2f.mul(correction, b.getInvertedMass())); + a.getPosition().sub(Vector2f.mul(correction, a.getInvertedMass())); + b.getPosition().add(Vector2f.mul(correction, b.getInvertedMass())); } private void initializeCollision() { @@ -144,20 +144,20 @@ private void initializeCollision() { // i.e. this is the threshold, if the energy is lower, then the body is at rest, if higher, // then the body moves. Dynamic friction - friction in the usual sense, when bodies rub against // each other, they lose part of their energy against each other - staticFriction = (float) StrictMath.sqrt( - a.staticFriction * a.staticFriction + b.staticFriction * b.staticFriction); - dynamicFriction = (float) StrictMath.sqrt( - a.dynamicFriction * a.dynamicFriction + b.dynamicFriction * b.dynamicFriction); + staticFriction = (float) StrictMath.sqrt(a.getStaticFriction() * a.getStaticFriction() + + b.getStaticFriction() * b.getStaticFriction()); + dynamicFriction = (float) StrictMath.sqrt(a.getDynamicFriction() * a.getDynamicFriction() + + b.getDynamicFriction() * b.getDynamicFriction()); // Calculate the elasticity - e = Math.min(a.restitution, b.restitution); + e = Math.min(a.getRestitution(), b.getRestitution()); for (int i = 0; i < contactCount; ++i) { // Calculate radii from COM to contact // Vec2 ra = contacts[i] - A->position; // Vec2 rb = contacts[i] - B->position; - Vector2f radA = Vector2f.sub(contacts[i], a.position); - Vector2f radB = Vector2f.sub(contacts[i], b.position); + Vector2f radA = Vector2f.sub(contacts[i], a.getPosition()); + Vector2f radB = Vector2f.sub(contacts[i], b.getPosition()); // Vec2 rv = B->velocity + Cross( B->angularVelocity, rb ) - // A->velocity - Cross( A->angularVelocity, ra ); @@ -165,9 +165,9 @@ private void initializeCollision() { // Vec2 rv = B->velocity + Cross( B->angularVelocity, rb ) - // A->velocity - Cross( A->angularVelocity, ra ); //relativeVelocity - Vector2f rv = Vector2f.sub(b.velocity, a.velocity); - rv.add(Vector2f.crossProduct(b.angularVelocity, radB)); - rv.sub(Vector2f.crossProduct(a.angularVelocity, radA)); + Vector2f rv = Vector2f.sub(b.getVelocity(), a.getVelocity()); + rv.add(Vector2f.crossProduct(b.getAngularVelocity(), radB)); + rv.sub(Vector2f.crossProduct(a.getAngularVelocity(), radA)); // Determine whether should perform a collision with a stop or not. // The idea is that the only thing that moves this object is gravity, diff --git a/core/src/main/java/com/github/introfog/pie/core/collisions/narrowphase/impl/CircleCircleCollisionHandler.java b/core/src/main/java/com/github/introfog/pie/core/collisions/narrowphase/impl/CircleCircleCollisionHandler.java index dc6a27e..cc732d4 100644 --- a/core/src/main/java/com/github/introfog/pie/core/collisions/narrowphase/impl/CircleCircleCollisionHandler.java +++ b/core/src/main/java/com/github/introfog/pie/core/collisions/narrowphase/impl/CircleCircleCollisionHandler.java @@ -37,7 +37,7 @@ public Manifold handleCollision(IShape aShape, IShape bShape, Context context) { Circle circleB = (Circle) bShape; Manifold manifold = new Manifold(circleA, circleB, context); - manifold.normal = Vector2f.sub(circleB.getBody().position, circleA.getBody().position); + manifold.normal = Vector2f.sub(circleB.getBody().getPosition(), circleA.getBody().getPosition()); final float distanceWithoutSqrt = manifold.normal.lengthWithoutSqrt(); if (!CircleCircleCollisionHandler.areIntersected(circleA, circleB, distanceWithoutSqrt)) { @@ -50,12 +50,12 @@ public Manifold handleCollision(IShape aShape, IShape bShape, Context context) { manifold.normal.normalize(); manifold.contacts[0].set(manifold.normal); manifold.contacts[0].mul(circleA.getRadius()); - manifold.contacts[0].add(circleA.getBody().position); + manifold.contacts[0].add(circleA.getBody().getPosition()); if (distanceWithoutSqrt == 0) { manifold.normal.set(1f, 0f); manifold.penetration = circleA.getRadius(); - manifold.contacts[0].set(circleA.getBody().position); + manifold.contacts[0].set(circleA.getBody().getPosition()); } return manifold; diff --git a/core/src/main/java/com/github/introfog/pie/core/collisions/narrowphase/impl/CirclePolygonCollisionHandler.java b/core/src/main/java/com/github/introfog/pie/core/collisions/narrowphase/impl/CirclePolygonCollisionHandler.java index 920ee77..ee105dc 100644 --- a/core/src/main/java/com/github/introfog/pie/core/collisions/narrowphase/impl/CirclePolygonCollisionHandler.java +++ b/core/src/main/java/com/github/introfog/pie/core/collisions/narrowphase/impl/CirclePolygonCollisionHandler.java @@ -54,8 +54,8 @@ public Manifold handleCollision(IShape aShape, IShape bShape, Context context) { Manifold manifold = new Manifold(circleA, polygonB, context); // Translate center coordinates to polygon coordinates // center = B->u.Transpose( ) * (center - b->position); - Vector2f centerA = new Vector2f(circleA.getBody().position); - centerA.sub(polygonB.getBody().position); + Vector2f centerA = new Vector2f(circleA.getBody().getPosition()); + centerA.sub(polygonB.getBody().getPosition()); polygonB.getRotateMatrix().transposeMul(centerA, centerA); // Looking for the nearest edge of the polygon to the center of the circle, @@ -105,7 +105,7 @@ public Manifold handleCollision(IShape aShape, IShape bShape, Context context) { manifold.contacts[0].set(manifold.normal); manifold.contacts[0].mul(circleA.getRadius()); - manifold.contacts[0].add(circleA.getBody().position); + manifold.contacts[0].add(circleA.getBody().getPosition()); manifold.penetration = circleA.getRadius(); return manifold; } @@ -138,7 +138,7 @@ public Manifold handleCollision(IShape aShape, IShape bShape, Context context) { n.normalize(); manifold.normal.set(n); polygonB.getRotateMatrix().mul(v1, v1); - v1.add(polygonB.getBody().position); + v1.add(polygonB.getBody().getPosition()); manifold.contacts[0].set(v1); } else if (dot2 <= 0f) { // Closer to the second vertex @@ -160,7 +160,7 @@ public Manifold handleCollision(IShape aShape, IShape bShape, Context context) { n.normalize(); manifold.normal.set(n); polygonB.getRotateMatrix().mul(v2, v2); - v2.add(polygonB.getBody().position); + v2.add(polygonB.getBody().getPosition()); manifold.contacts[0].set(v2); } else { // Closer to the front vertex @@ -177,7 +177,7 @@ public Manifold handleCollision(IShape aShape, IShape bShape, Context context) { manifold.normal.set(n); manifold.contacts[0].set(manifold.normal); manifold.contacts[0].mul(circleA.getRadius()); - manifold.contacts[0].add(circleA.getBody().position); + manifold.contacts[0].add(circleA.getBody().getPosition()); } return manifold; } diff --git a/core/src/main/java/com/github/introfog/pie/core/collisions/narrowphase/impl/PolygonPolygonCollisionHandler.java b/core/src/main/java/com/github/introfog/pie/core/collisions/narrowphase/impl/PolygonPolygonCollisionHandler.java index 06a406c..4e5b0fe 100644 --- a/core/src/main/java/com/github/introfog/pie/core/collisions/narrowphase/impl/PolygonPolygonCollisionHandler.java +++ b/core/src/main/java/com/github/introfog/pie/core/collisions/narrowphase/impl/PolygonPolygonCollisionHandler.java @@ -100,9 +100,9 @@ public Manifold handleCollision(IShape aShape, IShape bShape, Context context) { // v1 = RefPoly->u * v1 + RefPoly->body->position; // v2 = RefPoly->u * v2 + RefPoly->body->position; refPoly.getRotateMatrix().mul(v1, v1); - v1.add(refPoly.getBody().position); + v1.add(refPoly.getBody().getPosition()); refPoly.getRotateMatrix().mul(v2, v2); - v2.add(refPoly.getBody().position); + v2.add(refPoly.getBody().getPosition()); // Calculate reference face side normal in world space // Vec2 sidePlaneNormal = (v2 - v1); @@ -207,10 +207,10 @@ private void findIncidentFace(Vector2f[] v, Polygon refPoly, Polygon incPoly, in // v[1] = IncPoly->u * IncPoly->m_vertices[incidentFace] + // IncPoly->body->position; incPoly.getRotateMatrix().mul(incPoly.getVertices()[incidentFace], v[0]); - v[0].add(incPoly.getBody().position); + v[0].add(incPoly.getBody().getPosition()); incidentFace = incidentFace + 1 >= incPoly.getVertices().length ? 0 : incidentFace + 1; incPoly.getRotateMatrix().mul(incPoly.getVertices()[incidentFace], v[1]); - v[1].add(incPoly.getBody().position); + v[1].add(incPoly.getBody().getPosition()); } private int clip(Vector2f n, float c, Vector2f[] face) { @@ -287,8 +287,8 @@ private static float findAxisLeastPenetration(int[] faceIndex, Polygon polygonA, // v = buT * v; Vector2f v = new Vector2f(polygonA.getVertices()[i]); polygonA.getRotateMatrix().mul(v, v); - v.add(polygonA.getBody().position); - v.sub(polygonB.getBody().position); + v.add(polygonA.getBody().getPosition()); + v.sub(polygonB.getBody().getPosition()); polygonB.getRotateMatrix().transposeMul(v, v); // Calculate penetration (in local coordinates B) diff --git a/core/src/main/java/com/github/introfog/pie/core/shape/Body.java b/core/src/main/java/com/github/introfog/pie/core/shape/Body.java index d2b85de..357b912 100644 --- a/core/src/main/java/com/github/introfog/pie/core/shape/Body.java +++ b/core/src/main/java/com/github/introfog/pie/core/shape/Body.java @@ -24,34 +24,34 @@ * The class stores all the physical parameters of a shape, such as mass, position, speed, etc. */ public class Body { - /** The position. */ - public final Vector2f position; /** The density. */ protected final float density; /** The restitution. */ - public final float restitution; + protected final float restitution; /** The static friction. */ - public final float staticFriction; + protected final float staticFriction; /** The dynamic friction. */ - public final float dynamicFriction; + protected final float dynamicFriction; + + /** The body orientation in radians. */ + protected float orientation; + /** The angular velocity. */ + protected float angularVelocity; /** The torque. */ - public final float torque; + protected final float torque; /** The inverted mass. */ protected float invertedMass; /** The inverted inertia. */ protected float invertedInertia; - /** The body orientation in radians. */ - protected float orientation; - - /** The angular velocity. */ - public float angularVelocity; - /** The force. */ - public final Vector2f force; + /** The position. */ + protected final Vector2f position; /** The velocity. */ - public final Vector2f velocity; + protected final Vector2f velocity; + /** The force. */ + protected final Vector2f force; /** * Instantiates a new {@link Body} instance. @@ -62,15 +62,17 @@ public class Body { * @param restitution the body restitution */ public Body(float positionX, float positionY, float density, float restitution) { - position = new Vector2f(positionX, positionY); this.density = density; this.restitution = restitution; - staticFriction = 0.5f; - dynamicFriction = 0.3f; - torque = 0f; - force = new Vector2f(0f, 0f); - velocity = new Vector2f(0f, 0f); + this.staticFriction = 0.5f; + this.dynamicFriction = 0.3f; + + this.torque = 0; + + this.position = new Vector2f(positionX, positionY); + this.velocity = new Vector2f(0f, 0f); + this.force = new Vector2f(0f, 0f); } @Override @@ -82,25 +84,53 @@ public boolean equals(Object o) { return false; } Body body = (Body) o; - return Float.compare(body.density, density) == 0 && - Float.compare(body.restitution, restitution) == 0 && - position.equals(body.position); + return Float.compare(body.getDensity(), getDensity()) == 0 && + Float.compare(body.getRestitution(), getRestitution()) == 0 && + getPosition().equals(body.getPosition()); } @Override public int hashCode() { - return Objects.hash(density, restitution, position); + return Objects.hash(getDensity(), getRestitution(), getPosition()); } @Override public String toString() { return new StringJoiner("; ", "{", "}") - .add("position=" + position) - .add("density=" + density) - .add("restitution=" + restitution) + .add("position=" + getPosition()) + .add("density=" + getDensity()) + .add("restitution=" + getRestitution()) .toString(); } + public float getDensity() { + return density; + } + + public float getRestitution() { + return restitution; + } + + public float getStaticFriction() { + return staticFriction; + } + + public float getDynamicFriction() { + return dynamicFriction; + } + + public float getOrientation() { + return orientation; + } + + public float getAngularVelocity() { + return angularVelocity; + } + + public float getTorque() { + return torque; + } + public float getInvertedMass() { return invertedMass; } @@ -109,11 +139,15 @@ public float getInvertedInertia() { return invertedInertia; } - public float getOrientation() { - return orientation; + public Vector2f getPosition() { + return position; } - public float getDensity() { - return density; + public Vector2f getVelocity() { + return velocity; + } + + public Vector2f getForce() { + return force; } } diff --git a/core/src/main/java/com/github/introfog/pie/core/shape/Circle.java b/core/src/main/java/com/github/introfog/pie/core/shape/Circle.java index b52c5cf..af7688c 100644 --- a/core/src/main/java/com/github/introfog/pie/core/shape/Circle.java +++ b/core/src/main/java/com/github/introfog/pie/core/shape/Circle.java @@ -56,21 +56,21 @@ public final float getRadius() { @Override public void computeAabb() { - getAabb().min.set(getBody().position.x - radius, getBody().position.y - radius); - getAabb().max.set(getBody().position.x + radius, getBody().position.y + radius); + getAabb().min.set(getBody().getPosition().x - radius, getBody().getPosition().y - radius); + getAabb().max.set(getBody().getPosition().x + radius, getBody().getPosition().y + radius); } @Override public String toString() { return new StringJoiner("; ", "{", "}") - .add("center=" + getBody().position) + .add("center=" + getBody().getPosition()) .add("radius=" + radius) .toString(); } @Override protected void computeMassAndInertia() { - float mass = (float) Math.PI * radius * radius * getBody().density; + float mass = (float) Math.PI * radius * radius * getBody().getDensity(); getBody().invertedMass = (mass == 0f) ? 0f : 1f / mass; float inertia = radius * radius / (getBody().getInvertedMass() == 0 ? 1 : getBody().getInvertedMass()); diff --git a/core/src/main/java/com/github/introfog/pie/core/shape/IShape.java b/core/src/main/java/com/github/introfog/pie/core/shape/IShape.java index f8b6b65..4a08cd9 100644 --- a/core/src/main/java/com/github/introfog/pie/core/shape/IShape.java +++ b/core/src/main/java/com/github/introfog/pie/core/shape/IShape.java @@ -49,12 +49,15 @@ public IShape(Body body, Aabb aabb, RotationMatrix2x2 rotateMatrix) { this.rotateMatrix = rotateMatrix; } - /** - * Sets the shape orientation in space. - * - * @param radian the angle in radians that the shape will have in space - */ - public void setOrientation(float radian) { + public void integrateForce(float deltaTime, Vector2f gravity) { + body.getVelocity().add(body.getForce(), body.getInvertedMass() * deltaTime); + body.getVelocity().add(gravity, deltaTime); + body.angularVelocity += body.getTorque() * body.getInvertedInertia() * deltaTime; + } + + public void integrateVelocity(float deltaTime) { + body.getPosition().add(body.getVelocity(), deltaTime); + final float radian = body.getOrientation() + body.getAngularVelocity() * deltaTime; body.orientation = radian; rotateMatrix.setAngle(radian); } @@ -66,7 +69,7 @@ public void setOrientation(float radian) { * @param contactVector the point of impulse application (coordinates are set relative to the center of the shape) */ public void applyImpulse(Vector2f impulse, Vector2f contactVector) { - body.velocity.add(impulse, body.getInvertedMass()); + body.getVelocity().add(impulse, body.getInvertedMass()); body.angularVelocity += body.getInvertedInertia() * Vector2f.crossProduct(contactVector, impulse); } diff --git a/core/src/main/java/com/github/introfog/pie/core/shape/Polygon.java b/core/src/main/java/com/github/introfog/pie/core/shape/Polygon.java index 93c491f..54dae60 100644 --- a/core/src/main/java/com/github/introfog/pie/core/shape/Polygon.java +++ b/core/src/main/java/com/github/introfog/pie/core/shape/Polygon.java @@ -153,14 +153,14 @@ public void computeAabb() { } } - getAabb().min.add(getBody().position); - getAabb().max.add(getBody().position); + getAabb().min.add(getBody().getPosition()); + getAabb().max.add(getBody().getPosition()); } @Override public String toString() { return new StringJoiner("; ", "{", "}") - .add("center=" + getBody().position) + .add("center=" + getBody().getPosition()) .add("vertices=" + Arrays.toString(vertices)) .toString(); } @@ -211,9 +211,9 @@ protected void computeMassAndInertia() { I += (0.25f * k_inv3 * D) * (intX2 + intY2); } - float mass = getBody().density * area; + float mass = getBody().getDensity() * area; getBody().invertedMass = (mass != 0f) ? 1f / mass : 0f; - float inertia = I * getBody().density; + float inertia = I * getBody().getDensity(); getBody().invertedInertia = (inertia != 0f) ? 1f / inertia : 0f; } diff --git a/core/src/main/java/com/github/introfog/pie/core/util/ShapeIOUtil.java b/core/src/main/java/com/github/introfog/pie/core/util/ShapeIOUtil.java index 9d88289..05047ce 100644 --- a/core/src/main/java/com/github/introfog/pie/core/util/ShapeIOUtil.java +++ b/core/src/main/java/com/github/introfog/pie/core/util/ShapeIOUtil.java @@ -132,10 +132,10 @@ public static String convertShapeToString(IShape shape) { str.append(vec.x).append(";").append(vec.y).append(";"); } } - str.append(shape.getBody().position.x).append(";") - .append(shape.getBody().position.y).append(";") + str.append(shape.getBody().getPosition().x).append(";") + .append(shape.getBody().getPosition().y).append(";") .append(shape.getBody().getDensity()).append(";") - .append(shape.getBody().restitution).append("\n"); + .append(shape.getBody().getRestitution()).append("\n"); return str.toString(); } diff --git a/core/src/test/java/com/github/introfog/pie/core/WorldTest.java b/core/src/test/java/com/github/introfog/pie/core/WorldTest.java index 2e41c16..c889c24 100644 --- a/core/src/test/java/com/github/introfog/pie/core/WorldTest.java +++ b/core/src/test/java/com/github/introfog/pie/core/WorldTest.java @@ -238,19 +238,19 @@ public void highAndLowCollisionSolveIterationsTest() { World lowIterWorld = new World(properties); IShape cHigh1 = new Circle(10, 0, 0, 1f, 0.2f); - cHigh1.getBody().velocity.add(new Vector2f(0.1f, 0)); + cHigh1.getBody().getVelocity().add(new Vector2f(0.1f, 0)); IShape cHigh2 = new Circle(10, 15, 0, 1f, 0.2f); IShape cHigh3 = new Circle(10, 25, 0, 1f, 0.2f); - cHigh3.getBody().velocity.add(new Vector2f(-0.1f, 0)); + cHigh3.getBody().getVelocity().add(new Vector2f(-0.1f, 0)); highIterWorld.addShape(cHigh1); highIterWorld.addShape(cHigh2); highIterWorld.addShape(cHigh3); IShape cLow1 = new Circle(10, 0, 0, 1f, 0.2f); - cLow1.getBody().velocity.add(new Vector2f(0.1f, 0)); + cLow1.getBody().getVelocity().add(new Vector2f(0.1f, 0)); IShape cLow2 = new Circle(10, 15, 0, 1f, 0.2f); IShape cLow3 = new Circle(10, 25, 0, 1f, 0.2f); - cLow3.getBody().velocity.add(new Vector2f(-0.1f, 0)); + cLow3.getBody().getVelocity().add(new Vector2f(-0.1f, 0)); lowIterWorld.addShape(cLow1); lowIterWorld.addShape(cLow2); lowIterWorld.addShape(cLow3); @@ -263,8 +263,8 @@ public void highAndLowCollisionSolveIterationsTest() { // This assert checks that with a large value of the collision solve iterations number, // the calculation is more accurate, i.e. in our case, the penetration of one circle // into another is less, with a larger value of the collision solve iterations number - float penetrationWithHigh = cHigh1.getBody().position.x - cHigh2.getBody().position.x; - float penetrationWithLow = cLow1.getBody().position.x - cLow2.getBody().position.x; + float penetrationWithHigh = cHigh1.getBody().getPosition().x - cHigh2.getBody().getPosition().x; + float penetrationWithLow = cLow1.getBody().getPosition().x - cLow2.getBody().getPosition().x; Assert.assertTrue(penetrationWithLow - penetrationWithHigh > 0.02f); } diff --git a/core/src/test/java/com/github/introfog/pie/core/collisions/broadphase/aabbtree/AabbTreeNodeTest.java b/core/src/test/java/com/github/introfog/pie/core/collisions/broadphase/aabbtree/AabbTreeNodeTest.java index 59d6179..815b3ff 100644 --- a/core/src/test/java/com/github/introfog/pie/core/collisions/broadphase/aabbtree/AabbTreeNodeTest.java +++ b/core/src/test/java/com/github/introfog/pie/core/collisions/broadphase/aabbtree/AabbTreeNodeTest.java @@ -117,7 +117,7 @@ public void leafRootNotMovedShapeUpdateRootTest() { IShape circle = new Circle(10, 0, 0, MathPie.STATIC_BODY_DENSITY, 0); AabbTreeNode node = new AabbTreeNode(circle, 0.2f); Aabb aabb = node.aabb; - circle.getBody().position.add(new Vector2f(3.9f, 0)); + circle.getBody().getPosition().add(new Vector2f(3.9f, 0)); AabbTreeNode outputNode = AabbTreeNode.updateTree(node); Aabb outputAabb = outputNode.aabb; @@ -135,10 +135,10 @@ public void movedLeftLeafAndNullGrandpaUpdateRootTest() { IShape c2 = new Circle(10, 10, 0, MathPie.STATIC_BODY_DENSITY, 0); root = AabbTreeNode.insertLeaf(root, c2); - c1.getBody().position.add(new Vector2f(15f, 0)); + c1.getBody().getPosition().add(new Vector2f(15f, 0)); c1.computeAabb(); // Additional bBox size equal to 2, and if we move circle for 1.9, leaf shouldn't update - c2.getBody().position.add(new Vector2f(1.9f, 0)); + c2.getBody().getPosition().add(new Vector2f(1.9f, 0)); c2.computeAabb(); AabbTreeNode newRoot = AabbTreeNode.updateTree(root); @@ -164,7 +164,7 @@ public void movedRightLeafAndNullGrandpaUpdateRootTest() { root = AabbTreeNode.insertLeaf(root, c3); // Additional bBox size equal to 2, and if we move circle for 3, leaf should update - c2.getBody().position.add(new Vector2f(3f, 0)); + c2.getBody().getPosition().add(new Vector2f(3f, 0)); c2.computeAabb(); AabbTreeNode newRoot = AabbTreeNode.updateTree(root); @@ -192,7 +192,7 @@ public void movedLeftLeafAndUpdateRootTest() { root = AabbTreeNode.insertLeaf(root, c4); // Additional bBox size equal to 2, and if we move circle for 5, leaf should update - c4.getBody().position.add(new Vector2f(5f, 0)); + c4.getBody().getPosition().add(new Vector2f(5f, 0)); c4.computeAabb(); AabbTreeNode newRoot = AabbTreeNode.updateTree(root); @@ -245,7 +245,7 @@ public void insertLeafTest() { Assert.assertNotNull(root.children[1].children); Assert.assertSame(c2, root.children[1].children[1].shape); Assert.assertNotNull(root.children[1].children[0].shape); - Assert.assertEquals(new Vector2f(20, 0), root.children[1].children[0].shape.getBody().position); + Assert.assertEquals(new Vector2f(20, 0), root.children[1].children[0].shape.getBody().getPosition()); } @Test diff --git a/core/src/test/java/com/github/introfog/pie/core/shape/BodyTest.java b/core/src/test/java/com/github/introfog/pie/core/shape/BodyTest.java index 0a3b3ed..b719950 100644 --- a/core/src/test/java/com/github/introfog/pie/core/shape/BodyTest.java +++ b/core/src/test/java/com/github/introfog/pie/core/shape/BodyTest.java @@ -29,17 +29,17 @@ public class BodyTest extends PieTest { public void paramConstructorTest() { Body body = new Body(0.1f, 0.2f, 0.3f, 0.4f); - Assert.assertEquals(0.1f, body.position.x, FLOAT_EPSILON_COMPARISON); - Assert.assertEquals(0.2f, body.position.y, FLOAT_EPSILON_COMPARISON); - Assert.assertEquals(0.3f, body.density, FLOAT_EPSILON_COMPARISON); - Assert.assertEquals(0.4f, body.restitution, FLOAT_EPSILON_COMPARISON); - Assert.assertEquals(0.5f, body.staticFriction, FLOAT_EPSILON_COMPARISON); - Assert.assertEquals(0.3f, body.dynamicFriction, FLOAT_EPSILON_COMPARISON); - Assert.assertEquals(0, body.torque, FLOAT_EPSILON_COMPARISON); - Assert.assertEquals(0, body.force.x, FLOAT_EPSILON_COMPARISON); - Assert.assertEquals(0, body.force.y, FLOAT_EPSILON_COMPARISON); - Assert.assertEquals(0, body.velocity.x, FLOAT_EPSILON_COMPARISON); - Assert.assertEquals(0, body.velocity.y, FLOAT_EPSILON_COMPARISON); + Assert.assertEquals(0.1f, body.getPosition().x, FLOAT_EPSILON_COMPARISON); + Assert.assertEquals(0.2f, body.getPosition().y, FLOAT_EPSILON_COMPARISON); + Assert.assertEquals(0.3f, body.getDensity(), FLOAT_EPSILON_COMPARISON); + Assert.assertEquals(0.4f, body.getRestitution(), FLOAT_EPSILON_COMPARISON); + Assert.assertEquals(0.5f, body.getStaticFriction(), FLOAT_EPSILON_COMPARISON); + Assert.assertEquals(0.3f, body.getDynamicFriction(), FLOAT_EPSILON_COMPARISON); + Assert.assertEquals(0, body.getTorque(), FLOAT_EPSILON_COMPARISON); + Assert.assertEquals(0, body.getForce().x, FLOAT_EPSILON_COMPARISON); + Assert.assertEquals(0, body.getForce().y, FLOAT_EPSILON_COMPARISON); + Assert.assertEquals(0, body.getVelocity().x, FLOAT_EPSILON_COMPARISON); + Assert.assertEquals(0, body.getVelocity().y, FLOAT_EPSILON_COMPARISON); } @Test diff --git a/core/src/test/java/com/github/introfog/pie/core/shape/CircleTest.java b/core/src/test/java/com/github/introfog/pie/core/shape/CircleTest.java index d82ba42..287c9c2 100644 --- a/core/src/test/java/com/github/introfog/pie/core/shape/CircleTest.java +++ b/core/src/test/java/com/github/introfog/pie/core/shape/CircleTest.java @@ -34,9 +34,9 @@ public void paramConstructorWithNegativeRadiusTest() { public void paramConstructorTest() { Circle circle = new Circle(10, 1, 3, 0.1f, 0.2f); - Assert.assertEquals(new Vector2f(1, 3), circle.getBody().position); - Assert.assertEquals(0.1f, circle.getBody().density, PieTest.FLOAT_EPSILON_COMPARISON); - Assert.assertEquals(0.2f, circle.getBody().restitution, PieTest.FLOAT_EPSILON_COMPARISON); + Assert.assertEquals(new Vector2f(1, 3), circle.getBody().getPosition()); + Assert.assertEquals(0.1f, circle.getBody().getDensity(), PieTest.FLOAT_EPSILON_COMPARISON); + Assert.assertEquals(0.2f, circle.getBody().getRestitution(), PieTest.FLOAT_EPSILON_COMPARISON); } @Test diff --git a/core/src/test/java/com/github/introfog/pie/core/shape/IShapeTest.java b/core/src/test/java/com/github/introfog/pie/core/shape/IShapeTest.java index f306e05..e59b920 100644 --- a/core/src/test/java/com/github/introfog/pie/core/shape/IShapeTest.java +++ b/core/src/test/java/com/github/introfog/pie/core/shape/IShapeTest.java @@ -38,25 +38,12 @@ public void defaultConstructorTest() { Assert.assertEquals(1, shape.getRotateMatrix().m11, PieTest.FLOAT_EPSILON_COMPARISON); } - @Test - public void setOrientationTest() { - IShape shape = new Circle(10, 0,0, 0, 0); - shape.setOrientation((float) Math.PI / 3); - - Assert.assertEquals((float) Math.PI / 3, shape.getBody().getOrientation(), PieTest.FLOAT_EPSILON_COMPARISON); - - Assert.assertEquals(0.5f, shape.getRotateMatrix().m00, PieTest.FLOAT_EPSILON_COMPARISON); - Assert.assertEquals(-Math.sqrt(3) / 2, shape.getRotateMatrix().m01, PieTest.FLOAT_EPSILON_COMPARISON); - Assert.assertEquals(Math.sqrt(3) / 2, shape.getRotateMatrix().m10, PieTest.FLOAT_EPSILON_COMPARISON); - Assert.assertEquals(0.5f, shape.getRotateMatrix().m11, PieTest.FLOAT_EPSILON_COMPARISON); - } - @Test public void applyImpulseTest() { IShape shape = new Circle(1, 0,0, (float) (1 / Math.PI), 0); shape.applyImpulse(new Vector2f(10, 10), new Vector2f(1, 0)); - Assert.assertEquals(new Vector2f(10, 10), shape.getBody().velocity); - Assert.assertEquals(10, shape.getBody().angularVelocity, PieTest.FLOAT_EPSILON_COMPARISON); + Assert.assertEquals(new Vector2f(10, 10), shape.getBody().getVelocity()); + Assert.assertEquals(10, shape.getBody().getAngularVelocity(), PieTest.FLOAT_EPSILON_COMPARISON); } }