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() ) ); 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() public Vector3f getRot()
{ {
return this.rot; return this.rot;
@@ -27,8 +27,9 @@ import java.util.List;
import java.util.function.Function; import java.util.function.Function;
import net.minecraft.client.renderer.model.BakedQuad; 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.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
@@ -43,8 +44,6 @@ import appeng.core.AppEng;
class CableBuilder class CableBuilder
{ {
private final VertexFormat format;
// Textures for the cable core types, one per type/color pair // Textures for the cable core types, one per type/color pair
private final EnumMap<CableCoreType, EnumMap<AEColor, TextureAtlasSprite>> coreTextures; private final EnumMap<CableCoreType, EnumMap<AEColor, TextureAtlasSprite>> coreTextures;
@@ -53,9 +52,8 @@ class CableBuilder
private final SmartCableTextures smartCableTextures; 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 ); this.coreTextures = new EnumMap<>( CableCoreType.class );
for( CableCoreType type : CableCoreType.values() ) for( CableCoreType type : CableCoreType.values() )
@@ -87,7 +85,7 @@ class CableBuilder
this.smartCableTextures = new SmartCableTextures( bakedTextureGetter ); this.smartCableTextures = new SmartCableTextures( bakedTextureGetter );
} }
static ResourceLocation getConnectionTexture( AECableType cableType, AEColor color ) static Material getConnectionTexture( AECableType cableType, AEColor color )
{ {
String textureFolder; String textureFolder;
switch( cableType ) switch( cableType )
@@ -111,7 +109,7 @@ class CableBuilder
throw new IllegalStateException( "Cable type " + cableType + " does not support connections." ); 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 ) 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 ); TextureAtlasSprite texture = this.coreTextures.get( coreType ).get( color );
cubeBuilder.setTexture( texture ); cubeBuilder.setTexture( texture );
@@ -161,7 +159,7 @@ class CableBuilder
public void addGlassConnection( Direction facing, AEColor cableColor, AECableType connectionType, boolean cableBusAdjacent, List<BakedQuad> quadsOut ) 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 // We render all faces except the one on the connection side
cubeBuilder.setDrawFaces( EnumSet.complementOf( EnumSet.of( facing ) ) ); cubeBuilder.setDrawFaces( EnumSet.complementOf( EnumSet.of( facing ) ) );
@@ -203,7 +201,7 @@ class CableBuilder
public void addStraightGlassConnection( Direction facing, AEColor cableColor, List<BakedQuad> quadsOut ) 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 // 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 // and its ends will always be covered by something
@@ -238,7 +236,7 @@ class CableBuilder
return; return;
} }
CubeBuilder cubeBuilder = new CubeBuilder( this.format, quadsOut ); CubeBuilder cubeBuilder = new CubeBuilder( quadsOut );
TextureAtlasSprite texture = this.connectionTextures.get( AECableType.GLASS ).get( cableColor ); TextureAtlasSprite texture = this.connectionTextures.get( AECableType.GLASS ).get( cableColor );
cubeBuilder.setTexture( texture ); cubeBuilder.setTexture( texture );
@@ -269,7 +267,7 @@ class CableBuilder
public void addCoveredConnection( Direction facing, AEColor cableColor, AECableType connectionType, boolean cableBusAdjacent, List<BakedQuad> quadsOut ) 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 // We render all faces except the one on the connection side
cubeBuilder.setDrawFaces( EnumSet.complementOf( EnumSet.of( facing ) ) ); cubeBuilder.setDrawFaces( EnumSet.complementOf( EnumSet.of( facing ) ) );
@@ -288,7 +286,7 @@ class CableBuilder
public void addStraightCoveredConnection( Direction facing, AEColor cableColor, List<BakedQuad> quadsOut ) 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 ); TextureAtlasSprite texture = this.connectionTextures.get( AECableType.COVERED ).get( cableColor );
cubeBuilder.setTexture( texture ); cubeBuilder.setTexture( texture );
@@ -296,7 +294,6 @@ class CableBuilder
setStraightCableUVs( cubeBuilder, facing, 5, 11 ); setStraightCableUVs( cubeBuilder, facing, 5, 11 );
addStraightCoveredCableSizedCube( facing, cubeBuilder ); addStraightCoveredCableSizedCube( facing, cubeBuilder );
} }
private static void setStraightCableUVs( CubeBuilder cubeBuilder, Direction facing, int x, int y ) private static void setStraightCableUVs( CubeBuilder cubeBuilder, Direction facing, int x, int y )
@@ -336,13 +333,12 @@ class CableBuilder
return; return;
} }
CubeBuilder cubeBuilder = new CubeBuilder( this.format, quadsOut ); CubeBuilder cubeBuilder = new CubeBuilder( quadsOut );
TextureAtlasSprite texture = this.connectionTextures.get( AECableType.COVERED ).get( cableColor ); TextureAtlasSprite texture = this.connectionTextures.get( AECableType.COVERED ).get( cableColor );
cubeBuilder.setTexture( texture ); cubeBuilder.setTexture( texture );
addCoveredCableSizedCube( facing, distanceFromEdge, cubeBuilder ); addCoveredCableSizedCube( facing, distanceFromEdge, cubeBuilder );
} }
public void addSmartConnection( Direction facing, AEColor cableColor, AECableType connectionType, boolean cableBusAdjacent, int channels, List<BakedQuad> quadsOut ) public void addSmartConnection( Direction facing, AEColor cableColor, AECableType connectionType, boolean cableBusAdjacent, int channels, List<BakedQuad> quadsOut )
@@ -353,7 +349,7 @@ class CableBuilder
return; return;
} }
CubeBuilder cubeBuilder = new CubeBuilder( this.format, quadsOut ); CubeBuilder cubeBuilder = new CubeBuilder( quadsOut );
// We render all faces except the one on the connection side // We render all faces except the one on the connection side
cubeBuilder.setDrawFaces( EnumSet.complementOf( EnumSet.of( facing ) ) ); 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 ) 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 ); TextureAtlasSprite texture = this.connectionTextures.get( AECableType.SMART ).get( cableColor );
cubeBuilder.setTexture( texture ); cubeBuilder.setTexture( texture );
@@ -434,7 +430,7 @@ class CableBuilder
return; return;
} }
CubeBuilder cubeBuilder = new CubeBuilder( this.format, quadsOut ); CubeBuilder cubeBuilder = new CubeBuilder( quadsOut );
TextureAtlasSprite texture = this.connectionTextures.get( AECableType.SMART ).get( cableColor ); TextureAtlasSprite texture = this.connectionTextures.get( AECableType.SMART ).get( cableColor );
cubeBuilder.setTexture( texture ); cubeBuilder.setTexture( texture );
@@ -465,7 +461,7 @@ class CableBuilder
return; return;
} }
CubeBuilder cubeBuilder = new CubeBuilder( this.format, quadsOut ); CubeBuilder cubeBuilder = new CubeBuilder( quadsOut );
// We render all faces except the one on the connection side // We render all faces except the one on the connection side
cubeBuilder.setDrawFaces( EnumSet.complementOf( EnumSet.of( facing ) ) ); cubeBuilder.setDrawFaces( EnumSet.complementOf( EnumSet.of( facing ) ) );
@@ -499,7 +495,7 @@ class CableBuilder
return; return;
} }
CubeBuilder cubeBuilder = new CubeBuilder( this.format, quadsOut ); CubeBuilder cubeBuilder = new CubeBuilder( quadsOut );
// We render all faces except the one on the connection side // We render all faces except the one on the connection side
cubeBuilder.setDrawFaces( EnumSet.complementOf( EnumSet.of( facing ) ) ); cubeBuilder.setDrawFaces( EnumSet.complementOf( EnumSet.of( facing ) ) );
@@ -529,12 +525,11 @@ class CableBuilder
// Reset back to normal rendering for the rest // Reset back to normal rendering for the rest
cubeBuilder.setRenderFullBright( false ); cubeBuilder.setRenderFullBright( false );
cubeBuilder.setTexture( texture ); cubeBuilder.setTexture( texture );
} }
public void addStraightDenseCoveredConnection( Direction facing, AEColor cableColor, List<BakedQuad> quadsOut ) 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 ); TextureAtlasSprite texture = this.connectionTextures.get( AECableType.DENSE_COVERED ).get( cableColor );
cubeBuilder.setTexture( texture ); cubeBuilder.setTexture( texture );
@@ -546,7 +541,7 @@ class CableBuilder
public void addStraightDenseSmartConnection( Direction facing, AEColor cableColor, int channels, List<BakedQuad> quadsOut ) 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 ); TextureAtlasSprite texture = this.connectionTextures.get( AECableType.DENSE_SMART ).get( cableColor );
cubeBuilder.setTexture( texture ); cubeBuilder.setTexture( texture );
@@ -627,7 +622,6 @@ class CableBuilder
cubeBuilder.setUvRotation( Direction.WEST, 0 ); cubeBuilder.setUvRotation( Direction.WEST, 0 );
break; break;
} }
} }
// Adds a cube to the given cube builder that has the size of a covered cable connection from the core of the cable // 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 // 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() ) for( CableCoreType coreType : CableCoreType.values() )
{ {
@@ -774,5 +768,4 @@ class CableBuilder
{ {
return this.coreTextures.get( coreType ).get( color ); return this.coreTextures.get( coreType ).get( color );
} }
} }
@@ -27,28 +27,29 @@ import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Random;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.model.BakedQuad; import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.model.IBakedModel; import net.minecraft.client.renderer.model.IBakedModel;
import net.minecraft.client.renderer.model.ItemCameraTransforms; import net.minecraft.client.renderer.model.ItemCameraTransforms;
import net.minecraft.client.renderer.model.ItemOverrideList; 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.TextureAtlasSprite;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.MinecraftForgeClient; 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.IPartBakedModel;
import appeng.api.parts.IPartModel; import appeng.api.parts.IPartModel;
import appeng.api.util.AECableType; import appeng.api.util.AECableType;
import appeng.api.util.AEColor; import appeng.api.util.AEColor;
import appeng.block.networking.BlockCableBus;
public class CableBusBakedModel implements IBakedModel public class CableBusBakedModel implements IBakedModel
@@ -64,7 +65,8 @@ public class CableBusBakedModel implements IBakedModel
private final TextureAtlasSprite particleTexture; 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 ) CableBusBakedModel( CableBuilder cableBuilder, FacadeBuilder facadeBuilder, Map<ResourceLocation, IBakedModel> partModels, TextureAtlasSprite particleTexture )
{ {
@@ -75,28 +77,33 @@ public class CableBusBakedModel implements IBakedModel
} }
@Override @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 ) if( renderState == null || side != null )
{ {
return Collections.emptyList(); return Collections.emptyList();
} }
BlockRenderLayer layer = MinecraftForgeClient.getRenderLayer(); RenderType layer = MinecraftForgeClient.getRenderLayer();
List<BakedQuad> quads = new ArrayList<>(); List<BakedQuad> quads = new ArrayList<>();
// The core parts of the cable will only be rendered in the CUTOUT layer. // 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, // 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. // 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 // 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<>(); final List<BakedQuad> model = new ArrayList<>();
this.addCableQuads( renderState, model ); this.addCableQuads( renderState, model );
return 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), // 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. // 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 ); result.add( particleTexture );
} }
@@ -320,17 +327,6 @@ public class CableBusBakedModel implements IBakedModel
return result; 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 @Override
public boolean isAmbientOcclusion() public boolean isAmbientOcclusion()
{ {
@@ -343,6 +339,12 @@ public class CableBusBakedModel implements IBakedModel
return false; return false;
} }
@Override
public boolean func_230044_c_()
{
return false;//TODO
}
@Override @Override
public boolean isBuiltInRenderer() public boolean isBuiltInRenderer()
{ {
@@ -20,30 +20,31 @@ package appeng.client.render.cablebus;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
import javax.annotation.Nullable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; 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.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.util.ResourceLocation; 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.api.util.AEColor;
import appeng.core.AELog;
import appeng.core.features.registries.PartModels; import appeng.core.features.registries.PartModels;
/** /**
* The built-in model for the cable bus block. * The built-in model for the cable bus block.
*/ */
public class CableBusModel implements IModel public class CableBusModel implements IUnbakedModel
{ {
private final PartModels partModels; private final PartModels partModels;
@@ -61,19 +62,18 @@ public class CableBusModel implements IModel
} }
@Override @Override
public Collection<ResourceLocation> getTextures() public Collection<Material> getTextures( Function<ResourceLocation, IUnbakedModel> modelGetter, Set<Pair<String, String>> missingTextureErrors )
{ {
return ImmutableList.<ResourceLocation>builder() return Collections.unmodifiableList( CableBuilder.getTextures() );
.addAll( CableBuilder.getTextures() )
.build();
} }
@Nullable
@Override @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(); FacadeBuilder facadeBuilder = new FacadeBuilder();
// This should normally not be used, but we *have* to provide a particle texture or otherwise damage models will // 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 ); 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(); ImmutableMap.Builder<ResourceLocation, IBakedModel> result = ImmutableMap.builder();
for( ResourceLocation location : this.partModels.getModels() ) for( ResourceLocation location : this.partModels.getModels() )
{ {
IModel model = this.tryLoadPartModel( location ); result.put( location, modelBakeryIn.getBakedModel( location, transformIn, spriteGetterIn ) );
IBakedModel bakedModel = model.bake( state, format, bakedTextureGetter );
result.put( location, bakedModel );
} }
return result.build(); 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.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader; 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.parts.IPartModel;
import appeng.api.util.AECableType; import appeng.api.util.AECableType;
@@ -43,6 +45,8 @@ import appeng.api.util.AEColor;
public class CableBusRenderState 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 // The cable type used for rendering the outgoing connections to other blocks and attached parts
private AECableType cableType = AECableType.NONE; private AECableType cableType = AECableType.NONE;
@@ -73,7 +77,7 @@ public class CableBusRenderState
private EnumMap<Direction, FacadeRenderState> facades = new EnumMap<>( Direction.class ); private EnumMap<Direction, FacadeRenderState> facades = new EnumMap<>( Direction.class );
// Used for Facades. // Used for Facades.
private WeakReference<IBlockReader> world; private WeakReference<ILightReader> world;
private BlockPos pos; 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 // 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; return this.facades;
} }
public IBlockReader getWorld() public ILightReader getWorld()
{ {
return this.world.get(); return this.world.get();
} }
public void setWorld( IBlockReader world ) public void setWorld( ILightReader world )
{ {
this.world = new WeakReference<>( world ); this.world = new WeakReference<>( world );
} }
@@ -24,6 +24,8 @@ import java.util.Map;
import com.google.common.collect.ImmutableMap; 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 net.minecraft.util.ResourceLocation;
import appeng.api.util.AECableType; import appeng.api.util.AECableType;
@@ -78,9 +80,9 @@ public enum CableCoreType
return cableMapping.get( cableType ); 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 javax.annotation.Nullable;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.fluid.IFluidState;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader; import net.minecraft.world.ILightReader;
import net.minecraft.world.WorldType; import net.minecraft.world.level.ColorResolver;
import net.minecraft.world.biome.Biome; import net.minecraft.world.lighting.WorldLightManager;
/** /**
@@ -36,15 +37,15 @@ import net.minecraft.world.biome.Biome;
* *
* @author covers1624 * @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 BlockPos pos;
private final Direction side; private final Direction side;
private final BlockState state; 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.world = world;
this.pos = pos; this.pos = pos;
@@ -59,12 +60,6 @@ public class FacadeBlockAccess implements IBlockReader
return this.world.getTileEntity( pos ); return this.world.getTileEntity( pos );
} }
@Override
public int getCombinedLight( BlockPos pos, int lightValue )
{
return this.world.getCombinedLight( pos, lightValue );
}
@Override @Override
public BlockState getBlockState( BlockPos pos ) public BlockState getBlockState( BlockPos pos )
{ {
@@ -76,40 +71,20 @@ public class FacadeBlockAccess implements IBlockReader
} }
@Override @Override
public boolean isAirBlock( BlockPos pos ) public IFluidState getFluidState( BlockPos pos )
{ {
BlockState state = this.getBlockState( pos ); return world.getFluidState( pos );
return state.getBlock().isAir( state, this.world, pos );
} }
@Override @Override
public Biome getBiome( BlockPos pos ) public WorldLightManager getLightManager()
{ {
return this.world.getBiome( pos ); return world.getLightManager();
} }
@Override @Override
public int getStrongPower( BlockPos pos, Direction direction ) public int getBlockColor( BlockPos blockPosIn, ColorResolver colorResolverIn )
{ {
return this.world.getStrongPower( pos, direction ); return world.getBlockColor( blockPosIn, colorResolverIn );
}
@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 );
}
} }
} }
@@ -24,6 +24,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.function.Function; import java.util.function.Function;
@@ -32,21 +33,27 @@ import javax.annotation.Nullable;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockRendererDispatcher; 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.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.color.BlockColors; 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.item.ItemStack;
import net.minecraft.util.BlockRenderLayer;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis; import net.minecraft.util.Direction.Axis;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader; import net.minecraft.world.IBlockReader;
import net.minecraft.world.ILightReader;
import net.minecraftforge.client.ForgeHooksClient; 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.AEApi;
import appeng.api.util.AEAxisAlignedBB; import appeng.api.util.AEAxisAlignedBB;
import appeng.core.Api;
import appeng.parts.misc.PartCableAnchor; import appeng.parts.misc.PartCableAnchor;
import appeng.thirdparty.codechicken.lib.model.CachedFormat; import appeng.thirdparty.codechicken.lib.model.CachedFormat;
import appeng.thirdparty.codechicken.lib.model.Quad; 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 ) 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. // Clamper is responsible for clamping the vertex to the bounds specified.
.addElement( "clamper", QuadClamper.FACTORY ) .addElement( "clamper", QuadClamper.FACTORY )
// Strips faces if they match a mask. // Strips faces if they match a mask.
@@ -103,9 +110,9 @@ public class FacadeBuilder
.addElement( "transparent", QuadAlphaOverride.FACTORY, false, e -> e.setAlphaOverride( 0x4C / 255F ) ) .addElement( "transparent", QuadAlphaOverride.FACTORY, false, e -> e.setAlphaOverride( 0x4C / 255F ) )
.build()// .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(); BakedPipeline pipeline = this.pipelines.get();
Quad collectorQuad = this.collectors.get(); Quad collectorQuad = this.collectors.get();
@@ -113,7 +120,7 @@ public class FacadeBuilder
Map<Direction, FacadeRenderState> facadeStates = renderState.getFacades(); Map<Direction, FacadeRenderState> facadeStates = renderState.getFacades();
List<AxisAlignedBB> partBoxes = renderState.getBoundingBoxes(); List<AxisAlignedBB> partBoxes = renderState.getBoundingBoxes();
Set<Direction> sidesWithParts = renderState.getAttachments().keySet(); Set<Direction> sidesWithParts = renderState.getAttachments().keySet();
IBlockReader parentWorld = renderState.getWorld(); ILightReader parentWorld = renderState.getWorld();
BlockPos pos = renderState.getPos(); BlockPos pos = renderState.getPos();
BlockColors blockColors = Minecraft.getInstance().getBlockColors(); BlockColors blockColors = Minecraft.getInstance().getBlockColors();
boolean thinFacades = isUseThinFacades( partBoxes ); boolean thinFacades = isUseThinFacades( partBoxes );
@@ -124,17 +131,17 @@ public class FacadeBuilder
int sideIndex = side.ordinal(); int sideIndex = side.ordinal();
FacadeRenderState facadeRenderState = entry.getValue(); FacadeRenderState facadeRenderState = entry.getValue();
boolean renderStilt = !sidesWithParts.contains( side ); boolean renderStilt = !sidesWithParts.contains( side );
if( layer == BlockRenderLayer.CUTOUT && renderStilt ) if( layer == RenderType.getCutout() && renderStilt )
{ {
for( ResourceLocation part : PartCableAnchor.FACADE_MODELS.getModels() ) for( ResourceLocation part : PartCableAnchor.FACADE_MODELS.getModels() )
{ {
IBakedModel partModel = modelLookup.apply( part ); IBakedModel partModel = modelLookup.apply( part );
QuadRotator rotator = new QuadRotator(); 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 we are forcing transparency and this isn't the Translucent layer.
if( transparent && layer != BlockRenderLayer.TRANSLUCENT ) if( transparent && layer != RenderType.getTranslucent() )
{ {
continue; continue;
} }
@@ -143,7 +150,7 @@ public class FacadeBuilder
// If we aren't forcing transparency let the block decide if it should render. // If we aren't forcing transparency let the block decide if it should render.
if( !transparent && layer != null ) if( !transparent && layer != null )
{ {
if( !blockState.getBlock().canRenderInLayer( blockState, layer ) ) if( !RenderTypeLookup.canRenderInLayer( blockState, layer ) )
{ {
continue; continue;
} }
@@ -202,38 +209,24 @@ public class FacadeBuilder
AEAxisAlignedBB cutOutBox = getCutOutBox( facadeBox, partBoxes ); AEAxisAlignedBB cutOutBox = getCutOutBox( facadeBox, partBoxes );
List<AxisAlignedBB> holeStrips = getBoxes( facadeBox, cutOutBox, side.getAxis() ); 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(); BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher();
try
{
blockState = blockState.getActualState( facadeAccess, pos );
}
catch( Exception ignored )
{
}
IBakedModel model = dispatcher.getModelForState( blockState ); IBakedModel model = dispatcher.getModelForState( blockState );
try IModelData modelData = model.getModelData( facadeAccess, pos, blockState, EmptyModelData.INSTANCE );
{
blockState = blockState.getBlock().getExtendedState( blockState, facadeAccess, pos );
}
catch( Exception ignored )
{
}
List<BakedQuad> modelQuads = new ArrayList<>(); List<BakedQuad> modelQuads = new ArrayList<>();
// If we are forcing transparent facades, fake the render layer, and grab all quads. // If we are forcing transparent facades, fake the render layer, and grab all quads.
if( transparent || layer == null ) 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. // 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. // Force the layer and gather quads.
ForgeHooksClient.setRenderLayer( forcedLayer ); ForgeHooksClient.setRenderLayer( forcedLayer );
modelQuads.addAll( gatherQuads( model, blockState, rand ) ); modelQuads.addAll( gatherQuads( model, blockState, rand, modelData) );
} }
} }
@@ -242,7 +235,7 @@ public class FacadeBuilder
} }
else else
{ {
modelQuads.addAll( gatherQuads( model, blockState, rand ) ); modelQuads.addAll( gatherQuads( model, blockState, rand, modelData ) );
} }
// No quads.. Cool, next! // No quads.. Cool, next!
@@ -286,11 +279,11 @@ public class FacadeBuilder
for( BakedQuad quad : modelQuads ) for( BakedQuad quad : modelQuads )
{ {
// lookup the format in CachedFormat. // 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 this quad has a tint index, setup the tinter.
if( quad.hasTintIndex() ) 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 ) for( AxisAlignedBB box : holeStrips )
{ {
@@ -327,8 +320,8 @@ public class FacadeBuilder
public List<BakedQuad> buildFacadeItemQuads( ItemStack textureItem, Direction side ) public List<BakedQuad> buildFacadeItemQuads( ItemStack textureItem, Direction side )
{ {
List<BakedQuad> facadeQuads = new ArrayList<>(); List<BakedQuad> facadeQuads = new ArrayList<>();
IBakedModel model = Minecraft.getInstance().getRenderItem().getItemModelWithOverrides( textureItem, null, null ); IBakedModel model = Minecraft.getInstance().getItemRenderer().getItemModelWithOverrides( textureItem, null, null );
List<BakedQuad> modelQuads = gatherQuads( model, null, 0 ); List<BakedQuad> modelQuads = gatherQuads( model, null, new Random(), EmptyModelData.INSTANCE );
BakedPipeline pipeline = this.pipelines.get(); BakedPipeline pipeline = this.pipelines.get();
Quad collectorQuad = this.collectors.get(); Quad collectorQuad = this.collectors.get();
@@ -340,7 +333,7 @@ public class FacadeBuilder
for( BakedQuad quad : modelQuads ) for( BakedQuad quad : modelQuads )
{ {
// Lookup the CachedFormat for this quads format. // Lookup the CachedFormat for this quads format.
CachedFormat format = CachedFormat.lookup( quad.getFormat() ); CachedFormat format = CachedFormat.lookup( DefaultVertexFormats.BLOCK );
// Reset the pipeline. // Reset the pipeline.
pipeline.reset( format ); pipeline.reset( format );
// Reset the collector. // Reset the collector.
@@ -348,7 +341,7 @@ public class FacadeBuilder
// If we have a tint index, setup the tinter and enable it. // If we have a tint index, setup the tinter and enable it.
if( quad.hasTintIndex() ) if( quad.hasTintIndex() )
{ {
tinter.setTint( Minecraft.getInstance().getItemColors().colorMultiplier( textureItem, quad.getTintIndex() ) ); tinter.setTint( Minecraft.getInstance().getItemColors().getColor( textureItem, quad.getTintIndex() ) );
pipeline.enableElement( "tinter" ); pipeline.enableElement( "tinter" );
} }
// Disable elements we don't need for items. // 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. // Check the collector for data and add the quad if there was.
if( collectorQuad.full ) if( collectorQuad.full )
{ {
facadeQuads.add( collectorQuad.bakeUnpacked() ); facadeQuads.add( collectorQuad.bake() );
} }
} }
return facadeQuads; return facadeQuads;
} }
// Helper to gather all quads from a model into a list. // 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<>(); List<BakedQuad> modelQuads = new ArrayList<>();
for( Direction face : Direction.values() ) 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; return modelQuads;
} }
@@ -22,17 +22,15 @@ package appeng.client.render.cablebus;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; 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.model.BakedQuad;
import net.minecraft.client.renderer.vertex.VertexFormat; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.renderer.vertex.VertexFormatElement;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import appeng.client.render.FacingToRotation; 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 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 ) 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() ); 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 ) 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; return result;
} }
private BakedQuad rotateQuad( BakedQuad quad, Direction forward, Direction up ) private FacingToRotation getRotation( Direction forward, Direction up )
{ {
// Sanitize forward/up // Sanitize forward/up
if( forward.getAxis() == up.getAxis() ) if( forward.getAxis() == up.getAxis() )
@@ -74,116 +95,6 @@ public class QuadRotator
} }
} }
FacingToRotation rotation = FacingToRotation.get( forward, up ); return 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!" );
} }
} }
@@ -22,6 +22,8 @@ package appeng.client.render.cablebus;
import java.util.Arrays; import java.util.Arrays;
import java.util.function.Function; 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.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
@@ -34,21 +36,28 @@ import appeng.core.AppEng;
public class SmartCableTextures public class SmartCableTextures
{ {
public static final ResourceLocation[] SMART_CHANNELS_TEXTURES = { new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_00" ), public static final Material[] SMART_CHANNELS_TEXTURES = Arrays.stream( new ResourceLocation[] {
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_00" ),//
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_01" ),//
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_02" ),//
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_03" ),//
new ResourceLocation( AppEng.MOD_ID, "parts/cable/smart/channels_14" ) 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 // 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 // one of each set are composed together to get even/odd colored channels
private final TextureAtlasSprite[] textures; 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;
}
}