Posted May 11, 201510 yr Hi, I have implemented ISmartModel as instructed in TheGreyGhost's MBE04 tutorial. Things are working fine. In handleBlockState() I am looking up a model from an IBlockState I get from an unlisted property of the incoming IExtendedBlockState. Before returning the model, can I manipulate it? I am attempting to find a way to modify the color of it's texture (I posted a couple of days ago on this). There is a method returning the model's texture (of class TextureAtlasSprite), and a method to get the texture's texture data which is also setable. My printlns seem to indicate the texture data is changed, but I am not seeing any difference to the texture in game. Here is my implentation of ISmartModel: package ds.plato.block; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.ItemCameraTransforms; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.IBakedModel; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.util.EnumFacing; import net.minecraftforge.client.model.IFlexibleBakedModel; import net.minecraftforge.client.model.ISmartBlockModel; import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; public class BlockSelectedModel implements ISmartBlockModel { public static ModelResourceLocation modelResourceLocation = new ModelResourceLocation("plato:blockSelected"); private IBakedModel defaultModel; private IUnlistedProperty prevBlockProperty; public BlockSelectedModel(IBakedModel defaultModel, PropertyPreviousBlock prevBlockProperty) { super(); this.defaultModel = defaultModel; this.prevBlockProperty = prevBlockProperty; } @Override public IBakedModel handleBlockState(IBlockState state) { assert IExtendedBlockState.class.isAssignableFrom(state.getClass()); IBlockState s = ((IExtendedBlockState) state).getValue(prevBlockProperty); IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes() .getModelForState(s); IFlexibleBakedModel m = (IFlexibleBakedModel)model; TextureAtlasSprite t = m.getTexture(); int[][] td = t.getFrameTextureData(0); System.out.println(Arrays.deepToString(td)); td = modifyTextureData(td); List l = new ArrayList(); l.add(td); t.setFramesTextureData(l); t = m.getTexture(); td = t.getFrameTextureData(0); System.out.println(Arrays.deepToString(td)); return m; } @Override public List getFaceQuads(EnumFacing p_177551_1_) { // TODO Auto-generated method stub return null; } @Override public List getGeneralQuads() { // TODO Auto-generated method stub return null; } @Override public boolean isAmbientOcclusion() { // TODO Auto-generated method stub return false; } @Override public boolean isGui3d() { // TODO Auto-generated method stub return false; } @Override public boolean isBuiltInRenderer() { // TODO Auto-generated method stub return false; } @Override public TextureAtlasSprite getTexture() { return defaultModel.getTexture(); } @Override public ItemCameraTransforms getItemCameraTransforms() { // TODO Auto-generated method stub return null; } // Private------------------------------------------------------------- private int[][] modifyTextureData(int[][] data) { for (int i = 0; i < data.length; i++) { for (int j = 0; j < data[i].length; j++) { data[i][j] = 0; } } return data; } } For testing purposes I am just setting the texture data to 0. Seems I can cast the IBakedModel to an IFlexibleBakedModel, for whatever that's worth.
May 11, 201510 yr Hi the getTexture method is not generally used for rendering the block - it is used (for example) for the 'exploding shards' that you get when you destroy a block by digging it. In order to change the texture, you will need to change the BakedQuad data (each BakedQuad in your BlockModel is made up of four corners (vertices) - and at each vertex, it records the [x,y,z] position as well as a texture coordinate [u,v]. All of the textures for blocks and item models are "stitched together" into a large texture sheet, see the "Texture Coordinates" diagram on this page halfway down http://greyminecraftcoder.blogspot.co.at/2014/12/the-tessellator-and-worldrenderer-18.html You will need to create your BakedQuads with the correct texture coordinates of the new texture An example of how you can do this is in MBE15, this class works for the faces of the cube https://github.com/TheGreyGhost/MinecraftByExample/blob/master/src/main/java/minecraftbyexample/mbe15_item_smartitemmodel/ChessboardSmartItemModel.java see createBakedQuadForFace(). FaceBakery.makeBakedQuad() can be useful for generating quads If you want to change a model with arbitrary quads (not just the NEWSUD faces of the cube) then you can probably read the quads from the base model one by one, convert the int arrays to vertex data, replace the [u,v] with the new [u,v], and create a new list of BakedQuads from it. Haven't tried it, but it should work. -TGG
May 11, 201510 yr Author Thanks TGG for the response. I think the last, more generic, method you proposed is the way I need to go. Just a few questions to begin. Here is a start for new handleBlockState(): @Override public IBakedModel handleBlockState(IBlockState state) { assert IExtendedBlockState.class.isAssignableFrom(state.getClass()); IBlockState s = ((IExtendedBlockState) state).getValue(prevBlockProperty); IBakedModel model = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes() .getModelForState(s); IFlexibleBakedModel m = (IFlexibleBakedModel) model; VertexFormat format = m.getFormat(); System.out.println("format=" + format); List<BakedQuad> generalQuads = m.getGeneralQuads(); System.out.println(Arrays.toString(generalQuads.toArray())); for (BakedQuad q : generalQuads) { int[] vd = q.getVertexData(); System.out.println(Arrays.toString(vd)); } for (EnumFacing face : EnumFacing.values()) { List<BakedQuad> faceQuads = m.getFaceQuads(face); for (BakedQuad q : faceQuads) { int[] vd = q.getVertexData(); System.out.println(Arrays.toString(vd)); } } return m; } When I run and select a vanila block sand, it appears to have no generalQuad data(the list of BakedQuads is empty), only faceQuad data. Can I assume that any model which has more than 6 standard sides will implement getGeneralQuads()? Here is the output of vertex data from the faceQuads: [19:27:02] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:55]: [0, 0, 1065353216, -8421505, 1058537800, 1046480159, 0, 0, 0, 0, -8421505, 1058537800, 1048574689, 0, 1065353216, 0, 0, -8421505, 1059061432, 1048574689, 0, 1065353216, 0, 1065353216, -8421505, 1059061432, 1046480159, 0] [19:27:02] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:55]: [0, 1065353216, 0, -1, 1058537800, 1046480159, 0, 0, 1065353216, 1065353216, -1, 1058537800, 1048574689, 0, 1065353216, 1065353216, 1065353216, -1, 1059061432, 1048574689, 0, 1065353216, 1065353216, 0, -1, 1059061432, 1046480159, 0] [19:27:02] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:55]: [1065353216, 1065353216, 0, -3355444, 1058537800, 1046480159, 0, 1065353216, 0, 0, -3355444, 1058537800, 1048574689, 0, 0, 0, 0, -3355444, 1059061432, 1048574689, 0, 0, 1065353216, 0, -3355444, 1059061432, 1046480159, 0] [19:27:02] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:55]: [0, 1065353216, 1065353216, -3355444, 1058537800, 1046480159, 0, 0, 0, 1065353216, -3355444, 1058537800, 1048574689, 0, 1065353216, 0, 1065353216, -3355444, 1059061432, 1048574689, 0, 1065353216, 1065353216, 1065353216, -3355444, 1059061432, 1046480159, 0] [19:27:02] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:55]: [0, 1065353216, 0, -6710887, 1058537800, 1046480159, 0, 0, 0, 0, -6710887, 1058537800, 1048574689, 0, 0, 0, 1065353216, -6710887, 1059061432, 1048574689, 0, 0, 1065353216, 1065353216, -6710887, 1059061432, 1046480159, 0] [19:27:02] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:55]: [1065353216, 1065353216, 1065353216, -6710887, 1058537800, 1046480159, 0, 1065353216, 0, 1065353216, -6710887, 1058537800, 1048574689, 0, 1065353216, 0, 0, -6710887, 1059061432, 1048574689, 0, 1065353216, 1065353216, 0, -6710887, 1059061432, 1046480159, 0] Do I use the format from VertexFormat format = m.getFormat() to interpret these arrays of ints? Also, there is no setQuads() method on IFlexibleBakedModel. Is this going to be a problem?
May 12, 201510 yr Thanks TGG for the response. You're welcome When I run and select a vanila block sand, it appears to have no generalQuad data(the list of BakedQuads is empty), only faceQuad data. Can I assume that any model which has more than 6 standard sides will implement getGeneralQuads()? Yes. But in general a model may have any mixture of faceQuads and GeneralQuads - it may have all faceQuads, all generalQuads, or a mixture of both. faceQuads is mostly useful for blocks which don't draw some of their faces when they are next to each other. For example stone. Two stone blocks next to each other don't need to draw the two faces where they are touching. General quads are usually for odd-shaped faces such as the torch, or the ladder. Here is the output of vertex data from the faceQuads: [19:27:02] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:55]: [0, 0, 1065353216, -8421505, 1058537800, 1046480159, 0, 0, 0, 0, -8421505, 1058537800, 1048574689, 0, 1065353216, 0, 0, -8421505, 1059061432, 1048574689, 0, 1065353216, 0, 1065353216, -8421505, 1059061432, 1046480159, 0] [19:27:02] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:55]: [0, 1065353216, 0, -1, 1058537800, 1046480159, 0, 0, 1065353216, 1065353216, -1, 1058537800, 1048574689, 0, 1065353216, 1065353216, 1065353216, -1, 1059061432, 1048574689, 0, 1065353216, 1065353216, 0, -1, 1059061432, 1046480159, 0] [19:27:02] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:55]: [1065353216, 1065353216, 0, -3355444, 1058537800, 1046480159, 0, 1065353216, 0, 0, -3355444, 1058537800, 1048574689, 0, 0, 0, 0, -3355444, 1059061432, 1048574689, 0, 0, 1065353216, 0, -3355444, 1059061432, 1046480159, 0] [19:27:02] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:55]: [0, 1065353216, 1065353216, -3355444, 1058537800, 1046480159, 0, 0, 0, 1065353216, -3355444, 1058537800, 1048574689, 0, 1065353216, 0, 1065353216, -3355444, 1059061432, 1048574689, 0, 1065353216, 1065353216, 1065353216, -3355444, 1059061432, 1046480159, 0] [19:27:02] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:55]: [0, 1065353216, 0, -6710887, 1058537800, 1046480159, 0, 0, 0, 0, -6710887, 1058537800, 1048574689, 0, 0, 0, 1065353216, -6710887, 1059061432, 1048574689, 0, 0, 1065353216, 1065353216, -6710887, 1059061432, 1046480159, 0] [19:27:02] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:55]: [1065353216, 1065353216, 1065353216, -6710887, 1058537800, 1046480159, 0, 1065353216, 0, 1065353216, -6710887, 1058537800, 1048574689, 0, 1065353216, 0, 0, -6710887, 1059061432, 1048574689, 0, 1065353216, 1065353216, 0, -6710887, 1059061432, 1046480159, 0] Do I use the format from VertexFormat format = m.getFormat() to interpret these arrays of ints? Yes - you need to find the offset corresponding to VertexFormatElement.EnumUsage UV. If it's the standard format, vertexToInts() in this class https://github.com/TheGreyGhost/MinecraftByExample/blob/master/src/main/java/minecraftbyexample/mbe15_item_smartitemmodel/ChessboardSmartItemModel.java gives you the info you need - also shows you how to go from float to int, you just need to find the function to go back the other way from rawInts to float If you want to code for any generic VertextFormat, I think you should be able to iterate through its elements, find the one for UV, and get its offset. Also, there is no setQuads() method on IFlexibleBakedModel. Is this going to be a problem? No problem. Just create your own class extending IFlexibleBakedmodel and store your modified BakedQuads in it, then return it from handleBlockState. When your IFlexibleBakedModel instance is called i.e.getGeneralQuads or getFaceQuads, return your modified BakedQuads. -TGG
May 12, 201510 yr Author I have answered the last part of my question. Instead of returning the model looked up in handleBlockState() I return this (which is an IBakedModel). This gives me the oportunity to modify or rebuild the BakedQuads list returned from getFaceQuads() and getGeneralQuads(): package ds.plato.block; import java.util.Arrays; import java.util.List; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.block.model.BakedQuad; 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.client.resources.model.IBakedModel; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.util.EnumFacing; import net.minecraftforge.client.model.IFlexibleBakedModel; import net.minecraftforge.client.model.ISmartBlockModel; import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; public class BlockSelectedModel implements ISmartBlockModel { public static ModelResourceLocation modelResourceLocation = new ModelResourceLocation("plato:blockSelected"); private IBakedModel defaultModel; private IFlexibleBakedModel model; private IUnlistedProperty selectedBlockProperty; public BlockSelectedModel(IBakedModel defaultModel, PropertySelectedBlock selectedBlockProperty) { this.defaultModel = defaultModel; this.selectedBlockProperty = selectedBlockProperty; } @Override public IBakedModel handleBlockState(IBlockState state) { assert IExtendedBlockState.class.isAssignableFrom(state.getClass()); IBlockState s = ((IExtendedBlockState) state).getValue(selectedBlockProperty); System.out.println("Selected block="+s); IBakedModel m = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes().getModelForState(s); model = (IFlexibleBakedModel) m; return this; } @Override public List getFaceQuads(EnumFacing face) { List<BakedQuad> faceQuads = model.getFaceQuads(face); for (BakedQuad q : faceQuads) { int[] vd = q.getVertexData(); System.out.println(Arrays.toString(vd)); } //Modify list here return faceQuads; } @Override public List getGeneralQuads() { List<BakedQuad> generalQuads = model.getGeneralQuads(); System.out.println(Arrays.toString(generalQuads.toArray())); for (BakedQuad q : generalQuads) { int[] vd = q.getVertexData(); System.out.println(Arrays.toString(vd)); } //Modify list here return generalQuads; } @Override public boolean isAmbientOcclusion() { return model.isAmbientOcclusion(); } @Override public boolean isGui3d() { return model.isGui3d(); } @Override public boolean isBuiltInRenderer() { return model.isBuiltInRenderer(); } @Override public TextureAtlasSprite getTexture() { // return defaultModel.getTexture(); return model.getTexture(); } @Override public ItemCameraTransforms getItemCameraTransforms() { return model.getItemCameraTransforms(); } } This runs fine. My questions are: Why does BakedQuad.getVertexData() return ints, and what do they mean? The vertex data seems to be the same for every model looked up in handleBlockState(): [10:21:59] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:35]: Selected block=minecraft:sand[variant=sand] [10:21:59] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [0, 0, 1065353216, -8421505, 1058537800, 1046480159, 0, 0, 0, 0, -8421505, 1058537800, 1048574689, 0, 1065353216, 0, 0, -8421505, 1059061432, 1048574689, 0, 1065353216, 0, 1065353216, -8421505, 1059061432, 1046480159, 0] [10:21:59] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [0, 1065353216, 0, -1, 1058537800, 1046480159, 0, 0, 1065353216, 1065353216, -1, 1058537800, 1048574689, 0, 1065353216, 1065353216, 1065353216, -1, 1059061432, 1048574689, 0, 1065353216, 1065353216, 0, -1, 1059061432, 1046480159, 0] [10:21:59] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [1065353216, 1065353216, 0, -3355444, 1058537800, 1046480159, 0, 1065353216, 0, 0, -3355444, 1058537800, 1048574689, 0, 0, 0, 0, -3355444, 1059061432, 1048574689, 0, 0, 1065353216, 0, -3355444, 1059061432, 1046480159, 0] [10:21:59] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [0, 1065353216, 1065353216, -3355444, 1058537800, 1046480159, 0, 0, 0, 1065353216, -3355444, 1058537800, 1048574689, 0, 1065353216, 0, 1065353216, -3355444, 1059061432, 1048574689, 0, 1065353216, 1065353216, 1065353216, -3355444, 1059061432, 1046480159, 0] [10:21:59] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [0, 1065353216, 0, -6710887, 1058537800, 1046480159, 0, 0, 0, 0, -6710887, 1058537800, 1048574689, 0, 0, 0, 1065353216, -6710887, 1059061432, 1048574689, 0, 0, 1065353216, 1065353216, -6710887, 1059061432, 1046480159, 0] [10:21:59] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [1065353216, 1065353216, 1065353216, -6710887, 1058537800, 1046480159, 0, 1065353216, 0, 1065353216, -6710887, 1058537800, 1048574689, 0, 1065353216, 0, 0, -6710887, 1059061432, 1048574689, 0, 1065353216, 1065353216, 0, -6710887, 1059061432, 1046480159, 0] [10:21:59] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getGeneralQuads:55]: [] {ds.plato.block.PropertySelectedBlock@15af3a9b=Optional.of(minecraft:dirt[snowy=false,variant=dirt])} [10:22:06] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:handleBlockState:35]: Selected block=minecraft:dirt[snowy=false,variant=dirt] [10:22:06] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [0, 0, 1065353216, -8421505, 1048576655, 1044383007, 0, 0, 0, 0, -8421505, 1048576655, 1046477537, 0, 1065353216, 0, 0, -8421505, 1049623921, 1046477537, 0, 1065353216, 0, 1065353216, -8421505, 1049623921, 1044383007, 0] [10:22:06] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [0, 1065353216, 0, -1, 1048576655, 1044383007, 0, 0, 1065353216, 1065353216, -1, 1048576655, 1046477537, 0, 1065353216, 1065353216, 1065353216, -1, 1049623921, 1046477537, 0, 1065353216, 1065353216, 0, -1, 1049623921, 1044383007, 0] [10:22:06] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [1065353216, 1065353216, 0, -3355444, 1048576655, 1044383007, 0, 1065353216, 0, 0, -3355444, 1048576655, 1046477537, 0, 0, 0, 0, -3355444, 1049623921, 1046477537, 0, 0, 1065353216, 0, -3355444, 1049623921, 1044383007, 0] [10:22:06] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [0, 1065353216, 1065353216, -3355444, 1048576655, 1044383007, 0, 0, 0, 1065353216, -3355444, 1048576655, 1046477537, 0, 1065353216, 0, 1065353216, -3355444, 1049623921, 1046477537, 0, 1065353216, 1065353216, 1065353216, -3355444, 1049623921, 1044383007, 0] [10:22:06] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [0, 1065353216, 0, -6710887, 1048576655, 1044383007, 0, 0, 0, 0, -6710887, 1048576655, 1046477537, 0, 0, 0, 1065353216, -6710887, 1049623921, 1046477537, 0, 0, 1065353216, 1065353216, -6710887, 1049623921, 1044383007, 0] [10:22:06] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getFaceQuads:46]: [1065353216, 1065353216, 1065353216, -6710887, 1048576655, 1044383007, 0, 1065353216, 0, 1065353216, -6710887, 1048576655, 1046477537, 0, 1065353216, 0, 0, -6710887, 1049623921, 1046477537, 0, 1065353216, 1065353216, 0, -6710887, 1049623921, 1044383007, 0] [10:22:06] [Client thread/INFO] [sTDOUT]: [ds.plato.block.BlockSelectedModel:getGeneralQuads:55]: []
May 12, 201510 yr Author Ok, after looking closely at your excelent example, I've come up with this really simple solution which works ...almost. package ds.plato.block; import java.awt.Color; import java.util.List; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.ItemCameraTransforms; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.IBakedModel; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.util.EnumFacing; import net.minecraftforge.client.model.ISmartBlockModel; import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; public class BlockSelectedModel implements ISmartBlockModel { public static ModelResourceLocation modelResourceLocation = new ModelResourceLocation("plato:blockSelected"); private IBakedModel defaultModel, model; private IUnlistedProperty selectedBlockProperty; private final int tint = Color.RED.getRed(); public BlockSelectedModel(IBakedModel defaultModel, PropertySelectedBlock selectedBlockProperty) { this.defaultModel = defaultModel; this.selectedBlockProperty = selectedBlockProperty; } @Override public IBakedModel handleBlockState(IBlockState state) { assert IExtendedBlockState.class.isAssignableFrom(state.getClass()); IBlockState s = ((IExtendedBlockState) state).getValue(selectedBlockProperty); model = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes().getModelForState(s); return this; } @Override public List getFaceQuads(EnumFacing face) { List<BakedQuad> faceQuads = model.getFaceQuads(face); for (BakedQuad q : faceQuads) { q = new BakedQuad(tint(q.getVertexData()), 0, face); } return faceQuads; } @Override public List getGeneralQuads() { List<BakedQuad> generalQuads = model.getGeneralQuads(); for (BakedQuad q : generalQuads) { q = new BakedQuad(tint(q.getVertexData()), 0, q.getFace()); } return generalQuads; } @Override public boolean isAmbientOcclusion() { return model.isAmbientOcclusion(); } @Override public boolean isGui3d() { return model.isGui3d(); } @Override public boolean isBuiltInRenderer() { return model.isBuiltInRenderer(); } @Override public TextureAtlasSprite getTexture() { return model.getTexture(); } @Override public ItemCameraTransforms getItemCameraTransforms() { return model.getItemCameraTransforms(); } // Private----------------------------------------------------- private int[] tint(int[] vertexData) { //int[] vd = new int[vertexData.length]; //System.arraycopy(vertexData, 0, vd, 0, vertexData.length); int[] vd = vertexData; vd[3] = tint; vd[10] = tint; vd[17] = tint; vd[24] = tint; return vd; } } Just to recap, I am replacing the selected block with a new block that uses the model of the selected block. I modify to vertex data to tint the texture red. This works fine! The only problem is that some, but not all, of the blocks of the same type as the selected block are also tinted red: (How do I insert an image? file://~/image.png?, i'm on ubuntu.) If I return a copy of the new vertex data arrray as commented out in private method tint(), the problem goes away, but my block is not tinted. Any help appreciated.
May 12, 201510 yr Author Solved my problems. Works great. package ds.plato.block; import java.awt.Color; import java.util.ArrayList; import java.util.List; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.ItemCameraTransforms; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.client.resources.model.IBakedModel; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.util.EnumFacing; import net.minecraftforge.client.model.ISmartBlockModel; import net.minecraftforge.common.property.IExtendedBlockState; import net.minecraftforge.common.property.IUnlistedProperty; public class BlockSelectedModel implements ISmartBlockModel { public static ModelResourceLocation modelResourceLocation = new ModelResourceLocation("plato:blockSelected"); private IBakedModel defaultModel, model; private IUnlistedProperty selectedBlockProperty; private final int tint = Color.RED.getRed(); public BlockSelectedModel(IBakedModel defaultModel, PropertySelectedBlock selectedBlockProperty) { this.defaultModel = defaultModel; this.selectedBlockProperty = selectedBlockProperty; } @Override public IBakedModel handleBlockState(IBlockState state) { assert IExtendedBlockState.class.isAssignableFrom(state.getClass()); IBlockState s = ((IExtendedBlockState) state).getValue(selectedBlockProperty); model = Minecraft.getMinecraft().getBlockRendererDispatcher().getBlockModelShapes().getModelForState(s); return this; } @Override public List getFaceQuads(EnumFacing face) { List<BakedQuad> quads = new ArrayList<>(); List<BakedQuad> faceQuads = model.getFaceQuads(face); for (BakedQuad q : faceQuads) { quads.add(new BakedQuad(tint(q.getVertexData()), 0, face)); } return quads; } @Override public List getGeneralQuads() { List<BakedQuad> quads = new ArrayList<>(); List<BakedQuad> generalQuads = model.getGeneralQuads(); for (BakedQuad q : generalQuads) { quads.add( new BakedQuad(tint(q.getVertexData()), 0, q.getFace())); } return quads; } @Override public boolean isAmbientOcclusion() { return model.isAmbientOcclusion(); } @Override public boolean isGui3d() { return model.isGui3d(); } @Override public boolean isBuiltInRenderer() { return model.isBuiltInRenderer(); } @Override public TextureAtlasSprite getTexture() { return model.getTexture(); } @Override public ItemCameraTransforms getItemCameraTransforms() { return model.getItemCameraTransforms(); } // Private----------------------------------------------------- private int[] tint(int[] vertexData) { int[] vd = new int[vertexData.length]; System.arraycopy(vertexData, 0, vd, 0, vertexData.length); vd[3] = tint; vd[10] = tint; vd[17] = tint; vd[24] = tint; return vd; } } Thanks TGG!
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.