# Transforms direction from local space to world space?

How to Transforms direction from local space to world space?

May I use a unity3d doc explain the detail?
http://docs.unity3d.com/Documentation/ScriptReference/Transform.TransformDirection.html

Yes. I’m wondering a function in Blender like that or How to Do it in Blender?
Thanks.

there is convert_space for objects:
http://www.blender.org/documentation/blender_python_api_2_67_1/bpy.types.Object.html?highlight=convert_space#bpy.types.Object.convert_space

But generally, you just multiply a matrix with a local-space vector to get a global-space vector (assuming that matrix describes the relation between local and global space)

Usually you would do:

mat = bpy.context.object.matrix_world
vec = Vector((1,2,3))
vec_global = mat * vec

1 Like

Dear CoDEmanX.

convert_space Should be my wondering.

Thanks!

hm~
matrix * local_position can’t for direction.

So. I checked convert_space.
convert_space(pose_bone, matrix, from_space, to_space)

That’s meaning I should convert Vector3(direction) to matrix.

Then. I checked
http://www.blender.org/documentation/blender_python_api_2_67_1/mathutils.html
It’s seems no function convert Vector3 to Matrix directly.

Anyone show me the way?

Thanks!

What do you mean by “cant for direction” ?

There is no real difference between a position and a direction. Both are 3D vectors, and any vector can act as a direction (except a null vector of course). A vector is generally normalized in order to be useful as a direction.

What is it you are trying to do exactly?

Vector to Matrix, that is kinda impossible. A 3x3 matrix is basically a set of 3 vectors, all perpendicular to each other, up / forward / right. So how would you construct a matrix from a single vector? You could, but you would have to assume that it is e.g. the forward vector, then calc a vector that points right relative to your vector and assume up to be 0,0,1 etc.

I posted something about such matrix construction recently, so you may wanna search the python forums.

@Muffy
Thanks for your join.
This’s my test code.

``````
import bpy
import random

C = bpy.context

bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)

staticCube = C.active_object
staticCube.name = 'static'
staticCube.rotation_euler.x = random.random()

dynamicCube_for_position = C.active_object
dynamicCube_for_position.name = 'dynamic_for_position'
dynamicCube_for_position.rotation_euler.y = random.random()

dynamicCube_for_rotation = C.active_object
dynamicCube_for_rotation.name = 'dynamic_for_rotation'
dynamicCube_for_rotation.rotation_euler.y = random.random()

static_point_index = 2 #input any uint less than 6
static_wm = staticCube.matrix_world
static_point_position = staticCube.data.vertices[2].co
static_point_normal = staticCube.data.vertices[2].normal

## Begain Test

#"wm * co" is OK
dynamicCube_for_position.location = static_wm * static_point_position

#I'm not sure.But it's seems wrong result.
dynamicCube_for_rotation.rotation_euler = static_wm * static_point_normal

``````

@CoDEmanX
Should I google “python CoDEmanX matrix”?
Could you give me a URL? Thanks.

Dear CoDEmanX:
Thanks for your guide every time. My best mentor.
finally. I use a data-function to rotate the mesh.

This is my test code.

``````
import bpy
from mathutils import Matrix, Vector

C = bpy.context

#need two mesh, each one must have 1 selected point.
aobj = C.active_object
sobj = [i for i in C.selected_objects if i!= aobj][0]

selpnt = lambda x : [i.index for i in x.data.vertices if i.select][0]
apnt = selpnt(aobj)
spnt = selpnt(sobj)

amat = aobj.matrix_world.copy()
smat = sobj.matrix_world.copy()
anor = aobj.data.vertices[apnt].normal.copy().normalized()
snor = sobj.data.vertices[spnt].normal.copy().normalized()

#convert
amat = amat.inverted().transposed()
smat = smat.inverted().transposed()
anor = amat * anor
snor = smat * snor

angle = anor.angle(snor)
axis  = snor.cross(anor).normalized()
rot = Matrix.Rotation(angle, 4, axis)

#
#my addon use "bpy.ops.transform.rotate" cause Blender 2.65+ crash.
#I guess I'll never have capability for figure out that.
#so. I changed to this way.
#But in this way.
#
sobj.data.transform(rot)
sobj.data.update()

``````

Just to note; by using (mesh).data.transform(M), you are not transforming the object but rather all of the vertices in the object’s mesh data. Your object has not really rotated, its all of the vertices that have moved.

If you are looking to align the second object to a normal vector on the first object, you could just build a transformation matrix based on a position and normal that could then simply be applied as a target’s world matrix :

``````
import bpy
from math import pi
from random import random as Rfloat
from random import randint as Rint
from mathutils import *

C = bpy.context
SC = bpy.context.scene

#static mesh
meshA = SC.objects['Mesh_A']
#align mesh
meshB = SC.objects['Mesh_B']

### Randomize mesh A transform
meshA.rotation_euler = ( Rfloat()*pi*2 , Rfloat()*pi*2 , Rfloat()*pi*2 )

'''
Scene.update() necessary here. Otherwise transform matrix will not
update until end of script.
'''
C.scene.update()

### Get vertice WS co and WS normal
vnum = Rint(0,len(meshA.data.vertices)-1) #get a random vert on target
WM = meshA.matrix_world #get target current world transform
TGTloc = WM * (meshA.data.vertices[vnum].co) #target WS vert coord
TGTnrml = WM.copy().to_3x3() * (meshA.data.vertices[vnum].normal) #targetWS normal vector

#set cursor location to vert WS pos
SC.cursor_location = TGTloc

#=== ALIGN OBJ 2 ===#
'''
Build basis vectors for transform matrix,
using target normal as Z. Normalize to negate
XY scaling.
'''
TM = Matrix.Identity(3)
TM.col[2] = TGTnrml #Z
TM.col[1] = TGTnrml.cross( (0,0,1) ) #Y
TM.col[0] = TM.col[1].cross(TGTnrml) #X
TM.normalize()

#to 4x4 and include translation vec
TM = TM.to_4x4()
TM.col[3] = TGTloc.to_4d()

#Apply transform
meshB.matrix_world = TM

C.scene.update()

``````

Thanks! @@Muffy

I found that you have been fixed your code last year. and It’s working perfect.

Best Wishes.
Yang