private double blending(double x, double R) {
    int m = 1, n = 2;
    m = SceneManager.get().csgM;
    n = SceneManager.get().csgN;
    if (x > R) return 0;
    else if (x < -R) return 2;
    else if (0 <= x && x <= R)
      return (1.0 / Math.pow(R, m * n)) * Math.pow(Math.pow(R, m) - Math.pow(x, m), n);
    else if (-R <= x && x <= 0)
      return 2 - (1.0 / Math.pow(R, m * n)) * Math.pow(Math.pow(R, m) + Math.pow(x, m), n);

    // XXX: in some cases x is NaN, i don't know what is happening, i will just return zero
    return 0;

    // throw new RuntimeException("Unexpected value in function blending(): " + x);
  }
  private double basicCSG(Vector3f point, Skeleton currentSkeleton) {
    double sum = 0;
    boolean isCSG = SceneManager.get().csgEnabled;

    for (int i = 0; i < currentSkeleton.branches.size(); i++) {
      SkeletonBranch branch = currentSkeleton.branches.get(i);
      for (int j = 0; j < branch.points.size() - 1; j++) {
        SkeletonPoint SP1 = branch.points.get(j);
        SkeletonPoint SP2 = branch.points.get(j + 1);
        //            TriangulationPoint P1 = SP1.point;
        //            TriangulationPoint P2 = SP2.point;
        //            Vector3f p = new Vector3f(P1.getXf(), P1.getYf(), P1.getZf());
        //            Vector3f q = new Vector3f(P2.getXf(), P2.getYf(), P2.getZf());
        Vector3f p = SP1.point;
        Vector3f q = SP2.point;

        // calculate radius of influence
        float Rp = (float) SP1.radius;
        float Rq = (float) SP2.radius;

        // calculate surface points Sp and Sq
        Vector3f PQ = q.subtract(p);
        Vector3f normalVector = new Vector3f(-PQ.getY(), PQ.getX(), PQ.getZ()).normalize();
        Vector3f Sp = p.add(normalVector.mult(Rp));
        Vector3f Sq = q.add(normalVector.mult(Rq));
        Vector3f Smid = Sp.add(Sq).divide(2f);

        // System.out.println("L: " + PQ.length() + " Sp: " + Sp + " Sq: " +
        // Sq + " Smid: " + Smid);

        // calculate weights
        double w0 = T / flt(Sp, p, q);
        double w1 = T / ft(Sq, p, q);

        // division factor
        w0 /= (double) SP1.divisionFactor;
        w1 /= (double) SP2.divisionFactor;

        double k = T / (w0 * flt(Smid, p, q) + w1 * ft(Smid, p, q));

        // scale factor
        w0 *= k;
        w1 *= k;

        // System.out.println("j " + j);
        // System.out.println("w0 " + w0 + " w1 " + w1);

        // CSG blending
        if (isCSG) {
          double fx = cauchy(point, p, q, w0, w1);
          double R = cauchy(Smid, p, q, w0, w1);
          double blending = blending(-fx + T, R);
          sum += blending;
        } else {
          // common sum
          sum += cauchy(point, p, q, w0, w1);
        }
      }
    }

    // if(sum > 1)
    // blendingGTone++;
    // else if(sum < 1)
    // blendingLTone++;

    // sum /= n;

    // Vector3f A = new Vector3f(-5f, 0.0f, 0.0f);
    // Vector3f B = new Vector3f(5f, 0.0f, 0.0f);
    // Vector3f C = new Vector3f(-5f, 4.0f, 0.0f);
    // Vector3f D = new Vector3f(5f, 4.0f, 0.0f);
    //
    // // define threshold based on a pre determined surface point
    // float radius = 5.0f;
    // Vector3f AB = B.subtract(A);
    // Vector3f normalVectorAB = new Vector3f(-AB.getY(), AB.getX(),
    // AB.getZ()).normalize().mult(radius);
    // Vector3f midPointAB = (A.add(B)).divide(2f);
    // Vector3f surfacePointAB = midPointAB.add(normalVectorAB);
    //
    // T = 1.0;
    //
    // sum += blending(-cauchy(point, A, B) + T, cauchy(surfacePointAB, A,
    // B));
    // sum += blending(-cauchy(point, C, D) + T, cauchy(surfacePointAB, C,
    // D));

    // sum = cauchy(point, A, B) + cauchy(point, C, D);

    //      if(!single) //i.e. is multiple
    //      {
    //          // common sum
    ////          double result = -sum + T;
    ////          if (result > 0)
    ////             positive++;
    ////          else if (result < 0)
    ////             negative++;
    ////          return result;
    //          return sum;
    //      }
    //      else
    //      {
    if (!isCSG) return T - sum;
    else
      // CSG composition
      return 1 - sum;
    //      }
  }