package engine.utility;
import engine.geometry.Polygon;
import engine.geometry.Vector;
import game.terrain.Block;
public class Physics {
static PhysicsMode physicsMode = new PhysicsDan();
public static boolean intersects(Block[][] blocks, Polygon polygon) {
int r1 = (int) Math.floor(polygon.getMinY() / Block.HEIGHT);
int r2 = (int) Math.ceil(polygon.getMaxY() / Block.HEIGHT);
int c1 = (int) Math.floor(polygon.getMinX() / Block.WIDTH);
int c2 = (int) Math.ceil(polygon.getMaxX() / Block.WIDTH);
if (r1 < 0) {
r1 = 0;
} else if (r1 > blocks.length) {
r1 = blocks.length;
}
if (r2 < 0) {
r2 = 0;
} else if (r2 > blocks.length) {
r2 = blocks.length;
}
if (c1 < 0) {
c1 = 0;
} else if (c1 > blocks[0].length) {
c1 = blocks.length;
}
if (c2 < 0) {
c2 = 0;
} else if (c2 > blocks[0].length) {
c2 = blocks.length;
}
for (int r = r1; r < r2; r++) {
for (int c = c1; c < c2; c++) {
if (Physics.intersects(blocks[r][c].getPolygon(), polygon)) {
return true;
}
}
}
return false;
}
public static boolean intersects(Polygon p1, Polygon p2) {
if (p1 == null || p2 == null) {
return false;
}
final int size1 = p1.getSize();
for (int i = 0; i < size1; i++) {
if (Rough.lessEqual(p1.getMaxProjection(i), minProjection(p2, p1.getNormal(i)))) {
// Not overlapping on this axis
return false;
}
}
final int size2 = p2.getSize();
for (int i = 0; i < size2; i++) {
if (Rough.lessEqual(p2.getMaxProjection(i), minProjection(p1, p2.getNormal(i)))) {
// Not overlapping on this axis
return false;
}
}
// Overlapping on all axes
return true;
}
public static double maxProjection(Polygon polygon, Vector vector) {
double max = Double.NEGATIVE_INFINITY;
Vector v = new Vector();
final int size = polygon.getSize();
for (int i = 0; i < size; i++) {
double dot = polygon.getVertex(i, v).dot(vector);
if (dot > max) {
max = dot;
}
}
return max;
}
public static double minProjection(Polygon polygon, Vector vector) {
double min = Double.POSITIVE_INFINITY;
Vector v = new Vector();
final int size = polygon.getSize();
for (int i = 0; i < size; i++) {
double dot = polygon.getVertex(i, v).dot(vector);
if (dot < min) {
min = dot;
}
}
return min;
}
public static void setPhysicsMode(PhysicsMode physicsMode) {
Physics.physicsMode = physicsMode;
}
public static Vector move(Block[][] blocks, Polygon position, Vector velocity) {
return physicsMode.move(blocks, position, velocity);
}
}