mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-23 04:34:58 -04:00
more concise interpolation, fix last commit
This commit is contained in:
parent
55093847db
commit
e7aa519846
@ -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) {
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -150,6 +150,7 @@
|
||||
<Compile Include="Blocks\BlockInfo.Atlas.cs" />
|
||||
<Compile Include="Blocks\DefaultSet.cs" />
|
||||
<Compile Include="Commands\SinglePlayerCommands.cs" />
|
||||
<Compile Include="Entities\Components\IInterpComponent.cs" />
|
||||
<Compile Include="Entities\Components\LocalInterpComponent.cs" />
|
||||
<Compile Include="Entities\Mobs\AI\AI.cs" />
|
||||
<Compile Include="Entities\Mobs\AI\FleeAI.cs" />
|
||||
|
182
ClassicalSharp/Entities/Components/IInterpComponent.cs
Normal file
182
ClassicalSharp/Entities/Components/IInterpComponent.cs
Normal file
@ -0,0 +1,182 @@
|
||||
// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
|
||||
using System;
|
||||
using ClassicalSharp.Renderers;
|
||||
using OpenTK;
|
||||
|
||||
namespace ClassicalSharp.Entities {
|
||||
|
||||
/// <summary> Entity component that performs interpolation of position and orientation over time. </summary>
|
||||
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>(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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary> Entity component that performs interpolation of position and orientation over time. </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
||||
|
@ -5,84 +5,5 @@ using OpenTK;
|
||||
|
||||
namespace ClassicalSharp.Entities {
|
||||
|
||||
/// <summary> Entity component that performs interpolation of position and model head yaw over time. </summary>
|
||||
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>(T[] array, ref int count) {
|
||||
for (int i = 0; i < array.Length - 1; i++)
|
||||
array[i] = array[i + 1];
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -5,94 +5,6 @@ using OpenTK;
|
||||
|
||||
namespace ClassicalSharp.Entities {
|
||||
|
||||
/// <summary> Entity component that performs interpolation of position and model head yaw over time. </summary>
|
||||
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>(T[] array, ref int count) {
|
||||
for (int i = 0; i < array.Length - 1; i++)
|
||||
array[i] = array[i + 1];
|
||||
count--;
|
||||
}
|
||||
}
|
||||
/// <summary> Entity component that performs interpolation of position and orientation over time. </summary>
|
||||
|
||||
}
|
@ -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;
|
||||
|
@ -12,7 +12,7 @@ namespace ClassicalSharp.Entities {
|
||||
/// <summary> Position the player's position is set to when the 'respawn' key binding is pressed. </summary>
|
||||
public Vector3 Spawn;
|
||||
|
||||
public float SpawnYaw, SpawnPitch;
|
||||
public float SpawnRotY, SpawnHeadX;
|
||||
|
||||
/// <summary> The distance (in blocks) that players are allowed to
|
||||
/// reach to and interact/modify blocks in. </summary>
|
||||
@ -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 {
|
||||
/// <summary> Linearly interpolates position and rotation between the previous and next state. </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -25,7 +25,7 @@ namespace ClassicalSharp {
|
||||
public abstract void SendChat(string text, bool partial);
|
||||
|
||||
/// <summary> Informs the server of the client's current position and orientation. </summary>
|
||||
public abstract void SendPosition(Vector3 pos, float yaw, float pitch);
|
||||
public abstract void SendPosition(Vector3 pos, float rotY, float headX);
|
||||
|
||||
/// <summary> Informs the server that using the given mouse button,
|
||||
/// the client clicked on a particular block or entity. </summary>
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -35,7 +35,7 @@ namespace ClassicalSharp {
|
||||
/// <summary> Calculates the picked block based on the camera's current position. </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user