スタジオブロス TECH BLOG

スタジオブロススタッフからの最新ツール情報やチュートリアル・TIPSなどを紹介します

基礎から始める3dsmax/Python(MaxPlus)プログラミング⑤

今回は3dsMaxのPythonでこんなアニメーションを自動で作ってみようと思います。

vimeo.com

そのまえに前回の回転の設定の補足です。

ちょっと面倒だったと思いますが、もう少し楽な方法もあるのです。

例えば、ティーポット作って回転します。

これをリスナーで見ると・・・

このように表示されます。これはmaxスクリプトで回転している方法です。

max rotate は「選択して回転」ツールを選ぶコマンドです。

rotate $ (angleaxis -94.1097 [0,0,1]) は、前回説明のクォータニオンでZ回転で-94度で回転していることが解ります。

しかし、Pythonではこのままでは動きません。

そこで、このようにプログラムを書きます。

import MaxPlus
MaxPlus.Core.EvalMAXScript('rotate $ (angleaxis 90 [0,0,1])')

これを実行すると、ちゃんとZに90度回転してくれます。

このようにMaxPlusの命令が解りにくい場合、MaxPlus.Core.EvalMAXScript("maxスクリプトの命令") と書いて実行することでmaxスクリプトをPyhtonから実行できるのです。

あまり良い書き方ではないのですが、maxスクリプトだけの命令もあるので、知っていると便利です。

では、今回のプログラムです。参考にした元サンプルはこちらです。

help.autodesk.com

import MaxPlus as mp
# フレーム数に160倍で毎秒4800ティックにする
ticks = 160

def CreateTeapot():
  theTeapot = mp.Factory.CreateGeomObject(mp.ClassIds.Teapot)
  node = mp.Factory.CreateNode(theTeapot)
  return node

def AnimateTransform(teapot):
# ティーポットを選択、アニメーションのオブジェクト定義
  teapot.Select()
  anim = mp.Animation
#オートキーをON
  anim.SetAnimateButtonState(True)
# タイムスライダーを30フレームにする
  anim.SetTime(30 * ticks)
# ティーポットを移動1
  teapot.Move(mp.Point3(50, 0, 0))
# タイムスライダーを50フレームにする
  anim.SetTime(50 * ticks)
# ティーポットを移動2
  teapot.Move(mp.Point3(-50, 0, 0))
# ティーポットを回転1 
  mp.Core.EvalMAXScript('rotate $ (angleaxis 180 [0,0,1])')
# タイムスライダーを100フレームにする
  anim.SetTime(100 * ticks)
# ティーポットを移動3 
  teapot.Move(mp.Point3(50, 0, 0)) 
# ティーポットを回転2 
  mp.Core.EvalMAXScript('rotate $ (angleaxis 180 [0,0,1])') 
# オートキーをOFF
  anim.SetAnimateButtonState(False)

def DemoAnimation():
#新規シーン
  mp.FileManager.Reset(True)
#ティーポット作成の関数へ
  teapot = CreateTeapot()
#アニメーション設定の関数へ
  AnimateTransform(teapot)

#メインプログラム実行
DemoAnimation()

これを実行すると、最初にご覧いただいたアニメーションが自動で生成されます。

まず、今回は関数にすることで読みやすく工夫しています。

メイン関数は35~41行で、44行でその関数を実行しています。

mp.FileManager.Reset(True)

これは3dmaxを新規作成する命令です。プログラムを作る時には結構便利です。

teapot = CreateTeapot()

CreateTeapot関数でティーポットを作るだけです。これは前回でもやっているので省略します。

AnimateTransform(teapot)

ティーポットにアニメを付ける関数です。今回のメインのプログラムです。

3行目に飛びます。

ticks = 160

ちょっと解りにくいのですが、フレーム数を160倍しないとMaxPlusでは正しい時間指定にならないのです。

これは3dsmaxの中ではティックという単位で時間を管理していて、毎秒4800ティックなので、4800/30=160なので160倍する、という仕組みなのです。

10行目で作ったティーポットを関数で受け取ります。

def AnimateTransform(teapot):

12行でティーポットを選択、13行でアニメーションのオブジェクト(別の回に説明します)をanim作成します。

14~33行でアニメーションを付けていますが、3dsMaxユーザーの方なら解ると思いますが、いつもの手順のままプログラムを書きます。

1)AutoKeyをON

2)タイムスライターで時間を移動

3)移動や回転、スケール、モディファイアなど変化を設定する

4)2に戻って繰り返す

5)アニメを付け終わったら、AutoKeyをOFFにする

これをMaxPlusの命令に置き換えると・・・

1)が、 anim.SetAnimateButtonState(True)

2)が、anim.SetTime(フレーム数 * ticks=160)

3)が、teapot.Move(mp.Point3(移動X, Y, Z))

で、回転が最初に説明したMaxScript版のクォータニオンで、

mp.Core.EvalMAXScript("rotate $ (angleaxis 回転角 [軸X,軸Y,軸Z])")

5)が、anim.SetAnimateButtonState(False)

という流れです。

30フレーム=X50移動

50フレーム=X-50移動+Z180度回転

100フレーム=X50移動+Z180度回転

グラフを見てお分かりかと思いますが、値は相対値に設定されています。

いかがでしょうか?それほど難しくはないと思いますので、ぜひお試しください。