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; }
/// <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; } }
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; } } }
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; }
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); }
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; }
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(); } } }
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); } } }
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); }
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}" ); } }
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); } }
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); } }
// 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()); } } }
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; } }
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()); } } }
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; }
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); }
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()); } }
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()); } } } } }
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); } } }
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; } }
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()); } } } } }
private Krakensbane getKrakensbane() { if (krakensbane == null) krakensbane = (Krakensbane)FindObjectOfType(typeof(Krakensbane)); return krakensbane; }
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); } } }
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); } }
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); }
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; } } }
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; }
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(); } } } } }
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; } } }
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); } }
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)); } }