mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-14 06:24:29 +01:00
Angle aligned rotation
This commit is contained in:
parent
53e1f0f416
commit
ff6b80ee9f
@ -2,6 +2,7 @@ package com.simibubi.create.content.optics;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
import net.minecraft.util.LazyValue;
|
||||||
import net.minecraft.util.math.vector.Vector3d;
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
|
|
||||||
public class BeamSegment {
|
public class BeamSegment {
|
||||||
@ -9,12 +10,14 @@ public class BeamSegment {
|
|||||||
private final Vector3d direction;
|
private final Vector3d direction;
|
||||||
private final Vector3d start;
|
private final Vector3d start;
|
||||||
private int length;
|
private int length;
|
||||||
|
private final LazyValue<Vector3d> normalized;
|
||||||
|
|
||||||
public BeamSegment(@Nonnull float[] color, Vector3d start, Vector3d direction) {
|
public BeamSegment(@Nonnull float[] color, Vector3d start, Vector3d direction) {
|
||||||
this.colors = color;
|
this.colors = color;
|
||||||
this.direction = direction;
|
this.direction = direction;
|
||||||
this.start = start;
|
this.start = start;
|
||||||
this.length = 1;
|
this.length = 1;
|
||||||
|
this.normalized = new LazyValue<>(direction::normalize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void incrementLength() {
|
public void incrementLength() {
|
||||||
@ -36,4 +39,8 @@ public class BeamSegment {
|
|||||||
public Vector3d getStart() {
|
public Vector3d getStart() {
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Vector3d getNormalized() {
|
||||||
|
return normalized.getValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,34 +1,77 @@
|
|||||||
package com.simibubi.create.content.optics;
|
package com.simibubi.create.content.optics;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.BeaconHelper;
|
||||||
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.item.DyeColor;
|
||||||
import net.minecraft.tileentity.TileEntity;
|
import net.minecraft.tileentity.TileEntity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.BlockRayTraceResult;
|
|
||||||
import net.minecraft.util.math.RayTraceContext;
|
|
||||||
import net.minecraft.util.math.vector.Vector3d;
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
|
import net.minecraft.util.math.vector.Vector3f;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
public interface ILightHandler<T extends TileEntity & ILightHandler<T>> {
|
public interface ILightHandler<T extends TileEntity & ILightHandler<T>> {
|
||||||
Vector3d getBeamDirection();
|
Vector3d getBeamDirection();
|
||||||
|
|
||||||
default double getBeamLenght() {
|
default Collection<BeamSegment> constructOutBeam(Vector3d beamDirection) {
|
||||||
T te = getTile();
|
ArrayList<BeamSegment> beam = new ArrayList<>();
|
||||||
World world = te.getWorld();
|
float[] segmentColor = getSegmentStartColor();
|
||||||
BlockPos pos = te.getPos();
|
World world = getTile().getWorld();
|
||||||
if (pos == BlockPos.ZERO || world == null)
|
if (world == null)
|
||||||
return 0;
|
return beam;
|
||||||
|
Vector3d direction = VecHelper.step(beamDirection);
|
||||||
|
Vector3d testPos = VecHelper.getCenterOf(getTile().getPos());
|
||||||
|
|
||||||
Vector3d direction = getBeamDirection();
|
BeamSegment segment = new BeamSegment(segmentColor, testPos, direction);
|
||||||
BlockRayTraceResult raytrace = world
|
beam.add(segment);
|
||||||
.rayTraceBlocks(new RayTraceContext(Vector3d.of(pos).add(direction),
|
|
||||||
direction.normalize()
|
|
||||||
.scale(128)
|
|
||||||
.add(Vector3d.of(pos)),
|
|
||||||
RayTraceContext.BlockMode.OUTLINE, RayTraceContext.FluidMode.NONE, null));
|
|
||||||
|
|
||||||
return Vector3d.of(raytrace.getPos()
|
for (int i = 0; i < 128; i++) {
|
||||||
.subtract(pos))
|
testPos = testPos.add(direction); // check next block
|
||||||
.length();
|
BlockPos testBlockPos = new BlockPos(testPos.x, testPos.y, testPos.z);
|
||||||
|
BlockState testState = world.getBlockState(testBlockPos);
|
||||||
|
float[] newColor = BeaconHelper.getBeaconColorAt(testState.getBlock());
|
||||||
|
if (newColor == null) {
|
||||||
|
TileEntity te = testState.hasTileEntity() ? world.getTileEntity(testBlockPos) : null;
|
||||||
|
if (testState.getOpacity(world, testBlockPos) >= 15 && testState.getBlock() != Blocks.BEDROCK || te instanceof ILightHandler) {
|
||||||
|
if (te instanceof ILightHandler) {
|
||||||
|
((ILightHandler<?>) te).setColor(segmentColor);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (!Arrays.equals(segmentColor, newColor)) {
|
||||||
|
segmentColor = new float[]{(segment.colors[0] + newColor[0]) / 2.0F, (segment.colors[1] + newColor[1]) / 2.0F, (segment.colors[2] + newColor[2]) / 2.0F};
|
||||||
|
segment = new BeamSegment(newColor, testPos, direction);
|
||||||
|
beam.add(segment);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
segment.incrementLength();
|
||||||
|
}
|
||||||
|
return beam;
|
||||||
}
|
}
|
||||||
|
|
||||||
T getTile();
|
T getTile();
|
||||||
|
|
||||||
|
default void setColor(float[] segmentColor) {
|
||||||
|
}
|
||||||
|
|
||||||
|
default float[] getSegmentStartColor() {
|
||||||
|
return DyeColor.WHITE.getColorComponentValues();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
default Vector3f getBeamRotationAround() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.simibubi.create.content.optics.mirror;
|
package com.simibubi.create.content.optics.mirror;
|
||||||
|
|
||||||
|
import static com.simibubi.create.foundation.utility.VecHelper.UP;
|
||||||
import static net.minecraft.client.renderer.tileentity.BeaconTileEntityRenderer.TEXTURE_BEACON_BEAM;
|
import static net.minecraft.client.renderer.tileentity.BeaconTileEntityRenderer.TEXTURE_BEACON_BEAM;
|
||||||
|
|
||||||
import javax.annotation.ParametersAreNonnullByDefault;
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
@ -67,16 +68,16 @@ public class MirrorRenderer extends KineticTileEntityRenderer {
|
|||||||
MirrorTileEntity mirrorTe = (MirrorTileEntity) te;
|
MirrorTileEntity mirrorTe = (MirrorTileEntity) te;
|
||||||
|
|
||||||
renderMirror(mirrorTe, partialTicks, ms, buffer, light);
|
renderMirror(mirrorTe, partialTicks, ms, buffer, light);
|
||||||
renderOutBeam(mirrorTe, partialTicks, ms, buffer, light);
|
renderOutBeam(mirrorTe, partialTicks, ms, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderOutBeam(MirrorTileEntity mirrorTe, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light) {
|
private void renderOutBeam(MirrorTileEntity mirrorTe, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer) {
|
||||||
|
|
||||||
int start = 0;
|
int start = 0;
|
||||||
|
|
||||||
for (int k = 0; k < mirrorTe.beam.size(); k++) {
|
for (int k = 0; k < mirrorTe.beam.size(); k++) {
|
||||||
BeamSegment beamSegment = mirrorTe.beam.get(k);
|
BeamSegment beamSegment = mirrorTe.beam.get(k);
|
||||||
renderSegment(beamSegment, ms, buffer, partialTicks, mirrorTe.getWorld()
|
renderSegment(mirrorTe, beamSegment, ms, buffer, partialTicks, mirrorTe.getWorld()
|
||||||
.getGameTime(),
|
.getGameTime(),
|
||||||
beamSegment.getDirection()
|
beamSegment.getDirection()
|
||||||
.scale(start + beamSegment.getLength())
|
.scale(start + beamSegment.getLength())
|
||||||
@ -85,9 +86,15 @@ public class MirrorRenderer extends KineticTileEntityRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderSegment(BeamSegment beamSegment, MatrixStack ms, IRenderTypeBuffer buffer, float partialTicks, long gameTime, double length) {
|
private void renderSegment(MirrorTileEntity mirrorTe, BeamSegment beamSegment, MatrixStack ms, IRenderTypeBuffer buffer, float partialTicks, long gameTime, double length) {
|
||||||
float adjustedGameTime = (float) Math.floorMod(gameTime, 40L) + partialTicks;
|
float adjustedGameTime = (float) Math.floorMod(gameTime, 40L) + partialTicks;
|
||||||
ms.push();
|
ms.push();
|
||||||
|
ms.translate(0, 0.5D, 0.5D);
|
||||||
|
ms.multiply(mirrorTe.getBeamRotationAround()
|
||||||
|
.getRadialQuaternion((float) Math.acos(beamSegment.getNormalized()
|
||||||
|
.dotProduct(UP))));
|
||||||
|
ms.translate(0, -0.5D, -0.5D);
|
||||||
|
ms.push();
|
||||||
ms.translate(0.5D, 0.0D, 0.5D);
|
ms.translate(0.5D, 0.0D, 0.5D);
|
||||||
ms.push();
|
ms.push();
|
||||||
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(adjustedGameTime * 2.25F - 45.0F));
|
ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(adjustedGameTime * 2.25F - 45.0F));
|
||||||
@ -97,6 +104,7 @@ public class MirrorRenderer extends KineticTileEntityRenderer {
|
|||||||
method_22741(ms, buffer.getBuffer(RenderType.getBeaconBeam(TEXTURE_BEACON_BEAM, true)), beamSegment.colors, 1F, MathHelper.floor(length - beamSegment.getLength()), MathHelper.floor(length), 0F, 0.2F, .2F, 0F, -.2f, 0f, 0f, -.2f, 0f, 1f, f16, f15);
|
method_22741(ms, buffer.getBuffer(RenderType.getBeaconBeam(TEXTURE_BEACON_BEAM, true)), beamSegment.colors, 1F, MathHelper.floor(length - beamSegment.getLength()), MathHelper.floor(length), 0F, 0.2F, .2F, 0F, -.2f, 0f, 0f, -.2f, 0f, 1f, f16, f15);
|
||||||
ms.pop();
|
ms.pop();
|
||||||
ms.pop();
|
ms.pop();
|
||||||
|
ms.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderMirror(MirrorTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light) {
|
private void renderMirror(MirrorTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light) {
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
package com.simibubi.create.content.optics.mirror;
|
package com.simibubi.create.content.optics.mirror;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.content.optics.BeamSegment;
|
import com.simibubi.create.content.optics.BeamSegment;
|
||||||
import com.simibubi.create.content.optics.ILightHandler;
|
import com.simibubi.create.content.optics.ILightHandler;
|
||||||
@ -15,19 +16,23 @@ import com.simibubi.create.foundation.utility.VecHelper;
|
|||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.item.DyeColor;
|
import net.minecraft.item.DyeColor;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
import net.minecraft.tileentity.BeaconTileEntity;
|
import net.minecraft.tileentity.BeaconTileEntity;
|
||||||
import net.minecraft.tileentity.TileEntityType;
|
import net.minecraft.tileentity.TileEntityType;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.vector.Vector3d;
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
|
import net.minecraft.util.math.vector.Vector3f;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
public class MirrorTileEntity extends KineticTileEntity implements ILightHandler<MirrorTileEntity> {
|
public class MirrorTileEntity extends KineticTileEntity implements ILightHandler<MirrorTileEntity> {
|
||||||
public final List<BeamSegment> beam;
|
public final List<BeamSegment> beam;
|
||||||
protected float angle;
|
protected float angle;
|
||||||
protected float clientAngleDiff;
|
protected float clientAngleDiff;
|
||||||
private float prevAngle;
|
private float prevAngle;
|
||||||
private double length;
|
|
||||||
private Optional<BeaconTileEntity> beacon;
|
private Optional<BeaconTileEntity> beacon;
|
||||||
|
private float[] initialColor = DyeColor.WHITE.getColorComponentValues();
|
||||||
|
|
||||||
public MirrorTileEntity(TileEntityType<?> typeIn) {
|
public MirrorTileEntity(TileEntityType<?> typeIn) {
|
||||||
super(typeIn);
|
super(typeIn);
|
||||||
@ -44,10 +49,7 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void fromTag(BlockState state, CompoundNBT compound, boolean clientPacket) {
|
protected void fromTag(BlockState state, CompoundNBT compound, boolean clientPacket) {
|
||||||
if (wasMoved) {
|
|
||||||
super.fromTag(state, compound, clientPacket);
|
super.fromTag(state, compound, clientPacket);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
angle = compound.getFloat("Angle");
|
angle = compound.getFloat("Angle");
|
||||||
super.fromTag(state, compound, clientPacket);
|
super.fromTag(state, compound, clientPacket);
|
||||||
@ -87,29 +89,8 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
|||||||
public void lazyTick() {
|
public void lazyTick() {
|
||||||
super.lazyTick();
|
super.lazyTick();
|
||||||
beacon = BeaconHelper.getBeaconTE(pos, world);
|
beacon = BeaconHelper.getBeaconTE(pos, world);
|
||||||
length = getBeamLenght();
|
|
||||||
|
|
||||||
if (length < 1)
|
|
||||||
return;
|
|
||||||
Vector3d direction = VecHelper.step(getBeamDirection());
|
|
||||||
Vector3d startPos = VecHelper.getCenterOf(getPos());
|
|
||||||
beam.clear();
|
beam.clear();
|
||||||
|
beam.addAll(constructOutBeam(getBeamDirection()));
|
||||||
float[] startColor = DyeColor.WHITE.getColorComponentValues(); // TODO: Add mirroring of color
|
|
||||||
BeamSegment segment = new BeamSegment(startColor, startPos, direction);
|
|
||||||
|
|
||||||
for (int i = 0; i < length; i++) {
|
|
||||||
startPos = startPos.add(direction); // check next block
|
|
||||||
float[] newColor = BeaconHelper.getBeaconColorAt(startPos, world);
|
|
||||||
if (newColor != null && !Arrays.equals(startColor, newColor)) {
|
|
||||||
beam.add(segment);
|
|
||||||
startColor = new float[]{(segment.colors[0] + newColor[0]) / 2.0F, (segment.colors[1] + newColor[1]) / 2.0F, (segment.colors[2] + newColor[2]) / 2.0F};
|
|
||||||
segment = new BeamSegment(newColor, startPos, direction);
|
|
||||||
} else {
|
|
||||||
segment.incrementLength();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
beam.add(segment);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -117,10 +98,6 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAngle(float forcedAngle) {
|
|
||||||
angle = forcedAngle;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Vector3d getBeamDirection() {
|
public Vector3d getBeamDirection() {
|
||||||
// TODO: Implement properly
|
// TODO: Implement properly
|
||||||
@ -131,4 +108,30 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
|||||||
public MirrorTileEntity getTile() {
|
public MirrorTileEntity getTile() {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setColor(float[] initialColor) {
|
||||||
|
this.initialColor = initialColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float[] getSegmentStartColor() {
|
||||||
|
return initialColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
@Override
|
||||||
|
public Vector3f getBeamRotationAround() {
|
||||||
|
return Direction.getFacingFromAxisDirection(getBlockState().get(BlockStateProperties.AXIS), Direction.AxisDirection.POSITIVE)
|
||||||
|
.getUnitVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getAngle() {
|
||||||
|
return angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAngle(float forcedAngle) {
|
||||||
|
angle = forcedAngle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,11 +53,7 @@ public class BeaconHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static float[] getBeaconColorAt(Vector3d pos, @Nullable IBlockReader world) {
|
public static float[] getBeaconColorAt(Block block) {
|
||||||
if (world == null)
|
|
||||||
return null;
|
|
||||||
Block block = world.getBlockState(new BlockPos(pos.x, pos.y, pos.z))
|
|
||||||
.getBlock();
|
|
||||||
if (!(block instanceof IBeaconBeamColorProvider))
|
if (!(block instanceof IBeaconBeamColorProvider))
|
||||||
return null;
|
return null;
|
||||||
return ((IBeaconBeamColorProvider) block).getColor()
|
return ((IBeaconBeamColorProvider) block).getColor()
|
||||||
|
@ -22,6 +22,7 @@ import net.minecraft.util.math.vector.Vector3i;
|
|||||||
public class VecHelper {
|
public class VecHelper {
|
||||||
|
|
||||||
public static final Vector3d CENTER_OF_ORIGIN = new Vector3d(.5, .5, .5);
|
public static final Vector3d CENTER_OF_ORIGIN = new Vector3d(.5, .5, .5);
|
||||||
|
public static final Vector3d UP = new Vector3d(0, 1, 0);
|
||||||
|
|
||||||
public static Vector3d rotate(Vector3d vec, Vector3d rotationVec) {
|
public static Vector3d rotate(Vector3d vec, Vector3d rotationVec) {
|
||||||
return rotate(vec, rotationVec.x, rotationVec.y, rotationVec.z);
|
return rotate(vec, rotationVec.x, rotationVec.y, rotationVec.z);
|
||||||
|
Loading…
Reference in New Issue
Block a user