Jump to content

[1.8.8] Dynamically retexturing blocks that use OBJ models


Nuchaz

Recommended Posts

Hello everyone, I am working on updating BiblioCraft to v1.8.8 and am still working my way through all the new features trying to understand how to use them. I think I am going to really like the new systems once I get a feel for them. So far I think I have an understanding of how to render OBJ models, show/hide parts of the models, and apply transforms using the getExtendedState within my block classes. Now I am trying to understand how to dynamically update the texture of my blocks. I've looked over the retexture method in the OBJModel class so I sure there must be a way to do this. What I am doing is basically saving a string to NBT on the TileEntity (for ex: "minecraft:blocks/planks_oak") which I can pass on to easily work with either the retexture method in the OBJModel class or I can easily use it to get a TextureAtlasSprite. This only really needs to happen on block placement (the string will be saved to the ItemStack and passed to the Tile on placment) and when the blocks initially load. I also want to pull the string from NBT on the ItemStack, get the texture and apply it to the ItemStack model as well. That NBT tag can changed in game so the texture on the ItemStack model can change any number of times.

 

I've been looking at this example on the forge github of the ModelBakeEventDebug class trying to understand how I might approach this retexture problem. https://github.com/MinecraftForge/MinecraftForge/blob/master/src/test/java/net/minecraftforge/debug/ModelBakeEventDebug.java

From what I've learned from that I am guessing I may have to create a custom model class and implement several interfaces and use the handleBlockState and handleItemState methods. But I am not sure how to approach that using an OBJ model because there is already a OBJModel class and an OBJBakedModel class that already does all the things including the implementation of the retexture method from the IRetexturableModel interface. I thought about just extending the OBJBakedModel class and overrideing the handleBlockState method but the current OBJBakedModel handleBlockState method is doing some things that access private variables when dealing with the visibility groups. I am just not sure how to proceed. I am wondering if I have to do something in my model json file too.

 

Can anyone give me some tips on how to dynamically change the texture on an OBJ model? Or possibly is there any working examples out there I can read over that allow retexturing an OBJ model?

 

Thanks!

 

 

Link to comment
Share on other sites

I am retexturing OBJ models, but I am pre-baking all the models during model bake and cacheing them in an ISmartItemModel class that returns the appropriate pre-baked model during handleBlockState.  It should be possible to do this dynamically, but you'll likely want to cache your results and all your code will need to be thread-safe.  So far the memory usage of pre-baked model variants seems acceptable even with relative large numbers of variants.

 

The most relevant code is this:

 

			NiceCookbook.Ingredients ingredients = style.cookbook.getIngredients(substance, recipe, alt);

			IRetexturableModel template = (IRetexturableModel)event.modelLoader.getModel(new ModelResourceLocation(ingredients.modelName));

			IModel model=template.retexture(ingredients.textures);

			this.models[alt][recipe]=model.bake(ingredients.state, DefaultVertexFormats.ITEM, textureGetter);

 

The ingredients.textures call Returns an immutable hash map of textures to be used for baking. 

 

The template .OBJ model is loaded using a straightforward file system reference that includes the .OBJ suffix.  For example: "adversity:block/col_round_four_faces_full.obj".  Cast it to (IRetexturableModel) and then call .retexture with your textures. 

 

Your textures should all have been included during texture stitch so that they are available in the texture atlas. This is easily done with event.map.registerSprite.

 

For the replacement textures to map correctly, use names without a # prefix in the .MTL file. Use those same names (again without a # prefix) as keys in the hash map of textures you pass to .retexture.  As I'm typing this, I vaguely recall that the #prefix either was or is at some point going to be required, but it doesn't seem to be needed in the latest forge. 

 

Remember that your .OBJ models can share a .MTL file if you're going to be using the same material names in all of them.

 

You can look at my working code if you promise not to laugh:  https://github.com/grondag/Adversity. Code above is from NiceModel.handleBakeEvent.

Link to comment
Share on other sites

Thanks! That looks like exactly what I am looking for. I'll have a play around with it later.

 

I didn't know I could share an .mtl between obj models and I wasn't sure how to stitch textures. That was something I wanted to know at some point. So huge thanks for the extra tips too!

Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Announcements



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.