diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index 6453be2c4..83059c93e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -190,7 +190,7 @@ public abstract class Contraption { // Create subcontraptions for (BlockFace blockFace : pendingSubContraptions) { Direction face = blockFace.getFace(); - StabilizedContraption subContraption = new StabilizedContraption(this, face); + StabilizedContraption subContraption = new StabilizedContraption(entity.getUniqueID(), face); World world = entity.world; BlockPos pos = blockFace.getPos(); if (!subContraption.assemble(world, pos)) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingLighter.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingLighter.java index f18aa3349..d49efaa43 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingLighter.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/BearingLighter.java @@ -2,7 +2,6 @@ package com.simibubi.create.content.contraptions.components.structureMovement.be import com.simibubi.create.foundation.render.light.ContraptionLighter; import com.simibubi.create.foundation.render.light.GridAlignedBB; -import net.minecraft.util.math.AxisAlignedBB; public class BearingLighter extends ContraptionLighter { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedContraption.java index cb5396eca..92b4e8298 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedContraption.java @@ -1,24 +1,31 @@ package com.simibubi.create.content.contraptions.components.structureMovement.bearing; +import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; +import com.simibubi.create.foundation.render.light.ContraptionLighter; +import com.simibubi.create.foundation.utility.NBTHelper; +import net.minecraft.entity.Entity; import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import java.util.UUID; + public class StabilizedContraption extends Contraption { - public Contraption parent; + public UUID parentID; private Direction facing; public StabilizedContraption() {} - public StabilizedContraption(Contraption parent, Direction facing) { - this.parent = parent; + public StabilizedContraption(UUID parentID, Direction facing) { + this.parentID = parentID; this.facing = facing; } @@ -33,7 +40,7 @@ public class StabilizedContraption extends Contraption { return false; return true; } - + @Override protected boolean isAnchoringBlockAt(BlockPos pos) { return false; @@ -48,12 +55,14 @@ public class StabilizedContraption extends Contraption { public CompoundNBT writeNBT(boolean spawnPacket) { CompoundNBT tag = super.writeNBT(spawnPacket); tag.putInt("Facing", facing.getIndex()); + tag.putUniqueId("Parent", parentID); return tag; } @Override public void readNBT(World world, CompoundNBT tag, boolean spawnData) { facing = Direction.byIndex(tag.getInt("Facing")); + parentID = tag.getUniqueId("Parent"); super.readNBT(world, tag, spawnData); } @@ -66,4 +75,8 @@ public class StabilizedContraption extends Contraption { return facing; } + @Override + public ContraptionLighter makeLighter() { + return new StabilizedLighter(this); + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedLighter.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedLighter.java new file mode 100644 index 000000000..556d22462 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/StabilizedLighter.java @@ -0,0 +1,53 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.bearing; + +import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; +import com.simibubi.create.foundation.render.light.ContraptionLighter; +import com.simibubi.create.foundation.render.light.GridAlignedBB; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.Vec3i; + +import java.util.List; + +public class StabilizedLighter extends ContraptionLighter { + public StabilizedLighter(StabilizedContraption contraption) { + super(contraption); + } + + @Override + public GridAlignedBB getContraptionBounds() { + GridAlignedBB bb = GridAlignedBB.fromAABB(contraption.bounds); + + // TODO: this whole thing is a hack and is not generalizable + Iterable allEntities = ((ClientWorld) contraption.entity.world).getAllEntities(); + + for (Entity entity : allEntities) { + + if (entity.getUniqueID() == contraption.parentID && entity instanceof AbstractContraptionEntity) { + Contraption mountedOn = ((AbstractContraptionEntity) entity).getContraption(); + + GridAlignedBB mountedBounds = GridAlignedBB.fromAABB(mountedOn.bounds); + + Vec3i dir = contraption.getFacing().getDirectionVec(); + + int mulX = 1 - Math.abs(dir.getX()); + int mulY = 1 - Math.abs(dir.getY()); + int mulZ = 1 - Math.abs(dir.getZ()); + + bb.minX -= mulX * mountedBounds.sizeX(); + bb.minY -= mulY * mountedBounds.sizeY(); + bb.minZ -= mulZ * mountedBounds.sizeZ(); + bb.maxX += mulX * mountedBounds.sizeX(); + bb.maxY += mulY * mountedBounds.sizeY(); + bb.maxZ += mulZ * mountedBounds.sizeZ(); + + break; + } + } + + bb.translate(contraption.anchor); + + return bb; + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyContraption.java index d4a48a889..55bb14c93 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyContraption.java @@ -3,6 +3,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.pu import com.simibubi.create.content.contraptions.components.structureMovement.AllContraptionTypes; import com.simibubi.create.content.contraptions.components.structureMovement.TranslatingContraption; +import com.simibubi.create.foundation.render.light.ContraptionLighter; import net.minecraft.nbt.CompoundNBT; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -53,4 +54,8 @@ public class PulleyContraption extends TranslatingContraption { super.readNBT(world, nbt, spawnData); } + @Override + public ContraptionLighter makeLighter() { + return new PulleyLighter(this); + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyLighter.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyLighter.java new file mode 100644 index 000000000..fc60b3e84 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyLighter.java @@ -0,0 +1,32 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.pulley; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.foundation.render.light.ContraptionLighter; +import com.simibubi.create.foundation.render.light.GridAlignedBB; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +public class PulleyLighter extends ContraptionLighter { + public PulleyLighter(PulleyContraption contraption) { + super(contraption); + } + + @Override + public GridAlignedBB getContraptionBounds() { + + GridAlignedBB bounds = GridAlignedBB.fromAABB(contraption.bounds); + + World world = contraption.entity.world; + + BlockPos.Mutable pos = new BlockPos.Mutable(contraption.anchor); + while (!AllBlocks.ROPE_PULLEY.has(world.getBlockState(pos)) && pos.getY() < 256) { + pos.move(0, 1, 0); + } + + bounds.translate(pos); + bounds.minY = 1; // the super constructor will take care of making this 0 + + return bounds; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/mixin/RenderInLayerMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/RenderInLayerMixin.java index 5c019b01e..171943f5c 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/RenderInLayerMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/RenderInLayerMixin.java @@ -20,7 +20,7 @@ public class RenderInLayerMixin { * layer-correct custom rendering. RenderWorldLast is not refined enough for rendering world objects. * This should probably be a forge event. */ - @Inject(at = @At("HEAD"), method = "renderLayer") + @Inject(at = @At("TAIL"), method = "renderLayer") private void renderLayer(RenderType type, MatrixStack stack, double cameraX, double cameraY, double cameraZ, CallbackInfo ci) { FastRenderDispatcher.renderLayer(type, stack, cameraX, cameraY, cameraZ); } diff --git a/src/main/java/com/simibubi/create/foundation/render/ContraptionRenderDispatcher.java b/src/main/java/com/simibubi/create/foundation/render/ContraptionRenderDispatcher.java index c06c4ee2d..b34886d03 100644 --- a/src/main/java/com/simibubi/create/foundation/render/ContraptionRenderDispatcher.java +++ b/src/main/java/com/simibubi/create/foundation/render/ContraptionRenderDispatcher.java @@ -1,6 +1,7 @@ package com.simibubi.create.foundation.render; import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; import com.simibubi.create.foundation.render.light.LightVolume; import com.simibubi.create.foundation.render.shader.Shader; @@ -14,9 +15,7 @@ import net.minecraft.util.math.SectionPos; import net.minecraft.world.ILightReader; import net.minecraft.world.LightType; import net.minecraft.world.World; -import org.lwjgl.opengl.GL11; -import org.lwjgl.opengl.GL13; -import org.lwjgl.opengl.GL40; +import org.lwjgl.opengl.*; import java.util.ArrayList; import java.util.HashMap; @@ -53,6 +52,11 @@ public class ContraptionRenderDispatcher { if (renderers.isEmpty()) return; FastKineticRenderer.setup(Minecraft.getInstance().gameRenderer); +// if (renderType == RenderType.getTranslucent()) { +// GL30.glEnable(GL11.GL_DEPTH_TEST); +// GL20.glDepthFunc(GL20.GL_LESS); +// RenderSystem.defaultBlendFunc(); +// } GL11.glEnable(GL13.GL_TEXTURE_3D); GL13.glActiveTexture(GL40.GL_TEXTURE4); // the shaders expect light volumes to be in texture 4 @@ -81,6 +85,10 @@ public class ContraptionRenderDispatcher { ShaderHelper.releaseShader(); +// if (renderType == RenderType.getTranslucent()) { +// GL30.glEnable(GL11.GL_DEPTH_TEST); +// GL20.glDepthFunc(GL20.GL_LEQUAL); +// } GL11.glDisable(GL13.GL_TEXTURE_3D); FastKineticRenderer.teardown(); GL13.glActiveTexture(GL40.GL_TEXTURE0); diff --git a/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java b/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java index 6054e1b00..b5353d5dd 100644 --- a/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java +++ b/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java @@ -1,6 +1,7 @@ package com.simibubi.create.foundation.render; import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.CreateClient; import com.simibubi.create.foundation.render.instancing.IInstanceRendered; import com.simibubi.create.foundation.render.instancing.IInstancedTileEntityRenderer; @@ -22,6 +23,8 @@ import net.minecraft.util.math.SectionPos; import net.minecraft.world.ILightReader; import net.minecraft.world.LightType; import net.minecraft.world.chunk.Chunk; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL30; import java.util.Map; @@ -40,7 +43,12 @@ public class FastRenderDispatcher { Matrix4f projection = getProjectionMatrix(); if (type == FastKineticRenderer.getKineticRenderLayer()) { + RenderSystem.enableDepthTest(); + RenderSystem.enableCull(); + GL11.glCullFace(GL11.GL_BACK); CreateClient.kineticRenderer.renderInstancesAsWorld(type, projection, view); + RenderSystem.disableCull(); + //RenderSystem.disableDepthTest(); } ContraptionRenderDispatcher.renderLayer(type, projection, view); diff --git a/src/main/java/com/simibubi/create/foundation/render/light/ContraptionLighter.java b/src/main/java/com/simibubi/create/foundation/render/light/ContraptionLighter.java index 44786f256..110113283 100644 --- a/src/main/java/com/simibubi/create/foundation/render/light/ContraptionLighter.java +++ b/src/main/java/com/simibubi/create/foundation/render/light/ContraptionLighter.java @@ -15,11 +15,11 @@ public abstract class ContraptionLighter { this.contraption = contraption; GridAlignedBB bounds = getContraptionBounds(); - bounds.grow(1); // so we have at least enough data on the edges to avoid artifacts - GridAlignedBB importantArea = GridAlignedBB.copy(bounds); - bounds.nextPowerOf2Centered(); + bounds.grow(1); // so we have at least enough data on the edges to avoid artifacts and have smooth lighting + bounds.minY = Math.max(bounds.minY, 0); + bounds.maxY = Math.min(bounds.maxY, 255); - lightVolume = new LightVolume(bounds, importantArea); + lightVolume = new LightVolume(bounds); lightVolume.initialize(contraption.entity.world); } diff --git a/src/main/java/com/simibubi/create/foundation/render/light/GridAlignedBB.java b/src/main/java/com/simibubi/create/foundation/render/light/GridAlignedBB.java index bb86dd135..f47889b11 100644 --- a/src/main/java/com/simibubi/create/foundation/render/light/GridAlignedBB.java +++ b/src/main/java/com/simibubi/create/foundation/render/light/GridAlignedBB.java @@ -1,9 +1,11 @@ package com.simibubi.create.foundation.render.light; import com.simibubi.create.foundation.render.RenderMath; +import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.util.Direction; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.SectionPos; +import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3i; import static com.simibubi.create.foundation.render.RenderMath.isPowerOf2; @@ -99,6 +101,55 @@ public class GridAlignedBB { } } + public void mirrorAbout(Direction.Axis axis) { + Vec3i axisVec = Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getDirectionVec(); + int flipX = axisVec.getX() - 1; + int flipY = axisVec.getY() - 1; + int flipZ = axisVec.getZ() - 1; + + int maxX = this.maxX * flipX; + int maxY = this.maxY * flipY; + int maxZ = this.maxZ * flipZ; + this.maxX = this.minX * flipX; + this.maxY = this.minY * flipY; + this.maxZ = this.minZ * flipZ; + this.minX = maxX; + this.minY = maxY; + this.minZ = maxZ; + } + + public void expandAroundAxis(Direction.Axis axis) { + int maxXDiff = Math.max(this.maxX - 1, -this.minX); + int maxYDiff = Math.max(this.maxY - 1, -this.minY); + int maxZDiff = Math.max(this.maxZ - 1, -this.minZ); + + int maxDiff; + if (axis == Direction.Axis.X) + maxDiff = Math.max(maxZDiff, maxYDiff); + else if (axis == Direction.Axis.Y) + maxDiff = Math.max(maxZDiff, maxXDiff); + else if (axis == Direction.Axis.Z) + maxDiff = Math.max(maxXDiff, maxYDiff); + else + maxDiff = 0; + + Vec3i axisVec = Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getDirectionVec(); + int axisX = axisVec.getX(); + int axisY = axisVec.getY(); + int axisZ = axisVec.getZ(); + + int planeX = 1 - axisX; + int planeY = 1 - axisY; + int planeZ = 1 - axisZ; + + minX = axisX * minX - maxDiff * planeX; + minY = axisY * minY - maxDiff * planeY; + minZ = axisZ * minZ - maxDiff * planeZ; + maxX = axisX * maxX + (maxDiff + 1) * planeX; + maxY = axisY * maxY + (maxDiff + 1) * planeY; + maxZ = axisZ * maxZ + (maxDiff + 1) * planeZ; + } + /** * Grow this bounding box to have power of 2 side length, scaling from the center. */ @@ -192,6 +243,15 @@ public class GridAlignedBB { this.maxZ = Math.max(this.maxZ, other.maxZ); } + public void unionAssign(AxisAlignedBB other) { + this.minX = Math.min(this.minX, (int) Math.floor(other.minX)); + this.minY = Math.min(this.minY, (int) Math.floor(other.minY)); + this.minZ = Math.min(this.minZ, (int) Math.floor(other.minZ)); + this.maxX = Math.max(this.maxX, (int) Math.ceil(other.maxX)); + this.maxY = Math.max(this.maxY, (int) Math.ceil(other.maxY)); + this.maxZ = Math.max(this.maxZ, (int) Math.ceil(other.maxZ)); + } + public boolean intersects(GridAlignedBB other) { return this.intersects(other.minX, other.minY, other.minZ, other.maxX, other.maxY, other.maxZ); } diff --git a/src/main/java/com/simibubi/create/foundation/render/light/LightVolume.java b/src/main/java/com/simibubi/create/foundation/render/light/LightVolume.java index fd2a59fce..0f896cd2b 100644 --- a/src/main/java/com/simibubi/create/foundation/render/light/LightVolume.java +++ b/src/main/java/com/simibubi/create/foundation/render/light/LightVolume.java @@ -24,13 +24,10 @@ public class LightVolume { private int glTexture; - public LightVolume(GridAlignedBB textureVolume, GridAlignedBB sampleVolume) { - // the gpu requires that all textures have power of 2 side lengths - if (!textureVolume.hasPowerOf2Sides()) - throw new IllegalArgumentException("LightVolume must have power of 2 side lengths"); - - this.textureVolume = textureVolume; - this.sampleVolume = sampleVolume; + public LightVolume(GridAlignedBB sampleVolume) { + this.sampleVolume = GridAlignedBB.copy(sampleVolume); + sampleVolume.nextPowerOf2Centered(); + this.textureVolume = sampleVolume; this.glTexture = GL11.glGenTextures(); this.lightData = MemoryUtil.memAlloc(this.textureVolume.volume() * 2); // TODO: maybe figure out how to pack light coords into a single byte