Implemented facade rendering on the cable bus.
This commit is contained in:
parent
71396637e3
commit
2de1842445
|
@ -24,10 +24,12 @@
|
||||||
package appeng.api.parts;
|
package appeng.api.parts;
|
||||||
|
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
|
||||||
|
|
||||||
import appeng.api.util.AEPartLocation;
|
import appeng.api.util.AEPartLocation;
|
||||||
|
|
||||||
|
@ -58,18 +60,23 @@ public interface IFacadePart
|
||||||
*/
|
*/
|
||||||
AEPartLocation getSide();
|
AEPartLocation getSide();
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the box for the face of the facade
|
|
||||||
*/
|
|
||||||
AxisAlignedBB getPrimaryBox();
|
|
||||||
|
|
||||||
Item getItem();
|
Item getItem();
|
||||||
|
|
||||||
int getItemDamage();
|
int getItemDamage();
|
||||||
|
|
||||||
boolean notAEFacade();
|
boolean notAEFacade();
|
||||||
|
|
||||||
void setThinFacades( boolean useThinFacades );
|
|
||||||
|
|
||||||
boolean isTransparent();
|
boolean isTransparent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The item that this facade masquerades as.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
ItemStack getTextureItem();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The block state used for rendering.
|
||||||
|
*/
|
||||||
|
IBlockState getBlockState();
|
||||||
|
|
||||||
}
|
}
|
|
@ -58,6 +58,7 @@ import net.minecraftforge.fml.common.registry.GameRegistry;
|
||||||
import net.minecraftforge.fml.relauncher.Side;
|
import net.minecraftforge.fml.relauncher.Side;
|
||||||
import net.minecraftforge.fml.relauncher.SideOnly;
|
import net.minecraftforge.fml.relauncher.SideOnly;
|
||||||
|
|
||||||
|
import appeng.api.AEApi;
|
||||||
import appeng.api.parts.IPartHost;
|
import appeng.api.parts.IPartHost;
|
||||||
import appeng.api.parts.PartItemStack;
|
import appeng.api.parts.PartItemStack;
|
||||||
import appeng.api.parts.SelectedPart;
|
import appeng.api.parts.SelectedPart;
|
||||||
|
@ -405,6 +406,19 @@ public class BlockCableBus extends AEBaseTileBlock
|
||||||
ClientRegistry.bindTileEntitySpecialRenderer( BlockCableBus.getTesrTile(), new CableBusTESR() );
|
ClientRegistry.bindTileEntitySpecialRenderer( BlockCableBus.getTesrTile(), new CableBusTESR() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canRenderInLayer( IBlockState state, BlockRenderLayer layer )
|
||||||
|
{
|
||||||
|
if( AEApi.instance().partHelper().getCableRenderMode().transparentFacades )
|
||||||
|
{
|
||||||
|
return layer == BlockRenderLayer.TRANSLUCENT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return layer == BlockRenderLayer.CUTOUT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static Class<? extends AEBaseTile> getNoTesrTile()
|
public static Class<? extends AEBaseTile> getNoTesrTile()
|
||||||
{
|
{
|
||||||
return noTesrTile;
|
return noTesrTile;
|
||||||
|
|
|
@ -26,7 +26,6 @@ import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import net.minecraft.block.state.IBlockState;
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
@ -49,11 +48,14 @@ public class CableBusBakedModel implements IBakedModel
|
||||||
|
|
||||||
private final CableBuilder cableBuilder;
|
private final CableBuilder cableBuilder;
|
||||||
|
|
||||||
|
private final FacadeBuilder facadeBuilder;
|
||||||
|
|
||||||
private final Map<ResourceLocation, IBakedModel> partModels;
|
private final Map<ResourceLocation, IBakedModel> partModels;
|
||||||
|
|
||||||
CableBusBakedModel( CableBuilder cableBuilder, Map<ResourceLocation, IBakedModel> partModels )
|
CableBusBakedModel( CableBuilder cableBuilder, FacadeBuilder facadeBuilder, Map<ResourceLocation, IBakedModel> partModels )
|
||||||
{
|
{
|
||||||
this.cableBuilder = cableBuilder;
|
this.cableBuilder = cableBuilder;
|
||||||
|
this.facadeBuilder = facadeBuilder;
|
||||||
this.partModels = partModels;
|
this.partModels = partModels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,6 +100,14 @@ public class CableBusBakedModel implements IBakedModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
facadeBuilder.addFacades(
|
||||||
|
renderState.getFacades(),
|
||||||
|
renderState.getBoundingBoxes(),
|
||||||
|
renderState.getAttachments().keySet(),
|
||||||
|
rand,
|
||||||
|
quads
|
||||||
|
);
|
||||||
|
|
||||||
return quads;
|
return quads;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||||
|
@ -61,7 +62,10 @@ public class CableBusModel implements IModel
|
||||||
@Override
|
@Override
|
||||||
public Collection<ResourceLocation> getTextures()
|
public Collection<ResourceLocation> getTextures()
|
||||||
{
|
{
|
||||||
return CableBuilder.getTextures();
|
return ImmutableList.<ResourceLocation>builder()
|
||||||
|
.addAll( CableBuilder.getTextures() )
|
||||||
|
.addAll( FacadeBuilder.getTextures() )
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -71,7 +75,9 @@ public class CableBusModel implements IModel
|
||||||
Map<ResourceLocation, IBakedModel> partModels = loadPartModels( state, format, bakedTextureGetter );
|
Map<ResourceLocation, IBakedModel> partModels = loadPartModels( state, format, bakedTextureGetter );
|
||||||
|
|
||||||
CableBuilder cableBuilder = new CableBuilder( format, bakedTextureGetter );
|
CableBuilder cableBuilder = new CableBuilder( format, bakedTextureGetter );
|
||||||
return new CableBusBakedModel( cableBuilder, partModels );
|
FacadeBuilder facadeBuilder = new FacadeBuilder( format, bakedTextureGetter );
|
||||||
|
|
||||||
|
return new CableBusBakedModel( cableBuilder, facadeBuilder, partModels );
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<ResourceLocation, IBakedModel> loadPartModels( IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
|
private Map<ResourceLocation, IBakedModel> loadPartModels( IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
|
||||||
|
|
|
@ -19,12 +19,14 @@
|
||||||
package appeng.client.render.cablebus;
|
package appeng.client.render.cablebus;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.ResourceLocation;
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
|
|
||||||
import appeng.api.util.AECableType;
|
import appeng.api.util.AECableType;
|
||||||
import appeng.api.util.AEColor;
|
import appeng.api.util.AEColor;
|
||||||
|
@ -63,6 +65,13 @@ public class CableBusRenderState
|
||||||
// For each attachment, this contains the distance from the edge until which a cable connection should be drawn
|
// For each attachment, this contains the distance from the edge until which a cable connection should be drawn
|
||||||
private EnumMap<EnumFacing, Integer> attachmentConnections = new EnumMap<>( EnumFacing.class );
|
private EnumMap<EnumFacing, Integer> attachmentConnections = new EnumMap<>( EnumFacing.class );
|
||||||
|
|
||||||
|
// Contains the facade to use for each side that has a facade attached
|
||||||
|
private EnumMap<EnumFacing, FacadeRenderState> facades = new EnumMap<>( EnumFacing.class );
|
||||||
|
|
||||||
|
// Contains the bounding boxes of all parts on the cable bus to allow facades to cut out holes for the parts. This list is only populated if there are
|
||||||
|
// facades on this cable bus
|
||||||
|
private List<AxisAlignedBB> boundingBoxes = new ArrayList<>();
|
||||||
|
|
||||||
public CableCoreType getCoreType()
|
public CableCoreType getCoreType()
|
||||||
{
|
{
|
||||||
return coreType;
|
return coreType;
|
||||||
|
@ -133,4 +142,14 @@ public class CableBusRenderState
|
||||||
return attachmentConnections;
|
return attachmentConnections;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EnumMap<EnumFacing, FacadeRenderState> getFacades()
|
||||||
|
{
|
||||||
|
return facades;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<AxisAlignedBB> getBoundingBoxes()
|
||||||
|
{
|
||||||
|
return boundingBoxes;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -411,6 +411,11 @@ public class CubeBuilder
|
||||||
textures.put( EnumFacing.WEST, west );
|
textures.put( EnumFacing.WEST, west );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setTexture( EnumFacing facing, TextureAtlasSprite sprite )
|
||||||
|
{
|
||||||
|
textures.put( facing, sprite );
|
||||||
|
}
|
||||||
|
|
||||||
public void setDrawFaces( EnumSet<EnumFacing> drawFaces )
|
public void setDrawFaces( EnumSet<EnumFacing> drawFaces )
|
||||||
{
|
{
|
||||||
this.drawFaces = drawFaces;
|
this.drawFaces = drawFaces;
|
||||||
|
|
376
src/main/java/appeng/client/render/cablebus/FacadeBuilder.java
Normal file
376
src/main/java/appeng/client/render/cablebus/FacadeBuilder.java
Normal file
|
@ -0,0 +1,376 @@
|
||||||
|
/*
|
||||||
|
* This file is part of Applied Energistics 2.
|
||||||
|
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||||
|
*
|
||||||
|
* Applied Energistics 2 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 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Applied Energistics 2 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 Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package appeng.client.render.cablebus;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.vecmath.Vector3f;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.BlockRendererDispatcher;
|
||||||
|
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||||
|
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||||
|
import net.minecraft.client.renderer.color.BlockColors;
|
||||||
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||||
|
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
|
|
||||||
|
import appeng.api.AEApi;
|
||||||
|
import appeng.api.util.AEAxisAlignedBB;
|
||||||
|
import appeng.core.AELog;
|
||||||
|
import appeng.core.AppEng;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles creating the quads for facades attached to cable busses.
|
||||||
|
*/
|
||||||
|
class FacadeBuilder
|
||||||
|
{
|
||||||
|
|
||||||
|
static final ResourceLocation TEXTURE_FACADE = new ResourceLocation( AppEng.MOD_ID, "parts/cable_anchor" );
|
||||||
|
|
||||||
|
private final BlockColors blockColors = Minecraft.getMinecraft().getBlockColors();
|
||||||
|
|
||||||
|
private final VertexFormat format;
|
||||||
|
|
||||||
|
private final TextureAtlasSprite facadeTexture;
|
||||||
|
private final BlockRendererDispatcher blockRendererDispatcher = Minecraft.getMinecraft().getBlockRendererDispatcher();
|
||||||
|
|
||||||
|
FacadeBuilder( VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
|
||||||
|
{
|
||||||
|
this.format = format;
|
||||||
|
this.facadeTexture = bakedTextureGetter.apply( TEXTURE_FACADE );
|
||||||
|
}
|
||||||
|
|
||||||
|
static Collection<ResourceLocation> getTextures()
|
||||||
|
{
|
||||||
|
return Collections.singletonList( TEXTURE_FACADE );
|
||||||
|
}
|
||||||
|
|
||||||
|
void addFacades( Map<EnumFacing, FacadeRenderState> facadesState, List<AxisAlignedBB> partBoxes, Set<EnumFacing> sidesWithParts, long rand, List<BakedQuad> quads )
|
||||||
|
{
|
||||||
|
boolean thinFacades = isUseThinFacades( partBoxes );
|
||||||
|
|
||||||
|
CubeBuilder builder = new CubeBuilder( format, quads );
|
||||||
|
|
||||||
|
facadesState.forEach( ( side, textureItem ) ->
|
||||||
|
{
|
||||||
|
AxisAlignedBB facadeBox = getFacadeBox( side, thinFacades );
|
||||||
|
AEAxisAlignedBB cutOutBox = getCutOutBox( facadeBox, partBoxes );
|
||||||
|
boolean renderStilt = !sidesWithParts.contains( side );
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
addFacade( facadesState, side, cutOutBox, thinFacades, renderStilt, rand, builder );
|
||||||
|
}
|
||||||
|
catch( Throwable t )
|
||||||
|
{
|
||||||
|
AELog.debug( t );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addFacade( Map<EnumFacing, FacadeRenderState> facades, EnumFacing side, AEAxisAlignedBB busBounds, boolean thinFacades, boolean renderStilt, long rand, CubeBuilder builder )
|
||||||
|
{
|
||||||
|
|
||||||
|
FacadeRenderState facadeState = facades.get( side );
|
||||||
|
IBlockState blockState = facadeState.getSourceBlock();
|
||||||
|
|
||||||
|
builder.setDrawFaces( EnumSet.allOf( EnumFacing.class ) );
|
||||||
|
|
||||||
|
// We only render the stilt if we don't intersect with any part directly, and if there's no part on our side
|
||||||
|
if( renderStilt && busBounds == null )
|
||||||
|
{
|
||||||
|
builder.setTexture( facadeTexture );
|
||||||
|
switch( side )
|
||||||
|
{
|
||||||
|
case DOWN:
|
||||||
|
builder.addCube( 7, 1, 7, 9, 6, 9 );
|
||||||
|
break;
|
||||||
|
case UP:
|
||||||
|
builder.addCube( 7, 10, 7, 9, 15, 9 );
|
||||||
|
break;
|
||||||
|
case NORTH:
|
||||||
|
builder.addCube( 7, 7, 1, 9, 9, 6 );
|
||||||
|
break;
|
||||||
|
case SOUTH:
|
||||||
|
builder.addCube( 7, 7, 10, 9, 9, 15 );
|
||||||
|
break;
|
||||||
|
case WEST:
|
||||||
|
builder.addCube( 1, 7, 7, 6, 9, 9 );
|
||||||
|
break;
|
||||||
|
case EAST:
|
||||||
|
builder.addCube( 10, 7, 7, 15, 9, 9 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final float thickness = thinFacades ? 1 : 2;
|
||||||
|
|
||||||
|
IBakedModel blockModel = blockRendererDispatcher.getModelForState( blockState );
|
||||||
|
|
||||||
|
if( AEApi.instance().partHelper().getCableRenderMode().transparentFacades )
|
||||||
|
{
|
||||||
|
// TODO rbw.setOpacity( 0.3f );
|
||||||
|
}
|
||||||
|
|
||||||
|
int color = 0xffffff;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
blockColors.func_189991_a( blockState );
|
||||||
|
}
|
||||||
|
catch( final Throwable ignored )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.setColorRGB( color );
|
||||||
|
|
||||||
|
// TODO: Cache this
|
||||||
|
for( EnumFacing facing : facadeState.getOpenFaces() )
|
||||||
|
{
|
||||||
|
List<BakedQuad> quads = blockModel.getQuads( blockState, facing, rand );
|
||||||
|
for( BakedQuad quad : quads )
|
||||||
|
{
|
||||||
|
builder.setTexture( quad.getSprite() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.setDrawFaces( facadeState.getOpenFaces() );
|
||||||
|
|
||||||
|
AxisAlignedBB primaryBox = getFacadeBox( side, thinFacades );
|
||||||
|
|
||||||
|
Vector3f min = new Vector3f(
|
||||||
|
(float) primaryBox.minX * 16,
|
||||||
|
(float) primaryBox.minY * 16,
|
||||||
|
(float) primaryBox.minZ * 16
|
||||||
|
);
|
||||||
|
Vector3f max = new Vector3f(
|
||||||
|
(float) primaryBox.maxX * 16,
|
||||||
|
(float) primaryBox.maxY * 16,
|
||||||
|
(float) primaryBox.maxZ * 16
|
||||||
|
);
|
||||||
|
|
||||||
|
if( busBounds == null )
|
||||||
|
{
|
||||||
|
// Adjust the facade for neighboring facades so that facade cubes dont overlap with each other
|
||||||
|
if( side == EnumFacing.NORTH || side == EnumFacing.SOUTH )
|
||||||
|
{
|
||||||
|
if( facades.containsKey( EnumFacing.UP ) )
|
||||||
|
{
|
||||||
|
max.y -= thickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( facades.containsKey( EnumFacing.DOWN ) )
|
||||||
|
{
|
||||||
|
min.y += thickness;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( side == EnumFacing.EAST || side == EnumFacing.WEST )
|
||||||
|
{
|
||||||
|
if( facades.containsKey( EnumFacing.UP ) )
|
||||||
|
{
|
||||||
|
max.y -= thickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( facades.containsKey( EnumFacing.DOWN ) )
|
||||||
|
{
|
||||||
|
min.y += thickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( facades.containsKey( EnumFacing.SOUTH ) )
|
||||||
|
{
|
||||||
|
max.z -= thickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( facades.containsKey( EnumFacing.NORTH ) )
|
||||||
|
{
|
||||||
|
min.z += thickness;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.addCube( min.x, min.y, min.z, max.x, max.y, max.z );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Vector3f busMin = new Vector3f( (float) busBounds.minX * 16, (float) busBounds.minY * 16, (float) busBounds.minZ * 16 );
|
||||||
|
Vector3f busMax = new Vector3f( (float) busBounds.maxX * 16, (float) busBounds.maxY * 16, (float) busBounds.maxZ * 16 );
|
||||||
|
|
||||||
|
if( side == EnumFacing.UP || side == EnumFacing.DOWN )
|
||||||
|
{
|
||||||
|
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, 0.0f, busMax.z, 16.0f, 16.0f, 16.0f );
|
||||||
|
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, 0.0f, 0.0f, 16.0f, 16.0f, busMin.z );
|
||||||
|
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, 0.0f, busMin.z, busMin.x, 16.0f, busMax.z );
|
||||||
|
this.renderSegmentBlockCurrentBounds( builder, min, max, busMax.x, 0.0f, busMin.z, 16.0f, 16.0f, busMax.z );
|
||||||
|
}
|
||||||
|
else if( side == EnumFacing.NORTH || side == EnumFacing.SOUTH )
|
||||||
|
{
|
||||||
|
if( facades.get( EnumFacing.UP ) != null )
|
||||||
|
{
|
||||||
|
max.y -= thickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( facades.get( EnumFacing.DOWN ) != null )
|
||||||
|
{
|
||||||
|
min.y += thickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.renderSegmentBlockCurrentBounds( builder, min, max, busMax.x, 0.0f, 0.0f, 16.0f, 16.0f, 16.0f );
|
||||||
|
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, 0.0f, 0.0f, busMin.x, 16.0f, 16.0f );
|
||||||
|
this.renderSegmentBlockCurrentBounds( builder, min, max, busMin.x, 0.0f, 0.0f, busMax.x, busMin.y, 16.0f );
|
||||||
|
this.renderSegmentBlockCurrentBounds( builder, min, max, busMin.x, busMax.y, 0.0f, busMax.x, 16.0f, 16.0f );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( facades.get( EnumFacing.UP ) != null )
|
||||||
|
{
|
||||||
|
max.y -= thickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( facades.get( EnumFacing.DOWN ) != null )
|
||||||
|
{
|
||||||
|
min.y += thickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( facades.get( EnumFacing.SOUTH ) != null )
|
||||||
|
{
|
||||||
|
max.z -= thickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( facades.get( EnumFacing.NORTH ) != null )
|
||||||
|
{
|
||||||
|
min.z += thickness;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, 0.0f, busMax.z, 16.0f, 16.0f, 16.0f );
|
||||||
|
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, 0.0f, 0.0f, 16.0f, 16.0f, busMin.z );
|
||||||
|
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, 0.0f, busMin.z, 16.0f, busMin.y, busMax.z );
|
||||||
|
this.renderSegmentBlockCurrentBounds( builder, min, max, 0.0f, busMax.y, busMin.z, 16.0f, 16.0f, busMax.z );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renderSegmentBlockCurrentBounds( CubeBuilder builder, Vector3f min, Vector3f max,
|
||||||
|
float minX, float minY, float minZ, float maxX, float maxY, float maxZ )
|
||||||
|
{
|
||||||
|
minX = Math.max( min.x, minX );
|
||||||
|
minY = Math.max( min.y, minY );
|
||||||
|
minZ = Math.max( min.z, minZ );
|
||||||
|
maxX = Math.min( max.x, maxX );
|
||||||
|
maxY = Math.min( max.y, maxY );
|
||||||
|
maxZ = Math.min( max.z, maxZ );
|
||||||
|
|
||||||
|
// don't draw it if its not at least a pixel wide...
|
||||||
|
if( maxX - minX >= 1.0 && maxY - minY >= 1.0 && maxZ - minZ >= 1.0 )
|
||||||
|
{
|
||||||
|
builder.addCube( minX, minY, minZ, maxX, maxY, maxZ );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given the actual facade bounding box, and the bounding boxes of all parts, determine the biggest union of AABB that intersect with the
|
||||||
|
* facade's bounding box. This AABB will need to be "cut out" when the facade is rendered.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private static AEAxisAlignedBB getCutOutBox( AxisAlignedBB facadeBox, List<AxisAlignedBB> partBoxes )
|
||||||
|
{
|
||||||
|
AEAxisAlignedBB b = null;
|
||||||
|
for( AxisAlignedBB bb : partBoxes )
|
||||||
|
{
|
||||||
|
if( bb.intersectsWith( facadeBox ) )
|
||||||
|
{
|
||||||
|
if( b == null )
|
||||||
|
{
|
||||||
|
b = AEAxisAlignedBB.fromBounds( bb );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
b.maxX = Math.max( b.maxX, bb.maxX );
|
||||||
|
b.maxY = Math.max( b.maxY, bb.maxY );
|
||||||
|
b.maxZ = Math.max( b.maxZ, bb.maxZ );
|
||||||
|
b.minX = Math.min( b.minX, bb.minX );
|
||||||
|
b.minY = Math.min( b.minY, bb.minY );
|
||||||
|
b.minZ = Math.min( b.minZ, bb.minZ );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if any of the part's bounding boxes intersects with the outside 2 voxel wide layer.
|
||||||
|
* If so, we should use thinner facades (1 voxel deep).
|
||||||
|
*/
|
||||||
|
private static boolean isUseThinFacades( List<AxisAlignedBB> partBoxes )
|
||||||
|
{
|
||||||
|
final double min = 2.0 / 16.0;
|
||||||
|
final double max = 14.0 / 16.0;
|
||||||
|
|
||||||
|
for( AxisAlignedBB bb : partBoxes )
|
||||||
|
{
|
||||||
|
int o = 0;
|
||||||
|
o += bb.maxX > max ? 1 : 0;
|
||||||
|
o += bb.maxY > max ? 1 : 0;
|
||||||
|
o += bb.maxZ > max ? 1 : 0;
|
||||||
|
o += bb.minX < min ? 1 : 0;
|
||||||
|
o += bb.minY < min ? 1 : 0;
|
||||||
|
o += bb.minZ < min ? 1 : 0;
|
||||||
|
|
||||||
|
if( o >= 2 )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AxisAlignedBB getFacadeBox( EnumFacing side, boolean thinFacades )
|
||||||
|
{
|
||||||
|
int thickness = thinFacades ? 1 : 2;
|
||||||
|
|
||||||
|
switch( side )
|
||||||
|
{
|
||||||
|
case DOWN:
|
||||||
|
return new AxisAlignedBB( 0.0, 0.0, 0.0, 1.0, ( thickness ) / 16.0, 1.0 );
|
||||||
|
case EAST:
|
||||||
|
return new AxisAlignedBB( ( 16.0 - thickness ) / 16.0, 0.0, 0.0, 1.0, 1.0, 1.0 );
|
||||||
|
case NORTH:
|
||||||
|
return new AxisAlignedBB( 0.0, 0.0, 0.0, 1.0, 1.0, ( thickness ) / 16.0 );
|
||||||
|
case SOUTH:
|
||||||
|
return new AxisAlignedBB( 0.0, 0.0, ( 16.0 - thickness ) / 16.0, 1.0, 1.0, 1.0 );
|
||||||
|
case UP:
|
||||||
|
return new AxisAlignedBB( 0.0, ( 16.0 - thickness ) / 16.0, 0.0, 1.0, 1.0, 1.0 );
|
||||||
|
case WEST:
|
||||||
|
return new AxisAlignedBB( 0.0, 0.0, 0.0, ( thickness ) / 16.0, 1.0, 1.0 );
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException( "Unsupported face: " + side );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package appeng.client.render.cablebus;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
|
import net.minecraft.util.EnumFacing;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Captures the state required to render a facade properly.
|
||||||
|
*/
|
||||||
|
public class FacadeRenderState
|
||||||
|
{
|
||||||
|
|
||||||
|
// The block state to use for rendering this facade
|
||||||
|
private final IBlockState sourceBlock;
|
||||||
|
|
||||||
|
// Which faces of the cube should be rendered for this particular facade
|
||||||
|
private final EnumSet<EnumFacing> openFaces;
|
||||||
|
|
||||||
|
public FacadeRenderState( IBlockState sourceBlock, EnumSet<EnumFacing> openFaces )
|
||||||
|
{
|
||||||
|
this.sourceBlock = sourceBlock;
|
||||||
|
this.openFaces = openFaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IBlockState getSourceBlock()
|
||||||
|
{
|
||||||
|
return sourceBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EnumSet<EnumFacing> getOpenFaces()
|
||||||
|
{
|
||||||
|
return openFaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -22,21 +22,18 @@ package appeng.facade;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemBlock;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
|
||||||
|
|
||||||
import appeng.api.AEApi;
|
import appeng.api.AEApi;
|
||||||
import appeng.api.parts.IBoxProvider;
|
import appeng.api.parts.IBoxProvider;
|
||||||
import appeng.api.parts.IFacadePart;
|
import appeng.api.parts.IFacadePart;
|
||||||
import appeng.api.parts.IPartCollisionHelper;
|
import appeng.api.parts.IPartCollisionHelper;
|
||||||
import appeng.api.util.AEPartLocation;
|
import appeng.api.util.AEPartLocation;
|
||||||
import appeng.integration.IntegrationRegistry;
|
|
||||||
import appeng.integration.IntegrationType;
|
|
||||||
import appeng.integration.abstraction.IBuildCraftTransport;
|
|
||||||
import appeng.util.Platform;
|
|
||||||
|
|
||||||
|
|
||||||
public class FacadePart implements IFacadePart, IBoxProvider
|
public class FacadePart implements IFacadePart, IBoxProvider
|
||||||
|
@ -44,7 +41,6 @@ public class FacadePart implements IFacadePart, IBoxProvider
|
||||||
|
|
||||||
private final ItemStack facade;
|
private final ItemStack facade;
|
||||||
private final AEPartLocation side;
|
private final AEPartLocation side;
|
||||||
private int thickness = 2;
|
|
||||||
|
|
||||||
public FacadePart( final ItemStack facade, final AEPartLocation side )
|
public FacadePart( final ItemStack facade, final AEPartLocation side )
|
||||||
{
|
{
|
||||||
|
@ -89,16 +85,10 @@ public class FacadePart implements IFacadePart, IBoxProvider
|
||||||
return this.side;
|
return this.side;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public AxisAlignedBB getPrimaryBox()
|
|
||||||
{
|
|
||||||
return Platform.getPrimaryBox( this.side, this.thickness );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Item getItem()
|
public Item getItem()
|
||||||
{
|
{
|
||||||
final ItemStack is = this.getTexture();
|
final ItemStack is = this.getTextureItem();
|
||||||
if( is == null )
|
if( is == null )
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
|
@ -109,7 +99,7 @@ public class FacadePart implements IFacadePart, IBoxProvider
|
||||||
@Override
|
@Override
|
||||||
public int getItemDamage()
|
public int getItemDamage()
|
||||||
{
|
{
|
||||||
final ItemStack is = this.getTexture();
|
final ItemStack is = this.getTextureItem();
|
||||||
if( is == null )
|
if( is == null )
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -123,12 +113,6 @@ public class FacadePart implements IFacadePart, IBoxProvider
|
||||||
return !( this.facade.getItem() instanceof IFacadeItem );
|
return !( this.facade.getItem() instanceof IFacadeItem );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setThinFacades( final boolean useThinFacades )
|
|
||||||
{
|
|
||||||
this.thickness = useThinFacades ? 1 : 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isTransparent()
|
public boolean isTransparent()
|
||||||
{
|
{
|
||||||
|
@ -137,14 +121,15 @@ public class FacadePart implements IFacadePart, IBoxProvider
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
final ItemStack is = this.getTexture();
|
final ItemStack is = this.getTextureItem();
|
||||||
final Block blk = Block.getBlockFromItem( is.getItem() );
|
final Block blk = Block.getBlockFromItem( is.getItem() );
|
||||||
|
|
||||||
return !blk.isOpaqueCube( blk.getDefaultState() );
|
return !blk.isOpaqueCube( blk.getDefaultState() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private ItemStack getTexture()
|
@Override
|
||||||
|
public ItemStack getTextureItem()
|
||||||
{
|
{
|
||||||
final Item maybeFacade = this.facade.getItem();
|
final Item maybeFacade = this.facade.getItem();
|
||||||
|
|
||||||
|
@ -155,16 +140,34 @@ public class FacadePart implements IFacadePart, IBoxProvider
|
||||||
|
|
||||||
return facade.getTextureItem( this.facade );
|
return facade.getTextureItem( this.facade );
|
||||||
}
|
}
|
||||||
else if( IntegrationRegistry.INSTANCE.isEnabled( IntegrationType.BuildCraftTransport ) )
|
|
||||||
{
|
|
||||||
final IBuildCraftTransport bc = (IBuildCraftTransport) IntegrationRegistry.INSTANCE.getInstance( IntegrationType.BuildCraftTransport );
|
|
||||||
|
|
||||||
return bc.getTextureForFacade( this.facade );
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IBlockState getBlockState()
|
||||||
|
{
|
||||||
|
ItemStack itemStack = getTextureItem();
|
||||||
|
|
||||||
|
if( !(itemStack.getItem() instanceof ItemBlock ) )
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemBlock itemBlock = (ItemBlock) itemStack.getItem();
|
||||||
|
|
||||||
|
// Try to get the block state based on the item stack's meta. If this fails, don't consider it for a facade
|
||||||
|
// This for example fails for Pistons because they hardcoded an invalid meta value in vanilla
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return itemBlock.getBlock().getStateFromMeta( itemStack.getItemDamage() );
|
||||||
|
}
|
||||||
|
catch( Exception e )
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getBoxes( final IPartCollisionHelper bch )
|
public void getBoxes( final IPartCollisionHelper bch )
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,11 +25,11 @@ import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
|
||||||
|
import net.minecraft.block.state.IBlockState;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityLivingBase;
|
import net.minecraft.entity.EntityLivingBase;
|
||||||
import net.minecraft.entity.player.EntityPlayer;
|
import net.minecraft.entity.player.EntityPlayer;
|
||||||
|
@ -42,6 +42,7 @@ import net.minecraft.util.EnumHand;
|
||||||
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.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.IBlockAccess;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import appeng.api.AEApi;
|
import appeng.api.AEApi;
|
||||||
|
@ -65,6 +66,7 @@ import appeng.api.util.AEPartLocation;
|
||||||
import appeng.api.util.DimensionalCoord;
|
import appeng.api.util.DimensionalCoord;
|
||||||
import appeng.client.render.cablebus.CableBusRenderState;
|
import appeng.client.render.cablebus.CableBusRenderState;
|
||||||
import appeng.client.render.cablebus.CableCoreType;
|
import appeng.client.render.cablebus.CableCoreType;
|
||||||
|
import appeng.client.render.cablebus.FacadeRenderState;
|
||||||
import appeng.core.AELog;
|
import appeng.core.AELog;
|
||||||
import appeng.facade.FacadeContainer;
|
import appeng.facade.FacadeContainer;
|
||||||
import appeng.helpers.AEMultiTile;
|
import appeng.helpers.AEMultiTile;
|
||||||
|
@ -1155,7 +1157,6 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
||||||
@Override
|
@Override
|
||||||
public CableBusRenderState getRenderState()
|
public CableBusRenderState getRenderState()
|
||||||
{
|
{
|
||||||
// TODO: Inspect whether this is a problem. PartCable is the only implementor of IPartCable, which is not part of the public API
|
|
||||||
PartCable cable = (PartCable) getCenter();
|
PartCable cable = (PartCable) getCenter();
|
||||||
|
|
||||||
CableBusRenderState renderState = new CableBusRenderState();
|
CableBusRenderState renderState = new CableBusRenderState();
|
||||||
|
@ -1210,8 +1211,16 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Determine attachments and facades
|
||||||
for( EnumFacing facing : EnumFacing.values() )
|
for( EnumFacing facing : EnumFacing.values() )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
FacadeRenderState facadeState = getFacadeRenderState( facing );
|
||||||
|
if ( facadeState != null )
|
||||||
|
{
|
||||||
|
renderState.getFacades().put( facing, facadeState );
|
||||||
|
}
|
||||||
|
|
||||||
IPart part = getPart( facing );
|
IPart part = getPart( facing );
|
||||||
|
|
||||||
if( part == null )
|
if( part == null )
|
||||||
|
@ -1219,6 +1228,11 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This will add the part's bounding boxes to the render state, which is required for facades
|
||||||
|
AEPartLocation loc = AEPartLocation.fromFacing( facing );
|
||||||
|
IPartCollisionHelper bch = new BusCollisionHelper( renderState.getBoundingBoxes(), loc, null, true );
|
||||||
|
part.getBoxes( bch );
|
||||||
|
|
||||||
if( part instanceof IGridHost )
|
if( part instanceof IGridHost )
|
||||||
{
|
{
|
||||||
// Some attachments want a thicker cable than glass, account for that
|
// Some attachments want a thicker cable than glass, account for that
|
||||||
|
@ -1242,4 +1256,89 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I
|
||||||
return renderState;
|
return renderState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private FacadeRenderState getFacadeRenderState( EnumFacing side ) {
|
||||||
|
// Store the "masqueraded" itemstack for the given side, if there is a facade
|
||||||
|
IFacadePart facade = getFacade( side.ordinal() );
|
||||||
|
if( facade != null )
|
||||||
|
{
|
||||||
|
|
||||||
|
IBlockState blockState = facade.getBlockState();
|
||||||
|
if( blockState != null )
|
||||||
|
{
|
||||||
|
EnumSet<EnumFacing> openFaces = calculateFaceOpenFaces( side );
|
||||||
|
return new FacadeRenderState( blockState, openFaces );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private EnumSet<EnumFacing> calculateFaceOpenFaces( EnumFacing side )
|
||||||
|
{
|
||||||
|
final EnumSet<EnumFacing> out = EnumSet.of( side, side.getOpposite() );
|
||||||
|
final IFacadePart facade = getFacade( side.ordinal() );
|
||||||
|
|
||||||
|
IBlockAccess blockAccess = getTile().getWorld();
|
||||||
|
BlockPos pos = getTile().getPos();
|
||||||
|
for( final EnumFacing it : EnumFacing.values() )
|
||||||
|
{
|
||||||
|
if( !out.contains( it ) && this.hasAlphaDiff( blockAccess.getTileEntity( pos.offset( it ) ), side, facade ) )
|
||||||
|
{
|
||||||
|
out.add( it );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( out.contains( EnumFacing.UP ) && ( side.getFrontOffsetX() != 0 || side.getFrontOffsetZ() != 0 ) )
|
||||||
|
{
|
||||||
|
final IFacadePart fp = getFacade( EnumFacing.UP.ordinal() );
|
||||||
|
if( fp != null && ( fp.isTransparent() == facade.isTransparent() ) )
|
||||||
|
{
|
||||||
|
out.remove( EnumFacing.UP );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( out.contains( EnumFacing.DOWN ) && ( side.getFrontOffsetX() != 0 || side.getFrontOffsetZ() != 0 ) )
|
||||||
|
{
|
||||||
|
final IFacadePart fp = getFacade( EnumFacing.DOWN.ordinal() );
|
||||||
|
if( fp != null && ( fp.isTransparent() == facade.isTransparent() ) )
|
||||||
|
{
|
||||||
|
out.remove( EnumFacing.DOWN );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( out.contains( EnumFacing.SOUTH ) && ( side.getFrontOffsetX() != 0 ) )
|
||||||
|
{
|
||||||
|
final IFacadePart fp = getFacade( EnumFacing.SOUTH.ordinal() );
|
||||||
|
if( fp != null && ( fp.isTransparent() == facade.isTransparent() ) )
|
||||||
|
{
|
||||||
|
out.remove( EnumFacing.SOUTH );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( out.contains( EnumFacing.NORTH ) && ( side.getFrontOffsetX() != 0 ) )
|
||||||
|
{
|
||||||
|
final IFacadePart fp = getFacade( EnumFacing.NORTH.ordinal() );
|
||||||
|
if( fp != null && ( fp.isTransparent() == facade.isTransparent() ) )
|
||||||
|
{
|
||||||
|
out.remove( EnumFacing.NORTH );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasAlphaDiff( final TileEntity tileEntity, final EnumFacing side, final IFacadePart facade )
|
||||||
|
{
|
||||||
|
if( tileEntity instanceof IPartHost )
|
||||||
|
{
|
||||||
|
final IPartHost ph = (IPartHost) tileEntity;
|
||||||
|
final IFacadePart fp = ph.getFacadeContainer().getFacade( AEPartLocation.fromFacing( side ) );
|
||||||
|
|
||||||
|
return fp == null || ( fp.isTransparent() != facade.isTransparent() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2155,28 +2155,6 @@ public class Platform
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AxisAlignedBB getPrimaryBox( final AEPartLocation side, final int facadeThickness )
|
|
||||||
{
|
|
||||||
switch( side )
|
|
||||||
{
|
|
||||||
case DOWN:
|
|
||||||
return new AxisAlignedBB( 0.0, 0.0, 0.0, 1.0, ( facadeThickness ) / 16.0, 1.0 );
|
|
||||||
case EAST:
|
|
||||||
return new AxisAlignedBB( ( 16.0 - facadeThickness ) / 16.0, 0.0, 0.0, 1.0, 1.0, 1.0 );
|
|
||||||
case NORTH:
|
|
||||||
return new AxisAlignedBB( 0.0, 0.0, 0.0, 1.0, 1.0, ( facadeThickness ) / 16.0 );
|
|
||||||
case SOUTH:
|
|
||||||
return new AxisAlignedBB( 0.0, 0.0, ( 16.0 - facadeThickness ) / 16.0, 1.0, 1.0, 1.0 );
|
|
||||||
case UP:
|
|
||||||
return new AxisAlignedBB( 0.0, ( 16.0 - facadeThickness ) / 16.0, 0.0, 1.0, 1.0, 1.0 );
|
|
||||||
case WEST:
|
|
||||||
return new AxisAlignedBB( 0.0, 0.0, 0.0, ( facadeThickness ) / 16.0, 1.0, 1.0 );
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return new AxisAlignedBB( 0, 0, 0, 1, 1, 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float getEyeOffset( final EntityPlayer player )
|
public static float getEyeOffset( final EntityPlayer player )
|
||||||
{
|
{
|
||||||
assert player.worldObj.isRemote : "Valid only on client";
|
assert player.worldObj.isRemote : "Valid only on client";
|
||||||
|
|
Loading…
Reference in a new issue