public static RenderGeometry CreateConeGeometry(float radius, float height, int segmentP, int segmentH, bool smoothH, bool smoothV, float cutTop = 0, float cutAngle = 0)
    {
        if (cutTop == 0)
        {
            StructureGeometry       structure = new StructureGeometry();
            RenderGeometry.FaceType faceType  = GetFaceType(smoothH, smoothV);

            SurfaceComponentGeometry coneCap = SurfaceComponentGeometries.CreateConeCapGeometry(radius, height, segmentP, segmentH, cutAngle, 1, faceType);
            if (cutAngle == 0)
            {
                SurfaceComponentGeometry bottom = SurfaceComponentGeometries.CreateRegularPolygonGeometry(radius, segmentP, 2);
                bottom.ApplyRotation(Quaternion.AngleAxis(180, Vector3.right));

                Vertex corner = structure.CreateVertex();
                structure.CreateFace(coneCap, false, corner);
                structure.CreateFace(bottom, false, corner);
            }
            else
            {
                SurfaceComponentGeometry bottom = SurfaceComponentGeometries.CreateFanCapGeometry(radius, segmentP, 1, cutAngle, 2);
                SurfaceComponentGeometry wall1  = SurfaceComponentGeometries.CreateTriangleGeometry(1, 1, 0, segmentH, true, 3);
                SurfaceComponentGeometry wall2  = SurfaceComponentGeometries.CreateTriangleGeometry(1, 1, 0, segmentH, true, 4);

                Vertex cornerUp    = structure.CreateVertex(new Vector3(0, height, 0));
                Vertex cornerDownC = structure.CreateVertex(Vector3.zero);
                Vertex cornerDown1 = structure.CreateVertex(new Vector3(radius * Mathf.Cos(cutAngle), 0, -radius * Mathf.Sin(cutAngle)));
                Vertex cornerDown2 = structure.CreateVertex(new Vector3(radius, 0, 0));

                structure.CreateFace(coneCap, true, cornerDown1, cornerDown2, cornerUp);
                structure.CreateFace(bottom, true, cornerDown2, cornerDown1, cornerDownC);
                structure.CreateFace(wall1, true, cornerDown1, cornerUp, cornerDownC);
                structure.CreateFace(wall2, true, cornerDownC, cornerUp, cornerDown2);
            }
            return(structure.Build());
        }
        else
        {
            RenderGeometry geometry = CreateCylinderGeometry(radius, height, segmentP, segmentH, smoothH, smoothV, cutAngle);
            geometry.ApplyOffset(Vector3.up * (height / 2));

            float     shrinkCoeff = (1 - cutTop) / height;
            SpaceWarp warp        = new SpaceWarp($"x*(1-y*{shrinkCoeff})", "y", $"z*(1-y*{shrinkCoeff})");
            geometry.ApplySpaceWarp(warp);
            return(geometry);
        }
    }
    public static RenderGeometry CreateTorusGeometry(float ringRadius, float barRadius, int segmentRing, int segmentBar, bool smoothH, bool smoothV, float cutAngle = 0, float deltaAngle = 0)
    {
        StructureGeometry structure = new StructureGeometry();

        RenderGeometry.FaceType faceType = GetFaceType(smoothH, smoothV);

        SurfaceComponentGeometry face = SurfaceComponentGeometries.CreatePlaneGeometry(1, 1, segmentBar, segmentRing, 1, faceType);

        var warp = new SpaceWarp(
            $" a1=(z+0.5)*(2*PI-{cutAngle})",
            $" a2={deltaAngle}-x*(2*PI)",
            $" r={ringRadius}+{barRadius}*cos(a2)",
            $" X=r*cos(a1)",
            $" Y={barRadius}*sin(a2)",
            $" Z=r*sin(a1)"
            );

        face.ApplySpaceWarp(warp);

        if (cutAngle == 0)
        {
            Vertex corner = structure.CreateVertex();
            structure.CreateFace(face, false, corner, corner, corner, corner);
        }
        else
        {
            SurfaceComponentGeometry cap1 = SurfaceComponentGeometries.CreateRegularPolygonGeometry(barRadius, segmentBar, 2);
            SurfaceComponentGeometry cap2 = SurfaceComponentGeometries.CreateRegularPolygonGeometry(barRadius, segmentBar, 2);
            cap1.ApplyRotation(Quaternion.LookRotation(Vector3.down, Vector3.back) * Quaternion.AngleAxis(-deltaAngle, Vector3.up));
            cap1.ApplyOffset(Vector3.right * ringRadius);
            cap2.ApplyRotation(Quaternion.LookRotation(Vector3.up, Quaternion.AngleAxis(cutAngle * Mathf.Rad2Deg, Vector3.up) * Vector3.forward) * Quaternion.AngleAxis(deltaAngle * Mathf.Rad2Deg, Vector3.up));
            cap2.ApplyOffset(new Vector3(ringRadius * Mathf.Cos(cutAngle), 0, -ringRadius * Mathf.Sin(cutAngle)));

            Vertex corner1 = structure.CreateVertex();
            Vertex corner2 = structure.CreateVertex();
            structure.CreateFace(face, false, corner1, corner2, corner2, corner1);
            structure.CreateFace(cap1, false, corner1);
            structure.CreateFace(cap2, false, corner2);
        }
        return(structure.Build());
    }
    public static RenderGeometry CreateCapsuleGeometry(float radius, float height, int segmentP, int segmentH1, int segmentH2, bool smoothH, bool smoothV)
    {
        StructureGeometry structure = new StructureGeometry();

        RenderGeometry.FaceType faceType = GetFaceType(smoothH, smoothV);

        SurfaceComponentGeometry side = SurfaceComponentGeometries.CreateCylinderSideGeometry(radius, height, segmentP, segmentH1, faceType: faceType);

        SurfaceComponentGeometry upperCap = SurfaceComponentGeometries.CreateSphereCapGeometry(radius, segmentP, segmentH2, faceType: faceType);
        SurfaceComponentGeometry lowerCap = SurfaceComponentGeometries.CreateSphereCapGeometry(radius, segmentP, segmentH2, faceType: faceType);

        lowerCap.ApplyRotation(Quaternion.AngleAxis(180, Vector3.right));

        Vertex cornerUp   = structure.CreateVertex(new Vector3(radius, height / 2, 0));
        Vertex cornerDown = structure.CreateVertex(new Vector3(radius, -height / 2, 0));

        structure.CreateFace(side, false, cornerUp, cornerUp, cornerDown, cornerDown);
        structure.CreateFace(upperCap, true, cornerUp);
        structure.CreateFace(lowerCap, true, cornerDown);
        return(structure.Build());
    }