Don't recreate unbakedmodels

This commit is contained in:
quat1024 2023-07-04 23:38:06 -04:00
parent a981cd28c2
commit 657c597e87
3 changed files with 16 additions and 32 deletions

View File

@ -16,7 +16,6 @@ Template blocks can be placed in the world, then right-clicked with a full-size
## Todo ## Todo
* Evaluate whether I need to keep the `Supplier` in TemplatesModelProvider, or whether I can reuse my `UnbakedModel`s indefinitely
* `templates:block/slope_base` needs a suspicious amount of custom rotations. Maybe the model is pointing the wrong way. * `templates:block/slope_base` needs a suspicious amount of custom rotations. Maybe the model is pointing the wrong way.
* `uvlock` in a blockstate will not work for `RetexturedMeshTemplateUnbakedModel`s. Can it be fixed? * `uvlock` in a blockstate will not work for `RetexturedMeshTemplateUnbakedModel`s. Can it be fixed?
* Upside-down slopes would be nice... * Upside-down slopes would be nice...

View File

@ -56,12 +56,12 @@ public class TemplatesClient implements ClientModInitializer {
BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), Templates.SLOPE, Templates.SLAB); BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), Templates.SLOPE, Templates.SLAB);
provider.addTemplateModel(Templates.id("slope_special"), () -> new RetexturedMeshUnbakedModel(Templates.id("block/slope_base"), SlopeBaseMesh::make)); provider.addTemplateModel(Templates.id("slope_special"), new RetexturedMeshUnbakedModel(Templates.id("block/slope_base"), SlopeBaseMesh::make));
provider.assignItemModel(Templates.id("slope_special"), Templates.SLOPE); provider.assignItemModel(Templates.id("slope_special"), Templates.SLOPE);
provider.addTemplateModel(Templates.id("cube_special"), () -> new RetexturedJsonModelUnbakedModel(Templates.id("block/cube"))); provider.addTemplateModel(Templates.id("cube_special"), new RetexturedJsonModelUnbakedModel(Templates.id("block/cube")));
provider.addTemplateModel(Templates.id("slab_bottom_special"), () -> new RetexturedJsonModelUnbakedModel(Templates.id("block/slab_bottom"))); provider.addTemplateModel(Templates.id("slab_bottom_special"), new RetexturedJsonModelUnbakedModel(Templates.id("block/slab_bottom")));
provider.addTemplateModel(Templates.id("slab_top_special"), () -> new RetexturedJsonModelUnbakedModel(Templates.id("block/slab_top"))); provider.addTemplateModel(Templates.id("slab_top_special"), new RetexturedJsonModelUnbakedModel(Templates.id("block/slab_top")));
provider.assignItemModel(Templates.id("slab_bottom_special"), Templates.SLAB); provider.assignItemModel(Templates.id("slab_bottom_special"), Templates.SLAB);
} }
} }

View File

@ -18,32 +18,18 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier;
public class TemplatesModelProvider implements ModelResourceProvider, ModelVariantProvider { public class TemplatesModelProvider implements ModelResourceProvider, ModelVariantProvider {
private final Map<Identifier, Supplier<UnbakedModel>> factories = new HashMap<>(); private final Map<Identifier, UnbakedModel> models = new HashMap<>();
private final Map<ModelIdentifier, Identifier> itemAssignments = new HashMap<>(); private final Map<ModelIdentifier, Identifier> itemAssignments = new HashMap<>();
private final Map<Identifier, UnbakedModel> cache = new HashMap<>();
private volatile TemplateAppearanceManager appearanceManager; private volatile TemplateAppearanceManager appearanceManager;
/// model loading /// fabric model provider api
@Override @Override
public @Nullable UnbakedModel loadModelResource(Identifier resourceId, ModelProviderContext context) throws ModelProviderException { public @Nullable UnbakedModel loadModelResource(Identifier resourceId, ModelProviderContext context) {
UnbakedModel cacheResult = cache.get(resourceId); return models.get(resourceId);
if(cacheResult != null) return cacheResult;
//Either we have a factory for this model (just haven't cached its output yet),
Supplier<UnbakedModel> factory = factories.get(resourceId);
if(factory != null) {
UnbakedModel freshModel = factory.get();
cache.put(resourceId, freshModel);
return freshModel;
}
//or we don't cover this model at all.
return null;
} }
//For blocks, you can point the game directly at the custom model in the blockstate json file. //For blocks, you can point the game directly at the custom model in the blockstate json file.
@ -51,19 +37,19 @@ public class TemplatesModelProvider implements ModelResourceProvider, ModelVaria
//You *would* be able to create a model json for it and set the "parent" field to the custom model, //You *would* be able to create a model json for it and set the "parent" field to the custom model,
//but json models are never allowed to have non-json models as a parent, and template unbaked models are not json models. Ah well. //but json models are never allowed to have non-json models as a parent, and template unbaked models are not json models. Ah well.
//So, instead, we use a ModelVariantProvider to clunkily redirect the item:id#inventory model to the blockmodel. //So, instead, we use a ModelVariantProvider to clunkily redirect the item:id#inventory model to the blockmodel.
//Not my favorite solution (for one, it precludes setting custom rotations in the item model) but we'll live. //Not my favorite solution but we'll live.
@Override @Override
public @Nullable UnbakedModel loadModelVariant(ModelIdentifier modelId, ModelProviderContext context) throws ModelProviderException { public @Nullable UnbakedModel loadModelVariant(ModelIdentifier modelId, ModelProviderContext context) {
Identifier customModelId = itemAssignments.get(modelId); Identifier customModelId = itemAssignments.get(modelId);
return customModelId == null ? null : loadModelResource(customModelId, context); return customModelId == null ? null : loadModelResource(customModelId, context);
} }
/// template appearance manager cache, & other cache stuff /// template appearance manager cache
public TemplateAppearanceManager getOrCreateTemplateApperanceManager(Function<SpriteIdentifier, Sprite> spriteLookup) { public TemplateAppearanceManager getOrCreateTemplateApperanceManager(Function<SpriteIdentifier, Sprite> spriteLookup) {
//This is kind of needlessly fancy using the volatile "double checked locking" pattern. //This is kind of needlessly fancy using the "volatile double checked locking" pattern.
//I'd like all the template models to use the same TemplateApperanceManager, despite the model //I'd like all template models to use the same TemplateApperanceManager, despite the model
//making process happening concurrently on several threads. //baking process happening concurrently on several threads.
//Volatile field read: //Volatile field read:
TemplateAppearanceManager read = appearanceManager; TemplateAppearanceManager read = appearanceManager;
@ -85,14 +71,13 @@ public class TemplatesModelProvider implements ModelResourceProvider, ModelVaria
} }
public void dumpCache() { public void dumpCache() {
cache.clear();
appearanceManager = null; appearanceManager = null;
} }
/// "public api" /// "public api"
public void addTemplateModel(Identifier id, Supplier<UnbakedModel> modelFactory) { public void addTemplateModel(Identifier id, UnbakedModel modelFactory) {
factories.put(id, modelFactory); models.put(id, modelFactory);
} }
public void assignItemModel(Identifier templateModelId, ModelIdentifier... modelIds) { public void assignItemModel(Identifier templateModelId, ModelIdentifier... modelIds) {