ソラマメブログ
< 2012/01 >
S M T W T F S
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 31        

2009/11/21

カメラコントロール(リンデンスクリプト Tips)

アバターのカメラをコントロールします。3つの視点を登録可能です。
登録した視点に瞬時に切り替えることが可能です。
また、視点のズームインやズームアウトも可能です。
POPや動画の撮影とかに良いかもですw

「スクリプト内容」
//
//    SHOP ZERO Tips43 CameraControl Script   v1.0
//
//                   Created by Zero2000 Kid     2009/11/21
//                   
 
 
integer handle;
integer input_ch=-43;
list mlist=["Set1","Set2","Set3","Camera1","Camera2","Camera3","Zoom-IN","Zoom-OUT","Release"];
list cameraposlist=["","",""];
list camerarotlist=["","",""];
vector ZoomIN_offset=<5,0,0>;
vector ZoomOUT_offset=<-5,0,0>;
 
CameraControl(vector camerapos,rotation camerarot) {
    vector offset=<0.1,0,0>;
    vector cameraview=offset * camerarot + camerapos;
    llSetCameraParams([
        CAMERA_ACTIVE, 1,
        CAMERA_POSITION, camerapos, 
        CAMERA_POSITION_LOCKED, TRUE,
        CAMERA_FOCUS, cameraview,
        CAMERA_FOCUS_LOCKED, TRUE
    ]);
}
 
default
{
    state_entry() {
        llSetText("CameraControl", <1,1,1>, 1);
        llRequestPermissions(llGetOwner(), PERMISSION_TRACK_CAMERA | PERMISSION_CONTROL_CAMERA); 
    }
 
    touch_start(integer t) {
        handle = llListen(input_ch, "", llDetectedKey(0), "");
        llDialog(llDetectedKey(0), "Please select menu.", mlist, input_ch);
    }
 
    listen(integer ch, string name, key id, string message) {
        if (message=="Release") {
            llClearCameraParams();
            llListenRemove(handle);
        } else if (llSubStringIndex(message,"Zoom")!=-1) {
            vector camerapos=llGetCameraPos();
            rotation camerarot=llGetCameraRot();
            vector offset;
            if (message=="Zoom-IN") offset=ZoomIN_offset;
            else if (message=="Zoom-OUT") offset=ZoomOUT_offset;
            camerapos=offset * camerarot + camerapos;
            if (camerapos) CameraControl(camerapos,camerarot);
            llDialog(id, "Please select menu.", mlist, input_ch);
        } else if (llSubStringIndex(message,"Camera")!=-1) {
            integer number=(integer)llGetSubString(message,-1,-1);
            vector camerapos=llList2Vector(cameraposlist,number-1);
            rotation camerarot=llList2Rot(camerarotlist,number-1);
            if (camerapos) CameraControl(camerapos,camerarot);
            llDialog(id, "Please select menu.", mlist, input_ch);
        } else if (llSubStringIndex(message,"Set")!=-1) {
            integer number=(integer)llGetSubString(message,-1,-1); 
            vector camerapos=llGetCameraPos();
            rotation camerarot=llGetCameraRot();
            cameraposlist=llListReplaceList(cameraposlist,[camerapos],number-1,number-1);
            camerarotlist=llListReplaceList(camerarotlist,[camerarot],number-1,number-1);
            llListenRemove(handle);
        }
    }
 
    attach(key id){
        if (id){
            llRequestPermissions(llGetOwner(), PERMISSION_TRACK_CAMERA | PERMISSION_CONTROL_CAMERA); 
        }
    }
}
 
「セットアップ」 1. オブジェクトを1つ作成します。(球でもボックスでも何でも構いません。) 2. オブジェクトにスクリプトをドラッグします。 3. オブジェクトをHUDとして装着します。 以上です。 「使用方法」 1. 登録したいポイントに視点を移動します。 2. HUDをクリックして、青いダイアログからSet1をクリックします。 (視点が登録されます) 3. 追加でCamera2,Camara3を登録する場合は、視点を移動してSet2,Set3をクリックしてください。 4. ESCキーを一度押します。 5. (視点がアバターの位置に戻ります) 6. HUDをクリックして、青いダイアログからCamera1をクリックします。 7. 視点が先ほど登録したポイントに移動します。 8. ズームインやアウトしたい場合は、Zoom-INまたは、Zoom-OUTをクリックします。 9. 視点を戻す場合は、ダイアログからReleaseをクリックします。 * ズームの比率は、5m単位になっています。変更したい場合は、 下記のパラメータを変更して下さい。 vector ZoomIN_offset=<5,0,0>; vector ZoomOUT_offset=<-5,0,0>; * カメラは、SIM内どこでも移動可能ですが、アバターからの距離が離れすぎると  正確な映像は表示されません。正確な映像が表示される範囲は、あくまで  手動でカメラを操作可能な範囲内です。スカイに居ながら地上のアバターの  様子を見たりすることはできませんのであしからずw 「スクリプトの説明」 このスクリプトのポイントは、どのようにしてアバターの視点を決定するかという点です。 アバターの視点を操作するには、llSetCameraParams()という関数を使用しますが、 この関数には、引数として2つの情報を与える必要があります。 CAMERA_POSITIONとCAMERA_FOCUSです。 具体的には下記のような座標になります。 (1) CAMERA_POSITION : アバターのカメラの座標 (2) CAMERA_FOCUS : カメラと目標物を結んだ直線上の任意の座標(焦点の座標) この2点が求められればllSetCameraParams()を使用してアバターの視点を決定することが可能です。 CAMERA_POSITIONは、llGetCameraPos()を使って取得することが可能です。 CAMERA_FOCUSは、下記の計算式から求めることが可能です。 CAMERA_FOCUS = <オフセット座標> * <カメラのローテーション> + CAMERA_POSITION カメラのローテーションとは、カメラの方向を表わす数値で、llGetCameraRot()を使って 取得可能です。オフセット座標には、カメラの座標からの相対距離を指定します。 オフセット座標はvector値で表し、例えば<0.1,0,0>を指定した場合、カメラの向き(X方向) に向かって正方向に0.1m移動した座標を返します。また、<0,0,0.1>を指定した場合は、 カメラの向きの上方向(Z方向)に向かって正方向に0.1m移動した座標を返します。 今回は、カメラの座標と目標物を結んだ直線上の任意の点を求めるのでオフセットの値には、 X要素に値をセットします。スクリプトの中では、下記の部分に当たります。 vector offset=<0.1,0,0>; // X軸の正方向へ0.1mのオフセット vector cameraview=offset * camerarot + camerapos; // カメラからX軸の正方向へ0.1m先の座標 上記のスクリプトでは、カメラの向き(X方向)に向かって正方向に0.1m移動した座標を返して います。この座標は、視点の向きを知るためだけに必要な情報なので、カメラから正方向の X線上にあれば1m先でも10m先でも構いません。また、CAMERA_POSITIONとCAMERA_FOCUSの座標を X軸上で移動してあげれば、視点のズームインやズームアウトが可能になります。 スクリプトの流れですが、以下の通りです。 (1) カメラ情報取得の為のパーミション要求。 (2) アバターの視点を決定する為に必要な情報を取得。 (3) 取得した情報を元にカメラのパラメータをセット。 llSetCameraParams()の実行には、PERMISSION_CONTROL_CAMERAのパーミションが必要です。 llGetCameraPos()とllGetCameraRot()の実行には、PERMISSION_CONTROL_CAMERAのパーミションが必要です。 それぞれのパーミションを得るために、HUDを装着した時にパーミションの取得をします。 attach(key id){ if (id){ llRequestPermissions(llGetOwner(), PERMISSION_TRACK_CAMERA | PERMISSION_CONTROL_CAMERA); } } PERMISSION_TRACK_CAMERA | PERMISSION_CONTROL_CAMERA というように2つの パーミションを | で繋ぐと同時に2つのパーミションを取得することが可能です。 次にダイアログからSetというボタンが選ばれたときは下記の処理を実行します。 integer number=(integer)llGetSubString(message,-1,-1); vector camerapos=llGetCameraPos(); rotation camerarot=llGetCameraRot(); cameraposlist=llListReplaceList(cameraposlist,[camerapos],number-1,number-1); camerarotlist=llListReplaceList(camerarotlist,[camerarot],number-1,number-1); まずセットするカメラの番号を取得します。number=llGetSubString(message,-1,-1)を 実行すると文字列の最後尾の文字列を取得することが可能です。例えばmessageにSet1と いう文字列が入ってきたときは、変数numberには、1が入ります。次にllGetCameraPos() でカメラの座標、llGetCameraRot()でカメラの方向(ローテーション)を取得します。 取得した値は、それぞれcameraposlistとcamerarotlistのカメラのnumber番目に格納します。 リストは0番目から始まるので、number-1という感じで-1しています。 ダイアログからCameraが選ばれると下記の処理を実行します。 integer number=(integer)llGetSubString(message,-1,-1); vector camerapos=llList2Vector(cameraposlist,number-1); rotation camerarot=llList2Rot(camerarotlist,number-1); if (camerapos) CameraControl(camerapos,camerarot); llDialog(id, "Please select menu.", mlist, input_ch); まず視点をセットするカメラの番号を取得します。 次にその番号を元に情報が格納されているリスト(cameraposlist,camerarotlist)から カメラの座標とカメラの方向(ローテーション)の情報を取得します。 取得した情報は、関数CameraControlに引数として渡されます。 CameraControl(vector camerapos,rotation camerarot) { vector offset=<0.1,0,0>; vector cameraview=offset * camerarot + camerapos; llSetCameraParams([ CAMERA_ACTIVE, 1, CAMERA_POSITION, camerapos, CAMERA_POSITION_LOCKED, TRUE, CAMERA_FOCUS, cameraview, CAMERA_FOCUS_LOCKED, TRUE ]); } 関数CameraControlでは、渡された引数をもとにCAMERA_FOCUSの値を計算し、 llSetCameraParamsを実行します。 セットされた視点を開放するには、llClearCameraParams()を実行します。 llClearCameraParams()を実行するとカメラはデフォルトの位置(アバターの背後) に移動し、キーボードで視点の操作が可能になります。 リンデンスクリプト Tips Indexへ

この記事へのトラックバックURL