1

所以我在maya中有两个矩阵。我想反映一个关于另一个矩阵的 x 和 y 的矩阵。

举个例子:

Object 1's matrix is as such: [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] This is an object at the origin rotated 45沿 x 的度数。

对象 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没有旋转值。

When reflected on scaleX of object1 we get a matrix like this: [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 有某种方式,但无法弄清楚。

任何帮助将不胜感激!

4

4 回答 4

4

通常,您会在 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 可以让您设置旋转或缩放矩阵,而无需手动管理矩阵中的数字。

于 2013-08-19T22:33:55.793 回答
1

接受的答案包含不正确的示例。永远不要写诸如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]
于 2017-01-15T02:50:10.840 回答
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])

在这种情况下,我只制作了两个球体并能够反映这些矩阵。编辑:更正此以解决任何旋转问题。

于 2013-08-20T00:23:26.473 回答
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])

矢量反射公式

于 2013-08-20T15:42:08.960 回答