モデリングツールのようなカメラ制御

マウスで3D空間をぐりぐりと動かして、いろんな角度からワールドを観察したいという話。

2chで学んだ方法。

カメラの初期位置をXZ平面内、注視点を原点、上ベクトルを(0,1,0)にしておいて、行列変換でカメラ空間ごとぶん回す。

const D3DXVECTOR4 INIT_EYE(0.0f, 0.0f, -1000.0f, 1.0f);
const D3DXVECTOR4 INIT_AT (0.0f, 0.0f, 0.0f, 1.0f);
const D3DXVECTOR4 INIT_UP (0.0f, 1.0f, 0.0f, 0.0f);

D3DXMATRIX mat, scale, rot, trans;
D3DXMatrixIdentity(&mat);

//パンなので、移動を先に合成する
D3DXMatrixTranslation(&trans, panX, panY, 0.0f);
D3DXMatrixMultiply(&mat, &mat, &trans);

//回転
D3DXMatrixRotationX(&rot, rotX);
D3DXMatrixMultiply(&mat, &mat, &rot);
D3DXMatrixRotationY(&rot, rotY);
D3DXMatrixMultiply(&mat, &mat, &rot);

//ヨーピッチロールでも同じ
//D3DXMatrixRotationYawPitchRoll(&rot, rotY, rotX, 0.0f);

D3DXVECTOR4 eye, at, up;
D3DXVec4Transform(&eye, &INIT_EYE, &mat);
D3DXVec4Transform(&at, &INIT_AT, &mat);
D3DXVec4Transform(&up, &INIT_UP, &mat);

D3DXMatrixLookAtLH(&view, (D3DXVECTOR3*)&eye, (D3DXVECTOR3*)&at, (D3DXVECTOR3*)&up);

あとはパン移動量と回転角度をマウスで増減するようにすればいいだけ。
カメラを横倒しにしたかったら、Xの前にZ回転を入れる。
上ベクトルの初期値でwが0なのがポイント。上ベクトルは方向であって点の座標を表現しているわけではないので、平行移動は適用されてほしくないから。
ズームはスケール変換でもできるかもしれんが、普通に視野角でやるのがよさそう。