From 7cdff81b367ff86928ec8b25f116b5cd50507f18 Mon Sep 17 00:00:00 2001 From: Minecon724 Date: Wed, 17 Jul 2024 19:07:42 +0200 Subject: [PATCH] this --- src/main/java/net/pivipi/ball/Ball.java | 4 +- src/main/java/net/pivipi/ball/BallKicker.java | 3 +- src/main/java/net/pivipi/entity/AABB.java | 54 +++++++++++++++++++ .../java/net/pivipi/entity/PhysicsEntity.java | 21 ++++++++ .../java/net/pivipi/physics/Collision.java | 38 +++++++------ .../net/pivipi/physics/CollisionData.java | 2 +- src/main/java/net/pivipi/physics/Physics.java | 36 ++++++++++--- 7 files changed, 131 insertions(+), 27 deletions(-) create mode 100644 src/main/java/net/pivipi/entity/AABB.java create mode 100644 src/main/java/net/pivipi/entity/PhysicsEntity.java diff --git a/src/main/java/net/pivipi/ball/Ball.java b/src/main/java/net/pivipi/ball/Ball.java index 11f3055..48f6e96 100644 --- a/src/main/java/net/pivipi/ball/Ball.java +++ b/src/main/java/net/pivipi/ball/Ball.java @@ -1,15 +1,15 @@ package net.pivipi.ball; import net.minestom.server.coordinate.Vec; -import net.minestom.server.entity.Entity; import net.minestom.server.entity.EntityType; import net.minestom.server.entity.Player; import net.minestom.server.entity.metadata.other.FallingBlockMeta; import net.minestom.server.instance.block.Block; +import net.pivipi.entity.PhysicsEntity; import net.pivipi.game.Stadium; import net.pivipi.physics.Physics; -public class Ball extends Entity { +public class Ball extends PhysicsEntity { private long lastTick; private Player holder; diff --git a/src/main/java/net/pivipi/ball/BallKicker.java b/src/main/java/net/pivipi/ball/BallKicker.java index d140466..98ccbc8 100644 --- a/src/main/java/net/pivipi/ball/BallKicker.java +++ b/src/main/java/net/pivipi/ball/BallKicker.java @@ -77,8 +77,7 @@ public class BallKicker { // TODO apply physics settings here private void onSwing(PlayerHandAnimationEvent event) { Player player = event.getPlayer(); - CollisionData collisionData = new CollisionData(); - Collision.pushOutside(player, stadium.ball, false, collisionData); + CollisionData collisionData = Collision.pushOutside(player, stadium.ball, false); double distance = collisionData.distance.withY(0).distance(0, 0, 0); if (collisionData.distance.y() < verticalReach && distance < reach) { diff --git a/src/main/java/net/pivipi/entity/AABB.java b/src/main/java/net/pivipi/entity/AABB.java new file mode 100644 index 0000000..bcb9705 --- /dev/null +++ b/src/main/java/net/pivipi/entity/AABB.java @@ -0,0 +1,54 @@ +package net.pivipi.entity; + +import net.minestom.server.coordinate.Vec; + +public class AABB { + Vec min, max; + Vec velocity; + + public AABB(Vec min, Vec max, Vec velocity) { + this.min = min; + this.max = max; + this.velocity = velocity; + } + + /** + * gets the position of the lower corner + * @return + */ + public Vec getMin() { + return min; + } + + /** + * gets the position of the lower corner + velocity + * @return + */ + public Vec getMinSwept() { + return min.add(velocity); + } + + /** + * gets the position of the upper corner + * @return + */ + public Vec getMax() { + return min; + } + + /** + * gets the position of the upper corner + velocity + * @return + */ + public Vec getMaxSwept() { + return max.add(velocity); + } + + /** + * gets the velocity that is blocks per second + * @return + */ + public Vec getVelocity() { + return velocity; + } +} diff --git a/src/main/java/net/pivipi/entity/PhysicsEntity.java b/src/main/java/net/pivipi/entity/PhysicsEntity.java new file mode 100644 index 0000000..f45fe2c --- /dev/null +++ b/src/main/java/net/pivipi/entity/PhysicsEntity.java @@ -0,0 +1,21 @@ +package net.pivipi.entity; + +import org.jetbrains.annotations.NotNull; + +import net.minestom.server.coordinate.Vec; +import net.minestom.server.entity.Entity; +import net.minestom.server.entity.EntityType; + +public class PhysicsEntity extends Entity { + + public PhysicsEntity(@NotNull EntityType entityType) { + super(entityType); + // TODO Auto-generated constructor stub + } + + public AABB getAabb() { + Vec min = this.getPosition().sub(this.getBoundingBox().width() / 2, 0, this.getBoundingBox().depth() / 2).asVec(); + Vec max = this.getPosition().add(this.getBoundingBox().width() / 2, this.getBoundingBox().height(), this.getBoundingBox().depth() / 2).asVec(); + return new AABB(min, max, this.velocity); + } +} diff --git a/src/main/java/net/pivipi/physics/Collision.java b/src/main/java/net/pivipi/physics/Collision.java index f6831f1..30b5183 100644 --- a/src/main/java/net/pivipi/physics/Collision.java +++ b/src/main/java/net/pivipi/physics/Collision.java @@ -8,6 +8,14 @@ import net.minestom.server.coordinate.Vec; import net.minestom.server.entity.Entity; public class Collision { + /** + * + * @param pos static object's pos + * @param boundingBox static object's bounding box + * @param moving moving entity + * @param movement moving entity movement + * @return + */ private static CollisionData willCollide(Pos pos, BoundingBox boundingBox, Entity moving, Vec movement) { SweepResult sweepResult = new SweepResult(1, 0, 0, 0, null, 0, 0, 0); boolean collides = boundingBox.intersectBoxSwept(moving.getPosition(), movement, pos, moving.getBoundingBox(), sweepResult); @@ -43,6 +51,10 @@ public class Collision { return willCollide(new Pos(Double.MIN_VALUE, 0, Double.MIN_VALUE), new BoundingBox(Double.MAX_VALUE, 64, Double.MAX_VALUE), moving, movement); } + public static CollisionData willCollideWithBlock(Pos blockPos, Entity moving, Vec movement) { + return willCollide(blockPos, new BoundingBox(1, 1, 1), moving, movement); + } + public static boolean collidesWithEntity(Entity entity1, Entity entity2) { return entity1.getBoundingBox().intersectEntity(entity1.getPosition(), entity2); } @@ -61,8 +73,8 @@ public class Collision { * @param pushed the entity that's being pushed like a ball * @return offset you must apply to push the entity outside, null if doesn't collide */ - public static Vec pushOutside(Entity pusher, Entity pushed, boolean y, CollisionData collisionData) { - return pushOutside(pusher.getBoundingBox(), pusher.getPosition(), pushed, y, collisionData); + public static CollisionData pushOutside(Entity pusher, Entity pushed, boolean y) { + return pushOutside(pusher.getBoundingBox(), pusher.getPosition(), pushed, y); } /** @@ -71,8 +83,8 @@ public class Collision { * @param pushed the entity that's being pushed like a ball * @return offset you must apply to push the entity outside, null if doesn't collide */ - public static Vec pushOutside(Pos blockPos, Entity pushed, boolean y, CollisionData collisionData) { - return pushOutside(new BoundingBox(1, 1, 1), blockPos, pushed, y, collisionData); + public static CollisionData pushOutside(Pos blockPos, Entity pushed, boolean y) { + return pushOutside(new BoundingBox(1, 1, 1), blockPos, pushed, y); } @@ -130,10 +142,9 @@ public class Collision { * @param pusherBox the entity that's pushing like a player or a block, its bounding box * @param pusherPos the position, bottom center * @param pushed the entity that's being pushed like a ball - * @param collisionData puts data in this object - * @return offset you must apply to push the entity outside, null if doesn't collide + * @return collision data */ - private static Vec pushOutside(BoundingBox pusherBox, Pos pusherPos, Entity pushed, boolean y, CollisionData collisionData) { + private static CollisionData pushOutside(BoundingBox pusherBox, Pos pusherPos, Entity pushed, boolean y) { double ballXSize = pushed.getBoundingBox().width(); double playerXSize = pusherBox.width(); double ballZSize = pushed.getBoundingBox().depth(); @@ -148,9 +159,8 @@ public class Collision { Pos playerPos = playerCenterPos.sub(playerXSize / 2, 0, playerZSize / 2); Vec ballDistance = ballCenterPos.sub(playerCenterPos).asVec(); - if (collisionData != null) { - collisionData.distance = ballDistance; - } + CollisionData collisionData = new CollisionData(); + collisionData.distance = ballDistance; double diffX = ballDistance.x() > 0 ? ballPos.x() - (playerPos.x() + playerXSize) @@ -180,12 +190,8 @@ public class Collision { offset = newBallOffset.mul(1, 0, 0); } - if (collisionData != null) { - collisionData.distance = ballDistance; - collisionData.offset = offset; - } - - return offset; + collisionData.offset = offset; + return collisionData; } } diff --git a/src/main/java/net/pivipi/physics/CollisionData.java b/src/main/java/net/pivipi/physics/CollisionData.java index ca26f35..613eaa0 100644 --- a/src/main/java/net/pivipi/physics/CollisionData.java +++ b/src/main/java/net/pivipi/physics/CollisionData.java @@ -29,7 +29,7 @@ public class CollisionData { public Vec collidedPosition; /** - * I don't know what this is but it looks useful (only when swept) + * the direction and speed where an object should bounce (only when swept) */ public Vec normal; diff --git a/src/main/java/net/pivipi/physics/Physics.java b/src/main/java/net/pivipi/physics/Physics.java index 07900aa..2e4fe81 100644 --- a/src/main/java/net/pivipi/physics/Physics.java +++ b/src/main/java/net/pivipi/physics/Physics.java @@ -5,10 +5,11 @@ import java.util.Set; import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Vec; -import net.minestom.server.entity.Entity; import net.minestom.server.entity.Player; import net.minestom.server.network.packet.server.play.ParticlePacket; import net.minestom.server.particle.Particle; +import net.pivipi.entity.AABB; +import net.pivipi.entity.PhysicsEntity; import net.pivipi.game.PhysicsSettings; public class Physics { @@ -23,10 +24,10 @@ public class Physics { private Vec velocity = new Vec(0, 0, 0); - private final Entity entity; + private final PhysicsEntity entity; private int p; - public Physics(Entity entity) { + public Physics(PhysicsEntity entity) { this.entity = entity; } @@ -58,25 +59,48 @@ public class Physics { velocity = velocity.mul(1 - (settings.groundFriction * delta), -settings.blockBounciness, 1 - (settings.groundFriction * delta)); } else { for (Player player : players) { - CollisionData collisionData = new CollisionData(); - Vec offset = Collision.pushOutside(player, entity, false, collisionData); // TODO predict the collision + CollisionData collisionData = Collision.pushOutside(player, entity, false); // TODO predict the collision - if (offset != null) { + if (collisionData.offset != null) { collisionData.entity = player; collisions.add(collisionData); } } + + AABB aabb = entity.getAabb(); + int minX = aabb.getMin().blockX(); + int minY = aabb.getMin().blockY(); + int minZ = aabb.getMin().blockZ(); + int maxX = aabb.getMax().blockX(); + int maxY = aabb.getMax().blockY(); + int maxZ = aabb.getMax().blockZ(); + for (int x=minX; x<=maxX; x++) { + for (int y=minY; y<=maxY; y++) { + for (int z=minZ; z<=maxZ; z++) { + if (entity.getInstance().getBlock(x, y, z).isSolid()) { + CollisionData cd = Collision.pushOutside(new Pos(x, y, z), entity, true); + collisions.add(cd); + } + } + } + } } for (CollisionData collisionData : collisions) { if (collisionData.entity instanceof Player) { handlePlayerTouch((Player) collisionData.entity, collisionData); + } else { + handleBlockTouch(collisionData); } } return velocity; } + private void handleBlockTouch(CollisionData collisionData) { + + } + private void handlePlayerTouch(Player player, CollisionData collisionData) { Vec offset = collisionData.offset;