More Rendering fixes
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
package appeng.client.render.model;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.client.model.data.ModelProperty;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* This implementation of IModelData allows us to know precisely which data is part of the
|
||||
* model data. This is relevant for {@link AutoRotatingBakedModel} and {@link AutoRotatingCacheKey}.
|
||||
*/
|
||||
public class AEModelData implements IModelData {
|
||||
|
||||
private final Direction up;
|
||||
private final Direction forward;
|
||||
|
||||
public AEModelData(Direction up, Direction forward) {
|
||||
this.up = Preconditions.checkNotNull(up);
|
||||
this.forward = Preconditions.checkNotNull(forward);
|
||||
}
|
||||
|
||||
public Direction getUp() {
|
||||
return up;
|
||||
}
|
||||
|
||||
public Direction getForward() {
|
||||
return forward;
|
||||
}
|
||||
|
||||
public boolean isCacheable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AEModelData that = (AEModelData) o;
|
||||
return up == that.up &&
|
||||
forward == that.forward;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(up, forward);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasProperty(ModelProperty<?> prop) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T getData(ModelProperty<T> prop) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T> T setData(ModelProperty<T> prop, T data) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@
|
||||
package appeng.client.render.model;
|
||||
|
||||
|
||||
import appeng.block.AEBaseTileBlock;
|
||||
import appeng.client.render.FacingToRotation;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
@@ -36,7 +35,9 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormatElement;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Vec3i;
|
||||
import net.minecraft.world.ILightReader;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.client.model.pipeline.BakedQuadBuilder;
|
||||
@@ -63,17 +64,17 @@ public class AutoRotatingBakedModel implements IBakedModel
|
||||
this.quadCache = CacheBuilder.newBuilder().maximumSize( 252 ).build( new CacheLoader<AutoRotatingCacheKey, List<BakedQuad>>()
|
||||
{
|
||||
@Override
|
||||
public List<BakedQuad> load( AutoRotatingCacheKey key ) throws Exception
|
||||
public List<BakedQuad> load( AutoRotatingCacheKey key )
|
||||
{
|
||||
return AutoRotatingBakedModel.this.getRotatedModel( key.getBlockState(), key.getSide(), key.getForward(), key.getUp() );
|
||||
return AutoRotatingBakedModel.this.getRotatedModel( key.getBlockState(), key.getSide(), new Random(0), key.getModelData() );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
private List<BakedQuad> getRotatedModel( BlockState state, Direction side, Direction forward, Direction up )
|
||||
private List<BakedQuad> getRotatedModel(BlockState state, Direction side, Random rand, AEModelData modelData)
|
||||
{
|
||||
FacingToRotation f2r = FacingToRotation.get( forward, up );
|
||||
List<BakedQuad> original = AutoRotatingBakedModel.this.parent.getQuads( state, f2r.resultingRotate( side ), new Random(0) );
|
||||
FacingToRotation f2r = FacingToRotation.get( modelData.getForward(), modelData.getUp() );
|
||||
List<BakedQuad> original = AutoRotatingBakedModel.this.parent.getQuads( state, f2r.resultingRotate( side ), rand, modelData );
|
||||
List<BakedQuad> rotated = new ArrayList<>( original.size() );
|
||||
for( BakedQuad quad : original )
|
||||
{
|
||||
@@ -155,21 +156,23 @@ public class AutoRotatingBakedModel implements IBakedModel
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(@Nullable BlockState state, @Nullable Direction side, @Nonnull Random rand, @Nonnull IModelData extraData) {
|
||||
|
||||
Direction forward = extraData.getData(AEBaseTileBlock.FORWARD);
|
||||
Direction up = extraData.getData(AEBaseTileBlock.UP);
|
||||
|
||||
if( forward == null || up == null )
|
||||
{
|
||||
if (!(extraData instanceof AEModelData)) {
|
||||
return this.parent.getQuads( state, side, rand, extraData );
|
||||
}
|
||||
|
||||
// The model has other properties than just forward/up, so it would cause our cache to inadvertendly also cache
|
||||
// these
|
||||
// additional states, possibly leading to huge issues if the other extended state properties do not implement
|
||||
// equals/hashCode correctly
|
||||
// FIXME: IModelData does not expose a way for us to check if it only has the two properties and no other
|
||||
return this.getRotatedModel( state, side, forward, up );
|
||||
AEModelData aeModelData = (AEModelData) extraData;
|
||||
|
||||
if (aeModelData.isCacheable()) {
|
||||
return quadCache.getUnchecked(new AutoRotatingCacheKey(state, aeModelData, side));
|
||||
} else {
|
||||
return this.getRotatedModel(state, side, rand, aeModelData);
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public IModelData getModelData(@Nonnull ILightReader world, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nonnull IModelData tileData) {
|
||||
return this.parent.getModelData(world, pos, state, tileData);
|
||||
}
|
||||
|
||||
public static class VertexRotator extends QuadGatheringTransformer
|
||||
|
||||
@@ -29,15 +29,13 @@ import net.minecraft.util.Direction;
|
||||
final class AutoRotatingCacheKey
|
||||
{
|
||||
private final BlockState blockState;
|
||||
private final Direction forward;
|
||||
private final Direction up;
|
||||
private final AEModelData modelData;
|
||||
private final Direction side;
|
||||
|
||||
AutoRotatingCacheKey( BlockState blockState, Direction forward, Direction up, Direction side )
|
||||
AutoRotatingCacheKey( BlockState blockState, AEModelData modelData, Direction side )
|
||||
{
|
||||
this.blockState = blockState;
|
||||
this.forward = forward;
|
||||
this.up = up;
|
||||
this.modelData = modelData;
|
||||
this.side = side;
|
||||
}
|
||||
|
||||
@@ -46,14 +44,8 @@ final class AutoRotatingCacheKey
|
||||
return this.blockState;
|
||||
}
|
||||
|
||||
public Direction getForward()
|
||||
{
|
||||
return this.forward;
|
||||
}
|
||||
|
||||
public Direction getUp()
|
||||
{
|
||||
return this.up;
|
||||
public AEModelData getModelData() {
|
||||
return modelData;
|
||||
}
|
||||
|
||||
public Direction getSide()
|
||||
@@ -74,15 +66,14 @@ final class AutoRotatingCacheKey
|
||||
}
|
||||
|
||||
AutoRotatingCacheKey cacheKey = (AutoRotatingCacheKey) o;
|
||||
return this.blockState.equals( cacheKey.blockState ) && this.forward == cacheKey.forward && this.up == cacheKey.up && this.side == cacheKey.side;
|
||||
return this.blockState.equals( cacheKey.blockState ) && this.modelData.equals(cacheKey.modelData) && this.side == cacheKey.side;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
int result = this.blockState.hashCode();
|
||||
result = 31 * result + this.forward.hashCode();
|
||||
result = 31 * result + this.up.hashCode();
|
||||
result = 31 * result + this.modelData.hashCode();
|
||||
result = 31 * result + ( this.side != null ? this.side.hashCode() : 0 );
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -57,7 +57,12 @@ public class DriveBakedModel extends DelegateBakedModel
|
||||
|
||||
List<BakedQuad> result = new ArrayList<>(this.bakedBase.getQuads(state, side, rand, extraData));
|
||||
|
||||
DriveSlotsState slotsState = extraData.getData( TileDrive.SLOTS_STATE );
|
||||
if (!(extraData instanceof DriveModelData)) {
|
||||
return result;
|
||||
}
|
||||
DriveModelData driveModelData = (DriveModelData) extraData;
|
||||
|
||||
DriveSlotsState slotsState = driveModelData.getSlotsState();
|
||||
|
||||
if( side == null && slotsState != null )
|
||||
{
|
||||
|
||||
@@ -20,7 +20,9 @@ package appeng.client.render.model;
|
||||
|
||||
|
||||
import appeng.block.storage.DriveSlotState;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import net.minecraft.client.renderer.model.*;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
@@ -43,6 +45,11 @@ public class DriveModel implements IModelGeometry<DriveModel>
|
||||
DriveSlotState.TYPES_FULL, new ResourceLocation( "appliedenergistics2:block/drive_cell_types_full" ),
|
||||
DriveSlotState.FULL, new ResourceLocation( "appliedenergistics2:block/drive_cell_full" ) );
|
||||
|
||||
public static final Set<ResourceLocation> DEPENDENCIES = ImmutableSet.<ResourceLocation>builder()
|
||||
.addAll(MODELS_CELLS.values())
|
||||
.add(MODEL_BASE)
|
||||
.build();
|
||||
|
||||
@Override
|
||||
public IBakedModel bake(IModelConfiguration owner, ModelBakery bakery, Function<Material, TextureAtlasSprite> spriteGetter, IModelTransform modelTransform, ItemOverrideList overrides, ResourceLocation modelLocation) {
|
||||
EnumMap<DriveSlotState, IBakedModel> cellModels = new EnumMap<>( DriveSlotState.class );
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
package appeng.client.render.model;
|
||||
|
||||
import appeng.block.storage.DriveSlotsState;
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraftforge.client.model.data.IModelData;
|
||||
import net.minecraftforge.client.model.data.ModelProperty;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.Objects;
|
||||
|
||||
public class DriveModelData extends AEModelData {
|
||||
|
||||
private final DriveSlotsState slotsState;
|
||||
|
||||
public DriveModelData(Direction up, Direction forward, DriveSlotsState slotsState) {
|
||||
super(up, forward);
|
||||
this.slotsState = slotsState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCacheable() {
|
||||
return false; // Too many combinations
|
||||
}
|
||||
|
||||
public DriveSlotsState getSlotsState() {
|
||||
return slotsState;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
if (!super.equals(o)) return false;
|
||||
DriveModelData that = (DriveModelData) o;
|
||||
return slotsState.equals(that.slotsState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(super.hashCode(), slotsState);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user