Scaling the maximum range parameter of BVHTree.ray_cast I'm currently trying to use the BVHTree.ray_cast function for some distance measuring. The code down below is a minimal example of what I want to do. A plane is spawned and two rays are fired in it's direction. Without any scaling, the ray with a maximum distance of 9 doesn't return any hit while the ray with a maximum distance of 11 does. So far, so good. 

The problem now is that after scaling the target, both rays return a hit. For the setup given, I figured out that a maximum range of 1.4 doesn't hit while a range of 1.5 does. Now I don't have a clue how the scale the value for the maximum range, so that the behaviour is correct.

import bpy
from bpy import context 
from mathutils.bvhtree import BVHTree
from mathutils import Vector

def castRay(origin, direction, maxRange):
    # perform actual ray cast
    location, normal, index, distance = tree.ray_cast(origin, direction, maxRange)

    # print results
    if location is not None:
        print("Location ", mw @ location)
        print("Normal ", mw @ normal)
        print("Index ", index)
        print("Distance ", distance)
    else:
        print("No hit within range of %f" % maxRange)

# spawn new plane
bpy.ops.mesh.primitive_plane_add(size=2, enter_editmode=False, align='WORLD', location=(10, 0, 0), rotation=(0, 1.5708, 0))
target = bpy.context.active_object

# after uncommenting the following line, both ray casts return a hit
#target.scale = Vector((3.0,5.0,7.0))

# setup information needed for ray casting
depsgraph = context.evaluated_depsgraph_get()
tree = BVHTree.FromObject(target, depsgraph)

# setup origin and destination of ray
worldOrigin = Vector((0.0,0.0,0.0))
worldDestination = Vector((20.0,0.0,0.0))

# convert vectors into target coordinate system
mw = target.matrix_world
mwi = mw.inverted()

origin = mwi @ worldOrigin
destination = mwi @ worldDestination

# calculate direction in target coordinate system
direction = (destination - origin).normalized()

# fire rays
castRay(origin, direction,  9)
castRay(origin, direction, 11)
I now found a solution to this problem myself, so I post it here in case someone comes across this question. Instead of building the BVHTree directly from the object and transforming all returned values into the global coordinate system, it is way more handy to transform the object's coordinates once into the global space as it is shown here:

def bvhtree_from_object(ob):
    import bmesh
    bm = bmesh.new()

    mesh = ob.to_mesh(bpy.context.depsgraph, True)
    bm.from_mesh(mesh)
    bm.transform(ob.matrix_world)

    bvhtree = BVHTree.FromBMesh(bm)
    bpy.data.meshes.remove(mesh)
    return bvhtree


The ray_cast function then returns all values in global space so that no more transformation is needed.