Last active
December 23, 2015 05:49
-
-
Save JDPKSP/6589153 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using UnityEngine; | |
class ModuleSolarSail : ModuleAnimateGeneric { | |
[KSPField] | |
public string ForceTransformName = "ForceTransform"; | |
[KSPField] | |
public float MaxForce = 0f; | |
private Transform ForceTransform; | |
//returns the direction of the green axis of the ForceTransform. | |
private Vector3 ForceDir { | |
get { | |
return ForceTransform.up; | |
} | |
} | |
bool lineOfSight(Vector3 Origin, Vector3 Target, Vector3 sunDir) { | |
//check for all CelesTialBodies except the sun and return false if the body obstructs the sun. | |
foreach (CelestialBody referenceBody in FlightGlobals.Bodies) | |
if (referenceBody != Planetarium.fetch.Sun) { | |
Vector3d bodyFromOrigin = referenceBody.position - Origin; | |
Vector3d OriginFromTarget = Target - Origin; | |
if (Vector3d.Dot(bodyFromOrigin, OriginFromTarget) > 0) { | |
Vector3d bFromAnorm = OriginFromTarget.normalized; | |
if (Vector3d.Dot(bodyFromOrigin, bFromAnorm) < OriginFromTarget.magnitude) { // check lateral offset from line between b and a | |
Vector3d lateralOffset = bodyFromOrigin - Vector3d.Dot(bodyFromOrigin, bFromAnorm) * bFromAnorm; | |
if (lateralOffset.magnitude < (referenceBody.Radius - 5)) { | |
return false; | |
} | |
} | |
} | |
} | |
//check if any colliders within the 2 km loading range obstructs the sun. | |
if (Physics.Raycast(Origin, sunDir, 2000)) return false; | |
return true; | |
} | |
//returns a rough area representation of the angle; going from 0, if right angle (90 degrees) to 1 if 0 degrees. | |
private float ForceModifier { | |
get { | |
Vector3 Origin = ForceTransform.position; | |
Vector3 Sun = Planetarium.fetch.Sun.position; | |
Vector3 SunDir = (Sun - Origin).normalized; | |
//return 0 if sun is obstructed. | |
if (!lineOfSight(Origin, Sun, SunDir)) return 0; | |
float angle = Mathf.Deg2Rad * Vector3.Angle(SunDir, ForceDir); | |
//returns negative if the sun is behind the sail (angle above 90 degrees), resulting in a negative force being applied, accelerating in the correct direction (away from the sun). | |
//if this behaviour is not wanted, just return 1f - (float)Math.Cos(angle) | |
if (angle > Math.PI / 2) | |
return -(1f - (float)Math.Cos(angle)); | |
else | |
return 1f - (float)Math.Cos(angle); | |
} | |
} | |
public override void OnStart(PartModule.StartState state) { | |
base.OnStart(state); | |
//find the ForceTransform; | |
this.ForceTransform = part.FindModelTransform(ForceTransformName); | |
} | |
public override void OnUpdate() { | |
base.OnUpdate(); | |
float forcemodifier = ForceModifier; | |
//do nothing if the sail is folded or no force should be applied. | |
if (!base.animSwitch || forcemodifier == 0) return; | |
//Change orbit velocity if physics is not active, apply force if physics is active | |
if (vessel.HoldPhysics) { | |
float acceleration = (MaxForce * forcemodifier) / vessel.GetTotalMass(); | |
vessel.orbit.vel += ForceDir * acceleration * TimeWarp.deltaTime; | |
} else | |
part.rigidbody.AddForce(ForceDir * MaxForce * forcemodifier * TimeWarp.deltaTime); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment