2013-08-19 134 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