mayaのカメラにある postScaleは、レンズの数値そのままで画角を広げられるので
余白出しとかの時にとても重宝しています。
が、
他のソフトへカメラを渡す場合、mayaの固有機能であるpostScaleは渡せないのでこまったなー
となりました。
んじゃぁ postScale で調整後の画角のFocalLengthを算出してしまおうと
考える
そもそもpostScaleはどこに掛かるのか・・・
filmGate表示で確認してみると
外からnearClipを表示させてみて確認してみると
postScale 1.0
実際に filmGateサイズを変えてるわけではなく画像として拡縮してる感じですね。
広げてるのに0.8とは?と思いますが、1.0/0.8 = 1.25 とかその辺かなぁ
(filmApertureを0.8してる感じだろうか?)
今のfilmGateのサイズを求めて、postScaleの逆数掛けて、そこからFocalLengthを求められそうな気はします。
検証
とりあえず、filmGateのサイズを求め方を調べてみます。
アトリビュートには見当たらないので、とりあえずAPI眺めますか。
ん~ 具体的にコレというのが見当たりませんね・・・
うん、面倒ですが filmAperture から算出してしまいます。
なので、
- filmAperture と FocalLength と nearClipPlaneから filmGateサイズを算出
- filmGateにpostScale値の逆数を掛ける
- scale後のfilmGateから FocalLengthを算出
ん~ なんか無駄な事やってる気もしますが、とりあえずこれでやってみます。
実装
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 convertPostScaleToFLength(source):
sourceCamDAG = getDagNode(source)
sourceCamFn = om.MFnCamera(sourceCamDAG)
horizontalFilmAperture = sourceCamFn.horizontalFilmAperture
verticalFilmAperture = sourceCamFn.verticalFilmAperture
nearClippingPlane = sourceCamFn.nearClippingPlane
FLength = sourceCamFn.focalLength
postScale = sourceCamFn.postScale
invPostScale = 1.0 / postScale
filmGateH = horizontalFilmAperture * (nearClippingPlane / FLength)
filmGateV = verticalFilmAperture * (nearClippingPlane / FLength)
scaledHsize = filmGateH * invPostScale
scaledVsize = filmGateV * invPostScale
FLengthNew = (horizontalFilmAperture * nearClippingPlane)/scaledHsize
cmds.setAttr(source + ".focalLength",FLengthNew)
cmds.setAttr(source + ".postScale",1.0)
ではこんなカメラで試してみます。
convertPostScaleToFLength("persp1")
実行時にカメラの画角が一切動いてませんが、数値は変化したので成功したようです。
filmGateでやってるので、fitResolutionGateがVでもHでも問題なさそうです。
が、これよくよく考えてみたら
filmAperture 固定となるんで、 FocalLength * (1.0/postScale) でいいんじゃね? という疑問がわいたところでおしまいにします。