public void CalculateNonInterpolatedData(int nTime, int lastTick) { // TickToIndex: dit gebruikt % en zou het serieus kunnen vertragen. UpdateEntityPacket startPacket = UpdateEntityPacket.Empty; UpdateEntityPacket endPacket = UpdateEntityPacket.Empty; int startTick = -1; //int endTick = -1; //Find start snapshot. int iTick = lastTick; int index; while (iTick > firstElementTick) { index = TickToIndex(iTick); if (!snapshots[index].IsEmpty()) { startPacket = snapshots[index]; startTick = iTick; break; } iTick--; } Positie = startPacket.Positie; RotatieQuat = startPacket.RotatieQuat; }
private void tick() { deltaParser.StartWrite(tickNumber); for (int i = 0; i < actors.Count; i++) { var actor = actors[i]; actor.Tick(); var p = new UpdateEntityPacket(); p.Positie = actor.Positie; p.RotatieQuat = actor.RotatieQuat; deltaParser.WriteEntityUpdatePacket(actor.ID, p); } var packet = new DataPacket(); packet.Data = deltaParser.EndWrite(); if (packet.Data == null) { throw new InvalidOperationException("Cant be null??"); } deltaSnapshotTransporter.SendAll(packet); // Currently send time update every tick timeUpdateTransporter.SendAll(new TimeUpdatePacket { TickNumber = tickNumber, TotalTime = totalTime }); }
public void AddEntityUpdate(int nTick, UpdateEntityPacket p) { /*if ( nTick < firstElementTick || nTick >= firstElementTick + snapshots.Length ) * { * // nTick out of buffer range? should we reposition the firstElementTick or just dispose * // the update? * * //Dispose for now * return; * }*/ int temp = firstElementTick; /*firstElementTick = temp; * firstElementIndex = TickToIndex( firstElementTick );*/ if (nTick == firstElementTick + snapshots.Length) { //Move the buffer right by one. firstElementTick++; firstElementIndex++; if (firstElementIndex == snapshots.Length) { firstElementIndex = 0; } //Put the new packet in the buffer. The packet at the old firstElementIndex is now replaced by p snapshots[TickToIndex(nTick)] = p; } else if (nTick > firstElementTick + snapshots.Length) { MoveBufferStartTickRight(nTick - (firstElementTick + snapshots.Length - 1)); snapshots[TickToIndex(nTick)] = p; } else if (nTick < firstElementTick) { //Dispose the packet, out of date (do nothing) } else { //Packet is in range snapshots[TickToIndex(nTick)] = p; } if (firstElementIndex != TickToIndex(firstElementTick)) { throw new Exception(); } }
public void TestSyncDirect() { var client = new ClientSyncedActor(); var server = new ServerSyncedActor(); var physicsEngine = new PhysicsEngine(); StillDesign.PhysX.Scene serverScene = null; PhysicsDebugRendererXNA debugRenderer; PhysicsDebugRendererXNA debugRendererServer; var game = new XNAGame(); float totalTime = 0; float timeSinceTick = 0; float tickRate = 1 / 30f; int tickNumber = 0; float packetLoss = 0.25f; var rand = new Random(); game.InitializeEvent += delegate { physicsEngine.Initialize(); serverScene = physicsEngine.CreateScene(physicsEngine.Scene.Gravity, true); debugRenderer = new PhysicsDebugRendererXNA(game, physicsEngine.Scene); game.AddXNAObject(debugRenderer); debugRendererServer = new PhysicsDebugRendererXNA(game, serverScene); game.AddXNAObject(debugRendererServer); ActorDescription actorDesc; SphereShapeDescription shape; shape = new SphereShapeDescription(1); actorDesc = new ActorDescription(shape); actorDesc.BodyDescription = new BodyDescription(10); server.Actor = new WorldPhysxSyncActor(serverScene.CreateActor(actorDesc)); ((WorldPhysxSyncActor)server.Actor).Actor.AddForce(Vector3.UnitX * 200, ForceMode.Impulse); shape = new SphereShapeDescription(1); actorDesc = new ActorDescription(shape); actorDesc.BodyDescription = new BodyDescription(10); client.Actor = new WorldPhysxSyncActor(physicsEngine.Scene.CreateActor(actorDesc)); }; game.UpdateEvent += delegate { physicsEngine.Update(game); physicsEngine.UpdateScene(game.Elapsed, serverScene); totalTime += game.Elapsed; timeSinceTick += game.Elapsed; int totalMiliseconds = (int)(totalTime * 1000); while (timeSinceTick > tickRate) { timeSinceTick -= tickRate; //Do a tick tickNumber++; server.Tick(); var p = new UpdateEntityPacket(); p.Positie = server.Positie; p.RotatieQuat = server.RotatieQuat; if (rand.NextDouble() < 1 - packetLoss) { client.AddEntityUpdate(tickNumber, p); } } client.Process(totalMiliseconds, tickRate); }; game.Run(); physicsEngine.Dispose(); }
public void CalculateInterpolatedData(int nTime, int lastTick, float tickRate) { // TickToIndex: dit gebruikt % en zou het serieus kunnen vertragen. UpdateEntityPacket startPacket = UpdateEntityPacket.Empty; UpdateEntityPacket endPacket = UpdateEntityPacket.Empty; int startTick = -1; int endTick = -1; //Find start snapshot. int iTick = lastTick; int index; while (iTick > firstElementTick) { index = TickToIndex(iTick); if (!snapshots[index].IsEmpty()) { startPacket = snapshots[index]; startTick = iTick; break; } iTick--; } //Find end snapshot. iTick = lastTick + 1; while (iTick < firstElementTick + snapshots.Length) { index = TickToIndex(iTick); if (!snapshots[index].IsEmpty()) { endPacket = snapshots[index]; endTick = iTick; break; } iTick++; } if (startPacket.IsEmpty()) { return; } if (endPacket.IsEmpty()) { return; } int startTime = (int)Math.Floor(startTick * (tickRate * 1000)); int endTime = (int)Math.Floor(endTick * (tickRate * 1000)); int interval = endTime - startTime; //nTime -= startTime; //nTime /= interval; float amount = (float)(nTime - startTime) / (float)interval; Positie = Vector3.Lerp(startPacket.Positie, endPacket.Positie, amount); RotatieQuat = Quaternion.Lerp(startPacket.RotatieQuat, endPacket.RotatieQuat, amount); }