how to speed up c4d.utils.GeRayCollider()



  • On 06/03/2013 at 07:16, xxxxxxxx wrote:

    Hello everybody,

    So I have a working script which gets me the nearest object from an arbitrary start point.
    I am happy with it, but the speed of calculating every object with every object caught me.

    If the Object is lowpoly c4d.utils.GeRayCollider() is quiet fast (~1 ms, 1800 polys) but as soon as it gets a highpoly object to calculate it jumps up to high times (~552ms, 440000 polys).

    I can't exclude the high poly objects hence I want to check for visibility.
    Is it possible to speed up c4d.utils.GeRayCollider() even more somehow?
    I guess I am fishing for help so that my coding marathon was not for nothing.

    kind regards
    mogh

    # Ray stuff and nearest obj -------------------------------------------------------------------------------------   
    def get_ray(start_obj, end_obj, goal) : #modified to accept vectors as start instead of object Global Mg   
        start = ~goal.GetMg() * c4d.Vector(start_obj)   
        end = ~goal.GetMg() * end_obj.GetMg().off   
        return {'ray_p' : start, 'ray_length' : (end - start).GetLength(), 'ray_dir' : (end - start).GetNormalized()}   
      
    def firerayat (start, direction, length, optemp_test) : # startpoint, direction, length, object to colide   
        collider = c4d.utils.GeRayCollider()       
        collider.Init(optemp_test) #force cache rebuild with , True       
        if collider.Intersect(start, direction, length) :         
            return collider.GetNearestIntersection()["distance"]   
           
    def get_nearest_obj (start_point, target, obj_list, jump, overal_counter) :   
        micro_time_start = c4d.GeGetTimer()   
           
        temp_op_distance_list = [] #Reset   
        for obj_rows in obj_list:   
            micro_time_start_a = c4d.GeGetTimer()   
            overal_counter[0] += 1   
            ray = get_ray( start_point, target, obj_rows[0] ) # has to be calculated everytime hence we need the Matrix of the goal   
            distance = firerayat(ray['ray_p'], ray['ray_dir'], ray['ray_length'], obj_rows[0])   
            temp_op_distance_list.append([obj_rows[0] , distance])   
            print overal_counter[0], c4d.GeGetTimer() - micro_time_start_a, " ms internal"   
            
        try:   
            near_obj = min((e for e in temp_op_distance_list if e[1]), key = itemgetter(1))[0]   
            for i, row in enumerate(obj_list) :   
                if near_obj in row:   
                   obj_list[i][2] += 1 # increment the hitcounter   
        except ValueError:   
            near_obj = None   
        print c4d.GeGetTimer() - micro_time_start, " ms"   
    # End ray /////////////////////////////////////////////////////////////////////////////////////
    

Log in to reply