public object Interpolate(object a, object b, float progress) { PlayerInterpolationState aa = a as PlayerInterpolationState; PlayerInterpolationState bb = b as PlayerInterpolationState; PlayerInterpolationState cc = new PlayerInterpolationState(); cc.position = aa.position + (bb.position - aa.position) * progress; cc.heading = (byte)AngleInterpolation.InterpolateAngle256(aa.heading, bb.heading, progress); cc.pitch = (byte)AngleInterpolation.InterpolateAngle256(aa.pitch, bb.pitch, progress); return cc; }
private void DrawPlayers(float dt) { totaltime += dt; foreach (var k in clients.Players) { if (!playerdrawinfo.ContainsKey(k.Key)) { playerdrawinfo[k.Key] = new PlayerDrawInfo(); NetworkInterpolation n = new NetworkInterpolation(); n.req = new PlayerInterpolate(); n.DELAY = 0.5f; n.EXTRAPOLATE = true; n.EXTRAPOLATION_TIME = 0.3f; playerdrawinfo[k.Key].interpolation = n; } PlayerDrawInfo info = playerdrawinfo[k.Key]; Vector3 realpos = k.Value.Position; if (realpos != info.lastrealpos || k.Value.Heading != info.lastrealheading || k.Value.Pitch != info.lastrealpitch) { info.interpolation.AddNetworkPacket( new PlayerInterpolationState() { position = realpos, heading = k.Value.Heading, pitch = k.Value.Pitch, }, totaltime); } var curstate = ((PlayerInterpolationState)info.interpolation.InterpolatedState(totaltime)); if (curstate == null) { curstate = new PlayerInterpolationState(); } //do not interpolate player position if player is controlled by game world if (network.EnablePlayerUpdatePosition.ContainsKey(k.Key) && !network.EnablePlayerUpdatePosition[k.Key]) { curstate.position = k.Value.Position; } Vector3 curpos = curstate.position; bool moves = curpos != info.lastcurpos; DrawCharacter(info.anim, curpos + new Vector3(0, -CharacterPhysics.characterheight, 0) + new Vector3(0, -CharacterPhysics.walldistance, 0), curstate.heading, curstate.pitch, moves, dt, GetPlayerTexture(k.Key), clients.Players[k.Key].AnimationHint); info.lastcurpos = curpos; info.lastrealpos = realpos; info.lastrealheading = k.Value.Heading; info.lastrealpitch = k.Value.Pitch; } if (ENABLE_TPP_VIEW) { DrawCharacter(localplayeranim, LocalPlayerPosition + new Vector3(0, -CharacterPhysics.walldistance, 0), NetworkHelper.HeadingByte(LocalPlayerOrientation), NetworkHelper.PitchByte(LocalPlayerOrientation), lastlocalplayerpos != LocalPlayerPosition, dt, GetPlayerTexture(255), localplayeranimationhint); lastlocalplayerpos = LocalPlayerPosition; } }
private void DrawPlayers(float dt) { totaltime += dt; foreach (var k in d_Clients.Players) { if (k.Key == 255) { continue; } if (!playerdrawinfo.ContainsKey(k.Key)) { playerdrawinfo[k.Key] = new PlayerDrawInfo(); NetworkInterpolation n = new NetworkInterpolation(); n.req = new PlayerInterpolate(); n.DELAY = 0.5f; n.EXTRAPOLATE = true; n.EXTRAPOLATION_TIME = 0.3f; playerdrawinfo[k.Key].interpolation = n; } PlayerDrawInfo info = playerdrawinfo[k.Key]; Vector3 realpos = k.Value.Position; if (realpos != info.lastrealpos || k.Value.Heading != info.lastrealheading || k.Value.Pitch != info.lastrealpitch) { info.interpolation.AddNetworkPacket( new PlayerInterpolationState() { position = realpos, heading = k.Value.Heading, pitch = k.Value.Pitch, }, totaltime); } var curstate = ((PlayerInterpolationState)info.interpolation.InterpolatedState(totaltime)); if (curstate == null) { curstate = new PlayerInterpolationState(); } //do not interpolate player position if player is controlled by game world if (EnablePlayerUpdatePosition.ContainsKey(k.Key) && !EnablePlayerUpdatePosition[k.Key]) { curstate.position = k.Value.Position; } Vector3 curpos = curstate.position; bool moves = curpos != info.lastcurpos; info.lastcurpos = curpos; info.lastrealpos = realpos; info.lastrealheading = k.Value.Heading; info.lastrealpitch = k.Value.Pitch; if (!d_FrustumCulling.SphereInFrustum(curpos.X, curpos.Y, curpos.Z, 3)) { continue; } float shadow = (float)d_Shadows.MaybeGetLight((int)curpos.X, (int)curpos.Z, (int)curpos.Y) / d_Shadows.maxlight; GL.Color3(shadow, shadow, shadow); Vector3 FeetPos = curpos + new Vector3(0, -CharacterPhysics.characterheight, 0) + new Vector3(0, -CharacterPhysics.walldistance, 0); var animHint = d_Clients.Players[k.Key].AnimationHint; if (k.Value.Type == PlayerType.Player) { DrawCharacter(info.anim, FeetPos, curstate.heading, curstate.pitch, moves, dt, GetPlayerTexture(k.Key), animHint); } else { int type = k.Value.MonsterType; if (!MonsterRenderers.ContainsKey(type)) { var r = new CharacterRendererMonsterCode(); r.Load(new List<string>(d_DataMonsters.MonsterCode[type])); MonsterRenderers[type] = r; } MonsterRenderers[type].SetAnimation("walk"); //curpos += new Vector3(0, -CharacterPhysics.walldistance, 0); //todos MonsterRenderers[type].DrawCharacter(info.anim, curpos, (byte)(-curstate.heading - 256 / 4), curstate.pitch, moves, dt, GetPlayerTexture(k.Key), animHint); } GL.Color3(1f, 1f, 1f); } if (ENABLE_TPP_VIEW) { float shadow = (float)d_Shadows.MaybeGetLight( (int)LocalPlayerPosition.X, (int)LocalPlayerPosition.Z, (int)LocalPlayerPosition.Y) / d_Shadows.maxlight; GL.Color3(shadow, shadow, shadow); DrawCharacter(localplayeranim, LocalPlayerPosition + new Vector3(0, -CharacterPhysics.walldistance, 0), NetworkHelper.HeadingByte(LocalPlayerOrientation), NetworkHelper.PitchByte(LocalPlayerOrientation), lastlocalplayerpos != LocalPlayerPosition, dt, GetPlayerTexture(255), localplayeranimationhint); lastlocalplayerpos = LocalPlayerPosition; GL.Color3(1f, 1f, 1f); } }
public override InterpolatedObject Interpolate(InterpolatedObject a, InterpolatedObject b, float progress) { PlayerInterpolationState aa = platform.CastToPlayerInterpolationState(a); PlayerInterpolationState bb = platform.CastToPlayerInterpolationState(b); PlayerInterpolationState cc = new PlayerInterpolationState(); cc.positionX = aa.positionX + (bb.positionX - aa.positionX) * progress; cc.positionY = aa.positionY + (bb.positionY - aa.positionY) * progress; cc.positionZ = aa.positionZ + (bb.positionZ - aa.positionZ) * progress; //cc.heading = Game.IntToByte(AngleInterpolation.InterpolateAngle256(platform, aa.heading, bb.heading, progress)); //cc.pitch = Game.IntToByte(AngleInterpolation.InterpolateAngle256(platform, aa.pitch, bb.pitch, progress)); cc.rotx = DegToRad(AngleInterpolation.InterpolateAngle360(platform, RadToDeg(aa.rotx), RadToDeg(bb.rotx), progress)); cc.roty = DegToRad(AngleInterpolation.InterpolateAngle360(platform, RadToDeg(aa.roty), RadToDeg(bb.roty), progress)); cc.rotz = DegToRad(AngleInterpolation.InterpolateAngle360(platform, RadToDeg(aa.rotz), RadToDeg(bb.rotz), progress)); return cc; }
internal void InterpolatePositions(Game game, float dt) { for (int i = 0; i < game.entitiesCount; i++) { Entity e = game.entities[i]; if (e == null) { continue; } if (e.networkPosition == null) { continue; } if (i == game.LocalPlayerId) { continue; } if (!e.networkPosition.PositionLoaded) { continue; } if (e.playerDrawInfo == null) { e.playerDrawInfo = new PlayerDrawInfo(); } if (e.playerDrawInfo.interpolation == null) { NetworkInterpolation n = new NetworkInterpolation(); PlayerInterpolate playerInterpolate = new PlayerInterpolate(); playerInterpolate.platform = game.platform; n.req = playerInterpolate; n.DELAYMILLISECONDS = 500; n.EXTRAPOLATE = false; n.EXTRAPOLATION_TIMEMILLISECONDS = 300; e.playerDrawInfo.interpolation = n; } e.playerDrawInfo.interpolation.DELAYMILLISECONDS = MathCi.MaxInt(100, game.ServerInfo.ServerPing.RoundtripTimeTotalMilliseconds()); Entity p = e; PlayerDrawInfo info = p.playerDrawInfo; float networkposX = p.networkPosition.x; float networkposY = p.networkPosition.y; float networkposZ = p.networkPosition.z; if ((!game.Vec3Equal(networkposX, networkposY, networkposZ, info.lastnetworkposX, info.lastnetworkposY, info.lastnetworkposZ)) || p.networkPosition.rotx != info.lastnetworkrotx || p.networkPosition.roty != info.lastnetworkroty || p.networkPosition.rotz != info.lastnetworkrotz) { PlayerInterpolationState state = new PlayerInterpolationState(); state.positionX = networkposX; state.positionY = networkposY; state.positionZ = networkposZ; state.rotx = p.networkPosition.rotx; state.roty = p.networkPosition.roty; state.rotz = p.networkPosition.rotz; info.interpolation.AddNetworkPacket(state, game.totaltimeMilliseconds); } PlayerInterpolationState curstate = game.platform.CastToPlayerInterpolationState(info.interpolation.InterpolatedState(game.totaltimeMilliseconds)); if (curstate == null) { curstate = new PlayerInterpolationState(); } //do not interpolate player position if player is controlled by game world if (game.EnablePlayerUpdatePositionContainsKey(i) && !game.EnablePlayerUpdatePosition(i)) { curstate.positionX = p.networkPosition.x; curstate.positionY = p.networkPosition.y; curstate.positionZ = p.networkPosition.z; } float curposX = curstate.positionX; float curposY = curstate.positionY; float curposZ = curstate.positionZ; info.velocityX = curposX - info.lastcurposX; info.velocityY = curposY - info.lastcurposY; info.velocityZ = curposZ - info.lastcurposZ; info.moves = (!game.Vec3Equal(curposX, curposY, curposZ, info.lastcurposX, info.lastcurposY, info.lastcurposZ)); info.lastcurposX = curposX; info.lastcurposY = curposY; info.lastcurposZ = curposZ; info.lastnetworkposX = networkposX; info.lastnetworkposY = networkposY; info.lastnetworkposZ = networkposZ; info.lastnetworkrotx = p.networkPosition.rotx; info.lastnetworkroty = p.networkPosition.roty; info.lastnetworkrotz = p.networkPosition.rotz; p.position.x = curposX; p.position.y = curposY; p.position.z = curposZ; p.position.rotx = curstate.rotx; p.position.roty = curstate.roty; p.position.rotz = curstate.rotz; } }