MoveOnEdge_x64.zip
2008年10月01日
MoveOnEdge 64bit版
MoveOnEdge_x64.zip
2005年05月31日
2005年05月07日
EZMuscle
EZMuscleに以下のプラグインを追加
SetMuscle :モデラープラグイン
スケルゴンにEZMuscleのパラメータを埋め込む
EZMuscleを適用したいスケルゴンを選択してSetMuscleを実行
EZMuscleの設定をしたスケルゴンはデフォルトでは濃い赤になります
参照ボーンはスケルゴン名で保存するので、スケルゴン名はかぶらないように付けてください
ReadMuscle :レイアウトジェネリックプラグイン
スケルゴンからパラメータを読み込み、EZMuscleを適用する
SkelegonReaderなどで予めスケルゴンをボーンに変換しておく
オブジェクトを選択してReadMuscleを実行
スケルゴン名とボーン名が変わっていると正常に実行できません(例えば、Boneというスケルゴンが複数あると、
ボーンに変換した時にBone(1)とかに変わってしまう)
2005年04月27日
2005年03月29日
2005年03月25日
LW→MAX
LWで作ったモデルデータをMAXに持っていきたくて、いろいろ試行錯誤してみた
FBXファイルでほぼ完璧にデータを持っていけるんだけど、たまにうまくいかない場合がある(どうしても持っていきたいデータがうまくいかない)のでプラグインを作ってみようと思った
.maxファイルのフォーマットは公開されていないので、LWのエクスポーターを作るのは無理そうなので、MAXScriptでlwoインポーターを作ったんだけどバイナリファイルの実数がMAXScriptでうまく読み込め無いので断念
結局、間にテキストファイルを通して何とかMAXに持っていくことにした
今のところメッシュとボーンとボーンウェイトだけ
2005年02月18日
Keyframer2
とりあえず指定した範囲にキーフレームが打てればいいんで、仮で作ってみた
今のところは、followerをbakeする為だけのプラグインかも
あれば便利そうな機能とかは暇が出来てから
GUIは範囲の最初と最後、増分を入力する部分のみ
GoToFrameでフレームを移動して、CreaetKeyで選択されているオブジェクト等にキーフレームを打つ。
を指定した範囲分繰り返している
キーは全チャンネルに打たれてしまう
↓ソースの一部
続きを読む
2005年02月16日
2005年01月26日
PointMoveOnEdge2
途中経過
ポイント移動に使うデータベースの構築とワイヤフレーム表示まで出来た
Build関数部分ではポイントの移動だけなので、pntMoveで新しい座標入れればいいやなんて思っていたら、
pntMoveでエラーが返ってくる
返り値は2なので不正なレイヤーに対する操作をしたというエラー
addPointとか追加するのはエラーが起きない
続きを読む
2005年01月23日
PointMoveOnEdge
↓こんなの

スケルゴンを修正する時にポイントを真っ直ぐにできると便利だなと思って
先日見つけたプラグインを使っていたんだけど、真っ直ぐなのを保ったまま
ポイントを移動できた方がいいかなと
2004年12月16日
GradientWeightmap3
結局前回の1の方法を採用した
再帰的に隣接するポイントを探していく方法も失敗したので↓の方法で
最初に総ポイント数のメモリを確保
選択されているポイントの情報を配列の前から順に格納、終端にNULL
配列の頭から順に隣接するポイントを探す
配列に含まれていないポイントなら配列の終端に追加、NULLを後ろにずらす
終端のNULLに追いつくまで順に繰り返す
↑の処理をするタイミングは
インスタンスデータに関数のポインタを持たせて、build関数内でそれを実行する
最初やリセット直後はポイントリスト作成関数のポインタを入れておいて
ポイントリスト作成関数の最後でvmapを操作する関数のポインタをいれるようにした
2004年12月14日
GradientWeightmap2
隣接するポイントの取得方法で難航中 _| ̄|○
選択されたポイントが属するポリゴンから、隣接するポイントにマーキング。これを再帰的に繰り返していけば、 選択されたポイントからどれだけ離れているかという情報をすべてのポイントに持たせることが出来る(と思う)が、 この情報をどこに格納しておけばいいんだろ?
1.総ポイント数分のメモリを確保する
一番確実そうだけどポリゴンに属するポイントを探し出すに手間がかかりそう
2.MeshDataEditクラスにしてポイントのユーザーバッファを確保する
一番簡単かも、リアルタイムに範囲を確認できたほうがいいよなぁ。こんなのでパネル開いたり閉じたりってしたくないし
3.vmapに格納
俺様頂点マップタイプを作ってそれに格納。使った後で削除できるといいけど、削除出来なかったらゴミが残るなぁ、削除用のプラグインも作る?
1と3の場合はどのタイミングでこの処理をしたらいいんだろう
3日くらいで終わらす予定だったんだけどなぁ (´・ω・`)
2004年12月09日
GradientWeightmap1
↓のように選択したポイントから隣接するポイントにウエイトマップを広げていくプラグインを作る
fley.comでこういうプラグインを検索したら「GradientWeightmapCreater」
なるLScriptがあったけど、ちょっと違うので名前だけパクった。
↑のgifアニメを作ってるときに思ったのが、UVtoWeight使えば、割と簡単に似たような事が出来ますからぁ、残念っ!
けど他にネタが無いんで作ってみる、斬りぃっ!
2004年12月03日
簡易マッスルボーン2
変換マトリクス作成関数とEvaluate関数のコード
//ローカル→ワールド変換
LW_CMatrix_4x4 LtoW(LWItemID id, const LWItemInfo *iinfo, double
time)
{
LWItemID parent;
LW_CMatrix_4x4 mat;
LWDVector vec;
mat.init();
iinfo->param(id, LWIP_ROTATION, time, vec);
mat.rotateHPB(vec[0], vec[1], vec[2]);
iinfo->param(id, LWIP_POSITION, time, vec);
mat.translate(vec[0], vec[1], vec[2]);
parent = iinfo->parent(id);
if( parent ){
mat = mat * LtoW(parent, iinfo, time);
}
return mat;
}
//ワールド→ローカル変換
LW_CMatrix_4x4 WtoL(LWItemID id, const LWItemInfo *iinfo, double
time)
{
LWItemID parent;
LW_CMatrix_4x4 mat;
LWDVector vec;
int i;
mat.init();
iinfo->param(id, LWIP_POSITION, time, vec);
for(i=0; i<3; i++) vec[i] *= -1;
mat.translate(vec[0], vec[1], vec[2]);
iinfo->param(id, LWIP_ROTATION, time, vec);
for(i=0; i<3; i++) vec[i] *= -1;
mat.rotateY(vec[0]);
mat.rotateX(vec[1]);
mat.rotateZ(vec[2]);
parent = iinfo->parent(id);
if( parent ){
mat = WtoL(parent, iinfo, time) * mat;
}
return mat;
}
XCALL_(void) Evaluate(LWInstance inst, const LWItemMotionAccess
*access)
{
MyData *data =
(MyData*)inst;
LWDVector rot, scl, tip;
double length;
LW_CMatrix_4x4 mat;
*data->self = access->item;
if( NULL == *data->reference ) return;
memcpy(tip, data->refPos, sizeof(double)*3);
//ローカル(reference)→ワールド
mat = LtoW(*data->reference, data->iinfo,
access->time);
mat.Transform(tip);
#ifdef CHECK_VAL
if( fp )
fprintf(fp, CHECK_FORMAT, access->time,
tip[0], tip[1], tip[2], "ローカル→ワールド");
#endif//CHECK_VAL
//ワールド→ローカル(self)
mat = WtoL(*data->self, data->iinfo,
access->time);
mat.Transform(tip);
#ifdef CHECK_VAL
if( fp )
fprintf(fp, CHECK_FORMAT, access->time,
tip[0], tip[1], tip[2], "ワールド→ローカル");
#endif//CHECK_VAL
access->getParam(LWIP_ROTATION, access->time,
rot);
mat.init();
mat.rotateHPB(rot[0], rot[1], rot[2]);
mat.Transform(tip);
Angle(tip, rot);
length = Distance(tip);
access->getParam(LWIP_SCALING, access->time,
scl);
scl[2] = length / data->restLength;
if( data->holdVolume ){
scl[0] = scl[1] = sqrt(1/scl[2]);
}
access->setParam(LWIP_ROTATION, rot);
access->setParam(LWIP_SCALING, scl);
}
LW_CMatrix_4x4は自作の変換マトリクスクラス
LtoWとWtoL関数は再帰的に呼び出して、Root(親が無い)に達すると戻ってくる
Rootに向かって行くときに自分自身の変換マトリクスを作っておいて、帰るときに掛け合わせている
ワールド→ローカルとローカル→ワールドでは移動、回転のかける順番が違う
2004年11月30日
簡易マッスルボーン1
モーションプラグインでマッスルボーンっぽいのを作ってみる。
上図の様なA、B、Cの3っのボーンがあって、Cにマッスルボーンを適用する場合
CはAの子で、Cの先端はBの動きに合わせたい。
Cの先端をpとして、pをワールド座標に変換、次にBのローカル座標に変換して、その座標を覚えておく。
pをワールド座標に変換、Cのローカル座標に変換する。この座標を元にCの角度、長さを変える。
オプションとして、体績を保持する。
Xscale=Yscale=√1/Zscale
GUI
参照:ボーンの先端の親?を指定
更新:点pの再取得
体績を保持:オプション
2004年11月25日
ウエイトマップをミラーコピーするプラグイン3
アクティベーション関数のコード
LWがプラグインを実行すると、この関数が呼ばれる
処理の流れは、
データの初期化
設定ファイルから読み込み
パネルに渡すデータを収集
パネルを開く
設定ファイルに保存
VMAPの修正
//アクティベーション関数
XCALL_(int)Activate(long version, GlobalFunc *global, LWModCommand
*local, void *serverData)
{
LWMessageFuncs *msgf = (LWMessageFuncs*)global(
LWMESSAGEFUNCS_GLOBAL, GFUSE_TRANSIENT );
MyData data;
if( LWMODCOMMAND_VERSION != version )
return AFUNC_BADVERSION;
if( !msgf )
return AFUNC_BADGLOBAL;
data.global = global;
//設定読み込み
readConfig(&data);
//全ウエイトマップリスト作成
listupAllWMap(&data);
if( 0 == data.allwlist.size() ){
msgf->error("ウェイトマップがありません。", NULL);
return AFUNC_OK;
}
//ウエイトマップリスト作成
listupEditWMap(&data);
//パネル表示
if( 0 == Panel(&data, global) ){
return AFUNC_OK;
}
//設定保存
writeConfig(&data);
data.edit = local->editBegin(0, 0, OPSEL_GLOBAL);
//ポイントスキャン
data.edit->pointScan(data.edit->state, PointScanFunc,
&data, OPLYR_PRIMARY);
data.edit->done(data.edit->state, EDERR_NONE,
0);
return AFUNC_OK;
}
ポイントスキャン関数のコード
すべてのポイントに対して呼ばれる
元になるウエイトマップの値を取得
成功したら、X座標にoperationの値(1or-1)をかける
0より大きければ、対象ウエイトマップに値を設定、元マップを削除
0ならば、対象ウエイトマップに値を設定
//ポイントスキャン関数
EDError PointScanFunc(void *scanData, const EDPointInfo *info)
{
MyData *data = (MyData*)scanData;
MeshEditOp *edit = data->edit;
int result;
float val;
for(int i=0; i<data->wlist.size(); i++){
data->wlist[i].mapID =
(LWID)edit->pointVSet(edit->state,
(void*)data->wlist[i].mapID, LWVMAP_WGHT,
data->wlist[i].src.c_str());
result = edit->pointVGet(edit->state,
info->pnt, &val);
if( 0 != result ){
if( 0.0 < (info->position[0] *
data->operation) ){
edit->pntVMap(edit->state, info->pnt, LWVMAP_WGHT,
data->wlist[i].src.c_str(), 1, NULL);
edit->pntVMap(edit->state, info->pnt, LWVMAP_WGHT,
data->wlist[i].dist.c_str(), 1, NULL);
edit->pntVMap(edit->state, info->pnt, LWVMAP_WGHT,
data->wlist[i].dist.c_str(), 1, &val);
}else if( 0.0 ==
info->position[0] ){
edit->pntVMap(edit->state, info->pnt, LWVMAP_WGHT,
data->wlist[i].dist.c_str(), 1, &val);
}
}
}
return EDERR_NONE;
}
2004年11月24日
2004年11月18日
ウエイトマップをミラーコピーするプラグイン 1
実際にはウエイトマップのミラーコピーではなくて、ミラーツールで作った左右対称のオブジェクトのウエイトマップを左右に分離させる。
↓こんな感じ

パネルのメモ

データを一つの構造体に
//マルチリストコントロールで使いやすいように
typedef struct{
int active;
std::string src; //元Weightmap名称
std::string dist; //対象Weightmap名称
}WeightListData;
//メインデータ
typedef struct {
GlobalFunc *global;
std::vector
std::vector
int operation; //コピー方向
int replace; //置換位置
std::string srcKey; //置換文字
std::string distKey; //置換対象文字
}MyData;
次回はGUIのコーディングの予定
2004年11月17日
Borland C++Builder6 でビルド
Borland 版の SDK ライブラリをビルド(server.lib)
ファイル(F)→新規作成(N)→その他(O)

新規作成ダイアログが開く
新規作成タブ→ライブラリ

ファイル(F)→プロジェクトに名前を付けて保存(E)
適当なフォルダを作って保存
プロジェクト(P)→プロジェクトに追加(A)
servdesc.c、username.c、startup.c、shutdown.c を先ほど作ったフォルダにコピーして追加する
プロジェクト(P)→オプション(O)
コンパイラタブの「リリース」ボタンを押す

TLibタブの「共有 RTL DLL を使う(R)」のチェックを外す

プロジェクト(P)→server をメイク(M)
LWプラグインをビルド
SDK付属のサンプル
lwsdk80\sample\Modeler\CommandSequence\boxes\box1\box.c
をビルドする
ファイル(F)→新規作成(N)→その他(O)

新規作成ダイアログが開く
新規作成タブ→DLLウィザード

プロジェクト(P)→オプション(O)
アプリケーションタブの、ターゲットファイル拡張子を「dll」から「p」に変更
ディレクトリ/条件タブの、インクルードパスの右端のボタンを押す
LWSDKのフォルダを指定して追加ボタンを押す

server.lib、servmain.c、serv.def、box.cをフォルダにコピーして、プロジェクトに追加する
プロジェクト(P)→box をメイク(M)