mayaのカメラでちょっと困ったことがありまして、
fitResolutionGateが horizontal だったり verticalだったり 混ざっちゃってることがあります。
混ざっててもまぁ良いのですが、揃ってるとかなりありがたいので揃えたいのですがー
horizontal から vertical へ切り替えると
まぁこうなります。
どうなってる?
fitResolutionGate つまり、filmGateに対してresolutionGateをどのように定義するかですね。
horizontalは filmGateの横辺 = resolutionGateの横辺 と定義し、
resolutionGateの比率を元にresolutionGateの横辺から縦辺を定義する。
verticalはその逆ですね。
どうしよう?
horizontal -> vertical で考えてみます。
resolutionGateのサイズを維持したままにできればいいのですが、
filmGateのサイズは変更したくないですね。
となるとー postScaleでなんとか出来るでしょうか?
細かい数字はわかりませんが、目合わせでやるとこんな感じですね。
となると
特定の平面上で
- horizontal時のresolutionGateサイズを取得
- horizontalからverticalに変更
- vertical時のresolutionGateサイズを取得
- h : v の比率を出す
- postscaleに設定
でやってみます。
実装
今回は
OpenMaya.MFnCamera.getRenderingFrustum
これを使用してみます。
Returns the rendering frustum (left, right, bottom and top) for the camera.
This is the frustum that the maya renderer uses.
とのことです。
v -> h もまぁ同じ感じでとりあえずやってみます。
import maya.cmds as cmds
import maya.api.OpenMaya as om
def getDagNode(target):
try:
sellist = om.MGlobal.getSelectionListByName(target)
return sellist.getDagPath(0)
except:
return None
def convertFilmFitToPostScale(target):
deviceAspectRatio = cmds.getAttr("defaultResolution.deviceAspectRatio")
targetCamDAG = getDagNode(target)
targetCamFn = om.MFnCamera(targetCamDAG)
sourceCamRenderSize = targetCamFn.getRenderingFrustum(deviceAspectRatio)
if cmds.getAttr(target + ".filmFit") == 1:
cmds.setAttr(target + ".filmFit",2)
elif cmds.getAttr(target + ".filmFit") == 2:
cmds.setAttr(target + ".filmFit",1)
targetCamRenderSize = targetCamFn.getRenderingFrustum(deviceAspectRatio)
##(left, right, bottom and top)
sourceCamRenderHight = sourceCamRenderSize[3] - sourceCamRenderSize[2]
sourceCamRenderWidth = sourceCamRenderSize[1] - sourceCamRenderSize[0]
targetCamRenderHight = targetCamRenderSize[3] - targetCamRenderSize[2]
targetCamRenderWidth = targetCamRenderSize[1] - targetCamRenderSize[0]
postScale = 1.0
if cmds.getAttr(target + ".filmFit") == 2:
postScale = targetCamRenderHight / sourceCamRenderHight
elif cmds.getAttr(target + ".filmFit") == 1:
postScale = targetCamRenderWidth / sourceCamRenderWidth
cmds.setAttr(target + ".postScale", cmds.getAttr(target + ".postScale") * postScale)
horizontal の状態です。
1回スクリプトを実行します。
convertFilmFitToPostScale("persp1")
ん~一致してる・・・ような気がします。
もう1回スクリプトを実行します。
convertFilmFitToPostScale("persp1")
元に戻ったような気がします。
正しく確認するにはレンダリングして重ねてみない事には判らなそうですね。
レンダリングしてみたところ、ぴったりと合ってました。
で、postScaleをFocalLengthに変換すればカメラを出力できますね。