Render Diagonal Items properly

- Fixed position offsets for diagonal belts for both rendering and item ejects
- Blocks render stacks similar to ground items with random horizontal offsets
- Items on diagonal belts now render at 45 degree angles
- Ejecting from a belt now has a minimum motion to prevent items from getting stuck
This commit is contained in:
simibubi 2019-11-16 10:54:19 +01:00
parent d85a8e2a49
commit 85042d460a
3 changed files with 51 additions and 9 deletions

View file

@ -9,6 +9,7 @@ import java.util.Random;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState; import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState;
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -19,6 +20,7 @@ import net.minecraft.nbt.ListNBT;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3i; import net.minecraft.util.math.Vec3i;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -362,8 +364,8 @@ public class BeltInventory {
public void eject(TransportedItemStack stack) { public void eject(TransportedItemStack stack) {
ItemStack ejected = stack.stack; ItemStack ejected = stack.stack;
Vec3d outPos = getVectorForOffset(stack.beltPosition); Vec3d outPos = getVectorForOffset(stack.beltPosition);
Vec3d outMotion = new Vec3d(belt.getBeltChainDirection()).scale(Math.abs(belt.getBeltMovementSpeed())).add(0, float movementSpeed = Math.max(Math.abs(belt.getBeltMovementSpeed()), 1 / 8f);
1 / 8f, 0); Vec3d outMotion = new Vec3d(belt.getBeltChainDirection()).scale(movementSpeed).add(0, 1 / 8f, 0);
outPos.add(outMotion.normalize()); outPos.add(outMotion.normalize());
ItemEntity entity = new ItemEntity(belt.getWorld(), outPos.x, outPos.y + 6 / 16f, outPos.z, ejected); ItemEntity entity = new ItemEntity(belt.getWorld(), outPos.x, outPos.y + 6 / 16f, outPos.z, ejected);
entity.setMotion(outMotion); entity.setMotion(outMotion);
@ -372,8 +374,16 @@ public class BeltInventory {
} }
private Vec3d getVectorForOffset(float offset) { private Vec3d getVectorForOffset(float offset) {
Slope slope = belt.getBlockState().get(BeltBlock.SLOPE);
int verticality = slope == Slope.DOWNWARD ? -1 : slope == Slope.UPWARD ? 1 : 0;
float verticalMovement = verticality;
if (offset < .5)
verticalMovement = 0;
verticalMovement = verticalMovement * (Math.min(offset, belt.beltLength - .5f) - .5f);
Vec3d vec = VecHelper.getCenterOf(belt.getPos()); Vec3d vec = VecHelper.getCenterOf(belt.getPos());
vec = vec.add(new Vec3d(belt.getBeltFacing().getDirectionVec()).scale(offset - .5f)); vec = vec.add(new Vec3d(belt.getBeltFacing().getDirectionVec()).scale(offset - .5f)).add(0, verticalMovement,
0);
return vec; return vec;
} }
@ -388,7 +398,11 @@ public class BeltInventory {
private BlockPos getPositionForOffset(int offset) { private BlockPos getPositionForOffset(int offset) {
BlockPos pos = belt.getPos(); BlockPos pos = belt.getPos();
Vec3i vec = belt.getBeltFacing().getDirectionVec(); Vec3i vec = belt.getBeltFacing().getDirectionVec();
return pos.add(offset * vec.getX(), offset * vec.getY(), offset * vec.getZ()); Slope slope = belt.getBlockState().get(BeltBlock.SLOPE);
int verticality = slope == Slope.DOWNWARD ? -1 : slope == Slope.UPWARD ? 1 : 0;
return pos.add(offset * vec.getX(), MathHelper.clamp(offset, 0, belt.beltLength - 1) * verticality,
offset * vec.getZ());
} }
private boolean movingPositive() { private boolean movingPositive() {

View file

@ -42,7 +42,7 @@ public class BeltShapes {
if (slope == Slope.VERTICAL) if (slope == Slope.VERTICAL)
return VERTICAL_STRAIGHT.get(axis); return VERTICAL_STRAIGHT.get(axis);
if (part != Part.MIDDLE) { if (part != Part.MIDDLE && part != Part.PULLEY) {
boolean upward = slope == Slope.UPWARD; boolean upward = slope == Slope.UPWARD;
if (part == Part.START) if (part == Part.START)
upward = !upward; upward = !upward;

View file

@ -1,5 +1,7 @@
package com.simibubi.create.modules.contraptions.relays.belt; package com.simibubi.create.modules.contraptions.relays.belt;
import java.util.Random;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.utility.IndependentShadowRenderer; import com.simibubi.create.foundation.utility.IndependentShadowRenderer;
@ -8,6 +10,7 @@ import com.simibubi.create.modules.contraptions.base.IRotate;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer.BlockModelSpinner; import com.simibubi.create.modules.contraptions.base.KineticTileEntityRenderer.BlockModelSpinner;
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope;
import com.simibubi.create.modules.contraptions.relays.belt.BeltInventory.TransportedItemStack; import com.simibubi.create.modules.contraptions.relays.belt.BeltInventory.TransportedItemStack;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
@ -44,13 +47,26 @@ public class BeltTileEntityRenderer extends TileEntityRenderer<BeltTileEntity> {
Vec3i directionVec = te.getBeltFacing().getDirectionVec(); Vec3i directionVec = te.getBeltFacing().getDirectionVec();
Vec3d beltStartOffset = new Vec3d(directionVec).scale(-.5).add(.5, 13 / 16f + .125f, .5); Vec3d beltStartOffset = new Vec3d(directionVec).scale(-.5).add(.5, 13 / 16f + .125f, .5);
GlStateManager.translated(x + beltStartOffset.x, y + beltStartOffset.y, z + beltStartOffset.z); GlStateManager.translated(x + beltStartOffset.x, y + beltStartOffset.y, z + beltStartOffset.z);
Slope slope = te.getBlockState().get(BeltBlock.SLOPE);
int verticality = slope == Slope.DOWNWARD ? -1 : slope == Slope.UPWARD ? 1 : 0;
boolean slopeAlongX = te.getBeltFacing().getAxis() == Axis.X;
for (TransportedItemStack transported : te.getInventory().items) { for (TransportedItemStack transported : te.getInventory().items) {
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
float offset = MathHelper.lerp(partialTicks, transported.prevBeltPosition, transported.beltPosition); float offset = MathHelper.lerp(partialTicks, transported.prevBeltPosition, transported.beltPosition);
float sideOffset = MathHelper.lerp(partialTicks, transported.prevSideOffset, transported.sideOffset); float sideOffset = MathHelper.lerp(partialTicks, transported.prevSideOffset, transported.sideOffset);
Vec3d offsetVec = new Vec3d(directionVec).scale(offset); float verticalMovement = verticality;
if (offset < .5)
verticalMovement = 0;
verticalMovement = verticalMovement * (Math.min(offset, te.beltLength - .5f) - .5f);
Vec3d offsetVec = new Vec3d(directionVec).scale(offset).add(0, verticalMovement, 0);
boolean onSlope = slope != Slope.HORIZONTAL
&& MathHelper.clamp(offset, .5f, te.beltLength - .5f) == offset;
float slopeAngle = onSlope
? slope == Slope.DOWNWARD ^ te.getDirectionAwareBeltMovementSpeed() > 0 ? -45 : 45
: 0;
GlStateManager.translated(offsetVec.x, offsetVec.y, offsetVec.z); GlStateManager.translated(offsetVec.x, offsetVec.y, offsetVec.z);
boolean alongX = te.getBeltFacing().rotateY().getAxis() == Axis.X; boolean alongX = te.getBeltFacing().rotateY().getAxis() == Axis.X;
@ -70,6 +86,11 @@ public class BeltTileEntityRenderer extends TileEntityRenderer<BeltTileEntity> {
RenderHelper.enableStandardItemLighting(); RenderHelper.enableStandardItemLighting();
int count = (int) (MathHelper.log2((int) (transported.stack.getCount()))) / 2; int count = (int) (MathHelper.log2((int) (transported.stack.getCount()))) / 2;
GlStateManager.rotated(slopeAngle, slopeAlongX ? 0 : 1, 0, slopeAlongX ? 1 : 0);
if (onSlope)
GlStateManager.translated(0, 1 / 8f, 0);
Random r = new Random(transported.angle);
for (int i = 0; i <= count; i++) { for (int i = 0; i <= count; i++) {
GlStateManager.pushMatrix(); GlStateManager.pushMatrix();
@ -79,11 +100,18 @@ public class BeltTileEntityRenderer extends TileEntityRenderer<BeltTileEntity> {
GlStateManager.rotated(90, 1, 0, 0); GlStateManager.rotated(90, 1, 0, 0);
} }
if (blockItem) {
GlStateManager.translated(r.nextFloat() * .25f, 0, r.nextFloat() * .25f);
}
GlStateManager.scaled(.5, .5, .5); GlStateManager.scaled(.5, .5, .5);
itemRenderer.renderItem(transported.stack, TransformType.FIXED); itemRenderer.renderItem(transported.stack, TransformType.FIXED);
GlStateManager.popMatrix(); GlStateManager.popMatrix();
if (!blockItem)
GlStateManager.rotated(10, 0, 1, 0); GlStateManager.rotated(10, 0, 1, 0);
GlStateManager.translated(0, 1 / 16d, 0); GlStateManager.translated(0, blockItem ? 1 / 64d : 1 / 16d, 0);
} }
RenderHelper.disableStandardItemLighting(); RenderHelper.disableStandardItemLighting();