Fix spectator hand jumping when rotating across 0 yaw boundary, take 2
The `yaw` value of non-client-players is constraint to [0; 360), so when that boundary is crossed, the `renderYaw` starts interpolating to its goal the incorrect way round (instead of crossing the 360 boundary as well). To fix that, we now add the difference between the current `renderYaw` and the desired one, modulo 360 (but with range (-180; 180]), to the current `renderYaw`. That way we always take the short way round. Additionally, because for rendering MC looks at the difference without modulo, afterwards (and when a new `yaw` is set) we wrap the result around such that the actual difference is always less than 180 and therefore rendered as intended.
This commit is contained in:
@@ -248,6 +248,7 @@ public class CameraEntity
|
||||
this.lastRenderX = to.lastRenderX;
|
||||
this.lastRenderY = to.lastRenderY + yOffset;
|
||||
this.lastRenderZ = to.lastRenderZ;
|
||||
this.wrapArmYaw();
|
||||
updateBoundingBox();
|
||||
}
|
||||
|
||||
@@ -703,7 +704,35 @@ public class CameraEntity
|
||||
this.lastRenderYaw = this.renderYaw;
|
||||
this.lastRenderPitch = this.renderPitch;
|
||||
this.renderPitch = this.renderPitch + (this.pitch - this.renderPitch) * 0.5f;
|
||||
this.renderYaw = this.renderYaw + (this.yaw - this.renderYaw) * 0.5f;
|
||||
this.renderYaw = this.renderYaw + wrapDegrees(this.yaw - this.renderYaw) * 0.5f;
|
||||
this.wrapArmYaw();
|
||||
}
|
||||
|
||||
/**
|
||||
* Minecraft renders the arm offset based on the difference between {@link #yaw} and {@link #renderYaw}. It does not
|
||||
* wrap around the difference though, so if {@link #yaw} just wrapped around from 350 to 10 but {@link #renderYaw}
|
||||
* is still at 355, then the difference will be inappropriately large. To fix this, we always wrap the
|
||||
* {@link #renderYaw} such that it is no more than 180 degrees away from {@link #yaw}, even if that requires going
|
||||
* outside the normal range.
|
||||
*/
|
||||
private void wrapArmYaw() {
|
||||
this.renderYaw = wrapDegreesTo(this.renderYaw, this.yaw);
|
||||
this.lastRenderYaw = wrapDegreesTo(this.lastRenderYaw, this.renderYaw);
|
||||
}
|
||||
|
||||
private static float wrapDegreesTo(float value, float towardsValue) {
|
||||
while (towardsValue - value < -180) {
|
||||
value -= 360;
|
||||
}
|
||||
while (towardsValue - value >= 180) {
|
||||
value += 360;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private static float wrapDegrees(float value) {
|
||||
value %= 360;
|
||||
return wrapDegreesTo(value, 0);
|
||||
}
|
||||
|
||||
public boolean canSpectate(Entity e) {
|
||||
|
||||
Reference in New Issue
Block a user