Compare commits

..

No commits in common. "a3ffe17a7eac19140bf9804c91537db4553439f7" and "ce216d1f9fbb4d43bb644b7df07cc28603068617" have entirely different histories.

6 changed files with 78 additions and 22 deletions

View File

@ -6,5 +6,5 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockRenderView;
public interface DynamicBakedModel {
BakedModel computeQuads(BlockRenderView level, BlockState state, BlockPos pos, int theme_index);
BakedModel computeQuads(BlockRenderView level, BlockState state, BlockPos pos);
}

View File

@ -91,7 +91,7 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
}
if(theme.getBlock() == Blocks.BARRIER) return;
CamoAppearance camo = tam.getCamoAppearance(world, theme, pos, theme_index);
CamoAppearance camo = tam.getCamoAppearance(world, theme, pos);
long seed = theme.getRenderingSeed(pos);
int model_id = 0;
if (camo instanceof WeightedComputedAppearance wca) model_id = wca.getAppearanceIndex(seed);
@ -124,7 +124,7 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
int tint;
BlockState theme = ReFramedEntity.readStateFromItem(stack, theme_index);
if(!theme.isAir()) {
nbtAppearance = tam.getCamoAppearance(null, theme, null, theme_index);
nbtAppearance = tam.getCamoAppearance(null, theme, null);
tint = 0xFF000000 | ((MinecraftAccessor) MinecraftClient.getInstance()).getItemColors().getColor(new ItemStack(theme.getBlock()), 0);
} else {
nbtAppearance = tam.getDefaultAppearance(theme_index);

View File

@ -74,12 +74,12 @@ public class CamoAppearanceManager {
return appearance == 2 ? accent_appearance: default_appearance;
}
public CamoAppearance getCamoAppearance(BlockRenderView world, BlockState state, BlockPos pos, int theme_index) {
public CamoAppearance getCamoAppearance(BlockRenderView world, BlockState state, BlockPos pos) {
BakedModel model = MinecraftClient.getInstance().getBlockRenderManager().getModel(state);
// add support for connected textures and more generally any compatible models injected so that they return baked quads
if (model instanceof DynamicBakedModel dynamic_model) {
return computeAppearance(dynamic_model.computeQuads(world, state, pos, theme_index), state);
return computeAppearance(dynamic_model.computeQuads(world, state, pos), state);
}
return appearanceCache.computeIfAbsent(state, block_state -> computeAppearance(model, block_state));
}

View File

@ -0,0 +1,46 @@
package fr.adrien1106.reframed.mixin;
import com.llamalad7.mixinextras.sugar.Local;
import fr.adrien1106.reframed.util.ThemeableBlockEntity;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.util.function.BooleanBiFunction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.*;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(Block.class)
public class BlockMixin {
@Redirect(method = "shouldDrawSide", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/BlockState;isOpaque()Z"))
private static boolean isNeighborCamoOpaque(BlockState state, @Local(argsOnly = true) BlockView world, @Local(ordinal = 1, argsOnly = true) BlockPos pos) {
BlockEntity block_entity = world.getBlockEntity(pos);
if (!(block_entity instanceof ThemeableBlockEntity frame_entity)) return state.isOpaque();
return frame_entity.getFirstTheme().isOpaque();
}
@Redirect(method = "shouldDrawSide", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/BlockState;isSideInvisible(Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/Direction;)Z"))
private static boolean isCamoInvisible(BlockState state, BlockState other_state, Direction direction, @Local(argsOnly = true) BlockView world, @Local(ordinal = 0, argsOnly = true) BlockPos pos, @Local(ordinal = 1, argsOnly = true) BlockPos other_pos) {
if (world.getBlockEntity(other_pos) instanceof ThemeableBlockEntity entity) other_state = entity.getFirstTheme();
if (world.getBlockEntity(pos) instanceof ThemeableBlockEntity entity) state = entity.getFirstTheme();
return state.isSideInvisible(other_state, direction);
}
@Inject(method = "shouldDrawSide", at = @At(value = "RETURN", ordinal = 0), cancellable = true)
private static void shouldDrawGlassCamoSide(BlockState state, BlockView world, BlockPos pos, Direction side, BlockPos other_pos, CallbackInfoReturnable<Boolean> cir, @Local(ordinal = 1) BlockState neighbor) {
if (!(world.getBlockEntity(pos) instanceof ThemeableBlockEntity) && !(world.getBlockEntity(other_pos) instanceof ThemeableBlockEntity)) return;
VoxelShape voxel_block = state.getCullingFace(world, pos, side);
if (voxel_block.isEmpty()) {
cir.setReturnValue(true);
return;
}
VoxelShape voxel_neighbor = neighbor.getCullingFace(world, pos, side.getOpposite());
cir.setReturnValue(VoxelShapes.matchesAnywhere(voxel_block, voxel_neighbor, BooleanBiFunction.ONLY_FIRST));
}
}

View File

@ -6,7 +6,6 @@ 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 it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import net.fabricmc.fabric.api.renderer.v1.Renderer;
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
@ -40,7 +39,7 @@ public abstract class AthenaBakedModelMixin implements DynamicBakedModel, BakedM
* @return - the rebakedmodel containing the computed quads
*/
@Override
public BakedModel computeQuads(BlockRenderView level, BlockState state, BlockPos pos, int theme_index) {
public BakedModel computeQuads(BlockRenderView level, BlockState state, BlockPos pos) {
Map<Direction, List<BakedQuad>> face_quads = new HashMap<>();
Renderer r = ReFramedClient.HELPER.getFabricRenderer();
QuadEmitter emitter = r.meshBuilder().getEmitter();
@ -51,12 +50,7 @@ public abstract class AthenaBakedModelMixin implements DynamicBakedModel, BakedM
(level == null || pos == null
? model.getDefaultQuads(direction).get(direction)
: model.getQuads(
getter,
level.getBlockEntity(pos) instanceof ThemeableBlockEntity framed_entity
? framed_entity.getTheme(theme_index)
: state, pos, direction)
)
: model.getQuads(getter, state, pos, direction))
.forEach(sprite -> face_quads.computeIfPresent(direction, (d, quads) -> {
Sprite texture = textures.get(sprite.sprite());
if (texture == null) return quads;

View File

@ -1,30 +1,46 @@
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 net.minecraft.block.BlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.BlockRenderView;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(WrappedGetter.class)
public class AthenaWrappedGetterMixin {
// TODO return only the state that might be of interest
@Shadow @Final private BlockRenderView getter;
@Inject(method = "getBlockState", at = @At(value = "HEAD"), cancellable = true)
private void getCamoState(BlockPos pos, CallbackInfoReturnable<BlockState> cir) {
if (!(getter.getBlockEntity(pos) instanceof ThemeableBlockEntity framed_entity)) return;
cir.setReturnValue(framed_entity.getTheme(1)); // TODO theme
}
@Redirect(method = "getAppearance(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;)" +
"Lnet/minecraft/block/BlockState;",
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/BlockRenderView;" +
"getBlockState(Lnet/minecraft/util/math/BlockPos;)" +
"Lnet/minecraft/block/BlockState;"))
private BlockState appearanceCamoState(BlockRenderView world, BlockPos pos) {
if (world.getBlockEntity(pos) instanceof ThemeableBlockEntity framed_entity) return framed_entity.getTheme(1); // TODO theme
return world.getBlockState(pos);
}
@Redirect(method = "query",
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/BlockRenderView;" +
"getBlockState(Lnet/minecraft/util/math/BlockPos;)" +
"Lnet/minecraft/block/BlockState;"))
private BlockState queryCamoState(BlockRenderView world, BlockPos pos, @Local(argsOnly = true) BlockState reference_state) {
// get Any that will connect or return any other (/!\ isOf is an uncertain check)
if (world.getBlockEntity(pos) instanceof ThemeableBlockEntity framed_entity)
return framed_entity.getThemes()
.stream()
.filter(state -> reference_state.isOf(state.getBlock()))
.findAny()
.orElse(framed_entity.getTheme(1));
private BlockState queryCamoState(BlockRenderView world, BlockPos pos) {
if (world.getBlockEntity(pos) instanceof ThemeableBlockEntity framed_entity) return framed_entity.getTheme(1); // TODO theme
return world.getBlockState(pos);
}
}