From 5f87489939aa70e0167cfd2cc7414df2f77da9fa Mon Sep 17 00:00:00 2001 From: Adrien1106 Date: Wed, 6 Mar 2024 22:10:11 +0100 Subject: [PATCH] better caching for both appearances and meshed models --- .../java/fr/adrien1106/reframed/ReFramed.java | 6 +- .../reframed/block/ReFramedBlock.java | 21 ++- .../reframed/block/ReFramedDoubleBlock.java | 4 +- .../reframed/block/ReFramedDoubleEntity.java | 2 +- .../block/ReFramedDoubleSlabBlock.java | 19 +- .../block/ReFramedDoubleStairsBlock.java | 24 ++- .../block/ReFramedDoubleStepBlock.java | 16 +- .../reframed/block/ReFramedEntity.java | 8 +- .../reframed/block/ReFramedSlabBlock.java | 10 + .../reframed/block/ReFramedStairsBlock.java | 23 ++- .../reframed/block/ReFramedStepBlock.java | 18 +- .../model/DoubleRetexturingBakedModel.java | 2 +- .../client/model/MultiRetexturableModel.java | 3 +- .../client/model/RetexturingBakedModel.java | 172 +++++++----------- .../model/UnbakedAutoRetexturedModel.java | 2 +- .../model/UnbakedJsonRetexturedModel.java | 2 +- .../model/apperance/CamoAppearance.java | 71 +++++++- .../apperance/CamoAppearanceManager.java | 34 ++-- .../model/apperance/ComputedAppearance.java | 31 +--- .../apperance/SingleSpriteAppearance.java | 26 +-- .../apperance/WeightedComputedAppearance.java | 39 +--- .../reframed/mixin/BlockItemMixin.java | 1 + .../mixin/compat/AthenaBakedModelMixin.java | 2 +- .../AthenaConnectedBlockModelMixin.java | 2 +- .../compat/AthenaWrappedGetterMixin.java | 2 +- .../IndiumTerrainBlockRenderInfoMixin.java | 6 +- .../IndiumTerrainRenderContextMixin.java | 13 +- .../SodiumBlockOcclusionCacheMixin.java | 4 +- .../particles/MixinBlockDustParticle.java | 2 +- .../reframed/mixin/particles/MixinEntity.java | 2 +- .../mixin/particles/MixinLivingEntity.java | 2 +- .../mixin/render/BlockRenderInfoMixin.java | 6 +- .../render/MultipartBakedModelMixin.java | 2 +- .../render/TerrainRenderContextMixin.java | 18 +- .../reframed/mixin/sound/BlockItemMixin.java | 2 +- .../reframed/mixin/sound/EntityMixin.java | 2 +- .../mixin/sound/LivingEntityMixin.java | 2 +- .../mixin/sound/WorldRendererMixin.java | 2 +- .../util/{ => blocks}/BlockHelper.java | 23 ++- .../util/{ => blocks}/BlockProperties.java | 4 +- .../util/{property => blocks}/Corner.java | 2 +- .../{ => blocks}/ReframedInteractible.java | 2 +- .../util/{property => blocks}/StairShape.java | 2 +- .../{ => blocks}/ThemeableBlockEntity.java | 2 +- .../{ => mixin}/IBlockRenderInfoMixin.java | 2 +- .../IMultipartBakedModelMixin.java | 2 +- 46 files changed, 364 insertions(+), 278 deletions(-) rename src/main/java/fr/adrien1106/reframed/util/{ => blocks}/BlockHelper.java (93%) rename src/main/java/fr/adrien1106/reframed/util/{ => blocks}/BlockProperties.java (74%) rename src/main/java/fr/adrien1106/reframed/util/{property => blocks}/Corner.java (98%) rename src/main/java/fr/adrien1106/reframed/util/{ => blocks}/ReframedInteractible.java (93%) rename src/main/java/fr/adrien1106/reframed/util/{property => blocks}/StairShape.java (96%) rename src/main/java/fr/adrien1106/reframed/util/{ => blocks}/ThemeableBlockEntity.java (82%) rename src/main/java/fr/adrien1106/reframed/util/{ => mixin}/IBlockRenderInfoMixin.java (87%) rename src/main/java/fr/adrien1106/reframed/util/{ => mixin}/IMultipartBakedModelMixin.java (81%) diff --git a/src/main/java/fr/adrien1106/reframed/ReFramed.java b/src/main/java/fr/adrien1106/reframed/ReFramed.java index f546e28..daee2ba 100644 --- a/src/main/java/fr/adrien1106/reframed/ReFramed.java +++ b/src/main/java/fr/adrien1106/reframed/ReFramed.java @@ -1,7 +1,7 @@ package fr.adrien1106.reframed; import fr.adrien1106.reframed.block.*; -import fr.adrien1106.reframed.util.BlockHelper; +import fr.adrien1106.reframed.util.blocks.BlockHelper; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.itemgroup.v1.FabricItemGroup; import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder; @@ -26,7 +26,9 @@ import java.util.function.BiConsumer; import java.util.stream.Collectors; /** - * TODO self culling, fix other models, better connected textures, preload items, better cache + * TODO self culling + * TODO fix other models + * TODO better connected textures */ public class ReFramed implements ModInitializer { public static final String MODID = "reframed"; diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedBlock.java index d1609c3..c75b6a9 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedBlock.java @@ -2,7 +2,7 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.ReFramed; import fr.adrien1106.reframed.generator.RecipeSetter; -import fr.adrien1106.reframed.util.BlockHelper; +import fr.adrien1106.reframed.util.blocks.BlockHelper; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.*; import net.minecraft.block.entity.BlockEntity; @@ -33,7 +33,7 @@ import org.jetbrains.annotations.Nullable; import java.util.List; -import static fr.adrien1106.reframed.util.BlockProperties.LIGHT; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.LIGHT; public class ReFramedBlock extends Block implements BlockEntityProvider, RecipeSetter { @@ -41,6 +41,23 @@ public class ReFramedBlock extends Block implements BlockEntityProvider, RecipeS super(settings); setDefaultState(getDefaultState().with(LIGHT, false)); } + + /** + * Generates a record for the key so that it replaces the blockstate + * which may have states that returns same models + * @param state - the state_key to generate the key from + * @return a cache key with only relevant properties + */ + public Object getModelCacheKey(BlockState state) { + return ""; + } + + /** + * @return the amount of models the block can have prevents allocating too much space for a model + */ + public int getModelStateCount() { + return 1; + } //For addon devs: override this so your blocks don't end up trying to place my block entity, my BlockEntityType only handles blocks internal to the mod //Just make your own BlockEntityType, it's fine, you can even use the same ReFramedEntity class diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleBlock.java index 45756b6..cb708b0 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleBlock.java @@ -1,8 +1,8 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.ReFramed; -import fr.adrien1106.reframed.util.BlockHelper; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.block.ShapeContext; import net.minecraft.block.entity.BlockEntity; diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleEntity.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleEntity.java index 5090b0a..cecd4f6 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleEntity.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleEntity.java @@ -44,7 +44,7 @@ public class ReFramedDoubleEntity extends ReFramedEntity { public void readNbt(NbtCompound nbt) { super.readNbt(nbt); - BlockState rendered_state = second_state;// keep previous state to check if rerender is needed + BlockState rendered_state = second_state;// keep previous state_key to check if rerender is needed second_state = NbtHelper.toBlockState(Registries.BLOCK.getReadOnlyWrapper(), nbt.getCompound(BLOCKSTATE_KEY + 2)); // Force a chunk remesh on the client if the displayed blockstate has changed diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleSlabBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleSlabBlock.java index 5f11422..a7f4292 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleSlabBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleSlabBlock.java @@ -25,25 +25,36 @@ import static net.minecraft.data.client.VariantSettings.Rotation.R90; import static net.minecraft.state.property.Properties.AXIS; public class ReFramedDoubleSlabBlock extends ReFramedDoubleBlock implements BlockStateProvider { + public ReFramedDoubleSlabBlock(Settings settings) { super(settings); - setDefaultState(getDefaultState().with(Properties.AXIS, Direction.Axis.Y)); + setDefaultState(getDefaultState().with(AXIS, Direction.Axis.Y)); + } + + @Override + public Object getModelCacheKey(BlockState state) { + return state.get(AXIS); + } + + @Override + public int getModelStateCount() { + return 3; } @Override protected void appendProperties(StateManager.Builder builder) { - super.appendProperties(builder.add(Properties.AXIS)); + super.appendProperties(builder.add(AXIS)); } @Nullable @Override public BlockState getPlacementState(ItemPlacementContext ctx) { - return super.getPlacementState(ctx).with(Properties.AXIS, ctx.getSide().getAxis()); + return super.getPlacementState(ctx).with(AXIS, ctx.getSide().getAxis()); } @Override public VoxelShape getShape(BlockState state, int i) { - return switch (state.get(Properties.AXIS)) { + return switch (state.get(AXIS)) { case Y -> i == 2 ? UP : DOWN; case Z -> i == 2 ? NORTH : SOUTH; case X -> i == 2 ? EAST : WEST; diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStairsBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStairsBlock.java index c7ac022..6dda2df 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStairsBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStairsBlock.java @@ -2,9 +2,9 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.ReFramed; import fr.adrien1106.reframed.generator.BlockStateProvider; -import fr.adrien1106.reframed.util.BlockHelper; -import fr.adrien1106.reframed.util.property.Corner; -import fr.adrien1106.reframed.util.property.StairShape; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.blocks.Corner; +import fr.adrien1106.reframed.util.blocks.StairShape; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -28,17 +28,27 @@ import java.util.ArrayList; import java.util.List; import static fr.adrien1106.reframed.block.ReFramedStairsBlock.*; -import static fr.adrien1106.reframed.util.BlockProperties.CORNER; -import static fr.adrien1106.reframed.util.BlockProperties.STAIR_SHAPE; -import static fr.adrien1106.reframed.util.property.StairShape.STRAIGHT; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.STAIR_SHAPE; public class ReFramedDoubleStairsBlock extends ReFramedDoubleBlock implements BlockStateProvider { private static final List COMPLEMENT_LIST = new ArrayList<>(52); + private record ModelCacheKey(Corner corner, StairShape shape) {} public ReFramedDoubleStairsBlock(Settings settings) { super(settings); - setDefaultState(getDefaultState().with(CORNER, Corner.NORTH_DOWN).with(STAIR_SHAPE, STRAIGHT)); + setDefaultState(getDefaultState().with(CORNER, Corner.NORTH_DOWN).with(STAIR_SHAPE, StairShape.STRAIGHT)); + } + + @Override + public Object getModelCacheKey(BlockState state) { + return new ModelCacheKey(state.get(CORNER), state.get(STAIR_SHAPE)); + } + + @Override + public int getModelStateCount() { + return 108; // Has 12 * 9 state combination and 52 models still reduces cache size } @Override diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStepBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStepBlock.java index 5e76f44..453dc0f 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStepBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedDoubleStepBlock.java @@ -3,7 +3,9 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.ReFramed; import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.generator.BlockStateProvider; -import fr.adrien1106.reframed.util.BlockHelper; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.blocks.Corner; +import fr.adrien1106.reframed.util.blocks.StairShape; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -32,11 +34,23 @@ import static net.minecraft.state.property.Properties.AXIS; import static net.minecraft.util.shape.VoxelShapes.empty; public class ReFramedDoubleStepBlock extends WaterloggableReFramedDoubleBlock implements BlockStateProvider { + private record ModelCacheKey(Direction facing, Axis axis) {} + public ReFramedDoubleStepBlock(Settings settings) { super(settings); setDefaultState(getDefaultState().with(FACING, Direction.DOWN).with(AXIS, Axis.X)); } + @Override + public Object getModelCacheKey(BlockState state) { + return new ModelCacheKey(state.get(FACING), state.get(AXIS)); + } + + @Override + public int getModelStateCount() { + return 18; + } + @Override protected void appendProperties(StateManager.Builder builder) { super.appendProperties(builder.add(FACING, AXIS)); diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedEntity.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedEntity.java index cb7bde1..fc70154 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedEntity.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedEntity.java @@ -1,8 +1,8 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.ReFramed; -import fr.adrien1106.reframed.util.BlockProperties; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.BlockProperties; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.entity.BlockEntity; @@ -27,7 +27,7 @@ import java.util.Objects; //Keeping the weight of this block entity down, both in terms of memory consumption and NBT sync traffic, //is pretty important since players might place a lot of them. There were tons and tons of these at Blanketcon. -//To that end, most of the state has been crammed into a bitfield. +//To that end, most of the state_key has been crammed into a bitfield. public class ReFramedEntity extends BlockEntity implements ThemeableBlockEntity { protected BlockState first_state = Blocks.AIR.getDefaultState(); protected byte bit_field = SOLIDITY_MASK; @@ -47,7 +47,7 @@ public class ReFramedEntity extends BlockEntity implements ThemeableBlockEntity public void readNbt(NbtCompound nbt) { super.readNbt(nbt); - BlockState rendered_state = first_state; // keep previous state to check if rerender is needed + BlockState rendered_state = first_state; // keep previous state_key to check if rerender is needed first_state = NbtHelper.toBlockState(Registries.BLOCK.getReadOnlyWrapper(), nbt.getCompound(BLOCKSTATE_KEY + 1)); if (nbt.contains(BITFIELD_KEY)) bit_field = nbt.getByte(BITFIELD_KEY); diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedSlabBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedSlabBlock.java index fa65921..751588e 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedSlabBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedSlabBlock.java @@ -38,6 +38,16 @@ public class ReFramedSlabBlock extends WaterloggableReFramedBlock implements Blo super(settings); setDefaultState(getDefaultState().with(FACING, Direction.DOWN)); } + + @Override + public Object getModelCacheKey(BlockState state) { + return state.get(FACING); + } + + @Override + public int getModelStateCount() { + return 6; + } @Override protected void appendProperties(StateManager.Builder builder) { diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsBlock.java index ce7283b..3912786 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedStairsBlock.java @@ -3,10 +3,10 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.ReFramed; import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.generator.BlockStateProvider; -import fr.adrien1106.reframed.util.BlockHelper; +import fr.adrien1106.reframed.util.blocks.BlockHelper; import fr.adrien1106.reframed.util.VoxelHelper; -import fr.adrien1106.reframed.util.property.Corner; -import fr.adrien1106.reframed.util.property.StairShape; +import fr.adrien1106.reframed.util.blocks.Corner; +import fr.adrien1106.reframed.util.blocks.StairShape; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -34,19 +34,30 @@ import java.util.ArrayList; import java.util.List; import java.util.stream.Stream; -import static fr.adrien1106.reframed.util.BlockProperties.*; -import static fr.adrien1106.reframed.util.property.StairShape.*; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.*; +import static fr.adrien1106.reframed.util.blocks.StairShape.*; import static net.minecraft.data.client.VariantSettings.Rotation.*; -import static fr.adrien1106.reframed.util.property.Corner.*; +import static fr.adrien1106.reframed.util.blocks.Corner.*; public class ReFramedStairsBlock extends WaterloggableReFramedBlock implements BlockStateProvider { public static final List VOXEL_LIST = new ArrayList<>(52); + private record ModelCacheKey(Corner corner, StairShape shape) {} public ReFramedStairsBlock(Settings settings) { super(settings); setDefaultState(getDefaultState().with(CORNER, Corner.NORTH_DOWN).with(STAIR_SHAPE, STRAIGHT)); } + + @Override + public Object getModelCacheKey(BlockState state) { + return new ModelCacheKey(state.get(CORNER), state.get(STAIR_SHAPE)); + } + + @Override + public int getModelStateCount() { + return 108; // Has 12 * 9 state combination and 52 models still reduces cache size + } @Override protected void appendProperties(StateManager.Builder builder) { diff --git a/src/main/java/fr/adrien1106/reframed/block/ReFramedStepBlock.java b/src/main/java/fr/adrien1106/reframed/block/ReFramedStepBlock.java index a5c7841..8b33b9e 100644 --- a/src/main/java/fr/adrien1106/reframed/block/ReFramedStepBlock.java +++ b/src/main/java/fr/adrien1106/reframed/block/ReFramedStepBlock.java @@ -3,9 +3,9 @@ package fr.adrien1106.reframed.block; import fr.adrien1106.reframed.ReFramed; import fr.adrien1106.reframed.generator.GBlockstate; import fr.adrien1106.reframed.generator.BlockStateProvider; -import fr.adrien1106.reframed.util.BlockHelper; +import fr.adrien1106.reframed.util.blocks.BlockHelper; import fr.adrien1106.reframed.util.VoxelHelper; -import fr.adrien1106.reframed.util.property.Corner; +import fr.adrien1106.reframed.util.blocks.Corner; import net.fabricmc.fabric.api.datagen.v1.provider.FabricRecipeProvider; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -28,8 +28,8 @@ import org.jetbrains.annotations.Nullable; import java.util.ArrayList; import java.util.List; -import static fr.adrien1106.reframed.util.BlockProperties.CORNER; -import static fr.adrien1106.reframed.util.property.Corner.*; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER; +import static fr.adrien1106.reframed.util.blocks.Corner.*; import static net.minecraft.data.client.VariantSettings.Rotation.*; public class ReFramedStepBlock extends WaterloggableReFramedBlock implements BlockStateProvider { @@ -41,6 +41,16 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock implements Blo setDefaultState(getDefaultState().with(CORNER, Corner.NORTH_DOWN)); } + @Override + public Object getModelCacheKey(BlockState state) { + return state.get(CORNER); + } + + @Override + public int getModelStateCount() { + return 12; + } + @Override protected void appendProperties(StateManager.Builder builder) { super.appendProperties(builder.add(CORNER)); diff --git a/src/main/java/fr/adrien1106/reframed/client/model/DoubleRetexturingBakedModel.java b/src/main/java/fr/adrien1106/reframed/client/model/DoubleRetexturingBakedModel.java index a8bf841..29ff44b 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/DoubleRetexturingBakedModel.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/DoubleRetexturingBakedModel.java @@ -45,7 +45,7 @@ public class DoubleRetexturingBakedModel extends ForwardingBakedModel implements } @Override - public List models() { + public List models() { return List.of(model_1, model_2); } } diff --git a/src/main/java/fr/adrien1106/reframed/client/model/MultiRetexturableModel.java b/src/main/java/fr/adrien1106/reframed/client/model/MultiRetexturableModel.java index b1d7cea..bcd46de 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/MultiRetexturableModel.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/MultiRetexturableModel.java @@ -1,10 +1,11 @@ package fr.adrien1106.reframed.client.model; +import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel; import net.minecraft.client.render.model.BakedModel; import java.util.List; public interface MultiRetexturableModel { - List models(); + List models(); } diff --git a/src/main/java/fr/adrien1106/reframed/client/model/RetexturingBakedModel.java b/src/main/java/fr/adrien1106/reframed/client/model/RetexturingBakedModel.java index 548bdd9..0e18f93 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/RetexturingBakedModel.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/RetexturingBakedModel.java @@ -1,13 +1,14 @@ package fr.adrien1106.reframed.client.model; +import fr.adrien1106.reframed.block.ReFramedBlock; import fr.adrien1106.reframed.block.ReFramedEntity; import fr.adrien1106.reframed.client.ReFramedClient; -import fr.adrien1106.reframed.client.model.apperance.SpriteProperties; import fr.adrien1106.reframed.mixin.MinecraftAccessor; import fr.adrien1106.reframed.client.model.apperance.CamoAppearance; import fr.adrien1106.reframed.client.model.apperance.CamoAppearanceManager; import fr.adrien1106.reframed.client.model.apperance.WeightedComputedAppearance; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; +import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh; import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; @@ -26,34 +27,42 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.math.random.Random; import net.minecraft.world.BlockRenderView; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; import java.util.function.Supplier; public abstract class RetexturingBakedModel extends ForwardingBakedModel { public RetexturingBakedModel(BakedModel base_model, CamoAppearanceManager tam, int theme_index, ModelBakeSettings settings, BlockState item_state, boolean ao) { this.wrapped = base_model; //field from the superclass; vanilla getQuads etc. will delegate through to this - this.tam = tam; + this.appearance_manager = tam; this.theme_index = theme_index; this.uv_lock = settings.isUvLocked(); this.item_state = item_state; this.ao = ao; + + int cache_size = 64; // default is 64 why don't ask me and it should get overwritten + if (item_state.getBlock() instanceof ReFramedBlock frame_block) cache_size = frame_block.getModelStateCount() + 1; + BASE_MESH_CACHE = new Object2ObjectLinkedOpenHashMap<>(cache_size, 0.25f) { + @Override + protected void rehash(int v) {} + }; } - protected final CamoAppearanceManager tam; + protected final CamoAppearanceManager appearance_manager; protected final int theme_index; protected final boolean uv_lock; - protected final BlockState item_state; protected final boolean ao; + protected final BlockState item_state; - /* ----------------------------------------------- CACHE ELEMENT ------------------------------------------------ */ - // TODO make static ? for connected textures ? - protected record MeshCacheKey(BlockState state, TransformCacheKey transform) {} - protected record TransformCacheKey(CamoAppearance appearance, int model_id) {} - protected final ConcurrentMap retextured_transforms = new ConcurrentHashMap<>(); - protected final ConcurrentMap retextured_meshes = new ConcurrentHashMap<>(); //mutable, append-only cache + protected record MeshCacheKey(Object state_key, CamoAppearance appearance, int model_id) {} + /** cache that store retextured models */ + protected final Object2ObjectLinkedOpenHashMap RETEXTURED_MESH_CACHE = + new Object2ObjectLinkedOpenHashMap<>(128, 0.25f) { + @Override + protected void rehash(int v) {} + }; + + /** cache that stores the base meshes which has the size of the amount of models */ + protected final Object2ObjectLinkedOpenHashMap BASE_MESH_CACHE; protected static final Direction[] DIRECTIONS_AND_NULL; static { @@ -62,11 +71,12 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel { System.arraycopy(values, 0, DIRECTIONS_AND_NULL, 0, values.length); } - protected final ConcurrentMap jsonToMesh = new ConcurrentHashMap<>(); - - protected Mesh getBaseMesh(BlockState state) { + protected Mesh getBaseMesh(Object key, BlockState state) { //Convert models to re-texturable Meshes lazily, the first time we encounter each blockstate - return jsonToMesh.computeIfAbsent(state, this::convertModel); + if (BASE_MESH_CACHE.containsKey(key)) return BASE_MESH_CACHE.getAndMoveToFirst(key); + Mesh mesh = convertModel(state); + BASE_MESH_CACHE.putAndMoveToFirst(key, mesh); + return mesh; } protected abstract Mesh convertModel(BlockState state); @@ -78,39 +88,42 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel { @Override public Sprite getParticleSprite() { - return tam.getDefaultAppearance(theme_index).getSprites(Direction.UP, 0).get(0).sprite(); + return appearance_manager.getDefaultAppearance(theme_index).getSprites(Direction.UP, 0).get(0).sprite(); } @Override public void emitBlockQuads(BlockRenderView world, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context) { + // skip render if block not a frame (which should always be the case + if (!(state.getBlock() instanceof ReFramedBlock frame_block)) return; BlockState theme = (world.getBlockEntity(pos) instanceof ThemeableBlockEntity s) ? s.getTheme(theme_index) : null; QuadEmitter quad_emitter = context.getEmitter(); if(theme == null || theme.isAir()) { - getUntintedRetexturedMesh(new MeshCacheKey(state, new TransformCacheKey(tam.getDefaultAppearance(theme_index), 0)), 0).outputTo(quad_emitter); + getRetexturedMesh( + new MeshCacheKey( + frame_block.getModelCacheKey(state), + appearance_manager.getDefaultAppearance(theme_index), + 0 + ), + state + ).outputTo(quad_emitter); return; } if(theme.getBlock() == Blocks.BARRIER) return; - CamoAppearance camo = tam.getCamoAppearance(world, theme, pos, theme_index); + CamoAppearance camo = appearance_manager.getCamoAppearance(world, theme, pos, theme_index); long seed = theme.getRenderingSeed(pos); int model_id = 0; if (camo instanceof WeightedComputedAppearance wca) model_id = wca.getAppearanceIndex(seed); - + int tint = 0xFF000000 | MinecraftClient.getInstance().getBlockColors().getColor(theme, world, pos, 0); - Mesh untintedMesh = getUntintedRetexturedMesh( - new MeshCacheKey( - state, - new TransformCacheKey(camo, model_id) - ), - seed - ); + Mesh untintedMesh = getRetexturedMesh(new MeshCacheKey(frame_block.getModelCacheKey(state), camo, model_id), state); //The specific tint might vary a lot; imagine grass color smoothly changing. Trying to bake the tint into //the cached mesh will pollute it with a ton of single-use meshes with only slightly different colors. if(tint == 0xFFFFFFFF) { untintedMesh.outputTo(quad_emitter); } else { - context.pushTransform(new TintingTransformer(camo, tint, seed)); + context.pushTransform(new TintingTransformer(camo, model_id, tint)); untintedMesh.outputTo(quad_emitter); context.popTransform(); } @@ -120,121 +133,68 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel { public void emitItemQuads(ItemStack stack, Supplier randomSupplier, RenderContext context) { //cheeky: if the item has NBT data, pluck out the blockstate from it & look up the item color provider //none of this is accessible unless you're in creative mode doing ctrl-pick btw - CamoAppearance nbtAppearance; + CamoAppearance appearance; int tint; BlockState theme = ReFramedEntity.readStateFromItem(stack, theme_index); if(!theme.isAir()) { - nbtAppearance = tam.getCamoAppearance(null, theme, null, theme_index); + appearance = appearance_manager.getCamoAppearance(null, theme, null, theme_index); tint = 0xFF000000 | ((MinecraftAccessor) MinecraftClient.getInstance()).getItemColors().getColor(new ItemStack(theme.getBlock()), 0); } else { - nbtAppearance = tam.getDefaultAppearance(theme_index); + appearance = appearance_manager.getDefaultAppearance(theme_index); tint = 0xFFFFFFFF; } - Mesh untintedMesh = getUntintedRetexturedMesh(new MeshCacheKey(item_state, new TransformCacheKey(nbtAppearance, 0)), 0); + Mesh untintedMesh = getRetexturedMesh(new MeshCacheKey("I", appearance, 0), item_state); QuadEmitter quad_emitter = context.getEmitter(); if(tint == 0xFFFFFFFF) { untintedMesh.outputTo(quad_emitter); } else { - context.pushTransform(new TintingTransformer(nbtAppearance, tint, 0)); + context.pushTransform(new TintingTransformer(appearance, 0, tint)); untintedMesh.outputTo(quad_emitter); context.popTransform(); } } - protected Mesh getUntintedRetexturedMesh(MeshCacheKey key, long seed) { - return retextured_meshes.computeIfAbsent(key, (k) -> createUntintedRetexturedMesh(k, seed)); + protected Mesh getRetexturedMesh(MeshCacheKey key, BlockState state) { + if (RETEXTURED_MESH_CACHE.containsKey(key)) return RETEXTURED_MESH_CACHE.getAndMoveToFirst(key); + Mesh mesh = transformMesh(key, state); + RETEXTURED_MESH_CACHE.putAndMoveToFirst(key, mesh); + return mesh; } - protected Mesh createUntintedRetexturedMesh(MeshCacheKey key, long seed) { - RetexturingTransformer transformer = retextured_transforms.computeIfAbsent(key.transform, (k) -> new RetexturingTransformer(k.appearance, seed)); - return pretransformMesh(getBaseMesh(key.state), transformer); - } - - private static Mesh pretransformMesh(Mesh mesh, RetexturingTransformer transform) { + protected Mesh transformMesh(MeshCacheKey key, BlockState state) { MeshBuilder builder = ReFramedClient.HELPER.getFabricRenderer().meshBuilder(); QuadEmitter emitter = builder.getEmitter(); - mesh.forEach(quad -> { + getBaseMesh(key.state_key, state).forEach(quad -> { int i = -1; do { emitter.copyFrom(quad); - i = transform.transform(emitter, i); + i = key.appearance.transformQuad(emitter, i, key.model_id, ao, uv_lock); } while (i > 0); }); return builder.build(); } - - public class RetexturingTransformer { - private final long seed; - protected RetexturingTransformer(CamoAppearance ta, long seed) { - this.ta = ta; - this.seed = seed; - } - - protected final CamoAppearance ta; - public int transform(QuadEmitter quad, int i) { - if(quad.tag() == 0) return 0; //Pass the quad through unmodified. - - Direction direction = quad.nominalFace(); - List sprites = ta.getSprites(direction, seed); - if (i == -1) i = sprites.size(); - - SpriteProperties properties = sprites.get(sprites.size() - i); - i--; - QuadPosBounds bounds = properties.bounds(); - - if (bounds == null) { // sprite applies anywhere e.g. default behaviour - quad.material(ta.getRenderMaterial(ao)); - quad.spriteBake( - properties.sprite(), - MutableQuadView.BAKE_NORMALIZED - | properties.flags() - | (uv_lock ? MutableQuadView.BAKE_LOCK_UV : 0) - ); - quad.tag(i+1); - quad.emit(); - return i; - } - - // verify if sprite covers the current quad and apply the new size - QuadPosBounds origin_bounds = QuadPosBounds.read(quad, false); - if (!bounds.matches(origin_bounds)) return i; - - // apply new quad shape - quad.material(ta.getRenderMaterial(ao)); - bounds.intersection(origin_bounds, direction.getAxis()).apply(quad, origin_bounds); - quad.spriteBake( // seems to work without the flags and break with it - properties.sprite(), - MutableQuadView.BAKE_NORMALIZED - | MutableQuadView.BAKE_LOCK_UV - ); - quad.tag(i+1); - quad.emit(); - return i; - } - } - protected static class TintingTransformer implements RenderContext.QuadTransform { - private final long seed; - protected TintingTransformer(CamoAppearance ta, int tint, long seed) { - this.ta = ta; + private final CamoAppearance appearance; + private final int model_id; + private final int tint; + + protected TintingTransformer(CamoAppearance appearance, int model_id, int tint) { + this.appearance = appearance; + this.model_id = model_id; this.tint = tint; - this.seed = seed; } - - protected final CamoAppearance ta; - protected final int tint; - + @Override public boolean transform(MutableQuadView quad) { if(quad.tag() == 0) return true; - if(ta.hasColor(quad.nominalFace(), seed, quad.tag())) quad.color(tint, tint, tint, tint); - + if(appearance.hasColor(quad.nominalFace(), model_id, quad.tag())) quad.color(tint, tint, tint, tint); + return true; } } diff --git a/src/main/java/fr/adrien1106/reframed/client/model/UnbakedAutoRetexturedModel.java b/src/main/java/fr/adrien1106/reframed/client/model/UnbakedAutoRetexturedModel.java index dba3f74..b789e9f 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/UnbakedAutoRetexturedModel.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/UnbakedAutoRetexturedModel.java @@ -43,7 +43,7 @@ public class UnbakedAutoRetexturedModel extends UnbakedRetexturedModel { Renderer r = ReFramedClient.HELPER.getFabricRenderer(); MeshBuilder builder = r.meshBuilder(); QuadEmitter emitter = builder.getEmitter(); - RenderMaterial mat = tam.getCachedMaterial(state, false); + RenderMaterial mat = appearance_manager.getCachedMaterial(state, false); Random rand = Random.create(42); diff --git a/src/main/java/fr/adrien1106/reframed/client/model/UnbakedJsonRetexturedModel.java b/src/main/java/fr/adrien1106/reframed/client/model/UnbakedJsonRetexturedModel.java index 914ce00..48e5617 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/UnbakedJsonRetexturedModel.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/UnbakedJsonRetexturedModel.java @@ -51,7 +51,7 @@ public class UnbakedJsonRetexturedModel extends UnbakedRetexturedModel { Renderer r = ReFramedClient.HELPER.getFabricRenderer(); MeshBuilder builder = r.meshBuilder(); QuadEmitter emitter = builder.getEmitter(); - RenderMaterial mat = tam.getCachedMaterial(state, false); + RenderMaterial mat = appearance_manager.getCachedMaterial(state, false); Random rand = Random.create(42); diff --git a/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearance.java b/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearance.java index ad219e5..1e71f1b 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearance.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearance.java @@ -1,13 +1,76 @@ package fr.adrien1106.reframed.client.model.apperance; +import fr.adrien1106.reframed.client.model.QuadPosBounds; import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; +import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; import net.minecraft.util.math.Direction; import org.jetbrains.annotations.NotNull; import java.util.List; -public interface CamoAppearance { - @NotNull RenderMaterial getRenderMaterial(boolean ao); - @NotNull List getSprites(Direction dir, long seed); - boolean hasColor(Direction dir, long seed, int index); +public abstract class CamoAppearance { + protected final int id; + protected final RenderMaterial ao_material; + protected final RenderMaterial material; + + protected CamoAppearance(RenderMaterial ao_material, RenderMaterial material, int id) { + this.id = id; + + this.ao_material = ao_material; + this.material = material; + } + + public abstract @NotNull List getSprites(Direction dir, int model_id); + public abstract boolean hasColor(Direction dir, int model_id, int index); + + public @NotNull RenderMaterial getRenderMaterial(boolean ao) { + return ao && ao_material != null? ao_material : material; + } + + public int transformQuad(QuadEmitter quad, int i, int model_id, boolean ao, boolean uv_lock) { + if(quad.tag() == 0) return 0; // Pass the quad through unmodified. + + Direction direction = quad.nominalFace(); + List sprites = getSprites(direction, model_id); + if (i == -1) i = sprites.size(); + + SpriteProperties properties = sprites.get(sprites.size() - i); + i--; + QuadPosBounds bounds = properties.bounds(); + + if (bounds == null) { // sprite applies anywhere e.g. default behaviour + quad.material(getRenderMaterial(ao)); + quad.spriteBake( + properties.sprite(), + MutableQuadView.BAKE_NORMALIZED + | properties.flags() + | (uv_lock ? MutableQuadView.BAKE_LOCK_UV : 0) + ); + quad.tag(i+1); + quad.emit(); + return i; + } + + // verify if sprite covers the current quad and apply the new size + QuadPosBounds origin_bounds = QuadPosBounds.read(quad, false); + if (!bounds.matches(origin_bounds)) return i; + + // apply new quad shape + quad.material(getRenderMaterial(ao)); + bounds.intersection(origin_bounds, direction.getAxis()).apply(quad, origin_bounds); + quad.spriteBake( // seems to work without the flags and break with it + properties.sprite(), + MutableQuadView.BAKE_NORMALIZED + | MutableQuadView.BAKE_LOCK_UV + ); + quad.tag(i+1); + quad.emit(); + return i; + } + + @Override + public int hashCode() { + return id; + } } diff --git a/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearanceManager.java b/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearanceManager.java index 949545b..ce7515f 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearanceManager.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/apperance/CamoAppearanceManager.java @@ -5,6 +5,7 @@ import fr.adrien1106.reframed.client.ReFramedClient; import fr.adrien1106.reframed.client.model.DynamicBakedModel; import fr.adrien1106.reframed.client.model.QuadPosBounds; import fr.adrien1106.reframed.mixin.model.WeightedBakedModelAccessor; +import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap; import net.fabricmc.fabric.api.renderer.v1.Renderer; import net.fabricmc.fabric.api.renderer.v1.material.BlendMode; import net.fabricmc.fabric.api.renderer.v1.material.MaterialFinder; @@ -29,7 +30,6 @@ import net.minecraft.util.math.random.Random; import net.minecraft.world.BlockRenderView; import java.util.*; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; @@ -40,20 +40,20 @@ public class CamoAppearanceManager { for(BlendMode blend : BlendMode.values()) { finder.clear().disableDiffuse(false).blendMode(blend); - materialsWithoutAo.put(blend, finder.ambientOcclusion(TriState.FALSE).find()); - materialsWithAo.put(blend, finder.ambientOcclusion(TriState.DEFAULT).find()); //not "true" since that *forces* AO, i just want to *allow* AO + materials.put(blend, finder.ambientOcclusion(TriState.FALSE).find()); + ao_materials.put(blend, finder.ambientOcclusion(TriState.DEFAULT).find()); //not "true" since that *forces* AO, i just want to *allow* AO } Sprite sprite = spriteLookup.apply(DEFAULT_SPRITE_MAIN); if(sprite == null) throw new IllegalStateException("Couldn't locate " + DEFAULT_SPRITE_MAIN + " !"); - this.default_appearance = new SingleSpriteAppearance(sprite, materialsWithoutAo.get(BlendMode.CUTOUT), serial_number.getAndIncrement()); + this.default_appearance = new SingleSpriteAppearance(sprite, materials.get(BlendMode.CUTOUT), serial_number.getAndIncrement()); sprite = spriteLookup.apply(DEFAULT_SPRITE_SECONDARY); if(sprite == null) throw new IllegalStateException("Couldn't locate " + DEFAULT_SPRITE_MAIN + " !"); - this.accent_appearance = new SingleSpriteAppearance(sprite, materialsWithoutAo.get(BlendMode.CUTOUT), serial_number.getAndIncrement()); + this.accent_appearance = new SingleSpriteAppearance(sprite, materials.get(BlendMode.CUTOUT), serial_number.getAndIncrement()); sprite = spriteLookup.apply(BARRIER_SPRITE_ID); - this.barrierItemAppearance = new SingleSpriteAppearance(sprite, materialsWithoutAo.get(BlendMode.CUTOUT), serial_number.getAndIncrement()); + this.barrierItemAppearance = new SingleSpriteAppearance(sprite, materials.get(BlendMode.CUTOUT), serial_number.getAndIncrement()); } protected static final SpriteIdentifier DEFAULT_SPRITE_MAIN = new SpriteIdentifier(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, new Identifier(ReFramed.MODID, "block/framed_block")); @@ -63,12 +63,16 @@ public class CamoAppearanceManager { private final CamoAppearance default_appearance; private final CamoAppearance accent_appearance; private final CamoAppearance barrierItemAppearance; - - private final ConcurrentHashMap appearanceCache = new ConcurrentHashMap<>(); //Mutable, append-only cache + + private static final Object2ObjectLinkedOpenHashMap APPEARANCE_CACHE = + new Object2ObjectLinkedOpenHashMap<>(2048, 0.25f) { + @Override + protected void rehash(int n) {} + }; private final AtomicInteger serial_number = new AtomicInteger(0); //Mutable - private final EnumMap materialsWithAo = new EnumMap<>(BlendMode.class); - private final EnumMap materialsWithoutAo = new EnumMap<>(BlendMode.class); //Immutable contents + private final EnumMap ao_materials = new EnumMap<>(BlendMode.class); + private final EnumMap materials = new EnumMap<>(BlendMode.class); //Immutable contents public CamoAppearance getDefaultAppearance(int appearance) { return appearance == 2 ? accent_appearance: default_appearance; @@ -81,11 +85,17 @@ public class CamoAppearanceManager { if (model instanceof DynamicBakedModel dynamic_model) { return computeAppearance(dynamic_model.computeQuads(world, state, pos, theme_index), state); } - return appearanceCache.computeIfAbsent(state, block_state -> computeAppearance(model, block_state)); + + // refresh cache + if (APPEARANCE_CACHE.containsKey(state)) return APPEARANCE_CACHE.getAndMoveToFirst(state); + + CamoAppearance appearance = computeAppearance(model, state); + APPEARANCE_CACHE.putAndMoveToFirst(state, appearance); + return appearance; } public RenderMaterial getCachedMaterial(BlockState state, boolean ao) { - Map m = ao ? materialsWithAo : materialsWithoutAo; + Map m = ao ? ao_materials : materials; return m.get(BlendMode.fromRenderLayer(RenderLayers.getBlockLayer(state))); } diff --git a/src/main/java/fr/adrien1106/reframed/client/model/apperance/ComputedAppearance.java b/src/main/java/fr/adrien1106/reframed/client/model/apperance/ComputedAppearance.java index 52ccee0..24c0806 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/apperance/ComputedAppearance.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/apperance/ComputedAppearance.java @@ -6,33 +6,22 @@ import org.jetbrains.annotations.NotNull; import java.util.List; -public class ComputedAppearance implements CamoAppearance { +public class ComputedAppearance extends CamoAppearance { private final Appearance appearance; - private final int id; - private final RenderMaterial matWithAo; - private final RenderMaterial matWithoutAo; - public ComputedAppearance(@NotNull Appearance appearance, RenderMaterial withAo, RenderMaterial withoutAo, int id) { + public ComputedAppearance(@NotNull Appearance appearance, RenderMaterial ao_material, RenderMaterial material, int id) { + super(ao_material, material, id); this.appearance = appearance; - this.id = id; - - this.matWithAo = withAo; - this.matWithoutAo = withoutAo; } @Override - public @NotNull RenderMaterial getRenderMaterial(boolean ao) { - return ao ? matWithAo : matWithoutAo; - } - - @Override - public @NotNull List getSprites(Direction dir, long seed) { + public @NotNull List getSprites(Direction dir, int model_id) { return appearance.sprites().get(dir); } @Override - public boolean hasColor(Direction dir, long seed, int index) { - List properties = getSprites(dir, seed); + public boolean hasColor(Direction dir, int model_id, int index) { + List properties = getSprites(dir, model_id); if (index != 0) index = properties.size() - index; return properties.get(index).has_colors(); } @@ -40,13 +29,7 @@ public class ComputedAppearance implements CamoAppearance { @Override public boolean equals(Object o) { if(this == o) return true; - if(o == null || getClass() != o.getClass()) return false; - ComputedAppearance that = (ComputedAppearance) o; + if(!(o instanceof ComputedAppearance that)) return false; return id == that.id; } - - @Override - public int hashCode() { - return id; - } } diff --git a/src/main/java/fr/adrien1106/reframed/client/model/apperance/SingleSpriteAppearance.java b/src/main/java/fr/adrien1106/reframed/client/model/apperance/SingleSpriteAppearance.java index d62e38f..9e384b9 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/apperance/SingleSpriteAppearance.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/apperance/SingleSpriteAppearance.java @@ -7,47 +7,33 @@ import org.jetbrains.annotations.NotNull; import java.util.List; -public class SingleSpriteAppearance implements CamoAppearance { +public class SingleSpriteAppearance extends CamoAppearance { private final @NotNull Sprite defaultSprite; - private final RenderMaterial mat; - private final int id; public SingleSpriteAppearance(@NotNull Sprite defaultSprite, RenderMaterial mat, int id) { + super(null, mat, id); this.defaultSprite = defaultSprite; - this.mat = mat; - this.id = id; } @Override - public @NotNull RenderMaterial getRenderMaterial(boolean ao) { - return mat; - } - - @Override - public @NotNull List getSprites(Direction dir, long seed) { + public @NotNull List getSprites(Direction dir, int model_id) { return List.of(new SpriteProperties(defaultSprite, 0, null, false)); } @Override - public boolean hasColor(Direction dir, long seed, int index) { + public boolean hasColor(Direction dir, int model_id, int index) { return false; } @Override public boolean equals(Object o) { if(this == o) return true; - if(o == null || getClass() != o.getClass()) return false; - SingleSpriteAppearance that = (SingleSpriteAppearance) o; + if(!(o instanceof SingleSpriteAppearance that)) return false; return id == that.id; } - @Override - public int hashCode() { - return id; - } - @Override public String toString() { - return "SingleSpriteAppearance[defaultSprite=%s, mat=%s, id=%d]".formatted(defaultSprite, mat, id); + return "SingleSpriteAppearance[defaultSprite=%s, mat=%s, id=%d]".formatted(defaultSprite, material, id); } } diff --git a/src/main/java/fr/adrien1106/reframed/client/model/apperance/WeightedComputedAppearance.java b/src/main/java/fr/adrien1106/reframed/client/model/apperance/WeightedComputedAppearance.java index 4751711..b3c3b73 100644 --- a/src/main/java/fr/adrien1106/reframed/client/model/apperance/WeightedComputedAppearance.java +++ b/src/main/java/fr/adrien1106/reframed/client/model/apperance/WeightedComputedAppearance.java @@ -9,25 +9,14 @@ import org.jetbrains.annotations.NotNull; import java.util.List; -public class WeightedComputedAppearance implements CamoAppearance { +public class WeightedComputedAppearance extends CamoAppearance { private final List> appearances; private final int total_weight; - private final int id; - private final RenderMaterial matWithAo; - private final RenderMaterial matWithoutAo; - public WeightedComputedAppearance(@NotNull List> appearances, RenderMaterial withAo, RenderMaterial withoutAo, int id) { + public WeightedComputedAppearance(@NotNull List> appearances, RenderMaterial ao_material, RenderMaterial material, int id) { + super(ao_material, material, id); this.appearances = appearances; this.total_weight = Weighting.getWeightSum(appearances); - this.id = id; - - this.matWithAo = withAo; - this.matWithoutAo = withoutAo; - } - - @Override - public @NotNull RenderMaterial getRenderMaterial(boolean ao) { - return ao ? matWithAo : matWithoutAo; } @@ -37,21 +26,19 @@ public class WeightedComputedAppearance implements CamoAppearance { .map(appearances::indexOf).orElse(0); } - private Appearance getAppearance(long seed) { - Random random = Random.create(seed); - return Weighting.getAt(appearances, Math.abs((int)random.nextLong()) % total_weight) - .map(Weighted.Present::getData).get(); + private Appearance getAppearance(int model_id) { + return appearances.get(model_id).getData(); } @Override - public @NotNull List getSprites(Direction dir, long seed) { - return getAppearance(seed).sprites().get(dir); + public @NotNull List getSprites(Direction dir, int model_id) { + return getAppearance(model_id).sprites().get(dir); } @Override - public boolean hasColor(Direction dir, long seed, int index) { - List properties = getSprites(dir, seed); + public boolean hasColor(Direction dir, int model_id, int index) { + List properties = getSprites(dir, model_id); if (index != 0) index = properties.size() - index; return properties.get(index).has_colors(); } @@ -59,13 +46,7 @@ public class WeightedComputedAppearance implements CamoAppearance { @Override public boolean equals(Object o) { if(this == o) return true; - if(o == null || getClass() != o.getClass()) return false; - WeightedComputedAppearance that = (WeightedComputedAppearance) o; + if(!(o instanceof WeightedComputedAppearance that)) return false; return id == that.id; } - - @Override - public int hashCode() { - return id; - } } diff --git a/src/main/java/fr/adrien1106/reframed/mixin/BlockItemMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/BlockItemMixin.java index 6db8bd1..c233590 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/BlockItemMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/BlockItemMixin.java @@ -41,6 +41,7 @@ public class BlockItemMixin { || !Block.isShapeFullCube(block.getBlock().getDefaultState().getCollisionShape(world, pos)) ) return; NbtCompound new_comp = new NbtCompound(); + player.getOffHandStack().decrement(1); new_comp.put(BLOCKSTATE_KEY + 1, NbtHelper.fromBlockState(block.getBlock().getDefaultState())); compound.set(new_comp); } diff --git a/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaBakedModelMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaBakedModelMixin.java index ba6833d..aac9f62 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaBakedModelMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaBakedModelMixin.java @@ -6,7 +6,7 @@ import earth.terrarium.athena.api.client.models.AthenaBlockModel; import fr.adrien1106.reframed.client.ReFramedClient; import fr.adrien1106.reframed.client.model.DynamicBakedModel; import fr.adrien1106.reframed.compat.RebakedAthenaModel; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import net.fabricmc.fabric.api.renderer.v1.Renderer; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaConnectedBlockModelMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaConnectedBlockModelMixin.java index efc633b..ce1e96c 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaConnectedBlockModelMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaConnectedBlockModelMixin.java @@ -3,7 +3,7 @@ package fr.adrien1106.reframed.mixin.compat; import earth.terrarium.athena.api.client.utils.AppearanceAndTintGetter; import earth.terrarium.athena.api.client.utils.CtmUtils; import earth.terrarium.athena.impl.client.models.ConnectedBlockModel; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaWrappedGetterMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaWrappedGetterMixin.java index 73e1ea7..bb31415 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaWrappedGetterMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/compat/AthenaWrappedGetterMixin.java @@ -2,7 +2,7 @@ package fr.adrien1106.reframed.mixin.compat; import com.llamalad7.mixinextras.sugar.Local; import earth.terrarium.athena.api.client.fabric.WrappedGetter; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; import net.minecraft.world.BlockRenderView; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainBlockRenderInfoMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainBlockRenderInfoMixin.java index 4f6ec46..6922006 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainBlockRenderInfoMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainBlockRenderInfoMixin.java @@ -1,8 +1,8 @@ package fr.adrien1106.reframed.mixin.compat; -import fr.adrien1106.reframed.util.BlockHelper; -import fr.adrien1106.reframed.util.IBlockRenderInfoMixin; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import link.infra.indium.renderer.render.BlockRenderInfo; import link.infra.indium.renderer.render.TerrainBlockRenderInfo; import me.jellysquid.mods.sodium.client.render.chunk.compile.pipeline.BlockOcclusionCache; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainRenderContextMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainRenderContextMixin.java index c7ebd61..fcbce7f 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainRenderContextMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/compat/IndiumTerrainRenderContextMixin.java @@ -1,11 +1,12 @@ package fr.adrien1106.reframed.mixin.compat; import fr.adrien1106.reframed.client.model.MultiRetexturableModel; -import fr.adrien1106.reframed.util.IBlockRenderInfoMixin; -import fr.adrien1106.reframed.util.IMultipartBakedModelMixin; +import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin; +import fr.adrien1106.reframed.util.mixin.IMultipartBakedModelMixin; import link.infra.indium.renderer.render.AbstractBlockRenderContext; import link.infra.indium.renderer.render.TerrainRenderContext; import me.jellysquid.mods.sodium.client.render.chunk.compile.pipeline.BlockRenderContext; +import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel; import net.minecraft.client.render.model.BakedModel; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -29,13 +30,13 @@ public abstract class IndiumTerrainRenderContextMixin extends AbstractBlockRende if (!(ctx.model() instanceof IMultipartBakedModelMixin wrapped) || !(wrapped.getModel(ctx.state()) instanceof MultiRetexturableModel retexturing_model)) return; - List models = retexturing_model.models(); + List models = retexturing_model.models(); int i = 0; - for (BakedModel bakedModel : models) { + for (BakedModel model : models) { i++; aoCalc.clear(); - ((IBlockRenderInfoMixin) blockInfo).prepareForBlock(ctx.state(), ctx.pos(), ctx.seed(), bakedModel.useAmbientOcclusion(), i); - bakedModel.emitBlockQuads(blockInfo.blockView, blockInfo.blockState, blockInfo.blockPos, blockInfo.randomSupplier, this); + ((IBlockRenderInfoMixin) blockInfo).prepareForBlock(ctx.state(), ctx.pos(), ctx.seed(), model.useAmbientOcclusion(), i); + model.emitBlockQuads(blockInfo.blockView, blockInfo.blockState, blockInfo.blockPos, blockInfo.randomSupplier, this); } ci.cancel(); } diff --git a/src/main/java/fr/adrien1106/reframed/mixin/compat/SodiumBlockOcclusionCacheMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/compat/SodiumBlockOcclusionCacheMixin.java index 437f8a7..3e6c28d 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/compat/SodiumBlockOcclusionCacheMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/compat/SodiumBlockOcclusionCacheMixin.java @@ -1,8 +1,8 @@ package fr.adrien1106.reframed.mixin.compat; import com.llamalad7.mixinextras.sugar.Local; -import fr.adrien1106.reframed.util.BlockHelper; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import me.jellysquid.mods.sodium.client.render.chunk.compile.pipeline.BlockOcclusionCache; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinBlockDustParticle.java b/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinBlockDustParticle.java index 5348a91..95e03c0 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinBlockDustParticle.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinBlockDustParticle.java @@ -1,7 +1,7 @@ package fr.adrien1106.reframed.mixin.particles; import fr.adrien1106.reframed.block.ReFramedBlock; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.client.MinecraftClient; import net.minecraft.client.particle.BlockDustParticle; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinEntity.java b/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinEntity.java index bbba8fb..bb1afd1 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinEntity.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinEntity.java @@ -2,7 +2,7 @@ package fr.adrien1106.reframed.mixin.particles; import com.llamalad7.mixinextras.sugar.Local; import fr.adrien1106.reframed.block.ReFramedBlock; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; import net.minecraft.util.math.BlockPos; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinLivingEntity.java b/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinLivingEntity.java index d19193f..13dba79 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinLivingEntity.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/particles/MixinLivingEntity.java @@ -2,7 +2,7 @@ package fr.adrien1106.reframed.mixin.particles; import com.llamalad7.mixinextras.sugar.Local; import fr.adrien1106.reframed.block.ReFramedBlock; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/render/BlockRenderInfoMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/render/BlockRenderInfoMixin.java index 059fb1c..ee4a624 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/render/BlockRenderInfoMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/render/BlockRenderInfoMixin.java @@ -1,9 +1,9 @@ package fr.adrien1106.reframed.mixin.render; import com.llamalad7.mixinextras.sugar.Local; -import fr.adrien1106.reframed.util.BlockHelper; -import fr.adrien1106.reframed.util.IBlockRenderInfoMixin; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.BlockHelper; +import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.fabricmc.fabric.impl.client.indigo.renderer.render.BlockRenderInfo; import net.minecraft.block.BlockState; import net.minecraft.block.entity.BlockEntity; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/render/MultipartBakedModelMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/render/MultipartBakedModelMixin.java index 86c1819..2183590 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/render/MultipartBakedModelMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/render/MultipartBakedModelMixin.java @@ -1,6 +1,6 @@ package fr.adrien1106.reframed.mixin.render; -import fr.adrien1106.reframed.util.IMultipartBakedModelMixin; +import fr.adrien1106.reframed.util.mixin.IMultipartBakedModelMixin; import net.minecraft.block.BlockState; import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.render.model.MultipartBakedModel; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/render/TerrainRenderContextMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/render/TerrainRenderContextMixin.java index 18eac23..37677d5 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/render/TerrainRenderContextMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/render/TerrainRenderContextMixin.java @@ -1,8 +1,9 @@ package fr.adrien1106.reframed.mixin.render; import fr.adrien1106.reframed.client.model.MultiRetexturableModel; -import fr.adrien1106.reframed.util.IBlockRenderInfoMixin; -import fr.adrien1106.reframed.util.IMultipartBakedModelMixin; +import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin; +import fr.adrien1106.reframed.util.mixin.IMultipartBakedModelMixin; +import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel; import net.fabricmc.fabric.impl.client.indigo.renderer.render.AbstractBlockRenderContext; import net.fabricmc.fabric.impl.client.indigo.renderer.render.TerrainRenderContext; import net.minecraft.block.BlockState; @@ -28,13 +29,18 @@ public abstract class TerrainRenderContextMixin extends AbstractBlockRenderConte if (!(wrapper instanceof IMultipartBakedModelMixin wrapped) || !(wrapped.getModel(state) instanceof MultiRetexturableModel retexturing_model)) return; - List models = retexturing_model.models(); + List models = retexturing_model.models(); +// models.forEach(model -> // TODO self culling here +// model.getWrappedModel().getQuads(state_key, null, blockInfo.randomSupplier.get()) +// .forEach(quad -> QuadPosBounds.read(getEmitter().fromVanilla(quad.getVertexData(), 0)).min_x()) +// ); int i = 0; - for (BakedModel bakedModel : models) { + for (BakedModel model : models) { i++; aoCalc.clear(); - ((IBlockRenderInfoMixin) blockInfo).prepareForBlock(state, pos, bakedModel.useAmbientOcclusion(), i); - bakedModel.emitBlockQuads(blockInfo.blockView, blockInfo.blockState, blockInfo.blockPos, blockInfo.randomSupplier, this); + // TODO if (state_key.getBlock() instanceof ReFramedDoubleBlock frame_block) frame_block.getRenderOutline(i); + ((IBlockRenderInfoMixin) blockInfo).prepareForBlock(state, pos, model.useAmbientOcclusion(), i); + model.emitBlockQuads(blockInfo.blockView, blockInfo.blockState, blockInfo.blockPos, blockInfo.randomSupplier, this); } ci.cancel(); } diff --git a/src/main/java/fr/adrien1106/reframed/mixin/sound/BlockItemMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/sound/BlockItemMixin.java index 2ee7502..739adde 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/sound/BlockItemMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/sound/BlockItemMixin.java @@ -2,7 +2,7 @@ package fr.adrien1106.reframed.mixin.sound; import com.llamalad7.mixinextras.sugar.Local; import fr.adrien1106.reframed.block.ReFramedBlock; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.item.BlockItem; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/sound/EntityMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/sound/EntityMixin.java index d00f353..ab882df 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/sound/EntityMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/sound/EntityMixin.java @@ -2,7 +2,7 @@ package fr.adrien1106.reframed.mixin.sound; import com.llamalad7.mixinextras.sugar.Local; import fr.adrien1106.reframed.block.ReFramedBlock; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.entity.Entity; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/sound/LivingEntityMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/sound/LivingEntityMixin.java index 1d63f6a..ffcd7c9 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/sound/LivingEntityMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/sound/LivingEntityMixin.java @@ -1,7 +1,7 @@ package fr.adrien1106.reframed.mixin.sound; import fr.adrien1106.reframed.block.ReFramedBlock; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.entity.LivingEntity; diff --git a/src/main/java/fr/adrien1106/reframed/mixin/sound/WorldRendererMixin.java b/src/main/java/fr/adrien1106/reframed/mixin/sound/WorldRendererMixin.java index 8d2b11d..7f22f6c 100644 --- a/src/main/java/fr/adrien1106/reframed/mixin/sound/WorldRendererMixin.java +++ b/src/main/java/fr/adrien1106/reframed/mixin/sound/WorldRendererMixin.java @@ -2,7 +2,7 @@ package fr.adrien1106.reframed.mixin.sound; import com.llamalad7.mixinextras.sugar.Local; import fr.adrien1106.reframed.block.ReFramedBlock; -import fr.adrien1106.reframed.util.ThemeableBlockEntity; +import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.client.render.WorldRenderer; diff --git a/src/main/java/fr/adrien1106/reframed/util/BlockHelper.java b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java similarity index 93% rename from src/main/java/fr/adrien1106/reframed/util/BlockHelper.java rename to src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java index ca18ffb..a1eea54 100644 --- a/src/main/java/fr/adrien1106/reframed/util/BlockHelper.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockHelper.java @@ -1,9 +1,8 @@ -package fr.adrien1106.reframed.util; +package fr.adrien1106.reframed.util.blocks; import fr.adrien1106.reframed.block.ReFramedBlock; import fr.adrien1106.reframed.block.ReFramedEntity; -import fr.adrien1106.reframed.util.property.Corner; -import fr.adrien1106.reframed.util.property.StairShape; +import it.unimi.dsi.fastutil.objects.Object2ByteLinkedOpenHashMap; import net.minecraft.block.Block; import net.minecraft.block.BlockEntityProvider; import net.minecraft.block.BlockState; @@ -30,13 +29,25 @@ import java.util.Map; import java.util.stream.Collectors; import java.util.stream.Stream; -import static fr.adrien1106.reframed.util.BlockProperties.CORNER; -import static fr.adrien1106.reframed.util.BlockProperties.LIGHT; -import static fr.adrien1106.reframed.util.property.StairShape.*; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.CORNER; +import static fr.adrien1106.reframed.util.blocks.BlockProperties.LIGHT; +import static fr.adrien1106.reframed.util.blocks.StairShape.*; import static net.minecraft.util.shape.VoxelShapes.combine; public class BlockHelper { + // self culling cache TODO move + private static final ThreadLocal> INNER_FACE_CULL_MAP = ThreadLocal.withInitial(() -> { + Object2ByteLinkedOpenHashMap object2ByteLinkedOpenHashMap = new Object2ByteLinkedOpenHashMap<>(2048, 0.25F) { + protected void rehash(int newN) { + } + }; + object2ByteLinkedOpenHashMap.defaultReturnValue((byte)0); + return object2ByteLinkedOpenHashMap; + }); + + private record CullElement(BlockState state, int model, Direction side) {} + public static Corner getPlacementCorner(ItemPlacementContext ctx) { Direction side = ctx.getSide().getOpposite(); Vec3d pos = getHitPos(ctx.getHitPos(), ctx.getBlockPos()); diff --git a/src/main/java/fr/adrien1106/reframed/util/BlockProperties.java b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockProperties.java similarity index 74% rename from src/main/java/fr/adrien1106/reframed/util/BlockProperties.java rename to src/main/java/fr/adrien1106/reframed/util/blocks/BlockProperties.java index 11aab58..89d0b8d 100644 --- a/src/main/java/fr/adrien1106/reframed/util/BlockProperties.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/BlockProperties.java @@ -1,7 +1,5 @@ -package fr.adrien1106.reframed.util; +package fr.adrien1106.reframed.util.blocks; -import fr.adrien1106.reframed.util.property.Corner; -import fr.adrien1106.reframed.util.property.StairShape; import net.minecraft.state.property.BooleanProperty; import net.minecraft.state.property.EnumProperty; diff --git a/src/main/java/fr/adrien1106/reframed/util/property/Corner.java b/src/main/java/fr/adrien1106/reframed/util/blocks/Corner.java similarity index 98% rename from src/main/java/fr/adrien1106/reframed/util/property/Corner.java rename to src/main/java/fr/adrien1106/reframed/util/blocks/Corner.java index f95b3d0..6c74e9c 100644 --- a/src/main/java/fr/adrien1106/reframed/util/property/Corner.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/Corner.java @@ -1,4 +1,4 @@ -package fr.adrien1106.reframed.util.property; +package fr.adrien1106.reframed.util.blocks; import net.minecraft.util.StringIdentifiable; import net.minecraft.util.math.Direction; diff --git a/src/main/java/fr/adrien1106/reframed/util/ReframedInteractible.java b/src/main/java/fr/adrien1106/reframed/util/blocks/ReframedInteractible.java similarity index 93% rename from src/main/java/fr/adrien1106/reframed/util/ReframedInteractible.java rename to src/main/java/fr/adrien1106/reframed/util/blocks/ReframedInteractible.java index 13a7e72..4209add 100644 --- a/src/main/java/fr/adrien1106/reframed/util/ReframedInteractible.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/ReframedInteractible.java @@ -1,4 +1,4 @@ -package fr.adrien1106.reframed.util; +package fr.adrien1106.reframed.util.blocks; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; diff --git a/src/main/java/fr/adrien1106/reframed/util/property/StairShape.java b/src/main/java/fr/adrien1106/reframed/util/blocks/StairShape.java similarity index 96% rename from src/main/java/fr/adrien1106/reframed/util/property/StairShape.java rename to src/main/java/fr/adrien1106/reframed/util/blocks/StairShape.java index eef0c51..5019e89 100644 --- a/src/main/java/fr/adrien1106/reframed/util/property/StairShape.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/StairShape.java @@ -1,4 +1,4 @@ -package fr.adrien1106.reframed.util.property; +package fr.adrien1106.reframed.util.blocks; import net.minecraft.util.StringIdentifiable; diff --git a/src/main/java/fr/adrien1106/reframed/util/ThemeableBlockEntity.java b/src/main/java/fr/adrien1106/reframed/util/blocks/ThemeableBlockEntity.java similarity index 82% rename from src/main/java/fr/adrien1106/reframed/util/ThemeableBlockEntity.java rename to src/main/java/fr/adrien1106/reframed/util/blocks/ThemeableBlockEntity.java index 2213826..ace75e0 100644 --- a/src/main/java/fr/adrien1106/reframed/util/ThemeableBlockEntity.java +++ b/src/main/java/fr/adrien1106/reframed/util/blocks/ThemeableBlockEntity.java @@ -1,4 +1,4 @@ -package fr.adrien1106.reframed.util; +package fr.adrien1106.reframed.util.blocks; import net.minecraft.block.BlockState; diff --git a/src/main/java/fr/adrien1106/reframed/util/IBlockRenderInfoMixin.java b/src/main/java/fr/adrien1106/reframed/util/mixin/IBlockRenderInfoMixin.java similarity index 87% rename from src/main/java/fr/adrien1106/reframed/util/IBlockRenderInfoMixin.java rename to src/main/java/fr/adrien1106/reframed/util/mixin/IBlockRenderInfoMixin.java index 69aaeb6..57e8ff4 100644 --- a/src/main/java/fr/adrien1106/reframed/util/IBlockRenderInfoMixin.java +++ b/src/main/java/fr/adrien1106/reframed/util/mixin/IBlockRenderInfoMixin.java @@ -1,4 +1,4 @@ -package fr.adrien1106.reframed.util; +package fr.adrien1106.reframed.util.mixin; import net.minecraft.block.BlockState; import net.minecraft.util.math.BlockPos; diff --git a/src/main/java/fr/adrien1106/reframed/util/IMultipartBakedModelMixin.java b/src/main/java/fr/adrien1106/reframed/util/mixin/IMultipartBakedModelMixin.java similarity index 81% rename from src/main/java/fr/adrien1106/reframed/util/IMultipartBakedModelMixin.java rename to src/main/java/fr/adrien1106/reframed/util/mixin/IMultipartBakedModelMixin.java index 275f01d..8b7a01c 100644 --- a/src/main/java/fr/adrien1106/reframed/util/IMultipartBakedModelMixin.java +++ b/src/main/java/fr/adrien1106/reframed/util/mixin/IMultipartBakedModelMixin.java @@ -1,4 +1,4 @@ -package fr.adrien1106.reframed.util; +package fr.adrien1106.reframed.util.mixin; import net.minecraft.block.BlockState; import net.minecraft.client.render.model.BakedModel;