diff --git a/README.md b/README.md index f1afd41b7..8d94889d5 100644 --- a/README.md +++ b/README.md @@ -16,10 +16,12 @@ [![][shield:support-epl]][epl:release]  [![][shield:support-ctt]][ctt:release]  [![][shield:support-tm]][techmanager:release]  +[![][shield:support-ccfg]][cconfig:release]  **Table of Contents** ------------------------------------------ -* [0. People and FAQs][0] + +* [0. People, Facts, and FAQs][0] * [a. FAQs][0a] * [1. Installation and Interoperability][1] * [a. Installation][1a] @@ -28,8 +30,8 @@ * [2. Types of Scans][2] * [a. Native SCANsat][2a] * [b. Resource Scans][2b] - * [1. Kethane][2b1] [![][shield:support-ket]][kethane:release][![][shield:jenkins-ket]][SCANsat:ket-jenkins] - * [2. Regolith][2b2] + * [c. Regolith][2c] + * [d. Kethane][2d] [![][shield:support-ket]][kethane:release][![][shield:jenkins-ket]][SCANsat:ket-jenkins] * [3. Basic Usage][3] * [a. FAQ: Finding a Good Altitude][3a] * [b. Mismatched Scanners][3b] @@ -45,9 +47,13 @@ * [a. Community Tech Tree Support][6a] * [b. Minimum Scan for Science (30%)][6b] * [c. Getting Maximum Science][6c] -* [7. Background Scanning][7] -* [8. Time Warp][8] -* [9. Note: Data Sources][9] + * [d. Contracts][6d] +* [7. Color Management][7] +* [8. Instrument Window][8] +* [9. Background Scanning][9] +* [10. Time Warp][10] +* [11. Settings Menu][11] +* [12. Note: Data Sources][12] **WARNING**: @@ -59,9 +65,10 @@ Disclaimer aside, this add-on is widely used and it **usually** works just fine. ### [:top:][top] 0. People, Facts, and FAQs ------------------------------------------ + #### Maintainers The current maintainer is: - + [technogeeky][technogeeky] \<\> + + [DMagic][DMagic] \<\> Maintainers are the people who you should complain to if there is something wrong. @@ -90,6 +97,8 @@ As of August 2014, the vast majority of code is damny's and DMagic's; and techno In addition to the authors, the following people have contributed: + (Models, Graphics, Textures) [Milkshakefiend][Milkshakefiend] + + + (Science results text) [Olympic1][Olympic1] #### Licenses @@ -97,7 +106,7 @@ For licensing information, please see the [included LICENSE.txt][SCANsat:rel-lic [Source Code][SCANsat:rel-source] is available, as some licenses may require. -### [:top:][top] a. FAQs +### [:top:][top] 0a. FAQs * What does SCANsat do? * It allows you to scan planetary bodies for terrain, biome, and resource information and generate various kinds of maps. @@ -110,9 +119,9 @@ For licensing information, please see the [included LICENSE.txt][SCANsat:rel-lic * [Career Mode] Does SCANsat give us science points? * **Yes!** For each type of map, if you scan at least 30% of the surface, you can yse Data for partial science points; up until the maximum value at 95% map coverage. * [Career Mode] Is it integrated into the tech tree? - * **Yes!** This link tells you which nodes unlock which parts in the tech tree. + * **Yes!** [**This link**][6a] tells you which nodes unlock which parts in the tech tree. * [Contracts] Does SCANsat offer contracts to complete? - * **No.** This is a planned feature. + * **Yes/No.** Contracts are currently only supported through [**third-party addons**][6d]. * Can you add to SCANsat? * **Probably!** First, check the issues page to see if it's already been requested. If not, add a new issue. Even better, attempt to add the feature yourself and submit a pull request. We'll catch the bugs for you! @@ -121,16 +130,16 @@ For licensing information, please see the [included LICENSE.txt][SCANsat:rel-lic ### [:top:][top] 1. Installation and Interoperability ------------------------------------------ -#### [:top:][top] a. Installation +#### [:top:][top] 1a. Installation 1. Download the latest [SCANsat package][SCANsat:rel-dist-github] from the releases section of this GitHub Repo 2. Extract the included package and put the SCANsat folder in your KSP installation's GameData folder. -#### [:top:][top] b. GameData Layout +#### [:top:][top] 1b. GameData Layout ![][SCANsat:gamedata] -#### [:top:][top] c. Other Add-Ons +#### [:top:][top] 1c. Other Add-Ons S.C.A.N. is proud to collaborate with other KSP mods and modding teams. Following is a table of all of the mods, add-ons, or software that we interoperate with. @@ -148,7 +157,7 @@ S.C.A.N. is proud to collaborate with other KSP mods and modding teams. Followin * [x] [**v8.0**][SCANsat:rel-thread] SCANsat Release **version: v8.0** * [x] [**v9.0**][SCANsat:dev-thread] SCANsat Dev **version: v9.0** - **MM**, **RPM**, and **Toolbar** are all **soft** dependencies. This means your experience with SCANsat will be enhanced if you are using these mods, but they are not necessary. + **MM**, **RPM**, **Toolbar**, and **Resource Addons** are all **soft** dependencies. This means your experience with SCANsat will be enhanced if you are using these mods, but they are not necessary. **SCANsat** is built against the following mods: * [x] [![][shield:support-mm]][mm:release] @@ -166,6 +175,7 @@ S.C.A.N. is proud to collaborate with other KSP mods and modding teams. Followin ### [:top:][top] 2. Types of Scans ------------------------------------------ + SCANsat supports several different kinds of scans (as opposed to scanning modules or parts). @@ -177,10 +187,10 @@ scanning modules or parts). * **Resource**: Scan for chemical or mineral resource on the surface. Other parts and add-ons are free to include one or more of these kinds of scans. In general, -we would request that similar (same order of magitude) scanning paramters and limitations are used +we would request that similar (same order of magnitude) scanning parameters and limitations are used on custom parts, but this is not a requirement. -#### [:top:][top] a. SCANsat Scans +#### [:top:][top] 2a. SCANsat Scans Without any resource scanning mods installed, **SCANsat** can scan for a few basic types of data. All of these (non-resource) scans are shown as indicators on the Small Map. @@ -190,27 +200,40 @@ Data Type | Scan Type | Scan Indicator :--- | :--- | :---: Altimetry | **RADAR** | **LO** Altimetry | **SAR** | **HI** -Biome | **Biome** | **BIO** -Anomaly | **Anomaly** | **ANOM** +Biome | **Biome** | **MULTI** +Anomaly | **Anomaly** | **MULTI** Anomaly | **Been There, Done That(tm)** | **BTDT** * The **Slope** map is generated from either **HI** or **LO** data. -* The **Biome** scan only works for bodies that have biomes. For vanilla KSP, this means Kerbin, Mun, and Minmus. -* **Anomalies** are things the builds of KSC, hidden easter eggs, lowest or highest altitudes, etc... -* The *ANOM** data scans for anomalies from orbit, while +* The **Biome** scan only works for bodies that have biomes. For vanilla KSP, this means all planets except the sun and Jool. +* **Anomalies** are things the builds of KSC, hidden easter eggs, etc... +* The **Anomaly** data scans for anomalies from orbit, while * **BTDT** shows a camera view of an anomaly once you are near it +* The **Biome** and **Anomaly** scans are combined into the multi-spectral scanner; indicated by **MULTI** + +#### [:top:][top] 2b. Resource Scans + +**SCANsat** will scan planetoids for resources, assuming you have the relevant mods installed. All support for resource scanning is handled through one of two plugins. **Regolith** supports many resources, and **Kethane** supports a few. -#### [:top:][top] b. Resource Scans +Resource scans are initiated in the same way as any other scan. In this case they must use custom scanner parts included with the resource addon. +> ![][resource-scanner] -**SCANsat** will scan planetoids for resources, assuming you have the relevant mods installed. All support for resource scanning is handled through one of two plugins. **ORS** supports many resources, and **Kethane** supports a few. +Resource scanning proceeds the same way as standard SCANsat scanning instruments do. The grey scale color option generally works best when viewing resource overlays. +> ![][resource-bigmap] Each of the two resource systems can be enabled through the **SCANsat** Big Map: > ![][resource-walkthrough-v2] -Both of the two resource systems will work in IVA, too: -> ![][resource-iva] +##### [:top:][top] 2c. Regolith +[![][shield:jenkins-orsx]][SCANsat:orsx-jenkins] + +**Regolith** support is built internal to SCANsat. If you have a **Regolith** DLL loaded anywhere SCANsat will only target the newest version. + +With any **Regolith**-using mod installed, you can select their resources in the drop down menu from the Big Map or KSC Map, and enable their overlay with the resource icon. +For instance the **Karbonite** mod's resources can be viewed: +> ![][resource-orsx-karbonite-v2] -##### [:top:][top] 1. Kethane +##### [:top:][top] 2d. Kethane [![][shield:jenkins-ket]][SCANsat:ket-jenkins] **Kethane** support is built using an included extra DLL file. @@ -220,18 +243,8 @@ This file will only be loaded if you have a Kethane installed in its usual locat Once it is installed correctly, you will be able to enable Kethane resources in the settings menu: > ![][resource-kethane] - -##### [:top:][top] 2. Regolith -[![][shield:jenkins-orsx]][SCANsat:orsx-jenkins] - -**Regolith** support is built internal to SCANsat. If you have a **Regolith** DLL loaded anywhere SCANsat will only target the newest version. - -With any **Regolith**-using mod installed, you can select their resources in the drop down menu from the Big Map or KSC Map, and enable their overlay with the resource icon: -> ![][resource-orsx-v2] - -For instance the **Karbonite** mod's resources can be viewed: -> ![][resource-orsx-karbonite-v2] - +Both of the two resource systems will work in IVA, too: +> ![][resource-iva] ### [:top:][top] 3. Basic Usage ------------------------------------------ @@ -242,20 +255,20 @@ You can start scanning by selecting a SCANsat part's context menu, enabling the #### [:top:][top] 3a. FAQ: Finding a Good Altitude -Watch the data indicators on the small map to determine how well your scanners are performing. +Watch the data indicators on the small map to determine how well your scanners are performing. The right-click context menus also contain indicators for the proper scanning altitude. ###### too high Solid ORANGE means you're too high (and therefore no data is being recorded): -![][small-toohigh] +![][small-toohigh-v10] ###### too low Flashing ORANGE/GREEN means you're too low (and therefore you have a FOV penalty): -![][small-toolow] +![][small-toolow-v10] ###### just right Solid GREEN means you're in an ideal orbit. Notice the larger swath width on the right: -![][small-justright] +![][small-justright-v10] #### [:top:][top] 3b. Mismatched Scanners @@ -271,6 +284,8 @@ SAR (HI) has thin swaths due to low alt. | Multi and RADAR have similar ideal sw The mapping interface consists of a small-ish map of the planet, as far as it has been scanned in your current game. It scans and updates quickly and shows positions of the active vessel, as well as other scanning vessels in orbit around the same planet. Orbital information is also provided. For a slower but more detailed view, see the **[big map][4]**. +Note that the indicators flash blue when the gray-scale color option is selected on the big map. + Be sure to remember to pack enough batteries, radioisotope generators, and solar panels. If you forget, you'll run out of electricity, you'll stop recording data, and you'll see useless static: ###### Static! Oh no, adjust the rabbit ears! @@ -278,6 +293,7 @@ Be sure to remember to pack enough batteries, radioisotope generators, and solar ### [:top:][top] 4. Big Map ------------------------------------------ + ![A Big Big Map][bigmap-anim-v2] A bigger map can be rendered on demand. Rendered maps are automatically @@ -318,15 +334,15 @@ The re-size icon in the lower-right corner can be dragged to re-size the map. | [Been There Done That®][5d] | **Anomaly** | 1 | 0 m | 0 m | 2 km | [MapTraq® (deprecated)][5e] | **None** | N/A | N/A | N/A | N/A -#### [:top:][top] a. The RADAR Altimetry Sensor +#### [:top:][top] 5a. The RADAR Altimetry Sensor ![RADAR][vab-radar] -#### [:top:][top] b. The SAR Altimetry Sensor +#### [:top:][top] 5b. The SAR Altimetry Sensor ![SAR][vab-sar] -#### [:top:][top] c. The Multispectral Sensor +#### [:top:][top] 5c. The Multispectral Sensor ![Multi][vab-multi] -#### [:top:][top] d. Been There Done That +#### [:top:][top] 5d. Been There Done That ![BTDT][vab-btdt] -#### [:top:][top] e. MapTraq (deprecated) +#### [:top:][top] 5e. MapTraq (deprecated) ![MapTraq][vab-maptraq] @@ -364,7 +380,55 @@ the upper cutoff is 95% in case you didn't scan the whole map. ![Scan 95% to get all science][science-max] -### [:top:][top] 7. Background Scanning +##### [:top:][top] 6d. Contract Support +Career mode contracts are supported through third party addons. + +* [Contract Configurator Forum Thread][cconfig:release] +* [SCANsat Contract Pack][ccfgSCANsat:release] + +### [:top:][top] 7. Color Management +------------------------------------------ + +![][color-window] + +SCANsat provides multiple options for map color configurations and terrain level changes. + +The color management window can be accessed from the big or small map with the color palette icon, or from the toolbar menu. + +On the left are the various color palettes available; there are four different styles that can be selected from the drop down menu. +Palettes can be customized by changing the number of colors in the palette, reversing the order, or making the palette use discrete +color transitions, rather than the smooth gradient used by default. + +Changes to the color palette are reflected after selecting **Apply**, the big and small maps will automatically refresh using the newly selected color palette. +Note that only the altimetry map is affected by color palette selection. +![][color-palette-switch] + +There are several terrain height options available as well. +* The **Min** and **Max** height sliders can be used to set the lower and upper cutoff values for the terrain height-to-color algorithm. +* The **Clamp** option can be used to set a cutoff below which only the first two colors in the selected +palette will be used for the terrain height-to-color algorithm. This is especially useful on planets where there is an ocean, as it makes the transition +from ocean to solid terrain more pronounced. +![][color-clamp-terrain] + +All stock KSP planets have default color palette and terrain height values appropriate for the planet's terrain. Standard default values are used +for any addon planets. + +### [:top:][top] 8. Instrument Window +------------------------------------------ + +![][instruments-small] + +The instruments window provides a readout of several types of data based on current scanning coverage. + +* **Biome** Shows the biome that the current vessel is in or over +* **Altitude** Shows the vessel's current altitude above the terrain +* **Slope** Shows a highly localized slope based on a 3X3 grid centered 5m around the vessel +* **Anomaly** Shows the nearest anomaly and its distance from the vessel +* **BTDT Anomaly** Shows detailed information and a crude image about the nearest anomaly; scroll the mouse wheel when positioned over the anomaly window to switch between different structures if more than one is found + +![][instruments-btdt] + +### [:top:][top] 9. Background Scanning ------------------------------------------ ![Note the background scanning (non-active vessels are scanning)][small-scan] @@ -373,8 +437,9 @@ Unlike some other KSP scanning systems, SCANsat allows scanning with multiple vessels. All online scanners scan at the same time during any scene where time progresses; no active SCANsat parts are necessary. -### [:top:][top] 8. Time Warp +### [:top:][top] 10. Time Warp ------------------------------------------ + SCANsat does not interpolate satellite paths during time warp; nevertheless, due to the relatively large field of view of each sensor, it's still possible to acquire data faster by time warping. The maximum recommended time warp speed is currently **10,000x**. Scanning at this warp factor should allow identical scanning performance @@ -389,8 +454,22 @@ It starts at **1000x** and then speeds up to **10,000x**: Notice that the only gaps in coverage are those at the poles (ie, the selected inclination was not high enough to capture the poles). -### [:top:][top] 9. Note Concerning Data Sources +### [:top:][top] 11. Settings Menu +------------------------------------------ + +![][settings-window] + +The settings menu has a various general options +* The marker used for anomalies can be specified +* Background scanning can be controlled for each planet +* Background scanning resolution can be lowered for better performance (watch for short pauses when several scanners are active at very high timewarp; reducing the scanning resolution can help with this) +* Toggles control the availability of the stock app launcher button and the tooltips for various icons on other windows +* If the windows are ever dragged off screen there is an option to reset all windows to their default positions +* Data can be deleted for any or all planets; a confirmation box will appear when these options are selected + +### [:top:][top] 12. Note Concerning Data Sources ------------------------------------------ + All data this mod shows you is pulled from your game as you play. This includes: * terrain elevation @@ -412,6 +491,7 @@ sneaky then they can of course be sneaky. [DMagic]: http://forum.kerbalspaceprogram.com/members/59127-DMagic [damny]: http://forum.kerbalspaceprogram.com/members/80692-damny [Milkshakefiend]: http://forum.kerbalspaceprogram.com/members/72507-Milkshakefiend +[Olympic1]: http://forum.kerbalspaceprogram.com/members/81815 [KSP:developers]: https://kerbalspaceprogram.com/index.php [KSP:reddit]: http://www.reddit.com/r/KerbalSpaceProgram @@ -444,6 +524,9 @@ sneaky then they can of course be sneaky. [small-mismatch1]: https://i.imgur.com/fNztoUN.gif [small-mismatch2]: https://i.imgur.com/aQtTGvV.gif [small-newMap1]: http://i.imgur.com/mCnphuZ.gif +[small-toolow-v10]: http://i.imgur.com/USsvSSs.gif +[small-toohigh-v10]: http://i.imgur.com/i7rGDIj.gif +[small-justright-v10]: http://i.imgur.com/y7mHvEF.gif [bigmap-scan-10000x]: http://i.imgur.com/VEPL3oN.gif [bigmap-scan-100x]: http://i.imgur.com/bcht47p.gif @@ -456,40 +539,55 @@ sneaky then they can of course be sneaky. [resource-orsx-karbonite]: http://i.imgur.com/Sge2OGH.png?1 [resource-iva]: http://i.imgur.com/iRo4kSA.png [resource-walkthrough]: http://i.imgur.com/HJLK1yi.gif -[resource-walkthrough-v2]: http://i.imgur.com/80ximDP.gif +[resource-walkthrough-v2]: http://i.imgur.com/gU9E8PM.gif [resource-orsx-v2]: http://i.imgur.com/ERSFwCX.png [resource-orsx-karbonite-v2]: http://i.imgur.com/qVlHzSN.png +[resource-scanner]: http://i.imgur.com/7Q7a7aD.gif +[resource-bigmap]: http://i.imgur.com/aFu2U3F.gif + +[color-window]: http://i.imgur.com/XM2ynyZ.png +[color-palette-switch]: http://i.imgur.com/0XdMGSy.gif +[color-clamp-terrain]: http://i.imgur.com/8dgFLGj.gif + +[instruments-small]: http://i.imgur.com/DwkwCI5.gif +[instruments-btdt]: http://i.imgur.com/tybbDap.gif + +[settings-window]: http://i.imgur.com/ogQbeso.png [top]: #table-of-contents -[0]: #top-0-people-and-faqs -[0a]: #top-b-faqs +[0]: #top-0-people-facts-and-faqs +[0a]: #top-0a-faqs [1]: #top-1-installation-and-interoperability -[1a]: #top-a-installation -[1b]: #top-b-gamedata-layout -[1c]: #top-c-other-add-ons +[1a]: #top-1a-installation +[1b]: #top-1b-gamedata-layout +[1c]: #top-1c-other-add-ons [2]: #top-2-types-of-scans -[2a]: #top-a-scansat-scans -[2b]: #top-d-resource-scans -[2b1]: #top-1-kethane -[2b2]: #top-2-regolith +[2a]: #top-2a-scansat-scans +[2b]: #top-2b-resource-scans +[2c]: #top-2c-regolith +[2d]: #top-2d-kethane [3]: #top-3-basic-usage [3a]: #top-3a-faq-finding-a-good-altitude [3b]: #top-3b-mismatched-scanners [4]: #top-4-big-map [4a]: #top-4a-big-map-options [5]: #top-5-parts-and-sensor-types -[5a]: #top-a-the-radar-altimetry-sensor -[5b]: #top-b-the-sar-altimetry-sensor -[5c]: #top-c-the-multispectral-sensor -[5d]: #top-d-been-there-done-that -[5e]: #top-e-maptraq-deprecated +[5a]: #top-5a-the-radar-altimetry-sensor +[5b]: #top-5b-the-sar-altimetry-sensor +[5c]: #top-5c-the-multispectral-sensor +[5d]: #top-5d-been-there-done-that +[5e]: #top-5e-maptraq-deprecated [6]: #top-6-career-mode-research-and-development [6a]: #top-6a-community-tech-tree-support -[6b]: #top-6a-minimum-scan-for-science +[6b]: #top-6b-minimum-scan-for-science [6c]: #top-6c-getting-maximum-science -[7]: #top-7-background-scanning -[8]: #top-8-time-warp -[9]: #top-9-note-concerning-data-sources +[6d]: #top-6d-contract-support +[7]: #top-7-color-management +[8]: #top-8-instrument-window +[9]: #top-9-background-scanning +[10]: #top-10-time-warp +[11]: #top-11-settings-menu +[12]: #top-12-note-concerning-data-sources [shield:license-bsd]: http://img.shields.io/:license-bsd-blue.svg [shield:license-mit]: http://img.shields.io/:license-mit-a31f34.svg @@ -503,16 +601,17 @@ sneaky then they can of course be sneaky. [shield:support-rpm]: http://img.shields.io/badge/works%20with%20RPM-v0.18.3-a31f34.svg [shield:support-ket]: http://img.shields.io/badge/works%20with%20Kethane-v0.9.2-brightgreen.svg [shield:support-orsx]: http://img.shields.io/badge/works%20with%20ORSX-v0.1.2-000000.svg -[shield:support-mm]: http://img.shields.io/badge/works%20with%20MM-v2.5.5-40b7c0.svg +[shield:support-mm]: http://img.shields.io/badge/works%20with%20MM-v2.5.9-40b7c0.svg [shield:support-toolbar]: http://img.shields.io/badge/works%20with%20Blizzy's%20Toolbar-1.7.8-7c69c0.svg [shield:support-alcor]: http://img.shields.io/badge/works%20with%20ALCOR-0.9-299bc7.svg [shield:support-kspi]: http://img.shields.io/badge/works%20with%20Interstellar-0.13-a62374.svg -[shield:support-usi]:http://img.shields.io/badge/works%20with%20USI-0.22.1-34c566.svg -[shield:support-karbonite]: http://img.shields.io/badge/works%20with%20Karbonite-0.5-ff8c00.svg +[shield:support-usi]:http://img.shields.io/badge/works%20with%20USI-0.22.3-34c566.svg +[shield:support-karbonite]: http://img.shields.io/badge/works%20with%20Karbonite-0.5.1-ff8c00.svg [shield:support-epl]: http://img.shields.io/badge/works%20with%20EPL-4.2.3-ff8c00.svg [shield:support-ctt]: http://img.shields.io/badge/works%20with%20CTT-1.1-blue.svg [shield:support-tm]: http://img.shields.io/badge/works%20with%20TechManager-1.5-lightgrey.svg [shield:support-reg]: https://img.shields.io/badge/works%20with%20Regolith-1.1-000000.svg +[shield:support-ccfg]: https://img.shields.io/badge/works%20with%20Contract%20Configurator-6.0-yellowgreen.svg [shield:gittip-tg-img]: http://img.shields.io/gittip/technogeeky.png [shield:gittip-tg]: https://www.gittip.com/technogeeky/ @@ -602,3 +701,7 @@ sneaky then they can of course be sneaky. [rpm:release]: http://forum.kerbalspaceprogram.com/threads/57603 [reg:release]: http://forum.kerbalspaceprogram.com/threads/100162 + +[cconfig:release]: http://forum.kerbalspaceprogram.com/threads/101604 + +[ccfgSCANsat:release]: http://forum.kerbalspaceprogram.com/threads/108097 diff --git a/SCANassets/Icons/SCANsat_AppLauncherLarge_Icon.png b/SCANassets/Icons/SCANsat_AppLauncherLarge_Icon.png new file mode 100644 index 000000000..3073cc7f4 Binary files /dev/null and b/SCANassets/Icons/SCANsat_AppLauncherLarge_Icon.png differ diff --git a/SCANassets/Icons/SCANsat_AppLauncherSmall_Icon.png b/SCANassets/Icons/SCANsat_AppLauncherSmall_Icon.png new file mode 100644 index 000000000..6d33ba973 Binary files /dev/null and b/SCANassets/Icons/SCANsat_AppLauncherSmall_Icon.png differ diff --git a/SCANassets/Resources/SCANresource.cfg b/SCANassets/Resources/SCANresource.cfg index c7fadcb2f..212ae0eee 100644 --- a/SCANassets/Resources/SCANresource.cfg +++ b/SCANassets/Resources/SCANresource.cfg @@ -23,7 +23,7 @@ SCANSAT_SENSOR } SCANSAT_SENSOR { - name = Uranium + name = Uraninite SCANtype = 1024 //2^10 ColorEmpty = 0.9372549, 0.827451, 0.9058823 ColorFull = 0.6117647, 0.1098039, 0.4196078 diff --git a/SCANassets/Resources/ScienceDefs.cfg b/SCANassets/Resources/ScienceDefs.cfg index cc9fd4262..c33c18ee0 100644 --- a/SCANassets/Resources/ScienceDefs.cfg +++ b/SCANassets/Resources/ScienceDefs.cfg @@ -5,12 +5,32 @@ EXPERIMENT_DEFINITION baseValue = 20 scienceCap = 20 dataScale = 2 + requireAtmosphere = False situationMask = 0 biomeMask = 0 + RESULTS { default = Analyzed low resolution altimetry data. + default = "RADAR Altimetry Sensor is reporting in. I don't know how, but we have a strong signal and are getting data. This calls for a celebratory round of snacks!" + Sun = You wonder if the sensor is malfunctioning. + Moho = Well, at least this low resolution data makes Moho look kind of cool. Not quite giant lakes of lava, but still cool. + Eve = You contemplate the grainy, rough altitude estimates returned by the scanner and wish that you had sent the high resolution scanner instead. Oh well, it's a great reason to launch more rockets! (As if we really needed a reason anyway) + Gilly = Your low resolution scanning confirms what you already knew: Gilly is just a lumpy rock floating in space. At least you don't have to strain your eyes looking at the report. + Kerbin = Even this low resolution data of the planets surface is amazingly useful. You can't wait to deploy this technology on the Mun or beyond. + Mun = The data shows broad, sweeping strokes of the landscape below. A high resolution scan would be more helpful, but you can probably find a suitable landing site using this data. + Minmus = You grudgingly acknowledge that the guys over at the Kerbal Astronomical Society were right: Minmus really is a moon. You wouldn't have believed it if you hadn't seen the altimetry scan with your own eyes. + Duna = This low resolution data is a bit grainy and distorted, but it will still be invaluable in searching for a proper landing site on Duna. Suddenly a long-term Duna mission just became a real prospect. + Ike = As you pore over the data you are struck by how similar Ike appears to the Mun. You wonder about their comparative surface geology. + Dres = Even with the low resolution scanner it is quite apparent that Dres has some prominent mountains. You can't wait for the resource scan results because you're sure "there's gold in them their hills". + Jool = Altimetry, what altimetry? It's a gas giant for Kerbal's sake. Let's just pick a number at random and call it good. + Laythe = The sensor seems unable to penetrate the water. + Vall = Well, here it is: "The data you Vall been waiting for! Hahahahaha! Hahaha. Ha. Ha? What, SOMEONE has to find that funny." + Tylo = You're still not sure what the view from the surface with Laythe, Vall, and Jool overhead would be like, but this data will sure help you find a landing site so that you can find out. + Bop = Well, the low resolution altimetry data is in, and you decide to package it up and send it back to KSC. You just hope that there is enough juice left in the batteries to get it all sent and keep basic systems running at the same time. + Pol = The low resolution scan confirms that Pol does indeed look like a giant pollen grain. Until you upgrade to a high resolution scan, and advance the field of electron microscopy, you will still be left with the question of how strong this resemblance truly is. + Eeloo = The scientists back on Kerbin have been waiting for this data for a long time. No doubt there will be celebrations and snacks for all when it gets there. } } EXPERIMENT_DEFINITION @@ -20,12 +40,32 @@ EXPERIMENT_DEFINITION baseValue = 20 scienceCap = 20 dataScale = 3 + requireAtmosphere = False situationMask = 0 biomeMask = 0 + RESULTS { default = Analyzed high resolution altimetry data. + default = "The High Resolution Altimetry Scan definitely is better then the low resolution one. SCAN has once again proven their scanning skills." + Sun = You realize that you could have saved some money if you had trusted the low resolution sensor in the first place. + Moho = Finally, the awesomeness has returned to Moho! It may not be giant flowing rivers of lava, but this data is spectacular! + Eve = The high resolution sensor cut through the hazy purple atmosphere well, and you are able to distinguish minute details on the surface. The scientists back at KSC will be relieved. + Gilly = Even in super-high resolution Gilly somehow seems to be in low resolution. That is one seriously lumpy surface. + Kerbin = You become mesmerised by all the colors in the data that the new high resolution technology provides. Suddenly Mission Control awakes you from your stupor, and you quickly wipe the drool from the corner of your mouth. + Mun = "Hah! No more boring grey moon. Just look at all the colors in that scan! Now we can really pinpoint a prime landing site." + Minmus = Wow, not only is Minmus real, it has some amazing topography! You can't wait to land in one of those flat areas. + Duna = This high resolution data is amazing. You begin analyzing the hills and valleys, searching for the perfect landing spot. + Ike = The data confirms the presence of large sloping hills and craters. Hopefully the analysts back at KSC can use this to find a suitable landing place. + Dres = Those... are some serious mountains. You are glad to be analysing this data, rather than trying to climb up some of those hills. + Jool = Even in high resolution there does not appear to be a surface on Jool. So much for that theory. At least we still have the grant money! + Laythe = The map shows mostly negative heights. You consider draining Laythe just so you can climb its mountains. + Vall = The data from the high resolution scanner confirms that the surface of Vall is, indeed, "crinkly". Guess Gene owes you fifty funds. + Tylo = Tylo may have been the first of Jool's moons to be discovered, but this data makes it feel like you are discovering the moon for the first time. + Bop = Wow, look at all those colors. You have no idea what all that data means, but you're sure that this high resolution data will impress everyone back at KSC. + Pol = Even with this amount of high-quality data it is still difficult to find a suitable landing site. How the heck was this moon made, anyway? + Eeloo = The cracks and fissures on the surface stand out in striking detail as you examine the data from the SAR Altimetry Sensor. Just look at all those potential landing sites. } } EXPERIMENT_DEFINITION @@ -35,11 +75,33 @@ EXPERIMENT_DEFINITION baseValue = 20 scienceCap = 20 dataScale = 4 + requireAtmosphere = False situationMask = 0 biomeMask = 0 + RESULTS { default = Analyzed multispectral sensor data. + default = "Wow, how are we even receiving this data right now? Those SCAN engineers really know what they are doing. Either that or they have not the slightest idea what they are doing. Either way, it's time for some snacks!" + Sun = You are surprised by the lack of biometric data. + Sun = you wonder why there are no poles visible on the biome map. + Moho = As you pore through the data you wonder if you will find the elusive lava lake biome that so many scientists had speculated about. + Eve = The intricately swirled lines of Eve's biome map remind you of lava lamps and tie dyed shirts. Man those were the days. Next spacecraft to Eve will have a mandatory disco ball! + Gilly = Even with all that squinting those astronomers couldn't see the biomes here. Hah! Dumb astronomers! That's 1 point for science and 0 points for uhhhh... science. + Kerbin = This biome data is truly astounding. You just hope that it is crumb-resistant, as you remember eating a particularly messy box of snacks the day that the sensor was installed. + Mun = Huh, never knew the moon had biomes. Wonder which one the cheese is in. And if there are any other snacks there as well. + Minmus = You contemplate how fitting the name "Greater Flats" is as you pore over the data. Whoever thinks up these names is one smart Kerbal, unlike the engineers we have around here. + Duna = You comb through the biome data looking for just the right spot to gather all that sweet, sweet science data from. Mmmmm, science... and snacks. + Ike = As you pore over the data coming back from Ike you are surprised at the biome diversity. After all it's just a moon. You can't wait to get your hands on some of the scientific data locked up down there. + Dres = Poles, check. Highlands, check. Midlands, check. Lowlands, check. Ridges, check. Impact Ejecta, check. Impact Craters, check. Canyons, check. I think we got it all. Time to shut down the scanner and have some snacks! + Jool = You are surprised by the lack of biometric data. + Jool = you wonder why there are no poles visible on the biome map. + Laythe = You want to throw a party every time the sensor detects a land biome. + Vall = Pretty straightforward data: Poles, Highlands, Midlands, and Lowlands. That's a wrap. Now let's have some snacks! + Tylo = You are struck by the diversity of the biomes in the report. Not only is Tylo cool to look up from, it's cool to look down at too. + Bop = This detailed analysis of Bop's biomes will advance our understanding of the little moon beyond anything we could have hoped. It's been a great day. Snacks all around! + Pol = As you take in the biome data coming from Pol you begin to contemplate the possibility that pollen grains have biomes too. Then you quickly squash the thought, knowing what the activists would be like if they got a hold of that idea. + Eeloo = It is astounding to have such detailed biome data on a planet so far from Kerbin. You gaze in awe at the report as the data comes in. } -} +} \ No newline at end of file diff --git a/SCANassets/SCANsat.version b/SCANassets/SCANsat.version index 390567a48..89848bac7 100644 --- a/SCANassets/SCANsat.version +++ b/SCANassets/SCANsat.version @@ -1,6 +1,6 @@ { "NAME":"SCANsat", - "URL":"https://github.com/S-C-A-N/SCANsat/blob/dev/SCANassets/SCANsat.version", + "URL":"https://raw.githubusercontent.com/S-C-A-N/SCANsat/dev/SCANassets/SCANsat.version", "DOWNLOAD":"https://github.com/S-C-A-N/SCANsat/releases", "GITHUB":{ "USERNAME":"S-C-A-N", @@ -11,7 +11,7 @@ "MAJOR":1, "MINOR":0, "PATCH":9, - "BUILD":41 + "BUILD":5 }, "KSP_VERSION":{ "MAJOR":0, diff --git a/SCANsat/CHANGELOG.txt b/SCANsat/CHANGELOG.txt index 3b3869a7e..ea5f7df9e 100644 --- a/SCANsat/CHANGELOG.txt +++ b/SCANsat/CHANGELOG.txt @@ -1,3 +1,33 @@ +Version 9.5 - 2015-1-23 +------------------------ + +- Significant internal code changes; any addons with hard-depencies on SCANsat will likely need updating + - Public read-only properties added for most fields + +- Stock app launcher support added + - A single toolbar button opens/closes the small map + - Can be disabled through the settings menu + - When Blizzy's toolbar and the stock toolbar are disabled the small map can be opened by starting a scan with any SCANsat instrument + +- Improvements to big map terrain data caching + - Reduces memory used by the big map by 40% + - A single cache used for each map projection type + - Improves big map generation speed when switching projection types + +- Big map grid texture replaced by line rendering method + - Further reduces big map memory usage + +- Localized slope indicator added to the instrument window + - Slope calculated based on a 3X3 grid centered 5m around the vessel's location + - Altitude indicator displays the correct height above the terrain while under timewarp + +- Exported maps saved to GameData/SCANsat/PluginData folder + +- New science results text added + - Thanks Olympic1 + +- Uranium resource type changed to Uraninite + Version 9.4.1 - 2014-12-22 ------------------------ diff --git a/SCANsat/LICENSE.txt b/SCANsat/LICENSE.txt index ae19f6dbf..9657b7ac8 100644 --- a/SCANsat/LICENSE.txt +++ b/SCANsat/LICENSE.txt @@ -40,6 +40,18 @@ Milkshakefiend has given permission that these models and textures may be distributed with SCANsat, including derived works, as long as credit is given. +LICENSING INFORMATION FOR SCIENCE TEXT +--------------------------------------------- + +Science results text were created by Olympic1: +https://github.com/S-C-A-N/SCANsat/pull/110#issuecomment-71082065 + +All Rights Reserved - Olympic1 / Arne Peirs + +Olympic1 has given permission that these results texts may be distributed +with SCANsant, including derived works, as long as credit is given. + + LICENSING INFORMATION FOR LOGO --------------------------------------------- diff --git a/SCANsat/Platform/ConfigNodeStorage.cs b/SCANsat/Platform/ConfigNodeStorage.cs deleted file mode 100644 index bcdc24ca6..000000000 --- a/SCANsat/Platform/ConfigNodeStorage.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using Log = KSPPP.Logging.ConsoleLogger; - - -namespace KSPPP { - public abstract class ConfigNodeStorage : IPersistenceLoad, IPersistenceSave { - - Func timeNow = () => string.Format("{0:ddMMyyyy-HHmmss}", DateTime.Now); - - public ConfigNodeStorage() { } // FIXME: should be private? - public ConfigNodeStorage(string filePath) { FilePath = filePath; } // FIXME: should be private? - - private string _FilePath; - public string FilePath { - get { return _FilePath; } - set { _FilePath = System.IO.Path.Combine(_AssemblyFolder, value).Replace("\\","/"); } - } - public string FileName { get { return System.IO.Path.GetFileName(FilePath); } } - public bool FileExists { get { return System.IO.File.Exists(FilePath); } } - - void IPersistenceLoad.PersistenceLoad() { OnDecodeFromConfigNode(); } - void IPersistenceSave.PersistenceSave() { OnEncodeToConfigNode(); } - - public virtual void OnDecodeFromConfigNode() { } - public virtual void OnEncodeToConfigNode() { } - - public bool Load() { return Load(FilePath); } - public bool Load(string fileFullName) { - try { - Log.Debug("Loading ConfigNode"); - if (FileExists) { - ConfigNode cnToLoad = ConfigNode.Load(fileFullName); - ConfigNode cnUnwrapped = cnToLoad.GetNode(GetType().Name); - ConfigNode.LoadObjectFromConfig(this, cnUnwrapped); - return true; - } else { - Log.Now("File could not be found to load({0})", fileFullName); - return false; - } - } catch (Exception ex) { - Log.Now("Failed to Load ConfigNode from file ({0}) - Error:{1}", fileFullName, ex.Message); - Log.Now("Storing old config - {0}", fileFullName + ".err-" + timeNow); - System.IO.File.Copy(fileFullName, fileFullName + ".err-" + timeNow,true); - return false; - } - } - - public bool Save() { - Log.Debug("Saving ConfigNode"); - return Save(FilePath); - } - public bool Save(string fileFullName) { - try { - ConfigNode cnToSave = AsConfigNode; - ConfigNode cnSaveWrapper = new ConfigNode(GetType().Name); - cnSaveWrapper.AddNode(cnToSave); - cnSaveWrapper.Save(fileFullName); - return true; - } catch (Exception ex) { - Log.Now("Failed to Save ConfigNode to file({0})-Error:{1}", fileFullName, ex.Message); - return false; - } - } - - public ConfigNode AsConfigNode { - get { - try { - ConfigNode cnTemp = new ConfigNode(GetType().Name); - cnTemp = ConfigNode.CreateConfigFromObject(this, cnTemp); - return cnTemp; - } catch (Exception ex) { - Log.Now("Failed to generate ConfigNode-Error;{0}", ex.Message); - return new ConfigNode(GetType ().Name); - } - } - } - - internal static string _AssemblyName { get { return System.Reflection.Assembly.GetExecutingAssembly().GetName().Name; } } - internal static string _AssemblyLocation { get { return System.Reflection.Assembly.GetExecutingAssembly().Location; } } - internal static string _AssemblyFolder { get { return System.IO.Path.GetDirectoryName(_AssemblyLocation); } } - } -} diff --git a/SCANsat/Platform/KSPAddonImproved.cs b/SCANsat/Platform/KSPAddonImproved.cs deleted file mode 100644 index aad1c454b..000000000 --- a/SCANsat/Platform/KSPAddonImproved.cs +++ /dev/null @@ -1,229 +0,0 @@ -/* KSPAddonImproved by xEvilReeperx - * - * - Allows definition of multiple startup scenes - * - * http://forum.kerbalspaceprogram.com/threads/79889-Expanded-KSPAddon-modes?p=1157014&viewfull=1#post1157014 - * - * Provided in the Public Domain - * - */ - -using System; -using UnityEngine; -using System.Linq; -using System.Collections.Generic; - -namespace SCANsat.Platform -{ - - [AttributeUsage(AttributeTargets.Class)] - internal class SCAN_KSPAddonImproved : Attribute - { - [Flags] - public enum Startup - { - // KSPAddon.Startup values: - /* Instantly = -2, - EveryScene, - EditorAny = -3, - MainMenu = 2, - Settings, - SpaceCentre = 5, - Credits = 4, - EditorVAB = 6, - EditorSPH = 9, - Flight = 7, - TrackingStation, - PSystemSpawn = 10 - */ - - None = 0, - MainMenu = 1 << 0, - Settings = 1 << 1, - SpaceCenter = 1 << 2, - Credits = 1 << 3, - EditorVAB = 1 << 4, - EditorSPH = 1 << 5, - Flight = 1 << 6, - TrackingStation = 1 << 7, - PSystemSpawn = 1 << 8, - Instantly = 1 << 9, - - EditorAny = EditorVAB | EditorSPH, - TimeElapses = Flight | TrackingStation | SpaceCenter, - RealTime = TimeElapses, - EveryScene = ~0 - } - - public bool runOnce; - public Startup scenes; - - public SCAN_KSPAddonImproved(Startup mask, bool once = false) - { - runOnce = once; - scenes = mask; - } - } - - [KSPAddon(KSPAddon.Startup.Instantly, true)] - internal class CustomAddonLoader : MonoBehaviour - { - // What's improved? The KSPAddon.Startup is now a bitmask so you can - // use logical operations to specify which scenes you want your addon - // to be loaded in - - - // master list to keep track of addons in our assembly - List addons = new List(); - private string _identifier; - - // Mainly required so we can flag addons when they've - // been created in the case of runOnce = true - class AddonInfo - { - public readonly Type type; - public readonly SCAN_KSPAddonImproved addon; - public bool created; - - internal AddonInfo(Type t, SCAN_KSPAddonImproved add) - { - type = t; - created = false; - - addon = add; - } - - internal bool RunOnce - { - get - { - return addon.runOnce; - } - } - - internal SCAN_KSPAddonImproved.Startup Scenes - { - get - { - return addon.scenes; - } - } - } - - - - void Awake() - { - DontDestroyOnLoad(this); - - // multiple plugins using this source will create their own instances - // of the loader; the log can get confusing pretty fast without some - // way of telling them apart - _identifier = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name + "." + GetType().ToString(); - - // examine our assembly for loaded types - foreach (var ourType in System.Reflection.Assembly.GetExecutingAssembly().GetTypes()) - { - var attr = ((SCAN_KSPAddonImproved[])ourType.GetCustomAttributes(typeof(SCAN_KSPAddonImproved), true)).SingleOrDefault(); - if (attr != null) - { - Debug.Log(string.Format("Found KSPAddonImproved in {0}", ourType.FullName)); - addons.Add(new AddonInfo(ourType, attr)); - } - } - - // special case here: since we're already in the first scene, - // OnLevelWasLoaded won't be invoked so we need to fire off any - // "instant" loading addons now - OnLevelWasLoaded((int)GameScenes.LOADING); - } - - - - void OnLevelWasLoaded(int level) - { - GameScenes scene = (GameScenes)level; - SCAN_KSPAddonImproved.Startup mask = 0; - - if (scene == GameScenes.LOADINGBUFFER) - return; - - Debug.Log(string.Format("{1}: {0} was loaded; instantiating addons...", scene.ToString(), _identifier)); - - // Convert GameScenes => SceneMask - switch (scene) - { - case GameScenes.EDITOR: - mask = SCAN_KSPAddonImproved.Startup.EditorVAB; - break; - - case GameScenes.SPH: - mask = SCAN_KSPAddonImproved.Startup.EditorSPH; - break; - - case GameScenes.CREDITS: - mask = SCAN_KSPAddonImproved.Startup.Credits; - break; - - case GameScenes.FLIGHT: - mask = SCAN_KSPAddonImproved.Startup.Flight; - break; - - case GameScenes.LOADING: - mask = SCAN_KSPAddonImproved.Startup.Instantly; - break; - - case GameScenes.MAINMENU: - mask = SCAN_KSPAddonImproved.Startup.MainMenu; - break; - - case GameScenes.SETTINGS: - mask = SCAN_KSPAddonImproved.Startup.Settings; - break; - - case GameScenes.SPACECENTER: - mask = SCAN_KSPAddonImproved.Startup.SpaceCenter; - break; - - case GameScenes.TRACKSTATION: - mask = SCAN_KSPAddonImproved.Startup.TrackingStation; - break; - - case GameScenes.PSYSTEM: - mask = SCAN_KSPAddonImproved.Startup.PSystemSpawn; - break; - - case GameScenes.LOADINGBUFFER: - // intentionally left unset - break; - - default: - Debug.LogError(string.Format("{1} unrecognized scene: {0}", scene.ToString(), _identifier)); - break; - } - - int counter = 0; - - for (int i = 0; i < addons.Count; ++i) - { - var addon = addons[i]; - - if (addon.created && addon.RunOnce) - continue; // this addon was already loaded - - // should this addon be initialized in current scene? - if ((addon.Scenes & mask) != 0) - { - Debug.Log(string.Format("ImprovedAddonLoader: Creating addon '{0}'", addon.type.Name)); - GameObject go = new GameObject(addon.type.Name); - go.AddComponent(addon.type); - - addon.created = true; - ++counter; - } - } - - Debug.Log(string.Format("{1} finished; created {0} addons", counter, _identifier)); - } - } -} \ No newline at end of file diff --git a/SCANsat/Properties/AssemblyInfo.cs b/SCANsat/Properties/AssemblyInfo.cs index 82c146c43..c3fae26cc 100644 --- a/SCANsat/Properties/AssemblyInfo.cs +++ b/SCANsat/Properties/AssemblyInfo.cs @@ -16,8 +16,8 @@ // and "{Major}.{Minor}.{Build}.*" will update just the revision. [assembly: AssemblyVersion ("1.0.8.0")] [assembly: AssemblyFileVersion ("1.0.9.0")] -[assembly: AssemblyInformationalVersion ("v9rc4.1")] +[assembly: AssemblyInformationalVersion ("v9rc5")] -[assembly: KSPAssembly ("SCANsat", 0, 9)] +[assembly: KSPAssembly ("SCANsat", 0, 95)] diff --git a/SCANsat/SCAN_Data/SCANanomaly.cs b/SCANsat/SCAN_Data/SCANanomaly.cs new file mode 100644 index 000000000..02ee0f1eb --- /dev/null +++ b/SCANsat/SCAN_Data/SCANanomaly.cs @@ -0,0 +1,68 @@ +#region license +/* + * [Scientific Committee on Advanced Navigation] + * S.C.A.N. Satellite + * + * SCANanomaly - stores info on anomalies and their locations + * + * Copyright (c)2013 damny; + * Copyright (c)2014 technogeeky ; + * Copyright (c)2014 (Your Name Here) ; see LICENSE.txt for licensing details. +*/ +#endregion + +using System; + +namespace SCANsat.SCAN_Data +{ + public class SCANanomaly + { + internal SCANanomaly(string s, double lon, double lat, PQSMod m) + { + name = s; + longitude = lon; + latitude = lat; + known = false; + mod = m; + } + + private bool known; + private bool detail; + private string name; + private double longitude; + private double latitude; + private PQSMod mod; + + public bool Known + { + get { return known; } + internal set { known = value; } + } + + public bool Detail + { + get { return detail; } + internal set { detail = value; } + } + + public string Name + { + get { return name; } + } + + public double Longitude + { + get { return longitude; } + } + + public double Latitude + { + get { return latitude; } + } + + public PQSMod Mod + { + get { return mod; } + } + } +} diff --git a/SCANsat/SCANdata.cs b/SCANsat/SCAN_Data/SCANdata.cs similarity index 73% rename from SCANsat/SCANdata.cs rename to SCANsat/SCAN_Data/SCANdata.cs index 028e7b93b..8d706c60d 100644 --- a/SCANsat/SCANdata.cs +++ b/SCANsat/SCAN_Data/SCANdata.cs @@ -1,806 +1,887 @@ -#region license -/* - * [Scientific Committee on Advanced Navigation] - * S.C.A.N. Satellite - * - * SCANdata - encapsulates scanned data for a body - * - * Copyright (c)2013 damny; - * Copyright (c)2014 technogeeky ; - * Copyright (c)2014 (Your Name Here) ; see LICENSE.txt for licensing details. - */ -#endregion -using System; -using System.Linq; -using System.Collections.Generic; -using UnityEngine; -using SCANsat.Platform.Palettes; -using SCANsat.Platform.Palettes.ColorBrewer; -using palette = SCANsat.SCAN_UI.SCANpalette; - -namespace SCANsat -{ - public class SCANdata - { - /* MAP: state */ - private Int32[,] coverage = new Int32[360, 180]; - private float[,] heightmap = new float[360, 180]; - private float[,] kethaneValueMap = new float[360, 180]; //Store kethane cell data in here - private CelestialBody body; - private Texture2D map_small = new Texture2D(360, 180, TextureFormat.RGB24, false); - - /* MAP: options */ - private float minHeight, maxHeight; - private float? clampHeight; - private string paletteName; - private int paletteSize; - private bool paletteReverse, paletteDiscrete, disabled; - private Palette colorPalette; - - /* MAP: default values */ - private static float?[,] bodyHeightRange = new float?[17, 3] - { - { 0, 1000, null }, { -1500, 6500, 0 }, { -500, 7000, null }, { -500, 5500, null }, - { 0, 6500, null }, { -2000, 7000, 0 }, { 0, 7500, null }, { 0, 12000, null }, { 0, 1000, null }, - { -3000, 6000, 0 }, { -500, 7500, null }, { 2000, 21500, null }, { -500, 11000, null }, - { 1500, 6000, null }, { 500, 5500, null }, { 0, 5500, null }, { -500, 3500, null } - }; - private static Palette[] paletteDefaults = { PaletteLoader.defaultPalette, PaletteLoader.defaultPalette, - BrewerPalettes.RdGy(11), BrewerPalettes.Paired(9), BrewerPalettes.PuBuGn(6), BrewerPalettes.BuPu(7), - BrewerPalettes.BuGn(9), BrewerPalettes.BrBG(8), PaletteLoader.defaultPalette, BrewerPalettes.YlGnBu(8), - BrewerPalettes.Set1(9), BrewerPalettes.PuOr(7), BrewerPalettes.Set3(8), BrewerPalettes.Accent(7), - BrewerPalettes.Spectral(8), BrewerPalettes.Pastel1(9), BrewerPalettes.RdYlGn(10) }; - private static bool[] paletteReverseDefaults = { false, false, true, false, false, true, false, false, - false, true, false, false, false, false, true, false, false }; - private const float defaultMinHeight = -1000f; - private const float defaultMaxHeight = 8000f; - private float? defaultClampHeight = null; - private Palette defaultPalette = PaletteLoader.defaultPalette; - - /* MAP: constructor */ - internal SCANdata(CelestialBody b) - { - body = b; - if (b.flightGlobalsIndex <= 16) - { - minHeight = (float)bodyHeightRange[b.flightGlobalsIndex, 0]; - maxHeight = (float)bodyHeightRange[b.flightGlobalsIndex, 1]; - clampHeight = bodyHeightRange[b.flightGlobalsIndex, 2]; - colorPalette = paletteDefaults[b.flightGlobalsIndex]; - paletteName = colorPalette.name; - paletteSize = colorPalette.size; - paletteReverse = paletteReverseDefaults[b.flightGlobalsIndex]; - } - else - { - colorPalette = defaultPalette; - paletteName = colorPalette.name; - paletteSize = colorPalette.size; - minHeight = defaultMinHeight; - maxHeight = defaultMaxHeight; - if (b.ocean) - clampHeight = 0; - else - clampHeight = defaultClampHeight; - } - } - - #region Public accessors - /* Accessors: body-specific variables */ - public Int32[,] Coverage - { - get { return coverage; } - internal set { coverage = value; } - } - - public float[,] HeightMap - { - get { return heightmap; } - internal set { heightmap = value; } - } - - public CelestialBody Body - { - get { return body; } - } - - public Texture2D Map - { - get { return map_small; } - } - - public float[,] KethaneValueMap - { - get { return kethaneValueMap; } - set { kethaneValueMap = value; } - } - - public float MinHeight - { - get { return minHeight; } - internal set - { - if (value < maxHeight) - minHeight = value; - } - } - - public float MaxHeight - { - get { return maxHeight; } - internal set - { - if (value > minHeight) - maxHeight = value; - } - } - - public float DefaultMinHeight - { - get - { - if (body.flightGlobalsIndex < 17) - return (float)bodyHeightRange[body.flightGlobalsIndex, 0]; - else - return -1000f; - } - } - - public float DefaultMaxHeight - { - get - { - if (body.flightGlobalsIndex < 17) - return (float)bodyHeightRange[body.flightGlobalsIndex, 1]; - else - return 8000f; - } - } - - public float? ClampHeight - { - get { return clampHeight; } - internal set - { - if (value == null) - clampHeight = null; - else if (value > minHeight && value < maxHeight) - clampHeight = value; - } - } - - public float? DefaultClampHeight - { - get - { - if (body.flightGlobalsIndex < 17) - return bodyHeightRange[body.flightGlobalsIndex, 2]; - else - return defaultClampHeight; - } - } - - public bool PaletteReverse - { - get { return paletteReverse; } - internal set { paletteReverse = value; } - } - - public bool PaletteDiscrete - { - get { return paletteDiscrete; } - internal set { paletteDiscrete = value; } - } - - public string PaletteName - { - get { return paletteName; } - internal set { paletteName = value; } - } - - public Palette ColorPalette - { - get { return colorPalette; } - internal set { colorPalette = value; } - } - - public Palette DefaultColorPalette - { - get - { - if (body.flightGlobalsIndex < 17) - return paletteDefaults[body.flightGlobalsIndex]; - else - return paletteDefaults[0]; - } - } - - public bool DefaultReversePalette - { - get - { - if (body.flightGlobalsIndex < 17) - return paletteReverseDefaults[body.flightGlobalsIndex]; - else - return false; - } - } - - public int PaletteSize - { - get { return paletteSize; } - internal set - { - if (value >= 3) - paletteSize = value; - } - } - - public bool Disabled - { - get { return disabled; } - internal set { disabled = value; } - } - #endregion - - #region SCANtype enum - /* DATA: known types of data */ - public enum SCANtype : int - { - Nothing = 0, // no data (MapTraq) - AltimetryLoRes = 1 << 0, // low resolution altimetry (limited zoom) - AltimetryHiRes = 1 << 1, // high resolution altimetry (unlimited zoom) - Altimetry = (1 << 2) - 1, // both (setting) or either (testing) altimetry - SCANsat_1 = 1 << 2, // Unused, reserved for future SCANsat scanner - Biome = 1 << 3, // biome data - Anomaly = 1 << 4, // anomalies (position of anomaly) - AnomalyDetail = 1 << 5, // anomaly detail (name of anomaly, etc.) - Kethane = 1 << 6, // Kethane - K-type - Kethane - Ore = 1 << 7, // Ore - ORS & K-type - EPL & MKS - Kethane_3 = 1 << 8, // Reserved - K-type - Kethane_4 = 1 << 9, // Reserved - K-type - Uranium = 1 << 10, // Uranium - ORS - KSPI - Thorium = 1 << 11, // Thorium - ORS - KSPI - Alumina = 1 << 12, // Alumina - ORS - KSPI - Water = 1 << 13, // Water - ORS - KSPI - Aquifer = 1 << 14, // Aquifer - ORS & K-type - MKS - Minerals = 1 << 15, // Minerals - ORS & K-type - MKS - Substrate = 1 << 16, // Substrate - ORS & K-type - MKS - KEEZO = 1 << 17, // KEEZO - ORS - Kass Effect - Karbonite = 1 << 18, // Karbonite - ORS - ORS_10 = 1 << 19, // Reserved - ORS - - Everything_SCAN = (1 << 6) - 1, // All default SCANsat scanners - Everything = Int32.MaxValue // All scanner types - } - #endregion - - #region Resource classes - - public enum SCANResource_Source - { - Kethane = 1, - ORSX = 2, - Regolith = 3, - } - - /* DATA: resources */ - public class SCANResource //The new class to store resource information stored in the respective config nodes - { - public SCANResource(string n, string Body, Color full, Color empty, float min, float max, SCANresourceType t, SCANResource_Source s) - { - name = n; - body = Body; - fullColor = full; - emptyColor = empty; - //linear = sc; - //ORS_Scalar = scalar; - //ORS_Multiplier = mult; - //ORS_Threshold = threshold; - minValue = min; - maxValue = max; - resourceType = t; - type = resourceType.type; - source = s; - } - - private string name; - internal string body; - //internal double ORS_Scalar, ORS_Multiplier, ORS_Threshold; - internal Color fullColor, emptyColor; - //internal bool linear; - internal float minValue; - internal float maxValue; - private SCANtype type; - internal SCANresourceType resourceType; - private SCANResource_Source source; - - public string Name - { - get { return name; } - } - - public SCANtype Type - { - get { return type; } - } - - public SCANResource_Source Source - { - get { return source; } - } - } - - public class SCANresourceType - { - internal string name; - internal SCANtype type; - internal Color colorFull, colorEmpty; - - public SCANresourceType(string s, int i, string Full, string Empty) - { - name = s; - type = (SCANtype)i; - if ((type & SCANtype.Everything_SCAN) != SCANtype.Nothing) - { - Debug.LogWarning("[SCANsat] Attempt To Override Default SCANsat Sensors; Resetting Resource Scanner Type To 0"); - type = SCANtype.Nothing; - } - try - { - colorFull = ConfigNode.ParseColor(Full); - } - catch (Exception e) - { - SCANUtil.SCANlog("Color Format Incorrect; Reverting To Default Full Resource Color: {0}", e); - colorFull = palette.cb_reddishPurple; - } - try - { - colorEmpty = ConfigNode.ParseColor(Empty); - } - catch (Exception e) - { - SCANUtil.SCANlog("Color Format Incorrect; Reverting To Default Empty Resource Color: {0}", e); - colorEmpty = palette.magenta; - } - } - } - #endregion - - #region Anomalies - /* DATA: anomalies and such */ - internal class SCANanomaly - { - internal SCANanomaly(string s, double lon, double lat, PQSMod m) - { - name = s; - longitude = lon; - latitude = lat; - known = false; - mod = m; - } - - internal bool known; - internal bool detail; - internal string name; - internal double longitude; - internal double latitude; - internal PQSMod mod; - } - - private SCANanomaly[] anomalies; - - internal SCANanomaly[] Anomalies - { - get - { - if (anomalies == null) - { - PQSCity[] sites = body.GetComponentsInChildren(true); - anomalies = new SCANanomaly[sites.Length]; - for (int i = 0; i < sites.Length; ++i) - { - anomalies[i] = new SCANanomaly(sites[i].name, body.GetLongitude(sites[i].transform.position), body.GetLatitude(sites[i].transform.position), sites[i]); - } - } - for (int i = 0; i < anomalies.Length; ++i) - { - anomalies[i].known = SCANUtil.isCovered(anomalies[i].longitude, anomalies[i].latitude, this, SCANtype.Anomaly); - anomalies[i].detail = SCANUtil.isCovered(anomalies[i].longitude, anomalies[i].latitude, this, SCANtype.AnomalyDetail); - } - return anomalies; - } - } - #endregion - - #region Scanning coverage - /* DATA: coverage */ - internal int[] coverage_count = new int[32]; - internal void updateCoverage() - { - for (int i = 0; i < 32; ++i) - { - SCANtype t = (SCANtype)(1 << i); - int cc = 0; - for (int x = 0; x < 360; ++x) - { - for (int y = 0; y < 180; ++y) - { - if ((coverage[x, y] & (Int32)t) == 0) - ++cc; - } - } - coverage_count[i] = cc; - } - } - internal int getCoverage(SCANtype type) - { - int uncov = 0; - if ((type & SCANtype.AltimetryLoRes) != SCANtype.Nothing) - uncov += coverage_count[0]; - if ((type & SCANtype.AltimetryHiRes) != SCANtype.Nothing) - uncov += coverage_count[1]; - if ((type & SCANtype.Biome) != SCANtype.Nothing) - uncov += coverage_count[3]; - if ((type & SCANtype.Anomaly) != SCANtype.Nothing) - uncov += coverage_count[4]; - if ((type & SCANtype.AnomalyDetail) != SCANtype.Nothing) - uncov += coverage_count[5]; - if ((type & SCANtype.Kethane) != SCANtype.Nothing) - uncov += coverage_count[6]; - if ((type & SCANtype.Ore) != SCANtype.Nothing) - uncov += coverage_count[7]; - if ((type & SCANtype.Kethane_3) != SCANtype.Nothing) - uncov += coverage_count[8]; - if ((type & SCANtype.Kethane_4) != SCANtype.Nothing) - uncov += coverage_count[9]; - if ((type & SCANtype.Uranium) != SCANtype.Nothing) - uncov += coverage_count[10]; - if ((type & SCANtype.Thorium) != SCANtype.Nothing) - uncov += coverage_count[11]; - if ((type & SCANtype.Alumina) != SCANtype.Nothing) - uncov += coverage_count[12]; - if ((type & SCANtype.Water) != SCANtype.Nothing) - uncov += coverage_count[13]; - if ((type & SCANtype.Aquifer) != SCANtype.Nothing) - uncov += coverage_count[14]; - if ((type & SCANtype.Minerals) != SCANtype.Nothing) - uncov += coverage_count[15]; - if ((type & SCANtype.Substrate) != SCANtype.Nothing) - uncov += coverage_count[16]; - if ((type & SCANtype.KEEZO) != SCANtype.Nothing) - uncov += coverage_count[17]; - if ((type & SCANtype.Karbonite) != SCANtype.Nothing) - uncov += coverage_count[18]; - if ((type & SCANtype.ORS_10) != SCANtype.Nothing) - uncov += coverage_count[19]; - return uncov; - - } - internal double getCoveragePercentage(SCANtype type) - { - double cov = 0d; - if (type == SCANtype.Nothing) - type = SCANtype.AltimetryLoRes | SCANtype.AltimetryHiRes | SCANtype.Biome | SCANtype.Anomaly; - cov = getCoverage(type); - if (cov <= 0) - cov = 100; - else - cov = Math.Min(99.9d, 100 - cov * 100d / (360d * 180d * SCANUtil.countBits((int)type))); - return cov; - } - #endregion - - #region Map Texture - /* DATA: all hail the red line of scanning */ - private int scanline = 0; - private int scanstep = 0; - //Draws the actual map texture - internal void drawHeightScanline(SCANtype type) - { - Color[] cols_height_map_small = map_small.GetPixels(0, scanline, 360, 1); - for (int ilon = 0; ilon < 360; ilon += 1) - { - int scheme = SCANcontroller.controller.colours; - float val = heightmap[ilon, scanline]; - if (val == 0) - { //Some preparation for bigger changes in map caching, automatically calculate elevation for every point on the small map, only display scanned areas - if (body.pqsController == null) - { - heightmap[ilon, scanline] = 0; - cols_height_map_small[ilon] = palette.lerp(palette.black, palette.white, UnityEngine.Random.value); - continue; - } - else - { - // convert to radial vector - val = (float)SCANUtil.getElevation(body, ilon - 180, scanline - 90); - if (val == 0) - val = -0.001f; // this is terrible - heightmap[ilon, scanline] = val; - } - } - Color c = palette.black; - if (SCANUtil.isCovered(ilon, scanline, this, SCANtype.Altimetry)) - { //We check for coverage down here now, after elevation data is collected - if (SCANUtil.isCovered(ilon, scanline, this, SCANtype.AltimetryHiRes)) - c = palette.heightToColor(val, scheme, this); - else - c = palette.heightToColor(val, 1, this); - } - else - { - c = palette.grey; - if (scanline % 30 == 0 && ilon % 3 == 0) - { - c = palette.white; - } - else if (ilon % 30 == 0 && scanline % 3 == 0) - { - c = palette.white; - } - } - if (type != SCANtype.Nothing) - { - if (!SCANUtil.isCoveredByAll(ilon, scanline, this, type)) - { - c = palette.lerp(c, palette.black, 0.5f); - } - } - cols_height_map_small[ilon] = c; - } - map_small.SetPixels(0, scanline, 360, 1, cols_height_map_small); - scanline = scanline + 1; - if (scanline >= 180) - { - scanstep += 1; - scanline = 0; - } - } - - //Updates the red scanning line - internal void updateImages(SCANtype type) - { - if (palette.small_redline == null) - { - palette.small_redline = new Color[360]; - for (int i = 0; i < 360; i++) - palette.small_redline[i] = palette.red; - } - drawHeightScanline(type); - if (scanline < 179) - { - map_small.SetPixels(0, scanline + 1, 360, 1, palette.small_redline); - } - map_small.Apply(); - } - #endregion - - #region Map Utilities - /* DATA: debug option to fill in the map */ - internal void fillMap() - { - for (int i = 0; i < 360; i++) - { - for (int j = 0; j < 180; j++) - { - coverage[i, j] |= (Int32)SCANtype.Everything; - } - } - } - - /* DATA: reset the map */ - internal void reset() - { - coverage = new Int32[360, 180]; - heightmap = new float[360, 180]; - resetImages(); - } - internal void resetImages() - { - // Just draw a simple grid to initialize the image; the map will appear on top of it - for (int y = 0; y < map_small.height; y++) - { - for (int x = 0; x < map_small.width; x++) - { - if ((x % 30 == 0 && y % 3 > 0) || (y % 30 == 0 && x % 3 > 0)) - { - map_small.SetPixel(x, y, palette.white); - } - else - { - map_small.SetPixel(x, y, palette.grey); - } - } - } - map_small.Apply(); - } - #endregion - - #region Unused code - - /* MAP: anonymous functions (in place of preprocessor macros */ - // icLON and icLAT: [i]nteger casted, [c]lamped, longitude and latitude - //internal Func icLON = (lon) => ((int)(lon + 360 + 180)) % 360; - //internal Func icLAT = (lat) => ((int)(lat + 180 + 90 )) % 180; - //Func badLonLat = (lon,lat) => (lon < 0 || lat < 0 || lon >= 360 || lat >= 180); - - //****Commented code moved to SCANUtil**** - /* DATA: map passes and coverage (passes >= 1)*/ - //public void registerPass ( double lon , double lat , SCANtype type ) { - // int ilon = SCANUtil.icLON(lon); - // int ilat = SCANUtil.icLAT(lat); - // if (SCANUtil.badLonLat(ilon, ilat)) return; - // coverage [ilon, ilat] |= (Int32)type; - //} - //public bool isCovered ( double lon , double lat , SCANtype type ) { - // int ilon = SCANUtil.icLON(lon); - // int ilat = SCANUtil.icLAT(lat); - // if (SCANUtil.badLonLat(ilon, ilat)) return false; - // return (coverage [ilon, ilat] & (Int32)type) != 0; - //} - //public bool isCoveredByAll(double lon, double lat, SCANtype type) - //{ - // int ilon = SCANUtil.icLON(lon); - // int ilat = SCANUtil.icLAT(lat); - // if (SCANUtil.badLonLat(ilon, ilat)) return false; - // return (coverage[ilon, ilat] & (Int32)type) == (Int32)type; - //} - - /* DATA: elevation (called often, probably) */ - //public double getElevation ( double lon , double lat ) { - // if (body.pqsController == null) return 0; // FIXME: something == null does not imply sealevel. - // /* FIXME: unused */ //int ilon = ((int)(lon + 360 + 180)) % 360; - // /* FIXME: unused */ //int ilat = ((int)(lat + 180 + 90)) % 180; - // double rlon = Mathf.Deg2Rad * lon; - // double rlat = Mathf.Deg2Rad * lat; - // Vector3d rad = new Vector3d (Math.Cos (rlat) * Math.Cos (rlon) , Math.Sin (rlat) , Math.Cos (rlat) * Math.Sin (rlon)); - // return Math.Round (body.pqsController.GetSurfaceHeight (rad) - body.pqsController.radius , 1); - //} - - /* DATA: Biomes and such */ - //public int getBiomeIndex ( double lon , double lat ) { - // if (body.BiomeMap == null) return -1; - // if (body.BiomeMap.Map == null) return -1; - - // double u = ((lon + 360 + 180 + 90)) % 360; // not casted to int, so not the same - // double v = ((lat + 180 + 90)) % 180; // not casted to int, so not the same - - // if (u < 0 || v < 0 || u >= 360 || v >= 180) - // return -1; - // CBAttributeMap.MapAttribute att = body.BiomeMap.GetAtt (Mathf.Deg2Rad * lat , Mathf.Deg2Rad * lon); - // for (int i = 0; i < body.BiomeMap.Attributes.Length; ++i) { - // if (body.BiomeMap.Attributes [i] == att) { - // return i; - // } - // } - // return -1; - //} - //public double getBiomeIndexFraction ( double lon , double lat ) { - // if (body.BiomeMap == null) return 0f; - // return SCANUtil.getBiomeIndex(body, lon, lat) * 1.0f / body.BiomeMap.Attributes.Length; - //} - //public CBAttributeMap.MapAttribute getBiome ( double lon , double lat ) { - // if (body.BiomeMap == null) return null; - // if (body.BiomeMap.Map == null) return body.BiomeMap.defaultAttribute; - // int i = SCANUtil.getBiomeIndex(body, lon, lat); - // if (i < 0) return body.BiomeMap.defaultAttribute; - // else return body.BiomeMap.Attributes [i]; - //} - //public string getBiomeName ( double lon , double lat ) { - // CBAttributeMap.MapAttribute a = getBiome (lon , lat); - // if (a == null) - // return "unknown"; - // return a.name; - //} - - //public double ORSOverlay(double lon, double lat, int i, string s) //Uses ORS methods to grab the resource amount given a lat and long - //{ - // double amount = 0f; - // ORSPlanetaryResourcePixel overlayPixel = ORSPlanetaryResourceMapData.getResourceAvailability(i, s, lat, lon); - // amount = overlayPixel.getAmount(); - // return amount; - //} - - /* DATA: Array conversion **** Moved to SCANUtil*/ - ////Take the Int32[] coverage and convert it to a single dimension byte array - //private byte[] ConvertToByte (Int32[,] iArray) { - // byte[] bArray = new byte[360 * 180 * 4]; - // int k = 0; - // for (int i = 0; i < 360; i++) { - // for (int j = 0; j < 180; j++) { - // byte[] bytes = BitConverter.GetBytes(iArray[i,j]); - // for (int m = 0; m < bytes.Length; m++) { - // bArray[k++] = bytes[m]; - // } - // } - // } - // return bArray; - //} - - ////Convert byte array from persistent file to usable Int32[] - //private Int32[,] ConvertToInt (byte[] bArray) { - // Int32[,] iArray = new Int32[360, 180]; - // int k = 0; - // for (int i = 0; i < 360; i++) { - // for (int j = 0; j < 180; j++) { - // iArray[i,j] = BitConverter.ToInt32(bArray, k); - // k += 4; - // } - // } - // return iArray; - //} - - ////One time conversion of single byte[,] to Int32 to recover old scanning data - //private Int32[,] RecoverToInt (byte[,] bArray) { - // Int32[,] iArray = new Int32[360, 180]; - // for (int i = 0; i < 360; i++) { - // for (int j = 0; j < 180; j++) { - // iArray[i,j] = (Int32)bArray[i,j]; - // } - // } - // return iArray; - //} - - /* DATA: legacy serialization and compression */ - //internal string integerSerialize () { - // byte[] bytes = ConvertToByte(coverage); - // MemoryStream mem = new MemoryStream (); - // BinaryFormatter binf = new BinaryFormatter (); - // binf.Serialize (mem , bytes); - // string blob = Convert.ToBase64String (CLZF2.Compress (mem.ToArray ())); - // return blob.Replace ("/" , "-").Replace ("=" , "_"); - //} - - //public void integerDeserialize ( string blob, bool b ) { - // try { - // blob = blob.Replace ("-" , "/").Replace ("_" , "="); - // byte[] bytes = Convert.FromBase64String (blob); - // bytes = CLZF2.Decompress (bytes); - // MemoryStream mem = new MemoryStream (bytes , false); - // BinaryFormatter binf = new BinaryFormatter (); - // if (b) { - // byte[,] bRecover = new byte[360, 180]; - // bRecover = (byte[,])binf.Deserialize (mem); - // coverage = RecoverToInt(bRecover); - // } - // else { - // byte[] bArray = (byte[])binf.Deserialize (mem); - // coverage = ConvertToInt(bArray); - // } - // } catch (Exception e) { - // coverage = new Int32[360 , 180]; - // heightmap = new float[360 , 180]; - // throw e; - // } - // resetImages (); - //} - - ///* DATA: serialization and compression */ - //public string serialize () { - // // convert the byte[,] array into a KSP-savefile-safe variant of Base64 - // MemoryStream mem = new MemoryStream (); - // BinaryFormatter binf = new BinaryFormatter (); - // binf.Serialize (mem , backupCoverage); - // string blob = Convert.ToBase64String (CLZF2.Compress (mem.ToArray ())); - // return blob.Replace ("/" , "-").Replace ("=" , "_"); - //} - - //public void deserialize ( string blob ) { - // try { - // blob = blob.Replace ("-" , "/").Replace ("_" , "="); - // byte[] bytes = Convert.FromBase64String (blob); - // bytes = CLZF2.Decompress (bytes); - // MemoryStream mem = new MemoryStream (bytes , false); - // BinaryFormatter binf = new BinaryFormatter (); - // backupCoverage = (byte[,])binf.Deserialize (mem); - // } catch (Exception e) { - // backupCoverage = new byte[360 , 180]; - // throw e; - // } - //} - - #endregion - } -} +#region license +/* + * [Scientific Committee on Advanced Navigation] + * S.C.A.N. Satellite + * + * SCANdata - encapsulates scanned data for a body + * + * Copyright (c)2013 damny; + * Copyright (c)2014 technogeeky ; + * Copyright (c)2014 (Your Name Here) ; see LICENSE.txt for licensing details. + */ +#endregion +using System; +using System.Linq; +using System.Collections.Generic; +using UnityEngine; +using System.IO; +using System.Runtime.Serialization.Formatters.Binary; +using SCANsat.SCAN_Platform; +using SCANsat.SCAN_Platform.Palettes; +using SCANsat.SCAN_Platform.Palettes.ColorBrewer; +using palette = SCANsat.SCAN_UI.UI_Framework.SCANpalette; + +namespace SCANsat.SCAN_Data +{ + public class SCANdata + { + /* MAP: state */ + private Int32[,] coverage = new Int32[360, 180]; + private float[,] heightmap = new float[360, 180]; + private float[,] kethaneValueMap = new float[360, 180]; //Store kethane cell data in here + private CelestialBody body; + private Texture2D map_small = new Texture2D(360, 180, TextureFormat.RGB24, false); + + /* MAP: options */ + private float minHeight, maxHeight; + private float? clampHeight; + private string paletteName; + private int paletteSize; + private bool paletteReverse, paletteDiscrete, disabled; + private Palette colorPalette; + + /* MAP: default values */ + private static float?[,] bodyHeightRange = new float?[17, 3] + { + { 0, 1000, null }, { -1500, 6500, 0 }, { -500, 7000, null }, { -500, 5500, null }, + { 0, 6500, null }, { -2000, 7000, 0 }, { 0, 7500, null }, { 0, 12000, null }, { 0, 1000, null }, + { -3000, 6000, 0 }, { -500, 7500, null }, { 2000, 21500, null }, { -500, 11000, null }, + { 1500, 6000, null }, { 500, 5500, null }, { 0, 5500, null }, { -500, 3500, null } + }; + private static Palette[] paletteDefaults = { PaletteLoader.defaultPalette, PaletteLoader.defaultPalette, + BrewerPalettes.RdGy(11), BrewerPalettes.Paired(9), BrewerPalettes.PuBuGn(6), BrewerPalettes.BuPu(7), + BrewerPalettes.BuGn(9), BrewerPalettes.BrBG(8), PaletteLoader.defaultPalette, BrewerPalettes.YlGnBu(8), + BrewerPalettes.Set1(9), BrewerPalettes.PuOr(7), BrewerPalettes.Set3(8), BrewerPalettes.Accent(7), + BrewerPalettes.Spectral(8), BrewerPalettes.Pastel1(9), BrewerPalettes.RdYlGn(10) }; + private static bool[] paletteReverseDefaults = { false, false, true, false, false, true, false, false, + false, true, false, false, false, false, true, false, false }; + private const float defaultMinHeight = -1000f; + private const float defaultMaxHeight = 8000f; + private float? defaultClampHeight = null; + private Palette defaultPalette = PaletteLoader.defaultPalette; + + /* MAP: constructor */ + internal SCANdata(CelestialBody b) + { + body = b; + if (b.flightGlobalsIndex <= 16) + { + minHeight = (float)bodyHeightRange[b.flightGlobalsIndex, 0]; + maxHeight = (float)bodyHeightRange[b.flightGlobalsIndex, 1]; + clampHeight = bodyHeightRange[b.flightGlobalsIndex, 2]; + colorPalette = paletteDefaults[b.flightGlobalsIndex]; + paletteName = colorPalette.name; + paletteSize = colorPalette.size; + paletteReverse = paletteReverseDefaults[b.flightGlobalsIndex]; + } + else + { + colorPalette = defaultPalette; + paletteName = colorPalette.name; + paletteSize = colorPalette.size; + minHeight = defaultMinHeight; + maxHeight = defaultMaxHeight; + if (b.ocean) + clampHeight = 0; + else + clampHeight = defaultClampHeight; + } + } + + #region Public accessors + /* Accessors: body-specific variables */ + public Int32[,] Coverage + { + get { return coverage; } + internal set { coverage = value; } + } + + public float[,] HeightMap + { + get { return heightmap; } + internal set { heightmap = value; } + } + + public CelestialBody Body + { + get { return body; } + } + + public Texture2D Map + { + get { return map_small; } + } + + public float[,] KethaneValueMap + { + get { return kethaneValueMap; } + set { kethaneValueMap = value; } + } + + public float MinHeight + { + get { return minHeight; } + internal set + { + if (value < maxHeight) + minHeight = value; + } + } + + public float MaxHeight + { + get { return maxHeight; } + internal set + { + if (value > minHeight) + maxHeight = value; + } + } + + public float DefaultMinHeight + { + get + { + if (body.flightGlobalsIndex < 17) + return (float)bodyHeightRange[body.flightGlobalsIndex, 0]; + else + return -1000f; + } + } + + public float DefaultMaxHeight + { + get + { + if (body.flightGlobalsIndex < 17) + return (float)bodyHeightRange[body.flightGlobalsIndex, 1]; + else + return 8000f; + } + } + + public float? ClampHeight + { + get { return clampHeight; } + internal set + { + if (value == null) + clampHeight = null; + else if (value > minHeight && value < maxHeight) + clampHeight = value; + } + } + + public float? DefaultClampHeight + { + get + { + if (body.flightGlobalsIndex < 17) + return bodyHeightRange[body.flightGlobalsIndex, 2]; + else + return defaultClampHeight; + } + } + + public bool PaletteReverse + { + get { return paletteReverse; } + internal set { paletteReverse = value; } + } + + public bool PaletteDiscrete + { + get { return paletteDiscrete; } + internal set { paletteDiscrete = value; } + } + + public string PaletteName + { + get { return paletteName; } + internal set { paletteName = value; } + } + + public Palette ColorPalette + { + get { return colorPalette; } + internal set { colorPalette = value; } + } + + public Palette DefaultColorPalette + { + get + { + if (body.flightGlobalsIndex < 17) + return paletteDefaults[body.flightGlobalsIndex]; + else + return paletteDefaults[0]; + } + } + + public bool DefaultReversePalette + { + get + { + if (body.flightGlobalsIndex < 17) + return paletteReverseDefaults[body.flightGlobalsIndex]; + else + return false; + } + } + + public int PaletteSize + { + get { return paletteSize; } + internal set + { + if (value >= 3) + paletteSize = value; + } + } + + public bool Disabled + { + get { return disabled; } + internal set { disabled = value; } + } + #endregion + + #region Anomalies + /* DATA: anomalies and such */ + private SCANanomaly[] anomalies; + + public SCANanomaly[] Anomalies + { + get + { + if (anomalies == null) + { + PQSCity[] sites = body.GetComponentsInChildren(true); + anomalies = new SCANanomaly[sites.Length]; + for (int i = 0; i < sites.Length; ++i) + { + anomalies[i] = new SCANanomaly(sites[i].name, body.GetLongitude(sites[i].transform.position), body.GetLatitude(sites[i].transform.position), sites[i]); + } + } + for (int i = 0; i < anomalies.Length; ++i) + { + anomalies[i].Known = SCANUtil.isCovered(anomalies[i].Longitude, anomalies[i].Latitude, this, SCANtype.Anomaly); + anomalies[i].Detail = SCANUtil.isCovered(anomalies[i].Longitude, anomalies[i].Latitude, this, SCANtype.AnomalyDetail); + } + return anomalies; + } + } + + #endregion + + #region Scanning coverage + /* DATA: coverage */ + private int[] coverage_count = Enumerable.Repeat(360 * 180, 32).ToArray(); + internal void updateCoverage() + { + for (int i = 0; i < 32; ++i) + { + SCANtype t = (SCANtype)(1 << i); + int cc = 0; + for (int x = 0; x < 360; ++x) + { + for (int y = 0; y < 180; ++y) + { + if ((coverage[x, y] & (Int32)t) == 0) + ++cc; + } + } + coverage_count[i] = cc; + } + } + internal int getCoverage(SCANtype type) + { + int uncov = 0; + if ((type & SCANtype.AltimetryLoRes) != SCANtype.Nothing) + uncov += coverage_count[0]; + if ((type & SCANtype.AltimetryHiRes) != SCANtype.Nothing) + uncov += coverage_count[1]; + if ((type & SCANtype.Biome) != SCANtype.Nothing) + uncov += coverage_count[3]; + if ((type & SCANtype.Anomaly) != SCANtype.Nothing) + uncov += coverage_count[4]; + if ((type & SCANtype.AnomalyDetail) != SCANtype.Nothing) + uncov += coverage_count[5]; + if ((type & SCANtype.Kethane) != SCANtype.Nothing) + uncov += coverage_count[6]; + if ((type & SCANtype.Ore) != SCANtype.Nothing) + uncov += coverage_count[7]; + if ((type & SCANtype.Kethane_3) != SCANtype.Nothing) + uncov += coverage_count[8]; + if ((type & SCANtype.Kethane_4) != SCANtype.Nothing) + uncov += coverage_count[9]; + if ((type & SCANtype.Uranium) != SCANtype.Nothing) + uncov += coverage_count[10]; + if ((type & SCANtype.Thorium) != SCANtype.Nothing) + uncov += coverage_count[11]; + if ((type & SCANtype.Alumina) != SCANtype.Nothing) + uncov += coverage_count[12]; + if ((type & SCANtype.Water) != SCANtype.Nothing) + uncov += coverage_count[13]; + if ((type & SCANtype.Aquifer) != SCANtype.Nothing) + uncov += coverage_count[14]; + if ((type & SCANtype.Minerals) != SCANtype.Nothing) + uncov += coverage_count[15]; + if ((type & SCANtype.Substrate) != SCANtype.Nothing) + uncov += coverage_count[16]; + if ((type & SCANtype.KEEZO) != SCANtype.Nothing) + uncov += coverage_count[17]; + if ((type & SCANtype.Karbonite) != SCANtype.Nothing) + uncov += coverage_count[18]; + if ((type & SCANtype.Regolith_10) != SCANtype.Nothing) + uncov += coverage_count[19]; + if ((type & SCANtype.Regolith_11) != SCANtype.Nothing) + uncov += coverage_count[20]; + return uncov; + } + + #endregion + + #region Map Texture + /* DATA: all hail the red line of scanning */ + private int scanline = 0; + private int scanstep = 0; + //Draws the actual map texture + internal void drawHeightScanline(SCANtype type) + { + Color[] cols_height_map_small = map_small.GetPixels(0, scanline, 360, 1); + for (int ilon = 0; ilon < 360; ilon += 1) + { + int scheme = SCANcontroller.controller.colours; + float val = heightmap[ilon, scanline]; + if (val == 0) + { //Some preparation for bigger changes in map caching, automatically calculate elevation for every point on the small map, only display scanned areas + if (body.pqsController == null) + { + heightmap[ilon, scanline] = 0; + cols_height_map_small[ilon] = palette.lerp(palette.black, palette.white, UnityEngine.Random.value); + continue; + } + else + { + // convert to radial vector + val = (float)SCANUtil.getElevation(body, ilon - 180, scanline - 90); + if (val == 0) + val = -0.001f; // this is terrible + heightmap[ilon, scanline] = val; + } + } + Color c = palette.black; + if (SCANUtil.isCovered(ilon, scanline, this, SCANtype.Altimetry)) + { //We check for coverage down here now, after elevation data is collected + if (SCANUtil.isCovered(ilon, scanline, this, SCANtype.AltimetryHiRes)) + c = palette.heightToColor(val, scheme, this); + else + c = palette.heightToColor(val, 1, this); + } + else + { + c = palette.grey; + if (scanline % 30 == 0 && ilon % 3 == 0) + { + c = palette.white; + } + else if (ilon % 30 == 0 && scanline % 3 == 0) + { + c = palette.white; + } + } + if (type != SCANtype.Nothing) + { + if (!SCANUtil.isCoveredByAll(ilon, scanline, this, type)) + { + c = palette.lerp(c, palette.black, 0.5f); + } + } + cols_height_map_small[ilon] = c; + } + map_small.SetPixels(0, scanline, 360, 1, cols_height_map_small); + scanline = scanline + 1; + if (scanline >= 180) + { + scanstep += 1; + scanline = 0; + } + } + + //Updates the red scanning line + internal void updateImages(SCANtype type) + { + if (palette.small_redline == null) + { + palette.small_redline = new Color[360]; + for (int i = 0; i < 360; i++) + palette.small_redline[i] = palette.red; + } + drawHeightScanline(type); + if (scanline < 179) + { + map_small.SetPixels(0, scanline + 1, 360, 1, palette.small_redline); + } + map_small.Apply(); + } + #endregion + + #region Map Utilities + /* DATA: debug option to fill in the map */ + internal void fillMap() + { + for (int i = 0; i < 360; i++) + { + for (int j = 0; j < 180; j++) + { + coverage[i, j] |= (Int32)SCANtype.Everything; + } + } + } + + /* DATA: reset the map */ + internal void reset() + { + coverage = new Int32[360, 180]; + heightmap = new float[360, 180]; + resetImages(); + } + internal void resetImages() + { + // Just draw a simple grid to initialize the image; the map will appear on top of it + for (int y = 0; y < map_small.height; y++) + { + for (int x = 0; x < map_small.width; x++) + { + if ((x % 30 == 0 && y % 3 > 0) || (y % 30 == 0 && x % 3 > 0)) + { + map_small.SetPixel(x, y, palette.white); + } + else + { + map_small.SetPixel(x, y, palette.grey); + } + } + } + map_small.Apply(); + } + #endregion + + #region Data Serialize/Deserialize + + //Take the Int32[] coverage and convert it to a single dimension byte array + private byte[] ConvertToByte(Int32[,] iArray) + { + byte[] bArray = new byte[360 * 180 * 4]; + int k = 0; + for (int i = 0; i < 360; i++) + { + for (int j = 0; j < 180; j++) + { + byte[] bytes = BitConverter.GetBytes(iArray[i, j]); + for (int m = 0; m < bytes.Length; m++) + { + bArray[k++] = bytes[m]; + } + } + } + return bArray; + } + + //Convert byte array from persistent file to usable Int32[] + private Int32[,] ConvertToInt(byte[] bArray) + { + Int32[,] iArray = new Int32[360, 180]; + int k = 0; + for (int i = 0; i < 360; i++) + { + for (int j = 0; j < 180; j++) + { + iArray[i, j] = BitConverter.ToInt32(bArray, k); + k += 4; + } + } + return iArray; + } + + //One time conversion of single byte[,] to Int32 to recover old scanning data + private Int32[,] RecoverToInt(byte[,] bArray) + { + Int32[,] iArray = new Int32[360, 180]; + for (int i = 0; i < 360; i++) + { + for (int j = 0; j < 180; j++) + { + iArray[i, j] = (Int32)bArray[i, j]; + } + } + return iArray; + } + + /* DATA: serialization and compression */ + internal string integerSerialize() + { + byte[] bytes = ConvertToByte(Coverage); + MemoryStream mem = new MemoryStream(); + BinaryFormatter binf = new BinaryFormatter(); + binf.Serialize(mem, bytes); + string blob = Convert.ToBase64String(SCAN_CLZF2.Compress(mem.ToArray())); + return blob.Replace("/", "-").Replace("=", "_"); + } + + internal void integerDeserialize(string blob, bool b) + { + try + { + blob = blob.Replace("-", "/").Replace("_", "="); + byte[] bytes = Convert.FromBase64String(blob); + bytes = SCAN_CLZF2.Decompress(bytes); + MemoryStream mem = new MemoryStream(bytes, false); + BinaryFormatter binf = new BinaryFormatter(); + if (b) + { + byte[,] bRecover = new byte[360, 180]; + bRecover = (byte[,])binf.Deserialize(mem); + Coverage = RecoverToInt(bRecover); + } + else + { + byte[] bArray = (byte[])binf.Deserialize(mem); + Coverage = ConvertToInt(bArray); + } + } + catch (Exception e) + { + Coverage = new Int32[360, 180]; + HeightMap = new float[360, 180]; + throw e; + } + resetImages(); + } + +#endregion + + #region Unused code + + #region SCANtype enum + ///* DATA: known types of data */ + //public enum SCANtype : int + //{ + // Nothing = 0, // no data (MapTraq) + // AltimetryLoRes = 1 << 0, // low resolution altimetry (limited zoom) + // AltimetryHiRes = 1 << 1, // high resolution altimetry (unlimited zoom) + // Altimetry = (1 << 2) - 1, // both (setting) or either (testing) altimetry + // SCANsat_1 = 1 << 2, // Unused, reserved for future SCANsat scanner + // Biome = 1 << 3, // biome data + // Anomaly = 1 << 4, // anomalies (position of anomaly) + // AnomalyDetail = 1 << 5, // anomaly detail (name of anomaly, etc.) + // Kethane = 1 << 6, // Kethane - K-type - Kethane + // Ore = 1 << 7, // Ore - ORS & K-type - EPL & MKS + // Kethane_3 = 1 << 8, // Reserved - K-type + // Kethane_4 = 1 << 9, // Reserved - K-type + // Uranium = 1 << 10, // Uranium - ORS - KSPI + // Thorium = 1 << 11, // Thorium - ORS - KSPI + // Alumina = 1 << 12, // Alumina - ORS - KSPI + // Water = 1 << 13, // Water - ORS - KSPI + // Aquifer = 1 << 14, // Aquifer - ORS & K-type - MKS + // Minerals = 1 << 15, // Minerals - ORS & K-type - MKS + // Substrate = 1 << 16, // Substrate - ORS & K-type - MKS + // KEEZO = 1 << 17, // KEEZO - ORS - Kass Effect + // Karbonite = 1 << 18, // Karbonite - ORS + // ORS_10 = 1 << 19, // Reserved - ORS + + // Everything_SCAN = (1 << 6) - 1, // All default SCANsat scanners + // Everything = Int32.MaxValue // All scanner types + //} + #endregion + + #region Resource classes + + //public enum SCANResource_Source + //{ + // Kethane = 1, + // ORSX = 2, + // Regolith = 3, + //} + + ///* DATA: resources */ + //public class SCANResource //The new class to store resource information stored in the respective config nodes + //{ + // public SCANResource(string n, string Body, Color full, Color empty, float min, float max, SCANresourceType t, SCANResource_Source s) + // { + // name = n; + // body = Body; + // fullColor = full; + // emptyColor = empty; + // //linear = sc; + // //ORS_Scalar = scalar; + // //ORS_Multiplier = mult; + // //ORS_Threshold = threshold; + // minValue = min; + // maxValue = max; + // resourceType = t; + // type = resourceType.type; + // source = s; + // } + + // private string name; + // internal string body; + // //internal double ORS_Scalar, ORS_Multiplier, ORS_Threshold; + // internal Color fullColor, emptyColor; + // //internal bool linear; + // internal float minValue; + // internal float maxValue; + // private SCANtype type; + // internal SCANresourceType resourceType; + // private SCANResource_Source source; + + // public string Name + // { + // get { return name; } + // } + + // public SCANtype Type + // { + // get { return type; } + // } + + // public SCANResource_Source Source + // { + // get { return source; } + // } + //} + + //public class SCANresourceType + //{ + // internal string name; + // internal SCANtype type; + // internal Color colorFull, colorEmpty; + + // public SCANresourceType(string s, int i, string Full, string Empty) + // { + // name = s; + // type = (SCANtype)i; + // if ((type & SCANtype.Everything_SCAN) != SCANtype.Nothing) + // { + // Debug.LogWarning("[SCANsat] Attempt To Override Default SCANsat Sensors; Resetting Resource Scanner Type To 0"); + // type = SCANtype.Nothing; + // } + // try + // { + // colorFull = ConfigNode.ParseColor(Full); + // } + // catch (Exception e) + // { + // SCANUtil.SCANlog("Color Format Incorrect; Reverting To Default Full Resource Color: {0}", e); + // colorFull = palette.cb_reddishPurple; + // } + // try + // { + // colorEmpty = ConfigNode.ParseColor(Empty); + // } + // catch (Exception e) + // { + // SCANUtil.SCANlog("Color Format Incorrect; Reverting To Default Empty Resource Color: {0}", e); + // colorEmpty = palette.magenta; + // } + // } + //} + #endregion + +//internal double getCoveragePercentage(SCANtype type) + //{ + // double cov = 0d; + // if (type == SCANtype.Nothing) + // type = SCANtype.AltimetryLoRes | SCANtype.AltimetryHiRes | SCANtype.Biome | SCANtype.Anomaly; + // cov = getCoverage(type); + // if (cov <= 0) + // cov = 100; + // else + // cov = Math.Min(99.9d, 100 - cov * 100d / (360d * 180d * SCANUtil.countBits((int)type))); + // return cov; + //} + /* MAP: anonymous functions (in place of preprocessor macros */ + // icLON and icLAT: [i]nteger casted, [c]lamped, longitude and latitude + //internal Func icLON = (lon) => ((int)(lon + 360 + 180)) % 360; + //internal Func icLAT = (lat) => ((int)(lat + 180 + 90 )) % 180; + //Func badLonLat = (lon,lat) => (lon < 0 || lat < 0 || lon >= 360 || lat >= 180); + + //****Commented code moved to SCANUtil**** + /* DATA: map passes and coverage (passes >= 1)*/ + //public void registerPass ( double lon , double lat , SCANtype type ) { + // int ilon = SCANUtil.icLON(lon); + // int ilat = SCANUtil.icLAT(lat); + // if (SCANUtil.badLonLat(ilon, ilat)) return; + // coverage [ilon, ilat] |= (Int32)type; + //} + //public bool isCovered ( double lon , double lat , SCANtype type ) { + // int ilon = SCANUtil.icLON(lon); + // int ilat = SCANUtil.icLAT(lat); + // if (SCANUtil.badLonLat(ilon, ilat)) return false; + // return (coverage [ilon, ilat] & (Int32)type) != 0; + //} + //public bool isCoveredByAll(double lon, double lat, SCANtype type) + //{ + // int ilon = SCANUtil.icLON(lon); + // int ilat = SCANUtil.icLAT(lat); + // if (SCANUtil.badLonLat(ilon, ilat)) return false; + // return (coverage[ilon, ilat] & (Int32)type) == (Int32)type; + //} + + /* DATA: elevation (called often, probably) */ + //public double getElevation ( double lon , double lat ) { + // if (body.pqsController == null) return 0; // FIXME: something == null does not imply sealevel. + // /* FIXME: unused */ //int ilon = ((int)(lon + 360 + 180)) % 360; + // /* FIXME: unused */ //int ilat = ((int)(lat + 180 + 90)) % 180; + // double rlon = Mathf.Deg2Rad * lon; + // double rlat = Mathf.Deg2Rad * lat; + // Vector3d rad = new Vector3d (Math.Cos (rlat) * Math.Cos (rlon) , Math.Sin (rlat) , Math.Cos (rlat) * Math.Sin (rlon)); + // return Math.Round (body.pqsController.GetSurfaceHeight (rad) - body.pqsController.radius , 1); + //} + + /* DATA: Biomes and such */ + //public int getBiomeIndex ( double lon , double lat ) { + // if (body.BiomeMap == null) return -1; + // if (body.BiomeMap.Map == null) return -1; + + // double u = ((lon + 360 + 180 + 90)) % 360; // not casted to int, so not the same + // double v = ((lat + 180 + 90)) % 180; // not casted to int, so not the same + + // if (u < 0 || v < 0 || u >= 360 || v >= 180) + // return -1; + // CBAttributeMap.MapAttribute att = body.BiomeMap.GetAtt (Mathf.Deg2Rad * lat , Mathf.Deg2Rad * lon); + // for (int i = 0; i < body.BiomeMap.Attributes.Length; ++i) { + // if (body.BiomeMap.Attributes [i] == att) { + // return i; + // } + // } + // return -1; + //} + //public double getBiomeIndexFraction ( double lon , double lat ) { + // if (body.BiomeMap == null) return 0f; + // return SCANUtil.getBiomeIndex(body, lon, lat) * 1.0f / body.BiomeMap.Attributes.Length; + //} + //public CBAttributeMap.MapAttribute getBiome ( double lon , double lat ) { + // if (body.BiomeMap == null) return null; + // if (body.BiomeMap.Map == null) return body.BiomeMap.defaultAttribute; + // int i = SCANUtil.getBiomeIndex(body, lon, lat); + // if (i < 0) return body.BiomeMap.defaultAttribute; + // else return body.BiomeMap.Attributes [i]; + //} + //public string getBiomeName ( double lon , double lat ) { + // CBAttributeMap.MapAttribute a = getBiome (lon , lat); + // if (a == null) + // return "unknown"; + // return a.name; + //} + + //public double ORSOverlay(double lon, double lat, int i, string s) //Uses ORS methods to grab the resource amount given a lat and long + //{ + // double amount = 0f; + // ORSPlanetaryResourcePixel overlayPixel = ORSPlanetaryResourceMapData.getResourceAvailability(i, s, lat, lon); + // amount = overlayPixel.getAmount(); + // return amount; + //} + + /* DATA: Array conversion **** Moved to SCANUtil*/ + ////Take the Int32[] coverage and convert it to a single dimension byte array + //private byte[] ConvertToByte (Int32[,] iArray) { + // byte[] bArray = new byte[360 * 180 * 4]; + // int k = 0; + // for (int i = 0; i < 360; i++) { + // for (int j = 0; j < 180; j++) { + // byte[] bytes = BitConverter.GetBytes(iArray[i,j]); + // for (int m = 0; m < bytes.Length; m++) { + // bArray[k++] = bytes[m]; + // } + // } + // } + // return bArray; + //} + + ////Convert byte array from persistent file to usable Int32[] + //private Int32[,] ConvertToInt (byte[] bArray) { + // Int32[,] iArray = new Int32[360, 180]; + // int k = 0; + // for (int i = 0; i < 360; i++) { + // for (int j = 0; j < 180; j++) { + // iArray[i,j] = BitConverter.ToInt32(bArray, k); + // k += 4; + // } + // } + // return iArray; + //} + + ////One time conversion of single byte[,] to Int32 to recover old scanning data + //private Int32[,] RecoverToInt (byte[,] bArray) { + // Int32[,] iArray = new Int32[360, 180]; + // for (int i = 0; i < 360; i++) { + // for (int j = 0; j < 180; j++) { + // iArray[i,j] = (Int32)bArray[i,j]; + // } + // } + // return iArray; + //} + + /* DATA: legacy serialization and compression */ + //internal string integerSerialize () { + // byte[] bytes = ConvertToByte(coverage); + // MemoryStream mem = new MemoryStream (); + // BinaryFormatter binf = new BinaryFormatter (); + // binf.Serialize (mem , bytes); + // string blob = Convert.ToBase64String (CLZF2.Compress (mem.ToArray ())); + // return blob.Replace ("/" , "-").Replace ("=" , "_"); + //} + + //public void integerDeserialize ( string blob, bool b ) { + // try { + // blob = blob.Replace ("-" , "/").Replace ("_" , "="); + // byte[] bytes = Convert.FromBase64String (blob); + // bytes = CLZF2.Decompress (bytes); + // MemoryStream mem = new MemoryStream (bytes , false); + // BinaryFormatter binf = new BinaryFormatter (); + // if (b) { + // byte[,] bRecover = new byte[360, 180]; + // bRecover = (byte[,])binf.Deserialize (mem); + // coverage = RecoverToInt(bRecover); + // } + // else { + // byte[] bArray = (byte[])binf.Deserialize (mem); + // coverage = ConvertToInt(bArray); + // } + // } catch (Exception e) { + // coverage = new Int32[360 , 180]; + // heightmap = new float[360 , 180]; + // throw e; + // } + // resetImages (); + //} + + ///* DATA: serialization and compression */ + //public string serialize () { + // // convert the byte[,] array into a KSP-savefile-safe variant of Base64 + // MemoryStream mem = new MemoryStream (); + // BinaryFormatter binf = new BinaryFormatter (); + // binf.Serialize (mem , backupCoverage); + // string blob = Convert.ToBase64String (CLZF2.Compress (mem.ToArray ())); + // return blob.Replace ("/" , "-").Replace ("=" , "_"); + //} + + //public void deserialize ( string blob ) { + // try { + // blob = blob.Replace ("-" , "/").Replace ("_" , "="); + // byte[] bytes = Convert.FromBase64String (blob); + // bytes = CLZF2.Decompress (bytes); + // MemoryStream mem = new MemoryStream (bytes , false); + // BinaryFormatter binf = new BinaryFormatter (); + // backupCoverage = (byte[,])binf.Deserialize (mem); + // } catch (Exception e) { + // backupCoverage = new byte[360 , 180]; + // throw e; + // } + //} + + #endregion + } +} diff --git a/SCANsat/SCAN_Data/SCANresource.cs b/SCANsat/SCAN_Data/SCANresource.cs new file mode 100644 index 000000000..11cdb8e10 --- /dev/null +++ b/SCANsat/SCAN_Data/SCANresource.cs @@ -0,0 +1,160 @@ +#region license +/* + * [Scientific Committee on Advanced Navigation] + * S.C.A.N. Satellite + * + * SCANresource - Stores info on resources pulled from their respective addons and SCANsat configs + * + * Copyright (c)2013 damny; + * Copyright (c)2014 technogeeky ; + * Copyright (c)2014 (Your Name Here) ; see LICENSE.txt for licensing details. +*/ +#endregion + +using System; +using palette = SCANsat.SCAN_UI.UI_Framework.SCANpalette; +using UnityEngine; + +namespace SCANsat.SCAN_Data +{ + public enum SCANresource_Source + { + Kethane = 1, + Regolith = 2, + } + + public class SCANresource + { + internal SCANresource(string n, string Body, Color full, Color empty, float min, float max, SCANresourceType t, SCANresource_Source s) + { + name = n; + body = Body; + fullColor = full; + emptyColor = empty; + minValue = min; + maxValue = max; + resourceType = t; + type = resourceType.Type; + source = s; + } + + private string name; + private string body; + private Color fullColor, emptyColor; + private float minValue, maxValue; + private SCANtype type; + private SCANresourceType resourceType; + private SCANresource_Source source; + + public string Name + { + get { return name; } + } + + public string Body + { + get { return body; } + } + + public Color FullColor + { + get { return fullColor; } + } + + public Color EmptyColor + { + get { return emptyColor; } + } + + public SCANtype Type + { + get { return type; } + } + + public SCANresourceType ResourceType + { + get { return resourceType; } + } + + public float MinValue + { + get { return minValue; } + internal set + { + if (value >= 0) + minValue = value; + } + } + + public float MaxValue + { + get { return maxValue; } + internal set + { + if (value >= 0) + maxValue = value; + } + } + + public SCANresource_Source Source + { + get { return source; } + } + } + + public class SCANresourceType + { + private string name; + private SCANtype type; + private Color colorFull, colorEmpty; + + internal SCANresourceType(string s, int i, string Full, string Empty) + { + name = s; + type = (SCANtype)i; + if ((type & SCANtype.Everything_SCAN) != SCANtype.Nothing) + { + Debug.LogWarning("[SCANsat] Attempt To Override Default SCANsat Sensors; Resetting Resource Scanner Type To 0"); + type = SCANtype.Nothing; + } + try + { + colorFull = ConfigNode.ParseColor(Full); + } + catch (Exception e) + { + SCANUtil.SCANlog("Color Format Incorrect; Reverting To Default Full Resource Color: {0}", e); + colorFull = palette.cb_reddishPurple; + } + try + { + colorEmpty = ConfigNode.ParseColor(Empty); + } + catch (Exception e) + { + SCANUtil.SCANlog("Color Format Incorrect; Reverting To Default Empty Resource Color: {0}", e); + colorEmpty = palette.magenta; + } + } + + public string Name + { + get { return name; } + } + + public SCANtype Type + { + get { return type;} + } + + public Color ColorFull + { + get { return colorFull; } + } + + public Color ColorEmpty + { + get { return colorEmpty; } + } + } +} diff --git a/SCANsat/SCAN_Data/SCANtype.cs b/SCANsat/SCAN_Data/SCANtype.cs new file mode 100644 index 000000000..8ab4d92eb --- /dev/null +++ b/SCANsat/SCAN_Data/SCANtype.cs @@ -0,0 +1,47 @@ +#region license +/* + * [Scientific Committee on Advanced Navigation] + * S.C.A.N. Satellite + * + * SCANtype - Enum for SCANsat scanner types + * + * Copyright (c)2013 damny; + * Copyright (c)2014 technogeeky ; + * Copyright (c)2014 (Your Name Here) ; see LICENSE.txt for licensing details. +*/ +#endregion + +using System; + +namespace SCANsat.SCAN_Data +{ + public enum SCANtype : int + { + Nothing = 0, // no data (MapTraq) + AltimetryLoRes = 1 << 0, // low resolution altimetry (limited zoom) + AltimetryHiRes = 1 << 1, // high resolution altimetry (unlimited zoom) + Altimetry = (1 << 2) - 1, // both (setting) or either (testing) altimetry + SCANsat_1 = 1 << 2, // Unused, reserved for future SCANsat scanner + Biome = 1 << 3, // biome data + Anomaly = 1 << 4, // anomalies (position of anomaly) + AnomalyDetail = 1 << 5, // anomaly detail (name of anomaly, etc.) + Kethane = 1 << 6, // Kethane - K-type - Kethane + Ore = 1 << 7, // Ore - Regolith & K-type - EPL & MKS + Kethane_3 = 1 << 8, // Reserved - K-type + Kethane_4 = 1 << 9, // Reserved - K-type + Uranium = 1 << 10, // Uranium - Regolith - KSPI + Thorium = 1 << 11, // Thorium - Regolith - KSPI + Alumina = 1 << 12, // Alumina - Regolith - KSPI + Water = 1 << 13, // Water - Regolith - KSPI + Aquifer = 1 << 14, // Aquifer - Regolith & K-type - MKS + Minerals = 1 << 15, // Minerals - Regolith & K-type - MKS + Substrate = 1 << 16, // Substrate - Regolith & K-type - MKS + KEEZO = 1 << 17, // KEEZO - Regolith - Kass Effect + Karbonite = 1 << 18, // Karbonite - Regolith + Regolith_10 = 1 << 19, // Reserved - Regolith + Regolith_11 = 1<< 20, // Reserved - Regolith + + Everything_SCAN = (1 << 6) - 1, // All default SCANsat scanners + Everything = Int32.MaxValue // All scanner types + } +} diff --git a/SCANsat/SCAN_Map/SCANmap.cs b/SCANsat/SCAN_Map/SCANmap.cs new file mode 100644 index 000000000..2e8d6fa8e --- /dev/null +++ b/SCANsat/SCAN_Map/SCANmap.cs @@ -0,0 +1,917 @@ +#region license +/* + * [Scientific Committee on Advanced Navigation] + * S.C.A.N. Satellite + * + * SCANmap - makes maps from data + * + * Copyright (c)2013 damny; + * Copyright (c)2014 technogeeky ; + * Copyright (c)2014 (Your Name Here) ; see LICENSE.txt for licensing details. +*/ +#endregion + +using System; +using System.IO; +using UnityEngine; +using SCANsat.SCAN_Platform.Palettes; +using SCANsat.SCAN_Platform.Logging; +using SCANsat.SCAN_Data; +using palette = SCANsat.SCAN_UI.UI_Framework.SCANpalette; + +namespace SCANsat.SCAN_Map +{ + public class SCANmap + { + internal SCANmap(CelestialBody Body, bool Cache) + { + body = Body; + cache = Cache; + } + + internal SCANmap() + { + } + + #region Public Accessors + + public double MapScale + { + get { return mapscale; } + internal set { mapscale = value; } + } + + public double Lon_Offset + { + get { return lon_offset; } + } + + public double Lat_Offset + { + get { return lat_offset; } + } + + public int MapWidth + { + get { return mapwidth; } + } + + public int MapHeight + { + get { return mapheight; } + } + + public mapType MType + { + get { return mType; } + } + + public Texture2D Map + { + get { return map; } + } + + public CelestialBody Body + { + get { return body; } + } + + public SCANresource Resource + { + get { return resource; } + internal set { resource = value; } + } + + public SCANmapLegend MapLegend + { + get { return mapLegend; } + internal set { mapLegend = value; } + } + + public MapProjection Projection + { + get { return projection; } + } + + #endregion + + /* MAP: Big Map height map caching */ + private float[,] big_heightmap; + private CelestialBody big_heightmap_body; + private bool cache; + + private void terrainHeightToArray(double lon, double lat, int ilon, int ilat) + { + float alt = 0f; + alt = (float)SCANUtil.getElevation(body, lon, lat); + if (alt == 0f) + alt = -0.001f; + big_heightmap[ilon, ilat] = alt; + } + + /* MAP: Projection methods for converting planet coordinates to the rectangular texture */ + private MapProjection projection = MapProjection.Rectangular; + + internal void setProjection(MapProjection p) + { + if (projection == p) + return; + projection = p; + resetMap(); + } + + internal double projectLongitude(double lon, double lat) + { + lon = (lon + 3600 + 180) % 360 - 180; + lat = (lat + 1800 + 90) % 180 - 90; + switch (projection) + { + case MapProjection.KavrayskiyVII: + lon = Mathf.Deg2Rad * lon; + lat = Mathf.Deg2Rad * lat; + lon = (3.0f * lon / 2.0f / Math.PI) * Math.Sqrt(Math.PI * Math.PI / 3.0f - lat * lat); + return Mathf.Rad2Deg * lon; + case MapProjection.Polar: + lon = Mathf.Deg2Rad * lon; + lat = Mathf.Deg2Rad * lat; + if (lat < 0) + { + lon = 1.3 * Math.Cos(lat) * Math.Sin(lon) - Math.PI / 2; + } + else + { + lon = 1.3 * Math.Cos(lat) * Math.Sin(lon) + Math.PI / 2; + } + return Mathf.Rad2Deg * lon; + default: + return lon; + } + } + + internal double projectLatitude(double lon, double lat) + { + lon = (lon + 3600 + 180) % 360 - 180; + lat = (lat + 1800 + 90) % 180 - 90; + switch (projection) + { + case MapProjection.Polar: + lon = Mathf.Deg2Rad * lon; + lat = Mathf.Deg2Rad * lat; + if (lat < 0) + { + lat = 1.3 * Math.Cos(lat) * Math.Cos(lon); + } + else + { + lat = -1.3 * Math.Cos(lat) * Math.Cos(lon); + } + return Mathf.Rad2Deg * lat; + default: + return lat; + } + } + + internal double unprojectLongitude(double lon, double lat) + { + if (lat > 90) + { + lat = 180 - lat; + lon += 180; + } + else if (lat < -90) + { + lat = -180 - lat; + lon += 180; + } + lon = (lon + 3600 + 180) % 360 - 180; + lat = (lat + 1800 + 90) % 180 - 90; + switch (projection) + { + case MapProjection.KavrayskiyVII: + lon = Mathf.Deg2Rad * lon; + lat = Mathf.Deg2Rad * lat; + lon = lon / Math.Sqrt(Mathf.PI * Math.PI / 3.0f - lat * lat) * 2.0f * Math.PI / 3.0f; + return Mathf.Rad2Deg * lon; + case MapProjection.Polar: + lon = Mathf.Deg2Rad * lon; + lat = Mathf.Deg2Rad * lat; + double lat0 = Math.PI / 2; + if (lon < 0) + { + lon += Math.PI / 2; + lat0 = -Math.PI / 2; + } + else + { + lon -= Math.PI / 2; + } + lon /= 1.3; + lat /= 1.3; + double p = Math.Sqrt(lon * lon + lat * lat); + double c = Math.Asin(p); + lon = Math.Atan2((lon * Math.Sin(c)), (p * Math.Cos(lat0) * Math.Cos(c) - lat * Math.Sin(lat0) * Math.Sin(c))); + lon = (Mathf.Rad2Deg * lon + 180) % 360 - 180; + if (lon <= -180) + lon = -180; + return lon; + default: + return lon; + } + } + + internal double unprojectLatitude(double lon, double lat) + { + if (lat > 90) + { + lat = 180 - lat; + lon += 180; + } + else if (lat < -90) + { + lat = -180 - lat; + lon += 180; + } + lon = (lon + 3600 + 180) % 360 - 180; + lat = (lat + 1800 + 90) % 180 - 90; + switch (projection) + { + case MapProjection.Polar: + lon = Mathf.Deg2Rad * lon; + lat = Mathf.Deg2Rad * lat; + double lat0 = Math.PI / 2; + if (lon < 0) + { + lon += Math.PI / 2; + lat0 = -Math.PI / 2; + } + else + { + lon -= Math.PI / 2; + } + lon /= 1.3; + lat /= 1.3; + double p = Math.Sqrt(lon * lon + lat * lat); + double c = Math.Asin(p); + lat = Math.Asin(Math.Cos(c) * Math.Sin(lat0) + (lat * Math.Sin(c) * Math.Cos(lat0)) / (p)); + return Mathf.Rad2Deg * lat; + default: + return lat; + } + } + + /* MAP: scaling, centering (setting origin), translating, etc */ + private double mapscale, lon_offset, lat_offset; + private int mapwidth, mapheight; + + internal void setSize(int w, int h) + { + if (w == 0) + w = 360 * (Screen.width / 360); + if (w > 360 * 4) + w = 360 * 4; + mapwidth = w; + mapscale = mapwidth / 360f; + if (h <= 0) + h = (int)(180 * mapscale); + mapheight = h; + if (map != null) + { + if (mapwidth != map.width || mapheight != map.height) + map = null; + } + } + + internal void setWidth(int w) + { + if (w == 0) + { + w = 360 * (int)(Screen.width / 360); + if (w > 360 * 4) + w = 360 * 4; + } + if (w < 360) + w = 360; + if (mapwidth == w) + return; + mapwidth = w; + mapscale = mapwidth / 360f; + mapheight = (int)(w / 2); + /* big map caching */ + big_heightmap = new float[mapwidth, mapheight]; + big_heightmap_body = body; + map = null; + resetMap(); + } + + internal void centerAround(double lon, double lat) + { + lon_offset = 180 + lon - (mapwidth / mapscale) / 2; + lat_offset = 90 + lat - (mapheight / mapscale) / 2; + } + + internal double scaleLatitude(double lat) + { + lat -= lat_offset; + lat *= 180f / (mapheight / mapscale); + return lat; + } + + internal double scaleLongitude(double lon) + { + lon -= lon_offset; + lon *= 360f / (mapwidth / mapscale); + return lon; + } + + private double unScaleLatitude(double lat) + { + lat -= lat_offset; + lat += 90; + lat *= mapscale; + return lat; + } + + private double unScaleLongitude(double lon) + { + lon -= lon_offset; + lon += 180; + lon *= mapscale; + return lon; + } + + private double fixUnscale(double value, int size) + { + if (value < 0) + value = 0; + else if (value >= size - 0.5) + value = size - 1; + return value; + } + + /* MAP: internal state */ + private mapType mType; + private Texture2D map; // refs above: 214,215,216,232, below, and JSISCANsatRPM. + private CelestialBody body; // all refs are below + private SCANresource resource; + private SCANmapLegend mapLegend; + private int mapstep; // all refs are below + private double[] mapline; // all refs are below + + /* MAP: nearly trivial functions */ + public void setBody(CelestialBody b) + { + if (body == b) + return; + body = b; + //SCANcontroller.controller.Resources(b); //Repopulate resource list when changing SOI + if (SCANcontroller.controller.GlobalResourceOverlay) + resource = SCANcontroller.controller.ResourceList[SCANcontroller.controller.resourceSelection][b.name]; + resetMap(); + } + + internal bool isMapComplete() + { + if (map == null) + return false; + return mapstep >= map.height; + } + + public void resetMap() + { + mapstep = 0; + if (SCANcontroller.controller.GlobalResourceOverlay) + { //Make sure that a resource is initialized if necessary + if (resource == null && body != null) resource = SCANcontroller.controller.ResourceList[SCANcontroller.controller.resourceSelection][body.name]; + if (SCANcontroller.controller.resourceOverlayType == 1) + SCANcontroller.controller.KethaneReset = !SCANcontroller.controller.KethaneReset; + } + } + + public void resetMap(mapType mode, bool Cache) + { + mType = mode; + cache = Cache; + resetMap(); + } + + /* MAP: export: PNG file */ + internal void exportPNG() + { + string path = Path.Combine(new DirectoryInfo(KSPUtil.ApplicationRootPath).FullName, "GameData/SCANsat/PluginData/").Replace("\\", "/"); + string mode = ""; + + switch (mType) + { + case mapType.Altimetry: mode = "elevation"; break; + case mapType.Slope: mode = "slope"; break; + case mapType.Biome: mode = "biome"; break; + } + if (SCANcontroller.controller.map_ResourceOverlay && SCANcontroller.controller.GlobalResourceOverlay && !string.IsNullOrEmpty(SCANcontroller.controller.resourceSelection)) + mode += "-" + SCANcontroller.controller.resourceSelection; + if (SCANcontroller.controller.colours == 1) + mode += "-grey"; + string filename = string.Format("{0}_{1}_{2}x{3}", body.name, mode, map.width, map.height); + if (projection != MapProjection.Rectangular) + filename += "_" + projection.ToString(); + filename += ".png"; + + string fullPath = Path.Combine(path, filename); + System.IO.File.WriteAllBytes(fullPath, map.EncodeToPNG()); + + ScreenMessages.PostScreenMessage("Map saved: GameData/SCANsat/PluginData/" + filename, 8, ScreenMessageStyle.UPPER_CENTER); + } + + /* MAP: build: map to Texture2D */ + internal Texture2D getPartialMap() + { + SCANdata data = SCANUtil.getData(body); + if (data == null) + return new Texture2D(1, 1); + Color[] pix; + + /* init cache if necessary */ + if (cache) + { + if (body != big_heightmap_body) + { + for (int x = 0; x < mapwidth; x++) + { + for (int y = 0; y < mapwidth / 2; y++) + big_heightmap[x, y] = 0f; + } + big_heightmap_body = body; + } + } + + if (map == null) + { + map = new Texture2D(mapwidth, mapheight, TextureFormat.ARGB32, false); + pix = map.GetPixels(); + for (int i = 0; i < pix.Length; ++i) + pix[i] = palette.clear; + map.SetPixels(pix); + } + else if (mapstep >= map.height) + { + return map; + } + + if (palette.redline == null || palette.redline.Length != map.width) + { + palette.redline = new Color[map.width]; + for (int i = 0; i < palette.redline.Length; ++i) + palette.redline[i] = palette.red; + } + + if (mapstep < map.height - 1) + { + map.SetPixels(0, mapstep + 1, map.width, 1, palette.redline); + } + + if (mapstep <= 0) + { + mapstep = 0; + mapline = new double[map.width]; + } + + pix = map.GetPixels(0, mapstep, map.width, 1); + + for (int i = 0; i < map.width; i++) + { + Color baseColor = palette.grey; + pix[i] = baseColor; + int scheme = SCANcontroller.controller.colours; + float projVal = 0f; + double lat = (mapstep * 1.0f / mapscale) - 90f + lat_offset; + double lon = (i * 1.0f / mapscale) - 180f + lon_offset; + double la = lat, lo = lon; + lat = unprojectLatitude(lo, la); + lon = unprojectLongitude(lo, la); + + /* Introduce altimetry check here; Use unprojected lat/long coordinates + * All cached altimetry data stored in a single 2D array in rectangular format + * Pull altimetry data from cache after unprojection + */ + + if (body.pqsController != null && cache) + { + if (big_heightmap[i, mapstep] == 0f) + { + if (SCANUtil.isCovered(lo, la, data, SCANtype.Altimetry)) + terrainHeightToArray(lo, la, i, mapstep); + } + } + + if (double.IsNaN(lat) || double.IsNaN(lon) || lat < -90 || lat > 90 || lon < -180 || lon > 180) + { + pix[i] = palette.clear; + continue; + } + + if (mType == mapType.Altimetry) + { + if (body.pqsController == null) + { + baseColor = palette.lerp(palette.black, palette.white, UnityEngine.Random.value); + } + else if (SCANUtil.isCovered(lon, lat, data, SCANtype.Altimetry)) + { + projVal = terrainElevation(lon, lat, data, out scheme); + baseColor = palette.heightToColor(projVal, scheme, data); + } + + // if (cache) + // { + // projVal = big_heightmap[unScaleLongitude(lon), unScaleLatitude(lat)]; + // if (projVal == 0f) + // projVal = (float)SCANUtil.getElevation(body, lon, lat); + // } + // else + // projVal = (float)SCANUtil.getElevation(body, lon, lat); + // baseColor = palette.heightToColor(projVal, scheme, data); + //} + //else if (SCANUtil.isCovered(lon, lat, data, SCANtype.AltimetryLoRes)) + //{ + // // basic altimetry gets forced greyscale with lower resolution + // if (cache) + // { + // projVal = big_heightmap[(unScaleLongitude(lon) * 5) / 5, (unScaleLatitude(lat) * 5) / 5]; + // if (projVal == 0f) + // projVal = (float)SCANUtil.getElevation(body, ((int)(lon * 5)) / 5, ((int)(lat * 5)) / 5); + // } + // else + // projVal = (float)SCANUtil.getElevation(body, ((int)(lon * 5)) / 5, ((int)(lat * 5)) / 5); + // baseColor = palette.heightToColor(projVal, 1, data); + //} + mapline[i] = projVal; + + if (SCANcontroller.controller.map_ResourceOverlay && SCANcontroller.controller.GlobalResourceOverlay) + { + pix[i] = resourceToColor(lon, lat, data, baseColor); + + //if (SCANcontroller.controller.resourceOverlayType == 0 && SCANversions.RegolithFound) + //{ + // if (SCANUtil.isCovered(lon, lat, data, resource.Type)) //check our new resource coverage map + // { + // double amount = SCANUtil.RegolithOverlay(lat, lon, resource.Name, body.flightGlobalsIndex); //grab the resource amount for the current pixel + // double scalar = resource.MinValue + ((resource.MaxValue - resource.MinValue) / 5); + // amount *= 100; + // if (amount > scalar) + // { + // if (amount > 100) amount = 100; + // pix[i] = palette.lerp(baseColor, palette.lerp(resource.EmptyColor, resource.FullColor, (float)(amount) / (resource.MaxValue - resource.MinValue)), 0.3f); //vary color by resource amount + // } + // else pix[i] = palette.lerp(baseColor, palette.grey, 0.4f); + // } + // else pix[i] = baseColor; + //} + //else if (SCANcontroller.controller.resourceOverlayType == 1) //Kethane overlay + //{ + // if (SCANUtil.isCovered(lon, lat, data, resource.Type)) + // { + // int ilon = SCANUtil.icLON(lon); + // int ilat = SCANUtil.icLAT(lat); + // float amount = data.KethaneValueMap[ilon, ilat]; //Fetch Kethane resource values from cached array + // if (amount <= 0) pix[i] = palette.lerp(baseColor, palette.grey, 0.4f); + // else + // { + // pix[i] = palette.lerp(baseColor, palette.lerp(resource.EmptyColor, resource.FullColor, amount / resource.MaxValue), 0.8f); + // } + // } + // else pix[i] = baseColor; + //} + //else pix[i] = baseColor; + } + else pix[i] = baseColor; + + /* draw height lines - works, but mostly useless... + int step = (int)(val / 1000); + int step_h = step, step_v = step; + if(i > 0) step_h = (int)(bigline[i - 1] / 1000); + if(bigstep > 0) step_v = (int)(bigline[i] / 1000); + if(step != step_h || step != step_v) { + pix[i] = palette.white; + } + */ + //mapline [i] = val; + } + + else if (mType == mapType.Slope) + { + if (body.pqsController == null) + { + baseColor = palette.lerp(palette.black, palette.white, UnityEngine.Random.value); + } + else if (SCANUtil.isCovered(lon, lat, data, SCANtype.Altimetry)) + { + projVal = terrainElevation(lon, lat, data, out scheme); + + //if (SCANUtil.isCovered(lon, lat, data, SCANtype.AltimetryHiRes)) + //{ + // if (cache) + // { + // projVal = big_heightmap[unScaleLongitude(lon), unScaleLatitude(lat)]; + // if (projVal == 0f) + // projVal = (float)SCANUtil.getElevation(body, lon, lat); + // } + // else + // projVal = (float)SCANUtil.getElevation(body, lon, lat); + //} + //else + //{ + // if (cache) + // { + // projVal = big_heightmap[(unScaleLongitude(lon) * 5) / 5, (unScaleLatitude(lat) * 5) / 5]; + // if (projVal == 0f) + // projVal = (float)SCANUtil.getElevation(body, ((int)(lon * 5)) / 5, ((int)(lat * 5)) / 5); + // } + // else + // projVal = (float)SCANUtil.getElevation(body, ((int)(lon * 5)) / 5, ((int)(lat * 5)) / 5); + //} + if (mapstep == 0) + { + baseColor = palette.grey; + } + else + { + // This doesn't actually calculate the slope per se, but it's faster + // than asking for yet more elevation data. Please don't use this + // code to operate nuclear power plants or rockets. + double v1 = mapline[i]; + if (i > 0) + v1 = Math.Max(v1, mapline[i - 1]); + if (i < mapline.Length - 1) + v1 = Math.Max(v1, mapline[i + 1]); + float v = Mathf.Clamp((float)Math.Abs(projVal - v1) / 1000f, 0, 2f); + if (SCANcontroller.controller.colours == 1) + { + baseColor = palette.lerp(palette.black, palette.white, v / 2f); + } + else + { + if (v < 1) + { + baseColor = palette.lerp(palette.xkcd_PukeGreen, palette.xkcd_Lemon, v); + } + else + { + baseColor = palette.lerp(palette.xkcd_Lemon, palette.xkcd_OrangeRed, v - 1); + } + } + } + mapline[i] = projVal; + } + if (SCANcontroller.controller.map_ResourceOverlay && SCANcontroller.controller.GlobalResourceOverlay) + { + pix[i] = resourceToColor(lon, lat, data, baseColor); + + //if (SCANcontroller.controller.resourceOverlayType == 0 && SCANversions.RegolithFound) + //{ + // if (SCANUtil.isCovered(lon, lat, data, resource.Type)) //check our new resource coverage map + // { + // double amount = SCANUtil.RegolithOverlay(lat, lon, resource.Name, body.flightGlobalsIndex); //grab the resource amount for the current pixel + // double scalar = resource.MinValue + ((resource.MaxValue - resource.MinValue) / 5); + // amount *= 100; + // if (amount > scalar) + // { + // if (amount > 100) amount = 100; //max cutoff value + // pix[i] = palette.lerp(baseColor, palette.lerp(resource.EmptyColor, resource.FullColor, (float)(amount) / (resource.MaxValue - resource.MinValue)), 0.3f); //vary color by resource amount + // } + // else pix[i] = palette.lerp(baseColor, palette.grey, 0.4f); + // } + // else pix[i] = baseColor; + //} + //else if (SCANcontroller.controller.resourceOverlayType == 1) + //{ + // if (SCANUtil.isCovered(lon, lat, data, resource.Type)) + // { + // int ilon = SCANUtil.icLON(lon); + // int ilat = SCANUtil.icLAT(lat); + // float amount = data.KethaneValueMap[ilon, ilat]; + // if (amount <= 0) pix[i] = palette.lerp(baseColor, palette.grey, 0.4f); + // else + // { + // pix[i] = palette.lerp(baseColor, palette.lerp(resource.EmptyColor, resource.FullColor, amount / resource.MaxValue), 0.8f); + // } + // } + // else pix[i] = baseColor; + //} + //else pix[i] = baseColor; + } + else pix[i] = baseColor; + } + + else if (mType == mapType.Biome) + { + if (body.BiomeMap == null) + { + baseColor = palette.lerp(palette.black, palette.white, UnityEngine.Random.value); + } + /* // this just basically stretches the actual biome map to fit... it looks horrible + float u = ((lon + 360 + 180 + 90)) % 360; + float v = ((lat + 180 + 90)) % 180; + if(u < 0 || v < 0 || u >= 360 || v >= 180) continue; + u /= 360f; v /= 180f; + pix[i] = body.BiomeMap.Map.GetPixelBilinear(u, v); + */ + else if (SCANUtil.isCovered(lon, lat, data, SCANtype.Biome)) + { + double bio = SCANUtil.getBiomeIndexFraction(body, lon, lat); + Color biome = palette.grey; + if (SCANcontroller.controller.colours == 1) + { + if ((i > 0 && mapline[i - 1] != bio) || (mapstep > 0 && mapline[i] != bio)) + { + biome = palette.white; + } + else + { + biome = palette.lerp(palette.black, palette.white, (float)bio); + } + } + else + { + Color elevation = palette.grey; + if (body.pqsController == null) + { + baseColor = palette.lerp(palette.black, palette.white, UnityEngine.Random.value); + } + else if (SCANUtil.isCovered(lon, lat, data, SCANtype.Altimetry)) + { + projVal = terrainElevation(lon, lat, data, out scheme); + + //if (SCANUtil.isCovered(lon, lat, data, SCANtype.AltimetryHiRes)) + //{ + // if (cache) + // { + // projVal = big_heightmap[unScaleLongitude(lon), unScaleLatitude(lat)]; + // if (projVal == 0f) + // projVal = (float)SCANUtil.getElevation(body, lon, lat); + // } + // else + // projVal = (float)SCANUtil.getElevation(body, lon, lat); + //} + //else + //{ + // if (cache) + // { + // projVal = big_heightmap[(unScaleLongitude(lon) * 5) / 5, (unScaleLatitude(lat) * 5) / 5]; + // if (projVal == 0f) + // projVal = (float)SCANUtil.getElevation(body, ((int)(lon * 5)) / 5, ((int)(lat * 5)) / 5); + // } + // else + // projVal = (float)SCANUtil.getElevation(body, ((int)(lon * 5)) / 5, ((int)(lat * 5)) / 5); + //} + + elevation = palette.lerp(palette.black, palette.white, Mathf.Clamp(projVal + 1500f, 0, 9000) / 9000f); + } + Color bio1 = palette.xkcd_CamoGreen; + Color bio2 = palette.xkcd_Marigold; + if ((i > 0 && mapline[i - 1] != bio) || (mapstep > 0 && mapline[i] != bio)) + { + //biome = palette.lerp(palette.xkcd_Puce, elevation, 0.5f); + biome = palette.white; + } + else + { + biome = palette.lerp(palette.lerp(bio1, bio2, (float)bio), elevation, 0.5f); + } + } + + baseColor = biome; + mapline[i] = bio; + } + if (SCANcontroller.controller.map_ResourceOverlay && SCANcontroller.controller.GlobalResourceOverlay) + { + pix[i] = resourceToColor(lon, lat, data, baseColor); + + //if (SCANcontroller.controller.resourceOverlayType == 0 && SCANversions.RegolithFound) + //{ + // if (SCANUtil.isCovered(lon, lat, data, resource.Type)) //check our new resource coverage map + // { + // double amount = SCANUtil.RegolithOverlay(lat, lon, resource.Name, body.flightGlobalsIndex); //grab the resource amount for the current pixel + // double scalar = resource.MinValue + ((resource.MaxValue - resource.MinValue) / 5); + // amount *= 100; + // if (amount > scalar) + // { + // if (amount > 100) amount = 100; //max cutoff value + // pix[i] = palette.lerp(baseColor, palette.lerp(resource.EmptyColor, resource.FullColor, (float)(amount) / (resource.MaxValue - resource.MinValue)), 0.3f); //vary color by resource amount + // } + // else pix[i] = palette.lerp(baseColor, palette.grey, 0.4f); + // } + // else pix[i] = baseColor; + //} + //else if (SCANcontroller.controller.resourceOverlayType == 1) + //{ + // if (SCANUtil.isCovered(lon, lat, data, resource.Type)) + // { + // int ilon = SCANUtil.icLON(lon); + // int ilat = SCANUtil.icLAT(lat); + // float amount = data.KethaneValueMap[ilon, ilat]; + // if (amount <= 0) pix[i] = palette.lerp(baseColor, palette.grey, 0.4f); + // else + // { + // pix[i] = palette.lerp(baseColor, palette.lerp(resource.EmptyColor, resource.FullColor, amount / resource.MaxValue), 0.8f); + // } + // } + // else pix[i] = baseColor; + //} + //else pix[i] = baseColor; + } + else pix[i] = baseColor; + } + } + map.SetPixels(0, mapstep, map.width, 1, pix); + mapstep++; + if (mapstep % 10 == 0 || mapstep >= map.height) + map.Apply(); + return map; + } + + private float terrainElevation(double Lon, double Lat, SCANdata Data, out int Scheme) + { + float elevation = 0f; + Scheme = SCANcontroller.controller.colours; + if (SCANUtil.isCovered(Lon, Lat, Data, SCANtype.AltimetryHiRes)) + { + if (cache) + { + double lon = fixUnscale(unScaleLongitude(Lon), mapwidth); + double lat = fixUnscale(unScaleLatitude(Lat), mapheight); + elevation = big_heightmap[Mathf.RoundToInt((float)lon), Mathf.RoundToInt((float)lat)]; + if (elevation== 0f) + elevation = (float)SCANUtil.getElevation(body, Lon, Lat); + } + else + elevation = (float)SCANUtil.getElevation(body, Lon, Lat); + } + else + { + if (cache) + { + double lon = fixUnscale(unScaleLongitude(Lon), mapwidth); + double lat = fixUnscale(unScaleLatitude(Lat), mapheight); + elevation = big_heightmap[((int)(lon * 5)) / 5, ((int)(lat * 5)) / 5]; + if (elevation == 0f) + elevation = (float)SCANUtil.getElevation(body, ((int)(Lon * 5)) / 5, ((int)(Lat * 5)) / 5); + } + else + elevation = (float)SCANUtil.getElevation(body, ((int)(Lon * 5)) / 5, ((int)(Lat * 5)) / 5); + Scheme = 1; + } + + return elevation; + } + + private double resourceMapValue(double Lon, double Lat, SCANdata Data) + { + double amount = 0; + if (SCANcontroller.controller.resourceOverlayType == 0 && SCANversions.RegolithFound) + { + if (SCANUtil.isCovered(Lon, Lat, Data, resource.Type)) //check our new resource coverage map + { + amount = SCANUtil.RegolithOverlay(Lat, Lon, resource.Name, body.flightGlobalsIndex); //grab the resource amount for the current pixel + double scalar = resource.MinValue + ((resource.MaxValue - resource.MinValue) / 5); + amount *= 100; + if (amount > scalar) + { + if (amount > 100) + amount = 100; //max cutoff value + } + else + amount = 0; + } + else + amount = -1; + } + else if (SCANcontroller.controller.resourceOverlayType == 1) + { + if (SCANUtil.isCovered(Lon, Lat, Data, resource.Type)) + { + int ilon = SCANUtil.icLON(Lon); + int ilat = SCANUtil.icLAT(Lat); + amount = Data.KethaneValueMap[ilon, ilat]; + } + else + amount = -1; + } + return amount; + } + + private Color resourceToColor (double Lon, double Lat, SCANdata Data, Color BaseColor) + { + double amount = resourceMapValue(Lon, Lat, Data); + if (amount < 0) + return BaseColor; + else if (amount == 0) + return palette.lerp(BaseColor, palette.grey, 0.4f); + else if (SCANcontroller.controller.resourceOverlayType == 0 && SCANversions.RegolithFound) + return palette.lerp(BaseColor, palette.lerp(resource.EmptyColor, resource.FullColor, (float)amount / (resource.MaxValue - resource.MinValue)), 0.3f); + else if (SCANcontroller.controller.resourceOverlayType == 1) + return palette.lerp(BaseColor, palette.lerp(resource.EmptyColor, resource.FullColor, (float)amount / resource.MaxValue), 0.8f); + + return BaseColor; + } + + } +} diff --git a/SCANsat/SCAN_Map/SCANmapLegend.cs b/SCANsat/SCAN_Map/SCANmapLegend.cs new file mode 100644 index 000000000..39b266edb --- /dev/null +++ b/SCANsat/SCAN_Map/SCANmapLegend.cs @@ -0,0 +1,84 @@ +#region license +/* + * [Scientific Committee on Advanced Navigation] + * S.C.A.N. Satellite + * + * SCANmapLegend - Object to store data on map legend textures + * + * Copyright (c)2013 damny; + * Copyright (c)2014 technogeeky ; + * Copyright (c)2014 (Your Name Here) ; see LICENSE.txt for licensing details. +*/ +#endregion + +using System; +using SCANsat.SCAN_Platform.Palettes; +using SCANsat.SCAN_Data; +using palette = SCANsat.SCAN_UI.UI_Framework.SCANpalette; + +using UnityEngine; + +namespace SCANsat.SCAN_Map +{ + public class SCANmapLegend + { + private Texture2D legend; + private float legendMin, legendMax; + private Palette dataPalette; + private int legendScheme; + + public Texture2D Legend + { + get { return legend; } + set { legend = value; } + } + + internal Texture2D getLegend(float min, float max, int scheme, SCANdata data) + { + if (legend != null && legendMin == min && legendMax == max && legendScheme == scheme && data.ColorPalette == dataPalette) + return legend; + legend = new Texture2D(256, 1, TextureFormat.RGB24, false); + legendMin = min; + legendMax = max; + legendScheme = scheme; + dataPalette = data.ColorPalette; + Color[] pix = legend.GetPixels(); + for (int x = 0; x < 256; ++x) + { + float val = (x * (max - min)) / 256f + min; + pix[x] = palette.heightToColor(val, scheme, data); + } + legend.SetPixels(pix); + legend.Apply(); + return legend; + } + + internal Texture2D getLegend(int scheme, SCANdata data) + { + Texture2D t = new Texture2D(256, 1, TextureFormat.RGB24, false); + Color[] pix = t.GetPixels(); + for (int x = 0; x < 256; ++x) + { + float val = (x * (data.MaxHeight - data.MinHeight)) / 256f + data.MinHeight; + pix[x] = palette.heightToColor(val, scheme, data); + } + t.SetPixels(pix); + t.Apply(); + return t; + } + + internal Texture2D getLegend(float max, float min, float? clamp, bool discrete, Color32[] c) + { + Texture2D t = new Texture2D(128, 1, TextureFormat.RGB24, false); + Color[] pix = t.GetPixels(); + for (int x = 0; x < 128; x++) + { + float val = (x * (max - min)) / 128f + min; + pix[x] = palette.heightToColor(val, max, min, clamp, discrete, c); + } + t.SetPixels(pix); + t.Apply(); + return t; + } + } +} diff --git a/SCANsat/SCAN_Map/SCANmapProjection.cs b/SCANsat/SCAN_Map/SCANmapProjection.cs new file mode 100644 index 000000000..e36c6f447 --- /dev/null +++ b/SCANsat/SCAN_Map/SCANmapProjection.cs @@ -0,0 +1,38 @@ +#region license +/* + * [Scientific Committee on Advanced Navigation] + * S.C.A.N. Satellite + * + * SCANmapProjection - SCANsat projection types + * + * Copyright (c)2013 damny; + * Copyright (c)2014 technogeeky ; + * Copyright (c)2014 (Your Name Here) ; see LICENSE.txt for licensing details. +*/ +#endregion + +using System; + +namespace SCANsat.SCAN_Map +{ + public class SCANmapProjection + { + public static string[] projectionNames = getProjectionNames(); + + private static string[] getProjectionNames() + { + MapProjection[] v = (MapProjection[])Enum.GetValues(typeof(MapProjection)); + string[] r = new string[v.Length]; + for (int i = 0; i < v.Length; ++i) + r[i] = v[i].ToString(); + return r; + } + } + + public enum MapProjection + { + Rectangular = 0, + KavrayskiyVII = 1, + Polar = 2, + } +} diff --git a/SCANsat/SCAN_Map/SCANmapType.cs b/SCANsat/SCAN_Map/SCANmapType.cs new file mode 100644 index 000000000..cbc5c239d --- /dev/null +++ b/SCANsat/SCAN_Map/SCANmapType.cs @@ -0,0 +1,38 @@ +#region license +/* + * [Scientific Committee on Advanced Navigation] + * S.C.A.N. Satellite + * + * SCANmapType - All SCANsat map types + * + * Copyright (c)2013 damny; + * Copyright (c)2014 technogeeky ; + * Copyright (c)2014 (Your Name Here) ; see LICENSE.txt for licensing details. +*/ +#endregion + +using System; + +namespace SCANsat.SCAN_Map +{ + public class SCANmapType + { + public static string[] mapTypeNames = getMapTypeNames(); + + private static string[] getMapTypeNames() + { + mapType[] v = (mapType[])Enum.GetValues(typeof(mapType)); + string[] r = new string[v.Length]; + for (int i = 0; i < v.Length; i++) + r[i] = v[i].ToString(); + return r; + } + } + + public enum mapType + { + Altimetry = 0, + Slope = 1, + Biome = 2, + } +} diff --git a/SCANsat/Platform/Attributes/Bounds.cs b/SCANsat/SCAN_Platform/Attributes/Bounds.cs similarity index 99% rename from SCANsat/Platform/Attributes/Bounds.cs rename to SCANsat/SCAN_Platform/Attributes/Bounds.cs index f49a08c30..de9111a4c 100644 --- a/SCANsat/Platform/Attributes/Bounds.cs +++ b/SCANsat/SCAN_Platform/Attributes/Bounds.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.InteropServices; -namespace SCANsat.Platform.Attributes +namespace SCANsat.SCAN_Platform.Attributes { [StructLayout(LayoutKind.Explicit)] public struct AValue { diff --git a/SCANsat/Platform/ColorModels/CMYK.cs b/SCANsat/SCAN_Platform/ColorModels/CMYK.cs similarity index 62% rename from SCANsat/Platform/ColorModels/CMYK.cs rename to SCANsat/SCAN_Platform/ColorModels/CMYK.cs index e1328a219..56310041d 100644 --- a/SCANsat/Platform/ColorModels/CMYK.cs +++ b/SCANsat/SCAN_Platform/ColorModels/CMYK.cs @@ -1,5 +1,5 @@ using System; -namespace SCANsat.Platform.ColorModels +namespace SCANsat.SCAN_Platform.ColorModels { public class CMYK { diff --git a/SCANsat/Platform/ColorModels/HSBA.cs b/SCANsat/SCAN_Platform/ColorModels/HSBA.cs similarity index 98% rename from SCANsat/Platform/ColorModels/HSBA.cs rename to SCANsat/SCAN_Platform/ColorModels/HSBA.cs index 52dd08643..e0bd81df9 100644 --- a/SCANsat/Platform/ColorModels/HSBA.cs +++ b/SCANsat/SCAN_Platform/ColorModels/HSBA.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -using SCANsat.Platform.Attributes; +using SCANsat.SCAN_Platform.Attributes; using UnityEngine; -namespace SCANsat.Platform.ColorModels +namespace SCANsat.SCAN_Platform.ColorModels { public struct HSBA { [Norm(255)] public byte h; // 360 diff --git a/SCANsat/Platform/ColorModels/HSLA.cs b/SCANsat/SCAN_Platform/ColorModels/HSLA.cs similarity index 62% rename from SCANsat/Platform/ColorModels/HSLA.cs rename to SCANsat/SCAN_Platform/ColorModels/HSLA.cs index 53318c5fa..8936c7415 100644 --- a/SCANsat/Platform/ColorModels/HSLA.cs +++ b/SCANsat/SCAN_Platform/ColorModels/HSLA.cs @@ -1,5 +1,5 @@ using System; -namespace SCANsat.Platform.ColorModels +namespace SCANsat.SCAN_Platform.ColorModels { public class HSLA { diff --git a/SCANsat/Platform/ColorModels/HSVA.cs b/SCANsat/SCAN_Platform/ColorModels/HSVA.cs similarity index 98% rename from SCANsat/Platform/ColorModels/HSVA.cs rename to SCANsat/SCAN_Platform/ColorModels/HSVA.cs index 7bced2a98..c5978fd41 100644 --- a/SCANsat/Platform/ColorModels/HSVA.cs +++ b/SCANsat/SCAN_Platform/ColorModels/HSVA.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; -using SCANsat.Platform.Attributes; +using SCANsat.SCAN_Platform.Attributes; using UnityEngine; -namespace SCANsat.Platform.ColorModels +namespace SCANsat.SCAN_Platform.ColorModels { public struct HSVA { [Norm(1.0f)] public float h; diff --git a/SCANsat/Platform/ColorModels/RGBAb.cs b/SCANsat/SCAN_Platform/ColorModels/RGBAb.cs similarity index 62% rename from SCANsat/Platform/ColorModels/RGBAb.cs rename to SCANsat/SCAN_Platform/ColorModels/RGBAb.cs index 9e45fe61d..3e8b786a2 100644 --- a/SCANsat/Platform/ColorModels/RGBAb.cs +++ b/SCANsat/SCAN_Platform/ColorModels/RGBAb.cs @@ -1,5 +1,5 @@ using System; -namespace SCANsat.Platform.ColorModels +namespace SCANsat.SCAN_Platform.ColorModels { public class RGBAb { diff --git a/SCANsat/Platform/ColorModels/RGBAf.cs b/SCANsat/SCAN_Platform/ColorModels/RGBAf.cs similarity index 62% rename from SCANsat/Platform/ColorModels/RGBAf.cs rename to SCANsat/SCAN_Platform/ColorModels/RGBAf.cs index cce57745f..22190d9b6 100644 --- a/SCANsat/Platform/ColorModels/RGBAf.cs +++ b/SCANsat/SCAN_Platform/ColorModels/RGBAf.cs @@ -1,5 +1,5 @@ using System; -namespace SCANsat.Platform.ColorModels +namespace SCANsat.SCAN_Platform.ColorModels { public class RGBAf { diff --git a/SCANsat/Platform/Extensions/Colors/UnityEngine.Color32_.cs b/SCANsat/SCAN_Platform/Extensions/Colors/UnityEngine.Color32_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Colors/UnityEngine.Color32_.cs rename to SCANsat/SCAN_Platform/Extensions/Colors/UnityEngine.Color32_.cs diff --git a/SCANsat/Platform/Extensions/Colors/UnityEngine.Color_.cs b/SCANsat/SCAN_Platform/Extensions/Colors/UnityEngine.Color_.cs similarity index 98% rename from SCANsat/Platform/Extensions/Colors/UnityEngine.Color_.cs rename to SCANsat/SCAN_Platform/Extensions/Colors/UnityEngine.Color_.cs index 7dc3c9efa..e2da24a41 100644 --- a/SCANsat/Platform/Extensions/Colors/UnityEngine.Color_.cs +++ b/SCANsat/SCAN_Platform/Extensions/Colors/UnityEngine.Color_.cs @@ -4,7 +4,7 @@ using SG = System.Globalization; -using Log = SCANsat.Platform.Logging.ConsoleLogger; +using Log = SCANsat.SCAN_Platform.Logging.ConsoleLogger; namespace UnityEngine { diff --git a/SCANsat/Platform/Extensions/Colors/UnityEngine.GradientAlphaKey_.cs b/SCANsat/SCAN_Platform/Extensions/Colors/UnityEngine.GradientAlphaKey_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Colors/UnityEngine.GradientAlphaKey_.cs rename to SCANsat/SCAN_Platform/Extensions/Colors/UnityEngine.GradientAlphaKey_.cs diff --git a/SCANsat/Platform/Extensions/Colors/UnityEngine.GradientColorKey_.cs b/SCANsat/SCAN_Platform/Extensions/Colors/UnityEngine.GradientColorKey_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Colors/UnityEngine.GradientColorKey_.cs rename to SCANsat/SCAN_Platform/Extensions/Colors/UnityEngine.GradientColorKey_.cs diff --git a/SCANsat/Platform/Extensions/Colors/UnityEngine.Gradient_.cs b/SCANsat/SCAN_Platform/Extensions/Colors/UnityEngine.Gradient_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Colors/UnityEngine.Gradient_.cs rename to SCANsat/SCAN_Platform/Extensions/Colors/UnityEngine.Gradient_.cs diff --git a/SCANsat/Platform/Extensions/Data/UnityEngine.SerializeFIeld_.cs b/SCANsat/SCAN_Platform/Extensions/Data/UnityEngine.SerializeFIeld_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Data/UnityEngine.SerializeFIeld_.cs rename to SCANsat/SCAN_Platform/Extensions/Data/UnityEngine.SerializeFIeld_.cs diff --git a/SCANsat/Platform/Extensions/GUI/UnityEngine.GUIContent_.cs b/SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUIContent_.cs similarity index 100% rename from SCANsat/Platform/Extensions/GUI/UnityEngine.GUIContent_.cs rename to SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUIContent_.cs diff --git a/SCANsat/Platform/Extensions/GUI/UnityEngine.GUIElement_.cs b/SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUIElement_.cs similarity index 100% rename from SCANsat/Platform/Extensions/GUI/UnityEngine.GUIElement_.cs rename to SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUIElement_.cs diff --git a/SCANsat/Platform/Extensions/GUI/UnityEngine.GUILayer_.cs b/SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUILayer_.cs similarity index 100% rename from SCANsat/Platform/Extensions/GUI/UnityEngine.GUILayer_.cs rename to SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUILayer_.cs diff --git a/SCANsat/Platform/Extensions/GUI/UnityEngine.GUILayoutOption_.cs b/SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUILayoutOption_.cs similarity index 100% rename from SCANsat/Platform/Extensions/GUI/UnityEngine.GUILayoutOption_.cs rename to SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUILayoutOption_.cs diff --git a/SCANsat/Platform/Extensions/GUI/UnityEngine.GUILayoutUtility_.cs b/SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUILayoutUtility_.cs similarity index 100% rename from SCANsat/Platform/Extensions/GUI/UnityEngine.GUILayoutUtility_.cs rename to SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUILayoutUtility_.cs diff --git a/SCANsat/Platform/Extensions/GUI/UnityEngine.GUILayout_.cs b/SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUILayout_.cs similarity index 100% rename from SCANsat/Platform/Extensions/GUI/UnityEngine.GUILayout_.cs rename to SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUILayout_.cs diff --git a/SCANsat/Platform/Extensions/GUI/UnityEngine.GUISettings_.cs b/SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUISettings_.cs similarity index 100% rename from SCANsat/Platform/Extensions/GUI/UnityEngine.GUISettings_.cs rename to SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUISettings_.cs diff --git a/SCANsat/Platform/Extensions/GUI/UnityEngine.GUISkin_.cs b/SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUISkin_.cs similarity index 96% rename from SCANsat/Platform/Extensions/GUI/UnityEngine.GUISkin_.cs rename to SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUISkin_.cs index 63eeeb266..d95c7f990 100644 --- a/SCANsat/Platform/Extensions/GUI/UnityEngine.GUISkin_.cs +++ b/SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUISkin_.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -using SCANsat.Platform; -using Log = SCANsat.Platform.Logging.ConsoleLogger; +using SCANsat.SCAN_Platform; +using Log = SCANsat.SCAN_Platform.Logging.ConsoleLogger; namespace UnityEngine diff --git a/SCANsat/Platform/Extensions/GUI/UnityEngine.GUIStyleState_.cs b/SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUIStyleState_.cs similarity index 96% rename from SCANsat/Platform/Extensions/GUI/UnityEngine.GUIStyleState_.cs rename to SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUIStyleState_.cs index c2d42def6..5b0221740 100644 --- a/SCANsat/Platform/Extensions/GUI/UnityEngine.GUIStyleState_.cs +++ b/SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUIStyleState_.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using System.Text; -using Log = SCANsat.Platform.Logging.ConsoleLogger; +using Log = SCANsat.SCAN_Platform.Logging.ConsoleLogger; namespace UnityEngine { diff --git a/SCANsat/Platform/Extensions/GUI/UnityEngine.GUIStyle_.cs b/SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUIStyle_.cs similarity index 98% rename from SCANsat/Platform/Extensions/GUI/UnityEngine.GUIStyle_.cs rename to SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUIStyle_.cs index e61969346..5419677bc 100644 --- a/SCANsat/Platform/Extensions/GUI/UnityEngine.GUIStyle_.cs +++ b/SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUIStyle_.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using UnityEngine; -using Log = SCANsat.Platform.Logging.ConsoleLogger; +using Log = SCANsat.SCAN_Platform.Logging.ConsoleLogger; namespace UnityEngine { diff --git a/SCANsat/Platform/Extensions/GUI/UnityEngine.GUIText_.cs b/SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUIText_.cs similarity index 100% rename from SCANsat/Platform/Extensions/GUI/UnityEngine.GUIText_.cs rename to SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUIText_.cs diff --git a/SCANsat/Platform/Extensions/GUI/UnityEngine.GUITexture_.cs b/SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUITexture_.cs similarity index 100% rename from SCANsat/Platform/Extensions/GUI/UnityEngine.GUITexture_.cs rename to SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUITexture_.cs diff --git a/SCANsat/Platform/Extensions/GUI/UnityEngine.GUIUtility_.cs b/SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUIUtility_.cs similarity index 100% rename from SCANsat/Platform/Extensions/GUI/UnityEngine.GUIUtility_.cs rename to SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUIUtility_.cs diff --git a/SCANsat/Platform/Extensions/GUI/UnityEngine.GUI_.cs b/SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUI_.cs similarity index 100% rename from SCANsat/Platform/Extensions/GUI/UnityEngine.GUI_.cs rename to SCANsat/SCAN_Platform/Extensions/GUI/UnityEngine.GUI_.cs diff --git a/SCANsat/SCAN_Platform/Extensions/MJExtensions.cs b/SCANsat/SCAN_Platform/Extensions/MJExtensions.cs new file mode 100644 index 000000000..23229708d --- /dev/null +++ b/SCANsat/SCAN_Platform/Extensions/MJExtensions.cs @@ -0,0 +1,191 @@ +#region license +/* + * This extension is from MechJeb; Used with permission from r4m0n: https://github.com/MuMech/MechJeb2/blob/master/MechJeb2/OrbitExtensions.cs +*/ +#endregion + +using System; +using System.Collections.Generic; + +namespace SCANsat +{ + + public static class OrbitExtensions + { + //Returns whether a has an ascending node with b. This can be false + //if a is hyperbolic and the would-be ascending node is within the opening + //angle of the hyperbola. + public static bool AscendingNodeExists(this Orbit a, Orbit b) + { + return Math.Abs(JUtil.ClampDegrees180(a.AscendingNodeTrueAnomaly(b))) <= a.MaximumTrueAnomaly(); + } + //Gives the true anomaly (in a's orbit) at which a crosses its ascending node + //with b's orbit. + //The returned value is always between 0 and 360. + public static double AscendingNodeTrueAnomaly(this Orbit a, Orbit b) + { + Vector3d vectorToAN = Vector3d.Cross(a.SwappedOrbitNormal(), b.SwappedOrbitNormal()); + return a.TrueAnomalyFromVector(vectorToAN); + + } + //For hyperbolic orbits, the true anomaly only takes on values in the range + // -M < true anomaly < +M for some M. This function computes M. + public static double MaximumTrueAnomaly(this Orbit o) + { + if (o.eccentricity < 1) + return 180; + return 180 / Math.PI * Math.Acos(-1 / o.eccentricity); + } + //normalized vector perpendicular to the orbital plane + //convention: as you look down along the orbit normal, the satellite revolves counterclockwise + public static Vector3d SwappedOrbitNormal(this Orbit o) + { + return -(o.GetOrbitNormal().xzy).normalized; + } + + //Returns whether a has a descending node with b. This can be false + //if a is hyperbolic and the would-be descending node is within the opening + //angle of the hyperbola. + public static bool DescendingNodeExists(this Orbit a, Orbit b) + { + return Math.Abs(JUtil.ClampDegrees180(a.DescendingNodeTrueAnomaly(b))) <= a.MaximumTrueAnomaly(); + } + //Gives the true anomaly (in a's orbit) at which a crosses its descending node + //with b's orbit. + //The returned value is always between 0 and 360. + public static double DescendingNodeTrueAnomaly(this Orbit a, Orbit b) + { + return JUtil.ClampDegrees360(a.AscendingNodeTrueAnomaly(b) + 180); + } + //Returns the next time at which a will cross its ascending node with b. + //For elliptical orbits this is a time between UT and UT + a.period. + //For hyperbolic orbits this can be any time, including a time in the past if + //the ascending node is in the past. + //NOTE: this function will throw an ArgumentException if a is a hyperbolic orbit and the "ascending node" + //occurs at a true anomaly that a does not actually ever attain + public static double TimeOfAscendingNode(this Orbit a, Orbit b, double UT) + { + return a.TimeOfTrueAnomaly(a.AscendingNodeTrueAnomaly(b), UT); + } + //Returns the next time at which a will cross its descending node with b. + //For elliptical orbits this is a time between UT and UT + a.period. + //For hyperbolic orbits this can be any time, including a time in the past if + //the descending node is in the past. + //NOTE: this function will throw an ArgumentException if a is a hyperbolic orbit and the "descending node" + //occurs at a true anomaly that a does not actually ever attain + public static double TimeOfDescendingNode(this Orbit a, Orbit b, double UT) + { + return a.TimeOfTrueAnomaly(a.DescendingNodeTrueAnomaly(b), UT); + } + //NOTE: this function can throw an ArgumentException, if o is a hyperbolic orbit with an eccentricity + //large enough that it never attains the given true anomaly + public static double TimeOfTrueAnomaly(this Orbit o, double trueAnomaly, double UT) + { + return o.UTAtMeanAnomaly(o.GetMeanAnomalyAtEccentricAnomaly(o.GetEccentricAnomalyAtTrueAnomaly(trueAnomaly)), UT); + } + //The next time at which the orbiting object will reach the given mean anomaly. + //For elliptical orbits, this will be a time between UT and UT + o.period + //For hyperbolic orbits, this can be any time, including a time in the past, if + //the given mean anomaly occurred in the past + public static double UTAtMeanAnomaly(this Orbit o, double meanAnomaly, double UT) + { + double currentMeanAnomaly = o.MeanAnomalyAtUT(UT); + double meanDifference = meanAnomaly - currentMeanAnomaly; + if (o.eccentricity < 1) + meanDifference = JUtil.ClampRadiansTwoPi(meanDifference); + return UT + meanDifference / o.MeanMotion(); + } + //Converts an eccentric anomaly into a mean anomaly. + //For an elliptical orbit, the returned value is between 0 and 2pi + //For a hyperbolic orbit, the returned value is any number + public static double GetMeanAnomalyAtEccentricAnomaly(this Orbit o, double E) + { + double e = o.eccentricity; + if (e < 1) + { //elliptical orbits + return JUtil.ClampRadiansTwoPi(E - (e * Math.Sin(E))); + } //hyperbolic orbits + return (e * Math.Sinh(E)) - E; + } + //Originally by Zool, revised by The_Duck + //Converts a true anomaly into an eccentric anomaly. + //For elliptical orbits this returns a value between 0 and 2pi + //For hyperbolic orbits the returned value can be any number. + //NOTE: For a hyperbolic orbit, if a true anomaly is requested that does not exist (a true anomaly + //past the true anomaly of the asymptote) then an ArgumentException is thrown + public static double GetEccentricAnomalyAtTrueAnomaly(this Orbit o, double trueAnomaly) + { + double e = o.eccentricity; + trueAnomaly = JUtil.ClampDegrees360(trueAnomaly); + trueAnomaly = trueAnomaly * (Math.PI / 180); + + if (e < 1) + { //elliptical orbits + double cosE = (e + Math.Cos(trueAnomaly)) / (1 + e * Math.Cos(trueAnomaly)); + double sinE = Math.Sqrt(1 - (cosE * cosE)); + if (trueAnomaly > Math.PI) + sinE *= -1; + + return JUtil.ClampRadiansTwoPi(Math.Atan2(sinE, cosE)); + } + else + { //hyperbolic orbits + double coshE = (e + Math.Cos(trueAnomaly)) / (1 + e * Math.Cos(trueAnomaly)); + if (coshE < 1) + throw new ArgumentException("OrbitExtensions.GetEccentricAnomalyAtTrueAnomaly: True anomaly of " + trueAnomaly + " radians is not attained by orbit with eccentricity " + o.eccentricity); + + double E = JUtil.Acosh(coshE); + if (trueAnomaly > Math.PI) + E *= -1; + + return E; + } + } + //The mean anomaly of the orbit. + //For elliptical orbits, the value return is always between 0 and 2pi + //For hyperbolic orbits, the value can be any number. + public static double MeanAnomalyAtUT(this Orbit o, double UT) + { + double ret = o.meanAnomalyAtEpoch + o.MeanMotion() * (UT - o.epoch); + if (o.eccentricity < 1) + ret = JUtil.ClampRadiansTwoPi(ret); + return ret; + } + //mean motion is rate of increase of the mean anomaly + public static double MeanMotion(this Orbit o) + { + return Math.Sqrt(o.referenceBody.gravParameter / Math.Abs(Math.Pow(o.semiMajorAxis, 3))); + } + //Converts a direction, specified by a Vector3d, into a true anomaly. + //The vector is projected into the orbital plane and then the true anomaly is + //computed as the angle this vector makes with the vector pointing to the periapsis. + //The returned value is always between 0 and 360. + public static double TrueAnomalyFromVector(this Orbit o, Vector3d vec) + { + Vector3d projected = Vector3d.Exclude(o.SwappedOrbitNormal(), vec); + Vector3d vectorToPe = o.eccVec.xzy; + double angleFromPe = Math.Abs(Vector3d.Angle(vectorToPe, projected)); + + //If the vector points to the infalling part of the orbit then we need to do 360 minus the + //angle from Pe to get the true anomaly. Test this by taking the the cross product of the + //orbit normal and vector to the periapsis. This gives a vector that points to center of the + //outgoing side of the orbit. If vectorToAN is more than 90 degrees from this vector, it occurs + //during the infalling part of the orbit. + if (Math.Abs(Vector3d.Angle(projected, Vector3d.Cross(o.SwappedOrbitNormal(), vectorToPe))) < 90) + { + return angleFromPe; + } + return 360 - angleFromPe; + } + //distance from the center of the planet + public static double Radius(this Orbit o, double UT) + { + return o.SwappedRelativePositionAtUT(UT).magnitude; + } + //position relative to the primary + public static Vector3d SwappedRelativePositionAtUT(this Orbit o, double UT) + { + return o.getRelativePositionAtUT(UT).xzy; + } + } +} diff --git a/SCANsat/Platform/Extensions/Math/UnityEngine.Mathf_.cs b/SCANsat/SCAN_Platform/Extensions/Math/UnityEngine.Mathf_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Math/UnityEngine.Mathf_.cs rename to SCANsat/SCAN_Platform/Extensions/Math/UnityEngine.Mathf_.cs diff --git a/SCANsat/Platform/Extensions/Math/UnityEngine.Matrix4x4_.cs b/SCANsat/SCAN_Platform/Extensions/Math/UnityEngine.Matrix4x4_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Math/UnityEngine.Matrix4x4_.cs rename to SCANsat/SCAN_Platform/Extensions/Math/UnityEngine.Matrix4x4_.cs diff --git a/SCANsat/Platform/Extensions/Math/UnityEngine.Random_.cs b/SCANsat/SCAN_Platform/Extensions/Math/UnityEngine.Random_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Math/UnityEngine.Random_.cs rename to SCANsat/SCAN_Platform/Extensions/Math/UnityEngine.Random_.cs diff --git a/SCANsat/Platform/Extensions/Math/UnityEngine.RectOffset_.cs b/SCANsat/SCAN_Platform/Extensions/Math/UnityEngine.RectOffset_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Math/UnityEngine.RectOffset_.cs rename to SCANsat/SCAN_Platform/Extensions/Math/UnityEngine.RectOffset_.cs diff --git a/SCANsat/Platform/Extensions/Math/UnityEngine.Rect_.cs b/SCANsat/SCAN_Platform/Extensions/Math/UnityEngine.Rect_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Math/UnityEngine.Rect_.cs rename to SCANsat/SCAN_Platform/Extensions/Math/UnityEngine.Rect_.cs diff --git a/SCANsat/Platform/Extensions/Math/UnityEngine.Vector2_.cs b/SCANsat/SCAN_Platform/Extensions/Math/UnityEngine.Vector2_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Math/UnityEngine.Vector2_.cs rename to SCANsat/SCAN_Platform/Extensions/Math/UnityEngine.Vector2_.cs diff --git a/SCANsat/Platform/Extensions/Math/UnityEngine.Vector3_.cs b/SCANsat/SCAN_Platform/Extensions/Math/UnityEngine.Vector3_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Math/UnityEngine.Vector3_.cs rename to SCANsat/SCAN_Platform/Extensions/Math/UnityEngine.Vector3_.cs diff --git a/SCANsat/Platform/Extensions/Math/UnityEngine.Vector4_.cs b/SCANsat/SCAN_Platform/Extensions/Math/UnityEngine.Vector4_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Math/UnityEngine.Vector4_.cs rename to SCANsat/SCAN_Platform/Extensions/Math/UnityEngine.Vector4_.cs diff --git a/SCANsat/Platform/Extensions/Rendering/UnityEngine.Mesh_.cs b/SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.Mesh_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Rendering/UnityEngine.Mesh_.cs rename to SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.Mesh_.cs diff --git a/SCANsat/Platform/Extensions/Rendering/UnityEngine.RenderSettings_.cs b/SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.RenderSettings_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Rendering/UnityEngine.RenderSettings_.cs rename to SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.RenderSettings_.cs diff --git a/SCANsat/Platform/Extensions/Rendering/UnityEngine.Screen_.cs b/SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.Screen_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Rendering/UnityEngine.Screen_.cs rename to SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.Screen_.cs diff --git a/SCANsat/Platform/Extensions/Rendering/UnityEngine.Shader_.cs b/SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.Shader_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Rendering/UnityEngine.Shader_.cs rename to SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.Shader_.cs diff --git a/SCANsat/Platform/Extensions/Rendering/UnityEngine.SparseTexture_.cs b/SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.SparseTexture_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Rendering/UnityEngine.SparseTexture_.cs rename to SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.SparseTexture_.cs diff --git a/SCANsat/Platform/Extensions/Rendering/UnityEngine.SpriteRenderer_.cs b/SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.SpriteRenderer_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Rendering/UnityEngine.SpriteRenderer_.cs rename to SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.SpriteRenderer_.cs diff --git a/SCANsat/Platform/Extensions/Rendering/UnityEngine.Texture2D_.cs b/SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.Texture2D_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Rendering/UnityEngine.Texture2D_.cs rename to SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.Texture2D_.cs diff --git a/SCANsat/Platform/Extensions/Rendering/UnityEngine.Texture3D_.cs b/SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.Texture3D_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Rendering/UnityEngine.Texture3D_.cs rename to SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.Texture3D_.cs diff --git a/SCANsat/Platform/Extensions/Rendering/UnityEngine.Texture_.cs b/SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.Texture_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Rendering/UnityEngine.Texture_.cs rename to SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.Texture_.cs diff --git a/SCANsat/Platform/Extensions/Rendering/UnityEngine.TreeInstance_.cs b/SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.TreeInstance_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Rendering/UnityEngine.TreeInstance_.cs rename to SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.TreeInstance_.cs diff --git a/SCANsat/Platform/Extensions/Rendering/UnityEngine.UIVertex_.cs b/SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.UIVertex_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Rendering/UnityEngine.UIVertex_.cs rename to SCANsat/SCAN_Platform/Extensions/Rendering/UnityEngine.UIVertex_.cs diff --git a/SCANsat/Platform/Extensions/Text/UnityEngine.Font_.cs b/SCANsat/SCAN_Platform/Extensions/Text/UnityEngine.Font_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Text/UnityEngine.Font_.cs rename to SCANsat/SCAN_Platform/Extensions/Text/UnityEngine.Font_.cs diff --git a/SCANsat/Platform/Extensions/Text/UnityEngine.TextGenerationSettings_.cs b/SCANsat/SCAN_Platform/Extensions/Text/UnityEngine.TextGenerationSettings_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Text/UnityEngine.TextGenerationSettings_.cs rename to SCANsat/SCAN_Platform/Extensions/Text/UnityEngine.TextGenerationSettings_.cs diff --git a/SCANsat/Platform/Extensions/Text/UnityEngine.TextGenerator_.cs b/SCANsat/SCAN_Platform/Extensions/Text/UnityEngine.TextGenerator_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Text/UnityEngine.TextGenerator_.cs rename to SCANsat/SCAN_Platform/Extensions/Text/UnityEngine.TextGenerator_.cs diff --git a/SCANsat/Platform/Extensions/Text/UnityEngine.TextMesh_.cs b/SCANsat/SCAN_Platform/Extensions/Text/UnityEngine.TextMesh_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Text/UnityEngine.TextMesh_.cs rename to SCANsat/SCAN_Platform/Extensions/Text/UnityEngine.TextMesh_.cs diff --git a/SCANsat/Platform/Extensions/Time/UnityEngine.Event_.cs b/SCANsat/SCAN_Platform/Extensions/Time/UnityEngine.Event_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Time/UnityEngine.Event_.cs rename to SCANsat/SCAN_Platform/Extensions/Time/UnityEngine.Event_.cs diff --git a/SCANsat/Platform/Extensions/Time/UnityEngine.Time_.cs b/SCANsat/SCAN_Platform/Extensions/Time/UnityEngine.Time_.cs similarity index 100% rename from SCANsat/Platform/Extensions/Time/UnityEngine.Time_.cs rename to SCANsat/SCAN_Platform/Extensions/Time/UnityEngine.Time_.cs diff --git a/SCANsat/Platform/Logging.cs b/SCANsat/SCAN_Platform/Logging.cs similarity index 95% rename from SCANsat/Platform/Logging.cs rename to SCANsat/SCAN_Platform/Logging.cs index 83ee1c230..2c239e412 100644 --- a/SCANsat/Platform/Logging.cs +++ b/SCANsat/SCAN_Platform/Logging.cs @@ -1,5 +1,5 @@ using System; -namespace SCANsat.Platform.Logging +namespace SCANsat.SCAN_Platform.Logging { public class ConsoleLogger { diff --git a/SCANsat/Platform/Palettes/ColorBrewer/ColorBrewer.cs b/SCANsat/SCAN_Platform/Palettes/ColorBrewer/ColorBrewer.cs similarity index 99% rename from SCANsat/Platform/Palettes/ColorBrewer/ColorBrewer.cs rename to SCANsat/SCAN_Platform/Palettes/ColorBrewer/ColorBrewer.cs index 20b991e65..c1c6bce75 100644 --- a/SCANsat/Platform/Palettes/ColorBrewer/ColorBrewer.cs +++ b/SCANsat/SCAN_Platform/Palettes/ColorBrewer/ColorBrewer.cs @@ -3,7 +3,7 @@ using UnityEngine; -namespace SCANsat.Platform.Palettes.ColorBrewer { +namespace SCANsat.SCAN_Platform.Palettes.ColorBrewer { public static class BrewerPalettes { static Func RGB = (r,g,b) => new Color32(r,g,b,255); diff --git a/SCANsat/Platform/Palettes/ColorBrewer/Include/Original.cs b/SCANsat/SCAN_Platform/Palettes/ColorBrewer/Include/Original.cs similarity index 99% rename from SCANsat/Platform/Palettes/ColorBrewer/Include/Original.cs rename to SCANsat/SCAN_Platform/Palettes/ColorBrewer/Include/Original.cs index c3cf7a2fb..e10823941 100644 --- a/SCANsat/Platform/Palettes/ColorBrewer/Include/Original.cs +++ b/SCANsat/SCAN_Platform/Palettes/ColorBrewer/Include/Original.cs @@ -5,7 +5,7 @@ using System.Linq; using UnityEngine; -namespace SCANsat.Platform.Palettes.ColorBrewer.Include +namespace SCANsat.SCAN_Platform.Palettes.ColorBrewer.Include { public class Original { diff --git a/SCANsat/Platform/Palettes/FixedColors/FixedColorPalettes.cs b/SCANsat/SCAN_Platform/Palettes/FixedColors/FixedColorPalettes.cs similarity index 98% rename from SCANsat/Platform/Palettes/FixedColors/FixedColorPalettes.cs rename to SCANsat/SCAN_Platform/Palettes/FixedColors/FixedColorPalettes.cs index 65dbe0ae2..d211ebcc7 100644 --- a/SCANsat/Platform/Palettes/FixedColors/FixedColorPalettes.cs +++ b/SCANsat/SCAN_Platform/Palettes/FixedColors/FixedColorPalettes.cs @@ -2,7 +2,7 @@ using UnityEngine; -namespace SCANsat.Platform.Palettes.FixedColors +namespace SCANsat.SCAN_Platform.Palettes.FixedColors { public static class FixedColorPalettes { diff --git a/SCANsat/Platform/Palettes/Palette.cs b/SCANsat/SCAN_Platform/Palettes/Palette.cs similarity index 98% rename from SCANsat/Platform/Palettes/Palette.cs rename to SCANsat/SCAN_Platform/Palettes/Palette.cs index 3476427cc..b6a7065a0 100644 --- a/SCANsat/Platform/Palettes/Palette.cs +++ b/SCANsat/SCAN_Platform/Palettes/Palette.cs @@ -4,7 +4,7 @@ using UnityEngine; -namespace SCANsat.Platform.Palettes +namespace SCANsat.SCAN_Platform.Palettes { [Serializable] public class Palette diff --git a/SCANsat/Platform/Palettes/PaletteLoader.cs b/SCANsat/SCAN_Platform/Palettes/PaletteLoader.cs similarity index 97% rename from SCANsat/Platform/Palettes/PaletteLoader.cs rename to SCANsat/SCAN_Platform/Palettes/PaletteLoader.cs index 9b48c0d16..1755d1d79 100644 --- a/SCANsat/Platform/Palettes/PaletteLoader.cs +++ b/SCANsat/SCAN_Platform/Palettes/PaletteLoader.cs @@ -2,9 +2,9 @@ using System.Collections.Generic; using System.Linq; using UnityEngine; -using palette = SCANsat.SCAN_UI.SCANpalette; +using palette = SCANsat.SCAN_UI.UI_Framework.SCANpalette; -namespace SCANsat.Platform.Palettes +namespace SCANsat.SCAN_Platform.Palettes { static class PaletteLoader { diff --git a/SCANsat/Platform/Palettes/Palettes.cs b/SCANsat/SCAN_Platform/Palettes/Palettes.cs similarity index 97% rename from SCANsat/Platform/Palettes/Palettes.cs rename to SCANsat/SCAN_Platform/Palettes/Palettes.cs index daaf9c30c..603d7952c 100644 --- a/SCANsat/Platform/Palettes/Palettes.cs +++ b/SCANsat/SCAN_Platform/Palettes/Palettes.cs @@ -2,7 +2,7 @@ using UnityEngine; -namespace SCANsat.Platform.Palettes +namespace SCANsat.SCAN_Platform.Palettes { public class _Palettes { diff --git a/SCANsat/Platform/Palettes/Swatches.cs b/SCANsat/SCAN_Platform/Palettes/Swatches.cs similarity index 98% rename from SCANsat/Platform/Palettes/Swatches.cs rename to SCANsat/SCAN_Platform/Palettes/Swatches.cs index fca798c28..55c7eceda 100644 --- a/SCANsat/Platform/Palettes/Swatches.cs +++ b/SCANsat/SCAN_Platform/Palettes/Swatches.cs @@ -6,7 +6,7 @@ using System.Diagnostics; using System.Runtime.InteropServices; -namespace SCANsat.Platform.Palettes +namespace SCANsat.SCAN_Platform.Palettes { public class Swatches : ICollection { diff --git a/SCANsat/Platform/SCAN_CLZF2.cs b/SCANsat/SCAN_Platform/SCAN_CLZF2.cs similarity index 99% rename from SCANsat/Platform/SCAN_CLZF2.cs rename to SCANsat/SCAN_Platform/SCAN_CLZF2.cs index 78363ef74..4859fe448 100644 --- a/SCANsat/Platform/SCAN_CLZF2.cs +++ b/SCANsat/SCAN_Platform/SCAN_CLZF2.cs @@ -1,4 +1,4 @@ -namespace SCANsat.Platform +namespace SCANsat.SCAN_Platform { /* * Found here: diff --git a/SCANsat/Platform/SCAN_KSPAddonImproved.cs b/SCANsat/SCAN_Platform/SCAN_KSPAddonImproved.cs similarity index 99% rename from SCANsat/Platform/SCAN_KSPAddonImproved.cs rename to SCANsat/SCAN_Platform/SCAN_KSPAddonImproved.cs index d2138700b..b6caf85f1 100644 --- a/SCANsat/Platform/SCAN_KSPAddonImproved.cs +++ b/SCANsat/SCAN_Platform/SCAN_KSPAddonImproved.cs @@ -13,7 +13,7 @@ using System.Linq; using System.Collections.Generic; -namespace SCANsat.Platform +namespace SCANsat.SCAN_Platform { [AttributeUsage(AttributeTargets.Class)] diff --git a/SCANsat/Platform/SCAN_MBE.cs b/SCANsat/SCAN_Platform/SCAN_MBE.cs similarity index 98% rename from SCANsat/Platform/SCAN_MBE.cs rename to SCANsat/SCAN_Platform/SCAN_MBE.cs index c646a2309..f1432026d 100644 --- a/SCANsat/Platform/SCAN_MBE.cs +++ b/SCANsat/SCAN_Platform/SCAN_MBE.cs @@ -19,10 +19,10 @@ using UnityEngine; -using Log = SCANsat.Platform.Logging.ConsoleLogger; +using Log = SCANsat.SCAN_Platform.Logging.ConsoleLogger; -namespace SCANsat.Platform +namespace SCANsat.SCAN_Platform { public abstract class SCAN_MBE : MonoBehaviour { diff --git a/SCANsat/Platform/SCAN_MBW.cs b/SCANsat/SCAN_Platform/SCAN_MBW.cs similarity index 99% rename from SCANsat/Platform/SCAN_MBW.cs rename to SCANsat/SCAN_Platform/SCAN_MBW.cs index dd1981591..1dcc4a1df 100644 --- a/SCANsat/Platform/SCAN_MBW.cs +++ b/SCANsat/SCAN_Platform/SCAN_MBW.cs @@ -18,9 +18,9 @@ using System; using UnityEngine; -using Log = SCANsat.Platform.Logging.ConsoleLogger; +using Log = SCANsat.SCAN_Platform.Logging.ConsoleLogger; -namespace SCANsat.Platform +namespace SCANsat.SCAN_Platform { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)] diff --git a/SCANsat/Platform/SCAN_SkinsLibrary.cs b/SCANsat/SCAN_Platform/SCAN_SkinsLibrary.cs similarity index 98% rename from SCANsat/Platform/SCAN_SkinsLibrary.cs rename to SCANsat/SCAN_Platform/SCAN_SkinsLibrary.cs index d7548adb3..633ccf4e0 100644 --- a/SCANsat/Platform/SCAN_SkinsLibrary.cs +++ b/SCANsat/SCAN_Platform/SCAN_SkinsLibrary.cs @@ -21,9 +21,9 @@ using UnityEngine; -using Log = SCANsat.Platform.Logging.ConsoleLogger; +using Log = SCANsat.SCAN_Platform.Logging.ConsoleLogger; -namespace SCANsat.Platform +namespace SCANsat.SCAN_Platform { public static class SCAN_SkinsLibrary diff --git a/SCANsat/SCAN_Toolbar/SCANappLauncher.cs b/SCANsat/SCAN_Toolbar/SCANappLauncher.cs new file mode 100644 index 000000000..4cae59356 --- /dev/null +++ b/SCANsat/SCAN_Toolbar/SCANappLauncher.cs @@ -0,0 +1,89 @@ +#region license +/* + * [Scientific Committee on Advanced Navigation] + * S.C.A.N. Satellite + * + * SCANappLauncher - A class to initialize and destroy the stock app launcher button + * + * Copyright (c)2013 damny; + * Copyright (c)2014 technogeeky ; + * Copyright (c)2014 (Your Name Here) ; see LICENSE.txt for licensing details. +*/ +#endregion + +using System; +using System.Collections; +using SCANsat.SCAN_Platform; +using SCANsat.SCAN_UI; +using SCANsat.SCAN_UI.UI_Framework; + +namespace SCANsat.SCAN_Toolbar +{ + class SCANappLauncher : SCAN_MBE + { + private ApplicationLauncherButton SCANappLauncherButton = null; + + internal override void Start() + { + setupToolbar(); + } + + internal override void OnDestroy() + { + GameEvents.onGUIApplicationLauncherUnreadifying.Remove(removeButton); + + if (SCANappLauncherButton != null) + removeButton(HighLogic.LoadedScene); + } + + private void setupToolbar() + { + SCANUtil.SCANdebugLog("Starting App Launcher Manager"); + StartCoroutine(addButton()); + } + + IEnumerator addButton() + { + SCANUtil.SCANdebugLog("Waiting For Application Launcher..."); + + while (!ApplicationLauncher.Ready) + yield return null; + + if (HighLogic.LoadedScene == GameScenes.FLIGHT) + { + SCANappLauncherButton = ApplicationLauncher.Instance.AddModApplication(toggleFlight, toggleFlight, null, null, null, null, ApplicationLauncher.AppScenes.FLIGHT | ApplicationLauncher.AppScenes.MAPVIEW, SCANskins.SCAN_SmallMapAppIcon); + } + else if (HighLogic.LoadedScene == GameScenes.SPACECENTER || HighLogic.LoadedScene == GameScenes.TRACKSTATION) + { + SCANappLauncherButton = ApplicationLauncher.Instance.AddModApplication(toggleKSC, toggleKSC, null, null, null, null, ApplicationLauncher.AppScenes.SPACECENTER | ApplicationLauncher.AppScenes.TRACKSTATION, SCANskins.SCAN_BigMapAppIcon); + } + + GameEvents.onGUIApplicationLauncherUnreadifying.Add(removeButton); + } + + private void removeButton(GameScenes scene) + { + ApplicationLauncher.Instance.RemoveModApplication(SCANappLauncherButton); + SCANappLauncherButton = null; + SCANUtil.SCANdebugLog("App Launcher Button Removed"); + } + + private void toggleFlight() + { + if (SCANcontroller.controller != null) + { + SCANcontroller.controller.mainMap.Visible = !SCANcontroller.controller.mainMap.Visible; + SCANcontroller.controller.mainMapVisible = !SCANcontroller.controller.mainMapVisible; + } + } + + private void toggleKSC() + { + if (SCANcontroller.controller != null) + { + SCANcontroller.controller.kscMap.Visible = !SCANcontroller.controller.kscMap.Visible; + SCANcontroller.controller.kscMapVisible = !SCANcontroller.controller.kscMapVisible; + } + } + } +} diff --git a/SCANsat/SCAN_UI/UI_Framework/SCANtoolbar.cs b/SCANsat/SCAN_Toolbar/SCANtoolbar.cs similarity index 99% rename from SCANsat/SCAN_UI/UI_Framework/SCANtoolbar.cs rename to SCANsat/SCAN_Toolbar/SCANtoolbar.cs index 714a52350..a16eccc6f 100644 --- a/SCANsat/SCAN_UI/UI_Framework/SCANtoolbar.cs +++ b/SCANsat/SCAN_Toolbar/SCANtoolbar.cs @@ -14,9 +14,9 @@ #endregion using System.IO; using UnityEngine; -using SCANsat.Platform; +using SCANsat.SCAN_Platform; -namespace SCANsat.SCAN_UI +namespace SCANsat.SCAN_Toolbar { [SCAN_KSPAddonImproved(SCAN_KSPAddonImproved.Startup.TimeElapses, false)] class SCANtoolbar : MonoBehaviour diff --git a/SCANsat/SCAN_UI/UI_Framework/SCANtoolbarwrapper.cs b/SCANsat/SCAN_Toolbar/SCANtoolbarwrapper.cs similarity index 99% rename from SCANsat/SCAN_UI/UI_Framework/SCANtoolbarwrapper.cs rename to SCANsat/SCAN_Toolbar/SCANtoolbarwrapper.cs index 4091edf9b..14c656ade 100644 --- a/SCANsat/SCAN_UI/UI_Framework/SCANtoolbarwrapper.cs +++ b/SCANsat/SCAN_Toolbar/SCANtoolbarwrapper.cs @@ -33,7 +33,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE using UnityEngine; -namespace SCANsat.SCAN_UI { +namespace SCANsat.SCAN_Toolbar { diff --git a/SCANsat/SCAN_UI/SCANcolorSelection.cs b/SCANsat/SCAN_UI/SCANcolorSelection.cs index 255ae297e..866a7fa6a 100644 --- a/SCANsat/SCAN_UI/SCANcolorSelection.cs +++ b/SCANsat/SCAN_UI/SCANcolorSelection.cs @@ -15,9 +15,12 @@ using System; using System.Collections.Generic; using System.Linq; -using SCANsat.Platform; -using SCANsat.Platform.Palettes; -using palette = SCANsat.SCAN_UI.SCANpalette; +using SCANsat.SCAN_Data; +using SCANsat.SCAN_Map; +using SCANsat.SCAN_UI.UI_Framework; +using SCANsat.SCAN_Platform; +using SCANsat.SCAN_Platform.Palettes; +using palette = SCANsat.SCAN_UI.UI_Framework.SCANpalette; using UnityEngine; namespace SCANsat.SCAN_UI @@ -30,7 +33,7 @@ class SCANcolorSelection: SCAN_MBW private Palette dataPalette; private int paletteSizeInt, oldPaletteSizeInt = 6; private int paletteIndex; - private Texture2D currentLegend, previewLegend; + private SCANmapLegend currentLegend, previewLegend; private float sizeSlider, sizeSliderMin, sizeSliderMax, terrainSliderMinMin, terrainSliderMinMax, terrainSliderMaxMin, terrainSliderMaxMax, clampSliderMin, clampSliderMax; private float minHeightF, oldMinHeightF = -500; private float maxHeightF, oldMaxHeightF = 8000; @@ -475,7 +478,7 @@ private void palettePreview(int id) fillS(8); GUILayout.Label("", SCANskins.SCAN_legendTex, GUILayout.Width(180), GUILayout.Height(25)); Rect r = GUILayoutUtility.GetLastRect(); - GUI.DrawTexture(r, currentLegend); + GUI.DrawTexture(r, currentLegend.Legend); stopS(); fillS(8); growS(); @@ -483,7 +486,7 @@ private void palettePreview(int id) fillS(8); GUILayout.Label("", SCANskins.SCAN_legendTex, GUILayout.Width(180), GUILayout.Height(25)); r = GUILayoutUtility.GetLastRect(); - GUI.DrawTexture(r, previewLegend); + GUI.DrawTexture(r, previewLegend.Legend); stopS(); } @@ -577,7 +580,9 @@ private void paletteSelectionBox(int id) //Draws the palette swatch for the currently active SCANdata selection private void drawCurrentLegend() { - currentLegend = SCANmap.getLegend(0, data); + currentLegend = new SCANmapLegend(); + currentLegend.Legend = currentLegend.getLegend(0, data); + //currentLegend = SCANmapLegend.getLegend(0, data); } //Draws the palette swatch for the newly adjusted palette @@ -589,7 +594,9 @@ private void drawPreviewLegend() clamp = (float?)clampHeightF; if (reversePalette) c = palette.CurrentPalette.colorsReverse; - previewLegend = SCANmap.getLegend(maxHeightF, minHeightF, clamp, discretePalette, c); + previewLegend = new SCANmapLegend(); + previewLegend.Legend = previewLegend.getLegend(maxHeightF, minHeightF, clamp, discretePalette, c); + //previewLegend = SCANmapLegend.getLegend(maxHeightF, minHeightF, clamp, discretePalette, c); } //Resets the palettes whenever the size slider is adjusted diff --git a/SCANsat/SCAN_UI/SCANinstrumentUI.cs b/SCANsat/SCAN_UI/SCANinstrumentUI.cs index 68e24074e..ececcbc17 100644 --- a/SCANsat/SCAN_UI/SCANinstrumentUI.cs +++ b/SCANsat/SCAN_UI/SCANinstrumentUI.cs @@ -15,11 +15,13 @@ using System; using System.Collections.Generic; using System.Linq; -using SCANsat.Platform; +using SCANsat.SCAN_Platform; using SCANsat; +using SCANsat.SCAN_UI.UI_Framework; +using SCANsat.SCAN_Data; using UnityEngine; -using palette = SCANsat.SCAN_UI.SCANpalette; +using palette = SCANsat.SCAN_UI.UI_Framework.SCANpalette; namespace SCANsat.SCAN_UI { @@ -27,8 +29,13 @@ class SCANinstrumentUI: SCAN_MBW { private bool notMappingToday; //Unused out-of-power bool private SCANremoteView anomalyView; - private SCANdata.SCANtype sensors; + private SCANtype sensors; private SCANdata data; + private Vessel v; + private double degreeOffset; + private float lastUpdate = 0f; + private float updateInterval = 0.2f; + private double slopeAVG; internal static Rect defaultRect = new Rect(30, 600, 260, 60); protected override void Awake() @@ -53,6 +60,7 @@ internal override void Start() data = new SCANdata(FlightGlobals.currentMainBody); SCANcontroller.controller.addToBodyData(FlightGlobals.currentMainBody, data); } + planetConstants(FlightGlobals.currentMainBody); } internal override void OnDestroy() @@ -62,24 +70,26 @@ internal override void OnDestroy() protected override void DrawWindowPre(int id) { + v = FlightGlobals.ActiveVessel; + //Grab the active scanners on this vessel - sensors = SCANcontroller.controller.activeSensorsOnVessel(FlightGlobals.ActiveVessel.id); + sensors = SCANcontroller.controller.activeSensorsOnVessel(v.id); //if (maptraq_frame >= Time.frameCount - 5) //Still not sure what this actually does if (true) { //Check if region below the vessel is scanned - if (SCANUtil.isCovered(FlightGlobals.ActiveVessel.longitude, FlightGlobals.ActiveVessel.latitude, data, SCANdata.SCANtype.AltimetryLoRes)) + if (SCANUtil.isCovered(v.longitude, v.latitude, data, SCANtype.AltimetryLoRes)) { - sensors |= SCANdata.SCANtype.Altimetry; + sensors |= SCANtype.Altimetry; } - else if (SCANUtil.isCovered(FlightGlobals.ActiveVessel.longitude, FlightGlobals.ActiveVessel.latitude, data, SCANdata.SCANtype.AltimetryHiRes)) + else if (SCANUtil.isCovered(v.longitude, v.latitude, data, SCANtype.AltimetryHiRes)) { - sensors |= SCANdata.SCANtype.Altimetry; + sensors |= SCANtype.Altimetry; } - if (SCANUtil.isCovered(FlightGlobals.ActiveVessel.longitude, FlightGlobals.ActiveVessel.latitude, data, SCANdata.SCANtype.Biome)) + if (SCANUtil.isCovered(v.longitude, v.latitude, data, SCANtype.Biome)) { - sensors |= SCANdata.SCANtype.Biome; + sensors |= SCANtype.Biome; } } } @@ -96,7 +106,7 @@ protected override void DrawWindow(int id) else { if (biomeInfo(id)) ++parts; /* show current biome info */ - if (altInfo(id)) ++parts; /* show current altitude *FixMe - inaccurate* */ + if (altInfo(id)) ++parts; /* show current altitude and slope */ if (anomalyInfo(id)) ++parts; /* show nearest anomaly detail - including BTDT view */ if (parts <= 0) noData(id); /* nothing to show */ } @@ -128,25 +138,85 @@ private void noData(int id) //Display current biome info private bool biomeInfo(int id) { - if ((sensors & SCANdata.SCANtype.Biome) != SCANdata.SCANtype.Nothing) + if ((sensors & SCANtype.Biome) != SCANtype.Nothing && v.mainBody.BiomeMap != null) { - GUILayout.Label(string.Format("Biome: {0}", SCANUtil.getBiomeName(FlightGlobals.ActiveVessel.mainBody, FlightGlobals.ActiveVessel.longitude, FlightGlobals.ActiveVessel.latitude)), SCANskins.SCAN_insColorLabel); + GUILayout.Label(string.Format("Biome: {0}", SCANUtil.getBiomeName(v.mainBody, v.longitude, v.latitude)), SCANskins.SCAN_insColorLabel); fillS(-10); return true; } return false; } - //Display the current vessel altitude *Needs to be fixed to display accurate alt* + //Display the current vessel altitude private bool altInfo(int id) { - if ((sensors & SCANdata.SCANtype.Altimetry) != SCANdata.SCANtype.Nothing) + if ((sensors & SCANtype.Altimetry) != SCANtype.Nothing) { - double h = FlightGlobals.ActiveVessel.heightFromTerrain; + double h = v.altitude; + double pqs = 0; + if (v.mainBody.pqsController != null) + { + pqs = v.PQSAltitude(); + if (pqs > 0 || !v.mainBody.ocean) + h -= pqs; + } if (h < 0) - h = FlightGlobals.ActiveVessel.altitude; + h = v.altitude; + GUILayout.Label(string.Format("Altitude: {0}", SCANuiUtil.distanceString(h, 100000)), SCANskins.SCAN_insColorLabel); fillS(-10); + + //Calculate slope less frequently; the rapidly changing value makes it difficult to read otherwise + if (v.mainBody.pqsController != null) + { + float deltaTime = 1f; + if (Time.deltaTime != 0) + deltaTime = TimeWarp.deltaTime / Time.deltaTime; + if (deltaTime > 5) + deltaTime = 5; + if (((Time.time * deltaTime) - lastUpdate) > updateInterval) + { + lastUpdate = Time.time; + + /* Slope is calculated using a nine point grid centered 5m around the vessel location + * The rise between the vessel location's elevation and each point on the grid is calculated, converted to slope in degrees, and averaged; + * Note: Averageing is not the most accurate method + */ + + double lon = v.longitude; + double lat = v.latitude; + double latOffset = degreeOffset * Math.Cos(Mathf.Deg2Rad * lat); + double[] e = new double[9]; + double[] s = new double[8]; + e[0] = pqs; + e[1] = SCANUtil.getElevation(v.mainBody, lon + latOffset, lat); + e[2] = SCANUtil.getElevation(v.mainBody, lon - latOffset, lat); + e[3] = SCANUtil.getElevation(v.mainBody, lon, lat + latOffset); + e[4] = SCANUtil.getElevation(v.mainBody, lon, lat - latOffset); + e[5] = SCANUtil.getElevation(v.mainBody, lon + latOffset, lat + latOffset); + e[6] = SCANUtil.getElevation(v.mainBody, lon + latOffset, lat - latOffset); + e[7] = SCANUtil.getElevation(v.mainBody, lon - latOffset, lat + latOffset); + e[8] = SCANUtil.getElevation(v.mainBody, lon - latOffset, lat - latOffset); + + for (int i = 1; i <= 4; i++) + { + s[i - 1] = Math.Atan((Math.Abs(e[i] - e[0])) / 5) * Mathf.Rad2Deg; + } + for (int i = 5; i <= 8; i++) + { + s[i - 1] = Math.Atan((Math.Abs(e[i] - e[0])) / 7.071) * Mathf.Rad2Deg; + } + + //SCANUtil.SCANdebugLog("Elevations: {0:F3};{1:F3};{2:F3};{3:F3};{4:F3} ; Long: {5:F6};{6:F6};{7:F6};{8:F6};{9:F6} ; Lat: {10:F6};{11:F6};{12:F6};{13:F6};{14:F6} ; Slope: {15:F1};{16:F1};{17:F1};{18:F1}", e[0], e[1], e[2], e[3], e[4], lon, lon + latOffset, lon - latOffset, lon, lon, lat, lat, lat, lat + latOffset, lat - latOffset, s[0], s[1], s[2], s[3]); + + slopeAVG = s.Sum() / 8; + + } + + GUILayout.Label(string.Format("Slope: {0:F2}°", slopeAVG), SCANskins.SCAN_insColorLabel); + fillS(-10); + } + return true; } return false; @@ -155,15 +225,15 @@ private bool altInfo(int id) //Display info on the nearest anomaly *Need to separate the BTDT display* private bool anomalyInfo(int id) { - if ((sensors & SCANdata.SCANtype.AnomalyDetail) != SCANdata.SCANtype.Nothing) + if ((sensors & SCANtype.AnomalyDetail) != SCANtype.Nothing) { - SCANdata.SCANanomaly nearest = null; + SCANanomaly nearest = null; double nearest_dist = -1; - foreach (SCANdata.SCANanomaly a in data.Anomalies) + foreach (SCANanomaly a in data.Anomalies) { - if (!a.known) + if (!a.Known) continue; - double d = (a.mod.transform.position - FlightGlobals.ActiveVessel.transform.position).magnitude; + double d = (a.Mod.transform.position - v.transform.position).magnitude; if (d < nearest_dist || nearest_dist < 0) { if (d < 50000) @@ -176,8 +246,8 @@ private bool anomalyInfo(int id) if (nearest != null) { string txt = "Anomaly"; - if (nearest.detail) - txt = nearest.name; + if (nearest.Detail) + txt = nearest.Name; txt += ": " + SCANuiUtil.distanceString(nearest_dist, 5000); GUILayout.Label(txt, SCANskins.SCAN_insColorLabel); @@ -185,15 +255,15 @@ private bool anomalyInfo(int id) anomalyView = new SCANremoteView(); if (anomalyView != null) { - if (nearest.mod != null) + if (nearest.Mod != null) { - if (anomalyView.lookat != nearest.mod.gameObject) - anomalyView.setup(320, 240, nearest.mod.gameObject); + if (anomalyView.lookat != nearest.Mod.gameObject) + anomalyView.setup(320, 240, nearest.Mod.gameObject); Texture t = anomalyView.getTexture(); if (t != null) { GUILayout.Label(anomalyView.getTexture()); - anomalyView.drawOverlay(GUILayoutUtility.GetLastRect(), SCANskins.SCAN_anomalyOverlay, nearest.detail); + anomalyView.drawOverlay(GUILayoutUtility.GetLastRect(), SCANskins.SCAN_anomalyOverlay, nearest.Detail); } } } @@ -204,6 +274,13 @@ private bool anomalyInfo(int id) return false; } + private void planetConstants (CelestialBody b) + { + double circum = b.Radius * 2 * Math.PI; + double eqDistancePerDegree = circum / 360; + degreeOffset = 5 / eqDistancePerDegree; + } + private void soiChange (GameEvents.HostedFromToAction VC) { data = SCANUtil.getData(VC.to); @@ -212,6 +289,7 @@ private void soiChange (GameEvents.HostedFromToAction VC) data = new SCANdata(VC.to); SCANcontroller.controller.addToBodyData(VC.to, data); } + planetConstants(VC.to); } } diff --git a/SCANsat/SCAN_UI/SCANkscMap.cs b/SCANsat/SCAN_UI/SCANkscMap.cs index 40a819324..149c4e4ac 100644 --- a/SCANsat/SCAN_UI/SCANkscMap.cs +++ b/SCANsat/SCAN_UI/SCANkscMap.cs @@ -15,8 +15,11 @@ using System; using System.Collections.Generic; using System.Linq; -using SCANsat.Platform; +using SCANsat.SCAN_Platform; using SCANsat; +using SCANsat.SCAN_UI.UI_Framework; +using SCANsat.SCAN_Data; +using SCANsat.SCAN_Map; using UnityEngine; namespace SCANsat.SCAN_UI @@ -29,7 +32,8 @@ class SCANkscMap : SCAN_MBW private SCANdata data; private bool drawGrid, currentGrid, currentColor, lastColor, lastResource, spaceCenterLock, trackingStationLock; private bool drop_down_open, projection_drop_down, mapType_drop_down, resources_drop_down, planetoid_drop_down; - private Texture2D overlay_static; + //private Texture2D overlay_static; + private Dictionary>> gridLines = new Dictionary>>(); private Rect ddRect, zoomCloseRect; private Rect rc = new Rect(0, 0, 20, 20); private Vector2 scrollP, scrollR; @@ -62,8 +66,8 @@ internal override void Start() b = Planetarium.fetch.Home; if (bigmap == null) { - bigmap = new SCANmap(b); - bigmap.setProjection((SCANmap.MapProjection)SCANcontroller.controller.projection); + bigmap = new SCANmap(b, true); + bigmap.setProjection((MapProjection)SCANcontroller.controller.projection); bigmap.setWidth(720); //WindowRect.x = SCANcontroller.controller.map_x; //WindowRect.y = SCANcontroller.controller.map_y; @@ -86,7 +90,7 @@ internal override void Start() } bigmap.setBody(b); if (SCANcontroller.controller.ResourceList.Count > 0) - bigmap.resource = SCANcontroller.controller.ResourceList[SCANcontroller.controller.resourceSelection][b.name]; + bigmap.Resource = SCANcontroller.controller.ResourceList[SCANcontroller.controller.resourceSelection][b.name]; TooltipsEnabled = SCANcontroller.controller.toolTips; } @@ -109,7 +113,7 @@ public static SCANmap BigMap protected override void DrawWindowPre(int id) { if (bigmap != null) - mapTypeTitle = SCANmap.mapTypeNames[bigmap.mapmode]; + mapTypeTitle = SCANmapType.mapTypeNames[(int)bigmap.MType]; else mapTypeTitle = ""; @@ -433,34 +437,19 @@ private void mapDraw (int id) GUILayout.Label("", GUILayout.Width(MapTexture.width), GUILayout.Height(MapTexture.height)); TextureRect = GUILayoutUtility.GetLastRect(); - TextureRect.width = bigmap.mapwidth; - TextureRect.height = bigmap.mapheight; - - if (overlay_static == null) - { - overlay_static = new Texture2D((int)bigmap.mapwidth, (int)bigmap.mapheight, TextureFormat.ARGB32, false); - drawGrid = true; - } + TextureRect.width = bigmap.MapWidth; + TextureRect.height = bigmap.MapHeight; if (drawGrid) { - SCANuiUtil.clearTexture(overlay_static); - if (SCANcontroller.controller.map_grid) - { - SCANuiUtil.drawGrid(TextureRect, bigmap, overlay_static); - } - overlay_static.Apply(); + gridLines = new Dictionary>>(); + gridLines = SCANuiUtil.drawGridLine(TextureRect, bigmap); drawGrid = false; } GUI.DrawTexture(TextureRect, MapTexture); - if (overlay_static != null) - { - GUI.DrawTexture(TextureRect, overlay_static, ScaleMode.StretchToFill); - } - - if (bigmap.projection == SCANmap.MapProjection.Polar) + if (bigmap.Projection == MapProjection.Polar) { rc.x = TextureRect.x + TextureRect.width / 2 - TextureRect.width / 8; rc.y = TextureRect.y + TextureRect.height / 8; @@ -468,6 +457,23 @@ private void mapDraw (int id) rc.x = TextureRect.x + TextureRect.width / 2 + TextureRect.width / 8; SCANuiUtil.drawLabel(rc, "N", false, true, true); } + + if (SCANcontroller.controller.map_grid) + { + if (gridLines.Count > 0) + { + GL.PushMatrix(); + foreach (List points in gridLines[0]) + { + SCANuiUtil.drawGridLines(points, bigmap.MapWidth, TextureRect.x, TextureRect.y, SCANuiUtil.blackLineColor); + } + foreach (List points in gridLines[1]) + { + SCANuiUtil.drawGridLines(points, bigmap.MapWidth, TextureRect.x, TextureRect.y, SCANuiUtil.lineColor); + } + GL.PopMatrix(); + } + } } //Display info for mouse over in the map and handle the zoom map @@ -491,8 +497,8 @@ private void mouseOver(int id) if (mx >= pos_spotmap.x - TextureRect.x && my >= pos_spotmap.y - TextureRect.y && mx <= pos_spotmap.x + pos_spotmap.width - TextureRect.x && my <= pos_spotmap.y + pos_spotmap.height - TextureRect.y) { in_spotmap = true; - mlon = spotmap.lon_offset + ((mx - pos_spotmap.x + TextureRect.x) / spotmap.mapscale) - 180; - mlat = spotmap.lat_offset + ((pos_spotmap.height - (my - pos_spotmap.y + TextureRect.y)) / spotmap.mapscale) - 90; + mlon = spotmap.Lon_Offset + ((mx - pos_spotmap.x + TextureRect.x) / spotmap.MapScale) - 180; + mlat = spotmap.Lat_Offset + ((pos_spotmap.height - (my - pos_spotmap.y + TextureRect.y)) / spotmap.MapScale) - 90; if (mlat > 90) { mlon = (mlon + 360) % 360 - 180; @@ -530,14 +536,14 @@ private void mouseOver(int id) } if (in_spotmap) { - spotmap.mapscale = spotmap.mapscale * 1.25f; + spotmap.MapScale = spotmap.MapScale * 1.25f; } else { - spotmap.mapscale = 10; + spotmap.MapScale = 10; } spotmap.centerAround(mlon, mlat); - spotmap.resetMap(bigmap.mapmode, 1); + spotmap.resetMap(bigmap.MType, false); pos_spotmap.width = 180; pos_spotmap.height = 180; if (!in_spotmap) @@ -566,7 +572,7 @@ private void mouseOver(int id) //if (spotmap.mapscale < 10) // spotmap.mapscale = 10; spotmap.centerAround(mlon, mlat); - spotmap.resetMap(spotmap.mapmode, 1); + spotmap.resetMap(spotmap.MType, false); Event.current.Use(); } } @@ -584,8 +590,13 @@ private void mouseOver(int id) //Draw the altitude legend bar along the bottom private void legendBar(int id) { - if (bigmap.mapmode == 0 && SCANcontroller.controller.legend) - SCANuiUtil.drawLegend(data); + if (bigmap.MType == mapType.Altimetry && SCANcontroller.controller.legend) + { + if (bigmap.MapLegend == null) + bigmap.MapLegend = new SCANmapLegend(); + bigmap.MapLegend.Legend = bigmap.MapLegend.getLegend(data.MinHeight, data.MaxHeight, SCANcontroller.controller.colours, data); + SCANuiUtil.drawLegend(data, bigmap.MapLegend); + } } //Draw the zoom map and its overlays @@ -596,7 +607,7 @@ private void zoomMap(int id) spotmap.setBody(b); if (SCANcontroller.controller.GlobalResourceOverlay) - spotmap.resource = SCANcontroller.controller.ResourceList[SCANcontroller.controller.resourceSelection][b.name]; + spotmap.Resource = SCANcontroller.controller.ResourceList[SCANcontroller.controller.resourceSelection][b.name]; GUI.Box(pos_spotmap, spotmap.getPartialMap()); SCANuiUtil.drawMapLabels(pos_spotmap, null, spotmap, data, b); @@ -604,7 +615,7 @@ private void zoomMap(int id) if (GUI.Button(zoomCloseRect, SCANcontroller.controller.closeBox, SCANskins.SCAN_closeButton)) { - SCANUtil.SCANlog("Close Zoom Map"); + SCANUtil.SCANdebugLog("Close Zoom Map"); spotmap = null; } } @@ -623,12 +634,12 @@ private void dropDown(int id) { ddRect = new Rect(110, 45, 100, 70); GUI.Box(ddRect, "", SCANskins.SCAN_dropDownBox); - for (int i = 0; i < SCANmap.projectionNames.Length; ++i) + for (int i = 0; i < SCANmapProjection.projectionNames.Length; ++i) { Rect r = new Rect(ddRect.x + 2, ddRect.y + (24 * i), ddRect.width - 4, 20); - if (GUI.Button(r, SCANmap.projectionNames[i], SCANskins.SCAN_dropDownButton)) + if (GUI.Button(r, SCANmapProjection.projectionNames[i], SCANskins.SCAN_dropDownButton)) { - bigmap.setProjection((SCANmap.MapProjection)i); + bigmap.setProjection((MapProjection)i); SCANcontroller.controller.projection = i; drawGrid = true; drop_down_open = false; @@ -640,12 +651,12 @@ private void dropDown(int id) { ddRect = new Rect(270, 45, 70, 70); GUI.Box(ddRect, "", SCANskins.SCAN_dropDownBox); - for (int i = 0; i < SCANmap.mapTypeNames.Length; i++) + for (int i = 0; i < SCANmapType.mapTypeNames.Length; i++) { Rect r = new Rect(ddRect.x + 2, ddRect.y + (24 * i), ddRect.width - 4, 20); - if (GUI.Button(r, SCANmap.mapTypeNames[i], SCANskins.SCAN_dropDownButton)) + if (GUI.Button(r, SCANmapType.mapTypeNames[i], SCANskins.SCAN_dropDownButton)) { - bigmap.resetMap(i, 0); + bigmap.resetMap((mapType)i, true); drop_down_open = false; } } @@ -661,13 +672,14 @@ private void dropDown(int id) Rect r = new Rect(2, 20 * i, 96, 20); if (GUI.Button(r, SCANcontroller.controller.ResourceList.ElementAt(i).Key, SCANskins.SCAN_dropDownButton)) { - bigmap.resource = SCANcontroller.controller.ResourceList.ElementAt(i).Value[b.name]; - SCANcontroller.controller.resourceSelection = bigmap.resource.Name; - if (SCANcontroller.controller.ResourceList.ElementAt(i).Value[b.name].Source == SCANdata.SCANResource_Source.Kethane) + bigmap.Resource = SCANcontroller.controller.ResourceList.ElementAt(i).Value[b.name]; + SCANcontroller.controller.resourceSelection = bigmap.Resource.Name; + if (SCANcontroller.controller.ResourceList.ElementAt(i).Value[b.name].Source == SCANresource_Source.Kethane) SCANcontroller.controller.resourceOverlayType = 1; else SCANcontroller.controller.resourceOverlayType = 0; - bigmap.resetMap(); + if (SCANcontroller.controller.map_ResourceOverlay) + bigmap.resetMap(); drop_down_open = false; } GUI.EndScrollView(); diff --git a/SCANsat/SCAN_UI/SCANmainMap.cs b/SCANsat/SCAN_UI/SCANmainMap.cs index dac7f261d..eb97d80c3 100644 --- a/SCANsat/SCAN_UI/SCANmainMap.cs +++ b/SCANsat/SCAN_UI/SCANmainMap.cs @@ -16,10 +16,11 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; -using SCANsat.Platform; -using SCANsat; +using SCANsat.SCAN_Platform; +using SCANsat.SCAN_Data; +using SCANsat.SCAN_UI.UI_Framework; using UnityEngine; -using palette = SCANsat.SCAN_UI.SCANpalette; +using palette = SCANsat.SCAN_UI.UI_Framework.SCANpalette; namespace SCANsat.SCAN_UI { @@ -28,7 +29,7 @@ class SCANmainMap: SCAN_MBW private string infoText; private Vessel v; private SCANdata data; - private SCANdata.SCANtype sensors; + private SCANtype sensors; private bool notMappingToday; //Unused out-of-power bool private Rect mapRect; private static bool showVesselInfo = true; diff --git a/SCANsat/SCAN_UI/SCANnewBigMap.cs b/SCANsat/SCAN_UI/SCANnewBigMap.cs index f3e488730..31c354563 100644 --- a/SCANsat/SCAN_UI/SCANnewBigMap.cs +++ b/SCANsat/SCAN_UI/SCANnewBigMap.cs @@ -15,8 +15,11 @@ using System; using System.Collections.Generic; using System.Linq; -using SCANsat.Platform; +using SCANsat.SCAN_Platform; using SCANsat; +using SCANsat.SCAN_UI.UI_Framework; +using SCANsat.SCAN_Data; +using SCANsat.SCAN_Map; using UnityEngine; namespace SCANsat.SCAN_UI @@ -28,11 +31,11 @@ class SCANnewBigMap : SCAN_MBW private string mapTypeTitle = ""; private SCANdata data; private Vessel v; - private double startUT; private float resizeW, resizeH, dragX; private bool drawGrid, currentGrid, currentColor, lastColor, lastResource; private bool drop_down_open, projection_drop_down, mapType_drop_down, resources_drop_down, planetoid_drop_down; - private Texture2D overlay_static; + //private Texture2D overlay_static; + private Dictionary>> gridLines = new Dictionary>>(); private Rect ddRect, zoomCloseRect; private Rect rc = new Rect(0, 0, 20, 20); private Vector2 scrollP, scrollR; @@ -72,8 +75,8 @@ internal override void Start() b = v.mainBody; if (bigmap == null) { - bigmap = new SCANmap(b); - bigmap.setProjection((SCANmap.MapProjection)SCANcontroller.controller.projection); + bigmap = new SCANmap(b, true); + bigmap.setProjection((MapProjection)SCANcontroller.controller.projection); bigmap.setWidth(SCANcontroller.controller.map_width); WindowRect.x = SCANcontroller.controller.map_x; WindowRect.y = SCANcontroller.controller.map_y; @@ -96,7 +99,7 @@ internal override void Start() } bigmap.setBody(b); if (SCANcontroller.controller.ResourceList.Count > 0) - bigmap.resource = SCANcontroller.controller.ResourceList[SCANcontroller.controller.resourceSelection][b.name]; + bigmap.Resource = SCANcontroller.controller.ResourceList[SCANcontroller.controller.resourceSelection][b.name]; TooltipsEnabled = SCANcontroller.controller.toolTips; } @@ -115,7 +118,7 @@ protected override void DrawWindowPre(int id) { //Append the map type to the window caption if (bigmap != null) - mapTypeTitle = SCANmap.mapTypeNames[bigmap.mapmode]; + mapTypeTitle = SCANmapType.mapTypeNames[(int)bigmap.MType]; else mapTypeTitle = ""; @@ -132,8 +135,9 @@ protected override void DrawWindowPre(int id) if (resizeH < WindowRect_Min.height) resizeH = WindowRect_Min.height; bigmap.setWidth((int)resizeW); - overlay_static = null; - SCANcontroller.controller.map_width = bigmap.mapwidth; + //overlay_static = null; + drawGrid = true; + SCANcontroller.controller.map_width = bigmap.MapWidth; WindowRect_Last = new Rect(0, 0, WindowRect.width, WindowRect.height); } else @@ -460,25 +464,14 @@ private void mapDraw(int id) } TextureRect = GUILayoutUtility.GetLastRect(); - TextureRect.width = bigmap.mapwidth; - TextureRect.height = bigmap.mapheight; + TextureRect.width = bigmap.MapWidth; + TextureRect.height = bigmap.MapHeight; - //The background texture for the map - if (overlay_static == null) - { - overlay_static = new Texture2D((int)bigmap.mapwidth, (int)bigmap.mapheight, TextureFormat.ARGB32, false); - drawGrid = true; - } - - //Generate the grid texture + //Generate the grid lines if (drawGrid) { - SCANuiUtil.clearTexture(overlay_static); - if (SCANcontroller.controller.map_grid) - { - SCANuiUtil.drawGrid(TextureRect, bigmap, overlay_static); - } - overlay_static.Apply(); + gridLines = new Dictionary>>(); + gridLines = SCANuiUtil.drawGridLine(TextureRect, bigmap); drawGrid = false; } @@ -494,13 +487,8 @@ private void mapDraw(int id) GUI.DrawTexture(TextureRect, MapTexture); } - if (overlay_static != null) - { - GUI.DrawTexture(TextureRect, overlay_static, ScaleMode.StretchToFill); - } - //Add the North/South labels to the polar projection - if (bigmap.projection == SCANmap.MapProjection.Polar) + if (bigmap.Projection == MapProjection.Polar) { rc.x = TextureRect.x + TextureRect.width / 2 - TextureRect.width / 8; rc.y = TextureRect.y + TextureRect.height / 8; @@ -509,10 +497,27 @@ private void mapDraw(int id) SCANuiUtil.drawLabel(rc, "N", false, true, true); } + if (SCANcontroller.controller.map_grid && !IsResizing) + { + if (gridLines.Count > 0) + { + GL.PushMatrix(); + foreach (List points in gridLines[0]) + { + SCANuiUtil.drawGridLines(points, bigmap.MapWidth, TextureRect.x, TextureRect.y, SCANuiUtil.blackLineColor); + } + foreach (List points in gridLines[1]) + { + SCANuiUtil.drawGridLines(points, bigmap.MapWidth, TextureRect.x, TextureRect.y, SCANuiUtil.lineColor); + } + GL.PopMatrix(); + } + } + //Draw the orbit overlays if (SCANcontroller.controller.map_orbit) { - SCANuiUtil.drawOrbit(TextureRect, bigmap, v, startUT, overlay_static, b); + SCANuiUtil.drawOrbit(TextureRect, bigmap, v, b); } } @@ -541,8 +546,8 @@ private void mouseOver(int id) if (mx >= pos_spotmap.x - TextureRect.x && my >= pos_spotmap.y - TextureRect.y && mx <= pos_spotmap.x + pos_spotmap.width - TextureRect.x && my <= pos_spotmap.y + pos_spotmap.height - TextureRect.y) { in_spotmap = true; - mlon = spotmap.lon_offset + ((mx - pos_spotmap.x + TextureRect.x) / spotmap.mapscale) - 180; - mlat = spotmap.lat_offset + ((pos_spotmap.height - (my - pos_spotmap.y + TextureRect.y)) / spotmap.mapscale) - 90; + mlon = spotmap.Lon_Offset + ((mx - pos_spotmap.x + TextureRect.x) / spotmap.MapScale) - 180; + mlat = spotmap.Lat_Offset + ((pos_spotmap.height - (my - pos_spotmap.y + TextureRect.y)) / spotmap.MapScale) - 90; if (mlat > 90) { mlon = (mlon + 360) % 360 - 180; @@ -580,14 +585,14 @@ private void mouseOver(int id) } if (in_spotmap) { - spotmap.mapscale = spotmap.mapscale * 1.25f; + spotmap.MapScale = spotmap.MapScale * 1.25f; } else { - spotmap.mapscale = 10; + spotmap.MapScale = 10; } spotmap.centerAround(mlon, mlat); - spotmap.resetMap(bigmap.mapmode, 1); + spotmap.resetMap(bigmap.MType, false); pos_spotmap.width = 180; pos_spotmap.height = 180; if (!in_spotmap) @@ -616,7 +621,7 @@ private void mouseOver(int id) //if (spotmap.mapscale < 10) // spotmap.mapscale = 10; spotmap.centerAround(mlon, mlat); - spotmap.resetMap(spotmap.mapmode, 1); + spotmap.resetMap(spotmap.MType, false); Event.current.Use(); } } @@ -647,8 +652,13 @@ private void mouseOver(int id) //Draw the altitude legend bar along the bottom private void legendBar(int id) { - if (bigmap.mapmode == 0 && SCANcontroller.controller.legend) - SCANuiUtil.drawLegend(data); + if (bigmap.MType == mapType.Altimetry && SCANcontroller.controller.legend) + { + if (bigmap.MapLegend == null) + bigmap.MapLegend = new SCANmapLegend(); + bigmap.MapLegend.Legend = bigmap.MapLegend.getLegend(data.MinHeight, data.MaxHeight, SCANcontroller.controller.colours, data); + SCANuiUtil.drawLegend(data, bigmap.MapLegend); + } } //Draw the zoom map and its overlays @@ -659,10 +669,10 @@ private void zoomMap(int id) spotmap.setBody(b); if (SCANcontroller.controller.GlobalResourceOverlay) - spotmap.resource = SCANcontroller.controller.ResourceList[SCANcontroller.controller.resourceSelection][b.name]; + spotmap.Resource = SCANcontroller.controller.ResourceList[SCANcontroller.controller.resourceSelection][b.name]; GUI.Box(pos_spotmap, spotmap.getPartialMap()); - SCANuiUtil.drawOrbit(pos_spotmap, spotmap, v, startUT, overlay_static, b); + SCANuiUtil.drawOrbit(pos_spotmap, spotmap, v, b); SCANuiUtil.drawMapLabels(pos_spotmap, v, spotmap, data, v.mainBody); zoomCloseRect = new Rect(pos_spotmap.x + 180, pos_spotmap.y, 18, 18); @@ -686,12 +696,12 @@ private void dropDown(int id) { ddRect = new Rect(110, 45, 100, 70); GUI.Box(ddRect, "", SCANskins.SCAN_dropDownBox); - for (int i = 0; i < SCANmap.projectionNames.Length; ++i) + for (int i = 0; i < SCANmapProjection.projectionNames.Length; ++i) { Rect r = new Rect(ddRect.x + 2, ddRect.y + (24 * i), ddRect.width - 4, 20); - if (GUI.Button(r, SCANmap.projectionNames[i], SCANskins.SCAN_dropDownButton)) + if (GUI.Button(r, SCANmapProjection.projectionNames[i], SCANskins.SCAN_dropDownButton)) { - bigmap.setProjection((SCANmap.MapProjection)i); + bigmap.setProjection((MapProjection)i); SCANcontroller.controller.projection = i; drawGrid = true; drop_down_open = false; @@ -703,12 +713,12 @@ private void dropDown(int id) { ddRect = new Rect(270, 45, 70, 70); GUI.Box(ddRect, "", SCANskins.SCAN_dropDownBox); - for (int i = 0; i < SCANmap.mapTypeNames.Length; i++) + for (int i = 0; i < SCANmapType.mapTypeNames.Length; i++) { Rect r = new Rect(ddRect.x + 2, ddRect.y + (24 * i), ddRect.width - 4, 20); - if (GUI.Button(r, SCANmap.mapTypeNames[i], SCANskins.SCAN_dropDownButton)) + if (GUI.Button(r, SCANmapType.mapTypeNames[i], SCANskins.SCAN_dropDownButton)) { - bigmap.resetMap(i, 0); + bigmap.resetMap((mapType)i, true); drop_down_open = false; } } @@ -724,15 +734,16 @@ private void dropDown(int id) Rect r = new Rect(2, 20 * i, 96, 20); if (GUI.Button(r, SCANcontroller.controller.ResourceList.ElementAt(i).Key, SCANskins.SCAN_dropDownButton)) { - bigmap.resource = SCANcontroller.controller.ResourceList.ElementAt(i).Value[b.name]; - SCANcontroller.controller.resourceSelection = bigmap.resource.Name; - if (SCANcontroller.controller.ResourceList.ElementAt(i).Value[b.name].Source == SCANdata.SCANResource_Source.Kethane) + bigmap.Resource = SCANcontroller.controller.ResourceList.ElementAt(i).Value[b.name]; + SCANcontroller.controller.resourceSelection = bigmap.Resource.Name; + if (SCANcontroller.controller.ResourceList.ElementAt(i).Value[b.name].Source == SCANresource_Source.Kethane) SCANcontroller.controller.resourceOverlayType = 1; else SCANcontroller.controller.resourceOverlayType = 0; - bigmap.resetMap(); + if (SCANcontroller.controller.map_ResourceOverlay) + bigmap.resetMap(); drop_down_open = false; - SCANUtil.SCANlog("Resource {0} Selected; Min Value: {1}; Max Value: {2}", bigmap.resource.Name, bigmap.resource.minValue, bigmap.resource.maxValue); + SCANUtil.SCANdebugLog("Resource {0} Selected; Min Value: {1}; Max Value: {2}", bigmap.Resource.Name, bigmap.Resource.MinValue, bigmap.Resource.MaxValue); } GUI.EndScrollView(); } diff --git a/SCANsat/SCAN_UI/SCANsatRPM.cs b/SCANsat/SCAN_UI/SCANsatRPM.cs index 6a071d312..20d835518 100644 --- a/SCANsat/SCAN_UI/SCANsatRPM.cs +++ b/SCANsat/SCAN_UI/SCANsatRPM.cs @@ -19,6 +19,9 @@ using System.Linq; using System.Collections.Generic; using System.Globalization; +using SCANsat.SCAN_Map; +using SCANsat.SCAN_Data; +using SCANsat.SCAN_UI.UI_Framework; namespace SCANsat.SCAN_UI { @@ -102,7 +105,7 @@ public class JSISCANsatRPM: InternalModule private CelestialBody orbitingBody; private Vessel targetVessel; private double redrawDeviation; - private SCANdata.SCANanomaly[] localAnomalies; + private SCANanomaly[] localAnomalies; private Material iconMaterial; private SCANsat sat; internal RPMPersistence persist; @@ -177,7 +180,7 @@ public bool MapRenderer(RenderTexture screen, float cameraAspect) start = Planetarium.GetUniversalTime(); - Graphics.Blit(map.map, screen); + Graphics.Blit(map.Map, screen); GL.PushMatrix(); GL.LoadPixelMatrix(0, screenWidth, screenHeight, 0); @@ -194,11 +197,10 @@ public bool MapRenderer(RenderTexture screen, float cameraAspect) DrawTrail(trail, trailColorValue, new Vector2d(vessel.longitude, vessel.latitude), true); // Anomalies go above trails - foreach (SCANdata.SCANanomaly anomaly in localAnomalies) { - if (anomaly.known) - DrawIcon(anomaly.longitude, anomaly.latitude, - anomaly.detail ? (VesselType)int.MaxValue : VesselType.Unknown, - anomaly.detail ? iconColorVisitedAnomalyValue : iconColorUnvisitedAnomalyValue); + foreach (SCANanomaly anomaly in localAnomalies) { + if (anomaly.Known) + DrawIcon(anomaly.Longitude, anomaly.Latitude, SCANicon.orbitIconForVesselType(anomaly.Detail ? (VesselType)int.MaxValue : VesselType.Unknown), + anomaly.Detail ? iconColorVisitedAnomalyValue : iconColorUnvisitedAnomalyValue); } // Target orbit and targets go above anomalies if (targetVessel != null && targetVessel.mainBody == orbitingBody) { @@ -221,10 +223,10 @@ public bool MapRenderer(RenderTexture screen, float cameraAspect) } } } - DrawIcon(targetVessel.longitude, targetVessel.latitude, targetVessel.vesselType, iconColorTargetValue); + DrawIcon(targetVessel.longitude, targetVessel.latitude, SCANicon.orbitIconForVesselType(targetVessel.vesselType), iconColorTargetValue); if (showLines) { - DrawOrbitIcon(targetVessel, MapIcons.OtherIcon.AP, iconColorTargetValue); - DrawOrbitIcon(targetVessel, MapIcons.OtherIcon.PE, iconColorTargetValue); + DrawOrbitIcon(targetVessel, SCANicon.OrbitIcon.Ap, iconColorTargetValue); + DrawOrbitIcon(targetVessel, SCANicon.OrbitIcon.Pe, iconColorTargetValue); } @@ -232,13 +234,13 @@ public bool MapRenderer(RenderTexture screen, float cameraAspect) // Own orbit goes above that. if (showLines && JUtil.OrbitMakesSense(vessel)) { DrawOrbit(vessel, vessel.orbit, start, iconColorSelfValue); - DrawOrbitIcon(vessel, MapIcons.OtherIcon.AP, iconColorAPValue); - DrawOrbitIcon(vessel, MapIcons.OtherIcon.PE, iconColorPEValue); + DrawOrbitIcon(vessel, SCANicon.OrbitIcon.Ap, iconColorAPValue); + DrawOrbitIcon(vessel, SCANicon.OrbitIcon.Pe, iconColorPEValue); if (targetVessel != null && JUtil.OrbitMakesSense(targetVessel)) { if (vessel.orbit.AscendingNodeExists(targetVessel.orbit)) - DrawOrbitIcon(vessel, MapIcons.OtherIcon.AN, iconColorANDNValue, vessel.orbit.TimeOfAscendingNode(targetVessel.orbit, start)); + DrawOrbitIcon(vessel, SCANicon.OrbitIcon.AN, iconColorANDNValue, vessel.orbit.TimeOfAscendingNode(targetVessel.orbit, start)); if (vessel.orbit.DescendingNodeExists(targetVessel.orbit)) - DrawOrbitIcon(vessel, MapIcons.OtherIcon.DN, iconColorANDNValue, vessel.orbit.TimeOfDescendingNode(targetVessel.orbit, start)); + DrawOrbitIcon(vessel, SCANicon.OrbitIcon.DN, iconColorANDNValue, vessel.orbit.TimeOfDescendingNode(targetVessel.orbit, start)); } // And the maneuver node and post-maneuver orbit: if (vessel.patchedConicSolver != null) @@ -247,12 +249,12 @@ public bool MapRenderer(RenderTexture screen, float cameraAspect) if (node != null) { DrawOrbit(vessel, node.nextPatch, node.UT, iconColorNodeValue); - DrawOrbitIcon(vessel, MapIcons.OtherIcon.NODE, iconColorNodeValue, node.UT); + DrawOrbitIcon(vessel, SCANicon.OrbitIcon.ManeuverNode, iconColorNodeValue, node.UT); } } } // Own icon goes above that - DrawIcon(vessel.longitude, vessel.latitude, vessel.vesselType, iconColorSelfValue); + DrawIcon(vessel.longitude, vessel.latitude, SCANicon.orbitIconForVesselType(vessel.vesselType), iconColorSelfValue); // And scale goes above everything. DrawScale(); @@ -261,28 +263,31 @@ public bool MapRenderer(RenderTexture screen, float cameraAspect) return true; } - private void DrawOrbitIcon(Vessel thatVessel, MapIcons.OtherIcon iconType, Color iconColor, double givenPoint = 0) + private void DrawOrbitIcon(Vessel thatVessel, SCANicon.OrbitIcon iconType, Color iconColor, double givenPoint = 0) { double timePoint = start; switch (iconType) { - case MapIcons.OtherIcon.AP: + case SCANicon.OrbitIcon.Ap: timePoint += thatVessel.orbit.timeToAp; break; - case MapIcons.OtherIcon.PE: + case SCANicon.OrbitIcon.Pe: timePoint += thatVessel.orbit.timeToPe; break; - case MapIcons.OtherIcon.AN: - case MapIcons.OtherIcon.DN: - case MapIcons.OtherIcon.NODE: + case SCANicon.OrbitIcon.AN: + case SCANicon.OrbitIcon.DN: + case SCANicon.OrbitIcon.ManeuverNode: timePoint = givenPoint; break; + default: + iconType = SCANicon.orbitIconForVesselType(thatVessel.vesselType); + break; } if (JUtil.OrbitMakesSense(thatVessel)) { bool collision; Vector2d coord; if (GetPositionAtT(thatVessel, thatVessel.orbit, start, timePoint, out coord, out collision) && !collision) { - DrawIcon(coord.x, coord.y, thatVessel.vesselType, iconColor, iconType); + DrawIcon(coord.x, coord.y, iconType, iconColor); } } } @@ -420,21 +425,23 @@ private void DrawScale() Graphics.DrawTexture(scaleBarRect, scaleLabelTexture, new Rect(0f, scaleID * scaleLabelSpan, 1f, scaleLabelSpan), 0, 0, 0, 0, scaleTint); } - private void DrawIcon(double longitude, double latitude, VesselType vt, Color iconColor, MapIcons.OtherIcon icon = MapIcons.OtherIcon.None) + private void DrawIcon(double longitude, double latitude, SCANicon.OrbitIcon icon, Color iconColor) { - var position = new Rect((float)(longitudeToPixels(longitude, latitude) - iconPixelSize / 2), - (float)(latitudeToPixels(longitude, latitude) - iconPixelSize / 2), + var position = new Rect((float)(longitudeToPixels(longitude, latitude)), + (float)(latitudeToPixels(longitude, latitude)), iconPixelSize, iconPixelSize); Rect shadow = position; shadow.x += iconShadowShift.x; shadow.y += iconShadowShift.y; - iconMaterial.color = iconColorShadowValue; - Graphics.DrawTexture(shadow, MapView.OrbitIconsMap, MapIcons.VesselTypeIcon(vt, icon), 0, 0, 0, 0, iconMaterial); + SCANicon.drawOrbitIconGL((int)position.x, (int)position.y, icon, iconColor, iconColorShadowValue, iconMaterial, 16, true); + + //iconMaterial.color = iconColorShadowValue; + //Graphics.DrawTexture(shadow, MapView.OrbitIconsMap, MapIcons.VesselTypeIcon(vt, icon), 0, 0, 0, 0, iconMaterial); - iconMaterial.color = iconColor; - Graphics.DrawTexture(position, MapView.OrbitIconsMap, MapIcons.VesselTypeIcon(vt, icon), 0, 0, 0, 0, iconMaterial); + //iconMaterial.color = iconColor; + //Graphics.DrawTexture(position, MapView.OrbitIconsMap, MapIcons.VesselTypeIcon(vt, icon), 0, 0, 0, 0, iconMaterial); } private double longitudeToPixels(double longitude, double latitude) @@ -455,7 +462,7 @@ private double latitudeToPixels(double longitude, double latitude) // put the baseline latitude in the range [0,180] instead of // [-90, +90]. double projLat = map.projectLatitude(longitude, latitude); - double translatedLat = 90.0 + projLat - map.lat_offset; + double translatedLat = 90.0 + projLat - map.Lat_Offset; double scaledLat = translatedLat * mapSizeScale.y; double pix = scaledLat * screenHeight / 180.0; @@ -465,7 +472,7 @@ private double latitudeToPixels(double longitude, double latitude) private double rescaleLongitude(double lon) { - return Clamp(lon - map.lon_offset, 360d) * mapSizeScale.x; + return Clamp(lon - map.Lon_Offset, 360d) * mapSizeScale.x; } private static double Clamp(double value, double clamp) @@ -569,23 +576,23 @@ public override void OnUpdate() private void RedrawMap() { map = new SCANmap(); - map.setProjection(SCANmap.MapProjection.Rectangular); + map.setProjection(MapProjection.Rectangular); orbitingBody = vessel.mainBody; map.setBody(vessel.mainBody); map.setSize(screenWidth, screenHeight); - map.mapscale *= (zoomLevel * zoomLevel + zoomModifier); + map.MapScale *= (zoomLevel * zoomLevel + zoomModifier); mapCenterLong = vessel.longitude; mapCenterLat = vessel.latitude; // That's really just sweeping the problem under the carpet instead of fixing it, but meh. if (zoomLevel == 0) mapCenterLat = 0; map.centerAround(mapCenterLong, mapCenterLat); - map.resetMap(mapMode,1); + map.resetMap((mapType)mapMode, false); // Compute and store the map scale factors in mapSizeScale. We // use these values for every segment when drawing trails, so it // makes sense to compute it only when it changes. - mapSizeScale = new Vector2d(360.0 * map.mapscale / map.mapwidth, 180.0 * map.mapscale / map.mapheight); + mapSizeScale = new Vector2d(360.0 * map.MapScale / map.MapWidth, 180.0 * map.MapScale / map.MapHeight); redrawDeviation = redrawEdge * 180 / (zoomLevel * zoomLevel + zoomModifier); try { SCANdata data = SCANUtil.getData(vessel.mainBody); diff --git a/SCANsat/SCAN_UI/SCANsettingsUI.cs b/SCANsat/SCAN_UI/SCANsettingsUI.cs index 9483aa474..ee2e283c1 100644 --- a/SCANsat/SCAN_UI/SCANsettingsUI.cs +++ b/SCANsat/SCAN_UI/SCANsettingsUI.cs @@ -15,11 +15,14 @@ using System; using System.Collections.Generic; using System.Linq; -using SCANsat.Platform; -using SCANsat.Platform.Palettes; +using SCANsat.SCAN_Toolbar; +using SCANsat.SCAN_Data; +using SCANsat.SCAN_UI.UI_Framework; +using SCANsat.SCAN_Platform; +using SCANsat.SCAN_Platform.Palettes; using UnityEngine; -using palette = SCANsat.SCAN_UI.SCANpalette; +using palette = SCANsat.SCAN_UI.UI_Framework.SCANpalette; namespace SCANsat.SCAN_UI { @@ -34,6 +37,7 @@ class SCANsettingsUI: SCAN_MBW private bool warningBoxOne, warningBoxAll, spaceCenterLock, trackingStationLock; private Rect warningRect; private const string lockID = "settingLockID"; + private bool oldTooltips, stockToolbar; internal static Rect defaultRect = new Rect(Screen.width - (Screen.width / 2) - 180, 100, 360, 300); @@ -60,7 +64,8 @@ internal override void OnDestroy() internal override void Start() { - TooltipsEnabled = SCANcontroller.controller.toolTips; + oldTooltips = TooltipsEnabled = SCANcontroller.controller.toolTips; + stockToolbar = SCANcontroller.controller.useStockAppLauncher; } protected override void DrawWindowPre(int id) @@ -111,8 +116,8 @@ protected override void DrawWindow(int id) gui_settings_rebuild_kethane(id); /* rebuild Kethane database with SCANsat info */ gui_settings_timewarp(id); /* time warp resolution settings */ gui_settings_numbers(id); /* sensor/scanning statistics */ - gui_settings_data_resets(id); /* reset data and/or reset resources */ gui_settings_window_resets_tooltips(id);/* reset windows and positions and toggle tooltips*/ + gui_settings_data_resets(id); /* reset data and/or reset resources */ # if DEBUG gui_settings_window_mapFill(id); /* debug option to fill in maps */ #endif @@ -128,6 +133,28 @@ protected override void DrawWindowPost(int id) warningBoxOne = false; warningBoxAll = false; } + + if (oldTooltips != SCANcontroller.controller.toolTips) + { + oldTooltips = SCANcontroller.controller.toolTips; + TooltipsEnabled = SCANcontroller.controller.toolTips; + if (HighLogic.LoadedSceneIsFlight) + { + SCANcontroller.controller.newBigMap.TooltipsEnabled = SCANcontroller.controller.toolTips; + SCANcontroller.controller.mainMap.TooltipsEnabled = SCANcontroller.controller.toolTips; + } + if (HighLogic.LoadedScene == GameScenes.SPACECENTER || HighLogic.LoadedScene == GameScenes.TRACKSTATION) + SCANcontroller.controller.kscMap.TooltipsEnabled = SCANcontroller.controller.toolTips; + } + + if (stockToolbar != SCANcontroller.controller.useStockAppLauncher) + { + stockToolbar = SCANcontroller.controller.useStockAppLauncher; + if (stockToolbar) + SCANcontroller.controller.appLauncher = gameObject.AddComponent(); + else + Destroy(SCANcontroller.controller.appLauncher); + } } //Draw the version label in the upper left corner @@ -186,7 +213,7 @@ private void gui_settings_toggle_body_scanning(int id) foreach (var data in SCANcontroller.Body_Data) { if (count == 0) growS(); - data.Value.Disabled = !GUILayout.Toggle(!data.Value.Disabled, string.Format("{0} ({1:N1}%)", data.Key, data.Value.getCoveragePercentage(SCANdata.SCANtype.Nothing)), SCANskins.SCAN_settingsToggle); + data.Value.Disabled = !GUILayout.Toggle(!data.Value.Disabled, string.Format("{0} ({1:N1}%)", data.Key, SCANUtil.getCoveragePercentage(data.Value, SCANtype.Nothing)), SCANskins.SCAN_settingsToggle); switch (count) { case 5: stopS(); count = 0; break; @@ -272,38 +299,30 @@ private void gui_settings_data_resets(int id) //Resets all window positions, tooltip toggle private void gui_settings_window_resets_tooltips(int id) { + GUILayout.Label("Settings", SCANskins.SCAN_headline); growE(); - if (GUILayout.Button("Reset window positions", SCANskins.SCAN_buttonFixed)) + SCANcontroller.controller.useStockAppLauncher = GUILayout.Toggle(SCANcontroller.controller.useStockAppLauncher, "Use Stock Toolbar", SCANskins.SCAN_settingsToggle); + fillS(10); + SCANcontroller.controller.toolTips = GUILayout.Toggle(SCANcontroller.controller.toolTips, "Tooltips", SCANskins.SCAN_settingsToggle); + stopE(); + fillS(8); + if (GUILayout.Button("Reset window positions", SCANskins.SCAN_buttonFixed)) + { + if (HighLogic.LoadedSceneIsFlight) { - if (HighLogic.LoadedSceneIsFlight) - { - SCANuiUtil.resetMainMapPos(); - SCANuiUtil.resetBigMapPos(); - SCANuiUtil.resetInstUIPos(); - SCANuiUtil.resetSettingsUIPos(); - SCANuiUtil.resetColorMapPos(); - } - else - { - SCANuiUtil.resetKSCMapPos(); - SCANuiUtil.resetColorMapPos(); - SCANuiUtil.resetSettingsUIPos(); - } + SCANuiUtil.resetMainMapPos(); + SCANuiUtil.resetBigMapPos(); + SCANuiUtil.resetInstUIPos(); + SCANuiUtil.resetSettingsUIPos(); + SCANuiUtil.resetColorMapPos(); } - fillS(10); - if (GUILayout.Button(textWithTT("Tooltips","Toggle Tooltips"), SCANskins.SCAN_buttonFixed)) + else { - SCANcontroller.controller.toolTips = !SCANcontroller.controller.toolTips; - TooltipsEnabled = SCANcontroller.controller.toolTips; - if (HighLogic.LoadedSceneIsFlight) - { - SCANcontroller.controller.newBigMap.TooltipsEnabled = SCANcontroller.controller.toolTips; - SCANcontroller.controller.mainMap.TooltipsEnabled = SCANcontroller.controller.toolTips; - } - if (HighLogic.LoadedScene == GameScenes.SPACECENTER || HighLogic.LoadedScene == GameScenes.TRACKSTATION) - SCANcontroller.controller.kscMap.TooltipsEnabled = SCANcontroller.controller.toolTips; + SCANuiUtil.resetKSCMapPos(); + SCANuiUtil.resetColorMapPos(); + SCANuiUtil.resetSettingsUIPos(); } - stopE(); + } fillS(8); } @@ -345,7 +364,7 @@ private void warningBox(int id) if (warningBoxOne) { CelestialBody thisBody = FlightGlobals.currentMainBody; - warningRect = new Rect(WindowRect.width - (WindowRect.width / 2)- 150, WindowRect.height - 190, 300, 90); + warningRect = new Rect(WindowRect.width - (WindowRect.width / 2)- 150, WindowRect.height - 125, 300, 90); GUI.Box(warningRect, "", SCANskins.SCAN_dropDownBox); Rect r = new Rect(warningRect.x + 10, warningRect.y + 5, 280, 40); GUI.Label(r, "Erase all data for " + thisBody.theName + "?", SCANskins.SCAN_headlineSmall); @@ -363,7 +382,7 @@ private void warningBox(int id) } else if (warningBoxAll) { - warningRect = new Rect(WindowRect.width - (WindowRect.width / 2) - 120, WindowRect.height - 190, 240, 90); + warningRect = new Rect(WindowRect.width - (WindowRect.width / 2) - 120, WindowRect.height - 160, 240, 90); GUI.Box(warningRect, "", SCANskins.SCAN_dropDownBox); Rect r = new Rect(warningRect.x + 10, warningRect.y + 5, 220, 40); GUI.Label(r, "Erase all data ?", SCANskins.SCAN_headlineSmall); diff --git a/SCANsat/SCAN_UI/UI_Framework/SCANicon.cs b/SCANsat/SCAN_UI/UI_Framework/SCANicon.cs index b566584ff..9b4bd9f79 100644 --- a/SCANsat/SCAN_UI/UI_Framework/SCANicon.cs +++ b/SCANsat/SCAN_UI/UI_Framework/SCANicon.cs @@ -17,10 +17,10 @@ using System.Reflection; using UnityEngine; -using palette = SCANsat.SCAN_UI.SCANpalette; -using Log = SCANsat.Platform.Logging.ConsoleLogger; +using palette = SCANsat.SCAN_UI.UI_Framework.SCANpalette; +using Log = SCANsat.SCAN_Platform.Logging.ConsoleLogger; -namespace SCANsat.SCAN_UI +namespace SCANsat.SCAN_UI.UI_Framework { public static class String_ { @@ -124,6 +124,41 @@ internal static void drawOrbitIcon(int x, int y, OrbitIcon icon, Color c, int si GUI.color = old; } + internal static void drawOrbitIconGL(int x, int y, OrbitIcon icon, Color c, Color shadow, Material iconMat, int size = 32 /*px*/, bool outline = false) + { + // PX [0..n] + // ORIGIN: NorthWest + pos_icon.x = x - (size / 2); + pos_icon.y = y - (size / 2); + pos_icon.width = size; + pos_icon.height = size; + + // UV [0..1] + // Origin: SouthWest + grid_pos.width = 0.2f; + grid_pos.height = 0.2f; + grid_pos.x = 0.2f * ((int)icon % 5); + grid_pos.y = 0.2f * (4 - (int)icon / 5); + + if (outline) + { + iconMat.color = shadow; + pos_icon.x -= 1; + Graphics.DrawTexture(pos_icon, MapView.OrbitIconsMap, grid_pos, 0, 0, 0, 0, iconMat); + pos_icon.x += 2; + Graphics.DrawTexture(pos_icon, MapView.OrbitIconsMap, grid_pos, 0, 0, 0, 0, iconMat); + pos_icon.x -= 1; + pos_icon.y -= 1; + Graphics.DrawTexture(pos_icon, MapView.OrbitIconsMap, grid_pos, 0, 0, 0, 0, iconMat); + pos_icon.y += 2; + Graphics.DrawTexture(pos_icon, MapView.OrbitIconsMap, grid_pos, 0, 0, 0, 0, iconMat); + pos_icon.y -= 1; + } + + iconMat.color = c; + Graphics.DrawTexture(pos_icon, MapView.OrbitIconsMap, grid_pos, 0, 0, 0, 0, iconMat); + } + public static void drawIcon(Color c, int size = 32 /*px*/, bool outline = false) { var old = GUI.color; diff --git a/SCANsat/SCAN_UI/UI_Framework/SCANpalette.cs b/SCANsat/SCAN_UI/UI_Framework/SCANpalette.cs index 5311b9896..db105c453 100644 --- a/SCANsat/SCAN_UI/UI_Framework/SCANpalette.cs +++ b/SCANsat/SCAN_UI/UI_Framework/SCANpalette.cs @@ -13,10 +13,11 @@ //using System.Collections.Generic; //using System.Text.RegularExpressions; using UnityEngine; -using SCANsat.Platform.Palettes; -using SCANsat.Platform.Palettes.ColorBrewer; +using SCANsat.SCAN_Data; +using SCANsat.SCAN_Platform.Palettes; +using SCANsat.SCAN_Platform.Palettes.ColorBrewer; -namespace SCANsat.SCAN_UI +namespace SCANsat.SCAN_UI.UI_Framework { public class SCANpalette { diff --git a/SCANsat/SCAN_UI/UI_Framework/SCANremoteView.cs b/SCANsat/SCAN_UI/UI_Framework/SCANremoteView.cs index bba417dd8..e502bc8ed 100644 --- a/SCANsat/SCAN_UI/UI_Framework/SCANremoteView.cs +++ b/SCANsat/SCAN_UI/UI_Framework/SCANremoteView.cs @@ -11,10 +11,10 @@ using System; using System.Collections.Generic; using UnityEngine; -using palette = SCANsat.SCAN_UI.SCANpalette; +using palette = SCANsat.SCAN_UI.UI_Framework.SCANpalette; -namespace SCANsat.SCAN_UI +namespace SCANsat.SCAN_UI.UI_Framework { public class SCANremoteView { diff --git a/SCANsat/SCAN_UI/UI_Framework/SCANskins.cs b/SCANsat/SCAN_UI/UI_Framework/SCANskins.cs index 83c4f420a..02f81983b 100644 --- a/SCANsat/SCAN_UI/UI_Framework/SCANskins.cs +++ b/SCANsat/SCAN_UI/UI_Framework/SCANskins.cs @@ -15,13 +15,13 @@ using System; using System.Collections.Generic; using System.Linq; -using SCANsat.Platform; -using SCANsat.Platform.Palettes; -using palette = SCANsat.SCAN_UI.SCANpalette; +using SCANsat.SCAN_Platform; +using SCANsat.SCAN_Platform.Palettes; +using palette = SCANsat.SCAN_UI.UI_Framework.SCANpalette; using UnityEngine; -namespace SCANsat.SCAN_UI +namespace SCANsat.SCAN_UI.UI_Framework { [KSPAddon(KSPAddon.Startup.MainMenu, true)] class SCANskins: SCAN_MBE @@ -99,6 +99,10 @@ class SCANskins: SCAN_MBE internal static Texture2D SCAN_SmallMapIcon; internal static Texture2D SCAN_BigMapIcon; + //App Launcher Textures + internal static Texture2D SCAN_SmallMapAppIcon; + internal static Texture2D SCAN_BigMapAppIcon; + protected override void OnGUI_FirstRun() { initializeTextures(); @@ -126,6 +130,8 @@ private static void initializeTextures() SCAN_BigMapIcon = GameDatabase.Instance.GetTexture("SCANsat/Icons/SCANsat_Map_Icon", false); SCAN_ScreenshotIcon = GameDatabase.Instance.GetTexture("SCANsat/Icons/SCAN_Screenshot_Icon", false); SCAN_ResizeIcon = GameDatabase.Instance.GetTexture("SCANsat/Icons/SCAN_Resize_Icon", false); + SCAN_SmallMapAppIcon = GameDatabase.Instance.GetTexture("SCANsat/Icons/SCANsat_AppLauncherSmall_Icon", false); + SCAN_BigMapAppIcon = GameDatabase.Instance.GetTexture("SCANsat/Icons/SCANsat_AppLauncherLarge_Icon", false); } private static void initializeColors() @@ -213,6 +219,7 @@ private static void initializeSkins() SCAN_whiteReadoutLabel = new GUIStyle(SCAN_readoutLabel); SCAN_whiteReadoutLabel.name = "SCAN_WhiteLabel"; SCAN_whiteReadoutLabel.normal.textColor = palette.white; + SCAN_whiteReadoutLabel.wordWrap = false; SCAN_activeReadoutLabel = new GUIStyle(SCAN_readoutLabel); SCAN_activeReadoutLabel.name = "SCAN_ActiveLabel"; @@ -230,15 +237,13 @@ private static void initializeSkins() SCAN_insColorLabel = new GUIStyle(SCAN_label); SCAN_insColorLabel.name = "SCAN_InsColorLabel"; SCAN_insColorLabel.alignment = TextAnchor.MiddleCenter; - SCAN_insColorLabel.font = dotty; - SCAN_insColorLabel.fontSize = 36; + SCAN_insColorLabel.fontSize = 20; SCAN_insWhiteLabel = new GUIStyle(SCAN_whiteReadoutLabel); SCAN_insWhiteLabel.name = "SCAN_InsWhiteLabel"; SCAN_insWhiteLabel.alignment = TextAnchor.MiddleCenter; SCAN_insWhiteLabel.fontStyle = FontStyle.Normal; - SCAN_insWhiteLabel.font = dotty; - SCAN_insWhiteLabel.fontSize = 36; + SCAN_insWhiteLabel.fontSize = 20; SCAN_anomalyOverlay = new GUIStyle(SCAN_SkinsLibrary.DefUnitySkin.label); SCAN_anomalyOverlay.name = "SCAN_AnomalyOverlay"; diff --git a/SCANsat/SCAN_UI/UI_Framework/SCANuiUtil.cs b/SCANsat/SCAN_UI/UI_Framework/SCANuiUtil.cs index 27ffadbfd..ab0e65095 100644 --- a/SCANsat/SCAN_UI/UI_Framework/SCANuiUtil.cs +++ b/SCANsat/SCAN_UI/UI_Framework/SCANuiUtil.cs @@ -16,11 +16,13 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; -using SCANsat.Platform; -using palette = SCANsat.SCAN_UI.SCANpalette; +using SCANsat.SCAN_Platform; +using SCANsat.SCAN_Data; +using SCANsat.SCAN_Map; +using palette = SCANsat.SCAN_UI.UI_Framework.SCANpalette; using UnityEngine; -namespace SCANsat.SCAN_UI +namespace SCANsat.SCAN_UI.UI_Framework { static class SCANuiUtil { @@ -112,7 +114,7 @@ internal static void mouseOverInfo(double lon, double lat, SCANmap mapObj, SCANd if (b) { - if (SCANUtil.isCovered(lon, lat, data, SCANdata.SCANtype.AltimetryLoRes)) + if (SCANUtil.isCovered(lon, lat, data, SCANtype.AltimetryLoRes)) { if (body.pqsController == null) info += palette.colored(palette.c_ugly, "LO "); @@ -121,7 +123,7 @@ internal static void mouseOverInfo(double lon, double lat, SCANmap mapObj, SCANd } else info += palette.colored(palette.grey, "LO "); - if (SCANUtil.isCovered(lon, lat, data, SCANdata.SCANtype.AltimetryHiRes)) + if (SCANUtil.isCovered(lon, lat, data, SCANtype.AltimetryHiRes)) { if (body.pqsController == null) info += palette.colored(palette.c_ugly, "HI "); @@ -130,7 +132,7 @@ internal static void mouseOverInfo(double lon, double lat, SCANmap mapObj, SCANd } else info += palette.colored(palette.grey, "HI "); - if (SCANUtil.isCovered(lon, lat, data, SCANdata.SCANtype.Biome)) + if (SCANUtil.isCovered(lon, lat, data, SCANtype.Biome)) { if (body.BiomeMap == null) info += palette.colored(palette.c_ugly, "MULTI "); @@ -139,15 +141,15 @@ internal static void mouseOverInfo(double lon, double lat, SCANmap mapObj, SCANd } else info += palette.colored(palette.grey, "MULTI "); - if (SCANUtil.isCovered(lon, lat, data, SCANdata.SCANtype.AltimetryHiRes)) + if (SCANUtil.isCovered(lon, lat, data, SCANtype.AltimetryHiRes)) { info += SCANUtil.getElevation(body, lon, lat).ToString("N2") + "m "; } - else if (SCANUtil.isCovered(lon, lat, data, SCANdata.SCANtype.AltimetryLoRes)) + else if (SCANUtil.isCovered(lon, lat, data, SCANtype.AltimetryLoRes)) { info += (((int)SCANUtil.getElevation(body, lon, lat) / 500) * 500).ToString() + "m "; } - if (SCANUtil.isCovered(lon, lat, data, SCANdata.SCANtype.Biome)) + if (SCANUtil.isCovered(lon, lat, data, SCANtype.Biome)) { info += SCANUtil.getBiomeName(body, lon, lat) + " "; } @@ -156,24 +158,21 @@ internal static void mouseOverInfo(double lon, double lat, SCANmap mapObj, SCANd { if (SCANcontroller.controller.resourceOverlayType == 0 && SCANversions.RegolithFound) { - if (SCANUtil.isCovered(lon, lat, data, mapObj.resource.Type)) + if (SCANUtil.isCovered(lon, lat, data, mapObj.Resource.Type)) { - double amount = SCANUtil.RegolithOverlay(lat, lon, mapObj.resource.Name, mapObj.body.flightGlobalsIndex); + double amount = SCANUtil.RegolithOverlay(lat, lon, mapObj.Resource.Name, mapObj.Body.flightGlobalsIndex); string label; - //if (mapObj.resource.linear) //Make sure that ORS values are handled correctly based on which scale type they use label = amount.ToString("P2"); - //else - // label = (amount * 1000000).ToString("N1") + " ppm"; - info += palette.colored(mapObj.resource.fullColor, mapObj.resource.Name + ": " + label); + info += palette.colored(mapObj.Resource.FullColor, mapObj.Resource.Name + ": " + label); } } else if (SCANcontroller.controller.resourceOverlayType == 1) { - if (SCANUtil.isCovered(lon, lat, data, mapObj.resource.Type)) + if (SCANUtil.isCovered(lon, lat, data, mapObj.Resource.Type)) { double amount = data.KethaneValueMap[SCANUtil.icLON(lon), SCANUtil.icLAT(lat)]; if (amount < 0) amount = 0d; - info += palette.colored(mapObj.resource.fullColor, mapObj.resource.Name + ": " + amount.ToString("N1")); + info += palette.colored(mapObj.Resource.FullColor, mapObj.Resource.Name + ": " + amount.ToString("N1")); } } } @@ -199,7 +198,7 @@ internal static string InfoText(Vessel v, SCANdata data, bool b) SCANcontroller.SCANsensor s; //Check here for each sensor; if active, in range, and at the ideal altitude - s = SCANcontroller.controller.getSensorStatus(v, SCANdata.SCANtype.AltimetryLoRes); + s = SCANcontroller.controller.getSensorStatus(v, SCANtype.AltimetryLoRes); if (s == null) infotext += palette.colored(palette.grey, "LO"); else if (!s.inRange) @@ -209,7 +208,7 @@ internal static string InfoText(Vessel v, SCANdata data, bool b) else infotext += palette.colored(palette.c_good, "LO"); - s = SCANcontroller.controller.getSensorStatus(v, SCANdata.SCANtype.AltimetryHiRes); + s = SCANcontroller.controller.getSensorStatus(v, SCANtype.AltimetryHiRes); if (s == null) infotext += palette.colored(palette.grey, " HI"); else if (!s.inRange) @@ -219,7 +218,7 @@ internal static string InfoText(Vessel v, SCANdata data, bool b) else infotext += palette.colored(palette.c_good, " HI"); - s = SCANcontroller.controller.getSensorStatus(v, SCANdata.SCANtype.Biome); + s = SCANcontroller.controller.getSensorStatus(v, SCANtype.Biome); if (s == null) infotext += palette.colored(palette.grey, " MULTI"); else if (!s.inRange) @@ -229,7 +228,7 @@ internal static string InfoText(Vessel v, SCANdata data, bool b) else infotext += palette.colored(palette.c_good, " MULTI"); - s = SCANcontroller.controller.getSensorStatus(v, SCANdata.SCANtype.AnomalyDetail); + s = SCANcontroller.controller.getSensorStatus(v, SCANtype.AnomalyDetail); if (s == null) infotext += palette.colored(palette.grey, " BTDT"); else if (!s.inRange) @@ -240,10 +239,10 @@ internal static string InfoText(Vessel v, SCANdata data, bool b) infotext += palette.colored(palette.c_good, " BTDT"); //Get coverage percentage for all active scanners on the vessel - SCANdata.SCANtype active = SCANcontroller.controller.activeSensorsOnVessel(v.id); - if (active != SCANdata.SCANtype.Nothing) + SCANtype active = SCANcontroller.controller.activeSensorsOnVessel(v.id); + if (active != SCANtype.Nothing) { - double cov = data.getCoveragePercentage(active); + double cov = SCANUtil.getCoveragePercentage(data, active); infotext += string.Format(" {0:N1}%", cov); if (b) { @@ -391,7 +390,7 @@ internal static void drawMapLabels(Rect maprect, Vessel vessel, SCANmap map, SCA //This section handles anomaly labels if (SCANcontroller.controller.map_markers) { - foreach (SCANdata.SCANanomaly anomaly in data.Anomalies) + foreach (SCANanomaly anomaly in data.Anomalies) { drawAnomalyLabel(maprect, map, anomaly); } @@ -404,16 +403,16 @@ internal static void drawMapLabels(Rect maprect, Vessel vessel, SCANmap map, SCA } //Method to draw anomaly labels on the map - internal static void drawAnomalyLabel(Rect maprect, SCANmap map, SCANdata.SCANanomaly anomaly) + internal static void drawAnomalyLabel(Rect maprect, SCANmap map, SCANanomaly anomaly) { - if (!anomaly.known) + if (!anomaly.Known) return; - double lon = (anomaly.longitude + 360 + 180) % 360; - double lat = (anomaly.latitude + 180 + 90) % 180; + double lon = (anomaly.Longitude + 360 + 180) % 360; + double lat = (anomaly.Latitude + 180 + 90) % 180; if (map != null) { - lat = (map.projectLatitude(anomaly.longitude, anomaly.latitude) + 90) % 180; - lon = (map.projectLongitude(anomaly.longitude, anomaly.latitude) + 180) % 360; + lat = (map.projectLatitude(anomaly.Longitude, anomaly.Latitude) + 90) % 180; + lon = (map.projectLongitude(anomaly.Longitude, anomaly.Latitude) + 180) % 360; lat = map.scaleLatitude(lat); lon = map.scaleLongitude(lon); if (lat < 0 || lon < 0 || lat > 180 || lon > 360) @@ -421,8 +420,8 @@ internal static void drawAnomalyLabel(Rect maprect, SCANmap map, SCANdata.SCANan } lon = lon * maprect.width / 360f; lat = maprect.height - lat * maprect.height / 180f; - string txt = SCANcontroller.controller.anomalyMarker + " " + anomaly.name; - if (!anomaly.detail) + string txt = SCANcontroller.controller.anomalyMarker + " " + anomaly.Name; + if (!anomaly.Detail) txt = SCANcontroller.controller.anomalyMarker + " Anomaly"; Rect r = new Rect(maprect.x + (float)lon, maprect.y + (float)lat, 250f, 25f); drawLabel(r, txt, true, true, true); @@ -435,7 +434,7 @@ internal static void drawLegendLabel(Rect r, float val, float min, float max) return; float scale = r.width * 1f / (max - min); float x = r.x + scale * (val - min); - Rect lr = new Rect(x, r.y + r.height / 4, r.width - x, r.height); + Rect lr = new Rect(x, r.y + r.height / 4, 15, r.height); drawLabel(lr, "|", false, true, true); string txt = val.ToString("N0"); GUIContent c = new GUIContent(txt); @@ -446,6 +445,7 @@ internal static void drawLegendLabel(Rect r, float val, float min, float max) lr.x = r.x; if (lr.x + dim.x > r.x + r.width) lr.x = r.x + r.width - dim.x; + lr.width = dim.x; drawLabel(lr, txt, false, true, true); } @@ -464,12 +464,12 @@ internal static void drawSliderLabel(Rect r, string min, string max) } /* FIXME: This uses assumed, shared, static constants with Legend stuff in other SCANsat files */ - internal static void drawLegend(SCANdata data) + internal static void drawLegend(SCANdata data, SCANmapLegend legend) { GUILayout.Label("", GUILayout.ExpandWidth(true)); Rect r = GUILayoutUtility.GetLastRect(); r.width -= 64; - GUI.DrawTexture(r, SCANmap.getLegend(data.MinHeight, data.MaxHeight, SCANcontroller.controller.colours, data)); + GUI.DrawTexture(r, legend.Legend); //SCANmapLegend.getLegend(data.MinHeight, data.MaxHeight, SCANcontroller.controller.colours, data)); float minLabel = data.MinHeight; float maxLabel = data.MaxHeight; if (data.MinHeight % 1000 != 0) @@ -493,35 +493,230 @@ internal static void drawLegend(SCANdata data) #region Overlays //Setup the lat/long grid - internal static void drawGrid(Rect maprect, SCANmap map, Texture2D overlay_static) + //internal static void drawGrid(Rect maprect, SCANmap map, Texture2D overlay_static) + //{ + // int x, y; + // for (double lat = -90; lat < 90; lat += 2) + // { + // for (double lon = -180; lon < 180; lon += 2) + // { + // if (lat % 30 == 0 || lon % 30 == 0) + // { + // x = (int)(map.MapScale * ((map.projectLongitude(lon, lat) + 180) % 360)); + // y = (int)(map.MapScale * ((map.projectLatitude(lon, lat) + 90) % 180)); + // drawDot(x, y, palette.white, overlay_static); + // } + // } + // } + //} + + //Draw the actual dot textures for the grid + //private static void drawDot(int x, int y, Color c, Texture2D tex) + //{ + // tex.SetPixel(x, y, c); + // tex.SetPixel(x - 1, y, palette.black); + // tex.SetPixel(x + 1, y, palette.black); + // tex.SetPixel(x, y - 1, palette.black); + // tex.SetPixel(x, y + 1, palette.black); + //} + + internal static Color32 lineColor = new Color(1f, 1f, 1f, 1f); + internal static Color32 blackLineColor = new Color(0f, 0f, 0f, 0.9f); + private static Material lineMat = JUtil.DrawLineMaterial(); + + internal static Dictionary>> drawGridLine(Rect maprect, SCANmap map) { - int x, y; - for (double lat = -90; lat < 90; lat += 2) + var lineDict = new Dictionary>>(); + var whiteLineList = new List>(); + var blackLineList = new List>(); + + switch (map.Projection) { - for (double lon = -180; lon < 180; lon += 2) - { - if (lat % 30 == 0 || lon % 30 == 0) + case MapProjection.Rectangular: { - x = (int)(map.mapscale * ((map.projectLongitude(lon, lat) + 180) % 360)); - y = (int)(map.mapscale * ((map.projectLatitude(lon, lat) + 90) % 180)); - drawDot(x, y, palette.white, overlay_static); + for (double lon = -150; lon <= 150; lon += 30) + { + List points = new List(); + List pointsBlack = new List(); + points.Add(new Vector2d((int)(map.MapScale * (lon + 180)), 0)); + points.Add(new Vector2d((int)(map.MapScale * (lon + 180)), (int)(map.MapScale * 180))); + pointsBlack.Add(new Vector2d(points[0].x + 1, points[0].y)); + pointsBlack.Add(new Vector2d(points[1].x + 1, points[1].y)); + + whiteLineList.Add(points); + blackLineList.Add(pointsBlack); + } + for (double lat = -60; lat <= 60; lat += 30) + { + List points = new List(); + List pointsBlack = new List(); + points.Add(new Vector2d(0, (int)(map.MapScale * (lat + 90)))); + points.Add(new Vector2d((int)(map.MapScale * 360), (int)(map.MapScale * (lat + 90)))); + pointsBlack.Add(new Vector2d(points[0].x, points[0].y - 1)); + pointsBlack.Add(new Vector2d(points[1].x, points[1].y - 1)); + + whiteLineList.Add(points); + blackLineList.Add(pointsBlack); + } + break; + } + case MapProjection.KavrayskiyVII: + { + for (double lon = -150; lon <= 150; lon += 30) + { + List points = new List(); + List pointsBlack = new List(); + int i = 0; + for (double lat = -88; lat <= 88; lat += 4) + { + points.Add(new Vector2d((int)(map.MapScale * (map.projectLongitude(lon, lat) + 180)), (int)(map.MapScale * (map.projectLatitude(lon, lat) + 90)))); + pointsBlack.Add(new Vector2d(points[i].x + 1, points[i].y)); + i++; + } + + whiteLineList.Add(points); + blackLineList.Add(pointsBlack); + } + for (double lat = -60; lat <= 60; lat += 30) + { + List points = new List(); + List pointsBlack = new List(); + points.Add(new Vector2d((int)(map.MapScale * (map.projectLongitude(-179, lat) + 180)), (int)(map.MapScale * (lat + 90)))); + points.Add(new Vector2d((int)(map.MapScale * (map.projectLongitude(179, lat) + 180)), (int)(map.MapScale * (lat + 90)))); + pointsBlack.Add(new Vector2d(points[0].x, points[0].y - 1)); + pointsBlack.Add(new Vector2d(points[1].x, points[1].y - 1)); + + whiteLineList.Add(points); + blackLineList.Add(pointsBlack); + } + break; + } + case MapProjection.Polar: + { + for (double lon = -180; lon <= 150; lon += 30) + { + List pointsS = new List(); + List pointsBlackS = new List(); + pointsS.Add(new Vector2d((int)(map.MapScale * (map.projectLongitude(lon, -88) + 180)), (int)(map.MapScale * (map.projectLatitude(lon, -88) + 90)))); + pointsS.Add(new Vector2d((int)(map.MapScale * (map.projectLongitude(lon, -2) + 180)), (int)(map.MapScale * (map.projectLatitude(lon, -2) + 90)))); + + whiteLineList.Add(pointsS); + + List pointsN = new List(); + List pointsBlackN = new List(); + pointsN.Add(new Vector2d((int)(map.MapScale * (map.projectLongitude(lon, 2) + 180)), (int)(map.MapScale * (map.projectLatitude (lon, 2) + 90)))); + pointsN.Add(new Vector2d((int)(map.MapScale * (map.projectLongitude(lon, 88) + 180)), (int)(map.MapScale * (map.projectLatitude(lon, 88) + 90)))); + + whiteLineList.Add(pointsN); + + if (lon == -180 || lon == 0) + { + pointsBlackS.Add(new Vector2d(pointsS[0].x + 1, pointsS[0].y)); + pointsBlackS.Add(new Vector2d(pointsS[1].x + 1, pointsS[1].y)); + pointsBlackN.Add(new Vector2d(pointsN[0].x + 1, pointsN[0].y)); + pointsBlackN.Add(new Vector2d(pointsN[1].x + 1, pointsN[1].y)); + } + else if (lon == -90 || lon == 90) + { + pointsBlackS.Add(new Vector2d(pointsS[0].x, pointsS[0].y - 1)); + pointsBlackS.Add(new Vector2d(pointsS[1].x, pointsS[1].y - 1)); + pointsBlackN.Add(new Vector2d(pointsN[0].x, pointsN[0].y - 1)); + pointsBlackN.Add(new Vector2d(pointsN[1].x, pointsN[1].y - 1)); + } + else if (lon == -60 || lon == -30 || lon == 120 || lon == 150) + { + pointsBlackS.Add(new Vector2d(pointsS[0].x - 1, pointsS[0].y - 1)); + pointsBlackS.Add(new Vector2d(pointsS[1].x - 1, pointsS[1].y - 1)); + pointsBlackN.Add(new Vector2d(pointsN[0].x + 1, pointsN[0].y - 1)); + pointsBlackN.Add(new Vector2d(pointsN[1].x + 1, pointsN[1].y - 1)); + } + else + { + pointsBlackS.Add(new Vector2d(pointsS[0].x + 1, pointsS[0].y - 1)); + pointsBlackS.Add(new Vector2d(pointsS[1].x + 1, pointsS[1].y - 1)); + pointsBlackN.Add(new Vector2d(pointsN[0].x - 1, pointsN[0].y - 1)); + pointsBlackN.Add(new Vector2d(pointsN[1].x - 1, pointsN[1].y - 1)); + } + blackLineList.Add(pointsBlackS); + blackLineList.Add(pointsBlackN); + } + for (double lat = -88; lat <= 88; lat += 2) + { + if (lat != 0) + { + if (lat % 30 == 0 || lat == -88 || lat == 88) + { + List points = new List(); + List pointsBlack = new List(); + for (double lon = -180; lon <= 180; lon += 4) + { + points.Add(new Vector2d((int)(map.MapScale * (map.projectLongitude(lon, lat) + 180)), (int)(map.MapScale * (map.projectLatitude(lon, lat) + 90)))); + float offset = 0; + if (lat == 30) offset = -0.8f; + else if (lat == -30) offset = 0.8f; + else if (lat == 60) offset = -0.3f; + else if (lat == -60) offset = 0.3f; + if (lat != -88 && lat != 88) + pointsBlack.Add(new Vector2d((int)(map.MapScale * (map.projectLongitude(lon, lat + offset) + 180)), (int)(map.MapScale * (map.projectLatitude(lon, lat + offset) + 90)))); + } + whiteLineList.Add(points); + blackLineList.Add(pointsBlack); + } + } + } + break; } - } } + + lineDict.Add(0, blackLineList); + lineDict.Add(1, whiteLineList); + + return lineDict; } - //Draw the actual dot textures for the grid - private static void drawDot(int x, int y, Color c, Texture2D tex) + internal static void drawGridLines(IList points, float mapWidth, float left, float top, Color c) { - tex.SetPixel(x, y, c); - tex.SetPixel(x - 1, y, palette.black); - tex.SetPixel(x + 1, y, palette.black); - tex.SetPixel(x, y - 1, palette.black); - tex.SetPixel(x, y + 1, palette.black); + if (points.Count < 2) + return; + GL.Begin(GL.LINES); + lineMat.SetPass(0); + GL.Color(c); + float xStart, yStart; + xStart = (float)points[0].x; + yStart = (mapWidth / 2) - (float)points[0].y; + if (xStart < 0 || yStart < 0 || yStart > (mapWidth / 2) || xStart > mapWidth) + return; + xStart += left; + yStart += top; + for (int i = 1; i < points.Count; i++) + { + + float xEnd = (float)points[i].x; + float yEnd = (mapWidth / 2) - (float)points[i].y; + if (xEnd < 0 || yEnd < 0 || yEnd > (mapWidth / 2) || xEnd > mapWidth) + continue; + xEnd += left; + yEnd += top; + + drawLine(xStart, yStart, xEnd, yEnd); + + xStart = xEnd; + yStart = yEnd; + } + GL.End(); } - //Draw the orbit overlay; needs to be replaced with the method used by SCANsatRPM - internal static void drawOrbit(Rect maprect, SCANmap map, Vessel vessel, double startUT, Texture2D overlay_static, CelestialBody body) + private static void drawLine(float xStart, float yStart, float xEnd, float yEnd) + { + var start = new Vector2(xStart, yStart); + var end = new Vector2(xEnd, yEnd); + + GL.Vertex(start); + GL.Vertex(end); + } + + //Draw the orbit overlay + internal static void drawOrbit(Rect maprect, SCANmap map, Vessel vessel, CelestialBody body) { if (vessel.mainBody != body) return; int eqh = 16; @@ -530,9 +725,9 @@ internal static void drawOrbit(Rect maprect, SCANmap map, Vessel vessel, double return; bool lite = maprect.width < 400; Orbit o = vessel.orbit; - startUT = Planetarium.GetUniversalTime(); + double startUT = Planetarium.GetUniversalTime(); double UT = startUT; - int steps = 100; // increase for neater lines, decrease for better speed indication + int steps = 80; // increase for neater lines, decrease for better speed indication bool ath = false; if (vessel.mainBody.atmosphere) { @@ -675,9 +870,7 @@ internal static void drawOrbit(Rect maprect, SCANmap map, Vessel vessel, double if (o.PeA < 0) return; - if (overlay_static == null) - return; - if (map.projection == SCANmap.MapProjection.Polar) + if (map.Projection == MapProjection.Polar) return; if (SCANnewBigMap.eq_frame <= 0) @@ -690,10 +883,10 @@ internal static void drawOrbit(Rect maprect, SCANmap map, Vessel vessel, double double tAN = (((MAAN - o.meanAnomaly * Mathf.Rad2Deg + 360) % 360) / 360f * o.period + startUT); double tDN = (((MADN - o.meanAnomaly * Mathf.Rad2Deg + 360) % 360) / 360f * o.period + startUT); - if (SCANnewBigMap.eq_an_map == null || SCANnewBigMap.eq_dn_map == null || SCANnewBigMap.eq_an_map.Length != overlay_static.width) + if (SCANnewBigMap.eq_an_map == null || SCANnewBigMap.eq_dn_map == null || SCANnewBigMap.eq_an_map.Length != maprect.width) { - SCANnewBigMap.eq_an_map = new int[overlay_static.width]; - SCANnewBigMap.eq_dn_map = new int[overlay_static.width]; + SCANnewBigMap.eq_an_map = new int[(int)maprect.width]; + SCANnewBigMap.eq_dn_map = new int[(int)maprect.width]; } if (SCANnewBigMap.eq_map == null || SCANnewBigMap.eq_map.width != SCANnewBigMap.eq_an_map.Length) { @@ -840,5 +1033,116 @@ internal static double meanForTrue(double TA, double e) #endregion + #region newOrbitOverlay + + + + //internal static void newOrbitLine(Rect mapRect, SCANmap map, Vessel v, Orbit o, double startUT, CelestialBody b, int steps) + //{ + // if (steps == 0) + // return; + // double dTstep = Math.Floor(o.period / steps); + // startUT = Planetarium.GetUniversalTime(); + // var points = new List(); + // for (double time = (startUT - o.period); time < (startUT + o.period); time += dTstep) + // { + // bool collide; + // Vector2d coord; + // if (mapPosAtT(v, o, startUT, time, out coord, out collide)) + // points.Add(coord); + // if (collide) + // break; + // } + // //SCANUtil.SCANdebugLog("Orbit Line With {0} Points", points.Count); + // drawTrail(mapRect, map, points, Vector2d.zero); + //} + + //private static void drawTrail(Rect mapRect, SCANmap map, IList points, Vector2d end, bool hasEnd = false) + //{ + // if (points.Count < 2) + // return; + // GL.Begin(GL.LINES); + // lineMat.SetPass(0); + // GL.Color(lineColor); + // float xStart, yStart; + // float mapWidth = map.MapWidth; + // float mapHeight = map.MapHeight; + // xStart = (float)SCANUtil.fixLon(map.projectLongitude(points[0].x, points[0].y)); + // yStart = (float)SCANUtil.fixLat(map.projectLatitude(points[0].x, points[0].y)); + // xStart = (float)map.scaleLongitude(xStart); + // yStart = (float)map.scaleLatitude(yStart); + // if (xStart < 0 || yStart < 0 || yStart > 180 || xStart > 360) + // return; + // //SCANUtil.SCANdebugLog("Start Point Checks Out"); + // xStart = (xStart * mapWidth / 360f) + mapRect.x; + // yStart = (map.MapHeight - yStart * map.MapHeight / 180f) + mapRect.y; + // for (int i = 1; i < points.Count; i++) + // { + // float xEnd = (float)SCANUtil.fixLon(map.projectLongitude(points[i].x, points[i].y)); + // float yEnd = (float)SCANUtil.fixLat(map.projectLatitude(points[i].x, points[i].y)); + // xEnd = (float)map.scaleLongitude(xEnd); + // yEnd = (float)map.scaleLatitude(yEnd); + // //SCANUtil.SCANdebugLog("Checking Orbit End Point..."); + // if (xEnd < 0 || yEnd < 1|| yEnd > 179|| xEnd > 360) + // continue; + // xEnd = (xEnd* mapWidth / 360f) + mapRect.x; + // yEnd = (mapHeight - yEnd * mapHeight / 180f) + mapRect.y; + + // //SCANUtil.SCANdebugLog("Draw Line {0}", i); + // drawLine(xStart, yStart, xEnd, yEnd, mapRect, mapWidth); + + // xStart = xEnd; + // yStart = yEnd; + // } + // GL.End(); + //} + + //private static void drawLine(float xStart, float yStart, float xEnd, float yEnd, Rect mapRect, float width) + //{ + // var start = new Vector2(xStart, yStart); + // var end = new Vector2(xEnd, yEnd); + + // if (!mapRect.Contains(start) && !mapRect.Contains(end)) + // return; + + // //float leftX = Math.Min(start.x, end.x); + // //float rightX = Math.Max(start.x, end.x); + + // //if (leftX + width * 0.5f < rightX) + // //{ + // // if (start.x < end.x) + // // end.x -= width; + // // else + // // start.x -= width; + // //} + + // GL.Vertex(start); + // GL.Vertex(end); + //} + + //private static bool mapPosAtT(Vessel v, Orbit o, double start, double dT, out Vector2d Coord, out bool Collide) + //{ + // Coord = Vector2d.zero; + // Collide = false; + // double UT = start + dT; + // if (double.IsNaN(UT)) + // return false; + // if (double.IsNaN(o.getObtAtUT(UT))) + // return false; + // double rotOffset = 0; + // if (v.mainBody.rotates) + // rotOffset = (360 * ((dT - start) / v.mainBody.rotationPeriod)) % 360; + // Vector3d pos = o.getPositionAtUT(dT); + // if (o.Radius(dT) < v.mainBody.Radius + v.mainBody.getElevation(pos)) + // { + // Collide = true; + // return false; + // } + // Coord = new Vector2d(v.mainBody.GetLongitude(pos) - rotOffset, v.mainBody.GetLatitude(pos)); + // return true; + //} + + #endregion + } } diff --git a/SCANsat/SCANcontroller.cs b/SCANsat/SCANcontroller.cs index ac07b2554..4790980c6 100644 --- a/SCANsat/SCANcontroller.cs +++ b/SCANsat/SCANcontroller.cs @@ -17,11 +17,13 @@ using System.Collections.Generic; using UnityEngine; using SCANsat.SCAN_UI; -using SCANsat.Platform; -using SCANsat.Platform.Palettes; -using SCANsat.Platform.Palettes.ColorBrewer; -using SCANsat.Platform.Palettes.FixedColors; -using palette = SCANsat.SCAN_UI.SCANpalette; +using SCANsat.SCAN_Data; +using SCANsat.SCAN_Platform; +using SCANsat.SCAN_Platform.Palettes; +using SCANsat.SCAN_Platform.Palettes.ColorBrewer; +using SCANsat.SCAN_Platform.Palettes.FixedColors; +using SCANsat.SCAN_Toolbar; +using palette = SCANsat.SCAN_UI.UI_Framework.SCANpalette; namespace SCANsat { @@ -50,9 +52,9 @@ public static SCANcontroller controller } } - public static int minScanAlt = 5000; - public static int maxScanAlt = 500000; - public static int bestScanAlt = 250000; + private static int minScanAlt = 5000; + private static int maxScanAlt = 500000; + private static int bestScanAlt = 250000; [KSPField(isPersistant = true)] public int colours = 0; [KSPField(isPersistant = true)] @@ -98,9 +100,11 @@ public static SCANcontroller controller public bool kscMapVisible = false; [KSPField(isPersistant = true)] public bool toolTips = true; + [KSPField(isPersistant = true)] + public bool useStockAppLauncher = true; - /* Available resources for overlays; loaded from resource addon configs */ - private static Dictionary> resourceList; + /* Available resources for overlays; loaded from resource addon configs; only loaded once */ + private static Dictionary> resourceList; /* Primary SCANsat vessel dictionary; loaded every time */ private Dictionary knownVessels = new Dictionary(); @@ -109,7 +113,7 @@ public static SCANcontroller controller private static Dictionary body_data = new Dictionary(); /* Resource types loaded from configs; only needs to be loaded once */ - private static Dictionary resourceTypes; + private static Dictionary resourceTypes; /* Kethane integration */ private bool kethaneRebuild, kethaneReset, kethaneBusy = false; @@ -122,12 +126,17 @@ public static SCANcontroller controller internal SCAN_MBW kscMap; internal SCAN_MBW colorManager; + /* App launcher object */ + internal SCANappLauncher appLauncher; + /* Used in case the loading process is interupted somehow */ private bool loaded = false; + /* Governs resource overlay availability */ private static bool globalResourceOverlay = false; #region Public Accessors + public static Dictionary Body_Data { get { return body_data; } @@ -142,16 +151,16 @@ public void addToBodyData (CelestialBody b, SCANdata data) Debug.LogError("[SCANsat] Warning: SCANdata Dictionary Already Contains Key of This Type"); } - public Dictionary> ResourceList + public Dictionary> ResourceList { get { return resourceList; } } - public void addToResourceData (string name, string body, SCANdata.SCANResource res) + public void addToResourceData (string name, string body, SCANresource res) { if (!resourceList.ContainsKey(name)) { - Dictionary subDict = new Dictionary(); + Dictionary subDict = new Dictionary(); subDict.Add(body, res); resourceList.Add(name, subDict); } @@ -159,12 +168,19 @@ public void addToResourceData (string name, string body, SCANdata.SCANResource r { if (!resourceList[name].ContainsKey(body)) resourceList[name].Add(body, res); + else if (res.Source == SCANresource_Source.Regolith) + { + if (res.MinValue > resourceList[name][body].MinValue && res.MinValue < res.MaxValue) + resourceList[name][body].MinValue = res.MinValue; + if (res.MaxValue > resourceList[name][body].MaxValue && res.MaxValue > res.MinValue) + resourceList[name][body].MaxValue = res.MaxValue; + } else Debug.LogError(string.Format("[SCANsat] Warning: SCANResource Dictionary Already Contains Key of This Type: Resource: {0}; Body: {1}", name, body)); } } - public static Dictionary ResourceTypes + public static Dictionary ResourceTypes { get { return resourceTypes; } internal set { resourceTypes = value; } @@ -247,7 +263,7 @@ public override void OnLoad(ConfigNode node) max_alt = maxScanAlt; if (!double.TryParse(node_sensor.GetValue("best_alt"), out best_alt)) best_alt = bestScanAlt; - registerSensor(id, (SCANdata.SCANtype)sensor, fov, min_alt, max_alt, best_alt); + registerSensor(id, (SCANtype)sensor, fov, min_alt, max_alt, best_alt); } } } @@ -277,11 +293,11 @@ public override void OnLoad(ConfigNode node) string mapdata = node_body.GetValue("Map"); if (dataRebuild) { //On the first load deserialize the "Map" value to both coverage arrays - SCANUtil.integerDeserialize(mapdata, true, data); + data.integerDeserialize(mapdata, true); } else { - SCANUtil.integerDeserialize(mapdata, false, data); + data.integerDeserialize(mapdata, false); } } catch (Exception e) @@ -339,7 +355,7 @@ public override void OnLoad(ConfigNode node) catch (Exception e) { SCANUtil.SCANlog("Something Went Wrong Loading Resource Data: {0}", e); - } + } try { if (HighLogic.LoadedScene == GameScenes.FLIGHT) @@ -404,7 +420,7 @@ public override void OnSave(ConfigNode node) node_body.AddValue("PaletteSize", body_scan.PaletteSize); node_body.AddValue("PaletteReverse", body_scan.PaletteReverse); node_body.AddValue("PaletteDiscrete", body_scan.PaletteDiscrete); - node_body.AddValue("Map", SCANUtil.integerSerialize(body_scan)); + node_body.AddValue("Map", body_scan.integerSerialize()); node_progress.AddNode(node_body); } node.AddNode(node_progress); @@ -425,7 +441,8 @@ private void Start() if (!body_data.ContainsKey(Planetarium.fetch.Home.name)) body_data.Add(Planetarium.fetch.Home.name, new SCANdata(Planetarium.fetch.Home)); } - + if (useStockAppLauncher) + appLauncher = gameObject.AddComponent(); } private void Update() @@ -433,13 +450,6 @@ private void Update() if (scan_background && loaded) { scanFromAllVessels(); -#if DEBUG - //if (HighLogic.LoadedScene == GameScenes.FLIGHT) - //{ - // SCANui.gui_ping(false); - // SCANui.gui_ping_maptraq(); - //} -#endif } } @@ -456,6 +466,8 @@ private void OnDestroy() Destroy(kscMap); if (newBigMap != null) Destroy(newBigMap); + if (appLauncher != null) + Destroy(appLauncher); } private void SOIChange(GameEvents.HostedFromToAction VC) @@ -506,7 +518,7 @@ private void paletteLoad(SCANdata data) public class SCANsensor { - public SCANdata.SCANtype sensor; + public SCANtype sensor; public double fov; public double min_alt, max_alt, best_alt; @@ -518,7 +530,7 @@ public class SCANvessel { public Guid id; public Vessel vessel; - public Dictionary sensors = new Dictionary(); + public Dictionary sensors = new Dictionary(); public CelestialBody body; public double latitude, longitude; @@ -528,30 +540,30 @@ public class SCANvessel internal void loadResources() //Repopulates the master resources list with data from config nodes { - resourceList = new Dictionary>(); + resourceList = new Dictionary>(); if (SCANversions.RegolithFound) { foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("REGOLITH_GLOBAL_RESOURCE")) { if (node != null) { - SCANdata.SCANResource resource = null; + SCANresource resource = null; if ((resource = SCANUtil.RegolithConfigLoad(node)) == null) continue; foreach (CelestialBody body in FlightGlobals.Bodies) { - SCANdata.SCANResource bodyResource = null; + SCANresource bodyResource = null; foreach(ConfigNode bodyNode in GameDatabase.Instance.GetConfigNodes("REGOLITH_PLANETARY_RESOURCE")) { bodyResource = SCANUtil.RegolithConfigLoad(bodyNode); if (bodyResource == null) continue; - if (string.IsNullOrEmpty(bodyResource.body)) + if (string.IsNullOrEmpty(bodyResource.Body)) { bodyResource = null; continue; } - if (bodyResource.body == body.name) + if (bodyResource.Body == body.name) { if (bodyResource.Name == resource.Name) break; @@ -569,7 +581,7 @@ internal void loadResources() //Repopulates the master resources list with data } else { - addToResourceData(bodyResource.Name, bodyResource.body, bodyResource); + addToResourceData(bodyResource.Name, bodyResource.Body, bodyResource); } } } @@ -582,11 +594,11 @@ internal void loadResources() //Repopulates the master resources list with data if (node != null) { string name = node.GetValue("Resource"); - SCANdata.SCANresourceType type = null; + SCANresourceType type = null; if ((type = SCANUtil.OverlayResourceType(name)) == null) continue; - Color full = type.colorFull; - Color empty = type.colorFull; + Color full = type.ColorFull; + Color empty = type.ColorFull; float max = 1000000f; ConfigNode subNode = node.GetNode("Generator"); if (subNode != null) @@ -612,7 +624,7 @@ internal void loadResources() //Repopulates the master resources list with data } if (bodySubValue) max = subMax; - SCANdata.SCANResource resource = new SCANdata.SCANResource(name, Body.name, full, empty, 0f, max, type, SCANdata.SCANResource_Source.Kethane); + SCANresource resource = new SCANresource(name, Body.name, full, empty, 0f, max, type, SCANresource_Source.Kethane); addToResourceData(name, Body.name, resource); } } @@ -631,7 +643,7 @@ internal void loadResources() //Repopulates the master resources list with data } } - internal void registerSensor(Vessel v, SCANdata.SCANtype sensors, double fov, double min_alt, double max_alt, double best_alt) + internal void registerSensor(Vessel v, SCANtype sensors, double fov, double min_alt, double max_alt, double best_alt) { registerSensor(v.id, sensors, fov, min_alt, max_alt, best_alt); knownVessels[v.id].vessel = v; @@ -639,7 +651,7 @@ internal void registerSensor(Vessel v, SCANdata.SCANtype sensors, double fov, do knownVessels[v.id].longitude = SCANUtil.fixLonShift(v.longitude); } - private void registerSensor(Guid id, SCANdata.SCANtype sensors, double fov, double min_alt, double max_alt, double best_alt) + private void registerSensor(Guid id, SCANtype sensors, double fov, double min_alt, double max_alt, double best_alt) { if (id == null) return; @@ -652,10 +664,10 @@ private void registerSensor(Guid id, SCANdata.SCANtype sensors, double fov, doub knownVessels.Remove(id); return; } - foreach (SCANdata.SCANtype sensor in Enum.GetValues(typeof(SCANdata.SCANtype))) + foreach (SCANtype sensor in Enum.GetValues(typeof(SCANtype))) { if (SCANUtil.countBits((int)sensor) != 1) continue; - if ((sensor & sensors) == SCANdata.SCANtype.Nothing) continue; + if ((sensor & sensors) == SCANtype.Nothing) continue; double this_fov = fov, this_min_alt = min_alt, this_max_alt = max_alt, this_best_alt = best_alt; if (this_max_alt <= 0) { @@ -663,8 +675,8 @@ private void registerSensor(Guid id, SCANdata.SCANtype sensors, double fov, doub this_max_alt = 500000; this_best_alt = 200000; this_fov = 5; - if ((sensor & SCANdata.SCANtype.AltimetryHiRes) != SCANdata.SCANtype.Nothing) this_fov = 3; - if ((sensor & SCANdata.SCANtype.AnomalyDetail) != SCANdata.SCANtype.Nothing) + if ((sensor & SCANtype.AltimetryHiRes) != SCANtype.Nothing) this_fov = 3; + if ((sensor & SCANtype.AnomalyDetail) != SCANtype.Nothing) { this_min_alt = 0; this_max_alt = 2000; @@ -682,26 +694,26 @@ private void registerSensor(Guid id, SCANdata.SCANtype sensors, double fov, doub } } - internal void unregisterSensor(Vessel v, SCANdata.SCANtype sensors) + internal void unregisterSensor(Vessel v, SCANtype sensors) { if (!knownVessels.ContainsKey(v.id)) return; SCANvessel sv = knownVessels[v.id]; sv.id = v.id; sv.vessel = v; - foreach (SCANdata.SCANtype sensor in Enum.GetValues(typeof(SCANdata.SCANtype))) + foreach (SCANtype sensor in Enum.GetValues(typeof(SCANtype))) { - if ((sensors & sensor) == SCANdata.SCANtype.Nothing) continue; + if ((sensors & sensor) == SCANtype.Nothing) continue; if (!sv.sensors.ContainsKey(sensor)) continue; sv.sensors.Remove(sensor); } } - internal bool isVesselKnown(Guid id, SCANdata.SCANtype sensor) + internal bool isVesselKnown(Guid id, SCANtype sensor) { if (!knownVessels.ContainsKey(id)) return false; - SCANdata.SCANtype all = SCANdata.SCANtype.Nothing; - foreach (SCANdata.SCANtype s in knownVessels[id].sensors.Keys) all |= s; - return (all & sensor) != SCANdata.SCANtype.Nothing; + SCANtype all = SCANtype.Nothing; + foreach (SCANtype s in knownVessels[id].sensors.Keys) all |= s; + return (all & sensor) != SCANtype.Nothing; } private bool isVesselKnown(Guid id) @@ -716,18 +728,18 @@ private bool isVesselKnown(Vessel v) return isVesselKnown(v.id); } - internal SCANsensor getSensorStatus(Vessel v, SCANdata.SCANtype sensor) + internal SCANsensor getSensorStatus(Vessel v, SCANtype sensor) { if (!knownVessels.ContainsKey(v.id)) return null; if (!knownVessels[v.id].sensors.ContainsKey(sensor)) return null; return knownVessels[v.id].sensors[sensor]; } - internal SCANdata.SCANtype activeSensorsOnVessel(Guid id) + internal SCANtype activeSensorsOnVessel(Guid id) { - if (!knownVessels.ContainsKey(id)) return SCANdata.SCANtype.Nothing; - SCANdata.SCANtype sensors = SCANdata.SCANtype.Nothing; - foreach (SCANdata.SCANtype s in knownVessels[id].sensors.Keys) sensors |= s; + if (!knownVessels.ContainsKey(id)) return SCANtype.Nothing; + SCANtype sensors = SCANtype.Nothing; + foreach (SCANtype s in knownVessels[id].sensors.Keys) sensors |= s; return sensors; } diff --git a/SCANsat/SCANmap.cs b/SCANsat/SCANmap.cs deleted file mode 100644 index f42775e19..000000000 --- a/SCANsat/SCANmap.cs +++ /dev/null @@ -1,799 +0,0 @@ -#region license -/* - * [Scientific Committee on Advanced Navigation] - * S.C.A.N. Satellite - * - * SCANmap - makes maps from data - * - * Copyright (c)2013 damny; - * Copyright (c)2014 technogeeky ; - * Copyright (c)2014 (Your Name Here) ; see LICENSE.txt for licensing details. -*/ -#endregion -using System; -using UnityEngine; -using SCANsat.Platform.Palettes; -using palette = SCANsat.SCAN_UI.SCANpalette; - -namespace SCANsat -{ - public class SCANmap - { - internal SCANmap(CelestialBody Body) - { - body = Body; - } - - internal SCANmap() - { - - } - - /* MAP: legends */ - - public static Texture2D legend; - private static float legendMin, legendMax; - private static Palette dataPalette; - private static int legendScheme; - public static Texture2D getLegend(float min, float max, int scheme, SCANdata data) - { - if (legend != null && legendMin == min && legendMax == max && legendScheme == scheme && data.ColorPalette == dataPalette) - return legend; - legend = new Texture2D(256, 1, TextureFormat.RGB24, false); - legendMin = min; - legendMax = max; - legendScheme = scheme; - dataPalette = data.ColorPalette; - Color[] pix = legend.GetPixels(); - for (int x = 0; x < 256; ++x) - { - float val = (x * (max - min)) / 256f + min; - pix[x] = palette.heightToColor(val, scheme, data); - } - legend.SetPixels(pix); - legend.Apply(); - return legend; - } - - public static Texture2D getLegend(int scheme, SCANdata data) - { - Texture2D t = new Texture2D(256, 1, TextureFormat.RGB24, false); - Color[] pix = t.GetPixels(); - for (int x = 0; x < 256; ++x) - { - float val = (x * (data.MaxHeight - data.MinHeight)) / 256f + data.MinHeight; - pix[x] = palette.heightToColor(val, scheme, data); - } - t.SetPixels(pix); - t.Apply(); - return t; - } - - public static Texture2D getLegend(float max, float min, float? clamp, bool discrete, Color32[] c) - { - Texture2D t = new Texture2D(128, 1, TextureFormat.RGB24, false); - Color[] pix = t.GetPixels(); - for (int x = 0; x < 128; x++ ) - { - float val = (x * (max - min)) / 128f + min; - pix[x] = palette.heightToColor(val, max, min, clamp, discrete, c); - } - t.SetPixels(pix); - t.Apply(); - return t; - } - - /* MAP: projections */ - public enum MapProjection - { - Rectangular = 0, - KavrayskiyVII = 1, - Polar = 2, - } - public enum mapType - { - Altimetry = 0, - Slope = 1, - Biome = 2, - } - - private static string[] getProjectionNames() - { - MapProjection[] v = (MapProjection[])Enum.GetValues(typeof(MapProjection)); - string[] r = new string[v.Length]; - for (int i = 0; i < v.Length; ++i) - r[i] = v[i].ToString(); - return r; - } - - private static string[] getMapTypeNames() - { - mapType[] v = (mapType[])Enum.GetValues(typeof(mapType)); - string[] r = new string[v.Length]; - for (int i = 0; i < v.Length; i++) - r[i] = v[i].ToString(); - return r; - } - public static string[] projectionNames = getProjectionNames(); - public static string[] mapTypeNames = getMapTypeNames(); - public MapProjection projection = MapProjection.Rectangular; - - /* MAP: Big Map height map caching */ - protected float[, ,] big_heightmap; - protected CelestialBody big_heightmap_body; - internal mapType mType; - - - public void heightMapArray(float height, int line, int i, mapType type) - { - if (type == 0) - { - big_heightmap[i, line, SCANcontroller.controller.projection] = height; - } - } - - - public void setProjection(MapProjection p) - { - if (projection == p) - return; - projection = p; - resetMap(); - } - public double projectLongitude(double lon, double lat) - { - lon = (lon + 3600 + 180) % 360 - 180; - lat = (lat + 1800 + 90) % 180 - 90; - switch (projection) - { - case MapProjection.KavrayskiyVII: - lon = Mathf.Deg2Rad * lon; - lat = Mathf.Deg2Rad * lat; - lon = (3.0f * lon / 2.0f / Math.PI) * Math.Sqrt(Math.PI * Math.PI / 3.0f - lat * lat); - return Mathf.Rad2Deg * lon; - case MapProjection.Polar: - lon = Mathf.Deg2Rad * lon; - lat = Mathf.Deg2Rad * lat; - if (lat < 0) - { - lon = 1.3 * Math.Cos(lat) * Math.Sin(lon) - Math.PI / 2; - } - else - { - lon = 1.3 * Math.Cos(lat) * Math.Sin(lon) + Math.PI / 2; - } - return Mathf.Rad2Deg * lon; - default: - return lon; - } - } - public double projectLatitude(double lon, double lat) - { - lon = (lon + 3600 + 180) % 360 - 180; - lat = (lat + 1800 + 90) % 180 - 90; - switch (projection) - { - case MapProjection.Polar: - lon = Mathf.Deg2Rad * lon; - lat = Mathf.Deg2Rad * lat; - if (lat < 0) - { - lat = 1.3 * Math.Cos(lat) * Math.Cos(lon); - } - else - { - lat = -1.3 * Math.Cos(lat) * Math.Cos(lon); - } - return Mathf.Rad2Deg * lat; - default: - return lat; - } - } - public double unprojectLongitude(double lon, double lat) - { - if (lat > 90) - { - lat = 180 - lat; - lon += 180; - } - else if (lat < -90) - { - lat = -180 - lat; - lon += 180; - } - lon = (lon + 3600 + 180) % 360 - 180; - lat = (lat + 1800 + 90) % 180 - 90; - switch (projection) - { - case MapProjection.KavrayskiyVII: - lon = Mathf.Deg2Rad * lon; - lat = Mathf.Deg2Rad * lat; - lon = lon / Math.Sqrt(Mathf.PI * Math.PI / 3.0f - lat * lat) * 2.0f * Math.PI / 3.0f; - return Mathf.Rad2Deg * lon; - case MapProjection.Polar: - lon = Mathf.Deg2Rad * lon; - lat = Mathf.Deg2Rad * lat; - double lat0 = Math.PI / 2; - if (lon < 0) - { - lon += Math.PI / 2; - lat0 = -Math.PI / 2; - } - else - { - lon -= Math.PI / 2; - } - lon /= 1.3; - lat /= 1.3; - double p = Math.Sqrt(lon * lon + lat * lat); - double c = Math.Asin(p); - lon = Math.Atan2((lon * Math.Sin(c)), (p * Math.Cos(lat0) * Math.Cos(c) - lat * Math.Sin(lat0) * Math.Sin(c))); - lon = (Mathf.Rad2Deg * lon + 180) % 360 - 180; - if (lon <= -180) - lon = -180; - return lon; - default: - return lon; - } - } - public double unprojectLatitude(double lon, double lat) - { - if (lat > 90) - { - lat = 180 - lat; - lon += 180; - } - else if (lat < -90) - { - lat = -180 - lat; - lon += 180; - } - lon = (lon + 3600 + 180) % 360 - 180; - lat = (lat + 1800 + 90) % 180 - 90; - switch (projection) - { - case MapProjection.Polar: - lon = Mathf.Deg2Rad * lon; - lat = Mathf.Deg2Rad * lat; - double lat0 = Math.PI / 2; - if (lon < 0) - { - lon += Math.PI / 2; - lat0 = -Math.PI / 2; - } - else - { - lon -= Math.PI / 2; - } - lon /= 1.3; - lat /= 1.3; - double p = Math.Sqrt(lon * lon + lat * lat); - double c = Math.Asin(p); - lat = Math.Asin(Math.Cos(c) * Math.Sin(lat0) + (lat * Math.Sin(c) * Math.Cos(lat0)) / (p)); - return Mathf.Rad2Deg * lat; - default: - return lat; - } - } - - - /* MAP: scaling, centering (setting origin), translating, etc */ - public double mapscale, lon_offset, lat_offset; - public int mapwidth, mapheight; - public void setSize(int w, int h) - { - if (w == 0) - w = 360 * (Screen.width / 360); - if (w > 360 * 4) - w = 360 * 4; - mapwidth = w; - mapscale = mapwidth / 360f; - if (h <= 0) - h = (int)(180 * mapscale); - mapheight = h; - if (map != null) - { - if (mapwidth != map.width || mapheight != map.height) - map = null; - } - } - public void setWidth(int w) - { - if (w == 0) - { - w = 360 * (int)(Screen.width / 360); - if (w > 360 * 4) - w = 360 * 4; - } - if (w < 360) - w = 360; - if (mapwidth == w) - return; - mapwidth = w; - mapscale = mapwidth / 360f; - mapheight = (int)(w / 2); - /* big map caching */ - big_heightmap = new float[mapwidth, mapheight, 3]; - big_heightmap_body = body; - map = null; - resetMap(); - } - public void centerAround(double lon, double lat) - { - lon_offset = 180 + lon - (mapwidth / mapscale) / 2; - lat_offset = 90 + lat - (mapheight / mapscale) / 2; - } - public double scaleLatitude(double lat) - { - lat -= lat_offset; - lat *= 180f / (mapheight / mapscale); - return lat; - } - public double scaleLongitude(double lon) - { - lon -= lon_offset; - lon *= 360f / (mapwidth / mapscale); - return lon; - } - - /* MAP: shared state */ - public int mapmode = 0; // lots of EXTERNAL refs! - public Texture2D map; // refs above: 214,215,216,232, below, and JSISCANsatRPM. - - - /* MAP: internal state */ - protected int mapstep; // all refs are below - protected bool mapsaved; // all refs are below - protected double[] mapline; // all refs are below - internal CelestialBody body; // all refs are below - public SCANdata.SCANResource resource; - - /* MAP: nearly trivial functions */ - public void setBody(CelestialBody b) - { - if (body == b) - return; - body = b; - //SCANcontroller.controller.Resources(b); //Repopulate resource list when changing SOI - if (SCANcontroller.controller.GlobalResourceOverlay) - resource = SCANcontroller.controller.ResourceList[SCANcontroller.controller.resourceSelection][b.name]; - resetMap(); - } - public bool isMapComplete() - { - if (map == null) - return false; - return mapstep >= map.height; - } - public void resetMap() - { - mapstep = 0; - mapsaved = false; - if (SCANcontroller.controller.GlobalResourceOverlay) - { //Make sure that a resource is initialized if necessary - if (resource == null && body != null) resource = SCANcontroller.controller.ResourceList[SCANcontroller.controller.resourceSelection][body.name]; - if (SCANcontroller.controller.resourceOverlayType == 1) - SCANcontroller.controller.KethaneReset = !SCANcontroller.controller.KethaneReset; - } - } - public void resetMap(int mode, int maptype) - { - mapmode = mode; - mType = (mapType)maptype; - resetMap(); - } - //public void setResource(string s) - //{ //Used when a different resource is selected - // if (resource == null) resource = SCANcontroller.controller.ResourceList[SCANcontroller.controller.resourceSelection]; - // if (resource.Name == s) - // return; - // resource = SCANcontroller.controller.ResourceList[SCANcontroller.controller.resourceSelection]; - // resetMap(); - //} - - /* MAP: export: PNG file */ - public void exportPNG() - { - string mode; - - switch (mapmode) - { - case 0: mode = "elevation"; break; - case 1: mode = "slope"; break; - case 2: mode = "biome"; break; - default: mode = "unknown"; break; - } - - if (SCANcontroller.controller.colours == 1) - mode += "-grey"; - string filename = body.name + "_" + mode + "_" + map.width.ToString() + "x" + map.height.ToString(); - if (projection != MapProjection.Rectangular) - filename += "_" + projection.ToString(); - filename += ".png"; - KSP.IO.File.WriteAllBytes(map.EncodeToPNG(), filename, null); - mapsaved = true; - ScreenMessages.PostScreenMessage("Map saved: " + filename, 5, ScreenMessageStyle.UPPER_CENTER); - } - - /* MAP: build: map to Texture2D */ - public Texture2D getPartialMap() - { - SCANdata data = SCANUtil.getData(body); - if (data == null) - return new Texture2D(1, 1); - Color[] pix; - - /* init cache if necessary */ - if (body != big_heightmap_body) - { - switch (mType) - { - case 0: - { - for (int x = 0; x < mapwidth; x++) - { //Save memory by not unnecessarily making a new cache - for (int y = 0; y < mapwidth / 2; y++) - { - for (int z = 0; z < 3; z++) - { - big_heightmap[x, y, z] = 0f; - } - } - } - big_heightmap_body = body; - break; - } - default: break; - } - } - - if (map == null) - { - map = new Texture2D(mapwidth, mapheight, TextureFormat.ARGB32, false); - pix = map.GetPixels(); - for (int i = 0; i < pix.Length; ++i) - pix[i] = palette.clear; - map.SetPixels(pix); - } - else if (mapstep >= map.height) - { - return map; - } - if (palette.redline == null || palette.redline.Length != map.width) - { - palette.redline = new Color[map.width]; - for (int i = 0; i < palette.redline.Length; ++i) - palette.redline[i] = palette.red; - } - if (mapstep < map.height - 1) - { - map.SetPixels(0, mapstep + 1, map.width, 1, palette.redline); - } - if (mapstep <= 0) - { - mapstep = 0; - mapline = new double[map.width]; - } - pix = map.GetPixels(0, mapstep, map.width, 1); - for (int i = 0; i < map.width; i++) - { - Color baseColor = palette.grey; //default pixel color - int scheme = SCANcontroller.controller.colours; - double lat = (mapstep * 1.0f / mapscale) - 90f + lat_offset; - double lon = (i * 1.0f / mapscale) - 180f + lon_offset; - double la = lat, lo = lon; - lat = unprojectLatitude(lo, la); - lon = unprojectLongitude(lo, la); - pix[i] = baseColor; - if (double.IsNaN(lat) || double.IsNaN(lon) || lat < -90 || lat > 90 || lon < -180 || lon > 180) - { - pix[i] = palette.clear; - continue; - } - if (mapmode == 0) - { - if (body.pqsController == null) - { - baseColor = palette.lerp(palette.black, palette.white, UnityEngine.Random.value); - } - else if (SCANUtil.isCovered(lon, lat, data, SCANdata.SCANtype.Altimetry)) - { - float val = 0f; - if (mType == 0) - val = big_heightmap[i, mapstep, SCANcontroller.controller.projection]; - if (val == 0) - { - if (SCANUtil.isCovered(lon, lat, data, SCANdata.SCANtype.AltimetryHiRes)) - { - // high resolution gets a coloured pixel for the actual position - val = (float)SCANUtil.getElevation(body, lon, lat); - baseColor = palette.heightToColor(val, scheme, data); //use temporary color to store pixel value - if (val == 0f) val = -0.001f; - heightMapArray(val, mapstep, i, mType); - } - else - { - // basic altimetry gets forced greyscale with lower resolution - val = (float)SCANUtil.getElevation(body, ((int)(lon * 5)) / 5, ((int)(lat * 5)) / 5); - baseColor = palette.heightToColor(val, 1, data); - if (val == 0f) val = -0.001f; - heightMapArray(val, mapstep, i, mType); - } - } - else if (val != 0) - { - if (SCANUtil.isCovered(lon, lat, data, SCANdata.SCANtype.AltimetryHiRes)) - { - baseColor = palette.heightToColor(val, scheme, data); - } - else - { - baseColor = palette.heightToColor(val, 1, data); - } - } - mapline[i] = val; - } - if (SCANcontroller.controller.map_ResourceOverlay && SCANcontroller.controller.GlobalResourceOverlay) - { - if (SCANcontroller.controller.resourceOverlayType == 0 && SCANversions.RegolithFound) - { - if (SCANUtil.isCovered(lon, lat, data, resource.Type)) //check our new resource coverage map - { - double amount = SCANUtil.RegolithOverlay(lat, lon, resource.Name, body.flightGlobalsIndex); //grab the resource amount for the current pixel - double scalar = resource.minValue + ((resource.maxValue - resource.minValue) / 5); - amount *= 100; - if (amount > scalar) - { - if (amount > 100) amount = 100; - pix[i] = palette.lerp(baseColor, palette.lerp(resource.emptyColor, resource.fullColor, (float)(amount) / (resource.maxValue - resource.minValue)), 0.3f); //vary color by resource amount - } - else pix[i] = palette.lerp(baseColor, palette.grey, 0.4f); - } - else pix[i] = baseColor; - } - else if (SCANcontroller.controller.resourceOverlayType == 1) //Kethane overlay - { - if (SCANUtil.isCovered(lon, lat, data, resource.Type)) - { - int ilon = SCANUtil.icLON(lon); - int ilat = SCANUtil.icLAT(lat); - float amount = data.KethaneValueMap[ilon, ilat]; //Fetch Kethane resource values from cached array - if (amount <= 0) pix[i] = palette.lerp(baseColor, palette.grey, 0.4f); - else - { - pix[i] = palette.lerp(baseColor, palette.lerp(resource.emptyColor, resource.fullColor, amount / resource.maxValue), 0.8f); - } - } - else pix[i] = baseColor; - } - else pix[i] = baseColor; - } - else pix[i] = baseColor; - - /* draw height lines - works, but mostly useless... - int step = (int)(val / 1000); - int step_h = step, step_v = step; - if(i > 0) step_h = (int)(bigline[i - 1] / 1000); - if(bigstep > 0) step_v = (int)(bigline[i] / 1000); - if(step != step_h || step != step_v) { - pix[i] = palette.white; - } - */ - //mapline [i] = val; - } - else if (mapmode == 1) - { - if (body.pqsController == null) - { - baseColor = palette.lerp(palette.black, palette.white, UnityEngine.Random.value); - } - else if (SCANUtil.isCovered(lon, lat, data, SCANdata.SCANtype.Altimetry)) - { - float val = 0f; - if (mType == 0) - val = big_heightmap[i, mapstep, SCANcontroller.controller.projection]; - if (val == 0) - { - if (SCANUtil.isCovered(lon, lat, data, SCANdata.SCANtype.AltimetryHiRes)) - { - val = (float)SCANUtil.getElevation(body, lon, lat); - if (val == 0f) val = -0.001f; - heightMapArray(val, mapstep, i, mType); - } - else - { - val = (float)SCANUtil.getElevation(body, ((int)(lon * 5)) / 5, ((int)(lat * 5)) / 5); - if (val == 0f) val = -0.001f; - heightMapArray(val, mapstep, i, mType); - } - } - if (mapstep == 0) - { - baseColor = palette.grey; - } - else - { - // This doesn't actually calculate the slope per se, but it's faster - // than asking for yet more elevation data. Please don't use this - // code to operate nuclear power plants or rockets. - double v1 = mapline[i]; - if (i > 0) - v1 = Math.Max(v1, mapline[i - 1]); - if (i < mapline.Length - 1) - v1 = Math.Max(v1, mapline[i + 1]); - float v = Mathf.Clamp((float)Math.Abs(val - v1) / 1000f, 0, 2f); - if (SCANcontroller.controller.colours == 1) - { - baseColor = palette.lerp(palette.black, palette.white, v / 2f); - } - else - { - if (v < 1) - { - baseColor = palette.lerp(palette.xkcd_PukeGreen, palette.xkcd_Lemon, v); - } - else - { - baseColor = palette.lerp(palette.xkcd_Lemon, palette.xkcd_OrangeRed, v - 1); - } - } - } - mapline[i] = val; - } - if (SCANcontroller.controller.map_ResourceOverlay && SCANcontroller.controller.GlobalResourceOverlay) - { - if (SCANcontroller.controller.resourceOverlayType == 0 && SCANversions.RegolithFound) - { - if (SCANUtil.isCovered(lon, lat, data, resource.Type)) //check our new resource coverage map - { - double amount = SCANUtil.RegolithOverlay(lat, lon, resource.Name, body.flightGlobalsIndex); //grab the resource amount for the current pixel - double scalar = resource.minValue + ((resource.maxValue - resource.minValue) / 5); - amount *= 100; - if (amount > scalar) - { - if (amount > 100) amount = 100; //max cutoff value - pix[i] = palette.lerp(baseColor, palette.lerp(resource.emptyColor, resource.fullColor, (float)(amount) / (resource.maxValue - resource.minValue)), 0.3f); //vary color by resource amount - } - else pix[i] = palette.lerp(baseColor, palette.grey, 0.4f); - } - else pix[i] = baseColor; - } - else if (SCANcontroller.controller.resourceOverlayType == 1) - { - if (SCANUtil.isCovered(lon, lat, data, resource.Type)) - { - int ilon = SCANUtil.icLON(lon); - int ilat = SCANUtil.icLAT(lat); - float amount = data.KethaneValueMap[ilon, ilat]; - if (amount <= 0) pix[i] = palette.lerp(baseColor, palette.grey, 0.4f); - else - { - pix[i] = palette.lerp(baseColor, palette.lerp(resource.emptyColor, resource.fullColor, amount / resource.maxValue), 0.8f); - } - } - else pix[i] = baseColor; - } - else pix[i] = baseColor; - } - else pix[i] = baseColor; - } - else if (mapmode == 2) - { - if (body.BiomeMap == null) - { - baseColor = palette.lerp(palette.black, palette.white, UnityEngine.Random.value); - } - /* // this just basically stretches the actual biome map to fit... it looks horrible - float u = ((lon + 360 + 180 + 90)) % 360; - float v = ((lat + 180 + 90)) % 180; - if(u < 0 || v < 0 || u >= 360 || v >= 180) continue; - u /= 360f; v /= 180f; - pix[i] = body.BiomeMap.Map.GetPixelBilinear(u, v); - */ - else if (SCANUtil.isCovered(lon, lat, data, SCANdata.SCANtype.Biome)) - { - double bio = SCANUtil.getBiomeIndexFraction(body, lon, lat); - Color biome = palette.grey; - if (SCANcontroller.controller.colours == 1) - { - if ((i > 0 && mapline[i - 1] != bio) || (mapstep > 0 && mapline[i] != bio)) - { - biome = palette.white; - } - else - { - biome = palette.lerp(palette.black, palette.white, (float)bio); - } - } - else - { - Color elevation = palette.grey; - if (body.pqsController == null) - { - baseColor = palette.lerp(palette.black, palette.white, UnityEngine.Random.value); - } - else if (SCANUtil.isCovered(lon, lat, data, SCANdata.SCANtype.Altimetry)) - { - float val = 0f; - if (mType == 0) - val = big_heightmap[i, mapstep, SCANcontroller.controller.projection]; - if (val == 0) - { - if (SCANUtil.isCovered(lon, lat, data, SCANdata.SCANtype.AltimetryHiRes)) - { - val = (float)SCANUtil.getElevation(body, lon, lat); - if (val == 0f) val = -0.001f; - heightMapArray(val, mapstep, i, mType); - } - else - { - val = (float)SCANUtil.getElevation(body, ((int)(lon * 5)) / 5, ((int)(lat * 5)) / 5); - if (val == 0f) val = -0.001f; - heightMapArray(val, mapstep, i, mType); - } - } - elevation = palette.lerp(palette.black, palette.white, Mathf.Clamp(val + 1500f, 0, 9000) / 9000f); - } - Color bio1 = palette.xkcd_CamoGreen; - Color bio2 = palette.xkcd_Marigold; - if ((i > 0 && mapline[i - 1] != bio) || (mapstep > 0 && mapline[i] != bio)) - { - //biome = palette.lerp(palette.xkcd_Puce, elevation, 0.5f); - biome = palette.white; - } - else - { - biome = palette.lerp(palette.lerp(bio1, bio2, (float)bio), elevation, 0.5f); - } - } - - baseColor = biome; - mapline[i] = bio; - } - if (SCANcontroller.controller.map_ResourceOverlay && SCANcontroller.controller.GlobalResourceOverlay) - { - if (SCANcontroller.controller.resourceOverlayType == 0 && SCANversions.RegolithFound) - { - if (SCANUtil.isCovered(lon, lat, data, resource.Type)) //check our new resource coverage map - { - double amount = SCANUtil.RegolithOverlay(lat, lon, resource.Name, body.flightGlobalsIndex); //grab the resource amount for the current pixel - double scalar = resource.minValue + ((resource.maxValue - resource.minValue) / 5); - amount *= 100; - if (amount > scalar) - { - if (amount > 100) amount = 100; //max cutoff value - pix[i] = palette.lerp(baseColor, palette.lerp(resource.emptyColor, resource.fullColor, (float)(amount) / (resource.maxValue - resource.minValue)), 0.3f); //vary color by resource amount - } - else pix[i] = palette.lerp(baseColor, palette.grey, 0.4f); - } - else pix[i] = baseColor; - } - else if (SCANcontroller.controller.resourceOverlayType == 1) - { - if (SCANUtil.isCovered(lon, lat, data, resource.Type)) - { - int ilon = SCANUtil.icLON(lon); - int ilat = SCANUtil.icLAT(lat); - float amount = data.KethaneValueMap[ilon, ilat]; - if (amount <= 0) pix[i] = palette.lerp(baseColor, palette.grey, 0.4f); - else - { - pix[i] = palette.lerp(baseColor, palette.lerp(resource.emptyColor, resource.fullColor, amount / resource.maxValue), 0.8f); - } - } - else pix[i] = baseColor; - } - else pix[i] = baseColor; - } - else pix[i] = baseColor; - } - } - map.SetPixels(0, mapstep, map.width, 1, pix); - mapstep++; - if (mapstep % 10 == 0 || mapstep >= map.height) - map.Apply(); - return map; - } - - } -} diff --git a/SCANsat/SCANreflection.cs b/SCANsat/SCANreflection.cs index a6ef7380c..725080042 100644 --- a/SCANsat/SCANreflection.cs +++ b/SCANsat/SCANreflection.cs @@ -20,85 +20,24 @@ namespace SCANsat { static class SCANreflection { - private const string ORSXPlanetDataType = "ORSX.ORSX_PlanetaryResourceMapData"; - private const string ORSXPixelAbundanceMethod = "getPixelAbundanceValue"; - private const string ORSXAssemblyName = "ORSX"; private const string RegolithTypeName = "Regolith.Common.RegolithResourceMap"; private const string RegolithAssemblyName = "Regolith"; private const string RegolithMethodName = "GetAbundance"; - private static bool ORSXRun = false; - private static bool RegolithRun = false; - private delegate double ORSXpixelAbundance(int body, string resourceName, double lat, double lon); - private delegate float RegolithPosAbundance(double lat, double lon, string resource, int body, int type, double altitude); - private static ORSXpixelAbundance _ORSXpixelAbundance; - private static RegolithPosAbundance _RegolithPosAbundance; - internal static Type _ORSXPlanetType; - internal static Type _RegolithPlanetType; - internal static double ORSXpixelAbundanceValue(int body, string resourceName, double lat, double lon) - { - return _ORSXpixelAbundance(body, resourceName, lat, lon); - } - internal static float RegolithAbundanceValue(double lat, double lon, string resource, int body, int type, double altitude) { return _RegolithPosAbundance(lat, lon, resource, body, type, altitude); } - internal static bool ORSXReflectionMethod(Assembly ORSXAssembly) - { - if (_ORSXpixelAbundance != null) - return true; - - if (ORSXRun) - return false; - - ORSXRun = true; - - try - { - Type ORSXType = ORSXAssembly.GetExportedTypes() - .SingleOrDefault(t => t.FullName == ORSXPlanetDataType); - - if (ORSXType == null) - { - SCANUtil.SCANlog("ORSX Type Not Found"); - return false; - } - - _ORSXPlanetType = ORSXType; - - MethodInfo ORSXMethod = ORSXType.GetMethod(ORSXPixelAbundanceMethod, new Type[] { typeof(int), typeof(string), typeof(double), typeof(double) }); - - if (ORSXMethod == null) - { - SCANUtil.SCANlog("ORSX Method Not Found"); - return false; - } - - _ORSXpixelAbundance = (ORSXpixelAbundance)Delegate.CreateDelegate(typeof(ORSXpixelAbundance), ORSXMethod); - - SCANUtil.SCANlog("ORSX Reflection Method Assigned"); - - return true; - } - catch (Exception e) - { - Debug.LogWarning("[SCANsat] Exception While Loading ORSX Reflection Method: " + e); - } - - return false; - } - internal static bool RegolithReflectionMethod(Assembly RegolithAssembly) { if (_RegolithPosAbundance != null) diff --git a/SCANsat/SCANsat.cs b/SCANsat/SCANsat.cs index 57153d4c6..71ef77400 100644 --- a/SCANsat/SCANsat.cs +++ b/SCANsat/SCANsat.cs @@ -12,18 +12,21 @@ using System; using System.Collections.Generic; using System.Linq; +using SCANsat.SCAN_Data; +using SCANsat.SCAN_Toolbar; using SCANsat.SCAN_UI; + using UnityEngine; -using palette = SCANsat.SCAN_UI.SCANpalette; +using palette = SCANsat.SCAN_UI.UI_Framework.SCANpalette; namespace SCANsat { public class SCANsat : PartModule, IScienceDataContainer { - protected bool powerIsProblem; - protected Animation anim = null; - protected List storedData = new List(); - protected ExperimentsResultDialog expDialog = null; + private bool powerIsProblem; + private Animation anim = null; + private List storedData = new List(); + private ExperimentsResultDialog expDialog = null; /* SAT: KSP entry points */ public override void OnStart(StartState state) @@ -52,7 +55,7 @@ public override void OnStart(StartState state) } if (scanName != null) { // Use bitwise operators to check if the part has valid science collection scanners - if ((sensorType & (Int32)SCANdata.SCANtype.AltimetryLoRes) == 0 && (sensorType & (Int32)SCANdata.SCANtype.AltimetryHiRes) == 0 && (sensorType & (Int32)SCANdata.SCANtype.Biome) == 0) + if ((sensorType & (Int32)SCANtype.AltimetryLoRes) == 0 && (sensorType & (Int32)SCANtype.AltimetryHiRes) == 0 && (sensorType & (Int32)SCANtype.Biome) == 0) { Events["startScan"].guiName = "Start " + scanName; Events["stopScan"].guiName = "Stop " + scanName; @@ -116,7 +119,7 @@ public override void OnUpdate() } else { - if (sensorType == 0 || SCANcontroller.controller.isVesselKnown(vessel.id, (SCANdata.SCANtype)sensorType)) + if (sensorType == 0 || SCANcontroller.controller.isVesselKnown(vessel.id, (SCANtype)sensorType)) { if (TimeWarp.CurrentRate < 1500) { @@ -259,7 +262,10 @@ public override string GetInfo() public void startScan() { if (!ToolbarManager.ToolbarAvailable && SCANcontroller.controller != null) - SCANcontroller.controller.mainMap.Visible = true; + { + if (!SCANcontroller.controller.useStockAppLauncher) + SCANcontroller.controller.mainMap.Visible = true; + } #if DEBUG //SCANui.minimode = (SCANui.minimode > 0 ? 2 : -SCANui.minimode); #endif @@ -320,7 +326,7 @@ public void editorRetract() } /* SCAN: trivial function to do animation */ - public void animate(float speed, float time) + private void animate(float speed, float time) { if (anim != null && anim[animationName] != null) { @@ -375,7 +381,7 @@ public void analyzeData(KSPActionParam param) } /* SCAN: add static (a warning that we're low on electric charge) */ - public void addStatic() + private void addStatic() { SCANdata data = SCANUtil.getData(vessel.mainBody); if (data == null) @@ -391,18 +397,18 @@ public void addStatic() } /* SCAN: register scanners without going through animation */ - public void registerScanner() + private void registerScanner() { scanning = true; if (sensorType > 0 && SCANcontroller.controller != null) - SCANcontroller.controller.registerSensor(vessel, (SCANdata.SCANtype)sensorType, fov, min_alt, max_alt, best_alt); + SCANcontroller.controller.registerSensor(vessel, (SCANtype)sensorType, fov, min_alt, max_alt, best_alt); } - public void unregisterScanner() + private void unregisterScanner() { scanning = false; if (sensorType > 0 && SCANcontroller.controller != null) - SCANcontroller.controller.unregisterSensor(vessel, (SCANdata.SCANtype)sensorType); + SCANcontroller.controller.unregisterSensor(vessel, (SCANtype)sensorType); } private string scanAlt() @@ -421,28 +427,98 @@ private string scanAlt() /* SCAN: SCIENCE! make, store, transmit, keep * discard, review, count DATA */ - public void makeScienceData(bool notZero) + private void makeScienceData(bool notZero) { if (expDialog != null) DestroyImmediate(expDialog); storedData.Clear(); - ScienceData sd = SCANUtil.getAvailableScience(vessel, (SCANdata.SCANtype)sensorType, notZero); + ScienceData sd = getAvailableScience((SCANtype)sensorType, notZero); if (sd == null) return; storedData.Add(sd); } + private ScienceData getAvailableScience(SCANtype sensor, bool notZero) + { + SCANdata data = SCANUtil.getData(vessel.mainBody); + if (data == null) + return null; + ScienceData sd = null; + ScienceExperiment se = null; + ScienceSubject su = null; + bool found = false; + string id = null; + double coverage = 0f; + float multiplier = 1f; + + if (!found && (sensor & SCANtype.AltimetryLoRes) != SCANtype.Nothing) + { + found = true; + if (vessel.mainBody.pqsController == null) + multiplier = 0.5f; + id = "SCANsatAltimetryLoRes"; + coverage = SCANUtil.getCoveragePercentage(data, SCANtype.AltimetryLoRes); + } + else if (!found && (sensor & SCANtype.AltimetryHiRes) != SCANtype.Nothing) + { + found = true; + if (vessel.mainBody.pqsController == null) + multiplier = 0.5f; + id = "SCANsatAltimetryHiRes"; + coverage = SCANUtil.getCoveragePercentage(data, SCANtype.AltimetryHiRes); + } + else if (!found && (sensor & SCANtype.Biome) != SCANtype.Nothing) + { + found = true; + if (vessel.mainBody.BiomeMap == null) + multiplier = 0.5f; + id = "SCANsatBiomeAnomaly"; + coverage = SCANUtil.getCoveragePercentage(data, SCANtype.Biome); + } + if (!found) return null; + se = ResearchAndDevelopment.GetExperiment(id); + if (se == null) return null; + + su = ResearchAndDevelopment.GetExperimentSubject(se, ExperimentSituations.InSpaceHigh, vessel.mainBody, "surface"); + if (su == null) return null; + + su.scienceCap *= multiplier; + + SCANUtil.SCANlog("Coverage: {0}, Science cap: {1}, Subject value: {2}, Scientific value: {3}, Science: {4}", new object[5] { coverage.ToString("F1"), su.scienceCap.ToString("F1"), su.subjectValue.ToString("F2"), su.scientificValue.ToString("F2"), su.science.ToString("F2") }); + + su.scientificValue = 1; + + float science = (float)coverage; + if (science > 95) science = 100; + if (science < 30) science = 0; + science = science / 100f; + science = Mathf.Max(0, (science * su.scienceCap) - su.science); + + SCANUtil.SCANlog("Remaining science: {0}, Base value: {1}", new object[2] { science.ToString("F1"), se.baseValue.ToString("F1") }); + + science /= Mathf.Max(0.1f, su.scientificValue); //look 10 lines up; this is always 1... + science /= su.subjectValue; + + SCANUtil.SCANlog("Resulting science value: {0}", new object[1] { science.ToString("F2") }); + + if (notZero && science <= 0) science = 0.00001f; + + sd = new ScienceData(science * su.dataScale, 1f, 0f, su.id, se.experimentTitle + " of " + vessel.mainBody.theName); + su.title = sd.title; + return sd; + } + public ScienceData[] GetData() { return storedData.ToArray(); } - public void KeepData(ScienceData data) + private void KeepData(ScienceData data) { expDialog = null; } - public void TransmitData(ScienceData data) + private void TransmitData(ScienceData data) { expDialog = null; List tranList = vessel.FindPartModulesImplementing(); diff --git a/SCANsat/SCANsat.csproj b/SCANsat/SCANsat.csproj index f0470e9fd..160c39d60 100644 --- a/SCANsat/SCANsat.csproj +++ b/SCANsat/SCANsat.csproj @@ -45,121 +45,99 @@ true - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - Code - - - Code - - - - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - Code - - - - - - - - - diff --git a/SCANsat/SCANutil.cs b/SCANsat/SCANutil.cs index c80028499..c48d719c1 100644 --- a/SCANsat/SCANutil.cs +++ b/SCANsat/SCANutil.cs @@ -17,10 +17,9 @@ using System.Collections.Generic; using UnityEngine; using System.Linq; -using System.IO; -using System.Runtime.Serialization.Formatters.Binary; -using SCANsat.Platform; -using palette = SCANsat.SCAN_UI.SCANpalette; +using SCANsat.SCAN_Platform; +using SCANsat.SCAN_Data; +using palette = SCANsat.SCAN_UI.UI_Framework.SCANpalette; namespace SCANsat { @@ -87,7 +86,7 @@ public static double GetCoverage(int SCANtype, CelestialBody Body) { SCANdata data = getData(Body); if (data != null) - return data.getCoveragePercentage((SCANdata.SCANtype)SCANtype); + return getCoveragePercentage(data, (SCANtype)SCANtype); else return 0; } @@ -95,7 +94,25 @@ public static double GetCoverage(int SCANtype, CelestialBody Body) return 0; } - internal static bool isCovered(double lon, double lat, SCANdata data, SCANdata.SCANtype type) + /// + /// Given the name of the SCANtype, returns the int value. + /// + /// The name of the SCANtype. + /// The int value that can be used in other public methods. + public static int GetSCANtype(string SCANname) + { + try + { + return (int)Enum.Parse(typeof(SCANtype), SCANname); + } + catch (ArgumentException e) + { + throw new ArgumentException("An invalid SCANtype name was provided. Valid values are: " + + string.Join(", ", ((IEnumerable)Enum.GetValues(typeof(SCANtype))).Select(x => x.ToString()).ToArray())); + } + } + + internal static bool isCovered(double lon, double lat, SCANdata data, SCANtype type) { int ilon = icLON(lon); int ilat = icLAT(lat); @@ -103,33 +120,32 @@ internal static bool isCovered(double lon, double lat, SCANdata data, SCANdata.S return (data.Coverage[ilon, ilat] & (Int32)type) != 0; } - internal static bool isCovered(int lon, int lat, SCANdata data, SCANdata.SCANtype type) + internal static bool isCovered(int lon, int lat, SCANdata data, SCANtype type) { if (badLonLat(lon, lat)) return false; return (data.Coverage[lon, lat] & (Int32)type) != 0; } - internal static bool isCoveredByAll (int lon, int lat, SCANdata data, SCANdata.SCANtype type) + internal static bool isCoveredByAll (int lon, int lat, SCANdata data, SCANtype type) { if (badLonLat(lon,lat)) return false; return (data.Coverage[lon, lat] & (Int32)type) == (Int32)type; } - internal static void registerPass ( double lon, double lat, SCANdata data, SCANdata.SCANtype type ) { + internal static void registerPass ( double lon, double lat, SCANdata data, SCANtype type ) { int ilon = SCANUtil.icLON(lon); int ilat = SCANUtil.icLAT(lat); if (SCANUtil.badLonLat(ilon, ilat)) return; data.Coverage[ilon, ilat] |= (Int32)type; } - internal static double getCoveragePercentage(CelestialBody body, SCANdata.SCANtype type ) + internal static double getCoveragePercentage(SCANdata data, SCANtype type ) { - SCANdata data = getData(body); if (data == null) return 0; double cov = 0d; - if (type == SCANdata.SCANtype.Nothing) - type = SCANdata.SCANtype.AltimetryLoRes | SCANdata.SCANtype.AltimetryHiRes | SCANdata.SCANtype.Biome | SCANdata.SCANtype.Anomaly; + if (type == SCANtype.Nothing) + type = SCANtype.AltimetryLoRes | SCANtype.AltimetryHiRes | SCANtype.Biome | SCANtype.Anomaly; cov = data.getCoverage (type); if (cov <= 0) cov = 100; @@ -163,13 +179,28 @@ internal static double fixLon(double lon) return (lon + 360 + 180) % 360; } + /// + /// For a given Celestial Body this returns the SCANdata instance if it exists in the SCANcontroller master dictionary; return is null if the SCANdata does not exist for that body (ie it has never been visited while SCANsat has been active) + /// + /// Celestial Body object + /// SCANdata instance for the given Celestial Body; null if none exists public static SCANdata getData(CelestialBody body) { - if (!SCANcontroller.Body_Data.ContainsKey(body.name)) + return getData(body.name); + } + + /// + /// For a given Celestial Body name this returns the SCANdata instance if it exists in the SCANcontroller master dictionary; return is null if the SCANdata does not exist for that body (ie it has never been visited while SCANsat has been active) + /// + /// Name of celestial body (do not use TheName string) + /// SCANdata instance for the given Celestial Body; null if none exists + public static SCANdata getData(string BodyName) + { + if (!SCANcontroller.Body_Data.ContainsKey(BodyName)) { return null; } - SCANdata data = SCANcontroller.Body_Data[body.name]; + SCANdata data = SCANcontroller.Body_Data[BodyName]; return data; } @@ -202,83 +233,6 @@ internal static double getElevation(this CelestialBody body, Vector3d worldPosit return ret; } - internal static ScienceData getAvailableScience(Vessel v, SCANdata.SCANtype sensor, bool notZero) - { - SCANdata data = getData(v.mainBody); - if (data == null) - return null; - ScienceData sd = null; - ScienceExperiment se = null; - ScienceSubject su = null; - bool found = false; - string id = null; - double coverage = 0f; - float multiplier = 1f; - - if(!found && (sensor & SCANdata.SCANtype.AltimetryLoRes) != SCANdata.SCANtype.Nothing) { - found = true; - if (v.mainBody.pqsController == null) - multiplier = 0.5f; - id = "SCANsatAltimetryLoRes"; - coverage = data.getCoveragePercentage(SCANdata.SCANtype.AltimetryLoRes); - } - else if(!found && (sensor & SCANdata.SCANtype.AltimetryHiRes) != SCANdata.SCANtype.Nothing) { - found = true; - if (v.mainBody.pqsController == null) - multiplier = 0.5f; - id = "SCANsatAltimetryHiRes"; - coverage = data.getCoveragePercentage(SCANdata.SCANtype.AltimetryHiRes); - } - else if(!found && (sensor & SCANdata.SCANtype.Biome) != SCANdata.SCANtype.Nothing) { - found = true; - if (v.mainBody.BiomeMap == null) - multiplier = 0.5f; - id = "SCANsatBiomeAnomaly"; - coverage = data.getCoveragePercentage(SCANdata.SCANtype.Biome); - } - if(!found) return null; - se = ResearchAndDevelopment.GetExperiment(id); - if(se == null) return null; - - su = ResearchAndDevelopment.GetExperimentSubject(se, ExperimentSituations.InSpaceHigh, v.mainBody, "surface"); - if(su == null) return null; - - su.scienceCap *= multiplier; - - SCANlog("Coverage: {0}, Science cap: {1}, Subject value: {2}, Scientific value: {3}, Science: {4}", new object[5] {coverage.ToString("F1"), su.scienceCap.ToString("F1"), su.subjectValue.ToString("F2"), su.scientificValue.ToString("F2"), su.science.ToString("F2")}); - - su.scientificValue = 1; - - float science = (float)coverage; - if(science > 95) science = 100; - if(science < 30) science = 0; - science = science / 100f; - science = Mathf.Max(0, (science * su.scienceCap) - su.science); - - SCANlog("Remaining science: {0}, Base value: {1}", new object[2] {science.ToString("F1"), se.baseValue.ToString("F1")}); - - science /= Mathf.Max(0.1f, su.scientificValue); //look 10 lines up; this is always 1... - science /= su.subjectValue; - - SCANlog("Resulting science value: {0}", new object[1] {science.ToString("F2")}); - - if(notZero && science <= 0) science = 0.00001f; - - sd = new ScienceData(science * su.dataScale, 1f, 0f, su.id, se.experimentTitle + " of " + v.mainBody.theName); - su.title = sd.title; - return sd; - } - - internal static double ORSOverlay(double lon, double lat, int i, string s) - { - double amount = 0d; - amount = SCANreflection.ORSXpixelAbundanceValue(i, s, lat, lon); - //ORSPlanetaryResourcePixel overlayPixel = ORSPlanetaryResourceMapData.getResourceAvailability(i, s, lat, lon); - //if (overlayPixel != null) - // amount = overlayPixel.getAmount(); - return amount; - } - internal static float RegolithOverlay(double lat, double lon, string name, int body) { float amount = 0f; @@ -286,7 +240,7 @@ internal static float RegolithOverlay(double lat, double lon, string name, int b return amount; } - internal static SCANdata.SCANResource RegolithConfigLoad(ConfigNode node) + internal static SCANresource RegolithConfigLoad(ConfigNode node) { float min = .001f; float max = 10f; @@ -297,10 +251,10 @@ internal static SCANdata.SCANResource RegolithConfigLoad(ConfigNode node) name = node.GetValue("ResourceName"); else return null; - SCANdata.SCANresourceType type = OverlayResourceType(name); + SCANresourceType type = OverlayResourceType(name); if (type == null) return null; - if (type.type == SCANdata.SCANtype.Nothing) + if (type.Type == SCANtype.Nothing) return null; if (node.HasValue("PlanetName")) body = node.GetValue("PlanetName"); @@ -318,64 +272,16 @@ internal static SCANdata.SCANResource RegolithConfigLoad(ConfigNode node) } if (min == max) max += 0.001f; - SCANdata.SCANResource SCANres = new SCANdata.SCANResource(name, body, type.colorFull, type.colorEmpty, min, max, type, SCANdata.SCANResource_Source.Regolith); + SCANresource SCANres = new SCANresource(name, body, type.ColorFull, type.ColorEmpty, min, max, type, SCANresource_Source.Regolith); if (SCANres != null) return SCANres; return null; } - internal static SCANdata.SCANResource ORSConfigLoad(ConfigNode node) - { - double scalar = 1d; - double Threshold = 1d; - double mult = 1d; - string name = ""; - string body = ""; - bool scale = false; - if (node.HasValue("name")) - name = node.GetValue("name"); - else - return null; - SCANdata.SCANresourceType type = OverlayResourceType(name); - if (type == null) - return null; - if (type.type == SCANdata.SCANtype.Nothing) - return null; - if (node.HasValue("celestialBodyName")) - body = node.GetValue("celestialBodyName"); - else - return null; - if (node.HasValue("resourceScale")) - { - if (node.GetValue("resourceScale") == "LINEAR_SCALE") - scale = true; - else if (node.GetValue("resourceScale") == "LOG_SCALE") - scale = false; - } - if (node.HasValue("displayThreshold")) - double.TryParse(node.GetValue("displayThreshold"), out Threshold); - if (scale) - Threshold *= 10; - else - { - Threshold *= 10000; - if (node.HasValue("scaleFactor")) - double.TryParse(node.GetValue("scaleFactor"), out scalar); - } - if (node.HasValue("scaleMultiplier")) - double.TryParse(node.GetValue("scaleMultiplier"), out mult); - - //SCANdata.SCANResource SCANres = new SCANdata.SCANResource(name, body, type.colorFull, type.colorEmpty, scale, 1f, type, SCANdata.SCANResource_Source.ORSX); - //if (SCANres != null) - // return SCANres; - - return null; - } - internal static void loadSCANtypes() { - SCANcontroller.ResourceTypes = new Dictionary(); + SCANcontroller.ResourceTypes = new Dictionary(); foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("SCANSAT_SENSOR")) { string name = ""; @@ -392,20 +298,19 @@ internal static void loadSCANtypes() if (node.HasValue("ColorEmpty")) colorEmpty = node.GetValue("ColorEmpty"); if (!SCANcontroller.ResourceTypes.ContainsKey(name) && !string.IsNullOrEmpty(name)) - SCANcontroller.ResourceTypes.Add(name, new SCANdata.SCANresourceType(name, i, colorFull, colorEmpty)); + SCANcontroller.ResourceTypes.Add(name, new SCANresourceType(name, i, colorFull, colorEmpty)); } } - internal static SCANdata.SCANresourceType OverlayResourceType(string s) + internal static SCANresourceType OverlayResourceType(string s) { - var resourceType = SCANcontroller.ResourceTypes.FirstOrDefault(r => r.Value.name == s).Value; + var resourceType = SCANcontroller.ResourceTypes.FirstOrDefault(r => r.Value.Name == s).Value; return resourceType; } internal static int getBiomeIndex(CelestialBody body, double lon , double lat) { if (body.BiomeMap == null) return -1; - //if (body.BiomeMap.Map == null) return -1; double u = fixLon(lon); double v = fixLat(lat); @@ -429,9 +334,7 @@ internal static double getBiomeIndexFraction(CelestialBody body, double lon , do internal static CBAttributeMapSO.MapAttribute getBiome(CelestialBody body, double lon , double lat) { if (body.BiomeMap == null) return null; - //if (body.BiomeMap.Map == null) return body.BiomeMap.defaultAttribute; int i = getBiomeIndex(body, lon , lat); - //if (i < 0) return body.BiomeMap.defaultAttribute; return body.BiomeMap.Attributes [i]; } @@ -457,397 +360,144 @@ internal static void SCANlog(string log, params object[] stringObjects) Debug.Log(finalLog); } - //Take the Int32[] coverage and convert it to a single dimension byte array - private static byte[] ConvertToByte(Int32[,] iArray) + [System.Diagnostics.Conditional("DEBUG")] + internal static void SCANdebugLog(string log, params object[] stringObjects) { - byte[] bArray = new byte[360 * 180 * 4]; - int k = 0; - for (int i = 0; i < 360; i++) { - for (int j = 0; j < 180; j++) { - byte[] bytes = BitConverter.GetBytes(iArray[i, j]); - for (int m = 0; m < bytes.Length; m++) { - bArray[k++] = bytes[m]; - } - } - } - return bArray; - } - - //Convert byte array from persistent file to usable Int32[] - private static Int32[,] ConvertToInt(byte[] bArray) - { - Int32[,] iArray = new Int32[360, 180]; - int k = 0; - for (int i = 0; i < 360; i++) { - for (int j = 0; j < 180; j++) { - iArray[i, j] = BitConverter.ToInt32(bArray, k); - k += 4; - } - } - return iArray; - } - - //One time conversion of single byte[,] to Int32 to recover old scanning data - private static Int32[,] RecoverToInt(byte[,] bArray) - { - Int32[,] iArray = new Int32[360, 180]; - for (int i = 0; i < 360; i++) { - for (int j = 0; j < 180; j++) { - iArray[i, j] = (Int32)bArray[i, j]; - } - } - return iArray; - } - - /* DATA: serialization and compression */ - internal static string integerSerialize(SCANdata data) - { - byte[] bytes = ConvertToByte(data.Coverage); - MemoryStream mem = new MemoryStream(); - BinaryFormatter binf = new BinaryFormatter(); - binf.Serialize(mem, bytes); - string blob = Convert.ToBase64String(SCAN_CLZF2.Compress(mem.ToArray())); - return blob.Replace("/", "-").Replace("=", "_"); - } - - internal static void integerDeserialize(string blob, bool b, SCANdata data) - { - try { - blob = blob.Replace("-", "/").Replace("_", "="); - byte[] bytes = Convert.FromBase64String(blob); - bytes = SCAN_CLZF2.Decompress(bytes); - MemoryStream mem = new MemoryStream(bytes, false); - BinaryFormatter binf = new BinaryFormatter(); - if (b) { - byte[,] bRecover = new byte[360, 180]; - bRecover = (byte[,])binf.Deserialize(mem); - data.Coverage = RecoverToInt(bRecover); - } - else { - byte[] bArray = (byte[])binf.Deserialize(mem); - data.Coverage = ConvertToInt(bArray); - } - } - catch (Exception e) { - data.Coverage = new Int32[360, 180]; - data.HeightMap = new float[360, 180]; - throw e; - } - data.resetImages(); + SCANlog(log, stringObjects); } } - #region MechJeb Extensions - - // This extension is from MechJeb; Used with permission from r4m0n: https://github.com/MuMech/MechJeb2/blob/master/MechJeb2/OrbitExtensions.cs - - public static class OrbitExtensions - { - //Returns whether a has an ascending node with b. This can be false - //if a is hyperbolic and the would-be ascending node is within the opening - //angle of the hyperbola. - public static bool AscendingNodeExists(this Orbit a, Orbit b) - { - return Math.Abs(JUtil.ClampDegrees180(a.AscendingNodeTrueAnomaly(b))) <= a.MaximumTrueAnomaly(); - } - //Gives the true anomaly (in a's orbit) at which a crosses its ascending node - //with b's orbit. - //The returned value is always between 0 and 360. - public static double AscendingNodeTrueAnomaly(this Orbit a, Orbit b) - { - Vector3d vectorToAN = Vector3d.Cross (a.SwappedOrbitNormal (), b.SwappedOrbitNormal ()); - return a.TrueAnomalyFromVector(vectorToAN); - - } - //For hyperbolic orbits, the true anomaly only takes on values in the range - // -M < true anomaly < +M for some M. This function computes M. - public static double MaximumTrueAnomaly(this Orbit o) - { - if (o.eccentricity < 1) - return 180; - return 180 / Math.PI * Math.Acos(-1 / o.eccentricity); - } - //normalized vector perpendicular to the orbital plane - //convention: as you look down along the orbit normal, the satellite revolves counterclockwise - public static Vector3d SwappedOrbitNormal(this Orbit o) - { - return -(o.GetOrbitNormal().xzy).normalized; - } - - //Returns whether a has a descending node with b. This can be false - //if a is hyperbolic and the would-be descending node is within the opening - //angle of the hyperbola. - public static bool DescendingNodeExists(this Orbit a, Orbit b) - { - return Math.Abs(JUtil.ClampDegrees180(a.DescendingNodeTrueAnomaly(b))) <= a.MaximumTrueAnomaly(); - } - //Gives the true anomaly (in a's orbit) at which a crosses its descending node - //with b's orbit. - //The returned value is always between 0 and 360. - public static double DescendingNodeTrueAnomaly(this Orbit a, Orbit b) - { - return JUtil.ClampDegrees360(a.AscendingNodeTrueAnomaly(b) + 180); - } - //Returns the next time at which a will cross its ascending node with b. - //For elliptical orbits this is a time between UT and UT + a.period. - //For hyperbolic orbits this can be any time, including a time in the past if - //the ascending node is in the past. - //NOTE: this function will throw an ArgumentException if a is a hyperbolic orbit and the "ascending node" - //occurs at a true anomaly that a does not actually ever attain - public static double TimeOfAscendingNode(this Orbit a, Orbit b, double UT) - { - return a.TimeOfTrueAnomaly(a.AscendingNodeTrueAnomaly(b), UT); - } - //Returns the next time at which a will cross its descending node with b. - //For elliptical orbits this is a time between UT and UT + a.period. - //For hyperbolic orbits this can be any time, including a time in the past if - //the descending node is in the past. - //NOTE: this function will throw an ArgumentException if a is a hyperbolic orbit and the "descending node" - //occurs at a true anomaly that a does not actually ever attain - public static double TimeOfDescendingNode(this Orbit a, Orbit b, double UT) - { - return a.TimeOfTrueAnomaly(a.DescendingNodeTrueAnomaly(b), UT); - } - //NOTE: this function can throw an ArgumentException, if o is a hyperbolic orbit with an eccentricity - //large enough that it never attains the given true anomaly - public static double TimeOfTrueAnomaly(this Orbit o, double trueAnomaly, double UT) - { - return o.UTAtMeanAnomaly(o.GetMeanAnomalyAtEccentricAnomaly(o.GetEccentricAnomalyAtTrueAnomaly(trueAnomaly)), UT); - } - //The next time at which the orbiting object will reach the given mean anomaly. - //For elliptical orbits, this will be a time between UT and UT + o.period - //For hyperbolic orbits, this can be any time, including a time in the past, if - //the given mean anomaly occurred in the past - public static double UTAtMeanAnomaly(this Orbit o, double meanAnomaly, double UT) - { - double currentMeanAnomaly = o.MeanAnomalyAtUT(UT); - double meanDifference = meanAnomaly - currentMeanAnomaly; - if (o.eccentricity < 1) - meanDifference = JUtil.ClampRadiansTwoPi(meanDifference); - return UT + meanDifference / o.MeanMotion(); - } - //Converts an eccentric anomaly into a mean anomaly. - //For an elliptical orbit, the returned value is between 0 and 2pi - //For a hyperbolic orbit, the returned value is any number - public static double GetMeanAnomalyAtEccentricAnomaly(this Orbit o, double E) - { - double e = o.eccentricity; - if (e < 1) { //elliptical orbits - return JUtil.ClampRadiansTwoPi(E - (e * Math.Sin(E))); - } //hyperbolic orbits - return (e * Math.Sinh(E)) - E; - } - //Originally by Zool, revised by The_Duck - //Converts a true anomaly into an eccentric anomaly. - //For elliptical orbits this returns a value between 0 and 2pi - //For hyperbolic orbits the returned value can be any number. - //NOTE: For a hyperbolic orbit, if a true anomaly is requested that does not exist (a true anomaly - //past the true anomaly of the asymptote) then an ArgumentException is thrown - public static double GetEccentricAnomalyAtTrueAnomaly(this Orbit o, double trueAnomaly) - { - double e = o.eccentricity; - trueAnomaly = JUtil.ClampDegrees360(trueAnomaly); - trueAnomaly = trueAnomaly * (Math.PI / 180); - - if (e < 1) { //elliptical orbits - double cosE = (e + Math.Cos(trueAnomaly)) / (1 + e * Math.Cos(trueAnomaly)); - double sinE = Math.Sqrt(1 - (cosE * cosE)); - if (trueAnomaly > Math.PI) - sinE *= -1; - - return JUtil.ClampRadiansTwoPi(Math.Atan2(sinE, cosE)); - } else { //hyperbolic orbits - double coshE = (e + Math.Cos(trueAnomaly)) / (1 + e * Math.Cos(trueAnomaly)); - if (coshE < 1) - throw new ArgumentException("OrbitExtensions.GetEccentricAnomalyAtTrueAnomaly: True anomaly of " + trueAnomaly + " radians is not attained by orbit with eccentricity " + o.eccentricity); - - double E = JUtil.Acosh(coshE); - if (trueAnomaly > Math.PI) - E *= -1; - - return E; - } - } - //The mean anomaly of the orbit. - //For elliptical orbits, the value return is always between 0 and 2pi - //For hyperbolic orbits, the value can be any number. - public static double MeanAnomalyAtUT(this Orbit o, double UT) - { - double ret = o.meanAnomalyAtEpoch + o.MeanMotion() * (UT - o.epoch); - if (o.eccentricity < 1) - ret = JUtil.ClampRadiansTwoPi(ret); - return ret; - } - //mean motion is rate of increase of the mean anomaly - public static double MeanMotion(this Orbit o) - { - return Math.Sqrt(o.referenceBody.gravParameter / Math.Abs(Math.Pow(o.semiMajorAxis, 3))); - } - //Converts a direction, specified by a Vector3d, into a true anomaly. - //The vector is projected into the orbital plane and then the true anomaly is - //computed as the angle this vector makes with the vector pointing to the periapsis. - //The returned value is always between 0 and 360. - public static double TrueAnomalyFromVector(this Orbit o, Vector3d vec) - { - Vector3d projected = Vector3d.Exclude(o.SwappedOrbitNormal(), vec); - Vector3d vectorToPe = o.eccVec.xzy; - double angleFromPe = Math.Abs(Vector3d.Angle(vectorToPe, projected)); - - //If the vector points to the infalling part of the orbit then we need to do 360 minus the - //angle from Pe to get the true anomaly. Test this by taking the the cross product of the - //orbit normal and vector to the periapsis. This gives a vector that points to center of the - //outgoing side of the orbit. If vectorToAN is more than 90 degrees from this vector, it occurs - //during the infalling part of the orbit. - if (Math.Abs(Vector3d.Angle(projected, Vector3d.Cross(o.SwappedOrbitNormal(), vectorToPe))) < 90) { - return angleFromPe; - } - return 360 - angleFromPe; - } - //distance from the center of the planet - public static double Radius(this Orbit o, double UT) - { - return o.SwappedRelativePositionAtUT(UT).magnitude; - } - //position relative to the primary - public static Vector3d SwappedRelativePositionAtUT(this Orbit o, double UT) - { - return o.getRelativePositionAtUT(UT).xzy; - } - } - - #endregion - #region fix Duplicated Code // Mihara: Notice that quite a bit of it, at least conceptually, duplicates code that SCANsat already contains elsewhere, // and in general needs trimming. - public static class MapIcons - { - public enum OtherIcon - { - None, - PE, - AP, - AN, - DN, - NODE, - SHIPATINTERCEPT, - TGTATINTERCEPT, - ENTERSOI, - EXITSOI, - PLANET, - } - - public static Rect VesselTypeIcon(VesselType type, OtherIcon icon) - { - int x = 0; - int y = 0; - const float symbolSpan = 0.2f; - if (icon != OtherIcon.None) { - switch (icon) { - case OtherIcon.AP: - x = 1; - y = 4; - break; - case OtherIcon.PE: - x = 0; - y = 4; - break; - case OtherIcon.AN: - x = 2; - y = 4; - break; - case OtherIcon.DN: - x = 3; - y = 4; - break; - case OtherIcon.NODE: - x = 2; - y = 1; - break; - case OtherIcon.SHIPATINTERCEPT: - x = 0; - y = 1; - break; - case OtherIcon.TGTATINTERCEPT: - x = 1; - y = 1; - break; - case OtherIcon.ENTERSOI: - x = 0; - y = 2; - break; - case OtherIcon.EXITSOI: - x = 1; - y = 2; - break; - case OtherIcon.PLANET: - // Not sure if it is (2,3) or (3,2) - both are round - x = 2; - y = 3; - break; - } - } else { - switch (type) { - case VesselType.Base: - x = 2; - y = 0; - break; - case VesselType.Debris: - x = 1; - y = 3; - break; - case VesselType.EVA: - x = 2; - y = 2; - break; - case VesselType.Flag: - x = 4; - y = 0; - break; - case VesselType.Lander: - x = 3; - y = 0; - break; - case VesselType.Probe: - x = 1; - y = 0; - break; - case VesselType.Rover: - x = 0; - y = 0; - break; - case VesselType.Ship: - x = 0; - y = 3; - break; - case VesselType.Station: - x = 3; - y = 1; - break; - case VesselType.Unknown: - x = 3; - y = 3; - break; - case VesselType.SpaceObject: - x = 4; - y = 1; - break; - default: - x = 3; - y = 2; - break; - } - } - var result = new Rect(); - result.x = symbolSpan * x; - result.y = symbolSpan * y; - result.height = result.width = symbolSpan; - return result; - } - } + //public static class MapIcons + //{ + // public enum OtherIcon + // { + // None, + // PE, + // AP, + // AN, + // DN, + // NODE, + // SHIPATINTERCEPT, + // TGTATINTERCEPT, + // ENTERSOI, + // EXITSOI, + // PLANET, + // } + + // public static Rect VesselTypeIcon(VesselType type, OtherIcon icon) + // { + // int x = 0; + // int y = 0; + // const float symbolSpan = 0.2f; + // if (icon != OtherIcon.None) { + // switch (icon) { + // case OtherIcon.AP: + // x = 1; + // y = 4; + // break; + // case OtherIcon.PE: + // x = 0; + // y = 4; + // break; + // case OtherIcon.AN: + // x = 2; + // y = 4; + // break; + // case OtherIcon.DN: + // x = 3; + // y = 4; + // break; + // case OtherIcon.NODE: + // x = 2; + // y = 1; + // break; + // case OtherIcon.SHIPATINTERCEPT: + // x = 0; + // y = 1; + // break; + // case OtherIcon.TGTATINTERCEPT: + // x = 1; + // y = 1; + // break; + // case OtherIcon.ENTERSOI: + // x = 0; + // y = 2; + // break; + // case OtherIcon.EXITSOI: + // x = 1; + // y = 2; + // break; + // case OtherIcon.PLANET: + // // Not sure if it is (2,3) or (3,2) - both are round + // x = 2; + // y = 3; + // break; + // } + // } else { + // switch (type) { + // case VesselType.Base: + // x = 2; + // y = 0; + // break; + // case VesselType.Debris: + // x = 1; + // y = 3; + // break; + // case VesselType.EVA: + // x = 2; + // y = 2; + // break; + // case VesselType.Flag: + // x = 4; + // y = 0; + // break; + // case VesselType.Lander: + // x = 3; + // y = 0; + // break; + // case VesselType.Probe: + // x = 1; + // y = 0; + // break; + // case VesselType.Rover: + // x = 0; + // y = 0; + // break; + // case VesselType.Ship: + // x = 0; + // y = 3; + // break; + // case VesselType.Station: + // x = 3; + // y = 1; + // break; + // case VesselType.Unknown: + // x = 3; + // y = 3; + // break; + // case VesselType.SpaceObject: + // x = 4; + // y = 1; + // break; + // default: + // x = 3; + // y = 2; + // break; + // } + // } + // var result = new Rect(); + // result.x = symbolSpan * x; + // result.y = symbolSpan * y; + // result.height = result.width = symbolSpan; + // return result; + // } + //} #endregion diff --git a/SCANsat/SCANversions.cs b/SCANsat/SCANversions.cs index 1ce2c921c..a526ac29c 100644 --- a/SCANsat/SCANversions.cs +++ b/SCANsat/SCANversions.cs @@ -23,11 +23,10 @@ namespace SCANsat public class SCANversions : MonoBehaviour { private const string kVersion = "0.9.2"; - private string[] Assemblies = new string[9] { "SCANsatRPM", "SCANsatKethane", "Kethane", "GeodesicGrid", "RasterPropMonitor", "MechJebRPM", "MechJeb2", "ORSX", "Regolith" }; + private string[] Assemblies = new string[11] { "SCANsatRPM", "SCANsatKethane", "Kethane", "GeodesicGrid", "RasterPropMonitor", "MechJebRPM", "MechJeb2", "ORSX", "Regolith", "ContractConfigurator", "CC_SCANsat" }; internal static string SCANsatVersion = ""; public static bool kethaneLoaded = false; - internal static bool ORSXFound = false; internal static bool RegolithFound = false; private List assemblyList = new List(); @@ -56,11 +55,6 @@ private void findAssemblies(string[] assemblies) if (kAssembly.infoVersion == kVersion) kethaneLoaded = true; } - //var ORSXAssembly = assemblyList.FirstOrDefault(a => a.name == "ORSX"); - //if (ORSXAssembly != null) - //{ - // ORSXFound = SCANreflection.ORSXReflectionMethod(ORSXAssembly.assemblyLoaded); - //} var RegolithAssembly = assemblyList.FirstOrDefault(a => a.name == "Regolith"); if (RegolithAssembly != null) {