keichanぶろぐ

目次

Blog 利用状況

ニュース

FF XI

Profile

初音ミク

iKnow!

記事カテゴリ

書庫

日記カテゴリ

2008年5月8日 #

[3ds max][plugin]外部参照オブジェクトの外部参照コントローラのみをシーン合成する

max8では正常動作していたスクリプトをmax9で走らせると一部不具合が判明した。

不具合があった箇所というのは、複数のmaxファイルを外部参照オブジェクトとして読み込み、Offset, Rotation, Scaleを

予め用意しておいた数値でアニメーションキーを自動的に打つ部分。


max9では新たなアトリビュートとして「外部参照コントローラ」なるものが用意されていた。

コントローラも外部参照として扱われているので、シーン内でそのオブジェクトに新規にキーを打つことができない状態になっていた。

では、外部参照コントローラだけをシーン合成行うにはスクリプトでどうすればいいか調べてみたところ・・・

結論から言うと、スクリプトのみでは方法が「ない」んです。

maxscriptで外部参照オブジェクトに関して操作する場合、objXRefMgrインタフェースを使用します。

+ MAXScript 言語リファレンス
 + 3ds Max オブジェクト
  + インタフェース
   + コア インタフェース
    + コア インタフェースのドキュメント
     + インタフェース: objXRefMgr
maxscriptリファレンスの上記ツリーを確認してみると、


<Interface>AddXRefItemsFromFile <filename>fileName promptObjNames:<bool> objNames:<string array> xrefOptions:<&enum array>
 promptObjNames default value:false
 objNames default value: #()
 xrefOptions enums:{#asProxy|#xrefModifiers|#dropModifiers|#mergeModifiers|#mergeManipulators|#selectNodes|#mergeMaterials}
 xrefOptions default value: #()
 xrefOptions は In パラメータです
指定されたレコードに名前の配列を追加します。

とあります。この xrefOptions で本来であれば存在していなければならない #mergeControllers がありません。

つまり max9 においてスクリプトレベルでの制御は不可能ということです。

 

仕方がないので外部参照オブジェクトを読み込むルーチンのみをプラグインで書き、

スクリプト側からプラグインの関数を呼び出すようにしました。

以下はそのソース。



#include <Maxscrpt/Maxscrpt.h>
#include <maxscrpt/Strings.h>
#include <maxscrpt/arrays.h>
#include <maxscrpt/numbers.h>
#include <maxscrpt/maxobj.h>
#include <maxscrpt/definsfn.h>

#include <XRef/iXrefObjMgr8.h>

def_visible_primitive( MergeXRefControllersFromFile, "MergeXRefControllersFromFile" );
Value* MergeXRefControllersFromFile_cf(Value** arg_list, int count)
{
 
 check_arg_count_with_keys(MergeXRefControllersFromFile, 2, count);

 type_check(arg_list[0], String, "第1引数は外部参照オブジェクト先のmaxファイルパスじゃないとダメ");
 type_check(arg_list[1], Array , "第2引数は読み込むノード名配列");

 try
 {
  char* full_path_filename = arg_list[0]->to_string();
  Array* node_names_array = static_cast<Array*>(arg_list[1]);
  
  Tab<char*> tab_node;
  char** node_names = new char*[node_names_array->size];
  for( int i=0; i<node_names_array->size; ++i ) {
   node_names[i] = node_names_array->data[i]->to_string();
  }
  tab_node.Append(node_names_array->size, node_names);
  IObjXRefManager8* xref_manager = IObjXRefManager8::GetInstance();
  IObjXRefRecord* ixrRecord = xref_manager->AddXRefItemsFromFile(full_path_filename, false, &tab_node, XREF_MERGE_CONTROLLERS);

  delete[] node_names;
 }
 catch(...)
 {
  return new Integer(-1);
 }
 return new Integer(0);
}


 

これで、スクリプト側から
MergeXRefControllersFromFile "C:\\hoge.max" #("node1", "node2")
のような感じで呼び出せます。

とりあえず、上記対策を行って正常動作することは確認しました。

 

っが正直なところ、これくらいは maxscript で対応してくれてもよさそうです。

手元にある max2008 の maxscriptリファレンスを見ても、対応してませんでした。

max2009 はどうなんでしょうね・・

posted @ 16:35 | Feedback (1150)