Clean up and optimize copycat models

- Rename ITransformableTE -> ITransformableBlockEntity
This commit is contained in:
PepperCode1 2023-02-24 12:37:41 -08:00
parent 783cd126f7
commit 42675f9511
25 changed files with 296 additions and 301 deletions

View file

@ -831,8 +831,8 @@ public class AllBlockEntityTypes {
.validBlocks(AllBlocks.TRAIN_DOOR, AllBlocks.FRAMED_GLASS_DOOR)
.register();
public static final BlockEntityEntry<CopycatBlockEntity> UNIVERSAL_FRAME = REGISTRATE
.blockEntity("universal_frame", CopycatBlockEntity::new)
public static final BlockEntityEntry<CopycatBlockEntity> COPYCAT = REGISTRATE
.blockEntity("copycat", CopycatBlockEntity::new)
.validBlocks(AllBlocks.COPYCAT_PANEL, AllBlocks.COPYCAT_STEP)
.register();

View file

@ -1,6 +1,6 @@
package com.simibubi.create.content.contraptions.components.structureMovement;
public interface ITransformableTE {
public interface ITransformableBlockEntity {
void transform(StructureTransform transform);

View file

@ -111,8 +111,8 @@ public class StructureTransform {
}
public void apply(BlockEntity be) {
if (be instanceof ITransformableTE)
((ITransformableTE) be).transform(this);
if (be instanceof ITransformableBlockEntity)
((ITransformableBlockEntity) be).transform(this);
}
/**

View file

@ -10,8 +10,8 @@ import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour.A
import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour.AttachmentTypes.ComponentPartials;
import com.simibubi.create.content.contraptions.fluids.pipes.FluidPipeBlock;
import com.simibubi.create.content.contraptions.relays.elementary.BracketedBlockEntityBehaviour;
import com.simibubi.create.foundation.block.connected.BakedModelWrapperWithData;
import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour;
import com.simibubi.create.foundation.model.BakedModelWrapperWithData;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.client.Minecraft;
@ -34,7 +34,7 @@ public class PipeAttachmentModel extends BakedModelWrapperWithData {
}
@Override
protected Builder gatherModelData(Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state,
protected void gatherModelData(Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state,
IModelData blockEntityData) {
PipeModelData data = new PipeModelData();
FluidTransportBehaviour transport = BlockEntityBehaviour.get(world, pos, FluidTransportBehaviour.TYPE);
@ -47,7 +47,7 @@ public class PipeAttachmentModel extends BakedModelWrapperWithData {
data.putBracket(bracket.getBracket());
data.setEncased(FluidPipeBlock.shouldDrawCasing(world, pos, state));
return builder.withInitial(PIPE_PROPERTY, data);
builder.withInitial(PIPE_PROPERTY, data);
}
@Override

View file

@ -3,7 +3,7 @@ package com.simibubi.create.content.contraptions.fluids.pipes;
import java.util.List;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlockEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
import com.simibubi.create.content.contraptions.fluids.FluidPropagator;
import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour;
@ -17,7 +17,7 @@ import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
public class FluidPipeBlockEntity extends SmartBlockEntity implements ITransformableTE {
public class FluidPipeBlockEntity extends SmartBlockEntity implements ITransformableBlockEntity {
public FluidPipeBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);

View file

@ -42,12 +42,13 @@ public class FluidTankModel extends CTModel {
}
@Override
protected Builder gatherModelData(Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state,
protected void gatherModelData(Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state,
IModelData blockEntityData) {
super.gatherModelData(builder, world, pos, state, blockEntityData);
CullData cullData = new CullData();
for (Direction d : Iterate.horizontalDirections)
cullData.setCulled(d, ConnectivityHandler.isConnected(world, pos, pos.relative(d)));
return super.gatherModelData(builder, world, pos, state, blockEntityData).withInitial(CULL_PROPERTY, cullData);
builder.withInitial(CULL_PROPERTY, cullData);
}
@Override
@ -66,7 +67,7 @@ public class FluidTankModel extends CTModel {
return quads;
}
private class CullData {
private static class CullData {
boolean[] culledFaces;
public CullData() {

View file

@ -56,7 +56,6 @@ import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.data.ModelDataMap;
import net.minecraftforge.client.model.data.ModelProperty;
import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fml.DistExecutor;
@ -517,11 +516,9 @@ public class BeltBlockEntity extends KineticBlockEntity {
return empty;
}
public static final ModelProperty<CasingType> CASING_PROPERTY = new ModelProperty<>();
@Override
public IModelData getModelData() {
return new ModelDataMap.Builder().withInitial(CASING_PROPERTY, casing)
return new ModelDataMap.Builder().withInitial(BeltModel.CASING_PROPERTY, casing)
.build();
}

View file

@ -1,15 +1,13 @@
package com.simibubi.create.content.contraptions.relays.belt;
import static com.simibubi.create.content.contraptions.relays.belt.BeltBlockEntity.CASING_PROPERTY;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import com.simibubi.create.AllSpriteShifts;
import com.simibubi.create.content.contraptions.relays.belt.BeltBlockEntity.CasingType;
import com.simibubi.create.foundation.block.render.QuadHelper;
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
import com.simibubi.create.foundation.model.BakedQuadHelper;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
@ -18,9 +16,12 @@ import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.client.model.BakedModelWrapper;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.data.ModelProperty;
public class BeltModel extends BakedModelWrapper<BakedModel> {
public static final ModelProperty<CasingType> CASING_PROPERTY = new ModelProperty<>();
private static final SpriteShiftEntry SPRITE_SHIFT = AllSpriteShifts.ANDESIDE_BELT_CASING;
public BeltModel(BakedModel template) {
@ -44,14 +45,14 @@ public class BeltModel extends BakedModelWrapper<BakedModel> {
if (original != SPRITE_SHIFT.getOriginal())
continue;
BakedQuad newQuad = QuadHelper.clone(quad);
BakedQuad newQuad = BakedQuadHelper.clone(quad);
int[] vertexData = newQuad.getVertices();
for (int vertex = 0; vertex < 4; vertex++) {
float u = QuadHelper.getU(vertexData, vertex);
float v = QuadHelper.getV(vertexData, vertex);
QuadHelper.setU(vertexData, vertex, SPRITE_SHIFT.getTargetU(u));
QuadHelper.setV(vertexData, vertex, SPRITE_SHIFT.getTargetV(v));
float u = BakedQuadHelper.getU(vertexData, vertex);
float v = BakedQuadHelper.getV(vertexData, vertex);
BakedQuadHelper.setU(vertexData, vertex, SPRITE_SHIFT.getTargetU(u));
BakedQuadHelper.setV(vertexData, vertex, SPRITE_SHIFT.getTargetV(v));
}
quads.set(i, newQuad);

View file

@ -2,7 +2,7 @@ package com.simibubi.create.content.contraptions.relays.elementary;
import java.util.List;
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlockEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour;
@ -10,7 +10,7 @@ import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
public class BracketedKineticBlockEntity extends SimpleKineticBlockEntity implements ITransformableTE {
public class BracketedKineticBlockEntity extends SimpleKineticBlockEntity implements ITransformableBlockEntity {
public BracketedKineticBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);

View file

@ -81,7 +81,7 @@ public abstract class CopycatBlock extends Block implements IBE<CopycatBlockEnti
context.getLevel()
.levelEvent(2001, context.getClickedPos(), Block.getId(ufte.getBlockState()));
ufte.setMaterial(AllBlocks.COPYCAT_BASE.getDefaultState());
ufte.setItem(ItemStack.EMPTY);
ufte.setConsumedItem(ItemStack.EMPTY);
return InteractionResult.SUCCESS;
});
}
@ -116,7 +116,7 @@ public abstract class CopycatBlock extends Block implements IBE<CopycatBlockEnti
return InteractionResult.SUCCESS;
ufte.setMaterial(material);
ufte.setItem(itemInHand);
ufte.setConsumedItem(itemInHand);
ufte.getLevel()
.playSound(null, ufte.getBlockPos(), material.getSoundType()
.getPlaceSound(), SoundSource.BLOCKS, 1, .75f);
@ -146,7 +146,7 @@ public abstract class CopycatBlock extends Block implements IBE<CopycatBlockEnti
return;
ufte.setMaterial(appliedState);
ufte.setItem(offhandItem);
ufte.setConsumedItem(offhandItem);
if (pPlacer instanceof Player player && player.isCreative())
return;
@ -215,7 +215,7 @@ public abstract class CopycatBlock extends Block implements IBE<CopycatBlockEnti
public void playerWillDestroy(Level pLevel, BlockPos pPos, BlockState pState, Player pPlayer) {
super.playerWillDestroy(pLevel, pPos, pState, pPlayer);
if (pPlayer.isCreative())
withBlockEntityDo(pLevel, pPos, ufte -> ufte.setItem(ItemStack.EMPTY));
withBlockEntityDo(pLevel, pPos, ufte -> ufte.setConsumedItem(ItemStack.EMPTY));
}
@Override
@ -225,7 +225,7 @@ public abstract class CopycatBlock extends Block implements IBE<CopycatBlockEnti
@Override
public BlockEntityType<? extends CopycatBlockEntity> getBlockEntityType() {
return AllBlockEntityTypes.UNIVERSAL_FRAME.get();
return AllBlockEntityTypes.COPYCAT.get();
}
// Connected Textures

View file

@ -5,7 +5,7 @@ import java.util.List;
import com.google.gson.JsonParser;
import com.mojang.serialization.JsonOps;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlockEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
import com.simibubi.create.content.logistics.block.redstone.RoseQuartzLampBlock;
import com.simibubi.create.content.schematics.ISpecialBlockEntityItemRequirement;
@ -24,55 +24,46 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.data.ModelDataMap;
import net.minecraftforge.client.model.data.ModelProperty;
import net.minecraftforge.items.ItemHandlerHelper;
public class CopycatBlockEntity extends SmartBlockEntity implements ISpecialBlockEntityItemRequirement, ITransformableTE {
public class CopycatBlockEntity extends SmartBlockEntity implements ISpecialBlockEntityItemRequirement, ITransformableBlockEntity {
ItemStack consumedItem;
BlockState baseBlock;
private BlockState material;
private ItemStack consumedItem;
public CopycatBlockEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state);
baseBlock = AllBlocks.COPYCAT_BASE.getDefaultState();
material = AllBlocks.COPYCAT_BASE.getDefaultState();
consumedItem = ItemStack.EMPTY;
}
public void setItem(ItemStack item) {
consumedItem = ItemHandlerHelper.copyStackWithSize(item, 1);
setChanged();
public BlockState getMaterial() {
return material;
}
public ItemStack getConsumedItem() {
return consumedItem;
}
@Override
public ItemRequirement getRequiredItems(BlockState state) {
if (consumedItem.isEmpty())
return ItemRequirement.NONE;
return new ItemRequirement(ItemUseType.CONSUME, consumedItem);
public boolean hasCustomMaterial() {
return !AllBlocks.COPYCAT_BASE.has(getMaterial());
}
public void setMaterial(BlockState blockState) {
BlockState wrapperState = getBlockState();
if (!baseBlock.is(blockState.getBlock()))
if (!material.is(blockState.getBlock()))
for (Direction side : Iterate.directions) {
BlockPos neighbour = worldPosition.relative(side);
BlockState neighbourState = level.getBlockState(neighbour);
if (neighbourState != wrapperState)
continue;
if (!(level.getBlockEntity(neighbour)instanceof CopycatBlockEntity ufte))
if (!(level.getBlockEntity(neighbour) instanceof CopycatBlockEntity cbe))
continue;
BlockState otherMaterial = ufte.getMaterial();
BlockState otherMaterial = cbe.getMaterial();
if (!otherMaterial.is(blockState.getBlock()))
continue;
blockState = otherMaterial;
break;
}
baseBlock = blockState;
material = blockState;
if (!level.isClientSide()) {
notifyUpdate();
return;
@ -80,50 +71,32 @@ public class CopycatBlockEntity extends SmartBlockEntity implements ISpecialBloc
redraw();
}
public boolean hasCustomMaterial() {
return !AllBlocks.COPYCAT_BASE.has(getMaterial());
}
public BlockState getMaterial() {
return baseBlock;
}
public boolean cycleMaterial() {
if (baseBlock.hasProperty(BlockStateProperties.FACING))
setMaterial(baseBlock.cycle(BlockStateProperties.FACING));
else if (baseBlock.hasProperty(BlockStateProperties.HORIZONTAL_FACING))
setMaterial(baseBlock.cycle(BlockStateProperties.HORIZONTAL_FACING));
else if (baseBlock.hasProperty(BlockStateProperties.AXIS))
setMaterial(baseBlock.cycle(BlockStateProperties.AXIS));
else if (baseBlock.hasProperty(BlockStateProperties.HORIZONTAL_AXIS))
setMaterial(baseBlock.cycle(BlockStateProperties.HORIZONTAL_AXIS));
else if (baseBlock.hasProperty(BlockStateProperties.LIT))
setMaterial(baseBlock.cycle(BlockStateProperties.LIT));
else if (baseBlock.hasProperty(RoseQuartzLampBlock.POWERING))
setMaterial(baseBlock.cycle(RoseQuartzLampBlock.POWERING));
if (material.hasProperty(BlockStateProperties.FACING))
setMaterial(material.cycle(BlockStateProperties.FACING));
else if (material.hasProperty(BlockStateProperties.HORIZONTAL_FACING))
setMaterial(material.cycle(BlockStateProperties.HORIZONTAL_FACING));
else if (material.hasProperty(BlockStateProperties.AXIS))
setMaterial(material.cycle(BlockStateProperties.AXIS));
else if (material.hasProperty(BlockStateProperties.HORIZONTAL_AXIS))
setMaterial(material.cycle(BlockStateProperties.HORIZONTAL_AXIS));
else if (material.hasProperty(BlockStateProperties.LIT))
setMaterial(material.cycle(BlockStateProperties.LIT));
else if (material.hasProperty(RoseQuartzLampBlock.POWERING))
setMaterial(material.cycle(RoseQuartzLampBlock.POWERING));
else
return false;
return true;
}
@Override
protected void read(CompoundTag tag, boolean clientPacket) {
super.read(tag, clientPacket);
public ItemStack getConsumedItem() {
return consumedItem;
}
consumedItem = ItemStack.of(tag.getCompound("Item"));
BlockState prevMaterial = baseBlock;
if (!tag.contains("Material"))
return;
JsonOps ops = JsonOps.INSTANCE;
BlockState.CODEC.decode(ops, JsonParser.parseString(tag.getString("Material")))
.result()
.ifPresent(p -> baseBlock = p.getFirst());
if (clientPacket && prevMaterial != baseBlock)
redraw();
public void setConsumedItem(ItemStack stack) {
consumedItem = ItemHandlerHelper.copyStackWithSize(stack, 1);
setChanged();
}
private void redraw() {
@ -137,6 +110,41 @@ public class CopycatBlockEntity extends SmartBlockEntity implements ISpecialBloc
}
}
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {}
@Override
public ItemRequirement getRequiredItems(BlockState state) {
if (consumedItem.isEmpty())
return ItemRequirement.NONE;
return new ItemRequirement(ItemUseType.CONSUME, consumedItem);
}
@Override
public void transform(StructureTransform transform) {
material = transform.apply(material);
notifyUpdate();
}
@Override
protected void read(CompoundTag tag, boolean clientPacket) {
super.read(tag, clientPacket);
consumedItem = ItemStack.of(tag.getCompound("Item"));
BlockState prevMaterial = material;
if (!tag.contains("Material"))
return;
JsonOps ops = JsonOps.INSTANCE;
BlockState.CODEC.decode(ops, JsonParser.parseString(tag.getString("Material")))
.result()
.ifPresent(p -> material = p.getFirst());
if (clientPacket && prevMaterial != material)
redraw();
}
@Override
protected void write(CompoundTag tag, boolean clientPacket) {
super.write(tag, clientPacket);
@ -144,27 +152,16 @@ public class CopycatBlockEntity extends SmartBlockEntity implements ISpecialBloc
tag.put("Item", consumedItem.serializeNBT());
JsonOps ops = JsonOps.INSTANCE;
BlockState.CODEC.encode(baseBlock, ops, ops.empty())
BlockState.CODEC.encode(material, ops, ops.empty())
.result()
.map(je -> je.toString())
.ifPresent(s -> tag.putString("Material", s));
}
public static final ModelProperty<BlockState> MATERIAL_PROPERTY = new ModelProperty<>();
@Override
public IModelData getModelData() {
return new ModelDataMap.Builder().withInitial(MATERIAL_PROPERTY, baseBlock)
return new ModelDataMap.Builder().withInitial(CopycatModel.MATERIAL_PROPERTY, material)
.build();
}
@Override
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {}
@Override
public void transform(StructureTransform transform) {
baseBlock = transform.apply(baseBlock);
notifyUpdate();
}
}

View file

@ -1,20 +1,13 @@
package com.simibubi.create.content.curiosities.frames;
import static com.simibubi.create.content.curiosities.frames.CopycatBlockEntity.MATERIAL_PROPERTY;
import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUnInterpolatedU;
import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUnInterpolatedV;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import javax.annotation.Nullable;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.block.connected.BakedModelWrapperWithData;
import com.simibubi.create.foundation.block.render.QuadHelper;
import com.simibubi.create.foundation.model.BakedModelWrapperWithData;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ItemBlockRenderTypes;
@ -28,177 +21,94 @@ import net.minecraft.core.Direction;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.client.MinecraftForgeClient;
import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.client.model.data.IModelData;
import net.minecraftforge.client.model.data.ModelDataMap;
import net.minecraftforge.client.model.data.ModelDataMap.Builder;
import net.minecraftforge.client.model.data.ModelProperty;
public abstract class CopycatModel extends BakedModelWrapperWithData {
private static final ModelProperty<IModelData> WRAPPED_DATA_PROPERTY = new ModelProperty<>();
public static final ModelProperty<BlockState> MATERIAL_PROPERTY = new ModelProperty<>();
private static final ModelProperty<OcclusionData> OCCLUSION_PROPERTY = new ModelProperty<>();
private static final ModelProperty<IModelData> WRAPPED_DATA_PROPERTY = new ModelProperty<>();
public CopycatModel(BakedModel originalModel) {
super(originalModel);
}
@Override
protected Builder gatherModelData(Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state,
protected void gatherModelData(Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state,
IModelData blockEntityData) {
BlockState wrappedState = getMaterial(world, pos, state);
BlockState material = getMaterial(blockEntityData);
if (material == null)
return;
if (wrappedState == null)
return builder;
if (blockEntityData instanceof ModelDataMap mdm && mdm.hasProperty(MATERIAL_PROPERTY))
builder.withInitial(MATERIAL_PROPERTY, mdm.getData(MATERIAL_PROPERTY));
builder.withInitial(MATERIAL_PROPERTY, material);
OcclusionData occlusionData = new OcclusionData();
if (state.getBlock()instanceof CopycatBlock ufb) {
if (state.getBlock() instanceof CopycatBlock copycatBlock) {
MutableBlockPos mutablePos = new MutableBlockPos();
for (Direction face : Iterate.directions)
if (ufb.canFaceBeOccluded(state, face))
if (!Block.shouldRenderFace(wrappedState, world, pos, face, mutablePos.setWithOffset(pos, face)))
if (copycatBlock.canFaceBeOccluded(state, face))
if (!Block.shouldRenderFace(material, world, pos, face, mutablePos.setWithOffset(pos, face)))
occlusionData.occlude(face);
builder.withInitial(OCCLUSION_PROPERTY, occlusionData);
}
IModelData modelData = getModelOf(wrappedState).getModelData(world, pos, wrappedState, EmptyModelData.INSTANCE);
return builder.withInitial(WRAPPED_DATA_PROPERTY, modelData);
IModelData wrappedData = getModelOf(material).getModelData(world, pos, material, EmptyModelData.INSTANCE);
builder.withInitial(WRAPPED_DATA_PROPERTY, wrappedData);
}
@Override
public List<BakedQuad> getQuads(BlockState state, Direction side, Random rand, IModelData extraData) {
List<BakedQuad> quads = super.getQuads(state, side, rand, extraData);
BlockState material = getMaterial(extraData);
IModelData wrappedData = extraData.getData(WRAPPED_DATA_PROPERTY);
public List<BakedQuad> getQuads(BlockState state, Direction side, Random rand, IModelData data) {
BlockState material = getMaterial(data);
if (material == null)
return quads;
return super.getQuads(state, side, rand, data);
OcclusionData occlusionData = data.getData(OCCLUSION_PROPERTY);
if (occlusionData != null && occlusionData.isOccluded(side))
return super.getQuads(state, side, rand, data);
RenderType renderType = MinecraftForgeClient.getRenderType();
if (renderType != null && !ItemBlockRenderTypes.canRenderInLayer(material, renderType))
return quads;
return super.getQuads(state, side, rand, data);
IModelData wrappedData = data.getData(WRAPPED_DATA_PROPERTY);
if (wrappedData == null)
wrappedData = EmptyModelData.INSTANCE;
OcclusionData occlusionData = extraData.getData(OCCLUSION_PROPERTY);
if (occlusionData != null && occlusionData.isOccluded(side))
return quads;
return getCroppedQuads(state, side, rand, material, wrappedData);
}
protected abstract List<BakedQuad> getCroppedQuads(BlockState state, Direction side, Random rand,
BlockState material, IModelData wrappedData);
public static boolean cropAndMove(BakedQuad quad, AABB crop, Vec3 move) {
int[] vertexData = quad.getVertices();
Vec3 xyz0 = QuadHelper.getXYZ(vertexData, 0);
Vec3 xyz1 = QuadHelper.getXYZ(vertexData, 1);
Vec3 xyz2 = QuadHelper.getXYZ(vertexData, 2);
Vec3 xyz3 = QuadHelper.getXYZ(vertexData, 3);
Vec3 uAxis = xyz3.add(xyz2)
.scale(.5);
Vec3 vAxis = xyz1.add(xyz2)
.scale(.5);
Vec3 center = xyz3.add(xyz2)
.add(xyz0)
.add(xyz1)
.scale(.25);
float u0 = QuadHelper.getU(vertexData, 0);
float u3 = QuadHelper.getU(vertexData, 3);
float v0 = QuadHelper.getV(vertexData, 0);
float v1 = QuadHelper.getV(vertexData, 1);
TextureAtlasSprite sprite = quad.getSprite();
float uScale = (float) Math
.round((getUnInterpolatedU(sprite, u3) - getUnInterpolatedU(sprite, u0)) / xyz3.distanceTo(xyz0));
float vScale = (float) Math
.round((getUnInterpolatedV(sprite, v1) - getUnInterpolatedV(sprite, v0)) / xyz1.distanceTo(xyz0));
if (uScale == 0) {
float v3 = QuadHelper.getV(vertexData, 3);
float u1 = QuadHelper.getU(vertexData, 1);
uAxis = xyz1.add(xyz2)
.scale(.5);
vAxis = xyz3.add(xyz2)
.scale(.5);
uScale = (float) Math
.round((getUnInterpolatedU(sprite, u1) - getUnInterpolatedU(sprite, u0)) / xyz1.distanceTo(xyz0));
vScale = (float) Math
.round((getUnInterpolatedV(sprite, v3) - getUnInterpolatedV(sprite, v0)) / xyz3.distanceTo(xyz0));
}
uAxis = uAxis.subtract(center)
.normalize();
vAxis = vAxis.subtract(center)
.normalize();
Vec3 min = new Vec3(crop.minX, crop.minY, crop.minZ);
Vec3 max = new Vec3(crop.maxX, crop.maxY, crop.maxZ);
for (int vertex = 0; vertex < 4; vertex++) {
Vec3 xyz = QuadHelper.getXYZ(vertexData, vertex);
Vec3 newXyz = VecHelper.componentMin(max, VecHelper.componentMax(xyz, min));
Vec3 diff = newXyz.subtract(xyz);
if (diff.lengthSqr() > 0) {
float u = QuadHelper.getU(vertexData, vertex);
float v = QuadHelper.getV(vertexData, vertex);
float uDiff = (float) uAxis.dot(diff) * uScale;
float vDiff = (float) vAxis.dot(diff) * vScale;
QuadHelper.setU(vertexData, vertex, sprite.getU(getUnInterpolatedU(sprite, u) + uDiff));
QuadHelper.setV(vertexData, vertex, sprite.getV(getUnInterpolatedV(sprite, v) + vDiff));
}
QuadHelper.setXYZ(vertexData, vertex, newXyz.add(move));
}
return true;
}
@Override
public TextureAtlasSprite getParticleIcon(IModelData data) {
BlockState material = getMaterial(data);
IModelData wrappedData = data.getData(WRAPPED_DATA_PROPERTY);
if (material == null)
return super.getParticleIcon(data);
IModelData wrappedData = data.getData(WRAPPED_DATA_PROPERTY);
if (wrappedData == null)
wrappedData = EmptyModelData.INSTANCE;
if (material != null)
return getModelOf(material).getParticleIcon(wrappedData);
return super.getParticleIcon(data);
return getModelOf(material).getParticleIcon(wrappedData);
}
@Nullable
public BlockState getMaterial(IModelData extraData) {
BlockState material = extraData.getData(MATERIAL_PROPERTY);
public static BlockState getMaterial(IModelData data) {
BlockState material = data.getData(MATERIAL_PROPERTY);
return material == null ? AllBlocks.COPYCAT_BASE.getDefaultState() : material;
}
@Nullable
public BlockState getMaterial(BlockAndTintGetter world, BlockPos pos, BlockState state) {
if (!(state.getBlock()instanceof CopycatBlock ufb))
return null;
return ufb.getBlockEntityOptional(world, pos)
.map(CopycatBlockEntity::getMaterial)
.orElse(null);
}
public BakedModel getModelOf(BlockState wrappedState) {
public static BakedModel getModelOf(BlockState state) {
return Minecraft.getInstance()
.getBlockRenderer()
.getBlockModel(wrappedState);
.getBlockModel(state);
}
private static class OcclusionData {
@ -206,7 +116,6 @@ public abstract class CopycatModel extends BakedModelWrapperWithData {
public OcclusionData() {
occluded = new boolean[6];
Arrays.fill(occluded, false);
}
public void occlude(Direction face) {

View file

@ -4,7 +4,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import com.simibubi.create.foundation.block.render.QuadHelper;
import com.simibubi.create.foundation.model.BakedModelHelper;
import com.simibubi.create.foundation.model.BakedQuadHelper;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.client.renderer.block.model.BakedQuad;
@ -18,6 +19,8 @@ import net.minecraftforge.client.model.data.IModelData;
public class CopycatPanelModel extends CopycatModel {
protected static final AABB CUBE_AABB = new AABB(BlockPos.ZERO);
public CopycatPanelModel(BakedModel originalModel) {
super(originalModel);
}
@ -28,17 +31,22 @@ public class CopycatPanelModel extends CopycatModel {
Direction facing = state.getOptionalValue(CopycatPanelBlock.FACING)
.orElse(Direction.UP);
Vec3 normal = Vec3.atLowerCornerOf(facing.getNormal());
AABB cube = new AABB(BlockPos.ZERO);
BakedModel model = getModelOf(material);
List<BakedQuad> templateQuads = model.getQuads(material, side, rand, wrappedData);
int size = templateQuads.size();
List<BakedQuad> quads = new ArrayList<>();
Vec3 normal = Vec3.atLowerCornerOf(facing.getNormal());
Vec3 normalScaled14 = normal.scale(14 / 16f);
// 2 Pieces
for (boolean front : Iterate.trueAndFalse) {
Vec3 normalScaledN13 = normal.scale(front ? 0 : -13 / 16f);
float contract = 16 - (front ? 1 : 2);
AABB bb = CUBE_AABB.contract(normal.x * contract / 16, normal.y * contract / 16, normal.z * contract / 16);
if (!front)
bb = bb.move(normalScaled14);
for (int i = 0; i < size; i++) {
BakedQuad quad = templateQuads.get(i);
@ -49,15 +57,9 @@ public class CopycatPanelModel extends CopycatModel {
if (!front && direction == facing.getOpposite())
continue;
float contract = 16 - (front ? 1 : 2);
AABB bb = cube.contract(normal.x * contract / 16, normal.y * contract / 16, normal.z * contract / 16);
if (!front)
bb = bb.move(normal.scale(14 / 16f));
BakedQuad newQuad = QuadHelper.clone(quad);
if (cropAndMove(newQuad, bb, normal.scale(front ? 0 : -13 / 16f)));
quads.add(newQuad);
BakedQuad newQuad = BakedQuadHelper.clone(quad);
BakedModelHelper.cropAndMove(newQuad, bb, normalScaledN13);
quads.add(newQuad);
}
}

View file

@ -42,8 +42,8 @@ import net.minecraftforge.common.ForgeMod;
public class CopycatStepBlock extends WaterloggedCopycatBlock {
public static EnumProperty<Half> HALF = BlockStateProperties.HALF;
public static DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING;
public static final EnumProperty<Half> HALF = BlockStateProperties.HALF;
public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING;
private static final int placementHelperId = PlacementHelpers.register(new PlacementHelper());

View file

@ -4,7 +4,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import com.simibubi.create.foundation.block.render.QuadHelper;
import com.simibubi.create.foundation.model.BakedModelHelper;
import com.simibubi.create.foundation.model.BakedQuadHelper;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.client.renderer.block.model.BakedQuad;
@ -19,6 +20,11 @@ import net.minecraftforge.client.model.data.IModelData;
public class CopycatStepModel extends CopycatModel {
protected static final Vec3 VEC_Y_3 = new Vec3(0, .75, 0);
protected static final Vec3 VEC_Y_2 = new Vec3(0, .5, 0);
protected static final Vec3 VEC_Y_N2 = new Vec3(0, -.5, 0);
protected static final AABB CUBE_AABB = new AABB(BlockPos.ZERO);
public CopycatStepModel(BakedModel originalModel) {
super(originalModel);
}
@ -31,21 +37,33 @@ public class CopycatStepModel extends CopycatModel {
boolean upperHalf = state.getOptionalValue(CopycatStepBlock.HALF)
.orElse(Half.BOTTOM) == Half.TOP;
Vec3 zero = Vec3.ZERO;
Vec3 up = new Vec3(0, 1, 0);
Vec3 normal = Vec3.atLowerCornerOf(facing.getNormal());
BakedModel model = getModelOf(material);
List<BakedQuad> templateQuads = model.getQuads(material, side, rand, wrappedData);
int size = templateQuads.size();
AABB cube = new AABB(BlockPos.ZERO);
List<BakedQuad> quads = new ArrayList<>();
Vec3 normal = Vec3.atLowerCornerOf(facing.getNormal());
Vec3 normalScaled2 = normal.scale(.5);
Vec3 normalScaledN3 = normal.scale(-.75);
AABB bb = CUBE_AABB.contract(-normal.x * .75, .75, -normal.z * .75);
// 4 Pieces
for (boolean top : Iterate.trueAndFalse) {
for (boolean front : Iterate.trueAndFalse) {
AABB bb1 = bb;
if (front)
bb1 = bb1.move(normalScaledN3);
if (top)
bb1 = bb1.move(VEC_Y_3);
Vec3 offset = Vec3.ZERO;
if (front)
offset = offset.add(normalScaled2);
if (top != upperHalf)
offset = offset.add(upperHalf ? VEC_Y_2 : VEC_Y_N2);
for (int i = 0; i < size; i++) {
BakedQuad quad = templateQuads.get(i);
Direction direction = quad.getDirection();
@ -59,23 +77,9 @@ public class CopycatStepModel extends CopycatModel {
if (top && direction == Direction.DOWN)
continue;
AABB bb = cube.contract(-normal.x * .75, .75, -normal.z * .75);
if (front)
bb = bb.move(normal.scale(-.75));
if (top)
bb = bb.move(up.scale(.75));
Vec3 offset = zero;
if (front)
offset = offset.add(normal.scale(.5));
if (top != upperHalf)
offset = offset.add(up.scale(upperHalf ? .5 : -.5));
BakedQuad newQuad = QuadHelper.clone(quad);
if (cropAndMove(newQuad, bb, offset))
quads.add(newQuad);
BakedQuad newQuad = BakedQuadHelper.clone(quad);
BakedModelHelper.cropAndMove(newQuad, bb1, offset);
quads.add(newQuad);
}
}

View file

@ -21,20 +21,20 @@ import net.minecraftforge.client.model.data.ModelProperty;
public class ConnectedGirderModel extends CTModel {
protected static ModelProperty<ConnectionData> CONNECTION_PROPERTY = new ModelProperty<>();
protected static final ModelProperty<ConnectionData> CONNECTION_PROPERTY = new ModelProperty<>();
public ConnectedGirderModel(BakedModel originalModel) {
super(originalModel, new GirderCTBehaviour());
}
@Override
protected Builder gatherModelData(Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state,
protected void gatherModelData(Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state,
IModelData blockEntityData) {
super.gatherModelData(builder, world, pos, state, blockEntityData);
ConnectionData connectionData = new ConnectionData();
for (Direction d : Iterate.horizontalDirections)
connectionData.setConnected(d, GirderBlock.isConnected(world, pos, state, d));
return super.gatherModelData(builder, world, pos, state, blockEntityData).withInitial(CONNECTION_PROPERTY,
connectionData);
builder.withInitial(CONNECTION_PROPERTY, connectionData);
}
@Override
@ -52,7 +52,7 @@ public class ConnectedGirderModel extends CTModel {
return quads;
}
private class ConnectionData {
private static class ConnectionData {
boolean[] connectedFaces;
public ConnectionData() {

View file

@ -7,7 +7,7 @@ import javax.annotation.Nullable;
import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.base.KineticBlockEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlockEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
import com.simibubi.create.content.logistics.block.mechanicalArm.AllArmInteractionPointTypes.JukeboxPoint;
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Mode;
@ -45,7 +45,7 @@ import net.minecraft.world.level.chunk.ChunkSource;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class ArmBlockEntity extends KineticBlockEntity implements ITransformableTE {
public class ArmBlockEntity extends KineticBlockEntity implements ITransformableBlockEntity {
// Server
List<ArmInteractionPoint> inputs;

View file

@ -6,7 +6,7 @@ import javax.annotation.Nullable;
import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlockEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
import com.simibubi.create.content.logistics.block.display.DisplayLinkBlock;
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
@ -23,7 +23,7 @@ import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class TrackObserverBlockEntity extends SmartBlockEntity implements ITransformableTE {
public class TrackObserverBlockEntity extends SmartBlockEntity implements ITransformableBlockEntity {
public TrackTargetingBehaviour<TrackObserver> edgePoint;

View file

@ -4,7 +4,7 @@ import java.util.List;
import javax.annotation.Nullable;
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlockEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBehaviour;
@ -19,7 +19,7 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
public class SignalBlockEntity extends SmartBlockEntity implements ITransformableTE {
public class SignalBlockEntity extends SmartBlockEntity implements ITransformableBlockEntity {
public static enum OverlayState {
RENDER, SKIP, DUAL

View file

@ -17,7 +17,7 @@ import com.simibubi.create.AllItems;
import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlockEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
import com.simibubi.create.content.logistics.block.depot.DepotBehaviour;
import com.simibubi.create.content.logistics.block.display.DisplayLinkBlock;
@ -77,7 +77,7 @@ import net.minecraftforge.common.capabilities.Capability;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.network.PacketDistributor;
public class StationBlockEntity extends SmartBlockEntity implements ITransformableTE {
public class StationBlockEntity extends SmartBlockEntity implements ITransformableBlockEntity {
public TrackTargetingBehaviour<GlobalStation> edgePoint;
public LerpedFloat flag;

View file

@ -9,7 +9,7 @@ import java.util.Set;
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlockEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
import com.simibubi.create.content.logistics.trains.BezierConnection;
import com.simibubi.create.content.logistics.trains.ITrackBlock;
@ -46,7 +46,7 @@ import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.DistExecutor;
public class TrackBlockEntity extends SmartBlockEntity implements ITransformableTE, IMergeableBE {
public class TrackBlockEntity extends SmartBlockEntity implements ITransformableBlockEntity, IMergeableBE {
Map<BlockPos, BezierConnection> connections;
boolean cancelDrops;

View file

@ -7,7 +7,8 @@ import java.util.Random;
import com.simibubi.create.content.curiosities.frames.CopycatBlock;
import com.simibubi.create.foundation.block.connected.ConnectedTextureBehaviour.CTContext;
import com.simibubi.create.foundation.block.render.QuadHelper;
import com.simibubi.create.foundation.model.BakedModelWrapperWithData;
import com.simibubi.create.foundation.model.BakedQuadHelper;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.client.renderer.block.model.BakedQuad;
@ -34,9 +35,9 @@ public class CTModel extends BakedModelWrapperWithData {
}
@Override
protected Builder gatherModelData(Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state,
protected void gatherModelData(Builder builder, BlockAndTintGetter world, BlockPos pos, BlockState state,
IModelData blockEntityData) {
return builder.withInitial(CT_PROPERTY, createCTData(world, pos, state));
builder.withInitial(CT_PROPERTY, createCTData(world, pos, state));
}
protected CTData createCTData(BlockAndTintGetter world, BlockPos pos, BlockState state) {
@ -80,14 +81,14 @@ public class CTModel extends BakedModelWrapperWithData {
if (quad.getSprite() != spriteShift.getOriginal())
continue;
BakedQuad newQuad = QuadHelper.clone(quad);
BakedQuad newQuad = BakedQuadHelper.clone(quad);
int[] vertexData = newQuad.getVertices();
for (int vertex = 0; vertex < 4; vertex++) {
float u = QuadHelper.getU(vertexData, vertex);
float v = QuadHelper.getV(vertexData, vertex);
QuadHelper.setU(vertexData, vertex, spriteShift.getTargetU(u, index));
QuadHelper.setV(vertexData, vertex, spriteShift.getTargetV(v, index));
float u = BakedQuadHelper.getU(vertexData, vertex);
float v = BakedQuadHelper.getV(vertexData, vertex);
BakedQuadHelper.setU(vertexData, vertex, spriteShift.getTargetU(u, index));
BakedQuadHelper.setV(vertexData, vertex, spriteShift.getTargetV(v, index));
}
quads.set(i, newQuad);

View file

@ -0,0 +1,82 @@
package com.simibubi.create.foundation.model;
import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUnInterpolatedU;
import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUnInterpolatedV;
import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
public class BakedModelHelper {
public static void cropAndMove(BakedQuad quad, AABB crop, Vec3 move) {
int[] vertexData = quad.getVertices();
Vec3 xyz0 = BakedQuadHelper.getXYZ(vertexData, 0);
Vec3 xyz1 = BakedQuadHelper.getXYZ(vertexData, 1);
Vec3 xyz2 = BakedQuadHelper.getXYZ(vertexData, 2);
Vec3 xyz3 = BakedQuadHelper.getXYZ(vertexData, 3);
Vec3 uAxis = xyz3.add(xyz2)
.scale(.5);
Vec3 vAxis = xyz1.add(xyz2)
.scale(.5);
Vec3 center = xyz3.add(xyz2)
.add(xyz0)
.add(xyz1)
.scale(.25);
float u0 = BakedQuadHelper.getU(vertexData, 0);
float u3 = BakedQuadHelper.getU(vertexData, 3);
float v0 = BakedQuadHelper.getV(vertexData, 0);
float v1 = BakedQuadHelper.getV(vertexData, 1);
TextureAtlasSprite sprite = quad.getSprite();
float uScale = (float) Math
.round((getUnInterpolatedU(sprite, u3) - getUnInterpolatedU(sprite, u0)) / xyz3.distanceTo(xyz0));
float vScale = (float) Math
.round((getUnInterpolatedV(sprite, v1) - getUnInterpolatedV(sprite, v0)) / xyz1.distanceTo(xyz0));
if (uScale == 0) {
float v3 = BakedQuadHelper.getV(vertexData, 3);
float u1 = BakedQuadHelper.getU(vertexData, 1);
uAxis = xyz1.add(xyz2)
.scale(.5);
vAxis = xyz3.add(xyz2)
.scale(.5);
uScale = (float) Math
.round((getUnInterpolatedU(sprite, u1) - getUnInterpolatedU(sprite, u0)) / xyz1.distanceTo(xyz0));
vScale = (float) Math
.round((getUnInterpolatedV(sprite, v3) - getUnInterpolatedV(sprite, v0)) / xyz3.distanceTo(xyz0));
}
uAxis = uAxis.subtract(center)
.normalize();
vAxis = vAxis.subtract(center)
.normalize();
Vec3 min = new Vec3(crop.minX, crop.minY, crop.minZ);
Vec3 max = new Vec3(crop.maxX, crop.maxY, crop.maxZ);
for (int vertex = 0; vertex < 4; vertex++) {
Vec3 xyz = BakedQuadHelper.getXYZ(vertexData, vertex);
Vec3 newXyz = VecHelper.componentMin(max, VecHelper.componentMax(xyz, min));
Vec3 diff = newXyz.subtract(xyz);
if (diff.lengthSqr() > 0) {
float u = BakedQuadHelper.getU(vertexData, vertex);
float v = BakedQuadHelper.getV(vertexData, vertex);
float uDiff = (float) uAxis.dot(diff) * uScale;
float vDiff = (float) vAxis.dot(diff) * vScale;
BakedQuadHelper.setU(vertexData, vertex, sprite.getU(getUnInterpolatedU(sprite, u) + uDiff));
BakedQuadHelper.setV(vertexData, vertex, sprite.getV(getUnInterpolatedV(sprite, v) + vDiff));
}
BakedQuadHelper.setXYZ(vertexData, vertex, newXyz.add(move));
}
}
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.block.connected;
package com.simibubi.create.foundation.model;
import net.minecraft.client.resources.model.BakedModel;
import net.minecraft.core.BlockPos;
@ -21,10 +21,11 @@ public abstract class BakedModelWrapperWithData extends BakedModelWrapper<BakedM
Builder builder = new ModelDataMap.Builder();
if (originalModel instanceof BakedModelWrapperWithData)
((BakedModelWrapperWithData) originalModel).gatherModelData(builder, world, pos, state, blockEntityData);
return gatherModelData(builder, world, pos, state, blockEntityData).build();
gatherModelData(builder, world, pos, state, blockEntityData);
return builder.build();
}
protected abstract ModelDataMap.Builder gatherModelData(ModelDataMap.Builder builder, BlockAndTintGetter world,
protected abstract void gatherModelData(ModelDataMap.Builder builder, BlockAndTintGetter world,
BlockPos pos, BlockState state, IModelData blockEntityData);
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.block.render;
package com.simibubi.create.foundation.model;
import java.util.Arrays;
@ -8,7 +8,7 @@ import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.world.phys.Vec3;
public final class QuadHelper {
public final class BakedQuadHelper {
public static final VertexFormat FORMAT = DefaultVertexFormat.BLOCK;
public static final int VERTEX_STRIDE = FORMAT.getIntegerSize();
@ -22,7 +22,7 @@ public final class QuadHelper {
public static final int LIGHT_OFFSET = 6;
public static final int NORMAL_OFFSET = 7;
private QuadHelper() {}
private BakedQuadHelper() {}
public static BakedQuad clone(BakedQuad quad) {
return new BakedQuad(Arrays.copyOf(quad.getVertices(), quad.getVertices().length),
@ -36,6 +36,12 @@ public final class QuadHelper {
return new Vec3(x, y, z);
}
public static void setXYZ(int[] vertexData, int vertex, Vec3 xyz) {
vertexData[vertex * VERTEX_STRIDE + X_OFFSET] = Float.floatToRawIntBits((float) xyz.x);
vertexData[vertex * VERTEX_STRIDE + Y_OFFSET] = Float.floatToRawIntBits((float) xyz.y);
vertexData[vertex * VERTEX_STRIDE + Z_OFFSET] = Float.floatToRawIntBits((float) xyz.z);
}
public static float getU(int[] vertexData, int vertex) {
return Float.intBitsToFloat(vertexData[vertex * VERTEX_STRIDE + U_OFFSET]);
}
@ -44,12 +50,6 @@ public final class QuadHelper {
return Float.intBitsToFloat(vertexData[vertex * VERTEX_STRIDE + V_OFFSET]);
}
public static void setXYZ(int[] vertexData, int vertex, Vec3 xyz) {
vertexData[vertex * VERTEX_STRIDE + X_OFFSET] = Float.floatToRawIntBits((float) xyz.x);
vertexData[vertex * VERTEX_STRIDE + Y_OFFSET] = Float.floatToRawIntBits((float) xyz.y);
vertexData[vertex * VERTEX_STRIDE + Z_OFFSET] = Float.floatToRawIntBits((float) xyz.z);
}
public static void setU(int[] vertexData, int vertex, float u) {
vertexData[vertex * VERTEX_STRIDE + U_OFFSET] = Float.floatToRawIntBits(u);
}