メタセコイア

セカンドライフでジャンプ台を作る

投稿日: 更新日:


はじめまして。

セカンドライフ技術系 Advent Calendar 2015」の12月10日(木)担当の なたで です。
今回、初めての参加ですがよろしくお願いします。

今日は、セカンドライフでジャンプ台のオブジェクトを作ります。

baned001
上から乗るとぼよーんとするジャンプ台です。

解説の要点

・ジャンプ台のバネの部分を、Metasequoia でモデリングしよう
・ジャンプ台の上から押したときにだけ、ぼよーんとするスクリプトを書こう


ジャンプ台のバネの部分を、モデリングしよう

Metasequoia を作ってモデリングしていきます。

bane001bane002
ドーナッツ型の基本図形からバネを作成していきます。
細かいほうが綺麗に作れますが、単純化のために8角形でいきます。

bane003
bane004
8角形のうち、7つの角を選択して、上に 10 上げます。
複数の選択は、Shiftを押しながら選択でするとできます。

bane005
bane006
先ほど選択した 7つの角のうち、端っこの選択を解除して、上に 10 上げます。
解除は、Ctrlを押しながら選択すると解除できます。
端から 1 つずつ選択を解除しては 10 上げる作業を繰り返していきます。

bane007
これで、すこしラセンっぽくなりました。
この形をたくさんつなげれば、バネができそうです。

bane008
2回転にするために、上にコピーしましょう。

bane009
段差が変な部分の面を削除して、

bane010
上下のラセンのオブジェクトの断面を、面を繋げていきます。

bane011
これでバネが完成しました。

bane012bane013
あとは、木のような台を上下にくっつけて、ジャンプ台のモデルは完成です。
物理判定用のオブジェクトは適当に立方体で作成しておきます。
なお、この時点で、セカンドライフ上の軸と合うように回転させておきましょう。
右が赤のX座標。前が緑のY座標。上が青のZ座標です。
(→詳しくは、 軸についての記事

bane014
これをアップロードします。
アップロード直後は、
プレビューのように予め初期値で回転されているので、回転をもどして…

bane015
できました。


ジャンプ台のスクリプトを書こう

ジャンプ台のスクリプトを書いていきます。。

衝突時の判定は「collision_start」を使用するとよさそうです。
衝突したアバターを、指定した方向へ「llPushObject」で飛ばせばいいのです。
(※土地の設定を、プッシュ許可にしておくこと)

上記の関数を使って「衝突したアバターを、上へ飛ばす」プログラムを書いていくのですが、
単純に実装しようとすると、いくつか問題があることに気がつきます。

baned002
左右からジャンプ台にぶつかった場合でも上へ飛んでしまうのでは?

baned003
ジャンプ台が傾いていた場合に、上から踏んだ場合はどのようにすれば?

……などなど。

解決策

上記のあらゆる問題を解決するために、ジャンプ台で飛ばす方向に対して、
衝突したアバターの「めり込み具合」を調べて、正しく判断させようと思います。

今回は、ベクトルの計算が必要です。
ベクトルというのは、(x, y, z)など、たくさんの値をもつデータのようなものです。
なお、通常の1つしか値ない場合は、スカラーと呼びます。

今回は2種類のベクトルを使用します。

baned004
1つ目に、法線ベクトルがあります。
法線ベクトルは、物体の表面から垂直に伸びたベクトルです。

今回は、バネの向いている方向を、法線ベクトルとして考えたいと思います。
このベクトルは N と呼び、長さ(ノルム)を1とし、単位ベクトルとします。

なお、長さを1にすることで、純粋に方向のみを表すことができます。
よく使用するテクニックなので覚えておくといいかもしれません。
具体的には、「ベクトル」÷「ベクトルの長さ」の計算をすると、長さを1にできます。

baned005
次に、速度ベクトルVです。
衝突したオブジェクトがどの方向へどの速度で向かっているかとなります。
方向はオブジェクトが向かっている方向、長さは速度に相当します。

baned006
衝突したある点からの法線ベクトル N と、衝突時の速度ベクトル V があったときに、
このめり込み具合 d の長さを計算します。

実は、簡単に計算ができる方法あります。

baned007

こんな式です。

こんな計算で、dが求められるのと思うかもしれませんが、求められます。
ベクトル同士を「・」すると、内積となり、
細かいことはおいておいて、dが求まります。

baned008

Nが単位ベクトル(長さ=1)となっているところがポイントです。
すこし難しいですが、ベクトルVを、単位ベクトルであるNに射影したベクトルのノルムが内積となります。

さて、スクリプトは次のようになります。

integer i;

list		get_details			= [ PRIM_SIZE, PRIM_POSITION, PRIM_ROTATION ];
vector		object_size			= <0, 0, 0>;
vector		object_position		= <0, 0, 0>;
rotation	object_rotation		= <0, 0, 0, 1>;
vector		target_velocity		= <0, 0, 0>;
vector		object_normal		= <0, 0, 0>;
vector		object_normal_inv	= <0, 0, 0>;
vector		refrect_vector		= <0, 0, 0>;

// 設定値
float		power					= 3.0;	// 少しの力でもある程度飛ばす
float		rebound					= 2.0;	// 何倍の力で戻すか
float		threshold				= 0.5;	// この閾値より低いと吹き飛ばさない

getData() {
	list list_details = llGetPrimitiveParams(get_details);
	object_size		= llList2Vector(list_details, 0);
	object_position	= llList2Vector(list_details, 1);
	object_rotation	= llList2Rot(list_details, 2);
	object_normal		= <0, 0, 1> * object_rotation; // バネの上の向きベクトル
	object_normal_inv	= <0, 0, -1> * object_rotation; // バネの下の向きベクトル
}

onStartCollision(integer num_detected) {
	// 使用するオブジェクトのデータの取得
	getData();
	
	// めり込み度を計算(内積)
	float merikomi		= target_velocity * object_normal_inv;
	
	// あまり押されていなかったら、処理しない
	if(merikomi < threshold) {
		return;
	}
	
	// 跳ね返すベクトル
	refrect_vector	= (object_normal * (llFabs(merikomi) + power) ) * rebound;
	
	// プッシュ!
	for(i = 0; i < num_detected; i++) {
		llPushObject(llDetectedKey(i), refrect_vector, <0, 0, 0>, FALSE);
	}
	
	// オブジェクトが一瞬縮んで、押された感じにする
	vector object_position_new	= object_position + object_normal_inv * (object_size.z * 0.5);
	vector object_scale_new		= <object_size.x, object_size.y, object_size.z * 0.5>;
	llSetScale(object_scale_new);
	llSetPos(object_position_new);
	llSleep(0.1);
	llSetPos(object_position);
	llSetScale(object_size);
}

default {
	collision_start(integer num_detected ) {
		// 即速度を取得しないと、止まった時の速度を取得してしまう
		target_velocity = llDetectedVel(0);
		// 後はこの中で処理
		onStartCollision(num_detected);
	}
}

以上、「ジャンプ台を作る」の解説を終えます!
お疲れ様でした!

広告

メタセコイア作品集1

投稿日: 更新日:


買いましたといっても、先月買ったのですが、とても楽しいです。
値段も5400円とお得です。

無料の3Dモデリングソフトもあるのですが、
メタセコイアはユーザーインタフェースが分かりやすくてとっつきやすいです。
やっぱりインターフェースのデザインは大事です。
どんなに優れていても使いにくかったら意味がないのです。

2か月もあっというまにたちいろいろ作ったので、
作った物を紹介します!やったね!

ファンシースター ( fancy star )
cg_star_640
1作目です。
星のかたちを作るなんてすごいと一見思えますが、
「★」の文字を立体化をしてから、あとは角をまるめるだけです。
まるめるのも専用のコマンドがあるので、あとは整えたりします。
やわらかい質感を出そうとテクスチャは手描きでがんばりました。
頂点数92、面数192、三角形192

バケツ ( bucket )
baketsu_640
2作目です。(→専用の記事へ)
コップとかそういう系のもの練習で作りました。
円柱を作った後に、「押出」を駆使して拡大と移動でこねくりまわしました。
「4ビュー」という表示を初めて知ったのですが便利ですね。
一番大変だったのは、金具のと円柱とをつなげる穴です。
穴を空けるのは初めてだったんですが、あんなに難しいとは思いませんでした。
inkscapeなら、XOR演算で消せたりできるのですが、
3Dではポリゴンが基本となるので大変なんですね。
金具はドーナッツ型を基本として作ってます。
テクスチャは、GIレンダリングができるParthenonで作成。
頂点数398、面数596、三角形596

ダウジングロッド (dowsing rods)
dowsing_640
3作目です。
もうほとんど慣れてきました。
ただ内部の金属の円柱を曲げるというところが少し大変でした。
これもまたテクスチャは、Parthenonにお世話になってます。
1つ分かったことは、最初ダウジングロッドを実寸大で作成していまして、
それで、テクスチャの自動作成したら影がうまくできなかったのです。
影の付き方は大きさも考慮されているんでしょうね。
あと、テクスチャ自動展開が一部うまくいってないところがあようなのですが、
このときはテクスチャのUV座標の再設定を知らなかったので、もうこれで完成としました。
頂点数172、面数344、三角形344

もごし ( mogoshi )
mogoshi_640
4作目
もごし
スカイフィッシュを捕まえるための道具です。
金属のばね部分が難しかったです。
ドーナッツを形状から、1らせんを作ります。
1らせんから2らせんを作り、2らせんから4らせんを作り、ばねを作っていきます。
一度作ってしまうと、ばねの太さとか、簡単に変えられないのが大変です。今回少し細かったと思っています。
完成した後にわかったのですが、らせんを伸ばした後に頂点の結合を忘れたため、ポリゴン数が増えてしまいました。
頂点の結合は大事です。勉強になりました。
頂点数424、面数836、三角形836

かがみもち ( Kagami mochi )
kagamimochi_640
5作目
正月用に作りました。
球がおおいのでモデリングは楽です。
本当は下に台も作っていたんですが、作った後にあれ?台ってみんな丸い穴あいてる……。
穴あけ…やばい!となり、台を作る気力もなくこんな感じになりました。
みかんの葉っぱは葉脈があるのでinkscapeでテクスチャを作成。
あとは、持ちの下においてある紙は、1枚の紙に赤と白の部分をテクスチャで作ってしまうと、
拡大時にぼけてしまうので、普通に赤と白それぞれ2枚の紙を設置してます。
頂点数656、面数1264、三角形1264

岩風呂 ( magma bath )
iwaburo
6作目
お風呂です。
地底から暖かいお湯をお届けします。
普通の立方体をへこませて器型を作り、カットで頂点数を増やします。
あとは、手動でディスプレイスメントしていくといきました。
大げさにやらないと、岩のようなゴツゴツ感がでないので何度も調整しました。
溶岩については、パーリンノイズに色付けして作成していきます。
今回のレンダリングにはセカンドライフビューアを使用しています。
蛇口には環境マッピング設定を、溶岩にはグローと点光源を使用しています。
頂点数306、面数493、三角形493、四角形89(本体)
頂点数68、面数57、三角形0、四角形42、多角形15 (あふれた溶岩)

以上、紹介終わります!

1年前は3DCGなんか全く作れなかったのですが、
今は人や動物、柔らかい形状のものいがいなら、大体作れそうな感じです。
好きな物(SL)のためという目的があったんで、どんどん作っていけた感じがあります!


最後はメタセコイア関係の本の宣伝コーナー

(2014年発売) (2005年発売)

2005年のメタセコイアは、今の2014年のメタセコイアと使い勝手が
大分違うので、ツールの使い方から知りたいという方は新しいほうがいいかもしれません。

セカンドライフでモデリング2(メタセコイア編)

投稿日: 更新日:


セカンドライフでモデリング(メタセコイア編)」の続きです。
今回は、モデリングしたプリムで、
セカンドライフ上で後で色が変更できるプリム作りに挑戦したいと思います!

ほら、よく買った服とかで、ここの部分だけの色を変えれるとかありますよね。あれです!
模様はそのままついているのに、色だけ変えられるとか不思議ですよね。

前回の6つの面をそれぞれ別の色で設定するとどうなるかで、
ちょっとできそうだったので報告となるわけです!

では、まずはメタセコイアでモデリングしていきましょう。
sl1
これは、私が作った2作目のバケツです!
金具部分の穴あけが大変でした!

さて、オブジェクト数は1つ。材質数も1つです。
素晴らしいできなので、このままアップロードしてもいいのですが、
この場合は、面選択しても、すべて選択してしまうことになります。
テクスチャもないのでやっぱり味気ないです。

sl2
全ての面を3角ポリゴンにして、自動でUV展開します。
自動でUV展開すると、ポリゴンの各頂点にUV座標が設定されます。

sl3
これにBeeさんが制作した「Parthenon」でライトマップを作成しちゃいます!

sl4
テクスチャとしてライトマップを張るとこんな感じです。
なぜライトマップを張るのかというと、
あとで面ごとに色付けの話をするのですが、
陰影情報とかはテクスチャの指定が反映されるので、
見た目がかっこよくなるからです!テテーン!

sl5
さて、ここから重要なのですが、
オブジェクト数はそのままで、材質だけ3つに分けます。
例の上の画像では「hontai」「kanagu」「motsu」に分けてます。
ここで、材質を3つに分けたのですが、全て同一のテクスチャのままです。
ただ、色だけはわかりやすいように変えております。
なお、オブジェクトを分けてもいいのですが、
この場合リンク解除で解除できてしまうプリムになってしまうので注意しましょう。

sl6
これを通常のようにアップロードしましょう。
「テクスチャを含む」にしておいたほうが楽です。
3つの材質、同じテクスチャを指定していますが、同一のテクスチャであるか判断?しているようで、
1つのテクスチャしかアップロードされないので安心です。
※メタセコイア以外のツールで出力したものは未確認です。

sl7
アップロードした物は、以前の回でお話ししたようにモデルとテクスチャが分かれて記録されます。

sl8
アップロードすると、メタセコイア上で設定した色は反映されていませんが、
材質の設定はしっかり残っています。

sl9
面を選択していろいろ設定していきましょう。
色とテクスチャの関係ですが、少し専門的になりますが、
面の色を「CrCgCb」、テクスチャの色「Tr , Tg, Tb」とした場合。
R = Cr * Tr, G = Cg * Tg, B= Cb * Tb となります。
※色は0~1までの値をとるように正規化しているとします。

もちろん色以外にも、反射とか設定できるので、
金属部分だけは反射を高いとかにもできます。
この場合は「アルファモード」は「なし」にしてください。
「アルファブレンディング」のままだと、鏡面反射の設定が反映されません。

sl10
これで1プリムで色を変えられるバケツが完成です!

よかった!よかった!

ところで、今回はテクスチャ1枚にまとめたのですが、
もちろんそれぞれの材質に別のテクスチャを割り当てても構いません。
未確認ですが、ネット上の情報から1プリムには8種類まで材質が設定できるようです。
また、「Parthenon」では材質の一番上のライトマップが作成されるため、
材質の数だけ、メタセコイアファイルを作成して、ライトマップを作る必要があります。

セカンドライフでモデリング(メタセコイア編)

投稿日: 更新日:


セカンドライフでは、ユーザーが作ったポリゴンメッシュを持ち込むことができます
メッシュというのは、3Dの形状データのことです。
メッシュの形式は、いろいろありまして、たとえばDirectXでは、「.x」のファイルをロードできます。
セカンドライフでは、COLLADA形式(.dae)のファイルをアップロードできます。

このCOLLADA形式を吐き出せるツールはそんなにないですが、
使いやすい日本人が作成した有名な3Dモデリングツールであるメタセコイアで、
COLLADA形式を出力できるので、今回はこれを使用した場合の動作情報を紹介します。

※有料版でないと出力できないので注意。


座標とスケーリング

さて、メタセコイアで出力したファイルが
セカンドライフでも読み込めるということですが、いろいろ気になる点があると思います。
その1つとして、座標空間はどうなんだという点です。

座標軸の方向や意味がソフトによって異なるものであり、
たとえば正面を向いて作ったキャラクターを他のツールにアップロードしたら、
下を向いていたということもありうることなのです。

ほかにもメタセコイアでサイズを100として作ったモデルを、
他のツールにアップすると、超巨大なモデルになってしまったり、
ノミみたいな小さいモデルになってしまうこともあります。

まずは、この重要な座標軸、大きさがどのように反映されるのかテストしたいと思います。

dimtest_1s
こんなオブジェクトをメタセコイアで作ってみました。
正六面体で、6つの面にはそれぞれ次のような色の面の設定をしています。
ちなみにメタセコイアの座標家は、DirectXのような座標系になっています。
X+は赤、X-は水色 (Xは横)
Y+は緑、Y-は紫色 (Yは高さ)
Z+は青、Z-は黄色 (Zは奥行)
また、横×高さ×奥行を200x200x200で、立方体の重心を中心点に設定しています。

dimtest_2s
それをCOLLADA形式で出力します。
出力の際にダイアログでオプションが表示されますが、
とりあえずここはデフォルトのままで行きたいと思います。

dimtest_3s
これをアップロードします。
アップロード時でもスケールを設定できますが、ここではデフォルトの1.0倍(等倍)にしています。

dimtest_4s
さて、セカンドライフの世界では次のような表示になりました。
ここに表示されている座標軸をそのままみると、
セカンドライフのX軸+(東)は、メタセコイアのX軸+(左右)
セカンドライフのX軸-(西)は、メタセコイアのX軸-(左右)
セカンドライフのY軸+(北)は、メタセコイアのZ軸-(奥行)
セカンドライフのY軸-(南)は、メタセコイアのZ軸+(奥行)
セカンドライフのZ軸+(上)は、メタセコイアのY軸+(上)
セカンドライフのZ軸-(下)は、メタセコイアのY軸-(下)
一見座標軸は違うものの、作ったときと同じような見た目です。

dimtestX_1s
でも、実は注意点がありまして、最初からX軸で90度回転しています。

dimtestX_2s
そのため、90度の回転を戻すとこんな感じです。
セカンドライフのX軸+(東)は、メタセコイアのX軸+(左右)
セカンドライフのX軸-(西)は、メタセコイアのX軸-(左右)
セカンドライフのY軸+(北)は、メタセコイアのY軸+(上)
セカンドライフのY軸-(南)は、メタセコイアのY軸-(下)
セカンドライフのZ軸+(上)は、メタセコイアのZ軸+(奥行)
セカンドライフのZ軸-(下)は、メタセコイアのZ軸-(奥行)
軸はあっていますが、少しややこしいですね。
考えるのが面倒な場合や、動き系のスクリプトを組み込まない場合であれば、
X軸の90度回転を戻さずアップロードしても問題なさそうです。

dimtest_5s
スケールは、アップロード時にも見えていましたが、
メタセコイアで 200 と設定したものを、
メタセコイアのエクスポートで 0.001倍 にしてCOLLADAファイルを出力
これをセカンドライフで、等倍でアップロードすると 0.2 = 20cm となりました。
つまり、メタセコイアの1が、セカンドライフで1mに相当します。

ということは、メタセコイアで作ったデータで 200 を 200 cm とするならば、
メタセコイアのエクスポートで 0.01 倍にして出力すると期待した大きさになるということです。

select_s
ところで、今回メタセコイアで6つの材質を色をそれぞれ設定して、アップロードしました。
この場合、セカンドライフ上では、各面に色を設定した状態になる感じになります。
つまり材質で分けておくと、面選択でその材質のものを一括で選択できるということですね。

話は変わりますが、セカンドライフの世界では
X軸の+が正面(アバターの向いている方向)
Y軸の+が左(アバターの左側)
Z軸の+が天上(アバターの上側)
のようです。
何か作るときはこの軸を参考にアップロードしましょう。


テクスチャのUV

テクスチャのUVマッピングの座標がどのように反映されるか調べます。
これもUVの座標軸が異なると、テクスチャが正しく反映されない場合があります。
従ってメタセコイアからセカンドライフへデータを持って行った際のUVがどのようになるか、
とても重要な情報なのです。

textest
まずはテスト用のテクスチャをつくります。
このテクスチャのX軸がU軸、Y軸がV軸となっています。
学校で習ったグラフのように、
画像の右がX軸+、U軸+
画像の上がY軸+、V軸+

textest_2s
これを貼った平面を作りました。

textest_3s
これをアップロードしてみると、こんな感じに。
これをみると分かるようにメタセコイア上のUV座標のうち、
上下のV軸がセカンドライフでは逆になっているようです。

ちなみにプレビュー画面で実際のアップロード(有料)はまだしてませんので、
この時点で引き返せます。引き返しましょう!

textest_4s
さて、メタセコイアのエクスポート時の話に戻るのですが、
ここで「テクスチャのV方向を反転」というのにチェックしておきましょう。
ちなみに、先ほどのスケールの話から拡大率1.00 x 10^-2 としました。

textest_5s
これで上下の反転がなくなり、
正しくテクスチャを反映できたことが分かります。

textest_6s
実際にセカンドライフ上に設置してみると、こんな感じです。


その他のアップロード時のテクニック集

point_1s
描画詳細度 Level of Detail (LOD ) という項目があります。ここかなり重要です。
3D描写の負荷を下げるために、遠いオブジェクトはポリゴン数が少ない簡易モデルを表示させます。
ここでは、その簡易モデルの登録を行う設定となっています。

簡易モデルはいちいち作るのも面倒なので、通常は自動で計算したものを利用します。
ですが、たとえば今回、単純な平面や立方体をアップロードしたのですが、
あまりに座標数が少ないためか、自動計算で三角形が1となっています。
4点の座標が必要な平面を表示させるのに、
座標数が3と計算され、三角形1つとなってしまうのです。
とくに低ポリの場合は、しっかりここの設定について目を通しておきましょう。

point_3s
アップロードの設定に「テクスチャを含む」というのがあります。
これにチェックを打つと、後でテクスチャをアップロードして、設定するという手間が省けます。
なお、ここにチェックを入れてアップロードすると、
画像をアップロードするときにかかるお金はしっかり取られます。

texture_upload_s
テクスチャを含んでアップロードした場合、ここに自動で保存されます。


メタセコイア関係の本の宣伝コーナー

(2014年発売) (2005年発売)

2005年のメタセコイアは、今の2014年のメタセコイアと使い勝手が
大分違うので、ツールの使い方から知りたいという方は新しいほうがいいかもしれません。

以上!

またまたJavaで3D

投稿日: 更新日:


以前作ったこれは、とにかく3Dの表示にチャレンジということで拡張性がありませんでした。
ということで、今回は、物体を単位として色々設定できるオブジェクト、UV座標は0~1、
当たり判定、画像レンダリングを別スレッドへ、の4つを意識して再び作成。
モーションは、まだまだ敷居が高いので諦めます。(((っ・ω・)っ
「UV座標は0~1」というのは、以前は素の値(0-256とかそのままの大きさ)を用いていたので。

とりあえずメタセコイヤで作った3Dデータのロードは完成。

あと、ライトの計算を、見直しました。
今まで、レンダリングの際に、頂点は色情報のみ送って、後は補完をしていたのです。
つまり、頂点の色情報に、拡散反射・鏡面反射を加味した色に設定しておいたのです。
ですが、この方法をとった場合、テクスチャを描写しようとすると問題が発生するのです。
というわけで、色情報3種類以外に、拡散反射3種類、鏡面反射1種類を頂点の情報に持たせて、描写。
という感じに。

とりあえず、メタセコイアで立方体(

頂点数98、三角ポリゴン数192)を作って。

(無駄な頂点は、ライトの計算を増やすため。)

表示させたのがこんな感じ。↓ ライトは「環境光 + 平行光源 + 点ライトx2」の4つ。

テクスチャON。


テクスチャの線形補完は、以前作ったのがあったのですが、速度の関係で切ることに。

半透明とアルファチャンネル付きテクスチャも対応してみたのですが……つなぎ目が見えてしまう。

3Dのベースエンジンの目標として、あとビルボードとポイントスプライト(パーティクル)に対応させたい。

テクスチャのミップマップ、パースペクティブ補正は、対応しない予定。
パースペクティブ補正は上の方から眺める感じなら気にならないし。うん。
(バイリニアフィルタも、テクスチャを大きくすれば気にならない。)
ミップマップは、ほしいけどうん。まあ、最後の最後です。