コントローラは 3ds Max での、アニメーション タスクを処理するプラグインです。これらは通常、トラック ビューまたは[モーション](Motion)パネルのオブジェクトに割り当てられます。また、プログラムによって割り当てることもできます(このセクションの後で説明する例を参照)。
MAXScript のスクリプト定義アニメーション コントローラはパラメータ ブロックとロールアウトをサポートします。
スクリプト定義アニメーション プラグイン コントローラでは次のスーパークラスが定義されます。
スクリプト定義アニメーション コントローラ プラグインには、少なくとも getValue イベント ハンドラが 1 つ必要です。 その他のすべてのイベント ハンドラはオプションです。一時保存/復元システムに関連付けられているハンドラは通常実装されません。「一時保存と復元システム」の説明を参照してください。
コントローラのインスタンスがシーン内で作成されると呼び出されます。このハンドラは、コントローラの状態変数を設定するために使用されます(以下の「ローカル変数」を参照)。on create ハンドラの詳細については、「スクリプト定義プラグイン Clauses_TOPIC_740」の「イベント ハンドラ」セクションを参照してください。
コントローラが UI、MAXScript あるいは他の max コードのいずれかによって値に設定されると呼び出されます。このハンドラはオプションです。
setValue を相対モード(これは method == #relative でテストできます)で使用した場合、relVal には現在の値からのデルタが含まれます。absVal はユーザのために事前に計算された絶対値です。setValue を絶対モード(method == #absolute)で使用した場合、relVal と absVal は同じです。
commit パラメータは、コントローラが値の設定を持続するか、単に値の設定をキャッシュするかを指定します。 false の場合、commitValue および restoreValue ハンドラが必要になります。 ただし、知られている限りでは、現在のプラグインがこの値を false として渡すことはないので、これらのハンドラは不要です。詳細については、以下の「一時保存と復元システム」を参照してください。
ユーザがビューポートにマウスを置いた状態でコントローラの変更を開始すると呼び出されます。たとえば、ノードをビューポート内で移動すると、これは変換関連の各コントローラで呼び出されます。
ユーザがビューポートにマウスを置いた状態でコントローラの変更を終了すると呼び出されます。たとえば、ノードをビューポート内で移動すると、これは変換関連の各コントローラで呼び出されます。
注: mouseCycleCompleted は対応する mouseCycleStarted なしで呼び出すことができる場合があります。たとえば、トラック ビューでコントローラのキーを移動する場合です。
setValue ハンドラの commit パラメータが false の場合に呼び出されます。これはコントローラがキャッシュされた値から値の設定を持続することを意味します。
setValue ハンドラの commit パラメータが false の場合に呼び出されます。これはコントローラがキャッシュされた値を使用しないことを意味します。
setValue および commitValue/restoreValue ハンドラの commit パラメータは「内部の」一時保存と復元メカニズムの一部です。コントローラの SetValue() メソッドが呼び出されると、コミット パラメータが true の場合、コントローラは現在の時刻のコントローラの値をそのキャッシュに保存し、さらに値を「コミット」します。たとえば、キーフレーム コントローラの場合、これはキーを保存します。設定値がコミットされないと、RestoreValue() が呼び出されて前の値を復元します。これは、現在のキャッシュの値を SetValue() が最後に呼び出される前に設定された値に復元します。
以下の FloatController のスクリプト例には、このメカニズムが使用される場合の検出と情報表示が含まれます。
スクリプト定義アニメーション プラグイン コントローラには次のローカル変数を使用できます。
コントローラがリーフ コントローラであるかどうかを示します。コントローラがリーフ コントローラの場合、定義上はサブコントローラもリファレンスもありません。サブコントローラがない場合、コントローラは true を返します。たとえば、PRS コントローラはリーフ コントローラではありません(位置、回転、およびスケールのサブコントローラがあるため)が、単純なキーフレーム フロート コントローラはリーフ コントローラです。
イーズ/マルチプライヤ カーブおよび範囲外のタイプは、リーフ コントローラにのみ適用することができます。ツリービューで使用できるフィルタは、コントローラがリーフ コントローラかどうかによって異なります。この変数の既定値は false です。この変数は通常「on create」ハンドラで設定されます。
この変数は変換関連のスクリプト定義プラグイン コントローラで使用され、それ以外のスクリプト定義プラグイン コントローラでは「未定義」です。on getValue ハンドラ内で使用します。この変数には、method == #relative のときに変換関連のスクリプト定義プラグイン コントローラ(positionController、rotationController、scaleController、transformController)の on getValue ハンドラを評価する場合の(修正された)親ノード変換が含まれます。親の変換マトリクスのコピーはノードの変換コントローラに渡され、変換コントローラおよびそのサブコントローラは Matrix3 の値を操作および修正することができます。この値は、コントローラのパイプラインを通過する現在の変換の値を表します。
たとえば PRS コントローラでは、位置コントローラが通常 Point3 の値を使用して Matrix3 の値を変換し、修正された Matrix3 の値は回転コントローラに渡されます。これは通常 Matrix3 の値を回転させ、次に修正された Matrix3 の値がスケール コントローラに渡されます。この値は読み取り専用です。スクリプト定義プラグインの C++ 実装は getValue ハンドラから返される値に基づいてこの Matrix3 の値を操作します。
変換関連のコントローラの on getValue ハンドラで method == #absolute の場合、コントローラは直接評価され(たとえば MaxScript の <controller>.value を介して)、parentTransform は ID マトリクスになります。
フロート コントローラ プラグインのタイプは浮動小数点値をコントロールします。以下の例ではフロートにオフセット値を追加し、テスト ケースはオブジェクトの X 位置をコントロールします。このサンプルは、パラメータ ブロックとロールアウト UI の実装を示しています。これは、コントロールされるオブジェクトを選択したときに[モーション](Motion)パネルに表示されます。また、commitValue、restoreValue および holdBegin/holdEnd/holdRestore/holdRedo ハンドラに実装することによって一時保存/復元/やり直しシステムを使用する方法も示します。上の「一時保存と復元システム」で述べたように、現在出荷されているプラグインでこのメカニズムを使用しているものはないため、これらのハンドラは必要ではありません。ただしサードパーティのプラグインではこのメカニズムを使用するものがあるかもしれません。
plugin FloatController FloatController_example name:"FloatController Example" classID:#(0x47db14fe, 0x4e9b5f90) ( local first = true -- used for debug tracing of 'commit' handling local useCachedValue = false -- set when have SetValue with commit == false local cachedValue = undefined -- set when have SetValue with commit == false local inMouseCycle = false -- true when within mouseCycleStarted/mouseCycleCompleted local inMouseCycleControllerAssigned = false -- true when controller assigned within mouseCycleStarted/mouseCycleCompleted local inMouseCycleSetValue = false -- true when setValue w/o holdRestore occurred within mouseCycleStarted/mouseCycleCompleted parameters pblock rollout:params ( value type:#float animatable:true ui:value valueController type:#maxobject ) rollout params "FloatController Test Parameters" ( Spinner value "Value:" ) on getValue do ( format "getValue - useCachedValue: %; value: %; cachedValue: %\n" useCachedValue value cachedValue if useCachedValue then cachedValue else value ) on setValue val relVal commit do ( format "setValue - val: %; commit: %; useCachedValue: %; value: %; cachedValue: %\n" val commit useCachedValue value cachedValue if not commit and first do ( print (CaptureCallStack()) first = false messagebox "setValue called with commit = false - see listener for stack trace" ) if commit then ( useCachedValue = false cachedValue = undefined if inMouseCycle do inMouseCycleSetValue = true value = val ) else ( useCachedValue = true cachedValue = val ) SetControllerValue valueController val commit #absolute ) on commitValue do ( format "commitValue - useCachedValue: %; value: %; cachedValue: %\n" useCachedValue value cachedValue if first do ( print (CaptureCallStack()) first = false messagebox "commitValue called - see listener for stack trace" ) useCachedValue = false value = cachedValue cachedValue = undefined CommitControllerValue valueController ) on restoreValue do ( format "restoreValue - useCachedValue: %; value: %; cachedValue: %\n" useCachedValue value cachedValue if first do ( print (CaptureCallStack()) first = false messagebox "restoreValue called - see listener for stack trace" ) useCachedValue = false cachedValue = undefined RestoreControllerValue valueController ) on mouseCycleStarted do ( format "mouseCycleStarted - holding: %; value.controller: %\n" (theHold.Holding()) value.controller inMouseCycle = true inMouseCycleControllerAssigned = false ) on mouseCycleCompleted do ( format "mouseCycleCompleted - holding: %; value.controller: %\n" (theHold.Holding()) value.controller inMouseCycle = false inMouseCycleControllerAssigned = false ) on holdBegin do ( format "holdBegin\n" if inMouseCycle and animateMode and value.controller == undefined and (currenttime != 0) do ( inMouseCycleControllerAssigned = true with undo off value.controller = NewDefaultFloatController() ) ) on holdEnd do ( format "holdEnd - inMouseCycleControllerAssigned: %; inMouseCycleSetValue: %\n" inMouseCycleControllerAssigned inMouseCycleSetValue if inMouseCycleControllerAssigned and not inMouseCycleSetValue do with undo off value.controller = undefined ) on holdRestore do ( format "holdRestore\n" if inMouseCycle do inMouseCycleSetValue = false ) on holdRedo do format "holdRedo\n" on create do ( valueController = NewDefaultFloatController() isLeaf=true ) ) /* Test case: t = teapot isselected:true t.radius.controller = FloatController_test() t.pos.controller.x_position.controller = FloatController_example() */
これは、同じフロート コントローラで一時保存/復元システムを実装しないより典型的なバージョンです。また、手続き型コントローラを作成する方法も示します。この場合、コントロールされるフロート値を現在の時間とオフセットで修正しています。プラグイン定義で usePBValidity:false が使用されていることに注意してください。
plugin FloatController FloatController_simplified_example name:"Simplified FloatController Example" usePBValidity:false -- false because time dependent classID:#(0xc1dbcd6, 0x70ecb08a) ( parameters pblock rollout:params ( offset_value type:#float animatable:true ui:offset_value valueController type:#maxobject subAnim:true ) rollout params "FloatController Test Parameters" ( Spinner offset_value "Offset Value:" range:[0, 1e9, 40] ) on getValue do ( valueController.value +offset_value + currentTime as integer / framerate ) on setValue val relVal commit do ( val -= ( offset_value+ currentTime as integer / framerate) SetControllerValue valueController val commit #absolute ) on create do ( valueController = NewDefaultFloatController() isLeaf=true ) ) /* Test case: t = teapot isselected:true t.radius.controller = c = FloatController_simplified_example() c.isKeyable = true c.isleaf = false */
Point3Controller プラグインのタイプは、Point3 値をコントロールします。これは位置の値をコントロールしないことに注意してください。代わりに PositionController (以下を参照)を使用する必要があります。このコントローラは座標オフセットなどに使用することができます。次の例では、コントローラはマテリアルの拡散反射光マップ座標に適用されます。
plugin Point3Controller Point3Controller_example name:"Point3Controller Example" classID:#(0x47db14ff, 0x4e9b5f9f) ( parameters pblock ( offset_value type:#point3 animatable:true valueController type:#maxobject subAnim:true ) on getValue do ( valueController.value + offset_value ) on setValue val relVal commit do ( val -= offset_value SetControllerValue valueController val commit #absolute ) on create do ( valueController = NewDefaultPoint3Controller() isLeaf=true ) ) /* Test case: t = teapot isselected:true t.material = standard diffusemap:(cellular()) t.material.diffusemap.coords.offset.controller = Point3Controller_example() c = t.material.diffusemap.coords.offset.controller meditmaterials[1] = t.material.diffusemap max mtledit t.pos.controller = Point3Controller_example() -- will give: -- Runtime error: Incompatible controller type for property: position */
このプラグイン コントローラのタイプは、シェーダの 4D カラー スペースなど Point4 の値をコントロールします。
plugin Point4Controller Point4Controller_example name:"Point4Controller Example" classID:#(0x47db14ff, 0x4e9b5f9f) ( parameters pblock ( offset_value type:#point4 animatable:true valueController type:#maxobject subAnim:true ) on getValue do ( valueController.value + offset_value ) on setValue val relVal commit do ( val -= offset_value SetControllerValue valueController val commit #absolute ) on create do ( valueController = NewDefaultPoint4Controller() isLeaf=true ) ) /* Test case: c = Point4Controller_example() at time 100 with animate on c.offset_value =[100,200,300,400] slidertime = 50f c.offset_value c.value += [10,20,30,40] c.offset_value c.value c.valueController.value */
ColorController プラグインは、カラー値のアニメーションをコントロールします。この例では、コントローラはカラー値にオフセットを追加し、コントローラはマテリアルの拡散反射光カラーに適用されます。
plugin ColorController ColorController_example name:"ColorController Example" classID:#(0x47db14ba, 0x4e9b5f9f) ( parameters pblock ( offset_value type:#color animatable:true valueController type:#maxobject subAnim:true ) on getValue do ( valueController.value + offset_value ) on setValue val relVal commit do ( val -= offset_value SetControllerValue valueController val commit #absolute ) on create do ( valueController = NewDefaultColorController() isLeaf=true ) ) /* Test case: t = teapot isselected:true t.material = standard () t.material.diffuse.controller = ColorController_example() c = t.material.diffuse.controller meditmaterials[1] = t.material max mtledit */
PositionController プラグインのタイプはアニメート可能な位置をコントロールします。以下の例では、コントローラはオフセットをコントロールされる Point3 の値に追加します。この値はティーポット オブジェクトの位置に適用されます。
plugin PositionController PositionController_example name:"PositionController Example" classID:#(0x47db14fa, 0x4e9b5f9f) ( parameters pblock ( offset_value type:#point3 animatable:true valueController type:#maxobject subAnim:true ) on getValue do ( res = valueController.value + offset_value res ) on setValue val relVal commit do ( val -= offset_value format "committing val: %\n" val SetControllerValue valueController val commit #absolute ) on create do ( valueController = NewDefaultPositionController() isLeaf=true ) ) /* Test case: t = teapot isselected:true t.pos.controller = PositionController_example() c = t.pos.controller */
回転コントローラ プラグインのタイプは、シーン オブジェクトの回転の値をコントロールします。以下のコントローラの例では、回転の値は Matrix3 の値の回転の部分として格納されます。コントローラはオフセットをコントロールされる値に追加します。この値はオブジェクトの回転に適用されます。
plugin RotationController RotationController_example name:"RotationController Example" classID:#(0x47db14ac, 0x4e9b5f9f) ( parameters pblock ( offset_value type:#matrix3 animatable:true valueController type:#maxobject subAnim:true ) on getValue do ( res = valueController.value + offset_value.rotationpart res ) on setValue val relVal commit do ( val -= offset_value.rotationpart SetControllerValue valueController (val as matrix3) commit #absolute ) on create do ( valueController = NewDefaultRotationController() isLeaf=true ) ) /* Test case: t = teapot isselected:true t.rotation.controller = RotationController_example() c = t.rotation.controller */
ScaleController タイプのプラグインは、スケール値を Point3 としてコントロールします。以下の例では、コントローラはオフセットをコントロールされる値に追加します。
plugin ScaleController ScaleController_example name:"ScaleController Example" classID:#(0x7fa4db14, 0x4e5f9b9f) ( parameters pblock ( offset_value type:#point3 animatable:true valueController type:#maxobject subAnim:true ) on getValue do ( res = valueController.value + offset_value res ) on setValue val relVal commit do ( val -= offset_value SetControllerValue valueController val commit #absolute ) on create do ( valueController = NewDefaultScaleController() isLeaf=true ) ) /* Test case: t = teapot isselected:true t.scale.controller = ScaleController_example() c = t.scale.controller c.value = [.9,.9,.9] */
TransformController プラグインは変換値(Matrix3)をコントロールします。この例では、コントロールされる値にオフセットを追加します。
plugin TransformController TransformController_example name:"TransformController Example" classID:#(0x47db1cad, 0x4e9b5f9c) ( parameters pblock ( offset_value type:#matrix3 valueController type:#maxobject subAnim:true ) on getValue do ( res = valueController.value * offset_value res ) on setValue val relVal commit do ( val = val * inverse offset_value SetControllerValue valueController val commit #absolute ) on create do ( valueController = NewDefaultMatrix3Controller() isLeaf=true ) ) /* Test case: t = teapot isselected:true t.transform.controller = TransformController_example() c = t.transform.controller at time 100 c.value c.value = matrix3 1 */