示例#1
0
 public Site(TerraMesh _host, int _index)
 {
     m_Host       = _host;
     Index        = _index;
     CornerIdxs   = m_Host.SiteCorners[Index];
     NeighborIdxs = m_Host.SiteNeighbors[Index];
 }
示例#2
0
                public static void Conify(TerraMesh _tMesh, float _strength, Progress.OnUpdate _onUpdate = null)
                {
                    if (_onUpdate == null)
                    {
                        _onUpdate = (_prog, _str) => { }
                    }
                    ;
                    var prog = new Progress();

                    prog.SetOnUpdate(_onUpdate);

                    var cent   = _tMesh.m_Bounds.center.ToVec2();
                    var min    = _tMesh.m_Bounds.min.ToVec2();
                    var maxMag = (min - cent).magnitude;

                    prog.Update(0, "Conifying");
                    for (var sIdx = 0; sIdx < _tMesh.Vertices.Length; ++sIdx)
                    {
                        var sitePos = _tMesh.Vertices[sIdx];
                        var magScal = (new Vector2(sitePos.x, sitePos.y) - cent).magnitude / maxMag - 0.5f;
                        var zShift  = magScal * _strength / 2f;
                        var newPos  = new Vector3(sitePos.x, sitePos.y, zShift + sitePos.z);
                        _tMesh.Vertices[sIdx] = newPos;
                        prog.Update((float)sIdx / _tMesh.Vertices.Length);
                    }
                    _tMesh.RecalculateBounds();
                }
            //TODO update for new terramesh
            public static TerraMesh Deserialize(byte[] _serializedData)
            {
                var sb = new SerializedBundle(_serializedData);
                var tm = new TerraMesh(sb.Vertices, sb.Triangles);

                tm.HullSites         = sb.HullSites;
                tm.SiteCorners       = sb.SiteCorners;
                tm.SiteNeighbors     = sb.SiteNeighbors;
                tm.SitesHavingCorner = sb.SitesHavingCorner;
                return(tm);
            }
示例#4
0
                public static void SetSiteHeight(TerraMesh _terraMesh, int _siteIdx, float _newZ)
                {
                    var curSitePos    = _terraMesh.GetSitePosition(_siteIdx);
                    var heightDiff    = _newZ - curSitePos.z;
                    var cornerIndexes = _terraMesh.SiteCorners[_siteIdx];

                    foreach (var cornerIdx in cornerIndexes)
                    {
                        var curCornerPos = _terraMesh.Vertices[cornerIdx];
                        var newCornerPos = new Vector3(curCornerPos.x, curCornerPos.y, curCornerPos.z + heightDiff);
                        _terraMesh.Vertices[cornerIdx] = newCornerPos;
                        _terraMesh.m_Bounds.Encapsulate(newCornerPos);
                    }
                }
示例#5
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();
                }
示例#6
0
 public static void Blob(TerraMesh _tMesh, float _strength, float _radius, Vector2 _loc)
 {
     for (var sIdx = 0; sIdx < _tMesh.Vertices.Length; ++sIdx)
     {
         var sPos   = _tMesh.Vertices[sIdx];
         var vert2d = sPos.ToVec2();
         var dist   = (vert2d - _loc).magnitude;
         if (dist > _radius)
         {
             continue;
         }
         var cosVal = dist / _radius * (float)Math.PI / 2f;
         var zShift = _strength * (float)Math.Cos(cosVal);
         var newZ   = sPos.z + zShift;
         var newPos = new Vector3(vert2d.x, vert2d.y, sPos.z + zShift);
         _tMesh.Vertices[sIdx] = newPos;
     }
     _tMesh.RecalculateBounds();
 }
示例#7
0
                public void Generate(Progress.OnUpdate _onUpdate, OnComplete _onComplete)
                {
                    ProgOnUpdate = _onUpdate;
                    ProgressGenerator.SetOnUpdate(_onUpdate);

                    //Create and triangluate Delaunay
                    DoDelaunayTriangulation();

                    //Create Voronoi and Lloyd Relax
                    DoVoronoiAndRelax();

                    //Build TerraMesh Object
                    var mesh = Delaunay.Mesh;

                    TMesh = new TerraMesh(mesh.Vertices, mesh.Triangles);

                    IndexSites();
                    ComputeSiteData();
                    PopulateHullSites();

                    _onComplete(TMesh);
                }
示例#8
0
                public static void SlopeGlobal(TerraMesh _tMesh, Vector2 _dir, float _strength,
                                               Progress.OnUpdate _onUpdate = null)
                {
                    if (_onUpdate == null)
                    {
                        _onUpdate = (_prog, _str) => { }
                    }
                    ;
                    var prog = new Progress();

                    prog.SetOnUpdate(_onUpdate);


                    var dir  = _dir.normalized;
                    var bnds = _tMesh.bounds;
                    Func <Vector3, float> strf = _pos =>
                    {
                        var xPct = (_pos.x - bnds.min.x) / bnds.size.x - 0.5f;
                        var yPct = (_pos.y - bnds.min.y) / bnds.size.y - 0.5f;
                        var xStr = xPct * dir.x;
                        var yStr = yPct * dir.y;
                        return((xStr + yStr) * _strength / 4f);
                    };

                    prog.Update(0, "Global Slope");
                    for (var sIdx = 0; sIdx < _tMesh.Vertices.Length; ++sIdx)
                    {
                        //if (_tMesh.HullSites.Contains(sIdx))
                        //    Trace.WriteLine("Debug Hullsites"); //TODO DEbug
                        var sitePos = _tMesh.Vertices[sIdx];
                        var zShift  = strf(sitePos);
                        var newZ    = sitePos.z + zShift;
                        var newPos  = new Vector3(sitePos.x, sitePos.y, newZ);
                        _tMesh.Vertices[sIdx] = newPos;
                        prog.Update((float)sIdx / _tMesh.Vertices.Length);
                    }
                    _tMesh.RecalculateBounds();
                }
示例#9
0
                public static void SetHeightSpan(TerraMesh _terraMesh, float _min, float _max)
                {
                    float minZ = float.PositiveInfinity,
                          maxZ = float.NegativeInfinity;

                    for (var sIdx = 0; sIdx < _terraMesh.Vertices.Length; ++sIdx)
                    {
                        var z = _terraMesh.Vertices[sIdx].z;
                        if (z < minZ)
                        {
                            minZ = z;
                        }
                        if (z > maxZ)
                        {
                            maxZ = z;
                        }
                    }

                    var zSpan = maxZ - minZ;

                    var newSpan = _max - _min;


                    for (var sIdx = 0; sIdx < _terraMesh.Vertices.Length; ++sIdx)
                    {
                        var sPos = _terraMesh.Vertices[sIdx];
                        var zPct = (sPos.z - minZ) / zSpan;
                        _terraMesh.Vertices[sIdx].Set(sPos.x, sPos.y, zPct * newSpan + _min);
                    }

                    var bounds = _terraMesh.bounds;

                    bounds.min          = new Vector3(bounds.min.x, bounds.min.y, _min);
                    bounds.max          = new Vector3(bounds.max.x, bounds.max.y, _max);
                    _terraMesh.m_Bounds = bounds;
                }
                public SerializedBundle(TerraMesh _tm)
                {
                    Version = CUR_VERSION;

                    //Vector3 -- 12 bytes
                    Vertices = _tm.Vertices; //TODO Broken
                    //int - 4 bytes
                    Triangles = _tm.Triangles;
                    //int - 4 bytes
                    HullSites = _tm.HullSites;
                    //3 ints - 12 bytes
                    SiteCorners = _tm.SiteCorners;
                    //3 ints - 12 bytes
                    SiteNeighbors = _tm.SiteNeighbors;
                    //Vector3 -- 12 bytes
                    //SitePositions = _tm.SitePositions; //TODO BROKEN
                    //Variable -- need to track length for each set
                    SitesHavingCorner = _tm.SitesHavingCorner;

                    var totalSetCount = 0;

                    for (var cornerIdx = 0; cornerIdx < SitesHavingCorner.Length; ++cornerIdx)
                    {
                        totalSetCount += _tm.SitesHavingCorner[cornerIdx].Count;
                    }

                    var dataLen = sizeof(int);                           //Total size header

                    dataLen += sizeof(int);                              // Version
                    dataLen += sizeof(int);                              // Vertex count header
                    dataLen += Vertices.Length * sizeof(float) * 2;      // Vector2
                    dataLen += sizeof(int);                              // Triangle count header
                    dataLen += Triangles.Length * sizeof(int);           //int
                    dataLen += sizeof(int);                              // HullSites count header
                    dataLen += HullSites.Length * sizeof(int);           //int
                    dataLen += sizeof(int);                              // SiteCorners count header
                    dataLen += SiteCorners.Length * sizeof(int) * 3;     //int * 3
                    dataLen += sizeof(int);                              // SiteNeighbors count header
                    dataLen += SiteNeighbors.Length * sizeof(int) * 3;   // int * 3
                    dataLen += sizeof(int);                              // SitePositions count header
                    dataLen += SitePositions.Length * sizeof(float) * 3; // Vector3
                    dataLen += sizeof(int);                              // Site having corner set count
                    dataLen += SitesHavingCorner.Length * sizeof(int);   //Site Having corner count headers
                    dataLen += totalSetCount * sizeof(int);              //Sites having corner set indexes

                    SerializedData = new byte[dataLen];
                    BufIdx         = 0;

                    byte32    = new Byte32();
                    bytesVec2 = new ByteVector2();
                    bytesVec3 = new ByteVector3();

                    byte32.Write(SerializedData, ref BufIdx, dataLen);
                    byte32.Write(SerializedData, ref BufIdx, Version);
                    SerializeVertices(ref BufIdx, SerializedData);
                    SerializeTris(ref BufIdx, SerializedData);
                    SerializeHullSites(ref BufIdx, SerializedData);
                    SerializeSiteCorners(ref BufIdx, SerializedData);
                    SerializeSiteNeighbors(ref BufIdx, SerializedData);
                    SerializeSitePositions(ref BufIdx, SerializedData);
                    SerializeSitesHavingCorner(ref BufIdx, SerializedData);
                }
            public static byte[] Serialize(TerraMesh _terraMesh)
            {
                var sb = new SerializedBundle(_terraMesh);

                return(sb.SerializedData);
            }
示例#12
0
 public static void NormalizeHeight(TerraMesh _terraMesh)
 {
     SetHeightSpan(_terraMesh, 0, 1);
 }
示例#13
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);
                }
示例#14
0
            public static void Slice(TerraMesh _tMesh, int _maxVertCount, out int[][] _triIdxs)
            {
                //Check if already meet max vert count
                if (_tMesh.Vertices.Length <= _maxVertCount)
                {
                    _triIdxs    = new int[1][];
                    _triIdxs[0] = _tMesh.Triangles;
                    return;
                }

                var bndRect = new Rect(_tMesh.m_Bounds.min.x, _tMesh.m_Bounds.min.y,
                                       _tMesh.m_Bounds.size.x, _tMesh.m_Bounds.size.y);

                //Find correct slice count (2x2, 3x3, 4x4, etc.)
                var   rowCnt = 2;
                int   boxCnt;
                float sliceWidth;
                float sliceHeight;
                Dictionary <int, int> vIdxToMIdx;

                while (true)
                {
                    var nextRowCnt = false;
                    boxCnt      = rowCnt * rowCnt;
                    sliceWidth  = bndRect.width / rowCnt;
                    sliceHeight = bndRect.height / rowCnt;
                    var vertsPerBox = new int[boxCnt];
                    vIdxToMIdx = new Dictionary <int, int>();

                    for (var vIdx = 0; vIdx < _tMesh.Vertices.Length; ++vIdx)
                    {
                        var curVert = _tMesh.Vertices[vIdx];

                        //Find Col
                        for (var xScanIdx = 1; xScanIdx <= rowCnt; ++xScanIdx)
                        {
                            var pointBoxed = false;
                            var xMax       = xScanIdx * sliceWidth;
                            if (curVert.x > xMax)
                            {
                                continue;
                            }

                            //Find Row
                            for (var yScanIdx = 1; yScanIdx <= rowCnt; ++yScanIdx)
                            {
                                var yMax = yScanIdx * sliceHeight;
                                if (curVert.y > yMax)
                                {
                                    continue;
                                }

                                var meshIdx = (yScanIdx - 1) * rowCnt + (xScanIdx - 1);
                                vertsPerBox[meshIdx]++;
                                if (vertsPerBox[meshIdx] >= _maxVertCount)
                                {
                                    nextRowCnt = true;
                                    break;
                                }

                                vIdxToMIdx.Add(vIdx, meshIdx);
                                pointBoxed = true;
                                break;
                            }

                            if (nextRowCnt || pointBoxed)
                            {
                                break;
                            }
                        }

                        if (nextRowCnt)
                        {
                            break;
                        }
                    }

                    if (!nextRowCnt)
                    {
                        break;
                    }
                    rowCnt++;
                }

                boxCnt = rowCnt * rowCnt;
                var triIdx = new List <int> [boxCnt];
                var tris   = _tMesh.Triangles;

                for (var boxIdx = 0; boxIdx < boxCnt; ++boxIdx)
                {
                    triIdx[boxIdx] = new List <int>();
                }

                for (var tIdx = 0; tIdx < tris.Length; tIdx += 3)
                {
                    var idxa       = tris[tIdx];
                    var idxb       = tris[tIdx + 1];
                    var idxc       = tris[tIdx + 2];
                    var meshBoxIdx = vIdxToMIdx[idxa];
                    triIdx[meshBoxIdx].Add(idxa);
                    triIdx[meshBoxIdx].Add(idxb);
                    triIdx[meshBoxIdx].Add(idxc);
                }

                _triIdxs = new int[boxCnt][];
                for (var boxIdx = 0; boxIdx < boxCnt; ++boxIdx)
                {
                    _triIdxs[boxIdx] = triIdx[boxIdx].ToArray();
                }
            }