2
$\begingroup$

I'm trying to use ray_cast() in Blender Python and I found that you need the local location of every object instead of the global location.

I started searching on the web and people said you have to do it this way:

localPos = object.matrix_world_inverted() * target.location

But this gives me the same coordinates as the global location...

$\endgroup$
2
  • 1
    $\begingroup$ Except that the code should read .inverted() with a period, it works when I try it. Is object not at the origin ? $\endgroup$
    – user4979
    Commented Jul 17, 2014 at 12:47
  • $\begingroup$ I'll try with the '.' $\endgroup$
    – Bert VdB
    Commented Jul 17, 2014 at 13:09

1 Answer 1

11
$\begingroup$

Converting global coordinates of object B
to local coordinates of object A

The global coordinate of object A (obj_a)

global_coord = obj_a.matrix_world.translation

To convert from a global coordinate to the local space of object A

local_coord = obj_a.matrix_world.inverted() * global_coord

Using the global coordinate of object A in the local coordinate equation above yeilds Matrix.Identity().translation , since multiplying a matrix by its inverse results in the identity matrix, which has a translation component of (0, 9, 0) aka the origin of our local coordinate system.

Putting it altogether in a test script. Object A is represented by the context object All #other selected objects are iterated as object B.

import bpy
# context for test code
from bpy import context

selected_obs = context.selected_objects
ob_a = context.object
#selected_obs.remove(ob_a) # will be at local origin
mwi = ob_a.matrix_world.inverted()
print("local coordinates of", ob_a.name)
for ob_b in selected_obs:
    local_pos = mwi * ob_b.matrix_world.translation
    print(ob_b.name, local_pos)

Result of running on Default Scene, with cube then camera as active object

local coordinates of Cube
Cube <Vector (0.0000, 0.0000, 0.0000)>
Lamp <Vector (4.0762, 1.0055, 5.9039)>
Camera <Vector (7.4811, -6.5076, 5.3437)>

local coordinates of Camera
Cube <Vector (-0.3382, -0.3767, -11.2523)>
Lamp <Vector (3.1254, 3.9298, -6.5683)>
Camera <Vector (0.0000, 0.0000, -0.0000)>

Global locs from console

>>> for o in C.scene.objects:
...     o.name, o.matrix_world.translation
...     
('Cube', Vector((0.0, 0.0, 0.0)))
('Lamp', Vector((4.076245307922363, 1.0054539442062378, 5.903861999511719)))
('Camera', Vector((7.481131553649902, -6.5076398849487305, 5.34366512298584)))

>>> 
$\endgroup$
5
  • $\begingroup$ I'd like to mention here that the matrix multiplication operator in Blender 2.8 is now @ instead of * $\endgroup$
    – Ahmed Ali
    Commented Nov 2, 2019 at 15:00
  • 2
    $\begingroup$ If you could add that comment to all answers pre 2.8 using * instead of @ that would be great. $\endgroup$
    – batFINGER
    Commented Nov 2, 2019 at 15:48
  • $\begingroup$ If you have applied transformations to an object, it's matrix_world is Matrix(((1.0, 0.0, 0.0, 0.0), (0.0, 1.0, 0.0, 0.0), (0.0, 0.0, 1.0, 0.0), (0.0, 0.0, 0.0, 1.0))) which is useless (2.8x) $\endgroup$ Commented May 17, 2020 at 20:20
  • $\begingroup$ Matrix.Identity(4).translation $\endgroup$ Commented Jan 26, 2021 at 0:34
  • $\begingroup$ Can I do something similar with global rotation and local rotation? $\endgroup$ Commented Jun 3 at 2:24

You must log in to answer this question.

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