├── .gitattributes
├── .gitignore
├── CHANGELOG.md
├── CameraTools.sln
├── CameraTools
├── CCInputUtils.cs
├── CTAtmosphericAudioController.cs
├── CTPartAudioController.cs
├── CTPersistantFIeld.cs
├── CamTools.cs
├── CameraKeyframe.cs
├── CameraPath.cs
├── CameraTools.csproj
├── CameraTransformation.cs
├── Curve3D.cs
├── Distribution
│ └── GameData
│ │ └── CameraTools
│ │ ├── ATM_CameraTools.cfg
│ │ ├── CameraTools.version
│ │ ├── Changelog.txt
│ │ ├── License.txt
│ │ ├── Plugins
│ │ └── CameraTools.dll
│ │ ├── Sounds
│ │ ├── sonicBoom.wav
│ │ ├── windhowl.wav
│ │ ├── windloop.wav
│ │ └── windtear.wav
│ │ ├── Textures
│ │ └── icon.png
│ │ ├── paths.cfg
│ │ └── settings.cfg
├── LocalDev
│ ├── 7za_dir.txt
│ ├── dist_dir.txt
│ ├── ksp_dir.txt
│ ├── ksp_dir2.txt
│ ├── mono_exe.txt
│ └── pdb2mdb_exe.txt
├── Properties
│ └── AssemblyInfo.cs
├── RotationAnimation.cs
├── Vector3Animation.cs
└── bin
│ └── Release
│ └── CameraTools.dll
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 | *.sln merge=union
7 | *.csproj merge=union
8 | *.vbproj merge=union
9 | *.fsproj merge=union
10 | *.dbproj merge=union
11 |
12 | # Standard to msysgit
13 | *.doc diff=astextplain
14 | *.DOC diff=astextplain
15 | *.docx diff=astextplain
16 | *.DOCX diff=astextplain
17 | *.dot diff=astextplain
18 | *.DOT diff=astextplain
19 | *.pdf diff=astextplain
20 | *.PDF diff=astextplain
21 | *.rtf diff=astextplain
22 | *.RTF diff=astextplain
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | ## private libraries
5 | Assembly*
6 | System*
7 | mscorlib.dll
8 | Mono*
9 | TrackIR*
10 | Unity*
11 | TDx*
12 |
13 | # User-specific files
14 | *.suo
15 | *.user
16 | *.sln.docstates
17 |
18 | # Build results
19 | [Dd]ebug/
20 | [Dd]ebugPublic/
21 | #[Rr]elease/
22 | x64/
23 | build/
24 | bld/
25 | # [Bb]in/
26 | [Oo]bj/
27 |
28 | # MSTest test Results
29 | [Tt]est[Rr]esult*/
30 | [Bb]uild[Ll]og.*
31 |
32 | #NUNIT
33 | *.VisualState.xml
34 | TestResult.xml
35 |
36 | # Build Results of an ATL Project
37 | [Dd]ebugPS/
38 | [Rr]eleasePS/
39 | dlldata.c
40 |
41 | *_i.c
42 | *_p.c
43 | *_i.h
44 | *.ilk
45 | *.meta
46 | *.obj
47 | *.pch
48 | *.pdb
49 | *.pgc
50 | *.pgd
51 | *.rsp
52 | *.sbr
53 | *.tlb
54 | *.tli
55 | *.tlh
56 | *.tmp
57 | *.tmp_proj
58 | *.log
59 | *.vspscc
60 | *.vssscc
61 | .builds
62 | *.pidb
63 | *.svclog
64 | *.scc
65 |
66 | # Chutzpah Test files
67 | _Chutzpah*
68 |
69 | # Visual C++ cache files
70 | ipch/
71 | *.aps
72 | *.ncb
73 | *.opensdf
74 | *.sdf
75 | *.cachefile
76 |
77 | # Visual Studio profiler
78 | *.psess
79 | *.vsp
80 | *.vspx
81 |
82 | # TFS 2012 Local Workspace
83 | $tf/
84 |
85 | # Guidance Automation Toolkit
86 | *.gpState
87 |
88 | # ReSharper is a .NET coding add-in
89 | _ReSharper*/
90 | *.[Rr]e[Ss]harper
91 | *.DotSettings.user
92 |
93 | # JustCode is a .NET coding addin-in
94 | .JustCode
95 |
96 | # TeamCity is a build add-in
97 | _TeamCity*
98 |
99 | # DotCover is a Code Coverage Tool
100 | *.dotCover
101 |
102 | # NCrunch
103 | *.ncrunch*
104 | _NCrunch_*
105 | .*crunch*.local.xml
106 |
107 | # MightyMoose
108 | *.mm.*
109 | AutoTest.Net/
110 |
111 | # Web workbench (sass)
112 | .sass-cache/
113 |
114 | # Installshield output folder
115 | [Ee]xpress/
116 |
117 | # DocProject is a documentation generator add-in
118 | DocProject/buildhelp/
119 | DocProject/Help/*.HxT
120 | DocProject/Help/*.HxC
121 | DocProject/Help/*.hhc
122 | DocProject/Help/*.hhk
123 | DocProject/Help/*.hhp
124 | DocProject/Help/Html2
125 | DocProject/Help/html
126 |
127 | # Click-Once directory
128 | publish/
129 |
130 | # Publish Web Output
131 | *.[Pp]ublish.xml
132 | *.azurePubxml
133 |
134 | # NuGet Packages Directory
135 | packages/
136 | ## TODO: If the tool you use requires repositories.config uncomment the next line
137 | #!packages/repositories.config
138 |
139 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets
140 | # This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented)
141 | !packages/build/
142 |
143 | # Windows Azure Build Output
144 | csx/
145 | *.build.csdef
146 |
147 | # Windows Store app package directory
148 | AppPackages/
149 |
150 | # Others
151 | sql/
152 | *.Cache
153 | ClientBin/
154 | [Ss]tyle[Cc]op.*
155 | ~$*
156 | *~
157 | *.dbmdl
158 | *.dbproj.schemaview
159 | *.pfx
160 | *.publishsettings
161 | node_modules/
162 |
163 | # RIA/Silverlight projects
164 | Generated_Code/
165 |
166 | # Backup & report files from converting an old project file to a newer
167 | # Visual Studio version. Backup files are not needed, because we have git ;-)
168 | _UpgradeReport_Files/
169 | Backup*/
170 | UpgradeLog*.XML
171 | UpgradeLog*.htm
172 |
173 | # SQL Server files
174 | *.mdf
175 | *.ldf
176 |
177 | # Business Intelligence projects
178 | *.rdl.data
179 | *.bim.layout
180 | *.bim_*.settings
181 |
182 | # Microsoft Fakes
183 | FakesAssemblies/
184 |
185 | # =========================
186 | # Operating System Files
187 | # =========================
188 |
189 | # OSX
190 | # =========================
191 |
192 | .DS_Store
193 | .AppleDouble
194 | .LSOverride
195 |
196 | # Icon must ends with two \r.
197 | Icon
198 | # Thumbnails
199 | ._*
200 |
201 | # Files that might appear on external disk
202 | .Spotlight-V100
203 | .Trashes
204 |
205 | # Windows
206 | # =========================
207 |
208 | # Windows image file caches
209 | Thumbs.db
210 | ehthumbs.db
211 |
212 | # Folder config file
213 | Desktop.ini
214 |
215 | # Recycle Bin used on file shares
216 | $RECYCLE.BIN/
217 |
218 | # Windows Installer files
219 | *.cab
220 | *.msi
221 | *.msm
222 | *.msp
223 |
224 | *.zip
225 | *.bat
226 |
227 | KSPAssets.dll
228 | KSPCore.dll
229 | KSPUtil.dll
230 | SaveUpgradePipeline.Core.dll
231 | Vectrosity.dll
232 |
233 | /CameraTools/libs
234 | /.vs/config
235 | /CameraTools.sln.DotSettings
236 | /.vs/CameraTools/v15/sqlite3/storage.ide
237 | /.vs/CameraTools
238 | /.vs
239 | /CameraTools/bin/Release/KSPTrackIR.dll
240 | /CameraTools/bin/Release/KSPAssets.XmlSerializers.dll
241 | /CameraTools/bin/Release/Ionic.Zip.dll
242 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 |
2 | All changes below here are by BahamutoD with the exception of my recompile.
3 |
4 | v1.6.0 recompiled for 1.1.3 by westamastaflash
5 | - 1.1 compat and path tool
6 | - fix loading paths/deleting paths, fix deleting selected key
7 | - set spatial blend to 3d audio
8 |
9 | v1.5.1
10 | - Dogfight mode auto-resets when a new target is selected or active vessel is switched
11 | - Auto targeting option with BDArmory AI pilot target
12 |
13 | v1.5
14 | - Dogfight chase mode
15 | - Autozoom margin slider
16 |
17 | v1.4.2
18 | - Slight UI tweak
19 | - Incremental buttons for manual offset
20 |
21 | v1.4.1
22 | - Ability to save persistant settings
23 | - Fixed part audio too loud when stationary
24 | - Fixed inability to select auto position without unchecking manual position
25 | - Stopped sonic boom being played when vessel breaks sound barrier after wavefront already passed camera
26 | - Increased sonic boom volume
27 | - Temporary fix for silent atmospheric audio when >~600m/s
28 |
29 | v1.4
30 | - Atmospheric audio effects (toggleable)
31 | - Camera shake (adjustable)
32 |
33 | v1.3
34 | - 1.0+ Compatibility
35 | - Manual camera position now persists after resetting camera
36 | - Bind activate/reset key by recording instead of typing button name
37 | - Camera no longer resets when pausing
38 |
39 |
40 | v1.2
41 | - Added Orbit frame of reference
42 | - Fixed issues with setting camera offset to vertically launching vehicles
43 |
44 | v1.1
45 | - 0.25 update
46 | - Added ability to set location -before- activating camera
47 | - Fixed text fields in GUI (it won't fight you when entering negatives or decimals)
48 | - Fixed Toolbar Icon
49 | - Greatly reduced motion of stationary camera when vessel is accelerating/turning
50 |
51 |
52 | v1.0
53 | - Initial release
--------------------------------------------------------------------------------
/CameraTools.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25420.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CameraTools", "CameraTools\CameraTools.csproj", "{446E2470-00DC-4835-B62D-9DB8A7D41F4A}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Debug|x86 = Debug|x86
12 | Release|Any CPU = Release|Any CPU
13 | Release|x86 = Release|x86
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {446E2470-00DC-4835-B62D-9DB8A7D41F4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {446E2470-00DC-4835-B62D-9DB8A7D41F4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {446E2470-00DC-4835-B62D-9DB8A7D41F4A}.Debug|x86.ActiveCfg = Debug|x86
19 | {446E2470-00DC-4835-B62D-9DB8A7D41F4A}.Debug|x86.Build.0 = Debug|x86
20 | {446E2470-00DC-4835-B62D-9DB8A7D41F4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {446E2470-00DC-4835-B62D-9DB8A7D41F4A}.Release|Any CPU.Build.0 = Release|Any CPU
22 | {446E2470-00DC-4835-B62D-9DB8A7D41F4A}.Release|x86.ActiveCfg = Release|x86
23 | {446E2470-00DC-4835-B62D-9DB8A7D41F4A}.Release|x86.Build.0 = Release|x86
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | GlobalSection(MonoDevelopProperties) = preSolution
29 | StartupItem = CameraTools.csproj
30 | EndGlobalSection
31 | EndGlobal
32 |
--------------------------------------------------------------------------------
/CameraTools/CCInputUtils.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.18449
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 | using System;
11 | using UnityEngine;
12 |
13 | namespace CameraTools
14 | {
15 | public class CCInputUtils
16 | {
17 | public static string GetInputString()
18 | {
19 | //keyCodes
20 | string[] names = System.Enum.GetNames(typeof(KeyCode));
21 | int numberOfKeycodes = names.Length;
22 |
23 | for(int i = 0; i < numberOfKeycodes; i++)
24 | {
25 | string output = names[i];
26 |
27 | if(output.Contains("Keypad"))
28 | {
29 | output = "["+output.Substring(6).ToLower()+"]";
30 | }
31 | else if(output.Contains("Alpha"))
32 | {
33 | output = output.Substring(5);
34 | }
35 | else //lower case key
36 | {
37 | output = output.ToLower();
38 | }
39 |
40 | //modifiers
41 | if(output.Contains("control"))
42 | {
43 | output = output.Split('c')[0] + " ctrl";
44 | }
45 | else if(output.Contains("alt"))
46 | {
47 | output = output.Split('a')[0] + " alt";
48 | }
49 | else if(output.Contains("shift"))
50 | {
51 | output = output.Split ('s')[0] + " shift";
52 | }
53 | else if(output.Contains("command"))
54 | {
55 | output = output.Split('c')[0]+" cmd";
56 | }
57 |
58 |
59 | //special keys
60 | else if(output == "backslash")
61 | {
62 | output = @"\";
63 | }
64 | else if(output == "backquote")
65 | {
66 | output = "`";
67 | }
68 | else if(output == "[period]")
69 | {
70 | output = "[.]";
71 | }
72 | else if(output == "[plus]")
73 | {
74 | output = "[+]";
75 | }
76 | else if(output == "[multiply]")
77 | {
78 | output = "[*]";
79 | }
80 | else if(output == "[divide]")
81 | {
82 | output = "[/]";
83 | }
84 | else if(output == "[minus]")
85 | {
86 | output = "[-]";
87 | }
88 | else if(output == "[enter]")
89 | {
90 | output = "enter";
91 | }
92 | else if(output.Contains("page"))
93 | {
94 | output = output.Insert(4, " ");
95 | }
96 | else if(output.Contains("arrow"))
97 | {
98 | output = output.Split('a')[0];
99 | }
100 | else if(output == "capslock")
101 | {
102 | output = "caps lock";
103 | }
104 | else if(output == "minus")
105 | {
106 | output = "-";
107 | }
108 |
109 | //test if input is valid
110 | try
111 | {
112 | if(Input.GetKey(output))
113 | {
114 | return output;
115 | }
116 | }
117 | catch(System.Exception)
118 | {
119 | }
120 |
121 | }
122 |
123 | //mouse
124 | for(int m = 0; m < 6; m++)
125 | {
126 | string inputString = "mouse "+m;
127 | try
128 | {
129 | if(Input.GetKey(inputString))
130 | {
131 | return inputString;
132 | }
133 | }
134 | catch(UnityException)
135 | {
136 | Debug.Log ("Invalid mouse: "+inputString);
137 | }
138 | }
139 |
140 | //joysticks
141 | for(int j = 1; j < 12; j++)
142 | {
143 | for(int b = 0; b<20; b++)
144 | {
145 | string inputString = "joystick "+j+" button "+b;
146 | try
147 | {
148 | if(Input.GetKey(inputString))
149 | {
150 | return inputString;
151 | }
152 | }
153 | catch(UnityException)
154 | {
155 | return string.Empty;
156 | }
157 |
158 | }
159 | }
160 |
161 | return string.Empty;
162 | }
163 |
164 |
165 | }
166 | }
167 |
168 |
--------------------------------------------------------------------------------
/CameraTools/CTAtmosphericAudioController.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace CameraTools
4 | {
5 | public class CTAtmosphericAudioController : MonoBehaviour
6 | {
7 | AudioSource windAudioSource;
8 | AudioSource windHowlAudioSource;
9 | AudioSource windTearAudioSource;
10 |
11 | AudioSource sonicBoomSource;
12 |
13 | Vessel vessel;
14 |
15 | bool playedBoom = false;
16 |
17 | void Awake()
18 | {
19 | vessel = GetComponent();
20 | windAudioSource = gameObject.AddComponent();
21 | windAudioSource.minDistance = 10;
22 | windAudioSource.maxDistance = 10000;
23 | windAudioSource.dopplerLevel = .35f;
24 | windAudioSource.spatialBlend = 1;
25 | AudioClip windclip = GameDatabase.Instance.GetAudioClip("CameraTools/Sounds/windloop");
26 | if(!windclip)
27 | {
28 | Destroy (this);
29 | return;
30 | }
31 | windAudioSource.clip = windclip;
32 |
33 | windHowlAudioSource = gameObject.AddComponent();
34 | windHowlAudioSource.minDistance = 10;
35 | windHowlAudioSource.maxDistance = 7000;
36 | windHowlAudioSource.dopplerLevel = .5f;
37 | windHowlAudioSource.pitch = 0.25f;
38 | windHowlAudioSource.clip = GameDatabase.Instance.GetAudioClip("CameraTools/Sounds/windhowl");
39 | windHowlAudioSource.spatialBlend = 1;
40 |
41 | windTearAudioSource = gameObject.AddComponent();
42 | windTearAudioSource.minDistance = 10;
43 | windTearAudioSource.maxDistance = 5000;
44 | windTearAudioSource.dopplerLevel = 0.45f;
45 | windTearAudioSource.pitch = 0.65f;
46 | windTearAudioSource.clip = GameDatabase.Instance.GetAudioClip("CameraTools/Sounds/windtear");
47 | windTearAudioSource.spatialBlend = 1;
48 |
49 | sonicBoomSource = new GameObject().AddComponent();
50 | sonicBoomSource.transform.parent = vessel.transform;
51 | sonicBoomSource.transform.localPosition = Vector3.zero;
52 | sonicBoomSource.minDistance = 50;
53 | sonicBoomSource.maxDistance = 20000;
54 | sonicBoomSource.dopplerLevel = 0;
55 | sonicBoomSource.clip = GameDatabase.Instance.GetAudioClip("CameraTools/Sounds/sonicBoom");
56 | sonicBoomSource.volume = Mathf.Clamp01(vessel.GetTotalMass()/4f);
57 | sonicBoomSource.Stop();
58 | sonicBoomSource.spatialBlend = 1;
59 |
60 | float angleToCam = Vector3.Angle(vessel.srf_velocity, FlightCamera.fetch.mainCamera.transform.position - vessel.transform.position);
61 | angleToCam = Mathf.Clamp(angleToCam, 1, 180);
62 | if(vessel.srfSpeed / (angleToCam) < 3.67f)
63 | {
64 | playedBoom = true;
65 | }
66 |
67 | CamTools.OnResetCTools += OnResetCTools;
68 | }
69 |
70 |
71 | void FixedUpdate()
72 | {
73 | if(!vessel)
74 | {
75 | return;
76 | }
77 | if(Time.timeScale > 0 && vessel.dynamicPressurekPa > 0)
78 | {
79 | float srfSpeed = (float)vessel.srfSpeed;
80 | srfSpeed = Mathf.Min(srfSpeed, 550f);
81 | float angleToCam = Vector3.Angle(vessel.srf_velocity, FlightCamera.fetch.mainCamera.transform.position - vessel.transform.position);
82 | angleToCam = Mathf.Clamp(angleToCam, 1, 180);
83 |
84 |
85 | float lagAudioFactor = (75000 / (Vector3.Distance(vessel.transform.position, FlightCamera.fetch.mainCamera.transform.position) * srfSpeed * angleToCam / 90));
86 | lagAudioFactor = Mathf.Clamp(lagAudioFactor * lagAudioFactor * lagAudioFactor, 0, 4);
87 | lagAudioFactor += srfSpeed / 230;
88 |
89 | float waveFrontFactor = ((3.67f * angleToCam)/srfSpeed);
90 | waveFrontFactor = Mathf.Clamp(waveFrontFactor * waveFrontFactor * waveFrontFactor, 0, 2);
91 |
92 |
93 | if(vessel.srfSpeed > CamTools.speedOfSound)
94 | {
95 | waveFrontFactor = (srfSpeed / (angleToCam) < 3.67f) ? waveFrontFactor + ((srfSpeed/(float)CamTools.speedOfSound)*waveFrontFactor) : 0;
96 | if(waveFrontFactor > 0)
97 | {
98 | if(!playedBoom)
99 | {
100 | sonicBoomSource.transform.position = vessel.transform.position + (-vessel.srf_velocity);
101 | sonicBoomSource.PlayOneShot(sonicBoomSource.clip);
102 | }
103 | playedBoom = true;
104 | }
105 | else
106 | {
107 |
108 | }
109 | }
110 | else if(CamTools.speedOfSound / (angleToCam) < 3.67f)
111 | {
112 | playedBoom = true;
113 | }
114 |
115 | lagAudioFactor *= waveFrontFactor;
116 |
117 | float sqrAccel = (float)vessel.acceleration.sqrMagnitude;
118 |
119 | //windloop
120 | if(!windAudioSource.isPlaying)
121 | {
122 | windAudioSource.Play();
123 | //Debug.Log("vessel dynamic pressure: " + vessel.dynamicPressurekPa);
124 | }
125 | float pressureFactor = Mathf.Clamp01((float)vessel.dynamicPressurekPa / 50f);
126 | float massFactor = Mathf.Clamp01(vessel.GetTotalMass() / 60f);
127 | float gFactor = Mathf.Clamp(sqrAccel / 225, 0, 1.5f);
128 | windAudioSource.volume = massFactor * pressureFactor * gFactor * lagAudioFactor;
129 |
130 |
131 | //windhowl
132 | if(!windHowlAudioSource.isPlaying)
133 | {
134 | windHowlAudioSource.Play();
135 | }
136 | float pressureFactor2 = Mathf.Clamp01((float)vessel.dynamicPressurekPa / 20f);
137 | float massFactor2 = Mathf.Clamp01(vessel.GetTotalMass() / 30f);
138 | windHowlAudioSource.volume = pressureFactor2 * massFactor2 * lagAudioFactor;
139 | windHowlAudioSource.maxDistance = Mathf.Clamp(lagAudioFactor * 2500, windTearAudioSource.minDistance, 16000);
140 |
141 | //windtear
142 | if(!windTearAudioSource.isPlaying)
143 | {
144 | windTearAudioSource.Play();
145 | }
146 | float pressureFactor3 = Mathf.Clamp01((float)vessel.dynamicPressurekPa / 40f);
147 | float massFactor3 = Mathf.Clamp01(vessel.GetTotalMass() / 10f);
148 | //float gFactor3 = Mathf.Clamp(sqrAccel / 325, 0.25f, 1f);
149 | windTearAudioSource.volume = pressureFactor3 * massFactor3;
150 |
151 | windTearAudioSource.minDistance = lagAudioFactor * 1;
152 | windTearAudioSource.maxDistance = Mathf.Clamp(lagAudioFactor * 2500, windTearAudioSource.minDistance, 16000);
153 |
154 | }
155 | else
156 | {
157 | if(windAudioSource.isPlaying)
158 | {
159 | windAudioSource.Stop();
160 | }
161 |
162 | if(windHowlAudioSource.isPlaying)
163 | {
164 | windHowlAudioSource.Stop();
165 | }
166 |
167 | if(windTearAudioSource.isPlaying)
168 | {
169 | windTearAudioSource.Stop();
170 | }
171 | }
172 | }
173 |
174 | void OnDestroy()
175 | {
176 | if(sonicBoomSource)
177 | {
178 | Destroy(sonicBoomSource.gameObject);
179 | }
180 | CamTools.OnResetCTools -= OnResetCTools;
181 | }
182 |
183 | void OnResetCTools()
184 | {
185 | Destroy(windAudioSource);
186 | Destroy(windHowlAudioSource);
187 | Destroy(windTearAudioSource);
188 |
189 | Destroy(this);
190 | }
191 | }
192 | }
193 |
194 |
--------------------------------------------------------------------------------
/CameraTools/CTPartAudioController.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | namespace CameraTools
3 | {
4 | public class CTPartAudioController : MonoBehaviour
5 | {
6 | Vessel vessel;
7 | Part part;
8 |
9 | public AudioSource audioSource;
10 |
11 |
12 | float origMinDist = 1;
13 | float origMaxDist = 1;
14 |
15 | float modMinDist = 10;
16 | float modMaxDist = 10000;
17 |
18 | AudioRolloffMode origRolloffMode;
19 |
20 | void Awake()
21 | {
22 | part = GetComponentInParent();
23 | vessel = part.vessel;
24 |
25 | CamTools.OnResetCTools += OnResetCTools;
26 | }
27 |
28 | void Start()
29 | {
30 | if(!audioSource)
31 | {
32 | Destroy(this);
33 | return;
34 | }
35 |
36 | origMinDist = audioSource.minDistance;
37 | origMaxDist = audioSource.maxDistance;
38 | origRolloffMode = audioSource.rolloffMode;
39 | audioSource.rolloffMode = AudioRolloffMode.Logarithmic;
40 | audioSource.spatialBlend = 1;
41 |
42 | }
43 |
44 | void FixedUpdate()
45 | {
46 | if(!audioSource)
47 | {
48 | Destroy(this);
49 | return;
50 | }
51 |
52 | if(!part || !vessel)
53 | {
54 | Destroy(this);
55 | return;
56 | }
57 |
58 |
59 | float angleToCam = Vector3.Angle(vessel.srf_velocity, FlightCamera.fetch.mainCamera.transform.position - vessel.transform.position);
60 | angleToCam = Mathf.Clamp(angleToCam, 1, 180);
61 |
62 | float srfSpeed = (float)vessel.srfSpeed;
63 | srfSpeed = Mathf.Min(srfSpeed, 550f);
64 |
65 | float lagAudioFactor = (75000 / (Vector3.Distance(vessel.transform.position, FlightCamera.fetch.mainCamera.transform.position) * srfSpeed * angleToCam / 90));
66 | lagAudioFactor = Mathf.Clamp(lagAudioFactor * lagAudioFactor * lagAudioFactor, 0, 4);
67 | lagAudioFactor += srfSpeed / 230;
68 |
69 | float waveFrontFactor = ((3.67f * angleToCam)/srfSpeed);
70 | waveFrontFactor = Mathf.Clamp(waveFrontFactor * waveFrontFactor * waveFrontFactor, 0, 2);
71 | if(vessel.srfSpeed > CamTools.speedOfSound)
72 | {
73 | waveFrontFactor = (srfSpeed / (angleToCam) < 3.67f) ? waveFrontFactor + ((srfSpeed/(float)CamTools.speedOfSound)*waveFrontFactor): 0;
74 | }
75 |
76 | lagAudioFactor *= waveFrontFactor;
77 |
78 | audioSource.minDistance = Mathf.Lerp(origMinDist, modMinDist * lagAudioFactor, Mathf.Clamp01((float)vessel.srfSpeed/30));
79 | audioSource.maxDistance = Mathf.Lerp(origMaxDist,Mathf.Clamp(modMaxDist * lagAudioFactor, audioSource.minDistance, 16000), Mathf.Clamp01((float)vessel.srfSpeed/30));
80 |
81 | }
82 |
83 | void OnDestroy()
84 | {
85 | CamTools.OnResetCTools -= OnResetCTools;
86 |
87 |
88 | }
89 |
90 | void OnResetCTools()
91 | {
92 | audioSource.minDistance = origMinDist;
93 | audioSource.maxDistance = origMaxDist;
94 | audioSource.rolloffMode = origRolloffMode;
95 | Destroy(this);
96 | }
97 |
98 |
99 | }
100 | }
101 |
102 |
--------------------------------------------------------------------------------
/CameraTools/CTPersistantFIeld.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace CameraTools
4 | {
5 | [AttributeUsage(AttributeTargets.Field)]
6 | public class CTPersistantField : Attribute
7 | {
8 | public static string settingsURL = "GameData/CameraTools/settings.cfg";
9 |
10 | public CTPersistantField()
11 | {
12 |
13 | }
14 |
15 | public static void Save()
16 | {
17 | ConfigNode fileNode = ConfigNode.Load(settingsURL);
18 | ConfigNode settings = fileNode.GetNode("CToolsSettings");
19 |
20 |
21 | foreach(var field in typeof(CamTools).GetFields())
22 | {
23 | if(!field.IsDefined(typeof(CTPersistantField), false)) continue;
24 |
25 | settings.SetValue(field.Name, field.GetValue(CamTools.fetch).ToString(), true);
26 | }
27 |
28 | fileNode.Save(settingsURL);
29 | }
30 |
31 | public static void Load()
32 | {
33 | ConfigNode fileNode = ConfigNode.Load(settingsURL);
34 | ConfigNode settings = fileNode.GetNode("CToolsSettings");
35 |
36 | foreach(var field in typeof(CamTools).GetFields())
37 | {
38 | if(!field.IsDefined(typeof(CTPersistantField), false)) continue;
39 |
40 | if(settings.HasValue(field.Name))
41 | {
42 | object parsedValue = ParseValue(field.FieldType, settings.GetValue(field.Name));
43 | if(parsedValue != null)
44 | {
45 | field.SetValue(CamTools.fetch, parsedValue);
46 | }
47 | }
48 | }
49 | }
50 |
51 | public static object ParseValue(Type type, string value)
52 | {
53 | if(type == typeof(string))
54 | {
55 | return value;
56 | }
57 |
58 | if(type == typeof(bool))
59 | {
60 | return bool.Parse(value);
61 | }
62 | else if(type.IsEnum)
63 | {
64 | return Enum.Parse(type, value);
65 | }
66 | else if(type == typeof(float))
67 | {
68 | return float.Parse(value);
69 | }
70 | else if(type == typeof(Single))
71 | {
72 | return Single.Parse(value);
73 | }
74 |
75 |
76 | UnityEngine.Debug.LogError("CameraTools failed to parse settings field of type "+type.ToString()+" and value "+value);
77 |
78 | return null;
79 | }
80 | }
81 | }
82 |
83 |
--------------------------------------------------------------------------------
/CameraTools/CamTools.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using UnityEngine;
5 | using System.Reflection;
6 | using KSP.UI.Screens;
7 | namespace CameraTools
8 | {
9 | [KSPAddon(KSPAddon.Startup.Flight, false)]
10 | public class CamTools : MonoBehaviour
11 | {
12 | public static CamTools fetch;
13 |
14 | GameObject cameraParent;
15 | Vessel vessel;
16 | Vector3 origPosition;
17 | Quaternion origRotation;
18 | Transform origParent;
19 | float origNearClip;
20 | FlightCamera flightCamera;
21 |
22 | Part camTarget = null;
23 |
24 | [CTPersistantField]
25 | public ReferenceModes referenceMode = ReferenceModes.Surface;
26 | Vector3 cameraUp = Vector3.up;
27 |
28 | string fmUpKey = "[7]";
29 | string fmDownKey = "[1]";
30 | string fmForwardKey = "[8]";
31 | string fmBackKey = "[5]";
32 | string fmLeftKey = "[4]";
33 | string fmRightKey = "[6]";
34 | string fmZoomInKey = "[9]";
35 | string fmZoomOutKey = "[3]";
36 | //
37 |
38 |
39 | //current camera setting
40 | bool cameraToolActive = false;
41 |
42 |
43 | //GUI
44 | public static bool guiEnabled = false;
45 | public static bool hasAddedButton = false;
46 | bool updateFOV = false;
47 | float windowWidth = 250;
48 | float windowHeight = 400;
49 | float draggableHeight = 40;
50 | float leftIndent = 12;
51 | float entryHeight = 20;
52 |
53 | [CTPersistantField]
54 | public ToolModes toolMode = ToolModes.StationaryCamera;
55 |
56 | Rect windowRect = new Rect(0,0,0,0);
57 | bool gameUIToggle = true;
58 | float incrButtonWidth = 26;
59 |
60 | //stationary camera vars
61 | [CTPersistantField]
62 | public bool autoFlybyPosition = false;
63 | [CTPersistantField]
64 | public bool autoFOV = false;
65 | float manualFOV = 60;
66 | float currentFOV = 60;
67 | Vector3 manualPosition = Vector3.zero;
68 | [CTPersistantField]
69 | public float freeMoveSpeed = 10;
70 | string guiFreeMoveSpeed = "10";
71 | [CTPersistantField]
72 | public float keyZoomSpeed = 1;
73 | string guiKeyZoomSpeed = "1";
74 | float zoomFactor = 1;
75 | [CTPersistantField]
76 | public float zoomExp = 1;
77 | [CTPersistantField]
78 | public bool enableKeypad = false;
79 | [CTPersistantField]
80 | public float maxRelV = 2500;
81 |
82 | bool setPresetOffset = false;
83 | Vector3 presetOffset = Vector3.zero;
84 | bool hasSavedRotation = false;
85 | Quaternion savedRotation;
86 | [CTPersistantField]
87 | public bool manualOffset = false;
88 | [CTPersistantField]
89 | public float manualOffsetForward = 500;
90 | [CTPersistantField]
91 | public float manualOffsetRight = 50;
92 | [CTPersistantField]
93 | public float manualOffsetUp = 5;
94 | string guiOffsetForward = "500";
95 | string guiOffsetRight = "50";
96 | string guiOffsetUp = "5";
97 |
98 | Vector3 lastVesselPosition = Vector3.zero;
99 | Vector3 lastTargetPosition = Vector3.zero;
100 | bool hasTarget = false;
101 |
102 | [CTPersistantField]
103 | public bool useOrbital = false;
104 |
105 | [CTPersistantField]
106 | public bool targetCoM = false;
107 |
108 | bool hasDied = false;
109 | float diedTime = 0;
110 | //vessel reference mode
111 | Vector3 initialVelocity = Vector3.zero;
112 | Vector3 initialPosition = Vector3.zero;
113 | Orbit initialOrbit = null;
114 | double initialUT;
115 |
116 | //retaining position and rotation after vessel destruction
117 | Vector3 lastPosition;
118 | Quaternion lastRotation;
119 |
120 |
121 | //click waiting stuff
122 | bool waitingForTarget = false;
123 | bool waitingForPosition = false;
124 |
125 | bool mouseUp = false;
126 |
127 | //Keys
128 | [CTPersistantField]
129 | public string cameraKey = "home";
130 | [CTPersistantField]
131 | public string revertKey = "end";
132 |
133 | //recording input for key binding
134 | bool isRecordingInput = false;
135 | bool isRecordingActivate = false;
136 | bool isRecordingRevert = false;
137 |
138 | Vector3 resetPositionFix;//fixes position movement after setting and resetting camera
139 |
140 | //floating origin shift handler
141 | Vector3d lastOffset = FloatingOrigin.fetch.offset;
142 |
143 | AudioSource[] audioSources;
144 | float[] originalAudioSourceDoppler;
145 | bool hasSetDoppler = false;
146 |
147 | [CTPersistantField]
148 | public bool useAudioEffects = true;
149 |
150 | //camera shake
151 | Vector3 shakeOffset = Vector3.zero;
152 | float shakeMagnitude = 0;
153 | [CTPersistantField]
154 | public float shakeMultiplier = 1;
155 |
156 | public delegate void ResetCTools();
157 | public static event ResetCTools OnResetCTools;
158 | public static double speedOfSound = 330;
159 |
160 | //dogfight cam
161 | Vessel dogfightPrevTarget;
162 | Vessel dogfightTarget;
163 | [CTPersistantField]
164 | float dogfightDistance = 30;
165 | [CTPersistantField]
166 | float dogfightOffsetX = 10;
167 | [CTPersistantField]
168 | float dogfightOffsetY = 4;
169 | float dogfightMaxOffset = 50;
170 | float dogfightLerp = 20;
171 | [CTPersistantField]
172 | float autoZoomMargin = 20;
173 | List loadedVessels;
174 | bool showingVesselList = false;
175 | bool dogfightLastTarget = false;
176 | Vector3 dogfightLastTargetPosition;
177 | Vector3 dogfightLastTargetVelocity;
178 | bool dogfightVelocityChase = false;
179 | //bdarmory
180 | bool hasBDAI = false;
181 | [CTPersistantField]
182 | public bool useBDAutoTarget = false;
183 | object aiComponent = null;
184 | FieldInfo bdAiTargetField;
185 |
186 |
187 | //pathing
188 | int selectedPathIndex = -1;
189 | List availablePaths;
190 | CameraPath currentPath
191 | {
192 | get
193 | {
194 | if(selectedPathIndex >= 0 && selectedPathIndex < availablePaths.Count)
195 | {
196 | return availablePaths[selectedPathIndex];
197 | }
198 | else
199 | {
200 | return null;
201 | }
202 | }
203 | }
204 | int currentKeyframeIndex = -1;
205 | float currentKeyframeTime;
206 | string currKeyTimeString;
207 | bool showKeyframeEditor = false;
208 | float pathStartTime;
209 | bool isPlayingPath = false;
210 | float pathTime
211 | {
212 | get
213 | {
214 | return Time.time - pathStartTime;
215 | }
216 | }
217 | Vector2 keysScrollPos;
218 |
219 | void Awake()
220 | {
221 | if(fetch)
222 | {
223 | Destroy(fetch);
224 | }
225 |
226 | fetch = this;
227 |
228 | Load();
229 |
230 | guiOffsetForward = manualOffsetForward.ToString();
231 | guiOffsetRight = manualOffsetRight.ToString();
232 | guiOffsetUp = manualOffsetUp.ToString();
233 | guiKeyZoomSpeed = keyZoomSpeed.ToString();
234 | guiFreeMoveSpeed = freeMoveSpeed.ToString();
235 | }
236 |
237 | void Start()
238 | {
239 | windowRect = new Rect(Screen.width-windowWidth-40, 0, windowWidth, windowHeight);
240 | flightCamera = FlightCamera.fetch;
241 | cameraToolActive = false;
242 | SaveOriginalCamera();
243 |
244 | AddToolbarButton();
245 |
246 | GameEvents.onHideUI.Add(GameUIDisable);
247 | GameEvents.onShowUI.Add(GameUIEnable);
248 | //GameEvents.onGamePause.Add (PostDeathRevert);
249 | GameEvents.OnVesselRecoveryRequested.Add(PostDeathRevert);
250 | GameEvents.onFloatingOriginShift.Add(OnFloatingOriginShift);
251 | GameEvents.onGameSceneLoadRequested.Add(PostDeathRevert);
252 |
253 | cameraParent = new GameObject("StationaryCameraParent");
254 | //cameraParent.SetActive(true);
255 | //cameraParent = (GameObject) Instantiate(cameraParent, Vector3.zero, Quaternion.identity);
256 |
257 | if(FlightGlobals.ActiveVessel != null)
258 | {
259 | cameraParent.transform.position = FlightGlobals.ActiveVessel.transform.position;
260 | vessel = FlightGlobals.ActiveVessel;
261 |
262 | CheckForBDAI(FlightGlobals.ActiveVessel);
263 | }
264 | bdAiTargetField = GetAITargetField();
265 | GameEvents.onVesselChange.Add(SwitchToVessel);
266 | }
267 |
268 | void OnDestroy()
269 | {
270 | GameEvents.onVesselChange.Remove(SwitchToVessel);
271 | }
272 |
273 | void Update()
274 | {
275 | if(!isRecordingInput)
276 | {
277 | if(Input.GetKeyDown(KeyCode.KeypadDivide))
278 | {
279 | guiEnabled = !guiEnabled;
280 | }
281 |
282 | if(Input.GetKeyDown(revertKey))
283 | {
284 | RevertCamera();
285 | }
286 | else if(Input.GetKeyDown(cameraKey))
287 | {
288 | if(toolMode == ToolModes.StationaryCamera)
289 | {
290 | if(!cameraToolActive)
291 | {
292 | SaveOriginalCamera();
293 | StartStationaryCamera();
294 | }
295 | else
296 | {
297 | //RevertCamera();
298 | StartStationaryCamera();
299 | }
300 | }
301 | else if(toolMode == ToolModes.DogfightCamera)
302 | {
303 | if(!cameraToolActive)
304 | {
305 | SaveOriginalCamera();
306 | StartDogfightCamera();
307 | }
308 | else
309 | {
310 | StartDogfightCamera();
311 | }
312 | }
313 | else if(toolMode == ToolModes.Pathing)
314 | {
315 | if(!cameraToolActive)
316 | {
317 | SaveOriginalCamera();
318 | }
319 | StartPathingCam();
320 | PlayPathingCam();
321 | }
322 | }
323 |
324 |
325 | }
326 |
327 | if(Input.GetMouseButtonUp(0))
328 | {
329 | mouseUp = true;
330 | }
331 |
332 |
333 | //get target transform from mouseClick
334 | if(waitingForTarget && mouseUp && Input.GetKeyDown(KeyCode.Mouse0))
335 | {
336 | Part tgt = GetPartFromMouse();
337 | if(tgt!=null)
338 | {
339 | camTarget = tgt;
340 | hasTarget = true;
341 | }
342 | else
343 | {
344 | Vector3 pos = GetPosFromMouse();
345 | if(pos != Vector3.zero)
346 | {
347 | lastTargetPosition = pos;
348 | hasTarget = true;
349 | }
350 | }
351 |
352 | waitingForTarget = false;
353 | }
354 |
355 | //set position from mouseClick
356 | if(waitingForPosition && mouseUp && Input.GetKeyDown(KeyCode.Mouse0))
357 | {
358 | Vector3 pos = GetPosFromMouse();
359 | if(pos!=Vector3.zero)// && isStationaryCamera)
360 | {
361 | presetOffset = pos;
362 | setPresetOffset = true;
363 | }
364 | else Debug.Log ("No pos from mouse click");
365 |
366 | waitingForPosition = false;
367 | }
368 |
369 |
370 |
371 | }
372 |
373 | public void ShakeCamera(float magnitude)
374 | {
375 | shakeMagnitude = Mathf.Max(shakeMagnitude, magnitude);
376 | }
377 |
378 |
379 | int posCounter = 0;//debug
380 | void FixedUpdate()
381 | {
382 | if(!FlightGlobals.ready)
383 | {
384 | return;
385 | }
386 |
387 | if(FlightGlobals.ActiveVessel != null && (vessel==null || vessel!=FlightGlobals.ActiveVessel))
388 | {
389 | vessel = FlightGlobals.ActiveVessel;
390 | }
391 |
392 | if(vessel != null)
393 | {
394 | lastVesselPosition = vessel.transform.position;
395 | }
396 |
397 |
398 | //stationary camera
399 | if(cameraToolActive)
400 | {
401 | if(toolMode == ToolModes.StationaryCamera)
402 | {
403 | UpdateStationaryCamera();
404 | }
405 | else if(toolMode == ToolModes.DogfightCamera)
406 | {
407 | UpdateDogfightCamera();
408 | }
409 | else if(toolMode == ToolModes.Pathing)
410 | {
411 | UpdatePathingCam();
412 | }
413 | }
414 | else
415 | {
416 | if(!autoFOV)
417 | {
418 | zoomFactor = Mathf.Exp(zoomExp)/Mathf.Exp(1);
419 | }
420 | }
421 |
422 | if(toolMode == ToolModes.DogfightCamera)
423 | {
424 | if(dogfightTarget && dogfightTarget.isActiveVessel)
425 | {
426 | dogfightTarget = null;
427 | if(cameraToolActive)
428 | {
429 | RevertCamera();
430 | }
431 | }
432 | }
433 |
434 |
435 | if(hasDied && Time.time-diedTime > 2)
436 | {
437 | RevertCamera();
438 | }
439 | }
440 |
441 | void StartDogfightCamera()
442 | {
443 | if(FlightGlobals.ActiveVessel == null)
444 | {
445 | Debug.Log("No active vessel.");
446 | return;
447 | }
448 |
449 |
450 |
451 | if(!dogfightTarget)
452 | {
453 | dogfightVelocityChase = true;
454 | }
455 | else
456 | {
457 | dogfightVelocityChase = false;
458 | }
459 |
460 | dogfightPrevTarget = dogfightTarget;
461 |
462 | hasDied = false;
463 | vessel = FlightGlobals.ActiveVessel;
464 | cameraUp = -FlightGlobals.getGeeForceAtPosition(vessel.CoM).normalized;
465 |
466 | flightCamera.SetTargetNone();
467 | flightCamera.transform.parent = cameraParent.transform;
468 | flightCamera.DeactivateUpdate();
469 | cameraParent.transform.position = vessel.transform.position+vessel.rb_velocity*Time.fixedDeltaTime;
470 |
471 | cameraToolActive = true;
472 |
473 | ResetDoppler();
474 | if(OnResetCTools != null)
475 | {
476 | OnResetCTools();
477 | }
478 |
479 | SetDoppler(false);
480 | AddAtmoAudioControllers(false);
481 | }
482 |
483 | void UpdateDogfightCamera()
484 | {
485 | if(!vessel || (!dogfightTarget && !dogfightLastTarget && !dogfightVelocityChase))
486 | {
487 | RevertCamera();
488 | return;
489 | }
490 |
491 |
492 | if(dogfightTarget)
493 | {
494 | dogfightLastTarget = true;
495 | dogfightLastTargetPosition = dogfightTarget.CoM;
496 | dogfightLastTargetVelocity = dogfightTarget.rb_velocity;
497 | }
498 | else if(dogfightLastTarget)
499 | {
500 | dogfightLastTargetPosition += dogfightLastTargetVelocity * Time.fixedDeltaTime;
501 | }
502 |
503 | cameraParent.transform.position = (vessel.CoM - (vessel.rb_velocity * Time.fixedDeltaTime));
504 |
505 | if(dogfightVelocityChase)
506 | {
507 | if(vessel.srfSpeed > 1)
508 | {
509 | dogfightLastTargetPosition = vessel.CoM + (vessel.srf_velocity.normalized * 5000);
510 | }
511 | else
512 | {
513 | dogfightLastTargetPosition = vessel.CoM + (vessel.ReferenceTransform.up * 5000);
514 | }
515 | }
516 |
517 | Vector3 offsetDirection = Vector3.Cross(cameraUp, dogfightLastTargetPosition - vessel.CoM).normalized;
518 | Vector3 camPos = vessel.CoM + ((vessel.CoM - dogfightLastTargetPosition).normalized * dogfightDistance) + (dogfightOffsetX * offsetDirection) + (dogfightOffsetY * cameraUp);
519 |
520 | Vector3 localCamPos = cameraParent.transform.InverseTransformPoint(camPos);
521 | flightCamera.transform.localPosition = Vector3.Lerp(flightCamera.transform.localPosition, localCamPos, dogfightLerp * Time.fixedDeltaTime);
522 |
523 | //rotation
524 | Quaternion vesselLook = Quaternion.LookRotation(vessel.CoM-flightCamera.transform.position, cameraUp);
525 | Quaternion targetLook = Quaternion.LookRotation(dogfightLastTargetPosition-flightCamera.transform.position, cameraUp);
526 | Quaternion camRot = Quaternion.Lerp(vesselLook, targetLook, 0.5f);
527 | flightCamera.transform.rotation = Quaternion.Lerp(flightCamera.transform.rotation, camRot, dogfightLerp * Time.fixedDeltaTime);
528 |
529 | //autoFov
530 | if(autoFOV)
531 | {
532 | float targetFoV;
533 | if(dogfightVelocityChase)
534 | {
535 | targetFoV = Mathf.Clamp((7000 / (dogfightDistance + 100)) - 14 + autoZoomMargin, 2, 60);
536 | }
537 | else
538 | {
539 | float angle = Vector3.Angle((dogfightLastTargetPosition + (dogfightLastTargetVelocity * Time.fixedDeltaTime)) - flightCamera.transform.position, (vessel.CoM + (vessel.rb_velocity * Time.fixedDeltaTime)) - flightCamera.transform.position);
540 | targetFoV = Mathf.Clamp(angle + autoZoomMargin, 0.1f, 60f);
541 | }
542 | manualFOV = targetFoV;
543 | }
544 | //FOV
545 | if(!autoFOV)
546 | {
547 | zoomFactor = Mathf.Exp(zoomExp) / Mathf.Exp(1);
548 | manualFOV = 60 / zoomFactor;
549 | updateFOV = (currentFOV != manualFOV);
550 | if(updateFOV)
551 | {
552 | currentFOV = Mathf.Lerp(currentFOV, manualFOV, 0.1f);
553 | flightCamera.SetFoV(currentFOV);
554 | updateFOV = false;
555 | }
556 | }
557 | else
558 | {
559 | currentFOV = Mathf.Lerp(currentFOV, manualFOV, 0.1f);
560 | flightCamera.SetFoV(currentFOV);
561 | zoomFactor = 60 / currentFOV;
562 | }
563 |
564 | //free move
565 | if(enableKeypad)
566 | {
567 | if(Input.GetKey(fmUpKey))
568 | {
569 | dogfightOffsetY += freeMoveSpeed * Time.fixedDeltaTime;
570 | dogfightOffsetY = Mathf.Clamp(dogfightOffsetY, -dogfightMaxOffset, dogfightMaxOffset);
571 | }
572 | else if(Input.GetKey(fmDownKey))
573 | {
574 | dogfightOffsetY -= freeMoveSpeed * Time.fixedDeltaTime;
575 | dogfightOffsetY = Mathf.Clamp(dogfightOffsetY, -dogfightMaxOffset, dogfightMaxOffset);
576 | }
577 | if(Input.GetKey(fmForwardKey))
578 | {
579 | dogfightDistance -= freeMoveSpeed * Time.fixedDeltaTime;
580 | dogfightDistance = Mathf.Clamp(dogfightDistance, 1f, 100f);
581 | }
582 | else if(Input.GetKey(fmBackKey))
583 | {
584 | dogfightDistance += freeMoveSpeed * Time.fixedDeltaTime;
585 | dogfightDistance = Mathf.Clamp(dogfightDistance, 1f, 100f);
586 | }
587 | if(Input.GetKey(fmLeftKey))
588 | {
589 | dogfightOffsetX -= freeMoveSpeed * Time.fixedDeltaTime;
590 | dogfightOffsetX = Mathf.Clamp(dogfightOffsetX, -dogfightMaxOffset, dogfightMaxOffset);
591 | }
592 | else if(Input.GetKey(fmRightKey))
593 | {
594 | dogfightOffsetX += freeMoveSpeed * Time.fixedDeltaTime;
595 | dogfightOffsetX = Mathf.Clamp(dogfightOffsetX, -dogfightMaxOffset, dogfightMaxOffset);
596 | }
597 |
598 | //keyZoom
599 | if(!autoFOV)
600 | {
601 | if(Input.GetKey(fmZoomInKey))
602 | {
603 | zoomExp = Mathf.Clamp(zoomExp + (keyZoomSpeed * Time.fixedDeltaTime), 1, 8);
604 | }
605 | else if(Input.GetKey(fmZoomOutKey))
606 | {
607 | zoomExp = Mathf.Clamp(zoomExp - (keyZoomSpeed * Time.fixedDeltaTime), 1, 8);
608 | }
609 | }
610 | else
611 | {
612 | if(Input.GetKey(fmZoomInKey))
613 | {
614 | autoZoomMargin = Mathf.Clamp(autoZoomMargin + (keyZoomSpeed * 10 * Time.fixedDeltaTime), 0, 50);
615 | }
616 | else if(Input.GetKey(fmZoomOutKey))
617 | {
618 | autoZoomMargin = Mathf.Clamp(autoZoomMargin - (keyZoomSpeed * 10 * Time.fixedDeltaTime), 0, 50);
619 | }
620 | }
621 | }
622 |
623 | //vessel camera shake
624 | if(shakeMultiplier > 0)
625 | {
626 | foreach(var v in FlightGlobals.Vessels)
627 | {
628 | if(!v || !v.loaded || v.packed || v.isActiveVessel) continue;
629 | VesselCameraShake(v);
630 | }
631 | }
632 | UpdateCameraShake();
633 |
634 | if(hasBDAI && useBDAutoTarget)
635 | {
636 | Vessel newAITarget = GetAITargetedVessel();
637 | if(newAITarget)
638 | {
639 | dogfightTarget = newAITarget;
640 | }
641 | }
642 |
643 | if(dogfightTarget != dogfightPrevTarget)
644 | {
645 | //RevertCamera();
646 | StartDogfightCamera();
647 | }
648 | }
649 |
650 | void UpdateStationaryCamera()
651 | {
652 | if(useAudioEffects)
653 | {
654 | speedOfSound = 233 * Math.Sqrt(1 + (FlightGlobals.getExternalTemperature(vessel.GetWorldPos3D(), vessel.mainBody) / 273.15));
655 | //Debug.Log("speed of sound: " + speedOfSound);
656 | }
657 |
658 | if(posCounter < 3)
659 | {
660 | posCounter++;
661 | Debug.Log("flightCamera position: " + flightCamera.transform.position);
662 | flightCamera.transform.position = resetPositionFix;
663 | if(hasSavedRotation)
664 | {
665 | flightCamera.transform.rotation = savedRotation;
666 | }
667 | }
668 | if(flightCamera.Target != null) flightCamera.SetTargetNone(); //dont go to next vessel if vessel is destroyed
669 |
670 | if (camTarget != null)
671 | {
672 | Vector3 lookPosition = camTarget.transform.position;
673 | if(targetCoM)
674 | {
675 | lookPosition = camTarget.vessel.CoM;
676 | }
677 |
678 | lookPosition += 2*camTarget.vessel.rb_velocity * Time.fixedDeltaTime;
679 | if(targetCoM)
680 | {
681 | lookPosition += camTarget.vessel.rb_velocity * Time.fixedDeltaTime;
682 | }
683 |
684 | flightCamera.transform.rotation = Quaternion.LookRotation(lookPosition - flightCamera.transform.position, cameraUp);
685 | lastTargetPosition = lookPosition;
686 | }
687 | else if(hasTarget)
688 | {
689 | flightCamera.transform.rotation = Quaternion.LookRotation(lastTargetPosition - flightCamera.transform.position, cameraUp);
690 | }
691 |
692 |
693 |
694 | if(vessel != null)
695 | {
696 | cameraParent.transform.position = manualPosition + (vessel.CoM - vessel.rb_velocity * Time.fixedDeltaTime);
697 |
698 | if(referenceMode == ReferenceModes.Surface)
699 | {
700 | flightCamera.transform.position -= Time.fixedDeltaTime * Mathf.Clamp((float)vessel.srf_velocity.magnitude, 0, maxRelV) * vessel.srf_velocity.normalized;
701 | }
702 | else if(referenceMode == ReferenceModes.Orbit)
703 | {
704 | flightCamera.transform.position -= Time.fixedDeltaTime * Mathf.Clamp((float)vessel.obt_velocity.magnitude, 0, maxRelV) * vessel.obt_velocity.normalized;
705 | }
706 | else if(referenceMode == ReferenceModes.InitialVelocity)
707 | {
708 | Vector3 camVelocity = Vector3.zero;
709 | if(useOrbital && initialOrbit != null)
710 | {
711 | camVelocity = (initialOrbit.getOrbitalVelocityAtUT(Planetarium.GetUniversalTime()).xzy - vessel.GetObtVelocity());
712 | }
713 | else
714 | {
715 | camVelocity = (initialVelocity - vessel.srf_velocity);
716 | }
717 | flightCamera.transform.position += camVelocity * Time.fixedDeltaTime;
718 | }
719 | }
720 |
721 |
722 | //mouse panning, moving
723 | Vector3 forwardLevelAxis = (Quaternion.AngleAxis(-90, cameraUp) * flightCamera.transform.right).normalized;
724 | Vector3 rightAxis = (Quaternion.AngleAxis(90, forwardLevelAxis) * cameraUp).normalized;
725 |
726 | //free move
727 | if(enableKeypad)
728 | {
729 | if(Input.GetKey(fmUpKey))
730 | {
731 | manualPosition += cameraUp * freeMoveSpeed * Time.fixedDeltaTime;
732 | }
733 | else if(Input.GetKey(fmDownKey))
734 | {
735 | manualPosition -= cameraUp * freeMoveSpeed * Time.fixedDeltaTime;
736 | }
737 | if(Input.GetKey(fmForwardKey))
738 | {
739 | manualPosition += forwardLevelAxis * freeMoveSpeed * Time.fixedDeltaTime;
740 | }
741 | else if(Input.GetKey(fmBackKey))
742 | {
743 | manualPosition -= forwardLevelAxis * freeMoveSpeed * Time.fixedDeltaTime;
744 | }
745 | if(Input.GetKey(fmLeftKey))
746 | {
747 | manualPosition -= flightCamera.transform.right * freeMoveSpeed * Time.fixedDeltaTime;
748 | }
749 | else if(Input.GetKey(fmRightKey))
750 | {
751 | manualPosition += flightCamera.transform.right * freeMoveSpeed * Time.fixedDeltaTime;
752 | }
753 |
754 | //keyZoom
755 | if(!autoFOV)
756 | {
757 | if(Input.GetKey(fmZoomInKey))
758 | {
759 | zoomExp = Mathf.Clamp(zoomExp + (keyZoomSpeed * Time.fixedDeltaTime), 1, 8);
760 | }
761 | else if(Input.GetKey(fmZoomOutKey))
762 | {
763 | zoomExp = Mathf.Clamp(zoomExp - (keyZoomSpeed * Time.fixedDeltaTime), 1, 8);
764 | }
765 | }
766 | else
767 | {
768 | if(Input.GetKey(fmZoomInKey))
769 | {
770 | autoZoomMargin = Mathf.Clamp(autoZoomMargin + (keyZoomSpeed * 10 * Time.fixedDeltaTime), 0, 50);
771 | }
772 | else if(Input.GetKey(fmZoomOutKey))
773 | {
774 | autoZoomMargin = Mathf.Clamp(autoZoomMargin - (keyZoomSpeed * 10 * Time.fixedDeltaTime), 0, 50);
775 | }
776 | }
777 | }
778 |
779 |
780 | if(camTarget == null && Input.GetKey(KeyCode.Mouse1))
781 | {
782 | flightCamera.transform.rotation *= Quaternion.AngleAxis(Input.GetAxis("Mouse X") * 1.7f, Vector3.up); //*(Mathf.Abs(Mouse.delta.x)/7)
783 | flightCamera.transform.rotation *= Quaternion.AngleAxis(-Input.GetAxis("Mouse Y") * 1.7f, Vector3.right);
784 | flightCamera.transform.rotation = Quaternion.LookRotation(flightCamera.transform.forward, cameraUp);
785 | }
786 | if(Input.GetKey(KeyCode.Mouse2))
787 | {
788 | manualPosition += flightCamera.transform.right * Input.GetAxis("Mouse X") * 2;
789 | manualPosition += forwardLevelAxis * Input.GetAxis("Mouse Y") * 2;
790 | }
791 | manualPosition += cameraUp * 10 * Input.GetAxis("Mouse ScrollWheel");
792 |
793 | //autoFov
794 | if(camTarget != null && autoFOV)
795 | {
796 | float cameraDistance = Vector3.Distance(camTarget.transform.position, flightCamera.transform.position);
797 | float targetFoV = Mathf.Clamp((7000 / (cameraDistance + 100)) - 14 + autoZoomMargin, 2, 60);
798 | //flightCamera.SetFoV(targetFoV);
799 | manualFOV = targetFoV;
800 | }
801 | //FOV
802 | if(!autoFOV)
803 | {
804 | zoomFactor = Mathf.Exp(zoomExp) / Mathf.Exp(1);
805 | manualFOV = 60 / zoomFactor;
806 | updateFOV = (currentFOV != manualFOV);
807 | if(updateFOV)
808 | {
809 | currentFOV = Mathf.Lerp(currentFOV, manualFOV, 0.1f);
810 | flightCamera.SetFoV(currentFOV);
811 | updateFOV = false;
812 | }
813 | }
814 | else
815 | {
816 | currentFOV = Mathf.Lerp(currentFOV, manualFOV, 0.1f);
817 | flightCamera.SetFoV(currentFOV);
818 | zoomFactor = 60 / currentFOV;
819 | }
820 | lastPosition = flightCamera.transform.position;
821 | lastRotation = flightCamera.transform.rotation;
822 |
823 |
824 |
825 | //vessel camera shake
826 | if(shakeMultiplier > 0)
827 | {
828 | foreach(var v in FlightGlobals.Vessels)
829 | {
830 | if(!v || !v.loaded || v.packed) continue;
831 | VesselCameraShake(v);
832 | }
833 | }
834 | UpdateCameraShake();
835 | }
836 |
837 |
838 | void LateUpdate()
839 | {
840 |
841 | //retain pos and rot after vessel destruction
842 | if (cameraToolActive && flightCamera.transform.parent != cameraParent.transform)
843 | {
844 | flightCamera.SetTargetNone();
845 | flightCamera.transform.parent = null;
846 | flightCamera.transform.position = lastPosition;
847 | flightCamera.transform.rotation = lastRotation;
848 | hasDied = true;
849 | diedTime = Time.time;
850 | }
851 |
852 | }
853 |
854 | void UpdateCameraShake()
855 | {
856 | if(shakeMultiplier > 0)
857 | {
858 | if(shakeMagnitude > 0.1f)
859 | {
860 | Vector3 shakeAxis = UnityEngine.Random.onUnitSphere;
861 | shakeOffset = Mathf.Sin(shakeMagnitude * 20 * Time.time) * (shakeMagnitude / 10) * shakeAxis;
862 | }
863 |
864 |
865 | flightCamera.transform.rotation = Quaternion.AngleAxis((shakeMultiplier/2) * shakeMagnitude / 50f, Vector3.ProjectOnPlane(UnityEngine.Random.onUnitSphere, flightCamera.transform.forward)) * flightCamera.transform.rotation;
866 | }
867 |
868 | shakeMagnitude = Mathf.Lerp(shakeMagnitude, 0, 5*Time.fixedDeltaTime);
869 | }
870 |
871 | public void VesselCameraShake(Vessel vessel)
872 | {
873 | //shake
874 | float camDistance = Vector3.Distance(flightCamera.transform.position, vessel.CoM);
875 |
876 | float distanceFactor = 50f / camDistance;
877 | float fovFactor = 2f / zoomFactor;
878 | float thrustFactor = GetTotalThrust() / 1000f;
879 |
880 | float atmosphericFactor = (float)vessel.dynamicPressurekPa / 2f;
881 |
882 | float angleToCam = Vector3.Angle(vessel.srf_velocity, FlightCamera.fetch.mainCamera.transform.position - vessel.transform.position);
883 | angleToCam = Mathf.Clamp(angleToCam, 1, 180);
884 |
885 | float srfSpeed = (float)vessel.srfSpeed;
886 |
887 | float lagAudioFactor = (75000 / (Vector3.Distance(vessel.transform.position, FlightCamera.fetch.mainCamera.transform.position) * srfSpeed * angleToCam / 90));
888 | lagAudioFactor = Mathf.Clamp(lagAudioFactor * lagAudioFactor * lagAudioFactor, 0, 4);
889 | lagAudioFactor += srfSpeed / 230;
890 |
891 | float waveFrontFactor = ((3.67f * angleToCam) / srfSpeed);
892 | waveFrontFactor = Mathf.Clamp(waveFrontFactor * waveFrontFactor * waveFrontFactor, 0, 2);
893 | if(vessel.srfSpeed > 330)
894 | {
895 | waveFrontFactor = (srfSpeed / (angleToCam) < 3.67f) ? srfSpeed / 15 : 0;
896 | }
897 |
898 | lagAudioFactor *= waveFrontFactor;
899 |
900 | lagAudioFactor = Mathf.Clamp01(lagAudioFactor) * distanceFactor * fovFactor;
901 |
902 | atmosphericFactor *= lagAudioFactor;
903 |
904 | thrustFactor *= distanceFactor * fovFactor * lagAudioFactor;
905 |
906 | ShakeCamera(atmosphericFactor + thrustFactor);
907 | }
908 |
909 | float GetTotalThrust()
910 | {
911 | float total = 0;
912 | foreach(var engine in vessel.FindPartModulesImplementing())
913 | {
914 | total += engine.finalThrust;
915 | }
916 | return total;
917 | }
918 |
919 | void AddAtmoAudioControllers(bool includeActiveVessel)
920 | {
921 | if(!useAudioEffects)
922 | {
923 | return;
924 | }
925 |
926 | foreach(var vessel in FlightGlobals.Vessels)
927 | {
928 | if(!vessel || !vessel.loaded || vessel.packed || (!includeActiveVessel && vessel.isActiveVessel))
929 | {
930 | continue;
931 | }
932 |
933 | vessel.gameObject.AddComponent();
934 | }
935 | }
936 |
937 | void SetDoppler(bool includeActiveVessel)
938 | {
939 | if(hasSetDoppler)
940 | {
941 | return;
942 | }
943 |
944 | if(!useAudioEffects)
945 | {
946 | return;
947 | }
948 |
949 | audioSources = FindObjectsOfType();
950 | originalAudioSourceDoppler = new float[audioSources.Length];
951 |
952 | for(int i = 0; i < audioSources.Length; i++)
953 | {
954 | originalAudioSourceDoppler[i] = audioSources[i].dopplerLevel;
955 |
956 | if(!includeActiveVessel)
957 | {
958 | Part p = audioSources[i].GetComponentInParent();
959 | if(p && p.vessel.isActiveVessel) continue;
960 | }
961 |
962 | audioSources[i].dopplerLevel = 1;
963 | audioSources[i].velocityUpdateMode = AudioVelocityUpdateMode.Fixed;
964 | audioSources[i].bypassEffects = false;
965 | audioSources[i].spatialBlend = 1;
966 |
967 | if(audioSources[i].gameObject.GetComponentInParent())
968 | {
969 | //Debug.Log("Added CTPartAudioController to :" + audioSources[i].name);
970 | CTPartAudioController pa = audioSources[i].gameObject.AddComponent();
971 | pa.audioSource = audioSources[i];
972 | }
973 | }
974 |
975 | hasSetDoppler = true;
976 | }
977 |
978 | void ResetDoppler()
979 | {
980 | if(!hasSetDoppler)
981 | {
982 | return;
983 | }
984 |
985 | for(int i = 0; i < audioSources.Length; i++)
986 | {
987 | if(audioSources[i] != null)
988 | {
989 | audioSources[i].dopplerLevel = originalAudioSourceDoppler[i];
990 | audioSources[i].velocityUpdateMode = AudioVelocityUpdateMode.Auto;
991 | }
992 | }
993 |
994 |
995 |
996 | hasSetDoppler = false;
997 | }
998 |
999 |
1000 | void StartStationaryCamera()
1001 | {
1002 | Debug.Log ("flightCamera position init: "+flightCamera.transform.position);
1003 | if(FlightGlobals.ActiveVessel != null)
1004 | {
1005 | hasDied = false;
1006 | vessel = FlightGlobals.ActiveVessel;
1007 | cameraUp = -FlightGlobals.getGeeForceAtPosition(vessel.GetWorldPos3D()).normalized;
1008 | if(FlightCamera.fetch.mode == FlightCamera.Modes.ORBITAL || (FlightCamera.fetch.mode == FlightCamera.Modes.AUTO && FlightCamera.GetAutoModeForVessel(vessel) == FlightCamera.Modes.ORBITAL))
1009 | {
1010 | cameraUp = Vector3.up;
1011 | }
1012 |
1013 | flightCamera.SetTargetNone();
1014 | flightCamera.transform.parent = cameraParent.transform;
1015 | flightCamera.DeactivateUpdate();
1016 | cameraParent.transform.position = vessel.transform.position+vessel.rb_velocity*Time.fixedDeltaTime;
1017 | manualPosition = Vector3.zero;
1018 |
1019 |
1020 | hasTarget = (camTarget != null) ? true : false;
1021 |
1022 |
1023 | Vector3 rightAxis = -Vector3.Cross(vessel.srf_velocity, vessel.upAxis).normalized;
1024 | //Vector3 upAxis = flightCamera.transform.up;
1025 |
1026 |
1027 | if(autoFlybyPosition)
1028 | {
1029 | setPresetOffset = false;
1030 | Vector3 velocity = vessel.srf_velocity;
1031 | if(referenceMode == ReferenceModes.Orbit) velocity = vessel.obt_velocity;
1032 |
1033 | Vector3 clampedVelocity = Mathf.Clamp((float) vessel.srfSpeed, 0, maxRelV) * velocity.normalized;
1034 | float clampedSpeed = clampedVelocity.magnitude;
1035 | float sideDistance = Mathf.Clamp(20 + (clampedSpeed/10), 20, 150);
1036 | float distanceAhead = Mathf.Clamp(4 * clampedSpeed, 30, 3500);
1037 |
1038 | flightCamera.transform.rotation = Quaternion.LookRotation(vessel.transform.position - flightCamera.transform.position, cameraUp);
1039 |
1040 |
1041 | if(referenceMode == ReferenceModes.Surface && vessel.srfSpeed > 0)
1042 | {
1043 | flightCamera.transform.position = vessel.transform.position + (distanceAhead * vessel.srf_velocity.normalized);
1044 | }
1045 | else if(referenceMode == ReferenceModes.Orbit && vessel.obt_speed > 0)
1046 | {
1047 | flightCamera.transform.position = vessel.transform.position + (distanceAhead * vessel.obt_velocity.normalized);
1048 | }
1049 | else
1050 | {
1051 | flightCamera.transform.position = vessel.transform.position + (distanceAhead * vessel.vesselTransform.up);
1052 | }
1053 |
1054 |
1055 | if(flightCamera.mode == FlightCamera.Modes.FREE || FlightCamera.GetAutoModeForVessel(vessel) == FlightCamera.Modes.FREE)
1056 | {
1057 | flightCamera.transform.position += (sideDistance * rightAxis) + (15 * cameraUp);
1058 | }
1059 | else if(flightCamera.mode == FlightCamera.Modes.ORBITAL || FlightCamera.GetAutoModeForVessel(vessel) == FlightCamera.Modes.ORBITAL)
1060 | {
1061 | flightCamera.transform.position += (sideDistance * FlightGlobals.getUpAxis()) + (15 * Vector3.up);
1062 | }
1063 |
1064 |
1065 | }
1066 | else if(manualOffset)
1067 | {
1068 | setPresetOffset = false;
1069 | float sideDistance = manualOffsetRight;
1070 | float distanceAhead = manualOffsetForward;
1071 |
1072 |
1073 | flightCamera.transform.rotation = Quaternion.LookRotation(vessel.transform.position - flightCamera.transform.position, cameraUp);
1074 |
1075 | if(referenceMode == ReferenceModes.Surface && vessel.srfSpeed > 4)
1076 | {
1077 | flightCamera.transform.position = vessel.transform.position + (distanceAhead * vessel.srf_velocity.normalized);
1078 | }
1079 | else if(referenceMode == ReferenceModes.Orbit && vessel.obt_speed > 4)
1080 | {
1081 | flightCamera.transform.position = vessel.transform.position + (distanceAhead * vessel.obt_velocity.normalized);
1082 | }
1083 | else
1084 | {
1085 | flightCamera.transform.position = vessel.transform.position + (distanceAhead * vessel.vesselTransform.up);
1086 | }
1087 |
1088 | if(flightCamera.mode == FlightCamera.Modes.FREE || FlightCamera.GetAutoModeForVessel(vessel) == FlightCamera.Modes.FREE)
1089 | {
1090 | flightCamera.transform.position += (sideDistance * rightAxis) + (manualOffsetUp * cameraUp);
1091 | }
1092 | else if(flightCamera.mode == FlightCamera.Modes.ORBITAL || FlightCamera.GetAutoModeForVessel(vessel) == FlightCamera.Modes.ORBITAL)
1093 | {
1094 | flightCamera.transform.position += (sideDistance * FlightGlobals.getUpAxis()) + (manualOffsetUp * Vector3.up);
1095 | }
1096 | }
1097 | else if(setPresetOffset)
1098 | {
1099 | flightCamera.transform.position = presetOffset;
1100 | //setPresetOffset = false;
1101 | }
1102 |
1103 | initialVelocity = vessel.srf_velocity;
1104 | initialOrbit = new Orbit();
1105 | initialOrbit.UpdateFromStateVectors(vessel.orbit.pos, vessel.orbit.vel, FlightGlobals.currentMainBody, Planetarium.GetUniversalTime());
1106 | initialUT = Planetarium.GetUniversalTime();
1107 |
1108 | cameraToolActive = true;
1109 |
1110 | SetDoppler(true);
1111 | AddAtmoAudioControllers(true);
1112 | }
1113 | else
1114 | {
1115 | Debug.Log ("CameraTools: Stationary Camera failed. Active Vessel is null.");
1116 | }
1117 | resetPositionFix = flightCamera.transform.position;
1118 | Debug.Log ("flightCamera position post init: "+flightCamera.transform.position);
1119 | }
1120 |
1121 | void RevertCamera()
1122 | {
1123 | posCounter = 0;
1124 |
1125 | if(cameraToolActive)
1126 | {
1127 | presetOffset = flightCamera.transform.position;
1128 | if(camTarget==null)
1129 | {
1130 | savedRotation = flightCamera.transform.rotation;
1131 | hasSavedRotation = true;
1132 | }
1133 | else
1134 | {
1135 | hasSavedRotation = false;
1136 | }
1137 | }
1138 | hasDied = false;
1139 | if (FlightGlobals.ActiveVessel != null && HighLogic.LoadedScene == GameScenes.FLIGHT)
1140 | {
1141 | flightCamera.SetTarget(FlightGlobals.ActiveVessel.transform, FlightCamera.TargetMode.Vessel);
1142 | }
1143 | flightCamera.transform.parent = origParent;
1144 | flightCamera.transform.position = origPosition;
1145 | flightCamera.transform.rotation = origRotation;
1146 | Camera.main.nearClipPlane = origNearClip;
1147 |
1148 | flightCamera.SetFoV(60);
1149 | flightCamera.ActivateUpdate();
1150 | currentFOV = 60;
1151 |
1152 | cameraToolActive = false;
1153 |
1154 | ResetDoppler();
1155 | if(OnResetCTools != null)
1156 | {
1157 | OnResetCTools();
1158 | }
1159 |
1160 | StopPlayingPath();
1161 | }
1162 |
1163 | void SaveOriginalCamera()
1164 | {
1165 | origPosition = flightCamera.transform.position;
1166 | origRotation = flightCamera.transform.localRotation;
1167 | origParent = flightCamera.transform.parent;
1168 | origNearClip = Camera.main.nearClipPlane;
1169 | }
1170 |
1171 | Part GetPartFromMouse()
1172 | {
1173 | Vector3 mouseAim = new Vector3(Input.mousePosition.x/Screen.width, Input.mousePosition.y/Screen.height, 0);
1174 | Ray ray = FlightCamera.fetch.mainCamera.ViewportPointToRay(mouseAim);
1175 | RaycastHit hit;
1176 | if(Physics.Raycast(ray, out hit, 10000, 1<<0))
1177 | {
1178 | Part p = hit.transform.GetComponentInParent();
1179 | return p;
1180 | }
1181 | else return null;
1182 | }
1183 |
1184 | Vector3 GetPosFromMouse()
1185 | {
1186 | Vector3 mouseAim = new Vector3(Input.mousePosition.x/Screen.width, Input.mousePosition.y/Screen.height, 0);
1187 | Ray ray = FlightCamera.fetch.mainCamera.ViewportPointToRay(mouseAim);
1188 | RaycastHit hit;
1189 | if(Physics.Raycast(ray, out hit, 15000, 557057))
1190 | {
1191 | return hit.point - (10 * ray.direction);
1192 | }
1193 | else return Vector3.zero;
1194 | }
1195 |
1196 | void PostDeathRevert()
1197 | {
1198 | if(cameraToolActive)
1199 | {
1200 | RevertCamera();
1201 | }
1202 | }
1203 |
1204 | void PostDeathRevert(GameScenes f)
1205 | {
1206 | if(cameraToolActive)
1207 | {
1208 | RevertCamera();
1209 | }
1210 | }
1211 |
1212 | void PostDeathRevert(Vessel v)
1213 | {
1214 | if(cameraToolActive)
1215 | {
1216 | RevertCamera();
1217 | }
1218 | }
1219 |
1220 | //GUI
1221 | void OnGUI()
1222 | {
1223 | if(guiEnabled && gameUIToggle)
1224 | {
1225 | windowRect = GUI.Window(320, windowRect, GuiWindow, "");
1226 |
1227 | if(showKeyframeEditor)
1228 | {
1229 | KeyframeEditorWindow();
1230 | }
1231 | if(showPathSelectorWindow)
1232 | {
1233 | PathSelectorWindow();
1234 | }
1235 | }
1236 | }
1237 |
1238 | void GuiWindow(int windowID)
1239 | {
1240 | GUI.DragWindow(new Rect(0,0,windowWidth, draggableHeight));
1241 |
1242 | GUIStyle centerLabel = new GUIStyle();
1243 | centerLabel.alignment = TextAnchor.UpperCenter;
1244 | centerLabel.normal.textColor = Color.white;
1245 |
1246 | GUIStyle leftLabel = new GUIStyle();
1247 | leftLabel.alignment = TextAnchor.UpperLeft;
1248 | leftLabel.normal.textColor = Color.white;
1249 |
1250 | GUIStyle leftLabelBold = new GUIStyle(leftLabel);
1251 | leftLabelBold.fontStyle = FontStyle.Bold;
1252 |
1253 |
1254 |
1255 | float line = 1;
1256 | float contentWidth = (windowWidth) - (2*leftIndent);
1257 | float contentTop = 20;
1258 | GUIStyle titleStyle = new GUIStyle(centerLabel);
1259 | titleStyle.fontSize = 24;
1260 | titleStyle.alignment = TextAnchor.MiddleCenter;
1261 | GUI.Label(new Rect(0, contentTop, windowWidth, 40), "Camera Tools", titleStyle);
1262 | line++;
1263 | float parseResult;
1264 |
1265 | //tool mode switcher
1266 | GUI.Label(new Rect(leftIndent, contentTop+(line*entryHeight), contentWidth, entryHeight), "Tool: "+toolMode.ToString(), leftLabelBold);
1267 | line++;
1268 | if(!cameraToolActive)
1269 | {
1270 | if(GUI.Button(new Rect(leftIndent, contentTop + (line * entryHeight), 25, entryHeight - 2), "<"))
1271 | {
1272 | CycleToolMode(false);
1273 | }
1274 | if(GUI.Button(new Rect(leftIndent + 25 + 4, contentTop + (line * entryHeight), 25, entryHeight - 2), ">"))
1275 | {
1276 | CycleToolMode(true);
1277 | }
1278 | }
1279 | line++;
1280 | line++;
1281 | if(autoFOV)
1282 | {
1283 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth / 2, entryHeight), "Autozoom Margin: ");
1284 | line++;
1285 | autoZoomMargin = GUI.HorizontalSlider(new Rect(leftIndent, contentTop + ((line) * entryHeight), contentWidth - 45, entryHeight), autoZoomMargin, 0, 50);
1286 | GUI.Label(new Rect(leftIndent + contentWidth - 40, contentTop + ((line - 0.15f) * entryHeight), 40, entryHeight), autoZoomMargin.ToString("0.0"), leftLabel);
1287 | }
1288 | else
1289 | {
1290 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), "Zoom:", leftLabel);
1291 | line++;
1292 | zoomExp = GUI.HorizontalSlider(new Rect(leftIndent, contentTop + ((line) * entryHeight), contentWidth - 45, entryHeight), zoomExp, 1, 8);
1293 | GUI.Label(new Rect(leftIndent + contentWidth - 40, contentTop + ((line - 0.15f) * entryHeight), 40, entryHeight), zoomFactor.ToString("0.0") + "x", leftLabel);
1294 | }
1295 | line++;
1296 |
1297 | if(toolMode != ToolModes.Pathing)
1298 | {
1299 | autoFOV = GUI.Toggle(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), autoFOV, "Auto Zoom");//, leftLabel);
1300 | line++;
1301 | }
1302 | line++;
1303 | useAudioEffects = GUI.Toggle(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), useAudioEffects, "Use Audio Effects");
1304 | line++;
1305 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), "Camera shake:");
1306 | line++;
1307 | shakeMultiplier = GUI.HorizontalSlider(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth - 45, entryHeight), shakeMultiplier, 0f, 10f);
1308 | GUI.Label(new Rect(leftIndent + contentWidth - 40, contentTop + ((line - 0.25f) * entryHeight), 40, entryHeight), shakeMultiplier.ToString("0.00") + "x");
1309 | line++;
1310 | line++;
1311 |
1312 | //Stationary camera GUI
1313 | if(toolMode == ToolModes.StationaryCamera)
1314 | {
1315 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), "Frame of Reference: " + referenceMode.ToString(), leftLabel);
1316 | line++;
1317 | if(GUI.Button(new Rect(leftIndent, contentTop + (line * entryHeight), 25, entryHeight - 2), "<"))
1318 | {
1319 | CycleReferenceMode(false);
1320 | }
1321 | if(GUI.Button(new Rect(leftIndent + 25 + 4, contentTop + (line * entryHeight), 25, entryHeight - 2), ">"))
1322 | {
1323 | CycleReferenceMode(true);
1324 | }
1325 |
1326 | line++;
1327 |
1328 | if(referenceMode == ReferenceModes.Surface || referenceMode == ReferenceModes.Orbit)
1329 | {
1330 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth / 2, entryHeight), "Max Rel. V: ", leftLabel);
1331 | maxRelV = float.Parse(GUI.TextField(new Rect(leftIndent + contentWidth / 2, contentTop + (line * entryHeight), contentWidth / 2, entryHeight), maxRelV.ToString()));
1332 | }
1333 | else if(referenceMode == ReferenceModes.InitialVelocity)
1334 | {
1335 | useOrbital = GUI.Toggle(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), useOrbital, " Orbital");
1336 | }
1337 | line++;
1338 |
1339 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), "Camera Position:", leftLabel);
1340 | line++;
1341 | string posButtonText = "Set Position w/ Click";
1342 | if(setPresetOffset) posButtonText = "Clear Position";
1343 | if(waitingForPosition) posButtonText = "Waiting...";
1344 | if(FlightGlobals.ActiveVessel != null && GUI.Button(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight - 2), posButtonText))
1345 | {
1346 | if(setPresetOffset)
1347 | {
1348 | setPresetOffset = false;
1349 | }
1350 | else
1351 | {
1352 | waitingForPosition = true;
1353 | mouseUp = false;
1354 | }
1355 | }
1356 | line++;
1357 |
1358 |
1359 | autoFlybyPosition = GUI.Toggle(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), autoFlybyPosition, "Auto Flyby Position");
1360 | if(autoFlybyPosition) manualOffset = false;
1361 | line++;
1362 |
1363 | manualOffset = GUI.Toggle(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), manualOffset, "Manual Flyby Position");
1364 | line++;
1365 |
1366 | Color origGuiColor = GUI.color;
1367 | if(manualOffset)
1368 | {
1369 | autoFlybyPosition = false;
1370 | }
1371 | else
1372 | {
1373 | GUI.color = new Color(0.5f, 0.5f, 0.5f, origGuiColor.a);
1374 | }
1375 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), 60, entryHeight), "Fwd:", leftLabel);
1376 | float textFieldWidth = 42;
1377 | Rect fwdFieldRect = new Rect(leftIndent + contentWidth - textFieldWidth - (3 * incrButtonWidth), contentTop + (line * entryHeight), textFieldWidth, entryHeight);
1378 | guiOffsetForward = GUI.TextField(fwdFieldRect, guiOffsetForward.ToString());
1379 | if(float.TryParse(guiOffsetForward, out parseResult))
1380 | {
1381 | manualOffsetForward = parseResult;
1382 | }
1383 | DrawIncrementButtons(fwdFieldRect, ref manualOffsetForward);
1384 | guiOffsetForward = manualOffsetForward.ToString();
1385 |
1386 | line++;
1387 | Rect rightFieldRect = new Rect(fwdFieldRect.x, contentTop + (line * entryHeight), textFieldWidth, entryHeight);
1388 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), 60, entryHeight), "Right:", leftLabel);
1389 | guiOffsetRight = GUI.TextField(rightFieldRect, guiOffsetRight);
1390 | if(float.TryParse(guiOffsetRight, out parseResult))
1391 | {
1392 | manualOffsetRight = parseResult;
1393 | }
1394 | DrawIncrementButtons(rightFieldRect, ref manualOffsetRight);
1395 | guiOffsetRight = manualOffsetRight.ToString();
1396 | line++;
1397 |
1398 | Rect upFieldRect = new Rect(fwdFieldRect.x, contentTop + (line * entryHeight), textFieldWidth, entryHeight);
1399 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), 60, entryHeight), "Up:", leftLabel);
1400 | guiOffsetUp = GUI.TextField(upFieldRect, guiOffsetUp);
1401 | if(float.TryParse(guiOffsetUp, out parseResult))
1402 | {
1403 | manualOffsetUp = parseResult;
1404 | }
1405 | DrawIncrementButtons(upFieldRect, ref manualOffsetUp);
1406 | guiOffsetUp = manualOffsetUp.ToString();
1407 | GUI.color = origGuiColor;
1408 |
1409 | line++;
1410 | line++;
1411 |
1412 | string targetText = "None";
1413 | if(camTarget != null) targetText = camTarget.gameObject.name;
1414 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), "Camera Target: " + targetText, leftLabel);
1415 | line++;
1416 | string tgtButtonText = "Set Target w/ Click";
1417 | if(waitingForTarget) tgtButtonText = "waiting...";
1418 | if(GUI.Button(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight - 2), tgtButtonText))
1419 | {
1420 | waitingForTarget = true;
1421 | mouseUp = false;
1422 | }
1423 | line++;
1424 | if(GUI.Button(new Rect(leftIndent, contentTop + (line * entryHeight), (contentWidth / 2) - 2, entryHeight - 2), "Target Self"))
1425 | {
1426 | camTarget = FlightGlobals.ActiveVessel.GetReferenceTransformPart();
1427 | hasTarget = true;
1428 | }
1429 | if(GUI.Button(new Rect(2 + leftIndent + contentWidth / 2, contentTop + (line * entryHeight), (contentWidth / 2) - 2, entryHeight - 2), "Clear Target"))
1430 | {
1431 | camTarget = null;
1432 | hasTarget = false;
1433 | }
1434 | line++;
1435 |
1436 | targetCoM = GUI.Toggle(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight - 2), targetCoM, "Vessel Center of Mass");
1437 | }
1438 | else if(toolMode == ToolModes.DogfightCamera)
1439 | {
1440 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), "Secondary target:");
1441 | line++;
1442 | string tVesselLabel;
1443 | if(showingVesselList)
1444 | {
1445 | tVesselLabel = "Clear";
1446 | }
1447 | else if(dogfightTarget)
1448 | {
1449 | tVesselLabel = dogfightTarget.vesselName;
1450 | }
1451 | else
1452 | {
1453 | tVesselLabel = "None";
1454 | }
1455 | if(GUI.Button(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), tVesselLabel))
1456 | {
1457 | if(showingVesselList)
1458 | {
1459 | showingVesselList = false;
1460 | dogfightTarget = null;
1461 | }
1462 | else
1463 | {
1464 | UpdateLoadedVessels();
1465 | showingVesselList = true;
1466 | }
1467 | }
1468 | line++;
1469 |
1470 | if(showingVesselList)
1471 | {
1472 | foreach(var v in loadedVessels)
1473 | {
1474 | if(!v || !v.loaded) continue;
1475 | if(GUI.Button(new Rect(leftIndent + 10, contentTop + (line * entryHeight), contentWidth - 10, entryHeight), v.vesselName))
1476 | {
1477 | dogfightTarget = v;
1478 | showingVesselList = false;
1479 | }
1480 | line++;
1481 | }
1482 | }
1483 | line++;
1484 |
1485 | if(hasBDAI)
1486 | {
1487 | useBDAutoTarget = GUI.Toggle(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight - 2), useBDAutoTarget, "BDA AI Auto target");
1488 | line++;
1489 | }
1490 |
1491 | line++;
1492 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth / 2, entryHeight), "Distance: " + dogfightDistance.ToString("0.0"));
1493 | line++;
1494 | dogfightDistance = GUI.HorizontalSlider(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), dogfightDistance, 1, 100);
1495 | line += 1.5f;
1496 |
1497 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), "Offset:");
1498 | line++;
1499 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), 15, entryHeight), "X: ");
1500 | dogfightOffsetX = GUI.HorizontalSlider(new Rect(leftIndent + 15, contentTop + (line * entryHeight) + 6, contentWidth - 45, entryHeight), dogfightOffsetX, -dogfightMaxOffset, dogfightMaxOffset);
1501 | GUI.Label(new Rect(leftIndent + contentWidth - 25, contentTop + (line * entryHeight), 25, entryHeight), dogfightOffsetX.ToString("0.0"));
1502 | line++;
1503 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), 15, entryHeight), "Y: ");
1504 | dogfightOffsetY = GUI.HorizontalSlider(new Rect(leftIndent + 15, contentTop + (line * entryHeight) + 6, contentWidth - 45, entryHeight), dogfightOffsetY, -dogfightMaxOffset, dogfightMaxOffset);
1505 | GUI.Label(new Rect(leftIndent + contentWidth - 25, contentTop + (line * entryHeight), 25, entryHeight), dogfightOffsetY.ToString("0.0"));
1506 | line += 1.5f;
1507 | }
1508 | else if(toolMode == ToolModes.Pathing)
1509 | {
1510 | if(selectedPathIndex >= 0)
1511 | {
1512 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), "Path:");
1513 | currentPath.pathName = GUI.TextField(new Rect(leftIndent + 34, contentTop + (line * entryHeight), contentWidth-34, entryHeight), currentPath.pathName);
1514 | }
1515 | else
1516 | {
1517 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), "Path: None");
1518 | }
1519 | line += 1.25f;
1520 | if(GUI.Button(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), "Open Path"))
1521 | {
1522 | TogglePathList();
1523 | }
1524 | line++;
1525 | if(GUI.Button(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth/2, entryHeight), "New Path"))
1526 | {
1527 | CreateNewPath();
1528 | }
1529 | if(GUI.Button(new Rect(leftIndent + (contentWidth/2), contentTop + (line * entryHeight), contentWidth / 2, entryHeight), "Delete Path"))
1530 | {
1531 | DeletePath(selectedPathIndex);
1532 | }
1533 | line ++;
1534 | if(selectedPathIndex >= 0)
1535 | {
1536 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), "Interpolation rate: " + currentPath.lerpRate.ToString("0.0"));
1537 | line++;
1538 | currentPath.lerpRate = GUI.HorizontalSlider(new Rect(leftIndent, contentTop + (line * entryHeight) + 4, contentWidth - 50, entryHeight), currentPath.lerpRate, 1f, 15f);
1539 | currentPath.lerpRate = Mathf.Round(currentPath.lerpRate * 10) / 10;
1540 | line++;
1541 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), "Path timescale " + currentPath.timeScale.ToString("0.00"));
1542 | line++;
1543 | currentPath.timeScale = GUI.HorizontalSlider(new Rect(leftIndent, contentTop + (line * entryHeight) + 4, contentWidth - 50, entryHeight), currentPath.timeScale, 0.05f, 4f);
1544 | currentPath.timeScale = Mathf.Round(currentPath.timeScale * 20) / 20;
1545 | line++;
1546 | float viewHeight = Mathf.Max(6 * entryHeight, currentPath.keyframeCount * entryHeight);
1547 | Rect scrollRect = new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, 6 * entryHeight);
1548 | GUI.Box(scrollRect, string.Empty);
1549 | float viewContentWidth = contentWidth - (2 * leftIndent);
1550 | keysScrollPos = GUI.BeginScrollView(scrollRect, keysScrollPos, new Rect(0, 0, viewContentWidth, viewHeight));
1551 | if(currentPath.keyframeCount > 0)
1552 | {
1553 | Color origGuiColor = GUI.color;
1554 | for(int i = 0; i < currentPath.keyframeCount; i++)
1555 | {
1556 | if(i == currentKeyframeIndex)
1557 | {
1558 | GUI.color = Color.green;
1559 | }
1560 | else
1561 | {
1562 | GUI.color = origGuiColor;
1563 | }
1564 | string kLabel = "#" + i.ToString() + ": " + currentPath.GetKeyframe(i).time.ToString("0.00") + "s";
1565 | if(GUI.Button(new Rect(0, (i * entryHeight), 3 * viewContentWidth / 4, entryHeight), kLabel))
1566 | {
1567 | SelectKeyframe(i);
1568 | }
1569 | if(GUI.Button(new Rect((3 * contentWidth / 4), (i * entryHeight), (viewContentWidth / 4) - 20, entryHeight), "X"))
1570 | {
1571 | DeleteKeyframe(i);
1572 | break;
1573 | }
1574 | //line++;
1575 | }
1576 | GUI.color = origGuiColor;
1577 | }
1578 | GUI.EndScrollView();
1579 | line += 6;
1580 | line += 0.5f;
1581 | if(GUI.Button(new Rect(leftIndent, contentTop + (line * entryHeight), 3 * contentWidth / 4, entryHeight), "New Key"))
1582 | {
1583 | CreateNewKeyframe();
1584 | }
1585 | }
1586 | }
1587 |
1588 | line += 1.25f;
1589 |
1590 | enableKeypad = GUI.Toggle(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), enableKeypad, "Keypad Control");
1591 | if(enableKeypad)
1592 | {
1593 | line++;
1594 |
1595 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth / 2, entryHeight), "Move Speed:");
1596 | guiFreeMoveSpeed = GUI.TextField(new Rect(leftIndent + contentWidth / 2, contentTop + (line * entryHeight), contentWidth / 2, entryHeight), guiFreeMoveSpeed);
1597 | if(float.TryParse(guiFreeMoveSpeed, out parseResult))
1598 | {
1599 | freeMoveSpeed = Mathf.Abs(parseResult);
1600 | guiFreeMoveSpeed = freeMoveSpeed.ToString();
1601 | }
1602 |
1603 | line++;
1604 |
1605 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth / 2, entryHeight), "Zoom Speed:");
1606 | guiKeyZoomSpeed = GUI.TextField(new Rect(leftIndent + contentWidth / 2, contentTop + (line * entryHeight), contentWidth / 2, entryHeight), guiKeyZoomSpeed);
1607 | if(float.TryParse(guiKeyZoomSpeed, out parseResult))
1608 | {
1609 | keyZoomSpeed = Mathf.Abs(parseResult);
1610 | guiKeyZoomSpeed = keyZoomSpeed.ToString();
1611 | }
1612 | }
1613 | else
1614 | {
1615 | line++;
1616 | line++;
1617 | }
1618 |
1619 | line++;
1620 | line++;
1621 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), "Keys:", centerLabel);
1622 | line++;
1623 |
1624 | //activate key binding
1625 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), "Activate: ", leftLabel);
1626 | GUI.Label(new Rect(leftIndent + 60, contentTop + (line * entryHeight), 60, entryHeight), cameraKey, leftLabel);
1627 | if(!isRecordingInput)
1628 | {
1629 | if(GUI.Button(new Rect(leftIndent + 125, contentTop + (line * entryHeight), 100, entryHeight), "Bind Key"))
1630 | {
1631 | mouseUp = false;
1632 | isRecordingInput = true;
1633 | isRecordingActivate = true;
1634 | }
1635 | }
1636 | else if(mouseUp && isRecordingActivate)
1637 | {
1638 | GUI.Label(new Rect(leftIndent + 125, contentTop + (line * entryHeight), 100, entryHeight), "Press a Key", leftLabel);
1639 |
1640 | string inputString = CCInputUtils.GetInputString();
1641 | if(inputString.Length > 0)
1642 | {
1643 | cameraKey = inputString;
1644 | isRecordingInput = false;
1645 | isRecordingActivate = false;
1646 | }
1647 | }
1648 |
1649 | line++;
1650 |
1651 | //revert key binding
1652 | GUI.Label(new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth, entryHeight), "Revert: ", leftLabel);
1653 | GUI.Label(new Rect(leftIndent + 60, contentTop + (line * entryHeight), 60, entryHeight), revertKey);
1654 | if(!isRecordingInput)
1655 | {
1656 | if(GUI.Button(new Rect(leftIndent + 125, contentTop + (line * entryHeight), 100, entryHeight), "Bind Key"))
1657 | {
1658 | mouseUp = false;
1659 | isRecordingInput = true;
1660 | isRecordingRevert = true;
1661 | }
1662 | }
1663 | else if(mouseUp && isRecordingRevert)
1664 | {
1665 | GUI.Label(new Rect(leftIndent + 125, contentTop + (line * entryHeight), 100, entryHeight), "Press a Key", leftLabel);
1666 | string inputString = CCInputUtils.GetInputString();
1667 | if(inputString.Length > 0)
1668 | {
1669 | revertKey = inputString;
1670 | isRecordingInput = false;
1671 | isRecordingRevert = false;
1672 | }
1673 | }
1674 |
1675 | line++;
1676 | line++;
1677 | Rect saveRect = new Rect(leftIndent, contentTop + (line * entryHeight), contentWidth / 2, entryHeight);
1678 | if(GUI.Button(saveRect, "Save"))
1679 | {
1680 | Save();
1681 | }
1682 |
1683 | Rect loadRect = new Rect(saveRect);
1684 | loadRect.x += contentWidth / 2;
1685 | if(GUI.Button(loadRect, "Reload"))
1686 | {
1687 | Load();
1688 | }
1689 |
1690 | //fix length
1691 | windowHeight = contentTop+(line*entryHeight)+entryHeight+entryHeight;
1692 | windowRect.height = windowHeight;// = new Rect(windowRect.x, windowRect.y, windowWidth, windowHeight);
1693 | }
1694 |
1695 | public static string pathSaveURL = "GameData/CameraTools/paths.cfg";
1696 | void Save()
1697 | {
1698 | CTPersistantField.Save();
1699 |
1700 | ConfigNode pathFileNode = ConfigNode.Load(pathSaveURL);
1701 | ConfigNode pathsNode = pathFileNode.GetNode("CAMERAPATHS");
1702 | pathsNode.RemoveNodes("CAMERAPATH");
1703 |
1704 | foreach(var path in availablePaths)
1705 | {
1706 | path.Save(pathsNode);
1707 | }
1708 | pathFileNode.Save(pathSaveURL);
1709 | }
1710 |
1711 | void Load()
1712 | {
1713 | CTPersistantField.Load();
1714 | guiOffsetForward = manualOffsetForward.ToString();
1715 | guiOffsetRight = manualOffsetRight.ToString();
1716 | guiOffsetUp = manualOffsetUp.ToString();
1717 | guiKeyZoomSpeed = keyZoomSpeed.ToString();
1718 | guiFreeMoveSpeed = freeMoveSpeed.ToString();
1719 |
1720 | DeselectKeyframe();
1721 | selectedPathIndex = -1;
1722 | availablePaths = new List();
1723 | ConfigNode pathFileNode = ConfigNode.Load(pathSaveURL);
1724 | foreach(var node in pathFileNode.GetNode("CAMERAPATHS").GetNodes("CAMERAPATH"))
1725 | {
1726 | availablePaths.Add(CameraPath.Load(node));
1727 | }
1728 | }
1729 |
1730 | void KeyframeEditorWindow()
1731 | {
1732 | float width = 300;
1733 | float height = 130;
1734 | Rect kWindowRect = new Rect(windowRect.x - width, windowRect.y + 365, width, height);
1735 | GUI.Box(kWindowRect, string.Empty);
1736 | GUI.BeginGroup(kWindowRect);
1737 | GUI.Label(new Rect(5, 5, 100, 25), "Keyframe #"+currentKeyframeIndex);
1738 | if(GUI.Button(new Rect(105, 5, 180, 25), "Revert Pos"))
1739 | {
1740 | ViewKeyframe(currentKeyframeIndex);
1741 | }
1742 | GUI.Label(new Rect(5, 35, 80, 25), "Time: ");
1743 | currKeyTimeString = GUI.TextField(new Rect(100, 35, 195, 25), currKeyTimeString, 16);
1744 | float parsed;
1745 | if(float.TryParse(currKeyTimeString, out parsed))
1746 | {
1747 | currentKeyframeTime = parsed;
1748 | }
1749 | bool applied = false;
1750 | if(GUI.Button(new Rect(100, 65, 195, 25), "Apply"))
1751 | {
1752 | Debug.Log("Applying keyframe at time: " + currentKeyframeTime);
1753 | currentPath.SetTransform(currentKeyframeIndex, flightCamera.transform, zoomExp, currentKeyframeTime);
1754 | applied = true;
1755 | }
1756 | if(GUI.Button(new Rect(100, 105, 195, 20), "Cancel"))
1757 | {
1758 | applied = true;
1759 | }
1760 | GUI.EndGroup();
1761 |
1762 | if(applied)
1763 | {
1764 | DeselectKeyframe();
1765 | }
1766 | }
1767 |
1768 | bool showPathSelectorWindow = false;
1769 | Vector2 pathSelectScrollPos;
1770 | void PathSelectorWindow()
1771 | {
1772 | float width = 300;
1773 | float height = 300;
1774 | float indent = 5;
1775 | float scrollRectSize = width - indent - indent;
1776 | Rect pSelectRect = new Rect(windowRect.x - width, windowRect.y + 290, width, height);
1777 | GUI.Box(pSelectRect, string.Empty);
1778 | GUI.BeginGroup(pSelectRect);
1779 |
1780 | Rect scrollRect = new Rect(indent, indent, scrollRectSize, scrollRectSize);
1781 | float scrollHeight = Mathf.Max(scrollRectSize, entryHeight * availablePaths.Count);
1782 | Rect scrollViewRect = new Rect(0, 0, scrollRectSize-20, scrollHeight);
1783 | pathSelectScrollPos = GUI.BeginScrollView(scrollRect, pathSelectScrollPos, scrollViewRect);
1784 | bool selected = false;
1785 | for(int i = 0; i < availablePaths.Count; i++)
1786 | {
1787 | if(GUI.Button(new Rect(0, i * entryHeight, scrollRectSize - 90, entryHeight), availablePaths[i].pathName))
1788 | {
1789 | SelectPath(i);
1790 | selected = true;
1791 | }
1792 | if(GUI.Button(new Rect(scrollRectSize-80, i * entryHeight, 60, entryHeight), "Delete"))
1793 | {
1794 | DeletePath(i);
1795 | break;
1796 | }
1797 | }
1798 |
1799 | GUI.EndScrollView();
1800 |
1801 | GUI.EndGroup();
1802 | if(selected)
1803 | {
1804 | showPathSelectorWindow = false;
1805 | }
1806 | }
1807 |
1808 | void DrawIncrementButtons(Rect fieldRect, ref float val)
1809 | {
1810 | Rect incrButtonRect = new Rect(fieldRect.x-incrButtonWidth, fieldRect.y, incrButtonWidth, entryHeight);
1811 | if(GUI.Button(incrButtonRect, "-"))
1812 | {
1813 | val -= 5;
1814 | }
1815 |
1816 | incrButtonRect.x -= incrButtonWidth;
1817 |
1818 | if(GUI.Button(incrButtonRect, "--"))
1819 | {
1820 | val -= 50;
1821 | }
1822 |
1823 | incrButtonRect.x = fieldRect.x + fieldRect.width;
1824 |
1825 | if(GUI.Button(incrButtonRect, "+"))
1826 | {
1827 | val += 5;
1828 | }
1829 |
1830 | incrButtonRect.x += incrButtonWidth;
1831 |
1832 | if(GUI.Button(incrButtonRect, "++"))
1833 | {
1834 | val += 50;
1835 | }
1836 | }
1837 |
1838 | //AppLauncherSetup
1839 | void AddToolbarButton()
1840 | {
1841 | if(!hasAddedButton)
1842 | {
1843 | Texture buttonTexture = GameDatabase.Instance.GetTexture("CameraTools/Textures/icon", false);
1844 | ApplicationLauncher.Instance.AddModApplication(EnableGui, DisableGui, Dummy, Dummy, Dummy, Dummy, ApplicationLauncher.AppScenes.FLIGHT, buttonTexture);
1845 | CamTools.hasAddedButton = true;
1846 | }
1847 |
1848 | }
1849 |
1850 | void EnableGui()
1851 | {
1852 | guiEnabled = true;
1853 | Debug.Log ("Showing CamTools GUI");
1854 | }
1855 |
1856 | void DisableGui()
1857 | {
1858 | guiEnabled = false;
1859 | Debug.Log ("Hiding CamTools GUI");
1860 | }
1861 |
1862 | void Dummy()
1863 | {}
1864 |
1865 | void GameUIEnable()
1866 | {
1867 | gameUIToggle = true;
1868 | }
1869 |
1870 | void GameUIDisable()
1871 | {
1872 | gameUIToggle = false;
1873 | }
1874 |
1875 | void CycleReferenceMode(bool forward)
1876 | {
1877 | var length = System.Enum.GetValues(typeof(ReferenceModes)).Length;
1878 | if(forward)
1879 | {
1880 | referenceMode++;
1881 | if((int)referenceMode == length) referenceMode = 0;
1882 | }
1883 | else
1884 | {
1885 | referenceMode--;
1886 | if((int)referenceMode == -1) referenceMode = (ReferenceModes) length-1;
1887 | }
1888 | }
1889 |
1890 | void CycleToolMode(bool forward)
1891 | {
1892 | var length = System.Enum.GetValues(typeof(ToolModes)).Length;
1893 | if(forward)
1894 | {
1895 | toolMode++;
1896 | if((int)toolMode == length) toolMode = 0;
1897 | }
1898 | else
1899 | {
1900 | toolMode--;
1901 | if((int)toolMode == -1) toolMode = (ToolModes) length-1;
1902 | }
1903 | }
1904 |
1905 | void OnFloatingOriginShift(Vector3d offset, Vector3d data1)
1906 | {
1907 | /*
1908 | Debug.LogWarning ("======Floating origin shifted.======");
1909 | Debug.LogWarning ("======Passed offset: "+offset+"======");
1910 | Debug.LogWarning ("======FloatingOrigin offset: "+FloatingOrigin.fetch.offset+"======");
1911 | Debug.LogWarning("========Floating Origin threshold: "+FloatingOrigin.fetch.threshold+"==========");
1912 | */
1913 | }
1914 |
1915 | void UpdateLoadedVessels()
1916 | {
1917 | if(loadedVessels == null)
1918 | {
1919 | loadedVessels = new List();
1920 | }
1921 | else
1922 | {
1923 | loadedVessels.Clear();
1924 | }
1925 |
1926 | foreach(var v in FlightGlobals.Vessels)
1927 | {
1928 | if(v.loaded && v.vesselType != VesselType.Debris && !v.isActiveVessel)
1929 | {
1930 | loadedVessels.Add(v);
1931 | }
1932 | }
1933 | }
1934 |
1935 | private void CheckForBDAI(Vessel v)
1936 | {
1937 | hasBDAI = false;
1938 | aiComponent = null;
1939 | if(v)
1940 | {
1941 | foreach(Part p in v.parts)
1942 | {
1943 | if(p.GetComponent("BDModulePilotAI"))
1944 | {
1945 | hasBDAI = true;
1946 | aiComponent = (object)p.GetComponent("BDModulePilotAI");
1947 | return;
1948 | }
1949 | }
1950 | }
1951 | }
1952 |
1953 | private Vessel GetAITargetedVessel()
1954 | {
1955 | if(!hasBDAI || aiComponent==null || bdAiTargetField==null)
1956 | {
1957 | return null;
1958 | }
1959 |
1960 | return (Vessel) bdAiTargetField.GetValue(aiComponent);
1961 | }
1962 |
1963 | private Type AIModuleType()
1964 | {
1965 | //Debug.Log("loaded assy's: ");
1966 | foreach(var assy in AssemblyLoader.loadedAssemblies)
1967 | {
1968 | //Debug.Log("- "+assy.assembly.FullName);
1969 | if(assy.assembly.FullName.Contains("BDArmory"))
1970 | {
1971 | foreach(var t in assy.assembly.GetTypes())
1972 | {
1973 | if(t.Name == "BDModulePilotAI")
1974 | {
1975 | return t;
1976 | }
1977 | }
1978 | }
1979 | }
1980 |
1981 | return null;
1982 | }
1983 |
1984 | private FieldInfo GetAITargetField()
1985 | {
1986 | Type aiModType = AIModuleType();
1987 | if(aiModType == null) return null;
1988 |
1989 | FieldInfo[] fields = aiModType.GetFields(BindingFlags.NonPublic|BindingFlags.Instance);
1990 | //Debug.Log("bdai fields: ");
1991 | foreach(var f in fields)
1992 | {
1993 | //Debug.Log("- " + f.Name);
1994 | if(f.Name == "targetVessel")
1995 | {
1996 | return f;
1997 | }
1998 | }
1999 |
2000 | return null;
2001 | }
2002 |
2003 |
2004 | void SwitchToVessel(Vessel v)
2005 | {
2006 | vessel = v;
2007 |
2008 | CheckForBDAI(v);
2009 |
2010 | if(cameraToolActive)
2011 | {
2012 | if(toolMode == ToolModes.DogfightCamera)
2013 | {
2014 | StartCoroutine(ResetDogfightCamRoutine());
2015 | }
2016 | }
2017 | }
2018 |
2019 | IEnumerator ResetDogfightCamRoutine()
2020 | {
2021 | yield return new WaitForEndOfFrame();
2022 | RevertCamera();
2023 | StartDogfightCamera();
2024 | }
2025 |
2026 | void CreateNewPath()
2027 | {
2028 | showKeyframeEditor = false;
2029 | availablePaths.Add(new CameraPath());
2030 | selectedPathIndex = availablePaths.Count - 1;
2031 | }
2032 |
2033 | void DeletePath(int index)
2034 | {
2035 | if(index < 0) return;
2036 | if(index >= availablePaths.Count) return;
2037 | availablePaths.RemoveAt(index);
2038 | selectedPathIndex = -1;
2039 | }
2040 |
2041 | void SelectPath(int index)
2042 | {
2043 | selectedPathIndex = index;
2044 | }
2045 |
2046 | void SelectKeyframe(int index)
2047 | {
2048 | if(isPlayingPath)
2049 | {
2050 | StopPlayingPath();
2051 | }
2052 | currentKeyframeIndex = index;
2053 | UpdateCurrentValues();
2054 | showKeyframeEditor = true;
2055 | ViewKeyframe(currentKeyframeIndex);
2056 | }
2057 |
2058 | void DeselectKeyframe()
2059 | {
2060 | currentKeyframeIndex = -1;
2061 | showKeyframeEditor = false;
2062 | }
2063 |
2064 | void DeleteKeyframe(int index)
2065 | {
2066 | currentPath.RemoveKeyframe(index);
2067 | if(index == currentKeyframeIndex)
2068 | {
2069 | DeselectKeyframe();
2070 | }
2071 | if(currentPath.keyframeCount > 0 && currentKeyframeIndex >= 0)
2072 | {
2073 | SelectKeyframe(Mathf.Clamp(currentKeyframeIndex, 0, currentPath.keyframeCount - 1));
2074 | }
2075 | }
2076 |
2077 | void UpdateCurrentValues()
2078 | {
2079 | if(currentPath == null) return;
2080 | if(currentKeyframeIndex < 0 || currentKeyframeIndex >= currentPath.keyframeCount)
2081 | {
2082 | return;
2083 | }
2084 | CameraKeyframe currentKey = currentPath.GetKeyframe(currentKeyframeIndex);
2085 | currentKeyframeTime = currentKey.time;
2086 |
2087 | currKeyTimeString = currentKeyframeTime.ToString();
2088 | }
2089 |
2090 | void CreateNewKeyframe()
2091 | {
2092 | if(!cameraToolActive)
2093 | {
2094 | StartPathingCam();
2095 | }
2096 |
2097 | showPathSelectorWindow = false;
2098 |
2099 | float time = currentPath.keyframeCount > 0 ? currentPath.GetKeyframe(currentPath.keyframeCount - 1).time + 1 : 0;
2100 | currentPath.AddTransform(flightCamera.transform, zoomExp, time);
2101 | SelectKeyframe(currentPath.keyframeCount - 1);
2102 |
2103 | if(currentPath.keyframeCount > 6)
2104 | {
2105 | keysScrollPos.y += entryHeight;
2106 | }
2107 | }
2108 |
2109 | void ViewKeyframe(int index)
2110 | {
2111 | if(!cameraToolActive)
2112 | {
2113 | StartPathingCam();
2114 | }
2115 | CameraKeyframe currentKey = currentPath.GetKeyframe(index);
2116 | flightCamera.transform.localPosition = currentKey.position;
2117 | flightCamera.transform.localRotation = currentKey.rotation;
2118 | zoomExp = currentKey.zoom;
2119 | }
2120 |
2121 | void StartPathingCam()
2122 | {
2123 | vessel = FlightGlobals.ActiveVessel;
2124 | cameraUp = -FlightGlobals.getGeeForceAtPosition(vessel.GetWorldPos3D()).normalized;
2125 | if(FlightCamera.fetch.mode == FlightCamera.Modes.ORBITAL || (FlightCamera.fetch.mode == FlightCamera.Modes.AUTO && FlightCamera.GetAutoModeForVessel(vessel) == FlightCamera.Modes.ORBITAL))
2126 | {
2127 | cameraUp = Vector3.up;
2128 | }
2129 |
2130 | cameraParent.transform.position = vessel.transform.position+vessel.rb_velocity*Time.fixedDeltaTime;
2131 | cameraParent.transform.rotation = vessel.transform.rotation;
2132 | flightCamera.SetTargetNone();
2133 | flightCamera.transform.parent = cameraParent.transform;
2134 | flightCamera.DeactivateUpdate();
2135 |
2136 | cameraToolActive = true;
2137 | }
2138 |
2139 | void PlayPathingCam()
2140 | {
2141 | if(selectedPathIndex < 0)
2142 | {
2143 | RevertCamera();
2144 | return;
2145 | }
2146 |
2147 | if(currentPath.keyframeCount <= 0)
2148 | {
2149 | RevertCamera();
2150 | return;
2151 | }
2152 |
2153 | DeselectKeyframe();
2154 |
2155 | if(!cameraToolActive)
2156 | {
2157 | StartPathingCam();
2158 | }
2159 |
2160 | CameraTransformation firstFrame = currentPath.Evaulate(0);
2161 | flightCamera.transform.localPosition = firstFrame.position;
2162 | flightCamera.transform.localRotation = firstFrame.rotation;
2163 | zoomExp = firstFrame.zoom;
2164 |
2165 | isPlayingPath = true;
2166 | pathStartTime = Time.time;
2167 | }
2168 |
2169 | void StopPlayingPath()
2170 | {
2171 | isPlayingPath = false;
2172 | }
2173 |
2174 | void TogglePathList()
2175 | {
2176 | showKeyframeEditor = false;
2177 | showPathSelectorWindow = !showPathSelectorWindow;
2178 | }
2179 |
2180 | void UpdatePathingCam()
2181 | {
2182 | cameraParent.transform.position = vessel.transform.position+vessel.rb_velocity*Time.fixedDeltaTime;
2183 | cameraParent.transform.rotation = vessel.transform.rotation;
2184 |
2185 | if(isPlayingPath)
2186 | {
2187 | CameraTransformation tf = currentPath.Evaulate(pathTime * currentPath.timeScale);
2188 | flightCamera.transform.localPosition = Vector3.Lerp(flightCamera.transform.localPosition, tf.position, currentPath.lerpRate*Time.fixedDeltaTime);
2189 | flightCamera.transform.localRotation = Quaternion.Slerp(flightCamera.transform.localRotation, tf.rotation, currentPath.lerpRate*Time.fixedDeltaTime);
2190 | zoomExp = Mathf.Lerp(zoomExp, tf.zoom, currentPath.lerpRate*Time.fixedDeltaTime);
2191 | }
2192 | else
2193 | {
2194 | //move
2195 | //mouse panning, moving
2196 | Vector3 forwardLevelAxis = flightCamera.transform.forward;//(Quaternion.AngleAxis(-90, cameraUp) * flightCamera.transform.right).normalized;
2197 | Vector3 rightAxis = flightCamera.transform.right;//(Quaternion.AngleAxis(90, forwardLevelAxis) * cameraUp).normalized;
2198 | if(enableKeypad)
2199 | {
2200 | if(Input.GetKey(fmUpKey))
2201 | {
2202 | flightCamera.transform.position += cameraUp * freeMoveSpeed * Time.fixedDeltaTime;
2203 | }
2204 | else if(Input.GetKey(fmDownKey))
2205 | {
2206 | flightCamera.transform.position -= cameraUp * freeMoveSpeed * Time.fixedDeltaTime;
2207 | }
2208 | if(Input.GetKey(fmForwardKey))
2209 | {
2210 | flightCamera.transform.position += forwardLevelAxis * freeMoveSpeed * Time.fixedDeltaTime;
2211 | }
2212 | else if(Input.GetKey(fmBackKey))
2213 | {
2214 | flightCamera.transform.position -= forwardLevelAxis * freeMoveSpeed * Time.fixedDeltaTime;
2215 | }
2216 | if(Input.GetKey(fmLeftKey))
2217 | {
2218 | flightCamera.transform.position -= flightCamera.transform.right * freeMoveSpeed * Time.fixedDeltaTime;
2219 | }
2220 | else if(Input.GetKey(fmRightKey))
2221 | {
2222 | flightCamera.transform.position += flightCamera.transform.right * freeMoveSpeed * Time.fixedDeltaTime;
2223 | }
2224 |
2225 | //keyZoom
2226 | if(!autoFOV)
2227 | {
2228 | if(Input.GetKey(fmZoomInKey))
2229 | {
2230 | zoomExp = Mathf.Clamp(zoomExp + (keyZoomSpeed * Time.fixedDeltaTime), 1, 8);
2231 | }
2232 | else if(Input.GetKey(fmZoomOutKey))
2233 | {
2234 | zoomExp = Mathf.Clamp(zoomExp - (keyZoomSpeed * Time.fixedDeltaTime), 1, 8);
2235 | }
2236 | }
2237 | else
2238 | {
2239 | if(Input.GetKey(fmZoomInKey))
2240 | {
2241 | autoZoomMargin = Mathf.Clamp(autoZoomMargin + (keyZoomSpeed * 10 * Time.fixedDeltaTime), 0, 50);
2242 | }
2243 | else if(Input.GetKey(fmZoomOutKey))
2244 | {
2245 | autoZoomMargin = Mathf.Clamp(autoZoomMargin - (keyZoomSpeed * 10 * Time.fixedDeltaTime), 0, 50);
2246 | }
2247 | }
2248 | }
2249 |
2250 | if(Input.GetKey(KeyCode.Mouse1) && Input.GetKey(KeyCode.Mouse2))
2251 | {
2252 | flightCamera.transform.rotation = Quaternion.AngleAxis(Input.GetAxis("Mouse X") * -1.7f, flightCamera.transform.forward) * flightCamera.transform.rotation;
2253 | }
2254 | else
2255 | {
2256 | if(Input.GetKey(KeyCode.Mouse1))
2257 | {
2258 | flightCamera.transform.rotation *= Quaternion.AngleAxis(Input.GetAxis("Mouse X") * 1.7f/(zoomExp*zoomExp), Vector3.up); //*(Mathf.Abs(Mouse.delta.x)/7)
2259 | flightCamera.transform.rotation *= Quaternion.AngleAxis(-Input.GetAxis("Mouse Y") * 1.7f/(zoomExp*zoomExp), Vector3.right);
2260 | flightCamera.transform.rotation = Quaternion.LookRotation(flightCamera.transform.forward, flightCamera.transform.up);
2261 | }
2262 | if(Input.GetKey(KeyCode.Mouse2))
2263 | {
2264 | flightCamera.transform.position += flightCamera.transform.right * Input.GetAxis("Mouse X") * 2;
2265 | flightCamera.transform.position += forwardLevelAxis * Input.GetAxis("Mouse Y") * 2;
2266 | }
2267 | }
2268 | flightCamera.transform.position += flightCamera.transform.up * 10 * Input.GetAxis("Mouse ScrollWheel");
2269 |
2270 | }
2271 |
2272 | //zoom
2273 | zoomFactor = Mathf.Exp(zoomExp) / Mathf.Exp(1);
2274 | manualFOV = 60 / zoomFactor;
2275 | updateFOV = (currentFOV != manualFOV);
2276 | if(updateFOV)
2277 | {
2278 | currentFOV = Mathf.Lerp(currentFOV, manualFOV, 0.1f);
2279 | flightCamera.SetFoV(currentFOV);
2280 | updateFOV = false;
2281 | }
2282 | }
2283 |
2284 | }
2285 |
2286 |
2287 |
2288 |
2289 |
2290 | public enum ReferenceModes {InitialVelocity, Surface, Orbit}
2291 |
2292 | public enum ToolModes {StationaryCamera, DogfightCamera, Pathing};
2293 | }
2294 |
2295 |
--------------------------------------------------------------------------------
/CameraTools/CameraKeyframe.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | using System.Collections.Generic;
3 | namespace CameraTools
4 | {
5 | public struct CameraKeyframe
6 | {
7 | public Vector3 position;
8 | public Quaternion rotation;
9 | public float zoom;
10 | public float time;
11 |
12 | public CameraKeyframe(Vector3 pos, Quaternion rot, float z, float t)
13 | {
14 | position = pos;
15 | rotation = rot;
16 | zoom = z;
17 | time = t;
18 | }
19 |
20 | }
21 |
22 | public class CameraKeyframeComparer : IComparer
23 | {
24 | public int Compare(CameraKeyframe a, CameraKeyframe b)
25 | {
26 | return a.time.CompareTo(b.time);
27 | }
28 | }
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/CameraTools/CameraPath.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using UnityEngine;
4 |
5 | namespace CameraTools
6 | {
7 | public class CameraPath
8 | {
9 | public string pathName;
10 | int keyCount = 0;
11 | public int keyframeCount
12 | {
13 | get
14 | {
15 | return keyCount;
16 | }
17 | private set
18 | {
19 | keyCount = value;
20 | }
21 | }
22 | public List points;
23 | public List rotations;
24 | public List times;
25 | public List zooms;
26 |
27 | public float lerpRate = 15;
28 | public float timeScale = 1;
29 |
30 | Vector3Animation pointCurve;
31 | RotationAnimation rotationCurve;
32 | AnimationCurve zoomCurve;
33 |
34 | public CameraPath()
35 | {
36 | pathName = "New Path";
37 | points = new List();
38 | rotations = new List();
39 | times = new List();
40 | zooms = new List();
41 | }
42 |
43 | public static CameraPath Load(ConfigNode node)
44 | {
45 | CameraPath newPath = new CameraPath();
46 |
47 | newPath.pathName = node.GetValue("pathName");
48 | newPath.points = ParseVectorList(node.GetValue("points"));
49 | newPath.rotations = ParseQuaternionList(node.GetValue("rotations"));
50 | newPath.times = ParseFloatList(node.GetValue("times"));
51 | newPath.zooms = ParseFloatList(node.GetValue("zooms"));
52 | newPath.lerpRate = float.Parse(node.GetValue("lerpRate"));
53 | newPath.timeScale = float.Parse(node.GetValue("timeScale"));
54 | newPath.Refresh();
55 |
56 | return newPath;
57 | }
58 |
59 | public void Save(ConfigNode node)
60 | {
61 | Debug.Log("Saving path: " + pathName);
62 | ConfigNode pathNode = node.AddNode("CAMERAPATH");
63 | pathNode.AddValue("pathName", pathName);
64 | pathNode.AddValue("points", WriteVectorList(points));
65 | pathNode.AddValue("rotations", WriteQuaternionList(rotations));
66 | pathNode.AddValue("times", WriteFloatList(times));
67 | pathNode.AddValue("zooms", WriteFloatList(zooms));
68 | pathNode.AddValue("lerpRate", lerpRate);
69 | pathNode.AddValue("timeScale", timeScale);
70 | }
71 |
72 | public static string WriteVectorList(List list)
73 | {
74 | string output = string.Empty;
75 | foreach(var val in list)
76 | {
77 | output += ConfigNode.WriteVector(val) + ";";
78 | }
79 | return output;
80 | }
81 |
82 | public static string WriteQuaternionList(List list)
83 | {
84 | string output = string.Empty;
85 | foreach(var val in list)
86 | {
87 | output += ConfigNode.WriteQuaternion(val) + ";";
88 | }
89 | return output;
90 | }
91 |
92 | public static string WriteFloatList(List list)
93 | {
94 | string output = string.Empty;
95 | foreach(var val in list)
96 | {
97 | output += val.ToString() + ";";
98 | }
99 | return output;
100 | }
101 |
102 | public static List ParseVectorList(string arrayString)
103 | {
104 | string[] vectorStrings = arrayString.Split(new char[]{ ';' }, StringSplitOptions.RemoveEmptyEntries);
105 | List vList = new List();
106 | for(int i = 0; i < vectorStrings.Length; i++)
107 | {
108 | Debug.Log("attempting to parse vector: --" + vectorStrings[i] + "--");
109 | vList.Add(ConfigNode.ParseVector3(vectorStrings[i]));
110 | }
111 |
112 | return vList;
113 | }
114 |
115 | public static List ParseQuaternionList(string arrayString)
116 | {
117 | string[] qStrings = arrayString.Split(new char[]{ ';' }, StringSplitOptions.RemoveEmptyEntries);
118 | List qList = new List();
119 | for(int i = 0; i < qStrings.Length; i++)
120 | {
121 | qList.Add(ConfigNode.ParseQuaternion(qStrings[i]));
122 | }
123 |
124 | return qList;
125 | }
126 |
127 | public static List ParseFloatList(string arrayString)
128 | {
129 | string[] fStrings = arrayString.Split(new char[]{ ';' }, StringSplitOptions.RemoveEmptyEntries);
130 | List fList = new List();
131 | for(int i = 0; i < fStrings.Length; i++)
132 | {
133 | fList.Add(float.Parse(fStrings[i]));
134 | }
135 |
136 | return fList;
137 | }
138 |
139 | public void AddTransform(Transform cameraTransform, float zoom, float time)
140 | {
141 | points.Add(cameraTransform.localPosition);
142 | rotations.Add(cameraTransform.localRotation);
143 | zooms.Add(zoom);
144 | times.Add(time);
145 | keyframeCount = times.Count;
146 | Sort();
147 | UpdateCurves();
148 | }
149 |
150 | public void SetTransform(int index, Transform cameraTransform, float zoom, float time)
151 | {
152 | points[index] = cameraTransform.localPosition;
153 | rotations[index] = cameraTransform.localRotation;
154 | zooms[index] = zoom;
155 | times[index] = time;
156 | Sort();
157 | UpdateCurves();
158 | }
159 |
160 | public void Refresh()
161 | {
162 | keyframeCount = times.Count;
163 | Sort();
164 | UpdateCurves();
165 | }
166 |
167 | public void RemoveKeyframe(int index)
168 | {
169 | points.RemoveAt(index);
170 | rotations.RemoveAt(index);
171 | zooms.RemoveAt(index);
172 | times.RemoveAt(index);
173 | keyframeCount = times.Count;
174 | UpdateCurves();
175 | }
176 |
177 | public void Sort()
178 | {
179 | List keyframes = new List();
180 | for(int i = 0; i < points.Count; i++)
181 | {
182 | keyframes.Add(new CameraKeyframe(points[i], rotations[i], zooms[i], times[i]));
183 | }
184 | keyframes.Sort(new CameraKeyframeComparer());
185 |
186 | for(int i = 0; i < keyframes.Count; i++)
187 | {
188 | points[i] = keyframes[i].position;
189 | rotations[i] = keyframes[i].rotation;
190 | zooms[i] = keyframes[i].zoom;
191 | times[i] = keyframes[i].time;
192 | }
193 | }
194 |
195 | public CameraKeyframe GetKeyframe(int index)
196 | {
197 | int i = index;
198 | return new CameraKeyframe(points[i], rotations[i], zooms[i], times[i]);
199 | }
200 |
201 | public void UpdateCurves()
202 | {
203 | pointCurve = new Vector3Animation(points.ToArray(), times.ToArray());
204 | rotationCurve = new RotationAnimation(rotations.ToArray(), times.ToArray());
205 | zoomCurve = new AnimationCurve();
206 | for(int i = 0; i < zooms.Count; i++)
207 | {
208 | zoomCurve.AddKey(new Keyframe(times[i], zooms[i]));
209 | }
210 | }
211 |
212 | public CameraTransformation Evaulate(float time)
213 | {
214 | CameraTransformation tf = new CameraTransformation();
215 | tf.position = pointCurve.Evaluate(time);
216 | tf.rotation = rotationCurve.Evaluate(time);
217 | tf.zoom = zoomCurve.Evaluate(time);
218 |
219 | return tf;
220 | }
221 |
222 |
223 |
224 |
225 |
226 | }
227 | }
228 |
229 |
--------------------------------------------------------------------------------
/CameraTools/CameraTools.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | x86
6 | 9.0.21022
7 | 2.0
8 | {446E2470-00DC-4835-B62D-9DB8A7D41F4A}
9 | Library
10 | CameraTools
11 | CameraTools
12 | v4.7.2
13 |
14 |
15 |
16 |
17 | 3.5
18 |
19 |
20 |
21 |
22 | True
23 | full
24 | False
25 | bin\Debug
26 | DEBUG;
27 | prompt
28 | 4
29 | x86
30 | False
31 | false
32 |
33 |
34 | none
35 | False
36 | bin\Release
37 | prompt
38 | 4
39 | x86
40 | False
41 | false
42 |
43 |
44 | true
45 | bin\Debug\
46 | DEBUG;
47 | full
48 | AnyCPU
49 | prompt
50 | MinimumRecommendedRules.ruleset
51 | false
52 |
53 |
54 | bin\Release\
55 | AnyCPU
56 | prompt
57 | MinimumRecommendedRules.ruleset
58 | true
59 | false
60 | portable
61 | true
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | False
81 | ..\..\_LocalDev\KSPRefs\Assembly-CSharp.dll
82 |
83 |
84 | False
85 | ..\..\_LocalDev\KSPRefs\KSPAssets.dll
86 |
87 |
88 |
89 |
90 | False
91 | ..\..\_LocalDev\KSPRefs\UnityEngine.dll
92 |
93 |
94 | ..\..\_LocalDev\KSPRefs\UnityEngine.AnimationModule.dll
95 |
96 |
97 | ..\..\_LocalDev\KSPRefs\UnityEngine.AssetBundleModule.dll
98 |
99 |
100 | ..\..\_LocalDev\KSPRefs\UnityEngine.AudioModule.dll
101 |
102 |
103 | ..\..\_LocalDev\KSPRefs\UnityEngine.CoreModule.dll
104 |
105 |
106 | ..\..\_LocalDev\KSPRefs\UnityEngine.ImageConversionModule.dll
107 |
108 |
109 | ..\..\_LocalDev\KSPRefs\UnityEngine.IMGUIModule.dll
110 |
111 |
112 | ..\..\_LocalDev\KSPRefs\UnityEngine.InputLegacyModule.dll
113 |
114 |
115 | ..\..\_LocalDev\KSPRefs\UnityEngine.InputModule.dll
116 |
117 |
118 | ..\..\_LocalDev\KSPRefs\UnityEngine.JSONSerializeModule.dll
119 |
120 |
121 | ..\..\_LocalDev\KSPRefs\UnityEngine.ParticleSystemModule.dll
122 |
123 |
124 | ..\..\_LocalDev\KSPRefs\UnityEngine.PhysicsModule.dll
125 |
126 |
127 | ..\..\_LocalDev\KSPRefs\UnityEngine.TextCoreModule.dll
128 |
129 |
130 | ..\..\_LocalDev\KSPRefs\UnityEngine.TextRenderingModule.dll
131 |
132 |
133 | False
134 | ..\..\_LocalDev\KSPRefs\UnityEngine.UI.dll
135 |
136 |
137 | ..\..\_LocalDev\KSPRefs\UnityEngine.UIElementsModule.dll
138 |
139 |
140 | ..\..\_LocalDev\KSPRefs\UnityEngine.UIModule.dll
141 |
142 |
143 | ..\..\_LocalDev\KSPRefs\UnityEngine.UnityWebRequestWWWModule.dll
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 | @echo $(Targetname)
170 | @echo ...
171 | @echo set lpath vars from LocalDev storage...
172 | set /p KSP_DIR=<"$(ProjectDir)LocalDev\ksp_dir.txt"
173 | set /p PDB2MDB_EXE=<"$(ProjectDir)LocalDev\pdb2mdb_exe.txt"
174 | set /p ZA_DIR=<"$(ProjectDir)LocalDev\7za_dir.txt"
175 | set /p DIST_DIR=<"$(ProjectDir)LocalDev\dist_dir.txt"
176 |
177 | @echo distributing $(Targetname) files...
178 | copy /Y "$(TargetPath)" "$(ProjectDir)Distribution\GameData\CameraTools\Plugins\"
179 |
180 | if $(ConfigurationName) == Debug (
181 | @echo building $(Targetname).dll.mdb file...
182 | cd "$(TargetDir)"
183 | copy /Y "$(TargetDir)$(Targetname).pdb" "%25KSP_DIR%25\GameData\CameraTools\Plugins\"
184 | )
185 |
186 | @echo packaging files...
187 | if exist "%25DIST_DIR%25\CameraTools*.zip" del "%25DIST_DIR%25\CameraTools*.zip"
188 | call "%25ZA_DIR%25\7za.exe" a -tzip -r "%25DIST_DIR%25\CameraTools.@(VersionNumber)_%25DATE:~4,2%25%25DATE:~7,2%25%25DATE:~10,4%25.zip" "$(ProjectDir)Distribution\*.*"
189 |
190 | @echo Deploy $(Targetname) Distribution files to test env: %25KSP_DIR%25\GameData...
191 | @echo copying:"$(SolutionDir)\CameraTools\Distribution\GameData" to "%25KSP_DIR%25\GameData"
192 | xcopy /E /Y "$(SolutionDir)\CameraTools\Distribution\GameData" "%25KSP_DIR%25\GameData"
193 |
194 | if $(ConfigurationName) == Debug (
195 | copy /Y "$(TargetDir)$(Targetname).pdb" "%25KSP_DIR%25\GameData\CameraTools\Plugins\"
196 | )
197 |
198 | @echo Build/deploy complete!
199 |
200 |
--------------------------------------------------------------------------------
/CameraTools/CameraTransformation.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | namespace CameraTools
3 | {
4 | public struct CameraTransformation
5 | {
6 | public Vector3 position;
7 | public Quaternion rotation;
8 | public float zoom;
9 | }
10 | }
11 |
12 |
--------------------------------------------------------------------------------
/CameraTools/Curve3D.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace CameraTools
4 | {
5 | public class Curve3D
6 | {
7 | private Vector3[] points;
8 | private float[] times;
9 | private AnimationCurve[] curves;
10 |
11 | bool curveReady = false;
12 |
13 | // Use this for initialization
14 | public Curve3D()
15 | {
16 | curves = new AnimationCurve[]{new AnimationCurve(), new AnimationCurve(), new AnimationCurve()};
17 | }
18 |
19 | public Curve3D(Vector3[] newPoints, float[] newTimes)
20 | {
21 | curves = new AnimationCurve[]{new AnimationCurve(), new AnimationCurve(), new AnimationCurve()};
22 | SetPoints(newPoints, newTimes);
23 | }
24 |
25 | public void SetPoints(Vector3[] newPoints, float[] newTimes)
26 | {
27 | if(newPoints.Length != newTimes.Length)
28 | {
29 | Debug.LogError("Curve3D: points array must be same length as times array");
30 | return;
31 | }
32 | points = new Vector3[newPoints.Length];
33 | times = new float[newPoints.Length];
34 | for(int i = 0; i < points.Length; i++)
35 | {
36 | points[i] = newPoints[i];
37 | times[i] = newTimes[i];
38 | }
39 |
40 | UpdateCurve();
41 | }
42 |
43 | public void SetPoint(int index, Vector3 newPoint, float newTime)
44 | {
45 | if(index < points.Length)
46 | {
47 | SetAnimKey(index, newPoint, newTime);
48 | }
49 | else
50 | {
51 | Debug.LogError("Tried to set new point in a Curve3D beyond the existing array. Not yet implemented.");
52 | }
53 | }
54 |
55 |
56 | private void UpdateCurve()
57 | {
58 | curveReady = false;
59 | //clear existing keys
60 | for(int i = 0; i < 3; i++)
61 | {
62 | curves[i] = new AnimationCurve();
63 | }
64 |
65 | if(points.Length == 0) return;
66 |
67 | for(int i = 0; i < points.Length; i++)
68 | {
69 | SetAnimKey(i, points[i], times[i]);
70 | }
71 |
72 | curveReady = true;
73 | }
74 |
75 | void SetAnimKey(int index, Vector3 point, float time)
76 | {
77 | if(index >= curves[0].keys.Length)
78 | {
79 | curves[0].AddKey(time, point.x);
80 | curves[1].AddKey(time, point.y);
81 | curves[2].AddKey(time, point.z);
82 | }
83 | else
84 | {
85 | curves[0].MoveKey(index, new Keyframe(time, point.x));
86 | curves[1].MoveKey(index, new Keyframe(time, point.y));
87 | curves[2].MoveKey(index, new Keyframe(time, point.z));
88 | }
89 | }
90 |
91 | public Vector3 GetPoint(float time)
92 | {
93 | if(!curveReady)
94 | {
95 | Debug.LogWarning("Curve was accessed but it was not properly initialized.");
96 | return Vector3.zero;
97 | }
98 |
99 | float x = curves[0].Evaluate(time);
100 | float y = curves[1].Evaluate(time);
101 | float z = curves[2].Evaluate(time);
102 | return new Vector3(x,y,z);
103 | }
104 |
105 | public Vector3 GetTangent(float time)
106 | {
107 | if(!curveReady)
108 | {
109 | Debug.LogWarning("Curve was accessed but it was not properly initialized.");
110 | return Vector3.one;
111 | }
112 |
113 | if(time < 1)
114 | {
115 | return (GetPoint(Mathf.Min(time+0.01f, 1))-GetPoint(time)).normalized;
116 | }
117 | else
118 | {
119 | return (GetPoint(1)-GetPoint(0.99f)).normalized;
120 | }
121 | }
122 |
123 |
124 | }
125 | }
126 |
127 |
--------------------------------------------------------------------------------
/CameraTools/Distribution/GameData/CameraTools/ATM_CameraTools.cfg:
--------------------------------------------------------------------------------
1 | ACTIVE_TEXTURE_MANAGER_CONFIG
2 | {
3 | folder = CameraTools
4 | enabled = true
5 |
6 | OVERRIDES
7 | {
8 | CameraTools/Textures/.*
9 | {
10 | compress = true
11 | mipmaps = false
12 | scale = 1
13 | max_size = 0
14 | make_not_readable = false
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/CameraTools/Distribution/GameData/CameraTools/CameraTools.version:
--------------------------------------------------------------------------------
1 | {
2 | "NAME": "CameraTools",
3 | "URL": "https://raw.githubusercontent.com/jrodrigv/CameraTools/master/CameraTools/Distribution/GameData/CameraTools/CameraTools.version",
4 | "DOWNLOAD": "https://github.com/jrodrigv/CameraTools/releases/tag/v1.14.0",
5 | "CHANGE_LOG_URL": "https://github.com/jrodrigv/CameraTools/blob/master/CameraTools/Distribution/GameData/CameraTools/Changelog.txt",
6 | "VERSION": {
7 | "MAJOR": 1,
8 | "MINOR": 14,
9 | "PATCH": 0,
10 | "BUILD": 0
11 | },
12 | "KSP_VERSION": {
13 | "MAJOR": 1,
14 | "MINOR": 9,
15 | "PATCH": 0
16 | },
17 | "KSP_VERSION_MIN": {
18 | "MAJOR": 1,
19 | "MINOR": 9,
20 | "PATCH": 0
21 | },
22 | "KSP_VERSION_MAX": {
23 | "MAJOR": 1,
24 | "MINOR": 9,
25 | "PATCH": 99
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/CameraTools/Distribution/GameData/CameraTools/Changelog.txt:
--------------------------------------------------------------------------------
1 | v1.14.0
2 | - Compatibility with KSP 1.9.x
3 |
4 | v1.13.0
5 | - Compatibility with KSP 1.8.x
6 |
7 | v1.12.0
8 | - Compatibility with KSP 1.7.x
9 |
10 | v1.11.0
11 | - Compatibility with KSP 1.5.x
12 |
13 | v1.10.0
14 | - Compatibility with KSP 1.4.x
15 |
16 | v1.9.0
17 | - Compatibility with KSP 1.3.1
18 | - Fixing Dogfighting camera for BDArmory
19 |
20 | v1.8.0
21 | - Compatibility with KSP 1.2.2 and KSP 1.2.9 BETA
22 | - Fixing isssue when reverting the camera
23 |
24 |
25 | v1.7.0
26 | - Compatibility with KSP 1.2.1
27 |
28 | v1.6.0
29 | - 1.1 compat and path tool
30 | - fix loading paths/deleting paths, fix deleting selected key
31 | - set spatial blend to 3d audio
32 |
33 | v1.5.1
34 | - Dogfight mode auto-resets when a new target is selected or active vessel is switched
35 | - Auto targeting option with BDArmory AI pilot target
36 |
37 | v1.5
38 | - Dogfight chase mode
39 | - Autozoom margin slider
40 |
41 | v1.4.2
42 | - Slight UI tweak
43 | - Incremental buttons for manual offset
44 |
45 | v1.4.1
46 | - Ability to save persistant settings
47 | - Fixed part audio too loud when stationary
48 | - Fixed inability to select auto position without unchecking manual position
49 | - Stopped sonic boom being played when vessel breaks sound barrier after wavefront already passed camera
50 | - Increased sonic boom volume
51 | - Temporary fix for silent atmospheric audio when >~600m/s
52 |
53 | v1.4
54 | - Atmospheric audio effects (toggleable)
55 | - Camera shake (adjustable)
56 |
57 | v1.3
58 | - 1.0+ Compatibility
59 | - Manual camera position now persists after resetting camera
60 | - Bind activate/reset key by recording instead of typing button name
61 | - Camera no longer resets when pausing
62 |
63 |
64 | v1.2
65 | - Added Orbit frame of reference
66 | - Fixed issues with setting camera offset to vertically launching vehicles
67 |
68 | v1.1
69 | - 0.25 update
70 | - Added ability to set location -before- activating camera
71 | - Fixed text fields in GUI (it won't fight you when entering negatives or decimals)
72 | - Fixed Toolbar Icon
73 | - Greatly reduced motion of stationary camera when vessel is accelerating/turning
74 |
75 |
76 | v1.0
77 | - Initial release
--------------------------------------------------------------------------------
/CameraTools/Distribution/GameData/CameraTools/License.txt:
--------------------------------------------------------------------------------
1 | This plugin for Kerbal Space Program is licensed under GPLv3.
2 | For more information, please visit this site:
3 | http://www.gnu.org/copyleft/gpl.html
--------------------------------------------------------------------------------
/CameraTools/Distribution/GameData/CameraTools/Plugins/CameraTools.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrodrigv/CameraTools/c4e739d3b1142299d06cf46fb4df4c23a2b0690c/CameraTools/Distribution/GameData/CameraTools/Plugins/CameraTools.dll
--------------------------------------------------------------------------------
/CameraTools/Distribution/GameData/CameraTools/Sounds/sonicBoom.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrodrigv/CameraTools/c4e739d3b1142299d06cf46fb4df4c23a2b0690c/CameraTools/Distribution/GameData/CameraTools/Sounds/sonicBoom.wav
--------------------------------------------------------------------------------
/CameraTools/Distribution/GameData/CameraTools/Sounds/windhowl.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrodrigv/CameraTools/c4e739d3b1142299d06cf46fb4df4c23a2b0690c/CameraTools/Distribution/GameData/CameraTools/Sounds/windhowl.wav
--------------------------------------------------------------------------------
/CameraTools/Distribution/GameData/CameraTools/Sounds/windloop.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrodrigv/CameraTools/c4e739d3b1142299d06cf46fb4df4c23a2b0690c/CameraTools/Distribution/GameData/CameraTools/Sounds/windloop.wav
--------------------------------------------------------------------------------
/CameraTools/Distribution/GameData/CameraTools/Sounds/windtear.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrodrigv/CameraTools/c4e739d3b1142299d06cf46fb4df4c23a2b0690c/CameraTools/Distribution/GameData/CameraTools/Sounds/windtear.wav
--------------------------------------------------------------------------------
/CameraTools/Distribution/GameData/CameraTools/Textures/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrodrigv/CameraTools/c4e739d3b1142299d06cf46fb4df4c23a2b0690c/CameraTools/Distribution/GameData/CameraTools/Textures/icon.png
--------------------------------------------------------------------------------
/CameraTools/Distribution/GameData/CameraTools/paths.cfg:
--------------------------------------------------------------------------------
1 | CAMERAPATHS
2 | {
3 | CAMERAPATH
4 | {
5 | pathName = New Path
6 | points = 13.40305,-16.60615,-4.274539;14.48815,-13.88801,-4.26651;14.48839,-13.88819,-4.267331;15.52922,-14.25925,-4.280066;
7 | rotations = 0.5759971,0.2491289,-0.2965982,-0.7198553;-0.6991884,0.09197949,-0.08556388,0.7038141;-0.6991884,0.09197949,-0.08556388,0.7038141;-0.6506922,0.2786613,-0.271617,0.6520521;
8 | times = 0;1;2;6;
9 | zooms = 1;2.035503;3.402367;3.402367;
10 | lerpRate = 3.1
11 | timeScale = 0.29
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/CameraTools/Distribution/GameData/CameraTools/settings.cfg:
--------------------------------------------------------------------------------
1 | CToolsSettings
2 | {
3 |
4 | }
5 |
--------------------------------------------------------------------------------
/CameraTools/LocalDev/7za_dir.txt:
--------------------------------------------------------------------------------
1 | G:\7za\x64
--------------------------------------------------------------------------------
/CameraTools/LocalDev/dist_dir.txt:
--------------------------------------------------------------------------------
1 | D:\PROGRAMACION\KSP_Development
--------------------------------------------------------------------------------
/CameraTools/LocalDev/ksp_dir.txt:
--------------------------------------------------------------------------------
1 | G:\GAMES\KERBAL\Kerbal Space Program_18_DEV
--------------------------------------------------------------------------------
/CameraTools/LocalDev/ksp_dir2.txt:
--------------------------------------------------------------------------------
1 | G:\GAMES\KERBAL\Kerbal Space Program_DEV_161M
2 |
--------------------------------------------------------------------------------
/CameraTools/LocalDev/mono_exe.txt:
--------------------------------------------------------------------------------
1 | G:\Unity\Editor\Data\MonoBleedingEdge\bin\mono.exe
--------------------------------------------------------------------------------
/CameraTools/LocalDev/pdb2mdb_exe.txt:
--------------------------------------------------------------------------------
1 | G:\pdb2mdb\pdb2mdb.exe
--------------------------------------------------------------------------------
/CameraTools/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | // General Information about an assembly is controlled through the following
5 | // set of attributes. Change these attribute values to modify the information
6 | // associated with an assembly.
7 | [assembly: AssemblyTitle( "CameraTools" )]
8 | [assembly: AssemblyDescription( "" )]
9 | [assembly: AssemblyConfiguration( "" )]
10 | [assembly: AssemblyCompany( "" )]
11 | [assembly: AssemblyProduct( "CameraTools" )]
12 | [assembly: AssemblyCopyright( "Copyright © 2019" )]
13 | [assembly: AssemblyTrademark( "" )]
14 | [assembly: AssemblyCulture( "" )]
15 |
16 | // Setting ComVisible to false makes the types in this assembly not visible
17 | // to COM components. If you need to access a type in this assembly from
18 | // COM, set the ComVisible attribute to true on that type.
19 | [assembly: ComVisible( false )]
20 |
21 | // The following GUID is for the ID of the typelib if this project is exposed to COM
22 | [assembly: Guid( "d17db18a-01d0-4990-83f7-a17aa54ab16b" )]
23 |
24 | // Version information for an assembly consists of the following four values:
25 | //
26 | // Major Version
27 | // Minor Version
28 | // Build Number
29 | // Revision
30 | //
31 | [assembly: AssemblyVersion( "1.14.0" )]
32 | [assembly: AssemblyFileVersion( "1.14.0.0" )]
33 |
--------------------------------------------------------------------------------
/CameraTools/RotationAnimation.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 | namespace CameraTools
3 | {
4 | public class RotationAnimation
5 | {
6 | Quaternion[] rotations;
7 | float[] times;
8 |
9 | public RotationAnimation (Quaternion[] rots, float[] times)
10 | {
11 | this.rotations = rots;
12 | this.times = times;
13 | }
14 |
15 | public Quaternion Evaluate(float t)
16 | {
17 | int startIndex = 0;
18 | for(int i = 0; i < times.Length; i++)
19 | {
20 | if(t >= times[i])
21 | {
22 | startIndex = i;
23 | }
24 | else
25 | {
26 | break;
27 | }
28 | }
29 |
30 | int nextIndex = Mathf.RoundToInt(Mathf.Min(startIndex + 1, times.Length - 1));
31 |
32 | float overTime = t - times[startIndex];
33 | float intervalTime = times[nextIndex] - times[startIndex];
34 | if(intervalTime <= 0) return rotations[nextIndex];
35 |
36 | float normTime = overTime/intervalTime;
37 | return Quaternion.Lerp(rotations[startIndex], rotations[nextIndex], normTime);
38 | }
39 | }
40 | }
41 |
42 |
--------------------------------------------------------------------------------
/CameraTools/Vector3Animation.cs:
--------------------------------------------------------------------------------
1 | using UnityEngine;
2 |
3 | namespace CameraTools
4 | {
5 | public class Vector3Animation
6 | {
7 | Vector3[] positions;
8 | float[] times;
9 |
10 | public Vector3Animation(Vector3[] pos, float[] times)
11 | {
12 | this.positions = pos;
13 | this.times = times;
14 | }
15 |
16 | public Vector3 Evaluate(float t)
17 | {
18 | int startIndex = 0;
19 | for(int i = 0; i < times.Length; i++)
20 | {
21 | if(t >= times[i])
22 | {
23 | startIndex = i;
24 | }
25 | else
26 | {
27 | break;
28 | }
29 | }
30 |
31 | int nextIndex = Mathf.RoundToInt(Mathf.Min(startIndex + 1, times.Length - 1));
32 |
33 | float overTime = t - times[startIndex];
34 | float intervalTime = times[nextIndex] - times[startIndex];
35 | if(intervalTime <= 0) return positions[nextIndex];
36 |
37 | float normTime = overTime/intervalTime;
38 | return Vector3.Lerp(positions[startIndex], positions[nextIndex], normTime);
39 | }
40 | }
41 | }
42 |
43 |
--------------------------------------------------------------------------------
/CameraTools/bin/Release/CameraTools.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrodrigv/CameraTools/c4e739d3b1142299d06cf46fb4df4c23a2b0690c/CameraTools/bin/Release/CameraTools.dll
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Camera Tools (forked by westamastaflash)
2 |
3 | Custom Camera angles for Cinematics!
4 |
5 | KSP Forum Thread:
6 | http://forum.kerbalspaceprogram.com/index.php?/topic/84938-105-camera-tools-v151-dogfight-mode-autozoom-margin-slider-march-28/
7 |
8 |
9 |
--------------------------------------------------------------------------------