Meshのマルチテクスチャとスクリプト
この記事は セカンドライフ 技術系 Advent Calendar 2013 の参加記事です。
前回 Metasequoiaで始めるMesh入門 の続きに続き、セカンドライフのMesh関連の技術記事(のつもり)です。
今回のテーマは多面メッシュ(Multi-Face Mesh)の仕様と、スクリプトでのテクスチャ・色の制御です。
前半は多面メッシュの基本の紹介でMetasequoiaやBlenderがある程度使える方向けの説明になっています。
後半はLSLスクリプトも少しいじれる方向けの少し高度な内容になっています。
http://wiki.secondlife.com/wiki/メッシュとは何ですか?
http://wiki.secondlife.com/wiki/Mesh/What_is_mesh?
前置きとして、Meshには種類があります。
● simple mesh
:ただのメッシュ。モデラー上で何も特別な設定をしないとこれになります。スカルプトプリムと同様にテクスチャを1枚だけ貼れます。
● multi-face mesh
:多面メッシュ。今回の主役。テクスチャを8枚まで貼れます。simple meshの進化系。
● rigged mesh
:皆さんご存知の服を作るやつです。rigged meshの作り方は他の方がたくさん書いておられるので今回は触れません。
2つの機能を併せ持ったmulti-faceでriggedなmeshも作れます。
それと前回の記事を書いたあと更新を丸1年サボってる間に愛用のMetasequoiaが
ver4にメジャーバージョンアップしたのでver3系と変わった所にも少し触れます。
まずはモデラーで面が複数あるモデルを作成します。
買ったばかりのMetasequoia 4 EXを使って嬉々として解説を進めます。
まずはいつもどおりモデルを作ります。ここではただのタマにしておきます。
ベースとなるモデルの用意ができたら材質パネルの材質を2つに増やします。
ここでの材質の数がSLにアップロードした時の面の数になります。
練習なので[新規]・[複製]どちらでも問題ありません。
材質を変更したい面を選択します。
材質パネルで変更先の材質を選択します。
そのまま上のメニューから[選択部処理]>[面に現在の材質を指定]を選択します。
画像では材質が変わった時わかりやすいように予め材質の色を赤にしてあります。
赤い部分の材質が”mat2″に変わりました。これをCollada(.dae)で保存してSLにアップロードすれば多面メッシュになります。
(なんとなくmat1の色を青にしました。)
Metasequoia 3でも4でもGUIのデザインが違うだけで、Colladaへの吐き出しは同じ[ファイル]>[名前をつけて保存]からできます。
Metasequoia 3では保存前に1/100くらいにしないと、アップロードした時に巨大になるという罠がありましたが
Metasequoia 4になって保存ボタンを押したあとに出るダイアログに、拡大率を指定するダイアログが出るようになりました。
初期値で1/1000になってるので、特に事前に補正することなく保存してアップしてもちょうどいい手のひらサイズだったのでこの点少しだけ便利になりました。
ただし、まだちゃんと試してませんが(試せよっていう)UVマッピングのV方向(縦)が反転してしまうのは変わってない気がするので、
“テクスチャのV方向を反転”のチェックはお忘れなく。
材質パネルで設定した色がそのままプリムの面の色になったりします。
プリムの面の色なので編集から普通に白に戻せます。使いようによっては便利な小技かも?
(△芸術性のかけらのありません)
小技ついでにもう1つ紹介。メタセコの物体パネルで設定した物体の名前がMeshアップロード画面左上の「モデル名」に反映され、
アップロード後はオブジェクト名になります。これも使うかは否かは趣味の問題です。
また物体名にスペースが入っているとエラーになるようなのでこれも注意です。
無駄話が大半でしたが、以上が多面メッシュの基本になります。
SLでは材質(マテリアル)の数は8面まで使えるので、あとどう使うかは自由。
服だとアクセサリだけマテリアルを分けたり、車だとステッカーを別マテリアルで貼っておいて、
テクスチャをアルファ透過にすることでロゴだけ変えれるようにしたり、使い方は色々です。
モデラーの皆さん頑張って(UV展開して)ください!
さてここからはスクリプトの話です。
これを理解すると、巷でよく見かけるHUD付きテクスチャーチェンジスクリプトの原理部分を作れたり
かつて栄華を極めたスカルプマップを切り替えてアニメーションするようなアレと同じようなことが出来ます。
先に1つスクリプトを公開します。
~コードここから~
default
{
state_entry()
{
integer i;
integer face = llGetLinkNumberOfSides(LINK_THIS);
list data = [
"f56f5bba-e83f-1bb1-8a4f-23f18cfe5773", //0
"44c78d32-845c-d586-b213-530eb7f7ecd9", //1
"50330856-2510-bb1c-4ff2-838aa7d706aa", //2
"9bfaf28e-88e4-9d6e-98af-4f208112f61f", //3
"cc5ac2fc-efeb-701a-92df-15bb28792cda", //4
"dead6094-76a7-9fa8-1630-cbad1ace8000", //5
"63c205c9-1f5a-c07c-1d0d-d42d5889a3b2", //6
"078a7d3d-f1e8-8b67-07ec-bc32598a47db", //7
"3fa95aa6-c0ae-16ca-ff40-d13f378994fa" //8
];
for(i=0;i<face;i++){
llSetLinkPrimitiveParamsFast(LINK_THIS,[
PRIM_TEXTURE,i,llList2Key(data,i), <1.0, 1.0, 0.0>, <0.0, 0.0, 0.0>, 0.0]);
}
//色分けもしたい場合はコメントアウトを解除
/*
list color = [
< 255.0/255.0, 255.0/255.0, 255.0/255.0>, //WHITE
< 255.0/255.0, 0.0/255.0, 0.0/255.0>, //RED
< 255.0/255.0, 255.0/255.0, 0.0/255.0>, //YELLOW
< 0.0/255.0, 255.0/255.0, 0.0/255.0>, //GREEN
< 0.0/255.0, 0.0/255.0, 255.0/255.0>, //L.BLUE
< 255.0/255.0, 0.0/255.0, 255.0/255.0>, //BLUE
< 255.0/255.0, 255.0/255.0, 127.0/255.0>, //PINK
< 0.0/255.0, 255.0/255.0, 127.0/255.0>, //L.YELLOW
< 127.0/255.0, 255.0/255.0, 255.0/255.0> //SKY.BLUE
];
llSetColor(<1,1,1>,ALL_SIDES);
for(i=0;i<face;i++){
llSetLinkPrimitiveParamsFast(LINK_THIS,[
PRIM_COLOR,i,llList2Vector(color,i),1.0]);
}
*/
}
}
~コードここまで~
これをよくある通常プリムのBOXで作る9面プリムに入れて、材質タブのマッピングの水平・垂直スケールを 4.0, 4.0 にしてやると
こうなります。単純ですが要は面番号を視覚的に調べるスクリプトです。
お好みで/* と*/を消すと面ごとに色分けもされます。
公式Viewerの機能でも、アドバンスと開発タブを表示した状態で、
面を選択してCtrl+Alt+Shift+T(テクスチャ情報表示機能)を押すと面番号が調べられたり、
(私は使っていないので聞いた話ですが)FireStormでは面番号を表示する機能があるそうです。
各個人使いやすい方法があると思うのでどれでもいいんですが、私は視覚的に見れる方がしごとしやすいのでこの方法を使っています。
一方、こんなのを作ってみました。材質(マテリアル)を8つ使っています。
SLにアップするとこんな感じです。これに先ほどのスクリプトを入れて、テクスチャの水平・垂直スケールを 16.0, 16.0にしてやります。
先ほどの9面BOX同様、面番号が調べられました。(色は一旦白にしました)
水平・垂直スケールをいじるのはテクスチャが延びて字が読めないからです。(実際にやればわかります)
この手順は別に手作業でいいと思っています。
さて、具合的にMesh用のスクリプトを作るに当たってですが、Meshだからといって、
従来からあるllSetTexture,llSetColor,llSetAlpha,llSLPPFなどに相当する特別な関数やAPIが増えたわけではないです。
●スカルプトプリムではテクスチャは1枚だった→Meshでは最大8枚まで=llGetLinkNumberOfSidesの返り値が最大8
●面番号(face number)は0~7
これだけ覚えて、あとは調べた面番号を使って、従来通り llSetTexture したり llSetColor したりするだけです。
llSetScale系も従来通りです。
llSLPPFのパラメータだけPRIM_PHYSICS_SHAPE_TYPEとかだいぶ前に増えたりしていますが、
このネタは今回の趣旨とは外れるので割愛します。(またの機会に)
さいごに1つ用例を紹介します。
時々見かける、
llSetPrimitiveParams([PRIM_TYPE, PRIM_TYPE_SCULPT, “スカルプマップUUID”, PRIM_SCULPT_TYPE_SPHERE]);
とかして擬似的にプリムをアニメーションさせたり形を変えたりする技がありますが、
残念ながらスクリプトでMeshのアセットUUIDを指定して入れ替える事ができません。
Mesh Betaの頃にどっかのフォーラムで見かけたんですが、どうやら著作権関係の対策のためにLLが出来ない仕様にしたようです。
替わりにMeshには上述のmulti-face があるのでこれを利用します。
Q●3分クッキング的なノリでこんなモデルを用意しました。
子プリムなしのオブジェクトで、青がface number=0,赤がface number=1です。
~コードここから~
integer i;
default
{
touch_start(integer total_number)
{
i = 1 - i; //※
llSetAlpha(0.0,ALL_SIDES);
llSetAlpha(1.0,i);
}
}
~コードここまで~
このようなスクリプトを入れてやると A→B→A→B→A・・・というようにモデルが交互に表示されます。
llSLPPFを使えば関数1つでできるんですがllSLPPFって実はなんか重いらしいのでいつもllSetAlpha2回にしています。
(汎用化するならllGLPP併用になるしネ)
これを8面すべて使ってコマ送りアニメーションのようなことをしたい場合は※部分を
++i;
i = i % 8;
とかにしてやればいいわけです。分かってしまえば難しくないですね。
あとは具体的に開発を進めるにあたっては、UVマップとはなんぞやという部分をわかっていないとつまづくので、
スクリプターさんも3D-CGの勉強をしておきましょう。
テクスチャーチェンジHUDの設計の話とかしだすとまだまだ語る事が多くあるんですが
すでに長くなってしまったので今回はこのへんまでにします。
次回は当たり判定を使う話とかしたいですね。ネタを集めておきます。
ご清聴ありがとうございました。
カレンダー
2018年4月 日 月 火 水 木 金 土 « 12月 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 カテゴリー