Minestom/src/main/java/net/minestom/server/collision/EntityCollision.java
iam 7cce1aa479 hollow-cube/projectile-physics-improvements
* Add better protectiles

* Cleanup

* better physics

* Add filter

* Update EntityCollision.java

* Negate filter check

(cherry picked from commit 0400e2dda4)
2024-02-09 14:27:43 -05:00

69 lines
2.8 KiB
Java

package net.minestom.server.collision;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.Entity;
import net.minestom.server.instance.Instance;
import java.util.function.Function;
final class EntityCollision {
public static PhysicsResult checkCollision(Instance instance, BoundingBox boundingBox, Point point, Vec entityVelocity, double extendRadius, Function<Entity, Boolean> entityFilter, PhysicsResult res) {
double minimumRes = res != null ? res.res().res : Double.MAX_VALUE;
if (instance == null) return null;
SweepResult sweepResult = new SweepResult(minimumRes, 0, 0, 0, null, null);
double closestDistance = minimumRes;
Entity closestEntity = null;
var maxDistance = Math.pow(boundingBox.height() * boundingBox.height() + boundingBox.depth()/2 * boundingBox.depth()/2 + boundingBox.width()/2 * boundingBox.width()/2, 1/3.0);
double projectileDistance = entityVelocity.length();
for (Entity e : instance.getNearbyEntities(point, extendRadius + maxDistance + projectileDistance)) {
if (!entityFilter.apply(e)) continue;
if (!e.hasCollision()) continue;
// Overlapping with entity, math can't be done we return the entity
if (e.getBoundingBox().intersectBox(e.getPosition().sub(point), boundingBox)) {
var p = Pos.fromPoint(point);
return new PhysicsResult(p,
Vec.ZERO,
false,
true,
true,
true,
entityVelocity,
new Pos[] {p, p, p},
new Shape[] {e, e, e},
true,
sweepResult);
}
// Check collisions with entity
e.getBoundingBox().intersectBoxSwept(point, entityVelocity, e.getPosition(), boundingBox, sweepResult);
if (sweepResult.res < closestDistance && sweepResult.res < 1) {
closestDistance = sweepResult.res;
closestEntity = e;
}
}
Pos[] collisionPoints = new Pos[3];
return new PhysicsResult(Pos.fromPoint(point).add(entityVelocity.mul(closestDistance)),
Vec.ZERO,
sweepResult.normalY == -1,
sweepResult.normalX != 0,
sweepResult.normalY != 0,
sweepResult.normalZ != 0,
entityVelocity,
collisionPoints,
new Shape[] {closestEntity, closestEntity, closestEntity},
sweepResult.normalX != 0 || sweepResult.normalZ != 0 || sweepResult.normalY != 0,
sweepResult
);
}
}