新しいスクリプト定義アニメーション コントローラ プラグイン

コントローラは 3ds Max での、アニメーション タスクを処理するプラグインです。これらは通常、トラック ビューまたは[モーション](Motion)パネルのオブジェクトに割り当てられます。また、プログラムによって割り当てることもできます(このセクションの後で説明する例を参照)。

MAXScript のスクリプト定義アニメーション コントローラはパラメータ ブロックとロールアウトをサポートします。

スクリプト定義アニメーション プラグイン コントローラでは次のスーパークラスが定義されます。

イベント ハンドラ

スクリプト定義アニメーション コントローラ プラグインには、少なくとも getValue イベント ハンドラが 1 つ必要です。 その他のすべてのイベント ハンドラはオプションです。一時保存/復元システムに関連付けられているハンドラは通常実装されません。「一時保存と復元システム」の説明を参照してください。

注:これらのハンドラの評価中に未処理のランタイム エラーが発生する場合、プラグイン インスタンスは無効になります。

on create do <expr>

コントローラのインスタンスがシーン内で作成されると呼び出されます。このハンドラは、コントローラの状態変数を設定するために使用されます(以下の「ローカル変数」を参照)。on create ハンドラの詳細については、「スクリプト定義プラグイン Clauses_TOPIC_740」の「イベント ハンドラ」セクションを参照してください。

on getValue do <expr>

コントローラのタイプに応じて値、タイプを返します。

on setValue absVal relVal commit do <expr>

コントローラが UI、MAXScript あるいは他の max コードのいずれかによって値に設定されると呼び出されます。このハンドラはオプションです。

setValue を相対モード(これは method == #relative でテストできます)で使用した場合、relVal には現在の値からのデルタが含まれます。absVal はユーザのために事前に計算された絶対値です。setValue を絶対モード(method == #absolute)で使用した場合、relValabsVal は同じです。

commit パラメータは、コントローラが値の設定を持続するか、単に値の設定をキャッシュするかを指定します。 false の場合、commitValue および restoreValue ハンドラが必要になります。 ただし、知られている限りでは、現在のプラグインがこの値を false として渡すことはないので、これらのハンドラは不要です。詳細については、以下の「一時保存と復元システム」を参照してください。

on mouseCycleStarted do <expr>

ユーザがビューポートにマウスを置いた状態でコントローラの変更を開始すると呼び出されます。たとえば、ノードをビューポート内で移動すると、これは変換関連の各コントローラで呼び出されます。

このハンドラはオプションで、主に一時保存/復元システムをサポートします。

on mouseCycleCompleted do <expr>

ユーザがビューポートにマウスを置いた状態でコントローラの変更を終了すると呼び出されます。たとえば、ノードをビューポート内で移動すると、これは変換関連の各コントローラで呼び出されます。

注: mouseCycleCompleted は対応する mouseCycleStarted なしで呼び出すことができる場合があります。たとえば、トラック ビューでコントローラのキーを移動する場合です。

このハンドラはオプションで、主に一時保存/復元システムをサポートします。

on holdBegin do <expr>

コントローラの値の変更を開始すると呼び出されます。

このハンドラはオプションで、主に一時保存/復元システムをサポートします。

on holdEnd do <expr>

コントローラの値の変更を終了すると呼び出されます。

このハンドラはオプションで、主に一時保存/復元システムをサポートします。

on holdRestore do <expr>

ユーザがコントローラの設定値を元に戻すなど、コントローラがアンドゥ システムによって初期の値にリセットされると呼び出されます。

このハンドラはオプションで、主に一時保存/復元システムをサポートします。

on holdRedo do <expr>

コントローラがアンドゥ システムによって後者の値に設定されると呼び出されます。これはユーザがコントローラの設定値のやり直しを実行したときに呼び出されます。

このハンドラはオプションで、主に一時保存/復元システムをサポートします。

on commitValue do <expr>

setValue ハンドラの commit パラメータが false の場合に呼び出されます。これはコントローラがキャッシュされた値から値の設定を持続することを意味します。

このハンドラはオプションで、主に一時保存/復元システムをサポートします。

on restoreValue do <expr>

setValue ハンドラの commit パラメータが false の場合に呼び出されます。これはコントローラがキャッシュされた値を使用しないことを意味します。

このハンドラはオプションで、主に一時保存/復元システムをサポートします。

一時保存と復元システム

setValue および commitValue/restoreValue ハンドラの commit パラメータは「内部の」一時保存と復元メカニズムの一部です。コントローラの SetValue() メソッドが呼び出されると、コミット パラメータが true の場合、コントローラは現在の時刻のコントローラの値をそのキャッシュに保存し、さらに値を「コミット」します。たとえば、キーフレーム コントローラの場合、これはキーを保存します。設定値がコミットされないと、RestoreValue() が呼び出されて前の値を復元します。これは、現在のキャッシュの値を SetValue() が最後に呼び出される前に設定された値に復元します。

注:知られている限り、setValue へのコミット パラメータが現在のプラグインによって false として渡されることはないので、コントローラのスクリプト定義プラグインのタイプの将来の反復では削除される場合があります。ただし、コントローラ フレームワークはこの内部の一時保存と復元メカニズムを提供し、サードパーティのプラグインによって使用することができます。

以下の FloatController のスクリプト例には、このメカニズムが使用される場合の検出と情報表示が含まれます。

ローカル変数

スクリプト定義アニメーション プラグイン コントローラには次のローカル変数を使用できます。

isLeaf - 読み取り/書き込み - ブール値。

コントローラがリーフ コントローラであるかどうかを示します。コントローラがリーフ コントローラの場合、定義上はサブコントローラもリファレンスもありません。サブコントローラがない場合、コントローラは true を返します。たとえば、PRS コントローラはリーフ コントローラではありません(位置、回転、およびスケールのサブコントローラがあるため)が、単純なキーフレーム フロート コントローラはリーフ コントローラです。

イーズ/マルチプライヤ カーブおよび範囲外のタイプは、リーフ コントローラにのみ適用することができます。ツリービューで使用できるフィルタは、コントローラがリーフ コントローラかどうかによって異なります。この変数の既定値は false です。この変数は通常「on create」ハンドラで設定されます。

isKeyable - 読み取り/書き込み - ブール値
コントローラが適用されるパラメータにリンクされた UI 要素(スピナーまたはスライダ)が有効かどうかを示します。この変数が false の場合、UI 要素は無効になります。setValue ハンドラが定義されていない場合、この変数の既定値は false で、定義されている場合は true です。この変数を設定する場合、通常は「on create」ハンドラに設定します。
method - 読み取り専用 - 名前の値
setValue ハンドラ内で使用します。呼び出しが #relative または #absolute のどちらのメソッドで発生したかを指定します。
parentTransform - 読み取り専用 - Matrix3 値

この変数は変換関連のスクリプト定義プラグイン コントローラで使用され、それ以外のスクリプト定義プラグイン コントローラでは「未定義」です。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 マトリクスになります。

usesParentTransform - 読み取り/書き込み - ブール値
この変数はスクリプト定義プラグイン コントローラの現在の値のキャッシュをコントロールします。通常、コントローラはコントローラの妥当性間隔と現在の値をキャッシュします。getValue 呼び出しの発生時間の値が妥当性間隔の範囲内であれば、キャッシュされた現在の値は getValue ハンドラの評価なしで返されます。getValue ハンドラの呼び出しの戻り値が親の変換値に依存する場合、親ノードが変換される場合の結果が不正になります。それは、親ノードからすべての子ノードの変換関連のコントローラに通知が送信されず、それらのコントローラが無効になるためです。この変数が true である場合、キャッシュされた現在の値は使用されず、getValue ハンドラが常に呼び出されます。その結果さらに多くの評価が発生します。そのため、結果が親の変換に依存する変換関連のスクリプト定義プラグイン コントローラの場合のみ true に設定します。この変数の既定値は false です。この変数は通常 create ハンドラで設定されます。

FloatController

フロート コントローラ プラグインのタイプは浮動小数点値をコントロールします。以下の例ではフロートにオフセット値を追加し、テスト ケースはオブジェクトの X 位置をコントロールします。このサンプルは、パラメータ ブロックとロールアウト UI の実装を示しています。これは、コントロールされるオブジェクトを選択したときに[モーション](Motion)パネルに表示されます。また、commitValuerestoreValue および 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

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
*/

Point4Controller

このプラグイン コントローラのタイプは、シェーダの 4D カラー スペースなど Point4 の値をコントロールします。

この例では、オフセット値を 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

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

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 

*/

RotationController

回転コントローラ プラグインのタイプは、シーン オブジェクトの回転の値をコントロールします。以下のコントローラの例では、回転の値は 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

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

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


*/