Partially complete

- Begin work moving fully to partial models
- Add rotateToFace and rotateTo methods to RotatingInstance
- Port:
  - ShaftVisual (pulleys, chain drives, press, etc.)
  - Saw
  - Hand crank
  - Valve handle (now a separate visual)
  - Rope pulley
  - Flywheel
- Where possible in the above visuals, combine the models from different
  axes/facings
This commit is contained in:
Jozufozu 2025-01-16 19:04:37 -08:00
parent a1bcf6be5f
commit 86e14b3828
14 changed files with 184 additions and 85 deletions

View file

@ -95,6 +95,7 @@ import com.simibubi.create.content.kinetics.crank.HandCrankBlockEntity;
import com.simibubi.create.content.kinetics.crank.HandCrankRenderer;
import com.simibubi.create.content.kinetics.crank.HandCrankVisual;
import com.simibubi.create.content.kinetics.crank.ValveHandleBlockEntity;
import com.simibubi.create.content.kinetics.crank.ValveHandleVisual;
import com.simibubi.create.content.kinetics.crusher.CrushingWheelBlockEntity;
import com.simibubi.create.content.kinetics.crusher.CrushingWheelControllerBlockEntity;
import com.simibubi.create.content.kinetics.deployer.DeployerBlockEntity;
@ -349,7 +350,7 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<ValveHandleBlockEntity> VALVE_HANDLE = REGISTRATE
.blockEntity("valve_handle", ValveHandleBlockEntity::new)
.visual(() -> HandCrankVisual::new)
.visual(() -> ValveHandleVisual::new)
.validBlocks(AllBlocks.COPPER_VALVE_HANDLE)
.validBlocks(AllBlocks.DYED_VALVE_HANDLES.toArray())
.renderer(() -> HandCrankRenderer::new)
@ -506,7 +507,7 @@ public class AllBlockEntityTypes {
.validBlocks(AllBlocks.PACKAGER)
.renderer(() -> PackagerRenderer::new)
.register();
public static final BlockEntityEntry<RepackagerBlockEntity> REPACKAGER = REGISTRATE
.blockEntity("repackager", RepackagerBlockEntity::new)
.validBlocks(AllBlocks.REPACKAGER)

View file

@ -26,6 +26,7 @@ public class AllPartialModels {
SHAFTLESS_COGWHEEL = block("cogwheel_shaftless"), SHAFTLESS_LARGE_COGWHEEL = block("large_cogwheel_shaftless"),
COGWHEEL_SHAFT = block("cogwheel_shaft"), SHAFT_HALF = block("shaft_half"),
SHAFT = block("shaft"),
BELT_PULLEY = block("belt_pulley"), BELT_START = block("belt/start"), BELT_MIDDLE = block("belt/middle"),
BELT_END = block("belt/end"), BELT_START_BOTTOM = block("belt/start_bottom"),
@ -38,6 +39,8 @@ public class AllPartialModels {
BRASS_BELT_COVER_Z = block("belt_cover/brass_belt_cover_z"),
ENCASED_FAN_INNER = block("encased_fan/propeller"), HAND_CRANK_HANDLE = block("hand_crank/handle"),
HAND_CRANK_BASE = block("hand_crank/block"),
VALVE_HANDLE = block("valve_handle"),
MECHANICAL_PRESS_HEAD = block("mechanical_press/head"), MECHANICAL_MIXER_POLE = block("mechanical_mixer/pole"),
MECHANICAL_MIXER_HEAD = block("mechanical_mixer/head"),
MECHANICAL_CRAFTER_LID = block("mechanical_crafter/lid"),
@ -71,6 +74,8 @@ public class AllPartialModels {
ROPE_COIL = block("rope_pulley/rope_coil"), ROPE_HALF = block("rope_pulley/rope_half"),
ROPE_HALF_MAGNET = block("rope_pulley/rope_half_magnet"),
ROPE = block("rope_pulley/rope"),
PULLEY_MAGNET = block("rope_pulley/pulley_magnet"),
HOSE_COIL = block("hose_pulley/hose_coil"), HOSE = block("hose_pulley/rope"),
HOSE_MAGNET = block("hose_pulley/pulley_magnet"), HOSE_HALF = block("hose_pulley/rope_half"),
@ -85,7 +90,7 @@ public class AllPartialModels {
SYMMETRY_TRIPLEPLANE = block("symmetry_effect/tripleplane"),
STICKER_HEAD = block("sticker/head"),
DESK_BELL_PLUNGER = block("desk_bell/plunger"),
DESK_BELL_BELL = block("desk_bell/bell"),
@ -127,7 +132,7 @@ public class AllPartialModels {
PACKAGER_TRAY_REGULAR = block("packager/tray"), PACKAGER_TRAY_DEFRAG = block("repackager/tray"),
PACKAGER_HATCH_OPEN = block("packager/hatch_open"), PACKAGER_HATCH_CLOSED = block("packager/hatch_closed"),
TABLE_CLOTH_PRICE_SIDE = block("table_cloth/price_tag_side"),
TABLE_CLOTH_PRICE_TOP = block("table_cloth/price_tag_top"),
@ -187,7 +192,7 @@ public class AllPartialModels {
WATER_WHEEL = block("water_wheel/wheel"), LARGE_WATER_WHEEL = block("large_water_wheel/block"),
LARGE_WATER_WHEEL_EXTENSION = block("large_water_wheel/block_extension"),
FACTORY_PANEL = block("factory_gauge/panel"),
FACTORY_PANEL_WITH_BULB = block("factory_gauge/panel_with_bulb"),
FACTORY_PANEL_RESTOCKER = block("factory_gauge/panel_restocker"),
@ -199,7 +204,9 @@ public class AllPartialModels {
TABLE_CLOTH_NE = block("table_cloth/north_east"),
TABLE_CLOTH_SW = block("table_cloth/south_west"),
TABLE_CLOTH_SE = block("table_cloth/south_east"),
FLYWHEEL = block("flywheel/block"),
CRAFTING_BLUEPRINT_1x1 = entity("crafting_blueprint_small"),
CRAFTING_BLUEPRINT_2x2 = entity("crafting_blueprint_medium"),
CRAFTING_BLUEPRINT_3x3 = entity("crafting_blueprint_large"),
@ -217,7 +224,7 @@ public class AllPartialModels {
public static final Map<Direction, PartialModel> FACTORY_PANEL_ARROWS = new EnumMap<>(Direction.class);
public static final Map<Direction, PartialModel> FACTORY_PANEL_LINES = new EnumMap<>(Direction.class);
public static final Map<Direction, PartialModel> FACTORY_PANEL_DOTTED = new EnumMap<>(Direction.class);
public static final Map<Direction, PartialModel> METAL_GIRDER_BRACKETS = new EnumMap<>(Direction.class);
public static final Map<DyeColor, PartialModel> TOOLBOX_LIDS = new EnumMap<>(DyeColor.class);
public static final Map<ResourceLocation, Couple<PartialModel>> FOLDING_DOORS = new HashMap<>();

View file

@ -22,12 +22,12 @@ public class RopePulleyVisual extends AbstractPulleyVisual<PulleyBlockEntity> {
@Override
protected Instancer<TransformedInstance> getRopeModel() {
return instancerProvider().instancer(InstanceTypes.TRANSFORMED, VirtualRenderHelper.blockModel(AllBlocks.ROPE.getDefaultState()));
return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ROPE));
}
@Override
protected Instancer<TransformedInstance> getMagnetModel() {
return instancerProvider().instancer(InstanceTypes.TRANSFORMED, VirtualRenderHelper.blockModel(AllBlocks.PULLEY_MAGNET.getDefaultState()));
return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.PULLEY_MAGNET));
}
@Override
@ -54,10 +54,10 @@ public class RopePulleyVisual extends AbstractPulleyVisual<PulleyBlockEntity> {
protected boolean isRunning() {
return PulleyRenderer.isPulleyRunning(blockEntity);
}
@Override
protected SpriteShiftEntry getCoilAnimation() {
return AllSpriteShifts.ROPE_PULLEY_COIL;
}
}

View file

@ -43,6 +43,24 @@ public class RotatingInstance extends ColoredLitInstance {
return 0xFFFFFF;
}
public RotatingInstance rotateToFace(Direction.Axis axis) {
Direction orientation = Direction.get(Direction.AxisDirection.POSITIVE, axis);
return rotateToFace(orientation);
}
public RotatingInstance rotateToFace(Direction orientation) {
return rotateToFace(orientation.getStepX(), orientation.getStepY(), orientation.getStepZ());
}
public RotatingInstance rotateToFace(float stepX, float stepY, float stepZ) {
return rotateTo(0, 1, 0, stepX, stepY, stepZ);
}
public RotatingInstance rotateTo(float fromX, float fromY, float fromZ, float toX, float toY, float toZ) {
rotation.rotateTo(fromX, fromY, fromZ, toX, toY, toZ);
return this;
}
public RotatingInstance setRotationAxis(Direction.Axis axis) {
Direction orientation = Direction.get(Direction.AxisDirection.POSITIVE, axis);
return setRotationAxis(orientation.step());

View file

@ -1,8 +1,10 @@
package com.simibubi.create.content.kinetics.base;
import dev.engine_room.flywheel.api.model.Model;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.foundation.render.AllInstanceTypes;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import net.createmod.catnip.render.VirtualRenderHelper;
import dev.engine_room.flywheel.lib.model.Models;
public class ShaftVisual<T extends KineticBlockEntity> extends SingleRotatingVisual<T> {
@ -11,7 +13,9 @@ public class ShaftVisual<T extends KineticBlockEntity> extends SingleRotatingVis
}
@Override
protected Model model() {
return VirtualRenderHelper.blockModel(shaft());
public RotatingInstance createRotatingInstance() {
return instancerProvider().instancer(AllInstanceTypes.ROTATING, Models.partial(AllPartialModels.SHAFT))
.createInstance()
.rotateToFace(rotationAxis());
}
}

View file

@ -11,12 +11,11 @@ import net.createmod.catnip.render.VirtualRenderHelper;
public class SingleRotatingVisual<T extends KineticBlockEntity> extends KineticBlockEntityVisual<T> {
protected RotatingInstance rotatingModel;
protected final RotatingInstance rotatingModel;
public SingleRotatingVisual(VisualizationContext context, T blockEntity, float partialTick) {
super(context, blockEntity, partialTick);
rotatingModel = instancerProvider().instancer(AllInstanceTypes.ROTATING, model())
.createInstance();
rotatingModel = createRotatingInstance();
setup(rotatingModel);
}
@ -35,6 +34,11 @@ public class SingleRotatingVisual<T extends KineticBlockEntity> extends KineticB
rotatingModel.delete();
}
public RotatingInstance createRotatingInstance() {
return instancerProvider().instancer(AllInstanceTypes.ROTATING, model())
.createInstance();
}
protected Model model() {
return VirtualRenderHelper.blockModel(blockState);
}

View file

@ -100,14 +100,6 @@ public class HandCrankBlockEntity extends GeneratingKineticBlockEntity {
return CachedBuffers.partialFacing(AllPartialModels.HAND_CRANK_HANDLE, blockState, facing.getOpposite());
}
@OnlyIn(Dist.CLIENT)
public Model getRenderedHandleInstance() {
BlockState blockState = getBlockState();
Direction facing = blockState.getOptionalValue(HandCrankBlock.FACING)
.orElse(Direction.UP);
return Models.partial(AllPartialModels.HAND_CRANK_HANDLE, facing.getOpposite());
}
@OnlyIn(Dist.CLIENT)
public boolean shouldRenderShaft() {
return true;

View file

@ -2,6 +2,9 @@ package com.simibubi.create.content.kinetics.crank;
import java.util.function.Consumer;
import org.joml.Quaternionf;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.kinetics.base.KineticBlockEntityVisual;
import com.simibubi.create.content.kinetics.base.RotatingInstance;
import com.simibubi.create.foundation.render.AllInstanceTypes;
@ -12,31 +15,27 @@ import dev.engine_room.flywheel.api.visual.DynamicVisual;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.instance.InstanceTypes;
import dev.engine_room.flywheel.lib.instance.TransformedInstance;
import dev.engine_room.flywheel.lib.model.Models;
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
import net.createmod.catnip.render.VirtualRenderHelper;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
public class HandCrankVisual extends KineticBlockEntityVisual<HandCrankBlockEntity> implements SimpleDynamicVisual {
protected RotatingInstance rotatingModel;
private final RotatingInstance rotatingModel;
private final TransformedInstance crank;
private final Direction facing;
public HandCrankVisual(VisualizationContext modelManager, HandCrankBlockEntity blockEntity, float partialTick) {
super(modelManager, blockEntity, partialTick);
facing = blockState.getValue(BlockStateProperties.FACING);
Model model = blockEntity.getRenderedHandleInstance();
crank = instancerProvider().instancer(InstanceTypes.TRANSFORMED, model)
crank = instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.HAND_CRANK_HANDLE))
.createInstance();
rotateCrank(partialTick);
if (blockEntity.shouldRenderShaft()) {
rotatingModel = instancerProvider().instancer(AllInstanceTypes.ROTATING, VirtualRenderHelper.blockModel(blockState))
.createInstance();
setup(rotatingModel);
}
rotatingModel = instancerProvider().instancer(AllInstanceTypes.ROTATING, Models.partial(AllPartialModels.HAND_CRANK_BASE))
.createInstance()
.rotateToFace(blockState.getValue(BlockStateProperties.FACING));
setup(rotatingModel);
}
@Override
@ -45,13 +44,14 @@ public class HandCrankVisual extends KineticBlockEntityVisual<HandCrankBlockEnti
}
private void rotateCrank(float pt) {
Direction.Axis axis = facing.getAxis();
var facing = blockState.getValue(BlockStateProperties.FACING);
float angle = blockEntity.getIndependentAngle(pt);
crank.setIdentityTransform()
.translate(getVisualPosition())
.center()
.rotate(angle, Direction.get(Direction.AxisDirection.POSITIVE, axis))
.rotate(angle, Direction.get(Direction.AxisDirection.POSITIVE, facing.getAxis()))
.rotate(new Quaternionf().rotateTo(0, 0, -1, facing.getStepX(), facing.getStepY(), facing.getStepZ()))
.uncenter()
.setChanged();
}
@ -59,16 +59,12 @@ public class HandCrankVisual extends KineticBlockEntityVisual<HandCrankBlockEnti
@Override
protected void _delete() {
crank.delete();
if (rotatingModel != null) {
rotatingModel.delete();
}
rotatingModel.delete();
}
@Override
public void update(float pt) {
if (rotatingModel != null)
updateRotation(rotatingModel);
updateRotation(rotatingModel);
}
@Override

View file

@ -2,8 +2,11 @@ package com.simibubi.create.content.kinetics.crank;
import java.util.List;
import org.jetbrains.annotations.Nullable;
import com.google.common.collect.ImmutableList;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer;
import com.simibubi.create.content.kinetics.transmission.sequencer.SequencedGearshiftBlockEntity.SequenceContext;
@ -17,6 +20,7 @@ import com.simibubi.create.foundation.blockEntity.behaviour.scrollValue.ScrollVa
import com.simibubi.create.foundation.utility.CreateLang;
import dev.engine_room.flywheel.api.model.Model;
import dev.engine_room.flywheel.lib.model.Models;
import net.createmod.catnip.render.CachedBuffers;
import net.createmod.catnip.render.SuperByteBuffer;
import net.createmod.catnip.render.VirtualRenderHelper;
@ -147,12 +151,6 @@ public class ValveHandleBlockEntity extends HandCrankBlockEntity {
return CachedBuffers.block(getBlockState());
}
@Override
@OnlyIn(Dist.CLIENT)
public Model getRenderedHandleInstance() {
return VirtualRenderHelper.blockModel(getBlockState());
}
@Override
@OnlyIn(Dist.CLIENT)
public boolean shouldRenderShaft() {

View file

@ -0,0 +1,66 @@
package com.simibubi.create.content.kinetics.crank;
import java.util.function.Consumer;
import org.joml.Quaternionf;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.kinetics.base.KineticBlockEntityVisual;
import com.simibubi.create.content.kinetics.base.RotatingInstance;
import com.simibubi.create.foundation.render.AllInstanceTypes;
import dev.engine_room.flywheel.api.instance.Instance;
import dev.engine_room.flywheel.api.model.Model;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.instance.InstanceTypes;
import dev.engine_room.flywheel.lib.instance.TransformedInstance;
import dev.engine_room.flywheel.lib.model.Models;
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
public class ValveHandleVisual extends KineticBlockEntityVisual<HandCrankBlockEntity> implements SimpleDynamicVisual {
private final TransformedInstance crank;
public ValveHandleVisual(VisualizationContext modelManager, HandCrankBlockEntity blockEntity, float partialTick) {
super(modelManager, blockEntity, partialTick);
crank = instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.VALVE_HANDLE))
.createInstance();
rotateCrank(partialTick);
}
@Override
public void beginFrame(Context ctx) {
rotateCrank(ctx.partialTick());
}
private void rotateCrank(float pt) {
var facing = blockState.getValue(BlockStateProperties.FACING);
float angle = blockEntity.getIndependentAngle(pt);
crank.setIdentityTransform()
.translate(getVisualPosition())
.center()
.rotate(angle, Direction.get(Direction.AxisDirection.POSITIVE, facing.getAxis()))
.rotate(new Quaternionf().rotateTo(0, 1, 0, facing.getStepX(), facing.getStepY(), facing.getStepZ()))
.uncenter()
.setChanged();
}
@Override
protected void _delete() {
crank.delete();
}
@Override
public void updateLight(float partialTick) {
relight(crank);
}
@Override
public void collectCrumblingInstances(Consumer<Instance> consumer) {
consumer.accept(crank);
}
}

View file

@ -19,7 +19,6 @@ import dev.engine_room.flywheel.lib.instance.InstanceTypes;
import dev.engine_room.flywheel.lib.instance.TransformedInstance;
import dev.engine_room.flywheel.lib.model.Models;
import dev.engine_room.flywheel.lib.model.baked.PartialModel;
import net.createmod.catnip.render.VirtualRenderHelper;
import net.createmod.catnip.utility.AnimationTickHolder;
import net.createmod.catnip.utility.NBTHelper;
import net.createmod.catnip.utility.VecHelper;
@ -60,8 +59,9 @@ public class DeployerActorVisual extends ActorVisual {
hand = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(handPose)).createInstance();
Direction.Axis axis = KineticBlockEntityVisual.rotationAxis(state);
shaft = instancerProvider.instancer(AllInstanceTypes.ROTATING, VirtualRenderHelper.blockModel(KineticBlockEntityVisual.shaft(axis)))
.createInstance();
shaft = instancerProvider.instancer(AllInstanceTypes.ROTATING, Models.partial(AllPartialModels.SHAFT))
.createInstance()
.rotateToFace(axis);
int blockLight = localBlockLight();

View file

@ -2,7 +2,10 @@ package com.simibubi.create.content.kinetics.flywheel;
import java.util.function.Consumer;
import com.mojang.blaze3d.vertex.PoseStack;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.kinetics.base.KineticBlockEntityVisual;
import com.simibubi.create.content.kinetics.base.RotatingInstance;
import com.simibubi.create.foundation.render.AllInstanceTypes;
@ -12,9 +15,8 @@ import dev.engine_room.flywheel.api.visual.DynamicVisual;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.instance.InstanceTypes;
import dev.engine_room.flywheel.lib.instance.TransformedInstance;
import dev.engine_room.flywheel.lib.transform.TransformStack;
import dev.engine_room.flywheel.lib.model.Models;
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
import net.createmod.catnip.render.VirtualRenderHelper;
import net.createmod.catnip.utility.math.AngleHelper;
import net.minecraft.core.Direction;
@ -24,14 +26,27 @@ public class FlywheelVisual extends KineticBlockEntityVisual<FlywheelBlockEntity
protected final TransformedInstance wheel;
protected float lastAngle = Float.NaN;
protected final Matrix4f baseTransform = new Matrix4f();
public FlywheelVisual(VisualizationContext context, FlywheelBlockEntity blockEntity, float partialTick) {
super(context, blockEntity, partialTick);
shaft = setup(instancerProvider().instancer(AllInstanceTypes.ROTATING, VirtualRenderHelper.blockModel(shaft()))
.createInstance());
wheel = instancerProvider().instancer(InstanceTypes.TRANSFORMED, VirtualRenderHelper.blockModel(blockState))
var axis = rotationAxis();
shaft = setup(instancerProvider().instancer(AllInstanceTypes.ROTATING, Models.partial(AllPartialModels.SHAFT))
.createInstance())
.rotateToFace(axis);
wheel = instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.FLYWHEEL))
.createInstance();
Direction align = Direction.fromAxisAndDirection(axis, Direction.AxisDirection.POSITIVE);
wheel.translate(getVisualPosition())
.center()
.rotate(new Quaternionf().rotateTo(0, 1, 0, align.getStepX(), align.getStepY(), align.getStepZ()));
baseTransform.set(wheel.pose);
animate(blockEntity.angle);
}
@ -52,16 +67,10 @@ public class FlywheelVisual extends KineticBlockEntityVisual<FlywheelBlockEntity
}
private void animate(float angle) {
PoseStack ms = new PoseStack();
var msr = TransformStack.of(ms);
msr.translate(getVisualPosition());
msr.center()
.rotate(AngleHelper.rad(angle), Direction.get(Direction.AxisDirection.POSITIVE, rotationAxis()))
.uncenter();
wheel.setTransform(ms)
.setChanged();
wheel.setTransform(baseTransform)
.rotateY(AngleHelper.rad(angle))
.uncenter()
.setChanged();
}
@Override

View file

@ -17,8 +17,7 @@ public class SawActorVisual extends ActorVisual {
var state = movementContext.state;
var localPos = movementContext.localPos;
shaft = instancerProvider.instancer(AllInstanceTypes.ROTATING, SawVisual.shaftModel(simulationWorld, localPos, state))
.createInstance();
shaft = SawVisual.shaft(instancerProvider, simulationWorld, localPos, state);
var axis = KineticBlockEntityVisual.rotationAxis(state);
shaft.setRotationAxis(axis)

View file

@ -1,15 +1,16 @@
package com.simibubi.create.content.kinetics.saw;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.content.kinetics.base.KineticBlockEntityVisual;
import com.simibubi.create.content.kinetics.base.RotatingInstance;
import com.simibubi.create.content.kinetics.base.SingleRotatingVisual;
import com.simibubi.create.foundation.render.AllInstanceTypes;
import dev.engine_room.flywheel.api.model.Model;
import dev.engine_room.flywheel.api.instance.InstancerProvider;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
import dev.engine_room.flywheel.lib.model.Models;
import net.createmod.catnip.render.VirtualRenderHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.Rotation;
import net.minecraft.world.level.block.state.BlockState;
@ -22,19 +23,23 @@ public class SawVisual extends SingleRotatingVisual<SawBlockEntity> {
}
@Override
protected Model model() {
return shaftModel(level, pos, blockState);
public RotatingInstance createRotatingInstance() {
return shaft(instancerProvider(), level, pos, blockState);
}
public static Model shaftModel(LevelAccessor level, BlockPos pos, BlockState state) {
if (state.getValue(BlockStateProperties.FACING)
.getAxis()
.isHorizontal()) {
BlockState referenceState = state.rotate(level, pos, Rotation.CLOCKWISE_180);
Direction facing = referenceState.getValue(BlockStateProperties.FACING);
return Models.partial(AllPartialModels.SHAFT_HALF, facing);
public static RotatingInstance shaft(InstancerProvider instancerProvider, LevelAccessor level, BlockPos pos, BlockState state) {
var facing = state.getValue(BlockStateProperties.FACING);
var axis = facing
.getAxis();
if (axis.isHorizontal()) {
Direction align = facing.getOpposite();
return instancerProvider.instancer(AllInstanceTypes.ROTATING, Models.partial(AllPartialModels.SHAFT_HALF))
.createInstance()
.rotateTo(0, 0, 1, align.getStepX(), align.getStepY(), align.getStepZ());
} else {
return VirtualRenderHelper.blockModel(KineticBlockEntityVisual.shaft(state));
return instancerProvider.instancer(AllInstanceTypes.ROTATING, Models.partial(AllPartialModels.SHAFT))
.createInstance()
.rotateToFace(state.getValue(SawBlock.AXIS_ALONG_FIRST_COORDINATE) ? Axis.X : Axis.Z);
}
}
}