Fast exit in CollisionUtils

This commit is contained in:
TheMode 2021-07-13 02:32:44 +02:00
parent 66bac1b532
commit fe28ba6f04

View File

@ -1,14 +1,13 @@
package net.minestom.server.collision; package net.minestom.server.collision;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.Entity; import net.minestom.server.entity.Entity;
import net.minestom.server.instance.Chunk; import net.minestom.server.instance.Chunk;
import net.minestom.server.instance.Instance; import net.minestom.server.instance.Instance;
import net.minestom.server.instance.WorldBorder; import net.minestom.server.instance.WorldBorder;
import net.minestom.server.instance.block.Block; import net.minestom.server.instance.block.Block;
import net.minestom.server.utils.chunk.ChunkUtils; import net.minestom.server.utils.chunk.ChunkUtils;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class CollisionUtils { public class CollisionUtils {
@ -30,21 +29,35 @@ public class CollisionUtils {
final Pos currentPosition = entity.getPosition(); final Pos currentPosition = entity.getPosition();
final BoundingBox boundingBox = entity.getBoundingBox(); final BoundingBox boundingBox = entity.getBoundingBox();
final StepResult yCollision = stepAxis(instance, originChunk, currentPosition.asVec(), Y_AXIS, deltaPosition.y(), Vec stepVec = currentPosition.asVec();
boolean xCheck = false, yCheck = false, zCheck = false;
if (deltaPosition.y() != 0) {
final StepResult yCollision = stepAxis(instance, originChunk, stepVec, Y_AXIS, deltaPosition.y(),
deltaPosition.y() > 0 ? boundingBox.getTopFace() : boundingBox.getBottomFace()); deltaPosition.y() > 0 ? boundingBox.getTopFace() : boundingBox.getBottomFace());
yCheck = yCollision.foundCollision;
stepVec = yCollision.newPosition;
}
final StepResult xCollision = stepAxis(instance, originChunk, yCollision.newPosition, X_AXIS, deltaPosition.x(), if (deltaPosition.x() != 0) {
final StepResult xCollision = stepAxis(instance, originChunk, stepVec, X_AXIS, deltaPosition.x(),
deltaPosition.x() < 0 ? boundingBox.getLeftFace() : boundingBox.getRightFace()); deltaPosition.x() < 0 ? boundingBox.getLeftFace() : boundingBox.getRightFace());
xCheck = xCollision.foundCollision;
stepVec = xCollision.newPosition;
}
final StepResult zCollision = stepAxis(instance, originChunk, xCollision.newPosition, Z_AXIS, deltaPosition.z(), if (deltaPosition.z() != 0) {
final StepResult zCollision = stepAxis(instance, originChunk, stepVec, Z_AXIS, deltaPosition.z(),
deltaPosition.z() > 0 ? boundingBox.getBackFace() : boundingBox.getFrontFace()); deltaPosition.z() > 0 ? boundingBox.getBackFace() : boundingBox.getFrontFace());
zCheck = zCollision.foundCollision;
stepVec = zCollision.newPosition;
}
return new PhysicsResult(currentPosition.withCoord(zCollision.newPosition), return new PhysicsResult(currentPosition.samePoint(stepVec) ? currentPosition : currentPosition.withCoord(stepVec),
deltaPosition.apply(((x, y, z) -> new Vec( new Vec(xCheck ? 0 : deltaPosition.x(),
xCollision.foundCollision ? 0 : x, yCheck ? 0 : deltaPosition.y(),
yCollision.foundCollision ? 0 : y, zCheck ? 0 : deltaPosition.z()),
zCollision.foundCollision ? 0 : z yCheck && deltaPosition.y() < 0);
))), yCollision.foundCollision && deltaPosition.y() < 0);
} }
/** /**
@ -69,7 +82,8 @@ 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 (collisionFound = stepOnce(instance, originChunk, axis, sign, corners)) break; collisionFound = stepOnce(instance, originChunk, axis, sign, corners);
if (collisionFound) break;
} }
// add remainingLength // add remainingLength
@ -102,27 +116,22 @@ public class CollisionUtils {
for (int cornerIndex = 0; cornerIndex < corners.length; cornerIndex++) { for (int cornerIndex = 0; cornerIndex < corners.length; cornerIndex++) {
final Vec originalCorner = corners[cornerIndex]; final Vec originalCorner = corners[cornerIndex];
final Vec newCorner = originalCorner.add(axis.mul(amount)); final Vec newCorner = originalCorner.add(axis.mul(amount));
final Chunk chunk = ChunkUtils.retrieve(instance, originChunk, newCorner);
Chunk chunk = ChunkUtils.retrieve(instance, originChunk, newCorner);
if (!ChunkUtils.isLoaded(chunk)) { if (!ChunkUtils.isLoaded(chunk)) {
// Collision at chunk border // Collision at chunk border
return true; return true;
} }
final Block block = chunk.getBlock(newCorner); final Block block = chunk.getBlock(newCorner);
// TODO: block collision boxes // TODO: block collision boxes
// TODO: for the moment, always consider a full block // TODO: for the moment, always consider a full block
if (block.isSolid()) { if (block.isSolid()) {
corners[cornerIndex] = originalCorner.apply(((x, y, z) -> new Vec( corners[cornerIndex] = new Vec(
Math.abs(axis.x()) > 10e-16 ? newCorner.blockX() - axis.x() * sign : x, Math.abs(axis.x()) > 10e-16 ? newCorner.blockX() - axis.x() * sign : originalCorner.x(),
Math.abs(axis.y()) > 10e-16 ? newCorner.blockY() - axis.y() * sign : y, Math.abs(axis.y()) > 10e-16 ? newCorner.blockY() - axis.y() * sign : originalCorner.y(),
Math.abs(axis.z()) > 10e-16 ? newCorner.blockZ() - axis.z() * sign : z Math.abs(axis.z()) > 10e-16 ? newCorner.blockZ() - axis.z() * sign : originalCorner.z());
)));
return true; return true;
} }
corners[cornerIndex] = newCorner; corners[cornerIndex] = newCorner;
} }
return false; return false;