トップページ > 過去ログ > 記事閲覧
カメラの平面移動
名前:シスマ 日時: 2012/02/11 01:41

DXライブラリを使用して3Dモデルを描写するプログラムを製作しています。 そこでマウスでカメラの移動が出来るようにしたいです。 やりたい移動は3種類で、以下の通りです。 ・球面移動(注目点を中心に注目点とカメラの距離が常に一定のまま360度回転する) ・平面移動(現在カメラが向いている方向に対し垂直方向に移動) ・ズーム(注目点とカメラの距離を変える) 上記のカメラ移動は、3DCG作成ソフトなどでよく実装されているカメラ移動をイメージしています。 特に3Dモデル作成ソフトのメタセコイアと同じカメラ移動です。 このうち、球面移動とズームは実装できたのですが、平面移動は全く出来ません。 何度も作ってみても、ぐちゃぐちゃな移動になってしまいます。 この実装をするにはどうしたらよいのでしょうか? どうかよろしくお願いします。

Page: 1 |

Re: カメラの平面移動 ( No.1 )
名前:すにー 日時:2012/02/11 22:30

SetCamera〜 のどれを使っていますか?
Re: カメラの平面移動 ( No.2 )
名前:いっち 日時:2012/02/12 20:08

やってみましたが、できていないかもしれません・・・。 基本的には「DXライブラリ サンプルプログラム」の「32.3Dアクション基本」とあまり変わらないと思います。 (視点を動かさずにカメラの位置だけ平行移動させるのかもとも思ったのですが、とりあえず視点ごと平行移動しています) ※少し修正 //- 以下、テストコード ("SimpleModel.mqo" を使用) -// #include "DxLib.h" #include <math.h> struct CAMERA_INFO { VECTOR position; // Relative to Target VECTOR target; VECTOR head; }; void init_camera( CAMERA_INFO& camera ) { camera.position = VGet( 0.0f, 0.0f, -800.0f ); camera.target = VGet( 0.0f, 0.0f, 0.0f ); camera.head = VGet( 0.0f, 1.0f, 0.0f ); } int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) { const float rot_rate = PHI_F * 2.0f / 60.0f; const float move_rate = 5.0f; ChangeWindowMode( TRUE ); SetWindowText( "DxLib:" DXLIB_VERSION_STR ); if ( DxLib_Init( ) == -1 ) return -1; int white = GetColor( 255, 255, 255 ); int mh = MV1LoadModel( "SimpleModel.mqo" ); SetDrawScreen( DX_SCREEN_BACK ); CAMERA_INFO camera; init_camera( camera ); MATRIX matrixtemp; while ( ProcessMessage( ) == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) { ClearDrawScreen( ); if ( CheckHitKey( KEY_INPUT_SPACE ) ) { init_camera( camera ); } else if ( CheckHitKey( KEY_INPUT_LSHIFT ) ) { if ( CheckHitKey( KEY_INPUT_UP ) ) { camera.target = VAdd( camera.target, VScale( VNorm( camera.head ), move_rate ) ); } if ( CheckHitKey( KEY_INPUT_DOWN ) ) { camera.target = VAdd( camera.target, VScale( VNorm( camera.head ), -move_rate ) ); } if ( CheckHitKey( KEY_INPUT_LEFT ) ) { camera.target = VAdd( camera.target, VScale( VNorm( VCross( camera.position, camera.head ) ), -move_rate ) ); } if ( CheckHitKey( KEY_INPUT_RIGHT ) ) { camera.target = VAdd( camera.target, VScale( VNorm( VCross( camera.position, camera.head ) ), move_rate ) ); } if ( CheckHitKey( KEY_INPUT_Z ) ) { camera.target = VAdd( camera.target, VScale( VNorm( camera.position ), -move_rate ) ); } if ( CheckHitKey( KEY_INPUT_X ) ) { camera.target = VAdd( camera.target, VScale( VNorm( camera.position ), move_rate ) ); } } else if ( CheckHitKey( KEY_INPUT_RSHIFT ) ) { if ( CheckHitKey( KEY_INPUT_UP ) ) { if ( VSize( camera.position ) > 300.0f ) { camera.position = VAdd( camera.position, VScale( VNorm( camera.position ), -move_rate ) ); } } if ( CheckHitKey( KEY_INPUT_DOWN ) ) { if ( VSize( camera.position ) < 2000.0f ) { camera.position = VAdd( camera.position, VScale( VNorm( camera.position ), move_rate ) ); } } } else { if ( CheckHitKey( KEY_INPUT_UP ) ) { matrixtemp = MGetRotAxis( VCross( camera.position, camera.head ), rot_rate ); camera.position = VTransform( camera.position, matrixtemp ); camera.head = VTransform( camera.head, matrixtemp ); } if ( CheckHitKey( KEY_INPUT_DOWN ) ) { matrixtemp = MGetRotAxis( VCross( camera.position, camera.head ), -rot_rate ); camera.position = VTransform( camera.position, matrixtemp ); camera.head = VTransform( camera.head, matrixtemp ); } if ( CheckHitKey( KEY_INPUT_LEFT ) ) { matrixtemp = MGetRotAxis( camera.head, rot_rate ); camera.position = VTransform( camera.position, matrixtemp ); camera.head = VTransform( camera.head, matrixtemp ); // いらない? } if ( CheckHitKey( KEY_INPUT_RIGHT ) ) { matrixtemp = MGetRotAxis( camera.head, -rot_rate ); camera.position = VTransform( camera.position, matrixtemp ); camera.head = VTransform( camera.head, matrixtemp ); // いらない? } if ( CheckHitKey( KEY_INPUT_Z ) ) { matrixtemp = MGetRotAxis( camera.position, -rot_rate ); camera.position = VTransform( camera.position, matrixtemp ); // いらない? camera.head = VTransform( camera.head, matrixtemp ); } if ( CheckHitKey( KEY_INPUT_X ) ) { matrixtemp = MGetRotAxis( camera.position, rot_rate ); camera.position = VTransform( camera.position, matrixtemp ); // いらない? camera.head = VTransform( camera.head, matrixtemp ); } } SetCameraPositionAndTargetAndUpVec( VAdd( camera.target, camera.position ), camera.target, camera.head ); DrawPixel3D( camera.target, white ); DrawLine3D( VGet( 0.0f, 0.0f, 0.0f ), VGet( 1000.0f, 0.0f, 0.0f ), GetColor( 255, 0, 0 ) ); DrawLine3D( VGet( 0.0f, 0.0f, 0.0f ), VGet( 0.0f, 1000.0f, 0.0f ), GetColor( 0, 255, 0 ) ); DrawLine3D( VGet( 0.0f, 0.0f, 0.0f ), VGet( 0.0f, 0.0f, 1000.0f ), GetColor( 0, 0, 255 ) ); MV1DrawModel( mh ); DrawFormatString( 0, 0, white, "position x=%f y=%f z=%f size=%f", camera.position.x, camera.position.y, camera.position.z, VSize( camera.position ) ); DrawFormatString( 0, 20, white, "target x=%f y=%f z=%f size=%f", camera.target.x, camera.target.y, camera.target.z, VSize( camera.target ) ); DrawFormatString( 0, 40, white, "head x=%f y=%f z=%f size=%f", camera.head.x, camera.head.y, camera.head.z, VSize( camera.head ) ); ScreenFlip( ); } DxLib_End( ); return 0; }
Re: カメラの平面移動 ( No.3 )
名前:シスマ(解決) 日時:2012/02/13 21:40

>すにーさん SetCameraPositionAndTarget_UpVecYです。 >いっちさん サンプルソースありがとうございます! 私のソースに上手く組み込めました。 私が今まで作っていたものは、球面移動を無駄に複雑に作りすぎてしまっていたようで、それが悪かったみたいです。 やりたいことの実装が出来ましたので解決にしたいと思います。 本当にありがとうございました。
ちなみに... ( No.4 )
名前:みや 日時:2014/02/23 03:04

少し思ったので書いておきます><; オブジェクトを中心とした球面移動なら、 x1 = cos(上下回転ラジアン)*オブジェとの距離 y = sin(上下回転ラジアン)*オブジェとの距離標Y x2 = sin(左右回転ラジアン)*x1 z = cos(左右回転ラジアン)*x1 で、 SetCameraPositionAndTarget_UpVecY(VGet(x1+ターゲットX,y+ターゲットY,z+ターゲットZ),(ターゲットX,ターゲットY,ターゲットZ)) でOKです。 変数を使用すると、 // x1 = cos(ZAxisturn)*Distance; y = sin(ZAxisturn)*Distance; z = cos(YAxisturn)*x1; x2 = sin(YAxisturn)*x1; SetCameraPositionAndTarget_UpVecY(VGet(x1+tarX,y+tarY,z+tarZ),VGet(tarX,tarY,tarZ)); // これで終了です。 マウスで動かしたい時は、 あらかじめdouble mxa,mya,mxb,myb,mcx,mcy int MX,MY,MInputでwhile文の前に0で初期化しておいて、 mxb=MX; myb=MY; GetMousePoint(&MX,&MY); mxa=MX; mya=MY; mcx=mxa-mxb; mcy=mya-myb; MInput = GetMouseInput(); if(MInput & MOUSE_INPUT_LEFT){ ZAxisturn += mcy*3.14159265358979/180; YAxisturn += mcx*3.14159265358979/180; } mcx *= 0.9; mcy *= 0.9; // みたいにすると、マウスで回転でき、さらになめらかな操作になると思います。 もしよかったら試してみてください。><;
Re: カメラの平面移動 ( No.5 )
名前:みや 日時:2014/02/23 03:07

上から3、4行目に 「オブジェクトとの距離標Y」 となっていると思いますが、 「オブジェクトとの距離」の間違いです。

Page: 1 |