C#でツールを作る その8 -カメラの制御-
3Dのツールなので、マウスのドラッグ・ホイールによるカメラの制御は必須です。
ということで、以下の機能を追加します。
- 右ドラック:カメラの回転
- ホイール:ズーム
サンプル
- tool08.zip
- VisualC#2008EE用
極座標
カメラの回転の実装方法はいろいろありますが、今回は極座標で求めます。
wikiの解説とDirect3Dの軸の向きは異なるので、無理やり合わせます。
float X = ( float )( r * Math.Sin( theta ) * Math.Cos( phi ) ); float Y = ( float )( r * Math.Cos( theta ) ); float Z = ( float )( r * Math.Sin( theta ) * Math.Sin( phi ) );
View(UserControl1)にマウスのイベントハンドラを追加
- アプリケーションのコンストラクタでMouseMoveイベント、MouseWheelイベントを追加
- 北極、南極付近でジンバルロックが起こらないよう調整
- θを0°以下、180°以上にしない
- とりあえずズームの増加量は適当
private Point prev_mouse; private float theta = 45.0f; private float phi = -45.0f; private float zoom = 45.0f; public Hoge() { view = new UserControl1(); view.Paint += new PaintEventHandler( Paint ); view.MouseMove += new MouseEventHandler( view_MouseMove ); view.MouseWheel += new MouseEventHandler( view_MouseWheel ); MainForm = new Form1( view ); MainForm.Disposed += new EventHandler( ReleaseDevice ); } private void view_MouseMove( object sender, MouseEventArgs e ) { if( e.Button == MouseButtons.Right ) { float x = ( float )( e.Location.X - prev_mouse.X ) * 1.0f; float y = ( float )( e.Location.Y - prev_mouse.Y ) * 1.0f; phi -= x; theta -= y; if( theta >= 180.0f ) { theta = 179.99f; } if( theta <= 0.0f ) { theta = 0.01f; } view.Refresh(); } prev_mouse = e.Location; } private void view_MouseWheel( object sender, MouseEventArgs e ) { zoom -= e.Delta / 120.0f * 3; if( zoom < 0.0f )zoom = 1.0f; if( zoom > 180.0f )zoom = 179.0f; view.Refresh(); }
ビュー行列の設定
- degreeからradianへの変換
- Geometry.DegreeToRadian
float r = 5.0f; //半径 float t = Geometry.DegreeToRadian( theta ); float p = Geometry.DegreeToRadian( phi ); Vector3 v = Vector3.Empty; v.X = ( float )( r * Math.Sin( t ) * Math.Cos( p ) ); v.Y = ( float )( r * Math.Cos( t ) ); v.Z = ( float )( r * Math.Sin( t ) * Math.Sin( p ) ); device.Transform.View = Matrix.LookAtLH( v, //カメラ座標 new Vector3( 0.0f, 0.0f, 0.0f ), //注視点 new Vector3( 0.0f, 1.0f, 0.0f ) //カメラの真上方向 );