public static RenderGeometry CreateCylinderGeometry(float radius, float height, int segmentP, int segmentH, bool smoothH, bool smoothV, float cutAngle = 0, float hollowRatio = 0)
    {
        StructureGeometry structure = new StructureGeometry();

        RenderGeometry.FaceType faceType = GetFaceType(smoothH, smoothV);
        float hollowRadius = hollowRatio * radius;

        SurfaceComponentGeometry side      = SurfaceComponentGeometries.CreateCylinderSideGeometry(radius, height, segmentP, segmentH, cutAngle, false, 1, faceType);
        SurfaceComponentGeometry sideInner = null;

        if (hollowRatio > 0)
        {
            sideInner = SurfaceComponentGeometries.CreateCylinderSideGeometry(hollowRadius, height, segmentP, segmentH, cutAngle, true, 1, faceType);
        }
        SurfaceComponentGeometry upperCap, lowerCap;

        if (hollowRatio > 0)
        {
            upperCap = SurfaceComponentGeometries.CreateRingCapGeometry(radius, hollowRadius, segmentP, 1, cutAngle, 2);
            lowerCap = SurfaceComponentGeometries.CreateRingCapGeometry(radius, hollowRadius, segmentP, 1, cutAngle, 2);
        }
        else if (cutAngle == 0)
        {
            upperCap = SurfaceComponentGeometries.CreateRegularPolygonGeometry(radius, segmentP, 2);
            lowerCap = SurfaceComponentGeometries.CreateRegularPolygonGeometry(radius, segmentP, 2);
        }
        else
        {
            upperCap = SurfaceComponentGeometries.CreateFanCapGeometry(radius, segmentP, 1, cutAngle, 2);
            lowerCap = SurfaceComponentGeometries.CreateFanCapGeometry(radius, segmentP, 1, cutAngle, 2);
        }
        lowerCap.ApplyRotation(Quaternion.AngleAxis(cutAngle * Mathf.Rad2Deg, Vector3.up) * Quaternion.AngleAxis(180, Vector3.right));

        if (cutAngle == 0)
        {
            Vertex cornerUp   = structure.CreateVertex(new Vector3(radius, height / 2, 0));
            Vertex cornerDown = structure.CreateVertex(new Vector3(radius, -height / 2, 0));
            if (hollowRatio == 0)
            {
                structure.CreateFace(side, false, cornerUp, cornerUp, cornerDown, cornerDown);
                structure.CreateFace(upperCap, true, cornerUp);
                structure.CreateFace(lowerCap, true, cornerDown);
            }
            else
            {
                Vertex cornerUpInner   = structure.CreateVertex(new Vector3(hollowRadius, height / 2, 0));
                Vertex cornerDownInner = structure.CreateVertex(new Vector3(hollowRadius, -height / 2, 0));
                structure.CreateFace(side, false, cornerUp, cornerUp, cornerDown, cornerDown);
                structure.CreateFace(sideInner, false, cornerDownInner, cornerDownInner, cornerUpInner, cornerUpInner);
                structure.CreateFace(upperCap, true, cornerUpInner, cornerUpInner, cornerUp, cornerUp);
                structure.CreateFace(lowerCap, true, cornerDownInner, cornerDownInner, cornerDown, cornerDown);
            }
        }
        else
        {
            SurfaceComponentGeometry wall1 = SurfaceComponentGeometries.CreatePlaneGeometry(1, 1, 1, segmentH, 3);
            SurfaceComponentGeometry wall2 = SurfaceComponentGeometries.CreatePlaneGeometry(1, 1, 1, segmentH, 4);

            Vertex cornerUp1   = structure.CreateVertex(new Vector3(radius * Mathf.Cos(cutAngle), height / 2, -radius * Mathf.Sin(cutAngle)));
            Vertex cornerUp2   = structure.CreateVertex(new Vector3(radius, height / 2, 0));
            Vertex cornerDown1 = structure.CreateVertex(new Vector3(radius * Mathf.Cos(cutAngle), -height / 2, -radius * Mathf.Sin(cutAngle)));
            Vertex cornerDown2 = structure.CreateVertex(new Vector3(radius, -height / 2, 0));
            if (hollowRatio == 0)
            {
                Vertex cornerUpC   = structure.CreateVertex(new Vector3(0, height / 2, 0));
                Vertex cornerDownC = structure.CreateVertex(new Vector3(0, -height / 2, 0));
                structure.CreateFace(side, false, cornerUp2, cornerUp1, cornerDown1, cornerDown2);
                structure.CreateFace(upperCap, true, cornerUp1, cornerUp2, cornerUpC);
                structure.CreateFace(lowerCap, true, cornerDown2, cornerDown1, cornerDownC);
                structure.CreateFace(wall1, true, cornerUpC, cornerDownC, cornerDown1, cornerUp1);
                structure.CreateFace(wall2, true, cornerDownC, cornerUpC, cornerUp2, cornerDown2);
            }
            else
            {
                Vertex cornerUp1Inner   = structure.CreateVertex(new Vector3(hollowRadius * Mathf.Cos(cutAngle), height / 2, -hollowRadius * Mathf.Sin(cutAngle)));
                Vertex cornerUp2Inner   = structure.CreateVertex(new Vector3(hollowRadius, height / 2, 0));
                Vertex cornerDown1Inner = structure.CreateVertex(new Vector3(hollowRadius * Mathf.Cos(cutAngle), -height / 2, -hollowRadius * Mathf.Sin(cutAngle)));
                Vertex cornerDown2Inner = structure.CreateVertex(new Vector3(hollowRadius, -height / 2, 0));
                structure.CreateFace(side, false, cornerUp2, cornerUp1, cornerDown1, cornerDown2);
                structure.CreateFace(sideInner, false, cornerDown2Inner, cornerDown1Inner, cornerUp1Inner, cornerUp2Inner);
                structure.CreateFace(upperCap, true, cornerUp2Inner, cornerUp1Inner, cornerUp1, cornerUp2);
                structure.CreateFace(lowerCap, true, cornerDown1Inner, cornerDown2Inner, cornerDown2, cornerDown1);
                structure.CreateFace(wall1, true, cornerUp1Inner, cornerDown1Inner, cornerDown1, cornerUp1);
                structure.CreateFace(wall2, true, cornerDown2Inner, cornerUp2Inner, cornerUp2, cornerDown2);
            }
        }
        return(structure.Build());
    }