public void FixedUpdate() { if (!HighLogic.LoadedSceneIsFlight) { ExplosionEvents.Clear(); return; } //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); } } }
/// <inheritdoc/> public void ApplyGravity(Rigidbody rb, Vessel vessel, double rbAirDragMult = 1.0) { // Apply the gravity as it's done in FlightIntegrator for the physical object. var geeForce = FlightGlobals.getGeeForceAtPosition(vessel.CoMD, vessel.mainBody) + FlightGlobals.getCoriolisAcc(vessel.velocityD, vessel.mainBody) + FlightGlobals.getCentrifugalAcc(vessel.CoMD, vessel.mainBody); rb.AddForce(geeForce * PhysicsGlobals.GraviticForceMultiplier, ForceMode.Acceleration); // Apply the atmosphere drag force as it's done in FlightIntegrator for the physical object. if (PhysicsGlobals.ApplyDrag && vessel.atmDensity > 0) { var pseudoReDragMult = 1; //FIXME: find out what it is var d = 0.0005 * pseudoReDragMult * vessel.atmDensity * rbAirDragMult * (rb.velocity + Krakensbane.GetFrameVelocity()).sqrMagnitude * (double)PhysicsGlobals.DragMultiplier; if (!double.IsNaN(d) && !double.IsInfinity(d)) { var atmDragForce = -(rb.velocity + Krakensbane.GetFrameVelocity()).normalized * d; if (PhysicsGlobals.DragUsesAcceleration) { rb.AddForce(atmDragForce, ForceMode.Acceleration); } else { rb.AddForce(atmDragForce, ForceMode.Force); } } } }
void FixedUpdate() { if (deployed) { //floating origin and velocity offloading corrections if (!FloatingOrigin.Offset.IsZero() || !Krakensbane.GetFrameVelocity().IsZero()) { transform.position -= FloatingOrigin.OffsetNonKrakensbane; prevPosition -= FloatingOrigin.OffsetNonKrakensbane; } currPosition = transform.position; float dist = (currPosition - prevPosition).magnitude; Ray ray = new Ray(prevPosition, currPosition - prevPosition); RaycastHit hit; if (Physics.Raycast(ray, out hit, dist, 9076737)) { Destroy(gameObject); } else if (FlightGlobals.getAltitudeAtPos(currPosition) <= 0) { Destroy(gameObject); } else if (Time.time - startTime > 20) { Destroy(gameObject); } } }
public override 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 (start != StartState.Editor && (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(); 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()); } } } } }
/// <summary> /// Updates internal cached vars for external physical state -- velocity, dynamic pressure, etc. /// </summary> private void updateParachuteStats() { if (part == null || part.rb == null || vessel == null) { atmoDensity = 0.2; squareVelocity = 1; externalTemp = 350; dynamicPressure = atmoDensity * squareVelocity * 0.5d; return; } atmoDensity = part.atmDensity; squareVelocity = Krakensbane.GetFrameVelocity().sqrMagnitude + part.rb.velocity.sqrMagnitude; externalTemp = vessel.externalTemperature; dynamicPressure = atmoDensity * squareVelocity * 0.5d; //print("dens: " + atmoDensity); //print("sqvel: " + squareVelocity); //print("extemp:" + externalTemp); //print("dynpres:" + dynamicPressure); //print("part.. bucn" + part.buoyancyUseCubeNamed); //print("part.. cob" + part.CenterOfBuoyancy); //print("part.. bus" + part.buoyancyUseSine); //print("part.. cod" + part.CenterOfDisplacement); //print("land: " + vessel.LandedOrSplashed); //print("alt: " + vessel.altitude); //print("alt2: " + vessel.terrainAltitude); //print("alt3: " + vessel.heightFromSurface); //print("alt4: " + vessel.heightFromTerrain); }
void UpdateAerodynamics(ModularFI.ModularFlightIntegrator fi, Part part) { if (part.dragModel != Part.DragModel.CYLINDRICAL || part.vessel.isEVA) //FIXME Proper model for airbrakes { fi.BaseFIUpdateAerodynamics(part); return; } else { Rigidbody rb = part.Rigidbody; if (rb) { part.dragVector = rb.velocity + Krakensbane.GetFrameVelocity(); part.dragVectorSqrMag = part.dragVector.sqrMagnitude; if (part.dragVectorSqrMag == 0f) { 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); part.dragScalar = 0f; } if (!part.DragCubes.None) { part.DragCubes.SetDrag(part.dragVectorDirLocal, (float)fi.mach); } } } }
void UpdateAerodynamics(ModularFI.ModularFlightIntegrator fi, Part part) { if (part.Modules.Contains <ModuleAeroSurface>() || (part.Modules.Contains("MissileLauncher") && part.vessel.rootPart == part)) //FIXME Proper model for airbrakes { fi.BaseFIUpdateAerodynamics(part); return; } else { Rigidbody rb = part.rb; if (rb) { part.dragVector = rb.velocity + Krakensbane.GetFrameVelocity() - FARWind.GetWind(FlightGlobals.currentMainBody, part, rb.position); part.dragVectorSqrMag = part.dragVector.sqrMagnitude; if (part.dragVectorSqrMag == 0f || 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) { part.DragCubes.SetDrag(part.dragVectorDirLocal, (float)fi.mach); } } } }
void FixedUpdate() { if (!gameObject.activeInHierarchy) { return; } //floating origin and velocity offloading corrections if (!FloatingOrigin.Offset.IsZero() || !Krakensbane.GetFrameVelocity().IsZero()) { transform.position -= FloatingOrigin.OffsetNonKrakensbane; startPosition -= FloatingOrigin.OffsetNonKrakensbane; } if (tracerLength == 0) { // visual tracer velocity is relative to the observer linePositions[0] = transform.position + ((currentVelocity - FlightGlobals.ActiveVessel.Velocity()) * tracerDeltaFactor * 0.45f * Time.fixedDeltaTime); } else { linePositions[0] = transform.position + ((currentVelocity - FlightGlobals.ActiveVessel.Velocity()).normalized * tracerLength); } if (fadeColor) { FadeColor(); bulletTrail.material.SetColor("_TintColor", currentColor * tracerLuminance); } linePositions[1] = transform.position; bulletTrail.SetPositions(linePositions); if (Time.time > timeToLiveUntil) //kill bullet when TTL ends { KillBullet(); return; } if (CheckBulletCollision(Time.fixedDeltaTime)) { return; } MoveBullet(Time.fixedDeltaTime); ////////////////////////////////////////////////// //Flak Explosion (air detonation/proximity fuse) ////////////////////////////////////////////////// if (ProximityAirDetonation((float)distanceTraveled)) { //detonate ExplosionFx.CreateExplosion(currPosition, tntMass, explModelPath, explSoundPath, ExplosionSourceType.Bullet, caliber, null, sourceVesselName, null, currentVelocity); KillBullet(); return; } }
/// <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(Vessel vessel) { //if (PilotAssistantFlightCore.calculateDirection) //findVesselFwdAxis(vessl); //else vesselFacingAxis = vessel.transform.up; // 4 frames of reference to use. Orientation, Velocity, and both of the previous parallel to the surface radarAlt = vessel.altitude - (vessel.mainBody.ocean ? Math.Max(vessel.pqsAltitude, 0) : vessel.pqsAltitude); // do not use vessel.rootPart.Rigidbody.velocity as RigidBody can be null during // initialization of scene velocity = vessel.rb_velocity + Krakensbane.GetFrameVelocity(); acceleration = acceleration * 0.8 + 0.2 * (vessel.srfSpeed - oldSpd) / TimeWarp.fixedDeltaTime; // vessel.acceleration.magnitude includes acceleration by gravity vertSpeed = Vector3d.Dot((planetUp + lastPlanetUp) / 2, velocity); // this corrects for the slight angle between planetup and the direction of travel at constant altitude // surface vectors lastPlanetUp = planetUp; planetUp = (vessel.rootPart.transform.position - vessel.mainBody.position).normalized; // planetEast = vessel.mainBody.getRFrmVel(vessel.findWorldCenterOfMass()).normalized; planetEast = vessel.mainBody.getRFrmVel(vessel.GetWorldPos3D()).normalized; planetNorth = Vector3d.Cross(planetEast, planetUp).normalized; // Velocity forward and right vectors parallel to the surface surfVelRight = Vector3d.Cross(planetUp, vessel.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(vessel.obt_velocity, planetUp).normalized; obtRadial = Vector3.Cross(vessel.obt_velocity, obtNormal).normalized; srfNormal = Vector3.Cross(vessel.srf_velocity, planetUp).normalized; srfRadial = Vector3.Cross(vessel.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, vessel.ReferenceTransform.right) * Math.Sign(Vector3d.Dot(surfVesRight, -vessel.ReferenceTransform.forward)); if (vessel.srfSpeed > 1) { Vector3d AoAVec = vessel.srf_velocity.projectOnPlane(vessel.ReferenceTransform.right); AoA = Vector3d.Angle(AoAVec, vesselFacingAxis) * Math.Sign(Vector3d.Dot(AoAVec, vessel.ReferenceTransform.forward)); Vector3d yawVec = vessel.srf_velocity.projectOnPlane(vessel.ReferenceTransform.forward); yaw = Vector3d.Angle(yawVec, vesselFacingAxis) * Math.Sign(Vector3d.Dot(yawVec, vessel.ReferenceTransform.right)); } else { AoA = yaw = 0; } oldSpd = vessel.srfSpeed; }
void FixedUpdate() { if (deployed) { if (Time.time - startTime > 30) { Destroy(gameObject); return; } //floating origin and velocity offloading corrections if (!FloatingOrigin.Offset.IsZero() || !Krakensbane.GetFrameVelocity().IsZero()) { transform.position -= FloatingOrigin.OffsetNonKrakensbane; prevPosition -= FloatingOrigin.OffsetNonKrakensbane; } currPosition = transform.position; float dist = (currPosition - prevPosition).magnitude; Ray ray = new Ray(prevPosition, currPosition - prevPosition); RaycastHit hit; if (Physics.Raycast(ray, out hit, dist, 9076737)) { Part hitPart = null; try { hitPart = hit.collider.gameObject.GetComponentInParent <Part>(); } catch (NullReferenceException) { Debug.Log("[BDArmory]:NullReferenceException for Submunition Hit"); return; } if (hitPart != null || CheckBuildingHit(hit)) { Detonate(hit.point); } else if (hitPart == null) { Detonate(currPosition); } } else if (FlightGlobals.getAltitudeAtPos(currPosition) <= 0) { Detonate(currPosition); } prevPosition = transform.position; } }
static void UpdateWorldLocations() { for (int i = 0; i < activeBlastwaveObjects.Count; ++i) { Blastwave exp = activeBlastwaveObjects[i]; if (floatingOrigin != FloatingOrigin.Offset) { exp.worldLocation += (FloatingOrigin.Offset - floatingOrigin); } exp.worldLocation -= Krakensbane.GetFrameVelocity(); } floatingOrigin = FloatingOrigin.Offset; }
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; }
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(); } } }
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); } }
// 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() { //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; }
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.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()); } } } } }
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); } }
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); } } }
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); }
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; }
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); } }
void FixedUpdate() { if (!gameObject.activeInHierarchy) { return; } //floating origin and velocity offloading corrections if (!FloatingOrigin.Offset.IsZero() || !Krakensbane.GetFrameVelocity().IsZero()) { transform.position -= FloatingOrigin.OffsetNonKrakensbane; startPosition -= FloatingOrigin.OffsetNonKrakensbane; } float distanceFromStart = Vector3.Distance(transform.position, startPosition); //calculate flight time for drag purposes flightTimeElapsed += Time.fixedDeltaTime; // calculate flight distance for achievement purposes distanceTraveled += currentVelocity.magnitude * Time.fixedDeltaTime; //Drag types currently only affect Impactvelocity //Numerical Integration is currently Broken switch (dragType) { case BulletDragTypes.None: break; case BulletDragTypes.AnalyticEstimate: CalculateDragAnalyticEstimate(); break; case BulletDragTypes.NumericalIntegration: CalculateDragNumericalIntegration(); break; } if (tracerLength == 0) { // visual tracer velocity is relative to the observer linePositions[0] = transform.position + ((currentVelocity - FlightGlobals.ActiveVessel.Velocity()) * tracerDeltaFactor * 0.45f * Time.fixedDeltaTime); } else { linePositions[0] = transform.position + ((currentVelocity - FlightGlobals.ActiveVessel.Velocity()).normalized * tracerLength); } if (fadeColor) { FadeColor(); bulletTrail.material.SetColor("_TintColor", currentColor * tracerLuminance); } linePositions[1] = transform.position; bulletTrail.SetPositions(linePositions); currPosition = transform.position; if (Time.time > timeToLiveUntil) //kill bullet when TTL ends { KillBullet(); return; } // bullet collision block { //reset our hit variables to default state hasPenetrated = true; hasDetonated = false; hasRichocheted = false; penTicker = 0; float dist = currentVelocity.magnitude * Time.fixedDeltaTime; bulletRay = new Ray(currPosition, currentVelocity); var hits = Physics.RaycastAll(bulletRay, dist, 9076737); if (hits.Length > 0) { var orderedHits = hits.OrderBy(x => x.distance); using (var hitsEnu = orderedHits.GetEnumerator()) { while (hitsEnu.MoveNext()) { if (!hasPenetrated || hasRichocheted || hasDetonated) { break; } RaycastHit hit = hitsEnu.Current; Part hitPart = null; KerbalEVA hitEVA = null; try { hitPart = hit.collider.gameObject.GetComponentInParent <Part>(); hitEVA = hit.collider.gameObject.GetComponentUpwards <KerbalEVA>(); } catch (NullReferenceException) { Debug.Log("[BDArmory]:NullReferenceException for Ballistic Hit"); return; } if (hitEVA != null) { hitPart = hitEVA.part; // relative velocity, separate from the below statement, because the hitpart might be assigned only above if (hitPart?.rb != null) { impactVelocity = (currentVelocity * dragVelocityFactor - (hitPart.rb.velocity + Krakensbane.GetFrameVelocityV3f())).magnitude; } else { impactVelocity = currentVelocity.magnitude * dragVelocityFactor; } ApplyDamage(hitPart, hit, 1, 1); break; } if (hitPart?.vessel == sourceVessel) { continue; //avoid autohit; } Vector3 impactVector = currentVelocity; if (hitPart?.rb != null) { // using relative velocity vector instead of just bullet velocity // since KSP vessels might move faster than bullets impactVector = currentVelocity * dragVelocityFactor - (hitPart.rb.velocity + Krakensbane.GetFrameVelocityV3f()); } float hitAngle = Vector3.Angle(impactVector, -hit.normal); if (CheckGroundHit(hitPart, hit)) { CheckBuildingHit(hit); if (!RicochetScenery(hitAngle)) { ExplosiveDetonation(hitPart, hit, bulletRay); KillBullet(); } else { DoRicochet(hitPart, hit, hitAngle); } return; } //Standard Pipeline Hitpoints, Armor and Explosives impactVelocity = impactVector.magnitude; float anglemultiplier = (float)Math.Cos(Math.PI * hitAngle / 180.0); float penetrationFactor = CalculateArmorPenetration(hitPart, anglemultiplier, hit); if (penetrationFactor >= 2) { //its not going to bounce if it goes right through hasRichocheted = false; } else { if (RicochetOnPart(hitPart, hit, hitAngle, impactVelocity)) { hasRichocheted = true; } } if (penetrationFactor > 1 && !hasRichocheted) //fully penetrated continue ballistic damage { hasPenetrated = true; ApplyDamage(hitPart, hit, 1, penetrationFactor); penTicker += 1; CheckPartForExplosion(hitPart); //Explosive bullets that penetrate should explode shortly after //if penetration is very great, they will have moved on //checking velocity as they would not be able to come out the other side //if (explosive && penetrationFactor < 3 || currentVelocity.magnitude <= 800f) if (explosive) { //move bullet transform.position += (currentVelocity * Time.fixedDeltaTime) / 3; ExplosiveDetonation(hitPart, hit, bulletRay); hasDetonated = true; KillBullet(); } } else if (!hasRichocheted) // explosive bullets that get stopped by armor will explode { //New method if (hitPart.rb != null) { float forceAverageMagnitude = impactVelocity * impactVelocity * (1f / hit.distance) * (bulletMass - tntMass); float accelerationMagnitude = forceAverageMagnitude / (hitPart.vessel.GetTotalMass() * 1000); hitPart?.rb.AddForceAtPosition(impactVector.normalized * accelerationMagnitude, hit.point, ForceMode.Acceleration); if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BDArmory]: Force Applied " + Math.Round(accelerationMagnitude, 2) + "| Vessel mass in kgs=" + hitPart.vessel.GetTotalMass() * 1000 + "| bullet effective mass =" + (bulletMass - tntMass)); } } hasPenetrated = false; ApplyDamage(hitPart, hit, 1, penetrationFactor); ExplosiveDetonation(hitPart, hit, bulletRay); hasDetonated = true; KillBullet(); } ///////////////////////////////////////////////////////////////////////////////// // penetrated after a few ticks ///////////////////////////////////////////////////////////////////////////////// //penetrating explosive //richochets if ((penTicker >= 2 && explosive) || (hasRichocheted && explosive)) { //detonate ExplosiveDetonation(hitPart, hit, bulletRay, airDetonation); return; } //bullet should not go any further if moving too slowly after hit //smaller caliber rounds would be too deformed to do any further damage if (currentVelocity.magnitude <= 100 && hasPenetrated) { if (BDArmorySettings.DRAW_DEBUG_LABELS) { Debug.Log("[BDArmory]: Bullet Velocity too low, stopping"); } KillBullet(); return; } //we need to stop the loop if the bullet has stopped,richochet or detonated if (!hasPenetrated || hasRichocheted || hasDetonated) { break; } } //end While } //end enumerator } //end if hits } // end if collision ////////////////////////////////////////////////// //Flak Explosion (air detonation/proximity fuse) ////////////////////////////////////////////////// if (ProximityAirDetonation(distanceFromStart)) { //detonate ExplosionFx.CreateExplosion(currPosition, tntMass, explModelPath, explSoundPath, ExplosionSourceType.Bullet, caliber, null, sourceVesselName, null, currentVelocity); KillBullet(); return; } if (bulletDrop) { // Gravity??? var gravity_ = FlightGlobals.getGeeForceAtPosition(transform.position); //var gravity_ = Physics.gravity; currentVelocity += gravity_ * TimeWarp.deltaTime; } //move bullet transform.position += currentVelocity * Time.fixedDeltaTime; }