diff --git a/src/main/java/appeng/client/render/cablebus/CubeBuilder.java b/src/main/java/appeng/client/render/cablebus/CubeBuilder.java index 70b633ec..81dca1cc 100644 --- a/src/main/java/appeng/client/render/cablebus/CubeBuilder.java +++ b/src/main/java/appeng/client/render/cablebus/CubeBuilder.java @@ -23,7 +23,6 @@ import java.util.ArrayList; import java.util.EnumMap; import java.util.EnumSet; import java.util.List; - import javax.vecmath.Vector4f; import com.google.common.base.Preconditions; @@ -434,6 +433,11 @@ public class CubeBuilder setColor( color | 0xFF000000 ); } + public void setColorRGB( float r, float g, float b ) + { + setColorRGB( (int) ( r * 255 ) << 16 | (int) ( g * 255 ) << 8 | (int) ( b * 255 ) ); + } + public void setRenderFullBright( boolean renderFullBright ) { this.renderFullBright = renderFullBright; diff --git a/src/main/java/appeng/client/render/model/BiometricCardBakedModel.java b/src/main/java/appeng/client/render/model/BiometricCardBakedModel.java new file mode 100644 index 00000000..1c77135b --- /dev/null +++ b/src/main/java/appeng/client/render/model/BiometricCardBakedModel.java @@ -0,0 +1,220 @@ +package appeng.client.render.model; + + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ExecutionException; +import javax.annotation.Nullable; +import javax.vecmath.Matrix4f; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.mojang.authlib.GameProfile; + +import org.apache.commons.lang3.tuple.Pair; + +import net.minecraft.block.state.IBlockState; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.block.model.ItemOverrideList; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.item.ItemStack; +import net.minecraft.util.EnumFacing; +import net.minecraft.world.World; +import net.minecraftforge.client.model.IPerspectiveAwareModel; +import net.minecraftforge.common.model.TRSRTransformation; + +import appeng.api.implementations.items.IBiometricCard; +import appeng.api.util.AEColor; +import appeng.client.render.cablebus.CubeBuilder; +import appeng.core.AELog; + + +/** + * @author Sebastian + * @version rv3 - 10.10.2016 + * @since rv3 10.10.2016 + */ +public class BiometricCardBakedModel implements IPerspectiveAwareModel +{ + + private final VertexFormat format; + + private final IBakedModel baseModel; + + private final TextureAtlasSprite texture; + + private final int hash; + + private final ImmutableMap transforms; + + private final Cache modelCache; + + private final ImmutableList generalQuads; + + public BiometricCardBakedModel( VertexFormat format, IBakedModel baseModel, TextureAtlasSprite texture, ImmutableMap transforms ) + { + this( format, baseModel, texture, 0, transforms ); + } + + public BiometricCardBakedModel( VertexFormat format, IBakedModel baseModel, TextureAtlasSprite texture, int hash, ImmutableMap transforms ) + { + this.format = format; + this.baseModel = baseModel; + this.texture = texture; + this.hash = hash; + this.transforms = transforms; + this.generalQuads = ImmutableList.copyOf( buildGeneralQuads() ); + modelCache = CacheBuilder.newBuilder() + .maximumSize( 100 ) + .build(); + } + + @Override + public List getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand ) + { + + List quads = baseModel.getQuads( state, side, rand ); + + if( side != null ) + { + return quads; + } + + List result = new ArrayList<>( quads.size() + generalQuads.size() ); + result.addAll( quads ); + result.addAll( generalQuads ); + return result; + } + + private List buildGeneralQuads() + { + CubeBuilder builder = new CubeBuilder( this.format ); + + builder.setTexture( texture ); + + AEColor col = AEColor.values()[Math.abs( 3 + hash ) % AEColor.values().length]; + if( hash == 0 ) + { + col = AEColor.RED; + } + + for( int x = 0; x < 8; x++ ) + { + for( int y = 0; y < 6; y++ ) + { + final boolean isLit; + + // This makes the border always use the darker color + if( x == 0 || y == 0 || x == 7 || y == 5 ) + { + isLit = false; + } + else + { + isLit = ( hash & ( 1 << x ) ) != 0 || ( hash & ( 1 << y ) ) != 0; + } + + if( isLit ) + { + builder.setColorRGB( col.mediumVariant ); + } + else + { + final float scale = 0.3f / 255.0f; + builder.setColorRGB( ( ( col.blackVariant >> 16 ) & 0xff ) * scale, ( ( col.blackVariant >> 8 ) & 0xff ) * scale, ( col.blackVariant & 0xff ) * scale ); + } + + builder.addCube( 4 + x, 6 + y, 7.5f, 4 + x + 1, 6 + y + 1, 8.5f ); + } + } + return builder.getOutput(); + } + + @Override + public boolean isAmbientOcclusion() + { + return baseModel.isAmbientOcclusion(); + } + + @Override + public boolean isGui3d() + { + return baseModel.isGui3d(); + } + + @Override + public boolean isBuiltInRenderer() + { + return baseModel.isBuiltInRenderer(); + } + + @Override + public TextureAtlasSprite getParticleTexture() + { + return baseModel.getParticleTexture(); + } + + @Override + public ItemCameraTransforms getItemCameraTransforms() + { + return baseModel.getItemCameraTransforms(); + } + + @Override + public ItemOverrideList getOverrides() + { + return new ItemOverrideList( Collections.emptyList() ) + { + @Override + public IBakedModel handleItemState( IBakedModel originalModel, ItemStack stack, World world, EntityLivingBase entity ) + { + String username = ""; + if( stack.getItem() instanceof IBiometricCard ) + { + final GameProfile gp = ( (IBiometricCard) stack.getItem() ).getProfile( stack ); + if( gp != null ) + { + if( gp.getId() != null ) + { + username = gp.getId().toString(); + } + else + { + username = gp.getName(); + } + } + } + final int hash = !username.isEmpty() ? username.hashCode() : 0; + + // Get hash + if( hash == 0 ) + { + return BiometricCardBakedModel.this; + } + + try + { + return modelCache.get( hash, () -> new BiometricCardBakedModel( format, baseModel, texture, hash, transforms ) ); + } + catch( ExecutionException e ) + { + AELog.error( e ); + return BiometricCardBakedModel.this; + } + } + }; + } + + @Override + public Pair handlePerspective( ItemCameraTransforms.TransformType type ) + { + return IPerspectiveAwareModel.MapWrapper.handlePerspective( this, transforms, type ); + } +} diff --git a/src/main/java/appeng/client/render/model/BiometricCardModel.java b/src/main/java/appeng/client/render/model/BiometricCardModel.java new file mode 100644 index 00000000..120efa0b --- /dev/null +++ b/src/main/java/appeng/client/render/model/BiometricCardModel.java @@ -0,0 +1,75 @@ +package appeng.client.render.model; + + +import java.util.Collection; +import java.util.Collections; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableMap; + +import net.minecraft.client.renderer.block.model.IBakedModel; +import net.minecraft.client.renderer.block.model.ItemCameraTransforms; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.model.IModel; +import net.minecraftforge.client.model.IPerspectiveAwareModel; +import net.minecraftforge.client.model.ModelLoaderRegistry; +import net.minecraftforge.common.model.IModelState; +import net.minecraftforge.common.model.TRSRTransformation; + +import appeng.core.AppEng; + + +/** + * Model wrapper for the biometric card item model, which combines a base card layer with a "visual hash" of the player name + */ +public class BiometricCardModel implements IModel +{ + + private static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "item/biometric_card" ); + private static final ResourceLocation TEXTURE = new ResourceLocation( AppEng.MOD_ID, "items/biometric_card_hash" ); + + @Override + public Collection getDependencies() + { + return Collections.singletonList( MODEL_BASE ); + } + + @Override + public Collection getTextures() + { + return Collections.singletonList( TEXTURE ); + } + + @Override + public IBakedModel bake( IModelState state, VertexFormat format, Function bakedTextureGetter ) + { + TextureAtlasSprite texture = bakedTextureGetter.apply( TEXTURE ); + + IBakedModel baseModel = getBaseModel( state, format, bakedTextureGetter ); + + ImmutableMap map = IPerspectiveAwareModel.MapWrapper.getTransforms(state); + + return new BiometricCardBakedModel( format, baseModel, texture, map ); + } + + private IBakedModel getBaseModel( IModelState state, VertexFormat format, Function bakedTextureGetter ) + { + // Load the base model + try + { + return ModelLoaderRegistry.getModel( MODEL_BASE ).bake( state, format, bakedTextureGetter ); + } + catch( Exception e ) + { + throw new RuntimeException( e ); + } + } + + @Override + public IModelState getDefaultState() + { + return TRSRTransformation.identity(); + } +} diff --git a/src/main/java/appeng/core/api/definitions/ApiItems.java b/src/main/java/appeng/core/api/definitions/ApiItems.java index f95031b2..d8bb8676 100644 --- a/src/main/java/appeng/core/api/definitions/ApiItems.java +++ b/src/main/java/appeng/core/api/definitions/ApiItems.java @@ -44,6 +44,7 @@ import appeng.items.storage.ItemCreativeStorageCell; import appeng.items.storage.ItemSpatialStorageCell; import appeng.items.storage.ItemViewCell; import appeng.items.tools.ToolBiometricCard; +import appeng.items.tools.ToolBiometricCardRendering; import appeng.items.tools.ToolMemoryCard; import appeng.items.tools.ToolNetworkTool; import appeng.items.tools.powered.ToolChargedStaff; @@ -157,7 +158,9 @@ public final class ApiItems implements IItems .dispenserBehavior( DispenserBlockTool::new ) .build(); - this.biometricCard = registry.item( "biometric_card", ToolBiometricCard::new ).features( AEFeature.Security ).build(); + this.biometricCard = registry.item( "biometric_card", ToolBiometricCard::new ) + .rendering( new ToolBiometricCardRendering() ) + .features( AEFeature.Security ).build(); this.memoryCard = registry.item( "memory_card", ToolMemoryCard::new ).build(); this.networkTool = registry.item( "network_tool", ToolNetworkTool::new ).features( AEFeature.NetworkTool ).build(); diff --git a/src/main/java/appeng/items/tools/ToolBiometricCard.java b/src/main/java/appeng/items/tools/ToolBiometricCard.java index 7cabc602..52c4895b 100644 --- a/src/main/java/appeng/items/tools/ToolBiometricCard.java +++ b/src/main/java/appeng/items/tools/ToolBiometricCard.java @@ -48,12 +48,6 @@ public class ToolBiometricCard extends AEBaseItem implements IBiometricCard public ToolBiometricCard() { this.setMaxStackSize( 1 ); - - if( Platform.isClient() ) - { - // TODO - PORT ToolBiometricCardRender - // MinecraftForgeClient.registerItemRenderer( this, new ToolBiometricCardRender() ); - } } @Override diff --git a/src/main/java/appeng/items/tools/ToolBiometricCardRendering.java b/src/main/java/appeng/items/tools/ToolBiometricCardRendering.java new file mode 100644 index 00000000..b5214324 --- /dev/null +++ b/src/main/java/appeng/items/tools/ToolBiometricCardRendering.java @@ -0,0 +1,24 @@ +package appeng.items.tools; + + +import net.minecraft.client.renderer.block.model.ModelResourceLocation; +import net.minecraft.util.ResourceLocation; + +import appeng.bootstrap.IItemRendering; +import appeng.bootstrap.ItemRenderingCustomizer; +import appeng.client.render.model.BiometricCardModel; +import appeng.core.AppEng; + + +public class ToolBiometricCardRendering extends ItemRenderingCustomizer +{ + + public static final ResourceLocation MODEL = new ResourceLocation( AppEng.MOD_ID, "builtin/biometric_card" ); + + @Override + public void customize( IItemRendering rendering ) + { + rendering.builtInModel( "models/item/builtin/biometric_card", new BiometricCardModel() ); + rendering.model( new ModelResourceLocation( MODEL, "inventory" ) ).variants( MODEL ); + } +} diff --git a/src/main/resources/assets/appliedenergistics2/textures/items/biometric_card.png b/src/main/resources/assets/appliedenergistics2/textures/items/biometric_card.png index da67b5e8..42afaed3 100644 Binary files a/src/main/resources/assets/appliedenergistics2/textures/items/biometric_card.png and b/src/main/resources/assets/appliedenergistics2/textures/items/biometric_card.png differ diff --git a/src/main/resources/assets/appliedenergistics2/textures/items/biometric_card_hash.png b/src/main/resources/assets/appliedenergistics2/textures/items/biometric_card_hash.png new file mode 100644 index 00000000..26b4a34a Binary files /dev/null and b/src/main/resources/assets/appliedenergistics2/textures/items/biometric_card_hash.png differ