Skip to content

Commit

Permalink
replace raycast with a non-loading cylinder
Browse files Browse the repository at this point in the history
Co-authored-by: HestiMae <[email protected]>
  • Loading branch information
sisby-folk and HestiMae committed Mar 27, 2024
1 parent 3597bc6 commit a271e2b
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 11 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ org.gradle.configureondemand=true
# Enable advanced multi-module optimizations (share tiny-remaper instance between projects)
fabric.loom.multiProjectOptimisation=true
# Mod Properties
baseVersion = 0.1.0-beta.16
baseVersion = 0.1.0-beta.17
defaultBranch = 1.20
branch = 1.20
5 changes: 3 additions & 2 deletions src/main/java/folk/sisby/surveyor/Surveyor.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import folk.sisby.surveyor.structure.WorldStructureSummary;
import folk.sisby.surveyor.terrain.WorldTerrainSummary;
import folk.sisby.surveyor.util.RaycastUtil;
import it.unimi.dsi.fastutil.longs.LongArraySet;
import it.unimi.dsi.fastutil.longs.LongSet;
import net.fabricmc.api.ModInitializer;
Expand Down Expand Up @@ -54,7 +55,7 @@ public static void checkStructureExploration(ServerWorld world, ServerPlayerEnti
boolean found = false;
if (start.getBoundingBox().contains(pos)) {
for (StructurePiece piece : start.getChildren()) {
if (piece.getBoundingBox().contains(pos)) {
if (piece.getBoundingBox().expand(1).contains(pos)) {
exploration.addStructure(world.getRegistryKey(), structureKey, startPos);
found = true;
break;
Expand All @@ -79,7 +80,7 @@ public void onInitialize() {
if ((world.getTime() & 7) != 0) return;
for (ServerPlayerEntity player : world.getPlayers()) {
checkStructureExploration(world, player, player.getBlockPos());
checkStructureExploration(world, player, BlockPos.ofFloored(player.raycast(((SurveyorPlayer) player).surveyor$getViewDistance() << 4, 1.0F, false).getPos()));
checkStructureExploration(world, player, BlockPos.ofFloored(RaycastUtil.playerViewRaycast(player, ((SurveyorPlayer) player).surveyor$getViewDistance()).getPos()));
}
}));
}
Expand Down
9 changes: 2 additions & 7 deletions src/main/java/folk/sisby/surveyor/SurveyorExploration.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,8 @@ default Multimap<RegistryKey<Structure>, ChunkPos> limitStructureKeySet(Registry
if (structures == null) {
keySet.clear();
} else {
keySet.asMap().forEach((key, starts) -> {
if (structures.containsKey(key)) {
starts.removeIf(pos -> !structures.get(key).contains(pos.toLong()));
} else {
starts.clear();
}
});
keySet.keySet().removeIf(key -> !structures.containsKey(key));
keySet.asMap().forEach((key, starts) -> starts.removeIf(pos -> !structures.get(key).contains(pos.toLong())));
}
return keySet;
}
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/folk/sisby/surveyor/util/MapUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.google.common.collect.Multimap;

import java.util.Collection;
import java.util.HashSet;
import java.util.Map;

public class MapUtil {
Expand All @@ -15,7 +16,7 @@ public static <K, V> Multimap<K, V> asMultiMap(Map<K, ? extends Collection<V>> a

public static <K, V> Multimap<K, V> keyMultiMap(Map<K, ? extends Map<V, ?>> asMap) {
Multimap<K, V> map = HashMultimap.create();
asMap.forEach((key, innerMap) -> map.putAll(key, innerMap.keySet()));
asMap.forEach((key, innerMap) -> map.putAll(key, new HashSet<>(innerMap.keySet())));
return map;
}
}
66 changes: 66 additions & 0 deletions src/main/java/folk/sisby/surveyor/util/RaycastUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package folk.sisby.surveyor.util;

import net.minecraft.block.BlockState;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.fluid.FluidState;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.hit.HitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import net.minecraft.world.RaycastContext;

public class RaycastUtil {
public static HitResult playerViewRaycast(PlayerEntity player, int renderDistance) {
// Calculate View Distance to Rendering Cylinder
Vec3d cameraPos = player.getCameraPosVec(1.0F);
double pitch = player.getPitch(1.0F);
double phi = -pitch * (float) (Math.PI / 180.0);
int blockRadius = renderDistance << 4;
double y = blockRadius * Math.tan(phi);
double distance;
double bottom = player.getWorld().getBottomY() - cameraPos.y;
double top = player.getWorld().getTopY() - cameraPos.y;
if (y < bottom || y > top) { // Distance To Circular Planes
distance = Math.abs(MathHelper.clamp(y, bottom, top) / Math.sin(phi));
} else { // Distance To Curved Surface
distance = Math.sqrt(y * y + blockRadius * blockRadius);
}

// Scale Cartesian Rotation Vector By Distance
Vec3d cameraRotation = player.getRotationVec(1.0F);
Vec3d endPos = cameraPos.add(cameraRotation.x * distance, cameraRotation.y * distance, cameraRotation.z * distance);
return BlockView.raycast(
cameraPos,
endPos,
new RaycastContext(
cameraPos, endPos, RaycastContext.ShapeType.OUTLINE, RaycastContext.FluidHandling.NONE, player
),
(innerContext, pos) -> {
ChunkPos chunkPos = new ChunkPos(pos);
if (!player.getWorld().getChunkManager().isChunkLoaded(chunkPos.x, chunkPos.z)) {
Vec3d vec3d = innerContext.getStart().subtract(innerContext.getEnd());
return BlockHitResult.createMissed(pos.toCenterPos(), Direction.getFacing(vec3d.x, vec3d.y, vec3d.z), pos);
}
BlockState blockState = player.getWorld().getBlockState(pos);
FluidState fluidState = player.getWorld().getFluidState(pos);
Vec3d vec3d = innerContext.getStart();
Vec3d vec3d2 = innerContext.getEnd();
VoxelShape voxelShape = innerContext.getBlockShape(blockState, player.getWorld(), pos);
BlockHitResult blockHitResult = player.getWorld().raycastBlock(vec3d, vec3d2, pos, voxelShape, blockState);
VoxelShape voxelShape2 = innerContext.getFluidShape(fluidState, player.getWorld(), pos);
BlockHitResult blockHitResult2 = voxelShape2.raycast(vec3d, vec3d2, pos);
double d = blockHitResult == null ? Double.MAX_VALUE : innerContext.getStart().squaredDistanceTo(blockHitResult.getPos());
double e = blockHitResult2 == null ? Double.MAX_VALUE : innerContext.getStart().squaredDistanceTo(blockHitResult2.getPos());
return d <= e ? blockHitResult : blockHitResult2;
}, innerContext -> {
Vec3d vec3d = innerContext.getStart().subtract(innerContext.getEnd());
return BlockHitResult.createMissed(innerContext.getEnd(), Direction.getFacing(vec3d.x, vec3d.y, vec3d.z), BlockPos.ofFloored(innerContext.getEnd()));
}
);
}
}

0 comments on commit a271e2b

Please sign in to comment.