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; } }
internal void DrawPlayers(Game game, float dt) { game.totaltimeMilliseconds = game.platform.TimeMillisecondsFromStart(); for (int i = 0; i < game.entitiesCount; i++) { if (game.entities[i] == null) { continue; } if (game.entities[i].drawModel == null) { continue; } Entity p_ = game.entities[i]; if (i == game.LocalPlayerId && (!game.ENABLE_TPP_VIEW)) { continue; } if ((p_.networkPosition != null) && (!p_.networkPosition.PositionLoaded)) { continue; } if (!game.d_FrustumCulling.SphereInFrustum(p_.position.x, p_.position.y, p_.position.z, 3)) { continue; } if (p_.drawModel.CurrentTexture == -1) { continue; } int cx = game.platform.FloatToInt(p_.position.x) / Game.chunksize; int cy = game.platform.FloatToInt(p_.position.z) / Game.chunksize; int cz = game.platform.FloatToInt(p_.position.y) / Game.chunksize; if (game.map.IsValidChunkPos(cx, cy, cz)) { if (!game.map.IsChunkRendered(cx, cy, cz)) { continue; } } float shadow = (one * game.GetLight(game.platform.FloatToInt(p_.position.x), game.platform.FloatToInt(p_.position.z), game.platform.FloatToInt(p_.position.y))) / Game.maxlight; if (p_.playerDrawInfo == null) { p_.playerDrawInfo = new PlayerDrawInfo(); } p_.playerDrawInfo.anim.light = shadow; float FeetPosX = p_.position.x; float FeetPosY = p_.position.y; float FeetPosZ = p_.position.z; AnimationHint animHint = game.entities[i].playerDrawInfo.AnimationHint_; float playerspeed_; if (i == game.LocalPlayerId) { if (game.player.playerDrawInfo == null) { game.player.playerDrawInfo = new PlayerDrawInfo(); } Vector3Ref playerspeed = Vector3Ref.Create(game.playervelocity.X / 60, game.playervelocity.Y / 60, game.playervelocity.Z / 60); float playerspeedf = playerspeed.Length() * (one * 15 / 10); game.player.playerDrawInfo.moves = playerspeedf != 0; playerspeed_ = playerspeedf; } else { playerspeed_ = (game.Length(p_.playerDrawInfo.velocityX, p_.playerDrawInfo.velocityY, p_.playerDrawInfo.velocityZ) / dt) * (one * 4 / 100); } { if (p_.drawModel.renderer == null) { p_.drawModel.renderer = new AnimatedModelRenderer(); byte[] data = game.GetFile(p_.drawModel.Model_); int dataLength = game.GetFileLength(p_.drawModel.Model_); if (data != null) { string dataString = game.platform.StringFromUtf8ByteArray(data, dataLength); AnimatedModel model = AnimatedModelSerializer.Deserialize(game.platform, dataString); p_.drawModel.renderer.Start(game, model); } } game.GLPushMatrix(); game.GLTranslate(FeetPosX, FeetPosY, FeetPosZ); //game.GLRotate(PlayerInterpolate.RadToDeg(p_.position.rotx), 1, 0, 0); game.GLRotate(PlayerInterpolate.RadToDeg(-p_.position.roty + Game.GetPi()), 0, 1, 0); //game.GLRotate(PlayerInterpolate.RadToDeg(p_.position.rotz), 0, 0, 1); game.platform.BindTexture2d(game.entities[i].drawModel.CurrentTexture); p_.drawModel.renderer.Render(dt, PlayerInterpolate.RadToDeg(p_.position.rotx + Game.GetPi()), true, p_.playerDrawInfo.moves, shadow); game.GLPopMatrix(); } } }