예제 #1
0
                bool IsFlatAndFilled(CornerSet cS)
                {
                    if (!cS.Filled)
                    {
                        return(false);
                    }

                    var z = GetPos(_verts[cS.cornerIndices[0].Value]).Z;

                    var zFL = GetPos(_verts[cS.iFL]).Z;

                    if (z != zFL)
                    {
                        return(false);
                    }
                    var zFR = GetPos(_verts[cS.iFR]).Z;

                    if (z != zFR)
                    {
                        return(false);
                    }
                    var zBL = GetPos(_verts[cS.iBL]).Z;

                    if (z != zBL)
                    {
                        return(false);
                    }
                    var zBR = GetPos(_verts[cS.iBR]).Z;

                    if (z != zBR)
                    {
                        return(false);
                    }
                    var zF = GetPos(_verts[cS.iF]).Z;

                    if (z != zF)
                    {
                        return(false);
                    }
                    var zB = GetPos(_verts[cS.iB]).Z;

                    if (z != zB)
                    {
                        return(false);
                    }
                    var zL = GetPos(_verts[cS.iL]).Z;

                    if (z != zL)
                    {
                        return(false);
                    }
                    var zR = GetPos(_verts[cS.iR]).Z;

                    if (z != zR)
                    {
                        return(false);
                    }

                    return(true);
                }
예제 #2
0
                void MarkForRemove(CornerSet cS)
                {
                    Debug.Assert(cS.cornerIndices[0].HasValue);
                    {
                        var c0 = cS.cornerIndices[0].Value;

                        _indicesToRemove[c0]     = 0;
                        _indicesToRemove[c0 + 1] = 0;
                        _indicesToRemove[c0 + 2] = 0;
                        _indicesToRemove[c0 + 3] = 0;
                    }
                    Debug.Assert(cS.cornerIndices[1].HasValue);
                    {
                        var c1 = cS.cornerIndices[1].Value;

                        _indicesToRemove[c1]     = 0;
                        _indicesToRemove[c1 - 1] = 0;
                        _indicesToRemove[c1 - 2] = 0;
                        _indicesToRemove[c1 - 3] = 0;
                    }
                    Debug.Assert(cS.cornerIndices[2].HasValue);
                    {
                        var c2 = cS.cornerIndices[2].Value;

                        _indicesToRemove[c2]     = 0;
                        _indicesToRemove[c2 - 1] = 0;
                        _indicesToRemove[c2 + 1] = 0;
                        _indicesToRemove[c2 + 2] = 0;
                    }
                    Debug.Assert(cS.cornerIndices[3].HasValue);
                    {
                        var c3 = cS.cornerIndices[3].Value;

                        _indicesToRemove[c3]     = 0;
                        _indicesToRemove[c3 - 1] = 0;
                        _indicesToRemove[c3 - 2] = 0;
                        _indicesToRemove[c3 + 1] = 0;
                    }
                }
예제 #3
0
                bool IsRemoved(CornerSet cS, Corners cornersToIgnore)
                {
                    if ((cornersToIgnore & Corners.BR) == 0)
                    {
                        if (cS.cornerIndices[0].HasValue)
                        {
                            var c0 = cS.cornerIndices[0].Value;
                            if (_indicesToRemove.ContainsKey(c0))
                            {
                                return(true);
                            }
                            if (_indicesToRemove.ContainsKey(c0 + 1))
                            {
                                return(true);
                            }
                            if (_indicesToRemove.ContainsKey(c0 + 2))
                            {
                                return(true);
                            }
                            if (_indicesToRemove.ContainsKey(c0 + 3))
                            {
                                return(true);
                            }
                        }
                    }

                    if ((cornersToIgnore & Corners.FR) == 0)
                    {
                        if (cS.cornerIndices[1].HasValue)
                        {
                            var c1 = cS.cornerIndices[1].Value;

                            if (_indicesToRemove.ContainsKey(c1))
                            {
                                return(true);
                            }
                            if (_indicesToRemove.ContainsKey(c1 - 1))
                            {
                                return(true);
                            }
                            if (_indicesToRemove.ContainsKey(c1 - 2))
                            {
                                return(true);
                            }
                            if (_indicesToRemove.ContainsKey(c1 - 3))
                            {
                                return(true);
                            }
                        }
                    }

                    if ((cornersToIgnore & Corners.BL) == 0)
                    {
                        if (cS.cornerIndices[2].HasValue)
                        {
                            var c2 = cS.cornerIndices[2].Value;

                            if (_indicesToRemove.ContainsKey(c2))
                            {
                                return(true);
                            }
                            if (_indicesToRemove.ContainsKey(c2 - 1))
                            {
                                return(true);
                            }
                            if (_indicesToRemove.ContainsKey(c2 + 1))
                            {
                                return(true);
                            }
                            if (_indicesToRemove.ContainsKey(c2 + 2))
                            {
                                return(true);
                            }
                        }
                    }

                    if ((cornersToIgnore & Corners.FL) == 0)
                    {
                        if (cS.cornerIndices[3].HasValue)
                        {
                            var c3 = cS.cornerIndices[3].Value;

                            if (_indicesToRemove.ContainsKey(c3))
                            {
                                return(true);
                            }
                            if (_indicesToRemove.ContainsKey(c3 - 1))
                            {
                                return(true);
                            }
                            if (_indicesToRemove.ContainsKey(c3 - 2))
                            {
                                return(true);
                            }
                            if (_indicesToRemove.ContainsKey(c3 + 1))
                            {
                                return(true);
                            }
                        }
                    }

                    return(false);
                }
예제 #4
0
                public Terrain.TerrainVertex_FD[] Optimize()
                {
                    for (int i = 0; i < _numVerts; i++)
                    {
                        Terrain.TerrainVertex_FD v = _verts[i];
                        Vector3 pos    = GetPos(v);
                        int     corner = (int)((v.faceAndCorner & 0xff00) >> 8);

                        if (_posToCSs.ContainsKey(pos))
                        {
                            //Debug.Assert(_posToCSs[pos].cornerIndices[corner] == null);

                            _posToCSs[pos].cornerIndices[corner] = i;
                        }
                        else
                        {
                            CornerSet cS = new CornerSet();
                            cS.cornerIndices = new int?[4];

                            cS.cornerIndices[corner] = i;

                            _posToCSs.Add(pos, cS);
                        }
                    }

                    // Doesn't seem to be used...
                    //var toEmpty = new HashSet<CornerSet>();
                    List <Terrain.TerrainVertex_FD> toAdd = new List <Terrain.TerrainVertex_FD>();

                    foreach (CornerSet cS in _posToCSs.Values)
                    {
                        if (!IsRemoved(cS, Corners.None) && IsFlatAndFilled(cS))
                        {
                            MarkForRemove(cS);

                            //Traverse up the Y dir
                            CornerSet bCS         = cS;
                            CornerSet nBCS        = GetCornerSet(cS.iB);
                            int       bTraversals = 0;
                            while (!IsRemoved(nBCS, Corners.FL | Corners.FR) && IsFlatAndFilled(nBCS) && bTraversals < maxYTraversals)
                            {
                                bTraversals++;
                                bCS = nBCS;
                                MarkForRemove(bCS);
                                nBCS = GetCornerSet(nBCS.iB);
                            }

                            //Traverse up the X dir
                            CornerSet rCS         = cS;
                            CornerSet brCS        = bCS;
                            CornerSet nRCS        = GetCornerSet(rCS.iR);
                            int       rTraversals = 0;
                            while (!IsRemoved(nRCS, Corners.FL | Corners.BL) && IsFlatAndFilled(nRCS) && rTraversals < maxXTraversals)
                            {
                                rTraversals++;
                                List <CornerSet> tenativeToEmpty      = new List <CornerSet>();
                                bool             bTraversalsCompleted = true;
                                CornerSet        nBRCS = nRCS;
                                nBCS = nRCS;
                                for (int i = 0; i < bTraversals; i++)
                                {
                                    nBCS = GetCornerSet(nBCS.iB);
                                    if (!IsRemoved(nBCS, Corners.FL | Corners.FR | Corners.BL) && IsFlatAndFilled(nBCS))
                                    {
                                        tenativeToEmpty.Add(nBCS);
                                        nBRCS = nBCS;
                                    }
                                    else
                                    {
                                        bTraversalsCompleted = false;
                                        break;
                                    }
                                }

                                if (bTraversalsCompleted)
                                {
                                    brCS = nBRCS;
                                    rCS  = nRCS;
                                    MarkForRemove(rCS);
                                    for (int i = 0; i < tenativeToEmpty.Count; i++)
                                    {
                                        MarkForRemove(tenativeToEmpty[i]);
                                    }
                                    nRCS = GetCornerSet(nRCS.iR);
                                }
                                else
                                {
                                    break;
                                }
                            }

                            Terrain.TerrainVertex_FD vFL = _verts[cS.iFL];
                            Terrain.TerrainVertex_FD vBL = _verts[bCS.iBL];
                            Terrain.TerrainVertex_FD vBR = _verts[brCS.iBR];
                            Terrain.TerrainVertex_FD vFR = _verts[rCS.iFR];

                            toAdd.Add(vFL);
                            toAdd.Add(vFR);
                            toAdd.Add(vBR);
                            toAdd.Add(vBL);
                        }
                    }

                    for (int i = 0; i < _numVerts; i++)
                    {
                        if (!_indicesToRemove.ContainsKey(i))
                        {
                            toAdd.Add(_verts[i]);
                        }
                    }

                    Terrain.TerrainVertex_FD[] result = toAdd.ToArray();

                    return(result);
                }