I wanted tio dies but it now works. Featuring culling based on block camos as well as renderLayers

This commit is contained in:
Adrien1106 2024-02-15 23:16:17 +01:00
parent d0e22d21d4
commit ffd9e17001
6 changed files with 100 additions and 61 deletions

View File

@ -45,6 +45,7 @@ repositories {
dependencies {
// To change the versions see the gradle.properties file
include(implementation(annotationProcessor("io.github.llamalad7:mixinextras-fabric:0.2.2")))
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"

View File

@ -3,10 +3,7 @@ package fr.adrien1106.reframed.block;
import com.google.common.base.MoreObjects;
import fr.adrien1106.reframed.ReFramed;
import fr.adrien1106.reframed.util.ReFramedInteractionUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockEntityProvider;
import net.minecraft.block.BlockState;
import net.minecraft.block.ShapeContext;
import net.minecraft.block.*;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.player.PlayerEntity;

View File

@ -1,56 +0,0 @@
package fr.adrien1106.reframed.client.model;
import fr.adrien1106.reframed.client.ReFramedClient;
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.Baker;
import net.minecraft.client.render.model.ModelBakeSettings;
import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.texture.Sprite;
import net.minecraft.client.util.SpriteIdentifier;
import net.minecraft.util.Identifier;
import java.util.Collection;
import java.util.Collections;
import java.util.function.Function;
public class UnbakedMeshRetexturedModel implements UnbakedModel {
public UnbakedMeshRetexturedModel(Identifier parent, Function<Function<SpriteIdentifier, Sprite>, Mesh> baseMeshFactory) {
this.parent = parent;
this.baseMeshFactory = baseMeshFactory;
}
protected final Identifier parent;
protected final Function<Function<SpriteIdentifier, Sprite>, Mesh> baseMeshFactory;
protected boolean ao = true;
@Override
public Collection<Identifier> getModelDependencies() {
return Collections.singletonList(parent);
}
@Override
public void setParents(Function<Identifier, UnbakedModel> function) {
function.apply(parent).setParents(function);
}
@Override
public BakedModel bake(Baker baker, Function<SpriteIdentifier, Sprite> spriteLookup, ModelBakeSettings modelBakeSettings, Identifier identifier) {
Mesh transformedBaseMesh = MeshTransformUtil.pretransformMesh(baseMeshFactory.apply(spriteLookup), MeshTransformUtil.applyAffine(modelBakeSettings));
return new RetexturingBakedModel(
baker.bake(parent, modelBakeSettings),
ReFramedClient.HELPER.getCamoApperanceManager(spriteLookup),
modelBakeSettings,
Blocks.AIR.getDefaultState(),
ao
) {
@Override
protected Mesh getBaseMesh(BlockState state) {
return transformedBaseMesh;
}
};
}
}

View File

@ -0,0 +1,46 @@
package fr.adrien1106.reframed.mixin;
import com.llamalad7.mixinextras.sugar.Local;
import fr.adrien1106.reframed.block.ReFramedEntity;
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 ReFramedEntity frame_entity)) return state.isOpaque();
return frame_entity.getThemeState().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 ReFramedEntity entity) other_state = entity.getThemeState();
if (world.getBlockEntity(pos) instanceof ReFramedEntity entity) state = entity.getThemeState();
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 ReFramedEntity) && !(world.getBlockEntity(other_pos) instanceof ReFramedEntity)) 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

@ -0,0 +1,49 @@
package fr.adrien1106.reframed.mixin;
import com.llamalad7.mixinextras.sugar.Local;
import fr.adrien1106.reframed.block.ReFramedEntity;
import net.fabricmc.fabric.impl.client.indigo.renderer.render.BlockRenderInfo;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.entity.BlockEntity;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
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.ModifyArg;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(BlockRenderInfo.class)
public abstract class BlockRenderInfoMixin {
@Shadow public BlockPos blockPos;
@Shadow public BlockState blockState;
@Shadow public BlockRenderView blockView;
@Shadow @Final private BlockPos.Mutable searchPos;
@ModifyArg(method = "prepareForBlock",
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/RenderLayers;" +
"getBlockLayer(Lnet/minecraft/block/BlockState;)Lnet/minecraft/client/render/RenderLayer;"))
public BlockState prepareCamoLayer(BlockState state, @Local(argsOnly = true) BlockPos pos) {
BlockEntity block_entity = MinecraftClient.getInstance().world.getBlockEntity(pos);
if (!(block_entity instanceof ReFramedEntity frame_entity)) return state;
return frame_entity.getThemeState();
}
@Inject(method = "shouldDrawFace",
at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/util/math/Direction;getId()I"),
cancellable = true)
private void shouldDrawCamoFace(Direction face, CallbackInfoReturnable<Boolean> cir) {
BlockEntity block_entity = MinecraftClient.getInstance().world.getBlockEntity(blockPos);
if (!(block_entity instanceof ReFramedEntity)) return;
cir.setReturnValue(Block.shouldDrawSide(blockState, blockView, blockPos, face, searchPos.set(blockPos, face)));
}
}

View File

@ -9,6 +9,8 @@
"particles.MixinLivingEntity"
],
"client": [
"BlockRenderInfoMixin",
"BlockMixin",
"particles.AccessorParticle",
"particles.AccessorSpriteBillboardParticle",
"particles.MixinBlockDustParticle",