mirror of https://github.com/YatopiaMC/Yatopia.git
219 lines
11 KiB
Diff
219 lines
11 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Paul Sauve <paul@technove.co>
|
|
Date: Sat, 31 Oct 2020 18:43:02 -0500
|
|
Subject: [PATCH] Strip raytracing for EntityLiving#hasLineOfSight
|
|
|
|
The IBlockAccess#rayTrace method is very wasteful in both allocations,
|
|
and in logic. While EntityLiving#hasLineOfSight provides static
|
|
parameters for collisions with blocks and fluids, the method still does
|
|
a lot of dynamic checks for both of these, which result in extra work.
|
|
As well, since the fluid collision option is set to NONE, the entire
|
|
fluid collision system is completely unneeded, yet used anyways.
|
|
|
|
Airplane
|
|
Copyright (C) 2020 Technove LLC
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
diff --git a/src/main/java/net/minecraft/util/MathHelper.java b/src/main/java/net/minecraft/util/MathHelper.java
|
|
index cc566784c7dd21cc2c44e0f351347f657e57ddcf..e9e7fcf2b63febe2a7d055826fabb86bc13a5cf3 100644
|
|
--- a/src/main/java/net/minecraft/util/MathHelper.java
|
|
+++ b/src/main/java/net/minecraft/util/MathHelper.java
|
|
@@ -240,6 +240,7 @@ public class MathHelper {
|
|
return f - (float) d(f);
|
|
}
|
|
|
|
+ public static double getDecimals(double num) { return h(num); } // Airplane
|
|
public static double h(double d0) {
|
|
return d0 - (double) d(d0);
|
|
}
|
|
@@ -418,6 +419,7 @@ public class MathHelper {
|
|
return f1 + f * (f2 - f1);
|
|
}
|
|
|
|
+ public static double linearInterpolation(double value1, double value2, double amount) { return d(value1, value2, amount); } // Airplane - OBFHELPER
|
|
public static double d(double d0, double d1, double d2) {
|
|
return d1 + d0 * (d2 - d1);
|
|
}
|
|
@@ -434,6 +436,7 @@ public class MathHelper {
|
|
return d0 * d0 * d0 * (d0 * (d0 * 6.0D - 15.0D) + 10.0D);
|
|
}
|
|
|
|
+ public static int sign(double num) { return k(num); } // Airplane - OBFHELPER
|
|
public static int k(double d0) {
|
|
return d0 == 0.0D ? 0 : (d0 > 0.0D ? 1 : -1);
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/world/entity/EntityLiving.java b/src/main/java/net/minecraft/world/entity/EntityLiving.java
|
|
index 2ff3297fb8c0e4f8c969ba2727eecb7fe06525c4..56812a96b57586d91c0f218f4720807e2d957627 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/EntityLiving.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/EntityLiving.java
|
|
@@ -111,6 +111,7 @@ import net.minecraft.world.phys.AxisAlignedBB;
|
|
import net.minecraft.world.phys.MovingObjectPosition;
|
|
import net.minecraft.world.phys.MovingObjectPositionEntity;
|
|
import net.minecraft.world.phys.Vec3D;
|
|
+import net.minecraft.world.phys.shapes.VoxelShapeCollision;
|
|
import net.minecraft.world.scores.ScoreboardTeam;
|
|
import org.apache.logging.log4j.Logger;
|
|
|
|
@@ -3102,7 +3103,10 @@ public abstract class EntityLiving extends Entity {
|
|
Vec3D vec3d1 = new Vec3D(entity.locX(), entity.getHeadY(), entity.locZ());
|
|
|
|
// Paper - diff on change - used in CraftLivingEntity#hasLineOfSight(Location) and CraftWorld#lineOfSightExists
|
|
- return this.world.rayTrace(new RayTrace(vec3d, vec3d1, RayTrace.BlockCollisionOption.COLLIDER, RayTrace.FluidCollisionOption.NONE, this)).getType() == MovingObjectPosition.EnumMovingObjectType.MISS;
|
|
+ // Airplane start - use direct method
|
|
+ //return this.world.rayTrace(new RayTrace(vec3d, vec3d1, RayTrace.BlockCollisionOption.COLLIDER, RayTrace.FluidCollisionOption.NONE, this)).getType() == MovingObjectPosition.EnumMovingObjectType.MISS;
|
|
+ return this.world.rayTraceDirect(vec3d, vec3d1, VoxelShapeCollision.a(this)) == MovingObjectPosition.EnumMovingObjectType.MISS;
|
|
+ // Airplane end
|
|
}
|
|
|
|
@Override
|
|
diff --git a/src/main/java/net/minecraft/world/level/IBlockAccess.java b/src/main/java/net/minecraft/world/level/IBlockAccess.java
|
|
index e612e1d30f76e217b1aa23488ab025adce048f57..6109d59c02d0c7877e213213c6aec6f8513ccc47 100644
|
|
--- a/src/main/java/net/minecraft/world/level/IBlockAccess.java
|
|
+++ b/src/main/java/net/minecraft/world/level/IBlockAccess.java
|
|
@@ -14,9 +14,11 @@ import net.minecraft.world.level.block.state.IBlockData;
|
|
import net.minecraft.world.level.material.Fluid;
|
|
import net.minecraft.world.level.material.Material;
|
|
import net.minecraft.world.phys.AxisAlignedBB;
|
|
+import net.minecraft.world.phys.MovingObjectPosition;
|
|
import net.minecraft.world.phys.MovingObjectPositionBlock;
|
|
import net.minecraft.world.phys.Vec3D;
|
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
|
+import net.minecraft.world.phys.shapes.VoxelShapeCollision;
|
|
|
|
public interface IBlockAccess {
|
|
|
|
@@ -56,6 +58,16 @@ public interface IBlockAccess {
|
|
return BlockPosition.a(axisalignedbb).map(this::getType);
|
|
}
|
|
|
|
+ // Airplane start - broken down variant of below rayTraceBlock, used by World#rayTraceDirect
|
|
+ default MovingObjectPosition.EnumMovingObjectType rayTraceBlockDirect(Vec3D vec3d, Vec3D vec3d1, BlockPosition blockposition, IBlockData iblockdata, VoxelShapeCollision voxelshapecoll) {
|
|
+ if (iblockdata.isAir()) return null; // Tuinity - optimise air cases
|
|
+ VoxelShape voxelshape = RayTrace.BlockCollisionOption.COLLIDER.get(iblockdata, this, blockposition, voxelshapecoll);
|
|
+ MovingObjectPositionBlock movingobjectpositionblock = this.rayTrace(vec3d, vec3d1, blockposition, voxelshape, iblockdata);
|
|
+
|
|
+ return movingobjectpositionblock == null ? null : movingobjectpositionblock.getType();
|
|
+ }
|
|
+ // Airplane end
|
|
+
|
|
// CraftBukkit start - moved block handling into separate method for use by Block#rayTrace
|
|
default MovingObjectPositionBlock rayTraceBlock(RayTrace raytrace1, BlockPosition blockposition) {
|
|
// Paper start - Prevent raytrace from loading chunks
|
|
diff --git a/src/main/java/net/minecraft/world/level/World.java b/src/main/java/net/minecraft/world/level/World.java
|
|
index cb8064df7e9f1b8b4d4292486e2193680d83663c..37da32675f0c00c793cd137c9a7305932cefb705 100644
|
|
--- a/src/main/java/net/minecraft/world/level/World.java
|
|
+++ b/src/main/java/net/minecraft/world/level/World.java
|
|
@@ -69,6 +69,8 @@ import net.minecraft.world.level.saveddata.maps.WorldMap;
|
|
import net.minecraft.world.level.storage.WorldData;
|
|
import net.minecraft.world.level.storage.WorldDataMutable;
|
|
import net.minecraft.world.phys.AxisAlignedBB;
|
|
+import net.minecraft.world.phys.MovingObjectPosition;
|
|
+import net.minecraft.world.phys.Vec3D;
|
|
import net.minecraft.world.phys.shapes.OperatorBoolean;
|
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
|
import net.minecraft.world.phys.shapes.VoxelShapeCollision;
|
|
@@ -385,6 +387,91 @@ public abstract class World implements GeneratorAccess, AutoCloseable {
|
|
return null;
|
|
}
|
|
|
|
+ // Airplane start - broken down method of raytracing for EntityLiving#hasLineOfSight, replaces IBlockAccess#rayTrace(RayTrace)
|
|
+ public MovingObjectPosition.EnumMovingObjectType rayTraceDirect(Vec3D vec3d, Vec3D vec3d1, VoxelShapeCollision voxelshapecoll) {
|
|
+ // most of this code comes from IBlockAccess#a(RayTrace, BiFunction, Function), but removes the needless functions
|
|
+ if (vec3d.equals(vec3d1)) {
|
|
+ return MovingObjectPosition.EnumMovingObjectType.MISS;
|
|
+ }
|
|
+
|
|
+ double endX = MathHelper.linearInterpolation(-1.0E-7D, vec3d1.x, vec3d.x);
|
|
+ double endY = MathHelper.linearInterpolation(-1.0E-7D, vec3d1.y, vec3d.y);
|
|
+ double endZ = MathHelper.linearInterpolation(-1.0E-7D, vec3d1.z, vec3d.z);
|
|
+
|
|
+ double startX = MathHelper.linearInterpolation(-1.0E-7D, vec3d.x, vec3d1.x);
|
|
+ double startY = MathHelper.linearInterpolation(-1.0E-7D, vec3d.y, vec3d1.y);
|
|
+ double startZ = MathHelper.linearInterpolation(-1.0E-7D, vec3d.z, vec3d1.z);
|
|
+
|
|
+ int currentX = MathHelper.floor(startX);
|
|
+ int currentY = MathHelper.floor(startY);
|
|
+ int currentZ = MathHelper.floor(startZ);
|
|
+
|
|
+ BlockPosition.MutableBlockPosition currentBlock = new BlockPosition.MutableBlockPosition(currentX, currentY, currentZ);
|
|
+
|
|
+ Chunk chunk = this.getChunkIfLoaded(currentBlock);
|
|
+ if (chunk == null) {
|
|
+ return MovingObjectPosition.EnumMovingObjectType.MISS;
|
|
+ }
|
|
+
|
|
+ MovingObjectPosition.EnumMovingObjectType initialCheck = this.rayTraceBlockDirect(vec3d, vec3d1, currentBlock, chunk.getType(currentBlock), voxelshapecoll);
|
|
+
|
|
+ if (initialCheck != null) {
|
|
+ return initialCheck;
|
|
+ }
|
|
+
|
|
+ double diffX = endX - startX;
|
|
+ double diffY = endY - startY;
|
|
+ double diffZ = endZ - startZ;
|
|
+
|
|
+ int xDirection = MathHelper.sign(diffX);
|
|
+ int yDirection = MathHelper.sign(diffY);
|
|
+ int zDirection = MathHelper.sign(diffZ);
|
|
+
|
|
+ double normalizedX = xDirection == 0 ? Double.MAX_VALUE : (double) xDirection / diffX;
|
|
+ double normalizedY = yDirection == 0 ? Double.MAX_VALUE : (double) yDirection / diffY;
|
|
+ double normalizedZ = zDirection == 0 ? Double.MAX_VALUE : (double) zDirection / diffZ;
|
|
+
|
|
+ double normalizedXDirection = normalizedX * (xDirection > 0 ? 1.0D - MathHelper.getDecimals(startX) : MathHelper.getDecimals(startX));
|
|
+ double normalizedYDirection = normalizedY * (yDirection > 0 ? 1.0D - MathHelper.getDecimals(startY) : MathHelper.getDecimals(startY));
|
|
+ double normalizedZDirection = normalizedZ * (zDirection > 0 ? 1.0D - MathHelper.getDecimals(startZ) : MathHelper.getDecimals(startZ));
|
|
+
|
|
+ MovingObjectPosition.EnumMovingObjectType result;
|
|
+
|
|
+ do {
|
|
+ if (normalizedXDirection > 1.0D && normalizedYDirection > 1.0D && normalizedZDirection > 1.0D) {
|
|
+ return MovingObjectPosition.EnumMovingObjectType.MISS;
|
|
+ }
|
|
+
|
|
+ if (normalizedXDirection < normalizedYDirection) {
|
|
+ if (normalizedXDirection < normalizedZDirection) {
|
|
+ currentX += xDirection;
|
|
+ normalizedXDirection += normalizedX;
|
|
+ } else {
|
|
+ currentZ += zDirection;
|
|
+ normalizedZDirection += normalizedZ;
|
|
+ }
|
|
+ } else if (normalizedYDirection < normalizedZDirection) {
|
|
+ currentY += yDirection;
|
|
+ normalizedYDirection += normalizedY;
|
|
+ } else {
|
|
+ currentZ += zDirection;
|
|
+ normalizedZDirection += normalizedZ;
|
|
+ }
|
|
+
|
|
+ currentBlock.setValues(currentX, currentY, currentZ);
|
|
+ if (chunk.getPos().x != currentBlock.getX() >> 4 || chunk.getPos().z != currentBlock.getZ() >> 4) {
|
|
+ chunk = this.getChunkIfLoaded(currentBlock);
|
|
+ if (chunk == null) {
|
|
+ return MovingObjectPosition.EnumMovingObjectType.MISS;
|
|
+ }
|
|
+ }
|
|
+ result = this.rayTraceBlockDirect(vec3d, vec3d1, currentBlock, chunk.getType(currentBlock), voxelshapecoll);
|
|
+ } while (result == null);
|
|
+
|
|
+ return result;
|
|
+ }
|
|
+ // Airplane end
|
|
+
|
|
public static boolean isValidLocation(BlockPosition blockposition) {
|
|
return blockposition.isValidLocation(); // Paper - use better/optimized check
|
|
}
|