mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-10-06 12:37:28 -04:00
112 lines
3.2 KiB
C#
112 lines
3.2 KiB
C#
using System;
|
|
using ClassicalSharp.Renderers;
|
|
using OpenTK;
|
|
|
|
namespace ClassicalSharp {
|
|
|
|
public class NetPlayer : Player {
|
|
|
|
int tickCount;
|
|
public NetPlayer( string displayName, string skinName, Game game, byte id ) : base( game ) {
|
|
DisplayName = displayName;
|
|
SkinName = skinName;
|
|
SkinIdentifier = "skin_" + id;
|
|
InitRenderingData();
|
|
}
|
|
|
|
// Last known position and orientation sent by the server.
|
|
Vector3 serverPos;
|
|
float serverYaw, serverPitch;
|
|
|
|
public override void SetLocation( LocationUpdate update, bool interpolate ) {
|
|
Vector3 lastPos = serverPos;
|
|
float lastYaw = serverYaw, lastPitch = serverPitch;
|
|
if( update.IncludesPosition ) {
|
|
serverPos = update.RelativePosition ? serverPos + update.Pos : update.Pos;
|
|
}
|
|
if( update.IncludesOrientation ) {
|
|
serverYaw = update.Yaw; serverPitch = update.Pitch;
|
|
}
|
|
|
|
if( !interpolate ) {
|
|
stateCount = 0;
|
|
newState = oldState = new State( tickCount, serverPos, serverYaw, serverPitch );
|
|
yawStateCount = 0;
|
|
newYaw = oldYaw = serverYaw;
|
|
} else {
|
|
// Smoother interpolation by also adding midpoint.
|
|
Vector3 midPos = Vector3.Lerp( lastPos, serverPos, 0.5f );
|
|
float midYaw = Utils.LerpAngle( lastYaw, serverYaw, 0.5f );
|
|
float midPitch = Utils.LerpAngle( lastPitch, serverPitch, 0.5f );
|
|
AddState( new State( tickCount, midPos, midYaw, midPitch ) );
|
|
AddState( new State( tickCount, serverPos, serverYaw, serverPitch ) );
|
|
for( int i = 0; i < 3; i++ )
|
|
AddYaw( Utils.LerpAngle( lastYaw, serverYaw, (i + 1) / 3f ) );
|
|
}
|
|
}
|
|
|
|
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];
|
|
State newState, oldState;
|
|
float newYaw, oldYaw;
|
|
int stateCount, yawStateCount;
|
|
|
|
public override void Tick( double delta ) {
|
|
CheckSkin();
|
|
tickCount++;
|
|
UpdateCurrentState();
|
|
UpdateAnimState( oldState.pos, newState.pos, delta );
|
|
}
|
|
|
|
void AddState( State state ) {
|
|
if( stateCount == states.Length )
|
|
RemoveOldest( states, ref stateCount );
|
|
states[stateCount++] = state;
|
|
}
|
|
|
|
void AddYaw( float state ) {
|
|
if( yawStateCount == yawStates.Length )
|
|
RemoveOldest( yawStates, ref yawStateCount );
|
|
yawStates[yawStateCount++] = state;
|
|
}
|
|
|
|
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( yawStateCount > 0 ) {
|
|
newYaw = yawStates[0];
|
|
RemoveOldest( yawStates, ref yawStateCount );
|
|
}
|
|
}
|
|
|
|
public override void RenderModel( double deltaTime, float t ) {
|
|
Position = Vector3.Lerp( oldState.pos, newState.pos, t );
|
|
HeadYawDegrees = Utils.LerpAngle( oldState.headYaw, newState.headYaw, t );
|
|
YawDegrees = Utils.LerpAngle( oldYaw, newYaw, t );
|
|
PitchDegrees = Utils.LerpAngle( oldState.pitch, newState.pitch, t );
|
|
|
|
GetCurrentAnimState( t );
|
|
Model.RenderModel( this );
|
|
}
|
|
|
|
public override void RenderName() { DrawName(); }
|
|
}
|
|
} |