mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-13 05:54:17 +01:00
Rudebidium
- Misc. workarounds to make copycat blocks render correctly with sodiums optimization strategies
This commit is contained in:
parent
641e0f000a
commit
1432c46c47
@ -278,6 +278,10 @@ public abstract class CopycatBlock extends Block implements IBE<CopycatBlockEnti
|
||||
public boolean canFaceBeOccluded(BlockState state, Direction face) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean shouldFaceAlwaysRender(BlockState state, Direction face) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Wrapped properties
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.simibubi.create.content.curiosities.frames;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
@ -48,11 +49,7 @@ public abstract class CopycatModel extends BakedModelWrapperWithData {
|
||||
|
||||
OcclusionData occlusionData = new OcclusionData();
|
||||
if (state.getBlock() instanceof CopycatBlock copycatBlock) {
|
||||
MutableBlockPos mutablePos = new MutableBlockPos();
|
||||
for (Direction face : Iterate.directions)
|
||||
if (copycatBlock.canFaceBeOccluded(state, face))
|
||||
if (!Block.shouldRenderFace(material, world, pos, face, mutablePos.setWithOffset(pos, face)))
|
||||
occlusionData.occlude(face);
|
||||
gatherOcclusionData(world, pos, state, material, occlusionData, copycatBlock);
|
||||
builder.withInitial(OCCLUSION_PROPERTY, occlusionData);
|
||||
}
|
||||
|
||||
@ -60,8 +57,35 @@ public abstract class CopycatModel extends BakedModelWrapperWithData {
|
||||
builder.withInitial(WRAPPED_DATA_PROPERTY, wrappedData);
|
||||
}
|
||||
|
||||
private void gatherOcclusionData(BlockAndTintGetter world, BlockPos pos, BlockState state, BlockState material,
|
||||
OcclusionData occlusionData, CopycatBlock copycatBlock) {
|
||||
MutableBlockPos mutablePos = new MutableBlockPos();
|
||||
for (Direction face : Iterate.directions) {
|
||||
|
||||
// Rubidium: Run an additional IForgeBlock.hidesNeighborFace check because it
|
||||
// seems to be missing in Block.shouldRenderFace
|
||||
MutableBlockPos neighbourPos = mutablePos.setWithOffset(pos, face);
|
||||
BlockState neighbourState = world.getBlockState(neighbourPos);
|
||||
if (state.supportsExternalFaceHiding()
|
||||
&& neighbourState.hidesNeighborFace(world, neighbourPos, state, face.getOpposite())) {
|
||||
occlusionData.occlude(face);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!copycatBlock.canFaceBeOccluded(state, face))
|
||||
continue;
|
||||
if (!Block.shouldRenderFace(material, world, pos, face, neighbourPos))
|
||||
occlusionData.occlude(face);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads(BlockState state, Direction side, Random rand, IModelData data) {
|
||||
|
||||
// Rubidium: see below
|
||||
if (side != null && state.getBlock() instanceof CopycatBlock ccb && ccb.shouldFaceAlwaysRender(state, side))
|
||||
return Collections.emptyList();
|
||||
|
||||
BlockState material = getMaterial(data);
|
||||
|
||||
if (material == null)
|
||||
@ -79,7 +103,16 @@ public abstract class CopycatModel extends BakedModelWrapperWithData {
|
||||
if (wrappedData == null)
|
||||
wrappedData = EmptyModelData.INSTANCE;
|
||||
|
||||
return getCroppedQuads(state, side, rand, material, wrappedData);
|
||||
List<BakedQuad> croppedQuads = getCroppedQuads(state, side, rand, material, wrappedData);
|
||||
|
||||
// Rubidium: render side!=null versions of the base material during side==null,
|
||||
// to avoid getting culled away
|
||||
if (side == null && state.getBlock() instanceof CopycatBlock ccb)
|
||||
for (Direction nonOcclusionSide : Iterate.directions)
|
||||
if (ccb.shouldFaceAlwaysRender(state, nonOcclusionSide))
|
||||
croppedQuads.addAll(getCroppedQuads(state, nonOcclusionSide, rand, material, wrappedData));
|
||||
|
||||
return croppedQuads;
|
||||
}
|
||||
|
||||
protected abstract List<BakedQuad> getCroppedQuads(BlockState state, Direction side, Random rand,
|
||||
|
@ -118,6 +118,11 @@ public class CopycatPanelBlock extends WaterloggedCopycatBlock {
|
||||
.getOpposite() == face;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldFaceAlwaysRender(BlockState state, Direction face) {
|
||||
return canFaceBeOccluded(state, face.getOpposite());
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockState getConnectiveMaterial(BlockAndTintGetter reader, BlockState otherState, Direction face,
|
||||
BlockPos fromPos, BlockPos toPos) {
|
||||
|
@ -77,9 +77,8 @@ public class CopycatPanelModel extends CopycatModel {
|
||||
if (!front && direction == facing.getOpposite())
|
||||
continue;
|
||||
|
||||
BakedQuad newQuad = BakedQuadHelper.clone(quad);
|
||||
BakedModelHelper.cropAndMove(newQuad, bb, normalScaledN13);
|
||||
quads.add(newQuad);
|
||||
quads.add(BakedQuadHelper.cloneWithCustomGeometry(quad,
|
||||
BakedModelHelper.cropAndMove(quad.getVertices(), quad.getSprite(), bb, normalScaledN13)));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -138,6 +138,11 @@ public class CopycatStepBlock extends WaterloggedCopycatBlock {
|
||||
return (state.getValue(HALF) == Half.TOP) == (face == Direction.UP);
|
||||
return state.getValue(FACING) == face;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldFaceAlwaysRender(BlockState state, Direction face) {
|
||||
return canFaceBeOccluded(state, face.getOpposite());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPathfindable(BlockState pState, BlockGetter pLevel, BlockPos pPos, PathComputationType pType) {
|
||||
|
@ -77,9 +77,8 @@ public class CopycatStepModel extends CopycatModel {
|
||||
if (top && direction == Direction.DOWN)
|
||||
continue;
|
||||
|
||||
BakedQuad newQuad = BakedQuadHelper.clone(quad);
|
||||
BakedModelHelper.cropAndMove(newQuad, bb1, offset);
|
||||
quads.add(newQuad);
|
||||
quads.add(BakedQuadHelper.cloneWithCustomGeometry(quad,
|
||||
BakedModelHelper.cropAndMove(quad.getVertices(), quad.getSprite(), bb1, offset)));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUn
|
||||
import static com.simibubi.create.foundation.block.render.SpriteShiftEntry.getUnInterpolatedV;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.EnumMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -24,9 +25,10 @@ import net.minecraft.world.phys.Vec3;
|
||||
import net.minecraftforge.client.model.data.EmptyModelData;
|
||||
|
||||
public class BakedModelHelper {
|
||||
public static void cropAndMove(BakedQuad quad, AABB crop, Vec3 move) {
|
||||
int[] vertexData = quad.getVertices();
|
||||
|
||||
|
||||
public static int[] cropAndMove(int[] vertexData, TextureAtlasSprite sprite, AABB crop, Vec3 move) {
|
||||
vertexData = Arrays.copyOf(vertexData, vertexData.length);
|
||||
|
||||
Vec3 xyz0 = BakedQuadHelper.getXYZ(vertexData, 0);
|
||||
Vec3 xyz1 = BakedQuadHelper.getXYZ(vertexData, 1);
|
||||
Vec3 xyz2 = BakedQuadHelper.getXYZ(vertexData, 2);
|
||||
@ -46,8 +48,6 @@ public class BakedModelHelper {
|
||||
float v0 = BakedQuadHelper.getV(vertexData, 0);
|
||||
float v1 = BakedQuadHelper.getV(vertexData, 1);
|
||||
|
||||
TextureAtlasSprite sprite = quad.getSprite();
|
||||
|
||||
float uScale = (float) Math
|
||||
.round((getUnInterpolatedU(sprite, u3) - getUnInterpolatedU(sprite, u0)) / xyz3.distanceTo(xyz0));
|
||||
float vScale = (float) Math
|
||||
@ -91,6 +91,8 @@ public class BakedModelHelper {
|
||||
|
||||
BakedQuadHelper.setXYZ(vertexData, vertex, newXyz.add(move));
|
||||
}
|
||||
|
||||
return vertexData;
|
||||
}
|
||||
|
||||
public static BakedModel generateModel(BakedModel template, UnaryOperator<TextureAtlasSprite> spriteSwapper) {
|
||||
|
@ -29,6 +29,10 @@ public final class BakedQuadHelper {
|
||||
quad.getTintIndex(), quad.getDirection(), quad.getSprite(), quad.isShade());
|
||||
}
|
||||
|
||||
public static BakedQuad cloneWithCustomGeometry(BakedQuad quad, int[] vertexData) {
|
||||
return new BakedQuad(vertexData, quad.getTintIndex(), quad.getDirection(), quad.getSprite(), quad.isShade());
|
||||
}
|
||||
|
||||
public static Vec3 getXYZ(int[] vertexData, int vertex) {
|
||||
float x = Float.intBitsToFloat(vertexData[vertex * VERTEX_STRIDE + X_OFFSET]);
|
||||
float y = Float.intBitsToFloat(vertexData[vertex * VERTEX_STRIDE + Y_OFFSET]);
|
||||
|
Loading…
Reference in New Issue
Block a user