所以我在玛雅有两个矩阵。我想反映一个关于其他矩阵的x和y的矩阵。
以此为例:
对象1的矩阵是这样的: [1.0,0.0,0.0,0.0,0.0,0.70710678118654746,0.70710678118654757,0.0,0.0,-0.70710678118654757,0.70710678118654746,0.0,0.0,0.0,0.0,1.0] 这是原点上沿x旋转45度的物体。
对象2的矩阵是这样的: [1.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,1.0,0.0,2.0,2.0,2.0,1.0] 坐在世界空间的2,2,2,没有旋转值。
当反映在object1的scaleX上时,我们得到一个这样的矩阵: [1.0,0.0,-0.0,0.0,-0.0,0.70710678118654746,-0.70710678118654757,0.0,0.0,0.70710678118654757,0.70710678118654746,0.0,2.0,2.8284271247461898,-2.2204460492503131e-16,1.0]
当我手动反映对象的比例时,这只是我查询矩阵。在python API中执行此操作的方法是什么?
我假设某种方式使用MTransformationMatrix,但却无法解决这个问题。
非常感谢任何帮助!
答案 0 :(得分:2)
通常,您可以在API中创建MMatrix或MTransformationMatrix,并将它们串联在一起以获得所需的转换。麻烦是将Python中的值转换为这些类,这需要可怕的MScriptUtil
import maya.OpenMaya as OpenMaya
import maya.cds as cmds
def APIMatrix ( valList ): # where vallist is a list of floats
mat = OpenMaya.MMatrix()
OpenMaya.MScriptUtil.createMatrixFromList( valList, mat )
return mat
例如,可以从python数字列表中创建一个MMatrix。在Pymel中,使用Matrix类更容易:
import pymel.datatypes as dt
i = dt.Matrix() # creates an identity matrix
m = dt.Matrix ( list_of_values) # use supplied numbers
一旦你的矩阵相乘,你就可以用xform命令来应用它们:
cmds.xform(item, m = my_new_matrix)
或在pymel中:
import pymel.core as pm
pm.xform(item, my_new_pymel_matrix)
MMatrix是一个原始矩阵 - 只是数学MTransformationMatrix的数字更像是对象的实际变换:它提供了一些方法,例如,将数字戳入平移或旋转而不知道哪些矩阵成员旋转手工:
def get_obj_quaternion ( mayaTransform, worldSpace=True ):
'''
gets the rotation quat for the supplied dag node in world or local space
'''
#convert from mMatrix to MTransformationMatrix....
mMatrix = matrix_from_transform( mayaTransform, worldSpace=worldSpace )
mTransformMtx = OpenMaya.MTransformationMatrix( mMatrix )
# MscriptUtil. Sigh
xPtr = OpenMaya.MScriptUtil(0.0)
x = xPtr.asDoublePtr()
yPtr = OpenMaya.MScriptUtil(0.0)
y = yPtr.asDoublePtr()
zPtr = OpenMaya.MScriptUtil(0.0)
z = zPtr.asDoublePtr()
wPtr = OpenMaya.MScriptUtil(0.0)
w = wPtr.asDoublePtr()
mTransformMtx.getRotationQuaternion( x, y, z, w )
# getRotationQuaternion is an MTransformationMatrix method
#convert them back to normal python floats
x = OpenMaya.MScriptUtil().getDouble( x )
y = OpenMaya.MScriptUtil().getDouble( y )
z = OpenMaya.MScriptUtil().getDouble( z )
w = OpenMaya.MScriptUtil().getDouble( w )
return x, y, z, w
所以在你的情况下你想要:
1)获取目标对象的矩阵
2)获取反射对象的矩阵
3)制作一个反射矩阵,例如:
-1 0 0 0
0 1 0 0
0 0 -1 0
0 0 0 1
是反射X轴和Z轴的反射矩阵
4)将目标反映为:
reflected_matrix = reflectXZMatrix * reflectionObjectMatrix
result = target_matrix * reflected_matrix
cmds.xform( target_object, m = result)
这是仅使用MMatrices的极简主义版本 - 如果您需要自己构建矩阵,MTransformationMatrix将允许您设置旋转或缩放矩阵,而无需手动管理矩阵中的数字。
答案 1 :(得分:0)
这是我用你给我的想法的代码。现在非常有意义!
import maya.OpenMaya as OpenMaya
import maya.cmds as cmds
import math
reflectObj = cmds.xform('pSphere1', query=True, ws=True, matrix=True)
targetObj = cmds.xform('pSphere2', query=True, ws=True, matrix=True)
reflectXZ = [-1 * reflectObj[0], -1 * reflectObj[1], -1 * reflectObj[2], reflectObj[3],
-1 * reflectObj[4], -1 * reflectObj[5], -1 * reflectObj[6], reflectObj[7],
reflectObj[8], reflectObj[9], reflectObj[10], reflectObj[11],
reflectObj[12], reflectObj[13], reflectObj[14], reflectObj[15]]
targetMMatrix = OpenMaya.MMatrix()
OpenMaya.MScriptUtil.createMatrixFromList(targetObj, targetMMatrix)
reflectObjMMatrix = OpenMaya.MMatrix()
OpenMaya.MScriptUtil.createMatrixFromList(reflectObj, reflectObjMMatrix)
reflectXZMMatrix = OpenMaya.MMatrix()
OpenMaya.MScriptUtil.createMatrixFromList(reflectXZ, reflectXZMMatrix)
reflected_matrix = targetMMatrix * reflectObjMMatrix.inverse()
result = reflected_matrix * reflectXZMMatrix
mt = OpenMaya.MTransformationMatrix(result)
trans = mt.translation(OpenMaya.MSpace.kWorld)
eulerRot = mt.rotation().asEulerRotation()
angles = [math.degrees(angle) for angle in (eulerRot.x, eulerRot.y, eulerRot.z)]
loc = cmds.spaceLocator()
cmds.move(trans[0], trans[1], trans[2], loc[0])
cmds.rotate(angles[0], angles[1], angles[2], loc[0])
在这种情况下,我只做了两个球体,并能够反映这些矩阵。 编辑:更正此项以解决任何轮换问题。
答案 2 :(得分:0)
结束使用向量来获取位置。将obj1和obj2替换为您的反射对象和对象以反映。
import maya.OpenMaya as OpenMaya
import maya.cmds as cmds
from functools import partial
get_pnt = partial(cmds.xform,
query=True,
worldSpace=True,
translation=True)
N = OpenMaya.MVector(*get_pnt('obj1'))
N.normalize()
V = OpenMaya.MVector(*get_pnt('obj2'))
R = (N * 2.0) * (V * N) - V
loc = cmds.spaceLocator()
cmds.move(R.x, R.y, R.z, loc[0])
答案 3 :(得分:0)
接受的答案包含一个不正确的例子。 从不撰写ptr = OpenMaya.MScriptUtil().asDoublePtr()
之类的内容。为了解释原因,请阅读第二点:http://around-the-corner.typepad.com/adn/2013/03/possible-misuse-of-mscriptutil-in-maya.html。
此外,相同的示例有助于展示如何使用类MScriptUtil
,但是,对于此特定方法,这里的版本更便于编写和更快地运行:
def get_obj_quaternion ( mayaTransform, worldSpace=True ):
'''
gets the rotation quat for the supplied dag node in world or local space
'''
#convert from mMatrix to MTransformationMatrix....
mMatrix = matrix_from_transform( mayaTransform, worldSpace=worldSpace )
mTransformMtx = OpenMaya.MTransformationMatrix( mMatrix )
q = mTransformMtx.rotation()
return [q.x, q.y, q.z, q.w]