BlockModelLighter.java

net.minecraft.client.renderer.block.BlockModelLighter

信息

  • 全限定名:net.minecraft.client.renderer.block.BlockModelLighter
  • 类型:public class
  • 包:net.minecraft.client.renderer.block
  • 源码路径:src/main/java/net/minecraft/client/renderer/block/BlockModelLighter.java
  • 起始行号:L21
  • 职责:

    TODO

字段/常量

  • CACHE_SIZE

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L22
    • 说明:

      TODO

  • CACHE

    • 类型: ThreadLocal<BlockModelLighter.Cache>
    • 修饰符: private static final
    • 源码定位: L23
    • 说明:

      TODO

  • CHECK_LIGHT

    • 类型: int
    • 修饰符: public static final
    • 源码定位: L24
    • 说明:

      TODO

  • cache

    • 类型: BlockModelLighter.Cache
    • 修饰符: private final
    • 源码定位: L25
    • 说明:

      TODO

  • scratchPos

    • 类型: BlockPos.MutableBlockPos
    • 修饰符: private final
    • 源码定位: L26
    • 说明:

      TODO

  • faceCubic

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L27
    • 说明:

      TODO

  • facePartial

    • 类型: boolean
    • 修饰符: private
    • 源码定位: L28
    • 说明:

      TODO

  • faceShape

    • 类型: float[]
    • 修饰符: private final
    • 源码定位: L29
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.client.renderer.block.BlockModelLighter.AdjacencyInfo

    • 类型: enum
    • 修饰符: private static
    • 源码定位: L286
    • 说明:

      TODO

  • net.minecraft.client.renderer.block.BlockModelLighter.AmbientVertexRemap

    • 类型: enum
    • 修饰符: private static
    • 源码定位: L596
    • 说明:

      TODO

  • net.minecraft.client.renderer.block.BlockModelLighter.Cache

    • 类型: class
    • 修饰符: public static
    • 源码定位: L630
    • 说明:

      TODO

  • net.minecraft.client.renderer.block.BlockModelLighter.SizeInfo

    • 类型: enum
    • 修饰符: private static
    • 源码定位: L711
    • 说明:

      TODO

构造器

public BlockModelLighter() @ L31

  • 构造器名:BlockModelLighter
  • 源码定位:L31
  • 修饰符:public

参数:

说明:

TODO

方法

下面的方法块按源码顺序生成。

public int getLightCoords(BlockState state, BlockAndTintGetter level, BlockPos relativePos) @ L35

  • 方法名:getLightCoords
  • 源码定位:L35
  • 返回类型:int
  • 修饰符:public

参数:

  • state: BlockState
  • level: BlockAndTintGetter
  • relativePos: BlockPos

说明:

TODO

public void prepareQuadAmbientOcclusion(BlockAndTintGetter level, BlockState state, BlockPos centerPosition, BakedQuad quad, QuadInstance outputInstance) @ L39

  • 方法名:prepareQuadAmbientOcclusion
  • 源码定位:L39
  • 返回类型:void
  • 修饰符:public

参数:

  • level: BlockAndTintGetter
  • state: BlockState
  • centerPosition: BlockPos
  • quad: BakedQuad
  • outputInstance: QuadInstance

说明:

TODO

public void prepareQuadFlat(BlockAndTintGetter level, BlockState state, BlockPos pos, int lightCoords, BakedQuad quad, QuadInstance outputInstance) @ L208

  • 方法名:prepareQuadFlat
  • 源码定位:L208
  • 返回类型:void
  • 修饰符:public

参数:

  • level: BlockAndTintGetter
  • state: BlockState
  • pos: BlockPos
  • lightCoords: int
  • quad: BakedQuad
  • outputInstance: QuadInstance

说明:

TODO

private void prepareQuadShape(BlockAndTintGetter level, BlockState state, BlockPos pos, BakedQuad quad, boolean ambientOcclusion) @ L222

  • 方法名:prepareQuadShape
  • 源码定位:L222
  • 返回类型:void
  • 修饰符:private

参数:

  • level: BlockAndTintGetter
  • state: BlockState
  • pos: BlockPos
  • quad: BakedQuad
  • ambientOcclusion: boolean

说明:

TODO

public static void enableCaching() @ L277

  • 方法名:enableCaching
  • 源码定位:L277
  • 返回类型:void
  • 修饰符:public static

参数:

说明:

TODO

public static void clearCache() @ L281

  • 方法名:clearCache
  • 源码定位:L281
  • 返回类型:void
  • 修饰符:public static

参数:

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class BlockModelLighter {
    private static final int CACHE_SIZE = 100;
    private static final ThreadLocal<BlockModelLighter.Cache> CACHE = ThreadLocal.withInitial(BlockModelLighter.Cache::new);
    public static final int CHECK_LIGHT = -1;
    private final BlockModelLighter.Cache cache;
    private final BlockPos.MutableBlockPos scratchPos = new BlockPos.MutableBlockPos();
    private boolean faceCubic;
    private boolean facePartial;
    private final float[] faceShape = new float[BlockModelLighter.SizeInfo.COUNT];
 
    public BlockModelLighter() {
        this.cache = CACHE.get();
    }
 
    public int getLightCoords(BlockState state, BlockAndTintGetter level, BlockPos relativePos) {
        return this.cache.getLightCoords(state, level, relativePos);
    }
 
    public void prepareQuadAmbientOcclusion(BlockAndTintGetter level, BlockState state, BlockPos centerPosition, BakedQuad quad, QuadInstance outputInstance) {
        this.prepareQuadShape(level, state, centerPosition, quad, true);
        Direction direction = quad.direction();
        BlockPos basePosition = this.faceCubic ? centerPosition.relative(direction) : centerPosition;
        BlockModelLighter.AdjacencyInfo info = BlockModelLighter.AdjacencyInfo.fromFacing(direction);
        BlockPos.MutableBlockPos pos = this.scratchPos;
        pos.setWithOffset(basePosition, info.corners[0]);
        BlockState state0 = level.getBlockState(pos);
        int light0 = this.cache.getLightCoords(state0, level, pos);
        float shade0 = this.cache.getShadeBrightness(state0, level, pos);
        pos.setWithOffset(basePosition, info.corners[1]);
        BlockState state1 = level.getBlockState(pos);
        int light1 = this.cache.getLightCoords(state1, level, pos);
        float shade1 = this.cache.getShadeBrightness(state1, level, pos);
        pos.setWithOffset(basePosition, info.corners[2]);
        BlockState state2 = level.getBlockState(pos);
        int light2 = this.cache.getLightCoords(state2, level, pos);
        float shade2 = this.cache.getShadeBrightness(state2, level, pos);
        pos.setWithOffset(basePosition, info.corners[3]);
        BlockState state3 = level.getBlockState(pos);
        int light3 = this.cache.getLightCoords(state3, level, pos);
        float shade3 = this.cache.getShadeBrightness(state3, level, pos);
        BlockState corner0 = level.getBlockState(pos.setWithOffset(basePosition, info.corners[0]).move(direction));
        boolean translucent0 = !corner0.isViewBlocking(level, pos) || corner0.getLightDampening() == 0;
        BlockState corner1 = level.getBlockState(pos.setWithOffset(basePosition, info.corners[1]).move(direction));
        boolean translucent1 = !corner1.isViewBlocking(level, pos) || corner1.getLightDampening() == 0;
        BlockState corner2 = level.getBlockState(pos.setWithOffset(basePosition, info.corners[2]).move(direction));
        boolean translucent2 = !corner2.isViewBlocking(level, pos) || corner2.getLightDampening() == 0;
        BlockState corner3 = level.getBlockState(pos.setWithOffset(basePosition, info.corners[3]).move(direction));
        boolean translucent3 = !corner3.isViewBlocking(level, pos) || corner3.getLightDampening() == 0;
        float shadeCorner02;
        int lightCorner02;
        if (!translucent2 && !translucent0) {
            shadeCorner02 = shade0;
            lightCorner02 = light0;
        } else {
            pos.setWithOffset(basePosition, info.corners[0]).move(info.corners[2]);
            BlockState state02 = level.getBlockState(pos);
            shadeCorner02 = this.cache.getShadeBrightness(state02, level, pos);
            lightCorner02 = this.cache.getLightCoords(state02, level, pos);
        }
 
        float shadeCorner03;
        int lightCorner03;
        if (!translucent3 && !translucent0) {
            shadeCorner03 = shade0;
            lightCorner03 = light0;
        } else {
            pos.setWithOffset(basePosition, info.corners[0]).move(info.corners[3]);
            BlockState state03 = level.getBlockState(pos);
            shadeCorner03 = this.cache.getShadeBrightness(state03, level, pos);
            lightCorner03 = this.cache.getLightCoords(state03, level, pos);
        }
 
        float shadeCorner12;
        int lightCorner12;
        if (!translucent2 && !translucent1) {
            shadeCorner12 = shade0;
            lightCorner12 = light0;
        } else {
            pos.setWithOffset(basePosition, info.corners[1]).move(info.corners[2]);
            BlockState state12 = level.getBlockState(pos);
            shadeCorner12 = this.cache.getShadeBrightness(state12, level, pos);
            lightCorner12 = this.cache.getLightCoords(state12, level, pos);
        }
 
        float shadeCorner13;
        int lightCorner13;
        if (!translucent3 && !translucent1) {
            shadeCorner13 = shade0;
            lightCorner13 = light0;
        } else {
            pos.setWithOffset(basePosition, info.corners[1]).move(info.corners[3]);
            BlockState state13 = level.getBlockState(pos);
            shadeCorner13 = this.cache.getShadeBrightness(state13, level, pos);
            lightCorner13 = this.cache.getLightCoords(state13, level, pos);
        }
 
        int lightCenter = this.cache.getLightCoords(state, level, centerPosition);
        pos.setWithOffset(centerPosition, direction);
        BlockState nextState = level.getBlockState(pos);
        if (this.faceCubic || !nextState.isSolidRender()) {
            lightCenter = this.cache.getLightCoords(nextState, level, pos);
        }
 
        float shadeCenter = this.faceCubic
            ? this.cache.getShadeBrightness(level.getBlockState(basePosition), level, basePosition)
            : this.cache.getShadeBrightness(level.getBlockState(centerPosition), level, centerPosition);
        BlockModelLighter.AmbientVertexRemap remap = BlockModelLighter.AmbientVertexRemap.fromFacing(direction);
        if (this.facePartial && info.doNonCubicWeight) {
            float tempShade1 = (shade3 + shade0 + shadeCorner03 + shadeCenter) * 0.25F;
            float tempShade2 = (shade2 + shade0 + shadeCorner02 + shadeCenter) * 0.25F;
            float tempShade3 = (shade2 + shade1 + shadeCorner12 + shadeCenter) * 0.25F;
            float tempShade4 = (shade3 + shade1 + shadeCorner13 + shadeCenter) * 0.25F;
            float vert0weight01 = this.faceShape[info.vert0Weights[0].index] * this.faceShape[info.vert0Weights[1].index];
            float vert0weight23 = this.faceShape[info.vert0Weights[2].index] * this.faceShape[info.vert0Weights[3].index];
            float vert0weight45 = this.faceShape[info.vert0Weights[4].index] * this.faceShape[info.vert0Weights[5].index];
            float vert0weight67 = this.faceShape[info.vert0Weights[6].index] * this.faceShape[info.vert0Weights[7].index];
            float vert1weight01 = this.faceShape[info.vert1Weights[0].index] * this.faceShape[info.vert1Weights[1].index];
            float vert1weight23 = this.faceShape[info.vert1Weights[2].index] * this.faceShape[info.vert1Weights[3].index];
            float vert1weight45 = this.faceShape[info.vert1Weights[4].index] * this.faceShape[info.vert1Weights[5].index];
            float vert1weight67 = this.faceShape[info.vert1Weights[6].index] * this.faceShape[info.vert1Weights[7].index];
            float vert2weight01 = this.faceShape[info.vert2Weights[0].index] * this.faceShape[info.vert2Weights[1].index];
            float vert2weight23 = this.faceShape[info.vert2Weights[2].index] * this.faceShape[info.vert2Weights[3].index];
            float vert2weight45 = this.faceShape[info.vert2Weights[4].index] * this.faceShape[info.vert2Weights[5].index];
            float vert2weight67 = this.faceShape[info.vert2Weights[6].index] * this.faceShape[info.vert2Weights[7].index];
            float vert3weight01 = this.faceShape[info.vert3Weights[0].index] * this.faceShape[info.vert3Weights[1].index];
            float vert3weight23 = this.faceShape[info.vert3Weights[2].index] * this.faceShape[info.vert3Weights[3].index];
            float vert3weight45 = this.faceShape[info.vert3Weights[4].index] * this.faceShape[info.vert3Weights[5].index];
            float vert3weight67 = this.faceShape[info.vert3Weights[6].index] * this.faceShape[info.vert3Weights[7].index];
            outputInstance.setColor(
                remap.vert0,
                ARGB.gray(
                    Math.clamp(tempShade1 * vert0weight01 + tempShade2 * vert0weight23 + tempShade3 * vert0weight45 + tempShade4 * vert0weight67, 0.0F, 1.0F)
                )
            );
            outputInstance.setColor(
                remap.vert1,
                ARGB.gray(
                    Math.clamp(tempShade1 * vert1weight01 + tempShade2 * vert1weight23 + tempShade3 * vert1weight45 + tempShade4 * vert1weight67, 0.0F, 1.0F)
                )
            );
            outputInstance.setColor(
                remap.vert2,
                ARGB.gray(
                    Math.clamp(tempShade1 * vert2weight01 + tempShade2 * vert2weight23 + tempShade3 * vert2weight45 + tempShade4 * vert2weight67, 0.0F, 1.0F)
                )
            );
            outputInstance.setColor(
                remap.vert3,
                ARGB.gray(
                    Math.clamp(tempShade1 * vert3weight01 + tempShade2 * vert3weight23 + tempShade3 * vert3weight45 + tempShade4 * vert3weight67, 0.0F, 1.0F)
                )
            );
            int _tc1 = LightCoordsUtil.smoothBlend(light3, light0, lightCorner03, lightCenter);
            int _tc2 = LightCoordsUtil.smoothBlend(light2, light0, lightCorner02, lightCenter);
            int _tc3 = LightCoordsUtil.smoothBlend(light2, light1, lightCorner12, lightCenter);
            int _tc4 = LightCoordsUtil.smoothBlend(light3, light1, lightCorner13, lightCenter);
            outputInstance.setLightCoords(
                remap.vert0, LightCoordsUtil.smoothWeightedBlend(_tc1, _tc2, _tc3, _tc4, vert0weight01, vert0weight23, vert0weight45, vert0weight67)
            );
            outputInstance.setLightCoords(
                remap.vert1, LightCoordsUtil.smoothWeightedBlend(_tc1, _tc2, _tc3, _tc4, vert1weight01, vert1weight23, vert1weight45, vert1weight67)
            );
            outputInstance.setLightCoords(
                remap.vert2, LightCoordsUtil.smoothWeightedBlend(_tc1, _tc2, _tc3, _tc4, vert2weight01, vert2weight23, vert2weight45, vert2weight67)
            );
            outputInstance.setLightCoords(
                remap.vert3, LightCoordsUtil.smoothWeightedBlend(_tc1, _tc2, _tc3, _tc4, vert3weight01, vert3weight23, vert3weight45, vert3weight67)
            );
        } else {
            float lightLevel1 = (shade3 + shade0 + shadeCorner03 + shadeCenter) * 0.25F;
            float lightLevel2 = (shade2 + shade0 + shadeCorner02 + shadeCenter) * 0.25F;
            float lightLevel3 = (shade2 + shade1 + shadeCorner12 + shadeCenter) * 0.25F;
            float lightLevel4 = (shade3 + shade1 + shadeCorner13 + shadeCenter) * 0.25F;
            outputInstance.setLightCoords(remap.vert0, LightCoordsUtil.smoothBlend(light3, light0, lightCorner03, lightCenter));
            outputInstance.setLightCoords(remap.vert1, LightCoordsUtil.smoothBlend(light2, light0, lightCorner02, lightCenter));
            outputInstance.setLightCoords(remap.vert2, LightCoordsUtil.smoothBlend(light2, light1, lightCorner12, lightCenter));
            outputInstance.setLightCoords(remap.vert3, LightCoordsUtil.smoothBlend(light3, light1, lightCorner13, lightCenter));
            outputInstance.setColor(remap.vert0, ARGB.gray(lightLevel1));
            outputInstance.setColor(remap.vert1, ARGB.gray(lightLevel2));
            outputInstance.setColor(remap.vert2, ARGB.gray(lightLevel3));
            outputInstance.setColor(remap.vert3, ARGB.gray(lightLevel4));
        }
 
        CardinalLighting cardinalLighting = level.cardinalLighting();
        outputInstance.scaleColor(quad.materialInfo().shade() ? cardinalLighting.byFace(direction) : cardinalLighting.up());
    }
 
    public void prepareQuadFlat(BlockAndTintGetter level, BlockState state, BlockPos pos, int lightCoords, BakedQuad quad, QuadInstance outputInstance) {
        if (lightCoords == -1) {
            this.prepareQuadShape(level, state, pos, quad, false);
            BlockPos lightPos = (BlockPos)(this.faceCubic ? this.scratchPos.setWithOffset(pos, quad.direction()) : pos);
            outputInstance.setLightCoords(this.cache.getLightCoords(state, level, lightPos));
        } else {
            outputInstance.setLightCoords(lightCoords);
        }
 
        CardinalLighting cardinalLighting = level.cardinalLighting();
        float directionalBrightness = quad.materialInfo().shade() ? cardinalLighting.byFace(quad.direction()) : cardinalLighting.up();
        outputInstance.setColor(ARGB.gray(directionalBrightness));
    }
 
    private void prepareQuadShape(BlockAndTintGetter level, BlockState state, BlockPos pos, BakedQuad quad, boolean ambientOcclusion) {
        float minX = 32.0F;
        float minY = 32.0F;
        float minZ = 32.0F;
        float maxX = -32.0F;
        float maxY = -32.0F;
        float maxZ = -32.0F;
 
        for (int i = 0; i < 4; i++) {
            Vector3fc position = quad.position(i);
            float x = position.x();
            float y = position.y();
            float z = position.z();
            minX = Math.min(minX, x);
            minY = Math.min(minY, y);
            minZ = Math.min(minZ, z);
            maxX = Math.max(maxX, x);
            maxY = Math.max(maxY, y);
            maxZ = Math.max(maxZ, z);
        }
 
        if (ambientOcclusion) {
            this.faceShape[BlockModelLighter.SizeInfo.WEST.index] = minX;
            this.faceShape[BlockModelLighter.SizeInfo.EAST.index] = maxX;
            this.faceShape[BlockModelLighter.SizeInfo.DOWN.index] = minY;
            this.faceShape[BlockModelLighter.SizeInfo.UP.index] = maxY;
            this.faceShape[BlockModelLighter.SizeInfo.NORTH.index] = minZ;
            this.faceShape[BlockModelLighter.SizeInfo.SOUTH.index] = maxZ;
            this.faceShape[BlockModelLighter.SizeInfo.FLIP_WEST.index] = 1.0F - minX;
            this.faceShape[BlockModelLighter.SizeInfo.FLIP_EAST.index] = 1.0F - maxX;
            this.faceShape[BlockModelLighter.SizeInfo.FLIP_DOWN.index] = 1.0F - minY;
            this.faceShape[BlockModelLighter.SizeInfo.FLIP_UP.index] = 1.0F - maxY;
            this.faceShape[BlockModelLighter.SizeInfo.FLIP_NORTH.index] = 1.0F - minZ;
            this.faceShape[BlockModelLighter.SizeInfo.FLIP_SOUTH.index] = 1.0F - maxZ;
        }
 
        float minEpsilon = 1.0E-4F;
        float maxEpsilon = 0.9999F;
 
        this.facePartial = switch (quad.direction()) {
            case DOWN, UP -> minX >= 1.0E-4F || minZ >= 1.0E-4F || maxX <= 0.9999F || maxZ <= 0.9999F;
            case NORTH, SOUTH -> minX >= 1.0E-4F || minY >= 1.0E-4F || maxX <= 0.9999F || maxY <= 0.9999F;
            case WEST, EAST -> minY >= 1.0E-4F || minZ >= 1.0E-4F || maxY <= 0.9999F || maxZ <= 0.9999F;
        };
 
        this.faceCubic = switch (quad.direction()) {
            case DOWN -> minY == maxY && (minY < 1.0E-4F || state.isCollisionShapeFullBlock(level, pos));
            case UP -> minY == maxY && (maxY > 0.9999F || state.isCollisionShapeFullBlock(level, pos));
            case NORTH -> minZ == maxZ && (minZ < 1.0E-4F || state.isCollisionShapeFullBlock(level, pos));
            case SOUTH -> minZ == maxZ && (maxZ > 0.9999F || state.isCollisionShapeFullBlock(level, pos));
            case WEST -> minX == maxX && (minX < 1.0E-4F || state.isCollisionShapeFullBlock(level, pos));
            case EAST -> minX == maxX && (maxX > 0.9999F || state.isCollisionShapeFullBlock(level, pos));
        };
    }
 
    public static void enableCaching() {
        CACHE.get().enable();
    }
 
    public static void clearCache() {
        CACHE.get().disable();
    }
 
    @OnlyIn(Dist.CLIENT)
    private static enum AdjacencyInfo {
        DOWN(
            new Direction[]{Direction.WEST, Direction.EAST, Direction.NORTH, Direction.SOUTH},
            0.5F,
            true,
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.FLIP_WEST,
                BlockModelLighter.SizeInfo.SOUTH,
                BlockModelLighter.SizeInfo.FLIP_WEST,
                BlockModelLighter.SizeInfo.FLIP_SOUTH,
                BlockModelLighter.SizeInfo.WEST,
                BlockModelLighter.SizeInfo.FLIP_SOUTH,
                BlockModelLighter.SizeInfo.WEST,
                BlockModelLighter.SizeInfo.SOUTH
            },
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.FLIP_WEST,
                BlockModelLighter.SizeInfo.NORTH,
                BlockModelLighter.SizeInfo.FLIP_WEST,
                BlockModelLighter.SizeInfo.FLIP_NORTH,
                BlockModelLighter.SizeInfo.WEST,
                BlockModelLighter.SizeInfo.FLIP_NORTH,
                BlockModelLighter.SizeInfo.WEST,
                BlockModelLighter.SizeInfo.NORTH
            },
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.FLIP_EAST,
                BlockModelLighter.SizeInfo.NORTH,
                BlockModelLighter.SizeInfo.FLIP_EAST,
                BlockModelLighter.SizeInfo.FLIP_NORTH,
                BlockModelLighter.SizeInfo.EAST,
                BlockModelLighter.SizeInfo.FLIP_NORTH,
                BlockModelLighter.SizeInfo.EAST,
                BlockModelLighter.SizeInfo.NORTH
            },
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.FLIP_EAST,
                BlockModelLighter.SizeInfo.SOUTH,
                BlockModelLighter.SizeInfo.FLIP_EAST,
                BlockModelLighter.SizeInfo.FLIP_SOUTH,
                BlockModelLighter.SizeInfo.EAST,
                BlockModelLighter.SizeInfo.FLIP_SOUTH,
                BlockModelLighter.SizeInfo.EAST,
                BlockModelLighter.SizeInfo.SOUTH
            }
        ),
        UP(
            new Direction[]{Direction.EAST, Direction.WEST, Direction.NORTH, Direction.SOUTH},
            1.0F,
            true,
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.EAST,
                BlockModelLighter.SizeInfo.SOUTH,
                BlockModelLighter.SizeInfo.EAST,
                BlockModelLighter.SizeInfo.FLIP_SOUTH,
                BlockModelLighter.SizeInfo.FLIP_EAST,
                BlockModelLighter.SizeInfo.FLIP_SOUTH,
                BlockModelLighter.SizeInfo.FLIP_EAST,
                BlockModelLighter.SizeInfo.SOUTH
            },
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.EAST,
                BlockModelLighter.SizeInfo.NORTH,
                BlockModelLighter.SizeInfo.EAST,
                BlockModelLighter.SizeInfo.FLIP_NORTH,
                BlockModelLighter.SizeInfo.FLIP_EAST,
                BlockModelLighter.SizeInfo.FLIP_NORTH,
                BlockModelLighter.SizeInfo.FLIP_EAST,
                BlockModelLighter.SizeInfo.NORTH
            },
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.WEST,
                BlockModelLighter.SizeInfo.NORTH,
                BlockModelLighter.SizeInfo.WEST,
                BlockModelLighter.SizeInfo.FLIP_NORTH,
                BlockModelLighter.SizeInfo.FLIP_WEST,
                BlockModelLighter.SizeInfo.FLIP_NORTH,
                BlockModelLighter.SizeInfo.FLIP_WEST,
                BlockModelLighter.SizeInfo.NORTH
            },
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.WEST,
                BlockModelLighter.SizeInfo.SOUTH,
                BlockModelLighter.SizeInfo.WEST,
                BlockModelLighter.SizeInfo.FLIP_SOUTH,
                BlockModelLighter.SizeInfo.FLIP_WEST,
                BlockModelLighter.SizeInfo.FLIP_SOUTH,
                BlockModelLighter.SizeInfo.FLIP_WEST,
                BlockModelLighter.SizeInfo.SOUTH
            }
        ),
        NORTH(
            new Direction[]{Direction.UP, Direction.DOWN, Direction.EAST, Direction.WEST},
            0.8F,
            true,
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.UP,
                BlockModelLighter.SizeInfo.FLIP_WEST,
                BlockModelLighter.SizeInfo.UP,
                BlockModelLighter.SizeInfo.WEST,
                BlockModelLighter.SizeInfo.FLIP_UP,
                BlockModelLighter.SizeInfo.WEST,
                BlockModelLighter.SizeInfo.FLIP_UP,
                BlockModelLighter.SizeInfo.FLIP_WEST
            },
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.UP,
                BlockModelLighter.SizeInfo.FLIP_EAST,
                BlockModelLighter.SizeInfo.UP,
                BlockModelLighter.SizeInfo.EAST,
                BlockModelLighter.SizeInfo.FLIP_UP,
                BlockModelLighter.SizeInfo.EAST,
                BlockModelLighter.SizeInfo.FLIP_UP,
                BlockModelLighter.SizeInfo.FLIP_EAST
            },
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.DOWN,
                BlockModelLighter.SizeInfo.FLIP_EAST,
                BlockModelLighter.SizeInfo.DOWN,
                BlockModelLighter.SizeInfo.EAST,
                BlockModelLighter.SizeInfo.FLIP_DOWN,
                BlockModelLighter.SizeInfo.EAST,
                BlockModelLighter.SizeInfo.FLIP_DOWN,
                BlockModelLighter.SizeInfo.FLIP_EAST
            },
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.DOWN,
                BlockModelLighter.SizeInfo.FLIP_WEST,
                BlockModelLighter.SizeInfo.DOWN,
                BlockModelLighter.SizeInfo.WEST,
                BlockModelLighter.SizeInfo.FLIP_DOWN,
                BlockModelLighter.SizeInfo.WEST,
                BlockModelLighter.SizeInfo.FLIP_DOWN,
                BlockModelLighter.SizeInfo.FLIP_WEST
            }
        ),
        SOUTH(
            new Direction[]{Direction.WEST, Direction.EAST, Direction.DOWN, Direction.UP},
            0.8F,
            true,
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.UP,
                BlockModelLighter.SizeInfo.FLIP_WEST,
                BlockModelLighter.SizeInfo.FLIP_UP,
                BlockModelLighter.SizeInfo.FLIP_WEST,
                BlockModelLighter.SizeInfo.FLIP_UP,
                BlockModelLighter.SizeInfo.WEST,
                BlockModelLighter.SizeInfo.UP,
                BlockModelLighter.SizeInfo.WEST
            },
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.DOWN,
                BlockModelLighter.SizeInfo.FLIP_WEST,
                BlockModelLighter.SizeInfo.FLIP_DOWN,
                BlockModelLighter.SizeInfo.FLIP_WEST,
                BlockModelLighter.SizeInfo.FLIP_DOWN,
                BlockModelLighter.SizeInfo.WEST,
                BlockModelLighter.SizeInfo.DOWN,
                BlockModelLighter.SizeInfo.WEST
            },
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.DOWN,
                BlockModelLighter.SizeInfo.FLIP_EAST,
                BlockModelLighter.SizeInfo.FLIP_DOWN,
                BlockModelLighter.SizeInfo.FLIP_EAST,
                BlockModelLighter.SizeInfo.FLIP_DOWN,
                BlockModelLighter.SizeInfo.EAST,
                BlockModelLighter.SizeInfo.DOWN,
                BlockModelLighter.SizeInfo.EAST
            },
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.UP,
                BlockModelLighter.SizeInfo.FLIP_EAST,
                BlockModelLighter.SizeInfo.FLIP_UP,
                BlockModelLighter.SizeInfo.FLIP_EAST,
                BlockModelLighter.SizeInfo.FLIP_UP,
                BlockModelLighter.SizeInfo.EAST,
                BlockModelLighter.SizeInfo.UP,
                BlockModelLighter.SizeInfo.EAST
            }
        ),
        WEST(
            new Direction[]{Direction.UP, Direction.DOWN, Direction.NORTH, Direction.SOUTH},
            0.6F,
            true,
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.UP,
                BlockModelLighter.SizeInfo.SOUTH,
                BlockModelLighter.SizeInfo.UP,
                BlockModelLighter.SizeInfo.FLIP_SOUTH,
                BlockModelLighter.SizeInfo.FLIP_UP,
                BlockModelLighter.SizeInfo.FLIP_SOUTH,
                BlockModelLighter.SizeInfo.FLIP_UP,
                BlockModelLighter.SizeInfo.SOUTH
            },
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.UP,
                BlockModelLighter.SizeInfo.NORTH,
                BlockModelLighter.SizeInfo.UP,
                BlockModelLighter.SizeInfo.FLIP_NORTH,
                BlockModelLighter.SizeInfo.FLIP_UP,
                BlockModelLighter.SizeInfo.FLIP_NORTH,
                BlockModelLighter.SizeInfo.FLIP_UP,
                BlockModelLighter.SizeInfo.NORTH
            },
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.DOWN,
                BlockModelLighter.SizeInfo.NORTH,
                BlockModelLighter.SizeInfo.DOWN,
                BlockModelLighter.SizeInfo.FLIP_NORTH,
                BlockModelLighter.SizeInfo.FLIP_DOWN,
                BlockModelLighter.SizeInfo.FLIP_NORTH,
                BlockModelLighter.SizeInfo.FLIP_DOWN,
                BlockModelLighter.SizeInfo.NORTH
            },
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.DOWN,
                BlockModelLighter.SizeInfo.SOUTH,
                BlockModelLighter.SizeInfo.DOWN,
                BlockModelLighter.SizeInfo.FLIP_SOUTH,
                BlockModelLighter.SizeInfo.FLIP_DOWN,
                BlockModelLighter.SizeInfo.FLIP_SOUTH,
                BlockModelLighter.SizeInfo.FLIP_DOWN,
                BlockModelLighter.SizeInfo.SOUTH
            }
        ),
        EAST(
            new Direction[]{Direction.DOWN, Direction.UP, Direction.NORTH, Direction.SOUTH},
            0.6F,
            true,
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.FLIP_DOWN,
                BlockModelLighter.SizeInfo.SOUTH,
                BlockModelLighter.SizeInfo.FLIP_DOWN,
                BlockModelLighter.SizeInfo.FLIP_SOUTH,
                BlockModelLighter.SizeInfo.DOWN,
                BlockModelLighter.SizeInfo.FLIP_SOUTH,
                BlockModelLighter.SizeInfo.DOWN,
                BlockModelLighter.SizeInfo.SOUTH
            },
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.FLIP_DOWN,
                BlockModelLighter.SizeInfo.NORTH,
                BlockModelLighter.SizeInfo.FLIP_DOWN,
                BlockModelLighter.SizeInfo.FLIP_NORTH,
                BlockModelLighter.SizeInfo.DOWN,
                BlockModelLighter.SizeInfo.FLIP_NORTH,
                BlockModelLighter.SizeInfo.DOWN,
                BlockModelLighter.SizeInfo.NORTH
            },
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.FLIP_UP,
                BlockModelLighter.SizeInfo.NORTH,
                BlockModelLighter.SizeInfo.FLIP_UP,
                BlockModelLighter.SizeInfo.FLIP_NORTH,
                BlockModelLighter.SizeInfo.UP,
                BlockModelLighter.SizeInfo.FLIP_NORTH,
                BlockModelLighter.SizeInfo.UP,
                BlockModelLighter.SizeInfo.NORTH
            },
            new BlockModelLighter.SizeInfo[]{
                BlockModelLighter.SizeInfo.FLIP_UP,
                BlockModelLighter.SizeInfo.SOUTH,
                BlockModelLighter.SizeInfo.FLIP_UP,
                BlockModelLighter.SizeInfo.FLIP_SOUTH,
                BlockModelLighter.SizeInfo.UP,
                BlockModelLighter.SizeInfo.FLIP_SOUTH,
                BlockModelLighter.SizeInfo.UP,
                BlockModelLighter.SizeInfo.SOUTH
            }
        );
 
        private final Direction[] corners;
        private final boolean doNonCubicWeight;
        private final BlockModelLighter.SizeInfo[] vert0Weights;
        private final BlockModelLighter.SizeInfo[] vert1Weights;
        private final BlockModelLighter.SizeInfo[] vert2Weights;
        private final BlockModelLighter.SizeInfo[] vert3Weights;
        private static final BlockModelLighter.AdjacencyInfo[] BY_FACING = Util.make(new BlockModelLighter.AdjacencyInfo[6], map -> {
            map[Direction.DOWN.get3DDataValue()] = DOWN;
            map[Direction.UP.get3DDataValue()] = UP;
            map[Direction.NORTH.get3DDataValue()] = NORTH;
            map[Direction.SOUTH.get3DDataValue()] = SOUTH;
            map[Direction.WEST.get3DDataValue()] = WEST;
            map[Direction.EAST.get3DDataValue()] = EAST;
        });
 
        private AdjacencyInfo(
            Direction[] corners,
            float shadeWeight,
            boolean doNonCubicWeight,
            BlockModelLighter.SizeInfo[] vert0Weights,
            BlockModelLighter.SizeInfo[] vert1Weights,
            BlockModelLighter.SizeInfo[] vert2Weights,
            BlockModelLighter.SizeInfo[] vert3Weights
        ) {
            this.corners = corners;
            this.doNonCubicWeight = doNonCubicWeight;
            this.vert0Weights = vert0Weights;
            this.vert1Weights = vert1Weights;
            this.vert2Weights = vert2Weights;
            this.vert3Weights = vert3Weights;
        }
 
        public static BlockModelLighter.AdjacencyInfo fromFacing(Direction direction) {
            return BY_FACING[direction.get3DDataValue()];
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    private static enum AmbientVertexRemap {
        DOWN(0, 1, 2, 3),
        UP(2, 3, 0, 1),
        NORTH(3, 0, 1, 2),
        SOUTH(0, 1, 2, 3),
        WEST(3, 0, 1, 2),
        EAST(1, 2, 3, 0);
 
        private final int vert0;
        private final int vert1;
        private final int vert2;
        private final int vert3;
        private static final BlockModelLighter.AmbientVertexRemap[] BY_FACING = Util.make(new BlockModelLighter.AmbientVertexRemap[6], map -> {
            map[Direction.DOWN.get3DDataValue()] = DOWN;
            map[Direction.UP.get3DDataValue()] = UP;
            map[Direction.NORTH.get3DDataValue()] = NORTH;
            map[Direction.SOUTH.get3DDataValue()] = SOUTH;
            map[Direction.WEST.get3DDataValue()] = WEST;
            map[Direction.EAST.get3DDataValue()] = EAST;
        });
 
        private AmbientVertexRemap(int vert0, int vert1, int vert2, int vert3) {
            this.vert0 = vert0;
            this.vert1 = vert1;
            this.vert2 = vert2;
            this.vert3 = vert3;
        }
 
        public static BlockModelLighter.AmbientVertexRemap fromFacing(Direction direction) {
            return BY_FACING[direction.get3DDataValue()];
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    public static class Cache {
        private boolean enabled;
        private final Long2IntLinkedOpenHashMap colorCache = Util.make(() -> {
            Long2IntLinkedOpenHashMap map = new Long2IntLinkedOpenHashMap(100, 0.25F) {
                {
                    Objects.requireNonNull(Cache.this);
                }
 
                @Override
                protected void rehash(int newN) {
                }
            };
            map.defaultReturnValue(Integer.MAX_VALUE);
            return map;
        });
        private final Long2FloatLinkedOpenHashMap brightnessCache = Util.make(() -> {
            Long2FloatLinkedOpenHashMap map = new Long2FloatLinkedOpenHashMap(100, 0.25F) {
                {
                    Objects.requireNonNull(Cache.this);
                }
 
                @Override
                protected void rehash(int newN) {
                }
            };
            map.defaultReturnValue(Float.NaN);
            return map;
        });
        private final LevelRenderer.BrightnessGetter cachedBrightnessGetter = (level, pos) -> {
            long key = pos.asLong();
            int cached = this.colorCache.get(key);
            if (cached != Integer.MAX_VALUE) {
                return cached;
            } else {
                int value = LevelRenderer.BrightnessGetter.DEFAULT.packedBrightness(level, pos);
                if (this.colorCache.size() == 100) {
                    this.colorCache.removeFirstInt();
                }
 
                this.colorCache.put(key, value);
                return value;
            }
        };
 
        public void enable() {
            this.enabled = true;
        }
 
        public void disable() {
            this.enabled = false;
            this.colorCache.clear();
            this.brightnessCache.clear();
        }
 
        public int getLightCoords(BlockState state, BlockAndTintGetter level, BlockPos pos) {
            return LevelRenderer.getLightCoords(this.enabled ? this.cachedBrightnessGetter : LevelRenderer.BrightnessGetter.DEFAULT, level, state, pos);
        }
 
        public float getShadeBrightness(BlockState state, BlockAndTintGetter level, BlockPos pos) {
            long key = pos.asLong();
            if (this.enabled) {
                float cached = this.brightnessCache.get(key);
                if (!Float.isNaN(cached)) {
                    return cached;
                }
            }
 
            float brightness = state.getShadeBrightness(level, pos);
            if (this.enabled) {
                if (this.brightnessCache.size() == 100) {
                    this.brightnessCache.removeFirstFloat();
                }
 
                this.brightnessCache.put(key, brightness);
            }
 
            return brightness;
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    private static enum SizeInfo {
        DOWN(0),
        UP(1),
        NORTH(2),
        SOUTH(3),
        WEST(4),
        EAST(5),
        FLIP_DOWN(6),
        FLIP_UP(7),
        FLIP_NORTH(8),
        FLIP_SOUTH(9),
        FLIP_WEST(10),
        FLIP_EAST(11);
 
        public static final int COUNT = values().length;
        private final int index;
 
        private SizeInfo(int index) {
            this.index = index;
        }
    }
}

引用的其他类

  • QuadInstance

    • 引用位置: 参数
  • LevelRenderer

    • 引用位置: 方法调用
    • 关联成员: LevelRenderer.getLightCoords()
  • BlockAndTintGetter

    • 引用位置: 参数
  • BakedQuad

    • 引用位置: 参数
  • BlockPos

    • 引用位置: 参数/字段/方法调用/构造调用
    • 关联成员: BlockPos.MutableBlockPos(), MutableBlockPos()
  • ARGB

    • 引用位置: 方法调用
    • 关联成员: ARGB.gray()
  • LightCoordsUtil

    • 引用位置: 方法调用
    • 关联成员: LightCoordsUtil.smoothBlend(), LightCoordsUtil.smoothWeightedBlend()
  • Util

    • 引用位置: 方法调用
    • 关联成员: Util.make()
  • BlockState

    • 引用位置: 参数