diff --git a/src/main/java/appeng/client/render/FacingToRotation.java b/src/main/java/appeng/client/render/FacingToRotation.java index e6edb0048..777d1898e 100644 --- a/src/main/java/appeng/client/render/FacingToRotation.java +++ b/src/main/java/appeng/client/render/FacingToRotation.java @@ -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; diff --git a/src/main/java/appeng/client/render/cablebus/CableBuilder.java b/src/main/java/appeng/client/render/cablebus/CableBuilder.java index ea3f8e9a2..548f16e3c 100644 --- a/src/main/java/appeng/client/render/cablebus/CableBuilder.java +++ b/src/main/java/appeng/client/render/cablebus/CableBuilder.java @@ -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> coreTextures; @@ -53,9 +52,8 @@ class CableBuilder private final SmartCableTextures smartCableTextures; - CableBuilder( VertexFormat format, Function bakedTextureGetter ) + CableBuilder( Function 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 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 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 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 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 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 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 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 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 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 getTextures() + public static List getTextures() { - List locations = new ArrayList<>(); + List locations = new ArrayList<>(); for( CableCoreType coreType : CableCoreType.values() ) { @@ -774,5 +768,4 @@ class CableBuilder { return this.coreTextures.get( coreType ).get( color ); } - } diff --git a/src/main/java/appeng/client/render/cablebus/CableBusBakedModel.java b/src/main/java/appeng/client/render/cablebus/CableBusBakedModel.java index 2c498dbca..f4f59b884 100644 --- a/src/main/java/appeng/client/render/cablebus/CableBusBakedModel.java +++ b/src/main/java/appeng/client/render/cablebus/CableBusBakedModel.java @@ -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 partModels, TextureAtlasSprite particleTexture ) { @@ -75,28 +77,33 @@ public class CableBusBakedModel implements IBakedModel } @Override - public List getQuads( @Nullable BlockState state, @Nullable Direction side, long rand ) + public List getQuads( @Nullable BlockState state, @Nullable Direction side, Random rand ) { - CableBusRenderState renderState = getRenderingState( state ); + return getQuads( state, side, rand, EmptyModelData.INSTANCE ); + } + + @Override + public List 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 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 cableModel = CABLE_MODEL_CACHE.computeIfAbsent( renderState, k -> - { + final List cableModel = CABLE_MODEL_CACHE.computeIfAbsent( renderState, k -> { final List 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() { diff --git a/src/main/java/appeng/client/render/cablebus/CableBusModel.java b/src/main/java/appeng/client/render/cablebus/CableBusModel.java index 56856cd3e..ee2b84f14 100644 --- a/src/main/java/appeng/client/render/cablebus/CableBusModel.java +++ b/src/main/java/appeng/client/render/cablebus/CableBusModel.java @@ -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 getTextures() + public Collection getTextures( Function modelGetter, Set> missingTextureErrors ) { - return ImmutableList.builder() - .addAll( CableBuilder.getTextures() ) - .build(); + return Collections.unmodifiableList( CableBuilder.getTextures() ); } + @Nullable @Override - public IBakedModel bake( IModelState state, VertexFormat format, Function bakedTextureGetter ) + public IBakedModel bakeModel( ModelBakery modelBakeryIn, Function spriteGetterIn, IModelTransform transformIn, ResourceLocation locationIn ) { - Map partModels = this.loadPartModels( state, format, bakedTextureGetter ); + Map 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 loadPartModels( IModelState state, VertexFormat format, Function bakedTextureGetter ) + private Map loadPartModels( ModelBakery modelBakeryIn, Function spriteGetterIn, IModelTransform transformIn ) { ImmutableMap.Builder 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(); - } } diff --git a/src/main/java/appeng/client/render/cablebus/CableBusRenderState.java b/src/main/java/appeng/client/render/cablebus/CableBusRenderState.java index 0ef0c1e07..99aac7f9f 100644 --- a/src/main/java/appeng/client/render/cablebus/CableBusRenderState.java +++ b/src/main/java/appeng/client/render/cablebus/CableBusRenderState.java @@ -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 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 facades = new EnumMap<>( Direction.class ); // Used for Facades. - private WeakReference world; + private WeakReference 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 ); } diff --git a/src/main/java/appeng/client/render/cablebus/CableCoreType.java b/src/main/java/appeng/client/render/cablebus/CableCoreType.java index 0a0c58c2f..63b4b2a3a 100644 --- a/src/main/java/appeng/client/render/cablebus/CableCoreType.java +++ b/src/main/java/appeng/client/render/cablebus/CableCoreType.java @@ -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() ) ); } -} \ No newline at end of file +} diff --git a/src/main/java/appeng/client/render/cablebus/FacadeBlockAccess.java b/src/main/java/appeng/client/render/cablebus/FacadeBlockAccess.java index 9cedfbe79..3b2775890 100644 --- a/src/main/java/appeng/client/render/cablebus/FacadeBlockAccess.java +++ b/src/main/java/appeng/client/render/cablebus/FacadeBlockAccess.java @@ -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 ); } } diff --git a/src/main/java/appeng/client/render/cablebus/FacadeBuilder.java b/src/main/java/appeng/client/render/cablebus/FacadeBuilder.java index d9de99986..1efded313 100644 --- a/src/main/java/appeng/client/render/cablebus/FacadeBuilder.java +++ b/src/main/java/appeng/client/render/cablebus/FacadeBuilder.java @@ -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 pipelines = ThreadLocal.withInitial( () -> BakedPipeline.builder() + private final ThreadLocal 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 collectors = ThreadLocal.withInitial( Quad::new ); + private final ThreadLocal collectors = ThreadLocal.withInitial( Quad::new ); - public void buildFacadeQuads( BlockRenderLayer layer, CableBusRenderState renderState, long rand, List quads, Function modelLookup ) + public void buildFacadeQuads( RenderType layer, CableBusRenderState renderState, Random rand, List quads, Function modelLookup ) { BakedPipeline pipeline = this.pipelines.get(); Quad collectorQuad = this.collectors.get(); @@ -113,7 +120,7 @@ public class FacadeBuilder Map facadeStates = renderState.getFacades(); List partBoxes = renderState.getBoundingBoxes(); Set 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 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 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 buildFacadeItemQuads( ItemStack textureItem, Direction side ) { List facadeQuads = new ArrayList<>(); - IBakedModel model = Minecraft.getInstance().getRenderItem().getItemModelWithOverrides( textureItem, null, null ); - List modelQuads = gatherQuads( model, null, 0 ); + IBakedModel model = Minecraft.getInstance().getItemRenderer().getItemModelWithOverrides( textureItem, null, null ); + List 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 gatherQuads( IBakedModel model, BlockState state, long rand ) + private static List gatherQuads( IBakedModel model, BlockState state, Random rand, IModelData data ) { List 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; } diff --git a/src/main/java/appeng/client/render/cablebus/QuadRotator.java b/src/main/java/appeng/client/render/cablebus/QuadRotator.java index 7b0b17f92..59b8baa9a 100644 --- a/src/main/java/appeng/client/render/cablebus/QuadRotator.java +++ b/src/main/java/appeng/client/render/cablebus/QuadRotator.java @@ -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 pipelines = ThreadLocal.withInitial( () -> // + BakedPipeline.builder()// + .addElement( "transformer", QuadMatrixTransformer.FACTORY )// + .build() ); + private static final ThreadLocal collectors = ThreadLocal.withInitial( Quad::new ); public List rotateQuads( List quads, Direction newForward, Direction newUp ) { @@ -51,15 +54,33 @@ public class QuadRotator List 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 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 ); } } diff --git a/src/main/java/appeng/client/render/cablebus/SmartCableTextures.java b/src/main/java/appeng/client/render/cablebus/SmartCableTextures.java index 1bbc7eb84..c9c2dc219 100644 --- a/src/main/java/appeng/client/render/cablebus/SmartCableTextures.java +++ b/src/main/java/appeng/client/render/cablebus/SmartCableTextures.java @@ -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 bakedTextureGetter ) + public SmartCableTextures( Function 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 ); } /** diff --git a/src/main/java/appeng/thirdparty/codechicken/lib/model/pipeline/transformers/QuadMatrixTransformer.java b/src/main/java/appeng/thirdparty/codechicken/lib/model/pipeline/transformers/QuadMatrixTransformer.java new file mode 100644 index 000000000..7ace11f46 --- /dev/null +++ b/src/main/java/appeng/thirdparty/codechicken/lib/model/pipeline/transformers/QuadMatrixTransformer.java @@ -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 . + */ + +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 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; + } +}