public override void Generate(MapMagic.Chunk chunk) { Matrix matrix = (Matrix)input.GetObject(chunk); if (matrix != null) { matrix = matrix.Copy(null); } if (matrix == null) { matrix = chunk.defaultMatrix; } Matrix mask = (Matrix)maskIn.GetObject(chunk); if (!enabled) { output.SetObject(chunk, matrix); return; } if (chunk.stop) { return; } Noise(matrix, size, intensity, bias, detail, offset, seed, mask); if (chunk.stop) { return; //do not write object is generating is stopped } output.SetObject(chunk, matrix); }
public override void Generate(MapMagic.MapMagic.Chunk chunk) { Matrix src = (Matrix)input.GetObject(chunk); if (src == null || chunk.stop) { return; } if (!enabled) { output.SetObject(chunk, src); return; } Matrix dst = new Matrix(src.rect); Coord min = src.rect.Min; Coord max = src.rect.Max; for (int x = min.x; x < max.x; x++) { for (int z = min.z; z < max.z; z++) { float val = level - src[x, z]; dst[x, z] = val > 0? val : 0; } } if (chunk.stop) { return; } output.SetObject(chunk, dst); }
public override void Generate(MapMagic.Chunk chunk) { //getting input Matrix matrix = (Matrix)input.GetObject(chunk); //return on stop/disable/null input if (chunk.stop || !enabled || matrix == null) { return; } //preparing outputs Matrix result = new Matrix(matrix.rect); Matrix temp = new Matrix(matrix.rect); //cavity System.Func <float, float, float, float> cavityFn = delegate(float prev, float curr, float next) { float c = curr - (next + prev) / 2; return((c * c * (c > 0?1:-1)) * intensity * 100000); }; result.Blur(cavityFn, intensity: 1, additive: true, reference: matrix); //intensity is set in func if (chunk.stop) { return; } //borders result.RemoveBorders(); if (chunk.stop) { return; } //spread result.Spread(strength: spread, copy: temp); if (chunk.stop) { return; } //clamping and inverting for (int i = 0; i < result.count; i++) { temp.array[i] = 0; if (result.array[i] < 0) { temp.array[i] = -result.array[i]; result.array[i] = 0; } } //setting outputs if (chunk.stop) { return; } convexOut.SetObject(chunk, result); concaveOut.SetObject(chunk, temp); }
public override void Generate(MapMagic.Chunk chunk) { //getting input Matrix matrix = (Matrix)input.GetObject(chunk); //return on stop/disable/null input if (chunk.stop || !enabled || matrix == null) { return; } //preparing output Matrix result = new Matrix(matrix.rect); //using the terain-height relative values float dist = range; float start = steepness - dist / 4; //4, not 2 because blurring is additive //transforming to 0-1 range start = start / MapMagic.instance.terrainHeight; dist = dist / MapMagic.instance.terrainHeight; //incline System.Func <float, float, float, float> inclineFn = delegate(float prev, float curr, float next) { float prevDelta = prev - curr; if (prevDelta < 0) { prevDelta = -prevDelta; } float nextDelta = next - curr; if (nextDelta < 0) { nextDelta = -nextDelta; } float delta = prevDelta > nextDelta? prevDelta : nextDelta; delta *= 1.8f; //for backwards compatibility float val = (delta - start) / dist; if (val < 0) { val = 0; } if (val > 1) { val = 1; } return(val); }; result.Blur(inclineFn, intensity: 1, additive: true, reference: matrix); //intensity is set in func //setting output if (chunk.stop) { return; } output.SetObject(chunk, result); }
public object GetObject(MapMagic.Chunk tw, bool write) { if (link == null) { return(null); } if (!tw.results.ContainsKey(link)) { return(null); } return(tw.results[link]); }
public void GenerateRecursive(MapMagic.Chunk tw) { //generating input generators foreach (Input input in Inputs()) { if (input.linkGen == null) { continue; } if (tw.stop) { return; //before entry stop } input.linkGen.GenerateRecursive(tw); } if (tw.stop) { return; //before generate stop for time economy } //generating this if (!tw.ready.Contains(this)) { //starting timer if (MapMagic.instance.guiDebug) { if (timer == null) { timer = new System.Diagnostics.Stopwatch(); } else { timer.Reset(); } timer.Start(); } Generate(tw); if (!tw.stop) { tw.ready.Add(this); } //stopping timer if (timer != null) { timer.Stop(); } } }
public override void Generate(MapMagic.Chunk chunk) { Matrix matrix = chunk.defaultMatrix; if (!enabled || textureMatrix == null) { output.SetObject(chunk, matrix); return; } if (chunk.stop) { return; } //matrix = textureMatrix.Resize(matrix.rect); CoordRect scaledRect = new CoordRect( (int)(offset.x * MapMagic.instance.resolution / MapMagic.instance.terrainSize), (int)(offset.y * MapMagic.instance.resolution / MapMagic.instance.terrainSize), (int)(matrix.rect.size.x * scale), (int)(matrix.rect.size.z * scale)); Matrix scaledTexture = textureMatrix.Resize(scaledRect); matrix.Replicate(scaledTexture, tile: tile); matrix.Multiply(intensity); if (scale > 1) { Matrix cpy = matrix.Copy(); for (int i = 0; i < scale - 1; i++) { matrix.Blur(); } Matrix.SafeBorders(cpy, matrix, Mathf.Max(matrix.rect.size.x / 128, 4)); } //if (tile) textureMatrix.FromTextureTiled(texture); //else textureMatrix.FromTexture(texture); //if (!Mathf.Approximately(scale,1)) textureMatrix = textureMatrix.Resize(matrix.rect, result:matrix);*/ if (chunk.stop) { return; } output.SetObject(chunk, matrix); }
public void SetObject(MapMagic.Chunk terrain, object obj) //TODO: maybe better replace with CheckAdd { if (terrain.results.ContainsKey(this)) { if (obj == null) { terrain.results.Remove(this); } else { terrain.results[this] = obj; } } else { if (obj != null) { terrain.results.Add(this, obj); } } }
public void DrawIcon(Layout layout, bool drawLabel = true) { string textureName = ""; switch (type) { case InoutType.Map: textureName = "MapMagicMatrix"; break; case InoutType.Objects: textureName = "MapMagicScatter"; break; case InoutType.Spline: textureName = "MapMagicSpline"; break; } guiRect = new Rect(layout.field.x + layout.field.width - 18 + 5, layout.cursor.y + layout.field.y, 18, 18); if (drawLabel) { Rect nameRect = guiRect; nameRect.width = 100; nameRect.x -= 103; layout.Label(guiName, nameRect, textAnchor: TextAnchor.LowerRight, fontSize: 10); } layout.Icon(textureName, guiRect); //detail:resolution.ToString()); //drawing obj id if (MapMagic.instance.guiDebug) { Rect idRect = guiRect; idRect.width = 100; idRect.x += 25; MapMagic.Chunk closest = MapMagic.instance.terrains.GetClosestObj(new Coord(0, 0)); if (closest != null) { object obj = closest.results.CheckGet(this); layout.Label(obj != null? obj.GetHashCode().ToString() : "null", idRect, textAnchor: TextAnchor.LowerLeft); } } }
public void CheckClearRecursive(MapMagic.Chunk tw) //checks if prior generators were clearied, and if they were - clearing this one { //if (!tw.ready.Contains(this)) //TODO: optimize here foreach (Input input in Inputs()) { if (input.linkGen == null) { continue; } //recursive first input.linkGen.CheckClearRecursive(tw); //checking if clear if (!tw.ready.Contains(input.linkGen)) { if (tw.ready.Contains(this)) { tw.ready.Remove(this); } //break; do not break, go on checking in case of branching-then-connecting } } }
public void DrawSelectionFrame (Coord coord, float width=3f) { float margins = 3; int numSteps = 50; float sideSize = MapMagic.instance.terrainSize - margins*2f; float stepDist = sideSize / numSteps; Vector3 start = coord.ToVector3(MapMagic.instance.terrainSize) + new Vector3(margins,0,margins) + MapMagic.instance.transform.position; MapMagic.Chunk terrain = MapMagic.instance.terrains[coord]; if (terrain==null) { Handles.DrawAAPolyLine( width, new Vector3[] { start, start+new Vector3(sideSize,0,0), start+new Vector3(sideSize,0,sideSize), start+new Vector3(0,0,sideSize), start} ); } else { DrawLineOnTerrain(terrain.terrain, start, new Vector3(stepDist,0,0), numSteps+1, width); DrawLineOnTerrain(terrain.terrain, start+new Vector3(0,0,sideSize), new Vector3(stepDist,0,0), numSteps+1, width); DrawLineOnTerrain(terrain.terrain, start, new Vector3(0,0,stepDist), numSteps+1, width); DrawLineOnTerrain(terrain.terrain, start+new Vector3(sideSize,0,0), new Vector3(0,0,stepDist), numSteps+1, width); } }
public override void Generate(MapMagic.Chunk chunk) { Matrix matrix = (Matrix)input.GetObject(chunk); if (matrix != null) { matrix = matrix.Copy(null); } if (matrix == null) { matrix = chunk.defaultMatrix; } Matrix mask = (Matrix)maskIn.GetObject(chunk); if (chunk.stop) { return; } if (!enabled || intensity == 0 || cellCount == 0) { output.SetObject(chunk, matrix); return; } //NoiseGenerator.Noise(matrix,200,0.5f,Vector2.zero); //matrix.Multiply(amount); InstanceRandom random = new InstanceRandom(MapMagic.instance.seed + seed); //creating point matrix float cellSize = 1f * matrix.rect.size.x / cellCount; Matrix2 <Vector3> points = new Matrix2 <Vector3>(new CoordRect(0, 0, cellCount + 2, cellCount + 2)); points.rect.offset = new Coord(-1, -1); Coord matrixSpaceOffset = new Coord((int)(matrix.rect.offset.x / cellSize), (int)(matrix.rect.offset.z / cellSize)); //scattering points for (int x = -1; x < points.rect.size.x - 1; x++) { for (int z = -1; z < points.rect.size.z - 1; z++) { Vector3 randomPoint = new Vector3(x + random.CoordinateRandom(x + matrixSpaceOffset.x, z + matrixSpaceOffset.z), 0, z + random.NextCoordinateRandom()); Vector3 centerPoint = new Vector3(x + 0.5f, 0, z + 0.5f); Vector3 point = randomPoint * (1 - uniformity) + centerPoint * uniformity; point = point * cellSize + new Vector3(matrix.rect.offset.x, 0, matrix.rect.offset.z); point.y = random.NextCoordinateRandom(); points[x, z] = point; } } Coord min = matrix.rect.Min; Coord max = matrix.rect.Max; for (int x = min.x; x < max.x; x++) { for (int z = min.z; z < max.z; z++) { //finding current cell Coord cell = new Coord((int)((x - matrix.rect.offset.x) / cellSize), (int)((z - matrix.rect.offset.z) / cellSize)); //finding min dist float minDist = 200000000; float secondMinDist = 200000000; float minHeight = 0; //float secondMinHeight = 0; for (int ix = -1; ix <= 1; ix++) { for (int iz = -1; iz <= 1; iz++) { Coord nearCell = new Coord(cell.x + ix, cell.z + iz); //if (!points.rect.CheckInRange(nearCell)) continue; //no need to perform test as points have 1-cell border around matrix Vector3 point = points[nearCell]; float dist = (x - point.x) * (x - point.x) + (z - point.z) * (z - point.z); if (dist < minDist) { secondMinDist = minDist; minDist = dist; minHeight = point.y; } else if (dist < secondMinDist) { secondMinDist = dist; } } } float val = 0; switch (blendType) { case BlendType.flat: val = minHeight; break; case BlendType.closest: val = minDist / (MapMagic.instance.resolution * 16); break; case BlendType.secondClosest: val = secondMinDist / (MapMagic.instance.resolution * 16); break; case BlendType.cellular: val = (secondMinDist - minDist) / (MapMagic.instance.resolution * 16); break; case BlendType.organic: val = (secondMinDist + minDist) / 2 / (MapMagic.instance.resolution * 16); break; } if (mask == null) { matrix[x, z] += val * intensity; } else { matrix[x, z] += val * intensity * mask[x, z]; } } } if (chunk.stop) { return; //do not write object is generating is stopped } output.SetObject(chunk, matrix); }
public override void Generate(MapMagic.Chunk chunk) { }
public void OnSceneGUI () { if (script == null) script = (MapMagic)target; MapMagic.instance = script; if (!script.enabled) return; script.terrains.CheckEmpty(); #region Drawing Selection //drawing frames foreach(Coord coord in MapMagic.instance.terrains.Coords()) { Handles.color = nailColor*0.8f; if (MapMagic.instance.terrains[coord].locked) Handles.color = lockColor*0.8f; DrawSelectionFrame(coord, 5f); } #endregion #region Selecting terrains if (selectionMode==SelectionMode.nailing || selectionMode==SelectionMode.locking) { //disabling selection HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive)); //finding aiming ray Vector2 mousePos = Event.current.mousePosition; mousePos.y = Screen.height - mousePos.y - 40; Camera cam = UnityEditor.SceneView.lastActiveSceneView.camera; if (cam==null) return; Ray aimRay = cam.ScreenPointToRay(mousePos); //aiming terrain or empty place Vector3 aimPos = Vector3.zero; RaycastHit hit; if (Physics.Raycast(aimRay, out hit, Mathf.Infinity)) aimPos = hit.point; else { aimRay.direction = aimRay.direction.normalized; float aimDist = aimRay.origin.y / (-aimRay.direction.y); aimPos = aimRay.origin + aimRay.direction*aimDist; } Coord aimCoord = aimPos.FloorToCoord(MapMagic.instance.terrainSize); if (selectionMode == SelectionMode.nailing) { //drawing selection frame Handles.color = nailColor; DrawSelectionFrame(aimCoord, width:5f); //selecting / unselecting if (Event.current.type == EventType.MouseDown && Event.current.button == 0) { if (MapMagic.instance.terrains[aimCoord]==null) //if obj not exists - nail { Undo.RegisterFullObjectHierarchyUndo(MapMagic.instance, "MapMagic Pin Terrain"); MapMagic.instance.terrains.Nail(aimCoord); //MapMagic.instance.terrains.maxCount++; } else { Undo.DestroyObjectImmediate(MapMagic.instance.terrains[aimCoord].terrain.gameObject); Undo.RecordObject(MapMagic.instance, "MapMagic Unpin Terrain"); MapMagic.instance.setDirty = !MapMagic.instance.setDirty; MapMagic.instance.terrains.Unnail(aimCoord); //MapMagic.instance.terrains.maxCount--; } //if (MapMagic.instance.terrains.maxCount < MapMagic.instance.terrains.nailedHashes.Count+4) MapMagic.instance.terrains.maxCount = MapMagic.instance.terrains.nailedHashes.Count+4; //EditorUtility.SetDirty(MapMagic.instance); //already done via undo } } if (selectionMode == SelectionMode.locking) { MapMagic.Chunk aimedTerrain = MapMagic.instance.terrains[aimCoord]; if (aimedTerrain != null) { //drawing selection frame Handles.color = lockColor; DrawSelectionFrame(aimCoord, width:5f); //selecting / unselecting if (Event.current.type == EventType.MouseDown && Event.current.button == 0) { Undo.RecordObject(MapMagic.instance, "MapMagic Lock Terrain"); MapMagic.instance.setDirty = !MapMagic.instance.setDirty; aimedTerrain.locked = !aimedTerrain.locked; //EditorUtility.SetDirty(MapMagic.instance); //already done via undo } } } //redrawing scene by moving temp object if (script.sceneRedrawObject==null) { script.sceneRedrawObject = new GameObject(); script.sceneRedrawObject.hideFlags = HideFlags.HideInHierarchy; } script.sceneRedrawObject.transform.position = aimPos; } #endregion }
public object GetObject(MapMagic.Chunk tw) { return(GetObject(tw, write: write)); }
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); }
public abstract void Generate(MapMagic.Chunk terrain);