Skip to content

Commit a873363

Browse files
committed
add mapcamera
1 parent 4158e54 commit a873363

4 files changed

Lines changed: 240 additions & 5 deletions

File tree

GameData/kOS-Addons/StockCamera/KOS-StockCamera.version

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
},
1111
"VERSION": {
1212
"MAJOR": 0,
13-
"MINOR": 1,
14-
"PATCH": 2
13+
"MINOR": 2,
14+
"PATCH": 0
1515
},
1616
"KSP_VERSION": {
1717
"MAJOR": 1,

src/kOS.Addons.StockCamera/Addon.cs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using kOS.Safe.Encapsulation;
1+
using System;
2+
using kOS.Safe.Encapsulation;
23
using kOS.Safe.Encapsulation.Suffixes;
34
using kOS.Safe.Utilities;
45

@@ -9,13 +10,15 @@ namespace kOS.AddOns.StockCamera
910
public class Addon : Suffixed.Addon
1011
{
1112
private FlightCameraValue flightCam;
13+
private MapCameraValue mapCam;
1214

1315
public Addon(SharedObjects shared) : base(shared)
1416
{
1517
AddSuffix("FLIGHTCAMERA", new Suffix<FlightCameraValue>(GetFlightCamera));
18+
AddSuffix("MAPCAMERA", new Suffix<MapCameraValue>(GetMapCamera));
1619
}
1720

18-
public override BooleanValue Available()
21+
public override BooleanValue Available()
1922
{
2023
return BooleanValue.True;
2124
}
@@ -28,5 +31,14 @@ public FlightCameraValue GetFlightCamera()
2831
}
2932
return flightCam;
3033
}
31-
}
34+
35+
private MapCameraValue GetMapCamera()
36+
{
37+
if (mapCam == null)
38+
{
39+
mapCam = new MapCameraValue(shared);
40+
}
41+
return mapCam;
42+
}
43+
}
3244
}
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using kOS.Safe.Encapsulation;
6+
using kOS.Safe.Encapsulation.Suffixes;
7+
using kOS.Safe.Exceptions;
8+
using kOS.Safe.Utilities;
9+
using kOS.Suffixed;
10+
using kOS.Utilities;
11+
12+
namespace kOS.AddOns.StockCamera
13+
{
14+
[KOSNomenclature("MapCamera")]
15+
public class MapCameraValue : Structure
16+
{
17+
private SharedObjects shared;
18+
19+
public MapCameraValue(SharedObjects shared)
20+
{
21+
this.shared = shared;
22+
23+
AddSuffix("SETFILTER", new TwoArgsSuffix<StringValue, BooleanValue>(SetFilter));
24+
AddSuffix("GETFILTER", new OneArgsSuffix<BooleanValue, StringValue>(GetFilter));
25+
AddSuffix("COMMNETMODE", new SetSuffix<StringValue>(GetCommNetMode, SetCommNetMode));
26+
AddSuffix(new string[] { "PITCH", "CAMERAPITCH" }, new SetSuffix<ScalarValue>(GetCameraPitch, SetCameraPitch));
27+
AddSuffix(new string[] { "HDG", "HEADING", "CAMERAHDG" }, new SetSuffix<ScalarValue>(GetCameraHdg, SetCameraHdg));
28+
AddSuffix(new string[] { "DISTANCE", "CAMERADISTANCE" }, new SetSuffix<ScalarValue>(GetCameraDistance, SetCameraDistance));
29+
AddSuffix(new string[] { "POSITION", "CAMERAPOSITION" }, new SetSuffix<Vector>(GetCameraPosition, SetCameraPosition));
30+
AddSuffix("TARGET", new SetSuffix<Structure>(GetTarget, SetTarget));
31+
AddSuffix("FILTERNAMES", new Suffix<ListValue>(GetFilterNames));
32+
AddSuffix("COMMNETNAMES", new Suffix<ListValue>(GetCommNetNames));
33+
}
34+
35+
private ListValue GetCommNetNames()
36+
{
37+
return new ListValue(Enum.GetNames(typeof(CommNet.CommNetUI.DisplayMode)).Select(s => new StringValue(s)));
38+
}
39+
40+
private ListValue GetFilterNames()
41+
{
42+
return new ListValue(Enum.GetNames(typeof(MapViewFiltering.VesselTypeFilter)).Select(s => new StringValue(s)));
43+
}
44+
45+
private void SetCameraDistance(ScalarValue value)
46+
{
47+
PlanetariumCamera.fetch.SetDistance(value / ScaledSpace.ScaleFactor);
48+
}
49+
50+
private ScalarValue GetCameraDistance()
51+
{
52+
return PlanetariumCamera.fetch.Distance * ScaledSpace.ScaleFactor;
53+
}
54+
55+
private void SetCameraPosition(Vector value)
56+
{
57+
PlanetariumCamera.fetch.SetCamCoordsFromPosition(ScaledSpace.LocalToScaledSpace(value.ToVector3() + shared.Vessel.CoMD));
58+
}
59+
60+
private Vector GetCameraPosition()
61+
{
62+
return new Vector(ScaledSpace.ScaledToLocalSpace(PlanetariumCamera.fetch.transform.position) - shared.Vessel.CoMD);
63+
}
64+
65+
private void SetCameraHdg(ScalarValue value)
66+
{
67+
PlanetariumCamera.fetch.camHdg = (float)Utils.DegreesToRadians(value.GetDoubleValue());
68+
}
69+
70+
private ScalarValue GetCameraHdg()
71+
{
72+
// note - this converts to degrees
73+
return PlanetariumCamera.fetch.getYaw();
74+
}
75+
76+
private void SetCameraPitch(ScalarValue value)
77+
{
78+
var camera = PlanetariumCamera.fetch;
79+
float pitch = (float)Utils.DegreesToRadians(value.GetDoubleValue());
80+
camera.camPitch = Math.Max(camera.minPitch, Math.Min(camera.maxPitch, pitch));
81+
}
82+
83+
private ScalarValue GetCameraPitch()
84+
{
85+
// note - this converts to degrees
86+
return PlanetariumCamera.fetch.getPitch();
87+
}
88+
89+
private Structure GetTarget()
90+
{
91+
MapObject target = PlanetariumCamera.fetch.target;
92+
93+
if (target.vessel != null)
94+
{
95+
return VesselTarget.CreateOrGetExisting(PlanetariumCamera.fetch.target.vessel, shared);
96+
}
97+
else if (target.celestialBody != null)
98+
{
99+
return BodyTarget.CreateOrGetExisting(target.celestialBody, shared);
100+
}
101+
else if (target.maneuverNode != null)
102+
{
103+
// NOTE: assumption that this node is for the active vessel...
104+
// is it possible to focus on nodes of other vessels? Maybe only if it's your target?
105+
return Node.FromExisting(FlightGlobals.ActiveVessel, target.maneuverNode, shared);
106+
}
107+
else
108+
{
109+
throw new KOSException("Don't know how to handle mapview target type {0}", target.type);
110+
}
111+
}
112+
113+
private void SetTarget(Structure value)
114+
{
115+
if (value is VesselTarget vessel)
116+
{
117+
PlanetariumCamera.fetch.SetTarget(vessel.Vessel.mapObject);
118+
}
119+
else if (value is BodyTarget body)
120+
{
121+
PlanetariumCamera.fetch.SetTarget(body.Body);
122+
}
123+
else if (value is Node node)
124+
{
125+
var v = shared.Vessel;
126+
127+
// since KOS doesn't expose the internal ManeuverNode,
128+
// instead we have to go find it
129+
if (v.patchedConicSolver != null)
130+
{
131+
var maneuverNode = v.patchedConicSolver.maneuverNodes.SingleOrDefault(m => Node.FromExisting(v, m, shared) == node);
132+
var targetMapObject = maneuverNode == null ? null :
133+
PlanetariumCamera.fetch.targets.SingleOrDefault(t => t.maneuverNode == maneuverNode);
134+
135+
if (targetMapObject != null)
136+
{
137+
PlanetariumCamera.fetch.SetTarget(targetMapObject);
138+
}
139+
}
140+
}
141+
else
142+
{
143+
throw new KOSException("Invalid mapview target type - must be vessel, body, or node");
144+
}
145+
}
146+
147+
CommNet.CommNetUI.DisplayMode ParseCommNetMode(string name)
148+
{
149+
if (Enum.TryParse(name, true, out CommNet.CommNetUI.DisplayMode mode))
150+
{
151+
return mode;
152+
}
153+
else
154+
{
155+
throw new KOSException("Invalid CommNet display mode: {0}", name);
156+
}
157+
}
158+
159+
private void SetCommNetMode(StringValue value)
160+
{
161+
CommNet.CommNetUI.ModeFlightMap = ParseCommNetMode(value);
162+
}
163+
164+
private StringValue GetCommNetMode()
165+
{
166+
return CommNet.CommNetUI.ModeFlightMap.ToString();
167+
}
168+
169+
MapViewFiltering.VesselTypeFilter GetFilterValue(string filterName)
170+
{
171+
if (Enum.TryParse(filterName, true, out MapViewFiltering.VesselTypeFilter filterValue))
172+
{
173+
return filterValue;
174+
}
175+
else
176+
{
177+
throw new KOSException("Invalid map filter type: {0}", filterName);
178+
}
179+
}
180+
181+
private BooleanValue GetFilter(StringValue filter)
182+
{
183+
var filterValue = GetFilterValue(filter);
184+
int filterState = MapViewFiltering.GetFilterState();
185+
186+
if (filterValue == MapViewFiltering.VesselTypeFilter.All)
187+
{
188+
// assume the last value is the largest
189+
var values = Enum.GetValues(typeof(MapViewFiltering.VesselTypeFilter));
190+
int mask = (int)values.GetValue(values.Length - 1) * 2 - 1;
191+
192+
return filterState == mask;
193+
}
194+
else if (filterValue == MapViewFiltering.VesselTypeFilter.None)
195+
{
196+
return filterState == 0;
197+
}
198+
else
199+
{
200+
return (filterState & (int)filterValue) != 0;
201+
}
202+
}
203+
204+
private void SetFilter(StringValue filter, BooleanValue visible)
205+
{
206+
var filterValue = GetFilterValue(filter);
207+
int filterState = MapViewFiltering.GetFilterState();
208+
209+
if (visible)
210+
{
211+
filterState = filterState | (int)filterValue;
212+
}
213+
else
214+
{
215+
filterState = filterState & ~(int)filterValue;
216+
}
217+
218+
MapViewFiltering.SetFilter((MapViewFiltering.VesselTypeFilter)filterState);
219+
}
220+
}
221+
}

src/kOS.Addons.StockCamera/kOS.AddOns.StockCamera.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@
6464
<ItemGroup>
6565
<Compile Include="Addon.cs" />
6666
<Compile Include="FlightCameraValue.cs" />
67+
<Compile Include="MapCameraValue.cs" />
6768
<Compile Include="Properties\AssemblyInfo.cs" />
69+
<Compile Include="Safe\IUpdateObserver.cs" />
6870
</ItemGroup>
6971
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
7072
<PropertyGroup>

0 commit comments

Comments
 (0)