コード例 #1
0
        void get_moments()
        {
            cntrl_part_to_world = vessel.ReferenceTransform.rotation;
            world_to_cntrl_part = Quaternion.Inverse(cntrl_part_to_world);            // from world to control part rotation
            CoM      = vessel.CoM;
            MOI      = Vector3d.zero;
            AM       = Vector3d.zero;
            sum_mass = 0.0f;

            int indexing = vessel.parts.Count;

            // Get velocity
            surface_v = vessel.rb_velocityD;
            sum_mass  = (float)vessel.totalMass;

            // Get angular velocity
            for (int pi = 0; pi < indexing; pi++)
            {
                Part part = vessel.parts[pi];
                if (part.physicalSignificance == Part.PhysicalSignificance.NONE ||
                    part.vessel != vessel || part.State == PartStates.DEAD || part.rb == null)
                {
                    continue;
                }
                Quaternion part_to_cntrl = world_to_cntrl_part * part.transform.rotation;   // from part to root part rotation
                Vector3    moi           = Vector3d.zero;
                Vector3    am            = Vector3d.zero;
                float      mass          = part.rb.mass;
                Vector3    world_pv      = part.rb.worldCenterOfMass - CoM;
                Vector3    pv            = world_to_cntrl_part * world_pv;
                Vector3    impulse       = mass * (world_to_cntrl_part * (part.rb.velocity - surface_v));
                // from part.rb principal frame to control from part rotation
                Quaternion principal_to_cntrl = part_to_cntrl * part.rb.inertiaTensorRotation;
                // MOI of part as offsetted material point
                moi += mass * new Vector3(pv.y * pv.y + pv.z * pv.z, pv.x * pv.x + pv.z * pv.z, pv.x * pv.x + pv.y * pv.y);
                // MOI of part as rigid body
                Vector3 rotated_moi = get_rotated_moi(part.rb.inertiaTensor, principal_to_cntrl);
                moi += rotated_moi;
                // angular moment of part as offsetted material point
                am += Vector3.Cross(pv, impulse);
                // angular moment of part as rotating rigid body
                am += Vector3.Scale(rotated_moi, world_to_cntrl_part * part.rb.angularVelocity);

                MOI += moi;
                AM  -= am;                  // minus because left-handed Unity
            }
            angular_vel         = Common.divideVector(AM, MOI);
            angular_vel        -= world_to_cntrl_part * vessel.mainBody.angularVelocity; // unity physics reference frame is rotating
            surface_v          += Krakensbane.GetFrameVelocity();
            surface_v_magnitude = surface_v.magnitude;
        }
コード例 #2
0
        /// <summary>
        /// Called in OnPreAutoPilotUpdate. Do not call multiple times per physics frame or the "lastPlanetUp" vector will not be correct and VSpeed will not be calculated correctly
        /// Can't just leave it to a Coroutine becuase it has to be called before anything else
        /// </summary>
        public void updateAttitude()
        {
            //if (PilotAssistantFlightCore.calculateDirection)
            //findVesselFwdAxis(vRef.vesselRef);
            //else
            vesselFacingAxis = vesModule.vesselRef.transform.up;
            planetUp         = (vesModule.vesselRef.rootPart.transform.position - vesModule.vesselRef.mainBody.position).normalized;
            planetEast       = vesModule.vesselRef.mainBody.getRFrmVel(vesModule.vesselRef.findWorldCenterOfMass()).normalized;
            planetNorth      = Vector3d.Cross(planetEast, planetUp).normalized;

            // 4 frames of reference to use. Orientation, Velocity, and both of the previous parallel to the surface
            radarAlt      = vesModule.vesselRef.altitude - (vesModule.vesselRef.mainBody.ocean ? Math.Max(vesModule.vesselRef.pqsAltitude, 0) : vesModule.vesselRef.pqsAltitude);
            velocity      = vesModule.vesselRef.rootPart.Rigidbody.velocity + Krakensbane.GetFrameVelocity();
            acceleration  = (velocity - lastVelocity).magnitude / TimeWarp.fixedDeltaTime;
            acceleration *= Math.Sign(Vector3.Dot(velocity - lastVelocity, velocity));
            vertSpeed     = Vector3d.Dot(planetUp, (velocity + lastVelocity) / 2);
            lastVelocity  = velocity;

            // Velocity forward and right vectors parallel to the surface
            surfVelRight   = Vector3d.Cross(planetUp, vesModule.vesselRef.srf_velocity).normalized;
            surfVelForward = Vector3d.Cross(surfVelRight, planetUp).normalized;

            // Vessel forward and right vectors parallel to the surface
            surfVesRight   = Vector3d.Cross(planetUp, vesselFacingAxis).normalized;
            surfVesForward = Vector3d.Cross(surfVesRight, planetUp).normalized;

            obtNormal = Vector3.Cross(vesModule.vesselRef.obt_velocity, planetUp).normalized;
            obtRadial = Vector3.Cross(vesModule.vesselRef.obt_velocity, obtNormal).normalized;
            srfNormal = Vector3.Cross(vesModule.vesselRef.srf_velocity, planetUp).normalized;
            srfRadial = Vector3.Cross(vesModule.vesselRef.srf_velocity, srfNormal).normalized;

            pitch           = 90 - Vector3d.Angle(planetUp, vesselFacingAxis);
            heading         = (Vector3d.Angle(surfVesForward, planetNorth) * Math.Sign(Vector3d.Dot(surfVesForward, planetEast))).headingClamp(360);
            progradeHeading = (Vector3d.Angle(surfVelForward, planetNorth) * Math.Sign(Vector3d.Dot(surfVelForward, planetEast))).headingClamp(360);
            bank            = Vector3d.Angle(surfVesRight, vesModule.vesselRef.ReferenceTransform.right) * Math.Sign(Vector3d.Dot(surfVesRight, -vesModule.vesselRef.ReferenceTransform.forward));

            if (vesModule.vesselRef.srfSpeed > 1)
            {
                Vector3d AoAVec = vesModule.vesselRef.srf_velocity.projectOnPlane(vesModule.vesselRef.ReferenceTransform.right);
                AoA = Vector3d.Angle(AoAVec, vesselFacingAxis) * Math.Sign(Vector3d.Dot(AoAVec, vesModule.vesselRef.ReferenceTransform.forward));

                Vector3d yawVec = vesModule.vesselRef.srf_velocity.projectOnPlane(vesModule.vesselRef.ReferenceTransform.forward);
                yaw = Vector3d.Angle(yawVec, vesselFacingAxis) * Math.Sign(Vector3d.Dot(yawVec, vesModule.vesselRef.ReferenceTransform.right));
            }
            else
            {
                AoA = yaw = 0;
            }
        }
コード例 #3
0
 public void FixedUpdate()
 {
     if (TimeIndex >= 0.04 && Atmosphere < 0.05f)
     {
         transform.position = Position;
         //transform.position -= Direction * 20 * TimeWarp.fixedDeltaTime; // need a way to attach the FX to the transform to get it to travel w/ the vessel to make sure FX spawns where it needs to, but then be subject to world movement, not vessel movement, so vessel can "move away from the explosion"
     }             // do a hack with the FX having a local vel or force?
     else
     {
         if (!FloatingOrigin.Offset.IsZero() || !Krakensbane.GetFrameVelocity().IsZero())
         {
             transform.position -= FloatingOrigin.OffsetNonKrakensbane;
         }
     }
 }
コード例 #4
0
        public Vector3d GetVelocity(Vector3 refPoint)
        {
            Vector3d velocity = Vector3.zero;
            if (HighLogic.LoadedSceneIsFlight)
            {
                if (part.Rigidbody)
                    velocity += part.Rigidbody.GetPointVelocity(refPoint);

                velocity += Krakensbane.GetFrameVelocity() - Krakensbane.GetLastCorrection() * TimeWarp.fixedDeltaTime;
                velocity -= FARWind.GetWind(FlightGlobals.currentMainBody, part, part.Rigidbody.position);

                return velocity;
            }
            else
                return velocityEditor;
        }
コード例 #5
0
        public Vector3 GetVelocity(Rigidbody rigidbody, Vector3 refPoint) // from Ferram
        {
            Vector3 newVelocity = Vector3.zero;

            try
            {
                newVelocity += rigidbody.GetPointVelocity(refPoint);
                newVelocity += Krakensbane.GetFrameVelocityV3f() - Krakensbane.GetLastCorrection() * TimeWarp.fixedDeltaTime;
            }
            catch (Exception e)
            {
                Log.err("FSengineBladed GetVelocity Exception!");
                Log.ex(this, e);
            }
            return(newVelocity);
        }
コード例 #6
0
        private void UpdateWaterContact(double depth)
        {
            if (depth < 0)      //corresponds to above the ocean
            {
                if (part.WaterContact)
                {
                    part.WaterContact = false;
                    vessel.checkSplashed();
                }
                if (depthFactor < -1)
                {
                    splashDrag          = 0;
                    part.rb.drag        = 0;
                    part.rb.angularDrag = 0;
                }
                return;
            }

            float tmp = 0.15f;      //base drag

            tmp /= part.Rigidbody.mass;
            if (splashDrag > tmp)
            {
                splashDrag = splashDrag * 0.98f;
            }
            else
            {
                splashDrag = tmp;
            }

            if (!part.WaterContact)
            {
                part.WaterContact = true;
                vessel.checkSplashed();

                float vertVec = Vector3.Dot(part.rb.velocity + Krakensbane.GetFrameVelocityV3f(), vessel.upAxis);
                vertVec *= 0.1f;
                if (vertVec > 1)
                {
                    vertVec = 1;
                }

                splashDrag = Math.Max(20f * vertVec / part.rb.mass, tmp);
            }
            part.rb.drag        = splashDrag;
            part.rb.angularDrag = splashDrag * 10;
        }
コード例 #7
0
        private void CalculateAndApplyVesselAeroProperties()
        {
            float atmDensity = (float)_vessel.atmDensity;

            if (atmDensity <= 0)
            {
                machNumber     = 0;
                reynoldsNumber = 0;
                return;
            }

            machNumber     = _vessel.mach;
            reynoldsNumber = FARAeroUtil.CalculateReynoldsNumber(_vessel.atmDensity, Length, _vessel.srfSpeed, machNumber, FlightGlobals.getExternalTemperature((float)_vessel.altitude, _vessel.mainBody), _vessel.mainBody.atmosphereAdiabaticIndex);
            float skinFrictionDragCoefficient = (float)FARAeroUtil.SkinFrictionDrag(reynoldsNumber, machNumber);

            Vector3 frameVel = Krakensbane.GetFrameVelocityV3f();

            for (int i = 0; i < _currentAeroModules.Count; i++)
            {
                FARAeroPartModule m = _currentAeroModules[i];
                if (m != null)
                {
                    m.UpdateVelocityAndAngVelocity(frameVel);
                }
                else
                {
                    _currentAeroModules.RemoveAt(i);
                    i--;
                }
            }

            for (int i = 0; i < _currentAeroSections.Count; i++)
            {
                _currentAeroSections[i].FlightCalculateAeroForces(atmDensity, (float)machNumber, (float)(reynoldsNumber / Length), skinFrictionDragCoefficient);
            }

            _vesselIntakeRamDrag.ApplyIntakeRamDrag((float)machNumber, _vessel.srf_velocity.normalized, (float)_vessel.dynamicPressurekPa);

            for (int i = 0; i < _currentAeroModules.Count; i++)
            {
                FARAeroPartModule m = _currentAeroModules[i];
                if ((object)m != null)
                {
                    m.ApplyForces();
                }
            }
        }
コード例 #8
0
 private void ApplyAngularMomentum()
 {
     if (PreviousBodyName == FlightGlobals.currentMainBody)
     {
         if ((FlightGlobals.ActiveVessel.orbit.eccentricity > 1) && (ElipMode == 0))                 //For Hyperbolic Orbits. Conserve angular momentum by making orbit.h constant. GMp=h^2, so semi-latus rectum must be constant as well.).
         {
             Speed = Math.Sqrt(FlightGlobals.ActiveVessel.mainBody.gravParameter * ((2 / FlightGlobals.ActiveVessel.orbit.radius) - ((SemiLatusOriginal * FlightGlobals.ActiveVessel.mainBody.gravParameter) / (FlightGlobals.ActiveVessel.orbit.semiMajorAxis * OriginalMomentumSqr))));
             if (Vector3d.Magnitude(Krakensbane.GetFrameVelocity()) > 0)
             {
                 var VelocityOffset = (TravelDirection * Speed) - Krakensbane.GetFrameVelocity();
                 FlightGlobals.ActiveVessel.ChangeWorldVelocity(VelocityOffset);
             }
             else
             {
                 var VelocityOffset = (TravelDirection * Speed);
                 FlightGlobals.ActiveVessel.SetWorldVelocity(VelocityOffset);
             }
         }
         if ((FlightGlobals.ActiveVessel.orbit.eccentricity <= 1) && (ElipMode == 1))                 // For Elliptical Orbits. Conserve Angular Momentum directly by altering state vectors
         {
             Speed = OriginalSpeed * (OriginalFrameTrueRadius / (FlightGlobals.ActiveVessel.orbit.radius));
             if (Vector3d.Magnitude(Krakensbane.GetFrameVelocity()) > 0)
             {
                 var VelocityOffset = (TravelDirection * Speed) - Krakensbane.GetFrameVelocity();
                 FlightGlobals.ActiveVessel.ChangeWorldVelocity(VelocityOffset);
             }
             if (Vector3d.Magnitude(Krakensbane.GetFrameVelocity()) == 0)
             {
                 var VelocityOffset = (TravelDirection * Speed);
                 FlightGlobals.ActiveVessel.SetWorldVelocity(VelocityOffset);
             }
             if (((OriginalFrameTrueRadius / FlightGlobals.ActiveVessel.orbit.radius) <= 0.55) || ((OriginalFrameTrueRadius / FlightGlobals.ActiveVessel.orbit.radius) <= 1.75))                     // re-set variables when ratio between current ratio and original gets too far from 1
             {
                 OriginalSpeed           = Vector3d.Magnitude(FlightGlobals.ActiveVessel.orbit.GetRelativeVel());
                 OriginalFrameTrueRadius = FlightGlobals.ActiveVessel.orbit.radius;
             }
         }
     }
     if (((FlightGlobals.ActiveVessel.orbit.eccentricity < 1) && (ElipMode == 0)) || ((FlightGlobals.ActiveVessel.orbit.eccentricity > 1) && (ElipMode == 1)) || (PreviousBodyName != FlightGlobals.currentMainBody))
     {
         if (PreviousBodyName != FlightGlobals.currentMainBody)
         {
             SetAMStartStateVars();
         }
     }
 }
 void UpdateAerodynamics(ModularFI.ModularFlightIntegrator fi, Part part)
 {
     if (part.dragModel != Part.DragModel.CYLINDRICAL)// || part.Modules.Contains("KerbalEVA"))     //FIXME Proper model for airbrakes
     {
         fi.BaseFIUpdateAerodynamics(part);
         return;
     }
     else if (!part.DragCubes.None)
     {
         Rigidbody rb = part.Rigidbody;
         if (rb)
         {
             part.dragVectorDir      = -rb.velocity - Krakensbane.GetFrameVelocityV3f().normalized;
             part.dragVectorDirLocal = part.partTransform.worldToLocalMatrix.MultiplyVector(part.dragVectorDir);
             part.DragCubes.SetDrag(part.dragVectorDirLocal, (float)part.machNumber);
         }
     }
 }
コード例 #10
0
        public Vector3 GetVelocity(Rigidbody rigidbody, Vector3 refPoint) // from Ferram
        {
            Vector3 newVelocity = Vector3.zero;

            try
            {
                newVelocity += rigidbody.GetPointVelocity(refPoint);
                newVelocity += Krakensbane.GetFrameVelocityV3f() - Krakensbane.GetLastCorrection() * TimeWarp.fixedDeltaTime;
            }
            catch (Exception e)
            {
                if (debugMode)
                {
                    Debug.Log("FSengineBladed GetVelocity Exception " + e.GetType().ToString());
                }
            }
            return(newVelocity);
        }
コード例 #11
0
 void OnGUI()
 {
     if (BDArmorySettings.DRAW_DEBUG_LABELS)
     {
         var frameVelocity = Krakensbane.GetFrameVelocityV3f();
         //var rFrameVelocity = FlightGlobals.currentMainBody.getRFrmVel(Vector3d.zero);
         //var rFrameRotation = rFrameVelocity - FlightGlobals.currentMainBody.getRFrmVel(VectorUtils.GetUpDirection(Vector3.zero));
         GUI.Label(new Rect(10, 60, 400, 400),
                   $"Frame velocity: {frameVelocity.magnitude} ({frameVelocity}){Environment.NewLine}"
                   + $"Last offset {Time.time - lastShift}s ago{Environment.NewLine}"
                   + $"Local vessel speed: {FlightGlobals.ActiveVessel.rb_velocity.magnitude}, ({FlightGlobals.ActiveVessel.rb_velocity}){Environment.NewLine}"
                   //+ $"Reference frame speed: {rFrameVelocity}{Environment.NewLine}"
                   //+ $"Reference frame rotation speed: {rFrameRotation}{Environment.NewLine}"
                   //+ $"Reference frame angular speed: {rFrameRotation.magnitude / Mathf.PI * 180}{Environment.NewLine}"
                   //+ $"Ref frame is {(FlightGlobals.RefFrameIsRotating ? "" : "not ")}rotating{Environment.NewLine}"
                   );
     }
 }
コード例 #12
0
        public Vector3d GetVelocity(Vector3 refPoint)
        {
            Vector3d velocity = Vector3.zero;

            if (HighLogic.LoadedSceneIsFlight)
            {
                if (part.Rigidbody)
                {
                    velocity += part.Rigidbody.GetPointVelocity(refPoint);
                }

                velocity += Krakensbane.GetFrameVelocity() - Krakensbane.GetLastCorrection() * TimeWarp.fixedDeltaTime;
                return(velocity);
            }
            else
            {
                return(velocityEditor);
            }
        }
コード例 #13
0
        public Vector3d GetVelocity(Vector3 refPoint)
        {
            Vector3d velocity = Vector3.zero;

            if (start != StartState.Editor)
            {
                if (part.Rigidbody)
                {
                    velocity += part.Rigidbody.GetPointVelocity(refPoint);
                }

                velocity += Krakensbane.GetFrameVelocity() - Krakensbane.GetLastCorrection() * TimeWarp.fixedDeltaTime;
                return(velocity);
            }
            else
            {
                return(velocityEditor);
            }
        }
        private static void UpdateAerodynamics(ModularFlightIntegrator fi, Part part)
        {
            //FIXME Proper model for airbrakes
            if (part.Modules.Contains <ModuleAeroSurface>() ||
                part.Modules.Contains("MissileLauncher") && part.vessel.rootPart == part)
            {
                fi.BaseFIUpdateAerodynamics(part);
            }
            else
            {
                Rigidbody rb = part.rb;
                if (!rb)
                {
                    return;
                }
                part.dragVector = rb.velocity +
                                  Krakensbane.GetFrameVelocity() -
                                  FARAtmosphere.GetWind(FlightGlobals.currentMainBody, part, rb.position);
                part.dragVectorSqrMag = part.dragVector.sqrMagnitude;
                if (part.dragVectorSqrMag.NearlyEqual(0) || part.ShieldedFromAirstream)
                {
                    part.dragVectorMag      = 0f;
                    part.dragVectorDir      = Vector3.zero;
                    part.dragVectorDirLocal = Vector3.zero;
                    part.dragScalar         = 0f;
                }
                else
                {
                    part.dragVectorMag      = (float)Math.Sqrt(part.dragVectorSqrMag);
                    part.dragVectorDir      = part.dragVector / part.dragVectorMag;
                    part.dragVectorDirLocal = -part.partTransform.InverseTransformDirection(part.dragVectorDir);
                    CalculateLocalDynPresAndAngularDrag(fi, part);
                }

                if (part.DragCubes.None)
                {
                    return;
                }

                part.DragCubes.SetDrag(part.dragVectorDirLocal, (float)fi.mach);
            }
        }
コード例 #15
0
    // First, I tried to emit particles on regular Update, but stuff was weird, and the plume still appeared out of sync with frame draws
    // According to https://docs.unity3d.com/Manual/ExecutionOrder.html
    // LateUpdate is the last thing that happens before frame draw. That makes it as synced to frame draws, as possible
    // LateUpdate is called after physics calculations too, so the newly emitted plume particles are right where they should be.
    public void LateUpdate()
    {
        if (persistentEmitters == null || hostPart == null || hostPart.Rigidbody == null)
        {
            return;
        }

        // I think it's important to call this even though it doesn't count active particles
        // because it calculates how many particles should be removed on next emit pass.
        SmokeScreenConfig.UpdateParticlesCount();

        for (int i = 0; i < persistentEmitters.Count; i++)
        {
            PersistentKSPShurikenEmitter emitter = persistentEmitters[i];
            if (EmitOnUpdate)
            {
                emitter.EmitterOnUpdate(hostPart.Rigidbody.velocity + Krakensbane.GetFrameVelocity());
            }
        }
    }
コード例 #16
0
        public void FixedUpdate()
        {
            if (!gameObject.activeInHierarchy)
            {
                return;
            }

            //floating origin and velocity offloading corrections
            if (!FloatingOrigin.Offset.IsZero() || !Krakensbane.GetFrameVelocity().IsZero())
            {
                transform.position -= FloatingOrigin.OffsetNonKrakensbane;
            }
            if (!isFX)
            {
                while (ExplosionEvents.Count > 0 && ExplosionEvents.Peek().TimeToImpact <= TimeIndex)
                {
                    BlastHitEvent eventToExecute = ExplosionEvents.Dequeue();

                    var partBlastHitEvent = eventToExecute as PartBlastHitEvent;
                    if (partBlastHitEvent != null)
                    {
                        ExecutePartBlastEvent(partBlastHitEvent);
                    }
                    else
                    {
                        ExecuteBuildingBlastEvent((BuildingBlastHitEvent)eventToExecute);
                    }
                }
            }

            if (disabled && ExplosionEvents.Count == 0 && TimeIndex > MaxTime)
            {
                if (BDArmorySettings.DRAW_DEBUG_LABELS)
                {
                    Debug.Log("[BDArmory]:Explosion Finished");
                }

                gameObject.SetActive(false);
                return;
            }
        }
コード例 #17
0
    public void FixedUpdate()
    {
        //Print("FixedUpdate");
        if (persistentEmitters == null || hostPart == null || hostPart.Rigidbody == null)
        {
            return;
        }

        if (singleTimerEnd > 0)
        {
            if (Time.fixedTime <= singleTimerEnd)
            {
                OnEvent(1f);
            }
            else
            {
                OnEvent(0f);
                singleTimerEnd = 0;
            }
        }
        SmokeScreenConfig.UpdateParticlesCount();

        //RaycastHit vHit = new RaycastHit();
        //Ray vRay = Camera.main.ScreenPointToRay(Input.mousePosition);
        //if(Physics.Raycast(vRay, out vHit))
        //{
        //    RaycastHit vHit2 = new RaycastHit();
        //    if (Physics.Raycast(vHit.point + vHit.normal * 10, -vHit.normal, out vHit2))
        //        Debug.Log(vHit2.collider.name);
        //}

        for (int i = 0; i < persistentEmitters.Count; i++)
        {
            PersistentKSPShurikenEmitter emitter = persistentEmitters[i];
            // This is FixedUpdate, so don't emit here if particles should emit in LateUpdate
            if (!EmitOnUpdate)
            {
                emitter.EmitterOnUpdate(hostPart.Rigidbody.velocity + Krakensbane.GetFrameVelocity());
            }
        }
    }
コード例 #18
0
            public void Update()
            {
                if (transponder == null)
                {
                    return;
                }
                Vessel vsl = transponder.vessel;

                name = vsl.vesselName;

                altitude  = vsl.altitude;
                situation = vsl.situation;

                // Velocity/CoM stuff taken from MechJeb2
                Vector3d CoM    = Vector3d.zero;
                Vector3d obtVel = Vector3d.zero;
                double   mass   = 0;

                for (int i = 0; i < vsl.parts.Count; i++)
                {
                    Part p = vsl.parts[i];
                    if (p.rb != null)
                    {
                        mass   += p.rb.mass;
                        CoM     = CoM + (p.rb.worldCenterOfMass * p.rb.mass);
                        obtVel += p.rb.velocity * p.rb.mass;
                    }
                }
                CoM /= mass;
                if (vsl.packed)
                {
                    obtVel = vsl.obt_velocity;
                }
                else
                {
                    // XXX This could be a problem for non-active vessels...
                    obtVel = obtVel / mass + Krakensbane.GetFrameVelocity() + vsl.orbit.GetRotFrameVel(vsl.orbit.referenceBody).xzy;
                }

                velocity = (obtVel - vsl.mainBody.getRFrmVel(CoM)).magnitude;
            }
コード例 #19
0
        private bool CheckDieOnHighVelocity(Rigidbody body)
        {
            Vector3d velVector = body.velocity + Krakensbane.GetFrameVelocityV3f();

            double vertVec = Vector3d.Dot(velVector, vessel.upAxis);

            if (Math.Abs(vertVec) > part.crashTolerance * vertCrashTolFactor)
            {
                GameEvents.onCrashSplashdown.Fire(new EventReport(FlightEvents.SPLASHDOWN_CRASH, part, part.partInfo.title, "", 0, ""));
                part.Die();
                return(true);
            }
            double horizVel = (velVector - vertVec * vessel.upAxis).magnitude;

            if (horizVel > part.crashTolerance * horizCrashTolFactor)
            {
                GameEvents.onCrashSplashdown.Fire(new EventReport(FlightEvents.SPLASHDOWN_CRASH, part, part.partInfo.title, "", 0, ""));
                part.Die();
                return(true);
            }
            return(false);
        }
コード例 #20
0
    public void FixedUpdate()
    {
        //Print("FixedUpdate");
        if (persistentEmitters == null || hostPart == null || hostPart.rb == null)
        {
            return;
        }

        if (singleTimerEnd > 0)
        {
            if (Time.fixedTime <= singleTimerEnd)
            {
                OnEvent(1);
            }
            else
            {
                OnEvent(0);
                singleTimerEnd = 0;
            }
        }
        SmokeScreenConfig.UpdateParticlesCount();

        //RaycastHit vHit = new RaycastHit();
        //Ray vRay = Camera.main.ScreenPointToRay(Input.mousePosition);
        //if(Physics.Raycast(vRay, out vHit))
        //{
        //    RaycastHit vHit2 = new RaycastHit();
        //    if (Physics.Raycast(vHit.point + vHit.normal * 10, -vHit.normal, out vHit2))
        //        Debug.Log(vHit2.collider.name);
        //}

        PersistentKSPParticleEmitter[] persistentKspParticleEmitters = persistentEmitters.ToArray();
        for (int i = 0; i < persistentKspParticleEmitters.Length; i++)
        {
            PersistentKSPParticleEmitter persistentKspParticleEmitter = persistentKspParticleEmitters[i];

            persistentKspParticleEmitter.EmitterOnUpdate(hostPart.rb.velocity + Krakensbane.GetFrameVelocity());
        }
    }
コード例 #21
0
        public void FixedUpdate()
        {
            currentDrag = 0;

            // With unity objects, "foo" or "foo != null" calls a method to check if
            // it's destroyed. (object)foo != null just checks if it is actually null.
            if (HighLogic.LoadedSceneIsFlight && (object)part != null && FlightGlobals.ready)
            {
                if (animatingPart)
                {
                    UpdatePropertiesWithAnimation();
                }

                if (!isShielded)
                {
                    Rigidbody rb     = part.Rigidbody;
                    Vessel    vessel = part.vessel;

                    // Check that rb is not destroyed, but vessel is just not null
                    if (rb && (object)vessel != null && vessel.atmDensity > 0 && !vessel.packed)
                    {
                        Vector3d velocity = rb.velocity + Krakensbane.GetFrameVelocity()
                                            - FARWind.GetWind(FlightGlobals.currentMainBody, part, rb.position);

                        double machNumber, v_scalar = velocity.magnitude;

                        rho        = FARAeroUtil.GetCurrentDensity(vessel.mainBody, part.transform.position);
                        machNumber = GetMachNumber(vessel.mainBody, vessel.altitude, velocity);
                        if (rho > 0 && v_scalar > 0.1)
                        {
                            double   failureForceScaling = FARAeroUtil.GetFailureForceScaling(vessel);
                            Vector3d force = RunDragCalculation(velocity, machNumber, rho, failureForceScaling);
                            rb.AddForceAtPosition(force, GetCoD());
                        }
                    }
                }
            }
        }
コード例 #22
0
        public void FixedUpdate()
        {
            //floating origin and velocity offloading corrections
            if (!FloatingOrigin.Offset.IsZero() || !Krakensbane.GetFrameVelocity().IsZero())
            {
                transform.position -= FloatingOrigin.OffsetNonKrakensbane;
            }

            while (ExplosionEvents.Count > 0 && ExplosionEvents.Peek().TimeToImpact <= TimeIndex)
            {
                BlastHitEvent eventToExecute = ExplosionEvents.Dequeue();

                var partBlastHitEvent = eventToExecute as PartBlastHitEvent;
                if (partBlastHitEvent != null)
                {
                    ExecutePartBlastEvent(partBlastHitEvent);
                }
                else
                {
                    ExecuteBuildingBlastEvent((BuildingBlastHitEvent)eventToExecute);
                }
            }
        }
コード例 #23
0
        private void ApplyGravity()
        {
            KerbalIva.GetComponentCached(ref KerbalRigidbody);
            if (Gravity)
            {
                Vector3 gForce           = FlightGlobals.getGeeForceAtPosition(KerbalIva.transform.position);
                Vector3 centrifugalForce = FlightGlobals.getCentrifugalAcc(KerbalIva.transform.position, FreeIva.CurrentPart.orbit.referenceBody);
                Vector3 coriolisForce    = FlightGlobals.getCoriolisAcc(FreeIva.CurrentPart.vessel.rb_velocity + Krakensbane.GetFrameVelocityV3f(), FreeIva.CurrentPart.orbit.referenceBody);

                gForce           = InternalSpace.WorldToInternal(gForce);
                centrifugalForce = InternalSpace.WorldToInternal(centrifugalForce);
                coriolisForce    = InternalSpace.WorldToInternal(coriolisForce);
                flightForces     = gForce + centrifugalForce + coriolisForce;

                KerbalRigidbody.AddForce(gForce, ForceMode.Acceleration);
                KerbalRigidbody.AddForce(centrifugalForce, ForceMode.Acceleration);
                KerbalRigidbody.AddForce(coriolisForce, ForceMode.Acceleration);
                KerbalRigidbody.AddForce(Krakensbane.GetLastCorrection(), ForceMode.VelocityChange);

                if (FreeIva.SelectedObject != null)
                {
                    Rigidbody rbso = FreeIva.SelectedObject.GetComponent <Rigidbody>();
                    if (rbso == null)
                    {
                        rbso = FreeIva.SelectedObject.AddComponent <Rigidbody>();
                    }
                    rbso.AddForce(gForce, ForceMode.Acceleration);
                    rbso.AddForce(centrifugalForce, ForceMode.Acceleration);
                    rbso.AddForce(coriolisForce, ForceMode.Acceleration);
                }
            }
            else
            {
                KerbalRigidbody.velocity = Vector3.zero;
            }
        }
コード例 #24
0
        public void FixedUpdate()
        {
            currentDrag = 0;

            // With unity objects, "foo" or "foo != null" calls a method to check if
            // it's destroyed. (object)foo != null just checks if it is actually null.
            if (HighLogic.LoadedSceneIsFlight && (object)part != null)
            {
                if (animatingPart)
                {
                    UpdatePropertiesWithAnimation();
                }

                if (!isShielded)
                {
                    Rigidbody rb     = part.Rigidbody;
                    Vessel    vessel = part.vessel;

                    // Check that rb is not destroyed, but vessel is just not null
                    if (rb && (object)vessel != null && vessel.atmDensity > 0)
                    {
                        Vector3d velocity = rb.velocity + Krakensbane.GetFrameVelocity()
                                            + FARWind.GetWind(FlightGlobals.currentMainBody, part, rb.position);

                        double soundspeed, v_scalar = velocity.magnitude;

                        double rho = FARAeroUtil.GetCurrentDensity(vessel, out soundspeed);
                        if (rho > 0 && v_scalar > 0.1)
                        {
                            Vector3d force = RunDragCalculation(velocity, v_scalar / soundspeed, rho);
                            rb.AddForceAtPosition(force, GetCoD());
                        }
                    }
                }
            }
        }
コード例 #25
0
ファイル: KMPManager.cs プロジェクト: Jumba/KerbalMultiPlayer
 private Krakensbane getKrakensbane()
 {
     if (krakensbane == null) krakensbane = (Krakensbane)FindObjectOfType(typeof(Krakensbane));
     return krakensbane;
 }
コード例 #26
0
ファイル: RocketLauncher.cs プロジェクト: KAmaia/BDArmory
        void SimulateTrajectory()
        {
            if ((BDArmorySettings.AIM_ASSIST && BDArmorySettings.DRAW_AIMERS && drawAimer && vessel.isActiveVessel) || (weaponManager && weaponManager.guardMode && weaponManager.selectedWeaponString == GetShortName()))
            {
                float          simTime           = 0;
                Transform      fireTransform     = rockets[0].parent;
                Vector3        pointingDirection = fireTransform.forward;
                Vector3        simVelocity       = part.rb.velocity;
                Vector3        simCurrPos        = fireTransform.position + (part.rb.velocity * Time.fixedDeltaTime);
                Vector3        simPrevPos        = fireTransform.position + (part.rb.velocity * Time.fixedDeltaTime);
                Vector3        simStartPos       = fireTransform.position + (part.rb.velocity * Time.fixedDeltaTime);
                bool           simulating        = true;
                float          simDeltaTime      = 0.02f;
                List <Vector3> pointPositions    = new List <Vector3>();
                pointPositions.Add(simCurrPos);

                bool  slaved          = turret && weaponManager && (weaponManager.slavingTurrets || weaponManager.guardMode);
                float atmosMultiplier = Mathf.Clamp01(2.5f * (float)FlightGlobals.getAtmDensity(vessel.staticPressurekPa, vessel.externalTemperature, vessel.mainBody));
                while (simulating)
                {
                    RaycastHit hit;

                    if (simTime > thrustTime)
                    {
                        simDeltaTime = 0.1f;
                    }

                    if (simTime > 0.04f)
                    {
                        simDeltaTime = 0.02f;
                        if (simTime < thrustTime)
                        {
                            simVelocity += thrust / rocketMass * simDeltaTime * pointingDirection;
                        }

                        //rotation (aero stabilize)
                        pointingDirection = Vector3.RotateTowards(pointingDirection, simVelocity + Krakensbane.GetFrameVelocity(), atmosMultiplier * (0.5f * (simTime)) * 50 * simDeltaTime * Mathf.Deg2Rad, 0);
                    }

                    //gravity
                    simVelocity += FlightGlobals.getGeeForceAtPosition(simCurrPos) * simDeltaTime;

                    simCurrPos += simVelocity * simDeltaTime;
                    pointPositions.Add(simCurrPos);
                    if (!mouseAiming && !slaved)
                    {
                        if (simTime > 0.1f && Physics.Raycast(simPrevPos, simCurrPos - simPrevPos, out hit, Vector3.Distance(simPrevPos, simCurrPos), 557057))
                        {
                            rocketPrediction = hit.point;
                            simulating       = false;
                            break;
                        }
                        else if (FlightGlobals.getAltitudeAtPos(simCurrPos) < 0)
                        {
                            rocketPrediction = simCurrPos;
                            simulating       = false;
                            break;
                        }
                    }



                    simPrevPos = simCurrPos;

                    if ((simStartPos - simCurrPos).sqrMagnitude > currentTgtRange * currentTgtRange)
                    {
                        rocketPrediction = simStartPos + (simCurrPos - simStartPos).normalized * currentTgtRange;
                        //rocketPrediction = simCurrPos;
                        simulating = false;
                    }
                    simTime += simDeltaTime;
                }

                Vector3 pointingPos = fireTransform.position + (fireTransform.forward * currentTgtRange);
                trajectoryOffset    = pointingPos - rocketPrediction;
                predictedFlightTime = simTime;

                if (BDArmorySettings.DRAW_DEBUG_LINES && BDArmorySettings.DRAW_AIMERS)
                {
                    Vector3[] pointsArray = pointPositions.ToArray();
                    if (gameObject.GetComponent <LineRenderer>() == null)
                    {
                        LineRenderer lr = gameObject.AddComponent <LineRenderer>();
                        lr.SetWidth(.1f, .1f);
                        lr.SetVertexCount(pointsArray.Length);
                        for (int i = 0; i < pointsArray.Length; i++)
                        {
                            lr.SetPosition(i, pointsArray[i]);
                        }
                    }
                    else
                    {
                        LineRenderer lr = gameObject.GetComponent <LineRenderer>();
                        lr.enabled = true;
                        lr.SetVertexCount(pointsArray.Length);
                        for (int i = 0; i < pointsArray.Length; i++)
                        {
                            lr.SetPosition(i, pointsArray[i]);
                        }
                    }
                }
                else
                {
                    if (gameObject.GetComponent <LineRenderer>() != null)
                    {
                        gameObject.GetComponent <LineRenderer>().enabled = false;
                    }
                }
            }

            //for straight aimer
            else if (BDArmorySettings.DRAW_AIMERS && drawAimer && vessel.isActiveVessel)
            {
                RaycastHit hit;
                float      distance = 2500;
                if (Physics.Raycast(transform.position, transform.forward, out hit, distance, 557057))
                {
                    rocketPrediction = hit.point;
                }
                else
                {
                    rocketPrediction = transform.position + (transform.forward * distance);
                }
            }
        }
コード例 #27
0
ファイル: RocketLauncher.cs プロジェクト: KAmaia/BDArmory
        void FixedUpdate()
        {
            //floatingOrigin fix
            if (sourceVessel != null && (transform.position - sourceVessel.transform.position - relativePos).sqrMagnitude > 800 * 800)
            {
                transform.position = sourceVessel.transform.position + relativePos + (rb.velocity * Time.fixedDeltaTime);
            }
            if (sourceVessel != null)
            {
                relativePos = transform.position - sourceVessel.transform.position;
            }
            //


            if (Time.time - startTime < stayTime && transform.parent != null)
            {
                transform.rotation = transform.parent.rotation;
                transform.position = spawnTransform.position;                //+(transform.parent.rigidbody.velocity*Time.fixedDeltaTime);
            }
            else
            {
                if (transform.parent != null && parentRB)
                {
                    startVelocity    = parentRB.velocity;
                    transform.parent = null;
                    rb.isKinematic   = false;
                    rb.velocity      = startVelocity;
                }
            }

            if (rb && !rb.isKinematic)
            {
                //physics
                if (FlightGlobals.RefFrameIsRotating)
                {
                    rb.velocity += FlightGlobals.getGeeForceAtPosition(transform.position) * Time.fixedDeltaTime;
                }

                //guidance and attitude stabilisation scales to atmospheric density.
                float atmosMultiplier = Mathf.Clamp01(2.5f * (float)FlightGlobals.getAtmDensity(FlightGlobals.getStaticPressure(transform.position), FlightGlobals.getExternalTemperature(), FlightGlobals.currentMainBody));

                //model transform. always points prograde
                transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.LookRotation(rb.velocity + Krakensbane.GetFrameVelocity(), transform.up), atmosMultiplier * (0.5f * (Time.time - startTime)) * 50 * Time.fixedDeltaTime);


                if (Time.time - startTime < thrustTime && Time.time - startTime > stayTime)
                {
                    float random  = randomThrustDeviation * (1 - (Mathf.PerlinNoise(4 * Time.time, randThrustSeed) * 2));
                    float random2 = randomThrustDeviation * (1 - (Mathf.PerlinNoise(randThrustSeed, 4 * Time.time) * 2));
                    rb.AddRelativeForce(new Vector3(random, random2, thrust));
                }
            }



            if (Time.time - startTime > thrustTime)
            {
                //isThrusting = false;
                foreach (var pEmitter in pEmitters)
                {
                    if (pEmitter.useWorldSpace)
                    {
                        pEmitter.minSize = Mathf.MoveTowards(pEmitter.minSize, 0.1f, 0.05f);
                        pEmitter.maxSize = Mathf.MoveTowards(pEmitter.maxSize, 0.2f, 0.05f);
                    }
                    else
                    {
                        pEmitter.minSize = Mathf.MoveTowards(pEmitter.minSize, 0, 0.1f);
                        pEmitter.maxSize = Mathf.MoveTowards(pEmitter.maxSize, 0, 0.1f);
                        if (pEmitter.maxSize == 0)
                        {
                            pEmitter.emit = false;
                        }
                    }
                }
            }

            if (Time.time - startTime > 0.1f + stayTime)
            {
                //audioSource.pitch = SoundUtil.getDopplerPitchFactor(rigidbody.velocity, transform.position)*1.4f;
                currPosition = transform.position;
                float      dist = (currPosition - prevPosition).magnitude;
                Ray        ray  = new Ray(prevPosition, currPosition - prevPosition);
                RaycastHit hit;
                if (Physics.Raycast(ray, out hit, dist, 557057))
                {
                    Part hitPart = null;
                    try{
                        hitPart = Part.FromGO(hit.rigidbody.gameObject);
                    }catch (NullReferenceException) {}


                    if (hitPart == null || (hitPart != null && hitPart.vessel != sourceVessel))
                    {
                        Detonate(hit.point);
                    }
                }
                else if (FlightGlobals.getAltitudeAtPos(transform.position) < 0)
                {
                    Detonate(transform.position);
                }
            }
            else if (FlightGlobals.getAltitudeAtPos(currPosition) <= 0)
            {
                Detonate(currPosition);
            }
            prevPosition = currPosition;

            if (Time.time - startTime > lifeTime)
            {
                Detonate(transform.position);
            }

            //proxy detonation
            if (targetVessel != null && (transform.position - targetVessel.transform.position).sqrMagnitude < 0.5f * blastRadius * blastRadius)
            {
                Detonate(transform.position);
            }
        }
コード例 #28
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);
        }
コード例 #29
0
ファイル: ksp_plugin_adapter.cs プロジェクト: tsal/Principia
            private void FixedUpdate()
            {
                if (GameSettings.ORBIT_WARP_DOWN_AT_SOI) {
                  Log.Info("Setting GameSettings.ORBIT_WARP_DOWN_AT_SOI to false");
                  GameSettings.ORBIT_WARP_DOWN_AT_SOI = false;
                }
                if (PluginRunning()) {
                  double universal_time = Planetarium.GetUniversalTime();
                  double plugin_time = plugin_.CurrentTime();
                  if (plugin_time > universal_time) {
                // TODO(Egg): Make this resistant to bad floating points up to 2ULPs,
                // and make it fatal again.
                Log.Error("Closed Timelike Curve: " +
                  plugin_time + " > " + universal_time +
                  " plugin-universal=" + (plugin_time - universal_time));
                time_is_advancing_ = false;
                return;
                  } else if (plugin_time == universal_time) {
                time_is_advancing_ = false;
                return;
                  }
                  time_is_advancing_ = true;
                  if (has_inertial_physics_bubble_in_space() &&
                  (FlightGlobals.currentMainBody == previous_bubble_reference_body_ ||
                   previous_bubble_reference_body_ == null)) {
                ApplyToVesselsInPhysicsBubble(AddToPhysicsBubble);
                previous_bubble_reference_body_ = FlightGlobals.currentMainBody;
                  } else {
                if (FlightIntegrator.GraviticForceMultiplier != 1) {
                  Log.Info("Reinstating stock gravity");
                  FlightIntegrator.GraviticForceMultiplier = 1;  // sic.
                }
                previous_bubble_reference_body_ = null;
                  }
                  Vessel active_vessel = FlightGlobals.ActiveVessel;
                  bool ready_to_draw_active_vessel_trajectory =
                  draw_active_vessel_trajectory() &&
                  plugin_.HasVessel(active_vessel.id.ToString());

                  if (ready_to_draw_active_vessel_trajectory) {
                // TODO(egg): make the speed tolerance independent.  Also max_steps.
                AdaptiveStepParameters adaptive_step_parameters =
                new AdaptiveStepParameters {
                  max_steps = (Int64)prediction_steps_[prediction_steps_index_],
                  length_integration_tolerance =
                  prediction_length_tolerances_[
                      prediction_length_tolerance_index_],
                  speed_integration_tolerance =
                  prediction_length_tolerances_[
                      prediction_length_tolerance_index_]};
                plugin_.VesselSetPredictionAdaptiveStepParameters(
                active_vessel.id.ToString(), adaptive_step_parameters);
                plugin_.SetPredictionLength(double.PositiveInfinity);
                  }
                  plugin_.AdvanceTime(universal_time, Planetarium.InverseRotAngle);
                  if (ready_to_draw_active_vessel_trajectory) {
                plugin_.UpdatePrediction(active_vessel.id.ToString());
                  }
                  plugin_.ForgetAllHistoriesBefore(
                  universal_time - history_lengths_[history_length_index_]);
                  ApplyToBodyTree(body => UpdateBody(body, universal_time));
                  ApplyToVesselsOnRailsOrInInertialPhysicsBubbleInSpace(
                  vessel => UpdateVessel(vessel, universal_time));
                  if (!plugin_.PhysicsBubbleIsEmpty()) {
                Vector3d displacement_offset =
                (Vector3d)plugin_.BubbleDisplacementCorrection(
                          (XYZ)Planetarium.fetch.Sun.position);
                Vector3d velocity_offset =
                (Vector3d)plugin_.BubbleVelocityCorrection(
                          active_vessel.orbit.referenceBody.flightGlobalsIndex);
                if (krakensbane_ == null) {
                  krakensbane_ = (Krakensbane)FindObjectOfType(typeof(Krakensbane));
                }
                krakensbane_.setOffset(displacement_offset);
                krakensbane_.FrameVel += velocity_offset;
                  }
                }
            }
コード例 #30
0
        void FixedUpdate()
        {
            if (!gameObject.activeInHierarchy)
            {
                return;
            }

            //floating origin and velocity offloading corrections
            if (!FloatingOrigin.Offset.IsZero() || !Krakensbane.GetFrameVelocity().IsZero())
            {
                transform.position -= FloatingOrigin.OffsetNonKrakensbane;
            }

            if (velocity != Vector3.zero)
            {
                transform.rotation = Quaternion.LookRotation(velocity, upDirection);
            }

            //Particle effects
            //downforce
            Vector3 downForce = (Mathf.Clamp(velocity.magnitude, 0.1f, 150) / 150) * 20 * -upDirection;

            //turbulence
            List <BDAGaplessParticleEmitter> .Enumerator gEmitter = gaplessEmitters.GetEnumerator();
            while (gEmitter.MoveNext())
            {
                if (gEmitter.Current == null)
                {
                    continue;
                }
                if (!gEmitter.Current.pEmitter)
                {
                    continue;
                }
                try
                {
                    gEmitter.Current.pEmitter.worldVelocity = 2 * ParticleTurbulence.flareTurbulence + downForce;
                }
                catch (NullReferenceException)
                {
                    Debug.LogWarning("CMFlare NRE setting worldVelocity");
                }

                try
                {
                    if (FlightGlobals.ActiveVessel && FlightGlobals.ActiveVessel.atmDensity <= 0)
                    {
                        gEmitter.Current.emit = false;
                    }
                }
                catch (NullReferenceException)
                {
                    Debug.LogWarning("CMFlare NRE checking density");
                }
            }
            gEmitter.Dispose();
            //

            //thermal decay
            thermal = Mathf.MoveTowards(thermal, minThermal,
                                        ((thermal - minThermal) / lifeTime) * Time.fixedDeltaTime);

            if (Time.time - startTime > lifeTime) //stop emitting after lifeTime seconds
            {
                alive = false;
                BDArmorySetup.Flares.Remove(this);

                List <KSPParticleEmitter> .Enumerator pe = pEmitters.GetEnumerator();
                while (pe.MoveNext())
                {
                    if (pe.Current == null)
                    {
                        continue;
                    }
                    pe.Current.emit = false;
                }
                pe.Dispose();

                List <BDAGaplessParticleEmitter> .Enumerator gpe = gaplessEmitters.GetEnumerator();
                while (gpe.MoveNext())
                {
                    if (gpe.Current == null)
                    {
                        continue;
                    }
                    gpe.Current.emit = false;
                }
                gpe.Dispose();

                IEnumerator <Light> lgt = lights.AsEnumerable().GetEnumerator();
                while (lgt.MoveNext())
                {
                    if (lgt.Current == null)
                    {
                        continue;
                    }
                    lgt.Current.enabled = false;
                }
                lgt.Dispose();
            }

            if (Time.time - startTime > lifeTime + 11) //disable object after x seconds
            {
                BDArmorySetup.numberOfParticleEmitters--;
                gameObject.SetActive(false);
                return;
            }

            //physics
            //atmospheric drag (stock)
            float       simSpeedSquared = velocity.sqrMagnitude;
            Vector3     currPos         = transform.position;
            const float mass            = 0.001f;
            const float drag            = 1f;
            Vector3     dragForce       = (0.008f * mass) * drag * 0.5f * simSpeedSquared *
                                          (float)
                                          FlightGlobals.getAtmDensity(FlightGlobals.getStaticPressure(currPos),
                                                                      FlightGlobals.getExternalTemperature(), FlightGlobals.currentMainBody) *
                                          velocity.normalized;

            velocity -= (dragForce / mass) * Time.fixedDeltaTime;
            //

            //gravity
            if (FlightGlobals.RefFrameIsRotating)
            {
                velocity += FlightGlobals.getGeeForceAtPosition(transform.position) * Time.fixedDeltaTime;
            }

            transform.position += velocity * Time.fixedDeltaTime;
        }
コード例 #31
0
        private void FixedUpdate()
        {
            //Flight values
            if (!CompatibilityChecker.IsAllCompatible() || !HighLogic.LoadedSceneIsFlight || FlightGlobals.ActiveVessel == null || this.part.Rigidbody == null)
            {
                return;
            }
            this.pos     = this.part.partTransform.position;
            this.ASL     = FlightGlobals.getAltitudeAtPos(this.pos);
            this.trueAlt = this.ASL;
            if (this.vessel.mainBody.pqsController != null)
            {
                double terrainAlt = this.vessel.pqsAltitude;
                if (!this.vessel.mainBody.ocean || terrainAlt > 0)
                {
                    this.trueAlt -= terrainAlt;
                }
            }
            this.atmPressure = FlightGlobals.getStaticPressure(this.ASL, this.vessel.mainBody) * PhysicsGlobals.KpaToAtmospheres;
            this.atmDensity  = part.atmDensity;
            Vector3 velocity = this.part.Rigidbody.velocity + Krakensbane.GetFrameVelocityV3f();

            this.sqrSpeed   = velocity.sqrMagnitude;
            this.dragVector = -velocity.normalized;

            if (this.atmDensity > 0)
            {
                CalculateChuteFlux();
            }
            else
            {
                this.convFlux = 0;
            }

            CalculateSafeToDeployEstimate();

            if (!this.staged && GameSettings.LAUNCH_STAGES.GetKeyDown() && this.vessel.isActiveVessel && (this.part.inverseStage == Staging.CurrentStage - 1 || Staging.CurrentStage == 0))
            {
                ActivateRC();
            }

            if (this.staged)
            {
                //Checks if the parachute must disarm
                if (this.armed)
                {
                    this.part.stackIcon.SetIconColor(XKCDColors.LightCyan);
                    if (this.canDeploy)
                    {
                        this.armed = false;
                    }
                }
                //Parachute deployments
                else
                {
                    //Parachutes
                    if (this.canDeploy)
                    {
                        if (this.isDeployed)
                        {
                            if (!CalculateChuteTemp())
                            {
                                return;
                            }
                            FollowDragDirection();
                        }

                        switch (this.deploymentState)
                        {
                        case DeploymentStates.STOWED:
                        {
                            this.part.stackIcon.SetIconColor(XKCDColors.LightCyan);
                            if (this.pressureCheck && this.randomDeployment)
                            {
                                PreDeploy();
                            }
                            break;
                        }

                        case DeploymentStates.PREDEPLOYED:
                        {
                            this.part.Rigidbody.AddForceAtPosition(DragForce(0, this.preDeployedDiameter, 1f / this.semiDeploymentSpeed), this.forcePosition, ForceMode.Force);
                            if (this.trueAlt <= this.deployAltitude && this.dragTimer.elapsed.TotalSeconds >= 1f / this.semiDeploymentSpeed)
                            {
                                Deploy();
                            }
                            break;
                        }

                        case DeploymentStates.DEPLOYED:
                        {
                            this.part.rigidbody.AddForceAtPosition(DragForce(this.preDeployedDiameter, this.deployedDiameter, 1f / this.deploymentSpeed), this.forcePosition, ForceMode.Force);
                            break;
                        }

                        default:
                            break;
                        }
                    }
                    //Deactivation
                    else
                    {
                        if (this.isDeployed)
                        {
                            Cut();
                        }
                        else
                        {
                            this.failedTimer.Start();
                            StagingReset();
                        }
                    }
                }
            }
        }
コード例 #32
0
 private void FixedUpdate()
 {
     if (PluginRunning()) {
       double universal_time = Planetarium.GetUniversalTime();
       double plugin_time = current_time(plugin_);
       if (plugin_time > universal_time) {
     // TODO(Egg): Make this resistant to bad floating points up to 2ULPs,
     // and make it fatal again.
     Log.Error("Closed Timelike Curve: " +
       plugin_time + " > " + universal_time +
       " plugin-universal=" + (plugin_time - universal_time));
     time_is_advancing_ = false;
     return;
       } else if (plugin_time == universal_time) {
     time_is_advancing_ = false;
     return;
       }
       time_is_advancing_ = true;
       if (has_inertial_physics_bubble_in_space()) {
     ApplyToVesselsInPhysicsBubble(AddToPhysicsBubble);
       }
       Vessel active_vessel = FlightGlobals.ActiveVessel;
       bool ready_to_draw_active_vessel_trajectory =
       draw_active_vessel_trajectory() &&
       has_vessel(plugin_, active_vessel.id.ToString());
       if (ready_to_draw_active_vessel_trajectory) {
     set_prediction_length_tolerance(
     plugin_,
     prediction_length_tolerances_[prediction_length_tolerance_index_]);
     // TODO(egg): make the speed tolerance independent.
     set_prediction_speed_tolerance(
     plugin_,
     prediction_length_tolerances_[prediction_length_tolerance_index_]);
     set_prediction_length(plugin_,
                   prediction_lengths_[prediction_length_index_]);
       }
       AdvanceTime(plugin_, universal_time, Planetarium.InverseRotAngle);
       if (ready_to_draw_active_vessel_trajectory) {
     UpdatePrediction(plugin_, active_vessel.id.ToString());
       }
       ForgetAllHistoriesBefore(
       plugin_,
       universal_time - history_lengths_[history_length_index_]);
       ApplyToBodyTree(body => UpdateBody(body, universal_time));
       ApplyToVesselsOnRailsOrInInertialPhysicsBubbleInSpace(
       vessel => UpdateVessel(vessel, universal_time));
       if (!PhysicsBubbleIsEmpty(plugin_)) {
     Vector3d displacement_offset =
     (Vector3d)BubbleDisplacementCorrection(
               plugin_,
               (XYZ)Planetarium.fetch.Sun.position);
     Vector3d velocity_offset =
     (Vector3d)BubbleVelocityCorrection(
               plugin_,
               active_vessel.orbit.referenceBody.flightGlobalsIndex);
     if (krakensbane_ == null) {
       krakensbane_ = (Krakensbane)FindObjectOfType(typeof(Krakensbane));
     }
     krakensbane_.setOffset(displacement_offset);
     krakensbane_.FrameVel += velocity_offset;
       }
     }
 }
コード例 #33
0
ファイル: RocketLauncher.cs プロジェクト: terrynoya/BDArmory
        void FixedUpdate()
        {
            //floating origin and velocity offloading corrections
            if (!FloatingOrigin.Offset.IsZero() || !Krakensbane.GetFrameVelocity().IsZero())
            {
                transform.position -= FloatingOrigin.OffsetNonKrakensbane;
                prevPosition       -= FloatingOrigin.OffsetNonKrakensbane;
            }

            if (Time.time - startTime < stayTime && transform.parent != null)
            {
                transform.rotation = transform.parent.rotation;
                transform.position = spawnTransform.position;
                //+(transform.parent.rigidbody.velocity*Time.fixedDeltaTime);
            }
            else
            {
                if (transform.parent != null && parentRB)
                {
                    transform.parent = null;
                    rb.isKinematic   = false;
                    rb.velocity      = parentRB.velocity + Krakensbane.GetFrameVelocityV3f();
                }
            }

            if (rb && !rb.isKinematic)
            {
                //physics
                if (FlightGlobals.RefFrameIsRotating)
                {
                    rb.velocity += FlightGlobals.getGeeForceAtPosition(transform.position) * Time.fixedDeltaTime;
                }

                //guidance and attitude stabilisation scales to atmospheric density.
                float atmosMultiplier =
                    Mathf.Clamp01(2.5f *
                                  (float)
                                  FlightGlobals.getAtmDensity(FlightGlobals.getStaticPressure(transform.position),
                                                              FlightGlobals.getExternalTemperature(), FlightGlobals.currentMainBody));

                //model transform. always points prograde
                transform.rotation = Quaternion.RotateTowards(transform.rotation,
                                                              Quaternion.LookRotation(rb.velocity + Krakensbane.GetFrameVelocity(), transform.up),
                                                              atmosMultiplier * (0.5f * (Time.time - startTime)) * 50 * Time.fixedDeltaTime);

                if (Time.time - startTime < thrustTime && Time.time - startTime > stayTime)
                {
                    float random  = randomThrustDeviation * (1 - (Mathf.PerlinNoise(4 * Time.time, randThrustSeed) * 2));
                    float random2 = randomThrustDeviation * (1 - (Mathf.PerlinNoise(randThrustSeed, 4 * Time.time) * 2));
                    rb.AddRelativeForce(new Vector3(random, random2, thrust));
                }
            }

            if (Time.time - startTime > thrustTime)
            {
                //isThrusting = false;
                IEnumerator <KSPParticleEmitter> pEmitter = pEmitters.AsEnumerable().GetEnumerator();
                while (pEmitter.MoveNext())
                {
                    if (pEmitter.Current == null)
                    {
                        continue;
                    }
                    if (pEmitter.Current.useWorldSpace)
                    {
                        pEmitter.Current.minSize = Mathf.MoveTowards(pEmitter.Current.minSize, 0.1f, 0.05f);
                        pEmitter.Current.maxSize = Mathf.MoveTowards(pEmitter.Current.maxSize, 0.2f, 0.05f);
                    }
                    else
                    {
                        pEmitter.Current.minSize = Mathf.MoveTowards(pEmitter.Current.minSize, 0, 0.1f);
                        pEmitter.Current.maxSize = Mathf.MoveTowards(pEmitter.Current.maxSize, 0, 0.1f);
                        if (pEmitter.Current.maxSize == 0)
                        {
                            pEmitter.Current.emit = false;
                        }
                    }
                }
                pEmitter.Dispose();
            }

            if (Time.time - startTime > 0.1f + stayTime)
            {
                currPosition = transform.position;
                float      dist = (currPosition - prevPosition).magnitude;
                Ray        ray  = new Ray(prevPosition, currPosition - prevPosition);
                RaycastHit hit;
                KerbalEVA  hitEVA = null;
                //if (Physics.Raycast(ray, out hit, dist, 2228224))
                //{
                //    try
                //    {
                //        hitEVA = hit.collider.gameObject.GetComponentUpwards<KerbalEVA>();
                //        if (hitEVA != null)
                //            Debug.Log("[BDArmory]:Hit on kerbal confirmed!");
                //    }
                //    catch (NullReferenceException)
                //    {
                //        Debug.Log("[BDArmory]:Whoops ran amok of the exception handler");
                //    }

                //    if (hitEVA && hitEVA.part.vessel != sourceVessel)
                //    {
                //        Detonate(hit.point);
                //    }
                //}

                if (!hitEVA)
                {
                    if (Physics.Raycast(ray, out hit, dist, 9076737))
                    {
                        Part hitPart = null;
                        try
                        {
                            KerbalEVA eva = hit.collider.gameObject.GetComponentUpwards <KerbalEVA>();
                            hitPart = eva ? eva.part : hit.collider.gameObject.GetComponentInParent <Part>();
                        }
                        catch (NullReferenceException)
                        {
                        }

                        if (hitPart == null || (hitPart != null && hitPart.vessel != sourceVessel))
                        {
                            Detonate(hit.point);
                        }
                    }
                    else if (FlightGlobals.getAltitudeAtPos(transform.position) < 0)
                    {
                        Detonate(transform.position);
                    }
                }
            }
            else if (FlightGlobals.getAltitudeAtPos(currPosition) <= 0)
            {
                Detonate(currPosition);
            }
            prevPosition = currPosition;

            if (Time.time - startTime > lifeTime)
            {
                Detonate(transform.position);
            }
        }
コード例 #34
0
            private void FixedUpdate()
            {
                if (GameSettings.ORBIT_WARP_DOWN_AT_SOI) {
                  Log.Info("Setting GameSettings.ORBIT_WARP_DOWN_AT_SOI to false");
                  GameSettings.ORBIT_WARP_DOWN_AT_SOI = false;
                }
                if (PluginRunning()) {
                  double universal_time = Planetarium.GetUniversalTime();
                  plugin_.SetMainBody(
                  FlightGlobals.currentMainBody.GetValueOrDefault(
                  FlightGlobals.GetHomeBody()).flightGlobalsIndex);

                  if (has_inertial_physics_bubble_in_space() &&
                  (FlightGlobals.currentMainBody == previous_bubble_reference_body_ ||
                   previous_bubble_reference_body_ == null)) {
                ApplyToVesselsInPhysicsBubble(AddToPhysicsBubble);
                previous_bubble_reference_body_ = FlightGlobals.currentMainBody;
                  } else {
                if (PhysicsGlobals.GraviticForceMultiplier != 1) {
                  Log.Info("Reinstating stock gravity");
                  PhysicsGlobals.GraviticForceMultiplier = 1;  // sic.
                }
                previous_bubble_reference_body_ = null;
                  }
                  Vessel active_vessel = FlightGlobals.ActiveVessel;
                  bool ready_to_draw_active_vessel_trajectory =
                  draw_active_vessel_trajectory() &&
                  plugin_.HasVessel(active_vessel.id.ToString());

                  if (ready_to_draw_active_vessel_trajectory) {
                // TODO(egg): make the speed tolerance independent.  Also max_steps.
                AdaptiveStepParameters adaptive_step_parameters =
                new AdaptiveStepParameters {
                  max_steps = (Int64)prediction_steps_[prediction_steps_index_],
                  length_integration_tolerance =
                  prediction_length_tolerances_[
                      prediction_length_tolerance_index_],
                  speed_integration_tolerance =
                  prediction_length_tolerances_[
                      prediction_length_tolerance_index_]};
                plugin_.VesselSetPredictionAdaptiveStepParameters(
                active_vessel.id.ToString(), adaptive_step_parameters);
                plugin_.SetPredictionLength(double.PositiveInfinity);
                  }

                  if (ready_to_draw_active_vessel_trajectory) {
                plugin_.UpdatePrediction(active_vessel.id.ToString());
                  }
                  plugin_.ForgetAllHistoriesBefore(universal_time -
                                       history_lengths_[history_length_index_]);
                  if (FlightGlobals.currentMainBody != null) {
                FlightGlobals.currentMainBody.rotationPeriod =
                plugin_.CelestialRotationPeriod(
                FlightGlobals.currentMainBody.flightGlobalsIndex);
                FlightGlobals.currentMainBody.initialRotation =
                plugin_.CelestialInitialRotationInDegrees(
                FlightGlobals.currentMainBody.flightGlobalsIndex);
                  }
                  ApplyToBodyTree(body => UpdateBody(body, universal_time));
                  SetBodyFrames();
                  // TODO(egg): set the positions of vessels inside the physics bubble too;
                  // Only move the universe to set the centre of mass of all loaded PileUps
                  // at the centre of the physics bubble.
                  ApplyToVesselsOnRailsOrInInertialPhysicsBubbleInSpace(
                  vessel => UpdateVessel(vessel, universal_time));
                  if (!plugin_.PhysicsBubbleIsEmpty()) {
                Vector3d displacement_offset =
                (Vector3d)plugin_.PhysicsBubbleDisplacementCorrection(
                (XYZ)Planetarium.fetch.Sun.position);
                Vector3d velocity_offset =
                (Vector3d)plugin_.PhysicsBubbleVelocityCorrection(
                active_vessel.orbit.referenceBody.flightGlobalsIndex);
                if (krakensbane_ == null) {
                  krakensbane_ = (Krakensbane)FindObjectOfType(typeof(Krakensbane));
                }
                FloatingOrigin.SetOffset(displacement_offset);
                krakensbane_.FrameVel += velocity_offset;
                  }

                  // Now we let the game and Unity do their thing. among other things,
                  // the FashionablyLate callbacks, including ReportNonConservativeForces,
                  // then the FlightIntegrator's FixedUpdate will run, then the Vessel's,
                  // and eventually the physics simulation.
                  StartCoroutine(
                  AdvanceTimeAndNudgeVesselsAfterPhysicsSimulation(universal_time));
                }
            }