0
$\begingroup$

I am trying to write a simple script to understand the use of BVH and ray_cast. In particular, I am interested in knowing the hit location. Here the code:

import bpy
from mathutils.bvhtree import BVHTree
depsgraph = bpy.context.evaluated_depsgraph_get()
bvhtree = BVHTree.FromObject(bpy.data.objects['Cube'], depsgraph)
result = bvhtree.ray_cast((0,0,10),(0,0,-10))
print(result[0])

In this example, I use the default cube mesh, the source origin is at (0,0,10), and the the ray is directed down along the z-axis. If I run the script once, I get the correct result (0,0,1). However, if I then move my cube (e.g. 1 meter up), then I still get the same result (0,0,1), but I should get (0,0,2). Any idea why?

$\endgroup$

1 Answer 1

3
$\begingroup$

It is seems to be in local space. Try converting to global space:

print(bpy.context.object.matrix_world @ result[0])

It is not clear from your example, but rays should be in local space, aren't they?

So you have to convert ray to cube space, because your example will not work with cube shifted in X or Y axis.

Here is the final code:

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

object_matrix_inverted = copy.copy(bpy.context.object.matrix_world)
object_matrix_inverted.invert()

# apply local transform:
target = object_matrix_inverted @ Vector((0,0,10))
# direction vector is relative, no need to apply transform matrix
direction = Vector((0,0,-10))

depsgraph = bpy.context.evaluated_depsgraph_get()
bvhtree = BVHTree.FromObject(bpy.data.objects['Cube'], depsgraph)
result = bvhtree.ray_cast(target, direction)

# apply world transform:
if result[0] is None:
    print("Miss")
else:
    print(bpy.context.object.matrix_world @ result[0])
$\endgroup$
6
  • $\begingroup$ wasn't enough to just add print(bpy.context.object.matrix_world @ result[0])? It worked. $\endgroup$
    – Alex Mekx
    Jul 26, 2022 at 11:13
  • 1
    $\begingroup$ It works until you don't move the cube in any direction except Z $\endgroup$
    – Crantisz
    Jul 26, 2022 at 11:15
  • $\begingroup$ I actually get some errors when running your code. Instead of goal did you mean direction? Also, when I move the cube on xy plane, I get an error: Python: Traceback (most recent call last): File "\Text", line 19, in <module> TypeError: Matrix multiplication: not supported between 'Matrix' and 'NoneType' types $\endgroup$
    – Alex Mekx
    Jul 26, 2022 at 11:19
  • $\begingroup$ Yep, you are right $\endgroup$
    – Crantisz
    Jul 26, 2022 at 11:20
  • 1
    $\begingroup$ This is then ray misses the object. You can add a check like this (updated the post) $\endgroup$
    – Crantisz
    Jul 26, 2022 at 12:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .