Skip to content

Commit

Permalink
Fixes anchor rendering (AppliedEnergistics#2698)
Browse files Browse the repository at this point in the history
* Fixes AppliedEnergistics#2680: Use a shorter cable anchor model when blocked by a facade.
* Fixes AppliedEnergistics#2664: Prevent anchors from creating intersection.

Replaced the simple List<ResourceLocation> for the static models with a
new container also indicating a solid part, which can be used to prevent
the creation of an intersection.
  • Loading branch information
yueh authored and phit committed Dec 19, 2016
1 parent f916228 commit fb42cb3
Show file tree
Hide file tree
Showing 74 changed files with 525 additions and 320 deletions.
29 changes: 19 additions & 10 deletions src/api/java/appeng/api/parts/IPart.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@


import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import javax.annotation.Nonnull;

import io.netty.buffer.ByteBuf;

import net.minecraft.entity.Entity;
Expand All @@ -39,7 +40,6 @@
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
Expand Down Expand Up @@ -71,7 +71,8 @@ public interface IPart extends IBoxProvider, ICustomCableConnection
ItemStack getItemStack( PartItemStack type );

/**
* Render dynamic portions of this part, as part of the cable bus TESR. This part has to return true for {@link #requireDynamicRender()} in order for
* Render dynamic portions of this part, as part of the cable bus TESR. This part has to return true for
* {@link #requireDynamicRender()} in order for
* this method to be called.
*/
@SideOnly( Side.CLIENT )
Expand Down Expand Up @@ -267,8 +268,10 @@ default void renderDynamic( double x, double y, double z, float partialTicks, in
boolean canBePlacedOn( BusSupport what );

/**
* This method is used when a chunk is rebuilt to determine how this part should be rendered. The returned models should represent the
* part oriented north. They will be automatically rotated to match the part's actual orientation. Tint indices 1-4 can be used in the
* This method is used when a chunk is rebuilt to determine how this part should be rendered. The returned models
* should represent the
* part oriented north. They will be automatically rotated to match the part's actual orientation. Tint indices 1-4
* can be used in the
* models to access the parts color.
*
* <dl>
Expand All @@ -279,18 +282,23 @@ default void renderDynamic( double x, double y, double z, float partialTicks, in
* <dt>Tint Index 3</dt>
* <dd>The {@link AEColor#whiteVariant bright variant color} of the cable that this part is attached to.</dd>
* <dt>Tint Index 4</dt>
* <dd>A color variant that is between the cable's {@link AEColor#mediumVariant color} and its {@link AEColor#whiteVariant bright variant}.</dd>
* <dd>A color variant that is between the cable's {@link AEColor#mediumVariant color} and its
* {@link AEColor#whiteVariant bright variant}.</dd>
* </dl>
*
* <b>Important:</b> All models must have been registered via the {@link IPartModels} API before use.
*/
default List<ResourceLocation> getStaticModels()
@Nonnull
default IPartModel getStaticModels()
{
return Collections.emptyList();
return new IPartModel()
{
};
}

/**
* Implement this method if your part exposes capabilitys. Any requests for capabilities on the cable bus will be forwarded to parts on the appropriate
* Implement this method if your part exposes capabilitys. Any requests for capabilities on the cable bus will be
* forwarded to parts on the appropriate
* side.
*
* @see TileEntity#hasCapability(Capability, EnumFacing)
Expand All @@ -303,7 +311,8 @@ default boolean hasCapability( Capability<?> capabilityClass )
}

/**
* Implement this method if your part exposes capabilitys. Any requests for capabilities on the cable bus will be forwarded to parts on the appropriate
* Implement this method if your part exposes capabilitys. Any requests for capabilities on the cable bus will be
* forwarded to parts on the appropriate
* side.
*
* @see TileEntity#getCapability(Capability, EnumFacing)
Expand Down
65 changes: 65 additions & 0 deletions src/api/java/appeng/api/parts/IPartModel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2013 - 2015 AlgorithmX2
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

package appeng.api.parts;


import java.util.Collections;
import java.util.List;

import javax.annotation.Nonnull;

import net.minecraft.util.ResourceLocation;


/**
* A container to store a collection of {@link ResourceLocation} as models for a part as well as other properties.
*/
public interface IPartModel
{

/**
* A solid {@link IPartModel} indicates that the rendering requires a cable connection, which will also result in
* creating an intersection for the cable.
*
* This should be true for pretty much all parts.
*
* @return true for a solid part.
*/
default boolean requireCableConnection()
{
return true;
}

/**
* A collection of {@link ResourceLocation} used as models for a part.
*
* @return a collection of models, never null.
*/
@Nonnull
default List<ResourceLocation> getModels()
{
return Collections.emptyList();
}

}
2 changes: 0 additions & 2 deletions src/main/java/appeng/block/AEBaseBlock.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,8 @@
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
Expand Down
1 change: 1 addition & 0 deletions src/main/java/appeng/block/misc/BlockCharger.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Random;

import javax.annotation.Nullable;

import org.apache.commons.lang3.tuple.ImmutablePair;
Expand Down
1 change: 1 addition & 0 deletions src/main/java/appeng/block/networking/BlockCableBus.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.EnumSet;
import java.util.List;
import java.util.Random;

import javax.annotation.Nullable;

import net.minecraft.block.Block;
Expand Down
1 change: 1 addition & 0 deletions src/main/java/appeng/block/networking/BlockWireless.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import java.util.Collections;
import java.util.List;

import javax.annotation.Nullable;

import net.minecraft.block.properties.IProperty;
Expand Down
1 change: 1 addition & 0 deletions src/main/java/appeng/block/paint/PaintBakedModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.annotation.Nullable;

import com.google.common.base.Function;
Expand Down
1 change: 1 addition & 0 deletions src/main/java/appeng/block/qnb/QnbFormedBakedModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.util.EnumSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Nullable;

import com.google.common.base.Function;
Expand Down
1 change: 1 addition & 0 deletions src/main/java/appeng/bootstrap/BlockDefinitionBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;

import javax.annotation.Nullable;

import net.minecraft.block.Block;
Expand Down
1 change: 0 additions & 1 deletion src/main/java/appeng/client/gui/AEBaseGui.java
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@
import net.minecraft.item.ItemStack;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.fml.common.ObfuscationReflectionHelper;

import appeng.api.storage.data.IAEItemStack;
import appeng.client.gui.widgets.GuiScrollbar;
Expand Down
1 change: 1 addition & 0 deletions src/main/java/appeng/client/me/ItemRepo.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.ArrayList;
import java.util.Collections;
import java.util.regex.Pattern;

import javax.annotation.Nonnull;

import net.minecraft.item.ItemStack;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import java.util.Collections;
import java.util.List;

import javax.annotation.Nullable;

import net.minecraft.block.state.IBlockState;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;

import javax.annotation.Nullable;

import net.minecraft.block.state.IBlockState;
Expand Down
57 changes: 34 additions & 23 deletions src/main/java/appeng/client/render/cablebus/CableBusBakedModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Nullable;

import net.minecraft.block.state.IBlockState;
Expand All @@ -41,6 +43,7 @@
import net.minecraftforge.client.MinecraftForgeClient;
import net.minecraftforge.common.property.IExtendedBlockState;

import appeng.api.parts.IPartModel;
import appeng.api.util.AECableType;
import appeng.api.util.AEColor;
import appeng.block.networking.BlockCableBus;
Expand Down Expand Up @@ -81,22 +84,23 @@ public List<BakedQuad> getQuads( @Nullable IBlockState state, @Nullable EnumFaci

List<BakedQuad> quads = new ArrayList<>();

// The core parts of the cable will only be rendered in the CUTOUT layer. TRANSLUCENT is used only for translucent facades further down below.
if ( layer == BlockRenderLayer.CUTOUT )
// The core parts of the cable will only be rendered in the CUTOUT layer. TRANSLUCENT is used only for
// translucent facades further down below.
if( layer == BlockRenderLayer.CUTOUT )
{
// First, handle the cable at the center of the cable bus
addCableQuads( renderState, quads );

// Then handle attachments
for( EnumFacing facing : EnumFacing.values() )
{
List<ResourceLocation> models = renderState.getAttachments().get( facing );
if( models == null )
final IPartModel partModel = renderState.getAttachments().get( facing );
if( partModel == null )
{
continue;
}

for( ResourceLocation model : models )
for( ResourceLocation model : partModel.getModels() )
{
IBakedModel bakedModel = partModels.get( model );

Expand All @@ -122,34 +126,38 @@ public List<BakedQuad> getQuads( @Nullable IBlockState state, @Nullable EnumFaci
renderState.getBoundingBoxes(),
renderState.getAttachments().keySet(),
rand,
quads
);
quads );

return quads;
}

// Determines whether a cable is connected to exactly two sides that are opposite each other
private static boolean isStraightLine( AECableType cableType, EnumMap<EnumFacing, AECableType> sides )
{
Iterator<EnumFacing> it = sides.keySet().iterator();
final Iterator<Entry<EnumFacing, AECableType>> it = sides.entrySet().iterator();
if( !it.hasNext() )
{
return false; // No connections
}
EnumFacing firstSide = it.next();
AECableType firstType = sides.get( firstSide );

final Entry<EnumFacing, AECableType> nextConnection = it.next();
final EnumFacing firstSide = nextConnection.getKey();
final AECableType firstType = nextConnection.getValue();

if( !it.hasNext() )
{
return false; // Only a single connection
}
if( firstSide.getOpposite() != it.next() )
if( firstSide.getOpposite() != it.next().getKey() )
{
return false; // Connected to two sides that are not opposite each other
}
if (it.hasNext()) {
if( it.hasNext() )
{
return false; // Must not have any other connection points
}
AECableType secondType = sides.get( firstSide.getOpposite() );

final AECableType secondType = sides.get( firstSide.getOpposite() );

// Certain cable types have restrictions on when they're rendered as a straight connection
switch( cableType )
Expand All @@ -176,8 +184,8 @@ private void addCableQuads( CableBusRenderState renderState, List<BakedQuad> qua

// If the connection is straight, no busses are attached, and no covered core has been forced (in case of glass
// cables), then render the cable as a simplified straight line.
boolean noAttachments = renderState.getAttachments().isEmpty();
if( isStraightLine( cableType, connectionTypes ) && noAttachments )
boolean noAttachments = !renderState.getAttachments().values().stream().anyMatch( IPartModel::requireCableConnection );
if( noAttachments && isStraightLine( cableType, connectionTypes ) )
{
EnumFacing facing = connectionTypes.keySet().iterator().next();

Expand Down Expand Up @@ -227,11 +235,12 @@ private void addCableQuads( CableBusRenderState renderState, List<BakedQuad> qua
}

// Render all outgoing connections using the appropriate type
for( EnumFacing facing : connectionTypes.keySet() )
for( final Entry<EnumFacing, AECableType> connection : connectionTypes.entrySet() )
{
AECableType connectionType = connectionTypes.get( facing );
boolean cableBusAdjacent = renderState.getCableBusAdjacent().contains( facing );
int channels = renderState.getChannelsOnSide().get( facing );
final EnumFacing facing = connection.getKey();
final AECableType connectionType = connection.getValue();
final boolean cableBusAdjacent = renderState.getCableBusAdjacent().contains( facing );
final int channels = renderState.getChannelsOnSide().get( facing );

switch( cableType )
{
Expand Down Expand Up @@ -269,9 +278,9 @@ public List<TextureAtlasSprite> getParticleTextures( CableBusRenderState renderS
// If no core is present, just use the first part that comes into play
for( EnumFacing side : renderState.getAttachments().keySet() )
{
List<ResourceLocation> models = renderState.getAttachments().get( side );
IPartModel partModel = renderState.getAttachments().get( side );

for( ResourceLocation model : models )
for( ResourceLocation model : partModel.getModels() )
{
IBakedModel bakedModel = partModels.get( model );

Expand All @@ -282,9 +291,11 @@ public List<TextureAtlasSprite> getParticleTextures( CableBusRenderState renderS

TextureAtlasSprite particleTexture = bakedModel.getParticleTexture();

// If a part sub-model has no particle texture (indicated by it being the missing texture), don't add it,
// If a part sub-model has no particle texture (indicated by it being the missing texture), don't
// add
// it,
// so we don't get ugly missing texture break particles.
if ( textureMap.getMissingSprite() != particleTexture )
if( textureMap.getMissingSprite() != particleTexture )
{
result.add( particleTexture );
}
Expand Down
Loading

0 comments on commit fb42cb3

Please sign in to comment.