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); }
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); }
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); }