Exemple #1
0
            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;
                }
            }
Exemple #2
0
    // 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);
    }
Exemple #3
0
        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;
        }
Exemple #4
0
        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);
        }
Exemple #5
0
 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;
        }
Exemple #7
0
    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;
                }
            }
        }
    }