2013-08-19 99 views
0

所以我在Maya中有两个矩阵。我想反映关于另一个矩阵的x和y的一个矩阵。Maya Python API缩放关于另一个矩阵的矩阵

因此,作为一个例子:

对象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,但无法找出那一个。

任何帮助将不胜感激!

回答

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 

将从蟒蛇号码列表创建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可让您设置旋转或缩放矩阵,而无需手动管理矩阵中的数字。

+0

听起来不错我会给它一个回去找回你。感谢您的回应。我已经手动构建矩阵,但这对于反映它是有意义的。 – chribis

+0

如果您尚未完成此操作,则应查看Transform(http://download.autodesk.com/us/maya/2011help/Nodes/transform.html)的文档,其中对变换顺序进行了布局(maya使用post multiply :按照我上面的示例,按照从左到右的顺序进行转换) – theodox

+0

所以我实际上注意到了一个问题。当反思说使用我的代码旋转的球体时,它不会正确反映矩阵。想法?再次感谢所有的帮助。 – chribis

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]) 

在这种情况下,我只是做了两个领域,并能够反映在这些矩阵。 编辑:纠正此以消除任何旋转。

+0

很高兴帮助:) – theodox

+0

更新: 我最终通过做一些向量数学得到答案。 [下面是它的公式](http://www.3dkingdoms.com/weekly/weekly.php?a=2) – chribis

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]) 

Formula for vector reflection

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] 
+0

我不是一个声誉追逐者,即使我没有在这里回答这个问题,我希望这个答案是有利于防止人们盲目复制/粘贴示例中显示的代码。我试图编辑原始答案,但由于某些原因,编辑被拒绝... – ChristopherC

+0

我已经编辑了解决问题的答案(它必须经过同行评审)。我结束了与我发布的答案,所以我没有遇到这个具体问题。我没有看到您的版本的方法与发布的答案不同。谢谢! – chribis

+0

Woops,我的不好,我没有写完整的功能,现在已经修复了。这不是最关键的一点 - 我主要关心的是看到模式“OpenMaya.MScriptUtil()。asDoublePtr()”遍布全球。 – ChristopherC