         : bound(bound), boundInvSize(bound.InvertedSize()) {}
 
     __host__ __device__
-    inline MortonCode operator()(const thrust::tuple<float4, float4> ray) {
+    inline MortonCode operator()(const thrust::tuple<float4, float4> ray) const {
 
         float3 origin = make_float3(thrust::get<0>(ray));
         const float3 direction = make_float3(thrust::get<1>(ray));
+        return (*this)(origin, direction);
+    }
+    
+    __host__ __device__
+    inline MortonCode operator()(float3 origin, const float3 direction) const {
         
         float tHit;
         if (!bound.ClosestIntersection(origin, direction, tHit)) 

    int counter = 0;
    while (spherePartitions.size() - leafNodes > 0) {
        ++counter;
        cout << "\n *** ROUND " << counter << " - FIGHT ***\n" << endl;

        // Create new ray partitions through binary search
        const size_t activeNodes = rayPartitions.size() - leafNodes;

    out << i << ": [rays: [" << rayPartition.x << " -> " << rayPartition.y << 
        "], spheres: [" << spherePartition.x << " -> " << spherePartition.y << "]]";
    if (verbose) {
        Ray rMin = rays->GetLeafRay(rayPartition.x);
        Ray rMax = rays->GetLeafRay(rayPartition.y-1);
        
        RayMortonCoder rayMortonCoder(spheresGeom->GetBounds());
        MortonCode cMin = rayMortonCoder(rMin.origin, rMin.direction);
        MortonCode cMax = rayMortonCoder(rMin.origin, rMin.direction);
        out << "\n  Rays: [min: " << cMin << "\n         max: " << cMax << "]";
        out << "\n  Ray bound: " << MortonBound::LowestCommonBound(cMin, cMax);
        
        // out << "\n  Rays: [";
        // for (int r = rayPartition.x; r < rayPartition.y; ++r) {
        //     out << rays->GetLeafRay(r).id;
