public void traverseRayTopDown(OctreeHitResult hit_result){
    if( hit_result == null ){
      return ;
    }
    
    IDX_SHFT = 0;
    DwRay3D ray_mod = hit_result.ray.copy();  // copy ray

    if( mirrorComponent(root.aabb, ray_mod, 0) ) IDX_SHFT |= 4;
    if( mirrorComponent(root.aabb, ray_mod, 1) ) IDX_SHFT |= 2;
    if( mirrorComponent(root.aabb, ray_mod, 2) ) IDX_SHFT |= 1;
    
    // get intersection intervals
    float[] t0 = DwVec3.multiply_new(DwVec3.sub_new(root.aabb.min, ray_mod.o), ray_mod.d_rec);
    float[] t1 = DwVec3.multiply_new(DwVec3.sub_new(root.aabb.max, ray_mod.o), ray_mod.d_rec);

    OctreeTraversalData otd = new OctreeTraversalData(root,t0,t1);

    // if ray hits octree (root), traverse childs
    if( otd.tNear() < otd.tFar() ){ 
//      traverseOctree(otd, hit_result);
      traverseOctreeRecursive(otd, hit_result);
      for( OctreeTraversalData td_checked : hit_result.traversal_history){
        for(int id : td_checked.node.IDX_triangles){
          obj.f[id].FLAG_CHECKED = false; // reset flags!
        }
      }
    }
  }