added new blocks and further axiom support #17
@ -45,7 +45,10 @@ public class DoubleRetexturingBakedModel extends ForwardingBakedModel implements
|
||||
}
|
||||
|
||||
@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) {
|
||||
model_1.emitBlockQuads(world, state, pos, randomSupplier, context);
|
||||
model_2.emitBlockQuads(world, state, pos, randomSupplier, context);
|
||||
}
|
||||
|
||||
@Override // models are emitted here because no checks are done on items
|
||||
public void emitItemQuads(ItemStack stack, Supplier<Random> randomSupplier, RenderContext context) {
|
||||
|
@ -125,6 +125,7 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
||||
@Override
|
||||
public void emitBlockQuads(BlockRenderView world, BlockState state, BlockPos pos, Supplier<Random> randomSupplier, RenderContext context) {
|
||||
BlockState theme = (world.getBlockEntity(pos) instanceof ThemeableBlockEntity s) ? s.getTheme(theme_index) : null;
|
||||
|
||||
QuadEmitter quad_emitter = context.getEmitter();
|
||||
if(theme == null || theme.isAir()) {
|
||||
getRetexturedMesh(
|
||||
|
@ -12,7 +12,6 @@ import net.fabricmc.api.Environment;
|
||||
import net.fabricmc.fabric.api.renderer.v1.Renderer;
|
||||
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.function.BooleanBiFunction;
|
||||
@ -52,8 +51,6 @@ public class RenderHelper {
|
||||
Random random = Random.create();
|
||||
|
||||
List<List<QuadPosBounds>> model_bounds = models.stream()
|
||||
.map(ForwardingBakedModel::getWrappedModel)
|
||||
.filter(Objects::nonNull)
|
||||
.map(wrapped -> wrapped.getQuads(state, null, random))
|
||||
.map(quads -> quads.stream().map(quad -> {
|
||||
quad_emitter.fromVanilla(quad, material, null);
|
||||
@ -98,12 +95,17 @@ public class RenderHelper {
|
||||
|
||||
// Doing this method from scratch as it is simpler to do than injecting everywhere
|
||||
public static boolean shouldDrawSide(BlockState self_state, BlockView world, BlockPos pos, Direction side, BlockPos other_pos, int theme_index) {
|
||||
ThemeableBlockEntity self = world.getBlockEntity(pos) instanceof ThemeableBlockEntity e ? e : null;
|
||||
ThemeableBlockEntity other = world.getBlockEntity(other_pos) instanceof ThemeableBlockEntity e ? e : null;
|
||||
BlockState other_state = world.getBlockState(other_pos);
|
||||
ThemeableBlockEntity self = world.getBlockEntity(pos) instanceof ThemeableBlockEntity e
|
||||
&& self_state.getBlock() instanceof ReFramedBlock
|
||||
? e : null;
|
||||
ThemeableBlockEntity other = world.getBlockEntity(other_pos) instanceof ThemeableBlockEntity e
|
||||
&& other_state.getBlock() instanceof ReFramedBlock
|
||||
? e : null;
|
||||
|
||||
// normal behaviour
|
||||
if (self == null && other == null) return Block.shouldDrawSide(self_state, world, pos, side, other_pos);
|
||||
if (theme_index == 0 || (self == null && other == null))
|
||||
return Block.shouldDrawSide(self_state, world, pos, side, other_pos);
|
||||
|
||||
// self is a normal Block
|
||||
if (self == null && other_state.getBlock() instanceof ReFramedBlock other_block) {
|
||||
|
@ -26,8 +26,10 @@ public class CompatMixinPlugin implements IMixinConfigPlugin {
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.render.BlockRenderInfoMixin", () -> !LOADER.isModLoaded(COMPAT_MOD.get(1)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.render.AbstractBlockRenderContextMixin", () -> !LOADER.isModLoaded(COMPAT_MOD.get(1)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.IndiumTerrainRenderContextMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(1)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.IndiumTerrainBlockRenderInfoMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(1)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.IndiumAbstractBlockRenderContextMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(1)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.IndiumBlockRenderInfoMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(1)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.IndiumNonTerrainBlockRenderContextMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(1)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.render.BlockRenderContextMixin", () -> !LOADER.isModLoaded(COMPAT_MOD.get(1)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.SodiumBlockOcclusionCacheMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(2)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.ContinuityConnectionPredicateMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(4)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.ContinuityCTMBakedModelMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(4)));
|
||||
@ -38,6 +40,7 @@ public class CompatMixinPlugin implements IMixinConfigPlugin {
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.AxiomClipboardMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(5)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.AxiomCloneBuilderToolMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(5)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.AxiomPlacementMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(5)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.AxiomMappedBlockAndTintGetterMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(5)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.AxiomMoveBuilderToolMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(5)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.AxiomScale3xMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(5)));
|
||||
CONDITIONS.put("fr.adrien1106.reframed.mixin.compat.AxiomRotSpriteMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(5)));
|
||||
|
@ -1,5 +1,6 @@
|
||||
package fr.adrien1106.reframed.mixin.compat;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import com.moulberry.axiom.render.regions.ChunkedBlockRegion;
|
||||
import com.moulberry.axiom.utils.IntMatrix;
|
||||
import com.moulberry.axiom.world_modification.CompressedBlockEntity;
|
||||
@ -9,29 +10,27 @@ import fr.adrien1106.reframed.util.mixin.IAxiomChunkedBlockRegionMixin;
|
||||
import fr.adrien1106.reframed.util.mixin.IMultipartBakedModelMixin;
|
||||
import fr.adrien1106.reframed.util.mixin.ThemedBlockEntity;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import net.minecraft.block.BlockRenderType;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.client.render.BufferBuilder;
|
||||
import net.minecraft.client.render.Camera;
|
||||
import net.minecraft.client.render.OverlayTexture;
|
||||
import net.minecraft.client.render.block.BlockRenderManager;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.nbt.NbtHelper;
|
||||
import net.minecraft.registry.Registries;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.joml.Matrix4f;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
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.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@ -43,11 +42,10 @@ import static fr.adrien1106.reframed.block.ReFramedEntity.BLOCKSTATE_KEY;
|
||||
@Mixin(ChunkedBlockRegion.class) // TODO: Look here for better rotation/flip support
|
||||
public abstract class AxiomChunkedBlockRegionMixin implements IAxiomChunkedBlockRegionMixin {
|
||||
|
||||
@Shadow
|
||||
private static void renderBlock(BufferBuilder blockBuilder, BlockRenderManager renderManager, BlockPos.Mutable blockPos, Random rand, MatrixStack matrices, BlockRenderView blockAndTintGetter, Matrix4f currentPoseMatrix, Matrix4f basePoseMatrix, int x, int y, int z, BlockState dataState, boolean useAmbientOcclusion) {}
|
||||
|
||||
@Shadow public abstract BlockState getBlockState(BlockPos pos);
|
||||
|
||||
@Shadow public abstract @Nullable BlockEntity getBlockEntity(BlockPos pos);
|
||||
|
||||
@Unique
|
||||
private IntMatrix transform;
|
||||
@Unique
|
||||
@ -55,48 +53,46 @@ public abstract class AxiomChunkedBlockRegionMixin implements IAxiomChunkedBlock
|
||||
@Unique
|
||||
private Long2ObjectMap<CompressedBlockEntity> block_entities;
|
||||
|
||||
@Unique
|
||||
private static boolean isFrameModel(BakedModel model) {
|
||||
return model instanceof RetexturingBakedModel || model instanceof MultiRetexturableModel;
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "uploadDirty",
|
||||
@Unique
|
||||
private static List<BakedModel> getModels(BakedModel model, BlockState state) {
|
||||
if (isFrameModel(model))
|
||||
return List.of(model);
|
||||
else if (model instanceof IMultipartBakedModelMixin mpm)
|
||||
return mpm.getModels(state).stream().filter(AxiomChunkedBlockRegionMixin::isFrameModel).toList();
|
||||
else
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Inject(
|
||||
method = "renderBlock",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lcom/moulberry/axiom/render/regions/ChunkedBlockRegion;renderBlock(Lnet/minecraft/client/render/BufferBuilder;Lnet/minecraft/client/render/block/BlockRenderManager;Lnet/minecraft/util/math/BlockPos$Mutable;Lnet/minecraft/util/math/random/Random;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/world/BlockRenderView;Lorg/joml/Matrix4f;Lorg/joml/Matrix4f;IIILnet/minecraft/block/BlockState;Z)V"
|
||||
)
|
||||
)
|
||||
private void onRenderBlock(BufferBuilder buffer, BlockRenderManager renderer, BlockPos.Mutable pos, Random rand, MatrixStack matrices, BlockRenderView world, Matrix4f current_pos, Matrix4f base_pos, int x, int y, int z, BlockState state, boolean use_ao) {
|
||||
BakedModel model;
|
||||
value = "INVOKE_ASSIGN",
|
||||
target = "Lnet/minecraft/client/render/block/BlockRenderManager;getModel(Lnet/minecraft/block/BlockState;)Lnet/minecraft/client/render/model/BakedModel;",
|
||||
shift = At.Shift.AFTER
|
||||
),
|
||||
cancellable = true)
|
||||
private static void onRenderBlock(BufferBuilder blockBuilder, BlockRenderManager renderer, BlockPos.Mutable pos, Random rand, MatrixStack matrices, BlockRenderView world, Matrix4f currentPoseMatrix, Matrix4f basePoseMatrix, int x, int y, int z, BlockState state, boolean useAmbientOcclusion, CallbackInfo ci, @Local BakedModel model) {
|
||||
List<BakedModel> models;
|
||||
if (block_entities != null
|
||||
&& state.getRenderType() == BlockRenderType.MODEL
|
||||
&& (model = renderer.getModel(state)) != null
|
||||
&& model instanceof IMultipartBakedModelMixin mpm
|
||||
&& !(models = mpm.getModels(state)
|
||||
.stream()
|
||||
.filter(m -> m instanceof RetexturingBakedModel || m instanceof MultiRetexturableModel)
|
||||
.toList()).isEmpty()
|
||||
) {
|
||||
long key = BlockPos.asLong(
|
||||
inverse_transform.transformX(pos.getX(), pos.getY(), pos.getZ()),
|
||||
inverse_transform.transformY(pos.getX(), pos.getY(), pos.getZ()),
|
||||
inverse_transform.transformZ(pos.getX(), pos.getY(), pos.getZ())
|
||||
);
|
||||
if (block_entities.containsKey(key)) {
|
||||
NbtCompound compound = block_entities.get(key).decompress();
|
||||
models.stream()
|
||||
.flatMap(m -> m instanceof MultiRetexturableModel mm
|
||||
if ((models = getModels(model, state)).isEmpty() // not a retexturable model
|
||||
|| !(world.getBlockEntity(pos) instanceof ThemedBlockEntity block_entity) // not a themed block entity
|
||||
) return;
|
||||
|
||||
models.stream().flatMap(m -> m instanceof MultiRetexturableModel mm
|
||||
? mm.models().stream()
|
||||
: Stream.of((RetexturingBakedModel)m)
|
||||
)
|
||||
.forEach(m -> m.setCamo(
|
||||
world,
|
||||
compound.contains(BLOCKSTATE_KEY + m.getThemeIndex())
|
||||
? NbtHelper.toBlockState(Registries.BLOCK.getReadOnlyWrapper(), compound.getCompound(BLOCKSTATE_KEY + m.getThemeIndex()))
|
||||
: null,
|
||||
pos
|
||||
));
|
||||
}
|
||||
}
|
||||
renderBlock(buffer, renderer, pos, rand, matrices, world, current_pos, base_pos, x, y, z, state, use_ao);
|
||||
).forEach(m -> {
|
||||
m.setCamo(world, block_entity.getTheme(m.getThemeIndex()), pos);
|
||||
if (useAmbientOcclusion && state.getLuminance() == 0 && m.useAmbientOcclusion()) renderer.getModelRenderer()
|
||||
.renderSmooth(world, m, state, pos, matrices, blockBuilder, true, rand, state.getRenderingSeed(pos), OverlayTexture.DEFAULT_UV);
|
||||
else renderer.getModelRenderer()
|
||||
.renderFlat(world, m, state, pos, matrices, blockBuilder, true, rand, state.getRenderingSeed(pos), OverlayTexture.DEFAULT_UV);
|
||||
});
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
@Inject(
|
||||
|
@ -0,0 +1,32 @@
|
||||
package fr.adrien1106.reframed.mixin.compat;
|
||||
|
||||
import fr.adrien1106.reframed.block.ReFramedEntity;
|
||||
import net.minecraft.block.entity.BlockEntity;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.World;
|
||||
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.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(targets = "com.moulberry.axiom.render.ChunkRenderOverrider$MappedBlockAndTintGetter")
|
||||
public class AxiomMappedBlockAndTintGetterMixin {
|
||||
|
||||
@Shadow @Final private World level;
|
||||
|
||||
@Inject(
|
||||
method = "getBlockEntity",
|
||||
at = @At(
|
||||
value = "RETURN"
|
||||
),
|
||||
remap = false,
|
||||
cancellable = true
|
||||
)
|
||||
private void onGetBlockEntity(BlockPos pos, CallbackInfoReturnable<BlockEntity> cir) {
|
||||
if (!(level.getBlockEntity(pos) instanceof ReFramedEntity frame_entity)) return;
|
||||
cir.setReturnValue(frame_entity);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package fr.adrien1106.reframed.mixin.compat;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import fr.adrien1106.reframed.client.util.RenderHelper;
|
||||
import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity;
|
||||
import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin;
|
||||
import link.infra.indium.renderer.render.BlockRenderInfo;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
@Mixin(BlockRenderInfo.class)
|
||||
public abstract class IndiumBlockRenderInfoMixin implements IBlockRenderInfoMixin {
|
||||
|
||||
@Shadow public abstract void prepareForBlock(BlockState blockState, BlockPos blockPos, long seed, boolean modelAo);
|
||||
|
||||
@Shadow public BlockPos blockPos;
|
||||
@Shadow public BlockRenderView blockView;
|
||||
@Shadow public BlockState blockState;
|
||||
@Shadow(remap = false) private int cullResultFlags;
|
||||
|
||||
@Unique private int theme_index = 0;
|
||||
@Unique private int model_hash = 0;
|
||||
|
||||
@Inject(
|
||||
method = "shouldDrawFace",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Llink/infra/indium/renderer/render/BlockRenderInfo;shouldDrawFaceInner(Lnet/minecraft/util/math/Direction;)Z"
|
||||
),
|
||||
cancellable = true
|
||||
)
|
||||
private void shouldDrawInnerFace(Direction face, CallbackInfoReturnable<Boolean> cir, @Local int mask) {
|
||||
BlockPos other_pos = blockPos.offset(face);
|
||||
if (!(blockView.getBlockEntity(blockPos) instanceof ThemeableBlockEntity
|
||||
|| blockView.getBlockEntity(other_pos) instanceof ThemeableBlockEntity)
|
||||
) return;
|
||||
boolean result = RenderHelper.shouldDrawSide(blockState, blockView, blockPos, face, other_pos, theme_index);
|
||||
if (result) cullResultFlags |= mask;
|
||||
cir.setReturnValue(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareForBlock(BlockState blockState, BlockPos blockPos, long seed, boolean modelAo, int theme_index, int model_hash) {
|
||||
this.theme_index = theme_index;
|
||||
this.model_hash = model_hash;
|
||||
prepareForBlock(blockState, blockPos, seed, modelAo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getThemeIndex() {
|
||||
return theme_index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getModelHash() {
|
||||
return model_hash;
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
package fr.adrien1106.reframed.mixin.compat;
|
||||
|
||||
import fr.adrien1106.reframed.client.model.MultiRetexturableModel;
|
||||
import fr.adrien1106.reframed.client.model.RetexturingBakedModel;
|
||||
import fr.adrien1106.reframed.client.util.RenderHelper;
|
||||
import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin;
|
||||
import fr.adrien1106.reframed.util.mixin.IMultipartBakedModelMixin;
|
||||
import link.infra.indium.renderer.aocalc.AoCalculator;
|
||||
import link.infra.indium.renderer.render.AbstractBlockRenderContext;
|
||||
import link.infra.indium.renderer.render.BlockRenderInfo;
|
||||
import link.infra.indium.renderer.render.NonTerrainBlockRenderContext;
|
||||
import link.infra.indium.renderer.render.SingleBlockLightDataCache;
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
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.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(NonTerrainBlockRenderContext.class)
|
||||
public abstract class IndiumNonTerrainBlockRenderContextMixin extends AbstractBlockRenderContext {
|
||||
|
||||
@Shadow(remap = false) @Final private SingleBlockLightDataCache lightCache;
|
||||
|
||||
@Shadow private VertexConsumer vertexConsumer;
|
||||
|
||||
@Inject(
|
||||
method = "render",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Llink/infra/indium/renderer/render/BlockRenderInfo;prepareForWorld(Lnet/minecraft/world/BlockRenderView;Z)V",
|
||||
shift = At.Shift.AFTER
|
||||
),
|
||||
remap = false,
|
||||
cancellable = true
|
||||
)
|
||||
private void renderMultipleModels(BlockRenderView blockView, BakedModel wrapper, BlockState state, BlockPos pos, MatrixStack matrixStack, VertexConsumer buffer, boolean cull, Random random, long seed, int overlay, CallbackInfo ci) {
|
||||
if (!(wrapper instanceof IMultipartBakedModelMixin wrapped)) return;
|
||||
List<BakedModel> models = wrapped.getModels(state);
|
||||
if (models.stream().noneMatch(bakedModel ->
|
||||
bakedModel instanceof MultiRetexturableModel
|
||||
|| bakedModel instanceof RetexturingBakedModel
|
||||
)) return;
|
||||
|
||||
models.forEach(model -> {
|
||||
if (model instanceof MultiRetexturableModel multi_model) {
|
||||
RenderHelper.computeInnerCull(state, multi_model.models(), model.hashCode());
|
||||
multi_model.models().forEach(rexteruable_model ->
|
||||
renderModel(state, pos, seed, rexteruable_model, aoCalc, blockInfo, this, model.hashCode())
|
||||
);
|
||||
} else if (model instanceof RetexturingBakedModel rexteruable_model)
|
||||
renderModel(state, pos, seed, rexteruable_model, aoCalc, blockInfo, this, model.hashCode());
|
||||
else model.emitBlockQuads(blockInfo.blockView, blockInfo.blockState, blockInfo.blockPos, blockInfo.randomSupplier, this);
|
||||
});
|
||||
|
||||
blockInfo.release();
|
||||
lightCache.release();
|
||||
vertexConsumer = null;
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static void renderModel(BlockState state, BlockPos pos, long seed, RetexturingBakedModel model, AoCalculator aoCalc, BlockRenderInfo block_info, RenderContext context, int model_hash) {
|
||||
aoCalc.clear();
|
||||
((IBlockRenderInfoMixin) block_info).prepareForBlock(
|
||||
state, pos, seed,
|
||||
model.useAmbientOcclusion(block_info.blockView, pos),
|
||||
model.getThemeIndex(), model_hash
|
||||
);
|
||||
model.emitBlockQuads(block_info.blockView, block_info.blockState, block_info.blockPos, block_info.randomSupplier, context);
|
||||
}
|
||||
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
package fr.adrien1106.reframed.mixin.compat;
|
||||
|
||||
import fr.adrien1106.reframed.client.util.RenderHelper;
|
||||
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;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.BlockView;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(TerrainBlockRenderInfo.class)
|
||||
public abstract class IndiumTerrainBlockRenderInfoMixin extends BlockRenderInfo implements IBlockRenderInfoMixin {
|
||||
|
||||
@Unique private int theme_index = 0;
|
||||
@Unique private int model_hash = 0;
|
||||
|
||||
@Redirect(
|
||||
method = "shouldDrawFaceInner",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lme/jellysquid/mods/sodium/client/render/chunk/compile/pipeline/BlockOcclusionCache;shouldDrawSide(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;)Z"
|
||||
)
|
||||
)
|
||||
private boolean shouldDrawCamoSide(BlockOcclusionCache instance, BlockState state, BlockView view, BlockPos pos, Direction face) {
|
||||
BlockPos other_pos = pos.offset(face);
|
||||
if (!(view.getBlockEntity(pos) instanceof ThemeableBlockEntity
|
||||
|| view.getBlockEntity(other_pos) instanceof ThemeableBlockEntity))
|
||||
return instance.shouldDrawSide(state, view, pos, face);
|
||||
return RenderHelper.shouldDrawSide(state, view, pos, face, other_pos, theme_index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void prepareForBlock(BlockState blockState, BlockPos blockPos, long seed, boolean modelAo, int theme_index, int model_hash) {
|
||||
this.theme_index = theme_index;
|
||||
this.model_hash = model_hash;
|
||||
prepareForBlock(blockState, blockPos, seed, modelAo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getThemeIndex() {
|
||||
return theme_index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getModelHash() {
|
||||
return model_hash;
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package fr.adrien1106.reframed.mixin.render;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import fr.adrien1106.reframed.client.model.RetexturingBakedModel;
|
||||
import fr.adrien1106.reframed.client.util.RenderHelper;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.render.block.BlockModelRenderer;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.world.BlockView;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
|
||||
@Mixin(BlockModelRenderer.class)
|
||||
public class BlockModelRendererMixin {
|
||||
|
||||
@Redirect(
|
||||
method = "renderSmooth",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/block/Block;shouldDrawSide(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;Lnet/minecraft/util/math/BlockPos;)Z"
|
||||
)
|
||||
)
|
||||
private boolean shouldDrawFrameSideS(BlockState state, BlockView world, BlockPos pos, Direction side, BlockPos other_pos, @Local(argsOnly = true) BakedModel model) {
|
||||
return RenderHelper.shouldDrawSide(state, world, pos, side, other_pos, model instanceof RetexturingBakedModel rm ? rm.getThemeIndex() : 0);
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
method = "renderFlat",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/block/Block;shouldDrawSide(Lnet/minecraft/block/BlockState;Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/math/Direction;Lnet/minecraft/util/math/BlockPos;)Z"
|
||||
)
|
||||
)
|
||||
private boolean shouldDrawFrameSideF(BlockState state, BlockView world, BlockPos pos, Direction side, BlockPos other_pos, @Local(argsOnly = true) BakedModel model) {
|
||||
return RenderHelper.shouldDrawSide(state, world, pos, side, other_pos, model instanceof RetexturingBakedModel rm ? rm.getThemeIndex() : 0);
|
||||
}
|
||||
}
|
@ -0,0 +1,78 @@
|
||||
package fr.adrien1106.reframed.mixin.render;
|
||||
|
||||
import fr.adrien1106.reframed.client.model.MultiRetexturableModel;
|
||||
import fr.adrien1106.reframed.client.model.RetexturingBakedModel;
|
||||
import fr.adrien1106.reframed.client.util.RenderHelper;
|
||||
import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin;
|
||||
import fr.adrien1106.reframed.util.mixin.IMultipartBakedModelMixin;
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.aocalc.AoCalculator;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.render.AbstractBlockRenderContext;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.render.BlockRenderContext;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.render.BlockRenderInfo;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.render.model.BakedModel;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.Unique;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mixin(BlockRenderContext.class)
|
||||
public abstract class BlockRenderContextMixin extends AbstractBlockRenderContext {
|
||||
|
||||
@Shadow private VertexConsumer vertexConsumer;
|
||||
|
||||
@Inject(
|
||||
method = "render",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/fabricmc/fabric/impl/client/indigo/renderer/render/BlockRenderInfo;prepareForWorld(Lnet/minecraft/world/BlockRenderView;Z)V",
|
||||
shift = At.Shift.AFTER
|
||||
),
|
||||
cancellable = true
|
||||
)
|
||||
private void renderMultipleModels(BlockRenderView blockView, BakedModel wrapper, BlockState state, BlockPos pos, MatrixStack matrixStack, VertexConsumer buffer, boolean cull, Random random, long seed, int overlay, CallbackInfo ci) {
|
||||
if (!(wrapper instanceof IMultipartBakedModelMixin wrapped)) return;
|
||||
List<BakedModel> models = wrapped.getModels(state);
|
||||
if (models.stream().noneMatch(bakedModel ->
|
||||
bakedModel instanceof MultiRetexturableModel
|
||||
|| bakedModel instanceof RetexturingBakedModel
|
||||
)) return;
|
||||
|
||||
models.forEach(model -> {
|
||||
if (model instanceof MultiRetexturableModel multi_model) {
|
||||
RenderHelper.computeInnerCull(state, multi_model.models(), model.hashCode());
|
||||
multi_model.models().forEach(rexteruable_model ->
|
||||
renderModel(state, pos, rexteruable_model, aoCalc, blockInfo, this, model.hashCode())
|
||||
);
|
||||
} else if (model instanceof RetexturingBakedModel rexteruable_model)
|
||||
renderModel(state, pos, rexteruable_model, aoCalc, blockInfo, this, model.hashCode());
|
||||
else model.emitBlockQuads(blockInfo.blockView, blockInfo.blockState, blockInfo.blockPos, blockInfo.randomSupplier, this);
|
||||
});
|
||||
|
||||
blockInfo.release();
|
||||
vertexConsumer = null;
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
@Unique
|
||||
private static void renderModel(BlockState state, BlockPos pos, RetexturingBakedModel model, AoCalculator aoCalc, BlockRenderInfo block_info, RenderContext context, int model_hash) {
|
||||
aoCalc.clear();
|
||||
((IBlockRenderInfoMixin) block_info).prepareForBlock(
|
||||
state, pos,
|
||||
model.useAmbientOcclusion(block_info.blockView, pos),
|
||||
model.getThemeIndex(), model_hash
|
||||
);
|
||||
model.emitBlockQuads(block_info.blockView, block_info.blockState, block_info.blockPos, block_info.randomSupplier, context);
|
||||
}
|
||||
|
||||
}
|
@ -19,6 +19,7 @@
|
||||
"compat.AxiomClientBlockEntitySerializerMixin",
|
||||
"compat.AxiomClipboardMixin",
|
||||
"compat.AxiomCloneBuilderToolMixin",
|
||||
"compat.AxiomMappedBlockAndTintGetterMixin",
|
||||
"compat.AxiomMoveBuilderToolMixin",
|
||||
"compat.AxiomPlacementMixin",
|
||||
"compat.AxiomRotSpriteMixin",
|
||||
@ -28,7 +29,8 @@
|
||||
"compat.ContinuityCTMQuadTransformMixin",
|
||||
"compat.ContinuityModelWrappingHandlerMixin",
|
||||
"compat.IndiumAbstractBlockRenderContextMixin",
|
||||
"compat.IndiumTerrainBlockRenderInfoMixin",
|
||||
"compat.IndiumBlockRenderInfoMixin",
|
||||
"compat.IndiumNonTerrainBlockRenderContextMixin",
|
||||
"compat.IndiumTerrainRenderContextMixin",
|
||||
"compat.SodiumBlockOcclusionCacheMixin",
|
||||
"model.WeightedBakedModelAccessor",
|
||||
@ -36,6 +38,8 @@
|
||||
"particles.AccessorSpriteBillboardParticle",
|
||||
"particles.MixinBlockDustParticle",
|
||||
"render.AbstractBlockRenderContextMixin",
|
||||
"render.BlockModelRendererMixin",
|
||||
"render.BlockRenderContextMixin",
|
||||
"render.BlockRenderInfoMixin",
|
||||
"render.MultipartBakedModelMixin",
|
||||
"render.TerrainRenderContextMixin",
|
||||
|
Loading…
Reference in New Issue
Block a user