Poserでポーズや、アニメーションポーズを作ってて、こういう状況になることないだろうか?
▲足の向きは合ってるんだけど、なんかネジレちゃってる!?
インバースキネマティクス(IK)のオン・オフを頻繁にやっていると、なぜかこんな状態になる。もう、かれこれPoser5の時代からずっと解決していない。
理由は、IKのオン→オフの切り替えを行った時の内部のパラメータ変換がうまくいってないっぽいのだ。
▲いかにも異常な、Bend, Side-Side, Twistパラメータの値(IKオフ時)
数学的なことはよくわからないのだが、たぶんこの回転指定でも、関節は正しい方向を向くんだろう。ただ、「回転のさせすぎ」で、ねじれが発生するんだと思う。
で、民間療法的に、こいつを治すPythonスクリプトを作ってみた。
うーむ、自分で書いててよくわからん。つまり、なるべく回転が少ない関節パラメータ指定に変換するっていうこと。
スクリプトはこれ。Pythonスクリプトはインデントの深さ(行頭のタブっぽい空白のこと)も文法的に意味を持つので、コピペの時は気をつけて欲しい。
# -*- coding: utf-8 -*-
# PoserPythonライブラリを使うためのもの
import poser#必要モジュールのインポート
import os,sys,math#シーン全体
scene = poser.Scene()#選択中のパーツ(または、プロップ)
part = scene.CurrentActor()#パーツを選択していたら
if part:
XROT = part.ParameterByCode(poser.kParmCodeXROT)
YROT = part.ParameterByCode(poser.kParmCodeYROT)
ZROT = part.ParameterByCode(poser.kParmCodeZROT)
xrot = XROT.Value()
yrot = YROT.Value()
zrot = ZROT.Value()
# 360度を超えてたら、-360度する。負の場合も考慮。
if math.fabs( xrot ) > 360:
math.fabs( xrot ) - math.copysign( 1.0, xrot )*360
if math.fabs( yrot ) > 360:
math.fabs( yrot ) - math.copysign( 1.0, yrot )*360
if math.fabs( zrot ) > 360:
math.fabs( zrot ) - math.copysign( 1.0, zrot )*360# 3角度の和が大き過ぎたら、-180度づつ引く
xrot180 = xrot - math.copysign( 1.0, xrot )*180.0
yrot180 = yrot - math.copysign( 1.0, yrot )*180.0
zrot180 = zrot - math.copysign( 1.0, zrot )*180.0if math.fabs(xrot) + math.fabs(yrot) + math.fabs(zrot) > \
math.fabs(xrot180) + math.fabs(yrot180) + math.fabs(zrot180):
XROT.SetValue(xrot180)
YROT.SetValue(yrot180)
ZROT.SetValue(zrot180)
scene.DrawAll()
else:
# パーツを選択してしなかったときのメッセージ
print "Please select a part. "
使い方は、まずねじれた足首や手首を選択状態にしてから、スクリプトを実行するだけ。
あ、必ずIKオフの状態で使って欲しい。IKオンの状態で使うと多分、そうとうおかしなことになると思う。
▲スクリプトを適用したところ。あれだけ悩んでいたねじれがなおったんです!
この処理はPoser内部に組み込みたいくらいだなぁ。
最近のバージョンのPoserでは、pythonスクリプトのショートカット割り当てが効く(Pythonスクリプトでキーボードショートカット(不完全編) - Poser覚書)ので、ネジレたら選択してPython実行とかってやるといいかも知れない。
全フレーム対応版もあったほうがいいかなぁ。
関連: