Merge branch 'mc1.15/dev' of https://github.com/Creators-of-Create/Create into mc1.15/dev

This commit is contained in:
simibubi 2021-03-17 01:23:18 +01:00
commit cddc4a40f5
21 changed files with 498 additions and 71 deletions

View file

@ -12,6 +12,7 @@ import com.simibubi.create.content.contraptions.components.crank.HandCrankRender
import com.simibubi.create.content.contraptions.components.crank.HandCrankTileEntity; import com.simibubi.create.content.contraptions.components.crank.HandCrankTileEntity;
import com.simibubi.create.content.contraptions.components.crusher.CrushingWheelControllerTileEntity; import com.simibubi.create.content.contraptions.components.crusher.CrushingWheelControllerTileEntity;
import com.simibubi.create.content.contraptions.components.crusher.CrushingWheelTileEntity; import com.simibubi.create.content.contraptions.components.crusher.CrushingWheelTileEntity;
import com.simibubi.create.content.contraptions.components.deployer.DeployerInstance;
import com.simibubi.create.content.contraptions.components.deployer.DeployerRenderer; import com.simibubi.create.content.contraptions.components.deployer.DeployerRenderer;
import com.simibubi.create.content.contraptions.components.deployer.DeployerTileEntity; import com.simibubi.create.content.contraptions.components.deployer.DeployerTileEntity;
import com.simibubi.create.content.contraptions.components.fan.EncasedFanRenderer; import com.simibubi.create.content.contraptions.components.fan.EncasedFanRenderer;
@ -476,7 +477,7 @@ public class AllTileEntities {
public static final TileEntityEntry<DeployerTileEntity> DEPLOYER = Create.registrate() public static final TileEntityEntry<DeployerTileEntity> DEPLOYER = Create.registrate()
.tileEntity("deployer", DeployerTileEntity::new) .tileEntity("deployer", DeployerTileEntity::new)
.instance(() -> ShaftInstance::new) .instance(() -> DeployerInstance::new)
.validBlocks(AllBlocks.DEPLOYER) .validBlocks(AllBlocks.DEPLOYER)
.renderer(() -> DeployerRenderer::new) .renderer(() -> DeployerRenderer::new)
.register(); .register();

View file

@ -12,6 +12,7 @@ public enum ActorVertexAttributes implements IVertexAttrib {
AXIS("aAxis", CommonAttributes.NORMAL), AXIS("aAxis", CommonAttributes.NORMAL),
INSTANCE_ROTATION("aInstanceRot", CommonAttributes.VEC3), INSTANCE_ROTATION("aInstanceRot", CommonAttributes.VEC3),
ROTATION_CENTER("aRotationCenter", CommonAttributes.NORMAL), ROTATION_CENTER("aRotationCenter", CommonAttributes.NORMAL),
SPEED("aSpeed", CommonAttributes.FLOAT),
; ;
private final String name; private final String name;

View file

@ -30,6 +30,8 @@ public class ContraptionActorData extends InstanceData {
private byte rotationCenterY = 64; private byte rotationCenterY = 64;
private byte rotationCenterZ = 64; private byte rotationCenterZ = 64;
private float speed;
protected ContraptionActorData(InstancedModel<?> owner) { protected ContraptionActorData(InstancedModel<?> owner) {
super(owner); super(owner);
} }
@ -57,6 +59,11 @@ public class ContraptionActorData extends InstanceData {
return this; return this;
} }
public ContraptionActorData setSpeed(float speed) {
this.speed = speed;
return this;
}
public ContraptionActorData setRotationAxis(Vector3f axis) { public ContraptionActorData setRotationAxis(Vector3f axis) {
setRotationAxis(axis.getX(), axis.getY(), axis.getZ()); setRotationAxis(axis.getX(), axis.getY(), axis.getZ());
return this; return this;
@ -101,6 +108,7 @@ public class ContraptionActorData extends InstanceData {
putVec3(buf, rotationAxisX, rotationAxisY, rotationAxisZ); putVec3(buf, rotationAxisX, rotationAxisY, rotationAxisZ);
putVec3(buf, localRotationX, localRotationY, localRotationZ); putVec3(buf, localRotationX, localRotationY, localRotationZ);
putVec3(buf, rotationCenterX, rotationCenterY, rotationCenterZ); putVec3(buf, rotationCenterX, rotationCenterY, rotationCenterZ);
put(buf, speed);
} }
} }

View file

@ -0,0 +1,53 @@
package com.simibubi.create.content.contraptions.components.actors;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionKineticRenderer;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.block.BlockState;
import net.minecraft.util.Direction;
public class DrillActorInstance extends ActorInstance {
InstanceKey<ContraptionActorData> drillHead;
private Direction facing;
public DrillActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) {
super(modelManager, context);
RenderMaterial<?, InstancedModel<ContraptionActorData>> renderMaterial = modelManager.getActorMaterial();
BlockState state = context.state;
facing = state.get(DrillBlock.FACING);
float eulerX = AngleHelper.verticalAngle(facing) + ((facing.getAxis() == Direction.Axis.Y) ? 180 : 0);
float eulerY = facing.getHorizontalAngle();
drillHead = renderMaterial.getModel(AllBlockPartials.DRILL_HEAD, state).createInstance();
drillHead.getInstance()
.setPosition(context.localPos)
.setBlockLight(localBlockLight())
.setRotationOffset(0)
.setRotationAxis(0, 0, 1)
.setLocalRotation(eulerX, eulerY, 0)
.setSpeed(getSpeed(facing));
}
@Override
protected void tick() {
drillHead.getInstance().setSpeed(getSpeed(facing));
}
@Override
protected float getSpeed(Direction facing) {
if (context.contraption.stalled || !VecHelper.isVecPointingTowards(context.relativeMotion, facing.getOpposite()))
return context.getAnimationSpeed();
return 0;
}
}

View file

@ -22,23 +22,6 @@ public class DrillInstance extends SingleRotatingInstance {
super(modelManager, tile); super(modelManager, tile);
} }
public static void addInstanceForContraption(RenderedContraption contraption, MovementContext context) {
RenderMaterial<?, InstancedModel<ContraptionActorData>> renderMaterial = contraption.getActorMaterial();
BlockState state = context.state;
InstancedModel<ContraptionActorData> model = renderMaterial.getModel(AllBlockPartials.DRILL_HEAD, state);
Direction facing = state.get(DrillBlock.FACING);
float eulerX = AngleHelper.verticalAngle(facing) + ((facing.getAxis() == Direction.Axis.Y) ? 180 : 0);
float eulerY = facing.getHorizontalAngle();
model.getInstance(model.createInstance())
.setPosition(context.localPos)
.setBlockLight(contraption.renderWorld.getLightLevel(LightType.BLOCK, context.localPos))
.setRotationOffset(0)
.setRotationAxis(0, 0, 1)
.setLocalRotation(eulerX, eulerY, 0);
}
@Override @Override
protected InstancedModel<RotatingData> getModel() { protected InstancedModel<RotatingData> getModel() {
return AllBlockPartials.DRILL_HEAD.renderOnDirectionalSouthRotating(modelManager, tile.getBlockState()); return AllBlockPartials.DRILL_HEAD.renderOnDirectionalSouthRotating(modelManager, tile.getBlockState());

View file

@ -2,6 +2,8 @@ package com.simibubi.create.content.contraptions.components.actors;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionKineticRenderer;
import com.simibubi.create.content.contraptions.components.structureMovement.render.RenderedContraption; import com.simibubi.create.content.contraptions.components.structureMovement.render.RenderedContraption;
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
@ -15,6 +17,8 @@ import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import javax.annotation.Nullable;
public class DrillMovementBehaviour extends BlockBreakingMovementBehaviour { public class DrillMovementBehaviour extends BlockBreakingMovementBehaviour {
@Override @Override
@ -42,9 +46,10 @@ public class DrillMovementBehaviour extends BlockBreakingMovementBehaviour {
return true; return true;
} }
@Nullable
@Override @Override
public void addInstance(RenderedContraption contraption, MovementContext context) { public ActorInstance createInstance(ContraptionKineticRenderer kr, MovementContext context) {
DrillInstance.addInstanceForContraption(contraption, context); return new DrillActorInstance(kr, context);
} }
@Override @Override

View file

@ -42,7 +42,7 @@ public class DrillRenderer extends KineticTileEntityRenderer {
Direction facing = state.get(DrillBlock.FACING); Direction facing = state.get(DrillBlock.FACING);
float speed = (float) (context.contraption.stalled float speed = (float) (context.contraption.stalled
|| !VecHelper.isVecPointingTowards(context.relativeMotion, state.get(FACING) || !VecHelper.isVecPointingTowards(context.relativeMotion, facing
.getOpposite()) ? context.getAnimationSpeed() : 0); .getOpposite()) ? context.getAnimationSpeed() : 0);
float time = AnimationTickHolder.getRenderTime() / 20; float time = AnimationTickHolder.getRenderTime() / 20;
float angle = (float) (((time * speed) % 360)); float angle = (float) (((time * speed) % 360));

View file

@ -0,0 +1,49 @@
package com.simibubi.create.content.contraptions.components.actors;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionKineticRenderer;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.util.Direction;
import net.minecraft.world.LightType;
import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING;
public class HarvesterActorInstance extends ActorInstance {
InstanceKey<ContraptionActorData> harvester;
private Direction facing;
public HarvesterActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) {
super(modelManager, context);
RenderMaterial<?, InstancedModel<ContraptionActorData>> renderMaterial = modelManager.getActorMaterial();
BlockState state = context.state;
facing = state.get(HORIZONTAL_FACING);
float originOffset = 1 / 16f;
Vector3f rotOffset = new Vector3f(0.5f, -2 * originOffset + 0.5f, originOffset + 0.5f);
harvester = renderMaterial.getModel(AllBlockPartials.HARVESTER_BLADE, state).createInstance();
harvester.getInstance()
.setPosition(context.localPos)
.setBlockLight(localBlockLight())
.setRotationOffset(0)
.setRotationCenter(rotOffset)
.setRotationAxis(-1, 0, 0)
.setLocalRotation(0, facing.getHorizontalAngle(), 0)
.setSpeed(getSpeed(facing));
}
@Override
protected void tick() {
harvester.getInstance().setSpeed(getSpeed(facing));
}
}

View file

@ -2,6 +2,8 @@ package com.simibubi.create.content.contraptions.components.actors;
import static net.minecraft.block.HorizontalBlock.HORIZONTAL_FACING; import static net.minecraft.block.HorizontalBlock.HORIZONTAL_FACING;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionKineticRenderer;
import org.apache.commons.lang3.mutable.MutableBoolean; import org.apache.commons.lang3.mutable.MutableBoolean;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
@ -29,6 +31,8 @@ import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.common.IPlantable; import net.minecraftforge.common.IPlantable;
import javax.annotation.Nullable;
public class HarvesterMovementBehaviour extends MovementBehaviour { public class HarvesterMovementBehaviour extends MovementBehaviour {
@Override @Override
@ -42,9 +46,10 @@ public class HarvesterMovementBehaviour extends MovementBehaviour {
return true; return true;
} }
@Nullable
@Override @Override
public void addInstance(RenderedContraption contraption, MovementContext context) { public ActorInstance createInstance(ContraptionKineticRenderer kr, MovementContext context) {
HarvesterRenderer.addInstanceForContraption(contraption, context); return new HarvesterActorInstance(kr, context);
} }
@Override @Override

View file

@ -43,24 +43,6 @@ public class HarvesterRenderer extends SafeTileEntityRenderer<HarvesterTileEntit
.renderInto(ms, buffer.getBuffer(RenderType.getCutoutMipped())); .renderInto(ms, buffer.getBuffer(RenderType.getCutoutMipped()));
} }
public static void addInstanceForContraption(RenderedContraption contraption, MovementContext context) {
RenderMaterial<?, InstancedModel<ContraptionActorData>> renderMaterial = contraption.getActorMaterial();
BlockState state = context.state;
InstancedModel<ContraptionActorData> model = renderMaterial.getModel(AllBlockPartials.HARVESTER_BLADE, state);
Direction facing = state.get(HORIZONTAL_FACING);
float originOffset = 1 / 16f;
Vector3f rotOffset = new Vector3f(0.5f, -2 * originOffset + 0.5f, originOffset + 0.5f);
model.getInstance(model.createInstance())
.setPosition(context.localPos)
.setBlockLight(contraption.renderWorld.getLightLevel(LightType.BLOCK, context.localPos))
.setRotationOffset(0)
.setRotationCenter(rotOffset)
.setRotationAxis(-1, 0, 0)
.setLocalRotation(0, facing.getHorizontalAngle(), 0);
}
public static void renderInContraption(MovementContext context, MatrixStack ms, MatrixStack msLocal, public static void renderInContraption(MovementContext context, MatrixStack ms, MatrixStack msLocal,
IRenderTypeBuffer buffers) { IRenderTypeBuffer buffers) {
BlockState blockState = context.state; BlockState blockState = context.state;
@ -90,7 +72,4 @@ public class HarvesterRenderer extends SafeTileEntityRenderer<HarvesterTileEntit
.rotate(Direction.WEST, AngleHelper.rad(angle)) .rotate(Direction.WEST, AngleHelper.rad(angle))
.translate(-rotOffset.x, -rotOffset.y, -rotOffset.z); .translate(-rotOffset.x, -rotOffset.y, -rotOffset.z);
} }
public static void transformHead(MatrixStack ms, float angle) {}
} }

View file

@ -0,0 +1,98 @@
package com.simibubi.create.content.contraptions.components.deployer;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.*;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionKineticRenderer;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionProgram;
import com.simibubi.create.foundation.render.Compartment;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.utility.*;
import net.minecraft.block.BlockState;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import static com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE;
import static com.simibubi.create.content.contraptions.base.DirectionalKineticBlock.FACING;
public class DeployerActorInstance extends ActorInstance {
Direction facing;
boolean stationaryTimer;
float yRot;
float zRot;
float zRotPole;
InstanceKey<ModelData> pole;
InstanceKey<ModelData> hand;
InstanceKey<RotatingData> shaft;
public DeployerActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) {
super(modelManager, context);
RenderMaterial<ContraptionProgram, InstancedModel<ModelData>> mat = modelManager.basicMaterial();
BlockState state = context.state;
DeployerTileEntity.Mode mode = NBTHelper.readEnum(context.tileData, "Mode", DeployerTileEntity.Mode.class);
AllBlockPartials handPose = DeployerRenderer.getHandPose(mode);
stationaryTimer = context.data.contains("StationaryTimer");
facing = state.get(FACING);
boolean rotatePole = state.get(AXIS_ALONG_FIRST_COORDINATE) ^ facing.getAxis() == Direction.Axis.Z;
yRot = AngleHelper.horizontalAngle(facing);
zRot = facing == Direction.UP ? 270 : facing == Direction.DOWN ? 90 : 0;
zRotPole = rotatePole ? 90 : 0;
pole = mat.getModel(AllBlockPartials.DEPLOYER_POLE, state).createInstance();
hand = mat.getModel(handPose, state).createInstance();
Direction.Axis axis = ((IRotate) state.getBlock()).getRotationAxis(state);
shaft = modelManager.getMaterial(KineticRenderMaterials.ROTATING)
.getModel(KineticTileEntityRenderer.KINETIC_TILE, KineticTileInstance.shaft(axis))
.createInstance();
int blockLight = localBlockLight();
shaft.getInstance()
.setBlockLight(blockLight)
.setRotationAxis(axis)
.setPosition(context.localPos);
pole.getInstance().setBlockLight(blockLight);
hand.getInstance().setBlockLight(blockLight);
}
@Override
protected void tick() {
double factor;
if (context.contraption.stalled || context.position == null || context.data.contains("StationaryTimer")) {
factor = MathHelper.sin(AnimationTickHolder.getRenderTime() * .5f) * .25f + .25f;
} else {
Vec3d center = VecHelper.getCenterOf(new BlockPos(context.position));
double distance = context.position.distanceTo(center);
double nextDistance = context.position.add(context.motion)
.distanceTo(center);
factor = .5f - MathHelper.clamp(MathHelper.lerp(AnimationTickHolder.getPartialTicks(), distance, nextDistance), 0, 1);
}
Vec3d offset = new Vec3d(facing.getDirectionVec()).scale(factor);
MatrixStack ms = new MatrixStack();
MatrixStacker msr = MatrixStacker.of(ms);
msr.translate(context.localPos)
.translate(offset);
DeployerInstance.transformModel(msr, pole, hand, yRot, zRot, zRotPole);
}
}

View file

@ -0,0 +1,132 @@
package com.simibubi.create.content.contraptions.components.deployer;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance;
import com.simibubi.create.foundation.render.backend.instancing.*;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.MatrixStacker;
import net.minecraft.util.Direction;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import static com.simibubi.create.content.contraptions.base.DirectionalAxisKineticBlock.AXIS_ALONG_FIRST_COORDINATE;
import static com.simibubi.create.content.contraptions.base.DirectionalKineticBlock.FACING;
public class DeployerInstance extends ShaftInstance implements ITickableInstance {
DeployerTileEntity tile;
Direction facing;
InstanceKey<ModelData> pole;
AllBlockPartials currentHand;
InstanceKey<ModelData> hand;
float yRot;
float zRot;
float zRotPole;
public DeployerInstance(InstancedTileRenderer<?> dispatcher, KineticTileEntity tile) {
super(dispatcher, tile);
}
@Override
protected void init() {
super.init();
this.tile = (DeployerTileEntity) super.tile;
facing = lastState.get(FACING);
boolean rotatePole = lastState.get(AXIS_ALONG_FIRST_COORDINATE) ^ facing.getAxis() == Direction.Axis.Z;
yRot = AngleHelper.horizontalAngle(facing);
zRot = facing == Direction.UP ? 270 : facing == Direction.DOWN ? 90 : 0;
zRotPole = rotatePole ? 90 : 0;
pole = modelManager.basicMaterial().getModel(AllBlockPartials.DEPLOYER_POLE, lastState).createInstance();
updateHandPose();
relight(pos, pole.getInstance());
}
@Override
public void tick() {
updateHandPose();
MatrixStack ms = new MatrixStack();
MatrixStacker msr = MatrixStacker.of(ms);
msr.translate(getFloatingPos())
.translate(getHandOffset(AnimationTickHolder.getPartialTicks()));
transformModel(msr, pole, hand, yRot, zRot, zRotPole);
}
@Override
public void updateLight() {
super.updateLight();
relight(pos, hand.getInstance(), pole.getInstance());
}
@Override
public void remove() {
super.remove();
hand.delete();
pole.delete();
currentHand = null; // updateHandPose() uses an invalid key after a block update otherwise.
hand = null;
}
private boolean updateHandPose() {
AllBlockPartials handPose = tile.getHandPose();
if (currentHand == handPose) return false;
currentHand = handPose;
if (hand != null) hand.delete();
hand = modelManager.basicMaterial().getModel(currentHand, lastState).createInstance();
relight(pos, hand.getInstance());
return true;
}
protected Vec3d getHandOffset(float partialTicks) {
float progress = 0;
if (tile.state == DeployerTileEntity.State.EXPANDING)
progress = 1 - (tile.timer - partialTicks * tile.getTimerSpeed()) / 1000f;
if (tile.state == DeployerTileEntity.State.RETRACTING)
progress = (tile.timer - partialTicks * tile.getTimerSpeed()) / 1000f;
float handLength = tile.getHandPose() == AllBlockPartials.DEPLOYER_HAND_POINTING ? 0
: tile.getHandPose() == AllBlockPartials.DEPLOYER_HAND_HOLDING ? 4 / 16f : 3 / 16f;
float distance = Math.min(MathHelper.clamp(progress, 0, 1) * (tile.reach + handLength), 21 / 16f);
Vec3d offset = new Vec3d(facing.getDirectionVec()).scale(distance);
return offset;
}
static void transformModel(MatrixStacker msr, InstanceKey<ModelData> pole, InstanceKey<ModelData> hand, float yRot, float zRot, float zRotPole) {
msr.centre();
msr.rotate(Direction.SOUTH, (float) ((zRot) / 180 * Math.PI));
msr.rotate(Direction.UP, (float) ((yRot) / 180 * Math.PI));
msr.push();
msr.rotate(Direction.SOUTH, (float) ((zRotPole) / 180 * Math.PI));
msr.unCentre();
pole.getInstance().setTransform(msr.unwrap());
msr.pop();
msr.unCentre();
hand.getInstance().setTransform(msr.unwrap());
}
}

View file

@ -3,6 +3,9 @@ package com.simibubi.create.content.contraptions.components.deployer;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionKineticRenderer;
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
@ -24,6 +27,8 @@ import net.minecraft.util.math.Vec3d;
import net.minecraft.world.server.ServerWorld; import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.util.Constants.NBT; import net.minecraftforge.common.util.Constants.NBT;
import javax.annotation.Nullable;
public class DeployerMovementBehaviour extends MovementBehaviour { public class DeployerMovementBehaviour extends MovementBehaviour {
@Override @Override
@ -167,7 +172,18 @@ public class DeployerMovementBehaviour extends MovementBehaviour {
@Override @Override
public void renderInContraption(MovementContext context, MatrixStack ms, MatrixStack msLocal, public void renderInContraption(MovementContext context, MatrixStack ms, MatrixStack msLocal,
IRenderTypeBuffer buffers) { IRenderTypeBuffer buffers) {
DeployerRenderer.renderInContraption(context, ms, msLocal, buffers); if (!FastRenderDispatcher.available())
DeployerRenderer.renderInContraption(context, ms, msLocal, buffers);
} }
@Override
public boolean hasSpecialInstancedRendering() {
return true;
}
@Nullable
@Override
public ActorInstance createInstance(ContraptionKineticRenderer kr, MovementContext context) {
return new DeployerActorInstance(kr, context);
}
} }

View file

@ -49,11 +49,17 @@ public class DeployerRenderer extends SafeTileEntityRenderer<DeployerTileEntity>
int light, int overlay) { int light, int overlay) {
renderItem(te, partialTicks, ms, buffer, light, overlay); renderItem(te, partialTicks, ms, buffer, light, overlay);
FilteringRenderer.renderOnTileEntity(te, partialTicks, ms, buffer, light, overlay); FilteringRenderer.renderOnTileEntity(te, partialTicks, ms, buffer, light, overlay);
if (FastRenderDispatcher.available(te.getWorld())) return;
renderComponents(te, partialTicks, ms, buffer, light, overlay); renderComponents(te, partialTicks, ms, buffer, light, overlay);
} }
protected void renderItem(DeployerTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, protected void renderItem(DeployerTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
int light, int overlay) { int light, int overlay) {
if (te.heldItem.isEmpty()) return;
BlockState deployerState = te.getBlockState(); BlockState deployerState = te.getBlockState();
Vec3d offset = getHandOffset(te, partialTicks, deployerState).add(VecHelper.getCenterOf(BlockPos.ZERO)); Vec3d offset = getHandOffset(te, partialTicks, deployerState).add(VecHelper.getCenterOf(BlockPos.ZERO));
ms.push(); ms.push();
@ -157,8 +163,7 @@ public class DeployerRenderer extends SafeTileEntityRenderer<DeployerTileEntity>
BlockPos pos = BlockPos.ZERO; BlockPos pos = BlockPos.ZERO;
Mode mode = NBTHelper.readEnum(context.tileData, "Mode", Mode.class); Mode mode = NBTHelper.readEnum(context.tileData, "Mode", Mode.class);
World world = context.world; World world = context.world;
AllBlockPartials handPose = AllBlockPartials handPose = getHandPose(mode);
mode == Mode.PUNCH ? AllBlockPartials.DEPLOYER_HAND_PUNCHING : AllBlockPartials.DEPLOYER_HAND_POINTING;
SuperByteBuffer pole = AllBlockPartials.DEPLOYER_POLE.renderOn(blockState); SuperByteBuffer pole = AllBlockPartials.DEPLOYER_POLE.renderOn(blockState);
SuperByteBuffer hand = handPose.renderOn(blockState); SuperByteBuffer hand = handPose.renderOn(blockState);
@ -189,4 +194,8 @@ public class DeployerRenderer extends SafeTileEntityRenderer<DeployerTileEntity>
.renderInto(ms, builder); .renderInto(ms, builder);
} }
static AllBlockPartials getHandPose(DeployerTileEntity.Mode mode) {
return mode == DeployerTileEntity.Mode.PUNCH ? AllBlockPartials.DEPLOYER_HAND_PUNCHING : AllBlockPartials.DEPLOYER_HAND_POINTING;
}
} }

View file

@ -1,6 +1,8 @@
package com.simibubi.create.content.contraptions.components.structureMovement; package com.simibubi.create.content.contraptions.components.structureMovement;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionKineticRenderer;
import com.simibubi.create.content.contraptions.components.structureMovement.render.RenderedContraption; import com.simibubi.create.content.contraptions.components.structureMovement.render.RenderedContraption;
import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.IRenderTypeBuffer;
@ -8,10 +10,13 @@ import net.minecraft.entity.item.ItemEntity;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.world.gen.feature.template.Template;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.items.ItemHandlerHelper; import net.minecraftforge.items.ItemHandlerHelper;
import javax.annotation.Nullable;
public abstract class MovementBehaviour { public abstract class MovementBehaviour {
public boolean isActive(MovementContext context) { public boolean isActive(MovementContext context) {
@ -61,7 +66,10 @@ public abstract class MovementBehaviour {
IRenderTypeBuffer buffer) {} IRenderTypeBuffer buffer) {}
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
public void addInstance(RenderedContraption contraption, MovementContext context) {} @Nullable
public ActorInstance createInstance(ContraptionKineticRenderer kr, MovementContext context) {
return null;
}
public void onSpeedChanged(MovementContext context, Vec3d oldMotion, Vec3d motion) { public void onSpeedChanged(MovementContext context, Vec3d oldMotion, Vec3d motion) {

View file

@ -0,0 +1,29 @@
package com.simibubi.create.content.contraptions.components.structureMovement.render;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.util.Direction;
import net.minecraft.world.LightType;
public abstract class ActorInstance {
protected final ContraptionKineticRenderer modelManager;
protected final MovementContext context;
public ActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) {
this.modelManager = modelManager;
this.context = context;
}
protected void tick() { }
protected float getSpeed(Direction facing) {
if (context.contraption.stalled)
return 0;
return !VecHelper.isVecPointingTowards(context.relativeMotion, facing.getOpposite()) ? context.getAnimationSpeed() : 0;
}
protected int localBlockLight() {
return modelManager.contraption.renderWorld.getLightLevel(LightType.BLOCK, context.localPos);
}
}

View file

@ -1,20 +1,41 @@
package com.simibubi.create.content.contraptions.components.structureMovement.render; package com.simibubi.create.content.contraptions.components.structureMovement.render;
import com.simibubi.create.AllMovementBehaviours;
import com.simibubi.create.content.contraptions.base.KineticRenderMaterials; import com.simibubi.create.content.contraptions.base.KineticRenderMaterials;
import com.simibubi.create.content.contraptions.base.RotatingInstancedModel; import com.simibubi.create.content.contraptions.base.RotatingInstancedModel;
import com.simibubi.create.content.contraptions.components.actors.ContraptionActorData;
import com.simibubi.create.content.contraptions.components.actors.RotatingActorModel; import com.simibubi.create.content.contraptions.components.actors.RotatingActorModel;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel; import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel;
import com.simibubi.create.content.logistics.block.FlapInstancedModel; import com.simibubi.create.content.logistics.block.FlapInstancedModel;
import com.simibubi.create.foundation.render.AllProgramSpecs; import com.simibubi.create.foundation.render.AllProgramSpecs;
import com.simibubi.create.foundation.render.backend.Backend;
import com.simibubi.create.foundation.render.backend.RenderMaterials; import com.simibubi.create.foundation.render.backend.RenderMaterials;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; import com.simibubi.create.foundation.render.backend.instancing.*;
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
import com.simibubi.create.foundation.render.backend.instancing.impl.BasicInstancedModel; import com.simibubi.create.foundation.render.backend.instancing.impl.BasicInstancedModel;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.gen.feature.template.Template;
import org.apache.commons.lang3.tuple.MutablePair;
import org.apache.commons.lang3.tuple.Pair;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class ContraptionKineticRenderer extends InstancedTileRenderer<ContraptionProgram> { public class ContraptionKineticRenderer extends InstancedTileRenderer<ContraptionProgram> {
protected ArrayList<ActorInstance> actors = new ArrayList<>();
public final RenderedContraption contraption;
ContraptionKineticRenderer(RenderedContraption contraption) {
this.contraption = contraption;
}
@Override @Override
public void registerMaterials() { public void registerMaterials() {
materials.put(RenderMaterials.MODELS, new RenderMaterial<>(this, AllProgramSpecs.C_MODEL, BasicInstancedModel::new)); materials.put(RenderMaterials.MODELS, new RenderMaterial<>(this, AllProgramSpecs.C_MODEL, BasicInstancedModel::new));
@ -25,6 +46,36 @@ public class ContraptionKineticRenderer extends InstancedTileRenderer<Contraptio
materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(this, AllProgramSpecs.C_ACTOR, RotatingActorModel::new)); materials.put(KineticRenderMaterials.ACTORS, new RenderMaterial<>(this, AllProgramSpecs.C_ACTOR, RotatingActorModel::new));
} }
@Override
public void beginFrame(double cameraX, double cameraY, double cameraZ) {
super.beginFrame(cameraX, cameraY, cameraZ);
actors.forEach(ActorInstance::tick);
}
@Nullable
public ActorInstance createActor(Pair<Template.BlockInfo, MovementContext> actor) {
Template.BlockInfo blockInfo = actor.getLeft();
MovementContext context = actor.getRight();
MovementBehaviour movementBehaviour = AllMovementBehaviours.of(blockInfo.state);
if (movementBehaviour != null && movementBehaviour.hasSpecialInstancedRendering()) {
ActorInstance instance = movementBehaviour.createInstance(this, context);
actors.add(instance);
return instance;
}
return null;
}
public RenderMaterial<?, InstancedModel<ContraptionActorData>> getActorMaterial() {
return getMaterial(KineticRenderMaterials.ACTORS);
}
@Override @Override
public BlockPos getOriginCoordinate() { public BlockPos getOriginCoordinate() {
return BlockPos.ZERO; return BlockPos.ZERO;

View file

@ -64,7 +64,7 @@ public class RenderedContraption {
public RenderedContraption(World world, Contraption contraption) { public RenderedContraption(World world, Contraption contraption) {
this.contraption = contraption; this.contraption = contraption;
this.lighter = contraption.makeLighter(); this.lighter = contraption.makeLighter();
this.kinetics = new ContraptionKineticRenderer(); this.kinetics = new ContraptionKineticRenderer(this);
this.renderWorld = setupRenderWorld(world, contraption); this.renderWorld = setupRenderWorld(world, contraption);
buildLayers(); buildLayers();
@ -86,10 +86,6 @@ public class RenderedContraption {
return lighter; return lighter;
} }
public RenderMaterial<?, InstancedModel<ContraptionActorData>> getActorMaterial() {
return kinetics.getMaterial(KineticRenderMaterials.ACTORS);
}
public void doRenderLayer(RenderType layer, ContraptionProgram shader) { public void doRenderLayer(RenderType layer, ContraptionProgram shader) {
ContraptionModel structure = renderLayers.get(layer); ContraptionModel structure = renderLayers.get(layer);
if (structure != null) { if (structure != null) {
@ -172,18 +168,7 @@ public class RenderedContraption {
} }
private void buildActors() { private void buildActors() {
List<MutablePair<Template.BlockInfo, MovementContext>> actors = contraption.getActors(); contraption.getActors().forEach(kinetics::createActor);
for (MutablePair<Template.BlockInfo, MovementContext> actor : actors) {
Template.BlockInfo blockInfo = actor.left;
MovementContext context = actor.right;
MovementBehaviour movementBehaviour = AllMovementBehaviours.of(blockInfo.state);
if (movementBehaviour != null) {
movementBehaviour.addInstance(this, context);
}
}
} }
private static ContraptionModel buildStructureModel(PlacementSimulationWorld renderWorld, Contraption c, RenderType layer) { private static ContraptionModel buildStructureModel(PlacementSimulationWorld renderWorld, Contraption c, RenderType layer) {

View file

@ -109,4 +109,18 @@ public class MatrixStacker {
return this; return this;
} }
public MatrixStacker push() {
ms.push();
return this;
}
public MatrixStacker pop() {
ms.pop();
return this;
}
public MatrixStack unwrap() {
return ms;
}
} }

View file

@ -60,7 +60,8 @@ public class VecHelper {
} }
public static boolean isVecPointingTowards(Vec3d vec, Direction direction) { public static boolean isVecPointingTowards(Vec3d vec, Direction direction) {
return new Vec3d(direction.getDirectionVec()).distanceTo(vec.normalize()) < .75; return new Vec3d(direction.getDirectionVec()).dotProduct(vec.normalize()) > 0;
//return new Vec3d(direction.getDirectionVec()).distanceTo(vec.normalize()) < .75;
} }
public static Vec3d getCenterOf(Vec3i pos) { public static Vec3d getCenterOf(Vec3i pos) {

View file

@ -12,6 +12,7 @@ attribute float aOffset;
attribute vec3 aAxis; attribute vec3 aAxis;
attribute vec3 aInstanceRot; attribute vec3 aInstanceRot;
attribute vec3 aRotationCenter; attribute vec3 aRotationCenter;
attribute float aSpeed;
varying float Diffuse; varying float Diffuse;
@ -57,11 +58,10 @@ mat4 rotation(vec3 rot) {
} }
mat4 kineticRotation() { mat4 kineticRotation() {
const float speed = -20.; float degrees = aOffset + uTime * aSpeed / 20.;
float degrees = aOffset + uTime * speed * -3./10.;
float angle = fract(degrees / 360.) * PI * 2.; float angle = fract(degrees / 360.) * PI * 2.;
return rotate(normalize(aAxis), angle); return rotate(normalize(aAxis), -angle);
} }
void main() { void main() {