Pick a side

- Ponder's Identify mode now supports blocks with ray-specific pick block results
This commit is contained in:
simibubi 2022-10-07 19:33:10 +02:00
parent c4eb62c862
commit 7cd149ba06
2 changed files with 16 additions and 9 deletions

View file

@ -35,6 +35,7 @@ import com.simibubi.create.foundation.ponder.ui.PonderUI;
import com.simibubi.create.foundation.render.ForcedDiffuseState;
import com.simibubi.create.foundation.render.SuperRenderTypeBuffer;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.BlockFace;
import com.simibubi.create.foundation.utility.Pair;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
@ -134,14 +135,14 @@ public class PonderScene {
}
public Pair<ItemStack, BlockPos> rayTraceScene(Vec3 from, Vec3 to) {
MutableObject<Pair<WorldSectionElement, BlockPos>> nearestHit = new MutableObject<>();
MutableObject<Pair<WorldSectionElement, Pair<Vec3, BlockFace>>> nearestHit = new MutableObject<>();
MutableDouble bestDistance = new MutableDouble(0);
forEach(WorldSectionElement.class, wse -> {
wse.resetSelectedBlock();
if (!wse.isVisible())
return;
Pair<Vec3, BlockPos> rayTrace = wse.rayTrace(world, from, to);
Pair<Vec3, BlockFace> rayTrace = wse.rayTrace(world, from, to);
if (rayTrace == null)
return;
double distanceTo = rayTrace.getFirst()
@ -149,15 +150,20 @@ public class PonderScene {
if (nearestHit.getValue() != null && distanceTo >= bestDistance.getValue())
return;
nearestHit.setValue(Pair.of(wse, rayTrace.getSecond()));
nearestHit.setValue(Pair.of(wse, rayTrace));
bestDistance.setValue(distanceTo);
});
if (nearestHit.getValue() == null)
return Pair.of(ItemStack.EMPTY, null);
BlockPos selectedPos = nearestHit.getValue()
Pair<Vec3, BlockFace> selectedHit = nearestHit.getValue()
.getSecond();
BlockPos selectedPos = selectedHit.getSecond()
.getPos();
Direction selectedFace = selectedHit.getSecond()
.getFace();
Vec3 selectedVec = selectedHit.getFirst();
BlockPos origin = new BlockPos(basePlateOffsetX, 0, basePlateOffsetZ);
if (!world.getBounds()
@ -176,9 +182,9 @@ public class PonderScene {
.getFirst()
.selectBlock(selectedPos);
BlockState blockState = world.getBlockState(selectedPos);
ItemStack pickBlock = blockState.getCloneItemStack(
new BlockHitResult(VecHelper.getCenterOf(selectedPos), Direction.UP, selectedPos, true), world, selectedPos,
Minecraft.getInstance().player);
ItemStack pickBlock =
blockState.getCloneItemStack(new BlockHitResult(selectedVec, selectedFace, selectedPos, true), world,
selectedPos, Minecraft.getInstance().player);
return Pair.of(pickBlock, selectedPos);
}

View file

@ -26,6 +26,7 @@ import com.simibubi.create.foundation.render.SuperByteBufferCache;
import com.simibubi.create.foundation.render.SuperRenderTypeBuffer;
import com.simibubi.create.foundation.render.TileEntityRenderHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.BlockFace;
import com.simibubi.create.foundation.utility.Pair;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.utility.outliner.AABBOutline;
@ -181,7 +182,7 @@ public class WorldSectionElement extends AnimatedSceneElement {
BlockPos worldPos;
}
public Pair<Vec3, BlockPos> rayTrace(PonderWorld world, Vec3 source, Vec3 target) {
public Pair<Vec3, BlockFace> rayTrace(PonderWorld world, Vec3 source, Vec3 target) {
world.setMask(this.section);
Vec3 transformedTarget = reverseTransformVec(target);
BlockHitResult rayTraceBlocks = world.clip(new ClipContext(reverseTransformVec(source), transformedTarget,
@ -199,7 +200,7 @@ public class WorldSectionElement extends AnimatedSceneElement {
/ source.subtract(target)
.lengthSqr();
Vec3 actualHit = VecHelper.lerp((float) t, target, source);
return Pair.of(actualHit, rayTraceBlocks.getBlockPos());
return Pair.of(actualHit, new BlockFace(rayTraceBlocks.getBlockPos(), rayTraceBlocks.getDirection()));
}
private Vec3 reverseTransformVec(Vec3 in) {