2016. 3. 31. 16:57
Maya 에서 특정 프레임 f 에서 object 의 world position 을 얻는 가장 간단한 방법은 이것이다.
1 2 3 | import maya.cmds as mc mc.currentTime(f) # f is specific frame mc.xform(obj, q = True , t = True , ws = True ), #obj is specific object |
그러나, 이 방식의 경우 'currentTime()' 커맨드로 특정 프레임으로 이동한 다음 계산하므로 씬이 전체적으로 업데이트 되어야 해서 만약 다수의 프레임에 대해 처리를 해야 할 경우 속도가 매우 느리다.
'currentTime()' 커맨드를 쓰지 않고 위치정보를 받아올 수 있는 다른 방법으로는 'getAttr()' 커맨드를 이용하는 방식이 있는데, 이 방식은 말그대로 attribute 의 값을 가져올 뿐이므로, object 의 world position 같은 정보를 직접적으로 얻어올 수는 없다.
이를 위하여, 아래는 Maya Python API 2.0 을 활용하여 특정 ojbect 의 world position 을 내가 원하는 frame 에서 찾는 Python Script 이다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | import maya.cmds as mc import maya.api.OpenMaya as om def mayaTimeUnitTypeQuery(): mayaTimeUnitDic = { '100fps' : 25 , '10fps' : 18 , '1200fps' : 38 , '120fps' : 26 , '125fps' : 27 , '12fps' : 19 , '1500fps' : 39 , '150fps' : 28 , '16fps' : 20 , '2000fps' : 40 , '200fps' : 29 , '20fps' : 21 , '240fps' : 30 , '250fps' : 31 , '2fps' : 12 , '3000fps' : 41 , '300fps' : 32 , '375fps' : 13 , '400fps' : 34 , '40fps' : 22 , '4fps' : 14 , '500fps' : 35 , '5fps' : 15 , '6000fps' : 42 , '600fps' : 36 , '6fps' : 16 , '750fps' : 37 , '75fps' : 23 , '80fps' : 24 , '8fps' : 17 , 'film' : 6 , 'game' : 15 , 'hour' : 1 , 'millisec' : 4 , 'sec' : 3 , 'min' : 2 , 'ntsc' : 8 , 'ntscf' : 11 , 'palf' : 10 , 'pal' : 7 , 'show' : 9 } curTimeUnit = mc.currentUnit(q = True , time = True ) try : mayaTimeUnit = mayaTimeUnitDic[curTimeUnit] except : raise NameError( 'Invalid Maya time unit. %s is not in the Maya unit dictionary.' % (curTimeUnit)) return mayaTimeUnit def getWorldPosAtTime(obj, frame): sList = om.MSelectionList() sList.add(obj) dagPath = sList.getDagPath( 0 ) transFn = om.MFnDagNode(dagPath) matrixPlugArr = transFn.findPlug( 'worldMatrix' , 0 ) matrixPlugArr.evaluateNumElements() matrixPlug = matrixPlugArr.elementByPhysicalIndex( 0 ) curTimeUnit = mayaTimeUnitTypeQuery() mayaTime = om.MTime(frame, unit = curTimeUnit) timeContext = om.MDGContext(mayaTime) plugObj = matrixPlug.asMObject(timeContext) #print plugObj.apiTypeStr #kMatrixData plugObjFn = om.MFnMatrixData(plugObj) worldMatrix = plugObjFn.transformation() worldPos = worldMatrix.translation(om.MSpace.kWorld) return worldPos |
mayaTimeUnitTypeQuery() 함수는 현재 Maya 에 설정되어 있는 FPS 값을 미리 상수로 예약되어 있는 MayaTimeUnit 값으로 리턴해준다. Maya 에 예약된 모든 FPS 를 포함하는 함수이므로 유용할 것이다. 이 함수에서 오류가 난다면 버그가 있는 것이므로 제보바람.
getWorldPosAtTime() 함수가 우리가 원하는 일을 해 주는 함수인데, 위치를 알고싶은 obj 와 frame 을 입력하면 해당 frame 에서의 world position 을 반환해준다.
Object DagNode 의 worldMatrix plug 에서 matrix data 형태로 어떻게 가지고 오는지,
그리고 MTime 과 MDGContext timeContext 객체를 만들어 어떻게 특정 frame 에서의 value 를 retrieve 하는지가 주목할 만한 부분이다.