public UndoStep(float[,] heights, float[,,] splats, int heightsOffsetX, int heightsOffsetZ, int splatsOffsetX, int splatsOffsetZ) { //clamping offset low (no need to clamp high as float[,] already has proper size) if (heightsOffsetX < 0) { heightsOffsetX = 0; } if (heightsOffsetZ < 0) { heightsOffsetZ = 0; } if (splatsOffsetX < 0) { splatsOffsetX = 0; } if (splatsOffsetZ < 0) { splatsOffsetZ = 0; } this.heightsOffsetX = heightsOffsetX; this.heightsOffsetZ = heightsOffsetZ; this.splatsOffsetX = splatsOffsetX; this.splatsOffsetZ = splatsOffsetZ; this.heights = heights.Clone() as float[, ]; if (splats != null) { this.splats = splats.Clone() as float[, , ]; } else { this.splats = null; } }
// Smooth every cell in the alphamap using squareSize neighbors in each direction public static float[,,] SmoothAlphaMap(float[,,] alphamap, int squareSize) { var result = (float[, , ])alphamap.Clone(); var length = alphamap.GetLength(0); for (var y = 0; y < length; y++) { for (var x = 0; x < length; x++) { for (var i = 0; i < alphamap.GetLength(2); i++) { var count = 0; var sum = 0.0f; for (var yN = y - squareSize; yN < y + squareSize; yN++) { for (var xN = x - squareSize; xN <= x + squareSize; xN++) { if (xN < 0 || xN >= length || yN < 0 || yN >= length) { continue; } sum += alphamap[xN, yN, i]; count++; } } result[x, y, i] = sum / count; } } } return(result); }
protected override void ProcessData() { if (ForceRetransformation || _firstTime) { _dataCube = new DataCube(); float[, ,] inputData = _input.GetDataCube().DataArray; _outputData = replaceNaNPlaceholder(inputData); if (UseInterpolation) { _untouchedData = (float[, , ])_outputData.Clone(); _outputData = interpolateDataVariables(_outputData); _interpolatedOutputData = (float[, , ])_outputData.Clone(); } _firstTime = false; } else { if (UseInterpolation) { _outputData = (float[, , ])_interpolatedOutputData.Clone(); } else { _outputData = (float[, , ])_untouchedData.Clone(); } } _dataCube.DataArray = _outputData; }
public System.Drawing.Bitmap GetVisualization(int layer) { System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(width, height); float[, ,] scaled = (float[, , ])mapActivity.Clone(); float max = float.NegativeInfinity; float min = float.PositiveInfinity; //Scale for visualization for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { scaled[x, y, layer] = (float)Math.Pow(mapActivity[x, y, layer], 2.0); min = Math.Min(scaled[x, y, layer], min); max = Math.Max(scaled[x, y, layer], max); } } for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { scaled[x, y, layer] = (scaled[x, y, layer] - min) / (max - min); } } //Build the bmp for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { System.Drawing.Color color = ColorInterpolator.InterpolateBetween(Color.Blue, Color.Yellow, Color.Red, (float)scaled[x, y, layer]); bmp.SetPixel(x, y, color); if (x == lastWinX && y == lastWinY && layer == lastWinZ) { bmp.SetPixel(x, y, Color.Red); } } } foreach (MMCM_Electrode e in electrodes) { if (e.x < width && e.x >= 0 && e.y < height && e.y >= 0 && e.z == layer) { bmp.SetPixel(e.x, e.y, Color.HotPink); } } //Console.WriteLine("Visualization computed in " + (time2 - time1).ToString()); return(bmp); }
public UndoStep(float[,] heights, float[,,] splats, int heightsOffsetX, int heightsOffsetZ, int splatsOffsetX, int splatsOffsetZ) { this.heightsOffsetX = heightsOffsetX; this.heightsOffsetZ = heightsOffsetZ; this.splatsOffsetX = splatsOffsetX; this.splatsOffsetZ = splatsOffsetZ; this.heights = heights.Clone() as float[, ]; if (splats != null) { this.splats = splats.Clone() as float[, , ]; } else { this.splats = null; } }
public TerrainModificationData(int _xIndex, int _yIndex, int _xIndex_Alpha, int _yIndex_Alpha, float[,] _heights, float [,,] _maps, int xScale_Height, int zScale_Height, int xScale_Alpha, int zScale_Alpha, Terrain _terrain) { this.xIndex_Height = _xIndex; this.yIndex_Height = _yIndex; this.xIndex_Alpha = _xIndex_Alpha; this.yIndex_Alpha = _yIndex_Alpha; this.xScale_Height = xScale_Height; this.zScale_Height = zScale_Height; this.xScale_Alpha = xScale_Alpha; this.zScale_Alpha = zScale_Alpha; this.heights = _heights; this.maps = _maps; if (maps != null) { originalMaps = (float[, , ])maps.Clone(); } this.terrain = _terrain; }
private void DoRotate(float angle, Terrain newTerrain) { if (terrainTmp == null || origHeightMap == null) { grabOriginal = false; Debug.LogWarning("No terrain to rotate"); return; } isRotating = true; //Terrain terrain = o.GetComponent<Terrain>(); int nx, ny; float cs, sn; // heightmap rotation int tw = terrainTmp.terrainData.heightmapWidth; int th = terrainTmp.terrainData.heightmapHeight; float[,] newHeightMap = new float[tw, th]; float angleRad = angle * Mathf.Deg2Rad; float heightMiddle = (terrainTmp.terrainData.heightmapResolution) / 2.0f; // pivot at middle for (int y = 0; y < th; y++) { for (int x = 0; x < tw; x++) { cs = Mathf.Cos(angleRad); sn = Mathf.Sin(angleRad); nx = (int)((x - heightMiddle) * cs - (y - heightMiddle) * sn + heightMiddle); ny = (int)((x - heightMiddle) * sn + (y - heightMiddle) * cs + heightMiddle); if (nx < 0) { nx = 0; } if (nx > tw - 1) { nx = tw - 1; } if (ny < 0) { ny = 0; } if (ny > th - 1) { ny = th - 1; } newHeightMap[x, y] = origHeightMap[nx, ny]; } // for x } // for y // detail layer (grass, meshes) int dw = terrainTmp.terrainData.detailWidth; int dh = terrainTmp.terrainData.detailHeight; float detailMiddle = (terrainTmp.terrainData.detailResolution) / 2.0f; // pivot at middle int numDetails = terrainTmp.terrainData.detailPrototypes.Length; int[][,] newDetailLayer = new int[numDetails][, ]; // build new layer arrays for (int n = 0; n < numDetails; n++) { newDetailLayer[n] = new int[dw, dh]; } for (int z = 0; z < numDetails; z++) { for (int y = 0; y < dh; y++) { for (int x = 0; x < dw; x++) { cs = Mathf.Cos(angleRad); sn = Mathf.Sin(angleRad); nx = (int)((x - detailMiddle) * cs - (y - detailMiddle) * sn + detailMiddle); ny = (int)((x - detailMiddle) * sn + (y - detailMiddle) * cs + detailMiddle); if (nx < 0) { nx = 0; } if (nx > dw - 1) { nx = dw - 1; } if (ny < 0) { ny = 0; } if (ny > dh - 1) { ny = dh - 1; } newDetailLayer[z][x, y] = origDetailLayer[z][nx, ny]; } // for x } // for y } // for z // alpha layer (texture splatmap) rotation dw = terrainTmp.terrainData.alphamapWidth; dh = terrainTmp.terrainData.alphamapHeight; int dz = terrainTmp.terrainData.alphamapLayers; float alphaMiddle = (terrainTmp.terrainData.alphamapResolution) / 2.0f; // pivot at middle float[,,] newAlphaMap = new float[dw, dh, dz]; float[,,] origAlphaMapCopy; origAlphaMapCopy = origAlphaMap.Clone() as float[, , ]; for (int z = 0; z < dz; z++) { for (int y = 0; y < dh; y++) { for (int x = 0; x < dw; x++) { cs = Mathf.Cos(angleRad); sn = Mathf.Sin(angleRad); nx = (int)((x - alphaMiddle) * cs - (y - alphaMiddle) * sn + alphaMiddle); ny = (int)((x - alphaMiddle) * sn + (y - alphaMiddle) * cs + alphaMiddle); if (nx < 0) { nx = 0; } if (nx > dw - 1) { nx = dw - 1; } if (ny < 0) { ny = 0; } if (ny > dh - 1) { ny = dh - 1; } newAlphaMap[x, y, z] = origAlphaMapCopy[nx, ny, z]; } // for x } // for y } // for z // trees rotation, one by one.. // TODO: use list instead, then can remove trees outside the terrain int treeCount = terrainTmp.terrainData.treeInstances.Length; TreeInstance[] newTrees = new TreeInstance[treeCount]; Vector3 newTreePos = Vector3.zero; float tx, tz; for (int n = 0; n < treeCount; n++) { cs = Mathf.Cos(angleRad); sn = Mathf.Sin(angleRad); tx = origTrees[n].position.x - 0.5f; tz = origTrees[n].position.z - 0.5f; newTrees[n] = origTrees[n]; newTreePos.x = (cs * tx) - (sn * tz) + 0.5f; newTreePos.y = origTrees[n].position.y; newTreePos.z = (cs * tz) + (sn * tx) + 0.5f; newTrees[n].position = newTreePos; } // for treeCount // this is too slow in unity.. //Undo.RecordObject(terrain.terrainData,"Rotate terrain ("+angle+")"); // Apply new data to terrain //newTerrain.terrainData.treeInstances = newTrees; newTerrain.terrainData.treeInstances = new TreeInstance[] { /*newTrees[0]*/ }; //Just a test to delete tree colliders newTerrain.terrainData.SetHeightsDelayLOD(0, 0, newHeightMap); // splitting up SetHeights part1 newTerrain.ApplyDelayedHeightmapModification(); //part2 //newTerrain.terrainData.treeInstances = newTrees; newTerrain.terrainData.SetAlphamaps(0, 0, newAlphaMap); for (int n = 0; n < terrainTmp.terrainData.detailPrototypes.Length; n++) { newTerrain.terrainData.SetDetailLayer(0, 0, n, newDetailLayer[n]); } // we are done.. isRotating = false; } //TerrainRotate
void Awake() { // Cannot be smaller then cell size otherwise fire will not propagate if (m_maxHillPropagationDistance < m_cellSize) { m_maxHillPropagationDistance = m_cellSize; } // Make sure within 0->1 range if (m_visualExtinguishThreshold > 1.0f) { m_visualExtinguishThreshold = 1.0f; } if (m_visualExtinguishThreshold < 0.0f) { m_visualExtinguishThreshold = 0.0f; } if (m_combustionRate < 1.0f) { m_combustionRate = 1.0f; } if (m_propagationBias < 0.0000001f) { m_propagationBias = 0.0000001f; Debug.Log("Capping propagationBias to 0.0000001f, as it's to smaller or zero"); } if (m_propagationBias > 1.0f) { m_propagationBias = 1.0f; Debug.Log("Capping propagationBias to 1.0f, as it's too large"); } if (m_propagationHillBias < 1.0f) { m_propagationHillBias = 1.0f; Debug.Log("Capping propagationHillBias to 1.0f, as it's too small"); } // Get the terrain, need to be a child of a Terrain GameObject m_terrain = GetComponentInParent <Terrain>(); if (m_terrain != null) { m_terrainDetailWidth = m_terrain.terrainData.detailWidth; m_terrainDetailHeight = m_terrain.terrainData.detailHeight; m_terrainAlphaWidth = m_terrain.terrainData.alphamapWidth; m_terrainAlphaHeight = m_terrain.terrainData.alphamapHeight; // Use the arrays or the lists if (!m_maxGrassDetails) { m_terrainMap = m_terrain.terrainData.GetDetailLayer(0, 0, m_terrainDetailWidth, m_terrainDetailHeight, 0); m_terrainReplaceMap = m_terrain.terrainData.GetDetailLayer(0, 0, m_terrainDetailWidth, m_terrainDetailHeight, 1); m_terrainMapOriginal = (int[, ])m_terrainMap.Clone(); // performs a deep copy, Clone by itself performs a shallow copy (i.e. 2nd array has references to the 1st array) m_terrainReplaceMapOriginal = (int[, ])m_terrainReplaceMap.Clone(); } else { // Make sure a valid index was set if (m_burntGrassDetailIndex >= m_terrain.terrainData.detailPrototypes.Length || m_burntGrassDetailIndex < 0) { m_burntGrassDetailIndex = 0; Debug.Log("Burnt Grass Texture Index is higher/lower then the number of grass texture details set, setting to 0"); } // Set up Lists m_terrainMaps = new List <int[, ]>(); m_terrainMapsOriginal = new List <int[, ]>(); for (int i = 0; i < m_terrain.terrainData.detailPrototypes.Length; i++) { m_terrainMaps.Add(m_terrain.terrainData.GetDetailLayer(0, 0, m_terrainDetailWidth, m_terrainDetailHeight, i)); m_terrainMapsOriginal.Add(m_terrain.terrainData.GetDetailLayer(0, 0, m_terrainDetailWidth, m_terrainDetailHeight, i)); } } // Get the terrain textures m_terrainTexture = m_terrain.terrainData.GetAlphamaps(0, 0, m_terrainAlphaWidth, m_terrainAlphaHeight); m_terrainTextureOriginal = (float[, , ])m_terrainTexture.Clone(); int TerrainDetailMapSize = m_terrain.terrainData.detailResolution; if (m_terrain.terrainData.size.x != m_terrain.terrainData.size.z) { Debug.Log("X and Y size of terrain have to be the same."); return; } // Need to have at least one terrain texture defined if (terrainTextures.Length != terrainAlpha.GetLength(2)) { Debug.LogError("A different number of Terrain Textures are set in Fire Manager compared with the Terrain."); } m_terrainDetailSize = TerrainDetailMapSize / m_terrain.terrainData.size.x; if (m_cellFireSpawnPositions.Length == 0) { m_cellFireSpawnPositions = new Vector2[1] { new Vector2(0.5f, 0.5f) } } ; } else { Debug.LogError("Terrain not found! A Fire Manager should be a child of a Terrain GameObject."); } } // Use this for initialization void Start() { } // Update is called once per frame void Update() { // Make sure there is a FireGrid somewhere in the world if (m_activeFireGrids > 0) { // Start now, so when the first fire goes out the terrain will be instantly updated m_terrainUpdateTimer += Time.deltaTime; // If dirty, update the terrain. This is set when terrain data is changed like grass being removed by FireGrassRemover // also make sure one of the features has been turned one if (m_dirty) { // Make sure the set amount of time has past, then call coroutine if (m_terrainUpdateTimer >= m_terrainUpdateTime) { StartCoroutine(CoTerrainUpdate()); m_terrainUpdateTimer = 0.0f; } } } }