diff --git a/src/main/java/com/minelittlepony/transform/MotionCompositor.java b/src/main/java/com/minelittlepony/transform/MotionCompositor.java new file mode 100644 index 00000000..3d29aeea --- /dev/null +++ b/src/main/java/com/minelittlepony/transform/MotionCompositor.java @@ -0,0 +1,52 @@ +package com.minelittlepony.transform; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.math.MathHelper; + +import com.minelittlepony.util.math.MathUtil; + +/** + * Calculates roll and incline for a player based on their motion vectors. + * + * @author Polyakovich - Big thank you to this dude and his meta-physics friend for working this all out. + */ +public abstract class MotionCompositor { + + protected double calculateRoll(EntityPlayer player, double motionX, double motionY, double motionZ) { + + // since model roll should probably be calculated from model rotation rather than entity rotation... + double roll = MathUtil.sensibleAngle(player.prevRenderYawOffset - player.renderYawOffset); + double horMotion = Math.sqrt(motionX * motionX + motionZ * motionZ); + float modelYaw = MathUtil.sensibleAngle(player.renderYawOffset); + + // detecting that we're flying backwards and roll must be inverted + if (Math.abs(MathUtil.sensibleAngle((float) Math.toDegrees(Math.atan2(motionX, motionZ)) + modelYaw)) > 90) { + roll *= -1; + } + + // ayyy magic numbers (after 5 - an approximation of nice looking coefficients calculated by hand) + + // roll might be zero, in which case Math.pow produces +Infinity. Anything x Infinity = NaN. + double pow = roll != 0 ? Math.pow(Math.abs(roll), -0.191) : 0; + + roll *= horMotion * 5 * (3.6884f * pow); + + assert !Float.isNaN((float)roll); + + return MathHelper.clamp(roll, -54, 54); + } + + protected double calculateIncline(EntityPlayer player, double motionX, double motionY, double motionZ) { + double dist = Math.sqrt(motionX * motionX + motionZ * motionZ); + double angle = Math.atan2(motionY, dist); + + if (!player.capabilities.isFlying) { + angle /= 2; + } + + angle = MathUtil.clampLimit(angle, Math.PI / 3); + + return Math.toDegrees(angle); + } + +} diff --git a/src/main/java/com/minelittlepony/transform/PostureFlight.java b/src/main/java/com/minelittlepony/transform/PostureFlight.java index 761a0dd8..145b20e8 100644 --- a/src/main/java/com/minelittlepony/transform/PostureFlight.java +++ b/src/main/java/com/minelittlepony/transform/PostureFlight.java @@ -1,56 +1,17 @@ package com.minelittlepony.transform; import com.minelittlepony.model.AbstractPonyModel; -import com.minelittlepony.util.math.MathUtil; import net.minecraft.client.entity.AbstractClientPlayer; import net.minecraft.client.renderer.GlStateManager; import net.minecraft.entity.EntityLivingBase; -import net.minecraft.util.math.MathHelper; -public class PostureFlight implements PonyPosture { +public class PostureFlight extends MotionCompositor implements PonyPosture { @Override public boolean applies(EntityLivingBase entity) { return entity instanceof AbstractClientPlayer; } - protected double calculateRoll(AbstractClientPlayer player, double motionX, double motionY, double motionZ) { - - // since model roll should probably be calculated from model rotation rather than entity rotation... - double roll = MathUtil.sensibleAngle(player.prevRenderYawOffset - player.renderYawOffset); - double horMotion = Math.sqrt(motionX * motionX + motionZ * motionZ); - float modelYaw = MathUtil.sensibleAngle(player.renderYawOffset); - - // detecting that we're flying backwards and roll must be inverted - if (Math.abs(MathUtil.sensibleAngle((float) Math.toDegrees(Math.atan2(motionX, motionZ)) + modelYaw)) > 90) { - roll *= -1; - } - - // ayyy magic numbers (after 5 - an approximation of nice looking coefficients calculated by hand) - - // roll might be zero, in which case Math.pow produces +Infinity. Anything x Infinity = NaN. - double pow = roll != 0 ? Math.pow(Math.abs(roll), -0.191) : 0; - - roll *= horMotion * 5 * (3.6884f * pow); - - assert !Float.isNaN((float)roll); - - return MathHelper.clamp(roll, -54, 54); - } - - protected double calculateIncline(AbstractClientPlayer player, double motionX, double motionY, double motionZ) { - double dist = Math.sqrt(motionX * motionX + motionZ * motionZ); - double angle = Math.atan2(motionY, dist); - - if (!player.capabilities.isFlying) { - angle /= 2; - } - - angle = MathUtil.clampLimit(angle, Math.PI / 3); - - return Math.toDegrees(angle); - } - @Override public void transform(AbstractPonyModel model, AbstractClientPlayer player, double motionX, double motionY, double motionZ, float pitch, float yaw, float ticks) { model.motionPitch = (float) calculateIncline(player, motionX, motionY, motionZ); diff --git a/src/main/java/com/minelittlepony/transform/PostureSwimming.java b/src/main/java/com/minelittlepony/transform/PostureSwimming.java index c62ccc97..28b7d6b2 100644 --- a/src/main/java/com/minelittlepony/transform/PostureSwimming.java +++ b/src/main/java/com/minelittlepony/transform/PostureSwimming.java @@ -1,11 +1,11 @@ package com.minelittlepony.transform; -import net.minecraft.client.entity.AbstractClientPlayer; +import net.minecraft.entity.player.EntityPlayer; public class PostureSwimming extends PostureFlight { @Override - protected double calculateRoll(AbstractClientPlayer player, double motionX, double motionY, double motionZ) { + protected double calculateRoll(EntityPlayer player, double motionX, double motionY, double motionZ) { motionX *= 2; motionZ *= 2; @@ -14,7 +14,7 @@ public class PostureSwimming extends PostureFlight { } @Override - protected double calculateIncline(AbstractClientPlayer player, double motionX, double motionY, double motionZ) { + protected double calculateIncline(EntityPlayer player, double motionX, double motionY, double motionZ) { return super.calculateIncline(player, motionX, motionY, motionZ); } }