mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-14 06:24:29 +01:00
Better bounding boxes for bearings.
- Fix bug causing entities to slip off the far corners of bearing contraptions. - This was already implemented for BearingLighter.java, now it's promoted to Contraption.java. - Promote anonymous WrappedWorld in Contraption.java to inner class.
This commit is contained in:
parent
b7f0fe9b10
commit
c54d80a161
@ -20,6 +20,9 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.render.backend.instancing.IFlywheelWorld;
|
||||||
|
import com.simibubi.create.foundation.render.backend.light.GridAlignedBB;
|
||||||
|
import com.simibubi.create.foundation.utility.*;
|
||||||
import org.apache.commons.lang3.tuple.MutablePair;
|
import org.apache.commons.lang3.tuple.MutablePair;
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
@ -53,12 +56,6 @@ import com.simibubi.create.content.logistics.block.redstone.RedstoneContactBlock
|
|||||||
import com.simibubi.create.foundation.config.AllConfigs;
|
import com.simibubi.create.foundation.config.AllConfigs;
|
||||||
import com.simibubi.create.foundation.fluid.CombinedTankWrapper;
|
import com.simibubi.create.foundation.fluid.CombinedTankWrapper;
|
||||||
import com.simibubi.create.foundation.render.backend.light.EmptyLighter;
|
import com.simibubi.create.foundation.render.backend.light.EmptyLighter;
|
||||||
import com.simibubi.create.foundation.utility.BlockFace;
|
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
|
||||||
import com.simibubi.create.foundation.utility.NBTHelper;
|
|
||||||
import com.simibubi.create.foundation.utility.NBTProcessors;
|
|
||||||
import com.simibubi.create.foundation.utility.UniqueLinkedList;
|
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
|
||||||
import com.simibubi.create.foundation.utility.worldWrappers.WrappedWorld;
|
import com.simibubi.create.foundation.utility.worldWrappers.WrappedWorld;
|
||||||
|
|
||||||
import net.minecraft.block.AbstractButtonBlock;
|
import net.minecraft.block.AbstractButtonBlock;
|
||||||
@ -85,7 +82,6 @@ import net.minecraft.state.properties.PistonType;
|
|||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.Direction.Axis;
|
import net.minecraft.util.Direction.Axis;
|
||||||
import net.minecraft.util.Direction.AxisDirection;
|
|
||||||
import net.minecraft.util.Rotation;
|
import net.minecraft.util.Rotation;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
@ -853,16 +849,7 @@ public abstract class Contraption {
|
|||||||
TileEntity te = TileEntity.create(tag);
|
TileEntity te = TileEntity.create(tag);
|
||||||
if (te == null)
|
if (te == null)
|
||||||
return;
|
return;
|
||||||
te.setLocation(new WrappedWorld(world) {
|
te.setLocation(new ContraptionTileWorld(world, te, info), te.getPos());
|
||||||
|
|
||||||
@Override
|
|
||||||
public BlockState getBlockState(BlockPos pos) {
|
|
||||||
if (!pos.equals(te.getPos()))
|
|
||||||
return Blocks.AIR.getDefaultState();
|
|
||||||
return info.state;
|
|
||||||
}
|
|
||||||
|
|
||||||
}, te.getPos());
|
|
||||||
if (te instanceof KineticTileEntity)
|
if (te instanceof KineticTileEntity)
|
||||||
((KineticTileEntity) te).setSpeed(0);
|
((KineticTileEntity) te).setSpeed(0);
|
||||||
te.getBlockState();
|
te.getBlockState();
|
||||||
@ -1091,27 +1078,25 @@ public abstract class Contraption {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void expandBoundsAroundAxis(Axis axis) {
|
public void expandBoundsAroundAxis(Axis axis) {
|
||||||
AxisAlignedBB bb = bounds;
|
Set<BlockPos> blocks = getBlocks().keySet();
|
||||||
double maxXDiff = Math.max(bb.maxX - 1, -bb.minX);
|
|
||||||
double maxYDiff = Math.max(bb.maxY - 1, -bb.minY);
|
|
||||||
double maxZDiff = Math.max(bb.maxZ - 1, -bb.minZ);
|
|
||||||
double maxDiff = 0;
|
|
||||||
|
|
||||||
if (axis == Axis.X)
|
int radius = (int) (Math.ceil(Math.sqrt(getRadius(blocks, axis))));
|
||||||
maxDiff = Math.max(maxZDiff, maxYDiff);
|
|
||||||
if (axis == Axis.Y)
|
|
||||||
maxDiff = Math.max(maxZDiff, maxXDiff);
|
|
||||||
if (axis == Axis.Z)
|
|
||||||
maxDiff = Math.max(maxXDiff, maxYDiff);
|
|
||||||
|
|
||||||
Vec3d vec = new Vec3d(Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis)
|
GridAlignedBB betterBounds = GridAlignedBB.ofRadius(radius);
|
||||||
.getDirectionVec());
|
|
||||||
Vec3d planeByNormal = VecHelper.axisAlingedPlaneOf(vec);
|
GridAlignedBB contraptionBounds = GridAlignedBB.fromAABB(bounds);
|
||||||
Vec3d min = vec.mul(bb.minX, bb.minY, bb.minZ)
|
if (axis == Direction.Axis.X) {
|
||||||
.add(planeByNormal.scale(-maxDiff));
|
betterBounds.maxX = contraptionBounds.maxX;
|
||||||
Vec3d max = vec.mul(bb.maxX, bb.maxY, bb.maxZ)
|
betterBounds.minX = contraptionBounds.minX;
|
||||||
.add(planeByNormal.scale(maxDiff + 1));
|
} else if (axis == Direction.Axis.Y) {
|
||||||
bounds = new AxisAlignedBB(min, max);
|
betterBounds.maxY = contraptionBounds.maxY;
|
||||||
|
betterBounds.minY = contraptionBounds.minY;
|
||||||
|
} else if (axis == Direction.Axis.Z) {
|
||||||
|
betterBounds.maxZ = contraptionBounds.maxZ;
|
||||||
|
betterBounds.minZ = contraptionBounds.minZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
bounds = betterBounds.toAABB();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addExtraInventories(Entity entity) {}
|
public void addExtraInventories(Entity entity) {}
|
||||||
@ -1163,4 +1148,51 @@ public abstract class Contraption {
|
|||||||
return new EmptyLighter(this);
|
return new EmptyLighter(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static float getRadius(Set<BlockPos> blocks, Direction.Axis axis) {
|
||||||
|
switch (axis) {
|
||||||
|
case X:
|
||||||
|
return getMaxDistSqr(blocks, BlockPos::getY, BlockPos::getZ);
|
||||||
|
case Y:
|
||||||
|
return getMaxDistSqr(blocks, BlockPos::getX, BlockPos::getZ);
|
||||||
|
case Z:
|
||||||
|
return getMaxDistSqr(blocks, BlockPos::getX, BlockPos::getY);
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalStateException("Impossible axis");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float getMaxDistSqr(Set<BlockPos> blocks, Coordinate one, Coordinate other) {
|
||||||
|
float maxDistSq = -1;
|
||||||
|
for (BlockPos pos : blocks) {
|
||||||
|
float a = one.get(pos);
|
||||||
|
float b = other.get(pos);
|
||||||
|
|
||||||
|
float distSq = a * a + b * b;
|
||||||
|
|
||||||
|
|
||||||
|
if (distSq > maxDistSq) maxDistSq = distSq;
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxDistSq;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ContraptionTileWorld extends WrappedWorld implements IFlywheelWorld {
|
||||||
|
|
||||||
|
private final TileEntity te;
|
||||||
|
private final BlockInfo info;
|
||||||
|
|
||||||
|
public ContraptionTileWorld(World world, TileEntity te, BlockInfo info) {
|
||||||
|
super(world);
|
||||||
|
this.te = te;
|
||||||
|
this.info = info;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getBlockState(BlockPos pos) {
|
||||||
|
if (!pos.equals(te.getPos()))
|
||||||
|
return Blocks.AIR.getDefaultState();
|
||||||
|
return info.state;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
package com.simibubi.create.content.contraptions.components.structureMovement.bearing;
|
package com.simibubi.create.content.contraptions.components.structureMovement.bearing;
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionLighter;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionLighter;
|
||||||
import com.simibubi.create.foundation.render.backend.light.GridAlignedBB;
|
import com.simibubi.create.foundation.render.backend.light.GridAlignedBB;
|
||||||
|
|
||||||
import net.minecraft.util.Direction;
|
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
|
|
||||||
public class BearingLighter extends ContraptionLighter<BearingContraption> {
|
public class BearingLighter extends ContraptionLighter<BearingContraption> {
|
||||||
|
|
||||||
public BearingLighter(BearingContraption contraption) {
|
public BearingLighter(BearingContraption contraption) {
|
||||||
@ -16,60 +11,8 @@ public class BearingLighter extends ContraptionLighter<BearingContraption> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GridAlignedBB getContraptionBounds() {
|
public GridAlignedBB getContraptionBounds() {
|
||||||
Set<BlockPos> blocks = contraption.getBlocks().keySet();
|
GridAlignedBB bb = GridAlignedBB.fromAABB(contraption.bounds);
|
||||||
|
bb.translate(contraption.anchor);
|
||||||
Direction orientation = contraption.facing;
|
return bb;
|
||||||
Direction.Axis axis = orientation.getAxis();
|
|
||||||
|
|
||||||
int radius = (int) (Math.ceil(Math.sqrt(getRadius(blocks, axis))));
|
|
||||||
|
|
||||||
GridAlignedBB betterBounds = GridAlignedBB.ofRadius(radius);
|
|
||||||
|
|
||||||
GridAlignedBB contraptionBounds = GridAlignedBB.fromAABB(contraption.bounds);
|
|
||||||
if (axis == Direction.Axis.X) {
|
|
||||||
betterBounds.maxX = contraptionBounds.maxX;
|
|
||||||
betterBounds.minX = contraptionBounds.minX;
|
|
||||||
} else if (axis == Direction.Axis.Y) {
|
|
||||||
betterBounds.maxY = contraptionBounds.maxY;
|
|
||||||
betterBounds.minY = contraptionBounds.minY;
|
|
||||||
} else if (axis == Direction.Axis.Z) {
|
|
||||||
betterBounds.maxZ = contraptionBounds.maxZ;
|
|
||||||
betterBounds.minZ = contraptionBounds.minZ;
|
|
||||||
}
|
|
||||||
|
|
||||||
betterBounds.translate(contraption.anchor);
|
|
||||||
return betterBounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static float getRadius(Set<BlockPos> blocks, Direction.Axis axis) {
|
|
||||||
switch (axis) {
|
|
||||||
case X:
|
|
||||||
return getMaxDistSqr(blocks, BlockPos::getY, BlockPos::getZ);
|
|
||||||
case Y:
|
|
||||||
return getMaxDistSqr(blocks, BlockPos::getX, BlockPos::getZ);
|
|
||||||
case Z:
|
|
||||||
return getMaxDistSqr(blocks, BlockPos::getX, BlockPos::getY);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new IllegalStateException("Impossible axis");
|
|
||||||
}
|
|
||||||
|
|
||||||
private static float getMaxDistSqr(Set<BlockPos> blocks, Coordinate one, Coordinate other) {
|
|
||||||
float maxDistSq = -1;
|
|
||||||
for (BlockPos pos : blocks) {
|
|
||||||
float a = one.get(pos);
|
|
||||||
float b = other.get(pos);
|
|
||||||
|
|
||||||
float distSq = a * a + b * b;
|
|
||||||
|
|
||||||
|
|
||||||
if (distSq > maxDistSq) maxDistSq = distSq;
|
|
||||||
}
|
|
||||||
|
|
||||||
return maxDistSq;
|
|
||||||
}
|
|
||||||
|
|
||||||
private interface Coordinate {
|
|
||||||
float get(BlockPos from);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -269,6 +269,10 @@ public class GridAlignedBB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AxisAlignedBB toAABB() {
|
||||||
|
return toAABB(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.simibubi.create.foundation.utility;
|
||||||
|
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface Coordinate {
|
||||||
|
float get(BlockPos from);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user