Compare commits

...

2 Commits

29 changed files with 150 additions and 190 deletions

View File

@ -32,7 +32,6 @@ import static fr.adrien1106.reframed.util.blocks.BlockProperties.LIGHT;
* TODO add minecraft models like wall fence etc -> for v1.6 * TODO add minecraft models like wall fence etc -> for v1.6
* TODO better connected textures -> maybe v1.6 ? * TODO better connected textures -> maybe v1.6 ?
* TODO support continuity overlays -> not scheduled * TODO support continuity overlays -> not scheduled
* TODO better state caching per models (e.g. wall only has 3 max per model) -> not scheduled
*/ */
public class ReFramed implements ModInitializer { public class ReFramed implements ModInitializer {
public static final String MODID = "reframed"; public static final String MODID = "reframed";

View File

@ -52,13 +52,6 @@ public class ReFramedBlock extends Block implements BlockEntityProvider {
public Object getModelCacheKey(BlockState state) { public Object getModelCacheKey(BlockState state) {
return ""; 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 //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 //Just make your own BlockEntityType, it's fine, you can even use the same ReFramedEntity class

View File

@ -41,11 +41,6 @@ public class ReFramedHalfStairBlock extends WaterloggableReFramedBlock {
return new ModelCacheKey(state.get(CORNER), state.get(CORNER_FACE)); return new ModelCacheKey(state.get(CORNER), state.get(CORNER_FACE));
} }
@Override
public int getModelStateCount() {
return 24;
}
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(CORNER,CORNER_FACE)); super.appendProperties(builder.add(CORNER,CORNER_FACE));

View File

@ -34,11 +34,6 @@ public class ReFramedHalfStairsSlabBlock extends WaterloggableReFramedDoubleBloc
return new ModelCacheKey(state.get(CORNER), state.get(CORNER_FACE)); return new ModelCacheKey(state.get(CORNER), state.get(CORNER_FACE));
} }
@Override
public int getModelStateCount() {
return 24;
}
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(CORNER,CORNER_FACE)); super.appendProperties(builder.add(CORNER,CORNER_FACE));

View File

@ -32,11 +32,6 @@ public class ReFramedHalfStairsStairBlock extends WaterloggableReFramedDoubleBlo
return state.get(EDGE); return state.get(EDGE);
} }
@Override
public int getModelStateCount() {
return 12;
}
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(EDGE)); super.appendProperties(builder.add(EDGE));

View File

@ -32,11 +32,6 @@ public class ReFramedLayerBlock extends ReFramedSlabBlock {
return new ModelCacheKey(state.get(FACING), state.get(LAYERS)); return new ModelCacheKey(state.get(FACING), state.get(LAYERS));
} }
@Override
public int getModelStateCount() {
return 48;
}
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(LAYERS)); super.appendProperties(builder.add(LAYERS));

View File

@ -31,11 +31,6 @@ public class ReFramedPillarBlock extends WaterloggableReFramedBlock {
return state.get(AXIS); return state.get(AXIS);
} }
@Override
public int getModelStateCount() {
return 3;
}
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(AXIS)); super.appendProperties(builder.add(AXIS));

View File

@ -37,11 +37,6 @@ public class ReFramedSlabBlock extends WaterloggableReFramedBlock {
public Object getModelCacheKey(BlockState state) { public Object getModelCacheKey(BlockState state) {
return state.get(FACING); return state.get(FACING);
} }
@Override
public int getModelStateCount() {
return 6;
}
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {

View File

@ -23,11 +23,6 @@ public class ReFramedSlabsCubeBlock extends ReFramedDoubleBlock {
return state.get(AXIS); return state.get(AXIS);
} }
@Override
public int getModelStateCount() {
return 3;
}
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(AXIS)); super.appendProperties(builder.add(AXIS));

View File

@ -39,11 +39,6 @@ public class ReFramedSmallCubeBlock extends WaterloggableReFramedBlock {
return state.get(CORNER); return state.get(CORNER);
} }
@Override
public int getModelStateCount() {
return 8;
}
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(CORNER)); super.appendProperties(builder.add(CORNER));

View File

@ -30,11 +30,6 @@ public class ReFramedSmallCubesStepBlock extends WaterloggableReFramedDoubleBloc
return state.get(EDGE); return state.get(EDGE);
} }
@Override
public int getModelStateCount() {
return 12;
}
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(EDGE)); super.appendProperties(builder.add(EDGE));

View File

@ -42,11 +42,6 @@ public class ReFramedStairBlock extends WaterloggableReFramedBlock {
public Object getModelCacheKey(BlockState state) { public Object getModelCacheKey(BlockState state) {
return new ModelCacheKey(state.get(EDGE), state.get(STAIR_SHAPE)); return new ModelCacheKey(state.get(EDGE), state.get(STAIR_SHAPE));
} }
@Override
public int getModelStateCount() {
return 108; // Has 12 * 9 state combination and 52 models still reduces cache size
}
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {

View File

@ -34,11 +34,6 @@ public class ReFramedStairsCubeBlock extends ReFramedDoubleBlock {
return new ModelCacheKey(state.get(EDGE), state.get(STAIR_SHAPE)); return new ModelCacheKey(state.get(EDGE), state.get(STAIR_SHAPE));
} }
@Override
public int getModelStateCount() {
return 108; // Has 12 * 9 state combination and 52 models still reduces cache size
}
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(EDGE, STAIR_SHAPE)); super.appendProperties(builder.add(EDGE, STAIR_SHAPE));

View File

@ -39,11 +39,6 @@ public class ReFramedStepBlock extends WaterloggableReFramedBlock {
return state.get(EDGE); return state.get(EDGE);
} }
@Override
public int getModelStateCount() {
return 12;
}
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(EDGE)); super.appendProperties(builder.add(EDGE));

View File

@ -34,11 +34,6 @@ public class ReFramedStepsSlabBlock extends WaterloggableReFramedDoubleBlock {
return new ModelCacheKey(state.get(FACING), state.get(AXIS)); return new ModelCacheKey(state.get(FACING), state.get(AXIS));
} }
@Override
public int getModelStateCount() {
return 18;
}
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(FACING, AXIS)); super.appendProperties(builder.add(FACING, AXIS));

View File

@ -49,11 +49,6 @@ public class ReframedWallBlock extends WaterloggableReFramedBlock {
); );
} }
@Override
public int getModelStateCount() {
return 162;
}
@Override @Override
protected void appendProperties(StateManager.Builder<Block, BlockState> builder) { protected void appendProperties(StateManager.Builder<Block, BlockState> builder) {
super.appendProperties(builder.add(UP, EAST_WALL_SHAPE, NORTH_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE)); super.appendProperties(builder.add(UP, EAST_WALL_SHAPE, NORTH_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
@ -84,9 +79,12 @@ public class ReframedWallBlock extends WaterloggableReFramedBlock {
boolean side_full = other_state.isSideSolidFullSquare(world, moved, dir.getOpposite()); boolean side_full = other_state.isSideSolidFullSquare(world, moved, dir.getOpposite());
if (shouldConnectTo(other_state, side_full, dir.getOpposite())) { if (shouldConnectTo(other_state, side_full, dir.getOpposite())) {
Property<WallShape> wall_shape = getWallShape(dir);
new_state = new_state.with( new_state = new_state.with(
getWallShape(dir), wall_shape,
fs || shouldUseTall(WALL_VOXELS[dir.ordinal() + 3], top_shape) fs
|| (top_state.contains(wall_shape) && top_state.get(wall_shape) != WallShape.NONE)
|| shouldUseTall(WALL_VOXELS[dir.ordinal() + 3], top_shape)
? WallShape.TALL ? WallShape.TALL
: WallShape.LOW : WallShape.LOW
); );
@ -107,9 +105,12 @@ public class ReframedWallBlock extends WaterloggableReFramedBlock {
BlockState neighbor = world.getBlockState(offset); BlockState neighbor = world.getBlockState(offset);
boolean side_full = neighbor.isSideSolidFullSquare(world, offset, dir.getOpposite()); boolean side_full = neighbor.isSideSolidFullSquare(world, offset, dir.getOpposite());
if (shouldConnectTo(neighbor, side_full, dir.getOpposite())) { if (shouldConnectTo(neighbor, side_full, dir.getOpposite())) {
Property<WallShape> wall_shape = getWallShape(dir);
state = state.with( state = state.with(
getWallShape(dir), wall_shape,
fs || shouldUseTall(WALL_VOXELS[dir.ordinal() + 3], top_shape) fs
|| (top_state.contains(wall_shape) && top_state.get(wall_shape) != WallShape.NONE)
|| shouldUseTall(WALL_VOXELS[dir.ordinal() + 3], top_shape)
? WallShape.TALL ? WallShape.TALL
: WallShape.LOW : WallShape.LOW
); );
@ -138,6 +139,7 @@ public class ReframedWallBlock extends WaterloggableReFramedBlock {
@Override @Override
public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) { public VoxelShape getCollisionShape(BlockState state, BlockView view, BlockPos pos, ShapeContext ctx) {
if (isGhost(view, pos)) return VoxelShapes.empty();
VoxelShape shape = state.get(UP) ? WALL_VOXELS[9]: VoxelShapes.empty(); VoxelShape shape = state.get(UP) ? WALL_VOXELS[9]: VoxelShapes.empty();
for (Direction dir : Direction.Type.HORIZONTAL) { for (Direction dir : Direction.Type.HORIZONTAL) {
if (state.get(getWallShape(dir)) != WallShape.NONE) if (state.get(getWallShape(dir)) != WallShape.NONE)

View File

@ -14,6 +14,10 @@ import net.minecraft.resource.ResourceType;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.ChunkSectionPos; import net.minecraft.util.math.ChunkSectionPos;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.*;
import static fr.adrien1106.reframed.util.blocks.BlockProperties.STAIR_SHAPE;
import static net.minecraft.state.property.Properties.*;
public class ReFramedClient implements ClientModInitializer { public class ReFramedClient implements ClientModInitializer {
public static final ReFramedModelProvider PROVIDER = new ReFramedModelProvider(); public static final ReFramedModelProvider PROVIDER = new ReFramedModelProvider();
@ -27,92 +31,92 @@ public class ReFramedClient implements ClientModInitializer {
BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), ReFramed.BLOCKS.toArray(new Block[0])); BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), ReFramed.BLOCKS.toArray(new Block[0]));
// CUBE // CUBE
HELPER.addReFramedModel("cube" , HELPER.auto(new Identifier("block/cube"))); HELPER.addReFramedModel("cube" , HELPER.auto(new Identifier("block/cube"), 2));
// SMALL_CUBE // SMALL_CUBE
HELPER.addReFramedModel("small_cube" , HELPER.auto(ReFramed.id("block/small_cube/base"))); HELPER.addReFramedModel("small_cube" , HELPER.auto(ReFramed.id("block/small_cube/base"), 9, CORNER));
// SMALL_CUBES_STEP // SMALL_CUBES_STEP
HELPER.addReFramedModel("small_cubes_step" , HELPER.autoDouble(ReFramed.id("block/small_cube/base"), ReFramed.id("block/small_cube/step/base"))); HELPER.addReFramedModel("small_cubes_step" , HELPER.autoDouble(ReFramed.id("block/small_cube/base"), ReFramed.id("block/small_cube/step/base"), 9, EDGE));
HELPER.addReFramedModel("small_cubes_step_reverse" , HELPER.autoDouble(ReFramed.id("block/small_cube/step/base"), ReFramed.id("block/small_cube/base"))); HELPER.addReFramedModel("small_cubes_step_reverse" , HELPER.autoDouble(ReFramed.id("block/small_cube/step/base"), ReFramed.id("block/small_cube/base"), 4, EDGE));
// SLAB // SLAB
HELPER.addReFramedModel("slab" , HELPER.auto(new Identifier("block/slab"))); HELPER.addReFramedModel("slab" , HELPER.auto(new Identifier("block/slab"), 7, FACING));
// SLAB_CUBE // SLAB_CUBE
HELPER.addReFramedModel("double_slab" , HELPER.autoDouble(new Identifier("block/slab"), new Identifier("block/slab_top"))); HELPER.addReFramedModel("double_slab" , HELPER.autoDouble(new Identifier("block/slab"), new Identifier("block/slab_top"), 4, AXIS));
// STAIR // STAIR
HELPER.addReFramedModel("stair" , HELPER.auto(ReFramed.id("block/stair/straight"))); HELPER.addReFramedModel("stair" , HELPER.auto(ReFramed.id("block/stair/straight"), 13, EDGE));
HELPER.addReFramedModel("outers_stair" , HELPER.auto(ReFramed.id("block/stair/double_outer"))); HELPER.addReFramedModel("outers_stair" , HELPER.auto(ReFramed.id("block/stair/double_outer"), 24, EDGE, STAIR_SHAPE));
HELPER.addReFramedModel("inner_stair" , HELPER.auto(ReFramed.id("block/stair/inner"))); HELPER.addReFramedModel("inner_stair" , HELPER.auto(ReFramed.id("block/stair/inner"), 24, EDGE, STAIR_SHAPE));
HELPER.addReFramedModel("outer_stair" , HELPER.auto(ReFramed.id("block/stair/outer"))); HELPER.addReFramedModel("outer_stair" , HELPER.auto(ReFramed.id("block/stair/outer"), 16, EDGE, STAIR_SHAPE));
HELPER.addReFramedModel("outer_side_stair" , HELPER.auto(ReFramed.id("block/stair/outer_side"))); HELPER.addReFramedModel("outer_side_stair" , HELPER.auto(ReFramed.id("block/stair/outer_side"), 32, EDGE, STAIR_SHAPE));
// STAIRS_CUBE // STAIRS_CUBE
HELPER.addReFramedModel("stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/straight"), ReFramed.id("block/stair/cube/straight"))); HELPER.addReFramedModel("stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/straight"), ReFramed.id("block/stair/cube/straight"), 13, EDGE));
HELPER.addReFramedModel("outers_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/double_outer"), ReFramed.id("block/stair/cube/double_outer"))); HELPER.addReFramedModel("outers_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/double_outer"), ReFramed.id("block/stair/cube/double_outer"), 24, EDGE, STAIR_SHAPE));
HELPER.addReFramedModel("inner_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/inner"), ReFramed.id("block/stair/cube/inner"))); HELPER.addReFramedModel("inner_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/inner"), ReFramed.id("block/stair/cube/inner"), 24, EDGE, STAIR_SHAPE));
HELPER.addReFramedModel("outer_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/outer"), ReFramed.id("block/stair/cube/outer"))); HELPER.addReFramedModel("outer_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/outer"), ReFramed.id("block/stair/cube/outer"), 16, EDGE, STAIR_SHAPE));
HELPER.addReFramedModel("outer_side_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/outer_side"), ReFramed.id("block/stair/cube/outer_side"))); HELPER.addReFramedModel("outer_side_stairs_cube" , HELPER.autoDouble(ReFramed.id("block/stair/outer_side"), ReFramed.id("block/stair/cube/outer_side"), 32, EDGE, STAIR_SHAPE));
// HALF_STAIR // HALF_STAIR
HELPER.addReFramedModel("half_stair_down" , HELPER.auto(ReFramed.id("block/half_stair/down"))); HELPER.addReFramedModel("half_stair_down" , HELPER.auto(ReFramed.id("block/half_stair/down"), 9, CORNER, CORNER_FACE));
HELPER.addReFramedModel("half_stair_side" , HELPER.auto(ReFramed.id("block/half_stair/side"))); HELPER.addReFramedModel("half_stair_side" , HELPER.auto(ReFramed.id("block/half_stair/side"), 16, CORNER, CORNER_FACE));
// HALF_STAIRS_SLAB // HALF_STAIRS_SLAB
HELPER.addReFramedModel("half_stairs_slab_down" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/slab/down"))); HELPER.addReFramedModel("half_stairs_slab_down" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/slab/down"), 9, CORNER, CORNER_FACE));
HELPER.addReFramedModel("half_stairs_slab_side" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/slab/side"))); HELPER.addReFramedModel("half_stairs_slab_side" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/slab/side"), 16, CORNER, CORNER_FACE));
// HALF_STAIRS_STAIR // HALF_STAIRS_STAIR
HELPER.addReFramedModel("half_stairs_stair_down" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/stair/down"))); HELPER.addReFramedModel("half_stairs_stair_down" , HELPER.autoDouble(ReFramed.id("block/half_stair/down"), ReFramed.id("block/half_stair/stair/down"), 5, EDGE));
HELPER.addReFramedModel("half_stairs_stair_side" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/stair/side"))); HELPER.addReFramedModel("half_stairs_stair_side" , HELPER.autoDouble(ReFramed.id("block/half_stair/side"), ReFramed.id("block/half_stair/stair/side"), 6, EDGE));
HELPER.addReFramedModel("half_stairs_stair_reverse" , HELPER.autoDouble(ReFramed.id("block/half_stair/stair/side"), ReFramed.id("block/half_stair/side"))); HELPER.addReFramedModel("half_stairs_stair_reverse" , HELPER.autoDouble(ReFramed.id("block/half_stair/stair/side"), ReFramed.id("block/half_stair/side"), 2, EDGE));
// STEP // STEP
HELPER.addReFramedModel("step" , HELPER.auto(ReFramed.id("block/step/down"))); HELPER.addReFramedModel("step" , HELPER.auto(ReFramed.id("block/step/down"), 13, EDGE));
// STEPS_SLAB // STEPS_SLAB
HELPER.addReFramedModel("steps_slab" , HELPER.autoDouble(ReFramed.id("block/step/down"), ReFramed.id("block/step/slab/down"))); HELPER.addReFramedModel("steps_slab" , HELPER.autoDouble(ReFramed.id("block/step/down"), ReFramed.id("block/step/slab/down"), 5, FACING, AXIS));
HELPER.addReFramedModel("steps_slab_side" , HELPER.autoDouble(ReFramed.id("block/step/side"), ReFramed.id("block/step/slab/side"))); HELPER.addReFramedModel("steps_slab_side" , HELPER.autoDouble(ReFramed.id("block/step/side"), ReFramed.id("block/step/slab/side"), 8, FACING, AXIS));
// LAYER // LAYER
HELPER.addReFramedModel("layer_1" , HELPER.auto(new Identifier("block/snow_height2"))); HELPER.addReFramedModel("layer_1" , HELPER.auto(new Identifier("block/snow_height2"), 7, FACING));
HELPER.addReFramedModel("layer_2" , HELPER.auto(new Identifier("block/snow_height4"))); HELPER.addReFramedModel("layer_2" , HELPER.auto(new Identifier("block/snow_height4"), 6, FACING));
HELPER.addReFramedModel("layer_3" , HELPER.auto(new Identifier("block/snow_height6"))); HELPER.addReFramedModel("layer_3" , HELPER.auto(new Identifier("block/snow_height6"), 6, FACING));
HELPER.addReFramedModel("layer_4" , HELPER.auto(new Identifier("block/snow_height8"))); HELPER.addReFramedModel("layer_4" , HELPER.auto(new Identifier("block/snow_height8"), 6, FACING));
HELPER.addReFramedModel("layer_5" , HELPER.auto(new Identifier("block/snow_height10"))); HELPER.addReFramedModel("layer_5" , HELPER.auto(new Identifier("block/snow_height10"), 6, FACING));
HELPER.addReFramedModel("layer_6" , HELPER.auto(new Identifier("block/snow_height12"))); HELPER.addReFramedModel("layer_6" , HELPER.auto(new Identifier("block/snow_height12"), 6, FACING));
HELPER.addReFramedModel("layer_7" , HELPER.auto(new Identifier("block/snow_height14"))); HELPER.addReFramedModel("layer_7" , HELPER.auto(new Identifier("block/snow_height14"), 6, FACING));
HELPER.addReFramedModel("layer_8" , HELPER.auto(new Identifier("block/cube"))); HELPER.addReFramedModel("layer_8" , HELPER.auto(new Identifier("block/cube"), 1));
// PILLAR // PILLAR
HELPER.addReFramedModel("pillar" , HELPER.auto(ReFramed.id("block/pillar"))); HELPER.addReFramedModel("pillar" , HELPER.auto(ReFramed.id("block/pillar"), 4, AXIS));
// WALL // WALL
HELPER.addReFramedModel("wall_inventory" , HELPER.auto(ReFramed.id("block/wall/inventory/default"))); HELPER.addReFramedModel("wall_inventory" , HELPER.auto(ReFramed.id("block/wall/inventory/default"), 1));
// --------------------- pillar // --------------------- pillar
HELPER.addReFramedModel("wall_core" , HELPER.auto(ReFramed.id("block/wall/pillar/core"))); HELPER.addReFramedModel("wall_core" , HELPER.auto(ReFramed.id("block/wall/pillar/core"), 1, UP));
HELPER.addReFramedModel("wall_pillar_low" , HELPER.auto(ReFramed.id("block/wall/pillar/low"))); HELPER.addReFramedModel("wall_pillar_low" , HELPER.auto(ReFramed.id("block/wall/pillar/low"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_pillar_tall" , HELPER.auto(ReFramed.id("block/wall/pillar/tall"))); HELPER.addReFramedModel("wall_pillar_tall" , HELPER.auto(ReFramed.id("block/wall/pillar/tall"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_pillar_none" , HELPER.auto(ReFramed.id("block/wall/pillar/none"))); HELPER.addReFramedModel("wall_pillar_none" , HELPER.auto(ReFramed.id("block/wall/pillar/none"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
// --------------------- side // --------------------- side
HELPER.addReFramedModel("wall_side_low" , HELPER.auto(ReFramed.id("block/wall/side/low"))); HELPER.addReFramedModel("wall_side_low" , HELPER.auto(ReFramed.id("block/wall/side/low"), 92, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_side_tall" , HELPER.auto(ReFramed.id("block/wall/side/tall"))); HELPER.addReFramedModel("wall_side_tall" , HELPER.auto(ReFramed.id("block/wall/side/tall"), 92, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
// --------------------- junction // --------------------- junction
HELPER.addReFramedModel("wall_low_e" , HELPER.auto(ReFramed.id("block/wall/junction/low"))); HELPER.addReFramedModel("wall_low_e" , HELPER.auto(ReFramed.id("block/wall/junction/low"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_e" , HELPER.auto(ReFramed.id("block/wall/junction/tall"))); HELPER.addReFramedModel("wall_tall_e" , HELPER.auto(ReFramed.id("block/wall/junction/tall"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
// --------------------- junction_i // --------------------- junction_i
HELPER.addReFramedModel("wall_low_i" , HELPER.auto(ReFramed.id("block/wall/junction/low_i"))); HELPER.addReFramedModel("wall_low_i" , HELPER.auto(ReFramed.id("block/wall/junction/low_i"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_i" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i"))); HELPER.addReFramedModel("wall_tall_i" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_low_tall_i" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_i"))); HELPER.addReFramedModel("wall_low_tall_i" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_i"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
// --------------------- junction_c // --------------------- junction_c
HELPER.addReFramedModel("wall_low_c" , HELPER.auto(ReFramed.id("block/wall/junction/low_c"))); HELPER.addReFramedModel("wall_low_c" , HELPER.auto(ReFramed.id("block/wall/junction/low_c"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_c" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c"))); HELPER.addReFramedModel("wall_tall_c" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_low_tall_c" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_c"))); HELPER.addReFramedModel("wall_low_tall_c" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_c"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_low_c" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_c"))); HELPER.addReFramedModel("wall_tall_low_c" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_c"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
// --------------------- junction_t // --------------------- junction_t
HELPER.addReFramedModel("wall_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_t"))); HELPER.addReFramedModel("wall_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_t"))); HELPER.addReFramedModel("wall_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_low_c_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_c_t"))); HELPER.addReFramedModel("wall_tall_low_c_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_c_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_i_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i_low_t"))); HELPER.addReFramedModel("wall_tall_i_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i_low_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_low_i_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_i_tall_t"))); HELPER.addReFramedModel("wall_low_i_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_i_tall_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_low_tall_c_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_c_t"))); HELPER.addReFramedModel("wall_low_tall_c_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_tall_c_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_low_c_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_c_tall_t"))); HELPER.addReFramedModel("wall_low_c_tall_t" , HELPER.auto(ReFramed.id("block/wall/junction/low_c_tall_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_c_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c_low_t"))); HELPER.addReFramedModel("wall_tall_c_low_t" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c_low_t"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
// --------------------- junction_x // --------------------- junction_x
HELPER.addReFramedModel("wall_low_x" , HELPER.auto(ReFramed.id("block/wall/junction/low_x"))); HELPER.addReFramedModel("wall_low_x" , HELPER.auto(ReFramed.id("block/wall/junction/low_x"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_x"))); HELPER.addReFramedModel("wall_tall_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_x"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_i_low_i_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i_low_i_x"))); HELPER.addReFramedModel("wall_tall_i_low_i_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_i_low_i_x"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_low_t_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_t_x"))); HELPER.addReFramedModel("wall_tall_low_t_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_low_t_x"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_c_low_c_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c_low_c_x"))); HELPER.addReFramedModel("wall_tall_c_low_c_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_c_low_c_x"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
HELPER.addReFramedModel("wall_tall_t_low_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_t_low_x"))); HELPER.addReFramedModel("wall_tall_t_low_x" , HELPER.auto(ReFramed.id("block/wall/junction/tall_t_low_x"), 4, NORTH_WALL_SHAPE, EAST_WALL_SHAPE, SOUTH_WALL_SHAPE, WEST_WALL_SHAPE));
//item model assignments (in lieu of models/item/___.json) //item model assignments (in lieu of models/item/___.json)

View File

@ -13,6 +13,7 @@ import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.texture.Sprite; import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.SpriteIdentifier; import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemConvertible;
import net.minecraft.state.property.Property;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@ -27,16 +28,19 @@ public class ReFramedClientHelper {
private final ReFramedModelProvider prov; private final ReFramedModelProvider prov;
public UnbakedRetexturedModel auto(Identifier parent) { public UnbakedRetexturedModel auto(Identifier parent, int model_count, Property<?>... properties) {
return new UnbakedAutoRetexturedModel(parent); return new UnbakedAutoRetexturedModel(parent, model_count, properties);
} }
public UnbakedRetexturedModel json(Identifier parent) { public UnbakedRetexturedModel json(Identifier parent, int model_count, Property<?>... properties) {
return new UnbakedJsonRetexturedModel(parent); return new UnbakedJsonRetexturedModel(parent, model_count, properties);
} }
public UnbakedModel autoDouble(Identifier first, Identifier second) { public UnbakedModel autoDouble(Identifier first, Identifier second, int model_count, Property<?>... properties) {
return new UnbakedDoubleRetexturedModel(auto(first), auto(second)); return new UnbakedDoubleRetexturedModel(
auto(first, model_count, properties),
auto(second, model_count, properties)
);
} }
public void addReFramedModel(String id, UnbakedModel unbaked) { public void addReFramedModel(String id, UnbakedModel unbaked) {

View File

@ -1,6 +1,7 @@
package fr.adrien1106.reframed.client.model; package fr.adrien1106.reframed.client.model;
import fr.adrien1106.reframed.block.ReFramedBlock; import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import fr.adrien1106.reframed.block.ReFramedEntity; import fr.adrien1106.reframed.block.ReFramedEntity;
import fr.adrien1106.reframed.client.ReFramedClient; import fr.adrien1106.reframed.client.ReFramedClient;
import fr.adrien1106.reframed.mixin.MinecraftAccessor; import fr.adrien1106.reframed.mixin.MinecraftAccessor;
@ -19,27 +20,28 @@ import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.ModelBakeSettings; import net.minecraft.client.render.model.ModelBakeSettings;
import net.minecraft.client.texture.Sprite; import net.minecraft.client.texture.Sprite;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.state.property.Property;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.util.math.random.Random; import net.minecraft.util.math.random.Random;
import net.minecraft.world.BlockRenderView; import net.minecraft.world.BlockRenderView;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Stream;
public abstract class RetexturingBakedModel extends ForwardingBakedModel { public abstract class RetexturingBakedModel extends ForwardingBakedModel {
public RetexturingBakedModel(BakedModel base_model, CamoAppearanceManager tam, int theme_index, ModelBakeSettings settings, BlockState item_state, boolean ao) { public RetexturingBakedModel(BakedModel base_model, CamoAppearanceManager tam, int theme_index, ModelBakeSettings settings, BlockState item_state, int model_count, Property<?>... properties) {
this.wrapped = base_model; //field from the superclass; vanilla getQuads etc. will delegate through to this this.wrapped = base_model; //field from the superclass; vanilla getQuads etc. will delegate through to this
this.appearance_manager = tam; this.appearance_manager = tam;
this.theme_index = theme_index; this.theme_index = theme_index;
this.uv_lock = settings.isUvLocked(); this.uv_lock = settings.isUvLocked();
this.item_state = item_state; this.item_state = item_state;
this.ao = ao; this.properties = properties;
int cache_size = 64; // default is 64 why don't ask me and it should get overwritten BASE_MESH_CACHE = new Object2ObjectLinkedOpenHashMap<>(model_count, 0.25f) {
if (item_state.getBlock() instanceof ReFramedBlock frame_block) cache_size = frame_block.getModelStateCount() + 1;
BASE_MESH_CACHE = new Object2ObjectLinkedOpenHashMap<>(cache_size, 0.25f) {
@Override @Override
protected void rehash(int v) {} protected void rehash(int v) {}
}; };
@ -48,16 +50,13 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
protected final CamoAppearanceManager appearance_manager; protected final CamoAppearanceManager appearance_manager;
protected final int theme_index; protected final int theme_index;
protected final boolean uv_lock; protected final boolean uv_lock;
protected final boolean ao;
protected final BlockState item_state; protected final BlockState item_state;
protected final Property<?>[] properties;
protected record MeshCacheKey(Object state_key, CamoAppearance appearance, int model_id) {} protected record MeshCacheKey(Object state_key, CamoAppearance appearance, int model_id) {}
/** cache that store retextured models */ /** cache that store retextured models */
protected final Object2ObjectLinkedOpenHashMap<MeshCacheKey, Mesh> RETEXTURED_MESH_CACHE = // self culling cache of the models not made thread local so that it is only computed once
new Object2ObjectLinkedOpenHashMap<>(128, 0.25f) { protected final Cache<MeshCacheKey, Mesh> RETEXTURED_MESH_CACHE = CacheBuilder.newBuilder().maximumSize(256).build();
@Override
protected void rehash(int v) {}
};
/** cache that stores the base meshes which has the size of the amount of models */ /** cache that stores the base meshes which has the size of the amount of models */
protected final Object2ObjectLinkedOpenHashMap<Object, Mesh> BASE_MESH_CACHE; protected final Object2ObjectLinkedOpenHashMap<Object, Mesh> BASE_MESH_CACHE;
@ -91,14 +90,13 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
@Override @Override
public void emitBlockQuads(BlockRenderView world, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) { public void emitBlockQuads(BlockRenderView world, BlockState state, BlockPos pos, Supplier<Random> 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; BlockState theme = (world.getBlockEntity(pos) instanceof ThemeableBlockEntity s) ? s.getTheme(theme_index) : null;
QuadEmitter quad_emitter = context.getEmitter(); QuadEmitter quad_emitter = context.getEmitter();
List<?> model_key = Stream.of(properties).map(state::get).toList();
if(theme == null || theme.isAir()) { if(theme == null || theme.isAir()) {
getRetexturedMesh( getRetexturedMesh(
new MeshCacheKey( new MeshCacheKey(
frame_block.getModelCacheKey(state), model_key,
appearance_manager.getDefaultAppearance(theme_index), appearance_manager.getDefaultAppearance(theme_index),
0 0
), ),
@ -114,7 +112,7 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
if (camo instanceof WeightedComputedAppearance wca) model_id = wca.getAppearanceIndex(seed); if (camo instanceof WeightedComputedAppearance wca) model_id = wca.getAppearanceIndex(seed);
int tint = 0xFF000000 | MinecraftClient.getInstance().getBlockColors().getColor(theme, world, pos, 0); int tint = 0xFF000000 | MinecraftClient.getInstance().getBlockColors().getColor(theme, world, pos, 0);
MeshCacheKey key = new MeshCacheKey(frame_block.getModelCacheKey(state), camo, model_id); MeshCacheKey key = new MeshCacheKey(model_key, camo, model_id);
// do not clutter the cache with single-use meshes // do not clutter the cache with single-use meshes
Mesh untintedMesh = camo.hashCode() == -1 ? transformMesh(key, state) : getRetexturedMesh(key, state); Mesh untintedMesh = camo.hashCode() == -1 ? transformMesh(key, state) : getRetexturedMesh(key, state);
@ -157,9 +155,9 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
} }
protected Mesh getRetexturedMesh(MeshCacheKey key, BlockState state) { protected Mesh getRetexturedMesh(MeshCacheKey key, BlockState state) {
if (RETEXTURED_MESH_CACHE.containsKey(key)) return RETEXTURED_MESH_CACHE.getAndMoveToFirst(key); if (RETEXTURED_MESH_CACHE.asMap().containsKey(key)) return RETEXTURED_MESH_CACHE.getIfPresent(key);
Mesh mesh = transformMesh(key, state); Mesh mesh = transformMesh(key, state);
RETEXTURED_MESH_CACHE.putAndMoveToFirst(key, mesh); RETEXTURED_MESH_CACHE.put(key, mesh);
return mesh; return mesh;
} }
@ -172,7 +170,7 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
int i = -1; int i = -1;
do { do {
emitter.copyFrom(quad); emitter.copyFrom(quad);
i = key.appearance.transformQuad(emitter, i, quad_index.get(), key.model_id, ao, uv_lock); i = key.appearance.transformQuad(emitter, i, quad_index.get(), key.model_id, uv_lock);
} while (i > 0); } while (i > 0);
// kinda weird to do it like that but other directions don't use the quad_index so it doesn't matter // kinda weird to do it like that but other directions don't use the quad_index so it doesn't matter
if (quad.cullFace() == null) quad_index.getAndIncrement(); if (quad.cullFace() == null) quad_index.getAndIncrement();

View File

@ -14,6 +14,7 @@ import net.minecraft.client.render.model.Baker;
import net.minecraft.client.render.model.ModelBakeSettings; import net.minecraft.client.render.model.ModelBakeSettings;
import net.minecraft.client.texture.Sprite; import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.SpriteIdentifier; import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.state.property.Property;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.util.math.random.Random; import net.minecraft.util.math.random.Random;
@ -23,8 +24,8 @@ import java.util.function.Function;
public class UnbakedAutoRetexturedModel extends UnbakedRetexturedModel { public class UnbakedAutoRetexturedModel extends UnbakedRetexturedModel {
public UnbakedAutoRetexturedModel(Identifier parent) { public UnbakedAutoRetexturedModel(Identifier parent, int state_count, Property<?>... properties) {
super(parent); super(parent, state_count, properties);
item_state = Blocks.AIR.getDefaultState(); item_state = Blocks.AIR.getDefaultState();
} }
@ -37,7 +38,8 @@ public class UnbakedAutoRetexturedModel extends UnbakedRetexturedModel {
theme_index, theme_index,
bake_settings, bake_settings,
item_state, item_state,
ao state_count,
properties
) { ) {
protected Mesh convertModel(BlockState state) { protected Mesh convertModel(BlockState state) {
Renderer r = ReFramedClient.HELPER.getFabricRenderer(); Renderer r = ReFramedClient.HELPER.getFabricRenderer();

View File

@ -15,6 +15,7 @@ import net.minecraft.client.render.model.ModelBakeSettings;
import net.minecraft.client.texture.Sprite; import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.SpriteIdentifier; import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.screen.PlayerScreenHandler; import net.minecraft.screen.PlayerScreenHandler;
import net.minecraft.state.property.Property;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import net.minecraft.util.math.random.Random; import net.minecraft.util.math.random.Random;
@ -24,8 +25,8 @@ import java.util.Objects;
import java.util.function.Function; import java.util.function.Function;
public class UnbakedJsonRetexturedModel extends UnbakedRetexturedModel { public class UnbakedJsonRetexturedModel extends UnbakedRetexturedModel {
public UnbakedJsonRetexturedModel(Identifier parent) { public UnbakedJsonRetexturedModel(Identifier parent, int state_count, Property<?>... properties) {
super(parent); super(parent, state_count, properties);
} }
@Nullable @Nullable
@ -45,7 +46,8 @@ public class UnbakedJsonRetexturedModel extends UnbakedRetexturedModel {
theme_index, theme_index,
bake_settings, bake_settings,
item_state, item_state,
ao state_count,
properties
) { ) {
protected Mesh convertModel(BlockState state) { protected Mesh convertModel(BlockState state) {
Renderer r = ReFramedClient.HELPER.getFabricRenderer(); Renderer r = ReFramedClient.HELPER.getFabricRenderer();

View File

@ -2,6 +2,7 @@ package fr.adrien1106.reframed.client.model;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.render.model.UnbakedModel; import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.state.property.Property;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import java.util.Collection; import java.util.Collection;
@ -14,10 +15,13 @@ public abstract class UnbakedRetexturedModel implements UnbakedModel {
protected int theme_index = 1; protected int theme_index = 1;
protected BlockState item_state; protected BlockState item_state;
protected final boolean ao = true; protected final int state_count;
protected final Property<?>[] properties;
public UnbakedRetexturedModel(Identifier parent) { public UnbakedRetexturedModel(Identifier parent, int state_count, Property<?>... properties) {
this.parent = parent; this.parent = parent;
this.state_count = state_count;
this.properties = properties;
} }
public UnbakedRetexturedModel setThemeIndex(int theme_index) { public UnbakedRetexturedModel setThemeIndex(int theme_index) {

View File

@ -5,4 +5,4 @@ import net.minecraft.util.math.Direction;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public record Appearance(Map<Direction, List<SpriteProperties>> sprites) {} public record Appearance(Map<Direction, List<SpriteProperties>> sprites, boolean use_ao) {}

View File

@ -26,12 +26,13 @@ public abstract class CamoAppearance {
public abstract @NotNull List<SpriteProperties> getSprites(Direction dir, int model_id); public abstract @NotNull List<SpriteProperties> getSprites(Direction dir, int model_id);
public abstract boolean hasColor(Direction dir, int model_id, int index); public abstract boolean hasColor(Direction dir, int model_id, int index);
public abstract boolean getAO(int model_id);
public @NotNull RenderMaterial getRenderMaterial(boolean ao) { public @NotNull RenderMaterial getRenderMaterial(boolean ao) {
return ao && ao_material != null? ao_material : material; return ao && ao_material != null? ao_material : material;
} }
public int transformQuad(QuadEmitter quad, int i, int quad_index, int model_id, boolean ao, boolean uv_lock) { public int transformQuad(QuadEmitter quad, int i, int quad_index, int model_id, boolean uv_lock) {
if(quad.tag() == 0) return 0; // Pass the quad through unmodified. if(quad.tag() == 0) return 0; // Pass the quad through unmodified.
Direction direction = quad.nominalFace(); Direction direction = quad.nominalFace();
@ -44,7 +45,7 @@ public abstract class CamoAppearance {
QuadPosBounds bounds = properties.bounds(); QuadPosBounds bounds = properties.bounds();
if (bounds == null) { // sprite applies anywhere e.g. default behaviour if (bounds == null) { // sprite applies anywhere e.g. default behaviour
quad.material(getRenderMaterial(ao)); quad.material(getRenderMaterial(getAO(model_id)));
quad.spriteBake( quad.spriteBake(
properties.sprite(), properties.sprite(),
MutableQuadView.BAKE_NORMALIZED MutableQuadView.BAKE_NORMALIZED
@ -61,7 +62,7 @@ public abstract class CamoAppearance {
if (!bounds.matches(origin_bounds)) return i; if (!bounds.matches(origin_bounds)) return i;
// apply new quad shape // apply new quad shape
quad.material(getRenderMaterial(ao)); quad.material(getRenderMaterial(getAO(model_id)));
bounds.intersection(origin_bounds, direction.getAxis()).apply(quad, origin_bounds); bounds.intersection(origin_bounds, direction.getAxis()).apply(quad, origin_bounds);
quad.spriteBake( // seems to work without the flags and break with it quad.spriteBake( // seems to work without the flags and break with it
properties.sprite(), properties.sprite(),

View File

@ -64,12 +64,12 @@ public class CamoAppearanceManager {
this.accent_appearance = new SingleSpriteAppearance(sprite, materials.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); sprite = spriteLookup.apply(BARRIER_SPRITE_ID);
this.barrierItemAppearance = new SingleSpriteAppearance(sprite, materials.get(BlendMode.CUTOUT), serial_number.getAndIncrement()); this.barrier_appearance = new SingleSpriteAppearance(sprite, materials.get(BlendMode.CUTOUT), serial_number.getAndIncrement());
} }
private final CamoAppearance default_appearance; private final CamoAppearance default_appearance;
private final CamoAppearance accent_appearance; private final CamoAppearance accent_appearance;
private final CamoAppearance barrierItemAppearance; private final CamoAppearance barrier_appearance;
private final AtomicInteger serial_number = new AtomicInteger(0); //Mutable private final AtomicInteger serial_number = new AtomicInteger(0); //Mutable
@ -119,7 +119,7 @@ public class CamoAppearanceManager {
// The results are going to be the same, apart from their serialNumbers differing (= their equals & hashCode differing). // The results are going to be the same, apart from their serialNumbers differing (= their equals & hashCode differing).
// Tiny amount of wasted space in some caches if CamoAppearances are used as a map key, then. IMO it's not a critical issue. // Tiny amount of wasted space in some caches if CamoAppearances are used as a map key, then. IMO it's not a critical issue.
private CamoAppearance computeAppearance(BakedModel model, BlockState state, boolean is_dynamic) { private CamoAppearance computeAppearance(BakedModel model, BlockState state, boolean is_dynamic) {
if(state.getBlock() == Blocks.BARRIER) return barrierItemAppearance; if(state.getBlock() == Blocks.BARRIER) return barrier_appearance;
if (!(model instanceof WeightedBakedModelAccessor weighted_model)) { if (!(model instanceof WeightedBakedModelAccessor weighted_model)) {
return new ComputedAppearance( return new ComputedAppearance(
@ -175,7 +175,7 @@ public class CamoAppearanceManager {
}); });
}); });
return new Appearance(sprites); return new Appearance(sprites, model.useAmbientOcclusion());
} }
private static int getBakeFlags(QuadEmitter emitter, Sprite sprite) { private static int getBakeFlags(QuadEmitter emitter, Sprite sprite) {

View File

@ -16,7 +16,6 @@ public class ComputedAppearance extends CamoAppearance {
super(ao_material, material, id); super(ao_material, material, id);
this.appearance = appearance; this.appearance = appearance;
} }
@Override @Override
public @NotNull List<SpriteProperties> getSprites(Direction dir, int model_id) { public @NotNull List<SpriteProperties> getSprites(Direction dir, int model_id) {
return appearance.sprites().get(dir); return appearance.sprites().get(dir);
@ -29,6 +28,12 @@ public class ComputedAppearance extends CamoAppearance {
return properties.get(index).has_colors(); return properties.get(index).has_colors();
} }
@Override
public boolean getAO(int model_id) {
return appearance.use_ao();
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if(this == o) return true; if(this == o) return true;

View File

@ -35,6 +35,12 @@ public class SingleSpriteAppearance extends CamoAppearance {
return id == that.id; return id == that.id;
} }
@Override
public boolean getAO(int model_id) {
return false;
}
@Override @Override
public String toString() { public String toString() {
return "SingleSpriteAppearance[defaultSprite=%s, mat=%s, id=%d]".formatted(defaultSprite, material, id); return "SingleSpriteAppearance[defaultSprite=%s, mat=%s, id=%d]".formatted(defaultSprite, material, id);

View File

@ -46,6 +46,12 @@ public class WeightedComputedAppearance extends CamoAppearance {
return properties.get(index).has_colors(); return properties.get(index).has_colors();
} }
@Override
public boolean getAO(int model_id) {
return getAppearance(model_id).use_ao();
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if(this == o) return true; if(this == o) return true;

View File

@ -31,7 +31,6 @@ import static net.minecraft.util.shape.VoxelShapes.combine;
@Environment(EnvType.CLIENT) @Environment(EnvType.CLIENT)
public class RenderHelper { public class RenderHelper {
// self culling cache of the models not made thread local so that it is only computed once // self culling cache of the models not made thread local so that it is only computed once
private static final Cache<CullElement, Integer[]> INNER_CULL_MAP = CacheBuilder.newBuilder().maximumSize(1024).build(); private static final Cache<CullElement, Integer[]> INNER_CULL_MAP = CacheBuilder.newBuilder().maximumSize(1024).build();
private record CullElement(Block block, Object state_key, int model) {} private record CullElement(Block block, Object state_key, int model) {}