static public boolean intersect3(DwRay3D ray, float[] A, float[] B, float[] C, boolean two_sided, float[] ptr_hit_backface, float[] tuv){
    
    float rdx = ray.d[0];
    float rdy = ray.d[1];
    float rdz = ray.d[2];
    
    // edge1: v0 -> v1     // edge2: v0 -> v2
    E1x = B[0]-A[0];  E2x = C[0]-A[0];
    E1y = B[1]-A[1];  E2y = C[1]-A[1]; 
    E1z = B[2]-A[2];  E2z = C[2]-A[2];

    // normal
    nx = E1y * E2z - E1z * E2y;
    ny = E1z * E2x - E1x * E2z;
    nz = E1x * E2y - E1y * E2x;
    
    if( (nx*rdx+ny*rdy+nz*rdz) > 0.0){ // angle > 0.0
      ptr_hit_backface[0] = -1.0f;   // if there is any intersection it would be with a backface
      if( two_sided ) {              // so if the triangle is two_sided, switch edges for further computation
        swap_E1_E2();
      } else {
        return false;      // otherwise return "no intersection"
      }
    } else {
      ptr_hit_backface[0]= +1.0f;    // no backface, so normal direction stays the same
    }
    
    // cross of ray-direction and edge2
    Px = rdy * E2z - rdz * E2y;
    Py = rdz * E2x - rdx * E2z;
    Pz = rdx * E2y - rdy * E2x;
    
    det = E1x*Px + E1y*Py + E1z*Pz; // determinant
    if( Math.abs(det) < epsilon ) return false;
//    if( det < epsilon ) return Float.MAX_VALUE;
    
    // vector: v0 -> ray-origin
    Tx = ray.o[0] - A[0];
    Ty = ray.o[1] - A[1];
    Tz = ray.o[2] - A[2];
    u = Tx*Px + Ty*Py + Tz*Pz; // param u, + testing bounds
    if( u < 0.0 || u > det) return false;

    // cross of T and edge2
    Qx = Ty * E1z - Tz * E1y;
    Qy = Tz * E1x - Tx * E1z;
    Qz = Tx * E1y - Ty * E1x;
    v = Qx*rdx + Qy*rdy + Qz*rdz; // param v, + testing bounds
    if( v < 0.0 || (u+v) > det) return false;

    det = 1f/det;
    tuv[0] = det*(Qx*E2x + Qy*E2y + Qz*E2z);
    tuv[1] = det*u;
    tuv[2] = det*v;
    return true;
  }