Exemple #1
0
        public static void DrawMegaSplat(MatrixGenerators.MegaSplatOutput200 gen)
        {
                        #if !__MEGASPLAT__
            using (Cell.LinePx(60))
                Draw.Helpbox("MicroSplat doesn't seem to be installed, or MicroSplat compatibility is not enabled in settings");
                        #endif
            if (GraphWindow.current.mapMagic != null)
            {
                using (Cell.LineStd)
                {
                    GeneratorDraw.DrawGlobalVar(ref GraphWindow.current.mapMagic.terrainSettings.material, "Material");

                    if (Cell.current.valChanged)
                    {
                        GraphWindow.current.mapMagic.ApplyTerrainSettings();
                    }
                }

                using (Cell.LineStd)
                {
                                        #if __MEGASPLAT__
                    MegaSplatTextureList texList = GraphWindow.current.mapMagic.globals.megaSplatTexList as MegaSplatTextureList;
                    GeneratorDraw.DrawGlobalVar(ref texList, "TexList");
                    GraphWindow.current.mapMagic.globals.megaSplatTexList = texList;
                                        #endif
                }
            }

            using (Cell.LinePx(0)) CheckShader(gen);
        }
Exemple #2
0
        public static void DrawMegaSplat(MegaSplatOutput200 gen)
        {
                        #if !__MEGASPLAT__
            using (Cell.LinePx(60))
                Draw.Helpbox("MicroSplat doesn't seem to be installed, or MicroSplat compatibility is not enabled in settings");
                        #endif
            if (GraphWindow.current.mapMagic != null)
            {
                using (Cell.LineStd)
                {
                    GeneratorDraw.DrawGlobalVar(ref GraphWindow.current.mapMagic.terrainSettings.material, "Material");

                    if (Cell.current.valChanged)
                    {
                        GraphWindow.current.mapMagic.ApplyTerrainSettings();
                    }
                }

                using (Cell.LineStd)
                {
                                        #if __MEGASPLAT__
                    MegaSplatTextureList texList = GraphWindow.current.mapMagic.globals.megaSplatTexList as MegaSplatTextureList;
                    GeneratorDraw.DrawGlobalVar(ref texList, "TexList");
                    GraphWindow.current.mapMagic.globals.megaSplatTexList = texList;
                                        #endif
                }
            }
            else
            {
                using (Cell.LinePx(18 + 18)) Draw.Label("Not assigned to current \nMapMagic object");
            }

            using (Cell.LinePx(0)) CheckShader(gen);

            using (Cell.LinePx(20)) GeneratorDraw.DrawLayersAddRemove(gen, ref gen.layers, inversed: true, unlinkBackground: true);
            using (Cell.LinePx(0)) GeneratorDraw.DrawLayersThemselves(gen, gen.layers, inversed: true, layerEditor: DrawCTSLayer);
        }
Exemple #3
0
        private static void DrawCTSLayer(Generator tgen, int num)
        {
            MegaSplatOutput200 gen = (MegaSplatOutput200)tgen;

            MegaSplatOutput200.MegaSplatLayer layer = gen.layers[num];
            if (layer == null)
            {
                return;
            }

                        #if __MEGASPLAT__
            MegaSplatTextureList textureList = GraphWindow.current.mapMagic?.globals.megaSplatTexList as MegaSplatTextureList;
                        #endif

            Cell.EmptyLinePx(3);
            using (Cell.LinePx(28))
            {
                //Cell.current.margins = new Padding(0,0,0,1); //1-pixel more padding from the bottom since layers are 1 pixel overlayed

                if (num != 0)
                {
                    using (Cell.RowPx(0)) GeneratorDraw.DrawInlet(layer, gen);
                }
                else
                //disconnecting last layer inlet
                if (GraphWindow.current.graph.IsLinked(layer))
                {
                    GraphWindow.current.graph.UnlinkInlet(layer);
                }

                Cell.EmptyRowPx(10);

                //icon
                Texture2DArray icon  = null;
                int            index = -2;

                Material material = null;
                if (GraphWindow.current.mapMagic != null)
                {
                    material = GraphWindow.current.mapMagic.terrainSettings.material;
                }

                if (material != null && material.HasProperty("_Diffuse"))
                {
                    icon = (Texture2DArray)material?.GetTexture("_Diffuse");
                }

                                #if __MEGASPLAT__
                if (textureList != null)
                {
                    //icon = textureList.clusters[num].previewTex; //preview textures doesnt seem to be working in recent versions
                    index = textureList.clusters[num].indexes[0];
                }
                                #endif

                using (Cell.RowPx(28))
                {
                    if (icon != null && index >= 0)
                    {
                        Draw.TextureIcon(icon, index);
                    }
                }

                //channel
                Cell.EmptyRowPx(3);
                using (Cell.Row)
                {
                    Cell.EmptyLine();
                    using (Cell.LineStd)
                    {
                        Cell.current.fieldWidth = 0.4f;
                                                #if __MEGASPLAT__
                        if (textureList != null)
                        {
                            Draw.PopupSelector(ref layer.channelNum, textureList.textureNames);
                        }
                        else
                        {
                            Draw.Field(ref layer.channelNum, "Channel");
                        }
                                                #else
                        Draw.Field(ref layer.channelNum, "Channel");
                                                #endif
                    }
                    Cell.EmptyLine();
                }

                Cell.EmptyRowPx(10);
                using (Cell.RowPx(0)) GeneratorDraw.DrawOutlet(layer);
            }
            Cell.EmptyLinePx(3);
        }
Exemple #4
0
		public override void OnGUI (GeneratorsAsset gens)
		{
			#if __MEGASPLAT__
			layout.fieldSize = 0.5f; 

			//finding texture list from other generators
			if (textureList == null) 
				foreach (MegaSplatOutput gen in gens.GeneratorsOfType<MegaSplatOutput>(onlyEnabled: true, checkBiomes: true))
					if (gen.textureList != null) textureList = gen.textureList;

			//wrong material and settings warnings
			if (MapMagic.instance.showBaseMap) 
			{
				layout.Par(30);
            layout.Label("Show Base Map is turned on in Settings.", rect:layout.Inset(0.8f), helpbox:true);
				if (layout.Button("Fix",rect:layout.Inset(0.2f))) MapMagic.instance.showBaseMap = false;
			}

			if (MapMagic.instance.terrainMaterialType != Terrain.MaterialType.Custom)
			{
				layout.Par(30);
            layout.Label("Material Type is not switched to Custom.", rect:layout.Inset(0.8f), helpbox:true);
				if (layout.Button("Fix",rect:layout.Inset(0.2f))) 
				{
					MapMagic.instance.terrainMaterialType = Terrain.MaterialType.Custom;
					foreach (Chunk tw in MapMagic.instance.chunks.All()) tw.SetSettings();
				}
			}

			if (MapMagic.instance.customTerrainMaterial == null || !MapMagic.instance.customTerrainMaterial.shader.name.Contains("MegaSplat"))
			{
				layout.Par(42);
            layout.Label("No MegaSplat material is assigned as Custom Material in Terrain Settings.", rect:layout.Inset(), helpbox:true);
			}

			if (MapMagic.instance.customTerrainMaterial != null)
			{
				if (!MapMagic.instance.customTerrainMaterial.IsKeywordEnabled("_TERRAIN") || !MapMagic.instance.customTerrainMaterial.HasProperty("_SplatControl"))
				{
					layout.Par(42);
               layout.Label("Material must use a MegaSplat shader set to Terrain.", rect:layout.Inset(), helpbox:true);
				}

				if (MapMagic.instance.customTerrainMaterial.GetTexture("_Diffuse") == null)
				{
					layout.Par(42);
					layout.Label("Material does not have texture arrays assigned, please assign them.", rect:layout.Inset(), helpbox:true);
				}
			}

			/*if (!MapMagic.instance.materialTemplateMode)
			{
				layout.Par(30);
				layout.Label("Material Template Mode is off.", rect:layout.Inset(0.8f), helpbox:true);
				if (layout.Button("Fix",rect:layout.Inset(0.2f))) MapMagic.instance.materialTemplateMode = true;
			}*/

			if (MapMagic.instance.assignCustomTerrainMaterial)
			{
				layout.Par(30);
				layout.Label("Assign Custom Material is turned on.", rect:layout.Inset(0.8f), helpbox:true);
				if (layout.Button("Fix",rect:layout.Inset(0.2f))) 
				{
					MapMagic.instance.assignCustomTerrainMaterial = false;
				}
			}

			if (textureList == null || textureList.clusters == null || textureList.clusters.Length <= 0)
			{
				layout.Par(30);
            layout.Label("Please assign textures and list with clusters below:", rect:layout.Inset(), helpbox:true);

				layout.Field<MegaSplatTextureList>(ref textureList, "TextureList");
				foreach(Input input in Inputs()) input.link = null;
				return;
			}

			//drawing texture list field
			layout.Field<MegaSplatTextureList>(ref textureList, "TextureList");
			
			//setting all of the generators list to this one
			if (layout.change)
				foreach (MegaSplatOutput gen in gens.GeneratorsOfType<MegaSplatOutput>(onlyEnabled: true, checkBiomes: true))
					gen.textureList = textureList;

			//noise field
			layout.Par(5);
			layout.Field<float>(ref clusterNoiseScale, "Noise Scale");
			layout.Toggle(ref smoothFallof, "Smooth Fallof");

			//texture format
			layout.Par(5);
			layout.Toggle(ref MegaSplatOutput.formatARGB, "ARGB (since MS 1.14)");

			//gathering cluster names
			if (clusterNames.Length != textureList.clusters.Length)
				clusterNames = new string[textureList.clusters.Length];
			for (int i=0; i<clusterNames.Length; i++)
				clusterNames[i] = textureList.clusters[i].name;

			//drawing layers
			layout.Par(5);
			layout.Label("Layers:"); //needed to reset label bold style
			layout.margin = 20;
			layout.rightMargin = 20; 

			for (int i=baseLayers.Length-1; i>=0; i--)
			{
				if (baseLayers[i] == null)
					baseLayers[i] = new Layer();
			
				if (layout.DrawWithBackground(OnLayerGUI, active:i==selected, num:i, frameDisabled:false)) selected = i;
			}

			layout.Par(3); layout.Par();
			layout.DrawArrayAdd(ref baseLayers, ref selected, layout.Inset(0.25f));
			layout.DrawArrayRemove(ref baseLayers, ref selected, layout.Inset(0.25f));
			layout.DrawArrayUp(ref baseLayers, ref selected, layout.Inset(0.25f), reverseOrder:true);
			layout.DrawArrayDown(ref baseLayers, ref selected, layout.Inset(0.25f), reverseOrder:true);

			 //drawing effect layers
			layout.Par(5);
		 
			layout.Par(20); 
			wetnessIn.DrawIcon(layout);
			layout.Label("Wetness", layout.Inset());

			layout.Par(20); 
			puddlesIn.DrawIcon(layout);
			layout.Label("Puddles", layout.Inset());

			layout.Par(20); 
			displaceDampenIn.DrawIcon(layout);
			layout.Label("Displace Dampen", layout.Inset());

			#else

			layout.margin = 5;
			layout.rightMargin = 5;

			layout.Par(65);
			layout.Label("MegaSplat is not installed. Please install it from the Asset Store, it's really amazing, you'll like it..\n\t   Jason Booth", rect:layout.Inset(), helpbox:true);

			//What about adding a link to MegaSplat asset store page? Denis

			layout.Par(30);
			layout.Label("Restart Unity if you have just installed it.", rect:layout.Inset(), helpbox:true);

			#endif
		}
Exemple #5
0
		public static void Process(CoordRect rect, Chunk.Results results, GeneratorsAsset gens, Chunk.Size terrainSize, Func<float,bool> stop = null)
		{
			#if __MEGASPLAT__
			if (stop!=null && stop(0)) return;

			//using the first texture list for all
			MegaSplatTextureList textureList = null;
			bool smoothFallof = false;
         float clusterScale = 0.05f;
			foreach (MegaSplatOutput gen in gens.GeneratorsOfType<MegaSplatOutput>(onlyEnabled: true, checkBiomes: true))
			{
				if (gen.textureList != null) textureList = gen.textureList;
				smoothFallof = gen.smoothFallof;
            clusterScale = gen.clusterNoiseScale;
			}

			//creating color arrays
			MegaSplatData result = new MegaSplatData();

			result.control = new Color[MapMagic.instance.resolution * MapMagic.instance.resolution];
			result.param = new Color[MapMagic.instance.resolution * MapMagic.instance.resolution];
			
			//creating all and special layers/biomes lists
			List<Layer> allLayers = new List<Layer>(); //all layers count = gen num * layers num in each gen (excluding empty biomes, matrices, etc)
			List<Matrix> allMatrices = new List<Matrix>();
			List<Matrix> allBiomeMasks = new List<Matrix>();

			List<Matrix> specialWetnessMatrices = new List<Matrix>(); //special count = number of generators (excluding empty biomes only)
			List<Matrix> specialPuddlesMatrices = new List<Matrix>();
			List<Matrix> specialDampeningMatrices = new List<Matrix>();
			List<Matrix> specialBiomeMasks = new List<Matrix>();

			//filling all layers/biomes
			foreach (MegaSplatOutput gen in gens.GeneratorsOfType<MegaSplatOutput>(onlyEnabled: true, checkBiomes: true))
			{
				gen.textureList = textureList;

				//loading biome matrix
				Matrix biomeMask = null;
				if (gen.biome != null)
				{
					object biomeMaskObj = gen.biome.mask.GetObject(results);
					if (biomeMaskObj == null) continue; //adding nothing if biome has no mask
					biomeMask = (Matrix)biomeMaskObj;
					if (biomeMask == null) continue;
					if (biomeMask.IsEmpty()) continue; //optimizing empty biomes
				}

				for (int i = 0; i < gen.baseLayers.Length; i++)
				{
					//reading output directly
					Output output = gen.baseLayers[i].output;
					if (stop!=null && stop(0)) return; //checking stop before reading output
					if (!results.results.ContainsKey(output)) continue;
					Matrix matrix = (Matrix)results.results[output];
					if (matrix.IsEmpty()) continue;

					if (i >= textureList.clusters.Length)
					{
						Debug.LogError("Cluster out of range");
						continue;
					}

					//adding to lists
					allLayers.Add(gen.baseLayers[i]);
					allMatrices.Add(matrix);
					allBiomeMasks.Add(gen.biome == null ? null : biomeMask);
				}

				//adding special
				object wetnessObj = gen.wetnessIn.GetObject(results);
				specialWetnessMatrices.Add( wetnessObj!=null? (Matrix)wetnessObj : null );

				object puddlesObj = gen.puddlesIn.GetObject(results);
				specialPuddlesMatrices.Add( puddlesObj!=null? (Matrix)puddlesObj : null );

				object dampeingObj = gen.displaceDampenIn.GetObject(results);
				specialDampeningMatrices.Add( dampeingObj!=null? (Matrix)dampeingObj : null );

				specialBiomeMasks.Add(gen.biome == null ? null : biomeMask);
			}

			//if no texture list found in any of generators - returning
			if (textureList == null || allLayers.Count==0) return;

			//processing
			int allLayersCount = allLayers.Count;
			int specialCount = specialWetnessMatrices.Count;
			for (int x = 0; x<rect.size.x; x++)
				for (int z = 0; z<rect.size.z; z++)
				{
					int pos = rect.GetPos(x + rect.offset.x, z + rect.offset.z);

					// doesn't use height, normal, but I'm not sure how to get that here..
					Vector3 worldPos = new Vector3(
						1f * (x+rect.offset.x) / MapMagic.instance.resolution * rect.size.x,
						0,
						1f * (z+rect.offset.z) / MapMagic.instance.resolution * rect.size.z);
					float heightRatio = results.heights!=null? results.heights.array[pos] : 0.5f; //0 is the bottom point, 1 is the maximum top
					Vector3 normal = new Vector3(0,1,0);

					// find highest two layers
					int botIdx = 0;
					int topIdx = 0;
					float botWeight = 0;
					float topWeight = 0;

					for (int i = 0; i<allLayersCount; i++)
					{
						float val = allMatrices[i].array[pos];
						if (allBiomeMasks[i] != null) val *= allBiomeMasks[i].array[pos];

						// really want world position, Normal, and height ratio for brushes, but for now, just use x/z..

						if (val > botWeight)
						{
							topWeight = botWeight;
							topIdx = botIdx;

							botWeight = val;
							botIdx = i;
						}
						else if (val > topWeight)
						{
							topIdx = i;
							topWeight = val;
						}
					}

					//converting layer index to texture index
               topIdx = textureList.clusters[ allLayers[topIdx].index ].GetIndex(worldPos *  clusterScale, normal, heightRatio);
               botIdx = textureList.clusters[ allLayers[botIdx].index ].GetIndex(worldPos * clusterScale, normal, heightRatio);

					//swapping indexes to make topIdx always on top
					if (botIdx > topIdx) 
					{
						int tempIdx = topIdx;
						topIdx = botIdx;
						botIdx = tempIdx;

						float tempWeight = topWeight;
						topWeight = botWeight;
						botWeight = tempWeight;
					}

					//finding blend
					float totalWeight = topWeight + botWeight;	if (totalWeight<0.01f) totalWeight = 0.01f; //Mathf.Max and Clamp are slow
					float blend = botWeight / totalWeight;		if (blend>1) blend = 1;

					//adjusting blend curve
					if (smoothFallof) blend = (Mathf.Sqrt(blend) * (1-blend)) + blend*blend*blend;  //Magic secret formula! Inverse to 3*x^2 - 2*x^3

					//setting color
					result.control[pos] = new Color(botIdx / 255.0f, topIdx / 255.0f, 1.0f - blend, 1.0f);

					//params
					for (int i = 0; i<specialCount; i++)
					{
						float biomeVal = specialBiomeMasks[i]!=null? specialBiomeMasks[i].array[pos] : 1;

						if (specialWetnessMatrices[i]!=null) result.param[pos].b = specialWetnessMatrices[i].array[pos] * biomeVal;
						if (specialPuddlesMatrices[i]!=null) 
						{
							result.param[pos].a = specialPuddlesMatrices[i].array[pos] * biomeVal;
							result.param[pos].r = 0.5f;
							result.param[pos].g = 0.5f;
						}
						if (specialDampeningMatrices[i]!=null) result.control[pos].a = specialDampeningMatrices[i].array[pos] * biomeVal;
					}
						
				}
			
			//pushing to apply
			if (stop!=null && stop(0))
				return;
			results.apply.CheckAdd(typeof(MegaSplatOutput), result, replace: true);
			#endif
		}
        public static Color[] BlendMegaSplat(Area area, Matrix heights, MegaSplatTextureList textureList,
                                             Matrix[] matrices, Matrix[] biomeMasks, float[] opacities, int[] channelNums,
                                             StopToken stop = null)
        {
            CoordRect activeRect = area.active.rect;

            Color[] controlMap = new Color[activeRect.Count];

            //getting matrices rect
            CoordRect matrixRect = new CoordRect(0, 0, 0, 0);

            for (int m = 0; m < matrices.Length; m++)
            {
                if (matrices[m] != null)
                {
                    matrixRect = matrices[m].rect;
                }
            }

            //checking rect
            for (int m = 0; m < matrices.Length; m++)
            {
                if (matrices[m] != null && matrices[m].rect != matrixRect)
                {
                    throw new System.Exception("MapMagic: Matrix rect mismatch");
                }
            }
            for (int b = 0; b < biomeMasks.Length; b++)
            {
                if (biomeMasks[b] != null && biomeMasks[b].rect != matrixRect)
                {
                    throw new System.Exception("MapMagic: Biome matrix rect mismatch");
                }
            }

            //preparing row re-use array
            float[] values = new float[matrices.Length];

            //blending

            for (int x = 0; x < activeRect.size.x; x++)
            {
                for (int z = 0; z < activeRect.size.z; z++)
                {
                    int matrixPosX = activeRect.offset.x + x;
                    int matrixPosZ = activeRect.offset.z + z;
                    int matrixPos  = (matrixPosZ - matrixRect.offset.z) * matrixRect.size.x + matrixPosX - matrixRect.offset.x;

                    int colorsPos = z * activeRect.size.x + x;                   //(z-colorsRect.offset.z)*colorsRect.size.x + x - colorsRect.offset.x;

                    // find highest two layers
                    int   botOutputIdx = 0;
                    int   topOutputIdx = 0;
                    float botWeight    = 0;
                    float topWeight    = 0;

                    for (int i = 0; i < matrices.Length; i++)
                    {
                        //value
                        float val = matrices[i].arr[matrixPos];

                        //multiply with biome
                        Matrix biomeMask = biomeMasks[i];
                        if (biomeMask != null)                         //no empty biomes in list (so no mask == root biome)
                        {
                            val *= biomeMask.arr[matrixPos];           //if mask is not assigned biome was ignored, so only main outs with mask==null left here
                        }
                        //clamp
                        if (val < 0)
                        {
                            val = 0;
                        }
                        if (val > 1)
                        {
                            val = 1;
                        }

                        //finding if it's highest
                        if (val > botWeight)
                        {
                            topWeight    = botWeight;
                            topOutputIdx = botOutputIdx;

                            botWeight    = val;
                            botOutputIdx = i;
                        }

                        //or 2nd highest
                        else if (val > topWeight)
                        {
                            topOutputIdx = i;
                            topWeight    = val;
                        }
                    }


                    //converting layer index to texture index
                    int topClusterIdx = channelNums[topOutputIdx];
                    int botClusterIdx = channelNums[botOutputIdx];

                    Vector3 worldPos    = area.active.CoordToWorld(x, z);
                    float   heightRatio = heights != null? heights.arr[matrixPos] : 0.5f; //0 is the bottom point, 1 is the maximum top
                    Vector3 normal      = new Vector3(0, 1, 0);                           //TODO: get normal from matrix

                    int topTexIdx = textureList.clusters[topClusterIdx].GetIndex(worldPos * clusterNoiseScale, normal, heightRatio);
                    int botTexIdx = textureList.clusters[botClusterIdx].GetIndex(worldPos * clusterNoiseScale, normal, heightRatio);

                    //swapping indexes to make topIdx always on top

                    /*if (botIdx > topIdx)
                     * {
                     *      int tempIdx = topIdx;
                     *      topIdx = botIdx;
                     *      botIdx = tempIdx;
                     *
                     *      float tempWeight = topWeight;
                     *      topWeight = botWeight;
                     *      botWeight = tempWeight;
                     * }*/

                    //finding blend
                    float totalWeight = topWeight + botWeight;      if (totalWeight < 0.01f)
                    {
                        totalWeight = 0.01f;                                                                                        //Mathf.Max and Clamp are slow
                    }
                    float blend = botWeight / totalWeight;          if (blend > 1)
                    {
                        blend = 1;
                    }

                    //adjusting blend curve
                    if (smoothFallof)
                    {
                        blend = (Mathf.Sqrt(blend) * (1 - blend)) + blend * blend * blend;                              //Magic secret formula! Inverse to 3*x^2 - 2*x^3
                    }
                    //setting color
                    controlMap[colorsPos] = new Color(botTexIdx / 255.0f, topTexIdx / 255.0f, 1.0f - blend, 1.0f);

                    //params

                    /*for (int i = 0; i<specialCount; i++)
                     * {
                     *      float biomeVal = specialBiomeMasks[i]!=null? specialBiomeMasks[i].array[pos] : 1;
                     *
                     *      if (specialWetnessMatrices[i]!=null) result.param[pos].b = specialWetnessMatrices[i].array[pos] * biomeVal;
                     *      if (specialPuddlesMatrices[i]!=null)
                     *      {
                     *              result.param[pos].a = specialPuddlesMatrices[i].array[pos] * biomeVal;
                     *              result.param[pos].r = 0.5f;
                     *              result.param[pos].g = 0.5f;
                     *      }
                     *      if (specialDampeningMatrices[i]!=null) result.control[pos].a = specialDampeningMatrices[i].array[pos] * biomeVal;
                     * }*/
                }
            }

            return(controlMap);
        }