private void SendPhysicsUpdate(float timestamp) { if (LocalUser == null) { return; } PhysicsBridgePatch physicsPatch = new PhysicsBridgePatch(LocalUser.Id, PhysicsBridge.GenerateSnapshot(timestamp, SceneRoot)); // send only updates if there are any, to save band with // in order to produce any updates for settled bodies this should be handled within the physics bridge if (physicsPatch.DoSendThisPatch()) { EventManager.QueueEvent(new PhysicsBridgeUpdated(InstanceId, physicsPatch)); } //low frequency server upload transform stream { float systemTime = OS.GetTicksMsec() * 0.001f; if (PhysicsBridge.shouldSendLowFrequencyTransformUpload(systemTime)) { PhysicsTranformServerUploadPatch serverUploadPatch = PhysicsBridge.GenerateServerTransformUploadPatch(InstanceId, systemTime); // upload only if there is a real difference in the transforms if (serverUploadPatch.IsPatched()) { EventManager.QueueEvent(new PhysicsTranformServerUploadUpdated(InstanceId, serverUploadPatch)); } } } _shouldSendPhysicsUpdate = false; _timeSinceLastPhysicsUpdate = 0.0f; }
/// generates the message that updates the transforms on the server side (this is done in a low frequency manner) /// <returns> message that should be sent to the server</returns> public PhysicsTranformServerUploadPatch GenerateServerTransformUploadPatch(Guid instanceId, float systemTime) { var ret = new PhysicsTranformServerUploadPatch(); int numownedbodies = 0; int numUpdatedTransform = 0; List <PhysicsTranformServerUploadPatch.OneActorUpdate> allUpdates = new List <PhysicsTranformServerUploadPatch.OneActorUpdate>(); // first loop counts how many RBs do we own foreach (var rb in _rigidBodies.Values) { if (rb.Ownership) { numownedbodies++; var actor = rb.RigidBody.gameObject.GetComponent <Actor>(); if (actor != null) { // MUST be the same as PatchingUtilMethods.GenerateLocalTransformPatch // and PatchingUtilMethods.GenerateAppTransformPatch //update.localTransforms.Position = actor.transform.position; var update = new PhysicsTranformServerUploadPatch.OneActorUpdate( actor.Id, actor.transform.position, actor.transform.rotation, actor.App.SceneRoot.transform.InverseTransformPoint(actor.transform.position), Quaternion.Inverse(actor.App.SceneRoot.transform.rotation) * actor.transform.rotation ); // todo see if we sent this update already if (_lastServerUploadedTransforms.ContainsKey(rb.Id)) { var lastUpdate = _lastServerUploadedTransforms[rb.Id]; if (!lastUpdate.isEqual(update)) { allUpdates.Add(update); numUpdatedTransform++; _lastServerUploadedTransforms[rb.Id] = update; } } else { // add an update anyway allUpdates.Add(update); _lastServerUploadedTransforms.Add(rb.Id, update); numUpdatedTransform++; } } } else { // remove if this is in this list if (_lastServerUploadedTransforms.ContainsKey(rb.Id)) { _lastServerUploadedTransforms.Remove(rb.Id); } } } ret.updates = new PhysicsTranformServerUploadPatch.OneActorUpdate[numownedbodies]; ret.TransformCount = numUpdatedTransform; ret.Id = instanceId; numownedbodies = 0; foreach (var update in allUpdates) { // add the updates ret.updates[numownedbodies++] = update; } // store the last time _lastServerTransformUploadSentTime = systemTime; return(ret); }
public PhysicsTranformServerUploadUpdated(Guid id, PhysicsTranformServerUploadPatch physicsServerUploadPatch) : base(id) { _physicsTransformUploadPatch = physicsServerUploadPatch; }