static public Vector3[] buildInlineFairingShape(float baseRad, float maxRad, float topRad,
                                                        float cylStart, float cylEnd, float top,
                                                        Vector4 baseConeShape,
                                                        int baseConeSegments,
                                                        Vector4 vertMapping, float mappingScaleY)
        {
            float baseConeRad = maxRad - baseRad;
            float topConeRad  = maxRad - topRad;

            var baseSlope = new BezierSlope(baseConeShape);

            float baseV0 = vertMapping.x / mappingScaleY;
            float baseV1 = vertMapping.y / mappingScaleY;
            float noseV0 = vertMapping.z / mappingScaleY;

            var shape = new Vector3[2 + (cylStart == 0?0:baseConeSegments + 1) + (cylEnd == top?0:baseConeSegments + 1)];
            int vi    = 0;

            if (cylStart != 0)
            {
                for (int i = 0; i <= baseConeSegments; ++i, ++vi)
                {
                    float t = (float)i / baseConeSegments;
                    var   p = baseSlope.interp(t);
                    shape[vi] = new Vector3(p.x * baseConeRad + baseRad, p.y * cylStart,
                                            Mathf.Lerp(baseV0, baseV1, t));
                }
            }

            shape[vi++] = new Vector3(maxRad, cylStart, baseV1);
            shape[vi++] = new Vector3(maxRad, cylEnd, noseV0);

            if (cylEnd != top)
            {
                for (int i = 0; i <= baseConeSegments; ++i, ++vi)
                {
                    float t = (float)i / baseConeSegments;
                    var   p = baseSlope.interp(1 - t);
                    shape[vi] = new Vector3(p.x * topConeRad + topRad, Mathf.Lerp(top, cylEnd, p.y),
                                            Mathf.Lerp(baseV1, baseV0, t));
                }
            }

            return(shape);
        }
        static public Vector3[] buildFairingShape(float baseRad, float maxRad,
                                                  float cylStart, float cylEnd, float noseHeightRatio,
                                                  Vector4 baseConeShape, Vector4 noseConeShape,
                                                  int baseConeSegments, int noseConeSegments,
                                                  Vector4 vertMapping, float mappingScaleY)
        {
            float baseConeRad = maxRad - baseRad;
            float tip         = maxRad * noseHeightRatio;

            var baseSlope = new BezierSlope(baseConeShape);
            var noseSlope = new BezierSlope(noseConeShape);

            float baseV0 = vertMapping.x / mappingScaleY;
            float baseV1 = vertMapping.y / mappingScaleY;
            float noseV0 = vertMapping.z / mappingScaleY;
            float noseV1 = vertMapping.w / mappingScaleY;

            var shape = new Vector3[1 + (cylStart == 0?0:baseConeSegments) + 1 + noseConeSegments];
            int vi    = 0;

            if (cylStart != 0)
            {
                for (int i = 0; i <= baseConeSegments; ++i, ++vi)
                {
                    float t = (float)i / baseConeSegments;
                    var   p = baseSlope.interp(t);
                    shape[vi] = new Vector3(p.x * baseConeRad + baseRad, p.y * cylStart,
                                            Mathf.Lerp(baseV0, baseV1, t));
                }
            }
            else
            {
                shape[vi++] = new Vector3(baseRad, 0, baseV1);
            }

            for (int i = 0; i <= noseConeSegments; ++i, ++vi)
            {
                float t = (float)i / noseConeSegments;
                var   p = noseSlope.interp(1 - t);
                shape[vi] = new Vector3(p.x * maxRad, (1 - p.y) * tip + cylEnd,
                                        Mathf.Lerp(noseV0, noseV1, t));
            }

            return(shape);
        }
        public static Vector3[] buildFairingShape(float baseRad, float maxRad,
    float cylStart, float cylEnd, float noseHeightRatio,
    Vector4 baseConeShape, Vector4 noseConeShape,
    int baseConeSegments, int noseConeSegments,
    Vector4 vertMapping, float mappingScaleY)
        {
            float baseConeRad=maxRad-baseRad;
            float tip=maxRad*noseHeightRatio;

            var baseSlope=new BezierSlope(baseConeShape);
            var noseSlope=new BezierSlope(noseConeShape);

            float baseV0=vertMapping.x/mappingScaleY;
            float baseV1=vertMapping.y/mappingScaleY;
            float noseV0=vertMapping.z/mappingScaleY;
            float noseV1=vertMapping.w/mappingScaleY;

            var shape=new Vector3[1+(cylStart==0?0:baseConeSegments)+1+noseConeSegments];
            int vi=0;

            if (cylStart!=0)
            {
              for (int i=0; i<=baseConeSegments; ++i, ++vi)
              {
            float t=(float)i/baseConeSegments;
            var p=baseSlope.interp(t);
            shape[vi]=new Vector3(p.x*baseConeRad+baseRad, p.y*cylStart,
              Mathf.Lerp(baseV0, baseV1, t));
              }
            }
            else
              shape[vi++]=new Vector3(baseRad, 0, baseV1);

            for (int i=0; i<=noseConeSegments; ++i, ++vi)
            {
              float t=(float)i/noseConeSegments;
              var p=noseSlope.interp(1-t);
              shape[vi]=new Vector3(p.x*maxRad, (1-p.y)*tip+cylEnd,
            Mathf.Lerp(noseV0, noseV1, t));
            }

            return shape;
        }
        public static Vector3[] buildInlineFairingShape(float baseRad, float maxRad, float topRad,
    float cylStart, float cylEnd, float top,
    Vector4 baseConeShape,
    int baseConeSegments,
    Vector4 vertMapping, float mappingScaleY)
        {
            float baseConeRad=maxRad-baseRad;
            float  topConeRad=maxRad- topRad;

            var baseSlope=new BezierSlope(baseConeShape);

            float baseV0=vertMapping.x/mappingScaleY;
            float baseV1=vertMapping.y/mappingScaleY;
            float noseV0=vertMapping.z/mappingScaleY;

            var shape=new Vector3[2+(cylStart==0?0:baseConeSegments+1)+(cylEnd==top?0:baseConeSegments+1)];
            int vi=0;

            if (cylStart!=0)
            {
              for (int i=0; i<=baseConeSegments; ++i, ++vi)
              {
            float t=(float)i/baseConeSegments;
            var p=baseSlope.interp(t);
            shape[vi]=new Vector3(p.x*baseConeRad+baseRad, p.y*cylStart,
              Mathf.Lerp(baseV0, baseV1, t));
              }
            }

            shape[vi++]=new Vector3(maxRad, cylStart, baseV1);
            shape[vi++]=new Vector3(maxRad, cylEnd, noseV0);

            if (cylEnd!=top)
            {
              for (int i=0; i<=baseConeSegments; ++i, ++vi)
              {
            float t=(float)i/baseConeSegments;
            var p=baseSlope.interp(1-t);
            shape[vi]=new Vector3(p.x*topConeRad+topRad, Mathf.Lerp(top, cylEnd, p.y),
              Mathf.Lerp(baseV1, baseV0, t));
              }
            }

            return shape;
        }