« artist side/C4Dコミュニティ 「キャラクタを1フレーム毎にobj形式でXPressoでの保存」?-04 | トップページ | artist side/C4Dコミュニティ 「キャラクタを1フレーム毎にobj形式でXPressoでの保存」?-06 »

artist side/C4Dコミュニティ 「キャラクタを1フレーム毎にobj形式でXPressoでの保存」?-05

ユーザスクリプトで、実際にフレームを指定して移動し、オブジェクトの座標を直接取得できないとなると…
自分が取得できなかっただけで、もっと優秀な人がやればできるのかも知れませんが…

アニメーショントラックから、時間を指定して数値を取り出せば良いのだ…

で、どうやって?
そう言えば、以前にアニメーショントラックを…
http://villager-and-c4d.cocolog-nifty.com/blog/2008/06/post_56dd.html#more

以前の記事では、キーフレームまでの取得かぁ…

キーフレーム間の中割の数値は、どうやって取得するんだろうか?
SDK R9.5を見ても、らしいものは見当たらず…
そう言えば、自分の目は節穴だった…

とりあえず、アクティブオブジェクトのアニメーショントラックを取得してみよう。

アクティブオブジェクトのアニメーショントラック全ての名前をコンソールに表示してみます。

/*
アクティブオブジェクトのアニメーショントラックの名前をコンソールに表示
2009.7.13
*/


main(doc , op)
{
  var trc = op->GetFirstTrack();

  while(trc)
  {
    println(trc->GetName());
    trc = trc->GetNext();
  }
}

C4D R9.5で実行してみた。
勿論、キーフレームが設定されたオブジェクトを1個選択してね。

位置 . X
位置 . Y
位置 . Z
角度 . H
角度 . P
角度 . B
スケール . X
スケール . Y
スケール . Z

で、C4D R11Demoだったら…
スクリプトは、メンバ関数の明示はされているので、問題なさげだね。
では、キーフレームを設定したオブジェクトを1個選択して実行を…

何も表示されず…

そう言えば、C4D R9.5とC4D R11のタイムラインウィンドウの構成も変わったんだよね。
C4D R10からだね…

確認の為、1行追加…

/*
アクティブオブジェクトのアニメーショントラックの名前をコンソールに表示
2009.7.13
*/


main(doc , op)
{
  var trc = op->GetFirstTrack();

  println(trc);

  while(trc)
  {
    println(trc->GetName());
    trc = trc->GetNext();
  }
}

実行…

0

なるほど、トラックは取得できていないんだ…
ところで「0」って何だ?
トラックが取得できなかったら「nil」では?

まぁ、0 でも nil でも取得できないことには、変わらないね。

SDK R11を見ると…

CTrack/CCurve/CKeyと新しいクラスが追加されている。

なるほど、もうR9.5の時代ではないのだ…
手持ちのC4Dは、R9.5だからテンションがちょっと下がるね…

ではR11だと、「C」を付け加えて…

/*
アクティブオブジェクトのアニメーショントラックの名前をコンソールに表示 R11
2009.7.13
*/


main(doc , op)
{
  var trc = op->GetFirstCTrack();

  while(trc)
  {
    println(trc->GetName());
    trc = trc->GetNext();
  }
}

実行結果は…

位置 . X
位置 . Y
位置 . Z
スケール . X
スケール . Y
スケール . Z
角度 . H
角度 . P
角度 . B

R9.5とR11ではトラックの順番が違うのか…

R9.5のタイムライン

Export_13

R11のタイムライン

Export_12

トラックの順番を変えて実行してみたら?

Export_14

取得の順番も変わるのだ…

角度 . H
角度 . P
角度 . B
位置 . X
位置 . Y
位置 . Z
スケール . X
スケール . Y
スケール . Z

順番は入れ替えが可能だから、順番自体はどうでも良い事で…

で?
アニメーショントラックに対して、時間を指定して数値を取得するには?
SDK R9.5では、見当たらないから、C4D R11で。

[float]CTrack::GetValue([BaseDocument]doc , [BaseTime]tm , [int]fps)

これで、トラックに対して、時間を指定するとトラックの値が取得できます。

でも、なぜ、GetValue()にBaseDocumentを渡すんだろうか?
意味が無いような…ま、仕様だから仕方がない…

各トラックの最初の10フレームの数値を表示してみる。

/*
アクティブオブジェクトのアニメーショントラックの最初の10フレームを表示 R11
2009.7.13
*/


main(doc , op)
{
  var trc = op->GetFirstCTrack();
  var min_tm = int(doc->GetMinTime()->GetFrame(doc->GetFps()));
  var max_tm = int(doc->GetMaxTime()->GetFrame(doc->GetFps()));
  var tm = new(BaseTime);
  var c;

  if(max_tm > min_tm + 10)max_tm = min_tm + 10;

  while(trc)
  {
    println(trc->GetName() , "--------");
    for(c = min_tm ; c < max_tm ; c++)
    {
      tm->SetFrame(c , doc->GetFps());
      println(c , " : " , trc->GetValue(doc , tm , doc->GetFps()));
    }
    trc = trc->GetNext();
  }
}

結果は…

角度 . H--------
0 : 0.000000
1 : 0.000000
2 : 0.000000
3 : 0.000000
4 : 0.000000
5 : 0.000000
6 : 0.000000
7 : 0.000000
8 : 0.000000
9 : 0.000000
角度 . P--------
0 : 0.000000
1 : 0.000000
2 : 0.000000
3 : 0.000000
4 : 0.000000
5 : 0.000000
6 : 0.000000
7 : 0.000000
8 : 0.000000
9 : 0.000000
角度 . B--------
0 : 0.000000
1 : 0.000000
2 : 0.000000
3 : 0.000000
4 : 0.000000
5 : 0.000000
6 : 0.000000
7 : 0.000000
8 : 0.000000
9 : 0.000000
位置 . X--------
0 : 137.283600
1 : 137.182083
2 : 136.880600
3 : 136.383606
4 : 135.695801
5 : 134.821503
6 : 133.765549
7 : 132.532364
8 : 131.126205
9 : 129.552139
位置 . Y--------
0 : 195.832336
1 : 195.707336
2 : 195.336090
3 : 194.724075
4 : 193.877090
5 : 192.800461
6 : 191.500153
7 : 189.981567
8 : 188.250015
9 : 186.311676
位置 . Z--------
0 : 238.083374
1 : 237.917511
2 : 237.424942
3 : 236.612930
4 : 235.489151
5 : 234.060684
6 : 232.335403
7 : 230.320557
8 : 228.023132
9 : 225.451340
スケール . X--------
0 : 1.000000
1 : 1.000000
2 : 1.000000
3 : 1.000000
4 : 1.000000
5 : 1.000000
6 : 1.000000
7 : 1.000000
8 : 1.000000
9 : 1.000000
スケール . Y--------
0 : 1.000000
1 : 1.000000
2 : 1.000000
3 : 1.000000
4 : 1.000000
5 : 1.000000
6 : 1.000000
7 : 1.000000
8 : 1.000000
9 : 1.000000
スケール . Z--------
0 : 1.000000
1 : 1.000000
2 : 1.000000
3 : 1.000000
4 : 1.000000
5 : 1.000000
6 : 1.000000
7 : 1.000000
8 : 1.000000
9 : 1.000000

角度とスケールは値を変化させなかったから0.0と1.0で変化ありませんが、位置はXYZそれぞれ取得できています。

実際の5フレームのオブジェクトの座標です。

Export_15

上の結果と一致しています。

これで、トラックから数値を取得する事ができたのですが…

取得したトラックが一体何のトラックなのか、判別する方法がわかりません。
トラック名で判別する?
でも、全ての人が日本語表示にしているとは限りません。

もっと明確に、「このトラックはPositionTrackですよ。」「このトラックはRotationTrackですよ。」って具合にね、知る方法が必要だ…

では、取得したトラックのクラスを表示してみよう。

/*
アクティブオブジェクトのアニメーショントラックのクラスを表示 R11
2009.7.13
*/


main(doc , op)
{
  var trc = op->GetFirstCTrack();

  while(trc)
  {
    println(trc->GetName() , " : " , getclass(trc));
    trc = trc->GetNext();
  }
}

結果は…

角度 . H : [Class-CTrack]
角度 . P : [Class-CTrack]
角度 . B : [Class-CTrack]
位置 . X : [Class-CTrack]
位置 . Y : [Class-CTrack]
位置 . Z : [Class-CTrack]
スケール . X : [Class-CTrack]
スケール . Y : [Class-CTrack]
スケール . Z : [Class-CTrack]

全てがCTrackクラスで判別ができないね…

でもね、本当に欲しい物は…

フレームに対したオブジェクトのグローバルマトリクス
ポリゴン
ポイント
UVW
選択範囲

マトリクスは、オブジェクトの位置/回転/スケールから算出できるけど…
この場合のグローバルマトリクスは、BaseObject::GetMg()では取得しても意味がありません。
そうすると対象オブジェクトからルートまでの全ての親オブジェクトのマトリクスから算出しなければならないね。
そうなると、その全ての親のアニメーショントラックから、位置/回転/スケールをフレーム毎に取り出す事になります。

|

« artist side/C4Dコミュニティ 「キャラクタを1フレーム毎にobj形式でXPressoでの保存」?-04 | トップページ | artist side/C4Dコミュニティ 「キャラクタを1フレーム毎にobj形式でXPressoでの保存」?-06 »