mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-02-05 01:45:00 +01:00
Fix a bunch of stuff, mirroring colors now works correctly
This commit is contained in:
parent
5d54ed4682
commit
2b3fb358ad
4 changed files with 81 additions and 72 deletions
|
@ -8,44 +8,33 @@ import java.util.Set;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
import net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||||
|
import net.minecraft.item.DyeColor;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.vector.Vector3d;
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
|
|
||||||
public class Beam extends ArrayList<BeamSegment> {
|
public class Beam extends ArrayList<BeamSegment> {
|
||||||
public final Set<Beam> subBeams;
|
|
||||||
private final Set<ILightHandler<?>> lightEventListeners;
|
private final Set<ILightHandler<?>> lightEventListeners;
|
||||||
private final Vector3d direction;
|
private final Vector3d direction;
|
||||||
private boolean removed = false;
|
@Nullable
|
||||||
|
private final Beam parent;
|
||||||
|
|
||||||
public Beam(Vector3d direction) {
|
public Beam(@Nullable Beam parent, Vector3d direction) {
|
||||||
super();
|
super();
|
||||||
|
this.parent = parent;
|
||||||
this.direction = direction;
|
this.direction = direction;
|
||||||
lightEventListeners = new HashSet<>();
|
lightEventListeners = new HashSet<>();
|
||||||
subBeams = new HashSet<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onRemoved() {
|
|
||||||
lightEventListeners.forEach(handler -> handler.onBeamRemoved(this));
|
|
||||||
subBeams.forEach(Beam::onRemoved);
|
|
||||||
subBeams.clear();
|
|
||||||
removed = true;
|
|
||||||
clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onCreated() {
|
public void onCreated() {
|
||||||
lightEventListeners.stream()
|
lightEventListeners.stream()
|
||||||
.flatMap(handler -> handler.constructSubBeams(this))
|
.flatMap(handler -> handler.constructSubBeams(this))
|
||||||
.forEach(subBeams::add);
|
.forEach(Beam::onCreated);
|
||||||
}
|
|
||||||
|
|
||||||
public void registerSubBeam(Beam beam) {
|
|
||||||
subBeams.add(beam);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render(MatrixStack ms, IRenderTypeBuffer buffer, float partialTicks) {
|
public void render(MatrixStack ms, IRenderTypeBuffer buffer, float partialTicks) {
|
||||||
if (removed)
|
|
||||||
throw new IllegalStateException("tried to render removed beam");
|
|
||||||
forEach(beamSegment -> beamSegment.renderSegment(ms, buffer, partialTicks));
|
forEach(beamSegment -> beamSegment.renderSegment(ms, buffer, partialTicks));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,11 +53,28 @@ public class Beam extends ArrayList<BeamSegment> {
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
if (!super.equals(o)) return false;
|
if (!super.equals(o)) return false;
|
||||||
Beam that = (Beam) o;
|
Beam that = (Beam) o;
|
||||||
return removed == that.removed && subBeams.equals(that.subBeams) && lightEventListeners.equals(that.lightEventListeners) && Objects.equals(direction, that.direction);
|
return lightEventListeners.equals(that.lightEventListeners) && Objects.equals(direction, that.direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeSubBeam(Beam out) {
|
public boolean isRemoved() {
|
||||||
if (subBeams.remove(out))
|
return isEmpty() || get(0).getHandler()
|
||||||
out.onRemoved();
|
.getTile()
|
||||||
|
.isRemoved() || !get(0).getHandler()
|
||||||
|
.getOutBeams()
|
||||||
|
.contains(this) || (parent != null && parent.isRemoved());
|
||||||
|
}
|
||||||
|
|
||||||
|
public float[] getColorAt(BlockPos testBlockPos) {
|
||||||
|
float[] out = DyeColor.WHITE.getColorComponentValues();
|
||||||
|
for (BeamSegment segment : this) {
|
||||||
|
if (VecHelper.getCenterOf(testBlockPos)
|
||||||
|
.subtract(segment.getStart())
|
||||||
|
.dotProduct(segment.getNormalized()) > 0)
|
||||||
|
out = segment.getColors();
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,16 +120,12 @@ public class BeamSegment {
|
||||||
beaconBeamModifier = Quaternion.IDENTITY;
|
beaconBeamModifier = Quaternion.IDENTITY;
|
||||||
} else {
|
} else {
|
||||||
Vector3f unitVec = axis.getUnitVector();
|
Vector3f unitVec = axis.getUnitVector();
|
||||||
beaconBeamModifier = unitVec.getRadialQuaternion((float) (-Math.acos(dotProd) * Math.signum(new Vector3d(unitVec).dotProduct(getNormalized().crossProduct(UP)))));
|
beaconBeamModifier = unitVec.getRadialQuaternion((float) Math.acos(dotProd) * (new Vector3d(unitVec).dotProduct(getNormalized().crossProduct(UP)) > 0 ? -1 : 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return beaconBeamModifier;
|
return beaconBeamModifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getTotalSectionLength() {
|
|
||||||
return totalSectionLength.getValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getWorldTick() {
|
public long getWorldTick() {
|
||||||
World world = getHandler()
|
World world = getHandler()
|
||||||
.getTile()
|
.getTile()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.simibubi.create.content.optics;
|
package com.simibubi.create.content.optics;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
@ -22,19 +23,19 @@ import net.minecraft.world.World;
|
||||||
|
|
||||||
public interface ILightHandler<T extends SmartTileEntity & ILightHandler<T>> {
|
public interface ILightHandler<T extends SmartTileEntity & ILightHandler<T>> {
|
||||||
@Nullable
|
@Nullable
|
||||||
default Beam constructOutBeam(Vector3d beamDirection) {
|
default Beam constructOutBeam(@Nullable Beam parent, Vector3d beamDirection) {
|
||||||
return constructOutBeam(beamDirection, getTile().getPos());
|
return constructOutBeam(parent, beamDirection, getTile().getPos());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
default Beam constructOutBeam(Vector3d beamDirection, BlockPos testBlockPos) {
|
default Beam constructOutBeam(@Nullable Beam parent, Vector3d beamDirection, BlockPos testBlockPos) {
|
||||||
|
|
||||||
float[] segmentColor = getSegmentStartColor();
|
float[] segmentColor = parent == null ? DyeColor.WHITE.getColorComponentValues() : parent.getColorAt(testBlockPos);
|
||||||
World world = getTile().getWorld();
|
World world = getTile().getWorld();
|
||||||
if (world == null)
|
if (world == null)
|
||||||
return null;
|
return null;
|
||||||
Vector3d direction = VecHelper.step(beamDirection);
|
Vector3d direction = VecHelper.step(beamDirection);
|
||||||
Beam beam = new Beam(direction);
|
Beam beam = new Beam(parent, direction);
|
||||||
Vector3d testPos = VecHelper.getCenterOf(testBlockPos);
|
Vector3d testPos = VecHelper.getCenterOf(testBlockPos);
|
||||||
|
|
||||||
BeamSegment segment = new BeamSegment(this, segmentColor, testPos, direction);
|
BeamSegment segment = new BeamSegment(this, segmentColor, testPos, direction);
|
||||||
|
@ -74,18 +75,11 @@ public interface ILightHandler<T extends SmartTileEntity & ILightHandler<T>> {
|
||||||
default void setColor(float[] segmentColor) {
|
default void setColor(float[] segmentColor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
default float[] getSegmentStartColor() {
|
|
||||||
return DyeColor.WHITE.getColorComponentValues();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
default Direction getBeamRotationAround() {
|
default Direction getBeamRotationAround() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
default void onBeamRemoved(Beam beam) {
|
|
||||||
}
|
|
||||||
|
|
||||||
default Stream<Beam> constructSubBeams(Beam beam) {
|
default Stream<Beam> constructSubBeams(Beam beam) {
|
||||||
return Stream.empty();
|
return Stream.empty();
|
||||||
}
|
}
|
||||||
|
@ -97,4 +91,8 @@ public interface ILightHandler<T extends SmartTileEntity & ILightHandler<T>> {
|
||||||
default boolean canLightPass() {
|
default boolean canLightPass() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default Collection<Beam> getOutBeams() {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.simibubi.create.content.optics.mirror;
|
package com.simibubi.create.content.optics.mirror;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -20,7 +21,6 @@ import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
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.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.state.properties.BlockStateProperties;
|
import net.minecraft.state.properties.BlockStateProperties;
|
||||||
import net.minecraft.tileentity.BeaconTileEntity;
|
import net.minecraft.tileentity.BeaconTileEntity;
|
||||||
|
@ -40,7 +40,6 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
||||||
@Nullable
|
@Nullable
|
||||||
private BeaconTileEntity beacon;
|
private BeaconTileEntity beacon;
|
||||||
private Beam beaconBeam = null;
|
private Beam beaconBeam = null;
|
||||||
private float[] initialColor = DyeColor.WHITE.getColorComponentValues();
|
|
||||||
|
|
||||||
public MirrorTileEntity(TileEntityType<?> typeIn) {
|
public MirrorTileEntity(TileEntityType<?> typeIn) {
|
||||||
super(typeIn);
|
super(typeIn);
|
||||||
|
@ -93,7 +92,7 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
||||||
angle = newAngle % 360;
|
angle = newAngle % 360;
|
||||||
|
|
||||||
if (angle != prevAngle) {
|
if (angle != prevAngle) {
|
||||||
updateReflections();
|
updateBeams();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (beacon != null && beacon.isRemoved())
|
if (beacon != null && beacon.isRemoved())
|
||||||
|
@ -105,17 +104,14 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
||||||
beacon = BeaconHelper.getBeaconTE(pos, world)
|
beacon = BeaconHelper.getBeaconTE(pos, world)
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
|
|
||||||
if (beaconBefore == beacon)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (beaconBefore != null) {
|
if (beaconBefore != null) {
|
||||||
beaconBeam.onRemoved();
|
beaconBeam.clear();
|
||||||
beaconBeam = null;
|
beaconBeam = null;
|
||||||
updateReflections();
|
updateBeams();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (beacon != null) {
|
if (beacon != null) {
|
||||||
beaconBeam = constructOutBeam(VecHelper.UP, beacon.getPos());
|
beaconBeam = constructOutBeam(null, VecHelper.UP, beacon.getPos());
|
||||||
if (beaconBeam != null) {
|
if (beaconBeam != null) {
|
||||||
beaconBeam.addListener(this);
|
beaconBeam.addListener(this);
|
||||||
beaconBeam.onCreated();
|
beaconBeam.onCreated();
|
||||||
|
@ -123,12 +119,18 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateReflections() {
|
private void updateBeams() {
|
||||||
new HashMap<>(beams).forEach(Beam::removeSubBeam);
|
|
||||||
|
|
||||||
Map<Beam, Beam> newBeams = new HashMap<>();
|
Map<Beam, Beam> newBeams = new HashMap<>();
|
||||||
for (Beam beam : beams.keySet()) {
|
for (Map.Entry<Beam, Beam> entry : beams.entrySet()) {
|
||||||
newBeams.put(beam, reflectBeam(beam));
|
if (entry.getKey()
|
||||||
|
.isRemoved())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
Beam reflected = reflectBeam(entry.getKey());
|
||||||
|
if (reflected != null) {
|
||||||
|
newBeams.put(entry.getKey(), reflected);
|
||||||
|
reflected.onCreated();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
beams = newBeams;
|
beams = newBeams;
|
||||||
}
|
}
|
||||||
|
@ -145,7 +147,7 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
||||||
public void lazyTick() {
|
public void lazyTick() {
|
||||||
super.lazyTick();
|
super.lazyTick();
|
||||||
updateBeaconState();
|
updateBeaconState();
|
||||||
updateReflections();
|
updateBeams();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -160,12 +162,6 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setColor(float[] initialColor) {
|
public void setColor(float[] initialColor) {
|
||||||
this.initialColor = initialColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float[] getSegmentStartColor() {
|
|
||||||
return initialColor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
@ -205,17 +201,20 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
||||||
.iterator(), beaconIter);
|
.iterator(), beaconIter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBeamRemoved(Beam beam) {
|
|
||||||
beams.remove(beam);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Stream<Beam> constructSubBeams(Beam beam) {
|
public Stream<Beam> constructSubBeams(Beam beam) {
|
||||||
|
if (beams.keySet()
|
||||||
|
.stream()
|
||||||
|
.map(Beam::getDirection)
|
||||||
|
.map(Vector3d::normalize)
|
||||||
|
.anyMatch(beam.getDirection()
|
||||||
|
.normalize()::equals))
|
||||||
|
return Stream.empty();
|
||||||
Beam reflected = reflectBeam(beam);
|
Beam reflected = reflectBeam(beam);
|
||||||
if (reflected != null) {
|
if (reflected != null) {
|
||||||
beams.put(beam, reflected);
|
beams.put(beam, reflected);
|
||||||
|
beam.addListener(this);
|
||||||
return Stream.of(reflected);
|
return Stream.of(reflected);
|
||||||
}
|
}
|
||||||
return Stream.empty();
|
return Stream.empty();
|
||||||
|
@ -223,11 +222,21 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler
|
||||||
|
|
||||||
|
|
||||||
private Beam reflectBeam(Beam beam) {
|
private Beam reflectBeam(Beam beam) {
|
||||||
Beam reflected = constructOutBeam(getReflectionAngle(beam.getDirection()));
|
Vector3d inDir = beam.getDirection()
|
||||||
if (reflected != null) {
|
.normalize();
|
||||||
beam.registerSubBeam(reflected);
|
Vector3d outDir = getReflectionAngle(inDir).normalize();
|
||||||
reflected.onCreated();
|
|
||||||
}
|
if (inDir.subtract(outDir)
|
||||||
return reflected;
|
.normalize() == Vector3d.ZERO)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// TE already has input beam at that direction
|
||||||
|
|
||||||
|
return constructOutBeam(beam, outDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Beam> getOutBeams() {
|
||||||
|
return beams.keySet();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue