HumanoidModel.java

net.minecraft.client.model.HumanoidModel

信息

  • 全限定名:net.minecraft.client.model.HumanoidModel
  • 类型:public class
  • 包:net.minecraft.client.model
  • 源码路径:src/main/java/net/minecraft/client/model/HumanoidModel.java
  • 起始行号:L32
  • 继承:EntityModel
  • 实现:ArmedModel, HeadedModel
  • 职责:

    TODO

字段/常量

  • BABY_TRANSFORMER

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

      TODO

  • OVERLAY_SCALE

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

      TODO

  • HAT_OVERLAY_SCALE

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

      TODO

  • LEGGINGS_OVERLAY_SCALE

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

      TODO

  • DUCK_WALK_ROTATION

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

      TODO

  • SPYGLASS_ARM_ROT_Y

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

      TODO

  • SPYGLASS_ARM_ROT_X

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

      TODO

  • SPYGLASS_ARM_CROUCH_ROT_X

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

      TODO

  • HIGHEST_SHIELD_BLOCKING_ANGLE

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

      TODO

  • LOWEST_SHIELD_BLOCKING_ANGLE

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

      TODO

  • HORIZONTAL_SHIELD_MOVEMENT_LIMIT

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

      TODO

  • TOOT_HORN_XROT_BASE

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

      TODO

  • TOOT_HORN_YROT_BASE

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

      TODO

  • ADULT_ARMOR_PARTS_PER_SLOT

    • 类型: Map<EquipmentSlot,Set<String>>
    • 修饰符: protected static final
    • 源码定位: L46
    • 说明:

      TODO

  • BABY_ARMOR_PARTS_PER_SLOT

    • 类型: Map<EquipmentSlot,Set<String>>
    • 修饰符: protected static final
    • 源码定位: L58
    • 说明:

      TODO

  • head

    • 类型: ModelPart
    • 修饰符: public final
    • 源码定位: L70
    • 说明:

      TODO

  • hat

    • 类型: ModelPart
    • 修饰符: public final
    • 源码定位: L71
    • 说明:

      TODO

  • body

    • 类型: ModelPart
    • 修饰符: public final
    • 源码定位: L72
    • 说明:

      TODO

  • rightArm

    • 类型: ModelPart
    • 修饰符: public final
    • 源码定位: L73
    • 说明:

      TODO

  • leftArm

    • 类型: ModelPart
    • 修饰符: public final
    • 源码定位: L74
    • 说明:

      TODO

  • rightLeg

    • 类型: ModelPart
    • 修饰符: public final
    • 源码定位: L75
    • 说明:

      TODO

  • leftLeg

    • 类型: ModelPart
    • 修饰符: public final
    • 源码定位: L76
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.client.model.HumanoidModel.ArmPose
    • 类型: enum
    • 修饰符: public static
    • 源码定位: L498
    • 说明:

      TODO

构造器

public HumanoidModel(ModelPart root) @ L78

  • 构造器名:HumanoidModel
  • 源码定位:L78
  • 修饰符:public

参数:

  • root: ModelPart

说明:

TODO

public HumanoidModel(ModelPart root, Function<Identifier,RenderType> renderType) @ L82

  • 构造器名:HumanoidModel
  • 源码定位:L82
  • 修饰符:public

参数:

  • root: ModelPart
  • renderType: Function<Identifier,RenderType>

说明:

TODO

方法

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

public static MeshDefinition createMesh(CubeDeformation g, float yOffset) @ L93

  • 方法名:createMesh
  • 源码定位:L93
  • 返回类型:MeshDefinition
  • 修饰符:public static

参数:

  • g: CubeDeformation
  • yOffset: float

说明:

TODO

public static ArmorModelSet<MeshDefinition> createArmorMeshSet(CubeDeformation innerDeformation, CubeDeformation outerDeformation) @ L126

  • 方法名:createArmorMeshSet
  • 源码定位:L126
  • 返回类型:ArmorModelSet
  • 修饰符:public static

参数:

  • innerDeformation: CubeDeformation
  • outerDeformation: CubeDeformation

说明:

TODO

public static ArmorModelSet<MeshDefinition> createBabyArmorMeshSet(CubeDeformation innerDeformation, CubeDeformation outerDeformation, PartPose armOffset) @ L130

  • 方法名:createBabyArmorMeshSet
  • 源码定位:L130
  • 返回类型:ArmorModelSet
  • 修饰符:public static

参数:

  • innerDeformation: CubeDeformation
  • outerDeformation: CubeDeformation
  • armOffset: PartPose

说明:

TODO

protected static ArmorModelSet<MeshDefinition> createArmorMeshSet(Function<CubeDeformation,MeshDefinition> baseFactory, Map<EquipmentSlot,Set<String>> partsPerSlot, CubeDeformation innerDeformation, CubeDeformation outerDeformation) @ L134

  • 方法名:createArmorMeshSet
  • 源码定位:L134
  • 返回类型:ArmorModelSet
  • 修饰符:protected static

参数:

  • baseFactory: Function<CubeDeformation,MeshDefinition>
  • partsPerSlot: Map<EquipmentSlot,Set>
  • innerDeformation: CubeDeformation
  • outerDeformation: CubeDeformation

说明:

TODO

private static MeshDefinition createBaseArmorMesh(CubeDeformation g) @ L151

  • 方法名:createBaseArmorMesh
  • 源码定位:L151
  • 返回类型:MeshDefinition
  • 修饰符:private static

参数:

  • g: CubeDeformation

说明:

TODO

private static MeshDefinition createBabyArmorMesh(CubeDeformation g, PartPose armOffset) @ L167

  • 方法名:createBabyArmorMesh
  • 源码定位:L167
  • 返回类型:MeshDefinition
  • 修饰符:private static

参数:

  • g: CubeDeformation
  • armOffset: PartPose

说明:

TODO

public void setupAnim(T state) @ L216

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

参数:

  • state: T

说明:

TODO

private void poseRightArm(T state) @ L350

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

参数:

  • state: T

说明:

TODO

private void poseLeftArm(T state) @ L395

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

参数:

  • state: T

说明:

TODO

private void poseBlockingArm(ModelPart arm, boolean right) @ L440

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

参数:

  • arm: ModelPart
  • right: boolean

说明:

TODO

protected void setupAttackAnimation(T state) @ L445

  • 方法名:setupAttackAnimation
  • 源码定位:L445
  • 返回类型:void
  • 修饰符:protected

参数:

  • state: T

说明:

TODO

private float quadraticArmUpdate(float x) @ L479

  • 方法名:quadraticArmUpdate
  • 源码定位:L479
  • 返回类型:float
  • 修饰符:private

参数:

  • x: float

说明:

TODO

public void translateToHand(HumanoidRenderState state, HumanoidArm arm, PoseStack poseStack) @ L483

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

参数:

  • state: HumanoidRenderState
  • arm: HumanoidArm
  • poseStack: PoseStack

说明:

TODO

public ModelPart getArm(HumanoidArm arm) @ L488

  • 方法名:getArm
  • 源码定位:L488
  • 返回类型:ModelPart
  • 修饰符:public

参数:

  • arm: HumanoidArm

说明:

TODO

public ModelPart getHead() @ L492

  • 方法名:getHead
  • 源码定位:L492
  • 返回类型:ModelPart
  • 修饰符:public

参数:

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class HumanoidModel<T extends HumanoidRenderState> extends EntityModel<T> implements ArmedModel<T>, HeadedModel {
    public static final MeshTransformer BABY_TRANSFORMER = new BabyModelTransform(true, 16.0F, 0.0F, 2.0F, 2.0F, 24.0F, Set.of("head"));
    public static final float OVERLAY_SCALE = 0.25F;
    public static final float HAT_OVERLAY_SCALE = 0.5F;
    public static final float LEGGINGS_OVERLAY_SCALE = -0.1F;
    private static final float DUCK_WALK_ROTATION = 0.005F;
    private static final float SPYGLASS_ARM_ROT_Y = (float) (Math.PI / 12);
    private static final float SPYGLASS_ARM_ROT_X = 1.9198622F;
    private static final float SPYGLASS_ARM_CROUCH_ROT_X = (float) (Math.PI / 12);
    private static final float HIGHEST_SHIELD_BLOCKING_ANGLE = (float) (-Math.PI * 4.0 / 9.0);
    private static final float LOWEST_SHIELD_BLOCKING_ANGLE = 0.43633232F;
    private static final float HORIZONTAL_SHIELD_MOVEMENT_LIMIT = (float) (Math.PI / 6);
    public static final float TOOT_HORN_XROT_BASE = 1.4835298F;
    public static final float TOOT_HORN_YROT_BASE = (float) (Math.PI / 6);
    protected static final Map<EquipmentSlot, Set<String>> ADULT_ARMOR_PARTS_PER_SLOT = Maps.newEnumMap(
        Map.of(
            EquipmentSlot.HEAD,
            Set.of("head"),
            EquipmentSlot.CHEST,
            Set.of("body", "left_arm", "right_arm"),
            EquipmentSlot.LEGS,
            Set.of("left_leg", "right_leg", "body"),
            EquipmentSlot.FEET,
            Set.of("left_leg", "right_leg")
        )
    );
    protected static final Map<EquipmentSlot, Set<String>> BABY_ARMOR_PARTS_PER_SLOT = Maps.newEnumMap(
        Map.of(
            EquipmentSlot.HEAD,
            Set.of("head"),
            EquipmentSlot.CHEST,
            Set.of("body", "left_arm", "right_arm"),
            EquipmentSlot.LEGS,
            Set.of("left_leg", "right_leg", "waist"),
            EquipmentSlot.FEET,
            Set.of("left_foot", "right_foot")
        )
    );
    public final ModelPart head;
    public final ModelPart hat;
    public final ModelPart body;
    public final ModelPart rightArm;
    public final ModelPart leftArm;
    public final ModelPart rightLeg;
    public final ModelPart leftLeg;
 
    public HumanoidModel(ModelPart root) {
        this(root, RenderTypes::entityCutout);
    }
 
    public HumanoidModel(ModelPart root, Function<Identifier, RenderType> renderType) {
        super(root, renderType);
        this.head = root.getChild("head");
        this.hat = this.head.getChild("hat");
        this.body = root.getChild("body");
        this.rightArm = root.getChild("right_arm");
        this.leftArm = root.getChild("left_arm");
        this.rightLeg = root.getChild("right_leg");
        this.leftLeg = root.getChild("left_leg");
    }
 
    public static MeshDefinition createMesh(CubeDeformation g, float yOffset) {
        MeshDefinition mesh = new MeshDefinition();
        PartDefinition root = mesh.getRoot();
        PartDefinition head = root.addOrReplaceChild(
            "head", CubeListBuilder.create().texOffs(0, 0).addBox(-4.0F, -8.0F, -4.0F, 8.0F, 8.0F, 8.0F, g), PartPose.offset(0.0F, 0.0F + yOffset, 0.0F)
        );
        head.addOrReplaceChild("hat", CubeListBuilder.create().texOffs(32, 0).addBox(-4.0F, -8.0F, -4.0F, 8.0F, 8.0F, 8.0F, g.extend(0.5F)), PartPose.ZERO);
        root.addOrReplaceChild(
            "body", CubeListBuilder.create().texOffs(16, 16).addBox(-4.0F, 0.0F, -2.0F, 8.0F, 12.0F, 4.0F, g), PartPose.offset(0.0F, 0.0F + yOffset, 0.0F)
        );
        root.addOrReplaceChild(
            "right_arm",
            CubeListBuilder.create().texOffs(40, 16).addBox(-3.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, g),
            PartPose.offset(-5.0F, 2.0F + yOffset, 0.0F)
        );
        root.addOrReplaceChild(
            "left_arm",
            CubeListBuilder.create().texOffs(40, 16).mirror().addBox(-1.0F, -2.0F, -2.0F, 4.0F, 12.0F, 4.0F, g),
            PartPose.offset(5.0F, 2.0F + yOffset, 0.0F)
        );
        root.addOrReplaceChild(
            "right_leg",
            CubeListBuilder.create().texOffs(0, 16).addBox(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, g),
            PartPose.offset(-1.9F, 12.0F + yOffset, 0.0F)
        );
        root.addOrReplaceChild(
            "left_leg",
            CubeListBuilder.create().texOffs(0, 16).mirror().addBox(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, g),
            PartPose.offset(1.9F, 12.0F + yOffset, 0.0F)
        );
        return mesh;
    }
 
    public static ArmorModelSet<MeshDefinition> createArmorMeshSet(CubeDeformation innerDeformation, CubeDeformation outerDeformation) {
        return createArmorMeshSet(HumanoidModel::createBaseArmorMesh, ADULT_ARMOR_PARTS_PER_SLOT, innerDeformation, outerDeformation);
    }
 
    public static ArmorModelSet<MeshDefinition> createBabyArmorMeshSet(CubeDeformation innerDeformation, CubeDeformation outerDeformation, PartPose armOffset) {
        return createArmorMeshSet(cube -> createBabyArmorMesh(cube, armOffset), BABY_ARMOR_PARTS_PER_SLOT, innerDeformation, outerDeformation);
    }
 
    protected static ArmorModelSet<MeshDefinition> createArmorMeshSet(
        Function<CubeDeformation, MeshDefinition> baseFactory,
        Map<EquipmentSlot, Set<String>> partsPerSlot,
        CubeDeformation innerDeformation,
        CubeDeformation outerDeformation
    ) {
        MeshDefinition head = baseFactory.apply(outerDeformation);
        head.getRoot().retainPartsAndChildren(partsPerSlot.get(EquipmentSlot.HEAD));
        MeshDefinition chest = baseFactory.apply(outerDeformation);
        chest.getRoot().retainExactParts(partsPerSlot.get(EquipmentSlot.CHEST));
        MeshDefinition legs = baseFactory.apply(innerDeformation);
        legs.getRoot().retainExactParts(partsPerSlot.get(EquipmentSlot.LEGS));
        MeshDefinition feet = baseFactory.apply(outerDeformation);
        feet.getRoot().retainExactParts(partsPerSlot.get(EquipmentSlot.FEET));
        return new ArmorModelSet<>(head, chest, legs, feet);
    }
 
    private static MeshDefinition createBaseArmorMesh(CubeDeformation g) {
        MeshDefinition mesh = createMesh(g, 0.0F);
        PartDefinition root = mesh.getRoot();
        root.addOrReplaceChild(
            "right_leg",
            CubeListBuilder.create().texOffs(0, 16).addBox(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, g.extend(-0.1F)),
            PartPose.offset(-1.9F, 12.0F, 0.0F)
        );
        root.addOrReplaceChild(
            "left_leg",
            CubeListBuilder.create().texOffs(0, 16).mirror().addBox(-2.0F, 0.0F, -2.0F, 4.0F, 12.0F, 4.0F, g.extend(-0.1F)),
            PartPose.offset(1.9F, 12.0F, 0.0F)
        );
        return mesh;
    }
 
    private static MeshDefinition createBabyArmorMesh(CubeDeformation g, PartPose armOffset) {
        MeshDefinition mesh = new MeshDefinition();
        PartDefinition root = mesh.getRoot();
        PartDefinition head = root.addOrReplaceChild(
            "head", CubeListBuilder.create().texOffs(0, 0).addBox(-4.5F, -7.0F, -4.5F, 9.0F, 8.0F, 8.0F, g), PartPose.offset(0.0F, 15.0F, 0.0F)
        );
        root.addOrReplaceChild(
            "body", CubeListBuilder.create().texOffs(0, 17).addBox(-3.0F, -3.0F, -1.5F, 6.0F, 5.0F, 3.0F, g), PartPose.offset(0.0F, 18.0F, 0.0F)
        );
        root.addOrReplaceChild(
            "waist",
            CubeListBuilder.create().texOffs(0, 36).addBox(-3.0F, -1.2F, -1.49F, 5.9F, 2.0F, 2.9F, g.extend(-0.1F)),
            PartPose.offset(0.0F, 19.0F, 0.0F)
        );
        root.addOrReplaceChild(
            "right_arm",
            CubeListBuilder.create().texOffs(30, 25).addBox(-1.0F, 0.0F, -1.53F, 2.0F, 5.0F, 3.0F, g),
            PartPose.offset(-3.5F - armOffset.x(), 15.5F + armOffset.y(), 0.0F + armOffset.z())
        );
        root.addOrReplaceChild(
            "left_arm",
            CubeListBuilder.create().texOffs(30, 17).addBox(-1.0F, 0.0F, -1.53F, 2.0F, 5.0F, 3.0F, g),
            PartPose.offset(3.5F + armOffset.x(), 15.5F + armOffset.y(), 0.0F + armOffset.z())
        );
        root.addOrReplaceChild(
            "inner_body", CubeListBuilder.create().texOffs(0, 17).addBox(-3.0F, -3.0F, -1.5F, 6.0F, 5.0F, 3.0F, g), PartPose.offset(0.0F, 18.0F, 0.0F)
        );
        PartDefinition rightLeg = root.addOrReplaceChild(
            "left_leg",
            CubeListBuilder.create().texOffs(18, 24).addBox(-2.0F, -0.2F, -2.0F, 3.0F, 4.0F, 3.0F, g.extend(-0.1F)),
            PartPose.offset(1.5F, 20.0F, 0.5F)
        );
        PartDefinition leftLeg = root.addOrReplaceChild(
            "right_leg",
            CubeListBuilder.create().texOffs(18, 17).addBox(-1.0F, -0.2F, -2.0F, 3.0F, 4.0F, 3.0F, g.extend(-0.1F)),
            PartPose.offset(-1.5F, 20.0F, 0.5F)
        );
        rightLeg.addOrReplaceChild(
            "right_foot", CubeListBuilder.create().texOffs(0, 25).addBox(-2.0F, 2.9F, -2.0F, 3.0F, 1.0F, 3.0F, g), PartPose.offset(0.0F, 0.0F, 0.0F)
        );
        leftLeg.addOrReplaceChild(
            "left_foot",
            CubeListBuilder.create().texOffs(0, 29).mirror().addBox(-1.0F, 2.9F, -2.0F, 3.0F, 1.0F, 3.0F, g).mirror(false),
            PartPose.offset(0.0F, 0.0F, 0.0F)
        );
        head.addOrReplaceChild("hat", CubeListBuilder.create(), PartPose.ZERO);
        return mesh;
    }
 
    public void setupAnim(T state) {
        super.setupAnim(state);
        HumanoidModel.ArmPose leftArmPose = state.leftArmPose;
        HumanoidModel.ArmPose rightArmPose = state.rightArmPose;
        float swimAmount = state.swimAmount;
        boolean fallFlying = state.isFallFlying;
        this.head.xRot = state.xRot * (float) (Math.PI / 180.0);
        this.head.yRot = state.yRot * (float) (Math.PI / 180.0);
        if (fallFlying) {
            this.head.xRot = (float) (-Math.PI / 4);
        } else if (swimAmount > 0.0F) {
            this.head.xRot = Mth.rotLerpRad(swimAmount, this.head.xRot, (float) (-Math.PI / 4));
        }
 
        float animationPos = state.walkAnimationPos;
        float animationSpeed = state.walkAnimationSpeed;
        this.rightArm.xRot = Mth.cos(animationPos * 0.6662F + (float) Math.PI) * 2.0F * animationSpeed * 0.5F / state.speedValue;
        this.leftArm.xRot = Mth.cos(animationPos * 0.6662F) * 2.0F * animationSpeed * 0.5F / state.speedValue;
        this.rightLeg.xRot = Mth.cos(animationPos * 0.6662F) * 1.4F * animationSpeed / state.speedValue;
        this.leftLeg.xRot = Mth.cos(animationPos * 0.6662F + (float) Math.PI) * 1.4F * animationSpeed / state.speedValue;
        this.rightLeg.yRot = 0.005F;
        this.leftLeg.yRot = -0.005F;
        this.rightLeg.zRot = 0.005F;
        this.leftLeg.zRot = -0.005F;
        if (state.isPassenger) {
            this.rightArm.xRot += (float) (-Math.PI / 5);
            this.leftArm.xRot += (float) (-Math.PI / 5);
            this.rightLeg.xRot = -1.4137167F;
            this.rightLeg.yRot = (float) (Math.PI / 10);
            this.rightLeg.zRot = 0.07853982F;
            this.leftLeg.xRot = -1.4137167F;
            this.leftLeg.yRot = (float) (-Math.PI / 10);
            this.leftLeg.zRot = -0.07853982F;
        }
 
        boolean rightHanded = state.mainArm == HumanoidArm.RIGHT;
        if (state.isUsingItem) {
            boolean mainHandUsed = state.useItemHand == InteractionHand.MAIN_HAND;
            if (mainHandUsed == rightHanded) {
                this.poseRightArm(state);
                if (!state.rightArmPose.affectsOffhandPose()) {
                    this.poseLeftArm(state);
                }
            } else {
                this.poseLeftArm(state);
                if (!state.leftArmPose.affectsOffhandPose()) {
                    this.poseRightArm(state);
                }
            }
        } else {
            boolean twoHandedOffhand = rightHanded ? leftArmPose.isTwoHanded() : rightArmPose.isTwoHanded();
            if (rightHanded != twoHandedOffhand) {
                this.poseLeftArm(state);
                if (!state.leftArmPose.affectsOffhandPose()) {
                    this.poseRightArm(state);
                }
            } else {
                this.poseRightArm(state);
                if (!state.rightArmPose.affectsOffhandPose()) {
                    this.poseLeftArm(state);
                }
            }
        }
 
        this.setupAttackAnimation(state);
        if (state.isCrouching) {
            this.body.xRot = 0.5F;
            this.rightArm.xRot += 0.4F;
            this.leftArm.xRot += 0.4F;
            this.rightLeg.z += 4.0F;
            this.leftLeg.z += 4.0F;
            this.head.y += 4.2F;
            this.body.y += 3.2F;
            this.leftArm.y += 3.2F;
            this.rightArm.y += 3.2F;
        }
 
        if (rightArmPose != HumanoidModel.ArmPose.SPYGLASS) {
            AnimationUtils.bobModelPart(this.rightArm, state.ageInTicks, 1.0F);
        }
 
        if (leftArmPose != HumanoidModel.ArmPose.SPYGLASS) {
            AnimationUtils.bobModelPart(this.leftArm, state.ageInTicks, -1.0F);
        }
 
        if (swimAmount > 0.0F) {
            float swimPos = animationPos % 26.0F;
            HumanoidArm attackArm = state.attackArm;
            float rightArmSwimAmount = state.rightArmPose != HumanoidModel.ArmPose.SPEAR && (attackArm != HumanoidArm.RIGHT || !(state.attackTime > 0.0F))
                ? swimAmount
                : 0.0F;
            float leftArmSwimAmount = state.leftArmPose != HumanoidModel.ArmPose.SPEAR && (attackArm != HumanoidArm.LEFT || !(state.attackTime > 0.0F))
                ? swimAmount
                : 0.0F;
            if (!state.isUsingItem) {
                if (swimPos < 14.0F) {
                    this.leftArm.xRot = Mth.rotLerpRad(leftArmSwimAmount, this.leftArm.xRot, 0.0F);
                    this.rightArm.xRot = Mth.lerp(rightArmSwimAmount, this.rightArm.xRot, 0.0F);
                    this.leftArm.yRot = Mth.rotLerpRad(leftArmSwimAmount, this.leftArm.yRot, (float) Math.PI);
                    this.rightArm.yRot = Mth.lerp(rightArmSwimAmount, this.rightArm.yRot, (float) Math.PI);
                    this.leftArm.zRot = Mth.rotLerpRad(
                        leftArmSwimAmount, this.leftArm.zRot, (float) Math.PI + 1.8707964F * this.quadraticArmUpdate(swimPos) / this.quadraticArmUpdate(14.0F)
                    );
                    this.rightArm.zRot = Mth.lerp(
                        rightArmSwimAmount,
                        this.rightArm.zRot,
                        (float) Math.PI - 1.8707964F * this.quadraticArmUpdate(swimPos) / this.quadraticArmUpdate(14.0F)
                    );
                } else if (swimPos >= 14.0F && swimPos < 22.0F) {
                    float internalSwimPos = (swimPos - 14.0F) / 8.0F;
                    this.leftArm.xRot = Mth.rotLerpRad(leftArmSwimAmount, this.leftArm.xRot, (float) (Math.PI / 2) * internalSwimPos);
                    this.rightArm.xRot = Mth.lerp(rightArmSwimAmount, this.rightArm.xRot, (float) (Math.PI / 2) * internalSwimPos);
                    this.leftArm.yRot = Mth.rotLerpRad(leftArmSwimAmount, this.leftArm.yRot, (float) Math.PI);
                    this.rightArm.yRot = Mth.lerp(rightArmSwimAmount, this.rightArm.yRot, (float) Math.PI);
                    this.leftArm.zRot = Mth.rotLerpRad(leftArmSwimAmount, this.leftArm.zRot, 5.012389F - 1.8707964F * internalSwimPos);
                    this.rightArm.zRot = Mth.lerp(rightArmSwimAmount, this.rightArm.zRot, 1.2707963F + 1.8707964F * internalSwimPos);
                } else if (swimPos >= 22.0F && swimPos < 26.0F) {
                    float internalSwimPos = (swimPos - 22.0F) / 4.0F;
                    this.leftArm.xRot = Mth.rotLerpRad(leftArmSwimAmount, this.leftArm.xRot, (float) (Math.PI / 2) - (float) (Math.PI / 2) * internalSwimPos);
                    this.rightArm.xRot = Mth.lerp(rightArmSwimAmount, this.rightArm.xRot, (float) (Math.PI / 2) - (float) (Math.PI / 2) * internalSwimPos);
                    this.leftArm.yRot = Mth.rotLerpRad(leftArmSwimAmount, this.leftArm.yRot, (float) Math.PI);
                    this.rightArm.yRot = Mth.lerp(rightArmSwimAmount, this.rightArm.yRot, (float) Math.PI);
                    this.leftArm.zRot = Mth.rotLerpRad(leftArmSwimAmount, this.leftArm.zRot, (float) Math.PI);
                    this.rightArm.zRot = Mth.lerp(rightArmSwimAmount, this.rightArm.zRot, (float) Math.PI);
                }
            }
 
            float amplitude = 0.3F;
            float slowdown = 0.33333334F;
            this.leftLeg.xRot = Mth.lerp(swimAmount, this.leftLeg.xRot, 0.3F * Mth.cos(animationPos * 0.33333334F + (float) Math.PI));
            this.rightLeg.xRot = Mth.lerp(swimAmount, this.rightLeg.xRot, 0.3F * Mth.cos(animationPos * 0.33333334F));
        }
    }
 
    private void poseRightArm(T state) {
        switch (state.rightArmPose) {
            case EMPTY:
                this.rightArm.yRot = 0.0F;
                break;
            case ITEM:
                this.rightArm.xRot = this.rightArm.xRot * 0.5F - (float) (Math.PI / 10);
                this.rightArm.yRot = 0.0F;
                break;
            case BLOCK:
                this.poseBlockingArm(this.rightArm, true);
                break;
            case BOW_AND_ARROW:
                this.rightArm.yRot = -0.1F + this.head.yRot;
                this.leftArm.yRot = 0.1F + this.head.yRot + 0.4F;
                this.rightArm.xRot = (float) (-Math.PI / 2) + this.head.xRot;
                this.leftArm.xRot = (float) (-Math.PI / 2) + this.head.xRot;
                break;
            case THROW_TRIDENT:
                this.rightArm.xRot = this.rightArm.xRot * 0.5F - (float) Math.PI;
                this.rightArm.yRot = 0.0F;
                break;
            case CROSSBOW_CHARGE:
                AnimationUtils.animateCrossbowCharge(this.rightArm, this.leftArm, state.maxCrossbowChargeDuration, state.ticksUsingItem, true);
                break;
            case CROSSBOW_HOLD:
                AnimationUtils.animateCrossbowHold(this.rightArm, this.leftArm, this.head, true);
                break;
            case SPYGLASS:
                this.rightArm.xRot = Mth.clamp(this.head.xRot - 1.9198622F - (state.isCrouching ? (float) (Math.PI / 12) : 0.0F), -2.4F, 3.3F);
                this.rightArm.yRot = this.head.yRot - (float) (Math.PI / 12);
                break;
            case TOOT_HORN:
                this.rightArm.xRot = Mth.clamp(this.head.xRot, -1.2F, 1.2F) - 1.4835298F;
                this.rightArm.yRot = this.head.yRot - (float) (Math.PI / 6);
                break;
            case BRUSH:
                this.rightArm.xRot = this.rightArm.xRot * 0.5F - (float) (Math.PI / 5);
                this.rightArm.yRot = 0.0F;
                break;
            case SPEAR:
                SpearAnimations.thirdPersonHandUse(this.rightArm, this.head, true, state.getUseItemStackForArm(HumanoidArm.RIGHT), state);
        }
    }
 
    private void poseLeftArm(T state) {
        switch (state.leftArmPose) {
            case EMPTY:
                this.leftArm.yRot = 0.0F;
                break;
            case ITEM:
                this.leftArm.xRot = this.leftArm.xRot * 0.5F - (float) (Math.PI / 10);
                this.leftArm.yRot = 0.0F;
                break;
            case BLOCK:
                this.poseBlockingArm(this.leftArm, false);
                break;
            case BOW_AND_ARROW:
                this.rightArm.yRot = -0.1F + this.head.yRot - 0.4F;
                this.leftArm.yRot = 0.1F + this.head.yRot;
                this.rightArm.xRot = (float) (-Math.PI / 2) + this.head.xRot;
                this.leftArm.xRot = (float) (-Math.PI / 2) + this.head.xRot;
                break;
            case THROW_TRIDENT:
                this.leftArm.xRot = this.leftArm.xRot * 0.5F - (float) Math.PI;
                this.leftArm.yRot = 0.0F;
                break;
            case CROSSBOW_CHARGE:
                AnimationUtils.animateCrossbowCharge(this.rightArm, this.leftArm, state.maxCrossbowChargeDuration, state.ticksUsingItem, false);
                break;
            case CROSSBOW_HOLD:
                AnimationUtils.animateCrossbowHold(this.rightArm, this.leftArm, this.head, false);
                break;
            case SPYGLASS:
                this.leftArm.xRot = Mth.clamp(this.head.xRot - 1.9198622F - (state.isCrouching ? (float) (Math.PI / 12) : 0.0F), -2.4F, 3.3F);
                this.leftArm.yRot = this.head.yRot + (float) (Math.PI / 12);
                break;
            case TOOT_HORN:
                this.leftArm.xRot = Mth.clamp(this.head.xRot, -1.2F, 1.2F) - 1.4835298F;
                this.leftArm.yRot = this.head.yRot + (float) (Math.PI / 6);
                break;
            case BRUSH:
                this.leftArm.xRot = this.leftArm.xRot * 0.5F - (float) (Math.PI / 5);
                this.leftArm.yRot = 0.0F;
                break;
            case SPEAR:
                SpearAnimations.thirdPersonHandUse(this.leftArm, this.head, false, state.getUseItemStackForArm(HumanoidArm.LEFT), state);
        }
    }
 
    private void poseBlockingArm(ModelPart arm, boolean right) {
        arm.xRot = arm.xRot * 0.5F - 0.9424779F + Mth.clamp(this.head.xRot, (float) (-Math.PI * 4.0 / 9.0), 0.43633232F);
        arm.yRot = (right ? -30.0F : 30.0F) * (float) (Math.PI / 180.0) + Mth.clamp(this.head.yRot, (float) (-Math.PI / 6), (float) (Math.PI / 6));
    }
 
    protected void setupAttackAnimation(T state) {
        float attackTime = state.attackTime;
        if (!(attackTime <= 0.0F)) {
            this.body.yRot = Mth.sin(Mth.sqrt(attackTime) * (float) (Math.PI * 2)) * 0.2F;
            if (state.attackArm == HumanoidArm.LEFT) {
                this.body.yRot *= -1.0F;
            }
 
            float ageScale = state.ageScale;
            this.rightArm.z = Mth.sin(this.body.yRot) * 5.0F * ageScale;
            this.rightArm.x = -Mth.cos(this.body.yRot) * 5.0F * ageScale;
            this.leftArm.z = -Mth.sin(this.body.yRot) * 5.0F * ageScale;
            this.leftArm.x = Mth.cos(this.body.yRot) * 5.0F * ageScale;
            this.rightArm.yRot = this.rightArm.yRot + this.body.yRot;
            this.leftArm.yRot = this.leftArm.yRot + this.body.yRot;
            this.leftArm.xRot = this.leftArm.xRot + this.body.yRot;
            switch (state.swingAnimationType) {
                case WHACK:
                    float swing = Ease.outQuart(attackTime);
                    float aa = Mth.sin(swing * (float) Math.PI);
                    float bb = Mth.sin(attackTime * (float) Math.PI) * -(this.head.xRot - 0.7F) * 0.75F;
                    ModelPart attackArm = this.getArm(state.attackArm);
                    attackArm.xRot -= aa * 1.2F + bb;
                    attackArm.yRot = attackArm.yRot + this.body.yRot * 2.0F;
                    attackArm.zRot = attackArm.zRot + Mth.sin(attackTime * (float) Math.PI) * -0.4F;
                case NONE:
                default:
                    break;
                case STAB:
                    SpearAnimations.thirdPersonAttackHand(this, state);
            }
        }
    }
 
    private float quadraticArmUpdate(float x) {
        return -65.0F * x + x * x;
    }
 
    public void translateToHand(HumanoidRenderState state, HumanoidArm arm, PoseStack poseStack) {
        this.root.translateAndRotate(poseStack);
        this.getArm(arm).translateAndRotate(poseStack);
    }
 
    public ModelPart getArm(HumanoidArm arm) {
        return arm == HumanoidArm.LEFT ? this.leftArm : this.rightArm;
    }
 
    @Override
    public ModelPart getHead() {
        return this.head;
    }
 
    @OnlyIn(Dist.CLIENT)
    public static enum ArmPose {
        EMPTY(false, false),
        ITEM(false, false),
        BLOCK(false, false),
        BOW_AND_ARROW(true, true),
        THROW_TRIDENT(false, true),
        CROSSBOW_CHARGE(true, true),
        CROSSBOW_HOLD(true, true),
        SPYGLASS(false, false),
        TOOT_HORN(false, false),
        BRUSH(false, false),
        SPEAR(false, true) {
            @Override
            public <S extends ArmedEntityRenderState> void animateUseItem(
                S state, PoseStack poseStack, float ticksUsingItem, HumanoidArm arm, ItemStack actualItem
            ) {
                SpearAnimations.thirdPersonUseItem(state, poseStack, ticksUsingItem, arm, actualItem);
            }
        };
 
        private final boolean twoHanded;
        private final boolean affectsOffhandPose;
 
        private ArmPose(boolean twoHanded, boolean affectsOffhandPose) {
            this.twoHanded = twoHanded;
            this.affectsOffhandPose = affectsOffhandPose;
        }
 
        public boolean isTwoHanded() {
            return this.twoHanded;
        }
 
        public boolean affectsOffhandPose() {
            return this.affectsOffhandPose;
        }
 
        public <S extends ArmedEntityRenderState> void animateUseItem(S state, PoseStack poseStack, float ticksUsingItem, HumanoidArm arm, ItemStack actualItem) {
        }
    }
}

引用的其他类

  • PoseStack

    • 引用位置: 参数
  • AnimationUtils

    • 引用位置: 方法调用
    • 关联成员: AnimationUtils.animateCrossbowCharge(), AnimationUtils.animateCrossbowHold(), AnimationUtils.bobModelPart()
  • ArmedModel

    • 引用位置: 实现
  • BabyModelTransform

    • 引用位置: 构造调用
    • 关联成员: BabyModelTransform()
  • EntityModel

    • 引用位置: 继承
  • HeadedModel

    • 引用位置: 实现
  • SpearAnimations

    • 引用位置: 方法调用
    • 关联成员: SpearAnimations.thirdPersonAttackHand(), SpearAnimations.thirdPersonHandUse(), SpearAnimations.thirdPersonUseItem()
  • ModelPart

    • 引用位置: 参数/字段/返回值
  • PartPose

    • 引用位置: 参数/方法调用
    • 关联成员: PartPose.offset()
  • CubeDeformation

    • 引用位置: 参数
  • CubeListBuilder

    • 引用位置: 方法调用
    • 关联成员: CubeListBuilder.create()
  • MeshDefinition

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

    • 引用位置: 字段
  • ArmorModelSet

    • 引用位置: 返回值
  • HumanoidRenderState

    • 引用位置: 参数
  • RenderType

    • 引用位置: 参数
  • Identifier

    • 引用位置: 参数
  • Ease

    • 引用位置: 方法调用
    • 关联成员: Ease.outQuart()
  • Mth

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

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

    • 引用位置: 参数