EnderDragonRenderer.java

net.minecraft.client.renderer.entity.EnderDragonRenderer

信息

  • 全限定名:net.minecraft.client.renderer.entity.EnderDragonRenderer
  • 类型:public class
  • 包:net.minecraft.client.renderer.entity
  • 源码路径:src/main/java/net/minecraft/client/renderer/entity/EnderDragonRenderer.java
  • 起始行号:L31
  • 继承:EntityRenderer<EnderDragon,EnderDragonRenderState>
  • 职责:

    TODO

字段/常量

  • CRYSTAL_BEAM_LOCATION

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

      TODO

  • DRAGON_EXPLODING_LOCATION

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

      TODO

  • DRAGON_TEXTURE_LOCATION

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

      TODO

  • DRAGON_EYES_LOCATION

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

      TODO

  • DYING_RENDER_TYPE

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

      TODO

  • EYES

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

      TODO

  • BEAM

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

      TODO

  • HALF_SQRT_3

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

      TODO

  • model

    • 类型: EnderDragonModel
    • 修饰符: private final
    • 源码定位: L40
    • 说明:

      TODO

内部类/嵌套类型

构造器

public EnderDragonRenderer(EntityRendererProvider.Context context) @ L42

  • 构造器名:EnderDragonRenderer
  • 源码定位:L42
  • 修饰符:public

参数:

  • context: EntityRendererProvider.Context

说明:

TODO

方法

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

public void submit(EnderDragonRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) @ L48

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

参数:

  • state: EnderDragonRenderState
  • poseStack: PoseStack
  • submitNodeCollector: SubmitNodeCollector
  • camera: CameraRenderState

说明:

TODO

private static void submitRays(PoseStack poseStack, float deathTime, SubmitNodeCollector submitNodeCollector, RenderType renderType) @ L93

  • 方法名:submitRays
  • 源码定位:L93
  • 返回类型:void
  • 修饰符:private static

参数:

  • poseStack: PoseStack
  • deathTime: float
  • submitNodeCollector: SubmitNodeCollector
  • renderType: RenderType

说明:

TODO

public static void submitCrystalBeams(float deltaX, float deltaY, float deltaZ, float timeInTicks, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, int lightCoords) @ L138

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

参数:

  • deltaX: float
  • deltaY: float
  • deltaZ: float
  • timeInTicks: float
  • poseStack: PoseStack
  • submitNodeCollector: SubmitNodeCollector
  • lightCoords: int

说明:

TODO

public EnderDragonRenderState createRenderState() @ L195

  • 方法名:createRenderState
  • 源码定位:L195
  • 返回类型:EnderDragonRenderState
  • 修饰符:public

参数:

说明:

TODO

public void extractRenderState(EnderDragon entity, EnderDragonRenderState state, float partialTicks) @ L199

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

参数:

  • entity: EnderDragon
  • state: EnderDragonRenderState
  • partialTicks: float

说明:

TODO

protected boolean affectedByCulling(EnderDragon entity) @ L221

  • 方法名:affectedByCulling
  • 源码定位:L221
  • 返回类型:boolean
  • 修饰符:protected

参数:

  • entity: EnderDragon

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class EnderDragonRenderer extends EntityRenderer<EnderDragon, EnderDragonRenderState> {
    public static final Identifier CRYSTAL_BEAM_LOCATION = Identifier.withDefaultNamespace("textures/entity/end_crystal/end_crystal_beam.png");
    private static final Identifier DRAGON_EXPLODING_LOCATION = Identifier.withDefaultNamespace("textures/entity/enderdragon/dragon_exploding.png");
    private static final Identifier DRAGON_TEXTURE_LOCATION = Identifier.withDefaultNamespace("textures/entity/enderdragon/dragon.png");
    private static final Identifier DRAGON_EYES_LOCATION = Identifier.withDefaultNamespace("textures/entity/enderdragon/dragon_eyes.png");
    private static final RenderType DYING_RENDER_TYPE = RenderTypes.entityCutoutDissolve(DRAGON_TEXTURE_LOCATION, DRAGON_EXPLODING_LOCATION);
    private static final RenderType EYES = RenderTypes.eyes(DRAGON_EYES_LOCATION);
    private static final RenderType BEAM = RenderTypes.endCrystalBeam(CRYSTAL_BEAM_LOCATION);
    private static final float HALF_SQRT_3 = (float)(Math.sqrt(3.0) / 2.0);
    private final EnderDragonModel model;
 
    public EnderDragonRenderer(EntityRendererProvider.Context context) {
        super(context);
        this.shadowRadius = 0.5F;
        this.model = new EnderDragonModel(context.bakeLayer(ModelLayers.ENDER_DRAGON));
    }
 
    public void submit(EnderDragonRenderState state, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, CameraRenderState camera) {
        poseStack.pushPose();
        float yr = state.getHistoricalPos(7).yRot();
        float rot2 = (float)(state.getHistoricalPos(5).y() - state.getHistoricalPos(10).y());
        poseStack.mulPose(Axis.YP.rotationDegrees(-yr));
        poseStack.mulPose(Axis.XP.rotationDegrees(rot2 * 10.0F));
        poseStack.translate(0.0F, 0.0F, 1.0F);
        poseStack.scale(-1.0F, -1.0F, 1.0F);
        poseStack.translate(0.0F, -1.501F, 0.0F);
        int overlayCoords = OverlayTexture.pack(0.0F, state.hasRedOverlay);
        if (state.deathTime > 0.0F) {
            int color = ARGB.white(1.0F - state.deathTime / 200.0F);
            submitNodeCollector.submitModel(
                this.model, state, poseStack, DYING_RENDER_TYPE, state.lightCoords, OverlayTexture.NO_OVERLAY, color, null, state.outlineColor, null
            );
        } else {
            submitNodeCollector.submitModel(this.model, state, poseStack, DRAGON_TEXTURE_LOCATION, state.lightCoords, overlayCoords, state.outlineColor, null);
        }
 
        submitNodeCollector.submitModel(this.model, state, poseStack, EYES, state.lightCoords, OverlayTexture.NO_OVERLAY, state.outlineColor, null);
        if (state.deathTime > 0.0F) {
            float deathTime = state.deathTime / 200.0F;
            poseStack.pushPose();
            poseStack.translate(0.0F, -1.0F, -2.0F);
            submitRays(poseStack, deathTime, submitNodeCollector, RenderTypes.dragonRays());
            submitRays(poseStack, deathTime, submitNodeCollector, RenderTypes.dragonRaysDepth());
            poseStack.popPose();
        }
 
        poseStack.popPose();
        if (state.beamOffset != null) {
            submitCrystalBeams(
                (float)state.beamOffset.x,
                (float)state.beamOffset.y,
                (float)state.beamOffset.z,
                state.ageInTicks,
                poseStack,
                submitNodeCollector,
                state.lightCoords
            );
        }
 
        super.submit(state, poseStack, submitNodeCollector, camera);
    }
 
    private static void submitRays(PoseStack poseStack, float deathTime, SubmitNodeCollector submitNodeCollector, RenderType renderType) {
        submitNodeCollector.submitCustomGeometry(
            poseStack,
            renderType,
            (pose, buffer) -> {
                float overDrive = Math.min(deathTime > 0.8F ? (deathTime - 0.8F) / 0.2F : 0.0F, 1.0F);
                int innerColor = ARGB.colorFromFloat(1.0F - overDrive, 1.0F, 1.0F, 1.0F);
                int outerColor = 16711935;
                RandomSource random = RandomSource.createThreadLocalInstance(432L);
                Vector3f origin = new Vector3f();
                Vector3f outerLeft = new Vector3f();
                Vector3f outerRight = new Vector3f();
                Vector3f outerBottom = new Vector3f();
                Quaternionf rayRotation = new Quaternionf();
                int rayCount = Mth.floor((deathTime + deathTime * deathTime) / 2.0F * 60.0F);
 
                for (int i = 0; i < rayCount; i++) {
                    rayRotation.rotationXYZ(
                            random.nextFloat() * (float) (Math.PI * 2), random.nextFloat() * (float) (Math.PI * 2), random.nextFloat() * (float) (Math.PI * 2)
                        )
                        .rotateXYZ(
                            random.nextFloat() * (float) (Math.PI * 2),
                            random.nextFloat() * (float) (Math.PI * 2),
                            random.nextFloat() * (float) (Math.PI * 2) + deathTime * (float) (Math.PI / 2)
                        );
                    pose.rotate(rayRotation);
                    float length = random.nextFloat() * 20.0F + 5.0F + overDrive * 10.0F;
                    float width = random.nextFloat() * 2.0F + 1.0F + overDrive * 2.0F;
                    outerLeft.set(-HALF_SQRT_3 * width, length, -0.5F * width);
                    outerRight.set(HALF_SQRT_3 * width, length, -0.5F * width);
                    outerBottom.set(0.0F, length, width);
                    buffer.addVertex(pose, origin).setColor(innerColor);
                    buffer.addVertex(pose, outerLeft).setColor(16711935);
                    buffer.addVertex(pose, outerRight).setColor(16711935);
                    buffer.addVertex(pose, origin).setColor(innerColor);
                    buffer.addVertex(pose, outerRight).setColor(16711935);
                    buffer.addVertex(pose, outerBottom).setColor(16711935);
                    buffer.addVertex(pose, origin).setColor(innerColor);
                    buffer.addVertex(pose, outerBottom).setColor(16711935);
                    buffer.addVertex(pose, outerLeft).setColor(16711935);
                }
            }
        );
    }
 
    public static void submitCrystalBeams(
        float deltaX, float deltaY, float deltaZ, float timeInTicks, PoseStack poseStack, SubmitNodeCollector submitNodeCollector, int lightCoords
    ) {
        float horizontalLength = Mth.sqrt(deltaX * deltaX + deltaZ * deltaZ);
        float length = Mth.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);
        poseStack.pushPose();
        poseStack.translate(0.0F, 2.0F, 0.0F);
        poseStack.mulPose(Axis.YP.rotation((float)(-Math.atan2(deltaZ, deltaX)) - (float) (Math.PI / 2)));
        poseStack.mulPose(Axis.XP.rotation((float)(-Math.atan2(horizontalLength, deltaY)) - (float) (Math.PI / 2)));
        float v0 = 0.0F - timeInTicks * 0.01F;
        float v1 = length / 32.0F - timeInTicks * 0.01F;
        submitNodeCollector.submitCustomGeometry(
            poseStack,
            BEAM,
            (pose, buffer) -> {
                int steps = 8;
                float lastSin = 0.0F;
                float lastCos = 0.75F;
                float lastU = 0.0F;
 
                for (int i = 1; i <= 8; i++) {
                    float sin = Mth.sin(i * (float) (Math.PI * 2) / 8.0F) * 0.75F;
                    float cos = Mth.cos(i * (float) (Math.PI * 2) / 8.0F) * 0.75F;
                    float u = i / 8.0F;
                    buffer.addVertex(pose, lastSin * 0.2F, lastCos * 0.2F, 0.0F)
                        .setColor(-16777216)
                        .setUv(lastU, v0)
                        .setOverlay(OverlayTexture.NO_OVERLAY)
                        .setLight(lightCoords)
                        .setNormal(pose, 0.0F, -1.0F, 0.0F);
                    buffer.addVertex(pose, lastSin, lastCos, length)
                        .setColor(-1)
                        .setUv(lastU, v1)
                        .setOverlay(OverlayTexture.NO_OVERLAY)
                        .setLight(lightCoords)
                        .setNormal(pose, 0.0F, -1.0F, 0.0F);
                    buffer.addVertex(pose, sin, cos, length)
                        .setColor(-1)
                        .setUv(u, v1)
                        .setOverlay(OverlayTexture.NO_OVERLAY)
                        .setLight(lightCoords)
                        .setNormal(pose, 0.0F, -1.0F, 0.0F);
                    buffer.addVertex(pose, sin * 0.2F, cos * 0.2F, 0.0F)
                        .setColor(-16777216)
                        .setUv(u, v0)
                        .setOverlay(OverlayTexture.NO_OVERLAY)
                        .setLight(lightCoords)
                        .setNormal(pose, 0.0F, -1.0F, 0.0F);
                    lastSin = sin;
                    lastCos = cos;
                    lastU = u;
                }
            }
        );
        poseStack.popPose();
    }
 
    public EnderDragonRenderState createRenderState() {
        return new EnderDragonRenderState();
    }
 
    public void extractRenderState(EnderDragon entity, EnderDragonRenderState state, float partialTicks) {
        super.extractRenderState(entity, state, partialTicks);
        state.flapTime = Mth.lerp(partialTicks, entity.oFlapTime, entity.flapTime);
        state.deathTime = entity.dragonDeathTime > 0 ? entity.dragonDeathTime + partialTicks : 0.0F;
        state.hasRedOverlay = entity.hurtTime > 0;
        EndCrystal nearestCrystal = entity.nearestCrystal;
        if (nearestCrystal != null) {
            Vec3 crystalPosition = nearestCrystal.getPosition(partialTicks).add(0.0, EndCrystalRenderer.getY(nearestCrystal.time + partialTicks), 0.0);
            state.beamOffset = crystalPosition.subtract(entity.getPosition(partialTicks));
        } else {
            state.beamOffset = null;
        }
 
        DragonPhaseInstance phase = entity.getPhaseManager().getCurrentPhase();
        state.isLandingOrTakingOff = phase == EnderDragonPhase.LANDING || phase == EnderDragonPhase.TAKEOFF;
        state.isSitting = phase.isSitting();
        BlockPos egg = entity.level().getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, EndPodiumFeature.getLocation(entity.getFightOrigin()));
        state.distanceToEgg = egg.distToCenterSqr(entity.position());
        state.partialTicks = entity.isDeadOrDying() ? 0.0F : partialTicks;
        state.flightHistory.copyFrom(entity.flightHistory);
    }
 
    protected boolean affectedByCulling(EnderDragon entity) {
        return false;
    }
}

引用的其他类

  • PoseStack

    • 引用位置: 参数
  • EnderDragonModel

    • 引用位置: 字段/构造调用
    • 关联成员: EnderDragonModel()
  • SubmitNodeCollector

    • 引用位置: 参数
  • EndCrystalRenderer

    • 引用位置: 方法调用
    • 关联成员: EndCrystalRenderer.getY()
  • EntityRenderer

    • 引用位置: 继承
  • EntityRendererProvider

    • 引用位置: 参数
  • EnderDragonRenderState

    • 引用位置: 参数/构造调用/返回值
    • 关联成员: EnderDragonRenderState()
  • RenderType

    • 引用位置: 参数/字段
  • RenderTypes

    • 引用位置: 方法调用
    • 关联成员: RenderTypes.dragonRays(), RenderTypes.dragonRaysDepth(), RenderTypes.endCrystalBeam(), RenderTypes.entityCutoutDissolve(), RenderTypes.eyes()
  • CameraRenderState

    • 引用位置: 参数
  • OverlayTexture

    • 引用位置: 方法调用
    • 关联成员: OverlayTexture.pack()
  • Identifier

    • 引用位置: 字段/方法调用
    • 关联成员: Identifier.withDefaultNamespace()
  • ARGB

    • 引用位置: 方法调用
    • 关联成员: ARGB.colorFromFloat(), ARGB.white()
  • Mth

    • 引用位置: 方法调用
    • 关联成员: Mth.cos(), Mth.floor(), Mth.lerp(), Mth.sin(), Mth.sqrt()
  • RandomSource

    • 引用位置: 方法调用
    • 关联成员: RandomSource.createThreadLocalInstance()
  • EnderDragon

    • 引用位置: 参数
  • EndPodiumFeature

    • 引用位置: 方法调用
    • 关联成员: EndPodiumFeature.getLocation()