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 }
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; } } } }