Exemplo n.º 1
0
			public void Pour (float[,] array, CoordRect arrayRect) //using swapped x and z!
			{
				//arrayRect.z should be equal to array.GetLength(0), and arrayRect.x to array.GetLength(1)
				CoordRect intersection = CoordRect.Intersect(rect, arrayRect);
				Coord min = intersection.Min; Coord max = intersection.Max;
				for (int x=min.x; x<max.x; x++)
					for (int z=min.z; z<max.z; z++)
						array[z-arrayRect.offset.z,x-arrayRect.offset.x] = this[x,z];
			}
			/*public Vector2 GetAreaNormal (int cx, int cz, int range)
			{
				CoordRect areaRect = new CoordRect(cx-range-1, cz-range-1, cx+range, cz+range);
				CoordRect intersection = CoordRect.Intersect(rect, areaRect);

				float nx = 0; float nz = 0;

				Coord min = intersection.Min; Coord max = intersection.Max;
				for (int x=min.x; x<max.x; x++)
					for (int z=min.z; z<max.z; z++)
				{
					nx += 
				}

			}*/

		#endregion

		#region Sorting

			// ???
			public bool[] InRect (CoordRect area = new CoordRect())
			{
				Matrix2<bool> result = new Matrix2<bool>(rect);
				CoordRect intersection = CoordRect.Intersect(rect,area);
				Coord min = intersection.Min; Coord max = intersection.Max;
				for (int x=min.x; x<max.x; x++)
					for (int z=min.z; z<max.z; z++)
						result[x,z] = true;
				return result.array;
			}
			static public void AddSplatmaps (TerrainData data, Matrix[] matrices, int[] channels, float[] opacity, float[,,] array=null, float brushFallof=0.5f)
			{
				int numChannels = data.alphamapLayers;
				bool[] usedChannels = new bool[numChannels];
				for (int i=0; i<channels.Length; i++) usedChannels[channels[i]] = true;
				float[] slice = new float[numChannels];

				Coord dataSize = new Coord(data.alphamapResolution, data.alphamapResolution);
				CoordRect dataRect = new CoordRect(new Coord(0,0), dataSize);
				CoordRect intersection = CoordRect.Intersect(dataRect, matrices[0].rect);
				
				if (array==null) array = data.GetAlphamaps(intersection.offset.x, intersection.offset.z, intersection.size.x, intersection.size.z);

				Coord min = intersection.Min; Coord max = intersection.Max;
				for (int x=min.x; x<max.x; x++)
					for (int z=min.z; z<max.z; z++)
				{
					//calculating fallof and opacity
					float fallofFactor = matrices[0].Fallof(x,z,brushFallof);
					if (Mathf.Approximately(fallofFactor,0)) continue;

					//reading slice
					for (int c=0; c<numChannels; c++) slice[c] = array[z-min.z, x-min.x, c];

					//converting matrices to additive
					for (int i=0; i<matrices.Length; i++) matrices[i][x,z] = Mathf.Max(0, matrices[i][x,z] - slice[channels[i]]);

					//apply fallof
					for (int i=0; i<matrices.Length; i++) matrices[i][x,z] *= fallofFactor * opacity[i];

					//calculating sum of adding values
					float addedSum = 0; //the sum of adding channels
					for (int i=0; i<matrices.Length; i++) addedSum += matrices[i][x,z];
					//if (addedSum < 0.00001f) continue; //no need to do anything

					//if addedsum exceeds 1 - equalizing matrices
					if (addedSum > 1f) 
						{ for (int i=0; i<matrices.Length; i++) matrices[i][x,z] /= addedSum; addedSum=1; }

					//multiplying all values on a remaining amount
					float multiplier = 1-addedSum;
					for (int c=0; c<numChannels; c++) slice[c] *= multiplier;

					//adding matrices
					for (int i=0; i<matrices.Length; i++) slice[channels[i]] += matrices[i][x,z];

					//saving slice
					for (int c=0; c<numChannels; c++) array[z-min.z, x-min.x, c] = slice[c];
				}

				data.SetAlphamaps(intersection.offset.x, intersection.offset.z, array);
			}
Exemplo n.º 4
0
        public void Fill(Matrix2 <T> m, bool removeBorders = false)
        {
            CoordRect intersection = CoordRect.Intersect(rect, m.rect);
            Coord     min = intersection.Min; Coord max = intersection.Max;

            for (int x = min.x; x < max.x; x++)
            {
                for (int z = min.z; z < max.z; z++)
                {
                    this[x, z] = m[x, z];
                }
            }
            if (removeBorders)
            {
                RemoveBorders(intersection);
            }
        }
			/*public void FromTexture (Texture2D texture, Coord textureOffset=new Coord(), bool fillBorders=false)
			{
				Coord textureSize = new Coord(texture.width, texture.height);
				CoordRect textureRect = new CoordRect(textureOffset, textureSize);
				CoordRect intersection = CoordRect.Intersect(textureRect, rect);

				Color[] colors = texture.GetPixels(intersection.offset.x - textureOffset.x, intersection.offset.z - textureOffset.z, intersection.size.x, intersection.size.z);

				Coord min = intersection.Min; Coord max = intersection.Max;
				for (int x=min.x; x<max.x; x++)
					for (int z=min.z; z<max.z; z++)
				{
					int tx = x-min.x; int tz = z-min.z;
					Color col = colors[tz*(max.x-min.x) + tx];

					this[x,z] = (col.r+col.g+col.b)/3;
				}

				if (fillBorders) RemoveBorders(intersection);
			}*/

			public void FromTexture (Texture2D texture)
			{
				CoordRect textureRect = new CoordRect(0,0, texture.width, texture.height);
				CoordRect intersection = CoordRect.Intersect(textureRect, rect);

				Color[] colors = texture.GetPixels(intersection.offset.x, intersection.offset.z, intersection.size.x, intersection.size.z);

				Coord min = intersection.Min; Coord max = intersection.Max;
				for (int x=min.x; x<max.x; x++)
					for (int z=min.z; z<max.z; z++)
				{
					int tx = x-min.x; int tz = z-min.z;
					Color col = colors[tz*(max.x-min.x) + tx];

					this[x,z] = (col.r+col.g+col.b)/3;
				}
			}
			public float[,,] ReadSplatmap (TerrainData data, int channel, float[,,] array=null)
			{
				CoordRect intersection = CoordRect.Intersect(rect, new CoordRect(0,0,data.alphamapResolution, data.alphamapResolution));
				
				//get heights
				if (array==null) array = data.GetAlphamaps(intersection.offset.x, intersection.offset.z, intersection.size.x, intersection.size.z); //returns x and z swapped

				//reading array
				Coord min = intersection.Min; Coord max = intersection.Max;
				for (int x=min.x; x<max.x; x++)
					for (int z=min.z; z<max.z; z++)
						this[x,z] = array[z-min.z, x-min.x, channel];

				//removing borders
				RemoveBorders(intersection);

				return array;
			}
			public float[,] ReadHeighmap (TerrainData data, float height=1)
			{
				CoordRect intersection = CoordRect.Intersect(rect, new CoordRect(0,0,data.heightmapResolution, data.heightmapResolution));
				
				//get heights
				float[,] array = data.GetHeights(intersection.offset.x, intersection.offset.z, intersection.size.x, intersection.size.z); //returns x and z swapped

				//reading 2d array
				Coord min = intersection.Min; Coord max = intersection.Max;
				for (int x=min.x; x<max.x; x++)
					for (int z=min.z; z<max.z; z++)
						this[x,z] = array[z-min.z, x-min.x] * height;

				//removing borders
				RemoveBorders(intersection);

				return array;
			}
			public void ToTexture (Texture2D texture=null, Color[] colors=null, float rangeMin=0, float rangeMax=1, bool resizeTexture=false)
			{
				//creating or resizing texture
				if (texture == null) texture = new Texture2D(rect.size.x, rect.size.z);
				if (resizeTexture) texture.Resize(rect.size.x, rect.size.z);
				
				//finding matrix-texture intersection
				Coord textureSize = new Coord(texture.width, texture.height);
				CoordRect textureRect = new CoordRect(new Coord(0,0), textureSize);
				CoordRect intersection = CoordRect.Intersect(textureRect, rect);
				
				//checking ref color array
				if (colors == null || colors.Length != intersection.size.x*intersection.size.z) colors = new Color[intersection.size.x*intersection.size.z];

				//filling texture
				Coord min = intersection.Min; Coord max = intersection.Max;
				for (int x=min.x; x<max.x; x++)
					for (int z=min.z; z<max.z; z++)
				{
					float val = this[x,z];

					//adjusting value to range
					val -= rangeMin;
					val /= rangeMax-rangeMin;

					//making color gradient
					float byteVal = val * 256;
					int flooredByteVal = (int)byteVal;
					float remainder = byteVal - flooredByteVal;

					float flooredVal = flooredByteVal/256f;
					float ceiledVal = (flooredByteVal+1)/256f;
					
					//saving to colors
					int tx = x-min.x; int tz = z-min.z;
					colors[tz*(max.x-min.x) + tx] = new Color(flooredVal, remainder>0.333f ? ceiledVal : flooredVal, remainder>0.666f ? ceiledVal : flooredVal);
				}
			
				texture.SetPixels(intersection.offset.x, intersection.offset.z, intersection.size.x, intersection.size.z, colors);
				texture.Apply();
			}
			public void WriteHeightmap (TerrainData data, float[,] array=null, float brushFallof=0.5f, bool delayLod=false)
			{
				CoordRect intersection = CoordRect.Intersect(rect, new CoordRect(0,0,data.heightmapResolution, data.heightmapResolution));
				
				//checking ref array
				if (array == null || array.Length != intersection.size.x*intersection.size.z) array = new float[intersection.size.z,intersection.size.x]; //x and z swapped

				//write to 2d array
				Coord min = intersection.Min; Coord max = intersection.Max;
				for (int x=min.x; x<max.x; x++)
					for (int z=min.z; z<max.z; z++)
				{
					float fallofFactor = Fallof(x,z,brushFallof);
					if (Mathf.Approximately(fallofFactor,0)) continue;
					array[z-min.z, x-min.x] = this[x,z]*fallofFactor + array[z-min.z, x-min.x]*(1-fallofFactor);
					//array[z-min.z, x-min.x] += this[x,z];
				}

				if (delayLod) data.SetHeightsDelayLOD(intersection.offset.x, intersection.offset.z, array);
				else data.SetHeights(intersection.offset.x, intersection.offset.z, array);
			}
Exemplo n.º 10
0
        public override void Generate(MapMagic.Chunk chunk)
        {
            //getting inputs
            SpatialHash objects = (SpatialHash)objectsIn.GetObject(chunk);
            Matrix      src     = (Matrix)canvasIn.GetObject(chunk);

            //return on stop/disable/null input
            if (chunk.stop || objects == null)
            {
                return;
            }
            if (!enabled)
            {
                output.SetObject(chunk, src); return;
            }

            //preparing output
            Matrix dst;

            if (src != null)
            {
                dst = src.Copy(null);
            }
            else
            {
                dst = chunk.defaultMatrix;
            }

            //finding maximum radius
            float maxRadius = radius;

            if (sizeFactor > 0.00001f)
            {
                float maxObjSize = 0;
                foreach (SpatialObject obj in objects.AllObjs())
                {
                    if (obj.size > maxObjSize)
                    {
                        maxObjSize = obj.size;
                    }
                }
                maxObjSize = maxObjSize / MapMagic.instance.terrainSize * MapMagic.instance.resolution;                 //transforming to map-space
                maxRadius  = radius * (1 - sizeFactor) + radius * maxObjSize * sizeFactor;
            }

            //preparing procedural matrices
            Matrix noiseMatrix   = new Matrix(new CoordRect(0, 0, maxRadius * 2 + 2, maxRadius * 2 + 2));
            Matrix percentMatrix = new Matrix(new CoordRect(0, 0, maxRadius * 2 + 2, maxRadius * 2 + 2));

            foreach (SpatialObject obj in objects.AllObjs())
            {
                //finding current radius
                float curRadius = radius * (1 - sizeFactor) + radius * obj.size * sizeFactor;
                curRadius = curRadius / MapMagic.instance.terrainSize * MapMagic.instance.resolution;                 //transforming to map-space

                //resizing procedural matrices
                CoordRect matrixSize = new CoordRect(0, 0, curRadius * 2 + 2, curRadius * 2 + 2);
                noiseMatrix.ChangeRect(matrixSize);
                percentMatrix.ChangeRect(matrixSize);

                //apply stamp
                noiseMatrix.rect.offset   = new Coord((int)(obj.pos.x - curRadius - 1), (int)(obj.pos.y - curRadius - 1));
                percentMatrix.rect.offset = new Coord((int)(obj.pos.x - curRadius - 1), (int)(obj.pos.y - curRadius - 1));

                CoordRect intersection = CoordRect.Intersect(noiseMatrix.rect, dst.rect);
                Coord     min = intersection.Min; Coord max = intersection.Max;
                for (int x = min.x; x < max.x; x++)
                {
                    for (int z = min.z; z < max.z; z++)
                    {
                        float dist    = Mathf.Sqrt((x - obj.pos.x + 0.5f) * (x - obj.pos.x + 0.5f) + (z - obj.pos.y + 0.5f) * (z - obj.pos.y + 0.5f));
                        float percent = 1f - dist / curRadius;
                        if (percent < 0 || dist > curRadius)
                        {
                            percent = 0;
                        }

                        percentMatrix[x, z] = percent;
                    }
                }

                //adjusting value by curve
                Curve c = new Curve(curve);
                for (int i = 0; i < percentMatrix.array.Length; i++)
                {
                    percentMatrix.array[i] = c.Evaluate(percentMatrix.array[i]);
                }

                //adding some noise
                if (useNoise)
                {
                    NoiseGenerator.Noise(noiseMatrix, noiseSize, 0.5f, offset: Vector2.zero);

                    for (int x = min.x; x < max.x; x++)
                    {
                        for (int z = min.z; z < max.z; z++)
                        {
                            float val = percentMatrix[x, z];
                            if (val < 0.0001f)
                            {
                                continue;
                            }

                            float noise = noiseMatrix[x, z];
                            if (val < 0.5f)
                            {
                                noise *= val * 2;
                            }
                            else
                            {
                                noise = 1 - (1 - noise) * (1 - val) * 2;
                            }

                            percentMatrix[x, z] = noise * noiseAmount + val * (1 - noiseAmount);
                        }
                    }
                }

                //applying matrices
                for (int x = min.x; x < max.x; x++)
                {
                    for (int z = min.z; z < max.z; z++)
                    {
                        //float distSq = (x-obj.pos.x)*(x-obj.pos.x) + (z-obj.pos.y)*(z-obj.pos.y);
                        //if (distSq > radius*radius) continue;

                        float percent = percentMatrix[x, z];
                        dst[x, z] = (maxHeight? 1:obj.height) * percent + dst[x, z] * (1 - percent);
                    }
                }
            }

            Matrix mask = (Matrix)maskIn.GetObject(chunk);

            if (mask != null)
            {
                Matrix.Mask(src, dst, mask);
            }
            if (safeBorders != 0)
            {
                Matrix.SafeBorders(src, dst, safeBorders);
            }

            //setting output
            if (chunk.stop)
            {
                return;
            }
            output.SetObject(chunk, dst);
        }