public void subdivide(BvhNodeT node){
    if( !needsSubdivision(node)) 
      return;
    
    ArrayList<Integer> subset_A = new ArrayList<Integer>(0);
    ArrayList<Integer> subset_B = new ArrayList<Integer>(0);
    
    float SAH = Float.MAX_VALUE;

    // find best SAH
    
    // 1) aabb max
    for(int i = 0; i < 3; i++){
      sort_aabb_max.dim(i);
      Collections.sort( node._getObjects(), sort_aabb_max ); 
      SAH = genChildSubsets(SAH, node, subset_A, subset_B);
    }

    // 2) aabb center
    if( SAH_OPTIMIZATION >= 1) {
      for(int i = 0; i < 3; i++){
        sort_aabb_center.dim(i);
        Collections.sort( node._getObjects(), sort_aabb_center ); 
        SAH = genChildSubsets(SAH, node, subset_A, subset_B);
      }
    }

    // 3) face center
    if( SAH_OPTIMIZATION >= 2) {
      for(int i = 0; i < 3; i++){
        sort_face_center.dim(i);
        Collections.sort( node._getObjects(), sort_face_center ); 
        SAH = genChildSubsets(SAH, node, subset_A, subset_B);
      }
    }

    node.deleteObjects(); // node.IDX_triangles.clear();
    
    node.childA( new BvhNodeT(node._getDepth()+1, BvhBuilder.getAABBfromTriangles(obj, subset_A), subset_A) );
    node.childB( new BvhNodeT(node._getDepth()+1, BvhBuilder.getAABBfromTriangles(obj, subset_B), subset_B) );
    
    if( subset_A.size() >= subset_B.size() ){
      node.swapChilds();
    }
    
//    float[] eps = {0.01f, 0.01f, 0.01f};
//
//    DwVec3.add_ref_slf(eps, node.childA()._getAABB().max);
//    DwVec3.sub_ref_slf(eps, node.childA()._getAABB().min);
//    DwVec3.add_ref_slf(eps, node.childB()._getAABB().max);
//    DwVec3.sub_ref_slf(eps, node.childB()._getAABB().min);
    
    subdivide(node.childA());
    subdivide(node.childB());
    
    
//    if( node.child_A.aabb.getSurfaceArea() < node.child_B.aabb.getSurfaceArea() ){
//      node.swapChilds();
//    }
//    
//    if( node.child_A.getNumberOfchilds() >= node.child_B.getNumberOfchilds() ){
//      node.swapChilds();
//    }
    
  }