ICE のビデオチュートリアルをいつもVimeoサイトにたくさんアップして下さっているPaul Smith 氏の新作です。
今回は、エクスプレッションやパラメータコネクションを一切使わずに、ICEでシェイプベースのフェイシャル制御を実現するというユニークで実用的な3本立てチュートリアルです。
具体的には、眼球の回転角度をもとに、目の周りの筋肉の反応、そして瞬きというシェイプパターンをICEで連動制御させるテクニックを解説頂いています。
シェイプによる制御は、映像制作だけでなくゲーム開発の現場でもを使用されているケースもあると思います。特にフェイシャルキャプチャデータと自社リグの間にレイヤーとしてシェイプを挟まれているケースなど。
このICEベースのシェイプ制御のメリットは、一度組んでしまうと別のキャラクタに流用が行い易いことだと思います。また、エクスプレッション制御を仕込む方法よりも、ICEのほうがある意味わかりやすくて柔軟に感じる面もあります。技術力のある会社さんなんかは、自動フェイシャルリグのセットアップツールとかに使えるのではと思います。
パート1: ICE でシェイプ制御のテクニック解説
パート2: 片方のセットアップを効率的に流用するミラーリングテクニック
パート3: セットアップ済みのICE制御を別のキャラクタに適用するテクニック
1- エクスプレッション名の入れ替え
NewScene, False
CreatePrim "Cube", "MeshSurface"
SelectObj "cube.kine.local"
AddExpr "cube.kine.local.posx"
SetExpr "cube.kine.local.posx", "cube.kine.local.posy*1.5"
SelectObj "cube"
CreateModelAndConvertToRef ,QA_LocalXSIProject& "Models/NotMergeCubeRefModel.emdl"
SaveSceneAs QA_LocalXSIProject&"Scenes/MergeCubeRef.scn"
NewScene, False
CreatePrim "sphere","MeshSurface"
SelectObj "sphere.kine.local"
AddExpr "sphere.kine.local.posx"
SetExpr "sphere.kine.local.posx", "fc*1"
SelectObj "sphere"
CreateModelAndConvertToRef ,QA_LocalXSIProject& "Models/NotMergeSphereRefModel.emdl"
SaveSceneAs QA_LocalXSIProject&"Scenes/MergeSphereRef.scn"
NewScene, False
CreatePrim "cube","MeshSurface"
SelectObj "cube.kine.local"
AddExpr "cube.kine.local.posx"
SetExpr "cube.kine.local.posx", "cube.kine.local.posy*2"
SelectObj "cube"
CreateModelAndConvertToRef ,QA_LocalXSIProject& "Models/NotMergeCubeRefModel.emdl"
SaveSceneAs QA_LocalXSIProject&"Scenes/MergeCube2Ref.scn"
OpenScene QA_LocalXSIProject&"Scenes/MergeCubeRef.scn", false
MergeScene QA_LocalXSIProject&"Scenes/MergeSphereRef.scn"
MergeScene QA_LocalXSIProject&"Scenes/MergeCube2Ref.scn"
//結果: MergeCube2Ref、 MergeSphereRefと Modelの cube.local.posxは、
//modelxxx.cube.kine.local.posy*2です。
//Model1、Model2、Modelのエクスプレッション名は正しく処理されています。
2. Delta StoredExpressions 値に対するスクリプトアクセス
NewScene(null, false);
// Create a reference model from a cube
var oRoot = Application.ActiveProject.ActiveScene.Root;
var oCube = oRoot.AddGeometry("Cube", "MeshSurface");
var emdlFileRefModel = XSIUtils.BuildPath(Application.InstallationPath(siProjectPath), "Models", "MyModel.emdl");
CreateModelAndConvertToRef(oCube, emdlFileRefModel );
// Create a cone
var oCone = oRoot.AddGeometry("Cone", "MeshSurface");
// Create a sphere
var oSphere = oRoot.AddGeometry("Sphere", "MeshSurface");
// Translate the
Translate(oCone, 3.0, 3.0, 0.0, siRelative, siView, siObj, siXYZ, null, null, null, null, null, null, null, null, null, 0, null);
Translate(oSphere, -2.0, -2.0, 0.0, siRelative, siView, siObj, siXYZ, null, null, null, null, null, null, null, null, null, 0, null);
//ApplyCns("Position", oCube, oCone, null);
SetExpr("Model.cube.kine.local.posx", "cone.kine.local.posx\r\n", null);
// Get the Delta object
var oDelta = Dictionary.GetObject("Model.Delta");
// Get the collection of the first ActionDelta
var oActionDeltaItemsColl = oDelta.ActionDeltas(0).Items;
for (var i=0; i<oActionDeltaItemsColl.Count; i++) {
// Replace the cone as constraining object by the Sphere
Logmessage(oActionDeltaItemsColl(i).Value)
oActionDeltaItemsColl(i).Value = "Model.cube.kine.local.posx = Sphere.kine.local.posx";
Logmessage(oActionDeltaItemsColl(i).Value)
}
// Apply modification on the target reference asset container (the reference model)
oDelta.Apply()
// Reload the reference model to reset cube.kine.local.posx value
UpdateReferencedModel("Model");
1- Please support expression name replacement.
I did a big part last release and Bosheng is currently fixing some last defects.
2- Please also support a script access for Delta StoredExpressions value.
Seems to work
NewScene(null, false);
// Create a reference model from a cube
var oRoot = Application.ActiveProject.ActiveScene.Root;
var oCube = oRoot.AddGeometry("Cube", "MeshSurface");
var emdlFileRefModel = XSIUtils.BuildPath(Application.InstallationPath(siProjectPath), "Models", "MyModel.emdl");
CreateModelAndConvertToRef(oCube, emdlFileRefModel );
// Create a cone
var oCone = oRoot.AddGeometry("Cone", "MeshSurface");
// Create a sphere
var oSphere = oRoot.AddGeometry("Sphere", "MeshSurface");
// Translate the
Translate(oCone, 3.0, 3.0, 0.0, siRelative, siView, siObj, siXYZ, null, null, null, null, null, null, null, null, null, 0, null);
Translate(oSphere, -2.0, -2.0, 0.0, siRelative, siView, siObj, siXYZ, null, null, null, null, null, null, null, null, null, 0, null);
//ApplyCns("Position", oCube, oCone, null);
SetExpr("Model.cube.kine.local.posx", "cone.kine.local.posx\r\n", null);
// Get the Delta object
var oDelta = Dictionary.GetObject("Model.Delta");
// Get the collection of the first ActionDelta
var oActionDeltaItemsColl = oDelta.ActionDeltas(0).Items;
for (var i=0; i<oActionDeltaItemsColl.Count; i++) {
// Replace the cone as constraining object by the Sphere
Logmessage(oActionDeltaItemsColl(i).Value)
oActionDeltaItemsColl(i).Value = "Model.cube.kine.local.posx = Sphere.kine.local.posx";
Logmessage(oActionDeltaItemsColl(i).Value)
}
// Apply modification on the target reference asset container (the reference model)
oDelta.Apply()
// Reload the reference model to reset cube.kine.local.posx value
UpdateReferencedModel("Model");
http://marupuraxsi.wordpress.com/
