CycleDir GetPerspectiveTriangleOrder(double3 [] pts)
        {
            for (int i = 0; i < pts.Length; i++)
            {
                double z = pts [i].z <= 0 ? 1e-5 : pts [i].z;
                pts [i].xy /= z;
            }

            double signedArea = Math3.SignedArea2(pts [0].xy, pts [1].xy, pts [2].xy);

            return(signedArea >= 0 ? CycleDir.Ccw : CycleDir.Cw);
        }