private void InitSegmentsIfNull()
        {
            _segments = new QuadSegment[SegmentsCount];
            for (var i = 0; i < SegmentsCount; i++)
            {
                _segments[i] = new QuadSegment();
            }


            _segmentTris = new int[(SegmentsCount - 1) * 4 * 3];

            for (var segment = 0; segment < SegmentsCount - 1; segment++)
            {
                var vno = segment * 3;
                var ind = segment * 3 * 4;
                _segmentTris[ind] = vno; _segmentTris[ind + 1] = vno + 1; _segmentTris[ind + 2] = vno + 2;
                ind += 3;
                _segmentTris[ind] = vno; _segmentTris[ind + 1] = vno + 2; _segmentTris[ind + 2] = vno + 3;     //
                ind += 3;
                _segmentTris[ind] = vno + 2; _segmentTris[ind + 1] = vno + 1; _segmentTris[ind + 2] = vno + 4; //
                ind += 3;
                _segmentTris[ind] = vno + 3; _segmentTris[ind + 1] = vno + 2; _segmentTris[ind + 2] = vno + 4; //
            }
        }
        public Mesh GetStreak(Vector3 from, Vector3 to, float streakWidth, bool head, bool tail)
        {
            InitSegmentsIfNull();

            var headSegment = _segments[SegmentsCount - 1];
            var tailSegment = _segments[0];


            var     vector = to - from;
            Vector3 fromA;
            Vector3 fromB;

            var side = Vector3.Cross(vector, Vector3.forward).normalized *streakWidth / 2;

            if (!tail)
            {
                fromA = _prevA;
                fromB = _prevB;
            }
            else
            {
                fromA = from + side;
                fromB = from - side;
            }


            var toA = to + side;
            var toB = to - side;

            var dirA = toA - fromA;
            var dirB = toB - fromB;

            var offA = dirA.normalized * streakWidth * 0.5f;
            var offB = dirB.normalized * streakWidth * 0.5f;

            if (head)
            {
                headSegment.vertices[0] = toA + offA;
                headSegment.vertices[1] = toB + offB;
            }

            if (tail)
            {
                tailSegment.vertices[0] = fromA - offA;
                tailSegment.vertices[1] = fromB - offB;
            }

            var till = SegmentsCount - (head ? 1 : 0);

            var midSegment = SegmentsCount - 1 - ((tail ? 1 : 0) + (head ? 1 : 0));

            var stepA = (toA - fromA) / midSegment;
            var stepB = (toB - fromB) / midSegment;

            for (var i = (tail ? 1 : 0); i < till; i++)
            {
                var q = _segments[i];
                q.vertices[0] = fromA; //from+ side;
                q.vertices[1] = fromB; //from- side;

                //  from += step;
                fromA += stepA;
                fromB += stepB;
            }


            headSegment.SetSection(head ? SectionType.Head : SectionType.Center);
            tailSegment.SetSection(tail ? SectionType.Tail : SectionType.Center);


            for (var i = 0; i < SegmentsCount - 1; i++)
            {
                _segments[i].SetCenter(_segments[i + 1]);
            }

            var initializing = (!_segmentMesh);

            if (initializing)
            {
                _segmentMesh = new Mesh();
            }

            _segmentMesh.vertices = QuadSegment.VertexArrayFrom(_segments);
            _segmentMesh.uv       = QuadSegment.UvArrayFrom(_segments);

            if (initializing)
            {
                _segmentMesh.triangles = _segmentTris;
            }

            _prevA = toA;
            _prevB = toB;

            _segmentMesh.name = "Segment Mesh";

            return(_segmentMesh);
        }
 public void SetCenter(QuadSegment next)
 {
     vertices[2] = (vertices[0] + vertices[1] + next.vertices[0] + next.vertices[1]) / 4;
     _uv[2]      = (_uv[0] + _uv[1] + next._uv[0] + next._uv[1]) / 4;
 }