早いですね、、、1年って。で、最近はまってるのがニコニコ動画の「魔王エンジェル」の動画。
もともとアイマスっていうか、ニコマスの魔王エンジェル系の P さま系はすごすぎて、でも、カメラワークとかむっちゃ参考になるんですよね。
早いですね、、、1年って。で、最近はまってるのがニコニコ動画の「魔王エンジェル」の動画。
もともとアイマスっていうか、ニコマスの魔王エンジェル系の P さま系はすごすぎて、でも、カメラワークとかむっちゃ参考になるんですよね。
前回からの続き、、、ではなくて、ちょっと閑話休題。といっても、今回の一連のお話しの中で、私が勝手に造語的に使っている「移動量」って何?の補足みたいなお話しです。
[LSL] 位置と回転について ~移動量という考え方~ のエントリーで、球体で考える空間と位置指定の概念を説明するのに、地球の話を持ってきて「移動量」の話をしていますが、この移動量っていうのが、やっぱりよくわかんない、、、と感じる方も多いと思います。
移動量(正直、これ私が勝手にそう呼んでいるので、一般的な用語ではないことをご了承ください。)はクォータニオンそのものなんですが、イメージとしては地球上のある地点から他の地点までの最短距離(大圏航路)で、ぐるっ!と地球をまわして、一度の回転でA地点からB地点にいって、回転させる軸の傾きも含めたもの、、、としつこく書いています。
ふ~ん、そうなんだ、と思ってくれるといいのですが、「ん~、わかんない」となると、実は先に進めないのも事実。それが2年前の私の状態ですから(笑
イメージ、イメージっていってもしょうがないので、もうちょっと具体的に説明してみたいと思います。ただし、なぜこれまで具体的に説明していないか、、、といえば、最終的には必要になる場合もありますが、最初のほうでは具体的に理解する必要があまりない(というか邪魔な?)知識だと思ったためです。あ、もちろん、ここでも行列計算、虚数といった数学的な話にはなりません。
前のエントリーでも「羽田空港とJFK空港を結ぶ大圏航路でグルッと回す」、それが移動量って言い方をしていますが、一気に回すための傾いた軸って存在しますよね。
クォータニオンからは、まず、その軸の方向を導き出すことができます。その関数が llRot2Axis なんです。そして軸を使ってまわした角度が llRot2Angle なんです。
この軸の傾き(方向)と回る角度が移動量つまりクォータニオンを構成する要素なんですよね。
実際、Axis のベクターと、Angle の float からクォータニオンを計算する関数が llAxisAngle2Rot になるわけです。これでクォータニオン(移動量)を算出できるのです。
ネットや書籍でクォータニオンを調べると、そもそも LSL で使われる関数などでは説明されませんから、四元数で、実数部分と虚数部分にわかれ、、、、と説明されます。クォータニオンはローテーション型で <x, y, z ,s> の四元数にて LSL でも表現されますが、現実にその x, y, z, s の要素を直接いぢることは、最初の頃はほぼ皆無です。ちなみに2年前に私は ウィキペディアの四元数や、クォータニオンの説明を見てしまい、頭痛&挫折しそうになりましたし、wiki.secondlife.com での llRot2Axis や llRot2Angle の説明では、それらの関数と同じ動きをする llAcos や llFabs, llSqrt, llVecNorm で四元数の要素をいじるユーザー関数を紹介しています。ですが、その特記事項を見ても何を言っているのかわからなかったわけです。
実際はウィキペディアにある内容をもとにクォータニオンは計算され、四元数の各要素となって表現されるのですが、それを理解するためには数学の勉強は必須で、ちょっと敷居が高かったのです。(私にとっては、、、ですが)
このクォータニオンと軸の傾きと回転量の関係がわかっていれば、他のところでも応用可能なような気がしませんか?
回す軸の方向はわかっていて、何度まわしたい、、、ってあるでしょう?おおよそローカル軸が「回す軸の方向」なので、あまり Axis と Angle の関係を理解せずにz軸で回すなら <0.0, 0.0, PI/2> とかにして、llEuler2Rot を使ってクォータニオン(移動量)にして、現在の Rotation に左からかけたりする、、、。でも、ローカルの軸、もしくはグローバルの軸じゃなくても、llAxisAngle2Rot で任意の軸で回すことができる、、、と考えると、ちょっとどこかで使えそうな気がしません?
クォータニオンについては、最初の回で紹介したように、また、何度もしつこくいっているように「球体で考える空間と位置指定」の概念をきちんと持つことで、行列計算や三角関数を深く知らなくても、LSL の関数だけでほとんどの操作は克服できると思っています。その上のステップに行くときに、そこで必要な知識を吸収すればいいわけですよね。
さて、次はオブジェクトに座っているアバタ―を動かす(それも複数のアバタ―)です。
前回ではリージョン座標軸で表現される位置をクォータニオンと球体の中心からの距離で置き換える方法をご紹介しました。空間の概念は X, Y, Z 軸による立方体だけでなく、球体での移動量と球体の中心からの距離で表現できる「球体で考える空間と位置指定」の概念の重要性がご理解いただけたかな、と思います。
ここまででオイラー角による回転について1度も触れていないのは面白いですよね。移動量という言葉を使って「角度」という言葉を使っていないわけです。
プリムをまわす、回転させるときに一番最初に覚えるのは軸を中心とした回転ですよね。わたしもそうでした。Z軸で90度回転させる、なんてことをやるわけで、そのときラジアンによる角度表現が必要である、とか、llEuler2Rot という関数を知ったり、右ねじの法則、グローバル軸を基にした回転と、ローカル軸を基にした回転の違い、その方法を学ぶわけです。
もちろんオイラー角によるプリムの回転で事足りことも多いのですが、スクリプトでいろいろな操作をやろうとすると、はじめから角度がわかっていることって、、、少ないと思います。llGetPos や llGetRot、llGetObjectDetails, llGetLinkPrimitiveParams などで取れる数値は位置を表すベクター型であり、移動量をあらわすローテーション型のクォータニオンです。なので、位置ベクトルとクォータニオンを駆使して操作することになり、あらかじめ各軸の角度がわかっていれば使えるオイラー角による回転指定は、、、、実は、かぎられるような気がします。
前置きが長くなりましたが、今回は llSetLinkPrimitiveParams などで必須となるルートプリムと子プリムの関係、とくに位置(ローカルポジション)と向き/回転(ローカルローテーション)について考えてみたいと思います。
4. ルートプリムと子プリムたち
複数のプリムをリンクさせるとき、スクリプトを組み込む必要がなければ、あまりルートプリムがどれかを意識しないかもしれませんが、スクリプトをいれてなんらかの操作をしようとすると、ルートプリムがどれか、子プリムでもリンク番号は何番かが非常に重要になります。
基本的なリンク、リンクのさせかたについては wiki の記事や先輩諸氏のブログなどを参照してもらって、ルートプリムに入っているスクリプトから子プリムたちをどのように扱うかを見てみます。
ポイント1 リンクされた子プリムは「ルートだけ」とつながっている
ちょっといきなりハードルが高いかもしれませんが、プリムをリンクさせたとき、子プリムはルートプリムに対してリンクされている、ということを忘れるときがあります。1対1なら直感的ですが、子プリムの数が多くなり、造形的に階層構造のようなオブジェクトになったとき、見た目で土台になっているプリムを動かすと、それに「見た目」でのっているプリムが動きそうな気になるんですよね。
上の絵の緑色のルートプリムを動かせば、リンクされている子プリムたちはすべて追随するのですが、青いプリムを動かしても、見た目その上にある赤や黄色のプリムは動かない、、ということです。上のような単純なオブジェクトだと「当たり前じゃん」と思うでしょうが、造詣をしていって、見た目が子プリム同士関連しているように見えれば見えるほど、ルートだけにしかリンクしていないことを忘れます(笑
それが顕著にでるのが、プリムに座ったアバターを動かすときです。
どうしても座っているプリムを動かせば、座っている(=リンクしている)アバターも動くような気がしてしまいますが、アバターはルートにリンクしているであって、見た目座っているプリムとはリンクしていないのです。
ポイント2 子プリムの位置・回転はルートプリムが「基準」です
ですよね~、と思われるかもしれませんが、わたしも最初にはまった落とし穴は、ルートプリムのローカル座標軸(前後、左右、上下)がグローバル座標軸(東西、南北、天地)と重なっているのがおおよそ Rez した直後の初期値なので、グローバル座標軸を基準とした回転や位置指定を子プリムに対して行い、最初うまく動いている!と誤解してしまうことです。
うまく動いている状態だったのに、オブジェクトの向きを変えたら、予想もしない方向、位置に子プリムが動いた、、、となり、それが予想もつかない動きをするので悩んでしまう、、というものです。
ポイント3 ルートを基準とした位置の算出方法は球体で考える
正直、、、わたしは相当苦労しました。。。前に「位置と回転」について書いたブログが 2008 年のもの、、、当時はクォータニオンを理解しようとして行列計算や、関連しそうなネットの情報、書籍を読んでみて、興味深い内容が多かったものの、それぞれを理解したとはいえませんでした。
最近は wiki.secondlife.com のコンテンツも有志の方による日本語訳が充実してきているので、そこからある程度「こんなものかな」で理解してしまうほうがいいかもしれません。
ルートと子プリムの関係は、これまでご説明してきた「球体で考える空間と位置指定」の概念がわかっていれば比較的簡単に必要な数値の算出が可能になります。(なると思っています、、、)
まず、ルートから見た子プリムの相対位置です。
llGetLinkPrimitiveParams もしくは llGetObjectDetails で子プリムのグローバル座標を取得することができます。ルートプリムのグローバル座標もこの関数以外に llGetPos や llGetRootPosition で取得できるので、ルート、子プリムそれぞれのグローバル座標をもとに、ルートプリムからルートのローカル座標(前後、左右、上下)による子プリムまでの「軸上の移動距離」を算出することになります。ただし、この算出の場合も「球体で考える空間と位置指定」を使うことになります。
え?子プリムのグローバル座標からルートプリムのグローバル座標を引けばいいんじゃない?と思いたくなるのですが、その差分はグローバル座標軸における差(東西、南北、天地)であって、ルートプリムからのローカル座標軸(ルートプリムからの前後、左右、上下)での差分ではないのです。グローバル軸とローカル軸が重なっていれば問題ないですが、ずれた(ルートが回転した)瞬間から予期しない動きをしてしまいます。
ルートプリムから見た子プリムのローカル座標上の移動距離を算出する考え方と手順が以下になります。
a) 球体で考える空間と位置指定の概念を使ってルートプリムを球体の中心にもってくるイメージをしてみます
そのときのルートプリムの向きは llGetRot でとったそのままの傾きで、子プリムと一緒に動いてくるイメージです。球体の中心にきた時は、ルートプリムのローカル座標軸とグローバル座標軸はずれている感じです。そしてそのずれは移動量であり、ルートプリムのローテーションになります。
//ルートプリムのクォータニオン
rotation rootRot = llGetRot(); または llGetRootRotation();
b) 中心(ルート)から子プリムまでの直線距離とグローバル座標軸上の移動距離を算出します
グローバル座標軸における2つの位置ベクトル間の距離です。
vector rootPos = llGetPos(); または llGetRootPosition();
integer linkNum = 2; //ルートは1、それ以降は2~
list pList = llGetLinkPrimitiveParams(linkNum,[PRIM_POSITION]);
vector childPos = llList2Vector(pList,0);
float dist = llVecDist(rootPos, childPos);
グローバル座標上の子プリムの位置とルートプリムの位置の差分。つまり、ルートプリムが中心のときにグローバル座標上の子プリムの位置ベクトルになります。
vector childVec = childPos-rootPos;
c) ルートプリムをぐるりと回転させて、ルートプリムのローカル座標軸とグローバル座標軸を一致させるイメージを持ってみます
この時の移動量は a) の rootRot だけ「戻る」感じですよね。
ただし、このとき「移動」するのは実は子プリムなんです。ルートプリムは中心にいるので一切「移動」しないわけです。
なので、動かす前の子プリムの移動量を算出します。これは子プリムの向きを表すローテーションではありません。球体で考える空間の話を思い出してください。球体の中心(=ルートプリム)とX軸基準 <1.0, 0.0, 0.0> と自分のグローバル座標上の位置ベクトルから算出する移動量です。自分の位置ベクトルはグローバル座標上の XYZ であり、ルートプリムは球体の中心にきていますから、b) で算出した childVec になります。
rotation childRot = llRotBetween(<1.0,0.0,0.0>,childVec);
そして、ルートのローカル軸をグローバル軸にあわせるために、子プリムの移動量からルートの傾き分の移動量を引きます。(ルートプリムがぐるりとまわって元に戻る感じです。)ローテーションでの計算では除算します。ここがルートと子プリムの関係の最大のポイントです。
rotation q = childRot/rootRot;
これで移動量 q は、ルートのローカル軸、グローバル軸が重なった時点での球体上の子プリムの移動量となります。
d) ローカル座標の位置ベクトルを算出します
ローカル座標とグローバル座標は一致しているので、<1.0, 0.0, 0.0> と llRot2Fwd と使ったこれまでと同じ方法で算出します。
vector offset = llRot2Fwd(q)*dist;
この offset ベクターがルートプリムからの相対位置になります。
どうです?三角関数とか意識しなくても出せるような気がしませんか?
重要なのはイメージなんですよね。
と、、、ちょっと長くなったので、ルートプリムから見た子プリムの向きについては次回にします。
前回では移動量(クォータニオン)と高さを使えば空間のあらゆる位置を表現できる、という方法を説明してみました。ただし、その場合でもある地点を「基準」として考えたら、、、という前提があったことを思い出してください。
この基準、、、というのが難しいのです。
3. 基準はどこにあるの?
地球上の位置を考えたとき、よく例にでるのがイギリスにあるグリニッジ天文台の子午線ですが、前回ではそれに赤道も加え、経度0度の子午線と緯度0度の赤道の交点がギニア湾上にある、ということを紹介しました。その位置は「緯度0度、経度0度」の位置です。
そして、その位置は地球の中心から見て「地球の半径」の高さ(あえていえば、海抜 0 m もしくは標高 0 m)を加えることで「ピンポイント」で地球の表面上の位置の特定が可能になります。
そして以下の絵でご説明したように、回転であらわした「移動量」が同じでも、地球の半径に相当する R の距離(もしくは高さ)を変えることで違う位置をさすことが可能だということも理解できたと思います。
Secondlife のインワールドで移動量と半径Rで空間内のすべての位置を表現するには、考えなくてはならない「基準」が球体の中心 <0.0,0.0,0.0> だけではないのがミソなんです。
地球でいう緯度0度、経度0度、標高 0m の地点はどこにあるのでしょうか。
これ、、、実は明確には無いのです。(今のわたしの理解では^^;)
複数の SIM からなる SecondLife なので、他の SIM をぜーんぶひっくるめて「地球」のような感覚になりがちですが、位置の特定にかぎっていえば 1 つの SIM がすべてです。この1つの SIM で、球体の中心を <0.0, 0.0, 0.0> におき、さらに、LSL で扱いやすくするために、地球上のギニア湾上にある緯度0度、経度0度、標高0m(地球の半径)のような「基準」をグローバル座標で以下の地点だと「仮定」します。
<1.0, 0.0, 0.0>
上の絵で、<0.0, 0.0, 0.0> の球体の中心点からグローバル座標の X 軸上で 1m いった地点。これを緯度0度、経度0度、標高0m と同じように扱ってみるのです。ここが絵でいうピンクの線の基準。
ええ、、、でも、たとえば自分が <100.0, 82.0, 36.0> のグローバル座標の位置にいて、それで <1.0, 0.0, 0.0> の基準点(もしくは基準ベクトル)をつかって何がわかるの?となりますよね。ただ、もう一度思い出してください。同心円(もしくは同じ球面)にいなくても、移動量(クォータニオン)は 上の図でいえば A1, A2, A3 は同じ、B1, B2, B3 も同じ、、、ということを。そうすると、半径 1.0 m の球面上で、上の絵の中の線で言えば赤い直線、青い直線上の地点への移動量がわかれば、あとはどれだけ中心から離れているかの組み合わせで、<100.0, 82.0, 36.0> の地点を示すのと同じことができるのです。
そのための便利な関数が llRotBetween() なのです。
wiki の説明では llRotBetween の引数には単位ベクトル的な数値(x や y や z が 1.0) しか入れていませんが、この関数が本領発揮してくれるのは単位ベクトル以外のベクトルをいれても、2つの位置間の「移動量」を計算してくれるのです。
上の絵でいうと、A2 と B3 の間の移動量を出してくれる、ということです。同心円上の A2 と B2 の移動量も、同心円上にない A2 と B3 の移動量は同じことはもう理解できますよね。違うのは中心からの距離、半径 R なのです。
なので、グローバル座標上の <100.0, 82.0, 36.0> を移動量(クォータニオン)と <0.0,0.0,0.0> からの距離で表すと
移動量(クォータニオン)r は、
rotation r = llRotBetween(<1.0, 0.0, 0.0>,<100.0,82.0,36.0>);
<0.0, 0.0, 0.0>から<100.0, 82.0, 36.0>までの距離は
float d = llVecMag(<100.0, 82.0, 36.0>);
または
float d = llVecDist(<0.0,0.0,0.0>,<100.0,82.0,36.0>);
となります。この r と d でグローバル座標上の位置の計算は以下で可能です。
vector v = llRot2Fwd(r)*d; //注1) なぜ llRot2Fwd か理解できない人は最後の(注1)を参照してみてください。
これで、v の値は自分の位置の <100.0, 82.0, 36.0> になるのです。
この基準の考え方を応用すると、リンクされた子プリムのルートプリムからの相対位置を計算することができます。ルートに対する相対とは「ルートから見て(ルートを中心として)」どのくらい差分があるか、ということで、特に llSetLinkPrimitiveParams() で子プリムの位置や傾きを設定する PRIM_POSITION や PRIM_ROTATION で使用できます。子プリムがルートからみてどの位置にあるか、どんな傾きになっているかを算出してはじめて llSetLinkPrimitiveParams が使えるようになるわけです。そのときルートプリムは自分が傾いているなんて考えていません。また自分がグローバル座標のどの位置にいても、「自分からみてどのくらいの距離にいるか、自分から見て前後・左右・上下のどのくらいの位置にいるか」が重要となります。
次はここまでの知識を元にルートプリムと子プリムの関係について考えてみたいと思います。
(注1)llRot2Fwd を使ったのは、基準となる位置(ベクトル)を <1.0, 0.0, 0.0> と仮定したためです。X 軸は東西であると同時に前後になります。<0.0, 0.0, 0.0> から前に1歩進んだ状態で、移動量によってくるりと回転した状態からさらにベクトルを伸ばそうとするので前に進む、なので llRot2Fwd を使います。
もし基準となる位置(ベクトル)を <0.0,1.0,0.0> としたら、<0.0,0.0,0.0>から左に一歩分横に移動したようなものです。この状態で移動量分くるりとまわし、ベクトルを伸ばそうとすると、今度は llRot2Fwd ではなく llRot2Left を使って左に進むことでベクトル算出をすることになります。
前回、位置を表すには2つの方法があって、そのうちのひとつに地球を例にとって球体における位置の指定についてご紹介しました。
今回はその球体における位置指定について具体的に見ていきたいと思います。
2. 移動量という考え方
前回では成田空港と JFK 空港の位置は「緯度」と「経度」で指定できることをご紹介しました。緯度、経度が何か、、、はここでは詳しく説明しませんが、数値データで表現されるこの緯度、経度、、、それぞれの数値が 0 のところってどこでしょう?そしてそれはどんな意味を持つのか考えてみます。
緯度0度(つまり赤道上)で、経度0度(つまり、イギリスのグリニッジ天文台を通過する子午線)が交わる地球上の位置は残念ながら海上です。アフリカのガーナの下、ギニア湾上にありました。(上の Google Map の 青いマーカーです)
この緯度・経度が 0 の地点から「ある移動量で動いた地点」をクォータニオンで表すことができるのです。クォータニオンはプリム/オブジェクトの「回転」で出てくる重要な要素ですが、前回ご紹介した大圏航路をつかってある地点、たとえば成田空港まで(球面上で)緯度0度、経度0度の地点から線を引く時、地球を「ぐるっ」と斜めになっている軸で回すと、それも1回の回転だけで青のマーカーを成田空港のある位置まで「移動させる」ことが想像できると思います。(今は軸が何度傾いて、、、とかは考えないようにします。地球を回すと成田空港も逃げちゃうよ、、という突っ込みはなしで^^; 気になる人は成田空港があった位置まで、、、とでも置き換えてください。)
緯度0度、経度0度から成田空港へは地球の裏側にいくので、成田とJFKで大圏航路を。。。。
この斜めの軸でぐるっと回し移動させる傾きも含めた「量」を移動量として理解します。そして、その移動量は回転なのでクォータニオンで表現できる、、、と覚えます。
そうすると、緯度0度、経度0度を基準点とした成田空港地点への移動量(クォータニオン)は、成田空港の位置そのものをあらわしていると言えます。
なんとなく、基準点さえ決まっていれば移動量を用いて場所の特定ができそうかな、、、と思ってもらえればいいのですが。
ただ、ここで疑問が湧きます。Seondlife のインワールドではグローバル座標による位置の指定は直観的で、<24.0, 120.0, 30.0> であれば <0.0, 0.0, 0.0> から X 軸のプラス方向に 24 m 進んで、Y 軸のプラス方向に 120m 進んで、Z 軸のプラス方向に 30m 上がれば、そこが指定されている位置だということはわかります。クォータニオンを使った場合、球体の中心は、、、えっと、SIM が 256m X 256m X 256m の立方体だから、その中心は 128m x 128m x 128m、、、あ、でも高さはもっと何千メートルもあるから、、、あれ、中心ってどこだろう????と思います。私も最初のころは、これでつまづいていたんです。
クォータニオンを使った位置指定の重要なポイントは、上の疑問にあるように「球体の中心」をどこにもってくるか、、、なのですが、グローバル座標(リージョン座標)で考えるときは、そのものズバリ <0.0, 0.0, 0.0> を球の中心として考えるのです。
ん~、それですべての位置の表現ができるの?と思いますよね。クォータニオンによる位置の指定は直観的ではないので、もうすこし我慢してお付き合いください。
いきなり3次元だとつらいので、ちょっと高さは考えないで平面で移動量(クォータニオン)と位置についての関係を見てみたのが以下の絵です。
いわゆる同心円のお話しですが、ピンクの線を基準として青い線分だけ回ったとします。青い線の回転量は R1 の円上でも、R2 の円上でも、R3 の円上でも同じですよね。ただし、R に相当する半径の長さが違うので、A1, A2, A3 は違う位置をさしている、、、ということです。赤い線上の B1 ~ B3 についても同じことが言えます。回した角度(移動量)は同じでも、半径が違えば指し示す位置が違う、ということで、地球上の高さ/標高が違う同じ緯度・経度の位置の指定方法をイメージするとわかりやすいと思います。
移動量、つまりクォータニオンと、上述の半径 R、地球上でいえば標高の組み合わせで、空間上のすべての位置を指し示すことができる、ということになります。
グローバル座標では <0.0,0.0,0.0> を球体の中心として考えてもよさそう、、、と思いますが、上の例でのピンクの線の「基準」はいったいどれか、、、、基準とした中心が <0.0,0.0,0.0> 以外の場合は、、、など、もう少しこのあいまいそうな「基準」について考えることで、グローバル(絶対)位置とローカル(相対)位置の理解が深まるはずです。
次回は「基準」について考えてみます。
2010年9月11日~12日に行われた Electrogram2010 Sive。会場のクロス SIM ダンスパネルと、VectorChaos スクリプトスタッフ兼ビデオスタッフとして参加させていただきました。
そのときの模様の SS からお気に入りをご紹介。
そして、サプライズ イベント
RMO の matsuken さんの祝福の歌が感動的でした。
って、、、パソコン変えたらなんか SS 綺麗にとれるようになったかも?
そのほかの SS は私の flickr photostream で見ることができます。
みんな、お疲れ様~。
でも、わたしの Electrogram2010 はまだ終わっていないのでありました・・・
Vector Chaos の SS が少ないのはビデオを撮っていたから・・・で、素材だけで、当日分7GB、リハ含めると 24GB もあるよ~。(笑
もうちょっと待ってね~。
[追記] VectorChaos with P-Size “Don’t Stop Your Dance” あがりました~。
たまたま前に Filckr に投稿したフォトが BareRose のスタッフさんの目にとまり、B@R のフリッカーグループに招待されていたのですが、今回、BareRose の5周年記念フォトコンテストへの参加のお招きをいただき以下のフォトを投稿したら、、、3位もらっちゃいました。
コスチュームは左からいずれも BareRose の DoctressQ, NIGHT MISTRESS そして BLACK BRIZARD になります。お友達作成のお墓セットがあったので、それでスカイを作っての撮影で、画像は Windlight の設定のみで霧の雰囲気をだして、フレームのレイヤーを上からかぶせただけ、、というもので、、、正直他の方の作品に比べると恥ずかしいくらいだったんです。
最初はレタッチして HDR っぽい、色を鮮やかにしたフォトだったのですが、お墓の雰囲気ならもっと暗めにして、霧みたいな感じがいいんじゃない?というアドバイスをお友達からもらってその通りにしたのが幸いだったようです。HDR のような鮮やかできれいなフォトのエントリーが多かった分、逆に目立ったのかな?
1st Prize をゲットした作品はこちらです。Ocean Blackthrone さんの作品です。
2nd は Jill Black さん。
[追記] Jill Black さん、Flickr から退会されたようで写真がなくなりました。
3rd は私の他にお二人いらっしゃって、Bella Slade さんと Wakapa Hermit さん。
ね、、、、ちょっと3位いただいたのが不思議ちゃん(笑
なんか人知れず 2.1.1 出てます。
ビューワーとかにもアテンションでないし、オフシャルブログにも特に書かれていないようなのですが。。。
http://wiki.secondlife.com/wiki/Release_Notes/Second_Life_Release/2.1.1
そして、なんか不安定とかいうブログの書きこも散見されていますが、、、それ見る前にダウンロード&インストールしっちゃいました。><
ですが、どうやら、私はなんとか動いているようで、、、ちょっと不安な方は様子見したほうがいいかも。。。
[追記 2010.8.21]
うーん、やっぱり調子悪いかも。最初の立ち上がりでフリーズして、ビューワー落として再度立ち上げると、、、やっとまともに? うーん。
ひさしぶりに、Linden Script ネタです。
Link に関連するファンクションが増えてますね。
たとえば、llSetLinkPrimitiveParamsFast などはプリムのリンクを多用している人にとっては待ちに待った機能ですね。メインのスクリプトから子プリムたちの操作に遅延が発生しないからです。遅延以外は llSetLinkPrimitiveParams とまったく同じです。
llSetLinkTextureAnim も最近追加された Link 系のファンクションですね。これも子プリムの面に対して Texture Animation (アニメーションGIFみたいな動く画像)を貼り付けることができるようになりました。
おもしろいのは llLinkParticleSystem です。
パーティクルってなかなかむずかしいのですが、wiki にはとても詳しくその仕様について日本語ページに書かれています。(関係者・翻訳者のみなさん、本当におつかれさま&ありがとうございます)
ポイントは、パーティクルのエミッター(発生源とでもいいましょうか)はプリム1個に対して1つしか作ることができない、ということ。パーティクルを発生させるスクリプトを複数、1つのプリムにいれても、挙動がおかしくなるのはそのせいです。
もちろん、llParticleSystem によってパーティクルを発生させるスクリプトをそれぞれのプリムにいれて、それらを Link し、llMessageLinked で各プリムにメッセージを送って操作するやり方も可能でしたが、llLinkParticleSystem を使った複数のスクリプトをルートのプリムにいれて、llMessageLinked であったり、touch_start, listen などのイベントを各スクリプトが拾うことで、一斉・同時に違うパーティクルを出すことが可能になりました。ここのプリムにスクリプトが分散されていない分、スクリプトの修正やメンテナンスが楽になっていると思います。
パーティクルの色や形を変えたものを同時に出そうとすると、この llLinkParticleSystem はとても使い勝手がよいわけです。
llLinkParticleSystem 利用の注意点としては、もし、パーティクルに画像を指定した場合は、発生源である(子)プリムにその画像が存在していないと、デフォルトのパーティクルが使われるようです。もしかすると Key 指定だと存在しなくても OK かもしれませんが、string による画像名指定だとだめでした。
あと、これら Link 系のスクリプトを使う場合は、ルートプリムはどれか、子プリムはいったいいくつ Link されているのか、といったことを常に意識しなくてはなりません。
llGetNumberOfPrims その時点で Link されているプリムの数を取得します
llGetLinkNumber 自分の Link 番号を取得します
llGetLinkKey Link 番号を指定して Key を取得します
llGetLinkPrimitiveParams Link 番号を指定してプリムの情報を取得します
llSetLinkPrimitiveParamsFast Link 番号を指定して、リンクオブジェクトの設定を変えます
llGetLinkNumber は子プリム内でしか使えませんが、ルートのメインスクリプトと子プリムのスクリプトなどを llMessageLinked で複合させて使うことで、今いくつ Link されていて、Link 番号の 2 は何で、3は、、、とチェックすることができます。
スクリプトによる Link 番号決め打ちでもいいのですが、その際は Link させる順番に細心の注意を払うことになります。特に HUD などを作るときは Link させる順番に気を付けるか、スクリプトにより Link 番号とプリムのマッチングを行わせる、といった方法がありますね。また、プリムに座ったアバターを操作するときなども上述の関数を多用します。
お友達の日記に紹介されていた印象的な vimeo のビデオです。
Breathe 2 "it's a wonderful Second Life" from samlowry on Vimeo.
これ、公式にしてもいいんじゃない?(笑
M Linden のアナウンスでは、よりソーシャルな機能をいれていく、としてるけど、facebook や mixi と同じ方向を目指しても違うような気がしていたんですが、このビデオを見て、はっ、と気づきました。そうそう、YOUR WORLD, YOUR IMAGINATION, YOUR LIFE って、Secondlife はじめた最初のころよく見ていたフレーズだったことを思い出しました。
メインランドの Sandbox ではじめてべニア板のプリムを Rez したときの感覚、他の人の作品、SIM の世界観をみて感動したこと、こんなの作ってみたい!と思ったことなど、、、。
そして何より、このビデオで紹介されている SIM のクリエーターに日本の人が多いこと。
バタ臭くて日本じゃはやらない、と散々揶揄されましたが、日本人のクリエーターはその部分を自らのイマジネーションと作品をつくる技術でカバーしてきましたね。
創業者のフィリップが CEO として Linden に戻りました。原点回帰的ながらも、さらなる進化があれば、まだまだ楽しめると思ったのでした。
サーバーが 1.40 になって Havok7 が!なんて喜んで、物理玉(でも、一時オブジェクト)をブンブン rez して遊んでいたのですが、気が付いたら 1.3x に戻ってました、、なんてことがありました。
リンデンのオフィシャルブログによると、1.40 の改良版である 1.40.2 に6月29日から7月1日でサーバーがアップデートされるとのこと。
オフィシャルブログ Server 1.40.2 Deploy
リリースノートみると、やっぱり、Havok7 のせいなのか、はたまた関係ないのか、リンク、コリジョン関連で不具合があったようですね。乗り物系(VEHICLE) での不具合はすぐに報告あがりやすいですし。
あと Viewer 2.1 がベータになりましたね。
まえに試したときは表示上スクリプトのソースの改行がなくなっていて、スクリプトを扱うことができなかったので、すぐに使うのをあきらめましたが、今度は治っているようですね。
また、以前は Viewer の XML 設定ファイルをいぢらないとだめだった「チャット入力ボックスの幅」なんかも、ドラックして広げたり、狭めたりできるようです。これはうれしいかも。
このあたりの紹介は Torley がビデオでしてるので、ぜひ見てみてください。
サイドバーが嫌い、使いづらい、といわれている Viewer2 ですが、私はどちらかといえば Viewer2 に慣れてしまって、逆に今エメラルドを使うと戸惑うこともしばしば。
慣れると使いやすいと思いますよ~^^
Secondlife のサーバーがメンテ(正確には障害みたい)なので、MMD –> SL でたまにあるトラブルというか対処方法をご紹介。以前の投稿でもちょっとだけ触れた件です。
MMD (MikuMikuDance) のモーションデータの VMD ファイルを mio の VMD VIEWER で読み込もうとしたとき、以下のようなダイアログが表示されて変換できないことがたまにあります。
‘Shift_jis’ codec can’t decode byte 0x90 in position... というメッセージなので日本語関係かな、と推測がつくのですが、このメッセージは多くの場合、オリジナルの vmd ファイルが日本語で、それを英数字に名前変更して読み込ませたときに起こるようです。ただし、名前変更だけでもうまくいく場合もあります。
こんなときは、その VMD ファイルを MikuMikuDance に読みこませて、あらためてモーションの保存をするとき英数字の名前にしてあげると回避できます。
もちろん、MikuMikuDance がインストールされているのが前提です。MMD のインストールは VPVP Wiki を参考にしてください。
1. MMD でモデルを読み込む
MikuMikuDance を立ち上げて、画面中央下の [モデル操作] の [読込] をおして、モデルを読み込みます。この場合、どのモデルを選んでもかまいません。
2. モーション データを読み込む
メニューバーの [ファイル] から [モーションデータ読込] を選択します。
モーションデータ対象のモデルと、読み込んでいたモデルが違う場合は以下のダイアログがでますが、[OK] を押して続行します。
モーションが読みこまれると、ちゃんとモーションデータの最初のポーズをします。
ものすごくモーションデータが大きいときは以下のように (応答なし) なんて状態になりますが、あわてず待ちましょう。12分のモーション(!!)は読み込むまでに 5分かかりました、、、。
画面右下の [再生] ボタンを押せば、モーションの確認ができます。スカートや髪などはモデルによって違うので、微妙な動きをしていてもそこは無視します。
3. モーションデータを保存する
上記 2 で [ファイル] - [モーションデータ読込] をしましたが、その下に [モーションデータ保存] があるので、それをクリックして、英数字の名前でモーションデータを保存します。
これで VMD Viewer で読み込むことが可能になります。