Skip to content

Commit

Permalink
optimized bucket item model rendering to avoid lags in screens like J…
Browse files Browse the repository at this point in the history
  • Loading branch information
cech12 committed Jun 24, 2024
1 parent d602aa4 commit 6f4083b
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 38 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Forge Recommended Versioning](https://mcforge.readthedocs.io/en/latest/conventions/versioning/).

## [1.20.1-2.3.4.1] - 2024-06-24
### Fixed
- optimized bucket item model rendering to avoid lags in screens like JEI or EMI (thanks to truskawex for the report) https://github.com/cech12/WoodenBucket/issues/19

## [1.20.1-2.3.4.0] - 2024-05-10
### Added
- entity textures of Upgrade Aquatic mod
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ mixin_version=0.8.5

## Mod Properties
mod_id=bucketlib
mod_version=2.3.4.0
mod_version=2.3.4.1
mod_group_id=cech12.bucketlib
mod_name=BucketLib
mod_authors=Cech12
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/cech12/bucketlib/BucketLib.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import cech12.bucketlib.api.crafting.EntityIngredient;
import cech12.bucketlib.api.crafting.FluidIngredient;
import cech12.bucketlib.api.crafting.MilkIngredient;
import cech12.bucketlib.config.ServerConfig;
import cech12.bucketlib.api.item.UniversalBucketItem;
import cech12.bucketlib.config.ServerConfig;
import cech12.bucketlib.item.UniversalBucketDispenseBehaviour;
import cech12.bucketlib.item.crafting.BucketDyeingRecipe;
import cech12.bucketlib.item.crafting.BucketFillingShapedRecipe;
Expand All @@ -30,7 +30,6 @@
import net.minecraftforge.common.crafting.CraftingHelper;
import net.minecraftforge.event.BuildCreativeModeTabContentsEvent;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fluids.FluidUtil;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.common.Mod;
Expand Down Expand Up @@ -128,9 +127,10 @@ private void registerBucket(UniversalBucketItem bucket) {
return ColorUtil.getColor(stack, bucket.getDefaultColor());
}
if (layer == 1) {
return FluidUtil.getFluidContained(stack)
.map(fluidStack -> IClientFluidTypeExtensions.of(fluidStack.getFluid()).getTintColor(fluidStack))
.orElse(-1);
Fluid fluid = BucketLibUtil.getFluid(stack);
if (fluid != Fluids.EMPTY) {
return IClientFluidTypeExtensions.of(fluid).getTintColor();
}
}
return -1;
}, bucket));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import net.minecraft.client.resources.model.ModelBaker;
import net.minecraft.client.resources.model.ModelState;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.inventory.InventoryMenu;
import net.minecraft.world.item.ItemStack;
Expand All @@ -27,11 +26,10 @@
import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions;
import net.minecraftforge.client.model.CompositeModel;
import net.minecraftforge.client.model.DynamicFluidContainerModel;
import net.minecraftforge.client.model.IQuadTransformer;
import net.minecraftforge.client.model.QuadTransformers;
import net.minecraftforge.client.model.SimpleModelState;
import net.minecraftforge.client.model.geometry.IGeometryBakingContext;
import net.minecraftforge.client.model.geometry.IGeometryLoader;
import net.minecraftforge.client.model.SimpleModelState;
import net.minecraftforge.client.model.geometry.IUnbakedGeometry;
import net.minecraftforge.client.model.geometry.StandaloneGeometryBakingContext;
import net.minecraftforge.client.model.geometry.UnbakedGeometryHelper;
Expand All @@ -42,6 +40,7 @@
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;

/**
Expand All @@ -53,8 +52,6 @@ public class UniversalBucketModel implements IUnbakedGeometry<UniversalBucketMod
private static final Map<ResourceLocation, ResourceLocation> TEXTURE_MAP = Maps.newHashMap();
// Depth offsets to prevent Z-fighting
private static final Transformation DEPTH_OFFSET_TRANSFORM = new Transformation(new Vector3f(), new Quaternionf(), new Vector3f(1, 1, 1.002f), new Quaternionf());
// Transformer to set quads to max brightness
private static final IQuadTransformer MAX_LIGHTMAP_TRANSFORMER = QuadTransformers.applyingLightmap(0x00F000F0);

private static final Material MISSING_LOWER_CONTENT_MATERIAL = new Material(InventoryMenu.BLOCK_ATLAS, getContentTexture(new ResourceLocation(BucketLibApi.MOD_ID, "missing_lower_content")));

Expand Down Expand Up @@ -181,9 +178,9 @@ public BakedModel bake(IGeometryBakingContext owner, ModelBaker baker, Function<
var unbaked = UnbakedGeometryHelper.createUnbakedItemMaskElements(1, templateSprite.contents()); // Use template as mask
var quads = UnbakedGeometryHelper.bakeElements(unbaked, $ -> fluidSprite, transformedState, modelLocation); // Bake with fluid texture

var unlit = fluid.getFluidType().getLightLevel() > 0;
var renderTypes = DynamicFluidContainerModel.getLayerRenderTypes(unlit);
if (unlit) MAX_LIGHTMAP_TRANSFORMER.processInPlace(quads);
var emissive = fluid.getFluidType().getLightLevel() > 0;
var renderTypes = DynamicFluidContainerModel.getLayerRenderTypes(emissive);
if (emissive) QuadTransformers.settingEmissivity(fluid.getFluidType().getLightLevel()).processInPlace(quads);

modelBuilder.addQuads(renderTypes, quads);
}
Expand Down Expand Up @@ -211,13 +208,14 @@ private static final class ContainedFluidOverrideHandler extends ItemOverrides
{
private static final ResourceLocation REBAKE_LOCATION = new ResourceLocation(BucketLibApi.MOD_ID, "bucket_override");

private final Map<ResourceLocation, BakedModel> cache = Maps.newHashMap(); // contains all the baked models since they'll never change
private final Map<String, BakedModel> cache = Maps.newHashMap(); // contains all the baked models since they'll never change
private final ItemOverrides nested;
private final ModelBaker baker;
private final IGeometryBakingContext owner;
private final UniversalBucketModel parent;

private boolean isCracked;
private Integer upperBreakTemperature = null;
private Integer lowerBreakTemperature = null;

private ContainedFluidOverrideHandler(ItemOverrides nested, ModelBaker baker, IGeometryBakingContext owner, UniversalBucketModel parent)
{
Expand All @@ -234,32 +232,33 @@ public BakedModel resolve(@Nonnull BakedModel originalModel, @Nonnull ItemStack
BakedModel overridden = nested.resolve(originalModel, stack, world, entity, number);
if (overridden != originalModel) return overridden;
if (stack.getItem() instanceof UniversalBucketItem bucket) {
ResourceLocation content = null;
EntityType<?> entityType = BucketLibUtil.getEntityType(stack);
if (entityType != null) {
content = ForgeRegistries.ENTITY_TYPES.getKey(entityType);
}
if (content == null) {
content = BucketLibUtil.getContent(stack);
boolean containsEntityType = false;
String content = BucketLibUtil.getEntityTypeString(stack);
if (content != null) {
containsEntityType = true;
} else {
content = BucketLibUtil.getContentString(stack);
}
Fluid fluid = null;
if (content == null) {
fluid = BucketLibUtil.getFluid(stack);
content = ForgeRegistries.FLUIDS.getKey(fluid);
ResourceLocation location = ForgeRegistries.FLUIDS.getKey(fluid);
content = (location != null) ? location.toString() : null;
}
//reset cache if temperature config changed
boolean isCracked = bucket.isCracked(stack);
if (this.isCracked != isCracked) {
this.isCracked = isCracked;
if (!Objects.equals(upperBreakTemperature, bucket.getUpperBreakTemperature()) || !Objects.equals(lowerBreakTemperature, bucket.getLowerBreakTemperature())) {
upperBreakTemperature = bucket.getUpperBreakTemperature();
lowerBreakTemperature = bucket.getLowerBreakTemperature();
cache.clear();
}
if (!cache.containsKey(content)) {
UniversalBucketModel unbaked = (entityType != null || fluid == null) ? this.parent.withOtherContent(content, isCracked, entityType != null) : this.parent.withFluid(fluid, isCracked);
BakedModel bakedModel = unbaked.bake(owner, baker, Material::sprite, BlockModelRotation.X0_Y0, this, REBAKE_LOCATION);
BakedModel bakedModel = cache.get(content);
if (bakedModel == null && content != null) {
boolean isCracked = bucket.isCracked(stack);
UniversalBucketModel unbaked = (fluid == null) ? this.parent.withOtherContent(new ResourceLocation(content), isCracked, containsEntityType) : this.parent.withFluid(fluid, isCracked);
bakedModel = unbaked.bake(owner, baker, Material::sprite, BlockModelRotation.X0_Y0, this, REBAKE_LOCATION);
cache.put(content, bakedModel);
return bakedModel;
}
return cache.get(content);
return bakedModel;
}
return originalModel;
}
Expand Down
24 changes: 18 additions & 6 deletions src/main/java/cech12/bucketlib/util/BucketLibUtil.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package cech12.bucketlib.util;

import cech12.bucketlib.api.BucketLibTags;
import cech12.bucketlib.config.ServerConfig;
import cech12.bucketlib.api.item.UniversalBucketItem;
import cech12.bucketlib.config.ServerConfig;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
Expand Down Expand Up @@ -122,10 +122,14 @@ private static boolean containsTagContent(ItemStack itemStack, String tagName) {

private static String getTagContent(ItemStack itemStack, String tagName) {
CompoundTag nbt = itemStack.getTag();
if (nbt != null && nbt.contains(tagName)) {
return nbt.getString(tagName);
if (nbt == null) {
return null;
}
return null;
String content = nbt.getString(tagName);
if (content.isEmpty()) {
return null;
}
return content;
}

private static ItemStack setTagContent(ItemStack itemStack, String tagName, String tagContent) {
Expand Down Expand Up @@ -158,13 +162,17 @@ public static boolean containsContent(ItemStack itemStack) {
}

public static ResourceLocation getContent(ItemStack itemStack) {
String content = getTagContent(itemStack, "BucketContent");
String content = getContentString(itemStack);
if (content != null) {
return new ResourceLocation(content);
}
return null;
}

public static String getContentString(ItemStack itemStack) {
return getTagContent(itemStack, "BucketContent");
}

public static ItemStack addContent(ItemStack itemStack, ResourceLocation content) {
return setTagContent(itemStack, "BucketContent", content.toString());
}
Expand Down Expand Up @@ -243,13 +251,17 @@ public static boolean containsEntityType(ItemStack itemStack) {
}

public static EntityType<?> getEntityType(ItemStack itemStack) {
String content = getTagContent(itemStack, "EntityType");
String content = getEntityTypeString(itemStack);
if (content != null) {
return ForgeRegistries.ENTITY_TYPES.getValue(new ResourceLocation(content));
}
return null;
}

public static String getEntityTypeString(ItemStack itemStack) {
return getTagContent(itemStack, "EntityType");
}

public static ItemStack addEntityType(ItemStack itemStack, EntityType<?> entityType) {
return setTagContent(itemStack, "EntityType", Objects.requireNonNull(ForgeRegistries.ENTITY_TYPES.getKey(entityType)).toString());
}
Expand Down

0 comments on commit 6f4083b

Please sign in to comment.