Beispiel #1
0
        void GenerateCellsMesh()
        {
            if (gridPoints == null || gridPoints.Length == 0)
            {
                gridPoints = new Vector2[200000];
            }

            int gridPointsCount = 0;
            int y0 = (int)((gridRect.yMin + 0.5f) * _gridRows);
            int y1 = (int)((gridRect.yMax + 0.5f) * _gridRows);

            y0 = Mathf.Clamp(y0, 0, _gridRows - 1);
            y1 = Mathf.Clamp(y1, 0, _gridRows - 1);
            for (int y = y0; y <= y1; y++)
            {
                int yy = y * _gridColumns;
                int x0 = (int)((gridRect.xMin + 0.5f) * _gridColumns);
                int x1 = (int)((gridRect.xMax + 0.5f) * _gridColumns);
                for (int x = x0; x <= x1; x++)
                {
                    int wrapX = x;
                    if (_wrapHorizontally)
                    {
                        if (x < 0)
                        {
                            wrapX += _gridColumns;
                        }
                        else if (x >= gridColumns)
                        {
                            wrapX -= gridColumns;
                        }
                    }
                    if (wrapX < 0 || wrapX >= _gridColumns)
                    {
                        continue;
                    }
                    Cell cell = cells [yy + wrapX];
                    if (cell != null)
                    {
                        if (gridPoints.Length <= gridPointsCount + 12)
                        {
                            // Resize and copy elements; similar to C# standard list but we avoid excesive calls when accessing elements
                            int       newSize = gridPoints.Length * 2;
                            Vector2[] tmp     = new Vector2[newSize];
                            Array.Copy(gridPoints, tmp, gridPointsCount);
                            gridPoints = tmp;
                        }
                        for (int i = 0; i < 6; i++)
                        {
                            CellSegment s = cell.segments [i];
                            if (!s.isRepeated)
                            {
                                gridPoints [gridPointsCount++] = s.start;
                                gridPoints [gridPointsCount++] = s.end;
                            }
                        }
                    }
                }
            }

            int meshGroups = (gridPointsCount / 65000) + 1;
            int meshIndex  = -1;

            if (cellMeshIndices == null || cellMeshIndices.GetUpperBound(0) != meshGroups - 1)
            {
                cellMeshIndices = new int[meshGroups][];
                cellMeshBorders = new Vector3[meshGroups][];
                cellUVs         = new Vector2[meshGroups][];
            }
            if (gridPointsCount == 0)
            {
                cellMeshBorders [0] = new Vector3[0];
                cellMeshIndices [0] = new int[0];
                cellUVs [0]         = new Vector2[0];
            }
            else
            {
                for (int k = 0; k < gridPointsCount; k += 65000)
                {
                    int max = Mathf.Min(gridPointsCount - k, 65000);
                    ++meshIndex;
                    if (cellMeshBorders [meshIndex] == null || cellMeshBorders [0].GetUpperBound(0) != max - 1)
                    {
                        cellMeshBorders [meshIndex] = new Vector3[max];
                        cellMeshIndices [meshIndex] = new int[max];
                        cellUVs [meshIndex]         = new Vector2[max];
                    }
                    for (int j = 0; j < max; j++)
                    {
                        cellMeshBorders [meshIndex] [j].x = gridPoints [j + k].x;
                        cellMeshBorders [meshIndex] [j].y = gridPoints [j + k].y;
                        cellMeshIndices [meshIndex] [j]   = j;
                        cellUVs [meshIndex] [j].x         = gridPoints [j + k].x + 0.5f;
                        cellUVs [meshIndex] [j].y         = gridPoints [j + k].y + 0.5f;
                    }
                }
            }
            refreshMesh = false;             // mesh creation finished at this point
        }
Beispiel #2
0
        void CreateCells()
        {
            int newLength = _gridRows * _gridColumns;

            if (cells == null || cells.Length != newLength)
            {
                cells = new Cell[newLength];
            }
            if (_cellsCosts == null || _cellsCosts.Length != cells.Length)
            {
                _cellsCosts = new CellCosts[newLength];
            }
            lastCellLookupCount = -1;
            _cellLastPointerOn  = -1;
            float qxOffset = _wrapHorizontally ? 0 : 0.25f;

            float qx = _gridColumns * 3f / 4f + qxOffset;

            float stepX = 1f / qx;
            float stepY = 1f / _gridRows;

            float halfStepX    = stepX * 0.5f;
            float centerOffset = halfStepX;
            float halfStepY    = stepY * 0.5f;
            float halfStepX2   = stepX * 0.25f;

            int sidesCount = _gridRows * _gridColumns * 6;

            if (sides == null || sides.Length < sidesCount)
            {
                sides = new CellSegment[_gridRows * _gridColumns * 6];                 // 0 = left-up, 1 = top, 2 = right-up, 3 = right-down, 4 = down, 5 = left-down
            }
            Vector2 center, start, end;

            int sideIndex = 0;
            int cellIndex = 0;

            for (int j = 0; j < _gridRows; j++)
            {
                center.y = (float)j / _gridRows - 0.5f + halfStepY;
                for (int k = 0; k < _gridColumns; k++, cellIndex++)
                {
                    center.x  = (float)k / qx - 0.5f + centerOffset;
                    center.x -= k * halfStepX2;
                    Cell cell = new Cell(j, k, center);

                    float offsetY = (k % 2 == 0) ? 0 : -halfStepY;

                    start.x = center.x - halfStepX;
                    start.y = center.y + offsetY;
                    end.x   = center.x - halfStepX2;
                    end.y   = center.y + halfStepY + offsetY;
                    CellSegment leftUp;
                    if (k > 0 && offsetY < 0)
                    {
                        // leftUp is right-down edge of (k-1, j) but swapped
                        leftUp = sides [sideIndex - 3].swapped;                         // was sides[k - 1, j, 3].swapped;; sideIndex - 3 at this point equals to (k-1, j, 3)
                    }
                    else
                    {
                        leftUp = new CellSegment(start, end);
                    }
                    sides [sideIndex++] = leftUp;                     // 0

                    start.x = center.x - halfStepX2;
                    start.y = center.y + halfStepY + offsetY;
                    end.x   = center.x + halfStepX2;
                    end.y   = center.y + halfStepY + offsetY;
                    CellSegment top = new CellSegment(start, end);
                    sides [sideIndex++] = top;                      // 1

                    start.x = center.x + halfStepX2;
                    start.y = center.y + halfStepY + offsetY;
                    end.x   = center.x + halfStepX;
                    end.y   = center.y + offsetY;
                    CellSegment rightUp = new CellSegment(start, end);
                    if (_wrapHorizontally && k == _gridColumns - 1)
                    {
                        rightUp.isRepeated = true;
                    }
                    sides [sideIndex++] = rightUp;                     // 2

                    CellSegment rightDown;
                    if (j > 0 && k < _gridColumns - 1 && offsetY < 0)
                    {
                        // rightDown is left-up edge of (k+1, j-1) but swapped
                        rightDown = sides [sideIndex - _gridColumns * 6 + 3].swapped;                         // was sides[k + 1, j - 1, 0].swapped
                    }
                    else
                    {
                        start.x   = center.x + halfStepX;
                        start.y   = center.y + offsetY;
                        end.x     = center.x + halfStepX2;
                        end.y     = center.y - halfStepY + offsetY;
                        rightDown = new CellSegment(start, end);
                        if (_wrapHorizontally && k == _gridColumns - 1)
                        {
                            rightDown.isRepeated = true;
                        }
                    }
                    sides [sideIndex++] = rightDown;                     // 3

                    CellSegment bottom;
                    if (j > 0)
                    {
                        // bottom is top edge from (k, j-1) but swapped
                        bottom = sides [sideIndex - _gridColumns * 6 - 3].swapped;                         // was sides[k, j - 1, 1].swapped
                    }
                    else
                    {
                        start.x = center.x + halfStepX2;
                        start.y = center.y - halfStepY + offsetY;
                        end.x   = center.x - halfStepX2;
                        end.y   = center.y - halfStepY + offsetY;
                        bottom  = new CellSegment(start, end);
                    }
                    sides [sideIndex++] = bottom;                     // 4

                    CellSegment leftDown;
                    if (offsetY < 0 && j > 0)
                    {
                        // leftDown is right up from (k-1, j-1) but swapped
                        leftDown = sides [sideIndex - _gridColumns * 6 - 9].swapped;                         // was  sides [k - 1, j - 1, 2].swapped
                    }
                    else if (offsetY == 0 && k > 0)
                    {
                        // leftDOwn is right up from (k-1, j) but swapped
                        leftDown = sides [sideIndex - 9].swapped;                         // was sides [k - 1, j, 2].swapped
                    }
                    else
                    {
                        start.x  = center.x - halfStepX2;
                        start.y  = center.y - halfStepY + offsetY;
                        end.x    = center.x - halfStepX;
                        end.y    = center.y + offsetY;
                        leftDown = new CellSegment(start, end);
                    }
                    sides [sideIndex++] = leftDown;                     // 5

                    if (j > 0 || offsetY == 0)
                    {
                        cell.center.y += offsetY;

                        if (j == 1)
                        {
                            bottom.isRepeated = false;
                        }
                        else if (j == 0)
                        {
                            leftDown.isRepeated = false;
                        }

                        cell.segments [0] = leftUp;
                        cell.segments [1] = top;
                        cell.segments [2] = rightUp;
                        cell.segments [3] = rightDown;
                        cell.segments [4] = bottom;
                        cell.segments [5] = leftDown;
                        if (_wrapHorizontally && k == _gridColumns - 1)
                        {
                            cell.isWrapped = true;
                        }
                        cell.rect2D       = new Rect(leftUp.start.x, bottom.start.y, rightUp.end.x - leftUp.start.x, top.start.y - bottom.start.y);
                        cells [cellIndex] = cell;
                    }
                }
            }
        }