Пример #1
0
                public static void Erode(TerraMesh _tMesh, float _maxErosionRate, float[] _waterFlux)
                {
                    var sitePositions = _tMesh.GetAllSitePositions(); //TODO SLOW

                    //Get all site slope vectors and slope values
                    var slopeVecs = new Vector3[sitePositions.Length];
                    var slopeVals = new float[sitePositions.Length];

                    for (var pIdx = 0; pIdx < sitePositions.Length; ++pIdx)
                    {
                        var p      = sitePositions[pIdx];
                        var aveSlp = Vector3.zero;
                        var nbrCnt = 0;
                        foreach (var nIdx in _tMesh.SiteNeighbors[pIdx])
                        {
                            if (nIdx == SiteIdxNull)
                            {
                                continue;
                            }
                            nbrCnt++;
                            var n      = sitePositions[nIdx];
                            var slpVec = n - p;
                            if (slpVec.z > 0)
                            {
                                slpVec = -slpVec;
                            }
                            aveSlp += slpVec;
                        }

                        var slpVecCell = aveSlp / nbrCnt;
                        slopeVecs[pIdx] = slpVecCell;
                        slopeVals[pIdx] = slpVecCell.z / new Vector2(slpVecCell.x, slpVecCell.y).magnitude;
                    }

                    //Apply erosion to terra mesh surface
                    for (var pIdx = 0; pIdx < _waterFlux.Length; ++pIdx)
                    {
                        var sitePos      = sitePositions[pIdx];
                        var fx           = (float)Math.Sqrt(_waterFlux[pIdx]);
                        var slp          = slopeVals[pIdx];
                        var erosionShift = Math.Min(-slp * fx, _maxErosionRate);
                        //var newPos = new Vector3(sitePos.x, sitePos.y, sitePos.z - erosionShift);
                        SetSiteHeight(_tMesh, pIdx, sitePos.z - erosionShift);
                    }
                    _tMesh.RecalculateBounds();
                }
Пример #2
0
                public static Vector3[] PlanchonDarboux(TerraMesh _tMesh, float _minSlope, Progress.OnUpdate _onUpdate)
                {
                    var prog = new Progress("PlanchonDarboux");

                    prog.SetOnUpdate(_onUpdate);
                    var sitePosArr = _tMesh.GetAllSitePositions(); //TODO slow?
                    var hullSites  = new HashSet <int>(_tMesh.HullSites);
                    //var hullSites = _tMesh.HullSites;

                    //Generate waterflow surface points
                    var newSurf = new Vector3[sitePosArr.Length];

                    for (var pIdx = 0; pIdx < sitePosArr.Length; ++pIdx)
                    {
                        var sPos = sitePosArr[pIdx];
                        var z    = float.PositiveInfinity;
                        if (hullSites.Contains(pIdx))
                        {
                            z = sPos.z;
                        }
                        newSurf[pIdx] = new Vector3(sPos.x, sPos.y, z);
                    }

                    Func <int, float>      Z = _idx => sitePosArr[_idx].z;
                    Func <int, float>      W = _idx => newSurf[_idx].z;
                    Func <int, int, float> E = (_cIdx, _nIdx) =>
                    {
                        var cVert = sitePosArr[_cIdx];
                        var nVert = sitePosArr[_nIdx];
                        var subX  = nVert.x - cVert.x;
                        var subY  = nVert.y - cVert.y;
                        return((float)Math.Sqrt(subX * subX + subY * subY) * _minSlope);
                    };


                    var opDone = false;
                    var wCnt   = 0; //DEBUG todo

                    do
                    {
                        opDone = false;
                        var sitePosArrLen = sitePosArr.Length; //TODO Debug
                        for (var pIdx = 0; pIdx < sitePosArrLen; ++pIdx)
                        {
                            var progPct = (float)pIdx / sitePosArrLen;
                            prog.Update(progPct, pIdx + " of " + sitePosArrLen);
                            if (hullSites.Contains(pIdx))
                            {
                                continue;
                            }
                            var sitePos = sitePosArr[pIdx];
                            var c       = pIdx;
                            if (!(W(c) > Z(c)))
                            {
                                continue;
                            }
                            var cVertZ = sitePos;
                            foreach (var n in _tMesh.SiteNeighbors[pIdx])
                            {
                                var e   = E(c, n);
                                var wpn = W(n) + e;
                                if (cVertZ.z >= wpn)
                                {
                                    newSurf[c].Set(cVertZ.x, cVertZ.y, cVertZ.z);
                                    opDone = true;
                                    break;
                                }

                                if (W(c) > wpn)
                                {
                                    newSurf[c].Set(cVertZ.x, cVertZ.y, wpn);
                                    opDone = true;
                                }
                            }
                        }

                        if (++wCnt > 2)
                        {
                            break;             // TODO DEBUG
                        }
                    } while (opDone);

                    return(newSurf);
                }