From e7aa519846c898006e457ac3c8b8e46271c39238 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Wed, 25 Jan 2017 22:30:56 +1100 Subject: [PATCH] more concise interpolation, fix last commit --- .../2D/Screens/Menu/LoadLevelScreen.cs | 2 +- ClassicalSharp/Blocks/AutoRotate.cs | 6 +- ClassicalSharp/ClassicalSharp.csproj | 1 + .../Entities/Components/IInterpComponent.cs | 182 ++++++++++++++++++ .../Entities/Components/InputComponent.cs | 6 +- .../Components/LocalInterpComponent.cs | 81 +------- .../Entities/Components/NetInterpComponent.cs | 92 +-------- .../Entities/Components/SoundComponent.cs | 4 +- ClassicalSharp/Entities/LocalPlayer.cs | 8 +- ClassicalSharp/Entities/Mobs/MobEntity.cs | 6 +- ClassicalSharp/Entities/Model/BlockModel.cs | 6 +- ClassicalSharp/Entities/NetPlayer.cs | 12 +- ClassicalSharp/Game/PickingHandler.cs | 4 +- ClassicalSharp/Map/Formats/MapCw.Exporter.cs | 4 +- ClassicalSharp/Map/Formats/MapCw.Importer.cs | 4 +- .../Map/Formats/MapFcm3.Importer.cs | 4 +- ClassicalSharp/Map/Formats/MapLvl.Importer.cs | 4 +- ClassicalSharp/Network/IServerConnection.cs | 2 +- .../Network/NetworkProcessor.Helpers.cs | 8 +- ClassicalSharp/Rendering/ChunkUpdater.cs | 16 +- ClassicalSharp/Utils/Camera.cs | 18 +- 21 files changed, 243 insertions(+), 227 deletions(-) create mode 100644 ClassicalSharp/Entities/Components/IInterpComponent.cs diff --git a/ClassicalSharp/2D/Screens/Menu/LoadLevelScreen.cs b/ClassicalSharp/2D/Screens/Menu/LoadLevelScreen.cs index 83e89e1ef..d915b7792 100644 --- a/ClassicalSharp/2D/Screens/Menu/LoadLevelScreen.cs +++ b/ClassicalSharp/2D/Screens/Menu/LoadLevelScreen.cs @@ -73,7 +73,7 @@ namespace ClassicalSharp.Gui.Screens { game.Server.RetrieveTexturePack(game.World.TextureUrl); LocalPlayer p = game.LocalPlayer; - LocationUpdate update = LocationUpdate.MakePosAndOri(p.Spawn, p.SpawnYaw, p.SpawnPitch, false); + LocationUpdate update = LocationUpdate.MakePosAndOri(p.Spawn, p.SpawnRotY, p.SpawnHeadX, false); p.SetLocation(update, false); } } catch (Exception ex) { diff --git a/ClassicalSharp/Blocks/AutoRotate.cs b/ClassicalSharp/Blocks/AutoRotate.cs index 2506a4058..c300cafc0 100644 --- a/ClassicalSharp/Blocks/AutoRotate.cs +++ b/ClassicalSharp/Blocks/AutoRotate.cs @@ -52,10 +52,10 @@ namespace ClassicalSharp { static byte RotateOther(Game game, byte block, string name, Vector3 offset) { // Fence type blocks if (game.BlockInfo.FindID(name + "-UD") == -1) { - float yaw = game.LocalPlayer.HeadY; - if (yaw < 0) yaw += 360; + float headY = game.LocalPlayer.HeadY; + if (headY < 0) headY += 360; - if (yaw < 45 || (yaw >= 135 && yaw < 225) || yaw > 315) + if (headY < 45 || (headY >= 135 && headY < 225) || headY > 315) return Find(game, block, name + "-WE"); return Find(game, block, name + "-NS"); } diff --git a/ClassicalSharp/ClassicalSharp.csproj b/ClassicalSharp/ClassicalSharp.csproj index 86cb0a31f..21dc6ac75 100644 --- a/ClassicalSharp/ClassicalSharp.csproj +++ b/ClassicalSharp/ClassicalSharp.csproj @@ -150,6 +150,7 @@ + diff --git a/ClassicalSharp/Entities/Components/IInterpComponent.cs b/ClassicalSharp/Entities/Components/IInterpComponent.cs new file mode 100644 index 000000000..fc24fa3b0 --- /dev/null +++ b/ClassicalSharp/Entities/Components/IInterpComponent.cs @@ -0,0 +1,182 @@ +// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3 +using System; +using ClassicalSharp.Renderers; +using OpenTK; + +namespace ClassicalSharp.Entities { + + /// Entity component that performs interpolation of position and orientation over time. + public abstract class IInterpComponent { + + public abstract void SetLocation(LocationUpdate update, bool interpolate); + + public virtual void AdvanceState() { + prevRotY = nextRotY; + if (rotYStateCount == 0) return; + + nextRotY = rotYStates[0]; + RemoveOldest(rotYStates, ref rotYStateCount); + } + + + public State prev, next; + public float prevRotY, nextRotY; + + public struct State { + public Vector3 Pos; + public float HeadX, HeadY, RotX, RotZ; + + public State(Vector3 pos, float headX, float headY, float rotX, float rotZ) { + this.Pos = pos; + this.HeadX = headX; this.HeadY = headY; + this.RotX = rotX; this.RotZ = rotZ; + } + } + + public void LerpAngles(float t) { + entity.HeadX = Utils.LerpAngle(prev.HeadX, next.HeadX, t); + entity.HeadY = Utils.LerpAngle(prev.HeadY, next.HeadY, t); + entity.RotX = Utils.LerpAngle(prev.RotX, next.RotX, t); + entity.RotY = Utils.LerpAngle(prevRotY, nextRotY, t); + entity.RotZ = Utils.LerpAngle(prev.RotZ, next.RotZ, t); + } + + + protected Entity entity; + protected int rotYStateCount; + protected float[] rotYStates = new float[15]; + + protected void AddRotY(float state) { + if (rotYStateCount == rotYStates.Length) + RemoveOldest(rotYStates, ref rotYStateCount); + rotYStates[rotYStateCount++] = state; + } + + protected void RemoveOldest(T[] array, ref int count) { + for (int i = 0; i < array.Length - 1; i++) + array[i] = array[i + 1]; + count--; + } + } + + + public sealed class NetInterpComponent : IInterpComponent { + + public NetInterpComponent(Game game, Entity entity) { + this.entity = entity; + } + + // Last known position and orientation sent by the server. + internal Vector3 curPos; + internal float curRotX, curRotZ, curHeadX, curHeadY; + + public override void SetLocation(LocationUpdate update, bool interpolate) { + Vector3 lastPos = curPos; + float lastRotX = curRotX, lastRotZ = curRotZ; + float lastHeadX = curHeadX, lastHeadY = curHeadY; + + if (update.IncludesPosition) { + curPos = update.RelativePosition ? curPos + update.Pos : update.Pos; + } + curRotX = Next(update.RotX, curRotX); + curRotZ = Next(update.RotZ, curRotZ); + curHeadX = Next(update.HeadX, curHeadX); + curHeadY = Next(update.RotY, curHeadY); + + if (!interpolate) { + stateCount = 0; + next = prev = new State(curPos, curHeadX, curHeadY, curRotX, curRotZ); + rotYStateCount = 0; + nextRotY = prevRotY = curHeadY; + } else { + // Smoother interpolation by also adding midpoint. + Vector3 midPos = Vector3.Lerp(lastPos, curPos, 0.5f); + float midRotX = Utils.LerpAngle(lastRotX, curRotX, 0.5f); + float midRotZ = Utils.LerpAngle(lastRotZ, curRotZ, 0.5f); + float midHeadX = Utils.LerpAngle(lastHeadX, curHeadX, 0.5f); + float midHeadY = Utils.LerpAngle(lastHeadY, curHeadY, 0.5f); + + AddState(new State(midPos, midHeadX, midHeadY, midRotX, midRotZ)); + AddState(new State(curPos, curHeadX, curHeadY, curRotX, curRotZ)); + for (int i = 0; i < 3; i++) + AddRotY(Utils.LerpAngle(lastHeadY, curHeadY, (i + 1) / 3f)); + } + } + + public override void AdvanceState() { + prev = next; prevRotY = nextRotY; + + if (stateCount > 0) { + next = states[0]; + RemoveOldest(states, ref stateCount); + } + base.AdvanceState(); + } + + State[] states = new State[10]; + int stateCount; + + static float Next(float next, float cur) { + if (float.IsNaN(next)) return cur; + return next; + } + + void AddState(State state) { + if (stateCount == states.Length) + RemoveOldest(states, ref stateCount); + states[stateCount++] = state; + } + } + + + /// Entity component that performs interpolation of position and orientation over time. + public sealed class LocalInterpComponent : IInterpComponent { + + public LocalInterpComponent(Game game, Entity entity) { + this.entity = entity; + } + + public override void SetLocation(LocationUpdate update, bool interpolate) { + if (update.IncludesPosition) { + next.Pos = update.RelativePosition ? next.Pos + update.Pos : update.Pos; + double blockOffset = next.Pos.Y - Math.Floor(next.Pos.Y); + if (blockOffset < Entity.Adjustment) + next.Pos.Y += Entity.Adjustment; + + if (!interpolate) { + prev.Pos = entity.Position = next.Pos; + } + } + + next.RotX = Next(update.RotX, next.RotX, ref prev.RotX, interpolate); + next.RotZ = Next(update.RotZ, next.RotZ, ref prev.RotZ, interpolate); + next.HeadX = Next(update.HeadX, next.HeadX, ref prev.HeadX, interpolate); + next.HeadY = Next(update.RotY, next.HeadY, ref prev.HeadY, interpolate); + + if (!float.IsNaN(update.RotY)) { + // Body Y rotation lags slightly behind + if (!interpolate) { + nextRotY = update.RotY; entity.RotY = update.RotY; + rotYStateCount = 0; + } else { + for (int i = 0; i < 3; i++) + AddRotY(Utils.LerpAngle(prev.HeadY, next.HeadY, (i + 1) / 3f)); + nextRotY = rotYStates[0]; + } + } + LerpAngles(0); + } + + public override void AdvanceState() { + prev = next; entity.Position = next.Pos; + base.AdvanceState(); + } + + static float Next(float next, float cur, ref float last, bool interpolate) { + if (float.IsNaN(next)) return cur; + + if (!interpolate) last = next; + return next; + } + } +} \ No newline at end of file diff --git a/ClassicalSharp/Entities/Components/InputComponent.cs b/ClassicalSharp/Entities/Components/InputComponent.cs index 2eb6e6513..c00a900e4 100644 --- a/ClassicalSharp/Entities/Components/InputComponent.cs +++ b/ClassicalSharp/Entities/Components/InputComponent.cs @@ -29,8 +29,8 @@ namespace ClassicalSharp.Entities { p.Spawn = entity.Position; p.Spawn.X = Utils.Floor(p.Spawn.X) + 0.5f; p.Spawn.Z = Utils.Floor(p.Spawn.Z) + 0.5f; - p.SpawnYaw = entity.RotY; - p.SpawnPitch = entity.HeadX; + p.SpawnRotY = entity.RotY; + p.SpawnHeadX = entity.HeadX; DoRespawn(); } else if (key == keys[KeyBind.Fly] && Hacks.CanFly && Hacks.Enabled) { Hacks.Flying = !Hacks.Flying; @@ -58,7 +58,7 @@ namespace ClassicalSharp.Entities { FindHighestFree(ref spawn); spawn.Y += 2/16f; - LocationUpdate update = LocationUpdate.MakePosAndOri(spawn, p.SpawnYaw, p.SpawnPitch, false); + LocationUpdate update = LocationUpdate.MakePosAndOri(spawn, p.SpawnRotY, p.SpawnHeadX, false); entity.SetLocation(update, false); entity.Velocity = Vector3.Zero; diff --git a/ClassicalSharp/Entities/Components/LocalInterpComponent.cs b/ClassicalSharp/Entities/Components/LocalInterpComponent.cs index 4d540873e..07d06e955 100644 --- a/ClassicalSharp/Entities/Components/LocalInterpComponent.cs +++ b/ClassicalSharp/Entities/Components/LocalInterpComponent.cs @@ -5,84 +5,5 @@ using OpenTK; namespace ClassicalSharp.Entities { - /// Entity component that performs interpolation of position and model head yaw over time. - public sealed class LocalInterpComponent { - - Entity entity; - public LocalInterpComponent(Game game, Entity entity) { - this.entity = entity; - } - - internal Vector3 lastPos, nextPos; - internal float lastHeadY, lastHeadX, lastRotX, lastRotY, lastRotZ; - internal float nextHeadY, nextHeadX, nextRotX, nextRotY, nextRotZ; - int rotYStateCount; - float[] rotYStates = new float[15]; - - public void SetLocation(LocationUpdate update, bool interpolate) { - if (update.IncludesPosition) { - nextPos = update.RelativePosition ? nextPos + update.Pos : update.Pos; - double blockOffset = nextPos.Y - Math.Floor(nextPos.Y); - if (blockOffset < Entity.Adjustment) - nextPos.Y += Entity.Adjustment; - if (!interpolate) { - lastPos = entity.Position = nextPos; - } - } - - nextRotX = Next(update.RotX, nextRotX, ref lastRotX, interpolate); - nextRotZ = Next(update.RotZ, nextRotZ, ref lastRotZ, interpolate); - nextHeadX = Next(update.HeadX, nextHeadX, ref lastHeadX, interpolate); - - if (float.IsNaN(update.RotY)) return; - nextHeadY = update.RotY; - - if (!interpolate) { - lastHeadY = update.RotY; entity.HeadY = update.RotY; entity.RotY = update.RotY; - rotYStateCount = 0; - } else { - for (int i = 0; i < 3; i++) - AddRotY(Utils.LerpAngle(lastHeadY, nextHeadY, (i + 1) / 3f)); - } - } - - public void AdvanceState() { - lastPos = entity.Position = nextPos; - lastHeadY = nextHeadY; lastHeadX = nextHeadX; - lastRotX = nextRotX; lastRotY = nextRotY; lastRotZ = nextRotZ; - - if (rotYStateCount > 0) { - nextRotY = rotYStates[0]; - RemoveOldest(rotYStates, ref rotYStateCount); - } - } - - public void LerpAngles(float t) { - entity.HeadX = Utils.LerpAngle(lastHeadX, nextHeadX, t); - entity.HeadY = Utils.LerpAngle(lastHeadY, nextHeadY, t); - entity.RotX = Utils.LerpAngle(lastRotX, nextRotX, t); - entity.RotY = Utils.LerpAngle(lastRotY, nextRotY, t); - entity.RotZ = Utils.LerpAngle(lastRotZ, nextRotZ, t); - } - - - static float Next(float next, float cur, ref float last, bool interpolate) { - if (float.IsNaN(next)) return cur; - - if (!interpolate) last = next; - return next; - } - - void AddRotY(float state) { - if (rotYStateCount == rotYStates.Length) - RemoveOldest(rotYStates, ref rotYStateCount); - rotYStates[rotYStateCount++] = state; - } - - void RemoveOldest(T[] array, ref int count) { - for (int i = 0; i < array.Length - 1; i++) - array[i] = array[i + 1]; - count--; - } - } + } \ No newline at end of file diff --git a/ClassicalSharp/Entities/Components/NetInterpComponent.cs b/ClassicalSharp/Entities/Components/NetInterpComponent.cs index d6cfd0548..a38bca2d3 100644 --- a/ClassicalSharp/Entities/Components/NetInterpComponent.cs +++ b/ClassicalSharp/Entities/Components/NetInterpComponent.cs @@ -5,94 +5,6 @@ using OpenTK; namespace ClassicalSharp.Entities { - /// Entity component that performs interpolation of position and model head yaw over time. - public sealed class NetInterpComponent { - - Entity entity; - public NetInterpComponent(Game game, Entity entity) { - this.entity = entity; - } - - // Last known position and orientation sent by the server. - internal Vector3 serverPos; - internal float serverRotY, serverHeadX; - - public void SetLocation(LocationUpdate update, bool interpolate) { - /*Vector3 lastPos = serverPos; - float lastRotY = serverRotY, lastHeadX = serverHeadX; - if (update.IncludesPosition) { - serverPos = update.RelativePosition ? serverPos + update.Pos : update.Pos; - } - if (update.IncludesOrientation) { - serverRotY = update.RotY; serverHeadX = update.HeadX; - } - - if (!interpolate) { - stateCount = 0; - newState = oldState = new State(entity.tickCount, serverPos, serverRotY, serverHeadX); - rotYStateCount = 0; - newYaw = oldYaw = serverRotY; - } else { - // Smoother interpolation by also adding midpoint. - Vector3 midPos = Vector3.Lerp(lastPos, serverPos, 0.5f); - float midYaw = Utils.LerpAngle(lastRotY, serverRotY, 0.5f); - float midPitch = Utils.LerpAngle(lastHeadX, serverHeadX, 0.5f); - AddState(new State(entity.tickCount, midPos, midYaw, midPitch)); - AddState(new State(entity.tickCount, serverPos, serverRotY, serverHeadX)); - for (int i = 0; i < 3; i++) - AddYaw(Utils.LerpAngle(lastRotY, serverRotY, (i + 1) / 3f)); - }*/ - } - - public struct State { - public int tick; - public Vector3 pos; - public float headYaw, pitch; - - public State(int tick, Vector3 pos, float headYaw, float pitch) { - this.tick = tick; - this.pos = pos; - this.headYaw = headYaw; - this.pitch = pitch; - } - } - - State[] states = new State[10]; - float[] yawStates = new float[15]; - public State newState, oldState; - public float newYaw, oldYaw; - int stateCount, rotYStateCount; - - void AddState(State state) { - if (stateCount == states.Length) - RemoveOldest(states, ref stateCount); - states[stateCount++] = state; - } - - void AddYaw(float state) { - if (rotYStateCount == yawStates.Length) - RemoveOldest(yawStates, ref rotYStateCount); - yawStates[rotYStateCount++] = state; - } - - public void UpdateCurrentState() { - oldState = newState; - oldYaw = newYaw; - if (stateCount > 0) { - //if (states[0].tick > tickCount - 2) return; // 100 ms delay - newState = states[0]; - RemoveOldest(states, ref stateCount); - } - if (rotYStateCount > 0) { - newYaw = yawStates[0]; - RemoveOldest(yawStates, ref rotYStateCount); - } - } - - void RemoveOldest(T[] array, ref int count) { - for (int i = 0; i < array.Length - 1; i++) - array[i] = array[i + 1]; - count--; - } - } + /// Entity component that performs interpolation of position and orientation over time. + } \ No newline at end of file diff --git a/ClassicalSharp/Entities/Components/SoundComponent.cs b/ClassicalSharp/Entities/Components/SoundComponent.cs index 5df8d7c12..25463f386 100644 --- a/ClassicalSharp/Entities/Components/SoundComponent.cs +++ b/ClassicalSharp/Entities/Components/SoundComponent.cs @@ -22,7 +22,7 @@ namespace ClassicalSharp.Entities { Vector3 lastSoundPos; public void Tick(bool wasOnGround) { - Vector3 soundPos = p.interp.nextPos; + Vector3 soundPos = p.interp.next.Pos; GetSound(); if (!anyNonAir) soundPos = Utils.MaxPos(); @@ -55,7 +55,7 @@ namespace ClassicalSharp.Entities { bool anyNonAir = false; SoundType sndType = SoundType.None; void GetSound() { - Vector3 pos = p.interp.nextPos; + Vector3 pos = p.interp.next.Pos; AABB bounds = p.Bounds; sndType = SoundType.None; anyNonAir = false; diff --git a/ClassicalSharp/Entities/LocalPlayer.cs b/ClassicalSharp/Entities/LocalPlayer.cs index 402287292..b1f416fda 100644 --- a/ClassicalSharp/Entities/LocalPlayer.cs +++ b/ClassicalSharp/Entities/LocalPlayer.cs @@ -12,7 +12,7 @@ namespace ClassicalSharp.Entities { /// Position the player's position is set to when the 'respawn' key binding is pressed. public Vector3 Spawn; - public float SpawnYaw, SpawnPitch; + public float SpawnRotY, SpawnHeadX; /// The distance (in blocks) that players are allowed to /// reach to and interact/modify blocks in. @@ -63,8 +63,8 @@ namespace ClassicalSharp.Entities { physics.UpdateVelocityState(xMoving, zMoving); physics.PhysicsTick(xMoving, zMoving); - interp.nextPos = Position; Position = interp.lastPos; - anim.UpdateAnimState(interp.lastPos, interp.nextPos, delta); + interp.next.Pos = Position; Position = interp.prev.Pos; + anim.UpdateAnimState(interp.prev.Pos, interp.next.Pos, delta); CheckSkin(); sound.Tick(wasOnGround); @@ -120,7 +120,7 @@ namespace ClassicalSharp.Entities { /// Linearly interpolates position and rotation between the previous and next state. public void SetInterpPosition(float t) { if (!Hacks.WOMStyleHacks || !Hacks.Noclip) - Position = Vector3.Lerp(interp.lastPos, interp.nextPos, t); + Position = Vector3.Lerp(interp.prev.Pos, interp.next.Pos, t); interp.LerpAngles(t); } diff --git a/ClassicalSharp/Entities/Mobs/MobEntity.cs b/ClassicalSharp/Entities/Mobs/MobEntity.cs index 4eb63571b..8db1c7227 100644 --- a/ClassicalSharp/Entities/Mobs/MobEntity.cs +++ b/ClassicalSharp/Entities/Mobs/MobEntity.cs @@ -34,8 +34,8 @@ namespace ClassicalSharp.Entities.Mobs { bool wasOnGround = onGround; physics.UpdateVelocityState(xMoving, zMoving); physics.PhysicsTick(xMoving, zMoving); - interp.nextPos = Position; Position = interp.lastPos; - anim.UpdateAnimState(interp.lastPos, interp.nextPos, delta); + interp.next.Pos = Position; Position = interp.prev.Pos; + anim.UpdateAnimState(interp.prev.Pos, interp.next.Pos, delta); } public override void SetLocation(LocationUpdate update, bool interpolate) { @@ -43,7 +43,7 @@ namespace ClassicalSharp.Entities.Mobs { } public override void RenderModel(double deltaTime, float t) { - Position = Vector3.Lerp(interp.lastPos, interp.nextPos, t); + Position = Vector3.Lerp(interp.prev.Pos, interp.next.Pos, t); interp.LerpAngles(t); anim.GetCurrentAnimState(t); Model.Render(this); diff --git a/ClassicalSharp/Entities/Model/BlockModel.cs b/ClassicalSharp/Entities/Model/BlockModel.cs index aac35a797..2cdbd455d 100644 --- a/ClassicalSharp/Entities/Model/BlockModel.cs +++ b/ClassicalSharp/Entities/Model/BlockModel.cs @@ -86,11 +86,11 @@ namespace ClassicalSharp.Model { col = game.World.IsValidPos(P) ? game.Lighting.LightCol(P.X, P.Y, P.Z) : game.Lighting.Outside; // Adjust pitch so angle when looking straight down is 0. - float adjPitch = realP.HeadX - 90; - if (adjPitch < 0) adjPitch += 360; + float adjHeadX = realP.HeadX - 90; + if (adjHeadX < 0) adjHeadX += 360; // Adjust colour so held block is brighter when looking straght up - float t = Math.Abs(adjPitch - 180) / 180; + float t = Math.Abs(adjHeadX - 180) / 180; float colScale = Utils.Lerp(0.9f, 0.7f, t); col = FastColour.ScalePacked(col, colScale); block = ((FakePlayer)p).Block; diff --git a/ClassicalSharp/Entities/NetPlayer.cs b/ClassicalSharp/Entities/NetPlayer.cs index 1731bd44f..ecf6c2ac7 100644 --- a/ClassicalSharp/Entities/NetPlayer.cs +++ b/ClassicalSharp/Entities/NetPlayer.cs @@ -21,16 +21,16 @@ namespace ClassicalSharp.Entities { public override void Tick(double delta) { CheckSkin(); tickCount++; - interp.UpdateCurrentState(); - anim.UpdateAnimState(interp.oldState.pos, interp.newState.pos, delta); + interp.AdvanceState(); + anim.UpdateAnimState(interp.prev.Pos, interp.next.Pos, delta); } bool shouldRender = false; public override void RenderModel(double deltaTime, float t) { - Position = Vector3.Lerp(interp.oldState.pos, interp.newState.pos, t); - HeadY = Utils.LerpAngle(interp.oldState.headYaw, interp.newState.headYaw, t); - RotY = Utils.LerpAngle(interp.oldYaw, interp.newYaw, t); - HeadX = Utils.LerpAngle(interp.oldState.pitch, interp.newState.pitch, t); + Position = Vector3.Lerp(interp.prev.Pos, interp.next.Pos, t); + HeadY = Utils.LerpAngle(interp.prev.HeadY, interp.next.HeadY, t); + RotY = Utils.LerpAngle(interp.prevRotY, interp.nextRotY, t); + HeadX = Utils.LerpAngle(interp.prev.HeadX, interp.next.HeadX, t); anim.GetCurrentAnimState(t); shouldRender = Model.ShouldRender(this, game.Culling); diff --git a/ClassicalSharp/Game/PickingHandler.cs b/ClassicalSharp/Game/PickingHandler.cs index 47b3e87b1..9fdb31a3c 100644 --- a/ClassicalSharp/Game/PickingHandler.cs +++ b/ClassicalSharp/Game/PickingHandler.cs @@ -84,7 +84,7 @@ namespace ClassicalSharp { // NOTE: We need to also test against nextPos here, because otherwise // we can fall through the block as collision is performed against nextPos AABB localBB = AABB.Make(p.Position, p.Size); - localBB.Min.Y = Math.Min(p.interp.nextPos.Y, localBB.Min.Y); + localBB.Min.Y = Math.Min(p.interp.next.Pos.Y, localBB.Min.Y); if (p.Hacks.Noclip || !localBB.Intersects(blockBB)) return true; if (p.Hacks.CanPushbackBlocks && p.Hacks.PushbackPlacing && p.Hacks.Enabled) @@ -94,7 +94,7 @@ namespace ClassicalSharp { if (localBB.Intersects(blockBB)) return false; // Push player up if they are jumping and trying to place a block underneath them. - Vector3 next = game.LocalPlayer.interp.nextPos; + Vector3 next = game.LocalPlayer.interp.next.Pos; next.Y = pos.Y + game.BlockInfo.MaxBB[block].Y + Entity.Adjustment; LocationUpdate update = LocationUpdate.MakePos(next, false); game.LocalPlayer.SetLocation(update, false); diff --git a/ClassicalSharp/Map/Formats/MapCw.Exporter.cs b/ClassicalSharp/Map/Formats/MapCw.Exporter.cs index f0abe93e7..a6297ddb4 100644 --- a/ClassicalSharp/Map/Formats/MapCw.Exporter.cs +++ b/ClassicalSharp/Map/Formats/MapCw.Exporter.cs @@ -67,11 +67,11 @@ namespace ClassicalSharp.Map { nbt.Write(NbtTagType.Int8); nbt.Write("H"); - nbt.WriteUInt8((byte)Utils.DegreesToPacked(p.SpawnYaw)); + nbt.WriteUInt8((byte)Utils.DegreesToPacked(p.SpawnRotY)); nbt.Write(NbtTagType.Int8); nbt.Write("P"); - nbt.WriteUInt8((byte)Utils.DegreesToPacked(p.SpawnPitch)); + nbt.WriteUInt8((byte)Utils.DegreesToPacked(p.SpawnHeadX)); nbt.Write(NbtTagType.End); } diff --git a/ClassicalSharp/Map/Formats/MapCw.Importer.cs b/ClassicalSharp/Map/Formats/MapCw.Importer.cs index e09462dac..15d853212 100644 --- a/ClassicalSharp/Map/Formats/MapCw.Importer.cs +++ b/ClassicalSharp/Map/Formats/MapCw.Importer.cs @@ -40,9 +40,9 @@ namespace ClassicalSharp.Map { p.Spawn.Y = (short)spawn["Y"].Value; p.Spawn.Z = (short)spawn["Z"].Value; if (spawn.ContainsKey("H")) - p.SpawnYaw = (float)Utils.PackedToDegrees((byte)spawn["H"].Value); + p.SpawnRotY = (float)Utils.PackedToDegrees((byte)spawn["H"].Value); if (spawn.ContainsKey("P")) - p.SpawnPitch = (float)Utils.PackedToDegrees((byte)spawn["P"].Value); + p.SpawnHeadX = (float)Utils.PackedToDegrees((byte)spawn["P"].Value); map.Uuid = new Guid((byte[])children["UUID"].Value); width = (short)children["X"].Value; diff --git a/ClassicalSharp/Map/Formats/MapFcm3.Importer.cs b/ClassicalSharp/Map/Formats/MapFcm3.Importer.cs index 212f3e583..df033c173 100644 --- a/ClassicalSharp/Map/Formats/MapFcm3.Importer.cs +++ b/ClassicalSharp/Map/Formats/MapFcm3.Importer.cs @@ -27,8 +27,8 @@ namespace ClassicalSharp.Map { p.Spawn.X = r.ReadInt32() / 32f; p.Spawn.Y = r.ReadInt32() / 32f; p.Spawn.Z = r.ReadInt32() / 32f; - p.SpawnYaw = (float)Utils.PackedToDegrees(r.ReadByte()); - p.SpawnPitch = (float)Utils.PackedToDegrees(r.ReadByte()); + p.SpawnRotY = (float)Utils.PackedToDegrees(r.ReadByte()); + p.SpawnHeadX = (float)Utils.PackedToDegrees(r.ReadByte()); r.ReadUInt32(); // date modified r.ReadUInt32(); // date created diff --git a/ClassicalSharp/Map/Formats/MapLvl.Importer.cs b/ClassicalSharp/Map/Formats/MapLvl.Importer.cs index 9ee2645a6..aa3072b50 100644 --- a/ClassicalSharp/Map/Formats/MapLvl.Importer.cs +++ b/ClassicalSharp/Map/Formats/MapLvl.Importer.cs @@ -31,8 +31,8 @@ namespace ClassicalSharp.Map { p.Spawn.X = r.ReadUInt16(); p.Spawn.Z = r.ReadUInt16(); p.Spawn.Y = r.ReadUInt16(); - p.SpawnYaw = (float)Utils.PackedToDegrees(r.ReadByte()); - p.SpawnPitch = (float)Utils.PackedToDegrees(r.ReadByte()); + p.SpawnRotY = (float)Utils.PackedToDegrees(r.ReadByte()); + p.SpawnHeadX = (float)Utils.PackedToDegrees(r.ReadByte()); if (header == Version) r.ReadUInt16(); // pervisit and perbuild perms diff --git a/ClassicalSharp/Network/IServerConnection.cs b/ClassicalSharp/Network/IServerConnection.cs index 64a41fa20..dd78e2e42 100644 --- a/ClassicalSharp/Network/IServerConnection.cs +++ b/ClassicalSharp/Network/IServerConnection.cs @@ -25,7 +25,7 @@ namespace ClassicalSharp { public abstract void SendChat(string text, bool partial); /// Informs the server of the client's current position and orientation. - public abstract void SendPosition(Vector3 pos, float yaw, float pitch); + public abstract void SendPosition(Vector3 pos, float rotY, float headX); /// Informs the server that using the given mouse button, /// the client clicked on a particular block or entity. diff --git a/ClassicalSharp/Network/NetworkProcessor.Helpers.cs b/ClassicalSharp/Network/NetworkProcessor.Helpers.cs index 684ad36ec..e31f1f973 100644 --- a/ClassicalSharp/Network/NetworkProcessor.Helpers.cs +++ b/ClassicalSharp/Network/NetworkProcessor.Helpers.cs @@ -13,8 +13,8 @@ namespace ClassicalSharp.Network { classic.SendChat(text, partial); } - public override void SendPosition(Vector3 pos, float yaw, float pitch) { - classic.SendPosition(pos, yaw, pitch); + public override void SendPosition(Vector3 pos, float rotY, float headX) { + classic.SendPosition(pos, rotY, headX); } public override void SendPlayerClick(MouseButton button, bool buttonDown, byte targetId, PickedPos pos) { @@ -58,8 +58,8 @@ namespace ClassicalSharp.Network { if (id != 0xFF) return; LocalPlayer p = game.LocalPlayer; p.Spawn = p.Position; - p.SpawnYaw = p.HeadY; - p.SpawnPitch = p.HeadX; + p.SpawnRotY = p.HeadY; + p.SpawnHeadX = p.HeadX; } internal void RemoveEntity(byte id) { diff --git a/ClassicalSharp/Rendering/ChunkUpdater.cs b/ClassicalSharp/Rendering/ChunkUpdater.cs index 3e7a0c8f4..fe2ea8587 100644 --- a/ClassicalSharp/Rendering/ChunkUpdater.cs +++ b/ClassicalSharp/Rendering/ChunkUpdater.cs @@ -127,8 +127,8 @@ namespace ClassicalSharp.Renderers { void ViewDistanceChanged(object sender, EventArgs e) { lastCamPos = Utils.MaxPos(); - lastYaw = float.MaxValue; - lastPitch = float.MaxValue; + lastRotY = float.MaxValue; + lastHeadX = float.MaxValue; } internal void ResetUsedFlags() { @@ -168,8 +168,8 @@ namespace ClassicalSharp.Renderers { CreateChunkCache(); builder.OnNewMapLoaded(); lastCamPos = Utils.MaxPos(); - lastYaw = float.MaxValue; - lastPitch = float.MaxValue; + lastRotY = float.MaxValue; + lastHeadX = float.MaxValue; } void CreateChunkCache() { @@ -316,18 +316,18 @@ namespace ClassicalSharp.Renderers { LocalPlayer p = game.LocalPlayer; Vector3 cameraPos = game.CurrentCameraPos; - bool samePos = cameraPos == lastCamPos && p.HeadY == lastYaw - && p.HeadX == lastPitch; + bool samePos = cameraPos == lastCamPos && p.HeadY == lastRotY + && p.HeadX == lastHeadX; renderer.renderCount = samePos ? UpdateChunksStill(ref chunkUpdates) : UpdateChunksAndVisibility(ref chunkUpdates); lastCamPos = cameraPos; - lastYaw = p.HeadY; lastPitch = p.HeadX; + lastRotY = p.HeadY; lastHeadX = p.HeadX; if (!samePos || chunkUpdates != 0) ResetUsedFlags(); } Vector3 lastCamPos; - float lastYaw, lastPitch; + float lastRotY, lastHeadX; int UpdateChunksAndVisibility(ref int chunkUpdates) { ChunkInfo[] chunks = renderer.chunks, render = renderer.renderChunks; diff --git a/ClassicalSharp/Utils/Camera.cs b/ClassicalSharp/Utils/Camera.cs index b92660218..fe9a35e6e 100644 --- a/ClassicalSharp/Utils/Camera.cs +++ b/ClassicalSharp/Utils/Camera.cs @@ -35,7 +35,7 @@ namespace ClassicalSharp { /// Calculates the picked block based on the camera's current position. public virtual void GetPickedBlock(PickedPos pos) { } - protected float AdjustPitch(float value) { + protected float AdjustHeadX(float value) { if (value >= 90.0f && value <= 90.1f) return 90.1f * Utils.Deg2Rad; if (value >= 89.9f && value <= 90.0f) return 89.9f * Utils.Deg2Rad; if (value >= 270.0f && value <= 270.1f) return 270.1f * Utils.Deg2Rad; @@ -62,7 +62,7 @@ namespace ClassicalSharp { public override void GetPickedBlock(PickedPos pos) { Vector3 dir = Utils.GetDirVector(player.HeadYRadians, - AdjustPitch(player.HeadX)); + AdjustHeadX(player.HeadX)); Vector3 eyePos = player.EyePosition; float reach = game.LocalPlayer.ReachDistance; Picking.CalculatePickedBlock(game, eyePos, dir, reach, pos); @@ -94,14 +94,14 @@ namespace ClassicalSharp { static readonly float sensiFactor = 0.0002f / 3 * Utils.Rad2Deg; private void UpdateMouseRotation() { float sensitivity = sensiFactor * game.MouseSensitivity; - float rotY = player.interp.nextHeadY + delta.X * sensitivity; + float rotY = player.interp.next.HeadY + delta.X * sensitivity; float yAdj = game.InvertMouse ? -delta.Y * sensitivity : delta.Y * sensitivity; - float headX = player.interp.nextHeadX + yAdj; + float headX = player.interp.next.HeadX + yAdj; LocationUpdate update = LocationUpdate.MakeOri(rotY, headX); // Need to make sure we don't cross the vertical axes, because that gets weird. if (update.HeadX >= 90 && update.HeadX <= 270) - update.HeadX = player.interp.nextHeadX < 180 ? 89.9f : 270.1f; + update.HeadX = player.interp.next.HeadX < 180 ? 89.9f : 270.1f; game.LocalPlayer.SetLocation(update, true); } @@ -127,7 +127,7 @@ namespace ClassicalSharp { protected Vector3 GetDirVector() { return Utils.GetDirVector(player.HeadYRadians, - AdjustPitch(player.HeadX)); + AdjustHeadX(player.HeadX)); } } @@ -187,9 +187,9 @@ namespace ClassicalSharp { Vector3 camPos = player.EyePosition; camPos.Y += bobbingVer; - double adjYaw = player.HeadYRadians + Math.PI / 2; - camPos.X += bobbingHor * (float)Math.Sin(adjYaw); - camPos.Z -= bobbingHor * (float)Math.Cos(adjYaw); + double adjHeadY = player.HeadYRadians + Math.PI / 2; + camPos.X += bobbingHor * (float)Math.Sin(adjHeadY); + camPos.Z -= bobbingHor * (float)Math.Cos(adjHeadY); return camPos; } }