Secret Spinformation II: Hypervalve Decoder

- Integrated new valve handle model
- Valve handles can now be used to precisely turn mechanical bearings by a set angle
This commit is contained in:
simibubi 2023-03-30 00:55:13 +02:00
parent 65fab6f8e5
commit df7e97981a
18 changed files with 1214 additions and 525 deletions

View file

@ -578,7 +578,7 @@ bf2b0310500213ff853c748c236eb5d01f61658e assets/create/blockstates/yellow_toolbo
7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json 7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json
b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json
e4af08f4e51db9c4a722ebff44a04e8bd9a9dba6 assets/create/lang/en_ud.json e4af08f4e51db9c4a722ebff44a04e8bd9a9dba6 assets/create/lang/en_ud.json
e152e8712e17972200850ae7d4e5ce40a5dc9e91 assets/create/lang/en_us.json b14838ef90096d8877aa4ca10e5b261063a41805 assets/create/lang/en_us.json
487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json 487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json
b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json
3066db1bf03cffa1a9c7fbacf47ae586632f4eb3 assets/create/models/block/acacia_window_pane_noside_alt.json 3066db1bf03cffa1a9c7fbacf47ae586632f4eb3 assets/create/models/block/acacia_window_pane_noside_alt.json

View file

@ -961,6 +961,7 @@
"create.generic.length": "Length", "create.generic.length": "Length",
"create.generic.speed": "Speed", "create.generic.speed": "Speed",
"create.generic.delay": "Delay", "create.generic.delay": "Delay",
"create.generic.angle": "Angle",
"create.generic.duration": "Duration", "create.generic.duration": "Duration",
"create.generic.timeUnit": "Time Unit", "create.generic.timeUnit": "Time Unit",
"create.generic.unit.ticks": "Ticks", "create.generic.unit.ticks": "Ticks",
@ -1103,6 +1104,7 @@
"create.kinetics.creative_motor.rotation_speed": "Generated Speed in RPM", "create.kinetics.creative_motor.rotation_speed": "Generated Speed in RPM",
"create.kinetics.speed_controller.rotation_speed": "Targeted Speed in RPM", "create.kinetics.speed_controller.rotation_speed": "Targeted Speed in RPM",
"create.kinetics.valve_handle.rotated_angle": "Rotation when used",
"create.logistics.redstone_interval": "Redstone Interval", "create.logistics.redstone_interval": "Redstone Interval",

View file

@ -30,6 +30,7 @@ import com.simibubi.create.content.contraptions.components.crafter.ShaftlessCogw
import com.simibubi.create.content.contraptions.components.crank.HandCrankBlockEntity; import com.simibubi.create.content.contraptions.components.crank.HandCrankBlockEntity;
import com.simibubi.create.content.contraptions.components.crank.HandCrankInstance; import com.simibubi.create.content.contraptions.components.crank.HandCrankInstance;
import com.simibubi.create.content.contraptions.components.crank.HandCrankRenderer; import com.simibubi.create.content.contraptions.components.crank.HandCrankRenderer;
import com.simibubi.create.content.contraptions.components.crank.ValveHandleBlockEntity;
import com.simibubi.create.content.contraptions.components.crusher.CrushingWheelBlockEntity; import com.simibubi.create.content.contraptions.components.crusher.CrushingWheelBlockEntity;
import com.simibubi.create.content.contraptions.components.crusher.CrushingWheelControllerBlockEntity; import com.simibubi.create.content.contraptions.components.crusher.CrushingWheelControllerBlockEntity;
import com.simibubi.create.content.contraptions.components.deployer.DeployerBlockEntity; import com.simibubi.create.content.contraptions.components.deployer.DeployerBlockEntity;
@ -316,7 +317,14 @@ public class AllBlockEntityTypes {
public static final BlockEntityEntry<HandCrankBlockEntity> HAND_CRANK = REGISTRATE public static final BlockEntityEntry<HandCrankBlockEntity> HAND_CRANK = REGISTRATE
.blockEntity("hand_crank", HandCrankBlockEntity::new) .blockEntity("hand_crank", HandCrankBlockEntity::new)
.instance(() -> HandCrankInstance::new) .instance(() -> HandCrankInstance::new)
.validBlocks(AllBlocks.HAND_CRANK, AllBlocks.COPPER_VALVE_HANDLE) .validBlocks(AllBlocks.HAND_CRANK)
.renderer(() -> HandCrankRenderer::new)
.register();
public static final BlockEntityEntry<ValveHandleBlockEntity> VALVE_HANDLE = REGISTRATE
.blockEntity("valve_handle", ValveHandleBlockEntity::new)
.instance(() -> HandCrankInstance::new)
.validBlocks(AllBlocks.COPPER_VALVE_HANDLE)
.validBlocks(AllBlocks.DYED_VALVE_HANDLES.toArray()) .validBlocks(AllBlocks.DYED_VALVE_HANDLES.toArray())
.renderer(() -> HandCrankRenderer::new) .renderer(() -> HandCrankRenderer::new)
.register(); .register();

View file

@ -56,6 +56,8 @@ public class AllShapes {
.forDirectional(), .forDirectional(),
CRANK = shape(5, 0, 5, 11, 6, 11).add(1, 3, 1, 15, 8, 15) CRANK = shape(5, 0, 5, 11, 6, 11).add(1, 3, 1, 15, 8, 15)
.forDirectional(), .forDirectional(),
VALVE_HANDLE = shape(5, 0, 5, 11, 4, 11).add(1, 3, 1, 15, 8, 15)
.forDirectional(),
CART_ASSEMBLER = shape(0, 12, 0, 16, 16, 16).add(-2, 0, 1, 18, 14, 15) CART_ASSEMBLER = shape(0, 12, 0, 16, 16, 16).add(-2, 0, 1, 18, 14, 15)
.forHorizontalAxis(), .forHorizontalAxis(),
CART_ASSEMBLER_PLAYER_COLLISION = shape(0, 0, 1, 16, 16, 15).forHorizontalAxis(), CART_ASSEMBLER_PLAYER_COLLISION = shape(0, 0, 1, 16, 16, 15).forHorizontalAxis(),

View file

@ -1,8 +1,6 @@
package com.simibubi.create.content.contraptions.components.crank; package com.simibubi.create.content.contraptions.components.crank;
import com.jozufozu.flywheel.core.PartialModel;
import com.simibubi.create.AllBlockEntityTypes; import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.AllShapes; import com.simibubi.create.AllShapes;
import com.simibubi.create.content.contraptions.base.DirectionalKineticBlock; import com.simibubi.create.content.contraptions.base.DirectionalKineticBlock;
import com.simibubi.create.foundation.advancement.AllAdvancements; import com.simibubi.create.foundation.advancement.AllAdvancements;
@ -32,8 +30,6 @@ import net.minecraft.world.level.pathfinder.PathComputationType;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraft.world.phys.shapes.VoxelShape; import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class HandCrankBlock extends DirectionalKineticBlock public class HandCrankBlock extends DirectionalKineticBlock
implements IBE<HandCrankBlockEntity>, ProperWaterloggedBlock { implements IBE<HandCrankBlockEntity>, ProperWaterloggedBlock {
@ -53,11 +49,6 @@ public class HandCrankBlock extends DirectionalKineticBlock
super.createBlockStateDefinition(builder.add(WATERLOGGED)); super.createBlockStateDefinition(builder.add(WATERLOGGED));
} }
@OnlyIn(Dist.CLIENT)
public PartialModel getRenderedHandle() {
return AllPartialModels.HAND_CRANK_HANDLE;
}
public int getRotationSpeed() { public int getRotationSpeed() {
return 32; return 32;
} }
@ -117,14 +108,14 @@ public class HandCrankBlock extends DirectionalKineticBlock
} }
} }
} }
@Override @Override
public BlockState updateShape(BlockState pState, Direction pDirection, BlockState pNeighborState, public BlockState updateShape(BlockState pState, Direction pDirection, BlockState pNeighborState,
LevelAccessor pLevel, BlockPos pCurrentPos, BlockPos pNeighborPos) { LevelAccessor pLevel, BlockPos pCurrentPos, BlockPos pNeighborPos) {
updateWater(pLevel, pState, pCurrentPos); updateWater(pLevel, pState, pCurrentPos);
return pState; return pState;
} }
@Override @Override
public FluidState getFluidState(BlockState pState) { public FluidState getFluidState(BlockState pState) {
return fluidState(pState); return fluidState(pState);

View file

@ -1,11 +1,18 @@
package com.simibubi.create.content.contraptions.components.crank; package com.simibubi.create.content.contraptions.components.crank;
import com.jozufozu.flywheel.api.Instancer;
import com.jozufozu.flywheel.api.Material;
import com.jozufozu.flywheel.core.materials.model.ModelData;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.AllSoundEvents; import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.content.contraptions.base.GeneratingKineticBlockEntity; import com.simibubi.create.content.contraptions.base.GeneratingKineticBlockEntity;
import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.entity.BlockEntityType;
@ -36,25 +43,35 @@ public class HandCrankBlockEntity extends GeneratingKineticBlockEntity {
updateGeneratedRotation(); updateGeneratedRotation();
} }
public float getIndependentAngle(float partialTicks) {
return (independentAngle + partialTicks * chasingVelocity) / 360;
}
@Override @Override
public float getGeneratedSpeed() { public float getGeneratedSpeed() {
Block block = getBlockState().getBlock(); Block block = getBlockState().getBlock();
if (!(block instanceof HandCrankBlock)) if (!(block instanceof HandCrankBlock))
return 0; return 0;
HandCrankBlock crank = (HandCrankBlock) block; HandCrankBlock crank = (HandCrankBlock) block;
int speed = (inUse == 0 ? 0 : backwards ? -1 : 1) * crank.getRotationSpeed(); int speed = (inUse == 0 ? 0 : clockwise() ? -1 : 1) * crank.getRotationSpeed();
return convertToDirection(speed, getBlockState().getValue(HandCrankBlock.FACING)); return convertToDirection(speed, getBlockState().getValue(HandCrankBlock.FACING));
} }
protected boolean clockwise() {
return backwards;
}
@Override @Override
public void write(CompoundTag compound, boolean clientPacket) { public void write(CompoundTag compound, boolean clientPacket) {
compound.putInt("InUse", inUse); compound.putInt("InUse", inUse);
compound.putBoolean("Backwards", backwards);
super.write(compound, clientPacket); super.write(compound, clientPacket);
} }
@Override @Override
protected void read(CompoundTag compound, boolean clientPacket) { protected void read(CompoundTag compound, boolean clientPacket) {
inUse = compound.getInt("InUse"); inUse = compound.getInt("InUse");
backwards = compound.getBoolean("Backwards");
super.read(compound, clientPacket); super.read(compound, clientPacket);
} }
@ -69,11 +86,34 @@ public class HandCrankBlockEntity extends GeneratingKineticBlockEntity {
if (inUse > 0) { if (inUse > 0) {
inUse--; inUse--;
if (inUse == 0 && !level.isClientSide) if (inUse == 0 && !level.isClientSide) {
sequenceContext = null;
updateGeneratedRotation(); updateGeneratedRotation();
}
} }
} }
@OnlyIn(Dist.CLIENT)
public SuperByteBuffer getRenderedHandle() {
BlockState blockState = getBlockState();
Direction facing = blockState.getOptionalValue(HandCrankBlock.FACING)
.orElse(Direction.UP);
return CachedBufferer.partialFacing(AllPartialModels.HAND_CRANK_HANDLE, blockState, facing.getOpposite());
}
@OnlyIn(Dist.CLIENT)
public Instancer<ModelData> getRenderedHandleInstance(Material<ModelData> material) {
BlockState blockState = getBlockState();
Direction facing = blockState.getOptionalValue(HandCrankBlock.FACING)
.orElse(Direction.UP);
return material.getModel(AllPartialModels.HAND_CRANK_HANDLE, blockState, facing.getOpposite());
}
@OnlyIn(Dist.CLIENT)
public boolean shouldRenderShaft() {
return true;
}
@Override @Override
protected Block getStressConfigKey() { protected Block getStressConfigKey() {
return AllBlocks.HAND_CRANK.has(getBlockState()) ? AllBlocks.HAND_CRANK.get() return AllBlocks.HAND_CRANK.has(getBlockState()) ? AllBlocks.HAND_CRANK.get()

View file

@ -3,65 +3,70 @@ package com.simibubi.create.content.contraptions.components.crank;
import com.jozufozu.flywheel.api.Instancer; import com.jozufozu.flywheel.api.Instancer;
import com.jozufozu.flywheel.api.MaterialManager; import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.core.PartialModel;
import com.jozufozu.flywheel.core.materials.model.ModelData; import com.jozufozu.flywheel.core.materials.model.ModelData;
import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; import com.simibubi.create.content.contraptions.base.SingleRotatingInstance;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BlockStateProperties;
public class HandCrankInstance extends SingleRotatingInstance<HandCrankBlockEntity> implements DynamicInstance { public class HandCrankInstance extends SingleRotatingInstance<HandCrankBlockEntity> implements DynamicInstance {
private ModelData crank; private ModelData crank;
private Direction facing; private Direction facing;
public HandCrankInstance(MaterialManager modelManager, HandCrankBlockEntity blockEntity) {
super(modelManager, blockEntity);
Block block = blockState.getBlock();
PartialModel renderedHandle = null;
if (block instanceof HandCrankBlock)
renderedHandle = ((HandCrankBlock) block).getRenderedHandle();
if (renderedHandle == null)
return;
public HandCrankInstance(MaterialManager modelManager, HandCrankBlockEntity blockEntity) {
super(modelManager, blockEntity);
facing = blockState.getValue(BlockStateProperties.FACING); facing = blockState.getValue(BlockStateProperties.FACING);
Direction opposite = facing.getOpposite(); Instancer<ModelData> model = blockEntity.getRenderedHandleInstance(getTransformMaterial());
Instancer<ModelData> model = getTransformMaterial().getModel(renderedHandle, blockState, opposite);
crank = model.createInstance(); crank = model.createInstance();
rotateCrank();
}
@Override
public void beginFrame() {
if (crank == null)
return;
rotateCrank(); rotateCrank();
} }
@Override private void rotateCrank() {
public void beginFrame() { Direction.Axis axis = facing.getAxis();
if (crank == null) return; float angle = blockEntity.getIndependentAngle(AnimationTickHolder.getPartialTicks());
rotateCrank(); crank.loadIdentity()
} .translate(getInstancePosition())
.centre()
private void rotateCrank() { .rotate(Direction.get(Direction.AxisDirection.POSITIVE, axis), angle)
Direction.Axis axis = facing.getAxis(); .unCentre();
float angle = (blockEntity.independentAngle + AnimationTickHolder.getPartialTicks() * blockEntity.chasingVelocity) / 360;
crank.loadIdentity()
.translate(getInstancePosition())
.centre()
.rotate(Direction.get(Direction.AxisDirection.POSITIVE, axis), angle)
.unCentre();
} }
@Override @Override
public void remove() { public void init() {
super.remove(); if (blockEntity.shouldRenderShaft())
if (crank != null) crank.delete(); super.init();
} }
@Override @Override
public void updateLight() { public void remove() {
super.updateLight(); if (blockEntity.shouldRenderShaft())
if (crank != null) relight(pos, crank); super.remove();
} if (crank != null)
crank.delete();
}
@Override
public void update() {
if (blockEntity.shouldRenderShaft())
super.update();
}
@Override
public void updateLight() {
if (blockEntity.shouldRenderShaft())
super.updateLight();
if (crank != null)
relight(pos, crank);
}
} }

View file

@ -3,18 +3,13 @@ package com.simibubi.create.content.contraptions.components.crank;
import static net.minecraft.world.level.block.state.properties.BlockStateProperties.FACING; import static net.minecraft.world.level.block.state.properties.BlockStateProperties.FACING;
import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.core.PartialModel;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.content.contraptions.base.KineticBlockEntityRenderer; import com.simibubi.create.content.contraptions.base.KineticBlockEntityRenderer;
import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
public class HandCrankRenderer extends KineticBlockEntityRenderer<HandCrankBlockEntity> { public class HandCrankRenderer extends KineticBlockEntityRenderer<HandCrankBlockEntity> {
@ -25,23 +20,16 @@ public class HandCrankRenderer extends KineticBlockEntityRenderer<HandCrankBlock
@Override @Override
protected void renderSafe(HandCrankBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer, protected void renderSafe(HandCrankBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer,
int light, int overlay) { int light, int overlay) {
super.renderSafe(be, partialTicks, ms, buffer, light, overlay); if (be.shouldRenderShaft())
super.renderSafe(be, partialTicks, ms, buffer, light, overlay);
if (Backend.canUseInstancing(be.getLevel())) return; if (Backend.canUseInstancing(be.getLevel()))
BlockState state = be.getBlockState();
Block block = state.getBlock();
PartialModel renderedHandle = null;
if (block instanceof HandCrankBlock)
renderedHandle = ((HandCrankBlock) block).getRenderedHandle();
if (renderedHandle == null)
return; return;
Direction facing = state.getValue(FACING); Direction facing = be.getBlockState()
SuperByteBuffer handle = CachedBufferer.partialFacing(renderedHandle, state, facing.getOpposite()); .getValue(FACING);
kineticRotationTransform(handle, be, facing.getAxis(), kineticRotationTransform(be.getRenderedHandle(), be, facing.getAxis(), be.getIndependentAngle(partialTicks),
(be.independentAngle + partialTicks * be.chasingVelocity) / 360, light); light).renderInto(ms, buffer.getBuffer(RenderType.solid()));
handle.renderInto(ms, buffer.getBuffer(RenderType.solid()));
} }
} }

View file

@ -2,8 +2,9 @@ package com.simibubi.create.content.contraptions.components.crank;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import com.jozufozu.flywheel.core.PartialModel; import com.simibubi.create.AllBlockEntityTypes;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllShapes;
import com.simibubi.create.foundation.utility.BlockHelper; import com.simibubi.create.foundation.utility.BlockHelper;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
@ -15,13 +16,20 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.CreativeModeTab;
import net.minecraft.world.item.DyeColor; import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
import net.minecraftforge.api.distmarker.Dist; import net.minecraft.world.phys.shapes.CollisionContext;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraft.world.phys.shapes.VoxelShape;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.eventbus.api.EventPriority;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
@EventBusSubscriber
public class ValveHandleBlock extends HandCrankBlock { public class ValveHandleBlock extends HandCrankBlock {
private final DyeColor color; private final DyeColor color;
@ -42,19 +50,55 @@ public class ValveHandleBlock extends HandCrankBlock {
} }
@Override @Override
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, public VoxelShape getShape(BlockState pState, BlockGetter worldIn, BlockPos pos, CollisionContext context) {
BlockHitResult hit) { return AllShapes.VALVE_HANDLE.get(pState.getValue(FACING));
}
@SubscribeEvent(priority = EventPriority.LOW)
public static void onBlockActivated(PlayerInteractEvent.RightClickBlock event) {
BlockPos pos = event.getPos();
Level level = event.getWorld();
Player player = event.getPlayer();
BlockState blockState = level.getBlockState(pos);
if (!(blockState.getBlock() instanceof ValveHandleBlock vhb))
return;
if (vhb.clicked(level, pos, blockState, player, event.getHand())) {
event.setCanceled(true);
event.setCancellationResult(InteractionResult.SUCCESS);
}
}
@Override
public void onRemove(BlockState pState, Level pLevel, BlockPos pPos, BlockState pNewState, boolean pIsMoving) {
if (!(pNewState.getBlock() instanceof ValveHandleBlock))
super.onRemove(pState, pLevel, pPos, pNewState, pIsMoving);
}
public boolean clicked(Level level, BlockPos pos, BlockState blockState, Player player, InteractionHand hand) {
ItemStack heldItem = player.getItemInHand(hand); ItemStack heldItem = player.getItemInHand(hand);
DyeColor color = DyeColor.getColor(heldItem); DyeColor color = DyeColor.getColor(heldItem);
if (color != null && color != this.color) { if (color != null && color != this.color) {
if (world.isClientSide) if (!level.isClientSide)
return InteractionResult.SUCCESS; level.setBlockAndUpdate(pos,
BlockState newState = BlockHelper.copyProperties(state, AllBlocks.DYED_VALVE_HANDLES.get(color).getDefaultState()); BlockHelper.copyProperties(blockState, AllBlocks.DYED_VALVE_HANDLES.get(color)
world.setBlockAndUpdate(pos, newState); .getDefaultState()));
return InteractionResult.SUCCESS; return true;
} }
return super.use(state, world, pos, player, hand, hit); onBlockEntityUse(level, pos,
hcbe -> (hcbe instanceof ValveHandleBlockEntity vhbe) && vhbe.activate(player.isCrouching())
? InteractionResult.SUCCESS
: InteractionResult.PASS);
return true;
}
@Override
public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand,
BlockHitResult hit) {
return InteractionResult.PASS;
} }
@Override @Override
@ -65,16 +109,15 @@ public class ValveHandleBlock extends HandCrankBlock {
} }
@Override @Override
@OnlyIn(Dist.CLIENT) public BlockEntityType<? extends HandCrankBlockEntity> getBlockEntityType() {
public PartialModel getRenderedHandle() { return AllBlockEntityTypes.VALVE_HANDLE.get();
return null;
} }
@Override @Override
public int getRotationSpeed() { public int getRotationSpeed() {
return 16; return 16;
} }
public static Couple<Integer> getSpeedRange() { public static Couple<Integer> getSpeedRange() {
return Couple.create(16, 16); return Couple.create(16, 16);
} }

View file

@ -0,0 +1,229 @@
package com.simibubi.create.content.contraptions.components.crank;
import java.util.List;
import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.api.Instancer;
import com.jozufozu.flywheel.api.Material;
import com.jozufozu.flywheel.core.materials.model.ModelData;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.base.KineticBlockEntity;
import com.simibubi.create.content.contraptions.base.KineticBlockEntityRenderer;
import com.simibubi.create.content.contraptions.relays.advanced.sequencer.SequencedGearshiftBlockEntity.SequenceContext;
import com.simibubi.create.content.contraptions.relays.advanced.sequencer.SequencerInstructions;
import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour;
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform;
import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsBoard;
import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsFormatter;
import com.simibubi.create.foundation.blockEntity.behaviour.scrollvalue.ScrollValueBehaviour;
import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.utility.Components;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.ChatFormatting;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class ValveHandleBlockEntity extends HandCrankBlockEntity {
public ScrollValueBehaviour angleInput;
public int cooldown;
protected int startAngle;
protected int targetAngle;
protected int totalUseTicks;
public ValveHandleBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
}
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
super.addBehaviours(behaviours);
behaviours.add(angleInput = new ValveHandleScrollValueBehaviour(this).between(-180, 180));
angleInput.onlyActiveWhen(this::showValue);
angleInput.setValue(45);
}
@Override
protected boolean clockwise() {
return angleInput.getValue() < 0 ^ backwards;
}
@Override
public void write(CompoundTag compound, boolean clientPacket) {
super.write(compound, clientPacket);
compound.putInt("TotalUseTicks", totalUseTicks);
compound.putInt("StartAngle", startAngle);
compound.putInt("TargetAngle", targetAngle);
}
@Override
protected void read(CompoundTag compound, boolean clientPacket) {
super.read(compound, clientPacket);
totalUseTicks = compound.getInt("TotalUseTicks");
startAngle = compound.getInt("StartAngle");
targetAngle = compound.getInt("TargetAngle");
}
@Override
public void tick() {
super.tick();
if (inUse == 0 && cooldown > 0)
cooldown--;
independentAngle = getIndependentAngle(0);
}
@Override
public float getIndependentAngle(float partialTicks) {
if (inUse == 0 && source != null && getSpeed() != 0)
return KineticBlockEntityRenderer.getAngleForTe(this, worldPosition,
KineticBlockEntityRenderer.getRotationAxisOf(this));
int step = getBlockState().getOptionalValue(ValveHandleBlock.FACING)
.orElse(Direction.SOUTH)
.getAxisDirection()
.getStep();
return (inUse > 0 && totalUseTicks > 0
? Mth.lerp(Math.min(totalUseTicks, totalUseTicks - inUse + partialTicks) / (float) totalUseTicks,
startAngle, targetAngle)
: targetAngle) * Mth.DEG_TO_RAD * (backwards ? -1 : 1) * step;
}
public boolean showValue() {
return inUse == 0;
}
public boolean activate(boolean sneak) {
if (getTheoreticalSpeed() != 0)
return false;
if (inUse > 0 || cooldown > 0)
return false;
if (level.isClientSide)
return true;
// Always overshoot, target will stop early
int value = angleInput.getValue();
int target = Math.abs(value);
int rotationSpeed = AllBlocks.COPPER_VALVE_HANDLE.get()
.getRotationSpeed();
double degreesPerTick = KineticBlockEntity.convertToAngular(rotationSpeed);
inUse = (int) Math.ceil(target / degreesPerTick) + 2;
startAngle = (int) ((independentAngle) % 90 + 360) % 90;
targetAngle = Math.round((startAngle + (target > 135 ? 180 : 90) * Mth.sign(value)) / 90f) * 90;
totalUseTicks = inUse;
backwards = sneak;
sequenceContext = SequenceContext.fromGearshift(SequencerInstructions.TURN_ANGLE, rotationSpeed, target);
updateGeneratedRotation();
cooldown = 5;
return true;
}
@Override
protected void copySequenceContextFrom(KineticBlockEntity sourceBE) {}
@Override
@OnlyIn(Dist.CLIENT)
public SuperByteBuffer getRenderedHandle() {
return CachedBufferer.block(getBlockState());
}
@Override
@OnlyIn(Dist.CLIENT)
public Instancer<ModelData> getRenderedHandleInstance(Material<ModelData> material) {
return material.getModel(getBlockState());
}
@Override
@OnlyIn(Dist.CLIENT)
public boolean shouldRenderShaft() {
return false;
}
public static class ValveHandleScrollValueBehaviour extends ScrollValueBehaviour {
public ValveHandleScrollValueBehaviour(SmartBlockEntity be) {
super(Lang.translateDirect("kinetics.valve_handle.rotated_angle"), be, new ValveHandleValueBox());
withFormatter(v -> String.valueOf(Math.abs(v)) + Lang.translateDirect("generic.unit.degrees")
.getString());
}
@Override
public ValueSettingsBoard createBoard(Player player, BlockHitResult hitResult) {
ImmutableList<Component> rows = ImmutableList.of(Components.literal("\u27f3")
.withStyle(ChatFormatting.BOLD),
Components.literal("\u27f2")
.withStyle(ChatFormatting.BOLD));
return new ValueSettingsBoard(label, 180, 45, rows, new ValueSettingsFormatter(this::formatValue));
}
@Override
public void setValueSettings(Player player, ValueSettings valueSetting, boolean ctrlHeld) {
int value = Math.max(1, valueSetting.value());
if (!valueSetting.equals(getValueSettings()))
playFeedbackSound(this);
setValue(valueSetting.row() == 0 ? -value : value);
}
@Override
public ValueSettings getValueSettings() {
return new ValueSettings(value < 0 ? 0 : 1, Math.abs(value));
}
public MutableComponent formatValue(ValueSettings settings) {
return Lang.number(Math.max(1, Math.abs(settings.value())))
.add(Lang.translateDirect("generic.unit.degrees"))
.component();
}
@Override
public void onShortInteract(Player player, InteractionHand hand, Direction side) {
BlockState blockState = blockEntity.getBlockState();
if (blockState.getBlock() instanceof ValveHandleBlock vhb)
vhb.clicked(getWorld(), getPos(), blockState, player, hand);
}
}
public static class ValveHandleValueBox extends ValueBoxTransform.Sided {
@Override
protected boolean isSideActive(BlockState state, Direction direction) {
return direction == state.getValue(ValveHandleBlock.FACING);
}
@Override
protected Vec3 getSouthLocation() {
return VecHelper.voxelSpace(8, 8, 4.5);
}
@Override
public boolean testHit(BlockState state, Vec3 localHit) {
Vec3 offset = getLocalOffset(state);
if (offset == null)
return false;
return localHit.distanceTo(offset) < scale / 1.5f;
}
}
}

View file

@ -24,7 +24,7 @@ public class SequencedGearshiftBlockEntity extends SplitShaftBlockEntity {
public record SequenceContext(SequencerInstructions instruction, double relativeValue) { public record SequenceContext(SequencerInstructions instruction, double relativeValue) {
static SequenceContext fromGearshift(SequencerInstructions instruction, double kineticSpeed, public static SequenceContext fromGearshift(SequencerInstructions instruction, double kineticSpeed,
int absoluteValue) { int absoluteValue) {
return instruction.needsPropagation() return instruction.needsPropagation()
? new SequenceContext(instruction, kineticSpeed == 0 ? 0 : absoluteValue / kineticSpeed) ? new SequenceContext(instruction, kineticSpeed == 0 ? 0 : absoluteValue / kineticSpeed)

View file

@ -43,8 +43,10 @@ public class ScrollValueRenderer {
ScrollValueBehaviour behaviour = BlockEntityBehaviour.get(world, pos, ScrollValueBehaviour.TYPE); ScrollValueBehaviour behaviour = BlockEntityBehaviour.get(world, pos, ScrollValueBehaviour.TYPE);
if (behaviour == null) if (behaviour == null)
return; return;
if (!behaviour.isActive()) if (!behaviour.isActive()) {
CreateClient.OUTLINER.remove(pos);
return; return;
}
ItemStack mainhandItem = mc.player.getItemInHand(InteractionHand.MAIN_HAND); ItemStack mainhandItem = mc.player.getItemInHand(InteractionHand.MAIN_HAND);
boolean clipboard = AllItems.CLIPBOARD.isIn(mainhandItem); boolean clipboard = AllItems.CLIPBOARD.isIn(mainhandItem);
if (behaviour.needsWrench && !AllItems.WRENCH.isIn(mainhandItem) && !clipboard) if (behaviour.needsWrench && !AllItems.WRENCH.isIn(mainhandItem) && !clipboard)

View file

@ -84,6 +84,7 @@
"create.generic.length": "Length", "create.generic.length": "Length",
"create.generic.speed": "Speed", "create.generic.speed": "Speed",
"create.generic.delay": "Delay", "create.generic.delay": "Delay",
"create.generic.angle": "Angle",
"create.generic.duration": "Duration", "create.generic.duration": "Duration",
"create.generic.timeUnit": "Time Unit", "create.generic.timeUnit": "Time Unit",
"create.generic.unit.ticks": "Ticks", "create.generic.unit.ticks": "Ticks",
@ -231,6 +232,7 @@
"create.kinetics.creative_motor.rotation_speed": "Generated Speed in RPM", "create.kinetics.creative_motor.rotation_speed": "Generated Speed in RPM",
"create.kinetics.speed_controller.rotation_speed": "Targeted Speed in RPM", "create.kinetics.speed_controller.rotation_speed": "Targeted Speed in RPM",
"create.kinetics.valve_handle.rotated_angle": "Rotation when used",
"create.logistics.redstone_interval": "Redstone Interval", "create.logistics.redstone_interval": "Redstone Interval",

View file

@ -36,42 +36,16 @@
"down": {"uv": [6, 0, 10, 16], "rotation": 180, "texture": "#1_0"} "down": {"uv": [6, 0, 10, 16], "rotation": 180, "texture": "#1_0"}
} }
}, },
{
"from": [5, 14.1, 7],
"to": [7, 15.1, 9],
"rotation": {"angle": 45, "axis": "y", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [12, 2, 13, 4], "rotation": 270, "texture": "#4"},
"east": {"uv": [12, 2, 14, 3], "rotation": 180, "texture": "#4"},
"south": {"uv": [12, 3, 14, 4], "texture": "#4"},
"west": {"uv": [12, 3, 14, 4], "rotation": 180, "texture": "#4"},
"up": {"uv": [12, 2, 14, 4], "rotation": 90, "texture": "#4"},
"down": {"uv": [14, 2, 12, 4], "rotation": 90, "texture": "#4"}
}
},
{
"from": [5, 14.1, 9],
"to": [9, 15.1, 11],
"rotation": {"angle": 45, "axis": "y", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [12, 0, 13, 4], "rotation": 90, "texture": "#4"},
"east": {"uv": [14, 0, 16, 1], "rotation": 180, "texture": "#4"},
"south": {"uv": [15, 0, 16, 4], "rotation": 90, "texture": "#4"},
"west": {"uv": [12, 3, 14, 4], "texture": "#4"},
"up": {"uv": [14, 0, 16, 4], "rotation": 90, "texture": "#4"},
"down": {"uv": [16, 0, 14, 4], "rotation": 90, "texture": "#4"}
}
},
{ {
"from": [7, 14.1, 5], "from": [7, 14.1, 5],
"to": [9, 15.1, 7], "to": [9, 15.1, 7],
"rotation": {"angle": 45, "axis": "y", "origin": [8, 8, 8]}, "rotation": {"angle": 45, "axis": "y", "origin": [8, 8, 8]},
"faces": { "faces": {
"north": {"uv": [14, 3, 12, 4], "rotation": 180, "texture": "#4"}, "north": {"uv": [14, 0, 12, 1], "rotation": 180, "texture": "#4"},
"east": {"uv": [14, 3, 12, 4], "texture": "#4"}, "east": {"uv": [14, 3, 12, 4], "texture": "#4"},
"south": {"uv": [14, 2, 12, 3], "rotation": 180, "texture": "#4"}, "south": {"uv": [14, 2, 12, 3], "rotation": 180, "texture": "#4"},
"west": {"uv": [12, 4, 13, 2], "rotation": 270, "texture": "#4"}, "west": {"uv": [12, 0, 13, 2], "rotation": 270, "texture": "#4"},
"up": {"uv": [14, 2, 12, 4], "rotation": 180, "texture": "#4"}, "up": {"uv": [14, 2, 12, 0], "rotation": 180, "texture": "#4"},
"down": {"uv": [12, 2, 14, 4], "texture": "#4"} "down": {"uv": [12, 2, 14, 4], "texture": "#4"}
} }
}, },
@ -80,14 +54,40 @@
"to": [11, 15.1, 9], "to": [11, 15.1, 9],
"rotation": {"angle": 45, "axis": "y", "origin": [8, 8, 8]}, "rotation": {"angle": 45, "axis": "y", "origin": [8, 8, 8]},
"faces": { "faces": {
"north": {"uv": [14, 3, 12, 4], "texture": "#4"}, "north": {"uv": [16, 0, 14, 1], "texture": "#4"},
"east": {"uv": [15, 4, 16, 0], "rotation": 90, "texture": "#4"}, "east": {"uv": [15, 0, 16, 4], "rotation": 90, "texture": "#4"},
"south": {"uv": [16, 0, 14, 1], "rotation": 180, "texture": "#4"}, "south": {"uv": [16, 0, 14, 1], "rotation": 180, "texture": "#4"},
"west": {"uv": [12, 4, 13, 0], "rotation": 90, "texture": "#4"}, "west": {"uv": [12, 4, 13, 0], "rotation": 90, "texture": "#4"},
"up": {"uv": [16, 0, 14, 4], "rotation": 180, "texture": "#4"}, "up": {"uv": [16, 4, 14, 0], "rotation": 180, "texture": "#4"},
"down": {"uv": [14, 0, 16, 4], "texture": "#4"} "down": {"uv": [14, 0, 16, 4], "texture": "#4"}
} }
}, },
{
"from": [5, 14.1, 7],
"to": [7, 15.1, 11],
"rotation": {"angle": 45, "axis": "y", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [16, 0, 14, 1], "rotation": 180, "texture": "#4"},
"east": {"uv": [12, 4, 13, 0], "rotation": 90, "texture": "#4"},
"south": {"uv": [16, 0, 14, 1], "texture": "#4"},
"west": {"uv": [15, 0, 16, 4], "rotation": 90, "texture": "#4"},
"up": {"uv": [16, 4, 14, 0], "texture": "#4"},
"down": {"uv": [14, 0, 16, 4], "rotation": 180, "texture": "#4"}
}
},
{
"from": [7, 14.1, 9],
"to": [9, 15.1, 11],
"rotation": {"angle": 45, "axis": "y", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [14, 2, 12, 3], "rotation": 180, "texture": "#4"},
"east": {"uv": [12, 0, 13, 2], "rotation": 270, "texture": "#4"},
"south": {"uv": [14, 0, 12, 1], "rotation": 180, "texture": "#4"},
"west": {"uv": [14, 3, 12, 4], "texture": "#4"},
"up": {"uv": [14, 2, 12, 0], "texture": "#4"},
"down": {"uv": [12, 2, 14, 4], "rotation": 180, "texture": "#4"}
}
},
{ {
"name": "Center", "name": "Center",
"from": [7, 14, 7], "from": [7, 14, 7],
@ -173,13 +173,13 @@
"name": "arrow", "name": "arrow",
"origin": [8, 8, 8], "origin": [8, 8, 8],
"color": 0, "color": 0,
"children": [2, 3] "children": []
}, },
{ {
"name": "arrow", "name": "arrow",
"origin": [8, 8, 8], "origin": [8, 8, 8],
"color": 0, "color": 0,
"children": [4, 5] "children": [2, 3, 4, 5]
}, },
6 6
] ]

View file

@ -6,43 +6,17 @@
"particle": "create:block/copper_plating" "particle": "create:block/copper_plating"
}, },
"elements": [ "elements": [
{
"from": [5, 14.1, 7],
"to": [7, 15.1, 9],
"rotation": {"angle": 45, "axis": "y", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [12, 2, 13, 4], "rotation": 270, "texture": "#4"},
"east": {"uv": [12, 2, 14, 3], "rotation": 180, "texture": "#4"},
"south": {"uv": [12, 3, 14, 4], "texture": "#4"},
"west": {"uv": [12, 3, 14, 4], "rotation": 180, "texture": "#4"},
"up": {"uv": [12, 2, 14, 4], "rotation": 90, "texture": "#4"},
"down": {"uv": [14, 2, 12, 4], "rotation": 90, "texture": "#4"}
}
},
{
"from": [5, 14.1, 9],
"to": [9, 15.1, 11],
"rotation": {"angle": 45, "axis": "y", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [12, 0, 13, 4], "rotation": 90, "texture": "#4"},
"east": {"uv": [14, 0, 16, 1], "rotation": 180, "texture": "#4"},
"south": {"uv": [15, 0, 16, 4], "rotation": 90, "texture": "#4"},
"west": {"uv": [12, 3, 14, 4], "texture": "#4"},
"up": {"uv": [14, 0, 16, 4], "rotation": 90, "texture": "#4"},
"down": {"uv": [16, 0, 14, 4], "rotation": 90, "texture": "#4"}
}
},
{ {
"from": [7, 14.1, 5], "from": [7, 14.1, 5],
"to": [9, 15.1, 7], "to": [9, 15.1, 7],
"rotation": {"angle": 45, "axis": "y", "origin": [8, 8, 8]}, "rotation": {"angle": 45, "axis": "y", "origin": [8, 8, 8]},
"faces": { "faces": {
"north": {"uv": [14, 3, 12, 4], "rotation": 180, "texture": "#4"}, "north": {"uv": [14, 0, 12, 1], "rotation": 180, "texture": "#4"},
"east": {"uv": [14, 3, 12, 4], "texture": "#4"}, "east": {"uv": [14, 3, 12, 4], "texture": "#4"},
"south": {"uv": [14, 2, 12, 3], "rotation": 180, "texture": "#4"}, "south": {"uv": [14, 2, 12, 3], "rotation": 180, "texture": "#4"},
"west": {"uv": [12, 4, 13, 2], "rotation": 270, "texture": "#4"}, "west": {"uv": [12, 0, 13, 2], "rotation": 270, "texture": "#4"},
"up": {"uv": [14, 2, 12, 4], "rotation": 180, "texture": "#4"}, "up": {"uv": [12, 0, 14, 2], "texture": "#4"},
"down": {"uv": [12, 2, 14, 4], "texture": "#4"} "down": {"uv": [14, 0, 12, 2], "rotation": 180, "texture": "#4"}
} }
}, },
{ {
@ -50,12 +24,61 @@
"to": [11, 15.1, 9], "to": [11, 15.1, 9],
"rotation": {"angle": 45, "axis": "y", "origin": [8, 8, 8]}, "rotation": {"angle": 45, "axis": "y", "origin": [8, 8, 8]},
"faces": { "faces": {
"north": {"uv": [14, 3, 12, 4], "texture": "#4"}, "north": {"uv": [16, 0, 14, 1], "texture": "#4"},
"east": {"uv": [15, 4, 16, 0], "rotation": 90, "texture": "#4"}, "east": {"uv": [15, 0, 16, 4], "rotation": 90, "texture": "#4"},
"south": {"uv": [16, 0, 14, 1], "rotation": 180, "texture": "#4"}, "south": {"uv": [16, 0, 14, 1], "rotation": 180, "texture": "#4"},
"west": {"uv": [12, 4, 13, 0], "rotation": 90, "texture": "#4"}, "up": {"uv": [14, 0, 16, 4], "texture": "#4"},
"up": {"uv": [16, 0, 14, 4], "rotation": 180, "texture": "#4"}, "down": {"uv": [16, 0, 14, 4], "rotation": 180, "texture": "#4"}
"down": {"uv": [14, 0, 16, 4], "texture": "#4"} }
},
{
"from": [7, 14.1, 9],
"to": [11, 15.1, 11],
"rotation": {"angle": -45, "axis": "y", "origin": [8, 8, 8]},
"faces": {
"east": {"uv": [16, 0, 14, 1], "texture": "#4"},
"south": {"uv": [15, 0, 16, 4], "rotation": 90, "texture": "#4"},
"west": {"uv": [16, 0, 14, 1], "rotation": 180, "texture": "#4"},
"up": {"uv": [14, 0, 16, 4], "rotation": 90, "texture": "#4"},
"down": {"uv": [16, 0, 14, 4], "rotation": 90, "texture": "#4"}
}
},
{
"from": [9, 14.1, 7],
"to": [11, 15.1, 9],
"rotation": {"angle": -45, "axis": "y", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [12, 0, 13, 2], "rotation": 270, "texture": "#4"},
"east": {"uv": [14, 0, 12, 1], "rotation": 180, "texture": "#4"},
"south": {"uv": [14, 3, 12, 4], "texture": "#4"},
"west": {"uv": [14, 2, 12, 3], "rotation": 180, "texture": "#4"},
"up": {"uv": [12, 0, 14, 2], "rotation": 90, "texture": "#4"},
"down": {"uv": [14, 0, 12, 2], "rotation": 90, "texture": "#4"}
}
},
{
"from": [9, 14.1, 5],
"to": [11, 15.1, 9],
"rotation": {"angle": 45, "axis": "y", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [16, 0, 14, 1], "texture": "#4"},
"east": {"uv": [15, 0, 16, 4], "rotation": 90, "texture": "#4"},
"south": {"uv": [16, 0, 14, 1], "rotation": 180, "texture": "#4"},
"up": {"uv": [14, 0, 16, 4], "texture": "#4"},
"down": {"uv": [16, 0, 14, 4], "rotation": 180, "texture": "#4"}
}
},
{
"from": [7, 14.1, 5],
"to": [9, 15.1, 7],
"rotation": {"angle": 45, "axis": "y", "origin": [8, 8, 8]},
"faces": {
"north": {"uv": [14, 0, 12, 1], "rotation": 180, "texture": "#4"},
"east": {"uv": [14, 3, 12, 4], "texture": "#4"},
"south": {"uv": [14, 2, 12, 3], "rotation": 180, "texture": "#4"},
"west": {"uv": [12, 0, 13, 2], "rotation": 270, "texture": "#4"},
"up": {"uv": [12, 0, 14, 2], "texture": "#4"},
"down": {"uv": [14, 0, 12, 2], "rotation": 180, "texture": "#4"}
} }
}, },
{ {
@ -113,15 +136,15 @@
"name": "arrow", "name": "arrow",
"origin": [8, 8, 8], "origin": [8, 8, 8],
"color": 0, "color": 0,
"children": [0, 1] "children": []
}, },
{ {
"name": "arrow", "name": "arrow",
"origin": [8, 8, 8], "origin": [8, 8, 8],
"color": 0, "color": 0,
"children": [2, 3] "children": [0, 1, 2, 3, 4, 5]
}, },
4 6
] ]
} }
] ]

View file

@ -1,365 +1,10 @@
{ {
"credit": "Made with Blockbench",
"parent": "block/block", "parent": "block/block",
"loader": "forge:obj",
"flip-v": true,
"model": "create:models/block/valve_handle/valve_handle.obj",
"textures": { "textures": {
"particle": "block/copper_block", "3": "create:block/valve_handle/valve_handle_copper",
"3": "create:block/valve_handle/valve_handle_copper" "particle": "block/copper_block"
}, }
"elements": [
{
"name": "WheelMid",
"from": [5.5, 0, 5.5],
"to": [10.5, 4, 10.5],
"rotation": {"angle": 0, "axis": "y", "origin": [14, -7, 14]},
"faces": {
"north": {"uv": [0, 5, 5, 9], "texture": "#3"},
"east": {"uv": [0, 5, 5, 9], "texture": "#3"},
"south": {"uv": [0, 5, 5, 9], "texture": "#3"},
"west": {"uv": [0, 5, 5, 9], "texture": "#3"},
"up": {"uv": [0, 0, 5, 5], "rotation": 180, "texture": "#3"},
"down": {"uv": [0, 0, 5, 5], "texture": "#3"}
}
},
{
"name": "Nubbin",
"from": [6.5, 4, 6.5],
"to": [9.5, 5, 9.5],
"rotation": {"angle": 0, "axis": "y", "origin": [15.5, 11.5, 15.5]},
"faces": {
"north": {"uv": [1, 1, 4, 2], "texture": "#3"},
"east": {"uv": [1, 3, 4, 4], "rotation": 180, "texture": "#3"},
"south": {"uv": [1, 3, 4, 4], "texture": "#3"},
"west": {"uv": [1, 1, 2, 4], "rotation": 90, "texture": "#3"},
"up": {"uv": [1, 1, 4, 4], "texture": "#3"}
}
},
{
"name": "BranchNorthTop",
"from": [6.5, 2.8888, 12.3314],
"to": [9.5, 5.8888, 14.3314],
"rotation": {"angle": -45, "axis": "x", "origin": [7.14142, 4.75147, 12.11726]},
"faces": {
"north": {"uv": [4, 8, 5, 9], "texture": "#3"},
"east": {"uv": [1, 6, 4, 8], "rotation": 90, "texture": "#3"},
"south": {"uv": [0, 0, 0, 0], "texture": "#3"},
"west": {"uv": [1, 6, 4, 8], "rotation": 270, "texture": "#3"},
"up": {"uv": [1, 6, 4, 8], "texture": "#3"},
"down": {"uv": [1, 6, 4, 8], "rotation": 180, "texture": "#3"}
}
},
{
"name": "BranchNorthMid",
"from": [7, 3.3888, 9.3314],
"to": [9, 5.3888, 12.3314],
"rotation": {"angle": -45, "axis": "x", "origin": [7.14142, 4.75147, 12.11726]},
"faces": {
"east": {"uv": [5, 8, 8, 10], "texture": "#3"},
"west": {"uv": [5, 8, 8, 10], "rotation": 180, "texture": "#3"},
"up": {"uv": [5, 8, 8, 10], "rotation": 270, "texture": "#3"},
"down": {"uv": [5, 8, 8, 10], "rotation": 90, "texture": "#3"}
}
},
{
"name": "BranchNorthBottom",
"from": [6.5, 2.8888, 7.3314],
"to": [9.5, 5.8888, 9.3314],
"rotation": {"angle": -45, "axis": "x", "origin": [7.14142, 4.75147, 12.11726]},
"faces": {
"east": {"uv": [1, 6, 4, 8], "rotation": 270, "texture": "#3"},
"south": {"uv": [4, 8, 5, 9], "texture": "#3"},
"west": {"uv": [1, 6, 4, 8], "rotation": 90, "texture": "#3"},
"down": {"uv": [1, 6, 4, 8], "texture": "#3"}
}
},
{
"name": "WheelNorth",
"from": [5, 5, 12.8],
"to": [11, 8, 15],
"rotation": {"angle": 0, "axis": "y", "origin": [7.14142, 4.75147, 12.11726]},
"faces": {
"north": {"uv": [5, 5, 11, 8], "rotation": 180, "texture": "#3"},
"east": {"uv": [9, 4, 10, 5], "rotation": 270, "texture": "#3"},
"south": {"uv": [5, 2, 11, 5], "texture": "#3"},
"west": {"uv": [9, 4, 10, 5], "rotation": 180, "texture": "#3"},
"up": {"uv": [5, 0, 11, 2], "rotation": 180, "texture": "#3"},
"down": {"uv": [5, 0, 11, 2], "texture": "#3"}
}
},
{
"name": "WheelNorthEast",
"from": [3.5888, 5.1, 6.9846],
"to": [5.5888, 7.9, 12.64145],
"rotation": {"angle": 45, "axis": "y", "origin": [7.14142, 4.75147, 12.11726]},
"faces": {
"east": {"uv": [5, 5, 11, 8], "rotation": 180, "texture": "#3"},
"west": {"uv": [5, 2, 11, 5], "texture": "#3"},
"up": {"uv": [5, 0, 11, 2], "rotation": 270, "texture": "#3"},
"down": {"uv": [5, 0, 11, 2], "rotation": 270, "texture": "#3"}
}
},
{
"name": "BranchEastTop",
"from": [1, 5, 6.5],
"to": [3, 8, 9.5],
"rotation": {"angle": -45, "axis": "z", "origin": [1, 5, 8]},
"faces": {
"north": {"uv": [1, 6, 4, 8], "rotation": 270, "texture": "#3"},
"east": {"uv": [4, 8, 5, 9], "texture": "#3"},
"south": {"uv": [1, 6, 4, 8], "rotation": 90, "texture": "#3"},
"west": {"uv": [0, 0, 0, 0], "texture": "#3"},
"up": {"uv": [1, 6, 4, 8], "rotation": 90, "texture": "#3"},
"down": {"uv": [1, 6, 4, 8], "rotation": 90, "texture": "#3"}
}
},
{
"name": "BranchEastMid",
"from": [3, 5.5, 7],
"to": [6, 7.5, 9],
"rotation": {"angle": -45, "axis": "z", "origin": [1, 5, 8]},
"faces": {
"north": {"uv": [5, 8, 8, 10], "rotation": 180, "texture": "#3"},
"south": {"uv": [5, 8, 8, 10], "texture": "#3"},
"up": {"uv": [5, 8, 8, 10], "texture": "#3"},
"down": {"uv": [5, 8, 8, 10], "texture": "#3"}
}
},
{
"name": "BranchEastBottom",
"from": [6, 5, 6.5],
"to": [8, 8, 9.5],
"rotation": {"angle": -45, "axis": "z", "origin": [1, 5, 8]},
"faces": {
"north": {"uv": [1, 6, 4, 8], "rotation": 90, "texture": "#3"},
"south": {"uv": [1, 6, 4, 8], "rotation": 270, "texture": "#3"},
"west": {"uv": [4, 8, 5, 9], "texture": "#3"},
"down": {"uv": [1, 6, 4, 8], "rotation": 270, "texture": "#3"}
}
},
{
"name": "WheelEast",
"from": [5, 5, 1],
"to": [11, 8, 3.2],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 6.5, 1.9]},
"faces": {
"north": {"uv": [5, 2, 11, 5], "texture": "#3"},
"east": {"uv": [9, 4, 10, 5], "rotation": 180, "texture": "#3"},
"south": {"uv": [5, 5, 11, 8], "rotation": 180, "texture": "#3"},
"west": {"uv": [9, 4, 10, 5], "rotation": 270, "texture": "#3"},
"up": {"uv": [5, 0, 11, 2], "texture": "#3"},
"down": {"uv": [5, 0, 11, 2], "rotation": 180, "texture": "#3"}
}
},
{
"name": "WheelSouthEast",
"from": [3.5888, 5.1, 3.35855],
"to": [5.5888, 7.9, 9.0154],
"rotation": {"angle": -45, "axis": "y", "origin": [7.14142, 4.75147, 3.88274]},
"faces": {
"east": {"uv": [11, 5, 5, 8], "rotation": 180, "texture": "#3"},
"west": {"uv": [11, 2, 5, 5], "texture": "#3"},
"up": {"uv": [11, 0, 5, 2], "rotation": 270, "texture": "#3"},
"down": {"uv": [11, 0, 5, 2], "rotation": 270, "texture": "#3"}
}
},
{
"name": "BranchSouthTop",
"from": [6.5, 2.8888, 1.6686],
"to": [9.5, 5.8888, 3.6686],
"rotation": {"angle": 45, "axis": "x", "origin": [7.14142, 4.75147, 3.88274]},
"faces": {
"north": {"uv": [0, 0, 0, 0], "texture": "#3"},
"east": {"uv": [1, 8, 4, 6], "rotation": 90, "texture": "#3"},
"south": {"uv": [5, 8, 4, 9], "texture": "#3"},
"west": {"uv": [1, 8, 4, 6], "rotation": 270, "texture": "#3"},
"up": {"uv": [1, 8, 4, 6], "texture": "#3"},
"down": {"uv": [1, 8, 4, 6], "rotation": 180, "texture": "#3"}
}
},
{
"name": "BranchSouthMid",
"from": [7, 3.3888, 3.6686],
"to": [9, 5.3888, 6.6686],
"rotation": {"angle": 45, "axis": "x", "origin": [7.14142, 4.75147, 3.88274]},
"faces": {
"east": {"uv": [8, 8, 5, 10], "texture": "#3"},
"west": {"uv": [8, 8, 5, 10], "rotation": 180, "texture": "#3"},
"up": {"uv": [8, 8, 5, 10], "rotation": 270, "texture": "#3"},
"down": {"uv": [8, 8, 5, 10], "rotation": 90, "texture": "#3"}
}
},
{
"name": "BranchSouthBottom",
"from": [6.5, 2.8888, 6.6686],
"to": [9.5, 5.8888, 8.6686],
"rotation": {"angle": 45, "axis": "x", "origin": [7.14142, 4.75147, 3.88274]},
"faces": {
"north": {"uv": [5, 8, 4, 9], "texture": "#3"},
"east": {"uv": [1, 8, 4, 6], "rotation": 270, "texture": "#3"},
"west": {"uv": [1, 8, 4, 6], "rotation": 90, "texture": "#3"},
"down": {"uv": [1, 8, 4, 6], "texture": "#3"}
}
},
{
"name": "WheelSouth",
"from": [1, 5, 5],
"to": [3.2, 8, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [2, 6.5, 7.9]},
"faces": {
"north": {"uv": [9, 4, 10, 5], "rotation": 180, "texture": "#3"},
"east": {"uv": [5, 5, 11, 8], "rotation": 180, "texture": "#3"},
"south": {"uv": [9, 4, 10, 5], "rotation": 270, "texture": "#3"},
"west": {"uv": [5, 2, 11, 5], "texture": "#3"},
"up": {"uv": [5, 0, 11, 2], "rotation": 270, "texture": "#3"},
"down": {"uv": [5, 0, 11, 2], "rotation": 270, "texture": "#3"}
}
},
{
"name": "WheelSouthWest",
"from": [10.4112, 5.1, 3.35855],
"to": [12.4112, 7.9, 9.0154],
"rotation": {"angle": 45, "axis": "y", "origin": [8.85858, 4.75147, 3.88274]},
"faces": {
"east": {"uv": [5, 2, 11, 5], "texture": "#3"},
"west": {"uv": [5, 5, 11, 8], "rotation": 180, "texture": "#3"},
"up": {"uv": [11, 2, 5, 0], "rotation": 270, "texture": "#3"},
"down": {"uv": [11, 2, 5, 0], "rotation": 270, "texture": "#3"}
}
},
{
"name": "BranchWestBottom",
"from": [8, 5, 6.5],
"to": [10, 8, 9.5],
"rotation": {"angle": 45, "axis": "z", "origin": [15, 5, 8]},
"faces": {
"north": {"uv": [1, 8, 4, 6], "rotation": 90, "texture": "#3"},
"east": {"uv": [5, 8, 4, 9], "texture": "#3"},
"south": {"uv": [1, 8, 4, 6], "rotation": 270, "texture": "#3"},
"down": {"uv": [1, 8, 4, 6], "rotation": 270, "texture": "#3"}
}
},
{
"name": "BranchWestMid",
"from": [10, 5.5, 7],
"to": [13, 7.5, 9],
"rotation": {"angle": 45, "axis": "z", "origin": [15, 5, 8]},
"faces": {
"north": {"uv": [8, 8, 5, 10], "rotation": 180, "texture": "#3"},
"south": {"uv": [8, 8, 5, 10], "texture": "#3"},
"up": {"uv": [8, 8, 5, 10], "texture": "#3"},
"down": {"uv": [8, 8, 5, 10], "texture": "#3"}
}
},
{
"name": "BranchWestTop",
"from": [13, 5, 6.5],
"to": [15, 8, 9.5],
"rotation": {"angle": 45, "axis": "z", "origin": [15, 5, 8]},
"faces": {
"north": {"uv": [1, 8, 4, 6], "rotation": 270, "texture": "#3"},
"east": {"uv": [0, 0, 0, 0], "texture": "#3"},
"south": {"uv": [1, 8, 4, 6], "rotation": 90, "texture": "#3"},
"west": {"uv": [5, 8, 4, 9], "texture": "#3"},
"up": {"uv": [1, 8, 4, 6], "rotation": 90, "texture": "#3"},
"down": {"uv": [1, 8, 4, 6], "rotation": 90, "texture": "#3"}
}
},
{
"name": "WheelWest",
"from": [12.8, 5, 5],
"to": [15, 8, 11],
"rotation": {"angle": 0, "axis": "y", "origin": [14, 8, 8]},
"faces": {
"north": {"uv": [9, 4, 10, 5], "rotation": 270, "texture": "#3"},
"east": {"uv": [5, 2, 11, 5], "texture": "#3"},
"south": {"uv": [9, 4, 10, 5], "rotation": 180, "texture": "#3"},
"west": {"uv": [5, 5, 11, 8], "rotation": 180, "texture": "#3"},
"up": {"uv": [5, 0, 11, 2], "rotation": 90, "texture": "#3"},
"down": {"uv": [5, 0, 11, 2], "rotation": 90, "texture": "#3"}
}
},
{
"name": "WheelNorthWest",
"from": [10.4112, 5.1, 6.9846],
"to": [12.4112, 7.9, 12.64145],
"rotation": {"angle": -45, "axis": "y", "origin": [8.85858, 4.75147, 12.11726]},
"faces": {
"east": {"uv": [11, 2, 5, 5], "texture": "#3"},
"west": {"uv": [11, 5, 5, 8], "rotation": 180, "texture": "#3"},
"up": {"uv": [5, 2, 11, 0], "rotation": 270, "texture": "#3"},
"down": {"uv": [5, 2, 11, 0], "rotation": 270, "texture": "#3"}
}
}
],
"display": {
"thirdperson_righthand": {
"rotation": [75, 45, 0],
"translation": [0, 2.5, 0.75],
"scale": [0.375, 0.375, 0.375]
},
"thirdperson_lefthand": {
"rotation": [75, 45, 0],
"translation": [0, 2.5, 1],
"scale": [0.375, 0.375, 0.375]
},
"firstperson_righthand": {
"rotation": [0, 45, 0],
"translation": [0, 2.5, 0],
"scale": [0.4, 0.4, 0.4]
},
"firstperson_lefthand": {
"rotation": [0, 45, 0],
"translation": [0, 2.5, 0],
"scale": [0.4, 0.4, 0.4]
},
"ground": {
"translation": [0, 0.75, 0],
"scale": [0.35, 0.35, 0.35]
},
"gui": {
"rotation": [30, 225, 0],
"translation": [0, 2.75, 0],
"scale": [0.75, 0.75, 0.75]
},
"head": {
"translation": [0, 13, 0]
},
"fixed": {
"rotation": [-90, 0, 0],
"translation": [0, 0, -3.5],
"scale": [0.5, 0.5, 0.5]
}
},
"groups": [
{
"name": "Hub",
"origin": [8, 5.5, -2.5],
"children": [0, 1]
},
{
"name": "Wheel",
"origin": [8, 5.5, -2.5],
"children": [
{
"name": "North",
"origin": [1, 3, 11],
"children": [2, 3, 4, 5, 6]
},
{
"name": "East",
"origin": [1, 3, 11],
"children": [7, 8, 9, 10, 11]
},
{
"name": "South",
"origin": [1, 3, 11],
"children": [12, 13, 14, 15, 16]
},
{
"name": "West",
"origin": [1, 3, 11],
"children": [17, 18, 19, 20, 21]
}
]
}
]
} }

View file

@ -0,0 +1,5 @@
# Blender 3.5.0 MTL File: 'valve_handle.blend'
# www.blender.org
newmtl Material
map_Kd #3

View file

@ -0,0 +1,704 @@
# Blender 3.5.0
# www.blender.org
mtllib valve_handle.mtl
o Cube.009
v 0.312500 0.000000 0.687500
v 0.312500 0.125000 0.687500
v 0.312500 0.000000 0.312500
v 0.312500 0.125000 0.312500
v 0.687500 0.000000 0.687500
v 0.687500 0.125000 0.687500
v 0.687500 0.000000 0.312500
v 0.687500 0.125000 0.312500
v 0.681219 0.500000 0.062500
v 0.681219 0.312500 0.062500
v 0.629442 0.500000 0.187500
v 0.629442 0.312500 0.187500
v 0.937500 0.500000 0.318782
v 0.937500 0.312500 0.318782
v 0.812500 0.500000 0.370558
v 0.812500 0.312500 0.370558
v 0.937500 0.500000 0.681219
v 0.937500 0.312500 0.681219
v 0.812500 0.500000 0.629442
v 0.812500 0.312500 0.629442
v 0.681218 0.500000 0.937500
v 0.681218 0.312500 0.937500
v 0.629442 0.500000 0.812500
v 0.629442 0.312500 0.812500
v 0.318782 0.500000 0.937500
v 0.318782 0.312500 0.937500
v 0.370558 0.500000 0.812500
v 0.370558 0.312500 0.812500
v 0.062500 0.500000 0.681218
v 0.062500 0.312500 0.681218
v 0.187500 0.500000 0.629442
v 0.187500 0.312500 0.629442
v 0.062500 0.500000 0.318781
v 0.062500 0.312500 0.318781
v 0.187500 0.500000 0.370558
v 0.187500 0.312500 0.370558
v 0.318782 0.500000 0.062500
v 0.318782 0.312500 0.062500
v 0.370558 0.500000 0.187500
v 0.370558 0.312500 0.187500
v 0.375000 0.125000 0.625000
v 0.375000 0.312500 0.625000
v 0.375000 0.125000 0.375000
v 0.375000 0.312500 0.375000
v 0.625000 0.125000 0.625000
v 0.625000 0.312500 0.625000
v 0.625000 0.125000 0.375000
v 0.625000 0.312500 0.375000
v 0.437500 0.312500 0.099112
v 0.437500 0.400888 0.187500
v 0.562500 0.312500 0.099112
v 0.562500 0.400888 0.187500
v 0.437500 0.047335 0.364277
v 0.437500 0.135723 0.452665
v 0.562500 0.135723 0.452665
v 0.562500 0.047335 0.364277
v 0.437500 0.356694 0.231694
v 0.437500 0.312500 0.275888
v 0.437500 0.268306 0.320083
v 0.437500 0.224112 0.364277
v 0.437500 0.179917 0.408471
v 0.562500 0.179917 0.408471
v 0.562500 0.224112 0.364277
v 0.562500 0.268306 0.320083
v 0.562500 0.312500 0.275888
v 0.562500 0.356694 0.231694
v 0.562500 0.091529 0.320083
v 0.562500 0.135723 0.275888
v 0.562500 0.179917 0.231694
v 0.562500 0.224112 0.187500
v 0.562500 0.268306 0.143306
v 0.437500 0.268306 0.143306
v 0.437500 0.224112 0.187500
v 0.437500 0.179917 0.231694
v 0.437500 0.135723 0.275888
v 0.437500 0.091529 0.320083
v 0.099112 0.312500 0.562500
v 0.187500 0.400888 0.562500
v 0.099112 0.312500 0.437500
v 0.187500 0.400888 0.437500
v 0.364277 0.047335 0.562500
v 0.452665 0.135723 0.562500
v 0.452665 0.135723 0.437500
v 0.364277 0.047335 0.437500
v 0.231694 0.356694 0.562500
v 0.275888 0.312500 0.562500
v 0.320083 0.268306 0.562500
v 0.364277 0.224112 0.562500
v 0.408471 0.179917 0.562500
v 0.408471 0.179917 0.437500
v 0.364277 0.224112 0.437500
v 0.320083 0.268306 0.437500
v 0.275888 0.312500 0.437500
v 0.231694 0.356694 0.437500
v 0.320083 0.091529 0.437500
v 0.275888 0.135723 0.437500
v 0.231694 0.179917 0.437500
v 0.187500 0.224112 0.437500
v 0.143306 0.268306 0.437500
v 0.143306 0.268306 0.562500
v 0.187500 0.224112 0.562500
v 0.231694 0.179917 0.562500
v 0.275888 0.135723 0.562500
v 0.320083 0.091529 0.562500
v 0.562500 0.312500 0.900888
v 0.562500 0.400888 0.812500
v 0.437500 0.312500 0.900888
v 0.437500 0.400888 0.812500
v 0.562500 0.047335 0.635723
v 0.562500 0.135723 0.547335
v 0.437500 0.135723 0.547335
v 0.437500 0.047335 0.635723
v 0.562500 0.356694 0.768306
v 0.562500 0.312500 0.724112
v 0.562500 0.268306 0.679917
v 0.562500 0.224112 0.635723
v 0.562500 0.179917 0.591529
v 0.437500 0.179917 0.591529
v 0.437500 0.224112 0.635723
v 0.437500 0.268306 0.679917
v 0.437500 0.312500 0.724112
v 0.437500 0.356694 0.768306
v 0.437500 0.091529 0.679917
v 0.437500 0.135723 0.724112
v 0.437500 0.179917 0.768306
v 0.437500 0.224112 0.812500
v 0.437500 0.268306 0.856694
v 0.562500 0.268306 0.856694
v 0.562500 0.224112 0.812500
v 0.562500 0.179917 0.768306
v 0.562500 0.135723 0.724112
v 0.562500 0.091529 0.679917
v 0.900888 0.312500 0.437500
v 0.812500 0.400888 0.437500
v 0.900888 0.312500 0.562500
v 0.812500 0.400888 0.562500
v 0.635723 0.047335 0.437500
v 0.547335 0.135723 0.437500
v 0.547335 0.135723 0.562500
v 0.635723 0.047335 0.562500
v 0.768306 0.356694 0.437500
v 0.724112 0.312500 0.437500
v 0.679917 0.268306 0.437500
v 0.635723 0.224112 0.437500
v 0.591529 0.179917 0.437500
v 0.591529 0.179917 0.562500
v 0.635723 0.224112 0.562500
v 0.679918 0.268306 0.562500
v 0.724112 0.312500 0.562500
v 0.768306 0.356694 0.562500
v 0.679918 0.091529 0.562500
v 0.724112 0.135723 0.562500
v 0.768306 0.179917 0.562500
v 0.812500 0.224112 0.562500
v 0.856694 0.268306 0.562500
v 0.856694 0.268306 0.437500
v 0.812500 0.224112 0.437500
v 0.768306 0.179917 0.437500
v 0.724112 0.135723 0.437500
v 0.679917 0.091529 0.437500
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vn -0.0000 1.0000 -0.0000
vn -0.0000 -1.0000 -0.0000
vn 0.7071 -0.0000 -0.7071
vn -0.7071 -0.0000 0.7071
vn 0.7071 -0.0000 0.7071
vn -0.7071 -0.0000 -0.7071
vn -0.0000 0.7071 0.7071
vn -0.0000 -0.7071 -0.7071
vn 0.7071 0.7071 -0.0000
vn -0.7071 -0.7071 -0.0000
vn -0.0000 0.7071 -0.7071
vn -0.0000 -0.7071 0.7071
vn -0.7071 0.7071 -0.0000
vn 0.7071 -0.7071 -0.0000
vt 1.000000 0.500000
vt 0.625000 0.500000
vt 1.000000 0.625000
vt 1.000000 0.625000
vt 0.625000 0.625000
vt 0.625000 0.500000
vt 1.000000 0.500000
vt 1.000000 1.000000
vt 0.625000 0.625000
vt 1.000000 0.625000
vt 0.625000 1.000000
vt 0.625000 0.500000
vt 1.000000 0.500000
vt 0.625000 0.625000
vt 0.625000 0.625000
vt 1.000000 0.625000
vt 0.625000 0.500000
vt 1.000000 0.500000
vt 0.625000 1.000000
vt 0.625000 0.625000
vt 1.000000 0.625000
vt 1.000000 1.000000
vt 0.000000 0.687500
vt 0.375000 1.000000
vt 0.375000 0.687500
vt 0.000021 0.999979
vt 0.000000 0.500000
vt 0.375000 1.000000
vt 0.375000 0.500000
vt -0.000000 1.000000
vt 0.321429 0.875000
vt 0.053587 0.875000
vt 0.321429 0.687500
vt 0.321429 0.875000
vt 0.053587 0.687500
vt 0.053571 0.875000
vt 0.000000 0.687500
vt 0.375000 1.000000
vt 0.375000 0.687500
vt 0.000021 0.999979
vt 0.000000 0.500000
vt 0.375000 1.000000
vt 0.375000 0.500000
vt -0.000000 1.000000
vt 0.321429 0.875000
vt 0.053587 0.875000
vt 0.321429 0.687500
vt 0.321429 0.875000
vt 0.053587 0.687500
vt 0.053571 0.875000
vt 0.000000 0.687500
vt 0.375000 1.000000
vt 0.375000 0.687500
vt 0.000021 0.999979
vt 0.000000 0.500000
vt 0.375000 1.000000
vt 0.375000 0.500000
vt -0.000000 1.000000
vt 0.321429 0.875000
vt 0.053587 0.875000
vt 0.321429 0.687500
vt 0.321429 0.875000
vt 0.053587 0.687500
vt 0.053571 0.875000
vt 0.000000 0.687500
vt 0.375000 1.000000
vt 0.375000 0.687500
vt 0.000021 0.999979
vt 0.000000 0.500000
vt 0.375000 1.000000
vt 0.375000 0.500000
vt -0.000000 1.000000
vt 0.321429 0.875000
vt 0.053587 0.875000
vt 0.321429 0.687500
vt 0.321429 0.875000
vt 0.053587 0.687500
vt 0.053571 0.875000
vt 0.000000 0.687500
vt 0.375000 1.000000
vt 0.375000 0.687500
vt 0.000021 0.999979
vt 0.000000 0.500000
vt 0.375000 1.000000
vt 0.375000 0.500000
vt -0.000000 1.000000
vt 0.321429 0.875000
vt 0.053587 0.875000
vt 0.321429 0.687500
vt 0.321429 0.875000
vt 0.053587 0.687500
vt 0.053571 0.875000
vt 0.000000 0.687500
vt 0.375000 1.000000
vt 0.375000 0.687500
vt 0.000021 0.999979
vt 0.000000 0.500000
vt 0.375000 1.000000
vt 0.375000 0.500000
vt -0.000000 1.000000
vt 0.321429 0.875000
vt 0.053587 0.875000
vt 0.321429 0.687500
vt 0.321429 0.875000
vt 0.053587 0.687500
vt 0.053571 0.875000
vt 0.000000 0.687500
vt 0.375000 1.000000
vt 0.375000 0.687500
vt 0.000021 0.999979
vt 0.000000 0.500000
vt 0.375000 1.000000
vt 0.375000 0.500000
vt -0.000000 1.000000
vt 0.321429 0.875000
vt 0.053587 0.875000
vt 0.321429 0.687500
vt 0.321429 0.875000
vt 0.053587 0.687500
vt 0.053571 0.875000
vt 0.375000 0.687500
vt 0.000021 0.999979
vt 0.000000 0.687500
vt 0.375000 1.000000
vt 0.375000 0.500000
vt -0.000000 1.000000
vt 0.000000 0.500000
vt 0.375000 1.000000
vt 0.053587 0.875000
vt 0.321429 0.875000
vt 0.053587 0.687500
vt 0.053571 0.875000
vt 0.321429 0.687500
vt 0.321429 0.875000
vt 0.312500 -0.000000
vt 0.062500 -0.000000
vt 0.625000 1.000000
vt 0.312500 0.187500
vt 0.062500 0.187500
vt 0.062500 -0.000000
vt 0.312500 -0.000000
vt 0.625000 0.687500
vt 0.062500 0.187500
vt 0.312500 0.187500
vt 0.062500 0.437500
vt 0.062500 -0.000000
vt 0.312500 -0.000000
vt 0.937500 1.000000
vt 0.062500 0.187500
vt 0.312500 0.187500
vt 0.062500 -0.000000
vt 0.312500 -0.000000
vt 0.937500 0.687500
vt 0.062500 0.187500
vt 0.312500 0.187500
vt 0.312500 0.437500
vt 0.562500 1.000000
vt 0.437500 1.000000
vt 0.437500 1.000000
vt 0.562500 1.000000
vt 0.562500 1.000000
vt 0.437500 1.000000
vt 0.437500 1.000000
vt 0.562500 1.000000
vt 0.437500 0.625000
vt 0.562500 0.625000
vt 0.562500 0.625000
vt 0.437500 0.625000
vt 0.562500 0.625000
vt 0.437500 0.625000
vt 0.437500 0.625000
vt 0.562500 0.625000
vt 0.437500 0.937500
vt 0.562500 0.937500
vt 0.437500 0.875000
vt 0.562500 0.875000
vt 0.437500 0.812500
vt 0.562500 0.812500
vt 0.437500 0.750000
vt 0.562500 0.750000
vt 0.437500 0.687500
vt 0.562500 0.687500
vt 0.437500 0.687500
vt 0.562500 0.687500
vt 0.437500 0.750000
vt 0.562500 0.750000
vt 0.437500 0.812500
vt 0.562500 0.812500
vt 0.437500 0.875000
vt 0.562500 0.875000
vt 0.437500 0.937500
vt 0.562500 0.937500
vt 0.562500 0.687500
vt 0.437500 0.687500
vt 0.562500 0.750000
vt 0.437500 0.750000
vt 0.562500 0.812500
vt 0.437500 0.812500
vt 0.562500 0.875000
vt 0.437500 0.875000
vt 0.562500 0.937500
vt 0.437500 0.937500
vt 0.562500 0.937500
vt 0.437500 0.937500
vt 0.562500 0.875000
vt 0.437500 0.875000
vt 0.562500 0.812500
vt 0.437500 0.812500
vt 0.562500 0.750000
vt 0.437500 0.750000
vt 0.562500 0.687500
vt 0.437500 0.687500
vt 0.562500 1.000000
vt 0.437500 1.000000
vt 0.437500 1.000000
vt 0.562500 1.000000
vt 0.562500 1.000000
vt 0.437500 1.000000
vt 0.437500 1.000000
vt 0.562500 1.000000
vt 0.437500 0.625000
vt 0.562500 0.625000
vt 0.562500 0.625000
vt 0.437500 0.625000
vt 0.562500 0.625000
vt 0.437500 0.625000
vt 0.437500 0.625000
vt 0.562500 0.625000
vt 0.437500 0.937500
vt 0.562500 0.937500
vt 0.437500 0.875000
vt 0.562500 0.875000
vt 0.437500 0.812500
vt 0.562500 0.812500
vt 0.437500 0.750000
vt 0.562500 0.750000
vt 0.437500 0.687500
vt 0.562500 0.687500
vt 0.437500 0.687500
vt 0.562500 0.687500
vt 0.437500 0.750000
vt 0.562500 0.750000
vt 0.437500 0.812500
vt 0.562500 0.812500
vt 0.437500 0.875000
vt 0.562500 0.875000
vt 0.437500 0.937500
vt 0.562500 0.937500
vt 0.562500 0.687500
vt 0.437500 0.687500
vt 0.562500 0.750000
vt 0.437500 0.750000
vt 0.562500 0.812500
vt 0.437500 0.812500
vt 0.562500 0.875000
vt 0.437500 0.875000
vt 0.562500 0.937500
vt 0.437500 0.937500
vt 0.562500 0.937500
vt 0.437500 0.937500
vt 0.562500 0.875000
vt 0.437500 0.875000
vt 0.562500 0.812500
vt 0.437500 0.812500
vt 0.562500 0.750000
vt 0.437500 0.750000
vt 0.562500 0.687500
vt 0.437500 0.687500
vt 0.562500 1.000000
vt 0.437500 1.000000
vt 0.437500 1.000000
vt 0.562500 1.000000
vt 0.562500 1.000000
vt 0.437500 1.000000
vt 0.437500 1.000000
vt 0.562500 1.000000
vt 0.437500 0.625000
vt 0.562500 0.625000
vt 0.562500 0.625000
vt 0.437500 0.625000
vt 0.562500 0.625000
vt 0.437500 0.625000
vt 0.437500 0.625000
vt 0.562500 0.625000
vt 0.437500 0.937500
vt 0.562500 0.937500
vt 0.437500 0.875000
vt 0.562500 0.875000
vt 0.437500 0.812500
vt 0.562500 0.812500
vt 0.437500 0.750000
vt 0.562500 0.750000
vt 0.437500 0.687500
vt 0.562500 0.687500
vt 0.437500 0.687500
vt 0.562500 0.687500
vt 0.437500 0.750000
vt 0.562500 0.750000
vt 0.437500 0.812500
vt 0.562500 0.812500
vt 0.437500 0.875000
vt 0.562500 0.875000
vt 0.437500 0.937500
vt 0.562500 0.937500
vt 0.562500 0.687500
vt 0.437500 0.687500
vt 0.562500 0.750000
vt 0.437500 0.750000
vt 0.562500 0.812500
vt 0.437500 0.812500
vt 0.562500 0.875000
vt 0.437500 0.875000
vt 0.562500 0.937500
vt 0.437500 0.937500
vt 0.562500 0.937500
vt 0.437500 0.937500
vt 0.562500 0.875000
vt 0.437500 0.875000
vt 0.562500 0.812500
vt 0.437500 0.812500
vt 0.562500 0.750000
vt 0.437500 0.750000
vt 0.562500 0.687500
vt 0.437500 0.687500
vt 0.562500 1.000000
vt 0.437500 1.000000
vt 0.437500 1.000000
vt 0.562500 1.000000
vt 0.562500 1.000000
vt 0.437500 1.000000
vt 0.437500 1.000000
vt 0.562500 1.000000
vt 0.437500 0.625000
vt 0.562500 0.625000
vt 0.562500 0.625000
vt 0.437500 0.625000
vt 0.562500 0.625000
vt 0.437500 0.625000
vt 0.437500 0.625000
vt 0.562500 0.625000
vt 0.437500 0.937500
vt 0.562500 0.937500
vt 0.437500 0.875000
vt 0.562500 0.875000
vt 0.437500 0.812500
vt 0.562500 0.812500
vt 0.437500 0.750000
vt 0.562500 0.750000
vt 0.437500 0.687500
vt 0.562500 0.687500
vt 0.437500 0.687500
vt 0.562500 0.687500
vt 0.437500 0.750000
vt 0.562500 0.750000
vt 0.437500 0.812500
vt 0.562500 0.812500
vt 0.437500 0.875000
vt 0.562500 0.875000
vt 0.437500 0.937500
vt 0.562500 0.937500
vt 0.562500 0.687500
vt 0.437500 0.687500
vt 0.562500 0.750000
vt 0.437500 0.750000
vt 0.562500 0.812500
vt 0.437500 0.812500
vt 0.562500 0.875000
vt 0.437500 0.875000
vt 0.562500 0.937500
vt 0.437500 0.937500
vt 0.562500 0.937500
vt 0.437500 0.937500
vt 0.562500 0.875000
vt 0.437500 0.875000
vt 0.562500 0.812500
vt 0.437500 0.812500
vt 0.562500 0.750000
vt 0.437500 0.750000
vt 0.562500 0.687500
vt 0.437500 0.687500
s 0
usemtl Material
f 1/1/1 2/4/1 4/9/1 3/6/1
f 3/7/2 4/10/2 8/20/2 7/17/2
f 7/18/3 8/21/3 6/15/3 5/12/3
f 5/13/4 6/16/4 2/5/4 1/2/4
f 8/22/5 4/11/5 2/5/5 6/16/5
f 3/8/6 7/19/6 5/14/6 1/3/6
f 38/125/2 37/121/2 9/23/2 10/27/2
f 37/122/5 39/129/5 11/31/5 9/24/5
f 40/131/4 12/33/4 11/31/4 39/129/4
f 38/126/6 10/28/6 12/34/6 40/132/6
f 10/29/7 9/25/7 13/37/7 14/41/7
f 9/26/5 11/32/5 15/45/5 13/38/5
f 12/35/8 16/47/8 15/45/8 11/32/8
f 10/30/6 14/42/6 16/48/6 12/36/6
f 14/43/3 13/39/3 17/51/3 18/55/3
f 13/40/5 15/46/5 19/59/5 17/52/5
f 16/49/1 20/61/1 19/59/1 15/46/1
f 14/44/6 18/56/6 20/62/6 16/50/6
f 18/57/9 17/53/9 21/65/9 22/69/9
f 17/54/5 19/60/5 23/73/5 21/66/5
f 20/63/10 24/75/10 23/73/10 19/60/10
f 18/58/6 22/70/6 24/76/6 20/64/6
f 22/71/4 21/67/4 25/79/4 26/83/4
f 21/68/5 23/74/5 27/87/5 25/80/5
f 24/77/2 28/89/2 27/87/2 23/74/2
f 22/72/6 26/84/6 28/90/6 24/78/6
f 26/85/8 25/81/8 29/93/8 30/97/8
f 25/82/5 27/88/5 31/101/5 29/94/5
f 28/91/7 32/103/7 31/101/7 27/88/7
f 26/86/6 30/98/6 32/104/6 28/92/6
f 30/99/1 29/95/1 33/107/1 34/111/1
f 29/96/5 31/102/5 35/115/5 33/108/5
f 32/105/3 36/117/3 35/115/3 31/102/3
f 30/100/6 34/112/6 36/118/6 32/106/6
f 34/113/10 33/109/10 37/123/10 38/127/10
f 33/110/5 35/116/5 39/130/5 37/124/5
f 36/119/9 40/133/9 39/130/9 35/116/9
f 34/114/6 38/128/6 40/134/6 36/120/6
f 41/135/1 42/138/1 44/143/1 43/140/1
f 43/141/2 44/144/2 48/154/2 47/151/2
f 47/152/3 48/155/3 46/149/3 45/146/3
f 45/147/4 46/150/4 42/139/4 41/136/4
f 43/142/6 47/153/6 45/148/6 41/137/6
f 48/156/5 44/145/5 42/139/5 46/150/5
f 76/212/1 53/165/1 54/167/1 61/182/1
f 61/181/11 54/168/11 55/169/11 62/184/11
f 67/194/12 56/171/12 53/166/12 76/211/12
f 62/183/3 55/170/3 56/172/3 67/193/3
f 52/163/3 66/191/3 71/201/3 51/161/3
f 66/191/3 65/189/3 70/199/3 71/201/3
f 65/189/3 64/187/3 69/197/3 70/199/3
f 64/187/3 63/185/3 68/195/3 69/197/3
f 63/185/3 62/183/3 67/193/3 68/195/3
f 51/162/12 71/202/12 72/203/12 49/157/12
f 71/202/12 70/200/12 73/205/12 72/203/12
f 70/200/12 69/198/12 74/207/12 73/205/12
f 69/198/12 68/196/12 75/209/12 74/207/12
f 68/196/12 67/194/12 76/211/12 75/209/12
f 50/159/11 57/173/11 66/192/11 52/164/11
f 57/173/11 58/175/11 65/190/11 66/192/11
f 58/175/11 59/177/11 64/188/11 65/190/11
f 59/177/11 60/179/11 63/186/11 64/188/11
f 60/179/11 61/181/11 62/184/11 63/186/11
f 49/158/1 72/204/1 57/174/1 50/160/1
f 72/204/1 73/206/1 58/176/1 57/174/1
f 73/206/1 74/208/1 59/178/1 58/176/1
f 74/208/1 75/210/1 60/180/1 59/178/1
f 75/210/1 76/212/1 61/182/1 60/180/1
f 104/268/4 81/221/4 82/223/4 89/238/4
f 89/237/13 82/224/13 83/225/13 90/240/13
f 95/250/14 84/227/14 81/222/14 104/267/14
f 90/239/2 83/226/2 84/228/2 95/249/2
f 80/219/2 94/247/2 99/257/2 79/217/2
f 94/247/2 93/245/2 98/255/2 99/257/2
f 93/245/2 92/243/2 97/253/2 98/255/2
f 92/243/2 91/241/2 96/251/2 97/253/2
f 91/241/2 90/239/2 95/249/2 96/251/2
f 79/218/14 99/258/14 100/259/14 77/213/14
f 99/258/14 98/256/14 101/261/14 100/259/14
f 98/256/14 97/254/14 102/263/14 101/261/14
f 97/254/14 96/252/14 103/265/14 102/263/14
f 96/252/14 95/250/14 104/267/14 103/265/14
f 78/215/13 85/229/13 94/248/13 80/220/13
f 85/229/13 86/231/13 93/246/13 94/248/13
f 86/231/13 87/233/13 92/244/13 93/246/13
f 87/233/13 88/235/13 91/242/13 92/244/13
f 88/235/13 89/237/13 90/240/13 91/242/13
f 77/214/4 100/260/4 85/230/4 78/216/4
f 100/260/4 101/262/4 86/232/4 85/230/4
f 101/262/4 102/264/4 87/234/4 86/232/4
f 102/264/4 103/266/4 88/236/4 87/234/4
f 103/266/4 104/268/4 89/238/4 88/236/4
f 132/324/3 109/277/3 110/279/3 117/294/3
f 117/293/15 110/280/15 111/281/15 118/296/15
f 123/306/16 112/283/16 109/278/16 132/323/16
f 118/295/1 111/282/1 112/284/1 123/305/1
f 108/275/1 122/303/1 127/313/1 107/273/1
f 122/303/1 121/301/1 126/311/1 127/313/1
f 121/301/1 120/299/1 125/309/1 126/311/1
f 120/299/1 119/297/1 124/307/1 125/309/1
f 119/297/1 118/295/1 123/305/1 124/307/1
f 107/274/16 127/314/16 128/315/16 105/269/16
f 127/314/16 126/312/16 129/317/16 128/315/16
f 126/312/16 125/310/16 130/319/16 129/317/16
f 125/310/16 124/308/16 131/321/16 130/319/16
f 124/308/16 123/306/16 132/323/16 131/321/16
f 106/271/15 113/285/15 122/304/15 108/276/15
f 113/285/15 114/287/15 121/302/15 122/304/15
f 114/287/15 115/289/15 120/300/15 121/302/15
f 115/289/15 116/291/15 119/298/15 120/300/15
f 116/291/15 117/293/15 118/296/15 119/298/15
f 105/270/3 128/316/3 113/286/3 106/272/3
f 128/316/3 129/318/3 114/288/3 113/286/3
f 129/318/3 130/320/3 115/290/3 114/288/3
f 130/320/3 131/322/3 116/292/3 115/290/3
f 131/322/3 132/324/3 117/294/3 116/292/3
f 160/380/2 137/333/2 138/335/2 145/350/2
f 145/349/17 138/336/17 139/337/17 146/352/17
f 151/362/18 140/339/18 137/334/18 160/379/18
f 146/351/4 139/338/4 140/340/4 151/361/4
f 136/331/4 150/359/4 155/369/4 135/329/4
f 150/359/4 149/357/4 154/367/4 155/369/4
f 149/357/4 148/355/4 153/365/4 154/367/4
f 148/355/4 147/353/4 152/363/4 153/365/4
f 147/353/4 146/351/4 151/361/4 152/363/4
f 135/330/18 155/370/18 156/371/18 133/325/18
f 155/370/18 154/368/18 157/373/18 156/371/18
f 154/368/18 153/366/18 158/375/18 157/373/18
f 153/366/18 152/364/18 159/377/18 158/375/18
f 152/364/18 151/362/18 160/379/18 159/377/18
f 134/327/17 141/341/17 150/360/17 136/332/17
f 141/341/17 142/343/17 149/358/17 150/360/17
f 142/343/17 143/345/17 148/356/17 149/358/17
f 143/345/17 144/347/17 147/354/17 148/356/17
f 144/347/17 145/349/17 146/352/17 147/354/17
f 133/326/2 156/372/2 141/342/2 134/328/2
f 156/372/2 157/374/2 142/344/2 141/342/2
f 157/374/2 158/376/2 143/346/2 142/344/2
f 158/376/2 159/378/2 144/348/2 143/346/2
f 159/378/2 160/380/2 145/350/2 144/348/2