Пример #1
0
                Vector3 GetPos(Terrain.TerrainVertex_FD vert)
                {
                    var pos4 = vert.positionAndZDiff;

                    return(new Vector3(pos4.X, pos4.Y, pos4.Z));
                }
Пример #2
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);
                }