BlackSheep-LSL@Wiki カメラ制御
※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。


はじめに


最後に衝突について説明して初級スクリプト講座を終えようと思っていたのですが、最近、カメラのコントロールが意外に面白い効果を出せることに気づいたので、今回はカメラの制御について書きたいと思います。
SLで言うところのカメラとは、「視点」のことです。

通常、SLの視点はユーザーが自由に動かすことができます。
ALTを押しながらアバターを左クリックすると、そのアバターに注目したりもできますね。
結構自由なカメラコントロールが許されていて、私のように趣味でムービーを作る者にとっては重宝しています。

スクリプトからカメラをコントロールする方法も用意されており、これがまたムービー作成には非常に便利です。
どういうことかと言うと、撮影用の椅子を用意しておき、そこに座ると必ず特定の位置に視点が定まるようにできるのです。
例えば建物の建設の様子などを定期的に定点撮影したい、などという場合にも使えます。

カメラコントロール


カメラのコントロールは凝りだすと結構細かいところまで制御可能なのですが、今回扱うのはごく簡単なものだけにしておきます。
作成するものは「座ると特定の位置に視点が固定される椅子」です。

私はこれを使って映画館の椅子を作りました。
座ると視点が勝手にムービーのスクリーンに固定されるものです。
応用としては、座ると遠景が見える望遠鏡とか、乗り物に乗ったときに運転席からの視点にするなどが考えられます。

使う関数は二つです。
一つは、カメラの位置を決める関数llSetCameraEyeOffsetです。
もう一つは、カメラの向き(どこを見るか)を決める関数llSetCameraAtOffsetです。

これらの関数は「アバターがオブジェクトに座ったとき」の視点をコントロールします。
llSitTarget?関数と同様、あらかじめ設定しておかなければ動作しません。
現在座っているアバターの視点を変えられるわけではありませんので注意して下さい。

それぞれの関数について見てみましょう。

llSetCameraEyeOffset(vector offset);


この関数はアバターがオブジェクトに座ったときのカメラの位置を設定します。
引数offsetはオブジェクトからの相対位置です。
例えば、offsetに<0.5, 0.0, 1.0>という値を設定すると、カメラはオブジェクトからX方向に0.5m、Z方向に1m移動した場所にセットされます。

llSetCameraAtOffset(vector offset);


こちらの関数はアバターがオブジェクトに座ったときのカメラの向きを設定します。
引数offsetはカメラが向く方向(相対位置)です。
例えば<0.0, 0.0, 2.0>という値を設定すると、カメラはオブジェクトのZ方向2mの位置を向きます。

少々わかりにくいので図にしてみました。


この図では、カメラはオブジェクトからX方向2m・Z方向4.5mの位置から、Xマイナスの方向を見ることになります。
クライアントの視界となる位置に、見せたいものを配置しておけば、このオブジェクトに座った人は皆同じ景色を見ることができます。

定点カメラスクリプト


カメラの位置が相対指定というのは少々わかりにくいので、絶対座標で指定できるようなスクリプトを組んでみます。
ただし、回転を考慮しませんので、座るためのオブジェクトの回転はゼロである必要があります。

vector sit_pos = <0.0, 0.0, 0.5>;
vector sit_rot = <0.0, 0.0, 0.0>;
vector c_pos = <102.0, 70.0 ,24.5>;
vector c_vec = <97.5, 70.0 ,24.5>;

set_view(){
  vector object_pos=llGetPos();
  llSetCameraEyeOffset(c_pos - object_pos);
  llSetCameraAtOffset(c_vec - object_pos);
}

default {
  state_entry(){
    llSitTarget(sit_pos, llEuler2Rot(sit_rot * DEG_TO_RAD));
    set_view();
  }
  
  moving_end(){
    set_view();
  }
}

変数sit_posとsit_rotはオブジェクトに座る位置を指定するための値です。
state_entryの中でllSitTarget?関数に使っているだけです。

c_posはカメラの位置を指定します。
相対座標ではなく絶対座標です。
同じく、c_vecはカメラの見る点(視線の方向)を絶対座標で指定するものです。

ユーザー関数set_view()の中で、c_posとc_vecの値を使ってカメラ位置を設定しています。
まずllGetPos()関数でオブジェクトの位置を取得し、c_pos及びc_vecから減算することで、相対座標に変換します。
こうして求めた相対座標をllSetCameraEyeOffset関数とllSetCameraAtOffset関数に渡しています。

このようにすると、オブジェクトの位置がどうであろうと、特定の位置に視点が固定されます。
とは言っても、llSetCameraEyeOffset関数やllSetCameraAtOffset関数で指定できる値には限界値があると思いますので(未確認です。多分10メートル程度ならば問題ないでしょう)遠く離れた場所までは見れないかもしれませんが(^^;

一つだけ見慣れないイベントがありますね。

 moving_end(){
    // 移動し終わったときの処理
 }

moving_endイベントはオブジェクトが「移動し終わったとき」に発生するイベントです。
ここではオブジェクトが移動したときに、カメラの相対位置を設定し直す為に使っています。

なお、「移動し始めたとき」のイベントは、

 moving_start(){
    // 移動し始めたときの処理
 }

ご想像通りかと思います。
試したことはないですが、乗り物などで「走り始めたとき」に音を鳴らしたいとかいう場合に使えるのではないでしょうか。

今回のポイント


  • 座ったときのカメラ位置の設定:

 llSetCameraEyeOffset(vector offset);

  • 座ったときのカメラの向く方向の設定:

 llSetCameraAtOffset(vector offset);

  • 移動系イベント:

 moving_start(){
    // 移動し始めたときの処理
 }

 moving_end(){
    // 移動し終わったときの処理
 }

なお、より高度なカメラ制御については、スクリプト小技の記事「高度なカメラ制御」を参照して下さい。
短めですが、今回はこれにて。

名前:
コメント: