mirror of
https://github.com/Minestom/Minestom.git
synced 2025-01-07 17:08:30 +01:00
Fix math, improve physics performance
This commit is contained in:
parent
5adbc287b3
commit
6e0202c33b
@ -32,21 +32,22 @@ public class CollisionUtils {
|
|||||||
@NotNull Vector velocityOut) {
|
@NotNull Vector velocityOut) {
|
||||||
// TODO handle collisions with nearby entities (should it be done here?)
|
// TODO handle collisions with nearby entities (should it be done here?)
|
||||||
final Instance instance = entity.getInstance();
|
final Instance instance = entity.getInstance();
|
||||||
|
final Chunk originChunk = entity.getChunk();
|
||||||
final Position currentPosition = entity.getPosition();
|
final Position currentPosition = entity.getPosition();
|
||||||
final BoundingBox boundingBox = entity.getBoundingBox();
|
final BoundingBox boundingBox = entity.getBoundingBox();
|
||||||
|
|
||||||
Vector intermediaryPosition = new Vector();
|
Vector intermediaryPosition = new Vector();
|
||||||
final boolean yCollision = stepAxis(instance, currentPosition.toVector(), Y_AXIS, deltaPosition.getY(),
|
final boolean yCollision = stepAxis(instance, originChunk, currentPosition.toVector(), Y_AXIS, deltaPosition.getY(),
|
||||||
intermediaryPosition,
|
intermediaryPosition,
|
||||||
deltaPosition.getY() > 0 ? boundingBox.getTopFace() : boundingBox.getBottomFace()
|
deltaPosition.getY() > 0 ? boundingBox.getTopFace() : boundingBox.getBottomFace()
|
||||||
);
|
);
|
||||||
|
|
||||||
final boolean xCollision = stepAxis(instance, intermediaryPosition, X_AXIS, deltaPosition.getX(),
|
final boolean xCollision = stepAxis(instance, originChunk, intermediaryPosition, X_AXIS, deltaPosition.getX(),
|
||||||
intermediaryPosition,
|
intermediaryPosition,
|
||||||
deltaPosition.getX() < 0 ? boundingBox.getLeftFace() : boundingBox.getRightFace()
|
deltaPosition.getX() < 0 ? boundingBox.getLeftFace() : boundingBox.getRightFace()
|
||||||
);
|
);
|
||||||
|
|
||||||
final boolean zCollision = stepAxis(instance, intermediaryPosition, Z_AXIS, deltaPosition.getZ(),
|
final boolean zCollision = stepAxis(instance, originChunk, intermediaryPosition, Z_AXIS, deltaPosition.getZ(),
|
||||||
intermediaryPosition,
|
intermediaryPosition,
|
||||||
deltaPosition.getZ() > 0 ? boundingBox.getBackFace() : boundingBox.getFrontFace()
|
deltaPosition.getZ() > 0 ? boundingBox.getBackFace() : boundingBox.getFrontFace()
|
||||||
);
|
);
|
||||||
@ -80,7 +81,11 @@ public class CollisionUtils {
|
|||||||
* @param corners the corners to check against
|
* @param corners the corners to check against
|
||||||
* @return true if a collision has been found
|
* @return true if a collision has been found
|
||||||
*/
|
*/
|
||||||
private static boolean stepAxis(Instance instance, Vector startPosition, Vector axis, double stepAmount, Vector positionOut, Vector... corners) {
|
private static boolean stepAxis(Instance instance,
|
||||||
|
Chunk originChunk,
|
||||||
|
Vector startPosition, Vector axis,
|
||||||
|
double stepAmount, Vector positionOut,
|
||||||
|
Vector... corners) {
|
||||||
positionOut.copy(startPosition);
|
positionOut.copy(startPosition);
|
||||||
if (corners.length == 0)
|
if (corners.length == 0)
|
||||||
return false; // avoid degeneracy in following computations
|
return false; // avoid degeneracy in following computations
|
||||||
@ -99,7 +104,7 @@ public class CollisionUtils {
|
|||||||
// used to determine if 'remainingLength' should be used
|
// used to determine if 'remainingLength' should be used
|
||||||
boolean collisionFound = false;
|
boolean collisionFound = false;
|
||||||
for (int i = 0; i < Math.abs(blockLength); i++) {
|
for (int i = 0; i < Math.abs(blockLength); i++) {
|
||||||
if (!stepOnce(instance, axis, sign, cornersCopy, cornerPositions)) {
|
if (!stepOnce(instance, originChunk, axis, sign, cornersCopy, cornerPositions)) {
|
||||||
collisionFound = true;
|
collisionFound = true;
|
||||||
}
|
}
|
||||||
if (collisionFound) {
|
if (collisionFound) {
|
||||||
@ -111,7 +116,7 @@ public class CollisionUtils {
|
|||||||
if (!collisionFound) {
|
if (!collisionFound) {
|
||||||
Vector direction = new Vector();
|
Vector direction = new Vector();
|
||||||
direction.copy(axis);
|
direction.copy(axis);
|
||||||
collisionFound = !stepOnce(instance, direction, remainingLength, cornersCopy, cornerPositions);
|
collisionFound = !stepOnce(instance, originChunk, direction, remainingLength, cornersCopy, cornerPositions);
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the corner which moved the least
|
// find the corner which moved the least
|
||||||
@ -138,7 +143,9 @@ public class CollisionUtils {
|
|||||||
* @param cornerPositions the corners, converted to BlockPosition (mutable)
|
* @param cornerPositions the corners, converted to BlockPosition (mutable)
|
||||||
* @return false if this method encountered a collision
|
* @return false if this method encountered a collision
|
||||||
*/
|
*/
|
||||||
private static boolean stepOnce(Instance instance, Vector axis, double amount, Vector[] cornersCopy, BlockPosition[] cornerPositions) {
|
private static boolean stepOnce(Instance instance,
|
||||||
|
Chunk originChunk,
|
||||||
|
Vector axis, double amount, Vector[] cornersCopy, BlockPosition[] cornerPositions) {
|
||||||
final double sign = Math.signum(amount);
|
final double sign = Math.signum(amount);
|
||||||
for (int cornerIndex = 0; cornerIndex < cornersCopy.length; cornerIndex++) {
|
for (int cornerIndex = 0; cornerIndex < cornersCopy.length; cornerIndex++) {
|
||||||
Vector corner = cornersCopy[cornerIndex];
|
Vector corner = cornersCopy[cornerIndex];
|
||||||
@ -148,10 +155,13 @@ public class CollisionUtils {
|
|||||||
blockPos.setY((int) Math.floor(corner.getY()));
|
blockPos.setY((int) Math.floor(corner.getY()));
|
||||||
blockPos.setZ((int) Math.floor(corner.getZ()));
|
blockPos.setZ((int) Math.floor(corner.getZ()));
|
||||||
|
|
||||||
final Chunk chunk = instance.getChunkAt(blockPos);
|
Chunk chunk = originChunk;
|
||||||
if (!ChunkUtils.isLoaded(chunk)) {
|
if (!ChunkUtils.same(originChunk, blockPos.getX(), blockPos.getZ())) {
|
||||||
// Collision at chunk border
|
chunk = instance.getChunkAt(blockPos);
|
||||||
return false;
|
if (!ChunkUtils.isLoaded(chunk)) {
|
||||||
|
// Collision at chunk border
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final short blockStateId = chunk.getBlockStateId(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
final short blockStateId = chunk.getBlockStateId(blockPos.getX(), blockPos.getY(), blockPos.getZ());
|
||||||
|
@ -85,17 +85,17 @@ public final class ChunkUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean same(@NotNull Chunk chunk, double x, double z) {
|
public static boolean same(@NotNull Chunk chunk, double x, double z) {
|
||||||
final int chunkX = ChunkUtils.getChunkCoordinate(x);
|
final int chunkX = getChunkCoordinate(x);
|
||||||
final int chunkZ = ChunkUtils.getChunkCoordinate(z);
|
final int chunkZ = getChunkCoordinate(z);
|
||||||
return chunk.getChunkX() != chunkX || chunk.getChunkZ() != chunkZ;
|
return chunk.getChunkX() == chunkX && chunk.getChunkZ() == chunkZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean same(@NotNull Position pos1, @NotNull Position pos2) {
|
public static boolean same(@NotNull Position pos1, @NotNull Position pos2) {
|
||||||
final int x1 = ChunkUtils.getChunkCoordinate(pos1.getX());
|
final int x1 = getChunkCoordinate(pos1.getX());
|
||||||
final int z1 = ChunkUtils.getChunkCoordinate(pos1.getZ());
|
final int z1 = getChunkCoordinate(pos1.getZ());
|
||||||
final int x2 = ChunkUtils.getChunkCoordinate(pos2.getX());
|
final int x2 = getChunkCoordinate(pos2.getX());
|
||||||
final int z2 = ChunkUtils.getChunkCoordinate(pos2.getZ());
|
final int z2 = getChunkCoordinate(pos2.getZ());
|
||||||
return x1 != x2 || z1 != z2;
|
return x1 == x2 && z1 == z2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user