mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-27 23:47:38 +01:00
Better contraption actor instancing.
- Promoted actor instance creation to the ActorInstance class. - Drills and Harvesters' rotational speed is based on their movement speed with Flywheel on. - Deployers now use Flywheel.
This commit is contained in:
parent
8b5d5abc06
commit
018c177f1e
21 changed files with 498 additions and 71 deletions
|
@ -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.crusher.CrushingWheelControllerTileEntity;
|
||||
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.DeployerTileEntity;
|
||||
import com.simibubi.create.content.contraptions.components.fan.EncasedFanRenderer;
|
||||
|
@ -476,7 +477,7 @@ public class AllTileEntities {
|
|||
|
||||
public static final TileEntityEntry<DeployerTileEntity> DEPLOYER = Create.registrate()
|
||||
.tileEntity("deployer", DeployerTileEntity::new)
|
||||
.instance(() -> ShaftInstance::new)
|
||||
.instance(() -> DeployerInstance::new)
|
||||
.validBlocks(AllBlocks.DEPLOYER)
|
||||
.renderer(() -> DeployerRenderer::new)
|
||||
.register();
|
||||
|
|
|
@ -12,6 +12,7 @@ public enum ActorVertexAttributes implements IVertexAttrib {
|
|||
AXIS("aAxis", CommonAttributes.NORMAL),
|
||||
INSTANCE_ROTATION("aInstanceRot", CommonAttributes.VEC3),
|
||||
ROTATION_CENTER("aRotationCenter", CommonAttributes.NORMAL),
|
||||
SPEED("aSpeed", CommonAttributes.FLOAT),
|
||||
;
|
||||
|
||||
private final String name;
|
||||
|
|
|
@ -30,6 +30,8 @@ public class ContraptionActorData extends InstanceData {
|
|||
private byte rotationCenterY = 64;
|
||||
private byte rotationCenterZ = 64;
|
||||
|
||||
private float speed;
|
||||
|
||||
protected ContraptionActorData(InstancedModel<?> owner) {
|
||||
super(owner);
|
||||
}
|
||||
|
@ -57,6 +59,11 @@ public class ContraptionActorData extends InstanceData {
|
|||
return this;
|
||||
}
|
||||
|
||||
public ContraptionActorData setSpeed(float speed) {
|
||||
this.speed = speed;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ContraptionActorData setRotationAxis(Vector3f axis) {
|
||||
setRotationAxis(axis.getX(), axis.getY(), axis.getZ());
|
||||
return this;
|
||||
|
@ -101,6 +108,7 @@ public class ContraptionActorData extends InstanceData {
|
|||
putVec3(buf, rotationAxisX, rotationAxisY, rotationAxisZ);
|
||||
putVec3(buf, localRotationX, localRotationY, localRotationZ);
|
||||
putVec3(buf, rotationCenterX, rotationCenterY, rotationCenterZ);
|
||||
put(buf, speed);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -22,23 +22,6 @@ public class DrillInstance extends SingleRotatingInstance {
|
|||
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
|
||||
protected InstancedModel<RotatingData> getModel() {
|
||||
return AllBlockPartials.DRILL_HEAD.renderOnDirectionalSouthRotating(modelManager, tile.getBlockState());
|
||||
|
|
|
@ -2,6 +2,8 @@ package com.simibubi.create.content.contraptions.components.actors;
|
|||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
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.foundation.render.backend.FastRenderDispatcher;
|
||||
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.OnlyIn;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class DrillMovementBehaviour extends BlockBreakingMovementBehaviour {
|
||||
|
||||
@Override
|
||||
|
@ -42,9 +46,10 @@ public class DrillMovementBehaviour extends BlockBreakingMovementBehaviour {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public void addInstance(RenderedContraption contraption, MovementContext context) {
|
||||
DrillInstance.addInstanceForContraption(contraption, context);
|
||||
public ActorInstance createInstance(ContraptionKineticRenderer kr, MovementContext context) {
|
||||
return new DrillActorInstance(kr, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -42,7 +42,7 @@ public class DrillRenderer extends KineticTileEntityRenderer {
|
|||
Direction facing = state.get(DrillBlock.FACING);
|
||||
|
||||
float speed = (float) (context.contraption.stalled
|
||||
|| !VecHelper.isVecPointingTowards(context.relativeMotion, state.get(FACING)
|
||||
|| !VecHelper.isVecPointingTowards(context.relativeMotion, facing
|
||||
.getOpposite()) ? context.getAnimationSpeed() : 0);
|
||||
float time = AnimationTickHolder.getRenderTime() / 20;
|
||||
float angle = (float) (((time * speed) % 360));
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -2,6 +2,8 @@ package com.simibubi.create.content.contraptions.components.actors;
|
|||
|
||||
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 com.mojang.blaze3d.matrix.MatrixStack;
|
||||
|
@ -29,6 +31,8 @@ import net.minecraft.util.math.Vec3d;
|
|||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.IPlantable;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class HarvesterMovementBehaviour extends MovementBehaviour {
|
||||
|
||||
@Override
|
||||
|
@ -42,9 +46,10 @@ public class HarvesterMovementBehaviour extends MovementBehaviour {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public void addInstance(RenderedContraption contraption, MovementContext context) {
|
||||
HarvesterRenderer.addInstanceForContraption(contraption, context);
|
||||
public ActorInstance createInstance(ContraptionKineticRenderer kr, MovementContext context) {
|
||||
return new HarvesterActorInstance(kr, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -43,24 +43,6 @@ public class HarvesterRenderer extends SafeTileEntityRenderer<HarvesterTileEntit
|
|||
.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,
|
||||
IRenderTypeBuffer buffers) {
|
||||
BlockState blockState = context.state;
|
||||
|
@ -90,7 +72,4 @@ public class HarvesterRenderer extends SafeTileEntityRenderer<HarvesterTileEntit
|
|||
.rotate(Direction.WEST, AngleHelper.rad(angle))
|
||||
.translate(-rotOffset.x, -rotOffset.y, -rotOffset.z);
|
||||
}
|
||||
|
||||
public static void transformHead(MatrixStack ms, float angle) {}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -3,6 +3,9 @@ package com.simibubi.create.content.contraptions.components.deployer;
|
|||
import java.util.Arrays;
|
||||
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 com.mojang.blaze3d.matrix.MatrixStack;
|
||||
|
@ -24,6 +27,8 @@ import net.minecraft.util.math.Vec3d;
|
|||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.common.util.Constants.NBT;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class DeployerMovementBehaviour extends MovementBehaviour {
|
||||
|
||||
@Override
|
||||
|
@ -167,7 +172,18 @@ public class DeployerMovementBehaviour extends MovementBehaviour {
|
|||
@Override
|
||||
public void renderInContraption(MovementContext context, MatrixStack ms, MatrixStack msLocal,
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,11 +50,17 @@ public class DeployerRenderer extends SafeTileEntityRenderer<DeployerTileEntity>
|
|||
int light, int overlay) {
|
||||
renderItem(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);
|
||||
}
|
||||
|
||||
protected void renderItem(DeployerTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
||||
int light, int overlay) {
|
||||
|
||||
if (te.heldItem.isEmpty()) return;
|
||||
|
||||
BlockState deployerState = te.getBlockState();
|
||||
Vec3d offset = getHandOffset(te, partialTicks, deployerState).add(VecHelper.getCenterOf(BlockPos.ZERO));
|
||||
ms.push();
|
||||
|
@ -166,8 +172,7 @@ public class DeployerRenderer extends SafeTileEntityRenderer<DeployerTileEntity>
|
|||
BlockPos pos = BlockPos.ZERO;
|
||||
Mode mode = NBTHelper.readEnum(context.tileData, "Mode", Mode.class);
|
||||
World world = context.world;
|
||||
AllBlockPartials handPose =
|
||||
mode == Mode.PUNCH ? AllBlockPartials.DEPLOYER_HAND_PUNCHING : AllBlockPartials.DEPLOYER_HAND_POINTING;
|
||||
AllBlockPartials handPose = getHandPose(mode);
|
||||
|
||||
SuperByteBuffer pole = AllBlockPartials.DEPLOYER_POLE.renderOn(blockState);
|
||||
SuperByteBuffer hand = handPose.renderOn(blockState);
|
||||
|
@ -198,4 +203,8 @@ public class DeployerRenderer extends SafeTileEntityRenderer<DeployerTileEntity>
|
|||
.renderInto(ms, builder);
|
||||
}
|
||||
|
||||
static AllBlockPartials getHandPose(DeployerTileEntity.Mode mode) {
|
||||
return mode == DeployerTileEntity.Mode.PUNCH ? AllBlockPartials.DEPLOYER_HAND_PUNCHING : AllBlockPartials.DEPLOYER_HAND_POINTING;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement;
|
||||
|
||||
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 net.minecraft.client.renderer.IRenderTypeBuffer;
|
||||
|
@ -8,10 +10,13 @@ import net.minecraft.entity.item.ItemEntity;
|
|||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
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.OnlyIn;
|
||||
import net.minecraftforge.items.ItemHandlerHelper;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class MovementBehaviour {
|
||||
|
||||
public boolean isActive(MovementContext context) {
|
||||
|
@ -61,7 +66,10 @@ public abstract class MovementBehaviour {
|
|||
IRenderTypeBuffer buffer) {}
|
||||
|
||||
@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) {
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -1,20 +1,41 @@
|
|||
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.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.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.logistics.block.FlapInstancedModel;
|
||||
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.instancing.InstancedTileRenderer;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
|
||||
import com.simibubi.create.foundation.render.backend.instancing.*;
|
||||
|
||||
import com.simibubi.create.foundation.render.backend.instancing.impl.BasicInstancedModel;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
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> {
|
||||
|
||||
protected ArrayList<ActorInstance> actors = new ArrayList<>();
|
||||
|
||||
public final RenderedContraption contraption;
|
||||
|
||||
ContraptionKineticRenderer(RenderedContraption contraption) {
|
||||
this.contraption = contraption;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerMaterials() {
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
@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
|
||||
public BlockPos getOriginCoordinate() {
|
||||
return BlockPos.ZERO;
|
||||
|
|
|
@ -64,7 +64,7 @@ public class RenderedContraption {
|
|||
public RenderedContraption(World world, Contraption contraption) {
|
||||
this.contraption = contraption;
|
||||
this.lighter = contraption.makeLighter();
|
||||
this.kinetics = new ContraptionKineticRenderer();
|
||||
this.kinetics = new ContraptionKineticRenderer(this);
|
||||
this.renderWorld = setupRenderWorld(world, contraption);
|
||||
|
||||
buildLayers();
|
||||
|
@ -86,10 +86,6 @@ public class RenderedContraption {
|
|||
return lighter;
|
||||
}
|
||||
|
||||
public RenderMaterial<?, InstancedModel<ContraptionActorData>> getActorMaterial() {
|
||||
return kinetics.getMaterial(KineticRenderMaterials.ACTORS);
|
||||
}
|
||||
|
||||
public void doRenderLayer(RenderType layer, ContraptionProgram shader) {
|
||||
ContraptionModel structure = renderLayers.get(layer);
|
||||
if (structure != null) {
|
||||
|
@ -172,18 +168,7 @@ public class RenderedContraption {
|
|||
}
|
||||
|
||||
private void buildActors() {
|
||||
List<MutablePair<Template.BlockInfo, MovementContext>> actors = contraption.getActors();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
contraption.getActors().forEach(kinetics::createActor);
|
||||
}
|
||||
|
||||
private static ContraptionModel buildStructureModel(PlacementSimulationWorld renderWorld, Contraption c, RenderType layer) {
|
||||
|
|
|
@ -109,4 +109,18 @@ public class MatrixStacker {
|
|||
return this;
|
||||
}
|
||||
|
||||
public MatrixStacker push() {
|
||||
ms.push();
|
||||
return this;
|
||||
}
|
||||
|
||||
public MatrixStacker pop() {
|
||||
ms.pop();
|
||||
return this;
|
||||
}
|
||||
|
||||
public MatrixStack unwrap() {
|
||||
return ms;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -60,7 +60,8 @@ public class VecHelper {
|
|||
}
|
||||
|
||||
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) {
|
||||
|
|
|
@ -12,6 +12,7 @@ attribute float aOffset;
|
|||
attribute vec3 aAxis;
|
||||
attribute vec3 aInstanceRot;
|
||||
attribute vec3 aRotationCenter;
|
||||
attribute float aSpeed;
|
||||
|
||||
|
||||
varying float Diffuse;
|
||||
|
@ -57,11 +58,10 @@ mat4 rotation(vec3 rot) {
|
|||
}
|
||||
|
||||
mat4 kineticRotation() {
|
||||
const float speed = -20.;
|
||||
float degrees = aOffset + uTime * speed * -3./10.;
|
||||
float degrees = aOffset + uTime * aSpeed / 20.;
|
||||
float angle = fract(degrees / 360.) * PI * 2.;
|
||||
|
||||
return rotate(normalize(aAxis), angle);
|
||||
return rotate(normalize(aAxis), -angle);
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
|
Loading…
Reference in a new issue