2008年5月14日水曜日

セカンドライフのアニメーションを操る その5

その5、、、です。ちょっと小難しいスクリプトの話が続いたので、今回はアニメーションそのもののお話になります。(笑

MLDU1 and 2 (Massive Link Dance Unit version1 and 2)  ができたのは、LINZOO さんに「作ってみるー」と言ってから結構早かったんです。
ダンススロット(同時に Avatar が踊れる数)は 50 越えで、踊るダンスの組み合わせのセットは3つ、オーナーにはダイアログが表示されて、ダイアログのボタン操作でダンスセットを切り替え、アバターが踊っているダンスを変更する、ノートカードにダンスの順番、それぞれのダンスの再生秒数を指定する、、、など、現在の MLDU3 の基本仕様(というか、LINZOO さんの要求w) を含んでいました。

そのときのテスト模様は、、、こちらにあったり

0
雷神を使った MLDU テスト。この時、同期ダンス 50 人を達成しました。

が、LINZOO さんから一言。「ダンスセット、3つじゃ足りないなぁ~」(笑

MLDU1 and 2 は1つのノードカードにタグ形式でセットを記述するタイプでした。
こんな感じ、、、

<Set1>
10.0, dance1
12.0, dance2
.....
.....
.....
8.0, dance3
</Set1>
<Set2>
18.0, dance4
....
....
10.0, dance1
</Set2>
<Set3>
8.0, dance3
16.0, dance5
....
....
12.0, dance2
</Set3>

なので、本当に安易にこのノートカードにダンスセットを追加していきました。
でも、、、LINZOO さんの持っているダンスアニメーションの数が、、、半端じゃなかったんです。
そのときで 200 以上は持っていて、、、当然ノートカードの項目も長くなります。
なので、スクリプトのメモリーが足りなくなってノートカードが読めなくなったんです

アニメーションを操る、、、という意味でいうと、ノートカードに順番を入れるのはともかく、なんで秒数までいれるの?と思われる方も多いと思います。おおよそダンス・アニメーションとセットで配られているアニメーション再生スクリプトは 20秒から30秒くらいの「固定間隔」でダンスを切り替えます。これでも十分楽しいのですが、LINZOO さんがこだわったのは「ダンス終了後の立ち位置と、次に開始されるダンスの立ち位置の違い」でした。


高品質ダンス・アニメーションは開始位置と終了位置が一緒

フリーで配られているダンスの中にもすばらしいものもありますが、とくに Latin (ラテン) ダンス系のフリーものはダンスの開始位置と終了位置が大幅にずれているものがあります。ダンス・アニメーションはループアニメーションとして登録されている場合がほとんどなので、そのアニメーション単体を試してみるとすぐにその「不自然さ」がわかると思います。

最初、ラテン、サルサといったダンスはどうしても移動するので仕方ない、、、と思っていました。でも、ショップの有料ダンス・アニメ (ほとんどが 150L$ ~ 300L$ ですね) を見ると、、、これが見事に一致して、さらにはじめからループすることを見越して作っているようで、ループしても「切り替わった」ということを意識させないつくりになっています。
ですから、本来アニメーションがもっている「再生時間」を使ってダンス・アニメーションをつなげていくと、多くの場合は「基点」に戻るのでスムーズにダンスがつながって見えるのです。
せっかく基点にもどってきているのに、一定間隔で無造作に切り替えると台無し、、、というわけですよね。

また、開始位置と終了位置が違うものでも、もし、ダンスの移動中に開始位置に近い場所にくることがあれば、その時点でダンスを切り替えるとスムーズにダンスがつながってみえるわけです。

ただ、この作業、、、現在手作業でしかできませんね~。 LINZOO さんはストップウォッチ片手に計測しているみたいです。
llGetPos() を使って同じ位置近くにくる時間を自動的にとる、、、なんて最初考えましたが、アニメーションで動いているように見えても、実は Avatar の位置って、もともと立っていた位置の Vector 値を返します。スポットライトのスクリプトでアバターを追いかける、、、なんてのも、アバターを動かして歩いているのであればいいのですが、アニメーションによる動きだともともといた場所しか返さないので追いかけることができなかったりします。
このダンスの長さの情報、、、実はショップによってはきちんと公開しているところもあります。

Animazoo の場合

Animazoo は プロパティの Description にいろいろな情報があります。以下のようなものです。プライオリティ(優先順位)と秒数(赤字)が書かれています。
[Animzoo animations - Animazoo dance 25.0 - priority 3 - easing 1.0 - 9.15s l Chevvie dance 15.0]
[Animzoo animations - Animazoo dance 22.0 - priority 3 - easing 1.0 - 11.4s l Chevvie dance 8.0]

Sine Wave の場合

Sine Wave の場合は Animazoo のようにプロパティの Description に情報がないので大変、、、だったのですが、最近ものすごいことになっています。Sine Wave が配付している AO1.2 で Sine Wave の Web サイトと連携するようになりました。 Sine Wave AO 1.2 を Wear した状態で「/1 activate」とチャットすると Sine Wave Web サイトの自分専門の Page のリンクが Say されますので、それをクリックすることでそのページが開きます(最初はパスワードとかのセッティングが必要です)。

ページには Sine Wave が販売しているダンス・アニメーションのリストがあり、かつ、AO 1.2 に入れたダンス・アニメーションにチェックが入っていて、それぞれのアニメーションの時間まで、、、、Web 上で確認できます。(ただ、、残念ながら PlayList の使い方を把握しきれていないので、、、このサイトの使用はダンス・アニメーションの時間の確認のみですが、activation した上で AO を使うとそれぞれのダンス・アニメーションの再生時間はもっとも最適なものになっているのがわかります。)
0

OWENIMATIONS、Abranimations の場合

情報ないのでストップウォッチで計測するしかみたいですね、、、
と、ノートカードによるダンスセットの記述は手間がかかるものの、ダンスがスムーズにつながったり、曲調にあわせてダンスが切り替わるのを見ると時々「ぞくっ」とすることがあるくらい、綺麗に見えます。

万人向けじゃない、、、ですが、クラブでより多くの人に楽しんでもらいたい、と考えると、LINZOO さんの無茶な要求もわかるというもの、、、です。
話は戻って、、、メモリー不足への対応ですが、1枚のノートカードの情報を1つのスクリプトで読みきれないのであれば、ノートカードとスクリプトをそれぞれ分ければいい、、、とすぐに思いつき、それをやってみたわけです。それが MLDU2 となって LINZOO さんにお渡ししたわけです。

が、、、スクリプト、LSL 的には、ここからとっても勉強させられることになります。
とにかく、、、メモリが足りない、ノートカードにそれほど多くの情報がないのに Heap/Stack エラーになる、ちょっとでも SIM が重い・ラグな状態になるとノートカードの読み込みができない、、、、などなどに対応していくことになりました。。。
続く・・・かなぁ、、、(笑

2008年5月12日月曜日

セカンドライフのアニメーションを操る その4

アニメーションを操る、、、ということでシリーズもの(?)になってしまいました。
前回からの続きです、、、

LINZOO さんお得意の「つぶやき」にまんまと引っかかり(笑)、でも、今考えると本当に「安易」にダンス玉を作るといってしまった、、、と思います。

同期ダンスの仕組みはおおよそ予想がついていました。ちょうど大運動会のイカロス順位表示スクリプトを作ったので、メッセージを使ったスクリプトの連携などをすでに経験していました。なので、当時のエントリにもあるように llMessageLinked で「これ踊って~」というメッセージを投げ、それを複数のスクリプトが拾って llStartAnimation を Avatar に対して行う、この繰り返しでしょう、、、くらいの理解でした。

ビデオ玉音楽玉もすでに作っていたので、複数の人がひとつのスクリプトを利用する問題点と対応方法、ダイアログの使い方、ノートカードの読み込ませ方などもある程度わかっていたつもりでした。

0
当時のビデオ玉のダイアログ

スクリプトでアニメーションを操作して、アバターにダンスやポーズをさせる場合、Permission が必要だという話しはすでに書きましたが、この permission 、、、ちょっと危険な香りがする function なんです。それと (複数の人を対象としたダンス・スクリプトとしては、、、逆にかなり難しいですが) 複数の人がひとつのスクリプトを使った場合の llRequestPermissions の動きって、ちょっとトリッキーなんです。すぐに気がつきましたが、アニメーションを操る上では理解しておかないといけないポイントがいくつかあります。


llRequestPermissions... 許可をするときは覚悟が必要?(かも)


llRequestPermissions を使ったスクリプトは実はこれが初めてではありませんでした。はじめて llRequestPermissions を使ったのは「詐欺スクリプト」を検証してみた時だったんです。

詐欺注意 2007年6月23日の投稿です。

お金に絡む Permission の場合はダイアログが黄色になる、、、みたいな改善がその後行われてきましたが、いずれにせよ、この llRequestPermissions によるいくつかの制御の許可 (自分たちにしてみれば制御権限の委譲) は結構慎重にならなくてはいけないのかもしれません。

たかがダンス、、、といっても、スクリプトの書きかたが十分でないと、、、ダンスがとまらない、、、なんてことになっちゃうんです。


ポイントを以下に列挙します。
1)llRequestPermissions でスクリプトが取得した「許可」は一番最後に許可したアバターのもの (許可を受けとったもの) だけが有効。それ以前に許可した人については忘れてしまいます。(笑

2)「アバターに動きをつける」というダイアログの意味はアニメーションを開始させる、のほかに「アニメーションを停止させる」の意味も含みます。

3)上記からアバターのアニメーションの「開始」「停止」の両方を制御するためにはダンスするアバター分のスクリプトが必要になります。(実はそれだけではなく、llSetTimerEvent と timer() を使うのであれば、個別にスクリプトを用意する必要があります。)

4)停止方法が明記されてなくてもメニューの「ツール」-「アニメーションをすべて停止」からダンスアニメーションを止めることができます。しかし、それは自分のビュワーで止まって見えるだけで、他の人のビューワーでは動いて見えています。アニメーションの処理はそれぞれのクライアント・ビュワーでの画像処理になっているようです。

5)「許可をするときは覚悟が必要」もしくはスクリプトを書くときに注意しなくてはならない理由は、一度もらった(与えた) llRequestPermissions への許可は、スクリプト・リセット、そのスクリプトが無くなる、もしくは SIM リスタートによる SIM の全スクリプトのリセット以外に取り消すことができません。

6)ダンスアニメーションの場合のほとんどは llStartAnimation / llStopAnimation を llSetTimerEvent を使って何度も開始させています。ですので、上述の4)の方法でダンスを止めても、また、ログインしなおしても、そのスクリプトが「許可」を保持し続けている限り(きちんとしたエラー処理をすればするほど)スクリプトによる「アニメーションによる制御」がスクリプトリセットまで続きます。

7)この状態になってしまったら、プリムと同じ SIM にいる時は、ほとんど「奴隷」状態です。。。(ローリング・リスタートの有難みが・・・)
Permission については、以下のスクリプトを試してみるとわかると思います。試す場合はダンスアニメーションをスクリプトがあるプリムのコンテンツ・フォルダにドラッグ&ドロップして、以下のスクリプトの "Clube Dance 4" を該当するアニメーションの名前にしてくださいね。

key avatarKey; //プリムにタッチしたアバターの Key を格納するための key 変数宣言
default
{
    state_entry()
    {
        llSetText("",<1,1,1>,0);
        integer handle = llListen(0,"",NULL_KEY,""); //あえてオープンチャンネルの 0 を使ってます。
        llListenControl(handle, TRUE); //上記の Listen を開始します。
    }
    touch_start(integer total_number)
    {
        avatarKey = llDetectedKey(0); //タッチしたアバターの Key を取得します。
        llSay(0, "Touched by "+llKey2Name(avatarKey)); //タッチしたアバターの名前を Say します。
        // タッチしたアバターにアニメーションのパーミッションの許可を要求してダイアログを表示させます。
        llRequestPermissions(avatarKey, PERMISSION_TRIGGER_ANIMATION);                   
    }
    run_time_permissions(integer perm) //パーミッションのダイアログへの返信のイベント
    {  // もし返答が「はい」(許可する)だったら、
        if (perm & PERMISSION_TRIGGER_ANIMATION)
        { //プリムの上に現在パーミッションの許可をもらい制御可能なアバター名を表示
            llSetText(llKey2Name(llGetPermissionsKey())+" under control.",<1,1,1>,1);
            llStartAnimation("Club Dance 4"); //制御可能なアバターに対してダンスをスタートさせます。
        }
    }
    listen(integer chan, string name, key id, string msg)
    {  //この場合、オープンチャンネルの、そこにいる誰の発言でも、最初の 6 文字が /start だったら、
        if(llGetSubString(msg,0,5)=="/start")
        { // 発言した人が制御下にあるアバターのアニメーションを開始する、と言い、開始させます。
            llWhisper(0,llKey2Name(id)+" が "+llKey2Name(llGetPermissionsKey())+" のアニメーションを開始します。");
            llStartAnimation("Club Dance 4");
        } else if (llGetSubString(msg,0,4)=="/stop") // 発言の最初の 5 文字が /stop だったら、
        {  // 発言した人が制御下にあるアバターのアニメーションを停止する、と言い、停止させます。
            llWhisper(0,llKey2Name(id)+" が "+llKey2Name(llGetPermissionsKey())+" のアニメーションを停止します。");           
            llStopAnimation("Club Dance 4");
        }
    }
}

スクリプトを書く人は必ずアバターにアニメーションの開始・停止の機会を与えて、アバターが意図しないときに勝手にアニメーションを開始するようなことがないようにしなくてはいけませんし、利用するほうは、ダンスに限らず 「許可をする」系のダイアログの返信についてはよくよく考慮した上で返信([はい]を押す)をしたほうが良いでしょうね。

なので、海外に多い [Sit] タイプのダンスは安心ができる、、、と前の投稿で書きましたが、これはアニメーション停止の方法がわかりやすいだけであって、暗黙的ながらも上のスクリプト同様にパーミッションの許可を与えていますから、llSetTimerEvent を使った timer() によるアニメーション・コントロールをされてしまうと、、、、立ったにもかかわらずアニメーションが開始されてしまいます。

[追記] お金に関する PERMISSION_DEBIT はこの 「暗黙的許可」はありません。Sit しても Wear しても、今は黄色いおおきめのダイアログが表示されます。

と、、、パーミッションについてはこれくらいにして、、、(続く)

2008年5月10日土曜日

セカンドライフのアニメーションを操る その3

前回からの続きで「その3」になりました。
チャットキーボードの次は立ち姿の AO (Animation Override) を、、、と思ったわけですが、スクリプト以前にポーズというものが面白くて、QAvimator などを使って自分でポーズや短いアニメーションを作ってみたりしました。ポーズは Free のものでも相当の数、そしてなかにはクオリティが高いものが出回っていて、Secondlife を始めたころはひとつひとつ試してみたり、「その1」でご紹介したジェスチャに登録して使っていました。

アニメーションとポーズ、、、これは同じものなんですよね。
そのあたりは「ポーズは腰が命 全4回」(笑 や 「QAvimator って面白い」のエントリの中で紹介しています。 QAvimator の使い方、bvh ファイルの作成とアップロードの方法からわかってきました。

でも、自分の作ったポーズ(つまり、フレームを 2 つしか使っていないループアニメーション)って切り替えると「パッ!パッ!」とそのポーズになって、それが「不自然」ということに最初は気が付いていませんでした。それに気が付いたのが Maitreya のポーズを試してみたときでした。

MaitreyaPose21
Maitreya - CCRunwayPose21

それはポーズというよりも、立派なアニメーションでした。

これ、フォトだとまったくわからないと思いますが、「きめのポーズ」になるまでの体の動きがものすごくしなやかなんです。そして、数秒たったら、また違うポーズに変化する、、、、というものもありました。

アニメーションを操る、、、という意味では、 AO を設定し使うためのツールが提供されているのでまずはそれを使いこなすことですね。 ZHAO (もしくは ZHAO-Ⅱ) というツールが Secondlife では有名です。
ZHAO の使い方はいろいろなブログやサイトで詳細に説明されているので割愛しますがポイントは、

1) 地面上に ZHAO を Rez します。装着したままだとアニメーションをドロップできません。

2) 編集から ZHAO の [コンテンツ] フォルダを開き、購入したアニメーションをドロップします。

3) Empty や Default といった名前のノードカードがあるので、それを開いて AO させたいセクション(Walking や Standing)の直後にアニメーションの名前を書き込みます。アニメーションのプロパティを開いて名前をコピーしてノートカードに貼り付けるのがいいでしょうね。

4) 上記の設定が終わったら Take して、HUD として装着したら LOAD というボタン(もしくはダイアログのボタン)を押してノートカードを読み込ませ、アニメーションを有効化させます。

実は ZHAO ってあまり好きじゃなかったんです。それは、機能うんぬん、、、というより見た目でした。後でわかるのですが、ZHAO はいろいろな人、ショップがカスタマイズして提供しているので、それぞれ見た目は結構変わるんですよね。
でも、Secondlife をはじめた時に最初に見たのが以下の左側、、、
0
向かって右側のは Maitreya で配られている ZHAO です。最初に Maitreya の ZHAO を使っていたら、自分で AO 作ろうなんて思わなかったかもしれません。ちなみに ZHAO-ll だとダイアログを使ったメニューになっていますね。
とりあえず Standing のアニメーションだけオーバーライドさせたかったので、そんなに難しくないかも、、と考え、前回ご紹介した方法で作ってみようと思ったわけです。でも、そんな単純なものではありませんでした。(笑
(やっと本題?)

AO させるには Permission が必須

はじめて ZHAO を使った時 (もちろんスクリプトの中なんて見ません(笑)) まったく意識していなかったのですが、アバターに対してアニメーションをスタートさせるときはかならず llGetPermissions ([修正] ごめんなさい。許可をもらうのは llRequestPermissions です。)を使ってアバターから「許可」をもらわないといけません。
タッチしてダンスを踊るタイプのものだと以下のようなダイアログを見たことがあると思います。
1
「て・に・を・は」がちょっとおかしいですが、オブジェクト 'MLDU' がアバターを動かそうとしていますがいいですか? と聞いているわけです。([追記] 誤解ありそうな表現なので追記します。アニメーションをスタートさせることだけではなく、停止するにもこのパーミッションが必要なことから、animate you の部分は「(停止を含めた)動作をつける」という意味だと理解してくださいね。)

海外のダンスホールやクラブだとダンスフロアに配置されているダンスボールに Sit (パイメニューでは llSetSitText を使って "Dance" になっていると思います) するものが多くて、このダイアログってあまりみたことがありませんでした。ZHAO の AO も自分に「装着」しているのでこのダイアログはでません。

そうなんです。Sit もしくは装着しているとスクリプトは Permission をもらったとして処理し、このダイアログは表示しないんです。
でも、スクリプトの中ではきっちりと llGetPermissions llRequestPermissions が使われています。

この省略はとっても合理的だと思います。Sit でアニメーションが開始されて「やめたいな、止めたいな」と思ったときは Stand Up すればいいわけです。HUD や Dance Ring の場合は 取り外せば いいわけですよね。(llGetPermissions llRequestPermissions におけるダイアログ・タイプの注意点(恐怖?)は後日に・・・)
このとき作成した AO Ball (また、、、小さな玉でした、、)のソースを今みると、、、、ひどい・・・(笑

自分だけ、かつ、装着での使用なので問題ないのですが、run_time_permissions で PERMISSION_TRIGGER_ANIMATION がとれてなければ「また」llRequestPermissions をやっていたり、、、自分専用だからいいけど、、ちょっと公開するにはあまりにひどいので、、、ポイントだけ。
自分専用単機能 AO ボールのポイントは

1. attach(key id) イベントで id が NULL_KEY でなければ処理をします。NULL_KEY の場合は「はずされた」という意味です。
2. その処理では
a) for 文と llGetInventoryName(INVENTORY_ANIMATION, i) を使ってコンテンツフォルダにあるアニメーションの名前をすべてリストにいれる。
b) llRequestPermissions(id, PERMISSION_TRIGGER_ANIMATION) を使ってアニメーション開始の許可を id (装着している Avatar ) に申請する。
3. 装着の場合は暗黙的に許可が下りるので run_time_permissions(integer num) のイベントでは llSetTimerEvent を使って、0.1 秒や 0.2 秒といった間隔のタイマーをかける。
4. イベント timer() の中では
a) llGetAnimation を使って現在動いている Animation を取得
b) 現在の Animation が "Standing" だったら Override したいアニメーションの名前を List から llList2String で取り出す。
c) llStartAnimation を使ってアニメーションを開始する。
d) 上記 a)b)c) の処理のあと一定間隔後に、llStopAnimation で現在動かしているアニメーションをとめて、次のアニメーションを List から取り出し、開始させる。
e) "Standing" の状態でなくなったら、即時に llStopAnimation でオーバーライドしているアニメーションを停止する。

こんなところでしょうか。
当時の恥ずかしいスクリプトは、、、結構強引(無駄)なことをやっていたりしてます。
相当悩んだのが 4-d の「一定間隔後に止める」だったと記憶しています。llSetTimerEvent で 0.1 - 0.2 秒で timer() イベントを開始させる、というのは「続けなければならない」わけですから、llSetTimerEvent を使って 20 秒後にアニメーションを止める方法は 1つのスクリプトの中、1つのステート (State: 通常は default ) の中ではできないわけです。

今だったら、llResetTimellGetTime もしくは llGetAndResetTime を使うのでしょうが、当時はそれらを知らなくて、たとえば 0.2 秒ごとに timer() が呼ばれるなら、そこでカウントをとっていって、カウント数 X 0.2 が 20 以上になったら、、、みたいな処理をしてました。@@

状態監視については、ZHAO および ZHAO (改)などはもっと手の込んだことをしているようです。 ZHAO のソースは見ていませんが、どうやら llGetAgentInfo や llGetAnimationList のほかに control などを使って状態を監視しているようです。

これで、Permission の取得とアニメーションの開始、停止の基本ができたので、ははん、、、これでダンス・アニメーションを扱うスクリプトも書けるかなぁ、、などと「安易に」ぼんやり思いながら クラブ雷神で踊っていたら LINZOO さんの「10人でいっぱいになっちゃう同期ダンスユニットはねぇ、、、もっとたくさんのひとが踊れるのほしいよね」という言葉を聞いて「作ってみるー」と言ってしまったのでした、、、。
続く、、、え?まだ続くの?笑)

2008年5月8日木曜日

セカンドライフのアニメーションを操る その2 (でしょう、、

前回の投稿でチャットキーボードを作ることでスクリプトによるアニメーション操作を意識した、、、と書きましたが、チャットキーボードをつくった当時は「意識」しただけで、スクリプトが何をやっているのかほとんど理解していませんでした。(笑

チャットキーボードはアニメーション理解の原点(かな?)

チャットキーボード、、、チャットをしているときにアバターがキーボードをタイプするような動き(アニメーション)をするわけですが、せっかくキーボートをタイプしているような動作をするなら、キーボードだしちゃえ!っというのが出発点で、そのうちタイプしているアニメーション自体を変更(このアニメーションの変更を Animation Override (AO: アニメーション・オーバーライド)といいます)して違う動きにしちゃおう、などなど、本来提供されている動き・アニメーションをもとにいろいろなカスタマイズができちゃうわけです。

キャット・ウォークとかセクシー・ウォーク、つまり、飛んだり、走ったりするアニメーションを違うアニメーションに入れ替える AO も、基本このチャットキーボードの仕組みと同じものです。一番はじめにこの単純な「チャットのアニメーション」を利用・変更するということにトライしたのは、今考えると最初の入り口としてはとても敷居が低くてよかったんでしょうね。

ちなみにそのとき作ったチャットキーボードは以下です、、、
0

この時、同じ「アニメーション」でも「テクスチャ・アニメーション」というものの存在を知りました。黒の背景に緑の文字がばらばらと流れるものをこのテクスチャ・アニメを使って作りました。簡単に言うと、プリムに貼り付けるテクスチャも アニメーション GIF みたいに「動きがある」ものを使うことができて、それをスクリプトの llSetTextureAnim でコントロールすることができるんですよね。llSetTextureAnim も実は奥がとっても深くて、それだけで結構ながーいエントリになるかもしれません。アニメーションだけじゃなくて、たとえば瞬時に画像を切り替えたい場合などは llSetTexture で個別の画像を切り替えるより、llSetTextureAnim と使用する複数の画像を一枚にしたものを使うと、画像切り替え時に灰色になることを避けることができたりします。もちろん、、、画像サイズにもよりますが。

(脱線、脱線、、、)話しを戻して、、、


チャットキーボードのときに参考にさせてもらったのが以下のスクリプトでした。
赤のテキストは私の補足です。
// the first free keyboard script
// by nonnux White
// free to mod, sell, erase, explode, burn :)
list anims = []; //その時点で動いているアニメーションをすべていれる空のリストを宣言
default{
    state_entry() {
        llSetTimerEvent(.2);  //0.2秒の感覚で time() を動かす=動き続けます!
    }
    timer() {
        // オーナー(使用者)の動いているアニメーションすべてを anims リストにいれる
        anims = llGetAnimationList(llGetOwner());
// "c541c47...." というアニメーションが anims リストの中にあったら...
        if(llListFindList(anims,[(key)("c541c47f-e0c0-058b-ad1a-d6ae3a4584d9")]) != -1)
        {
// このスクリプトが入っているオブジェクト上に表示されているテキストを(この場合は)空にして
        // リンクされているオブジェクトのすべての面を表示する(Alphaを1.0にする)

            llSetText("",<1,0,0>,1);
            llSetLinkAlpha(LINK_SET,1.0,ALL_SIDES);           
        }
// "c541c47...." というアニメーションが anims リストになかったら...
        if(llListFindList(anims,[(key)("c541c47f-e0c0-058b-ad1a-d6ae3a4584d9")]) == -1)
        {
        // テキストを空にして、すべての面を透明化(Alphaを0)する
            llSetText("",<1,1,0>,1);
            llSetLinkAlpha(LINK_SET,0.0,ALL_SIDES);
        }
    }
}
使用するスクリプトの関数は後々良く利用するものばかりでした。特に llListFindList といった List 操作系の関数は「なんらかの操作をする」場合によく使うことになりました。
でも、アニメーションを操作する、、、、ということでのここでのポイントは List 系の関数の話しではなく、
"c541c47f-e0c0-058b-ad1a-d6ae3a4584d9" というアニメーションの Key がタイピングのアニメーションを指し、llGetAnimationList はそのとき動いているアニメーションすべてをとる関数、、、ということです。

これも、、、運ですよねぇ、、、実は AO のための「今、何をしているか」を取得するスクリプトとしては、このとき私が参考にしたものよりも一般的なのは以下のような llGetAgentInfo を使う方法だと思います。if をネストしないのは浮きながらタイプする、、、など同時にその行為が行われている可能性があるからです。llWhisper の部分を上のようなオブジェクトの Alpha の操作に変えればいいわけです。(もちろん、、、このままではだめで、すでに Override しているなら何もしない、、、とかの処理が必要になります。あと、これをみたら AO って短い時間にぐるぐるまわるから、混んでいる SIM などでははずしたほうがいいことがおわかりになると思います。)

default {
    state_entry() {
        llSetTimerEvent(0.2);
    }
    timer() {
        integer bits = llGetAgentInfo(llGetOwner());
        if (bits & AGENT_TYPING) {
            llWhisper(0,"Now I'm typing!!!");
        }
        if (bits & AGENT_WALKING) {
            llWhisper(0,"Now I'm walking!!!");
        }
        if (bits & AGENT_FLYING) {
            llWhisper(0,"Now I'm flying");
        }
        if (bits & AGENT_IN_AIR) {
            llWhisper(0, "Now I'm hovering");
        }
    }
}

この方法を当時知らなかったので、逆に「"c541c47f-e0c0-058b-ad1a-d6ae3a4584d9"ってなに??」から始まり、llGetAnimationList って何???となったわけで(笑
ビルトイン・アニメーションの Key については secondlife wiki で確認することができます。(今は有志による日本語化された文書があるので、、、すばらしいですね)

でも、、、その後わかるのですが、アニメーションを操る上では、アニメーションの Key (UUID) って実はあまり使えない、、、のです。LSL は key でいろいろな操作が可能です。 llSetTexture なども貼り付けるテクスチャは、テクスチャの名前(string)だけじゃなくて、key (UUID) を指定することで利用できますが、アニメーションは llStartAnimation で Key の利用はできません。

と、、長くなってきましたが、最後に llGetAnimationList と動いているアニメーションの確認に関して。

今どんなアニメーションが動いているのかな?というのは、この関数を使わなくても確認することができます。この方法は「何が動いている?」を知るのによく使う方法ですが、もうひとつ重要なのは動いているアニメーションの優先順位を確認することができる点です。これも後々悩むのですが、ショップで売っているアニメーションの優先順位って結構バラバラだったりします。アニメーションのプロパティを見てもそのアニメーションの優先順位ってわからないんですよね。(少なくても私は、、、他の方法を見つけられてません) なので、よくダンス・アニメーションがうまく開始されていない、、、などという場合はこの方法で本当にアニメーションが開始されているか、邪魔している優先順位の高いアニメーションは他にないか(よくあるのが ポーズなどの AO をつけたままダンスを踊ろうとしている人とか、、、)を確認します。

1. Ctrl+Alt+D (Windows) で [Advanced] メニューを出します

2. [Advanced] メニューから [Character] を選び、[Animation Info] をクリックしてチェックをいれます

これだけです。
すると、画面上の「すべてのアバター」の頭の上に現在動いているアニメーション名(一部 Key)とそれぞれの優先順位が表示されます。
1
この情報を llGetAnimationList は取得してるんですよね。
で、、、、チャットキーボードを出展しましたが、ひとつも売れませんでしたね~
私はとても気に入っているので今でもつかってますけどね(笑
次にショップからアニメーションを購入して Animation Override を作ることにトライしました。といってもダンス・アニメーションじゃなくて「スタンディング・ポーズ」のアニメーションです。チャットキーボードが Typing の状況を監視してオブジェクトを出したり消したりしていたので、スタンディングの状況を監視して購入したアニメーションを開始させればいいはず、、、と考えたわけです。
このつづきは、、、その3かな?

2008年5月6日火曜日

セカンドライフのアニメーションを操る その1(かな)

ASUKA の雷神に設置させてもらっている MLDU (Massive Dance Link Unit) を作ったことで、Secondlife 内の「アニメーション」や「ダンス」、動きはないけど仕組みとしては一緒の「ポーズ」などをスクリプトで扱う方法をそこそこ理解できるようになってきました。

Free のダンスもいろいろありますが、Sine Wave や Animazoo、OWENIMATIONS といったアニメーション専門店で素敵なポーズやダンスを見て思わず買ってしまった、、、なんて経験がある方も多いのではないでしょうか。

このアニメーションを使うために AO (Animation Override) ユニットを配付しているショップもありますが、英語での説明だったり、コンテンツフォルダに保存したアニメーションを名前順に同じ時間間隔で再生するといった単機能だったりして使用勝手が、、、と思われている方もいると思います。

そこで(どこで??笑)アニメーションを扱う方法についてこれまで私が経験したことをちょっとまとめてみようと思いました。はい、急に思い立ちました(笑

アニメーション操作のファースト・ステップ 「ジェスチャ」

フルパーミッション(コピー可、プレゼント可、修正可)のダンス、アニメーション、ポーズならばジェスチャ作成してカスタマイズするのが一番でしょう。マクロ(?)みたいな感じですが、スクリプトを書くよりはものすごく簡単に、アニメーション、サウンド、チャットの組み合わせをひとつのジェスチャの中に登録することが可能です。時間を指定して次の動作に移ったり、同時にアクションを開始したり、、、とアイディア次第ではかなり凝ったことができます。ビルトイン・アニメーションも使えますので、たとえばビルトイン・アニメーションを流用した「クチパク」などはスクリプトを組まなくてもジェスチャ登録することで作成することが可能です。「あ」とか「い」といった母音の発音の口の形に近いジェスチャを作って Shift+F5, F6, F7 とかに登録しておき、それらをタイミングよく連打すると話しているように見えます。

アニメーションには実行時の優先順位というのがあり、同時に複数のアニメーションが動くと、高いものが優先されて動きます。また、複数のアニメーションを同時に動かすと、アニメーション指定が重なっていない「部分」などは複合して動きます。クチパクなんかも優先順位の同じビルトイン・アニメーションを複合させると思いもよらない表情をみせてくれることがあります。

以下の「お」という発音のクチパク・ジェスチャの例では「Open Mouth」というアニメーションと「Kiss」のアニメーションを同時に動かして、0.2秒後にそれらを止める、という Steps を登録したものです。
 1

すると、、、ちょっと間抜けですが、以下のような顔になります(笑
0
これ、Kiss アニメーションの目と Open Mouth のクチが組み合わさっているんですよね。
[Wait] を追加して [アニメーションが完了するまで] のチェックをはずした状態で明示的に再生秒数を指定して、その直後にアニメーションを停止(STOP)させるステップをいれると最初の「0.2秒だけ」アニメーション(それも複合)を再生することが可能になるわけです。
ジェスチャの基本については以下を参考にしてください。

http://help.secondlife.com/jp/avatar/gestures.php

思えば1年くらい前にはこのジェスチャくらいしかアニメーションを操る方法を知らなかったんですよねぇ。。。フリーなものしか持ってなかった、、、というのもありますが。
残念ながら、ショップのダンスなどはコピー不可になっているものがほとんどですから、このジェスチャ機能は使えないわけです。
そこでスクリプトによる操作、制御、、、というのが出てくるわけですが、私がはじめてスクリプトを使って「アニメーション操作」を意識したのはクラフターズカップの「チャットキーボード コンテスト」でした。

って、、、長くなったので次回に続く、、、、かな?(笑

2008年5月3日土曜日

ネトラジ・チェンジャー

商売っ気がまったくない、、、といえばないのですが、、、(笑
いろいろな「玉」を作ってきましたが、お友達から予想以上に評判がいいのが ネットラジオ・チェンジャー (NetRadioChanger - NRC) です。

やっぱり、自宅、お店、クラブなどなど、、、音楽があったほうが楽しいわけで。
でも、いちいち土地情報開いて、、、なんてめんどうだったり。

そこで、llSetParcelMusicURL を使って、ノートカードに登録している URL をダイアログに表示して、ボタンで切り替える、、、という「玉」を作って、お友達にお渡ししていたわけです。

といっても、あまりエラー処理とか日本語のメッセージとかにしてなかったので、それらをいれて SUZAKU の "Snuript Library" にベンダーとしておきました。 [追記 2009: 今はなくなっています。もうしわけございません。]

といっても、、、 100 L$ ですけど(笑
nrc9
(青いグローな玉です、、、、って、パッケージングとかほんと、手抜き、、、)

でもね、実は、この単純な NRC2.2 は Snuript の技術を結集、、、(笑

1) ノートカードへの記述が増えれば自動的にダイアログのページも増えます
現時点で 75 のネトラジが登録されていますが、減らすことも増やすことも可能です。ノートカードにフォーマット通りに追記してもらえれば、ダイアログのページは自動的に増えます。
nrc3
登録する URL の長さにもよりますが、118 局、ダイアログで 14 ページまで追加できました。
nrc6
メモリーが足りなくなるくらいの長いノートカードになったときは、その旨メッセージがでますので、ご安心ください。

2) ノードカード変更後のスクリプトのリセットを簡略化しました
Change イベントを拾って、ノートカードが変更されたときに「コンテンツが変更されたので、スクリプトをリセットしてください」は当然の処理だとしても、オブジェクトの編集を選んで、パーミッションのないソースを開いて [リセット] ボタンって、あまりユーザーフレンドリじゃないと思っていました。そこで、Change イベントが発生したら、通常のダイアログの [Close] ボタンを [RESET] にして、そのボタンを押すことでスクリプトのリセットをかけるようにしました。
ノートカードの変更・局の追加はそこそこ発生しますからね~。
nrc5
3) 土地・区画のオーナー情報を表示するようにしました
これは、、、一番最初しか使わないのですが、ネトラジ・チャンジャーは土地・区画のオーナーもしくはオーナーになっているグループの所有でないと動きません。今までは llGetLandOwnerAt(llGetPos()) とオブジェクトのオーナーを比較して、違っていたら「オーナーエラーです」だけでしたが、だれがオーナーなのかを表示するようにして、その人にオブジェクトを渡して設定してくださいー、というメッセージを出すようにしました。設定してもらえれば、その土地・区画のオーナーじゃなくても音楽を切り替えることが可能になります。
こんな感じ、、、
nrc2a
で、意外に難しかったのがグループ所有の場合。Key はとれるんだけど、llRequestAgentData だとアバター名はとれても、グループ名ってとれないんですね、、、
でも、やり方、見つけちゃっいました。
で、とったのが以下。
nrc1a
world.secondlife.com に llHTTPRequest で GET メソッドを使う方法です。プロフィールの画像をとる方法の応用ですね。プロフ画像の取り方をご存知ない方はこちらなどを参照にしてみてください。 llHTTPRequest などは NRC の隣にポン、、、と置いてある非売品の辞書の応用でもありますが、、、(笑
あとは、、、スクリプト作る人の自己満足的な、、、(笑
[追記 2009/10] 今はこの方法は使えません。スクリプトからのアクセスって制限されたようです。

4) llDialog の問題を解決してみようと、、、
過去のエントリにありますが、llDialog って一言でいっても検討する余地が結構ありました。
だれでも使えるようにしてあげて、ダイアログから選択させる、、、という処理の場合は、タイムアウトを設定しなきゃいけない、、、そうすると最後にタッチした人にタイムアウトが設定される、、、[無視] をおされたら Listen チャンネルが残る、、、など。
NRC は、他の人がダイアログを開いていると「今使用できません、しばらく待ってください」というメッセージを表示して、一時点で一人しか対応しないようにしてます。でも、これ、dialogSlot というスクリプトを増やせば、その数だけ使える人数が増えていく仕掛けです。(NRC だと意味ないですが 笑)
ダンス玉の応用ですね~

と、、、 うーん、100L$ のわりには結構スクリプトのテクニックが詰め込まれて、、、って、MusicURL 変えるくらいだと、こんなにこだわらなくてもよかったのかな(笑
なお、SUZAKU のお店でご購入いただく際はパイメニューの [購入..] からお願いしますー。
nrc8
最後に、、、参考として付属しているネトラジの URL や内容、それが利用可能かどうか、、、などなどに関してはまったく関与していませんので、その点ご了承ください。いろいろな方からの情報、いろいろな方のご協力をもとに NOTECARD の内容が構成されていますが、NOTECARD の内容については一切お答えできませんのでよろしくお願いします。

SUZAKU の "Snuript Library" すみません~、いまは販売してません~^^;

p.s.
あ、そうそう、このネトラジ・チェンジャーですが、概観などは Mod 可能です。もっといえば、スクリプトを抜いて、他のオブジェクトにいれてしまうことも可能です。「玉」が気にいらない人はかっこいいオブジェに変えてください。

2008年4月24日木曜日

Steam Glider レース

先日 ASUKA/BYAKKO で行われた Steam Glider のレース模様を撮影したビデオです。。。



撮影班兼スクリプターで、、、レースのためのスクリプト動かないし。。。
なので、参加のみなさんの機体などをまんべんなく撮ることができなくてごめんなさい~。

今回のビデオ編集では、レースの模様を撮影しただけの「定点でのカメラ回し」が少なく、パーンやズームを使うか、もしくは動いている被写体(機体)にロックをかけての撮影なので、Yaz さんの supernovasupoersonique のようなテンポのよい曲があうな~、と思いました。
3D Connexion を使っての撮影は動きがスムーズになるのでとってもいいですね。
サブリミナルみたいな、俗称「パカパカ」を無償ソフトのムービーメーカーで試してみました。
映像を分断(A1,A2)して、そこに 0.2 秒くらいの別の映像(B)をいれます。A1+B+A2 みたいになるので、A2の特殊効果として「フェードイン 白から」を追加してみたら、、、まぁ、そこそこ「らしく」なったかもw

イベント系はとりなおしがきかないから、すべてを音楽に合わせようとするとつらくなっちゃうので、途中途中はあわせてませんが、どちらかといえば「早く見たい」っていう人がいますし、この程度の編集でおゆるしくださいませ。

でも、、、ただただ飛ぶんじゃなくて、パーティクル障害あり、マシンガンあり、、、は SIM 重くなるけど面白いw
はやくスクリプトの実行環境が MONO になってくれたら、今の4倍速くなる、もしくは軽くなるんでしょうね。
[追記]
YouTube にもアップしました。YouTube の高画質オプションも利用できますが、もっとも High Quality で動画を見たい方は以下がお勧め。Silverlight Plug-in が必要になります。
[追記: 上記の HQ サービスは終了予定となりました]

2008年4月22日火曜日

KoinUp-Video/Photo SNS

KoinUp っていう virtual world のビデオ、フォトの投稿を専門にした SNS があって、そこにはとっても参考になる Music Video がアップされていたりします。

http://www.koinup.com/on-videos/

そのひとつ。とっても気になったビデオです。

&lt;a href="http://www.koinup.com/beyondthevoid/work/25621/"&gt;SEDUCTORA - beyond the void&lt;/a&gt; - a &lt;a href="http://www.koinup.com/in-second-life/on-videos/"&gt;Second Life Videos&lt;/a&gt; by &lt;a href="http://www.koinup.com/beyondthevoid/"&gt;beyondthevoid&lt;/a&gt; on &lt;a href="hhtp://www.koinup.com"&gt;Koinup&lt;/a>
SEDUCTORA - beyond the void

すばらしい~。カットやつなぎ、ライティングとか撮影場所とか、、、もちろん、曲もw
いつかこんなビデオを作れるようになりたいですね~。

でも、こうなっちゃうと、、、あまりにすごすぎて「ごめんなさい」って、なっちゃいます。。。。
<a href="http://www.koinup.com/BKiddo/work/27263/">"The Cats Will Play" Grindhous...</a> - a <a href="http://www.koinup.com/in-second-life/on-videos/">Second Life Videos</a> by <a href="http://www.koinup.com/BKiddo/">BKiddo</a> on <a href="hhtp://www.koinup.com">Koinup</a>
"The Cats Will Play" Grindhouse Tribute

撮影した後でエフェクトによる動画編集はあこがれるんですが、、、ソフトもそれなりに良い(高価な)ものが必要になってしまうし、、、最初にご紹介した beyond the void さんのビデオだと、カット、アングル、撮影場所など、なんとなく近づけそうな「気」になりますが、プラスして編集・エフェクトでここまでやられると手の届かないところにあって、、、(笑
素人は素人なりに楽しみます(笑

2008年4月12日土曜日

スローな曲とスローなダンス

前々から Yaz さんの Instant Sorrow を使ったダンスシーンの動画を作ってみたいと思っていたのですが、いつものダンサブルな元気よくみんなで踊るような曲ではないので、どういうのがいいのかなぁ、、、と考えていました。

スローな曲にスローなダンスを使ってみたらどうだろう?と、やってみたのがこちらになります。
(スローというか、リリックといかメロウというか・・・笑)



ダンスアニメーションは Sine Wave のスローダンス系のものを使い、イントロの 48 秒間の部分と2分58秒くらいから3分44秒の間を話題の 3D マウス3Dconnexion SpaceNavigator を使って撮影しました。

動画の中で使った Sine のダンスアニメーションは以下です。
- crimson breeze
- crystal roses
- danish
- dizzy orchid
- firefly
- honeysuckle
- sprite
Sine Wave のダンスアニメはとてもスムーズで、ほんとうによくできた bvh ファイルだと思います。
モーションキャプチャを使って作っているのでしょうが、リアルでそれらの作成工程や時間・費用を考えると、in-world で 200 - 350 L$ で購入できることは、、、驚きですよね。100円とか140円とか、そんなレベルですから。in-world だけでのビジネスを考えたら、ぜんぜんペイしないんじゃないでしょうか。
Sine Wave のホームページをみると、3つの事業を展開されているみたい。
- Animation
- Event
- Robot
海外にはこのような Virtual World でプロダクト、サービス提供する技術力の高い専門の会社さんがいくつかあって、有名どころとしてはThe Electric Sheep Company などもあります。 ここは CSI:NY 向けのビューワー OnRez を作ったり、日産の新しいSIMのスクリプトを作ったりしてますね。(ダンスは、、、ありません笑)
Electric Sheep Company は大きなクライアント(PEPSI, MTV...)がついているのでリアルなビジネスになっているようですが、、、、HP を見る限り SINE はちょっと心配・・・がんばってほしいですね。
あと、3Dconnexion SpaceNavigator はまだ操作慣れしてませんが、1.20 ではアバターもこのマウスで動かすことができます。向かって左のボタンをクリックするとカメラワークとの切り替えが可能ですが、ビューワーの右下のほうに "flycam" という文字が表示されてしまって、これ、Alt+Ctrl+F1 で UI を消しても文字がでたまま、、、、なのがちょっと不満だったり。そのうち改善されるでしょうね。
このマウスについてはいろいろ試して別途ご紹介したいと思います。

2008年4月2日水曜日

セカンドライフマガジンの記事アップデート

とあるご縁で、インプレス R&D さんが出している「セカンドライフマガジン」の Vol.2 の 「特集1 2008年 春のセカンドライフ 何でもはじめてみよう!」の「セカンドライフの出来事を録画してアップしたい」を寄稿させていただきました。



先日、編集部の方から雑誌が届き、、、私の稚拙な文章をほんとうによくまとめていただきました。 また、縦書きの雑誌って、、、カタカナ・英語が多い記事・内容はちょっとつらいかもね。

いくつか記事を書いているときと状況が変わっているものがあるのと、補足したほうがいいのがあるので、、、ここに書いちゃいます(笑

[追記]

・ カメラワーク

カメラワークで ALT+マウス操作の部分は「左クリック(=普通にやるクリック)」になっていますが、ALT+CTRL/ALT+CTRL+SHIFT は「左クリック」のところが「右クリック」になっています。最初、右クリックと間違った記述をして、その後「左クリック」に修正してください、と頼んだのですが、ALT+マウス操作の部分だけ修正されたようです。混乱した方ごめんなさい。

[追記おわり]

・ 動画ファイルのエンコード

まず、、、画像がね、ちょっと違うものが入り込んじゃってるw
P40 の 「Expression Encoder でエンコードする」の 04 の画像は Fraps.... (笑
文章通り、[出力] タブから指定してくれればいいのですが。。。混乱された方はごめんなさい。

実は最初 SUPER(C) や Media Coder などメジャーなエンコードソフトの話を書いていたのですが誌面に収まりきれず、また、対象が「はじめてのユーザー」ということから、思い切って Expression Encoder に絞ったという経緯がありました。
雑誌に書かれている URL だともしかすると新しく出ている Encoder 2 というベータ版をダウンロードしかねないので、以下のリンク/URLをクリックしてもらうと助かるのですが・・・(笑

http://www.microsoft.com/japan/products/expression/expression-studio/free-trial.mspx#encoder

60日評価版と書かれていますが、その下のほうに 180日まで拡張できるプロダクトコードがあるのでそれを [ヘルプ] - [プロダクトキーの入力] にて入力してください。

エンコーダについての過去の私の顛末はこちらの投稿を(笑

ムービー変換考察(1)
ムービー変換考察(2)
ムービー変換考察(3)

・ 動画の編集とBGM公開

ほんと、編集については「書けるほどのレベルじゃない」ことは重々承知しています。いつも「あー、ここ失敗したぁ、、、」なんてシーンがありますから。このあたりはご容赦ください。
動画に使う楽曲についてですが、かなり動きがありましたね。ちょっと注意しなきゃいけないのは楽曲使用については「どの共有サービスを使うか」という点ですべて物事が進んでいるようです。アーティスト、レーベル別、、、というものではなく、YouTube なら OK、他はだめ、、、みたいな括りですね。
JASRAC と各動画共有サービスプロバイダーとの「包括利用契約」が遅々と進まない中でミスチルの曲が YouTube での楽曲使用を認める、という記事が出ました。ミスチル「ら」の曲って JASRAC 管理じゃなくて、JRC という会社が管理しているのですね。JRC はミスチル、浜田省吾、布袋さん、L'Arc-en-Ciel、スピッツ、、といったアーティストの約5,000曲を管理しているということ。
「ミスチルらの楽曲の演奏・合唱、ユーチューブに使用許可」(asahi.com へリンク)
JRC(ジャパン・ライツ・クリアランス)の公式発表はこちら。
03/27/2008 JRC「YouTube™」の日本における音楽著作権の包括利用許諾契約を締結
このあたりの流れ・動きはまだまだウォッチが必要ですね。
それと、、、記事のほうには「できないじゃん、残念。。。」と書いてあった日本向け video.msn.com のユーザー投稿サービスですが、これも今は可能になりました。
「MSNビデオ」で動画共有サービス「Soapbox」日本語版開始(impress internet watch へリンク) [追記 2009 : Soapbox のユーザー投稿サービスは終了しました]
私の投稿していたビデオに日本語で「セカンドライフ」というタグをつけたので、「セカンドライフ」で検索すると Soapbox ユーザービデオの結果でビデオを見ることが可能になりました(笑 うん、前はできなかったんですよ。
と、ちょっとしたアップデートでした。
ということで日本語の video.msn.com YouTube の「ビデオの埋め込み」を使った貼り付けは以下w