Compress() public method

Compress texture into DXT format.

public Compress ( bool highQuality ) : void
highQuality bool
return void
        private static void ModifyTexture(this Material material, string propertyName, Texture2D newTexture)
        {
            var currentTexture = material.GetTexture(propertyName) as Texture2D;

            if (currentTexture == null)
            {
                return;
            }

            var needCompression = currentTexture.format == TextureFormat.DXT1 ||
                                  currentTexture.format == TextureFormat.DXT5;

            if (!needCompression)
            {
                needCompression = newTexture.format != TextureFormat.DXT1 &&
                                  newTexture.format != TextureFormat.DXT5;
            }

            if (needCompression)
            {
                newTexture.Compress(false);
            }

            material.SetTexture(propertyName, newTexture);
        }
示例#2
0
 private void LoadJPGTextures(ZipFile pk3)
 {
     foreach (Texture tex in Textures)
     {
         // The size of the new Texture2D object doesn't matter. It will be replaced (including its size) with the data from the .jpg texture that's getting pulled from the pk3 file.
         if (pk3.ContainsEntry(tex.Name + ".jpg"))
         {
             Texture2D readyTex = new Texture2D(4, 4);
             var entry = pk3 [tex.Name + ".jpg"];
             using (var stream = entry.OpenReader())
             {
                 var ms = new MemoryStream();
                 entry.Extract(ms);
                 readyTex.LoadImage(ms.GetBuffer());
             }
             
             readyTex.name = tex.Name;
             readyTex.filterMode = FilterMode.Trilinear;
             readyTex.Compress(true);
             
             if (readyTextures.ContainsKey(tex.Name))
             {
                 Debug.Log("Updating texture with name " + tex.Name);
                 readyTextures [tex.Name] = readyTex;
             } else
                 readyTextures.Add(tex.Name, readyTex);
         }
     }
 }
示例#3
0
			public TextureAppender (Texture2D[] textures)
			{
				uv = new Rect[textures.Length];

				int sizeX = textures [0].width;
				int sizeY = 0;
				foreach (Texture2D texture in textures)
				{
					sizeY += texture.height;
				}

				Texture2D output = new Texture2D(sizeX, sizeY);
				int currHeight = 0;
				for (int i=0; i<textures.Length; i++)
				{
					for (int y=0; y<textures[i].height; y++)
					{
						for (int x=0; x<textures[i].width; x++)
						{
							output.SetPixel(x, currHeight + y, textures[i].GetPixel(x,y));
						}
					}
					uv[i] = new Rect(0, currHeight/(float)sizeY, textures[i].width/(float)sizeX, textures[i].height/(float)sizeY);
					currHeight += textures[i].height;
				}
				output.Apply();
				output.Compress (true);
				textureAtlas = output;
			}
 static public int Compress(IntPtr l)
 {
     try {
                     #if DEBUG
         var    method     = System.Reflection.MethodBase.GetCurrentMethod();
         string methodName = GetMethodName(method);
                     #if UNITY_5_5_OR_NEWER
         UnityEngine.Profiling.Profiler.BeginSample(methodName);
                     #else
         Profiler.BeginSample(methodName);
                     #endif
                     #endif
         UnityEngine.Texture2D self = (UnityEngine.Texture2D)checkSelf(l);
         System.Boolean        a1;
         checkType(l, 2, out a1);
         self.Compress(a1);
         pushValue(l, true);
         return(1);
     }
     catch (Exception e) {
         return(error(l, e));
     }
             #if DEBUG
     finally {
                     #if UNITY_5_5_OR_NEWER
         UnityEngine.Profiling.Profiler.EndSample();
                     #else
         Profiler.EndSample();
                     #endif
     }
             #endif
 }
        // This function generates the biomes for the planet. (Coupled with an
        // appropriate Texture2D.)
        public static CBAttributeMapSO GenerateCBAttributeMapSO(string name)
        {
            Debug.Log("[Kopernicus] GenerateCBAttributeMapSO begins  r4");
            CBAttributeMapSO rv = ScriptableObject.CreateInstance<CBAttributeMapSO>();
            Texture2D map = new Texture2D(4, 4, TextureFormat.RGB24, false);
            Debug.Log("[Kopernicus] map=" + map);
            map.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/Biomes.png"));
            //map.Compress(true); // This might make the edges funny.
            map.Compress(false);
            // If it will let us take in an indexed color PNG that would be preferable - bcs
            map.Apply(true, false);
            rv.CreateMap(MapSO.MapDepth.RGB, map);
            //rv.nonExactThreshold = -1f; // This will theoretically return the "best match". It also depends on float comparison, but at least it's to a constant.
            rv.nonExactThreshold = 0.05f; // 0.6 0.0 0.4 matches 1 0 0 at .33 so .1 is fairly generous and should be reduced for maps with many colors
            // "exact" match is a broken concept (floats should never be compared to floats with == or !=) and (as implemented as of KSP .24.2) should
            // never be used.
            rv.exactSearch = false;
            rv.Attributes = new CBAttributeMapSO.MapAttribute[3];

            rv.Attributes[0] = new CBAttributeMapSO.MapAttribute();
            rv.Attributes[0].name = "PolarCaps";
            rv.Attributes[0].value = 1.5f;
            rv.Attributes[0].mapColor = new Color(0f, 1f, 0f);

            rv.Attributes[1] = new CBAttributeMapSO.MapAttribute();
            rv.Attributes[1].name = "Mares";
            rv.Attributes[1].value = 1.0f;
            rv.Attributes[1].mapColor = new Color(0f, 0f, 1f);

            rv.Attributes[2] = new CBAttributeMapSO.MapAttribute();
            rv.Attributes[2].name = "Dunes";
            rv.Attributes[2].value = 1.0f;
            rv.Attributes[2].mapColor = new Color(1f, 0f, 0f);

            //rv.defaultAttribute = rv.Attributes [0];
            /*
            // Troubleshooting fosssil
            Vector4 pixelBilinear;
            Vector4 color;
            for (float lat = -3f; lat < 3f; lat += .1f)
                for (float lon = 0f; lon < 6f; lon += .1f) {
                    float innerlon = lon - 1.5707963267948966f;

                    float v = (float)(lat / 3.1415926535897931) + 0.5f;
                    float u = (float)(innerlon / 6.2831853071795862f);
                    pixelBilinear = rv.Map.GetPixelBilinear (u, v);
                    color = rv.Attributes [2].mapColor;

                    Debug.Log ("X<A "+ lat + " "+lon+" clr="+ color + " pbl=" + pixelBilinear+" rv=" + rv.GetAtt (lat, lon).name + ":" +
                           (color-pixelBilinear).sqrMagnitude);
                }
            */
            Debug.Log("[Kopernicus] GenerateCBAttributeMapSO ends");

            return rv;
        }
示例#6
0
		public static Texture2D generateBlankNormal () {
			Texture2D texture = new Texture2D ( 16, 16, TextureFormat.ARGB32, false );
			Color32[] cols = texture.GetPixels32 ( 0 );
			int colsLength = cols.Length;
			for( int i=0 ; i < colsLength; i++ ) {
				cols[i] = new Color ( 0f, 0.5f, 0f, 0.5f );
			}
			texture.SetPixels32 ( cols, 0 );
			texture.Apply();
			texture.Compress ( false );
			return texture;
		}
 static public int Compress(IntPtr l)
 {
     try {
         UnityEngine.Texture2D self = (UnityEngine.Texture2D)checkSelf(l);
         System.Boolean        a1;
         checkType(l, 2, out a1);
         self.Compress(a1);
         return(0);
     }
     catch (Exception e) {
         return(error(l, e));
     }
 }
示例#8
0
 static int QPYX_Compress_YXQP(IntPtr L_YXQP)
 {
     try
     {
         ToLua.CheckArgsCount(L_YXQP, 2);
         UnityEngine.Texture2D QPYX_obj_YXQP = (UnityEngine.Texture2D)ToLua.CheckObject(L_YXQP, 1, typeof(UnityEngine.Texture2D));
         bool QPYX_arg0_YXQP = LuaDLL.luaL_checkboolean(L_YXQP, 2);
         QPYX_obj_YXQP.Compress(QPYX_arg0_YXQP);
         return(0);
     }
     catch (Exception e_YXQP)                {
         return(LuaDLL.toluaL_exception(L_YXQP, e_YXQP));
     }
 }
 public static int Compress_wrap(long L)
 {
     try
     {
         long nThisPtr             = FCLibHelper.fc_get_inport_obj_ptr(L);
         UnityEngine.Texture2D obj = get_obj(nThisPtr);
         bool arg0 = FCLibHelper.fc_get_bool(L, 0);
         obj.Compress(arg0);
     }
     catch (Exception e)
     {
         Debug.LogException(e);
     }
     return(0);
 }
示例#10
0
 static int Compress(IntPtr L)
 {
     try
     {
         ToLua.CheckArgsCount(L, 2);
         UnityEngine.Texture2D obj = (UnityEngine.Texture2D)ToLua.CheckObject(L, 1, typeof(UnityEngine.Texture2D));
         bool arg0 = LuaDLL.luaL_checkboolean(L, 2);
         obj.Compress(arg0);
         return(0);
     }
     catch (Exception e)
     {
         return(LuaDLL.toluaL_exception(L, e));
     }
 }
示例#11
0
文件: App.cs 项目: webconfig/project
    IEnumerator OnScreenCapture()
    {
        yield return new WaitForEndOfFrame();
        string path="";
        try
        {
            int width = Screen.width;
            int height = Screen.height;
            Texture2D tex = new Texture2D(width, height, TextureFormat.RGB24, false);
            tex.ReadPixels(new Rect(0, 0, width, height), 0, 0, true);
            byte[] imagebytes = tex.EncodeToPNG();
            tex.Compress(false);
            tex.Apply();
            if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.IPhonePlayer)
            {
                 string origin  = Application.persistentDataPath + System.DateTime.Now.Ticks + ".png";

                string destination = "/mnt/sdcard/moliputao";

                if (!Directory.Exists(destination))
                {
                    Directory.CreateDirectory(destination);
                }

                destination = destination + "/" + System.DateTime.Now.Ticks + ".png";

                if (System.IO.File.Exists(origin))
                {
                    System.IO.File.Move(origin, destination);
                }
                path = destination;

            }
            else if (Application.platform == RuntimePlatform.WindowsEditor)
            {
                path = Application.dataPath;
                path = path.Replace("/Assets", "/" + System.DateTime.Now.Ticks + ".png");
            }
            File.WriteAllBytes(path, imagebytes);
        }
        catch (System.Exception e)
        {
            Debug.Log("ScreenCaptrueError:" + e);
        }
    }
示例#12
0
    static int Compress(IntPtr L)
    {
#if UNITY_EDITOR
        ToluaProfiler.AddCallRecord("UnityEngine.Texture2D.Compress");
#endif
        try
        {
            ToLua.CheckArgsCount(L, 2);
            UnityEngine.Texture2D obj = (UnityEngine.Texture2D)ToLua.CheckObject(L, 1, typeof(UnityEngine.Texture2D));
            bool arg0 = LuaDLL.luaL_checkboolean(L, 2);
            obj.Compress(arg0);
            return(0);
        }
        catch (Exception e)
        {
            return(LuaDLL.toluaL_exception(L, e));
        }
    }
        public static Texture2D AsTexture(this byte[] textureBytes, string textureName, TextureType type)
        {
            switch (type)
            {
                case TextureType.Default:
                    {
                        var texture = new Texture2D(1, 1, TextureFormat.ARGB32, true);
                        texture.name = textureName;
                        texture.LoadImage(textureBytes);
                        texture.anisoLevel = 8;
                        texture.filterMode = FilterMode.Bilinear;
                        texture.Compress(true);
                        texture.Apply(true, true);
                        return texture;
                    }

                case TextureType.LOD:
                    {
                        var texture = new Texture2D(1, 1, TextureFormat.ARGB32, false);
                        texture.name = textureName;
                        texture.LoadImage(textureBytes);
                        texture.anisoLevel = 8;
                        texture.filterMode = FilterMode.Bilinear;
                        texture.Compress(true);
                        texture.Apply();
                        return texture;
                    }

                case TextureType.UI:
                    {
                        var texture = new Texture2D(1, 1, TextureFormat.ARGB32, false);
                        texture.name = textureName;
                        texture.LoadImage(textureBytes);
                        texture.Apply();
                        return texture;
                    }

                default:
                    throw new ArgumentOutOfRangeException("type");
            }
        }
示例#14
0
 public static Texture2D CombineHeights(Texture2D source_tex0, Texture2D source_tex1, Texture2D source_tex2, Texture2D source_tex3)
 {
     Texture2D rendered_tex=new Texture2D(source_tex0.width, source_tex0.height, TextureFormat.ARGB32, true, true);
     byte[] colsR=rtp_functions.get_alpha_channel(source_tex0);
     byte[] colsG=rtp_functions.get_alpha_channel(source_tex1);
     byte[] colsB=rtp_functions.get_alpha_channel(source_tex2);
     byte[] colsA=rtp_functions.get_alpha_channel(source_tex3);
     Color32[] cols=rendered_tex.GetPixels32();
     for(int i=0; i<cols.Length; i++) {
         cols[i].r=colsR[i];
         cols[i].g=colsG[i];
         cols[i].b=colsB[i];
         cols[i].a=colsA[i];
     }
     rendered_tex.SetPixels32(cols);
     rendered_tex.Apply(true, false);
     rendered_tex.Compress(true);
     //rendered_tex.Apply(true, true); // (non readable robione przy publishingu)
     rendered_tex.filterMode=FilterMode.Trilinear;
     return rendered_tex;
 }
示例#15
0
 public static Texture2D CombineHeights(Texture2D source_tex0, Texture2D source_tex1, Texture2D source_tex2, Texture2D source_tex3)
 {
     Texture2D texture2D = new Texture2D(source_tex0.width, source_tex0.height, TextureFormat.ARGB32, true, true);
     byte[] array = rtp_functions.get_alpha_channel(source_tex0);
     byte[] array2 = rtp_functions.get_alpha_channel(source_tex1);
     byte[] array3 = rtp_functions.get_alpha_channel(source_tex2);
     byte[] array4 = rtp_functions.get_alpha_channel(source_tex3);
     Color32[] pixels = texture2D.GetPixels32();
     for (int i = 0; i < pixels.Length; i++)
     {
         pixels[i].r = array[i];
         pixels[i].g = array2[i];
         pixels[i].b = array3[i];
         pixels[i].a = array4[i];
     }
     texture2D.SetPixels32(pixels);
     texture2D.Apply(true, false);
     texture2D.Compress(true);
     texture2D.filterMode = FilterMode.Trilinear;
     return texture2D;
 }
    public void Generate()
    {
        ShaderEmulate emulate = null;
        switch(Effect)
        {
        case EffectType.Deffault:
            emulate = GenerateDiffuse;
            break;
        case EffectType.Grayscale:
            emulate = GenerateGrayscale;
            break;
        }

        if(emulate == null)
        {
            throw new System.Exception("Shader emulate function not found");
        }

        Texture2D _tex = new Texture2D((int)Size.x, (int)Size.y, TextureFormat.RGB24, false);
        for (int x = 0; x < Size.x; x++)
        {
            for (int y = 0; y < Size.y; y++)
            {
                Color _color = emulate(x, y);
                switch(Line)
                {
                case LineType.Horizontal:
                    _color += GetLine(0, y);
                    break;
                }
                _tex.SetPixel(x, y, _color);
            }
        }
        _tex.Compress(false);
        _tex.Apply();
        GetComponent<Renderer>().material.mainTexture = _tex;
        if(IsGenNormalMap)
            NormalMap(_tex);
        System.GC.Collect();
    }
示例#17
0
        // TODO unload textures at some point?
        // Game breaks when you destroy textures when going back to main menu
        public Texture2D GetTexture(string texturePath)
        {
            Texture2D texture = null;

            if (!textures.TryGetValue(texturePath, out texture))
            {
                if (File.Exists(texturePath))
                {
                    texture = new Texture2D(1, 1);
                    texture.LoadImage(File.ReadAllBytes(texturePath));
                    texture.Compress(true);
                    texture.anisoLevel = 8;
                    texture.name = MOD_TEXTURE_PREFIX + counter++;

                    // TODO save RAM, send texture to graphics card

                    textures[texturePath] = texture;
                }
            }

            return texture;
        }
示例#18
0
    IEnumerator loadImage(string newUrl,Vector2 wallSize)
    {
        newUrl=newUrl.Replace("\"", "");

        WWW www = new WWW(newUrl);
        yield return www;
        //www.texture.Resize(512,512);
        Texture2D tex = new Texture2D(256,256);
        www.LoadImageIntoTexture(tex);
        imageSize = new Vector2(www.texture.width,www.texture.height);

        float ratio = imageSize.x/imageSize.y;
        float paintingMaxRatio = .33f;

        tex.Compress(false);

        render.material.mainTexture = tex;

        //print (imageSize);

        float newY = wallSize.y * 2/3.0f;
        float newX = newY*ratio;
        //print (ratio);
        //print (newX);
        //print(newY);
        if(newX > wallSize.x*paintingMaxRatio)
        {
            newX = wallSize.x*paintingMaxRatio;
            newY = newX/(ratio);
        }

        transform.localScale = new Vector3( newX,newY,transform.localScale.z);
        //print ("hey");
        // frame scaling
        float frameScaleX, frameScaleY;
        frameScaleX = (newX + 2 * frameWidth)/newX;
        frameScaleY = (newY + 2 * frameWidth)/newY;
        transform.GetChild (0).localScale = new Vector3 (frameScaleX, frameScaleY, .8f);
    }
        public static void OnGUI()
        {
            // Initialize icon list
            if (icons == null)
            {
                List<GUIContent> content = new List<GUIContent>();

                foreach (GameDatabase.TextureInfo texInfo in GameDatabase.Instance.databaseTexture.Where(t => t.name.StartsWith("Squad/Contracts/Icons/")))
                {
                    string name = texInfo.name.Replace("Squad/Contracts/Icons/", "");
                    if (forbiddenIcons.Contains(name))
                    {
                        continue;
                    }

                    content.Add(new GUIContent(ContractDefs.sprites[name].texture, name));
                }

                icons = content.ToArray();
            }

            // Initialize color list
            if (colors == null)
            {
                List<GUIContent> content = new List<GUIContent>();

                foreach (int seed in seeds)
                {
                    Color color = SystemUtilities.RandomColor(seed, 1.0f, 1.0f, 1.0f);
                    Texture2D texture = new Texture2D(6, 12, TextureFormat.RGBA32, false);

                    Color[] pixels = new Color[6 * 16];
                    for (int i = 0; i < pixels.Length; i++)
                    {
                        pixels[i] = color;
                    }
                    texture.SetPixels(pixels);
                    texture.Compress(true);

                    content.Add(new GUIContent(texture));
                }

                colors = content.ToArray();

                // Set the styles used
                colorWheelStyle = new GUIStyle(GUI.skin.label);
                colorWheelStyle.padding = new RectOffset(0, 0, 2, 2);
                colorWheelStyle.margin = new RectOffset(0, -1, 0, 0);

                colorLabelStyle = new GUIStyle(GUI.skin.label);
                colorLabelStyle.padding = new RectOffset(0, 0, 0, 0);
                colorLabelStyle.margin = new RectOffset(4, 4, 6, 6);
                colorLabelStyle.stretchWidth = true;
                colorLabelStyle.fixedHeight = 12;

                disabledText = new GUIStyle(GUI.skin.textField);
                disabledText.normal.textColor = Color.gray;
            }

            if (WaypointManager.Instance != null && WaypointManager.Instance.visible)
            {
                if (windowMode != WindowMode.None && windowMode != WindowMode.Delete)
                {
                    wpWindowPos = GUILayout.Window(
                        typeof(WaypointManager).FullName.GetHashCode() + 2,
                        wpWindowPos,
                        WindowGUI,
                        windowMode.ToString() + " Waypoint",
                        GUILayout.Height(1), GUILayout.ExpandHeight(true));

                    // Add the close icon
                    if (GUI.Button(new Rect(wpWindowPos.xMax - 18, wpWindowPos.yMin + 2, 16, 16), Config.closeIcon, GUI.skin.label))
                    {
                        windowMode = WindowMode.None;
                    }

                    if (showIconPicker)
                    {
                        // Default iconPicker position
                        if (iconPickerPosition.xMin == iconPickerPosition.xMax)
                        {
                            iconPickerPosition = new Rect((Screen.width - ICON_PICKER_WIDTH) / 2.0f, wpWindowPos.yMax, ICON_PICKER_WIDTH, 1);
                        }

                        iconPickerPosition = GUILayout.Window(
                            typeof(WaypointManager).FullName.GetHashCode() + 3,
                            iconPickerPosition,
                            IconPickerGUI,
                            "Icon Selector");

                        // Add the close icon
                        if (GUI.Button(new Rect(iconPickerPosition.xMax - 18, iconPickerPosition.yMin + 2, 16, 16), Config.closeIcon, GUI.skin.label))
                        {
                            showIconPicker = false;
                        }
                    }

                    // Reset the position of the iconPicker window
                    if (!showIconPicker)
                    {
                        iconPickerPosition.xMax = iconPickerPosition.xMin;
                    }
                }
                else if (windowMode == WindowMode.Delete)
                {
                    rmWindowPos = GUILayout.Window(
                        typeof(WaypointManager).FullName.GetHashCode() + 2,
                        rmWindowPos,
                        DeleteGUI,
                        windowMode.ToString() + " Waypoint");

                    // Add the close icon
                    if (GUI.Button(new Rect(rmWindowPos.xMax - 18, rmWindowPos.yMin + 2, 16, 16), Config.closeIcon, GUI.skin.label))
                    {
                        windowMode = WindowMode.None;
                    }
                }

                if (showExportDialog)
                {
                    expWindowPos = GUILayout.Window(
                        typeof(WaypointManager).FullName.GetHashCode() + 3,
                        expWindowPos,
                        ExportGUI,
                        "Overwrite export file?");

                    // Add the close icon
                    if (GUI.Button(new Rect(expWindowPos.xMax - 18, expWindowPos.yMin + 2, 16, 16), Config.closeIcon, GUI.skin.label))
                    {
                        showExportDialog = false;
                    }
                }

                if (mapLocationMode)
                {
                    PlaceWaypointAtCursor();

                    // Lock the waypoint if the user clicks
                    if (Event.current.type == EventType.MouseUp && Event.current.button == 0)
                    {
                        mapLocationMode = false;
                    }
                }
            }
        }
示例#20
0
		private void MakeCombinedGrayscale(int beg, ref Texture2D SSColorCombined) {
			ReliefTerrain _targetRT=(ReliefTerrain)target;
			ReliefTerrainGlobalSettingsHolder _target=_targetRT.globalSettingsHolder;
			
			for(int n=beg; n<_target.numLayers; n++) {
				int min_size=9999;
				for(int m=(n/4)*4; (m<((n/4)*4+4)) && (m<_target.numLayers); m++) {
					if (_target.splats[m]) { // czasem może byc błędnie wprowadzony jako null
						if (_target.splats[m].width<min_size) min_size=_target.splats[m].width;
					}
				}		
				AssetImporter _importer=AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(_target.splats[n]));
				if (_importer) {
					TextureImporter tex_importer=(TextureImporter)_importer;
					bool reimport_flag=false;
					if (!tex_importer.isReadable) {
						Debug.LogWarning("Detail texture "+n+" ("+_target.splats[n].name+") has been reimported as readable.");
						tex_importer.isReadable=true;
						reimport_flag=true;
					}
					if (_target.splats[n] && _target.splats[n].width>min_size) {
						Debug.LogWarning("Detail texture "+n+" ("+_target.splats[n].name+") has been reimported with "+min_size+" size.");
						tex_importer.maxTextureSize=min_size;
						reimport_flag=true;
					}
					if (reimport_flag) {
						AssetDatabase.ImportAsset(AssetDatabase.GetAssetPath(_target.splats[n]),  ImportAssetOptions.ForceUpdate);
					}
				}					
			}				
			
			int i;
			for(i=0; i<_target.numLayers; i++) {
				try { 
					_target.splats[i].GetPixels(0,0,4,4,0);
				} catch (Exception e) {
					Debug.LogError("Splat texture "+i+" has to be marked as isReadable...");
					Debug.LogError(e.Message);
					return;
				}
			}
			int w=_target.splats[0].width;
			for(i=1; i<_target.numLayers; i++) {
				if (_target.splats[i].width!=w) {
					Debug.LogError("For performance reasons - all splats (detail textures) should have the same size");
					Debug.LogError("Detail tex 0 size="+w+" while detail tex "+i+" size="+_target.splats[i].width);
					return;
				}
			}
			
			int num=_target.numLayers<=8 ? _target.numLayers : 8;
			Texture2D[] splats=new Texture2D[4];
			for(i=0; i<splats.Length; i++) {
				if (i<4) {
					if (i<num) {
						splats[i]=_target.splats[i+beg];
					} else {
						splats[i]=new Texture2D(_target.splats[num-1].width, _target.splats[num-1].width);
					}
				}
			}
			Color[] tex0=splats[0].GetPixels(0);
			Color[] tex1=splats[1].GetPixels(0);
			Color[] tex2=splats[2].GetPixels(0);
			Color[] tex3=splats[3].GetPixels(0);
			Color[] result=new Color[tex0.Length];
			for(i=0; i<tex0.Length; i++) {
				result[i]=new Color( tex0[i].grayscale, tex1[i].grayscale, tex2[i].grayscale, tex3[i].grayscale);
			}
			SSColorCombined=new Texture2D(splats[0].width, splats[0].height, TextureFormat.ARGB32, true, true);
			SSColorCombined.SetPixels(result);
			SSColorCombined.Apply(true,false);
			SSColorCombined.Compress(true);
		}
示例#21
0
文件: GUIHelper.cs 项目: huin/kerbcam
 private static Texture2D MakeConstantTexture(Color fill)
 {
     const int size = 32;
     Texture2D txt = new Texture2D(size, size);
     for (int row = 0; row < size; row++) {
         for (int col = 0; col < size; col++) {
             txt.SetPixel(col, row, fill);
         }
     }
     txt.Apply();
     txt.Compress(false);
     return txt;
 }
示例#22
0
文件: TermWindow.cs 项目: KSP-KOS/KOS
        private void LoadFontArray()
        {
            // Calculate image size from the presumption that it is a hardcoded number of char
            // pictures wide and that each image is square.
            // Then calculate everything else dynamically from that so that
            // you can experiment with swapping in different font image files and the code
            // will still work without a recompile:
            int charSourceSize = fontImage.width / FONTIMAGE_CHARS_PER_ROW;
            int numRows = fontImage.width / charSourceSize;
            int numCharImages = numRows * FONTIMAGE_CHARS_PER_ROW;

            // Make it hold all possible ASCII values even though many will be blank pictures:
            fontArray = new Texture2D[numCharImages];

            for (int i = 0 ; i < numCharImages ; ++i)
            {
                // TextureFormat cannot be DXT1 or DXT5 if you want to ever perform a
                // SetPixel on the texture (which we do).  So we start it off as a ARGB32
                // first, long enough to perform the SetPixel call, then compress it
                // afterward into a DXT5:
                Texture2D charImage = new Texture2D(charSourceSize, charSourceSize, TextureFormat.ARGB32, false);

                int tx = i % FONTIMAGE_CHARS_PER_ROW;
                int ty = i / FONTIMAGE_CHARS_PER_ROW;

                // While Unity uses the convention of upside down textures common in
                // 3D (2D images put orgin at upper-left, 3D uses lower-left), it doesn't seem
                // to apply this rule to textures loaded from files like the fontImage.
                // Thus the difference requiring the upside-down Y coord below.
                charImage.SetPixels(fontImage.GetPixels(tx * charSourceSize, fontImage.height - (ty+1) * charSourceSize, charSourceSize, charSourceSize));
                charImage.Compress(false);
                charImage.Apply();

                fontArray[i] = charImage;
            }
        }
	public static Texture2D LoadTexture2DFromGamedata(string scd, string LocalPath, bool NormalMap = false){
		if(string.IsNullOrEmpty(LocalPath)) return null;

		if(!Directory.Exists(EnvPaths.GetGamedataPath())){
			Debug.LogError("Gamedata path not exist!");
			return null;
		}
		ZipFile zf = null;
		Texture2D texture = null;


		bool Mipmaps = false;
		try{
			FileStream fs = File.OpenRead(EnvPaths.GetGamedataPath() + scd);
			zf = new ZipFile(fs);


			ZipEntry zipEntry2 =  zf.GetEntry(LocalPath);
			if(zipEntry2 == null){
				Debug.LogError("Zip Entry is empty for: " + LocalPath);
				return null;
			}

			byte[] FinalTextureData2 = new byte[4096]; // 4K is optimum

			if (zipEntry2 != null)
			{
				Stream s = zf.GetInputStream(zipEntry2);
				FinalTextureData2 = new byte[zipEntry2.Size];
				s.Read(FinalTextureData2, 0, FinalTextureData2.Length);
			}

			TextureFormat format = GetFormatOfDdsBytes(FinalTextureData2);
			Mipmaps = LoadDDsHeader.mipmapcount > 0;
			texture = new Texture2D((int)LoadDDsHeader.width, (int)LoadDDsHeader.height, format, Mipmaps, true);

			int DDS_HEADER_SIZE = 128;
			byte[] dxtBytes = new byte[FinalTextureData2.Length - DDS_HEADER_SIZE];
			Buffer.BlockCopy(FinalTextureData2, DDS_HEADER_SIZE, dxtBytes, 0, FinalTextureData2.Length - DDS_HEADER_SIZE);

			if(IsDxt3){
				texture = DDS.DDSReader.LoadDDSTexture( new MemoryStream(FinalTextureData2), false).ToTexture2D();
				texture.Apply(false);
			}
			else{
				texture.LoadRawTextureData(dxtBytes);
				texture.Apply(false);
			}
		} finally {
			if (zf != null) {
				zf.IsStreamOwner = true; // Makes close also shut the underlying stream
				zf.Close(); // Ensure we release resources
			}
		}

		if(NormalMap){
			texture.Compress(true);

			Texture2D normalTexture = new Texture2D((int)LoadDDsHeader.width, (int)LoadDDsHeader.height, TextureFormat.RGBA32, Mipmaps, true);

			Color theColour = new Color();
			Color[] Pixels;

			for(int m = 0; m < LoadDDsHeader.mipmapcount + 1; m++){
				int Texwidth = texture.width;
				int Texheight = texture.height;

				if(m > 0){
					Texwidth /= (int)Mathf.Pow(2, m);
					Texheight /= (int)Mathf.Pow(2, m);
				}
				Pixels = texture.GetPixels(0, 0, Texwidth, Texheight, m);

				for(int i = 0; i < Pixels.Length; i++){
					theColour.r = Pixels[i].r;
					theColour.g = Pixels[i].g;
					theColour.b = 1;
					theColour.a = Pixels[i].g;
					Pixels[i] = theColour;
				}
				normalTexture.SetPixels(0, 0, Texwidth, Texheight, Pixels, m);
			}

			normalTexture.Apply(false);

			normalTexture.mipMapBias = MipmapBias;
			normalTexture.filterMode = FilterMode.Bilinear;
			normalTexture.anisoLevel = AnisoLevel;
			return normalTexture;
		}
		else{
			texture.mipMapBias = MipmapBias;
			texture.filterMode = FilterMode.Bilinear;
			texture.anisoLevel = AnisoLevel;
		}

		return texture;
	}
        public void writeTexture()
        {
            if (Global.Debug2) Utils.Log("writeTexture start");

            Image textureImage = new Image();
            Image normalMapImage = new Image();

            if (_baseTexture.hasNormalMap())
            {
                _baseTexture.drawOnImage(ref textureImage, ref normalMapImage);
                _imageModifiers.drawOnImage(ref textureImage, ref normalMapImage, _boundingBox);
            }
            else
            {
                _baseTexture.drawOnImage(ref textureImage);
                _imageModifiers.drawOnImage(ref textureImage, _boundingBox);
            }

            Texture2D mainTexture = new Texture2D(textureImage.width, textureImage.height, TextureFormat.ARGB32, true);
            mainTexture.SetPixels32(textureImage.pixels);
            mainTexture.name = _baseTexture.mainUrl() + "_TWS";

            if (outputReadable) mainTexture.Apply(true);
            else
            {
                mainTexture.Apply(true);
                mainTexture.Compress(true);
                mainTexture.Apply(false, true);
            }

            foreach (Transform transform in _transforms)
            {
                if (Global.Debug3) Utils.Log("setting texture in transform {0}", transform.name);
                transform.gameObject.renderer.material.SetTexture("_MainTex", mainTexture);
            }

            Texture2D normalMapTexture = null;
            if (_baseTexture.hasNormalMap())
            {
                normalMapTexture = new Texture2D(normalMapImage.width, normalMapImage.height, TextureFormat.ARGB32, false);
                normalMapTexture.SetPixels32(normalMapImage.pixels);
                normalMapTexture.name = _baseTexture.normalMapUrl() + "_TWS";

                if (outputReadable) normalMapTexture.Apply(false);
                else normalMapTexture.Apply(false, true);

                foreach (Transform transform in _transforms)
                {
                    if (Global.Debug3) Utils.Log("setting normalMap in transform {0}", transform.name);
                    transform.gameObject.renderer.material.SetTexture("_BumpMap", normalMapTexture);
                }
            }

            if (_generatedMainTexture != null) Destroy(_generatedMainTexture);
            _generatedMainTexture = mainTexture;

            if (_generatedNormalMap != null) Destroy(_generatedNormalMap);
            if (normalMapTexture != null) _generatedNormalMap = normalMapTexture;
            else _generatedNormalMap = null;

            // clean up memory usage
            _baseTexture.cleanUp();
            _imageModifiers.cleanUp();

            _usedPaint = true;
        }
    public static Texture2D Load(string TextureName)
    {
        if (!File.Exists(Configuration.GameFld + Configuration.Mod + "/materials/" + TextureName + ".vtf"))
            return new Texture2D(1, 1);

        CRead = new CustomReader(File.OpenRead(Configuration.GameFld + Configuration.Mod + "/materials/" + TextureName + ".vtf"));
        VTF_Header = CRead.ReadType<tagVTFHEADER>();

        Texture2D VTF_Texture = default(Texture2D); TextureFormat ImageFormat;
        long OffsetInFile = VTF_Header.Width * VTF_Header.Height * uiBytesPerPixels[(int)VTF_Header.HighResImageFormat];

        switch (VTF_Header.HighResImageFormat)
        {
            case VTFImageFormat.IMAGE_FORMAT_DXT1:
                OffsetInFile = ((VTF_Header.Width + 3) / 4) * ((VTF_Header.Height + 3) / 4) * 8;
                ImageFormat = TextureFormat.DXT1; break;

            case VTFImageFormat.IMAGE_FORMAT_DXT3:
            case VTFImageFormat.IMAGE_FORMAT_DXT5:
                OffsetInFile = ((VTF_Header.Width + 3) / 4) * ((VTF_Header.Height + 3) / 4) * 16;
                ImageFormat = TextureFormat.DXT5; break;

            case VTFImageFormat.IMAGE_FORMAT_RGB888:
            case VTFImageFormat.IMAGE_FORMAT_BGR888:
                ImageFormat = TextureFormat.RGB24; break;

            case VTFImageFormat.IMAGE_FORMAT_RGBA8888:
                ImageFormat = TextureFormat.RGBA32; break;

            case VTFImageFormat.IMAGE_FORMAT_ARGB8888:
                ImageFormat = TextureFormat.ARGB32; break;

            case VTFImageFormat.IMAGE_FORMAT_BGRA8888:
                ImageFormat = TextureFormat.BGRA32; break;

            default: return new Texture2D(1, 1);
        }

        VTF_Texture = new Texture2D(VTF_Header.Width, VTF_Header.Height, ImageFormat, false);
        byte[] VTF_File = CRead.GetBytes((int)OffsetInFile, CRead.InputStream.Length - OffsetInFile);

        if (VTF_Header.HighResImageFormat == VTFImageFormat.IMAGE_FORMAT_BGR888)
        {
            for (int i = 0; i < VTF_File.Length - 1; i += 3)
            {
                byte Temp = VTF_File[i];
                VTF_File[i] = VTF_File[i + 2];
                VTF_File[i + 2] = Temp;
            }
        }

        VTF_Texture.LoadRawTextureData(VTF_File);

        Texture2D Mip_Texture = new Texture2D(VTF_Header.Width, VTF_Header.Height, TextureFormat.RGBA32, true);
        Mip_Texture.SetPixels32(VTF_Texture.GetPixels32());

        Mip_Texture.Apply(); Mip_Texture.Compress(false);
        Object.DestroyImmediate(VTF_Texture);

        CRead.Dispose();
        return Mip_Texture;
    }
示例#26
0
        public void Start()
        {
            if (doneRSS)
                return;

            // First, run GC.
            ProfileTimer.Push("RSS_FirstGC");
            print("*RSS*: Total memory in use: " + GC.GetTotalMemory(true));
            ProfileTimer.Pop("RSS_FirstGC");
            // Constants
            double DEG2RAD = Math.PI / 180.0;
            string guiMajorBase = "";

            ConfigNode RSSSettings = null;
            foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("REALSOLARSYSTEM"))
                RSSSettings = node;

            if (RSSSettings == null)
                throw new UnityException("*RSS* REALSOLARSYSTEM node not found!");

            /*print("*RSS* Printing CBTs");
            foreach (PQSMod_CelestialBodyTransform c in Resources.FindObjectsOfTypeAll(typeof(PQSMod_CelestialBodyTransform)))
                Utils.DumpCBT(c);*/

            print("*RSS* fixing bodies");
            double epoch = 0;
            bool useEpoch = false;
            bool doWrap = false;
            bool updateMass = true;
            bool compressNormals = false;
            bool spheresOnly = false;
            bool defaultAtmoScale = true;
            float SSAtmoScale = 1.0f;
            useEpoch = RSSSettings.TryGetValue("Epoch", ref epoch);
            RSSSettings.TryGetValue("wrap", ref doWrap);
            RSSSettings.TryGetValue("compressNormals", ref compressNormals);
            RSSSettings.TryGetValue("spheresOnly", ref spheresOnly);
            RSSSettings.TryGetValue("defaultAtmoScale", ref defaultAtmoScale);
            RSSSettings.TryGetValue("SSAtmoScale", ref SSAtmoScale);

            // get spherical scaledspace mesh
            MeshFilter joolMesh = null;
            if (ScaledSpace.Instance != null)
            {
                //print("*RSS* Printing ScaledSpace Transforms");
                foreach (Transform t in ScaledSpace.Instance.scaledSpaceTransforms)
                {
                    /*print("***** TRANSFROM: " + t.name);
                    Utils.PrintTransformUp(t);
                    Utils.PrintTransformRecursive(t);*/
                    if (t.name.Equals("Jool"))
                        joolMesh = (MeshFilter)t.GetComponent(typeof(MeshFilter));
                }
                //print("*RSS* InverseScaleFactor = " + ScaledSpace.InverseScaleFactor);
            }
            showGUI = true;
            guiMajorBase = "Editing Body: ";
            //OnGui();
            foreach (ConfigNode node in RSSSettings.nodes)
            {
                foreach (CelestialBody body in FlightGlobals.fetch.bodies) //Resources.FindObjectsOfTypeAll(typeof(CelestialBody))) //in FlightGlobals.fetch.bodies)
                {
                    if (body.name.Equals(node.name))
                    {
                        guiMajor = guiMajorBase + node.name;
                        //OnGui();
                        #region CBChanges
                        print("Fixing CB " + node.name + " of radius " + body.Radius);
                        guiMinor = "CelestialBody";
                        //OnGui();
                        double dtmp;
                        float ftmp;
                        int itmp;
                        bool btmp;
                        double origRadius = body.Radius;
                        double origAtmo = body.maxAtmosphereAltitude;

                        #region CBMassRadius

                        node.TryGetValue("bodyName", ref body.bodyName);
                        node.TryGetValue("bodyDescription", ref body.bodyDescription);
                        node.TryGetValue("Radius", ref body.Radius);
                        print("Radius ratio: " + body.Radius / origRadius);

                        if (node.TryGetValue("Mass", ref body.Mass))
                        {
                            MassToOthers(body);
                            updateMass = false;
                        }
                        if (node.TryGetValue("GeeASL", ref body.GeeASL))
                        {
                            GeeASLToOthers(body);
                            updateMass = false;
                        }
                        if (node.TryGetValue("gravParameter", ref body.gravParameter))
                        {
                            GravParamToOthers(body);
                            updateMass = false;
                        }
                        #endregion

                        #region CBAtmosphereTemperature
                        node.TryGetValue("atmosphericAmbientColor", ref body.atmosphericAmbientColor);
                        node.TryGetValue("atmosphere", ref body.atmosphere);
                        node.TryGetValue("atmosphereScaleHeight", ref body.atmosphereScaleHeight);
                        node.TryGetValue("atmosphereMultiplier", ref body.atmosphereMultiplier);
                        node.TryGetValue("maxAtmosphereAltitude", ref body.maxAtmosphereAltitude);
                        node.TryGetValue("staticPressureASL", ref body.staticPressureASL);
                        node.TryGetValue("useLegacyAtmosphere", ref body.useLegacyAtmosphere);
                        if (!body.useLegacyAtmosphere)
                        {
                            ConfigNode PCnode = node.GetNode("pressureCurve");
                            if (PCnode != null)
                            {
                                string[] curve = PCnode.GetValues("key");
                                body.altitudeMultiplier = 1f;
                                body.pressureMultiplier = 1f;
                                AnimationCurve pressureCurve = loadAnimationCurve(curve);
                                if (pressureCurve != null)
                                    body.pressureCurve = pressureCurve;
                                else
                                {
                                    body.useLegacyAtmosphere = true;
                                    Debug.LogWarning("Unable to load pressureCurve data for " + body.name + ": Using legacy atmosphere");
                                }
                                print("*RSS* finished with " + body.GetName() + ".pressureCurve (" + body.pressureCurve.keys.Length.ToString() + " keys)");
                            }
                            else
                            {
                                print("*RSS* useLegacyAtmosphere = False but pressureCurve not found!");
                            }
                        }
                        if (node.HasNode("temperatureCurve"))
                        {
                            ConfigNode TCnode = node.GetNode("temperatureCurve");
                            if (TCnode != null)
                            {
                                string[] curve = TCnode.GetValues("key");
                                AnimationCurve temperatureCurve = loadAnimationCurve(curve);
                                if (temperatureCurve != null)
                                {
                                    body.temperatureCurve = temperatureCurve;
                                    print("*RSS* found and loaded temperatureCurve data for " + body.name);
                                }
                            }
                        }
                        #endregion

                        #region CBRotation
                        node.TryGetValue("rotationPeriod", ref body.rotationPeriod);
                        node.TryGetValue("tidallyLocked", ref body.tidallyLocked);
                        node.TryGetValue("initialRotation", ref body.initialRotation);
                        node.TryGetValue("inverseRotation", ref body.inverseRotation);
                        #endregion

                        if (updateMass)
                            GeeASLToOthers(body);

                        /*if (node.HasValue("axialTilt"))
                        {
                            if (!body.inverseRotation && double.TryParse(node.GetValue("axialTilt"), out dtmp))
                            {
                                CBRotationFixer.CBRotations.Add(body.name, new CBRotation(body.name, dtmp, body.rotationPeriod, body.initialRotation));
                                body.rotationPeriod = 0;
                            }
                        }*/

                        #region CBOrbit
                        ConfigNode onode = node.GetNode("Orbit");
                        if (body.orbitDriver != null && body.orbit != null && onode != null)
                        {
                            if (useEpoch)
                                body.orbit.epoch = epoch;

                            onode.TryGetValue("semiMajorAxis", ref body.orbit.semiMajorAxis);
                            onode.TryGetValue("eccentricity", ref body.orbit.eccentricity);
                            onode.TryGetValue("meanAnomalyAtEpoch", ref body.orbit.meanAnomalyAtEpoch);
                            if (onode.TryGetValue("meanAnomalyAtEpochD", ref body.orbit.meanAnomalyAtEpoch))
                                body.orbit.meanAnomalyAtEpoch *= DEG2RAD;
                            onode.TryGetValue("inclination", ref body.orbit.inclination);
                            onode.TryGetValue("period", ref body.orbit.period);
                            onode.TryGetValue("LAN", ref body.orbit.LAN);
                            onode.TryGetValue("argumentOfPeriapsis", ref body.orbit.argumentOfPeriapsis);
                            if(onode.HasValue("orbitColor"))
                            {
                                try
                                {
                                    Vector4 col = KSPUtil.ParseVector4(onode.GetValue("orbitColor"));
                                    Color c = new Color(col.x, col.y, col.z, col.w);
                                    body.GetOrbitDriver().orbitColor = c;
                                }
                                catch(Exception e)
                                {
                                    print("*RSS* Error parsing as color4: original text: " + onode.GetValue("orbitColor") + " --- exception " + e.Message);
                                }
                            }
                            string bodyname = "";
                            if (onode.TryGetValue("referenceBody", ref bodyname))
                            {
                                if (body.orbit.referenceBody == null || !body.orbit.referenceBody.Equals(bodyname))
                                {
                                    foreach (CelestialBody b in FlightGlobals.Bodies)
                                    {
                                        if (b.name.Equals(bodyname))
                                        {
                                            if (body.orbit.referenceBody)
                                            {
                                                body.orbit.referenceBody.orbitingBodies.Remove(body);
                                            }
                                            b.orbitingBodies.Add(body);
                                            body.orbit.referenceBody = b;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                        // SOI and HillSphere done at end
                        body.CBUpdate();
                        #endregion
                        #endregion

                        #region SSPQSFade
                        // Scaled space fader
                        float SSFMult = 1.0f;
                        float SSFStart = -1, SSFEnd = -1;
                        node.TryGetValue("SSFStart", ref SSFStart);
                        node.TryGetValue("SSFEnd", ref SSFEnd);
                        node.TryGetValue("SSFMult", ref SSFMult);

                        foreach (ScaledSpaceFader ssf in Resources.FindObjectsOfTypeAll(typeof(ScaledSpaceFader)))
                        {
                            if (ssf.celestialBody != null)
                            {
                                if (ssf.celestialBody.name.Equals(node.name))
                                {
                                    if (SSFStart >= 0)
                                        ssf.fadeStart = SSFStart;
                                    else
                                        ssf.fadeStart *= SSFMult;

                                    if (SSFEnd >= 0)
                                        ssf.fadeEnd = SSFEnd;
                                    else
                                        ssf.fadeEnd *= SSFMult;
                                }
                            }
                        }
                        // The CBT that fades out the PQS
                        // Should probably do this as just another PQSMod, actually.
                        foreach (PQSMod_CelestialBodyTransform c in Resources.FindObjectsOfTypeAll(typeof(PQSMod_CelestialBodyTransform)))
                        {
                            try
                            {
                                if (c.body != null)
                                {
                                    if (c.body.name.Equals(node.name))
                                    {
                                        print("Found CBT for " + node.name);
                                        node.TryGetValue("PQSdeactivateAltitude", ref c.deactivateAltitude);
                                        if (c.planetFade != null)
                                        {
                                            node.TryGetValue("PQSfadeStart", ref c.planetFade.fadeStart);
                                            node.TryGetValue("PQSfadeEnd", ref c.planetFade.fadeEnd);
                                            if (c.secondaryFades != null)
                                            {
                                                foreach (PQSMod_CelestialBodyTransform.AltitudeFade af in c.secondaryFades)
                                                {
                                                    node.TryGetValue("PQSSecfadeStart", ref af.fadeStart);
                                                    node.TryGetValue("PQSSecfadeEnd", ref af.fadeEnd);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            catch (Exception e)
                            {
                                print("CBT fix for " + node.name + " failed: " + e.Message);
                            }
                        }
                        print("Did CBT for " + node.name);
                        #endregion

                        #region PQS
                        guiMinor = "PQS";
                        //OnGui();
                        // the Planet Quadtree Sphere
                        List<string> PQSs = new List<string>();
                        bool custom = false;
                        if (node.HasNode("PQS"))
                        {
                            foreach (ConfigNode n in node.GetNode("PQS").nodes)
                                PQSs.Add(n.name);
                            custom = true;
                        }
                        else
                        {
                            if (body.Radius != origRadius)
                            {
                                PQSs.Add(node.name);
                                PQSs.Add(node.name + "Ocean");
                            }
                        }
                        foreach (string pName in PQSs)
                        {
                            print("Finding PQS " + pName);
                            foreach (PQS p in Resources.FindObjectsOfTypeAll(typeof(PQS)))
                            {
                                if (p.name.Equals(pName))
                                {
                                    if (body.pqsController != p)
                                        if (body.pqsController != p.parentSphere)
                                            continue;
                                    guiMinor = "PQS " + p.name;
                                    //OnGui();
                                    p.radius = body.Radius;
                                    print("Editing PQS " + pName + ", default set radius = " + p.radius);
                                    if (custom) // YES, THIS IS SILLY
                                    // I SHOULD JUST WRITE A REAL C# EXTENSIBLE LOADER
                                    // Oh well. Hacks are quicker.
                                    {
                                        ConfigNode pqsNode = node.GetNode("PQS").GetNode(pName);

                                        // PQS members
                                        if (pqsNode.HasValue("radius"))
                                        {
                                            if (double.TryParse(pqsNode.GetValue("radius"), out dtmp))
                                            {
                                                p.radius = dtmp;
                                                print("Editing PQS " + pName + ", config set radius = " + p.radius);
                                            }
                                        }
                                        if(pqsNode.HasValue("maxLevel"))
                                        {
                                            if (int.TryParse(pqsNode.GetValue("maxLevel"), out itmp))
                                            {
                                                p.maxLevel = itmp;
                                                try
                                                {
                                                    PQSCache.PresetList.GetPreset(p.name).maxSubdivision = itmp;
                                                }
                                                catch (Exception e)
                                                {
                                                    print("*RSS* ERROR: Applying change to preset for " + p.name + ", exception: " + e.Message);
                                                }
                                            }
                                        }
                                        if (pqsNode.HasValue("maxQuadLenghtsPerFrame"))
                                        {
                                            if (float.TryParse(pqsNode.GetValue("maxQuadLenghtsPerFrame"), out ftmp))
                                            {
                                                p.maxQuadLenghtsPerFrame = ftmp;
                                            }
                                        }
                                        if (pqsNode.HasValue("visRadAltitudeMax"))
                                        {
                                            if (double.TryParse(pqsNode.GetValue("visRadAltitudeMax"), out dtmp))
                                            {
                                                p.visRadAltitudeMax = dtmp;
                                            }
                                        }
                                        if (pqsNode.HasValue("visRadAltitudeValue"))
                                        {
                                            if (double.TryParse(pqsNode.GetValue("visRadAltitudeValue"), out dtmp))
                                            {
                                                p.visRadAltitudeValue = dtmp;
                                            }
                                        }
                                        if (pqsNode.HasValue("visRadSeaLevelValue"))
                                        {
                                            if (double.TryParse(pqsNode.GetValue("visRadSeaLevelValue"), out dtmp))
                                            {
                                                p.visRadSeaLevelValue = dtmp;
                                            }
                                        }

                                        // PQSMods
                                        var mods = p.transform.GetComponentsInChildren(typeof(PQSMod), true);
                                        foreach (var m in mods)
                                        {
                                            print("Processing " + m.GetType().Name);
                                            guiExtra = m.GetType().Name;
                                            //OnGui();
                                            foreach (ConfigNode modNode in pqsNode.nodes)
                                            {
                                                if (modNode.name.Equals("PQSMod_VertexSimplexHeightAbsolute") && m.GetType().ToString().Equals(modNode.name))
                                                {
                                                    PQSMod_VertexSimplexHeightAbsolute mod = m as PQSMod_VertexSimplexHeightAbsolute;
                                                    if (modNode.HasValue("deformity"))
                                                    {
                                                        if (double.TryParse(modNode.GetValue("deformity"), out dtmp))
                                                            mod.deformity = dtmp;
                                                    }
                                                    if (modNode.HasValue("persistence"))
                                                    {
                                                        if (double.TryParse(modNode.GetValue("persistence"), out dtmp))
                                                            mod.persistence = dtmp;
                                                    }
                                                    if (modNode.HasValue("frequency"))
                                                    {
                                                        if (double.TryParse(modNode.GetValue("frequency"), out dtmp))
                                                            mod.frequency = dtmp;
                                                    }
                                                    mod.OnSetup();
                                                }
                                                if (modNode.name.Equals("PQSMod_VertexHeightNoiseVertHeightCurve2") && m.GetType().ToString().Equals(modNode.name))
                                                {
                                                    PQSMod_VertexHeightNoiseVertHeightCurve2 mod = m as PQSMod_VertexHeightNoiseVertHeightCurve2;
                                                    if (modNode.HasValue("deformity"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("deformity"), out ftmp))
                                                            mod.deformity = ftmp;
                                                    }
                                                    if (modNode.HasValue("ridgedAddFrequency"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("ridgedAddFrequency"), out ftmp))
                                                            mod.ridgedAddFrequency = ftmp;
                                                    }
                                                    if (modNode.HasValue("ridgedSubFrequency"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("ridgedSubFrequency"), out ftmp))
                                                            mod.ridgedSubFrequency = ftmp;
                                                    }
                                                    if (modNode.HasValue("ridgedAddOctaves"))
                                                    {
                                                        if (int.TryParse(modNode.GetValue("ridgedAddOctaves"), out itmp))
                                                            mod.ridgedAddOctaves = itmp;
                                                    }
                                                    if (modNode.HasValue("simplexHeightStart"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("simplexHeightStart"), out ftmp))
                                                            mod.simplexHeightStart = ftmp;
                                                    }
                                                    if (modNode.HasValue("simplexHeightEnd"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("simplexHeightEnd"), out ftmp))
                                                            mod.simplexHeightEnd = ftmp;
                                                    }
                                                    mod.OnSetup();
                                                }
                                                if (modNode.name.Equals("PQSMod_VertexRidgedAltitudeCurve") && m.GetType().ToString().Equals(modNode.name))
                                                {
                                                    PQSMod_VertexRidgedAltitudeCurve mod = m as PQSMod_VertexRidgedAltitudeCurve;
                                                    if (modNode.HasValue("deformity"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("deformity"), out ftmp))
                                                            mod.deformity = ftmp;
                                                    }
                                                    if (modNode.HasValue("ridgedAddFrequency"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("ridgedAddFrequency"), out ftmp))
                                                            mod.ridgedAddFrequency = ftmp;
                                                    }
                                                    if (modNode.HasValue("ridgedAddOctaves"))
                                                    {
                                                        if (int.TryParse(modNode.GetValue("ridgedAddOctaves"), out itmp))
                                                            mod.ridgedAddOctaves = itmp;
                                                    }
                                                    if (modNode.HasValue("simplexHeightStart"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("simplexHeightStart"), out ftmp))
                                                            mod.simplexHeightStart = ftmp;
                                                    }
                                                    if (modNode.HasValue("simplexHeightEnd"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("simplexHeightEnd"), out ftmp))
                                                            mod.simplexHeightEnd = ftmp;
                                                    }
                                                    mod.OnSetup();
                                                }
                                                ///
                                                if (modNode.name.Equals("PQSMod_VertexHeightMap") && m.GetType().ToString().Equals(modNode.name))
                                                {
                                                    PQSMod_VertexHeightMap mod = m as PQSMod_VertexHeightMap;
                                                    if (modNode.HasValue("heightMapDeformity"))
                                                    {
                                                        if (double.TryParse(modNode.GetValue("heightMapDeformity"), out dtmp))
                                                            mod.heightMapDeformity = dtmp;
                                                    }
                                                    if (modNode.HasValue("heightMapOffset"))
                                                    {
                                                        if (double.TryParse(modNode.GetValue("heightMapOffset"), out dtmp))
                                                            mod.heightMapOffset = dtmp;
                                                        print("*RSS* Set offset " + mod.heightMapOffset);
                                                    }
                                                    if (modNode.HasValue("heightMap"))
                                                    {
                                                        if (File.Exists(KSPUtil.ApplicationRootPath + modNode.GetValue("heightMap")))
                                                        {
                                                            Texture2D map = new Texture2D(4, 4, TextureFormat.Alpha8, false);
                                                            map.LoadImage(System.IO.File.ReadAllBytes(modNode.GetValue("heightMap")));
                                                            //print("*RSS* MapSO: depth " + mod.heightMap.Depth + "(" + mod.heightMap.Width + "x" + mod.heightMap.Height + ")");
                                                            //System.IO.File.WriteAllBytes("oldHeightmap.png", mod.heightMap.CompileToTexture().EncodeToPNG());
                                                            //DestroyImmediate(mod.heightMap);
                                                            //mod.heightMap = ScriptableObject.CreateInstance<MapSO>();
                                                            mod.heightMap.CreateMap(MapSO.MapDepth.Greyscale, map);
                                                            DestroyImmediate(map);
                                                        }
                                                        else
                                                            print("*RSS* *ERROR* texture does not exist! " + modNode.GetValue("heightMap"));
                                                    }
                                                    mod.OnSetup();
                                                }
                                                if (modNode.name.Equals("PQSMod_AltitudeAlpha") && m.GetType().ToString().Equals(modNode.name))
                                                {
                                                    PQSMod_AltitudeAlpha mod = m as PQSMod_AltitudeAlpha;
                                                    if (modNode.HasValue("atmosphereDepth"))
                                                    {
                                                        if (double.TryParse(modNode.GetValue("atmosphereDepth"), out dtmp))
                                                            mod.atmosphereDepth = dtmp;
                                                    }
                                                    mod.OnSetup();
                                                }
                                                if (modNode.name.Equals("PQSMod_AerialPerspectiveMaterial") && m.GetType().ToString().Equals(modNode.name))
                                                {
                                                    PQSMod_AerialPerspectiveMaterial mod = m as PQSMod_AerialPerspectiveMaterial;
                                                    if (modNode.HasValue("heightMapDeformity"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("heightMapDeformity"), out ftmp))
                                                            mod.atmosphereDepth = ftmp;
                                                    }
                                                    mod.OnSetup();
                                                }
                                                if (modNode.name.Equals("PQSMod_VertexSimplexHeight") && m.GetType().ToString().Equals(modNode.name))
                                                {
                                                    PQSMod_VertexSimplexHeight mod = m as PQSMod_VertexSimplexHeight;
                                                    if (modNode.HasValue("deformity"))
                                                    {
                                                        if (double.TryParse(modNode.GetValue("deformity"), out dtmp))
                                                            mod.deformity = dtmp;
                                                    }
                                                    if (modNode.HasValue("persistence"))
                                                    {
                                                        if (double.TryParse(modNode.GetValue("persistence"), out dtmp))
                                                            mod.persistence = dtmp;
                                                    }
                                                    if (modNode.HasValue("frequency"))
                                                    {
                                                        if (double.TryParse(modNode.GetValue("frequency"), out dtmp))
                                                            mod.frequency = dtmp;
                                                    }
                                                    if (modNode.HasValue("octaves"))
                                                    {
                                                        if (double.TryParse(modNode.GetValue("octaves"), out dtmp))
                                                            mod.octaves = dtmp;
                                                    }
                                                    mod.OnSetup();
                                                }
                                                if (modNode.name.Equals("PQSMod_VertexHeightNoiseVertHeight") && m.GetType().ToString().Equals(modNode.name))
                                                {
                                                    PQSMod_VertexHeightNoiseVertHeight mod = m as PQSMod_VertexHeightNoiseVertHeight;
                                                    if (modNode.HasValue("deformity"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("deformity"), out ftmp))
                                                            mod.deformity = ftmp;
                                                    }
                                                    if (modNode.HasValue("frequency"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("frequency"), out ftmp))
                                                            mod.frequency = ftmp;
                                                    }
                                                    if (modNode.HasValue("octaves"))
                                                    {
                                                        if (int.TryParse(modNode.GetValue("octaves"), out itmp))
                                                            mod.octaves = itmp;
                                                    }
                                                    mod.OnSetup();
                                                }
                                                if (modNode.name.Equals("PQSMod_VoronoiCraters") && m.GetType().ToString().Equals(modNode.name))
                                                {
                                                    PQSMod_VoronoiCraters mod = m as PQSMod_VoronoiCraters;
                                                    if (modNode.HasValue("KEYvoronoiSeed"))
                                                        if (int.Parse(modNode.GetValue("KEYvoronoiSeed")) != mod.voronoiSeed)
                                                            continue;

                                                    if (modNode.HasValue("deformation"))
                                                    {
                                                        if (double.TryParse(modNode.GetValue("deformation"), out dtmp))
                                                            mod.deformation = dtmp;
                                                    }
                                                    if (modNode.HasValue("voronoiFrequency"))
                                                    {
                                                        if (double.TryParse(modNode.GetValue("voronoiFrequency"), out dtmp))
                                                            mod.voronoiFrequency = dtmp;
                                                    }
                                                    mod.OnSetup();
                                                }
                                                if (modNode.name.Equals("PQSMod_VertexHeightNoise") && m.GetType().ToString().Equals(modNode.name))
                                                {
                                                    PQSMod_VertexHeightNoise mod = m as PQSMod_VertexHeightNoise;
                                                    if (modNode.HasValue("deformity"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("deformity"), out ftmp))
                                                            mod.deformity = ftmp;
                                                    }
                                                    if (modNode.HasValue("frequency"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("frequency"), out ftmp))
                                                            mod.frequency = ftmp;
                                                    }
                                                    mod.OnSetup();
                                                }
                                                if (modNode.name.Equals("PQSLandControl") && m.GetType().ToString().Equals(modNode.name))
                                                {
                                                    PQSLandControl mod = m as PQSLandControl;

                                                    if (modNode.HasValue("vHeightMax"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("vHeightMax"), out ftmp))
                                                            mod.vHeightMax = ftmp;
                                                    }
                                                    if (modNode.HasValue("altitudeBlend"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("altitudeBlend"), out ftmp))
                                                            mod.altitudeBlend = ftmp;
                                                    }
                                                    if (modNode.HasValue("altitudeFrequency"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("altitudeFrequency"), out ftmp))
                                                            mod.altitudeFrequency = ftmp;
                                                    }
                                                    if (modNode.HasValue("altitudePersistance"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("altitudePersistance"), out ftmp))
                                                            mod.altitudePersistance = ftmp;
                                                    }
                                                    if (modNode.HasValue("latitudeBlend"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("latitudeBlend"), out ftmp))
                                                            mod.latitudeBlend = ftmp;
                                                    }
                                                    if (modNode.HasValue("latitudeFrequency"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("latitudeFrequency"), out ftmp))
                                                            mod.latitudeFrequency = ftmp;
                                                    }
                                                    if (modNode.HasValue("latitudePersistance"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("latitudePersistance"), out ftmp))
                                                            mod.latitudePersistance = ftmp;
                                                    }
                                                    if (modNode.HasValue("longitudeBlend"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("longitudeBlend"), out ftmp))
                                                            mod.longitudeBlend = ftmp;
                                                    }
                                                    if (modNode.HasValue("longitudeFrequency"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("longitudeFrequency"), out ftmp))
                                                            mod.longitudeFrequency = ftmp;
                                                    }
                                                    if (modNode.HasValue("longitudePersistance"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("longitudePersistance"), out ftmp))
                                                            mod.longitudePersistance = ftmp;
                                                    }
                                                    foreach (ConfigNode lcNode in modNode.GetNodes("LandClass"))
                                                    {
                                                        bool found = false;
                                                        string lcName = lcNode.GetValue("landClassName");
                                                        foreach (PQSLandControl.LandClass lc in mod.landClasses)
                                                        {
                                                            if (lc.landClassName.Equals(lcName))
                                                            {
                                                                found = true;
                                                                if (lcNode.HasValue("color"))
                                                                {
                                                                    try
                                                                    {
                                                                        Vector4 col = KSPUtil.ParseVector4(lcNode.GetValue("color"));
                                                                        lc.color = new Color(col.x, col.y, col.z, col.w);
                                                                    }
                                                                    catch(Exception e)
                                                                    {
                                                                        print("*RSS* Error parsing as color4: original text: " + lcNode.GetValue("color") + " --- exception " + e.Message);
                                                                    }
                                                                }
                                                                if (lcNode.HasValue("noiseColor"))
                                                                {
                                                                    try
                                                                    {
                                                                        Vector4 col = KSPUtil.ParseVector4(lcNode.GetValue("noiseColor"));
                                                                        lc.noiseColor = new Color(col.x, col.y, col.z, col.w);
                                                                    }
                                                                    catch(Exception e)
                                                                    {
                                                                        print("*RSS* Error parsing as color4: original text: " + lcNode.GetValue("noiseColor") + " --- exception " + e.Message);
                                                                    }
                                                                }

                                                                // ranges
                                                                if(lcNode.HasNode("altitudeRange"))
                                                                {
                                                                    ConfigNode range = lcNode.GetNode("altitudeRange");
                                                                    if (range.HasValue("startStart"))
                                                                        if (double.TryParse(range.GetValue("startStart"), out dtmp))
                                                                            lc.altitudeRange.startStart = dtmp;
                                                                    if (range.HasValue("startEnd"))
                                                                        if (double.TryParse(range.GetValue("startEnd"), out dtmp))
                                                                            lc.altitudeRange.startEnd = dtmp;
                                                                    if (range.HasValue("endStart"))
                                                                        if (double.TryParse(range.GetValue("endStart"), out dtmp))
                                                                            lc.altitudeRange.endStart = dtmp;
                                                                    if (range.HasValue("endEnd"))
                                                                        if (double.TryParse(range.GetValue("endEnd"), out dtmp))
                                                                            lc.altitudeRange.endEnd = dtmp;
                                                                }
                                                                if (lcNode.HasNode("latitudeRange"))
                                                                {
                                                                    ConfigNode range = lcNode.GetNode("latitudeRange");
                                                                    if (range.HasValue("startStart"))
                                                                        if (double.TryParse(range.GetValue("startStart"), out dtmp))
                                                                            lc.latitudeRange.startStart = dtmp;
                                                                    if (range.HasValue("startEnd"))
                                                                        if (double.TryParse(range.GetValue("startEnd"), out dtmp))
                                                                            lc.latitudeRange.startEnd = dtmp;
                                                                    if (range.HasValue("endStart"))
                                                                        if (double.TryParse(range.GetValue("endStart"), out dtmp))
                                                                            lc.latitudeRange.endStart = dtmp;
                                                                    if (range.HasValue("endEnd"))
                                                                        if (double.TryParse(range.GetValue("endEnd"), out dtmp))
                                                                            lc.latitudeRange.endEnd = dtmp;
                                                                }
                                                                if (lcNode.HasNode("longitudeRange"))
                                                                {
                                                                    ConfigNode range = lcNode.GetNode("longitudeRange");
                                                                    if (range.HasValue("startStart"))
                                                                        if (double.TryParse(range.GetValue("startStart"), out dtmp))
                                                                            lc.longitudeRange.startStart = dtmp;
                                                                    if (range.HasValue("startEnd"))
                                                                        if (double.TryParse(range.GetValue("startEnd"), out dtmp))
                                                                            lc.longitudeRange.startEnd = dtmp;
                                                                    if (range.HasValue("endStart"))
                                                                        if (double.TryParse(range.GetValue("endStart"), out dtmp))
                                                                            lc.longitudeRange.endStart = dtmp;
                                                                    if (range.HasValue("endEnd"))
                                                                        if (double.TryParse(range.GetValue("endEnd"), out dtmp))
                                                                            lc.longitudeRange.endEnd = dtmp;
                                                                }
                                                                if (lcNode.HasValue("latitudeDouble"))
                                                                {
                                                                    if (bool.TryParse(lcNode.GetValue("latitudeDouble"), out btmp))
                                                                        lc.latitudeDouble = btmp;
                                                                }
                                                                if (lcNode.HasValue("minimumRealHeight"))
                                                                    if (double.TryParse(lcNode.GetValue("minimumRealHeight"), out dtmp))
                                                                        lc.minimumRealHeight = dtmp;
                                                                if (lcNode.HasValue("alterRealHeight"))
                                                                    if (double.TryParse(lcNode.GetValue("alterRealHeight"), out dtmp))
                                                                        lc.alterRealHeight = dtmp;
                                                                if (lcNode.HasValue("alterApparentHeight"))
                                                                    if (float.TryParse(lcNode.GetValue("alterApparentHeight"), out ftmp))
                                                                        lc.alterApparentHeight = ftmp;

                                                                break; // don't need to find any more
                                                            }
                                                        }
                                                        if (!found)
                                                            print("*RSS* LandClass " + lcName + " not found in PQSLandControl for PQS " + p.name + " of CB " + body.name);
                                                    }
                                                    mod.OnSetup();
                                                }

                                                // City
                                                if (modNode.name.Equals("PQSCity") && m.GetType().ToString().Equals(modNode.name))
                                                {
                                                    PQSCity mod = m as PQSCity;
                                                    if (modNode.HasValue("KEYname"))
                                                        if (!(mod.name.Equals(modNode.GetValue("KEYname"))))
                                                            continue;

                                                    if (modNode.HasValue("repositionRadial"))
                                                    {
                                                        try
                                                        {
                                                            mod.repositionRadial = KSPUtil.ParseVector3(modNode.GetValue("repositionRadial"));
                                                        }
                                                        catch(Exception e)
                                                        {
                                                            print("*RSS* Error parsing as vec3: original text: " + modNode.GetValue("repositionRadial") + " --- exception " + e.Message);
                                                        }
                                                    }
                                                    if (modNode.HasValue("latitude") && modNode.HasValue("longitude"))
                                                    {
                                                        double lat, lon;
                                                        double.TryParse(modNode.GetValue("latitude"), out lat);
                                                        double.TryParse(modNode.GetValue("longitude"), out lon);

                                                        mod.repositionRadial = LLAtoECEF(lat, lon, 0, body.Radius);
                                                    }
                                                    if (modNode.HasValue("reorientInitialUp"))
                                                    {
                                                        try
                                                        {
                                                            mod.reorientInitialUp = KSPUtil.ParseVector3(modNode.GetValue("reorientInitialUp"));
                                                        }
                                                        catch(Exception e)
                                                        {
                                                            print("*RSS* Error parsing as vec3: original text: " + modNode.GetValue("reorientInitialUp") + " --- exception " + e.Message);
                                                        }
                                                    }
                                                    if (modNode.HasValue("repositionToSphere"))
                                                    {
                                                        if (bool.TryParse(modNode.GetValue("repositionToSphere"), out btmp))
                                                            mod.repositionToSphere = btmp;
                                                    }
                                                    if (modNode.HasValue("repositionToSphereSurface"))
                                                    {
                                                        if (bool.TryParse(modNode.GetValue("repositionToSphereSurface"), out btmp))
                                                            mod.repositionToSphereSurface = btmp;
                                                    }
                                                    if (modNode.HasValue("repositionToSphereSurfaceAddHeight"))
                                                    {
                                                        if (bool.TryParse(modNode.GetValue("repositionToSphereSurfaceAddHeight"), out btmp))
                                                            mod.repositionToSphereSurfaceAddHeight = btmp;
                                                    }
                                                    if (modNode.HasValue("reorientToSphere"))
                                                    {
                                                        if (bool.TryParse(modNode.GetValue("reorientToSphere"), out btmp))
                                                            mod.reorientToSphere = btmp;
                                                    }
                                                    if (modNode.HasValue("repositionRadiusOffset"))
                                                    {
                                                        if (double.TryParse(modNode.GetValue("repositionRadiusOffset"), out dtmp))
                                                            mod.repositionRadiusOffset = dtmp;
                                                    }
                                                    if (modNode.HasValue("lodvisibleRangeMult"))
                                                    {
                                                        if (double.TryParse(modNode.GetValue("lodvisibleRangeMult"), out dtmp))
                                                            foreach (PQSCity.LODRange l in mod.lod)
                                                                l.visibleRange *= (float)dtmp;
                                                    }

                                                    if (modNode.HasValue("reorientFinalAngle"))
                                                    {
                                                        if (float.TryParse(modNode.GetValue("reorientFinalAngle"), out ftmp))
                                                            mod.reorientFinalAngle = ftmp;
                                                    }

                                                    mod.OnSetup();
                                                }
                                                // KSC Flat area
                                                if(modNode.name.Equals("PQSMod_MapDecalTangent")  && m.GetType().ToString().Equals(modNode.name))
                                                {
                                                    // thanks to asmi for this!
                                                    PQSMod_MapDecalTangent mod = m as PQSMod_MapDecalTangent;
                                                    if (modNode.HasValue("position"))
                                                    {
                                                        try
                                                        {
                                                            mod.position = KSPUtil.ParseVector3(modNode.GetValue("position"));
                                                        }
                                                        catch(Exception e)
                                                        {
                                                            print("*RSS* Error parsing as vec3: original text: " + modNode.GetValue("position") + " --- exception " + e.Message);
                                                        }
                                                    }
                                                    if (modNode.HasValue("radius"))
                                                    {
                                                        if (double.TryParse(modNode.GetValue("radius"), out dtmp))
                                                            mod.radius = dtmp;
                                                    }
                                                    if (modNode.HasValue("heightMapDeformity"))
                                                    {
                                                        if (double.TryParse(modNode.GetValue("heightMapDeformity"), out dtmp))
                                                            mod.heightMapDeformity = dtmp;
                                                    }
                                                    if (modNode.HasValue("absoluteOffset"))
                                                    {
                                                        if (double.TryParse(modNode.GetValue("absoluteOffset"), out dtmp))
                                                            mod.absoluteOffset = dtmp;
                                                    }

                                                    if (modNode.HasValue("absolute"))
                                                    {
                                                        if (bool.TryParse(modNode.GetValue("absolute"), out btmp))
                                                            mod.absolute = btmp;
                                                    }
                                                    if(modNode.HasValue("rescaleToRadius"))
                                                    {
                                                        mod.position *= (float)(body.Radius / origRadius);
                                                        mod.radius *= (body.Radius / origRadius);
                                                    }
                                                    if (modNode.HasValue("latitude") && modNode.HasValue("longitude"))
                                                    {
                                                        double lat, lon;
                                                        double.TryParse(modNode.GetValue("latitude"), out lat);
                                                        double.TryParse(modNode.GetValue("longitude"), out lon);

                                                        mod.position = LLAtoECEF(lat, lon, 0, body.Radius);
                                                    }
                                                    mod.OnSetup();
                                                }
                                                if (modNode.name.Equals("PQSMod_VertexColorMapBlend") && m.GetType().ToString().Equals(modNode.name))
                                                {
                                                    PQSMod_VertexColorMapBlend mod = m as PQSMod_VertexColorMapBlend;
                                                    if (modNode.HasValue("blend"))
                                                        if (float.TryParse(modNode.GetValue("blend"), out ftmp))
                                                            mod.blend = ftmp;

                                                    if (modNode.HasValue("order"))
                                                        if (int.TryParse(modNode.GetValue("order"), out itmp))
                                                            mod.order = itmp;

                                                    if (modNode.HasValue("vertexColorMap") && File.Exists(KSPUtil.ApplicationRootPath + modNode.GetValue("vertexColorMap")))
                                                    {
                                                        // for now don't destroy old map, use GC.
                                                        Texture2D map = new Texture2D(4, 4, TextureFormat.RGB24, false);
                                                        map.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + modNode.GetValue("vertexColorMap")));
                                                        mod.vertexColorMap = ScriptableObject.CreateInstance<MapSO>();
                                                        mod.vertexColorMap.CreateMap(MapSO.MapDepth.RGB, map);
                                                        DestroyImmediate(map);
                                                    }
                                                    else
                                                        print("*RSS* *ERROR* texture does not exist! " + modNode.GetValue("vertexColorMap"));

                                                }
                                                if (modNode.name.Equals("PQSMod_VertexColorSolid") && m.GetType().ToString().Equals(modNode.name))
                                                {
                                                    PQSMod_VertexColorSolid mod = m as PQSMod_VertexColorSolid;
                                                    if (modNode.HasValue("blend"))
                                                        if (float.TryParse(modNode.GetValue("blend"), out ftmp))
                                                            mod.blend = ftmp;

                                                    if (modNode.HasValue("order"))
                                                        if (int.TryParse(modNode.GetValue("order"), out itmp))
                                                            mod.order = itmp;

                                                    if (modNode.HasValue("color"))
                                                    {
                                                        try
                                                        {
                                                            Vector4 col = KSPUtil.ParseVector4(modNode.GetValue("color"));
                                                            Color c = new Color(col.x, col.y, col.z, col.w);
                                                            mod.color = c;
                                                        }
                                                        catch (Exception e)
                                                        {
                                                            print("*RSS* Error parsing as vec4: original text: " + modNode.GetValue("color") + " --- exception " + e.Message);
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                        if (pqsNode.HasNode("Add"))
                                        {
                                            foreach (ConfigNode modNode in pqsNode.GetNode("Add").nodes)
                                            {
                                                print("Adding " + modNode.name);
                                                guiExtra = "Add " + modNode.name;
                                                //OnGui();
                                                if (modNode.name.Equals("PQSMod_VertexColorMapBlend"))
                                                {
                                                    if (File.Exists(KSPUtil.ApplicationRootPath + modNode.GetValue("vertexColorMap")))
                                                    {
                                                        GameObject tempObj = new GameObject();

                                                        PQSMod_VertexColorMapBlend colorMap = (PQSMod_VertexColorMapBlend)tempObj.AddComponent(typeof(PQSMod_VertexColorMapBlend));

                                                        tempObj.transform.parent = p.gameObject.transform;
                                                        colorMap.sphere = p;

                                                        Texture2D map = new Texture2D(4, 4, TextureFormat.RGB24, false);
                                                        map.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + modNode.GetValue("vertexColorMap")));
                                                        colorMap.vertexColorMap = ScriptableObject.CreateInstance<MapSO>();
                                                        colorMap.vertexColorMap.CreateMap(MapSO.MapDepth.RGB, map);

                                                        colorMap.blend = 1.0f;
                                                        if (modNode.HasValue("blend"))
                                                            if (float.TryParse(modNode.GetValue("blend"), out ftmp))
                                                                colorMap.blend = ftmp;

                                                        colorMap.order = 9999993;
                                                        if (modNode.HasValue("order"))
                                                            if (int.TryParse(modNode.GetValue("order"), out itmp))
                                                                colorMap.order = itmp;

                                                        colorMap.modEnabled = true;
                                                        DestroyImmediate(map);
                                                    }
                                                    else
                                                        print("*RSS* *ERROR* texture does not exist! " + modNode.GetValue("vertexColorMap"));

                                                }
                                                if (modNode.name.Equals("PQSMod_VertexSimplexNoiseColor"))
                                                {
                                                    GameObject tempObj = new GameObject();
                                                    PQSMod_VertexSimplexNoiseColor vertColor = (PQSMod_VertexSimplexNoiseColor)tempObj.AddComponent(typeof(PQSMod_VertexSimplexNoiseColor));

                                                    tempObj.transform.parent = p.gameObject.transform;
                                                    vertColor.sphere = p;

                                                    vertColor.blend = 1.0f;
                                                    modNode.TryGetValue("blend", ref vertColor.blend);

                                                    vertColor.order = 9999994;
                                                    modNode.TryGetValue("order", ref vertColor.order);
                                                    modNode.TryGetValue("octaves", ref vertColor.octaves);
                                                    modNode.TryGetValue("persistence", ref vertColor.persistence);
                                                    modNode.TryGetValue("frequency", ref vertColor.frequency);
                                                    modNode.TryGetValue("colorStart", ref vertColor.colorStart);
                                                    modNode.TryGetValue("colorEnd", ref vertColor.colorEnd);
                                                    modNode.TryGetValue("frequency", ref vertColor.seed);

                                                    vertColor.modEnabled = true;
                                                }
                                                if (modNode.name.Equals("PQSMod_VertexColorSolid"))
                                                {
                                                    GameObject tempObj = new GameObject();

                                                    PQSMod_VertexColorSolid vertColor = (PQSMod_VertexColorSolid)tempObj.AddComponent(typeof(PQSMod_VertexColorSolid));

                                                    tempObj.transform.parent = p.gameObject.transform;
                                                    vertColor.sphere = p;

                                                    vertColor.blend = 1.0f;
                                                    if (modNode.HasValue("blend"))
                                                        if (float.TryParse(modNode.GetValue("blend"), out ftmp))
                                                            vertColor.blend = ftmp;

                                                    vertColor.order = 9999992;
                                                    if (modNode.HasValue("order"))
                                                        if (int.TryParse(modNode.GetValue("order"), out itmp))
                                                            vertColor.order = itmp;

                                                    if (modNode.HasValue("color"))
                                                    {
                                                        try
                                                        {
                                                            Vector4 col = KSPUtil.ParseVector4(modNode.GetValue("color"));
                                                            Color c = new Color(col.x, col.y, col.z, col.w);
                                                            vertColor.color = c;
                                                        }
                                                        catch(Exception e)
                                                        {
                                                            print("*RSS* Error parsing as vec4: original text: " + modNode.GetValue("color") + " --- exception " + e.Message);
                                                        }
                                                    }

                                                    vertColor.modEnabled = true;
                                                }
                                                if (modNode.name.Equals("PQSMod_VertexHeightMap"))
                                                {
                                                    if (File.Exists(KSPUtil.ApplicationRootPath + modNode.GetValue("heightMap")))
                                                    {
                                                        GameObject tempObj = new GameObject();

                                                        PQSMod_VertexHeightMap heightMap = (PQSMod_VertexHeightMap)tempObj.AddComponent(typeof(PQSMod_VertexHeightMap));
                                                        tempObj.transform.parent = p.gameObject.transform;
                                                        heightMap.sphere = p;

                                                        Texture2D map = new Texture2D(4, 4, TextureFormat.Alpha8, false);
                                                        map.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + modNode.GetValue("heightMap")));
                                                        heightMap.heightMap = ScriptableObject.CreateInstance<MapSO>();
                                                        heightMap.heightMap.CreateMap(MapSO.MapDepth.Greyscale, map);

                                                        heightMap.heightMapOffset = 0.0f;
                                                        modNode.TryGetValue("heightMapOffset", ref heightMap.heightMapOffset);

                                                        heightMap.heightMapDeformity = 100.0f;
                                                        modNode.TryGetValue("heightMapDeformity", ref heightMap.heightMapDeformity);

                                                        heightMap.scaleDeformityByRadius = false;
                                                        modNode.TryGetValue("scaleDeformityByRadius", ref heightMap.scaleDeformityByRadius);

                                                        heightMap.order = 10;
                                                        modNode.TryGetValue("order", ref heightMap.order);
                                                        heightMap.scaleDeformityByRadius = false;

                                                        heightMap.modEnabled = true;
                                                        DestroyImmediate(map);
                                                    }
                                                    else
                                                        print("*RSS* *ERROR* texture does not exist! " + modNode.GetValue("vertexColorMap"));

                                                }
                                            }
                                        }
                                        if (pqsNode.HasNode("Disable"))
                                        {
                                            foreach (ConfigNode modNode in pqsNode.GetNode("Disable").nodes)
                                            {
                                                string mName = modNode.name;
                                                print("Disabling " + mName);
                                                guiExtra = "Disable " + mName;
                                                //OnGui();
                                                if (mName.Equals("PQSLandControl"))
                                                {
                                                    List<PQSLandControl> modList = p.transform.GetComponentsInChildren<PQSLandControl>(true).ToList();
                                                    foreach (PQSLandControl m in modList)
                                                    {
                                                        m.modEnabled = false;
                                                    }
                                                }
                                                else
                                                {
                                                    int idx = 0;
                                                    bool doAll = false;
                                                    if (mName.Contains(","))
                                                    {
                                                        string[] splt = mName.Split(',');
                                                        mName = splt[0];
                                                        if(splt[1][0].Equals('*'))
                                                            doAll = true;
                                                        else
                                                            int.TryParse(splt[1], out idx);
                                                    }
                                                    print("Generic disable: " + mName + " with idx: " + idx + "; doAll: " + doAll);
                                                    int cur = 0;
                                                    foreach (var m in mods)
                                                    {
                                                        if (modNode.name.Equals(m.GetType().Name))
                                                        {
                                                            if (cur == idx || doAll)
                                                            {
                                                                m.GetType().GetField("modEnabled").SetValue(m, false);
                                                                print("Found and disabled " + m.GetType().Name);
                                                            }
                                                            else
                                                                cur++;
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    try
                                    {
                                        print("Rebuilding sphere " + p.name);
                                        guiExtra = "Rebuilding " + p.name;
                                        //OnGui();
                                        //p.ResetSphere();
                                        p.RebuildSphere();
                                    }
                                    catch (Exception e)
                                    {
                                        print("Rebuild sphere for " + node.name + " failed: " + e.Message);
                                    }
                                }
                            }
                        }
                        guiExtra = "";
                        //OnGui();
                        #endregion

                        #region ScaledSpace
                        // Scaled space
                        Transform scaledSpaceTransform = null;
                        Transform atmo = null;
                        guiMinor = "Scaled Space";
                        //OnGui();
                        if (ScaledSpace.Instance != null)
                        {
                            float SSTScale = 1.0f;
                            node.TryGetValue("SSTScale", ref SSTScale);
                            foreach (Transform t in ScaledSpace.Instance.scaledSpaceTransforms)
                            {
                                if (t.name.Equals(node.name))
                                {
                                    print("*RSS* Found scaledspace transform for " + t.name + ", scale " + t.localScale.x);
                                    scaledSpaceTransform = t;
                                    // replace
                                    int replaceColor = 0;
                                    string path = "";
                                    if (node.HasValue("SSColor"))
                                    {
                                        replaceColor = 1;
                                        path = node.GetValue("SSColor");
                                    }
                                    if (node.HasValue("SSColor32"))
                                    {
                                        replaceColor = 2;
                                        path = node.GetValue("SSColor32");
                                    }
                                    if (replaceColor > 0)
                                    {
                                        guiExtra = "Color map";
                                        //OnGui();
                                        if (File.Exists(KSPUtil.ApplicationRootPath + path))
                                        {
                                            Texture2D map = new Texture2D(4, 4, replaceColor == 1 ? TextureFormat.RGB24: TextureFormat.RGBA32, true);
                                            map.LoadImage(System.IO.File.ReadAllBytes(path));
                                            map.Compress(true);
                                            map.Apply(true, true);
                                            Texture oldColor = t.gameObject.renderer.material.GetTexture("_MainTex");
                                            foreach(Material m in Resources.FindObjectsOfTypeAll(typeof(Material)))
                                            {
                                                if(m.GetTexture("_MainTex") == oldColor)
                                                    m.SetTexture("_MainTex", map);
                                            }
                                            DestroyImmediate(oldColor);
                                            // shouldn't be needed - t.gameObject.renderer.material.SetTexture("_MainTex", map);
                                        }
                                        else
                                            print("*RSS* *ERROR* texture does not exist! " + path);

                                        guiExtra = "";
                                        //OnGui();
                                    }
                                    if (node.HasValue("SSBump"))
                                    {
                                        if (File.Exists(KSPUtil.ApplicationRootPath + node.GetValue("SSBump")))
                                        {
                                            guiExtra = "Normal Map";
                                            //OnGui();
                                            Texture2D map = new Texture2D(4, 4, TextureFormat.RGB24, true);
                                            map.LoadImage(System.IO.File.ReadAllBytes(node.GetValue("SSBump")));
                                            if(compressNormals)
                                                map.Compress(true);
                                            map.Apply(true, true);
                                            Texture oldBump = t.gameObject.renderer.material.GetTexture("_BumpMap");
                                            if (oldBump != null)
                                            {
                                                foreach (Material m in Resources.FindObjectsOfTypeAll(typeof(Material)))
                                                {
                                                    if (m.GetTexture("_BumpMap") == oldBump)
                                                        m.SetTexture("_BumpMap", map);
                                                }
                                                DestroyImmediate(oldBump);
                                            }
                                        }
                                        else
                                            print("*RSS* *ERROR* texture does not exist! " + node.GetValue("SSBump"));

                                        guiExtra = "";
                                        //OnGui();
                                    }
                                    /*if (t.gameObject.renderer.material.GetTexture("_rimColorRamp") != null)
                                    {
                                        try
                                        {
                                            System.IO.File.WriteAllBytes(KSPUtil.ApplicationRootPath + body.name + "Ramp.png", ((Texture2D)t.gameObject.renderer.material.GetTexture("_rimColorRamp")).EncodeToPNG());
                                        }
                                        catch (Exception e)
                                        {
                                            print("*RSS* Failed to get/write ramp for " + body.name + ", exception: " + e.Message);
                                        }
                                    }*/
                                    if (node.HasValue("SSRampRef"))
                                    {
                                        //if (t.gameObject.renderer.material.GetTexture("_rimColorRamp") != null)
                                        // for now try setting anyway.
                                        Texture map = null;
                                        map = GetRamp(node.GetValue("SSRampRef"));
                                        if(map != null)
                                            t.gameObject.renderer.material.SetTexture("_rimColorRamp", map);
                                        else
                                            print("*RSS* *ERROR* texture does not exist! " + node.GetValue("SSRamp"));
                                    }
                                    if (node.HasValue("SSRamp"))
                                    {
                                        Texture2D map = GameDatabase.Instance.GetTexture(node.GetValue("SSRamp"), false);
                                        bool localLoad = false;
                                        if (map == null)
                                        {
                                            if (File.Exists(KSPUtil.ApplicationRootPath + node.GetValue("SSRamp")))
                                            {
                                                map.LoadImage(System.IO.File.ReadAllBytes(node.GetValue("SSRamp")));
                                                map.Compress(true);
                                                map.Apply(true, true);
                                                localLoad = true;
                                            }
                                        }
                                        if (map != null)
                                        {
                                            if (t.gameObject.renderer.material.GetTexture("_rimColorRamp") != null)
                                                t.gameObject.renderer.material.SetTexture("_rimColorRamp", map);
                                            else
                                                if (localLoad)
                                                    DestroyImmediate(map);
                                        }
                                        else
                                            print("*RSS* *ERROR* texture does not exist! " + node.GetValue("SSRamp"));
                                    }
                                    if (node.HasValue("SSSpec"))
                                    {
                                        try
                                        {
                                            Vector4 col = KSPUtil.ParseVector4(node.GetValue("SSSpec"));
                                            Color c = new Color(col.x, col.y, col.z, col.w);
                                            t.gameObject.renderer.material.SetColor("_SpecColor", c);
                                        }
                                        catch(Exception e)
                                        {
                                            print("*RSS* Error reading SSSpec as color4: original text: " + node.GetValue("SSSpec") + " --- exception " + e.Message);
                                        }
                                    }

                                    // Fix mesh
                                    bool rescale = true;
                                    bool doWrapHere = doWrap;
                                    node.TryGetValue("wrap", ref doWrapHere);
                                    bool sphereVal = spheresOnly;
                                    bool sphereHere = node.TryGetValue("useSphericalSSM", ref sphereVal);
                                    float origLocalScale = t.localScale.x; // assume uniform scale
                                    if (body.pqsController != null && doWrapHere)
                                    {
                                        MeshFilter m = (MeshFilter)t.GetComponent(typeof(MeshFilter));
                                        if (m == null || m.mesh == null)
                                        {
                                            print("*RSS* Failure getting SSM for " + body.pqsController.name + ": mesh is null");
                                        }
                                        else
                                        {
                                            guiExtra = "Mesh";
                                            //OnGui();
                                            if (sphereVal)
                                            {
                                                Mesh tMesh = new Mesh();
                                                Utils.CopyMesh(joolMesh.mesh, tMesh);
                                                float scaleFactor = (float)(origRadius / (1000 * 6000 * (double)origLocalScale)); // scale mesh such that it will end up right.
                                                // (need to scale it such that in the end localScale will = origLocalScale * radius/origRadius)
                                                print("*RSS* using Jool scaledspace mesh (spherical) for body " + body.pqsController.name + ". Vertex Scale " + scaleFactor);
                                                Utils.ScaleVerts(tMesh, scaleFactor);
                                                tMesh.RecalculateBounds();
                                                m.mesh = tMesh;
                                                // do normal rescaling below.
                                            }
                                            else
                                            {
                                                // **** No longer exporting and importing
                                                // Now I just do everything except tangents each time. Tangents don't seem necessary to fix, and
                                                // the rest is fast enough...and something in .24/64 broke importing for *some* planets. WEIRD.
                                                char sep = System.IO.Path.DirectorySeparatorChar;
                                                string filePath = KSPUtil.ApplicationRootPath + "GameData" + sep + "RealSolarSystem" + sep + "Plugins"
                                                            + sep + "PluginData" + sep + t.name;

                                                filePath += ".obj";

                                                try
                                                {
                                                    print("*RSS* wrapping ScaledSpace mesh " + m.name + " to PQS " + body.pqsController.name);
                                                    ProfileTimer.Push("Wrap time for " + body.name);
                                                    Mesh tMesh = new Mesh();
                                                    Utils.CopyMesh(joolMesh.mesh, tMesh);
                                                    float scaleFactor = (float)(origRadius / (1000 * 6000 * (double)origLocalScale)); // scale mesh such that it will end up right.
                                                    // (need to scale it such that in the end localScale will = origLocalScale * radius/origRadius)
                                                    Utils.MatchVerts(tMesh, body.pqsController, body.ocean ? body.Radius : 0.0, scaleFactor);
                                                    //ProfileTimer.Push("Recalc Normals");
                                                    tMesh.RecalculateNormals();
                                                    //ProfileTimer.Pop("Recalc Normals");
                                                    //ObjLib.UpdateTangents(tMesh);
                                                    //print("*RSS* wrapped.");
                                                    /*try
                                                    {
                                                        ObjLib.MeshToFile(m, filePath);
                                                    }
                                                    catch (Exception e)
                                                    {
                                                        print("*RSS* Exception saving wrapped mesh " + filePath + ": " + e.Message);
                                                    }*/
                                                    //print("*RSS*: Done wrapping and exporting. Setting scale");

                                                    tMesh.RecalculateBounds();
                                                    m.mesh = tMesh;
                                                    // do normal rescaling below.
                                                    ProfileTimer.Pop("Wrap time for " + body.name);
                                                }
                                                catch (Exception e)
                                                {
                                                    print("*RSS* Exception wrapping: " + e.Message);
                                                }
                                            }
                                            guiExtra = "";
                                            //OnGui();
                                        }
                                        atmo = t.FindChild("Atmosphere");
                                    }
                                    guiExtra = "";
                                    //OnGui();
                                    if (rescale)
                                    {
                                        float scaleFactor = (float)((double)origLocalScale * body.Radius / origRadius * SSTScale);
                                        t.localScale = new Vector3(scaleFactor, scaleFactor, scaleFactor);
                                    }
                                    else
                                    {
                                        // rescale only atmo
                                        if (atmo != null)
                                        {
                                            print("*RSS* found atmo transform for " + node.name);
                                            float scaleFactor = SSAtmoScale; // default to global default
                                            if (!node.TryGetValue("SSAtmoScale", ref scaleFactor)) // if no override multiplier
                                            {
                                                if (defaultAtmoScale) // use stock KSP multiplier
                                                    scaleFactor *= 1.025f;
                                                else // or use atmosphere height-dependent multiplier
                                                    scaleFactor *= (float)((body.Radius + body.maxAtmosphereAltitude) / body.Radius);
                                            }
                                            scaleFactor *= origLocalScale / t.localScale.x * (float)(body.Radius / origRadius); // since our parent transform changed, we no longer are the same scale as the planet.
                                            atmo.localScale = new Vector3(scaleFactor, scaleFactor, scaleFactor);
                                            print("*RSS* final scale of atmo for " + body.name + " in scaledspace: " + atmo.localScale.x);
                                        }
                                    }
                                    print("*RSS* final scale of " + body.name + " in scaledspace: " + t.localScale.x);
                                }
                            }
                        }
                        #region AtmosphereFromGround
                        foreach (AtmosphereFromGround ag in Resources.FindObjectsOfTypeAll(typeof(AtmosphereFromGround)))
                        {
                            //print("*RSS* Found AG " + ag.name + " " + (ag.tag == null ? "" : ag.tag) + ". Planet " + (ag.planet == null ? "NULL" : ag.planet.name));
                            if (ag != null && ag.planet != null)
                            {
                                // generalized version of Starwaster's code. Thanks Starwaster!
                                if (ag.planet.name.Equals(node.name))
                                {
                                    print("Found atmo for " + node.name + ": " + ag.name + ", has localScale " + ag.transform.localScale.x);
                                    UpdateAFG(body, ag, node.GetNode("AtmosphereFromGround"));
                                    print("Atmo updated");
                                }
                            }
                        }
                        #endregion
                        #endregion

                        #region Science
                        // Science
                        if (node.HasNode("CelestialBodyScienceParams"))
                        {
                            guiMinor = "Science";
                            //OnGui();
                            ConfigNode spNode = node.GetNode("CelestialBodyScienceParams");
                            if (body.scienceValues != null)
                            {
                                foreach (ConfigNode.Value val in spNode.values)
                                {
                                    // meh, for now hard-code it. Saves worry of GIGO.
                                    /*if(body.scienceValues.GetType().GetField(val.name) != null)
                                        if(float.TryParse(val.value, out ftmp))
                                            body.scienceValues.GetType().GetField(val.name).SetValue(*/
                                    spNode.TryGetValue("LandedDataValue", ref body.scienceValues.LandedDataValue);
                                    spNode.TryGetValue("SplashedDataValue", ref body.scienceValues.SplashedDataValue);
                                    spNode.TryGetValue("FlyingLowDataValue", ref body.scienceValues.FlyingLowDataValue);
                                    spNode.TryGetValue("FlyingHighDataValue", ref body.scienceValues.FlyingHighDataValue);
                                    spNode.TryGetValue("InSpaceLowDataValue", ref body.scienceValues.InSpaceLowDataValue);
                                    spNode.TryGetValue("InSpaceHighDataValue", ref body.scienceValues.InSpaceHighDataValue);
                                    spNode.TryGetValue("RecoveryValue", ref body.scienceValues.RecoveryValue);
                                    spNode.TryGetValue("flyingAltitudeThreshold", ref body.scienceValues.flyingAltitudeThreshold);
                                    spNode.TryGetValue("spaceAltitudeThreshold", ref body.scienceValues.spaceAltitudeThreshold);
                                }
                            }
                            guiMinor = "";
                            //OnGui();
                        }
                        #endregion

                        #region Export
                        // texture rebuild
                        if (node.HasNode("Export"))
                        {
                            try
                            {
                                guiMinor = "Exporting maps";
                                //OnGui();
                                int res = 2048;
                                bool ocean = false;
                                Color oceanColor;
                                double maxHeight, oceanHeight;
                                PQS bodyPQS = null;
                                foreach (PQS p in Resources.FindObjectsOfTypeAll(typeof(PQS)))
                                    if (p.name.Equals(body.name))
                                    {
                                        bodyPQS = p;
                                        break;
                                    }
                                if (bodyPQS != null)
                                {
                                    maxHeight = bodyPQS.radiusDelta * 0.5;
                                    oceanHeight = 0;
                                    ocean = body.ocean;
                                    oceanColor = new Color(0.1255f, 0.22353f, 0.35683f);
                                    ConfigNode exportNode = node.GetNode("Export");
                                    if (exportNode.HasValue("resolution"))
                                    {
                                        if (int.TryParse(exportNode.GetValue("resolution"), out itmp))
                                            res = itmp;
                                    }
                                    if (exportNode.HasValue("maxHeight"))
                                    {
                                        if (double.TryParse(exportNode.GetValue("maxHeight"), out dtmp))
                                            maxHeight = dtmp;
                                    }
                                    if (exportNode.HasValue("ocean"))
                                    {
                                        if (bool.TryParse(exportNode.GetValue("ocean"), out btmp))
                                            ocean = btmp;
                                    }
                                    if (exportNode.HasValue("oceanHeight"))
                                    {
                                        if (double.TryParse(exportNode.GetValue("oceanHeight"), out dtmp))
                                            oceanHeight = dtmp;
                                    }
                                    if (exportNode.HasValue("oceanColor"))
                                    {
                                        try
                                        {
                                            ocean = true;
                                            Vector4 col = KSPUtil.ParseVector4(exportNode.GetValue("oceanColor"));
                                            oceanColor = new Color(col.x, col.y, col.z, col.w);
                                        }
                                        catch(Exception e)
                                        {
                                            print("*RSS* Error parsing as col3: original text: " + exportNode.GetValue("oceanColor") + " --- exception " + e.Message);
                                        }
                                    }
                                    Texture2D[] outputMaps = bodyPQS.CreateMaps(res, maxHeight, ocean, oceanHeight, oceanColor);
                                    System.IO.File.WriteAllBytes(KSPUtil.ApplicationRootPath + body.name + "1.png", outputMaps[0].EncodeToPNG());
                                    System.IO.File.WriteAllBytes(KSPUtil.ApplicationRootPath + body.name + "2.png", outputMaps[1].EncodeToPNG());
                                }
                            }
                            catch (Exception e)
                            {
                                print("Export for " + node.name + " failed: " + e.Message);
                            }
                            guiMinor = "";
                            //OnGui();
                        }
                        #endregion
                        print("*RSS* Memory now " + GC.GetTotalMemory(true)); // Free memory
                    }
                }
            }
            // do final update for all SoIs and hillSpheres and periods
            guiMajorBase = "Fixing orbit: ";
            //OnGui();
            foreach (CelestialBody body in FlightGlobals.fetch.bodies)
            {
                try
                {
                    guiMajor = guiMajorBase + body.name;
                    //OnGui();
                    if (body.orbitDriver != null)
                    {
                        if (body.referenceBody != null)
                        {
                            body.hillSphere = body.orbit.semiMajorAxis * (1.0 - body.orbit.eccentricity) * Math.Pow(body.Mass / body.orbit.referenceBody.Mass, 1 / 3);
                            body.sphereOfInfluence = body.orbit.semiMajorAxis * Math.Pow(body.Mass / body.orbit.referenceBody.Mass, 0.4);
                            if (body.sphereOfInfluence < body.Radius * 1.5 || body.sphereOfInfluence < body.Radius + 20000.0)
                                body.sphereOfInfluence = Math.Max(body.Radius * 1.5, body.Radius + 20000.0); // sanity check

                            body.orbit.period = 2 * Math.PI * Math.Sqrt(Math.Pow(body.orbit.semiMajorAxis, 2) / 6.674E-11 * body.orbit.semiMajorAxis / (body.Mass + body.referenceBody.Mass));
                            if (body.orbit.eccentricity <= 1.0)
                            {
                                body.orbit.meanAnomaly = body.orbit.meanAnomalyAtEpoch;
                                body.orbit.orbitPercent = body.orbit.meanAnomalyAtEpoch / (Math.PI * 2);
                                body.orbit.ObTAtEpoch = body.orbit.orbitPercent * body.orbit.period;
                            }
                            else
                            {
                                // ignores this body's own mass for this one...
                                body.orbit.meanAnomaly = body.orbit.meanAnomalyAtEpoch;
                                body.orbit.ObT = Math.Pow(Math.Pow(Math.Abs(body.orbit.semiMajorAxis), 3.0) / body.orbit.referenceBody.gravParameter, 0.5) * body.orbit.meanAnomaly;
                                body.orbit.ObTAtEpoch = body.orbit.ObT;
                            }
                        }
                        else
                        {
                            body.sphereOfInfluence = double.PositiveInfinity;
                            body.hillSphere = double.PositiveInfinity;
                        }
                        // doesn't seem needed - body.orbitDriver.QueuedUpdate = true;
                    }
                    try
                    {
                        body.CBUpdate();
                    }
                    catch (Exception e)
                    {
                        print("CBUpdate for " + body.name + " failed: " + e.Message);
                    }
                }
                catch (Exception e)
                {
                    print("Final update bodies failed: " + e.Message);
                }
            }
            print("*RSS* Done loading!");
            guiExtra = "";
            guiMinor = "";
            guiMajor = "Done!";
            doneRSS = true;
        }
示例#27
0
    IEnumerator ScreenshotEncode(GameObject prom)
    {
        // wait for graphics to render
        yield return new WaitForEndOfFrame();

        // create a texture to pass to encoding
        //Texture2D texture = new Texture2D(512, 418, TextureFormat.RGB24, false);
        //Debug.Log ("width: "+Screen.width/2+", height: "+(Screen.height/2));
        //Texture2D texture = new Texture2D(Screen.width-100, Screen.height, TextureFormat.RGB24, false);
        Texture2D texture = new Texture2D(320, 250, TextureFormat.RGB24, false);
         		//Texture2D texture = new Texture2D((int)Mathf.Round ((float)(Screen.width/2)), (int)Mathf.Round ((float)(Screen.height/1.837)), TextureFormat.RGB24, false);
        // put buffer into texture
        texture.ReadPixels(new Rect(145, 250, 320, 250), 0, 0);
        //texture.ReadPixels(new Rect(460, 170, 512, 418), 0, 0);
        //texture.ReadPixels (new Rect(50, 0, Screen.width-50, Screen.height), 0,0);
        //texture.ReadPixels(new Rect((int)Mathf.Round ((float)(Screen.width/2.226)), (int)Mathf.Round ((float)(Screen.height/4.517)), (int)Mathf.Round ((float)(Screen.width/2)), (int)Mathf.Round ((float)(Screen.height/1.837))), 0, 0);
        texture.Apply();
         		//cameraOverlay.SetActive (true);
        // split the process up--ReadPixels() and the GetPixels() call inside of the encoder are both pretty heavy
        yield return 0;

        byte[] bytes = texture.EncodeToPNG();

        // save our test image (could also upload to WWW)
        if(prom != null)
        {
            File.WriteAllBytes(Application.dataPath + "/../pictures/promi-" + promCount + ".png", bytes);
            promCount++;
            //texture.Resize (100,100);
            texture.Compress (false);
            //textures.Add (texture);
            promiTable.Add (prom.name, texture);
            found.Add (prom.name);
            currNewsPaper = (GameObject)newsTable[prom.name];
            currNewsPaper.SetActive(true);
            currTexture = texture;
            Debug.Log (prom.name + "_news");
            newsPaper = true;
            //currTime = Time.frameCount;
            currTime = Time.time;
        }
        else
        {
            File.WriteAllBytes(Application.dataPath + "/../pictures/picture-" + count + ".png", bytes);
            count++;
            DestroyObject( texture );
        }

        // Added by Karl. - Tell unity to delete the texture, by default it seems to keep hold of it and memory crashes will occur after too many screenshots.
        //DestroyObject( texture );

        //Debug.Log( Application.dataPath + "/../testscreen-" + count + ".png" );
    }
示例#28
0
        public bool Push(string key, Texture2D texture)
        {
            if (string.IsNullOrEmpty(key))
            {
                return(true);
            }

            if (texture == null)
            {
                return(true);
            }

            for (int i = 0; i < m_sprites.Count; i++)
            {
                m_sprites[i].index = i;
                m_sprites[i].color = m_texture.GetPixels((int)m_sprites[i].rect.x, (int)m_sprites[i].rect.y, (int)m_sprites[i].rect.width, (int)m_sprites[i].rect.height);
            }

            m_sprites.Add(new DynamicSprite()
            {
                key   = key,
                index = -1,
                rect  = new Rect(0, 0, texture.width, texture.height),
                color = texture.GetPixels(),
            });

            m_packer.reset(width, height, padding);

            for (int i = 0; i < m_sprites.Count; i++)
            {
                m_packer.insertRectangle((int)m_sprites[i].rect.width, (int)m_sprites[i].rect.height, m_sprites[i].index);
            }

            int count = m_packer.packRectangles();

            enough = m_sprites.Count > count;

            if (enough)
            {
                m_sprites.RemoveAt(m_sprites.FindIndex(x => x.key == key));

                for (int i = 0; i < m_sprites.Count; i++)
                {
                    m_sprites[i].color = null;
                }

                return(false);
            }
            else
            {
                if (texture != null)
                {
                    texture = null;
                }

                if (m_texture.format != TextureFormat.RGBA32)
                {
                    Object.Destroy(m_texture);

                    m_texture = new Texture2D(width, height, TextureFormat.RGBA32, false);
                }
                m_texture.SetPixels32(m_color);

                IntegerRectangle rect = new IntegerRectangle();

                Color32[] color;

                int index, id, size;

                for (int i = 0; i < count; i++)
                {
                    rect = m_packer.getRectangle(i, rect);

                    id = m_packer.getRectangleId(i);

                    index = m_sprites.FindIndex(x => x.index == id);

                    if (index != -1)
                    {
                        m_sprites[index].rect = new Rect(rect.x, rect.y, rect.width, rect.height);

                        color = new Color32[m_sprites[index].color.Length];

                        for (int j = 0; j < m_sprites[index].color.Length; j++)
                        {
                            color[j] = m_sprites[index].color[j];
                        }
                    }
                    else
                    {
                        size = rect.width * rect.height;

                        color = new Color32[size];

                        for (int j = 0; j < size; j++)
                        {
                            color[j] = Color.black;
                        }
                    }
                    m_texture.SetPixels32(rect.x, rect.y, rect.width, rect.height, color);
                }

                for (int i = 0; i < m_sprites.Count; i++)
                {
                    m_sprites[i].color = null;
                }

                if (compress)
                {
                    m_texture.Compress(true);
                }

                m_texture.Apply();

                return(true);
            }
        }
示例#29
0
 // atlas
 public static Texture2D MakeTexture(Texture2D sourceTexture, RTPGlossBaked[] tilesData)
 {
     Texture2D targetTexture=new Texture2D(sourceTexture.width, sourceTexture.height, TextureFormat.ARGB32, true);
     for(int tile=0; tile<4; tile++) {
         int halfSize=sourceTexture.width>>1;
         int bx=(tile%2)*halfSize;
         int by=((tile%4)<2) ? 0 : halfSize;
         Color[] prevCols=sourceTexture.GetPixels(bx,by,halfSize,halfSize,0);
         // use gloss shaping for MIP0 (reszta już przygotowana do skopiowania)
         for(int i=0; i<prevCols.Length; i++) {
             float glossiness=Mathf.Clamp01(prevCols[i].a*tilesData[tile].gloss_mult);
             float gloss_shaped=glossiness;
             float gloss_shaped_inv=1-glossiness;
             gloss_shaped=gloss_shaped*gloss_shaped*gloss_shaped;
             gloss_shaped_inv=gloss_shaped_inv*gloss_shaped_inv*gloss_shaped_inv;
             float gls=Mathf.Lerp(gloss_shaped, 1-gloss_shaped_inv, tilesData[tile].gloss_shaping);
             gls=Mathf.Clamp01(gls);
             prevCols[i].a=gls;
         }
         targetTexture.SetPixels(bx,by,halfSize,halfSize,prevCols,0);
         for(int mip=1; mip<sourceTexture.mipmapCount-1; mip++) {
             int curSize=(targetTexture.width>>(mip+1));
             Color[] cols=new Color[curSize * curSize];
             byte[] glossMIPData=tilesData[tile].GetGlossMipLevel(mip);
             int len=glossMIPData.Length;
             for(int i=0; i<len; i++) {
                 int ix=i%curSize;
                 int iy=i/curSize;
                 int idx0=iy*curSize*4+ix*2;
                 int idx1=idx0+1;
                 int idx2=idx0+curSize*2;
                 int idx3=idx2+1;
                 // musimy ręcznie obliczyć kolejne MIPmapy koloru, GetPixels(dla miplevel>0) potrafi wywalić Unity (coś z przydziałem pamięci poważnie zaczyna szwankować)
                 cols[i].r=((prevCols[idx0].r+prevCols[idx1].r+prevCols[idx2].r+prevCols[idx3].r)/4);
                 cols[i].g=((prevCols[idx0].g+prevCols[idx1].g+prevCols[idx2].g+prevCols[idx3].g)/4);
                 cols[i].b=((prevCols[idx0].b+prevCols[idx1].b+prevCols[idx2].b+prevCols[idx3].b)/4);
                 cols[i].a=glossMIPData[i]/255.0f;
             }
             prevCols=cols;
             bx=bx>>1;
             by=by>>1;
             halfSize=halfSize>>1;
             targetTexture.SetPixels(bx,by,halfSize,halfSize,cols, mip);
         }
     }
     targetTexture.Apply(false, false);
     targetTexture.Compress(true);
     targetTexture.Apply(false, true);
     targetTexture.wrapMode=sourceTexture.wrapMode;
     targetTexture.anisoLevel=sourceTexture.anisoLevel;
     targetTexture.filterMode=sourceTexture.filterMode;
     return targetTexture;
 }
示例#30
0
 // pojedyncza tekstura
 public Texture2D MakeTexture(Texture2D sourceTexture)
 {
     Texture2D targetTexture=new Texture2D(sourceTexture.width, sourceTexture.height, TextureFormat.ARGB32, true);
     Color32[] prevCols=sourceTexture.GetPixels32(0);
     // use gloss shaping for MIP0 (reszta już przygotowana do skopiowania)
     for(int i=0; i<prevCols.Length; i++) {
         float glossiness=Mathf.Clamp01(prevCols[i].a/255.0f*gloss_mult);
         float gloss_shaped=glossiness;
         float gloss_shaped_inv=1-glossiness;
         gloss_shaped=gloss_shaped*gloss_shaped*gloss_shaped;
         gloss_shaped_inv=gloss_shaped_inv*gloss_shaped_inv*gloss_shaped_inv;
         float gls=Mathf.Lerp(gloss_shaped, 1-gloss_shaped_inv, gloss_shaping);
         gls=Mathf.Clamp01(gls);
         prevCols[i].a=(byte)(gls*255.0f);
     }
     targetTexture.SetPixels32(prevCols, 0);
     for(int mip=1; mip<sourceTexture.mipmapCount; mip++) {
         int curSize=(targetTexture.width>>mip);
         Color32[] cols=new Color32[curSize * curSize];
         byte[] glossMIPData=GetGlossMipLevel(mip);
         int len=glossMIPData.Length;
         for(int i=0; i<len; i++) {
             int ix=i%curSize;
             int iy=i/curSize;
             int idx0=iy*curSize*4+ix*2;
             int idx1=idx0+1;
             int idx2=idx0+curSize*2;
             int idx3=idx2+1;
             // musimy ręcznie obliczyć kolejne MIPmapy koloru, GetPixels(dla miplevel>0) potrafi wywalić Unity (coś z przydziałem pamięci poważnie zaczyna szwankować)
             cols[i].r=(byte)((prevCols[idx0].r+prevCols[idx1].r+prevCols[idx2].r+prevCols[idx3].r)>>2);
             cols[i].g=(byte)((prevCols[idx0].g+prevCols[idx1].g+prevCols[idx2].g+prevCols[idx3].g)>>2);
             cols[i].b=(byte)((prevCols[idx0].b+prevCols[idx1].b+prevCols[idx2].b+prevCols[idx3].b)>>2);
             cols[i].a=glossMIPData[i];
         }
         prevCols=cols;
         targetTexture.SetPixels32(cols, mip);
     }
     targetTexture.Apply(false, false);
     targetTexture.Compress(true);
     targetTexture.Apply(false, true);
     targetTexture.wrapMode=sourceTexture.wrapMode;
     targetTexture.anisoLevel=sourceTexture.anisoLevel;
     targetTexture.filterMode=sourceTexture.filterMode;
     return targetTexture;
 }
        public static PSystemBody GenerateSystemBody(PSystem system, PSystemBody parent, String name, Orbit orbit = null)
        {
            PSystemBody Jool = Utility.FindBody (system.rootBody, "Jool");  // Need the geosphere for scaled version
            PSystemBody Laythe = Utility.FindBody (system.rootBody, "Laythe"); // Need pqs and ocean definitions

            //Utility.DumpObject (Laythe.celestialBody, " Laythe Celestial Body ");
            //Utility.DumpObject (Laythe.pqsVersion, " Laythe PQS ");
            //Transform laytheOcean = Utility.FindInChildren (Laythe.pqsVersion.transform, "LaytheOcean");
            //Utility.DumpObject (laytheOcean.GetComponent<PQS> (), " Laythe Ocean PQS ");

            // AddBody makes the GameObject and stuff. It also attaches it to the system and parent.
            PSystemBody body = system.AddBody (parent);

            // set up the various parameters
            body.name = name;
            body.flightGlobalsIndex = 100;

            // Some parameters of the celestialBody, which represents the actual planet...
            // PSystemBody is more of a container that associates the planet with its orbit
            // and position in the planetary system, etc.
            body.celestialBody.bodyName               = name;
            body.celestialBody.bodyDescription        = "Merciful Kod, this thing just APPEARED! And unlike last time, it wasn't bird droppings on the telescope.";
            body.celestialBody.Radius                 = 320000;
            //body.celestialBody.Radius                 = 3380100;
            body.celestialBody.GeeASL                 = 0.3;
            //body.celestialBody.Mass                   = 6.4185E+23;
            body.celestialBody.Mass                   = 4.5154812E+21;
            body.celestialBody.timeWarpAltitudeLimits = (float[])Laythe.celestialBody.timeWarpAltitudeLimits.Clone();
            body.celestialBody.rotationPeriod         = 88642.6848;
            body.celestialBody.rotates                = true;
            body.celestialBody.BiomeMap               = GenerateCBAttributeMapSO(name);//Dres.celestialBody.BiomeMap;//
            body.celestialBody.scienceValues          = Laythe.celestialBody.scienceValues;
            body.celestialBody.ocean                  = false;

            // Presumably true of Kerbin. I do not know what the consequences are of messing with this exactly.
            // I think this just affects where the Planetarium/Tracking station starts.
            body.celestialBody.isHomeWorld            = false;

            // Setup the orbit of "Kopernicus."  The "Orbit" class actually is built to support serialization straight
            // from Squad, so storing these to files (and loading them) will be pretty easy.
            body.orbitRenderer.orbitColor             = Color.magenta;
            body.orbitDriver.celestialBody            = body.celestialBody;
            body.orbitDriver.updateMode               = OrbitDriver.UpdateMode.UPDATE;
            if (orbit == null)
                body.orbitDriver.orbit = new Orbit (0.0, 0.0, 47500000000, 0, 0, 0, 0, system.rootBody.celestialBody);
            else
                body.orbitDriver.orbit = orbit;

            #region PSystemBody.pqsVersion generation

            // Create the PQS controller game object for Kopernicus
            GameObject controllerRoot       = new GameObject(name);
            controllerRoot.layer            = Constants.GameLayers.LocalSpace;
            controllerRoot.transform.parent = Utility.Deactivator;

            // Create the PQS object and pull all the values from Dres (has some future proofing i guess? adapts to PQS changes)
            body.pqsVersion = controllerRoot.AddComponent<PQS>();
            Utility.CopyObjectFields(Laythe.pqsVersion, body.pqsVersion);
            //body.pqsVersion.surfaceMaterial = new PQSProjectionSurfaceQuad();
            //body.pqsVersion.fallbackMaterial = new PQSProjectionFallback();
            body.pqsVersion.surfaceMaterial = new PQSProjectionAerialQuadRelative(Laythe.pqsVersion.surfaceMaterial); // use until we determine all the functions of the shader textures
            body.pqsVersion.fallbackMaterial = new PQSProjectionFallback(Laythe.pqsVersion.fallbackMaterial);
            body.pqsVersion.radius = body.celestialBody.Radius;
            body.pqsVersion.mapOcean = false;

            // Debug
            Utility.DumpObjectProperties(body.pqsVersion.surfaceMaterial, " Surface Material ");
            Utility.DumpObjectProperties(body.pqsVersion.fallbackMaterial, " Fallback Material ");

            // Detail defaults
            body.pqsVersion.maxQuadLenghtsPerFrame = 0.03f;
            body.pqsVersion.minLevel = 1;
            body.pqsVersion.maxLevel = 10;
            body.pqsVersion.minDetailDistance = 8;

            // Create the celestial body transform
            GameObject mod = new GameObject("_CelestialBody");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_CelestialBodyTransform celestialBodyTransform = mod.AddComponent<PQSMod_CelestialBodyTransform>();
            celestialBodyTransform.sphere = body.pqsVersion;
            celestialBodyTransform.forceActivate = false;
            celestialBodyTransform.deactivateAltitude = 115000;
            celestialBodyTransform.forceRebuildOnTargetChange = false;
            celestialBodyTransform.planetFade = new PQSMod_CelestialBodyTransform.AltitudeFade();
            celestialBodyTransform.planetFade.fadeFloatName = "_PlanetOpacity";
            celestialBodyTransform.planetFade.fadeStart = 100000.0f;
            celestialBodyTransform.planetFade.fadeEnd = 110000.0f;
            celestialBodyTransform.planetFade.valueStart = 0.0f;
            celestialBodyTransform.planetFade.valueEnd = 1.0f;
            celestialBodyTransform.planetFade.secondaryRenderers = new List<GameObject>();
            celestialBodyTransform.secondaryFades = new PQSMod_CelestialBodyTransform.AltitudeFade[0];
            celestialBodyTransform.requirements = PQS.ModiferRequirements.Default;
            celestialBodyTransform.modEnabled = true;
            celestialBodyTransform.order = 10;

            // Create the color PQS mods
            mod = new GameObject("_Color");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_VertexSimplexNoiseColor vertexSimplexNoiseColor = mod.AddComponent<PQSMod_VertexSimplexNoiseColor>();
            vertexSimplexNoiseColor.sphere = body.pqsVersion;
            vertexSimplexNoiseColor.seed = 45;
            vertexSimplexNoiseColor.blend = 1.0f;
            vertexSimplexNoiseColor.colorStart = new Color(0.768656731f, 0.6996614f, 0.653089464f, 1);
            vertexSimplexNoiseColor.colorEnd = new Color(0.0f, 0.0f, 0.0f, 1.0f);
            vertexSimplexNoiseColor.octaves = 12.0;
            vertexSimplexNoiseColor.persistence = 0.5;
            vertexSimplexNoiseColor.frequency = 2.0;
            vertexSimplexNoiseColor.requirements = PQS.ModiferRequirements.MeshColorChannel;
            vertexSimplexNoiseColor.modEnabled = true;
            vertexSimplexNoiseColor.order = 200;

            PQSMod_HeightColorMap heightColorMap = mod.AddComponent<PQSMod_HeightColorMap>();
            heightColorMap.sphere = body.pqsVersion;
            List<PQSMod_HeightColorMap.LandClass> landClasses = new List<PQSMod_HeightColorMap.LandClass>();

            PQSMod_HeightColorMap.LandClass landClass = new PQSMod_HeightColorMap.LandClass("AbyPl", 0.0, 0.5, new Color(0.0f, 0.0f, 0.0f, 1.0f), Color.white, double.NaN);
            landClass.lerpToNext = true;
            landClasses.Add(landClass);

            landClass = new PQSMod_HeightColorMap.LandClass("Beach", 0.5, 0.550000011920929, new Color(0.164179087f, 0.164179087f, 0.164179087f, 1.0f), Color.white, double.NaN);
            landClass.lerpToNext = true;
            landClasses.Add(landClass);

            landClass = new PQSMod_HeightColorMap.LandClass("Beach", 0.550000011920929, 1.0, new Color(0.373134315f, 0.373134315f, 0.373134315f, 1.0f), Color.white, double.NaN);
            landClass.lerpToNext = false;
            landClasses.Add(landClass);

            // Generate an array from the land classes list
            heightColorMap.landClasses = landClasses.ToArray();
            heightColorMap.blend = 0.7f;
            heightColorMap.lcCount = 3;
            heightColorMap.requirements = PQS.ModiferRequirements.MeshColorChannel;
            heightColorMap.modEnabled = true;
            heightColorMap.order = 201;

            // Create the alititude alpha mods
            mod = new GameObject("_Material_ModProjection");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_AltitudeAlpha altitudeAlpha = mod.AddComponent<PQSMod_AltitudeAlpha>();
            altitudeAlpha.sphere = body.pqsVersion;
            altitudeAlpha.atmosphereDepth = 4000.0;
            altitudeAlpha.invert = false;
            altitudeAlpha.requirements = PQS.ModiferRequirements.Default;
            altitudeAlpha.modEnabled = false;
            altitudeAlpha.order = 999999999;

            // Create the aerial perspective material
            mod = new GameObject("_Material_AerialPerspective");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_AerialPerspectiveMaterial aerialPerspectiveMaterial = mod.AddComponent<PQSMod_AerialPerspectiveMaterial>();
            aerialPerspectiveMaterial.sphere = body.pqsVersion;
            aerialPerspectiveMaterial.globalDensity = -0.00001f;
            aerialPerspectiveMaterial.heightFalloff = 6.75f;
            aerialPerspectiveMaterial.atmosphereDepth = 150000;
            aerialPerspectiveMaterial.DEBUG_SetEveryFrame = true;
            aerialPerspectiveMaterial.cameraAlt = 0;
            aerialPerspectiveMaterial.cameraAtmosAlt = 0;
            aerialPerspectiveMaterial.heightDensAtViewer = 0;
            aerialPerspectiveMaterial.requirements = PQS.ModiferRequirements.Default;
            aerialPerspectiveMaterial.modEnabled = true;
            aerialPerspectiveMaterial.order = 100;

            // Create the UV planet relative position
            mod = new GameObject("_Material_SurfaceQuads");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_UVPlanetRelativePosition planetRelativePosition = mod.AddComponent<PQSMod_UVPlanetRelativePosition>();
            planetRelativePosition.sphere = body.pqsVersion;
            planetRelativePosition.requirements = PQS.ModiferRequirements.Default;
            planetRelativePosition.modEnabled = true;
            planetRelativePosition.order = 999999;

            // Create the height noise module
            mod = new GameObject("_HeightNoise");
            mod.transform.parent = controllerRoot.transform;
            PQSMod_VertexHeightMap vertexHeightMap = mod.gameObject.AddComponent<PQSMod_VertexHeightMap>();
            vertexHeightMap.sphere = body.pqsVersion;
            //vertexHeightMap.heightMapDeformity = 29457.0;
            vertexHeightMap.heightMapDeformity = 10000.0;
            vertexHeightMap.heightMapOffset = -1000.0;
            vertexHeightMap.scaleDeformityByRadius = false;
            vertexHeightMap.requirements = PQS.ModiferRequirements.MeshCustomNormals | PQS.ModiferRequirements.VertexMapCoords;
            vertexHeightMap.modEnabled = true;
            vertexHeightMap.order = 20;

            // Load the heightmap for this planet
            Texture2D map = new Texture2D(4, 4, TextureFormat.Alpha8, false);
            map.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/Height.png"));
            vertexHeightMap.heightMap = ScriptableObject.CreateInstance<MapSO>();
            vertexHeightMap.heightMap.CreateMap(MapSO.MapDepth.Greyscale, map);
            UnityEngine.Object.DestroyImmediate(map);

            // Create the simplex height module
            PQSMod_VertexSimplexHeight vertexSimplexHeight = mod.AddComponent<PQSMod_VertexSimplexHeight>();
            vertexSimplexHeight.sphere = body.pqsVersion;
            vertexSimplexHeight.seed = 670000;
            vertexSimplexHeight.deformity = 1700.0;
            vertexSimplexHeight.octaves = 12.0;
            vertexSimplexHeight.persistence = 0.5;
            vertexSimplexHeight.frequency = 4.0;
            vertexSimplexHeight.requirements = PQS.ModiferRequirements.MeshCustomNormals;
            vertexSimplexHeight.modEnabled = true;
            vertexSimplexHeight.order = 21;

            // SERIOUSLY RECOMMENDED FOR NO OCEAN WORLDS
            // Create the flatten ocean module
            PQSMod_FlattenOcean flattenOcean = mod.AddComponent<PQSMod_FlattenOcean>();
            flattenOcean.sphere = body.pqsVersion;
            flattenOcean.oceanRadius = 1.0;
            flattenOcean.requirements = PQS.ModiferRequirements.MeshCustomNormals;
            flattenOcean.modEnabled = true;
            flattenOcean.order = 25;

            // Creat the vertex height noise module
            PQSMod_VertexHeightNoise vertexHeightNoise = mod.AddComponent<PQSMod_VertexHeightNoise>();
            vertexHeightNoise.sphere = body.pqsVersion;
            vertexHeightNoise.noiseType = PQSMod_VertexHeightNoise.NoiseType.RiggedMultifractal;
            vertexHeightNoise.deformity = 1000.0f;
            vertexHeightNoise.seed = 5906;
            vertexHeightNoise.frequency = 2.0f;
            vertexHeightNoise.lacunarity = 2.5f;
            vertexHeightNoise.persistance = 0.5f;
            vertexHeightNoise.octaves = 4;
            vertexHeightNoise.mode = LibNoise.Unity.QualityMode.Low;
            vertexHeightNoise.requirements = PQS.ModiferRequirements.MeshColorChannel;
            vertexHeightNoise.modEnabled = true;
            vertexHeightNoise.order = 22;

            // Create the material direction
            mod = new GameObject("_Material_SunLight");
            mod.transform.parent = controllerRoot.gameObject.transform;
            PQSMod_MaterialSetDirection materialSetDirection = mod.AddComponent<PQSMod_MaterialSetDirection>();
            materialSetDirection.sphere = body.pqsVersion;
            materialSetDirection.valueName = "_sunLightDirection";
            materialSetDirection.requirements = PQS.ModiferRequirements.Default;
            materialSetDirection.modEnabled = true;
            materialSetDirection.order = 100;

            // Crete the quad mesh colliders
            mod = new GameObject("QuadMeshColliders");
            mod.transform.parent = controllerRoot.gameObject.transform;
            PQSMod_QuadMeshColliders quadMeshColliders = mod.AddComponent<PQSMod_QuadMeshColliders>();
            quadMeshColliders.sphere = body.pqsVersion;
            quadMeshColliders.maxLevelOffset = 0;
            quadMeshColliders.physicsMaterial = new PhysicMaterial();
            quadMeshColliders.physicsMaterial.name = "Ground";
            quadMeshColliders.physicsMaterial.dynamicFriction = 0.6f;
            quadMeshColliders.physicsMaterial.staticFriction = 0.8f;
            quadMeshColliders.physicsMaterial.bounciness = 0.0f;
            quadMeshColliders.physicsMaterial.frictionDirection2 = Vector3.zero;
            quadMeshColliders.physicsMaterial.dynamicFriction2 = 0.0f;
            quadMeshColliders.physicsMaterial.staticFriction2 = 0.0f;
            quadMeshColliders.physicsMaterial.frictionCombine = PhysicMaterialCombine.Maximum;
            quadMeshColliders.physicsMaterial.bounceCombine = PhysicMaterialCombine.Average;
            quadMeshColliders.requirements = PQS.ModiferRequirements.Default;
            quadMeshColliders.modEnabled = true;
            quadMeshColliders.order = 100;

            // Create the simplex height absolute
            mod = new GameObject("_FineDetail");
            mod.transform.parent = controllerRoot.gameObject.transform;
            PQSMod_VertexSimplexHeightAbsolute vertexSimplexHeightAbsolute = mod.AddComponent<PQSMod_VertexSimplexHeightAbsolute>();
            vertexSimplexHeightAbsolute.sphere = body.pqsVersion;
            vertexSimplexHeightAbsolute.seed = 4234;
            vertexSimplexHeightAbsolute.deformity = 400.0;
            vertexSimplexHeightAbsolute.octaves = 6.0;
            vertexSimplexHeightAbsolute.persistence = 0.5;
            vertexSimplexHeightAbsolute.frequency = 18.0;
            vertexSimplexHeightAbsolute.requirements = PQS.ModiferRequirements.Default;
            vertexSimplexHeightAbsolute.modEnabled = true;
            vertexSimplexHeightAbsolute.order = 30;

            // Surface color map
            mod = new GameObject("_LandClass");
            mod.transform.parent = body.pqsVersion.gameObject.transform;
            PQSMod_VertexColorMap colorMap = mod.AddComponent<PQSMod_VertexColorMap>();
            colorMap.sphere = body.pqsVersion;
            colorMap.order = 500;
            colorMap.modEnabled = true;

            // Decompress and load the color
            map = new Texture2D(4, 4, TextureFormat.RGB24, false);
            map.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/Color.png"));
            colorMap.vertexColorMap = ScriptableObject.CreateInstance<MapSO>();
            colorMap.vertexColorMap.CreateMap(MapSO.MapDepth.RGB, map);
            UnityEngine.Object.DestroyImmediate(map);

            #endregion

            #region PSystemBody.scaledVersion generation

            // Create the scaled version of the planet for use in map view
            body.scaledVersion = new GameObject(name);
            body.scaledVersion.layer = Constants.GameLayers.ScaledSpace;
            body.scaledVersion.transform.parent = Utility.Deactivator;

            // DEPRECATED - USE PQSMeshWrapper
            // Make sure the scaled version cooresponds to the size of the body
            // Turns out that the localScale is directly related to the planet size.
            // Jool's local scale is {1,1,1}, Kerbin's is {0.1,0.1,0.1}.  Jool's
            // radius is 6000 km, Kerbin's is 600 km.  Notice the relation?
            float scale = (float) body.celestialBody.Radius / 6000000.0f;
            body.scaledVersion.transform.localScale = new Vector3(scale, scale, scale);

            // Generate a mesh to fit the PQS we generated (it would be cool to generate this FROM the PQS)
            Mesh mesh = new Mesh();
            Utility.CopyMesh(Jool.scaledVersion.GetComponent<MeshFilter>().sharedMesh, mesh);

            // Iterate though the UVs
            // Geosphere with a radius of 1000, cooresponds to an object 6000km in radius
            Vector3[] vertices = mesh.vertices;
            for(int i = 0; i < mesh.vertexCount; i++)
            {
                // Get the height offset from the height map
                Vector2 uv = mesh.uv[i];
                float displacement = vertexHeightMap.heightMap.GetPixelFloat(uv.x, uv.y);

                // Since this is a geosphere, normalizing the vertex gives the vector to translate on
                Vector3 v = vertices[i];
                v.Normalize();

                // Calculate the real height displacement (in meters), normalized vector "v" scale (1 unit = 6 km)
                displacement = (float) vertexHeightMap.heightMapOffset + (displacement * (float) vertexHeightMap.heightMapDeformity);
                Vector3 offset = v * ((displacement / 6000.0f) / scale);

                // Adjust the displacement
                vertices[i] += offset;
            }
            mesh.vertices = vertices;
            mesh.RecalculateNormals();

            // Create the mesh filter
            MeshFilter meshFilter = body.scaledVersion.AddComponent<MeshFilter> ();
            meshFilter.mesh = mesh;

            // Load and compress the color texture for the custom planet
            Texture2D colorTexture = new Texture2D(4, 4, TextureFormat.RGBA32, true);
            colorTexture.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/Color.png"));
            colorTexture.Compress(true);
            colorTexture.Apply(true, true);

            // Load and compress the color texture for the custom planet
            Texture2D normalTexture = new Texture2D(4, 4, TextureFormat.RGB24, true);
            normalTexture.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/Normals.png"));
            //normalTexture = GameDatabase.BitmapToUnityNormalMap(normalTexture);
            normalTexture.Compress(true);
            normalTexture.Apply(true, true);

            // Create the renderer and material for the scaled version
            MeshRenderer renderer = body.scaledVersion.AddComponent<MeshRenderer>();
            //ScaledPlanetSimple material = new ScaledPlanetSimple();   // for atmosphereless planets
            ScaledPlanetRimAerial material = new ScaledPlanetRimAerial();
            material.color       = Color.white;
            material.specColor   = Color.black;
            material.mainTexture = colorTexture;
            material.bumpMap     = normalTexture;
            renderer.material    = material;

            // Create the sphere collider
            SphereCollider collider = body.scaledVersion.AddComponent<SphereCollider> ();
            collider.center         = Vector3.zero;
            collider.radius         = 1000.0f;

            // Create the ScaledSpaceFader to fade the orbit out where we view it (maybe?)
            ScaledSpaceFader fader = body.scaledVersion.AddComponent<ScaledSpaceFader> ();
            fader.celestialBody    = body.celestialBody;
            fader.fadeStart        = 95000.0f;
            fader.fadeEnd          = 100000.0f;
            fader.floatName        = "_Opacity";

            #endregion

            #region Atmosphere
            //--------------------- PROPERTIES EXCLUSIVE TO BODIES WITH ATMOSPHERE

            // Load the atmosphere gradient (compress it, does not need to be high quality)
            Texture2D atmosphereGradient = new Texture2D(4, 4, TextureFormat.RGB24, true);
            atmosphereGradient.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/AtmosphereGradient.png"));
            atmosphereGradient.Compress(true);
            atmosphereGradient.wrapMode = TextureWrapMode.Clamp;
            atmosphereGradient.mipMapBias = 0.0f;
            atmosphereGradient.Apply(true, true);

            // Set the additional settings in the scaledVersion body's shader
            material.rimPower = 2.06f;
            material.rimBlend = 0.3f;
            material.rimColorRamp = atmosphereGradient;

            // Atmosphere specific properties (for scaled version root) (copied from duna)
            MaterialSetDirection materialLightDirection = body.scaledVersion.AddComponent<MaterialSetDirection>();
            materialLightDirection.valueName            = "_localLightDirection";

            // Create the atmosphere shell itself
            GameObject scaledAtmosphere               = new GameObject("atmosphere");
            scaledAtmosphere.transform.parent         = body.scaledVersion.transform;
            scaledAtmosphere.layer                    = Constants.GameLayers.ScaledSpaceAtmosphere;
            meshFilter                                = scaledAtmosphere.AddComponent<MeshFilter>();
            meshFilter.sharedMesh                     = Jool.scaledVersion.GetComponent<MeshFilter>().sharedMesh;
            renderer                                  = scaledAtmosphere.AddComponent<MeshRenderer>();
            renderer.material                         = new Kopernicus.MaterialWrapper.AtmosphereFromGround();
            AtmosphereFromGround atmosphereRenderInfo = scaledAtmosphere.AddComponent<AtmosphereFromGround>();
            atmosphereRenderInfo.waveLength           = new Color(0.509f, 0.588f, 0.643f, 0.000f);

            // Technical info for atmosphere
            body.celestialBody.atmosphere = true;
            body.celestialBody.atmosphereContainsOxygen = true;
            body.celestialBody.staticPressureASL = 1.0; // can't find anything that references this, especially with the equation in mind - where is this used?
            body.celestialBody.altitudeMultiplier = 1.4285f; // ditto
            body.celestialBody.atmosphereScaleHeight = 4.0;   // pressure (in atm) = atmosphereMultipler * e ^ -(altitude / (atmosphereScaleHeight * 1000))
            body.celestialBody.atmosphereMultiplier = 0.8f;
            body.celestialBody.atmoshpereTemperatureMultiplier = 1.0f; // how does this coorespond?
            body.celestialBody.maxAtmosphereAltitude = 55000.0f;  // i guess this is so the math doesn't drag out?
            body.celestialBody.useLegacyAtmosphere = true;
            body.celestialBody.atmosphericAmbientColor = new Color(0.306f, 0.187f, 0.235f, 1.000f);
            #endregion

            #region Ocean
            // ---------------- FOR BODIES WITH OCEANS ----------
            /*body.celestialBody.ocean = true;

            // Setup the laythe ocean info in master pqs
            body.pqsVersion.mapOcean = true;
            body.pqsVersion.mapOceanColor = new Color(0.117f, 0.126f, 0.157f, 1.000f);
            body.pqsVersion.mapOceanHeight = 0.0f;

            // Generate the PQS object
            GameObject oceanRoot       = new GameObject(name + "Ocean");
            oceanRoot.transform.parent = body.pqsVersion.transform;
            oceanRoot.layer            = Constants.GameLayers.LocalSpace;
            PQS oceanPQS               = oceanRoot.AddComponent<PQS>();

            // Add this new PQS to the secondary renderers of the altitude fade controller
            celestialBodyTransform.planetFade.secondaryRenderers.Add(oceanRoot);

            // Setup the PQS object data
            Utility.CopyObjectFields<PQS>(laytheOcean.GetComponent<PQS>(), oceanPQS);
            oceanPQS.radius            = body.pqsVersion.radius;
            oceanPQS.surfaceMaterial   = new PQSOceanSurfaceQuad(laytheOcean.GetComponent<PQS>().surfaceMaterial);
            oceanPQS.fallbackMaterial  = new PQSOceanSurfaceQuadFallback(laytheOcean.GetComponent<PQS>().fallbackMaterial);
            Utility.DumpObjectProperties(oceanPQS.surfaceMaterial, oceanPQS.surfaceMaterial.ToString());
            Utility.DumpObjectProperties(oceanPQS.fallbackMaterial, oceanPQS.fallbackMaterial.ToString());

            // Create the aerial perspective material
            mod = new GameObject("_Material_AerialPerspective");
            mod.transform.parent = oceanRoot.transform;
            aerialPerspectiveMaterial = mod.AddComponent<PQSMod_AerialPerspectiveMaterial>();
            aerialPerspectiveMaterial.sphere = body.pqsVersion;
            aerialPerspectiveMaterial.globalDensity = -0.00001f;
            aerialPerspectiveMaterial.heightFalloff = 6.75f;
            aerialPerspectiveMaterial.atmosphereDepth = 150000;
            aerialPerspectiveMaterial.DEBUG_SetEveryFrame = true;
            aerialPerspectiveMaterial.cameraAlt = 0;
            aerialPerspectiveMaterial.cameraAtmosAlt = 0;
            aerialPerspectiveMaterial.heightDensAtViewer = 0;
            aerialPerspectiveMaterial.requirements = PQS.ModiferRequirements.Default;
            aerialPerspectiveMaterial.modEnabled = true;
            aerialPerspectiveMaterial.order = 100;

            // Create the UV planet relative position
            mod = new GameObject("_Material_SurfaceQuads");
            mod.transform.parent = oceanRoot.transform;
            planetRelativePosition = mod.AddComponent<PQSMod_UVPlanetRelativePosition>();
            planetRelativePosition.sphere = body.pqsVersion;
            planetRelativePosition.requirements = PQS.ModiferRequirements.Default;
            planetRelativePosition.modEnabled = true;
            planetRelativePosition.order = 100;

            // Create the quad map remover (da f**k?)
            mod = new GameObject("QuadRemoveMap");
            mod.transform.parent = oceanRoot.transform;
            PQSMod_RemoveQuadMap removeQuadMap = mod.AddComponent<PQSMod_RemoveQuadMap>();
            removeQuadMap.mapDeformity = 0.0f;
            removeQuadMap.minHeight = 0.0f;
            removeQuadMap.maxHeight = 0.5f;
            removeQuadMap.requirements = PQS.ModiferRequirements.Default;
            removeQuadMap.modEnabled = true;
            removeQuadMap.order = 1000;

            // Load the heightmap into whatever the hell this is
            map = new Texture2D(4, 4, TextureFormat.Alpha8, false);
            map.LoadImage(System.IO.File.ReadAllBytes(KSPUtil.ApplicationRootPath + PluginDirectory + "/Planets/" + name + "/Height.png"));
            removeQuadMap.map = ScriptableObject.CreateInstance<MapSO>();
            removeQuadMap.map.CreateMap(MapSO.MapDepth.Greyscale, map);
            UnityEngine.Object.DestroyImmediate(map);

            // Setup the ocean effects
            mod = new GameObject("OceanFX");
            mod.transform.parent = oceanRoot.transform;
            PQSMod_OceanFX oceanFX = mod.AddComponent<PQSMod_OceanFX>();
            oceanFX.watermain = Utility.RecursivelyGetComponent<PQSMod_OceanFX>(laytheOcean).watermain.Clone() as Texture2D[];
            oceanFX.requirements = PQS.ModiferRequirements.Default;
            oceanFX.modEnabled = true;
            oceanFX.order = 100;*/

            #endregion

            // Return the new body
            return body;
        }
    private void CreateAtlases(ShadersGroup sg)
    {
        List<Renderer> renderers = new List<Renderer>();

        for (int i = 0; i < sg.gameObjects.Count; i++)
        {
            if (sg.gameObjects[i].GetComponent<Renderer>() != null)
                renderers.Add(sg.gameObjects[i].GetComponent<Renderer>());
            else
                sg.gameObjects.Remove(sg.gameObjects[i]);
        }

        AssetsReimporter tr = new AssetsReimporter();
        tr.Reimport(GetTextures(renderers.ToArray()) as Texture[]);

        Texture2D[] textures = GetTextures(renderers.ToArray());

        if (textures == null || textures.Length == 0 || textures.Length == 1)
            return;

        Texture2D atlas = new Texture2D(32,32,TextureFormat.DXT1,true);
        Material newMaterial = new Material(sg.gameObjects[0].GetComponent<Renderer>().sharedMaterial);

        Rect[] rects = atlas.PackTextures(textures,0,4096,false);

        atlas.Compress(true);
        atlas.Apply();

        newMaterial.mainTexture = atlas as Texture;

        for(int i = 0;i < sg.gameObjects.Count;i++)
        {
            if(rects[i].x == 0 && rects[i].y == 0 && rects[i].width == 1 && rects[i].height == 1)
                continue;

            Vector2[] uv,uvs;

            uv = sg.gameObjects[i].GetComponent<MeshFilter>().sharedMesh.uv;
            uvs = uv;

            float offsetX = 0;
            float offsetY = 0;

            int scaleFactor = 1;

            #region Offset

            for (int c = 0; c < uv.Length; c++)
            {
                if (uv[c].x < offsetX)
                    offsetX = uv[c].x;

                if (uv[c].y < offsetY)
                    offsetY = uv[c].y;
            }

            #endregion

            if (!superOptimization && (offsetX < 0 || offsetY < 0))
                continue;

            #region SetOffset

            for (int c = 0; c < uv.Length; c++)
                uvs[c] = new Vector2(uv[c].x + (-(offsetX)), uv[c].y + (-(offsetY)));

            #endregion

            #region Scale

            for (int c = 0; c < uvs.Length; c++)
            {

                int rounded = 0;
                float value = 0;

                if (uvs[c].x < 0)
                    value = -uvs[c].x;
                else
                    value = uvs[c].x;

                rounded = Mathf.CeilToInt(value);

                if (rounded > scaleFactor)
                    scaleFactor = rounded;

                rounded = 0;
                value = 0;

                if (uv[c].y < 0)
                    value = -uvs[c].y;
                else
                    value = uvs[c].y;

                rounded = Mathf.CeilToInt(value);

                if (rounded > scaleFactor)
                    scaleFactor = rounded;
            }

            #endregion

            if (!superOptimization && scaleFactor > 1)
                continue;

            #region SetScale

            for (int c = 0; c < uvs.Length; c++)
                uvs[c] = new Vector2(uvs[c].x / scaleFactor, uvs[c].y / scaleFactor);

            #endregion

            for (int c = 0; c < uvs.Length; c++)
            {
                uvs[c] = new Vector2((float)(((float)uvs[c].x * (float)rects[i].width) + (float)rects[i].x), (float)(((float)uvs[c].y * (float)rects[i].height) + (float)rects[i].y));
            }

            sg.gameObjects[i].GetComponent<MeshFilter>().sharedMesh.uv = uvs;
            sg.gameObjects[i].GetComponent<Renderer>().sharedMaterial = newMaterial;
            sg.gameObjects[i].GetComponent<Renderer>().sharedMaterial.mainTextureOffset = new Vector2(0, 0);
            sg.gameObjects[i].GetComponent<Renderer>().sharedMaterial.mainTextureScale = new Vector2(1, 1);
        }
    }
        static Texture2D GetTexture(long pColorRGBA)
        {
            if(mTextures.ContainsKey(pColorRGBA) && mTextures[pColorRGBA] != null)
                return mTextures[pColorRGBA];

            Color32 c = GetColor(pColorRGBA);

            var tmp = new Texture2D(4,4);
            for(int x = 0;x < 4;x++)
                for(int y = 0;y < 4;y++)
                    tmp.SetPixel(x,y,c);
            tmp.Apply();
            tmp.Compress(true);

            mTextures[pColorRGBA] = tmp;

            return tmp;
        }
        /**
         *  This function returns two variables:
        -> The tecture atlas
        -> An array of the old textures and their new positions. (Used for UV modification)
        */
        public static Material combine(Material[] combines, out TexturePosition[] texturePositions, TextureAtlasInfo atlasInfo)
        {
            if (atlasInfo == null) {
                Debug.LogError("atlasInfo is null. Try removing and reattaching combine children component");
                texturePositions = null;
                return null;
            }
            if (atlasInfo.shaderPropertiesToLookFor.Length <= 0) {
                Debug.LogError("You need to enter some shader properties to look for into Atlas Info. Cannot combine with 0 properties");
                texturePositions = null;
                return null;
            }
            List<ShaderProperties> properties = new List<ShaderProperties>();

            for (int i = 0; i < atlasInfo.shaderPropertiesToLookFor.Length; i++) {
                if (combines [0].HasProperty(atlasInfo.shaderPropertiesToLookFor [i].propertyName)) {
                    properties.Add(atlasInfo.shaderPropertiesToLookFor [i]);
                }
            }

            texturePositions = new TexturePosition[combines.Length];

            for (int i = 0; i < combines.Length; i++) {
                TexturePosition tempTexturePosition = new TexturePosition();
                tempTexturePosition.textures = new Texture2D[properties.Count];

                for (int j = 0; j < properties.Count; j++) {
                    //Debug.Log((combines[i].GetTexture(properties[j].propertyName) == null) + ", " +  properties[j].propertyName + ", " + combines[i].name);
                    if (combines [i].GetTexture(properties [j].propertyName) == null) {
                        Debug.LogError("Cannot combine textures when using Unity's default material texture");
                        texturePositions = null;
                        return null;
                    }
                    tempTexturePosition.textures [j] = Object.Instantiate(combines [i].GetTexture(properties [j].propertyName)) as Texture2D;
                    tempTexturePosition.textures [j].name = tempTexturePosition.textures [j].name.Remove(tempTexturePosition.textures [j].name.IndexOf("(Clone)", System.StringComparison.Ordinal));

                }

                texturePositions [i] = tempTexturePosition;
            }

            textureQuickSort(texturePositions, 0, texturePositions.Length - 1);

            for (int i = 0; i < texturePositions.Length; i++) {
                for (int j = 1; j < texturePositions[i].textures.Length; j++) {
                    texturePositions [i].textures [j] = scaleTexture(texturePositions [i].textures [j], texturePositions [i].textures [0].width, texturePositions [i].textures [0].height);
                }
            }

            texturePositions [0].position.x = texturePositions [0].position.y = 0;
            texturePositions [0].position.width = texturePositions [0].textures [0].width;
            texturePositions [0].position.height = texturePositions [0].textures [0].height;

            int height = texturePositions [0].textures [0].height;
            int width = texturePositions [0].textures [0].width;

            int widthIndex = width;
            int heightIndex = 0;

            bool useHeightAsReference = true;
            for (int i = 1; i < texturePositions.Length; i++) {
                texturePositions [i].position.x = widthIndex;
                texturePositions [i].position.y = heightIndex;
                texturePositions [i].position.width = texturePositions [i].textures [0].width;
                texturePositions [i].position.height = texturePositions [i].textures [0].height;

                if (useHeightAsReference) {
                    if (widthIndex + texturePositions [i].textures [0].width > width) {
                        width = widthIndex + texturePositions [i].textures [0].width;
                    }

                    heightIndex += texturePositions [i].textures [0].height;

                    if (heightIndex >= height) {
                        useHeightAsReference = false;
                        height = heightIndex;
                        heightIndex = height;

                        widthIndex = 0;
                    }
                } else {
                    if (heightIndex + texturePositions [i].textures [0].height > height) {
                        height = heightIndex + texturePositions [i].textures [0].height;
                    }

                    widthIndex += texturePositions [i].textures [0].width;

                    if (widthIndex >= width) {
                        useHeightAsReference = true;
                        width = widthIndex;
                        widthIndex = width;

                        heightIndex = 0;
                    }
                }
            }

            if (height > width) {
                width = height;
            } else {
                height = width;
            }
            float textureSizeFactor = 1.0f / height;

            Material newMaterial = new Material(combines [0]);

            for (int i = 0; i < properties.Count; i++) {
                Texture2D combinesTextures = new Texture2D(width, height, (atlasInfo.ignoreAlpha && !properties [i].markAsNormal) ? TextureFormat.RGB24 : TextureFormat.ARGB32, true);
                combinesTextures.anisoLevel = atlasInfo.anisoLevel;
                combinesTextures.filterMode = atlasInfo.filterMode;
                combinesTextures.wrapMode = atlasInfo.wrapMode;

                for (int j = 0; j < texturePositions.Length; j++) {
                    combinesTextures.SetPixels((int)texturePositions [j].position.x, (int)texturePositions [j].position.y, texturePositions [j].textures [i].width, texturePositions [j].textures [i].height, texturePositions [j].textures [i].GetPixels());
                }

                combinesTextures.Apply();

                if (atlasInfo.compressTexturesInMemory) {
                    combinesTextures.Compress(true);
                }

                newMaterial.SetTexture(properties [i].propertyName, combinesTextures);
            }

            for (int i = 0; i < texturePositions.Length; i++) {
                texturePositions [i].position.x = texturePositions [i].position.x * textureSizeFactor;
                texturePositions [i].position.y = texturePositions [i].position.y * textureSizeFactor;
                texturePositions [i].position.width = texturePositions [i].position.width * textureSizeFactor;
                texturePositions [i].position.height = texturePositions [i].position.height * textureSizeFactor;
            }

            return newMaterial;
        }
示例#35
0
 public Texture2D MakeTexture(Texture2D sourceTexture)
 {
     Texture2D texture2D = new Texture2D(sourceTexture.width, sourceTexture.height, TextureFormat.ARGB32, true);
     Color32[] array = sourceTexture.GetPixels32(0);
     for (int i = 0; i < array.Length; i++)
     {
         float num = Mathf.Clamp01((float)array[i].a / 255f * this.gloss_mult);
         float num2 = num;
         float num3 = 1f - num;
         num2 = num2 * num2 * num2;
         num3 = num3 * num3 * num3;
         float num4 = Mathf.Lerp(num2, 1f - num3, this.gloss_shaping);
         num4 = Mathf.Clamp01(num4);
         array[i].a = (byte)(num4 * 255f);
     }
     texture2D.SetPixels32(array, 0);
     for (int j = 1; j < sourceTexture.mipmapCount; j++)
     {
         int num5 = texture2D.width >> j;
         Color32[] array2 = new Color32[num5 * num5];
         byte[] glossMipLevel = this.GetGlossMipLevel(j);
         int num6 = glossMipLevel.Length;
         for (int k = 0; k < num6; k++)
         {
             int num7 = k % num5;
             int num8 = k / num5;
             int num9 = num8 * num5 * 4 + num7 * 2;
             int num10 = num9 + 1;
             int num11 = num9 + num5 * 2;
             int num12 = num11 + 1;
             array2[k].r = (byte)(array[num9].r + array[num10].r + array[num11].r + array[num12].r >> 2);
             array2[k].g = (byte)(array[num9].g + array[num10].g + array[num11].g + array[num12].g >> 2);
             array2[k].b = (byte)(array[num9].b + array[num10].b + array[num11].b + array[num12].b >> 2);
             array2[k].a = glossMipLevel[k];
         }
         array = array2;
         texture2D.SetPixels32(array2, j);
     }
     texture2D.Apply(false, false);
     texture2D.Compress(true);
     texture2D.Apply(false, true);
     texture2D.wrapMode = sourceTexture.wrapMode;
     texture2D.anisoLevel = sourceTexture.anisoLevel;
     texture2D.filterMode = sourceTexture.filterMode;
     return texture2D;
 }
示例#36
0
 public static Texture2D MakeTexture(Texture2D sourceTexture, RTPGlossBaked[] tilesData)
 {
     Texture2D texture2D = new Texture2D(sourceTexture.width, sourceTexture.height, TextureFormat.ARGB32, true);
     for (int i = 0; i < 4; i++)
     {
         int num = sourceTexture.width >> 1;
         int num2 = i % 2 * num;
         int num3 = (i % 4 >= 2) ? num : 0;
         Color[] array = sourceTexture.GetPixels(num2, num3, num, num, 0);
         for (int j = 0; j < array.Length; j++)
         {
             float num4 = Mathf.Clamp01(array[j].a * tilesData[i].gloss_mult);
             float num5 = num4;
             float num6 = 1f - num4;
             num5 = num5 * num5 * num5;
             num6 = num6 * num6 * num6;
             float num7 = Mathf.Lerp(num5, 1f - num6, tilesData[i].gloss_shaping);
             num7 = Mathf.Clamp01(num7);
             array[j].a = num7;
         }
         texture2D.SetPixels(num2, num3, num, num, array, 0);
         for (int k = 1; k < sourceTexture.mipmapCount - 1; k++)
         {
             int num8 = texture2D.width >> k + 1;
             Color[] array2 = new Color[num8 * num8];
             byte[] glossMipLevel = tilesData[i].GetGlossMipLevel(k);
             int num9 = glossMipLevel.Length;
             for (int l = 0; l < num9; l++)
             {
                 int num10 = l % num8;
                 int num11 = l / num8;
                 int num12 = num11 * num8 * 4 + num10 * 2;
                 int num13 = num12 + 1;
                 int num14 = num12 + num8 * 2;
                 int num15 = num14 + 1;
                 array2[l].r = (array[num12].r + array[num13].r + array[num14].r + array[num15].r) / 4f;
                 array2[l].g = (array[num12].g + array[num13].g + array[num14].g + array[num15].g) / 4f;
                 array2[l].b = (array[num12].b + array[num13].b + array[num14].b + array[num15].b) / 4f;
                 array2[l].a = (float)glossMipLevel[l] / 255f;
             }
             array = array2;
             num2 >>= 1;
             num3 >>= 1;
             num >>= 1;
             texture2D.SetPixels(num2, num3, num, num, array2, k);
         }
     }
     texture2D.Apply(false, false);
     texture2D.Compress(true);
     texture2D.Apply(false, true);
     texture2D.wrapMode = sourceTexture.wrapMode;
     texture2D.anisoLevel = sourceTexture.anisoLevel;
     texture2D.filterMode = sourceTexture.filterMode;
     return texture2D;
 }
示例#37
0
 private static Texture2D LoadTextureFromStream(bool readOnly, Stream textureStream)
 {
     var buf = new byte[textureStream.Length]; //declare arraysize
     textureStream.Read(buf, 0, buf.Length); // read from stream to byte array
     textureStream.Close();
     var tex = new Texture2D(2, 2, TextureFormat.ARGB32, false);
     tex.LoadImage(buf);
     tex.name = Guid.NewGuid().ToString();
     tex.filterMode = FilterMode.Bilinear;
     tex.Compress(false);
     tex.Apply(false, readOnly);
     return tex;
 }