Beispiel #1
0
 public void Update()
 {
     foreach (Guid vesselID in currentVesselUpdates.Keys)
     {
         //Not sure if this can happen, but we don't want to apply updates to vessels we are supposed to be updating.
         if (lockSystem.LockIsOurs("update-" + vesselID))
         {
             continue;
         }
         Vessel updateVessel = FlightGlobals.fetch.vessels.Find(v => v.id == vesselID);
         if (updateVessel == null)
         {
             continue;
         }
         if (!updateVessel.packed)
         {
             continue;
         }
         VesselUpdate vu = currentVesselUpdates[vesselID];
         //Apply updates for up to 5 seconds
         double timeDiff = Planetarium.GetUniversalTime() - vu.planetTime;
         if (timeDiff < 5f && timeDiff > -5f)
         {
             vu.Apply(posistionStatistics, null);
         }
     }
 }
Beispiel #2
0
        private void StepExtrapolateWithRotation(VesselUpdate previous, Vector3d pos, Vector3d vel, Vector3d acc, double timeDiff, out Vector3d newPostion, out Vector3d newVelocity)
        {
            Vector3d stepPos = pos;
            Vector3d stepVel = vel;
            //Option for adding rotation, this seems to make things worse
            Quaternion previousRot = new Quaternion(previous.rotation[0], previous.rotation[1], previous.rotation[2], previous.rotation[3]);
            Quaternion thisRot     = new Quaternion(rotation[0], rotation[1], rotation[2], rotation[3]);
            Quaternion rotDelta    = thisRot * Quaternion.Inverse(previousRot);
            int        steps       = (int)(Math.Abs(timeDiff) / STEP_DISTANCE);

            if (steps == 0)
            {
                steps = 1;
            }
            double actualStepDiff = timeDiff / steps;
            double rotDiff        = planetTime - previous.planetTime;

            for (int i = 0; i < steps; i++)
            {
                double     scaling = (i * actualStepDiff) / rotDiff;
                Quaternion rotAcc  = RotationLerp(Quaternion.identity, rotDelta, (float)scaling);
                Vector3d   stepAcc = rotAcc * acc;
                stepVel = stepVel + stepAcc * actualStepDiff;
                stepPos = stepPos + stepVel * actualStepDiff;
            }
            newPostion  = stepPos;
            newVelocity = stepVel;
        }
 public void SetVesselUpdate(Guid guid, VesselUpdate vesselUpdate)
 {
     if (loadingFlyingVessels.ContainsKey(guid))
     {
         loadingFlyingVessels[guid].lastVesselUpdate = vesselUpdate;
     }
 }
Beispiel #4
0
        public void Update()
        {
            if (playback)
            {
                if (Planetarium.GetUniversalTime() > (lastTime))
                {
                    playback = false;
                    ScreenMessages.RemoveMessage(screenMessage);
                    screenMessage = null;
                }
                else
                {
                    int timeLeft = (int)(lastTime - Planetarium.GetUniversalTime());
                    ScreenMessages.RemoveMessage(screenMessage);
                    screenMessage = ScreenMessages.PostScreenMessage("Playback time left: " + timeLeft + " / " + (int)(lastTime - firstTime) + " seconds", float.MaxValue, ScreenMessageStyle.UPPER_CENTER);
                }
            }

            if (active)
            {
                VesselUpdate  vu          = VesselUpdate.CopyFromVessel(vesselWorker, FlightGlobals.fetch.activeVessel);
                ClientMessage updateBytes = networkWorker.GetVesselUpdateMessage(vu);
                byte[]        lengthBytes = BitConverter.GetBytes(updateBytes.data.Length);
                if (BitConverter.IsLittleEndian)
                {
                    Array.Reverse(lengthBytes);
                }
                recordingVector.Write(lengthBytes, 0, lengthBytes.Length);
                recordingVector.Write(updateBytes.data, 0, updateBytes.data.Length);
            }
        }
Beispiel #5
0
 public void SetNextUpdate(Guid vesselID, VesselUpdate nextUpdate)
 {
     if (nextVesselUpdates.ContainsKey(vesselID))
     {
         nextVesselUpdates[vesselID] = nextUpdate;
     }
 }
 public void SetVesselUpdate(Guid guid, VesselUpdate vesselUpdate)
 {
     if (loadingFlyingVessels.ContainsKey(guid))
     {
         loadingFlyingVessels[guid].lastVesselUpdate = vesselUpdate;
     }
 }
Beispiel #7
0
        public void StartRecord()
        {
            active          = true;
            recording       = new MemoryStream();
            recordingVector = new MemoryStream();
            VesselUpdate update = VesselUpdate.CopyFromVessel(vesselWorker, FlightGlobals.fetch.activeVessel);

            networkWorker.SendVesselUpdate(update);
        }
        public void StartRecord()
        {
            active          = true;
            recording       = new MemoryStream();
            recordingVector = new MemoryStream();
            VesselUpdate update = Recycler <VesselUpdate> .GetObject();

            update.SetVesselWorker(vesselWorker);
            update.CopyFromVessel(FlightGlobals.fetch.activeVessel);
            networkWorker.SendVesselUpdate(update);
            Recycler <VesselUpdate> .ReleaseObject(update);
        }
        public void DisplayUpdateVesselOffset()
        {
            double interpolatorDelay = 0;

            if (dmpSettings.interpolatorType == InterpolatorType.INTERPOLATE1S)
            {
                interpolatorDelay = 1;
            }
            if (dmpSettings.interpolatorType == InterpolatorType.INTERPOLATE3S)
            {
                interpolatorDelay = 3;
            }

            while (playbackQueue.Count > 0 && Planetarium.GetUniversalTime() > (playbackQueue.Peek().planetTime + interpolatorDelay))
            {
                if (lastUpdate != null)
                {
                    Recycler <VesselUpdate> .ReleaseObject(lastUpdate);
                }
                lastUpdate = playbackQueue.Dequeue();
                playbackID = lastUpdate.vesselID;
            }
            if (playbackQueue.Count > 0)
            {
                VesselUpdate vu = playbackQueue.Peek();
                if (lastUpdate != null && vu != null && lastUpdate.isSurfaceUpdate && vu.isSurfaceUpdate)
                {
                    Vessel av = FlightGlobals.fetch.vessels.Find(v => v.id == vu.vesselID);
                    if (av != null)
                    {
                        double   scaling       = (Planetarium.GetUniversalTime() - interpolatorDelay - lastUpdate.planetTime) / (vu.planetTime - lastUpdate.planetTime);
                        Vector3d orgPos        = new Vector3d(lastUpdate.position[0], lastUpdate.position[1], lastUpdate.position[2]);
                        Vector3d nextPos       = new Vector3d(vu.position[0], vu.position[1], vu.position[2]);
                        Vector3d updatePos     = Vector3d.Lerp(orgPos, nextPos, scaling);
                        Vector3d distanceInPos = av.mainBody.GetWorldSurfacePosition(av.latitude, av.longitude, av.altitude) - av.mainBody.GetWorldSurfacePosition(updatePos.x, updatePos.y, updatePos.z);
                        double   timeDiff      = Planetarium.GetUniversalTime() - interpolatorDelay - lastUpdate.planetTime;
                        DarkLog.Debug("Difference in position: " + Math.Round(distanceInPos.magnitude, 3) + ", scaling: " + Math.Round(scaling, 3));
                    }
                }
            }
            else
            {
                //Free the last update too!
                if (lastUpdate != null)
                {
                    Recycler <VesselUpdate> .ReleaseObject(lastUpdate);

                    lastUpdate = null;
                }
            }
        }
 public void CopyFromUpdate(VesselUpdate source)
 {
     updateOK = source.updateOK;
     SetVesselWorker(source.vesselWorker);
     vesselID           = source.vesselID;
     planetTime         = source.planetTime;
     bodyName           = source.bodyName;
     rotation[0]        = source.rotation[0];
     rotation[1]        = source.rotation[1];
     rotation[2]        = source.rotation[2];
     rotation[3]        = source.rotation[3];
     angularVelocity[0] = source.angularVelocity[0];
     angularVelocity[1] = source.angularVelocity[1];
     angularVelocity[2] = source.angularVelocity[2];
     flightState.CopyFrom(source.flightState);
     actiongroupControls[0] = source.actiongroupControls[0];
     actiongroupControls[1] = source.actiongroupControls[1];
     actiongroupControls[2] = source.actiongroupControls[2];
     actiongroupControls[3] = source.actiongroupControls[3];
     actiongroupControls[4] = source.actiongroupControls[4];
     isSurfaceUpdate        = source.isSurfaceUpdate;
     terrainNormal[0]       = source.terrainNormal[0];
     terrainNormal[1]       = source.terrainNormal[1];
     terrainNormal[2]       = source.terrainNormal[2];
     velocity[0]            = source.velocity[0];
     velocity[1]            = source.velocity[1];
     velocity[2]            = source.velocity[2];
     acceleration[0]        = source.acceleration[0];
     acceleration[1]        = source.acceleration[1];
     acceleration[2]        = source.acceleration[2];
     orbit[0]          = source.orbit[0];
     orbit[1]          = source.orbit[1];
     orbit[2]          = source.orbit[2];
     orbit[3]          = source.orbit[3];
     orbit[4]          = source.orbit[4];
     orbit[5]          = source.orbit[5];
     orbit[6]          = source.orbit[6];
     sasEnabled        = source.sasEnabled;
     autopilotMode     = source.autopilotMode;
     lockedRotation[0] = source.lockedRotation[0];
     lockedRotation[1] = source.lockedRotation[1];
     lockedRotation[2] = source.lockedRotation[2];
     lockedRotation[3] = source.lockedRotation[3];
 }
Beispiel #11
0
 public void Update()
 {
     foreach (Guid vesselID in currentVesselUpdates.Keys)
     {
         //Not sure if this can happen, but we don't want to apply updates to vessels we are supposed to be updating.
         if (lockSystem.LockIsOurs("update-" + vesselID))
         {
             continue;
         }
         Vessel updateVessel = FlightGlobals.fetch.vessels.Find(v => v.id == vesselID);
         if (updateVessel == null)
         {
             continue;
         }
         if (!updateVessel.packed && !dmpSettings.interframeEnabled)
         {
             return;
         }
         if (dmpSettings.interpolatorType == InterpolatorType.DISABLED)
         {
             return;
         }
         VesselUpdate vu = currentVesselUpdates[vesselID];
         VesselUpdate pu = null;
         if (previousVesselUpdates.ContainsKey(vesselID))
         {
             pu = previousVesselUpdates[vesselID];
         }
         VesselUpdate nu = null;
         if (nextVesselUpdates.ContainsKey(vesselID))
         {
             nu = nextVesselUpdates[vesselID];
         }
         //Apply updates for up to 5 seconds
         double timeDiff = Planetarium.GetUniversalTime() - vu.planetTime;
         if (timeDiff < 5f && timeDiff > -5f)
         {
             vu.Apply(posistionStatistics, null, pu, nu, dmpSettings);
         }
     }
 }
        private void ApplyVesselUpdate(VesselUpdate update)
        {
            if (HighLogic.LoadedScene == GameScenes.LOADING)
            {
                return;
            }
            //Get updating player
            string updatePlayer = LockSystem.fetch.LockExists(update.vesselID) ? LockSystem.fetch.LockOwner(update.vesselID) : "Unknown";
            //Ignore updates to our own vessel if we are in flight and we aren't spectating
            if (!isSpectating && (FlightGlobals.fetch.activeVessel != null ? FlightGlobals.fetch.activeVessel.id.ToString() == update.vesselID : false) && HighLogic.LoadedScene == GameScenes.FLIGHT)
            {
                DarkLog.Debug("ApplyVesselUpdate - Ignoring update for active vessel from " + updatePlayer);
                return;
            }
            Vessel updateVessel = FlightGlobals.fetch.vessels.FindLast(v => v.id.ToString() == update.vesselID);
            if (updateVessel == null)
            {
                //DarkLog.Debug("ApplyVesselUpdate - Got vessel update for " + update.vesselID + " but vessel does not exist");
                return;
            }
            CelestialBody updateBody = FlightGlobals.Bodies.Find(b => b.bodyName == update.bodyName);
            if (updateBody == null)
            {
                DarkLog.Debug("ApplyVesselUpdate - updateBody not found");
                return;
            }

            //Rotation
            Quaternion updateRotation = new Quaternion(update.rotation[0], update.rotation[1], update.rotation[2], update.rotation[3]);
            updateVessel.SetRotation(updateVessel.mainBody.bodyTransform.rotation * updateRotation);

            //Position/Velocity
            if (update.isSurfaceUpdate)
            {
                //Get the new position/velocity
                Vector3d updatePostion = updateBody.GetWorldSurfacePosition(update.position[0], update.position[1], update.position[2]);
                Vector3d updateVelocity = updateBody.bodyTransform.rotation * new Vector3d(update.velocity[0], update.velocity[1], update.velocity[2]);
                //Figure out how far away we are if we can
                double updateDistance = Double.PositiveInfinity;
                if ((HighLogic.LoadedScene == GameScenes.FLIGHT) && (FlightGlobals.fetch.activeVessel != null))
                {
                    if (FlightGlobals.fetch.activeVessel.mainBody == updateVessel.mainBody)
                    {
                        Vector3d ourPos = FlightGlobals.fetch.activeVessel.mainBody.GetWorldSurfacePosition(FlightGlobals.fetch.activeVessel.latitude, FlightGlobals.fetch.activeVessel.longitude, FlightGlobals.fetch.activeVessel.altitude);
                        Vector3d theirPos = updateVessel.mainBody.GetWorldSurfacePosition(updateVessel.latitude, updateVessel.longitude, updateVessel.altitude);
                        updateDistance = Vector3.Distance(ourPos, theirPos);
                    }
                }
                bool isLoading = (updateDistance < Vessel.loadDistance) && !updateVessel.loaded;
                bool isUnpacking = (updateDistance < updateVessel.distanceUnpackThreshold) && updateVessel.packed && updateVessel.loaded;
                if (updateVessel.HoldPhysics)
                {
                    //DarkLog.Debug("Skipping update, physics held");
                    return;
                }
                //Don't set the position while the vessel is unpacking / loading - It doesn't apply properly.
                if (isUnpacking || isLoading)
                {
                    //DarkLog.Debug("Skipping update, isUnpacking: " + isUnpacking + " isLoading: " + isLoading);
                    return;
                }
                if (updateVessel.packed)
                {
                    updateVessel.latitude = update.position[0];
                    updateVessel.longitude = update.position[1];
                    updateVessel.altitude = update.position[2];
                    if (!updateVessel.LandedOrSplashed)
                    {
                        //Not landed but under 10km.
                        Vector3d orbitalPos = updatePostion - updateBody.position;
                        Vector3d surfaceOrbitVelDiff = updateBody.getRFrmVel(updatePostion);
                        Vector3d orbitalVel = updateVelocity + surfaceOrbitVelDiff;
                        updateVessel.orbitDriver.orbit.UpdateFromStateVectors(orbitalPos.xzy, orbitalVel.xzy, updateBody, Planetarium.GetUniversalTime());
                        updateVessel.orbitDriver.pos = updateVessel.orbitDriver.orbit.pos.xzy;
                        updateVessel.orbitDriver.vel = updateVessel.orbitDriver.orbit.vel;
                        /*
                        DarkLog.Debug("updateVelocity: " + (Vector3)updateVelocity + ", |vel| " + updateVelocity.magnitude);
                        DarkLog.Debug("surfaceOrbitVelDiff: " + (Vector3)surfaceOrbitVelDiff + ", |vel| " + surfaceOrbitVelDiff.magnitude);
                        */
                        /*
                        if (HighLogic.LoadedScene == GameScenes.FLIGHT && FlightGlobals.fetch.activeVessel != null)
                        {
                            DarkLog.Debug("ourVel: " + (Vector3)FlightGlobals.fetch.activeVessel.orbitDriver.vel + ", |vel| " + updateVessel.orbitDriver.vel.magnitude);
                        }
                        DarkLog.Debug("theirVel: " + (Vector3)updateVessel.orbitDriver.vel + ", |vel| " + updateVessel.orbitDriver.vel.magnitude);
                        */
                    }
                }
                else
                {
                    Vector3d velocityOffset = updateVelocity - updateVessel.srf_velocity;
                    updateVessel.SetPosition(updatePostion, true);
                    updateVessel.ChangeWorldVelocity(velocityOffset);
                }
            }
            else
            {
                Orbit updateOrbit = new Orbit(update.orbit[0], update.orbit[1], update.orbit[2], update.orbit[3], update.orbit[4], update.orbit[5], update.orbit[6], updateBody);
                updateOrbit.Init();
                updateOrbit.UpdateFromUT(Planetarium.GetUniversalTime());

                if (updateVessel.packed)
                {
                    //The OrbitDriver update call will set the vessel position on the next fixed update
                    CopyOrbit(updateOrbit, updateVessel.orbitDriver.orbit);
                    updateVessel.orbitDriver.pos = updateVessel.orbitDriver.orbit.pos.xzy;
                    updateVessel.orbitDriver.vel = updateVessel.orbitDriver.orbit.vel;
                }
                else
                {
                    //Vessel.SetPosition is full of fun and games. Avoid at all costs.
                    //Also, It's quite difficult to figure out the world velocity due to Krakensbane, and the reference frame.
                    Vector3d posDelta = updateOrbit.getPositionAtUT(Planetarium.GetUniversalTime()) - updateVessel.orbitDriver.orbit.getPositionAtUT(Planetarium.GetUniversalTime());
                    Vector3d velDelta = updateOrbit.getOrbitalVelocityAtUT(Planetarium.GetUniversalTime()).xzy - updateVessel.orbitDriver.orbit.getOrbitalVelocityAtUT(Planetarium.GetUniversalTime()).xzy;
                    //Vector3d velDelta = updateOrbit.vel.xzy - updateVessel.orbitDriver.orbit.vel.xzy;
                    updateVessel.Translate(posDelta);
                    updateVessel.ChangeWorldVelocity(velDelta);
                }
            }

            //Angular velocity
            Vector3 angularVelocity = new Vector3(update.angularVelocity[0], update.angularVelocity[1], update.angularVelocity[2]);
            if (updateVessel.parts != null)
            {
                Vector3 newAng = updateVessel.ReferenceTransform.rotation * angularVelocity;
                foreach (Part vesselPart in updateVessel.parts)
                {
                    if (vesselPart.rb != null && !vesselPart.rb.isKinematic && vesselPart.State == PartStates.ACTIVE)
                    {
                        //The parts can have different rotations - This transforms them into the root part direction which is where the angular velocity is transferred.
                        vesselPart.rb.angularVelocity = (Quaternion.Inverse(updateVessel.rootPart.rb.rotation) * vesselPart.rb.rotation) * newAng;
                    }
                }
            }

            //Flight state controls (Throttle etc)
            if (!isSpectating)
            {
                updateVessel.ctrlState.CopyFrom(update.flightState);
            }
            else
            {
                FlightInputHandler.state.CopyFrom(update.flightState);
            }

            //Action group controls
            updateVessel.ActionGroups.SetGroup(KSPActionGroup.Gear, update.actiongroupControls[0]);
            updateVessel.ActionGroups.SetGroup(KSPActionGroup.Light, update.actiongroupControls[1]);
            updateVessel.ActionGroups.SetGroup(KSPActionGroup.Brakes, update.actiongroupControls[2]);
            updateVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, update.actiongroupControls[3]);
            updateVessel.ActionGroups.SetGroup(KSPActionGroup.RCS, update.actiongroupControls[4]);
        }
Beispiel #13
0
        public void Apply(PosistionStatistics posistionStatistics, Dictionary <Guid, VesselCtrlUpdate> ctrlUpdate, VesselUpdate previousUpdate, VesselUpdate nextUpdate, Settings dmpSettings)
        {
            if (HighLogic.LoadedScene == GameScenes.LOADING)
            {
                return;
            }

            //Ignore updates to our own vessel if we are in flight and we aren't spectating
            if (!vesselWorker.isSpectating && (FlightGlobals.fetch.activeVessel != null ? FlightGlobals.fetch.activeVessel.id == vesselID : false) && HighLogic.LoadedScene == GameScenes.FLIGHT)
            {
                return;
            }
            Vessel updateVessel = FlightGlobals.fetch.vessels.FindLast(v => v.id == vesselID);

            if (updateVessel == null)
            {
                //DarkLog.Debug("ApplyVesselUpdate - Got vessel update for " + vesselID + " but vessel does not exist");
                return;
            }
            CelestialBody updateBody = FlightGlobals.Bodies.Find(b => b.bodyName == bodyName);

            if (updateBody == null)
            {
                //DarkLog.Debug("ApplyVesselUpdate - updateBody not found");
                return;
            }

            double interpolatorDelay = 0f;

            if (dmpSettings.interpolatorType == InterpolatorType.INTERPOLATE1S)
            {
                interpolatorDelay = 1f;
            }
            if (dmpSettings.interpolatorType == InterpolatorType.INTERPOLATE3S)
            {
                interpolatorDelay = 3f;
            }

            bool interpolatorEnabled = dmpSettings.interpolatorType == InterpolatorType.INTERPOLATE1S || dmpSettings.interpolatorType == InterpolatorType.INTERPOLATE3S;
            bool extrapolatorEnabled = dmpSettings.interpolatorType == InterpolatorType.EXTRAPOLATE_NO_ROT || dmpSettings.interpolatorType == InterpolatorType.EXTRAPOLATE_FULL;

            Quaternion normalRotate = Quaternion.identity;
            Vector3    oldPos       = updateVessel.GetWorldPos3D();
            Vector3    oldVelocity  = updateVessel.orbitDriver.orbit.GetVel();

            //Position/Velocity
            if (isSurfaceUpdate)
            {
                //Get the new position/velocity
                double altitudeFudge = 0;
                VesselUtil.DMPRaycastPair dmpRaycast = VesselUtil.RaycastGround(position[0], position[1], updateBody);
                if (dmpRaycast.altitude != -1d && position[3] != -1d)
                {
                    Vector3 theirNormal = new Vector3(terrainNormal[0], terrainNormal[1], terrainNormal[2]);
                    altitudeFudge = dmpRaycast.altitude - position[3];
                    if (Math.Abs(position[2] - position[3]) < 50f)
                    {
                        normalRotate = Quaternion.FromToRotation(theirNormal, dmpRaycast.terrainNormal);
                    }
                }

                Vector3d updateAcceleration = updateBody.bodyTransform.rotation * new Vector3d(acceleration[0], acceleration[1], acceleration[2]);
                Vector3d updateVelocity     = updateBody.bodyTransform.rotation * new Vector3d(velocity[0], velocity[1], velocity[2]);
                Vector3d updatePostion      = updateBody.GetWorldSurfacePosition(position[0], position[1], position[2] + altitudeFudge);
                Vector3d newUpdatePostion   = updatePostion;
                Vector3d newUpdateVelocity  = updateVelocity;

                double planetariumDifference = Planetarium.GetUniversalTime() - (planetTime + interpolatorDelay);

                if (extrapolatorEnabled)
                {
                    if (Math.Abs(planetariumDifference) < 3f)
                    {
                        if (dmpSettings.interpolatorType == InterpolatorType.EXTRAPOLATE_NO_ROT || previousUpdate == null)
                        {
                            StepExtrapolate(updatePostion, updateVelocity, updateAcceleration, planetariumDifference, out newUpdatePostion, out newUpdateVelocity);
                        }
                        if (dmpSettings.interpolatorType == InterpolatorType.EXTRAPOLATE_FULL && previousUpdate != null)
                        {
                            StepExtrapolateWithRotation(previousUpdate, updatePostion, updateVelocity, updateAcceleration, planetariumDifference, out newUpdatePostion, out newUpdateVelocity);
                        }
                    }
                }

                if (interpolatorEnabled && nextUpdate != null && (Math.Abs(nextUpdate.planetTime - Planetarium.GetUniversalTime())) < 5f)
                {
                    double   scaling      = (Planetarium.GetUniversalTime() - interpolatorDelay - planetTime) / (nextUpdate.planetTime - planetTime);
                    Vector3d nextPosition = updateBody.GetWorldSurfacePosition(nextUpdate.position[0], nextUpdate.position[1], nextUpdate.position[2] + altitudeFudge);
                    Vector3d nextVelocity = updateBody.bodyTransform.rotation * new Vector3d(nextUpdate.velocity[0], nextUpdate.velocity[1], nextUpdate.velocity[2]);
                    newUpdatePostion  = Vector3d.Lerp(updatePostion, nextPosition, scaling);
                    newUpdateVelocity = Vector3d.Lerp(updateVelocity, nextVelocity, scaling);
                }

                Vector3d orbitalPos          = newUpdatePostion - updateBody.position;
                Vector3d surfaceOrbitVelDiff = updateBody.getRFrmVel(newUpdatePostion);
                Vector3d orbitalVel          = newUpdateVelocity + surfaceOrbitVelDiff;
                updateVessel.orbitDriver.orbit.UpdateFromStateVectors(orbitalPos.xzy, orbitalVel.xzy, updateBody, Planetarium.GetUniversalTime());
            }
            else
            {
                updateVessel.orbit.SetOrbit(orbit[0], orbit[1], orbit[2], orbit[3], orbit[4], orbit[5], orbit[6], updateBody);
            }
            //Updates orbit.pos/vel
            updateVessel.orbitDriver.orbit.UpdateFromOrbitAtUT(updateVessel.orbitDriver.orbit, Planetarium.GetUniversalTime(), updateBody);

            //Updates vessel pos from the orbit, as if on rails
            updateVessel.orbitDriver.updateFromParameters();

            //Rotation
            Quaternion unfudgedRotation = new Quaternion(rotation[0], rotation[1], rotation[2], rotation[3]);

            //Rotation extrapolation? :O
            if (previousUpdate != null && (extrapolatorEnabled || (interpolatorEnabled && !isSurfaceUpdate)))
            {
                double deltaUpdateT = planetTime - previousUpdate.planetTime;
                double deltaRealT   = Planetarium.GetUniversalTime() - previousUpdate.planetTime;
                float  scaling      = (float)(deltaRealT / deltaUpdateT);
                if (Math.Abs(deltaRealT) < 3f)
                {
                    Quaternion previousRotation = new Quaternion(previousUpdate.rotation[0], previousUpdate.rotation[1], previousUpdate.rotation[2], previousUpdate.rotation[3]);
                    unfudgedRotation = RotationLerp(previousRotation, unfudgedRotation, scaling);
                }
            }

            if (nextUpdate != null && interpolatorEnabled && isSurfaceUpdate)
            {
                double deltaUpdateT = nextUpdate.planetTime - planetTime;
                double deltaRealT   = Planetarium.GetUniversalTime() - interpolatorDelay - planetTime;
                float  scaling      = (float)(deltaRealT / deltaUpdateT);
                if (Math.Abs(deltaRealT) < 3f)
                {
                    Quaternion nextRotation = new Quaternion(nextUpdate.rotation[0], nextUpdate.rotation[1], nextUpdate.rotation[2], nextUpdate.rotation[3]);
                    unfudgedRotation = RotationLerp(unfudgedRotation, nextRotation, scaling);
                }
            }

            Quaternion updateRotation = normalRotate * unfudgedRotation;
            //Rotational error tracking
            double rotationalError = Quaternion.Angle(updateVessel.srfRelRotation, updateRotation);

            updateVessel.SetRotation(updateVessel.mainBody.bodyTransform.rotation * updateRotation);
            updateVessel.srfRelRotation = updateRotation;

            Vector3 angularVel = updateVessel.ReferenceTransform.rotation * new Vector3(angularVelocity[0], angularVelocity[1], angularVelocity[2]);

            if (updateVessel.parts != null && !updateVessel.packed)
            {
                for (int i = 0; i < updateVessel.parts.Count; i++)
                {
                    Part thisPart = updateVessel.parts[i];
                    thisPart.vel = updateVessel.orbit.GetVel() - Krakensbane.GetFrameVelocity();
                    if (thisPart.orbit.referenceBody.inverseRotation)
                    {
                        thisPart.vel -= updateBody.getRFrmVel(thisPart.partTransform.position);
                    }
                    if (thisPart.rb != null && thisPart.State != PartStates.DEAD)
                    {
                        thisPart.rb.velocity = thisPart.vel;
                        //Angular Vel
                        thisPart.rb.angularVelocity = angularVel;
                        if (thisPart != updateVessel.rootPart)
                        {
                            Vector3 diffPos           = thisPart.rb.position - updateVessel.CoM;
                            Vector3 partVelDifference = Vector3.Cross(angularVel, diffPos);
                            thisPart.rb.velocity = thisPart.rb.velocity + partVelDifference;
                        }
                    }
                }
            }

            //Updates Vessel.CoMD, which is used for GetWorldPos3D
            updateVessel.precalc.CalculatePhysicsStats();
            updateVessel.latitude  = updateBody.GetLatitude(updateVessel.GetWorldPos3D());
            updateVessel.longitude = updateBody.GetLongitude(updateVessel.GetWorldPos3D());
            updateVessel.altitude  = updateBody.GetAltitude(updateVessel.GetWorldPos3D());

            double distanceError = Vector3d.Distance(oldPos, updateVessel.GetWorldPos3D());
            double velocityError = Vector3d.Distance(oldVelocity, updateVessel.orbitDriver.orbit.GetVel());

            if (ctrlUpdate != null)
            {
                if (ctrlUpdate.ContainsKey(updateVessel.id))
                {
                    updateVessel.OnFlyByWire -= ctrlUpdate[updateVessel.id].UpdateControls;
                    ctrlUpdate.Remove(updateVessel.id);
                }
                VesselCtrlUpdate vcu = new VesselCtrlUpdate(updateVessel, ctrlUpdate, planetTime + 5, flightState);
                ctrlUpdate.Add(updateVessel.id, vcu);
                updateVessel.OnFlyByWire += vcu.UpdateControls;
            }

            //Action group controls
            updateVessel.ActionGroups.SetGroup(KSPActionGroup.Gear, actiongroupControls[0]);
            updateVessel.ActionGroups.SetGroup(KSPActionGroup.Light, actiongroupControls[1]);
            updateVessel.ActionGroups.SetGroup(KSPActionGroup.Brakes, actiongroupControls[2]);
            updateVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, actiongroupControls[3]);
            updateVessel.ActionGroups.SetGroup(KSPActionGroup.RCS, actiongroupControls[4]);

            if (sasEnabled)
            {
                updateVessel.Autopilot.SetMode((VesselAutopilot.AutopilotMode)autopilotMode);
                updateVessel.Autopilot.SAS.LockRotation(new Quaternion(lockedRotation[0], lockedRotation[1], lockedRotation[2], lockedRotation[3]));
            }
            UpdateProtovessel(updateVessel);
            posistionStatistics.LogError(updateVessel.id, distanceError, velocityError, rotationalError, planetTime);
        }
Beispiel #14
0
 public void SetVesselUpdate(Guid vesselID, VesselUpdate vesselUpdate, VesselUpdate previousUpdate, VesselUpdate nextUpdate)
 {
     nextVesselUpdates[vesselID]     = nextUpdate;
     currentVesselUpdates[vesselID]  = vesselUpdate;
     previousVesselUpdates[vesselID] = previousUpdate;
 }
Beispiel #15
0
 public void QueueVesselUpdate(int subspace, VesselUpdate update)
 {
     if (!vesselUpdateQueue.ContainsKey(subspace))
     {
         SetupSubspace(subspace);
     }
     vesselUpdateQueue[subspace].Enqueue(update);
     if (latestVesselUpdate.ContainsKey(update.vesselID) ? latestVesselUpdate[update.vesselID] < update.planetTime : true)
     {
         latestVesselUpdate[update.vesselID] = update.planetTime;
     }
 }
        private void ApplyVesselUpdate(VesselUpdate update)
        {
            if (HighLogic.LoadedScene == GameScenes.LOADING)
            {
                return;
            }
            //Get updating player
            string updatePlayer = LockSystem.fetch.LockExists(update.vesselID) ? LockSystem.fetch.LockOwner(update.vesselID) : "Unknown";
            //Ignore updates to our own vessel
            if (!isSpectating && (FlightGlobals.ActiveVessel != null ? FlightGlobals.ActiveVessel.id.ToString() == update.vesselID : false))
            {
                DarkLog.Debug("ApplyVesselUpdate - Ignoring update for active vessel from " + updatePlayer);
                return;
            }
            Vessel updateVessel = FlightGlobals.fetch.vessels.FindLast(v => v.id.ToString() == update.vesselID);
            if (updateVessel == null)
            {
                //DarkLog.Debug("ApplyVesselUpdate - Got vessel update for " + update.vesselID + " but vessel does not exist");
                return;
            }
            CelestialBody updateBody = FlightGlobals.Bodies.Find(b => b.bodyName == update.bodyName);
            if (updateBody == null)
            {
                DarkLog.Debug("ApplyVesselUpdate - updateBody not found");
                return;
            }
            if (update.isSurfaceUpdate)
            {
                double updateDistance = Double.PositiveInfinity;
                if ((HighLogic.LoadedScene == GameScenes.FLIGHT) && (FlightGlobals.fetch.activeVessel != null))
                {
                    updateDistance = Vector3.Distance(FlightGlobals.fetch.activeVessel.GetWorldPos3D(), updateVessel.GetWorldPos3D());
                }
                bool isUnpacking = (updateDistance < updateVessel.distanceUnpackThreshold) && updateVessel.packed;
                if (!updateVessel.packed && !isUnpacking)
                {
                    Vector3d updatePostion = updateBody.GetWorldSurfacePosition(update.position[0], update.position[1], update.position[2]);
                    Vector3d updateVelocity = new Vector3d(update.velocity[0], update.velocity[1], update.velocity[2]);
                    Vector3d velocityOffset = updateVelocity - updateVessel.srf_velocity;
                    updateVessel.SetPosition(updatePostion);
                    updateVessel.ChangeWorldVelocity(velocityOffset);
                }
            }
            else
            {
                Orbit updateOrbit = new Orbit(update.orbit[0], update.orbit[1], update.orbit[2], update.orbit[3], update.orbit[4], update.orbit[5], update.orbit[6], updateBody);

                if (updateVessel.packed)
                {
                    CopyOrbit(updateOrbit, updateVessel.orbitDriver.orbit);
                }
                else
                {
                    updateVessel.SetPosition(updateOrbit.getPositionAtUT(Planetarium.GetUniversalTime()));
                    Vector3d velocityOffset = updateOrbit.getOrbitalVelocityAtUT(Planetarium.GetUniversalTime()).xzy - updateVessel.orbit.getOrbitalVelocityAtUT(Planetarium.GetUniversalTime()).xzy;
                    updateVessel.ChangeWorldVelocity(velocityOffset);
                }

            }
            //Quaternion updateRotation = new Quaternion(update.rotation[0], update.rotation[1], update.rotation[2], update.rotation[3]);
            //updateVessel.SetRotation(updateRotation);

            Vector3 vesselForward = new Vector3(update.vesselForward[0], update.vesselForward[1], update.vesselForward[2]);
            Vector3 vesselUp = new Vector3(update.vesselUp[0], update.vesselUp[1], update.vesselUp[2]);

            updateVessel.transform.LookAt(updateVessel.transform.position + updateVessel.mainBody.transform.TransformDirection(vesselForward).normalized, updateVessel.mainBody.transform.TransformDirection(vesselUp));
            updateVessel.SetRotation(updateVessel.transform.rotation);

            if (!updateVessel.packed)
            {
                updateVessel.angularVelocity = new Vector3(update.angularVelocity[0], update.angularVelocity[1], update.angularVelocity[2]);
            }
            if (!isSpectating)
            {
                updateVessel.ctrlState.CopyFrom(update.flightState);
            }
            else
            {
                FlightInputHandler.state.CopyFrom(update.flightState);
            }
            updateVessel.ActionGroups.SetGroup(KSPActionGroup.Gear, update.actiongroupControls[0]);
            updateVessel.ActionGroups.SetGroup(KSPActionGroup.Light, update.actiongroupControls[1]);
            updateVessel.ActionGroups.SetGroup(KSPActionGroup.Brakes, update.actiongroupControls[2]);
            updateVessel.ActionGroups.SetGroup(KSPActionGroup.SAS, update.actiongroupControls[3]);
            updateVessel.ActionGroups.SetGroup(KSPActionGroup.RCS, update.actiongroupControls[4]);
        }
 public void QueueVesselUpdate(VesselUpdate update)
 {
     lock (updateQueueLock)
     {
         if (!vesselUpdateQueue.ContainsKey(update.vesselID))
         {
             vesselUpdateQueue.Add(update.vesselID, new Queue<VesselUpdate>());
         }
         Queue<VesselUpdate> vuQueue = vesselUpdateQueue[update.vesselID];
         if (vesselUpdateHistoryTime.ContainsKey(update.vesselID))
         {
             //If we get an update older than the current queue peek, then someone has gone back in time and the timeline needs to be fixed.
             if (update.planetTime < vesselUpdateHistoryTime[update.vesselID])
             {
                 DarkLog.Debug("Vessel " + update.vesselID + " went back in time - rewriting the update history for it.");
                 Queue<VesselUpdate> newQueue = new Queue<VesselUpdate>();
                 while (vuQueue.Count > 0)
                 {
                     VesselUpdate oldVu = vuQueue.Dequeue();
                     //Save the updates from before the revert
                     if (oldVu.planetTime < update.planetTime)
                     {
                         newQueue.Enqueue(oldVu);
                     }
                 }
                 vuQueue = newQueue;
                 vesselUpdateQueue[update.vesselID] = newQueue;
                 //Clean the history too
                 if (Settings.fetch.revertEnabled)
                 {
                     if (vesselUpdateHistory.ContainsKey(update.vesselID))
                     {
                         List<VesselUpdate> vuh = vesselUpdateHistory[update.vesselID];
                         foreach (VesselUpdate oldVu in vuh.ToArray())
                         {
                             if (oldVu.planetTime > update.planetTime)
                             {
                                 vuh.Remove(oldVu);
                             }
                         }
                     }
                 }
             }
         }
         vuQueue.Enqueue(update);
         //Mark the last update time
         if (latestVesselUpdate.ContainsKey(update.vesselID) ? latestVesselUpdate[update.vesselID] < update.planetTime : true)
         {
             latestVesselUpdate[update.vesselID] = update.planetTime;
         }
         //Revert support
         if (Settings.fetch.revertEnabled)
         {
             if (!vesselUpdateHistory.ContainsKey(update.vesselID))
             {
                 vesselUpdateHistory.Add(update.vesselID, new List<VesselUpdate>());
             }
             vesselUpdateHistory[update.vesselID].Add(update);
         }
         vesselUpdateHistoryTime[update.vesselID] = update.planetTime;
     }
 }
Beispiel #18
0
 private void HandleVesselUpdate(byte[] messageData)
 {
     VesselUpdate update = new VesselUpdate();
     using (MessageReader mr = new MessageReader(messageData, false))
     {
         int subspaceID = mr.Read<int>();
         update.planetTime = mr.Read<double>();
         update.vesselID = mr.Read<string>();
         update.bodyName = mr.Read<string>();
         //update.rotation = mr.Read<float[]>();
         update.vesselForward = mr.Read<float[]>();
         update.vesselUp = mr.Read<float[]>();
         update.angularVelocity = mr.Read<float[]>();
         update.flightState = new FlightCtrlState();
         byte[] flightData = mr.Read<byte[]>();
         using (MemoryStream ms = new MemoryStream(flightData))
         {
             ConfigNode flightNode;
             BinaryFormatter bf = new BinaryFormatter();
             flightNode = (ConfigNode)bf.Deserialize(ms);
             update.flightState.Load(flightNode);
         }
         update.actiongroupControls = mr.Read<bool[]>();
         update.isSurfaceUpdate = mr.Read<bool>();
         if (update.isSurfaceUpdate)
         {
             update.position = mr.Read<double[]>();
             update.velocity = mr.Read<double[]>();
         }
         else
         {
             update.orbit = mr.Read<double[]>();
         }
         VesselWorker.fetch.QueueVesselUpdate(subspaceID, update);
     }
 }
Beispiel #19
0
 //Called from vesselWorker
 public void SendVesselUpdate(VesselUpdate update)
 {
     ClientMessage newMessage = new ClientMessage();
     newMessage.type = ClientMessageType.VESSEL_UPDATE;
     using (MessageWriter mw = new MessageWriter())
     {
         mw.Write<int>(TimeSyncer.fetch.currentSubspace);
         mw.Write<double>(update.planetTime);
         mw.Write<string>(update.vesselID);
         mw.Write<string>(update.bodyName);
         //mw.Write<float[]>(update.rotation);
         mw.Write<float[]>(update.vesselForward);
         mw.Write<float[]>(update.vesselUp);
         mw.Write<float[]>(update.angularVelocity);
         using (MemoryStream ms = new MemoryStream())
         {
             ConfigNode flightNode = new ConfigNode();
             update.flightState.Save(flightNode);
             BinaryFormatter bf = new BinaryFormatter();
             bf.Serialize(ms, flightNode);
             mw.Write<byte[]>(ms.ToArray());
         }
         mw.Write<bool[]>(update.actiongroupControls);
         mw.Write<bool>(update.isSurfaceUpdate);
         if (update.isSurfaceUpdate)
         {
             mw.Write<double[]>(update.position);
             mw.Write<double[]>(update.velocity);
         }
         else
         {
             mw.Write<double[]>(update.orbit);
         }
         newMessage.data = mw.GetMessageBytes();
     }
     sendMessageQueueLow.Enqueue(newMessage);
 }
 private void HandleVesselUpdate(byte[] messageData)
 {
     VesselUpdate update = new VesselUpdate();
     using (MessageReader mr = new MessageReader(messageData, false))
     {
         update.planetTime = mr.Read<double>();
         update.vesselID = mr.Read<string>();
         update.bodyName = mr.Read<string>();
         update.rotation = mr.Read<float[]>();
         update.angularVelocity = mr.Read<float[]>();
         //FlightState variables
         update.flightState = new FlightCtrlState();
         update.flightState.mainThrottle = mr.Read<float>();
         update.flightState.wheelThrottleTrim = mr.Read<float>();
         update.flightState.X = mr.Read<float>();
         update.flightState.Y = mr.Read<float>();
         update.flightState.Z = mr.Read<float>();
         update.flightState.killRot = mr.Read<bool>();
         update.flightState.gearUp = mr.Read<bool>();
         update.flightState.gearDown = mr.Read<bool>();
         update.flightState.headlight = mr.Read<bool>();
         update.flightState.wheelThrottle = mr.Read<float>();
         update.flightState.fastThrottle = mr.Read<float>();
         update.flightState.roll = mr.Read<float>();
         update.flightState.yaw = mr.Read<float>();
         update.flightState.pitch = mr.Read<float>();
         update.flightState.rollTrim = mr.Read<float>();
         update.flightState.yawTrim = mr.Read<float>();
         update.flightState.pitchTrim = mr.Read<float>();
         update.flightState.wheelSteer = mr.Read<float>();
         update.flightState.wheelSteerTrim = mr.Read<float>();
         //Action group controls
         update.actiongroupControls = mr.Read<bool[]>();
         //Position/velocity
         update.isSurfaceUpdate = mr.Read<bool>();
         if (update.isSurfaceUpdate)
         {
             update.position = mr.Read<double[]>();
             update.velocity = mr.Read<double[]>();
         }
         else
         {
             update.orbit = mr.Read<double[]>();
         }
         VesselWorker.fetch.QueueVesselUpdate(update);
     }
 }
Beispiel #21
0
        public static VesselUpdate CopyFromVessel(VesselWorker vesselWorker, Vessel updateVessel)
        {
            VesselUpdate returnUpdate = new VesselUpdate(vesselWorker);

            try
            {
                returnUpdate.vesselID   = updateVessel.id;
                returnUpdate.planetTime = Planetarium.GetUniversalTime();
                returnUpdate.bodyName   = updateVessel.mainBody.bodyName;

                returnUpdate.rotation    = new float[4];
                returnUpdate.rotation[0] = updateVessel.srfRelRotation.x;
                returnUpdate.rotation[1] = updateVessel.srfRelRotation.y;
                returnUpdate.rotation[2] = updateVessel.srfRelRotation.z;
                returnUpdate.rotation[3] = updateVessel.srfRelRotation.w;

                returnUpdate.angularVelocity    = new float[3];
                returnUpdate.angularVelocity[0] = updateVessel.angularVelocity.x;
                returnUpdate.angularVelocity[1] = updateVessel.angularVelocity.y;
                returnUpdate.angularVelocity[2] = updateVessel.angularVelocity.z;
                //Flight state
                returnUpdate.flightState = new FlightCtrlState();
                returnUpdate.flightState.CopyFrom(updateVessel.ctrlState);
                returnUpdate.actiongroupControls    = new bool[5];
                returnUpdate.actiongroupControls[0] = updateVessel.ActionGroups[KSPActionGroup.Gear];
                returnUpdate.actiongroupControls[1] = updateVessel.ActionGroups[KSPActionGroup.Light];
                returnUpdate.actiongroupControls[2] = updateVessel.ActionGroups[KSPActionGroup.Brakes];
                returnUpdate.actiongroupControls[3] = updateVessel.ActionGroups[KSPActionGroup.SAS];
                returnUpdate.actiongroupControls[4] = updateVessel.ActionGroups[KSPActionGroup.RCS];

                if (updateVessel.altitude < 10000)
                {
                    //Use surface position under 10k
                    returnUpdate.isSurfaceUpdate = true;
                    returnUpdate.position        = new double[4];
                    returnUpdate.position[0]     = updateVessel.latitude;
                    returnUpdate.position[1]     = updateVessel.longitude;
                    returnUpdate.position[2]     = updateVessel.altitude;
                    VesselUtil.DMPRaycastPair groundRaycast = VesselUtil.RaycastGround(updateVessel.latitude, updateVessel.longitude, updateVessel.mainBody);
                    returnUpdate.position[3]      = groundRaycast.altitude;
                    returnUpdate.terrainNormal    = new float[3];
                    returnUpdate.terrainNormal[0] = groundRaycast.terrainNormal.x;
                    returnUpdate.terrainNormal[1] = groundRaycast.terrainNormal.y;
                    returnUpdate.terrainNormal[2] = groundRaycast.terrainNormal.z;
                    returnUpdate.velocity         = new double[3];
                    Vector3d srfVel = Quaternion.Inverse(updateVessel.mainBody.bodyTransform.rotation) * updateVessel.srf_velocity;
                    returnUpdate.velocity[0]  = srfVel.x;
                    returnUpdate.velocity[1]  = srfVel.y;
                    returnUpdate.velocity[2]  = srfVel.z;
                    returnUpdate.acceleration = new double[3];
                    Vector3d srfAcceleration = Quaternion.Inverse(updateVessel.mainBody.bodyTransform.rotation) * updateVessel.acceleration;
                    returnUpdate.acceleration[0] = srfAcceleration.x;
                    returnUpdate.acceleration[1] = srfAcceleration.y;
                    returnUpdate.acceleration[2] = srfAcceleration.z;
                }
                else
                {
                    //Use orbital positioning over 10k
                    returnUpdate.isSurfaceUpdate = false;
                    returnUpdate.orbit           = new double[7];
                    returnUpdate.orbit[0]        = updateVessel.orbit.inclination;
                    returnUpdate.orbit[1]        = updateVessel.orbit.eccentricity;
                    returnUpdate.orbit[2]        = updateVessel.orbit.semiMajorAxis;
                    returnUpdate.orbit[3]        = updateVessel.orbit.LAN;
                    returnUpdate.orbit[4]        = updateVessel.orbit.argumentOfPeriapsis;
                    returnUpdate.orbit[5]        = updateVessel.orbit.meanAnomalyAtEpoch;
                    returnUpdate.orbit[6]        = updateVessel.orbit.epoch;
                }
                returnUpdate.sasEnabled = updateVessel.Autopilot.Enabled;
                if (returnUpdate.sasEnabled)
                {
                    returnUpdate.autopilotMode     = (int)updateVessel.Autopilot.Mode;
                    returnUpdate.lockedRotation    = new float[4];
                    returnUpdate.lockedRotation[0] = updateVessel.Autopilot.SAS.lockedRotation.x;
                    returnUpdate.lockedRotation[1] = updateVessel.Autopilot.SAS.lockedRotation.y;
                    returnUpdate.lockedRotation[2] = updateVessel.Autopilot.SAS.lockedRotation.z;
                    returnUpdate.lockedRotation[3] = updateVessel.Autopilot.SAS.lockedRotation.w;
                }
            }
            catch (Exception e)
            {
                DarkLog.Debug("Failed to get vessel update, exception: " + e);
                returnUpdate = null;
            }
            return(returnUpdate);
        }
 //Called from vesselWorker
 public void SendVesselUpdate(VesselUpdate update)
 {
     ClientMessage newMessage = new ClientMessage();
     newMessage.type = ClientMessageType.VESSEL_UPDATE;
     using (MessageWriter mw = new MessageWriter())
     {
         mw.Write<double>(update.planetTime);
         mw.Write<string>(update.vesselID);
         mw.Write<string>(update.bodyName);
         mw.Write<float[]>(update.rotation);
         //mw.Write<float[]>(update.vesselForward);
         //mw.Write<float[]>(update.vesselUp);
         mw.Write<float[]>(update.angularVelocity);
         //FlightState variables
         mw.Write<float>(update.flightState.mainThrottle);
         mw.Write<float>(update.flightState.wheelThrottleTrim);
         mw.Write<float>(update.flightState.X);
         mw.Write<float>(update.flightState.Y);
         mw.Write<float>(update.flightState.Z);
         mw.Write<bool>(update.flightState.killRot);
         mw.Write<bool>(update.flightState.gearUp);
         mw.Write<bool>(update.flightState.gearDown);
         mw.Write<bool>(update.flightState.headlight);
         mw.Write<float>(update.flightState.wheelThrottle);
         mw.Write<float>(update.flightState.fastThrottle);
         mw.Write<float>(update.flightState.roll);
         mw.Write<float>(update.flightState.yaw);
         mw.Write<float>(update.flightState.pitch);
         mw.Write<float>(update.flightState.rollTrim);
         mw.Write<float>(update.flightState.yawTrim);
         mw.Write<float>(update.flightState.pitchTrim);
         mw.Write<float>(update.flightState.wheelSteer);
         mw.Write<float>(update.flightState.wheelSteerTrim);
         //Action group controls
         mw.Write<bool[]>(update.actiongroupControls);
         //Position/velocity
         mw.Write<bool>(update.isSurfaceUpdate);
         if (update.isSurfaceUpdate)
         {
             mw.Write<double[]>(update.position);
             mw.Write<double[]>(update.velocity);
         }
         else
         {
             mw.Write<double[]>(update.orbit);
         }
         newMessage.data = mw.GetMessageBytes();
     }
     QueueOutgoingMessage(newMessage, false);
 }
 public void QueueVesselUpdate(VesselUpdate update)
 {
     lock (updateQueueLock)
     {
         if (!vesselUpdateQueue.ContainsKey(update.vesselID))
         {
             vesselUpdateQueue.Add(update.vesselID, new Queue<VesselUpdate>());
         }
         vesselUpdateQueue[update.vesselID].Enqueue(update);
         if (latestVesselUpdate.ContainsKey(update.vesselID) ? latestVesselUpdate[update.vesselID] < update.planetTime : true)
         {
             latestVesselUpdate[update.vesselID] = update.planetTime;
         }
     }
 }
        public void StartPlayback()
        {
            int       messagesLoaded = 0;
            bool      firstMessage   = true;
            ByteArray headerBytes    = ByteRecycler.GetObject(8);

            using (FileStream fs = new FileStream(recordPath, FileMode.Open))
            {
                while (fs.Position < fs.Length)
                {
                    messagesLoaded++;
                    fs.Read(headerBytes.data, 0, 8);
                    using (MessageReader mr = new MessageReader(headerBytes.data))
                    {
                        ClientMessageType messageType = (ClientMessageType)mr.Read <int>();
                        int       length    = mr.Read <int>();
                        ByteArray dataBytes = ByteRecycler.GetObject(length);
                        fs.Read(dataBytes.data, 0, length);
                        using (MessageReader timeReader = new MessageReader(dataBytes.data))
                        {
                            //Planet time is the first part of the message for the three types we care about here
                            double planetTime = timeReader.Read <double>();
                            lastTime = planetTime;
                            if (firstMessage)
                            {
                                firstTime    = planetTime;
                                firstMessage = false;
                                Planetarium.SetUniversalTime(planetTime - 5d);
                                warpWorker.SendNewSubspace();
                            }
                        }
                        using (MessageReader mrignore = new MessageReader(dataBytes.data))
                        {
                            //Planet time, don't care here
                            mrignore.Read <double>();
                            string vesselID = mrignore.Read <string>();
                            vesselWorker.IgnoreVessel(new Guid(vesselID));
                        }
                        switch (messageType)
                        {
                        case ClientMessageType.VESSEL_PROTO:
                            HandleProtoUpdate(dataBytes);
                            break;

                        case ClientMessageType.VESSEL_UPDATE:
                            HandleVesselUpdate(dataBytes, false);
                            break;

                        case ClientMessageType.VESSEL_REMOVE:
                            HandleVesselRemove(dataBytes);
                            break;

                        default:
                            break;
                        }
                        ByteRecycler.ReleaseObject(dataBytes);
                    }
                }
                ByteRecycler.ReleaseObject(headerBytes);
            }

            playbackQueue = new Queue <VesselUpdate>();
            using (FileStream fs = new FileStream(recordVectorPath, FileMode.Open))
            {
                while (fs.Position < fs.Length)
                {
                    fs.Read(headerBytesInt, 0, 4);
                    if (BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(headerBytesInt);
                    }
                    int       updateLength = BitConverter.ToInt32(headerBytesInt, 0);
                    ByteArray updateBytes  = ByteRecycler.GetObject(updateLength);
                    fs.Read(updateBytes.data, 0, updateLength);
                    VesselUpdate vu = networkWorker.VeselUpdateFromBytes(updateBytes.data, false);
                    playbackQueue.Enqueue(vu);
                    ByteRecycler.ReleaseObject(updateBytes);
                }
            }

            ScreenMessages.PostScreenMessage("Loaded " + messagesLoaded + " saved updates.", 5f, ScreenMessageStyle.UPPER_CENTER);
            screenMessage = ScreenMessages.PostScreenMessage("Playback 0 / " + (int)(lastTime - firstTime) + " seconds.", float.MaxValue, ScreenMessageStyle.UPPER_CENTER);
            playback      = true;
        }
        private VesselUpdate GetVesselUpdate(Vessel updateVessel)
        {
            VesselUpdate returnUpdate = new VesselUpdate();
            try
            {
                returnUpdate.vesselID = updateVessel.id.ToString();
                returnUpdate.planetTime = Planetarium.GetUniversalTime();
                returnUpdate.bodyName = updateVessel.mainBody.bodyName;

                returnUpdate.rotation = new float[4];
                returnUpdate.rotation[0] = updateVessel.srfRelRotation.x;
                returnUpdate.rotation[1] = updateVessel.srfRelRotation.y;
                returnUpdate.rotation[2] = updateVessel.srfRelRotation.z;
                returnUpdate.rotation[3] = updateVessel.srfRelRotation.w;

                returnUpdate.angularVelocity = new float[3];
                returnUpdate.angularVelocity[0] = updateVessel.angularVelocity.x;
                returnUpdate.angularVelocity[1] = updateVessel.angularVelocity.y;
                returnUpdate.angularVelocity[2] = updateVessel.angularVelocity.z;
                //Flight state
                returnUpdate.flightState = new FlightCtrlState();
                returnUpdate.flightState.CopyFrom(updateVessel.ctrlState);
                returnUpdate.actiongroupControls = new bool[5];
                returnUpdate.actiongroupControls[0] = updateVessel.ActionGroups[KSPActionGroup.Gear];
                returnUpdate.actiongroupControls[1] = updateVessel.ActionGroups[KSPActionGroup.Light];
                returnUpdate.actiongroupControls[2] = updateVessel.ActionGroups[KSPActionGroup.Brakes];
                returnUpdate.actiongroupControls[3] = updateVessel.ActionGroups[KSPActionGroup.SAS];
                returnUpdate.actiongroupControls[4] = updateVessel.ActionGroups[KSPActionGroup.RCS];

                if (updateVessel.altitude < 10000)
                {
                    //Use surface position under 10k
                    returnUpdate.isSurfaceUpdate = true;
                    returnUpdate.position = new double[3];
                    returnUpdate.position[0] = updateVessel.latitude;
                    returnUpdate.position[1] = updateVessel.longitude;
                    returnUpdate.position[2] = updateVessel.altitude;
                    returnUpdate.velocity = new double[3];
                    Vector3d srfVel = Quaternion.Inverse(updateVessel.mainBody.bodyTransform.rotation) * updateVessel.srf_velocity;
                    returnUpdate.velocity[0] = srfVel.x;
                    returnUpdate.velocity[1] = srfVel.y;
                    returnUpdate.velocity[2] = srfVel.z;
                }
                else
                {
                    //Use orbital positioning over 10k
                    returnUpdate.isSurfaceUpdate = false;
                    returnUpdate.orbit = new double[7];
                    returnUpdate.orbit[0] = updateVessel.orbit.inclination;
                    returnUpdate.orbit[1] = updateVessel.orbit.eccentricity;
                    returnUpdate.orbit[2] = updateVessel.orbit.semiMajorAxis;
                    returnUpdate.orbit[3] = updateVessel.orbit.LAN;
                    returnUpdate.orbit[4] = updateVessel.orbit.argumentOfPeriapsis;
                    returnUpdate.orbit[5] = updateVessel.orbit.meanAnomalyAtEpoch;
                    returnUpdate.orbit[6] = updateVessel.orbit.epoch;
                }

            }
            catch (Exception e)
            {
                DarkLog.Debug("Failed to get vessel update, exception: " + e);
                returnUpdate = null;
            }
            return returnUpdate;
        }
Beispiel #26
0
 public void SetVesselUpdate(Guid vesselID, VesselUpdate vesselUpdate)
 {
     DarkLog.Debug("Vessel update set: " + vesselID);
     currentVesselUpdates[vesselID] = vesselUpdate;
 }