2019-03-23 20:49:34 +01:00
|
|
|
package com.minelittlepony.client.model;
|
|
|
|
|
2019-05-28 10:26:26 +02:00
|
|
|
import com.minelittlepony.client.model.armour.ModelPonyArmour;
|
|
|
|
import com.minelittlepony.client.model.armour.ArmourWrapper;
|
2019-03-23 20:49:34 +01:00
|
|
|
import com.minelittlepony.client.model.components.PonySnout;
|
|
|
|
import com.minelittlepony.client.transform.PonyTransformation;
|
2019-03-23 20:58:50 +01:00
|
|
|
import com.minelittlepony.model.BodyPart;
|
|
|
|
import com.minelittlepony.model.IPart;
|
|
|
|
import com.minelittlepony.model.armour.IEquestrianArmour;
|
2019-11-23 18:28:42 +01:00
|
|
|
import com.minelittlepony.mson.api.model.MsonPart;
|
|
|
|
|
2019-11-22 18:24:22 +01:00
|
|
|
import net.minecraft.client.model.ModelPart;
|
2019-11-23 18:28:42 +01:00
|
|
|
import net.minecraft.client.render.VertexConsumer;
|
|
|
|
import net.minecraft.client.util.math.MatrixStack;
|
|
|
|
import net.minecraft.client.util.math.Vector3f;
|
2015-08-02 00:36:33 +02:00
|
|
|
import net.minecraft.entity.Entity;
|
2019-05-27 17:59:15 +02:00
|
|
|
import net.minecraft.entity.LivingEntity;
|
2019-07-20 20:16:54 +02:00
|
|
|
import net.minecraft.util.Arm;
|
2016-05-04 03:23:57 +02:00
|
|
|
import net.minecraft.util.math.MathHelper;
|
2015-08-02 00:36:33 +02:00
|
|
|
|
2016-11-25 05:40:19 +01:00
|
|
|
/**
|
2018-04-29 14:22:26 +02:00
|
|
|
* Foundation class for all types of ponies.
|
2016-11-25 05:40:19 +01:00
|
|
|
*/
|
2019-05-27 17:59:15 +02:00
|
|
|
public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPonyModel<T> {
|
2015-12-09 04:14:42 +01:00
|
|
|
|
2019-11-23 18:28:42 +01:00
|
|
|
protected ModelPart upperTorso;
|
|
|
|
protected ModelPart upperTorsoOverlay;
|
2019-08-18 15:19:05 +02:00
|
|
|
|
2019-11-23 18:28:42 +01:00
|
|
|
protected ModelPart neck;
|
2015-12-09 04:14:42 +01:00
|
|
|
|
2019-06-24 11:25:39 +02:00
|
|
|
protected IPart tail;
|
|
|
|
protected PonySnout snout;
|
2019-10-12 10:58:18 +02:00
|
|
|
protected IPart ears;
|
2019-01-06 17:07:42 +01:00
|
|
|
|
2016-01-19 06:34:07 +01:00
|
|
|
public AbstractPonyModel(boolean arms) {
|
|
|
|
super(0, arms);
|
2015-08-02 00:36:33 +02:00
|
|
|
}
|
|
|
|
|
2018-04-29 14:22:26 +02:00
|
|
|
@Override
|
2019-03-23 20:49:34 +01:00
|
|
|
public IEquestrianArmour<?> createArmour() {
|
2019-08-11 13:54:57 +02:00
|
|
|
return new ArmourWrapper<>(ModelPonyArmour::new);
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
|
2018-05-01 12:38:13 +02:00
|
|
|
/**
|
|
|
|
* Sets the model's various rotation angles.
|
|
|
|
*
|
2019-06-24 11:25:39 +02:00
|
|
|
* @param move Entity motion parameter
|
|
|
|
* i.e. velocity in no specific direction used in bipeds to calculate step amount.
|
2018-05-01 12:38:13 +02:00
|
|
|
* @param swing Degree to which each 'limb' swings.
|
2019-06-24 11:25:39 +02:00
|
|
|
* @param ticks Total whole and partial ticks since the entity's existence.
|
|
|
|
* Used in animations together with {@code swing} and {@code move}.
|
2018-05-01 12:38:13 +02:00
|
|
|
* @param headYaw Horizontal head motion in radians.
|
|
|
|
* @param headPitch Vertical head motion in radians.
|
2019-06-24 11:25:39 +02:00
|
|
|
* @param scale Scaling factor used to render this model.
|
|
|
|
* Determined by the return value of {@link RenderLivingBase.prepareScale}.
|
|
|
|
* Usually {@code 0.0625F}.
|
2018-05-01 12:38:13 +02:00
|
|
|
* @param entity The entity we're being called for.
|
|
|
|
*/
|
2018-04-29 14:22:26 +02:00
|
|
|
@Override
|
2019-11-23 18:28:42 +01:00
|
|
|
public void setAngles(T entity, float move, float swing, float ticks, float headYaw, float headPitch) {
|
2019-06-24 11:25:39 +02:00
|
|
|
attributes.checkRainboom(entity, swing, canFly());
|
2018-05-10 18:24:27 +02:00
|
|
|
|
2019-11-23 18:28:42 +01:00
|
|
|
super.setAngles(entity, move, swing, ticks, headYaw, headPitch);
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-06-24 11:25:39 +02:00
|
|
|
updateHeadRotation(headYaw, headPitch);
|
2018-06-03 16:38:03 +02:00
|
|
|
shakeBody(move, swing, getWobbleAmount(), ticks);
|
|
|
|
rotateLegs(move, swing, ticks, entity);
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-06-24 11:25:39 +02:00
|
|
|
if (!attributes.isSwimming && !attributes.isGoingFast) {
|
2018-05-10 18:24:27 +02:00
|
|
|
holdItem(swing);
|
|
|
|
}
|
2018-05-01 12:38:13 +02:00
|
|
|
swingItem(entity);
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-06-24 11:25:39 +02:00
|
|
|
if (attributes.isCrouching) {
|
2018-12-09 22:02:04 +01:00
|
|
|
ponyCrouch();
|
2018-04-29 14:22:26 +02:00
|
|
|
} else if (isRiding) {
|
2018-12-09 22:02:04 +01:00
|
|
|
ponyRide();
|
2018-04-29 14:22:26 +02:00
|
|
|
} else {
|
2018-08-18 00:24:58 +02:00
|
|
|
adjustBody(BODY_ROT_X_NOTSNEAK, BODY_RP_Y_NOTSNEAK, BODY_RP_Z_NOTSNEAK);
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-11-22 18:24:22 +01:00
|
|
|
rightLeg.pivotY = FRONT_LEG_RP_Y_NOTSNEAK;
|
|
|
|
leftLeg.pivotY = FRONT_LEG_RP_Y_NOTSNEAK;
|
2019-07-06 18:29:28 +02:00
|
|
|
|
|
|
|
if (!attributes.isSleeping) {
|
|
|
|
animateBreathing(ticks);
|
|
|
|
}
|
2019-07-05 10:28:50 +02:00
|
|
|
|
2019-08-05 10:49:14 +02:00
|
|
|
if (attributes.isSwimmingRotated) {
|
2019-11-22 18:24:22 +01:00
|
|
|
head.setPivot(0, -2, -2);
|
2019-07-05 10:28:50 +02:00
|
|
|
} else {
|
2019-11-22 18:24:22 +01:00
|
|
|
head.setPivot(0, 0, 0);
|
2019-07-05 10:28:50 +02:00
|
|
|
}
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
|
2019-06-24 11:25:39 +02:00
|
|
|
if (attributes.isSleeping) {
|
2018-12-09 22:02:04 +01:00
|
|
|
ponySleep();
|
|
|
|
}
|
2018-04-29 14:22:26 +02:00
|
|
|
|
|
|
|
animateWears();
|
|
|
|
|
2019-06-24 11:25:39 +02:00
|
|
|
snout.setGender(getMetadata().getGender());
|
2018-06-02 20:05:22 +02:00
|
|
|
}
|
|
|
|
|
2018-12-09 22:02:04 +01:00
|
|
|
/**
|
|
|
|
* Aligns legs to a sneaky position.
|
|
|
|
*/
|
|
|
|
protected void ponyCrouch() {
|
|
|
|
adjustBody(BODY_ROT_X_SNEAK, BODY_RP_Y_SNEAK, BODY_RP_Z_SNEAK);
|
2019-11-22 18:24:22 +01:00
|
|
|
head.setPivot(0, 6, -2);
|
2018-12-09 22:02:04 +01:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
rightArm.pitch -= LEG_ROT_X_SNEAK_ADJ;
|
|
|
|
leftArm.pitch -= LEG_ROT_X_SNEAK_ADJ;
|
2018-12-09 22:02:04 +01:00
|
|
|
|
2019-11-22 18:24:22 +01:00
|
|
|
leftLeg.pivotY = FRONT_LEG_RP_Y_SNEAK;
|
|
|
|
rightLeg.pivotY = FRONT_LEG_RP_Y_SNEAK;
|
2018-12-09 22:02:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected void ponySleep() {
|
2019-05-27 17:59:15 +02:00
|
|
|
rightArm.pitch = ROTATE_270;
|
|
|
|
leftArm.pitch = ROTATE_270;
|
2018-12-09 22:02:04 +01:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
rightLeg.pitch = ROTATE_90;
|
|
|
|
leftLeg.pitch = ROTATE_90;
|
2018-12-09 22:02:04 +01:00
|
|
|
|
2019-11-22 18:24:22 +01:00
|
|
|
head.setPivot(1, 2, isSneaking ? -1 : 1);
|
2018-12-09 22:02:04 +01:00
|
|
|
|
2019-11-23 18:28:42 +01:00
|
|
|
((MsonPart)rightArm).shift(0, 2, 6);
|
|
|
|
((MsonPart)leftArm).shift(0, 2, 6);
|
|
|
|
((MsonPart)rightLeg).shift(0, 2, -8);
|
|
|
|
((MsonPart)leftLeg).shift(0, 2, -8);
|
2018-12-09 22:02:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
protected void ponyRide() {
|
2019-06-24 11:25:39 +02:00
|
|
|
if (attributes.isSitting) {
|
2018-09-19 23:22:59 +02:00
|
|
|
adjustBodyComponents(BODY_ROT_X_RIDING * 2, BODY_RP_Y_RIDING, BODY_RP_Z_RIDING);
|
|
|
|
adjustNeck(BODY_ROT_X_NOTSNEAK * 2, BODY_RP_Y_NOTSNEAK, BODY_RP_Z_NOTSNEAK - 4);
|
2019-11-22 18:24:22 +01:00
|
|
|
head.setPivot(0, -2, -5);
|
2018-09-19 23:22:59 +02:00
|
|
|
} else {
|
|
|
|
adjustBodyComponents(BODY_ROT_X_RIDING, BODY_RP_Y_RIDING, BODY_RP_Z_RIDING);
|
|
|
|
adjustNeck(BODY_ROT_X_NOTSNEAK, BODY_RP_Y_NOTSNEAK, BODY_RP_Z_NOTSNEAK);
|
2019-11-22 18:24:22 +01:00
|
|
|
head.setPivot(0, 0, 0);
|
2018-09-19 23:22:59 +02:00
|
|
|
}
|
|
|
|
|
2019-11-22 18:24:22 +01:00
|
|
|
leftLeg.pivotZ = 15;
|
|
|
|
leftLeg.pivotY = 9;
|
2019-05-27 17:59:15 +02:00
|
|
|
leftLeg.pitch = -PI / 4;
|
|
|
|
leftLeg.yaw = -PI / 5;
|
2018-12-09 22:02:04 +01:00
|
|
|
|
2019-11-22 18:24:22 +01:00
|
|
|
rightLeg.pivotZ = 15;
|
|
|
|
rightLeg.pivotY = 9;
|
2019-05-27 17:59:15 +02:00
|
|
|
rightLeg.pitch = -PI / 4;
|
|
|
|
rightLeg.yaw = PI / 5;
|
2018-12-09 22:02:04 +01:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
leftArm.roll = -PI * 0.06f;
|
|
|
|
rightArm.roll = PI * 0.06f;
|
2018-09-19 23:22:59 +02:00
|
|
|
|
2019-06-24 11:25:39 +02:00
|
|
|
if (attributes.isSitting) {
|
2019-05-27 17:59:15 +02:00
|
|
|
leftLeg.yaw = PI / 15;
|
|
|
|
leftLeg.pitch = PI / 9;
|
2018-12-09 22:02:04 +01:00
|
|
|
|
2019-11-22 18:24:22 +01:00
|
|
|
leftLeg.pivotZ = 10;
|
|
|
|
leftLeg.pivotY = 7;
|
2018-12-09 22:02:04 +01:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
rightLeg.yaw = -PI / 15;
|
|
|
|
rightLeg.pitch = PI / 9;
|
2018-12-09 22:02:04 +01:00
|
|
|
|
2019-11-22 18:24:22 +01:00
|
|
|
rightLeg.pivotZ = 10;
|
|
|
|
rightLeg.pivotY = 7;
|
2018-12-09 22:02:04 +01:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
leftArm.pitch = PI / 6;
|
|
|
|
rightArm.pitch = PI / 6;
|
2018-12-09 22:02:04 +01:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
leftArm.roll *= 2;
|
|
|
|
rightArm.roll *= 2;
|
2018-12-09 22:02:04 +01:00
|
|
|
}
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
|
2018-05-01 12:38:13 +02:00
|
|
|
/**
|
|
|
|
* Sets the model's various rotation angles.
|
|
|
|
*
|
|
|
|
* @param move Entity motion parameter - i.e. velocity in no specific direction used in bipeds to calculate step amount.
|
|
|
|
* @param swing Degree to which each 'limb' swings.
|
|
|
|
* @param bodySwing Horizontal (Y) body rotation.
|
|
|
|
* @param ticks Total whole and partial ticks since the entity's existance. Used in animations together with {@code swing} and {@code move}.
|
|
|
|
*/
|
2018-06-03 16:38:03 +02:00
|
|
|
protected void shakeBody(float move, float swing, float bodySwing, float ticks) {
|
2019-06-24 11:25:39 +02:00
|
|
|
tail.setRotationAndAngles(attributes.isSwimming || attributes.isGoingFast, attributes.interpolatorId, move, swing, bodySwing * 5, ticks);
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
upperTorso.yaw = bodySwing;
|
2019-11-22 18:24:22 +01:00
|
|
|
torso.yaw = bodySwing;
|
2019-05-27 17:59:15 +02:00
|
|
|
neck.yaw = bodySwing;
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private void animateWears() {
|
2019-11-22 18:24:22 +01:00
|
|
|
leftSleeve.copyPositionAndRotation(leftArm);
|
|
|
|
rightSleeve.copyPositionAndRotation(rightArm);
|
|
|
|
leftPantLeg.copyPositionAndRotation(leftLeg);
|
|
|
|
rightPantLeg.copyPositionAndRotation(rightLeg);
|
|
|
|
jacket.copyPositionAndRotation(torso);
|
|
|
|
helmet.copyPositionAndRotation(head);
|
|
|
|
upperTorsoOverlay.copyPositionAndRotation(upperTorso);
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Called to update the head rotation.
|
|
|
|
*
|
2018-05-01 12:38:13 +02:00
|
|
|
* @param x New rotation X
|
|
|
|
* @param y New rotation Y
|
2018-04-29 14:22:26 +02:00
|
|
|
*/
|
2019-06-24 11:25:39 +02:00
|
|
|
private void updateHeadRotation(float headYaw, float headPitch) {
|
2019-08-11 13:55:39 +02:00
|
|
|
headYaw = attributes.isSleeping ? (Math.abs(attributes.interpolatorId.getMostSignificantBits()) % 2.8F) - 1.9F : headYaw / 57.29578F;
|
2019-06-24 11:25:39 +02:00
|
|
|
headPitch = attributes.isSleeping ? 0.1f : headPitch / 57.29578F;
|
|
|
|
|
2019-08-05 10:49:14 +02:00
|
|
|
if (attributes.isSwimming && attributes.motionPitch != 0) {
|
2019-07-05 10:28:50 +02:00
|
|
|
headPitch -= 0.9F;
|
2019-06-26 15:44:15 +02:00
|
|
|
}
|
|
|
|
|
2019-08-11 13:55:39 +02:00
|
|
|
head.yaw = 0;
|
|
|
|
head.roll = 0;
|
|
|
|
|
|
|
|
if (attributes.isSwimmingRotated) {
|
|
|
|
head.roll = -headYaw;
|
|
|
|
} else {
|
|
|
|
head.yaw = headYaw;
|
|
|
|
}
|
|
|
|
|
2019-07-05 10:28:50 +02:00
|
|
|
float pitch = (float)Math.toRadians(attributes.motionPitch);
|
|
|
|
|
|
|
|
head.pitch = MathHelper.clamp(headPitch, -1.25f - pitch, 0.5f - pitch);
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
|
2018-05-01 12:38:13 +02:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* Used to set the legs rotation based on walking/crouching animations.
|
|
|
|
*
|
|
|
|
* Takes the same parameters as {@link AbstractPonyModel.setRotationAndAngles}
|
|
|
|
*
|
|
|
|
*/
|
2019-05-27 17:59:15 +02:00
|
|
|
protected void rotateLegs(float move, float swing, float ticks, T entity) {
|
2019-06-24 11:25:39 +02:00
|
|
|
if (attributes.isSwimming) {
|
2018-06-29 18:36:03 +02:00
|
|
|
rotateLegsSwimming(move, swing, ticks, entity);
|
2019-06-24 11:25:39 +02:00
|
|
|
} else if (attributes.isGoingFast) {
|
2018-05-01 12:38:13 +02:00
|
|
|
rotateLegsInFlight(move, swing, ticks, entity);
|
2018-04-29 14:22:26 +02:00
|
|
|
} else {
|
2018-05-01 12:38:13 +02:00
|
|
|
rotateLegsOnGround(move, swing, ticks, entity);
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
|
2019-11-22 18:24:22 +01:00
|
|
|
float sin = MathHelper.sin(torso.yaw) * 5;
|
|
|
|
float cos = MathHelper.cos(torso.yaw) * 5;
|
2018-06-03 16:38:03 +02:00
|
|
|
|
2019-06-24 11:25:39 +02:00
|
|
|
float spread = attributes.isGoingFast ? 2 : 1;
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-11-22 18:24:22 +01:00
|
|
|
rightArm.pivotZ = spread + sin;
|
|
|
|
leftArm.pivotZ = spread - sin;
|
2018-06-03 16:38:03 +02:00
|
|
|
|
2018-10-28 15:26:00 +01:00
|
|
|
float legRPX = cos - getLegOutset() - 0.001F;
|
2018-06-03 16:38:03 +02:00
|
|
|
|
2019-06-24 11:25:39 +02:00
|
|
|
legRPX = getMetadata().getInterpolator(attributes.interpolatorId).interpolate("legOffset", legRPX, 3);
|
2018-06-11 19:25:02 +02:00
|
|
|
|
2019-11-22 18:24:22 +01:00
|
|
|
rightArm.pivotX = -legRPX;
|
|
|
|
rightLeg.pivotX = -legRPX;
|
2018-06-03 16:38:03 +02:00
|
|
|
|
2019-11-22 18:24:22 +01:00
|
|
|
leftArm.pivotX = legRPX;
|
|
|
|
leftLeg.pivotX = legRPX;
|
2018-06-03 16:38:03 +02:00
|
|
|
|
2019-11-22 18:24:22 +01:00
|
|
|
rightArm.yaw += torso.yaw;
|
|
|
|
leftArm.yaw += torso.yaw;
|
2018-06-03 16:38:03 +02:00
|
|
|
|
2019-11-22 18:24:22 +01:00
|
|
|
rightArm.pivotY = leftArm.pivotY = 8;
|
|
|
|
rightLeg.pivotZ = leftLeg.pivotZ = 10;
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
|
2018-06-29 18:36:03 +02:00
|
|
|
/**
|
2019-06-24 11:25:39 +02:00
|
|
|
* Rotates legs in a quopy fashion whilst swimming.
|
2018-06-29 18:36:03 +02:00
|
|
|
*
|
2019-06-24 11:25:39 +02:00
|
|
|
* Takes the same parameters as {@link AbstractPonyModel.setRotationAndAngles}
|
2018-06-29 18:36:03 +02:00
|
|
|
*/
|
2019-05-27 17:59:15 +02:00
|
|
|
protected void rotateLegsSwimming(float move, float swing, float ticks, T entity) {
|
2018-06-29 18:36:03 +02:00
|
|
|
|
2019-06-26 15:44:15 +02:00
|
|
|
float lerp = entity.isSwimming() ? (float)attributes.motionLerp : 1;
|
|
|
|
|
|
|
|
float legLeft = (ROTATE_90 + MathHelper.sin((move / 3) + 2 * PI/3) / 2) * lerp;
|
2018-06-29 18:36:03 +02:00
|
|
|
|
2019-06-26 15:44:15 +02:00
|
|
|
float left = (ROTATE_90 + MathHelper.sin((move / 3) + 2 * PI) / 2) * lerp;
|
|
|
|
float right = (ROTATE_90 + MathHelper.sin(move / 3) / 2) * lerp;
|
2018-06-29 18:36:03 +02:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
leftArm.pitch = -left;
|
|
|
|
leftArm.yaw = -left/2;
|
|
|
|
leftArm.roll = left/2;
|
2018-06-29 18:36:03 +02:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
rightArm.pitch = -right;
|
|
|
|
rightArm.yaw = right/2;
|
|
|
|
rightArm.roll = -right/2;
|
2018-06-29 18:36:03 +02:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
leftLeg.pitch = legLeft;
|
|
|
|
rightLeg.pitch = right;
|
2018-06-29 18:36:03 +02:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
leftLeg.yaw = 0;
|
|
|
|
rightLeg.yaw = 0;
|
2018-06-29 18:36:03 +02:00
|
|
|
}
|
2018-06-03 16:38:03 +02:00
|
|
|
|
2018-05-01 12:38:13 +02:00
|
|
|
/**
|
|
|
|
* Rotates legs in quopy fashion whilst flying.
|
|
|
|
*
|
2019-06-24 11:25:39 +02:00
|
|
|
* Takes the same parameters as {@link AbstractPonyModel.setRotationAndAngles}
|
2018-05-01 12:38:13 +02:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
protected void rotateLegsInFlight(float move, float swing, float ticks, Entity entity) {
|
2019-06-24 11:25:39 +02:00
|
|
|
float armX = attributes.isGoingFast ? ROTATE_270 : MathHelper.sin(-swing / 2);
|
|
|
|
float legX = attributes.isGoingFast ? ROTATE_90 : MathHelper.sin(swing / 2);
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
leftArm.pitch = armX;
|
|
|
|
rightArm.pitch = armX;
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
leftLeg.pitch = legX;
|
|
|
|
rightLeg.pitch = legX;
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
leftArm.yaw = -0.2F;
|
|
|
|
leftLeg.yaw = 0.2F;
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
rightArm.yaw = 0.2F;
|
|
|
|
rightLeg.yaw = -0.2F;
|
2018-10-21 17:15:42 +02:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
rightArm.roll = 0;
|
|
|
|
leftArm.roll = 0;
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
|
2018-05-01 12:38:13 +02:00
|
|
|
/**
|
|
|
|
* Rotates legs in quopy fashion for walking.
|
|
|
|
*
|
2019-06-24 11:25:39 +02:00
|
|
|
* Takes the same parameters as {@link AbstractPonyModel.setRotationAndAngles}
|
2018-05-01 12:38:13 +02:00
|
|
|
*
|
|
|
|
*/
|
2019-05-27 17:59:15 +02:00
|
|
|
protected void rotateLegsOnGround(float move, float swing, float ticks, T entity) {
|
2018-05-01 12:38:13 +02:00
|
|
|
float angle = PI * (float) Math.pow(swing, 16);
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2018-05-01 12:38:13 +02:00
|
|
|
float baseRotation = move * 0.6662F; // magic number ahoy
|
|
|
|
float scale = swing / 4;
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
leftArm.pitch = MathHelper.cos(baseRotation + angle) * scale;
|
|
|
|
rightArm.pitch = MathHelper.cos(baseRotation + PI + angle / 2) * scale;
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
leftLeg.pitch = MathHelper.cos(baseRotation + PI - (angle * 0.4f)) * scale;
|
|
|
|
rightLeg.pitch = MathHelper.cos(baseRotation + angle / 5) * scale;
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
leftArm.yaw = 0;
|
|
|
|
rightArm.yaw = 0;
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
leftLeg.yaw = 0;
|
|
|
|
rightLeg.yaw = 0;
|
2018-10-21 17:15:42 +02:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
rightArm.roll = 0;
|
|
|
|
leftArm.roll = 0;
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
protected float getLegOutset() {
|
2019-06-24 11:25:39 +02:00
|
|
|
if (attributes.isSleeping) {
|
2018-12-09 22:02:04 +01:00
|
|
|
return 3.6f;
|
|
|
|
}
|
|
|
|
|
2019-06-24 11:25:39 +02:00
|
|
|
if (attributes.isCrouching) {
|
2018-12-09 22:02:04 +01:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2018-04-29 23:06:34 +02:00
|
|
|
return 5;
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
|
2018-05-01 12:38:13 +02:00
|
|
|
/**
|
2019-06-24 11:25:39 +02:00
|
|
|
* Adjusts legs as if holding an item. Delegates to the correct arm/leg/limb as necessary.
|
2018-05-01 12:38:13 +02:00
|
|
|
*/
|
2018-04-29 14:22:26 +02:00
|
|
|
protected void holdItem(float swing) {
|
|
|
|
boolean both = leftArmPose == ArmPose.ITEM && rightArmPose == ArmPose.ITEM;
|
|
|
|
|
2019-07-20 20:16:54 +02:00
|
|
|
alignArmForAction(getArm(Arm.LEFT), leftArmPose, rightArmPose, both, swing, 1);
|
|
|
|
alignArmForAction(getArm(Arm.RIGHT), rightArmPose, leftArmPose, both, swing, -1);
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
|
2019-04-14 22:06:25 +02:00
|
|
|
@Override
|
2019-11-22 18:24:22 +01:00
|
|
|
public ModelPart getBodyPart(BodyPart part) {
|
2019-04-14 22:06:25 +02:00
|
|
|
switch (part) {
|
|
|
|
default:
|
2019-05-27 17:59:15 +02:00
|
|
|
case HEAD: return head;
|
2019-04-14 22:06:25 +02:00
|
|
|
case NECK: return neck;
|
|
|
|
case TAIL:
|
|
|
|
case LEGS:
|
2019-11-22 18:24:22 +01:00
|
|
|
case BODY: return torso;
|
2019-04-14 22:06:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-01 12:38:13 +02:00
|
|
|
/**
|
|
|
|
* Aligns an arm for the appropriate arm pose
|
|
|
|
*
|
|
|
|
* @param arm The arm model to align
|
|
|
|
* @param pose The post to align to
|
|
|
|
* @param both True if we have something in both hands
|
|
|
|
* @param swing Degree to which each 'limb' swings.
|
|
|
|
*/
|
2019-11-22 18:24:22 +01:00
|
|
|
protected void alignArmForAction(ModelPart arm, ArmPose pose, ArmPose complement, boolean both, float swing, float reflect) {
|
2018-04-29 14:22:26 +02:00
|
|
|
switch (pose) {
|
|
|
|
case ITEM:
|
2019-07-06 18:29:28 +02:00
|
|
|
arm.yaw = 0;
|
|
|
|
|
|
|
|
if ((!both || reflect == (attributes.isLeftHanded ? 1 : -1)) && complement != ArmPose.BLOCK) {
|
|
|
|
float swag = 1;
|
|
|
|
if (!isFlying() && both) {
|
|
|
|
swag -= (float)Math.pow(swing, 2);
|
|
|
|
}
|
|
|
|
|
|
|
|
float mult = 1 - swag/2;
|
|
|
|
arm.pitch = arm.pitch * mult - (PI / 10) * swag;
|
|
|
|
arm.roll = -reflect * (PI / 15);
|
|
|
|
|
|
|
|
if (attributes.isCrouching) {
|
2019-11-22 18:24:22 +01:00
|
|
|
arm.pivotX -= reflect * 2;
|
2019-07-06 18:29:28 +02:00
|
|
|
}
|
2018-06-03 16:38:03 +02:00
|
|
|
}
|
2019-07-06 18:29:28 +02:00
|
|
|
|
|
|
|
break;
|
2018-04-29 14:22:26 +02:00
|
|
|
case EMPTY:
|
2019-05-27 17:59:15 +02:00
|
|
|
arm.yaw = 0;
|
2018-04-29 14:22:26 +02:00
|
|
|
break;
|
|
|
|
case BLOCK:
|
2019-05-27 17:59:15 +02:00
|
|
|
arm.pitch = (arm.pitch / 2 - 0.9424779F) - 0.3F;
|
|
|
|
arm.yaw = reflect * PI / 9;
|
2018-08-22 15:15:48 +02:00
|
|
|
if (complement == pose) {
|
2019-05-27 17:59:15 +02:00
|
|
|
arm.yaw -= reflect * PI / 18;
|
2018-08-22 15:15:48 +02:00
|
|
|
}
|
2019-11-22 18:24:22 +01:00
|
|
|
arm.pivotX += reflect;
|
|
|
|
arm.pivotZ += 3;
|
2019-06-24 11:25:39 +02:00
|
|
|
if (attributes.isCrouching) {
|
2019-11-22 18:24:22 +01:00
|
|
|
arm.pivotY += 4;
|
2018-06-03 16:38:03 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case BOW_AND_ARROW:
|
|
|
|
aimBow(arm, swing);
|
2018-04-29 14:22:26 +02:00
|
|
|
break;
|
2019-06-02 16:36:21 +02:00
|
|
|
case CROSSBOW_HOLD:
|
|
|
|
aimBow(arm, swing);
|
|
|
|
|
|
|
|
arm.pitch = head.pitch - ROTATE_90;
|
|
|
|
arm.yaw = head.yaw + 0.06F;
|
|
|
|
break;
|
|
|
|
case CROSSBOW_CHARGE:
|
|
|
|
aimBow(arm, swing);
|
|
|
|
|
|
|
|
arm.pitch = -0.8F;
|
|
|
|
arm.yaw = head.yaw + 0.06F;
|
|
|
|
break;
|
|
|
|
case THROW_SPEAR:
|
|
|
|
arm.pitch = ROTATE_90 * 2;
|
|
|
|
break;
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-22 18:24:22 +01:00
|
|
|
protected void aimBow(ModelPart arm, float ticks) {
|
2019-05-27 17:59:15 +02:00
|
|
|
arm.pitch = ROTATE_270 + head.pitch + (MathHelper.sin(ticks * 0.067F) * 0.05F);
|
|
|
|
arm.yaw = head.yaw - 0.06F;
|
|
|
|
arm.roll = MathHelper.cos(ticks * 0.09F) * 0.05F + 0.05F;
|
2018-12-09 22:02:04 +01:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
if (isSneaking) {
|
2019-11-22 18:24:22 +01:00
|
|
|
arm.pivotY += 4;
|
2018-06-03 16:38:03 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-01 12:38:13 +02:00
|
|
|
/**
|
|
|
|
* Animates arm swinging. Delegates to the correct arm/leg/limb as neccessary.
|
|
|
|
*
|
|
|
|
* @param entity The entity we are being called for.
|
|
|
|
*/
|
2019-05-27 17:59:15 +02:00
|
|
|
protected void swingItem(T entity) {
|
2019-06-24 11:25:39 +02:00
|
|
|
if (getSwingAmount() > 0 && !attributes.isSleeping) {
|
2019-07-20 20:16:54 +02:00
|
|
|
Arm mainSide = getPreferredArm(entity);
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
swingArm(getArm(mainSide));
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-01 12:38:13 +02:00
|
|
|
/**
|
|
|
|
* Animates arm swinging.
|
|
|
|
*
|
|
|
|
* @param arm The arm to swing
|
|
|
|
*/
|
2019-11-22 18:24:22 +01:00
|
|
|
protected void swingArm(ModelPart arm) {
|
2019-05-27 17:59:15 +02:00
|
|
|
float swing = 1 - (float)Math.pow(1 - getSwingAmount(), 3);
|
2018-04-29 14:22:26 +02:00
|
|
|
|
|
|
|
float deltaX = MathHelper.sin(swing * PI);
|
2019-05-27 17:59:15 +02:00
|
|
|
float deltaZ = MathHelper.sin(getSwingAmount() * PI);
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
float deltaAim = deltaZ * (0.7F - head.pitch) * 0.75F;
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
arm.pitch -= deltaAim + deltaX * 1.2F;
|
2019-11-22 18:24:22 +01:00
|
|
|
arm.yaw += torso.yaw * 2;
|
2019-05-27 17:59:15 +02:00
|
|
|
arm.roll = -deltaZ * 0.4F;
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
|
2018-05-01 12:38:13 +02:00
|
|
|
/**
|
2019-06-24 11:25:39 +02:00
|
|
|
* Animates the arm's breathing animation when holding items.
|
2018-05-01 12:38:13 +02:00
|
|
|
*
|
2019-06-24 11:25:39 +02:00
|
|
|
* @param ticks Total whole and partial ticks since the entity's existence.
|
|
|
|
* Used in animations together with {@code swing} and {@code move}.
|
2018-05-01 12:38:13 +02:00
|
|
|
*/
|
2019-06-24 11:25:39 +02:00
|
|
|
protected void animateBreathing(float ticks) {
|
2018-05-01 12:38:13 +02:00
|
|
|
float cos = MathHelper.cos(ticks * 0.09F) * 0.05F + 0.05F;
|
|
|
|
float sin = MathHelper.sin(ticks * 0.067F) * 0.05F;
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-07-06 18:29:28 +02:00
|
|
|
boolean animateLeft =
|
|
|
|
(leftArmPose != ArmPose.EMPTY && (leftArmPose != rightArmPose || attributes.isLeftHanded))
|
|
|
|
&& rightArmPose != ArmPose.BLOCK;
|
|
|
|
boolean animateRight =
|
|
|
|
(rightArmPose != ArmPose.EMPTY && (leftArmPose != rightArmPose || !attributes.isLeftHanded))
|
|
|
|
&& leftArmPose != ArmPose.BLOCK;
|
|
|
|
|
|
|
|
if (animateRight) {
|
2019-05-27 17:59:15 +02:00
|
|
|
rightArm.roll += cos;
|
|
|
|
rightArm.pitch += sin;
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
|
2019-07-06 18:29:28 +02:00
|
|
|
if (animateLeft) {
|
2019-05-27 17:59:15 +02:00
|
|
|
leftArm.roll += cos;
|
|
|
|
leftArm.pitch += sin;
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void adjustBody(float rotateAngleX, float rotationPointY, float rotationPointZ) {
|
|
|
|
adjustBodyComponents(rotateAngleX, rotationPointY, rotationPointZ);
|
|
|
|
adjustNeck(rotateAngleX, rotationPointY, rotationPointZ);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected void adjustBodyComponents(float rotateAngleX, float rotationPointY, float rotationPointZ) {
|
2019-11-22 18:24:22 +01:00
|
|
|
torso.pitch = rotateAngleX;
|
|
|
|
torso.pivotY = rotationPointY;
|
|
|
|
torso.pivotZ = rotationPointZ;
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-05-27 17:59:15 +02:00
|
|
|
upperTorso.pitch = rotateAngleX;
|
2019-11-22 18:24:22 +01:00
|
|
|
upperTorso.pivotY = rotationPointY;
|
|
|
|
upperTorso.pivotZ = rotationPointZ;
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
|
2019-06-24 11:25:39 +02:00
|
|
|
private void adjustNeck(float rotateAngleX, float rotationPointY, float rotationPointZ) {
|
2019-11-22 18:24:22 +01:00
|
|
|
neck.setPivot(NECK_ROT_X + rotateAngleX, rotationPointY, rotationPointZ);
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
|
2018-07-01 17:33:30 +02:00
|
|
|
@Override
|
2018-07-08 12:21:57 +02:00
|
|
|
public float getRiderYOffset() {
|
2018-07-22 17:20:14 +02:00
|
|
|
|
2018-07-08 12:21:57 +02:00
|
|
|
if (isChild()) {
|
2018-07-22 17:20:14 +02:00
|
|
|
return 0.25F;
|
2018-07-08 12:21:57 +02:00
|
|
|
}
|
|
|
|
|
2018-07-28 19:01:12 +02:00
|
|
|
switch (getSize()) {
|
2018-07-08 12:21:57 +02:00
|
|
|
case NORMAL: return 0.4F;
|
2018-07-22 17:20:14 +02:00
|
|
|
case FOAL:
|
2018-07-08 12:21:57 +02:00
|
|
|
case TALL:
|
2018-10-20 19:09:58 +02:00
|
|
|
case BULKY:
|
2018-07-22 17:20:14 +02:00
|
|
|
default: return 0.25F;
|
2018-07-08 12:21:57 +02:00
|
|
|
}
|
2018-07-01 17:33:30 +02:00
|
|
|
}
|
|
|
|
|
2018-04-29 14:22:26 +02:00
|
|
|
@Override
|
2019-11-23 18:28:42 +01:00
|
|
|
public void render(MatrixStack stack, VertexConsumer vertices, int overlayUv, int lightUv, float red, float green, float blue, float alpha) {
|
|
|
|
renderStage(BodyPart.BODY, stack, vertices, overlayUv, lightUv, red, green, blue, alpha, this::renderBody);
|
|
|
|
renderStage(BodyPart.NECK, stack, vertices, overlayUv, lightUv, red, green, blue, alpha, this::renderNeck);
|
|
|
|
renderStage(BodyPart.HEAD, stack, vertices, overlayUv, lightUv, red, green, blue, alpha, this::renderHead);
|
|
|
|
renderStage(BodyPart.LEGS, stack, vertices, overlayUv, lightUv, red, green, blue, alpha, this::renderLegs);
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-06-24 11:25:39 +02:00
|
|
|
if (textureHeight == 64) {
|
2019-11-23 18:28:42 +01:00
|
|
|
renderStage(BodyPart.LEGS, stack, vertices, overlayUv, lightUv, red, green, blue, alpha, this::renderSleeves);
|
|
|
|
renderStage(BodyPart.BODY, stack, vertices, overlayUv, lightUv, red, green, blue, alpha, this::renderVest);
|
2019-06-24 11:25:39 +02:00
|
|
|
}
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-11-23 18:28:42 +01:00
|
|
|
renderStage(BodyPart.HEAD, stack, vertices, overlayUv, lightUv, red, green, blue, alpha, this::renderHelmet);
|
2019-06-24 11:25:39 +02:00
|
|
|
}
|
2018-08-24 13:54:24 +02:00
|
|
|
|
2019-11-23 18:28:42 +01:00
|
|
|
protected void renderStage(BodyPart part, MatrixStack stack, VertexConsumer vertices, int overlayUv, int lightUv, float red, float green, float blue, float alpha, RenderStage action) {
|
|
|
|
stack.push();
|
|
|
|
transform(part, stack);
|
|
|
|
action.accept(stack, vertices, overlayUv, lightUv, red, green, blue, alpha);
|
|
|
|
stack.pop();
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
|
2019-11-23 18:28:42 +01:00
|
|
|
protected void renderHead(MatrixStack stack, VertexConsumer vertices, int overlayUv, int lightUv, float red, float green, float blue, float alpha) {
|
|
|
|
head.render(stack, vertices, overlayUv, lightUv, red, green, blue, alpha);
|
2019-05-29 12:49:17 +02:00
|
|
|
}
|
|
|
|
|
2019-11-23 18:28:42 +01:00
|
|
|
protected void renderHelmet(MatrixStack stack, VertexConsumer vertices, int overlayUv, int lightUv, float red, float green, float blue, float alpha) {
|
|
|
|
helmet.render(stack, vertices, overlayUv, lightUv, red, green, blue, alpha);
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
|
2019-11-23 18:28:42 +01:00
|
|
|
protected void renderNeck(MatrixStack stack, VertexConsumer vertices, int overlayUv, int lightUv, float red, float green, float blue, float alpha) {
|
|
|
|
stack.scale(0.9F, 0.9F, 0.9F);
|
|
|
|
neck.render(stack, vertices, overlayUv, lightUv, red, green, blue, alpha);
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
|
2019-11-23 18:28:42 +01:00
|
|
|
protected void renderBody(MatrixStack stack, VertexConsumer vertices, int overlayUv, int lightUv, float red, float green, float blue, float alpha) {
|
|
|
|
torso.render(stack, vertices, overlayUv, lightUv, red, green, blue, alpha);
|
|
|
|
upperTorso.render(stack, vertices, overlayUv, lightUv, red, green, blue, alpha);
|
|
|
|
torso.rotate(stack);
|
|
|
|
tail.renderPart(stack, vertices, overlayUv, lightUv, red, green, blue, alpha, attributes.interpolatorId);
|
2019-06-24 11:25:39 +02:00
|
|
|
}
|
2019-06-20 04:12:44 +02:00
|
|
|
|
2019-11-23 18:28:42 +01:00
|
|
|
protected void renderVest(MatrixStack stack, VertexConsumer vertices, int overlayUv, int lightUv, float red, float green, float blue, float alpha) {
|
|
|
|
jacket.render(stack, vertices, overlayUv, lightUv, red, green, blue, alpha);
|
|
|
|
upperTorsoOverlay.render(stack, vertices, overlayUv, lightUv, red, green, blue, alpha);
|
2018-04-29 14:22:26 +02:00
|
|
|
}
|
|
|
|
|
2019-11-23 18:28:42 +01:00
|
|
|
protected void renderLegs(MatrixStack stack, VertexConsumer vertices, int overlayUv, int lightUv, float red, float green, float blue, float alpha) {
|
2019-05-29 12:49:17 +02:00
|
|
|
if (!isSneaking) {
|
2019-11-23 18:28:42 +01:00
|
|
|
torso.rotate(stack);
|
2019-05-29 12:49:17 +02:00
|
|
|
}
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-11-23 18:28:42 +01:00
|
|
|
leftArm.render(stack, vertices, overlayUv, lightUv, red, green, blue, alpha);
|
|
|
|
rightArm.render(stack, vertices, overlayUv, lightUv, red, green, blue, alpha);
|
|
|
|
leftLeg.render(stack, vertices, overlayUv, lightUv, red, green, blue, alpha);
|
|
|
|
rightLeg.render(stack, vertices, overlayUv, lightUv, red, green, blue, alpha);
|
2019-05-29 12:49:17 +02:00
|
|
|
}
|
2018-04-29 14:22:26 +02:00
|
|
|
|
2019-11-23 18:28:42 +01:00
|
|
|
protected void renderSleeves(MatrixStack stack, VertexConsumer vertices, int overlayUv, int lightUv, float red, float green, float blue, float alpha) {
|
|
|
|
leftSleeve.render(stack, vertices, overlayUv, lightUv, red, green, blue, alpha);
|
|
|
|
rightSleeve.render(stack, vertices, overlayUv, lightUv, red, green, blue, alpha);
|
|
|
|
leftPantLeg.render(stack, vertices, overlayUv, lightUv, red, green, blue, alpha);
|
|
|
|
rightPantLeg.render(stack, vertices, overlayUv, lightUv, red, green, blue, alpha);
|
2018-04-25 16:40:47 +02:00
|
|
|
}
|
2015-12-14 09:29:10 +01:00
|
|
|
|
2019-08-18 15:53:15 +02:00
|
|
|
@Override
|
|
|
|
public void setVisible(boolean visible) {
|
|
|
|
super.setVisible(visible);
|
|
|
|
|
|
|
|
upperTorso.visible = visible;
|
|
|
|
upperTorsoOverlay.visible = visible;
|
|
|
|
|
|
|
|
neck.visible = visible;
|
|
|
|
|
|
|
|
tail.setVisible(visible);
|
|
|
|
}
|
|
|
|
|
2018-04-29 11:56:26 +02:00
|
|
|
@Override
|
2019-11-23 18:28:42 +01:00
|
|
|
public void transform(BodyPart part, MatrixStack stack) {
|
2019-06-24 11:25:39 +02:00
|
|
|
if (attributes.isSleeping) {
|
2019-11-23 18:28:42 +01:00
|
|
|
stack.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(90));
|
|
|
|
stack.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(180));
|
2015-12-14 09:29:10 +01:00
|
|
|
}
|
|
|
|
|
2018-04-29 20:18:57 +02:00
|
|
|
if (part == BodyPart.HEAD) {
|
2019-11-23 18:28:42 +01:00
|
|
|
stack.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(attributes.motionPitch));
|
2018-04-29 20:18:57 +02:00
|
|
|
}
|
|
|
|
|
2019-03-23 20:49:34 +01:00
|
|
|
PonyTransformation.forSize(getSize()).transform(this, part);
|
2015-12-14 09:29:10 +01:00
|
|
|
}
|
2019-11-23 18:28:42 +01:00
|
|
|
|
|
|
|
interface RenderStage {
|
|
|
|
void accept(MatrixStack stack, VertexConsumer vertices, int overlayUv, int lightUv, float red, float green, float blue, float alpha);
|
|
|
|
}
|
2015-08-02 00:36:33 +02:00
|
|
|
}
|