self culling !!
This commit is contained in:
parent
239802ce7b
commit
e6c9ee63cd
@ -76,4 +76,15 @@ public record QuadPosBounds(float min_x, float max_x, float min_y, float max_y,
|
||||
quad.pos(i, pos);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof QuadPosBounds other)) return false;
|
||||
return MathHelper.approximatelyEquals(min_x, other.min_x)
|
||||
&& MathHelper.approximatelyEquals(min_y, other.min_y)
|
||||
&& MathHelper.approximatelyEquals(min_z, other.min_z)
|
||||
&& MathHelper.approximatelyEquals(max_x, other.max_x)
|
||||
&& MathHelper.approximatelyEquals(max_y, other.max_y)
|
||||
&& MathHelper.approximatelyEquals(max_z, other.max_z);
|
||||
}
|
||||
}
|
||||
|
@ -9,10 +9,7 @@ import fr.adrien1106.reframed.client.model.apperance.CamoAppearanceManager;
|
||||
import fr.adrien1106.reframed.client.model.apperance.WeightedComputedAppearance;
|
||||
import fr.adrien1106.reframed.util.blocks.ThemeableBlockEntity;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter;
|
||||
import net.fabricmc.fabric.api.renderer.v1.mesh.*;
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel;
|
||||
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
|
||||
import net.minecraft.block.BlockState;
|
||||
@ -27,6 +24,7 @@ import net.minecraft.util.math.Direction;
|
||||
import net.minecraft.util.math.random.Random;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
||||
@ -167,12 +165,15 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
||||
MeshBuilder builder = ReFramedClient.HELPER.getFabricRenderer().meshBuilder();
|
||||
QuadEmitter emitter = builder.getEmitter();
|
||||
|
||||
AtomicInteger quad_index = new AtomicInteger();
|
||||
getBaseMesh(key.state_key, state).forEach(quad -> {
|
||||
int i = -1;
|
||||
do {
|
||||
emitter.copyFrom(quad);
|
||||
i = key.appearance.transformQuad(emitter, i, key.model_id, ao, uv_lock);
|
||||
i = key.appearance.transformQuad(emitter, i, quad_index.get(), key.model_id, ao, uv_lock);
|
||||
} while (i > 0);
|
||||
// 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();
|
||||
});
|
||||
|
||||
return builder.build();
|
||||
@ -191,9 +192,10 @@ public abstract class RetexturingBakedModel extends ForwardingBakedModel {
|
||||
|
||||
@Override
|
||||
public boolean transform(MutableQuadView quad) {
|
||||
if(quad.tag() == 0) return true;
|
||||
int camo_quad_index = quad.tag() - ((quad.tag() >>> 8) << 8);
|
||||
if(camo_quad_index == 0) return true;
|
||||
|
||||
if(appearance.hasColor(quad.nominalFace(), model_id, quad.tag())) quad.color(tint, tint, tint, tint);
|
||||
if(appearance.hasColor(quad.nominalFace(), model_id, camo_quad_index)) quad.color(tint, tint, tint, tint);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ public abstract class CamoAppearance {
|
||||
return ao && ao_material != null? ao_material : material;
|
||||
}
|
||||
|
||||
public int transformQuad(QuadEmitter quad, int i, int model_id, boolean ao, boolean uv_lock) {
|
||||
public int transformQuad(QuadEmitter quad, int i, int quad_index, int model_id, boolean ao, boolean uv_lock) {
|
||||
if(quad.tag() == 0) return 0; // Pass the quad through unmodified.
|
||||
|
||||
Direction direction = quad.nominalFace();
|
||||
@ -36,6 +36,7 @@ public abstract class CamoAppearance {
|
||||
if (i == -1) i = sprites.size();
|
||||
|
||||
SpriteProperties properties = sprites.get(sprites.size() - i);
|
||||
int tag = i + (quad_index << 8);
|
||||
i--;
|
||||
QuadPosBounds bounds = properties.bounds();
|
||||
|
||||
@ -47,7 +48,7 @@ public abstract class CamoAppearance {
|
||||
| properties.flags()
|
||||
| (uv_lock ? MutableQuadView.BAKE_LOCK_UV : 0)
|
||||
);
|
||||
quad.tag(i+1);
|
||||
quad.tag(tag);
|
||||
quad.emit();
|
||||
return i;
|
||||
}
|
||||
@ -64,7 +65,7 @@ public abstract class CamoAppearance {
|
||||
MutableQuadView.BAKE_NORMALIZED
|
||||
| MutableQuadView.BAKE_LOCK_UV
|
||||
);
|
||||
quad.tag(i+1);
|
||||
quad.tag(tag);
|
||||
quad.emit();
|
||||
return i;
|
||||
}
|
||||
|
@ -11,9 +11,7 @@ import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.nbt.NbtHelper;
|
||||
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;
|
||||
|
@ -21,9 +21,11 @@ public class CompatMixinPlugin implements IMixinConfigPlugin {
|
||||
"fr.adrien1106.reframed.mixin.compat.AthenaBakedModelMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(0)),
|
||||
"fr.adrien1106.reframed.mixin.compat.AthenaWrappedGetterMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(0)),
|
||||
"fr.adrien1106.reframed.mixin.render.TerrainRenderContextMixin", () -> !LOADER.isModLoaded(COMPAT_MOD.get(1)),
|
||||
"fr.adrien1106.reframed.mixin.compat.IndiumTerrainRenderContextMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(1)),
|
||||
"fr.adrien1106.reframed.mixin.render.BlockRenderInfoMixin", () -> !LOADER.isModLoaded(COMPAT_MOD.get(1)),
|
||||
"fr.adrien1106.reframed.mixin.render.AbstractBlockRenderContextMixin", () -> !LOADER.isModLoaded(COMPAT_MOD.get(1)),
|
||||
"fr.adrien1106.reframed.mixin.compat.IndiumTerrainRenderContextMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(1)),
|
||||
"fr.adrien1106.reframed.mixin.compat.IndiumTerrainBlockRenderInfoMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(1)),
|
||||
"fr.adrien1106.reframed.mixin.compat.IndiumAbstractBlockRenderContextMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(1)),
|
||||
"fr.adrien1106.reframed.mixin.compat.SodiumBlockOcclusionCacheMixin", () -> LOADER.isModLoaded(COMPAT_MOD.get(2))
|
||||
);
|
||||
|
||||
|
@ -0,0 +1,29 @@
|
||||
package fr.adrien1106.reframed.mixin.compat;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import fr.adrien1106.reframed.util.blocks.BlockHelper;
|
||||
import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin;
|
||||
import link.infra.indium.renderer.mesh.MutableQuadViewImpl;
|
||||
import link.infra.indium.renderer.render.AbstractBlockRenderContext;
|
||||
import link.infra.indium.renderer.render.BlockRenderInfo;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
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.Redirect;
|
||||
|
||||
@Mixin(AbstractBlockRenderContext.class)
|
||||
public abstract class IndiumAbstractBlockRenderContextMixin {
|
||||
|
||||
@Shadow(remap = false) protected BlockRenderInfo blockInfo;
|
||||
|
||||
@Shadow public abstract boolean isFaceCulled(@Nullable Direction face);
|
||||
|
||||
@Redirect(method = "renderQuad", at = @At(value = "INVOKE", target = "Llink/infra/indium/renderer/render/AbstractBlockRenderContext;isFaceCulled(Lnet/minecraft/util/math/Direction;)Z"))
|
||||
private boolean shouldDrawInnerQuad(AbstractBlockRenderContext instance, Direction face, @Local(argsOnly = true) MutableQuadViewImpl quad) {
|
||||
if (face != null || quad.tag() == 0 || !(blockInfo instanceof IBlockRenderInfoMixin info) || info.getThemeIndex() == 0) return isFaceCulled(face);
|
||||
|
||||
return !BlockHelper.shouldDrawInnerFace(blockInfo.blockState, blockInfo.blockView, blockInfo.blockPos, quad.tag() >>> 8, info.getThemeIndex());
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
@Mixin(TerrainBlockRenderInfo.class)
|
||||
public abstract class IndiumTerrainBlockRenderInfoMixin extends BlockRenderInfo implements IBlockRenderInfoMixin {
|
||||
|
||||
@Unique private int theme_index = 1;
|
||||
@Unique private int theme_index = 0;
|
||||
|
||||
@Redirect(
|
||||
method = "shouldDrawFaceInner",
|
||||
@ -40,4 +40,9 @@ public abstract class IndiumTerrainBlockRenderInfoMixin extends BlockRenderInfo
|
||||
this.theme_index = theme_index;
|
||||
prepareForBlock(blockState, blockPos, seed, modelAo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getThemeIndex() {
|
||||
return theme_index;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package fr.adrien1106.reframed.mixin.compat;
|
||||
|
||||
import fr.adrien1106.reframed.client.model.MultiRetexturableModel;
|
||||
import fr.adrien1106.reframed.util.blocks.BlockHelper;
|
||||
import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin;
|
||||
import fr.adrien1106.reframed.util.mixin.IMultipartBakedModelMixin;
|
||||
import link.infra.indium.renderer.render.AbstractBlockRenderContext;
|
||||
@ -31,6 +32,7 @@ public abstract class IndiumTerrainRenderContextMixin extends AbstractBlockRende
|
||||
|| !(wrapped.getModel(ctx.state()) instanceof MultiRetexturableModel retexturing_model)) return;
|
||||
|
||||
List<ForwardingBakedModel> models = retexturing_model.models();
|
||||
BlockHelper.computeInnerCull(ctx.state(), models);
|
||||
int i = 0;
|
||||
for (BakedModel model : models) {
|
||||
i++;
|
||||
|
@ -0,0 +1,36 @@
|
||||
package fr.adrien1106.reframed.mixin.render;
|
||||
|
||||
import com.llamalad7.mixinextras.sugar.Local;
|
||||
import fr.adrien1106.reframed.util.blocks.BlockHelper;
|
||||
import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.mesh.MutableQuadViewImpl;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.render.AbstractBlockRenderContext;
|
||||
import net.fabricmc.fabric.impl.client.indigo.renderer.render.BlockRenderInfo;
|
||||
import net.minecraft.util.math.Direction;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
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.Redirect;
|
||||
|
||||
@Mixin(AbstractBlockRenderContext.class)
|
||||
public abstract class AbstractBlockRenderContextMixin {
|
||||
|
||||
@Shadow public abstract boolean isFaceCulled(@Nullable Direction face);
|
||||
|
||||
@Shadow(remap = false) @Final protected BlockRenderInfo blockInfo;
|
||||
|
||||
@Redirect(
|
||||
method = "renderQuad",
|
||||
at = @At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/fabricmc/fabric/impl/client/indigo/renderer/render/AbstractBlockRenderContext;isFaceCulled(Lnet/minecraft/util/math/Direction;)Z"
|
||||
)
|
||||
)
|
||||
private boolean shouldDrawInnerQuad(AbstractBlockRenderContext instance, Direction face, @Local(argsOnly = true) MutableQuadViewImpl quad) {
|
||||
if (face != null || quad.tag() == 0 || !(blockInfo instanceof IBlockRenderInfoMixin info) || info.getThemeIndex() == 0) return isFaceCulled(face);
|
||||
|
||||
return !BlockHelper.shouldDrawInnerFace(blockInfo.blockState, blockInfo.blockView, blockInfo.blockPos, quad.tag() >>> 8, info.getThemeIndex());
|
||||
}
|
||||
}
|
@ -24,8 +24,7 @@ public abstract class BlockRenderInfoMixin implements IBlockRenderInfoMixin {
|
||||
@Shadow public abstract void prepareForBlock(BlockState blockState, BlockPos blockPos, boolean modelAo);
|
||||
|
||||
@Shadow public BlockRenderView blockView;
|
||||
@Unique
|
||||
private int theme_index = 1;
|
||||
@Unique private int theme_index = 0;
|
||||
|
||||
@ModifyArg(method = "prepareForBlock",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/RenderLayers;" +
|
||||
@ -47,4 +46,9 @@ public abstract class BlockRenderInfoMixin implements IBlockRenderInfoMixin {
|
||||
this.theme_index = theme_index;
|
||||
prepareForBlock(state, pos, ao);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getThemeIndex() {
|
||||
return theme_index;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package fr.adrien1106.reframed.mixin.render;
|
||||
|
||||
import fr.adrien1106.reframed.client.model.MultiRetexturableModel;
|
||||
import fr.adrien1106.reframed.util.blocks.BlockHelper;
|
||||
import fr.adrien1106.reframed.util.mixin.IBlockRenderInfoMixin;
|
||||
import fr.adrien1106.reframed.util.mixin.IMultipartBakedModelMixin;
|
||||
import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel;
|
||||
@ -30,10 +31,7 @@ public abstract class TerrainRenderContextMixin extends AbstractBlockRenderConte
|
||||
|| !(wrapped.getModel(state) instanceof MultiRetexturableModel retexturing_model)) return;
|
||||
|
||||
List<ForwardingBakedModel> models = retexturing_model.models();
|
||||
// models.forEach(model -> // TODO self culling here
|
||||
// model.getWrappedModel().getQuads(state_key, null, blockInfo.randomSupplier.get())
|
||||
// .forEach(quad -> QuadPosBounds.read(getEmitter().fromVanilla(quad.getVertexData(), 0)).min_x())
|
||||
// );
|
||||
BlockHelper.computeInnerCull(state, models);
|
||||
int i = 0;
|
||||
for (BakedModel model : models) {
|
||||
i++;
|
||||
|
@ -1,8 +1,15 @@
|
||||
package fr.adrien1106.reframed.util.blocks;
|
||||
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import fr.adrien1106.reframed.block.ReFramedBlock;
|
||||
import fr.adrien1106.reframed.block.ReFramedEntity;
|
||||
import it.unimi.dsi.fastutil.objects.Object2ByteLinkedOpenHashMap;
|
||||
import fr.adrien1106.reframed.client.ReFramedClient;
|
||||
import fr.adrien1106.reframed.client.model.QuadPosBounds;
|
||||
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.BlockEntityProvider;
|
||||
import net.minecraft.block.BlockState;
|
||||
@ -18,14 +25,17 @@ import net.minecraft.util.hit.BlockHitResult;
|
||||
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.util.shape.VoxelShape;
|
||||
import net.minecraft.util.shape.VoxelShapes;
|
||||
import net.minecraft.world.BlockRenderView;
|
||||
import net.minecraft.world.BlockView;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@ -36,17 +46,10 @@ import static net.minecraft.util.shape.VoxelShapes.combine;
|
||||
|
||||
public class BlockHelper {
|
||||
|
||||
// self culling cache TODO move
|
||||
private static final ThreadLocal<Object2ByteLinkedOpenHashMap<CullElement>> INNER_FACE_CULL_MAP = ThreadLocal.withInitial(() -> {
|
||||
Object2ByteLinkedOpenHashMap<CullElement> object2ByteLinkedOpenHashMap = new Object2ByteLinkedOpenHashMap<>(2048, 0.25F) {
|
||||
protected void rehash(int newN) {
|
||||
}
|
||||
};
|
||||
object2ByteLinkedOpenHashMap.defaultReturnValue((byte)0);
|
||||
return object2ByteLinkedOpenHashMap;
|
||||
});
|
||||
// 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).concurrencyLevel().build();
|
||||
|
||||
private record CullElement(BlockState state, int model, Direction side) {}
|
||||
private record CullElement(Object state_key, int model) {}
|
||||
|
||||
public static Corner getPlacementCorner(ItemPlacementContext ctx) {
|
||||
Direction side = ctx.getSide().getOpposite();
|
||||
@ -69,7 +72,7 @@ public class BlockHelper {
|
||||
Math.abs(axis_1.choose(pos.x, pos.y, pos.z)) > Math.abs(axis_2.choose(pos.x, pos.y, pos.z))
|
||||
? axis_1
|
||||
: axis_2
|
||||
).get();
|
||||
).orElse(null);
|
||||
}
|
||||
|
||||
public static Vec3d getRelativePos(Vec3d pos, BlockPos block_pos) {
|
||||
@ -216,6 +219,66 @@ public class BlockHelper {
|
||||
return ActionResult.PASS;
|
||||
}
|
||||
|
||||
/**
|
||||
* compute which quad might cull with another model quad
|
||||
* @param state - the state of the model
|
||||
* @param models - list of models on the same block
|
||||
*/
|
||||
public static void computeInnerCull(BlockState state, List<ForwardingBakedModel> models) {
|
||||
if (!(state.getBlock() instanceof ReFramedBlock frame_block)) return;
|
||||
Object key = frame_block.getModelCacheKey(state);
|
||||
if (INNER_CULL_MAP.asMap().containsKey(new CullElement(key, 1))) return;
|
||||
|
||||
Renderer r = ReFramedClient.HELPER.getFabricRenderer();
|
||||
QuadEmitter quad_emitter = r.meshBuilder().getEmitter();
|
||||
RenderMaterial material = r.materialFinder().clear().find();
|
||||
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);
|
||||
return QuadPosBounds.read(quad_emitter, false);
|
||||
}).toList()).toList();
|
||||
|
||||
Integer[] cull_array;
|
||||
for(int self_id = 1; self_id <= model_bounds.size(); self_id++) {
|
||||
List<QuadPosBounds> self_bounds = model_bounds.get(self_id - 1);
|
||||
cull_array = new Integer[self_bounds.size()];
|
||||
for (int self_quad = 0; self_quad < cull_array.length; self_quad++) {
|
||||
QuadPosBounds self_bound = self_bounds.get(self_quad);
|
||||
for(int other_id = 1; other_id <= model_bounds.size(); other_id++) {
|
||||
if (other_id == self_id) continue;
|
||||
if (model_bounds.get(other_id - 1).stream().anyMatch(other_bound -> other_bound.equals(self_bound))) {
|
||||
cull_array[self_quad] = other_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
INNER_CULL_MAP.put(new CullElement(key, self_id), cull_array);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean shouldDrawInnerFace(BlockState state, BlockRenderView view, BlockPos pos, int quad_index, int theme_index) {
|
||||
if ( !(state.getBlock() instanceof ReFramedBlock frame_block)
|
||||
|| !(view.getBlockEntity(pos) instanceof ThemeableBlockEntity frame_entity)
|
||||
) return true;
|
||||
CullElement key = new CullElement(frame_block.getModelCacheKey(state), theme_index);
|
||||
if (!INNER_CULL_MAP.asMap().containsKey(key)) return true;
|
||||
|
||||
// needs to be Integer object because array is initialized with null not 0
|
||||
Integer cull_theme = Objects.requireNonNull(INNER_CULL_MAP.getIfPresent(key))[quad_index];
|
||||
if (cull_theme == null) return true; // no culling possible
|
||||
|
||||
BlockState self_theme = frame_entity.getTheme(theme_index);
|
||||
BlockState other_theme = frame_entity.getTheme(cull_theme);
|
||||
|
||||
if (self_theme.isSideInvisible(other_theme, null)) return false;
|
||||
return !self_theme.isOpaque() || !other_theme.isOpaque();
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
@ -8,4 +8,6 @@ public interface IBlockRenderInfoMixin {
|
||||
void prepareForBlock(BlockState state, BlockPos pos, boolean ao, int theme_index);
|
||||
|
||||
void prepareForBlock(BlockState state, BlockPos pos, long seed, boolean ao, int theme_index);
|
||||
|
||||
int getThemeIndex();
|
||||
}
|
||||
|
@ -30,7 +30,7 @@
|
||||
"fabricloader": "^${loader_version}",
|
||||
"fabric-api": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"suggests": {
|
||||
"athena": "^${athena_version}",
|
||||
"sodium": "^${sodium_version}",
|
||||
"indium": "^${indium_version}"
|
||||
|
@ -14,6 +14,7 @@
|
||||
"compat.AthenaBakedModelMixin",
|
||||
"compat.AthenaConnectedBlockModelMixin",
|
||||
"compat.AthenaWrappedGetterMixin",
|
||||
"compat.IndiumAbstractBlockRenderContextMixin",
|
||||
"compat.IndiumTerrainBlockRenderInfoMixin",
|
||||
"compat.IndiumTerrainRenderContextMixin",
|
||||
"compat.SodiumBlockOcclusionCacheMixin",
|
||||
@ -21,6 +22,7 @@
|
||||
"particles.AccessorParticle",
|
||||
"particles.AccessorSpriteBillboardParticle",
|
||||
"particles.MixinBlockDustParticle",
|
||||
"render.AbstractBlockRenderContextMixin",
|
||||
"render.BlockRenderInfoMixin",
|
||||
"render.MultipartBakedModelMixin",
|
||||
"render.TerrainRenderContextMixin",
|
||||
|
Loading…
Reference in New Issue
Block a user