-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathNavBallDockingAlignmentIndicator.cs
149 lines (125 loc) · 4.53 KB
/
NavBallDockingAlignmentIndicator.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
using System;
using UnityEngine;
using KSP.IO;
[KSPAddon(KSPAddon.Startup.Flight, false)]
public class NavBallDockingAlignmentIndicator : MonoBehaviour
{
private NavBall navBallBehaviour;
private GameObject indicator;
public void Start()
{
PluginConfiguration cfg = KSP.IO.PluginConfiguration.CreateForType<NavBallDockingAlignmentIndicator>();
cfg.load();
Vector3 tmp = cfg.GetValue<Vector3>("alignmentmarkercolor", new Vector3(1f, 0f, 0f)); // default: red
Color alignmentmarkercolor = new Color(tmp.x, tmp.y, tmp.z);
Vector2 alignmentmarkertexture = cfg.GetValue<Vector2>("alignmentmarkertexture", new Vector2(0f, 2f)); // default: prograde marker
cfg.save();
float texturescalefactor = 1f / 3f;
// get navball object
GameObject navBall = GameObject.Find("NavBall");
Transform navBallVectorsPivotTransform = navBall.transform.FindChild("vectorsPivot");
navBallBehaviour = navBall.GetComponent<NavBall>();
// get indicator texture (use the prograde marker, since it has a clear 'upwards' direction)
ManeuverGizmo maneuverGizmo = MapView.ManeuverNodePrefab.GetComponent<ManeuverGizmo>();
ManeuverGizmoHandle maneuverGizmoHandle = maneuverGizmo.handleNormal;
Transform transform = maneuverGizmoHandle.flag;
Renderer renderer = transform.renderer;
Material maneuverTexture = renderer.sharedMaterial;
// create alignment indicator game object
indicator = Create2DObject(
name: "navballalignmentindicator",
size: 0.025f, // the same size as all other markers
col: alignmentmarkercolor,
texture: maneuverTexture,
textureScale: Vector2.one * texturescalefactor,
textureOffset: alignmentmarkertexture * texturescalefactor,
parentTransform: navBallVectorsPivotTransform,
layer: 12 // the navball layer
);
}
private GameObject Create2DObject(
string name,
float size,
Color col,
Material texture,
Vector2 textureScale,
Vector2 textureOffset,
Transform parentTransform,
int layer)
{
GameObject o = new GameObject(name);
Mesh m = new Mesh();
MeshFilter meshFilter = o.AddComponent<MeshFilter>();
o.AddComponent<MeshRenderer>();
const float uvize = 1f;
Vector3 p0 = new Vector3(-size, 0, size);
Vector3 p1 = new Vector3(size, 0, size);
Vector3 p2 = new Vector3(-size, 0, -size);
Vector3 p3 = new Vector3(size, 0, -size);
m.vertices = new[]
{
p0, p1, p2,
p1, p3, p2
};
m.triangles = new[]
{
0, 1, 2,
3, 4, 5
};
Vector2 uv1 = new Vector2(0, 0);
Vector2 uv2 = new Vector2(uvize, uvize);
Vector2 uv3 = new Vector2(0, uvize);
Vector2 uv4 = new Vector2(uvize, 0);
m.uv = new[]{
uv1, uv4, uv3,
uv4, uv2, uv3
};
m.RecalculateNormals();
m.RecalculateBounds();
m.Optimize();
meshFilter.mesh = m;
o.layer = layer;
o.transform.parent = parentTransform;
o.transform.localPosition = Vector3.zero;
o.transform.localRotation = Quaternion.Euler(90f, 180f, 0);
o.renderer.sharedMaterial = new Material(texture);
o.renderer.sharedMaterial.mainTextureScale = textureScale;
o.renderer.sharedMaterial.mainTextureOffset = textureOffset;
o.renderer.sharedMaterial.color = col;
return o;
}
public void LateUpdate()
{
if(FlightGlobals.ready == false) {
return;
}
if(FlightGlobals.fetch != null) {
if(FlightGlobals.fetch.VesselTarget != null) {
if(FlightGlobals.fetch.VesselTarget.GetTargetingMode() == VesselTargetModes.DirectionVelocityAndOrientation) {
ITargetable targetPort = FlightGlobals.fetch.VesselTarget;
Transform targetTransform = targetPort.GetTransform();
Transform selfTransform = FlightGlobals.ActiveVessel.ReferenceTransform;
// indicator position
Vector3 targetPortOutVector = targetTransform.forward.normalized;
Vector3 targetPortInVector = -targetPortOutVector;
Vector3 rotatedTargetPortInVector = navBallBehaviour.attitudeGymbal * targetPortInVector;
indicator.transform.localPosition = rotatedTargetPortInVector * navBallBehaviour.progradeVector.localPosition.magnitude;
// indicator rotation
Vector3 v1 = Vector3.Cross(selfTransform.up, -targetTransform.up);
Vector3 v2 = Vector3.Cross(selfTransform.up, selfTransform.forward);
float ang = Vector3.Angle(v1, v2);
if(Vector3.Dot(selfTransform.up, Vector3.Cross(v1, v2)) < 0) {
ang = -ang;
}
indicator.transform.rotation = Quaternion.Euler(90 + ang, 90, 270);
// indicator visibility (invisible if on back half sphere)
indicator.SetActive(indicator.transform.localPosition.z > 0.0d);
return;
}
}
}
// no docking port is currently selected
indicator.SetActive(false);
return;
}
}