Even more compile

This commit is contained in:
covers1624
2020-06-02 19:09:53 +09:30
parent 3f5c299d09
commit fb4995da62
11 changed files with 265 additions and 304 deletions
@@ -91,6 +91,11 @@ public enum FacingToRotation
this.mat.mul( zRot = Vector3f.ZP.rotationDegrees( rot.getZ() ) );
}
public boolean isRedundant()
{
return rot.getX() == 0 && rot.getY() == 0 && rot.getZ() == 0;
}
public Vector3f getRot()
{
return this.rot;
@@ -27,8 +27,9 @@ import java.util.List;
import java.util.function.Function;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.model.Material;
import net.minecraft.client.renderer.texture.AtlasTexture;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
@@ -43,8 +44,6 @@ import appeng.core.AppEng;
class CableBuilder
{
private final VertexFormat format;
// Textures for the cable core types, one per type/color pair
private final EnumMap<CableCoreType, EnumMap<AEColor, TextureAtlasSprite>> coreTextures;
@@ -53,9 +52,8 @@ class CableBuilder
private final SmartCableTextures smartCableTextures;
CableBuilder( VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
CableBuilder( Function<Material, TextureAtlasSprite> bakedTextureGetter )
{
this.format = format;
this.coreTextures = new EnumMap<>( CableCoreType.class );
for( CableCoreType type : CableCoreType.values() )
@@ -87,7 +85,7 @@ class CableBuilder
this.smartCableTextures = new SmartCableTextures( bakedTextureGetter );
}
static ResourceLocation getConnectionTexture( AECableType cableType, AEColor color )
static Material getConnectionTexture( AECableType cableType, AEColor color )
{
String textureFolder;
switch( cableType )
@@ -111,7 +109,7 @@ class CableBuilder
throw new IllegalStateException( "Cable type " + cableType + " does not support connections." );
}
return new ResourceLocation( AppEng.MOD_ID, textureFolder + color.name().toLowerCase() );
return new Material( AtlasTexture.LOCATION_BLOCKS_TEXTURE, new ResourceLocation( AppEng.MOD_ID, textureFolder + color.name().toLowerCase() ) );
}
/**
@@ -140,7 +138,7 @@ class CableBuilder
public void addCableCore( CableCoreType coreType, AEColor color, List<BakedQuad> quadsOut )
{
CubeBuilder cubeBuilder = new CubeBuilder( this.format, quadsOut );
CubeBuilder cubeBuilder = new CubeBuilder( quadsOut );
TextureAtlasSprite texture = this.coreTextures.get( coreType ).get( color );
cubeBuilder.setTexture( texture );
@@ -161,7 +159,7 @@ class CableBuilder
public void addGlassConnection( Direction facing, AEColor cableColor, AECableType connectionType, boolean cableBusAdjacent, List<BakedQuad> quadsOut )
{
CubeBuilder cubeBuilder = new CubeBuilder( this.format, quadsOut );
CubeBuilder cubeBuilder = new CubeBuilder( quadsOut );
// We render all faces except the one on the connection side
cubeBuilder.setDrawFaces( EnumSet.complementOf( EnumSet.of( facing ) ) );
@@ -203,7 +201,7 @@ class CableBuilder
public void addStraightGlassConnection( Direction facing, AEColor cableColor, List<BakedQuad> quadsOut )
{
CubeBuilder cubeBuilder = new CubeBuilder( this.format, quadsOut );
CubeBuilder cubeBuilder = new CubeBuilder( quadsOut );
// We render all faces except the connection caps. We can do this because the glass cable is the smallest one
// and its ends will always be covered by something
@@ -238,7 +236,7 @@ class CableBuilder
return;
}
CubeBuilder cubeBuilder = new CubeBuilder( this.format, quadsOut );
CubeBuilder cubeBuilder = new CubeBuilder( quadsOut );
TextureAtlasSprite texture = this.connectionTextures.get( AECableType.GLASS ).get( cableColor );
cubeBuilder.setTexture( texture );
@@ -269,7 +267,7 @@ class CableBuilder
public void addCoveredConnection( Direction facing, AEColor cableColor, AECableType connectionType, boolean cableBusAdjacent, List<BakedQuad> quadsOut )
{
CubeBuilder cubeBuilder = new CubeBuilder( this.format, quadsOut );
CubeBuilder cubeBuilder = new CubeBuilder( quadsOut );
// We render all faces except the one on the connection side
cubeBuilder.setDrawFaces( EnumSet.complementOf( EnumSet.of( facing ) ) );
@@ -288,7 +286,7 @@ class CableBuilder
public void addStraightCoveredConnection( Direction facing, AEColor cableColor, List<BakedQuad> quadsOut )
{
CubeBuilder cubeBuilder = new CubeBuilder( this.format, quadsOut );
CubeBuilder cubeBuilder = new CubeBuilder( quadsOut );
TextureAtlasSprite texture = this.connectionTextures.get( AECableType.COVERED ).get( cableColor );
cubeBuilder.setTexture( texture );
@@ -296,7 +294,6 @@ class CableBuilder
setStraightCableUVs( cubeBuilder, facing, 5, 11 );
addStraightCoveredCableSizedCube( facing, cubeBuilder );
}
private static void setStraightCableUVs( CubeBuilder cubeBuilder, Direction facing, int x, int y )
@@ -336,13 +333,12 @@ class CableBuilder
return;
}
CubeBuilder cubeBuilder = new CubeBuilder( this.format, quadsOut );
CubeBuilder cubeBuilder = new CubeBuilder( quadsOut );
TextureAtlasSprite texture = this.connectionTextures.get( AECableType.COVERED ).get( cableColor );
cubeBuilder.setTexture( texture );
addCoveredCableSizedCube( facing, distanceFromEdge, cubeBuilder );
}
public void addSmartConnection( Direction facing, AEColor cableColor, AECableType connectionType, boolean cableBusAdjacent, int channels, List<BakedQuad> quadsOut )
@@ -353,7 +349,7 @@ class CableBuilder
return;
}
CubeBuilder cubeBuilder = new CubeBuilder( this.format, quadsOut );
CubeBuilder cubeBuilder = new CubeBuilder( quadsOut );
// We render all faces except the one on the connection side
cubeBuilder.setDrawFaces( EnumSet.complementOf( EnumSet.of( facing ) ) );
@@ -401,7 +397,7 @@ class CableBuilder
public void addStraightSmartConnection( Direction facing, AEColor cableColor, int channels, List<BakedQuad> quadsOut )
{
CubeBuilder cubeBuilder = new CubeBuilder( this.format, quadsOut );
CubeBuilder cubeBuilder = new CubeBuilder( quadsOut );
TextureAtlasSprite texture = this.connectionTextures.get( AECableType.SMART ).get( cableColor );
cubeBuilder.setTexture( texture );
@@ -434,7 +430,7 @@ class CableBuilder
return;
}
CubeBuilder cubeBuilder = new CubeBuilder( this.format, quadsOut );
CubeBuilder cubeBuilder = new CubeBuilder( quadsOut );
TextureAtlasSprite texture = this.connectionTextures.get( AECableType.SMART ).get( cableColor );
cubeBuilder.setTexture( texture );
@@ -465,7 +461,7 @@ class CableBuilder
return;
}
CubeBuilder cubeBuilder = new CubeBuilder( this.format, quadsOut );
CubeBuilder cubeBuilder = new CubeBuilder( quadsOut );
// We render all faces except the one on the connection side
cubeBuilder.setDrawFaces( EnumSet.complementOf( EnumSet.of( facing ) ) );
@@ -499,7 +495,7 @@ class CableBuilder
return;
}
CubeBuilder cubeBuilder = new CubeBuilder( this.format, quadsOut );
CubeBuilder cubeBuilder = new CubeBuilder( quadsOut );
// We render all faces except the one on the connection side
cubeBuilder.setDrawFaces( EnumSet.complementOf( EnumSet.of( facing ) ) );
@@ -529,12 +525,11 @@ class CableBuilder
// Reset back to normal rendering for the rest
cubeBuilder.setRenderFullBright( false );
cubeBuilder.setTexture( texture );
}
public void addStraightDenseCoveredConnection( Direction facing, AEColor cableColor, List<BakedQuad> quadsOut )
{
CubeBuilder cubeBuilder = new CubeBuilder( this.format, quadsOut );
CubeBuilder cubeBuilder = new CubeBuilder( quadsOut );
TextureAtlasSprite texture = this.connectionTextures.get( AECableType.DENSE_COVERED ).get( cableColor );
cubeBuilder.setTexture( texture );
@@ -546,7 +541,7 @@ class CableBuilder
public void addStraightDenseSmartConnection( Direction facing, AEColor cableColor, int channels, List<BakedQuad> quadsOut )
{
CubeBuilder cubeBuilder = new CubeBuilder( this.format, quadsOut );
CubeBuilder cubeBuilder = new CubeBuilder( quadsOut );
TextureAtlasSprite texture = this.connectionTextures.get( AECableType.DENSE_SMART ).get( cableColor );
cubeBuilder.setTexture( texture );
@@ -627,7 +622,6 @@ class CableBuilder
cubeBuilder.setUvRotation( Direction.WEST, 0 );
break;
}
}
// Adds a cube to the given cube builder that has the size of a covered cable connection from the core of the cable
@@ -745,9 +739,9 @@ class CableBuilder
}
// Get all textures needed for building the actual cable quads
public static List<ResourceLocation> getTextures()
public static List<Material> getTextures()
{
List<ResourceLocation> locations = new ArrayList<>();
List<Material> locations = new ArrayList<>();
for( CableCoreType coreType : CableCoreType.values() )
{
@@ -774,5 +768,4 @@ class CableBuilder
{
return this.coreTextures.get( coreType ).get( color );
}
}
@@ -27,28 +27,29 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import javax.annotation.Nullable;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.model.ItemCameraTransforms;
import net.minecraft.client.renderer.model.ItemOverrideList;
import net.minecraft.client.renderer.texture.AtlasTexture;
import net.minecraft.client.renderer.texture.MissingTextureSprite;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.MinecraftForgeClient;
import net.minecraftforge.common.property.IExtendedBlockState;
import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.client.model.data.IModelData;
import appeng.api.parts.IPartBakedModel;
import appeng.api.parts.IPartModel;
import appeng.api.util.AECableType;
import appeng.api.util.AEColor;
import appeng.block.networking.BlockCableBus;
public class CableBusBakedModel implements IBakedModel
@@ -64,7 +65,8 @@ public class CableBusBakedModel implements IBakedModel
private final TextureAtlasSprite particleTexture;
private final TextureMap textureMap = Minecraft.getInstance().getTextureMapBlocks();
private final AtlasTexture textureMap = Minecraft.getInstance().getModelManager().getAtlasTexture( AtlasTexture.LOCATION_BLOCKS_TEXTURE );
private final TextureAtlasSprite missingTexture = textureMap.getSprite( MissingTextureSprite.getLocation() );
CableBusBakedModel( CableBuilder cableBuilder, FacadeBuilder facadeBuilder, Map<ResourceLocation, IBakedModel> partModels, TextureAtlasSprite particleTexture )
{
@@ -75,28 +77,33 @@ public class CableBusBakedModel implements IBakedModel
}
@Override
public List<BakedQuad> getQuads( @Nullable BlockState state, @Nullable Direction side, long rand )
public List<BakedQuad> getQuads( @Nullable BlockState state, @Nullable Direction side, Random rand )
{
CableBusRenderState renderState = getRenderingState( state );
return getQuads( state, side, rand, EmptyModelData.INSTANCE );
}
@Override
public List<BakedQuad> getQuads( @Nullable BlockState state, @Nullable Direction side, Random rand, IModelData data )
{
CableBusRenderState renderState = data.getData( CableBusRenderState.PROPERTY );
if( renderState == null || side != null )
{
return Collections.emptyList();
}
BlockRenderLayer layer = MinecraftForgeClient.getRenderLayer();
RenderType layer = MinecraftForgeClient.getRenderLayer();
List<BakedQuad> quads = new ArrayList<>();
// The core parts of the cable will only be rendered in the CUTOUT layer.
// Facades will add them selves to what ever the block would be rendered with,
// except when transparent facades are enabled, they are forced to TRANSPARENT.
if( layer == BlockRenderLayer.CUTOUT )
if( layer == RenderType.getCutout() )
{
// First, handle the cable at the center of the cable bus
final List<BakedQuad> cableModel = CABLE_MODEL_CACHE.computeIfAbsent( renderState, k ->
{
final List<BakedQuad> cableModel = CABLE_MODEL_CACHE.computeIfAbsent( renderState, k -> {
final List<BakedQuad> model = new ArrayList<>();
this.addCableQuads( renderState, model );
return model;
@@ -310,7 +317,7 @@ public class CableBusBakedModel implements IBakedModel
// If a part sub-model has no particle texture (indicated by it being the missing texture),
// don't add it, so we don't get ugly missing texture break particles.
if( this.textureMap.getMissingSprite() != particleTexture )
if( this.missingTexture != particleTexture )
{
result.add( particleTexture );
}
@@ -320,17 +327,6 @@ public class CableBusBakedModel implements IBakedModel
return result;
}
private static CableBusRenderState getRenderingState( BlockState state )
{
if( state == null || !( state instanceof IExtendedBlockState ) )
{
return null;
}
IExtendedBlockState extendedBlockState = (IExtendedBlockState) state;
return extendedBlockState.getValue( BlockCableBus.RENDER_STATE_PROPERTY );
}
@Override
public boolean isAmbientOcclusion()
{
@@ -343,6 +339,12 @@ public class CableBusBakedModel implements IBakedModel
return false;
}
@Override
public boolean func_230044_c_()
{
return false;//TODO
}
@Override
public boolean isBuiltInRenderer()
{
@@ -20,30 +20,31 @@ package appeng.client.render.cablebus;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import javax.annotation.Nullable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.mojang.datafixers.util.Pair;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.model.IModelTransform;
import net.minecraft.client.renderer.model.IUnbakedModel;
import net.minecraft.client.renderer.model.Material;
import net.minecraft.client.renderer.model.ModelBakery;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.ModelLoaderRegistry;
import net.minecraftforge.common.model.IModelState;
import net.minecraftforge.common.model.TRSRTransformation;
import appeng.api.util.AEColor;
import appeng.core.AELog;
import appeng.core.features.registries.PartModels;
/**
* The built-in model for the cable bus block.
*/
public class CableBusModel implements IModel
public class CableBusModel implements IUnbakedModel
{
private final PartModels partModels;
@@ -61,19 +62,18 @@ public class CableBusModel implements IModel
}
@Override
public Collection<ResourceLocation> getTextures()
public Collection<Material> getTextures( Function<ResourceLocation, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors )
{
return ImmutableList.<ResourceLocation>builder()
.addAll( CableBuilder.getTextures() )
.build();
return Collections.unmodifiableList( CableBuilder.getTextures() );
}
@Nullable
@Override
public IBakedModel bake( IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
public IBakedModel bakeModel( ModelBakery modelBakeryIn, Function<Material, TextureAtlasSprite> spriteGetterIn, IModelTransform transformIn, ResourceLocation locationIn )
{
Map<ResourceLocation, IBakedModel> partModels = this.loadPartModels( state, format, bakedTextureGetter );
Map<ResourceLocation, IBakedModel> partModels = this.loadPartModels( modelBakeryIn, spriteGetterIn, transformIn );
CableBuilder cableBuilder = new CableBuilder( format, bakedTextureGetter );
CableBuilder cableBuilder = new CableBuilder( spriteGetterIn );
FacadeBuilder facadeBuilder = new FacadeBuilder();
// This should normally not be used, but we *have* to provide a particle texture or otherwise damage models will
@@ -83,36 +83,15 @@ public class CableBusModel implements IModel
return new CableBusBakedModel( cableBuilder, facadeBuilder, partModels, particleTexture );
}
private Map<ResourceLocation, IBakedModel> loadPartModels( IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
private Map<ResourceLocation, IBakedModel> loadPartModels( ModelBakery modelBakeryIn, Function<Material, TextureAtlasSprite> spriteGetterIn, IModelTransform transformIn )
{
ImmutableMap.Builder<ResourceLocation, IBakedModel> result = ImmutableMap.builder();
for( ResourceLocation location : this.partModels.getModels() )
{
IModel model = this.tryLoadPartModel( location );
IBakedModel bakedModel = model.bake( state, format, bakedTextureGetter );
result.put( location, bakedModel );
result.put( location, modelBakeryIn.getBakedModel( location, transformIn, spriteGetterIn ) );
}
return result.build();
}
private IModel tryLoadPartModel( ResourceLocation location )
{
try
{
return ModelLoaderRegistry.getModel( location );
}
catch( Exception e )
{
AELog.error( e, "Unable to load part model " + location );
return ModelLoaderRegistry.getMissingModel();
}
}
@Override
public IModelState getDefaultState()
{
return TRSRTransformation.identity();
}
}
@@ -30,6 +30,8 @@ import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.ILightReader;
import net.minecraftforge.client.model.data.ModelProperty;
import appeng.api.parts.IPartModel;
import appeng.api.util.AECableType;
@@ -43,6 +45,8 @@ import appeng.api.util.AEColor;
public class CableBusRenderState
{
public static final ModelProperty<CableBusRenderState> PROPERTY = new ModelProperty<>();
// The cable type used for rendering the outgoing connections to other blocks and attached parts
private AECableType cableType = AECableType.NONE;
@@ -73,7 +77,7 @@ public class CableBusRenderState
private EnumMap<Direction, FacadeRenderState> facades = new EnumMap<>( Direction.class );
// Used for Facades.
private WeakReference<IBlockReader> world;
private WeakReference<ILightReader> world;
private BlockPos pos;
// Contains the bounding boxes of all parts on the cable bus to allow facades to cut out holes for the parts. This
@@ -158,12 +162,12 @@ public class CableBusRenderState
return this.facades;
}
public IBlockReader getWorld()
public ILightReader getWorld()
{
return this.world.get();
}
public void setWorld( IBlockReader world )
public void setWorld( ILightReader world )
{
this.world = new WeakReference<>( world );
}
@@ -24,6 +24,8 @@ import java.util.Map;
import com.google.common.collect.ImmutableMap;
import net.minecraft.client.renderer.model.Material;
import net.minecraft.client.renderer.texture.AtlasTexture;
import net.minecraft.util.ResourceLocation;
import appeng.api.util.AECableType;
@@ -78,9 +80,9 @@ public enum CableCoreType
return cableMapping.get( cableType );
}
public ResourceLocation getTexture( AEColor color )
public Material getTexture( AEColor color )
{
return new ResourceLocation( AppEng.MOD_ID, this.textureFolder + "/" + color.name().toLowerCase() );
return new Material( AtlasTexture.LOCATION_BLOCKS_TEXTURE, new ResourceLocation( AppEng.MOD_ID, this.textureFolder + "/" + color.name().toLowerCase() ) );
}
}
}
@@ -22,12 +22,13 @@ package appeng.client.render.cablebus;
import javax.annotation.Nullable;
import net.minecraft.block.BlockState;
import net.minecraft.fluid.IFluidState;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.WorldType;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.ILightReader;
import net.minecraft.world.level.ColorResolver;
import net.minecraft.world.lighting.WorldLightManager;
/**
@@ -36,15 +37,15 @@ import net.minecraft.world.biome.Biome;
*
* @author covers1624
*/
public class FacadeBlockAccess implements IBlockReader
public class FacadeBlockAccess implements ILightReader
{
private final IBlockReader world;
private final ILightReader world;
private final BlockPos pos;
private final Direction side;
private final BlockState state;
public FacadeBlockAccess( IBlockReader world, BlockPos pos, Direction side, BlockState state )
public FacadeBlockAccess( ILightReader world, BlockPos pos, Direction side, BlockState state )
{
this.world = world;
this.pos = pos;
@@ -59,12 +60,6 @@ public class FacadeBlockAccess implements IBlockReader
return this.world.getTileEntity( pos );
}
@Override
public int getCombinedLight( BlockPos pos, int lightValue )
{
return this.world.getCombinedLight( pos, lightValue );
}
@Override
public BlockState getBlockState( BlockPos pos )
{
@@ -76,40 +71,20 @@ public class FacadeBlockAccess implements IBlockReader
}
@Override
public boolean isAirBlock( BlockPos pos )
public IFluidState getFluidState( BlockPos pos )
{
BlockState state = this.getBlockState( pos );
return state.getBlock().isAir( state, this.world, pos );
return world.getFluidState( pos );
}
@Override
public Biome getBiome( BlockPos pos )
public WorldLightManager getLightManager()
{
return this.world.getBiome( pos );
return world.getLightManager();
}
@Override
public int getStrongPower( BlockPos pos, Direction direction )
public int getBlockColor( BlockPos blockPosIn, ColorResolver colorResolverIn )
{
return this.world.getStrongPower( pos, direction );
}
@Override
public WorldType getWorldType()
{
return this.world.getWorldType();
}
@Override
public boolean isSideSolid( BlockPos pos, Direction side, boolean _default )
{
if( pos.getX() < -30000000 || pos.getZ() < -30000000 || pos.getX() >= 30000000 || pos.getZ() >= 30000000 )
{
return _default;
}
else
{
return this.getBlockState( pos ).isSideSolid( this, pos, side );
}
return world.getBlockColor( blockPosIn, colorResolverIn );
}
}
@@ -24,6 +24,7 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;
import java.util.function.Function;
@@ -32,21 +33,27 @@ import javax.annotation.Nullable;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockRendererDispatcher;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.RenderTypeLookup;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.color.BlockColors;
import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.item.ItemStack;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.ILightReader;
import net.minecraftforge.client.ForgeHooksClient;
import net.minecraftforge.client.model.data.EmptyModelData;
import net.minecraftforge.client.model.data.IModelData;
import appeng.api.AEApi;
import appeng.api.util.AEAxisAlignedBB;
import appeng.core.Api;
import appeng.parts.misc.PartCableAnchor;
import appeng.thirdparty.codechicken.lib.model.CachedFormat;
import appeng.thirdparty.codechicken.lib.model.Quad;
@@ -88,7 +95,7 @@ public class FacadeBuilder
new AxisAlignedBB( 1.0 - THIN_THICKNESS, 0.0, 0.0, 1.0, 1.0, 1.0 )
};
private ThreadLocal<BakedPipeline> pipelines = ThreadLocal.withInitial( () -> BakedPipeline.builder()
private final ThreadLocal<BakedPipeline> pipelines = ThreadLocal.withInitial( () -> BakedPipeline.builder()
// Clamper is responsible for clamping the vertex to the bounds specified.
.addElement( "clamper", QuadClamper.FACTORY )
// Strips faces if they match a mask.
@@ -103,9 +110,9 @@ public class FacadeBuilder
.addElement( "transparent", QuadAlphaOverride.FACTORY, false, e -> e.setAlphaOverride( 0x4C / 255F ) )
.build()//
);
private ThreadLocal<Quad> collectors = ThreadLocal.withInitial( Quad::new );
private final ThreadLocal<Quad> collectors = ThreadLocal.withInitial( Quad::new );
public void buildFacadeQuads( BlockRenderLayer layer, CableBusRenderState renderState, long rand, List<BakedQuad> quads, Function<ResourceLocation, IBakedModel> modelLookup )
public void buildFacadeQuads( RenderType layer, CableBusRenderState renderState, Random rand, List<BakedQuad> quads, Function<ResourceLocation, IBakedModel> modelLookup )
{
BakedPipeline pipeline = this.pipelines.get();
Quad collectorQuad = this.collectors.get();
@@ -113,7 +120,7 @@ public class FacadeBuilder
Map<Direction, FacadeRenderState> facadeStates = renderState.getFacades();
List<AxisAlignedBB> partBoxes = renderState.getBoundingBoxes();
Set<Direction> sidesWithParts = renderState.getAttachments().keySet();
IBlockReader parentWorld = renderState.getWorld();
ILightReader parentWorld = renderState.getWorld();
BlockPos pos = renderState.getPos();
BlockColors blockColors = Minecraft.getInstance().getBlockColors();
boolean thinFacades = isUseThinFacades( partBoxes );
@@ -124,17 +131,17 @@ public class FacadeBuilder
int sideIndex = side.ordinal();
FacadeRenderState facadeRenderState = entry.getValue();
boolean renderStilt = !sidesWithParts.contains( side );
if( layer == BlockRenderLayer.CUTOUT && renderStilt )
if( layer == RenderType.getCutout() && renderStilt )
{
for( ResourceLocation part : PartCableAnchor.FACADE_MODELS.getModels() )
{
IBakedModel partModel = modelLookup.apply( part );
QuadRotator rotator = new QuadRotator();
quads.addAll( rotator.rotateQuads( gatherQuads( partModel, null, rand ), side, Direction.UP ) );
quads.addAll( rotator.rotateQuads( gatherQuads( partModel, null, rand, EmptyModelData.INSTANCE ), side, Direction.UP ) );
}
}
// If we are forcing transparency and this isn't the Translucent layer.
if( transparent && layer != BlockRenderLayer.TRANSLUCENT )
if( transparent && layer != RenderType.getTranslucent() )
{
continue;
}
@@ -143,7 +150,7 @@ public class FacadeBuilder
// If we aren't forcing transparency let the block decide if it should render.
if( !transparent && layer != null )
{
if( !blockState.getBlock().canRenderInLayer( blockState, layer ) )
if( !RenderTypeLookup.canRenderInLayer( blockState, layer ) )
{
continue;
}
@@ -202,38 +209,24 @@ public class FacadeBuilder
AEAxisAlignedBB cutOutBox = getCutOutBox( facadeBox, partBoxes );
List<AxisAlignedBB> holeStrips = getBoxes( facadeBox, cutOutBox, side.getAxis() );
IBlockReader facadeAccess = new FacadeBlockAccess( parentWorld, pos, side, blockState );
ILightReader facadeAccess = new FacadeBlockAccess( parentWorld, pos, side, blockState );
BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher();
try
{
blockState = blockState.getActualState( facadeAccess, pos );
}
catch( Exception ignored )
{
}
IBakedModel model = dispatcher.getModelForState( blockState );
try
{
blockState = blockState.getBlock().getExtendedState( blockState, facadeAccess, pos );
}
catch( Exception ignored )
{
}
IModelData modelData = model.getModelData( facadeAccess, pos, blockState, EmptyModelData.INSTANCE );
List<BakedQuad> modelQuads = new ArrayList<>();
// If we are forcing transparent facades, fake the render layer, and grab all quads.
if( transparent || layer == null )
{
for( BlockRenderLayer forcedLayer : BlockRenderLayer.values() )
for( RenderType forcedLayer : RenderType.getBlockRenderTypes() )
{
// Check if the block renders on the layer we want to force.
if( blockState.getBlock().canRenderInLayer( blockState, forcedLayer ) )
if( RenderTypeLookup.canRenderInLayer( blockState, forcedLayer ) )
{
// Force the layer and gather quads.
ForgeHooksClient.setRenderLayer( forcedLayer );
modelQuads.addAll( gatherQuads( model, blockState, rand ) );
modelQuads.addAll( gatherQuads( model, blockState, rand, modelData) );
}
}
@@ -242,7 +235,7 @@ public class FacadeBuilder
}
else
{
modelQuads.addAll( gatherQuads( model, blockState, rand ) );
modelQuads.addAll( gatherQuads( model, blockState, rand, modelData ) );
}
// No quads.. Cool, next!
@@ -286,11 +279,11 @@ public class FacadeBuilder
for( BakedQuad quad : modelQuads )
{
// lookup the format in CachedFormat.
CachedFormat format = CachedFormat.lookup( quad.getFormat() );
CachedFormat format = CachedFormat.lookup( DefaultVertexFormats.BLOCK );
// If this quad has a tint index, setup the tinter.
if( quad.hasTintIndex() )
{
tinter.setTint( blockColors.colorMultiplier( blockState, facadeAccess, pos, quad.getTintIndex() ) );
tinter.setTint( blockColors.getColor( blockState, facadeAccess, pos, quad.getTintIndex() ) );
}
for( AxisAlignedBB box : holeStrips )
{
@@ -327,8 +320,8 @@ public class FacadeBuilder
public List<BakedQuad> buildFacadeItemQuads( ItemStack textureItem, Direction side )
{
List<BakedQuad> facadeQuads = new ArrayList<>();
IBakedModel model = Minecraft.getInstance().getRenderItem().getItemModelWithOverrides( textureItem, null, null );
List<BakedQuad> modelQuads = gatherQuads( model, null, 0 );
IBakedModel model = Minecraft.getInstance().getItemRenderer().getItemModelWithOverrides( textureItem, null, null );
List<BakedQuad> modelQuads = gatherQuads( model, null, new Random(), EmptyModelData.INSTANCE );
BakedPipeline pipeline = this.pipelines.get();
Quad collectorQuad = this.collectors.get();
@@ -340,7 +333,7 @@ public class FacadeBuilder
for( BakedQuad quad : modelQuads )
{
// Lookup the CachedFormat for this quads format.
CachedFormat format = CachedFormat.lookup( quad.getFormat() );
CachedFormat format = CachedFormat.lookup( DefaultVertexFormats.BLOCK );
// Reset the pipeline.
pipeline.reset( format );
// Reset the collector.
@@ -348,7 +341,7 @@ public class FacadeBuilder
// If we have a tint index, setup the tinter and enable it.
if( quad.hasTintIndex() )
{
tinter.setTint( Minecraft.getInstance().getItemColors().colorMultiplier( textureItem, quad.getTintIndex() ) );
tinter.setTint( Minecraft.getInstance().getItemColors().getColor( textureItem, quad.getTintIndex() ) );
pipeline.enableElement( "tinter" );
}
// Disable elements we don't need for items.
@@ -363,21 +356,21 @@ public class FacadeBuilder
// Check the collector for data and add the quad if there was.
if( collectorQuad.full )
{
facadeQuads.add( collectorQuad.bakeUnpacked() );
facadeQuads.add( collectorQuad.bake() );
}
}
return facadeQuads;
}
// Helper to gather all quads from a model into a list.
private static List<BakedQuad> gatherQuads( IBakedModel model, BlockState state, long rand )
private static List<BakedQuad> gatherQuads( IBakedModel model, BlockState state, Random rand, IModelData data )
{
List<BakedQuad> modelQuads = new ArrayList<>();
for( Direction face : Direction.values() )
{
modelQuads.addAll( model.getQuads( state, face, rand ) );
modelQuads.addAll( model.getQuads( state, face, rand, data) );
}
modelQuads.addAll( model.getQuads( state, null, rand ) );
modelQuads.addAll( model.getQuads( state, null, rand, data ) );
return modelQuads;
}
@@ -22,17 +22,15 @@ package appeng.client.render.cablebus;
import java.util.ArrayList;
import java.util.List;
import javax.vecmath.Matrix4f;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.Direction;
import appeng.client.render.FacingToRotation;
import appeng.core.AELog;
import appeng.thirdparty.codechicken.lib.model.CachedFormat;
import appeng.thirdparty.codechicken.lib.model.Quad;
import appeng.thirdparty.codechicken.lib.model.pipeline.BakedPipeline;
import appeng.thirdparty.codechicken.lib.model.pipeline.transformers.QuadMatrixTransformer;
/**
@@ -41,6 +39,11 @@ import appeng.core.AELog;
*/
public class QuadRotator
{
private static final ThreadLocal<BakedPipeline> pipelines = ThreadLocal.withInitial( () -> //
BakedPipeline.builder()//
.addElement( "transformer", QuadMatrixTransformer.FACTORY )//
.build() );
private static final ThreadLocal<Quad> collectors = ThreadLocal.withInitial( Quad::new );
public List<BakedQuad> rotateQuads( List<BakedQuad> quads, Direction newForward, Direction newUp )
{
@@ -51,15 +54,33 @@ public class QuadRotator
List<BakedQuad> result = new ArrayList<>( quads.size() );
CachedFormat format = CachedFormat.lookup( DefaultVertexFormats.BLOCK );
BakedPipeline pipeline = pipelines.get();
Quad collector = collectors.get();
pipeline.reset( format );
collector.reset( format );
QuadMatrixTransformer transformer = pipeline.getElement( "transformer", QuadMatrixTransformer.class );
for( BakedQuad quad : quads )
{
result.add( this.rotateQuad( quad, newForward, newUp ) );
FacingToRotation rotation = getRotation( newForward, newUp );
if( rotation.isRedundant() )
{
result.add( quad );//Redundant rotation, just don't do anything.
}
else
{
transformer.setMatrix( rotation.getMat() );
pipeline.prepare( collector );
quad.pipe( pipeline );
result.add( collector.bake() );
}
}
return result;
}
private BakedQuad rotateQuad( BakedQuad quad, Direction forward, Direction up )
private FacingToRotation getRotation( Direction forward, Direction up )
{
// Sanitize forward/up
if( forward.getAxis() == up.getAxis() )
@@ -74,116 +95,6 @@ public class QuadRotator
}
}
FacingToRotation rotation = FacingToRotation.get( forward, up );
Matrix4f mat = rotation.getMat();
// Clone the vertex data used by the quad
int[] newData = quad.getVertexData().clone();
// Figure out where the position is in the array
VertexFormat format = quad.getFormat();
int posIdx = this.findPositionOffset( format ) / 4;
int stride = format.getNextOffset() / 4;
int normalIdx = format.getNormalOffset();
VertexFormatElement.EnumType normalType = null;
// Figure out the type of the normals
if( normalIdx != -1 )
{
for( int i = 0; i < format.getElements().size(); i++ )
{
VertexFormatElement element = format.getElement( i );
if( element.getUsage() == VertexFormatElement.EnumUsage.NORMAL )
{
normalType = element.getType();
}
}
}
for( int i = 0; i < 4; i++ )
{
Point3f pos = new Point3f( Float.intBitsToFloat( newData[i * stride + posIdx] ) - 0.5f, Float
.intBitsToFloat( newData[i * stride + posIdx + 1] ) - 0.5f, Float.intBitsToFloat( newData[i * stride + posIdx + 2] ) - 0.5f );
// Rotate stuff around
mat.transform( pos );
// Write back
newData[i * stride + posIdx] = Float.floatToIntBits( pos.getX() + 0.5f );
newData[i * stride + posIdx + 1] = Float.floatToIntBits( pos.getY() + 0.5f );
newData[i * stride + posIdx + 2] = Float.floatToIntBits( pos.getZ() + 0.5f );
// Transform the normal if one is present
if( normalIdx != -1 )
{
if( normalType == VertexFormatElement.EnumType.FLOAT )
{
Vector3f normal = new Vector3f( Float.intBitsToFloat( newData[i * stride + normalIdx] ), Float
.intBitsToFloat( newData[i * stride + normalIdx + 1] ), Float.intBitsToFloat( newData[i * stride + normalIdx + 2] ) );
// Rotate stuff around
mat.transform( normal );
// Write back
newData[i * stride + normalIdx] = Float.floatToIntBits( normal.getX() );
newData[i * stride + normalIdx + 1] = Float.floatToIntBits( normal.getY() );
newData[i * stride + normalIdx + 2] = Float.floatToIntBits( normal.getZ() );
}
else if( normalType == VertexFormatElement.EnumType.BYTE )
{
int idx = i * stride * 4 + normalIdx;
Vector3f normal = new Vector3f( getByte( newData, idx ) / 127.0f, getByte( newData, idx + 1 ) / 127.0f, getByte( newData,
idx + 2 ) / 127.0f );
// Rotate stuff around
mat.transform( normal );
// Write back
setByte( newData, idx, (int) ( normal.getX() * 127 ) );
setByte( newData, idx + 1, (int) ( normal.getY() * 127 ) );
setByte( newData, idx + 2, (int) ( normal.getZ() * 127 ) );
}
else
{
AELog.warn( "Unsupported normal format: {}", normalType );
}
}
}
Direction newFace = rotation.rotate( quad.getFace() );
return new BakedQuad( newData, quad.getTintIndex(), newFace, quad.getSprite(), quad.shouldApplyDiffuseLighting(), quad.getFormat() );
}
private static int getByte( int[] data, int offset )
{
int idx = offset / 4;
int subOffset = offset % 4;
return (byte) ( data[idx] >> ( subOffset * 8 ) );
}
private static void setByte( int[] data, int offset, int value )
{
int idx = offset / 4;
int subOffset = offset % 4;
int mask = 0xFF << ( subOffset * 8 );
data[idx] = data[idx] & ( ~mask ) | ( ( value & 0xFF ) << ( subOffset * 8 ) );
}
private int findPositionOffset( VertexFormat format )
{
List<VertexFormatElement> elements = format.getElements();
for( int i = 0; i < elements.size(); i++ )
{
VertexFormatElement e = elements.get( i );
if( e.isPositionElement() )
{
if( e.getType() != VertexFormatElement.EnumType.FLOAT )
{
throw new IllegalArgumentException( "Only floating point positions are supported" );
}
return i;
}
}
throw new IllegalArgumentException( "Vertex format " + format + " has no position attribute!" );
return FacingToRotation.get( forward, up );
}
}
@@ -22,6 +22,8 @@ package appeng.client.render.cablebus;
import java.util.Arrays;
import java.util.function.Function;
import net.minecraft.client.renderer.model.Material;
import net.minecraft.client.renderer.texture.AtlasTexture;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.util.ResourceLocation;
@@ -34,21 +36,28 @@ import appeng.core.AppEng;
public class SmartCableTextures
{
public static final ResourceLocation[] SMART_CHANNELS_TEXTURES = { new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_00" ),
new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_01" ), new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_02" ),
new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_03" ), new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_04" ),
new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_10" ), new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_11" ),
new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_12" ), new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_13" ),
new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_14" )
};
public static final Material[] SMART_CHANNELS_TEXTURES = Arrays.stream( new ResourceLocation[] {
new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_00" ),//
new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_01" ),//
new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_02" ),//
new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_03" ),//
new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_04" ),//
new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_10" ),//
new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_11" ),//
new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_12" ),//
new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_13" ),//
new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_14" )//
} ).map( e -> new Material( AtlasTexture.LOCATION_BLOCKS_TEXTURE, e ) ).toArray( Material[]::new );
// Textures used to display channels on smart cables. There's two sets of 5 textures each, and
// one of each set are composed together to get even/odd colored channels
private final TextureAtlasSprite[] textures;
public SmartCableTextures( Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
public SmartCableTextures( Function<Material, TextureAtlasSprite> bakedTextureGetter )
{
this.textures = Arrays.stream( SMART_CHANNELS_TEXTURES ).map( bakedTextureGetter::apply ).toArray( TextureAtlasSprite[]::new );
this.textures = Arrays.stream( SMART_CHANNELS_TEXTURES )//
.map( bakedTextureGetter )//
.toArray( TextureAtlasSprite[]::new );
}
/**
@@ -0,0 +1,88 @@
/*
* This file is part of CodeChickenLib.
* Copyright (c) 2018, covers1624, All rights reserved.
*
* CodeChickenLib is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* CodeChickenLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with CodeChickenLib. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.thirdparty.codechicken.lib.model.pipeline.transformers;
import net.minecraft.client.renderer.Matrix4f;
import net.minecraft.client.renderer.Vector4f;
import net.minecraftforge.client.model.pipeline.IVertexConsumer;
import appeng.thirdparty.codechicken.lib.model.Quad;
import appeng.thirdparty.codechicken.lib.model.pipeline.IPipelineElementFactory;
import appeng.thirdparty.codechicken.lib.model.pipeline.QuadTransformer;
/**
* Created by covers1624 on 2/6/20.
*/
public class QuadMatrixTransformer extends QuadTransformer
{
public static IPipelineElementFactory<QuadMatrixTransformer> FACTORY = QuadMatrixTransformer::new;
private static final Matrix4f identity;
static
{
identity = new Matrix4f();
identity.setIdentity();
}
private final Vector4f storage = new Vector4f();
private Matrix4f matrix;
QuadMatrixTransformer()
{
super();
}
public QuadMatrixTransformer( IVertexConsumer parent, Matrix4f matrix )
{
super( parent );
this.matrix = matrix;
}
public void setMatrix( Matrix4f matrix )
{
this.matrix = matrix;
}
@Override
public boolean transform()
{
if( matrix.equals( identity ) )
{
return true;
}
for( Quad.Vertex vertex : this.quad.vertices )
{
storage.set( vertex.vec[0], vertex.vec[1], vertex.vec[2], 1 );
storage.transform( matrix );
vertex.vec[0] = storage.getX();
vertex.vec[1] = storage.getY();
vertex.vec[2] = storage.getZ();
storage.set( vertex.normal[0], vertex.normal[1], vertex.normal[2], 1 );
storage.transform( matrix );
storage.normalize();
vertex.normal[0] = storage.getX();
vertex.normal[1] = storage.getY();
vertex.normal[2] = storage.getZ();
}
return true;
}
}