3Dの醍醐味と言ったらダイナミックに動き回るオブジェクトと視点です。
変形の種類を考えてみます。
まずは移動ですね。もしも全部のものが、同じ場所にあったら意味無いですよね。
次は回転です。いつも同じ方向を向いていても仕方ないですよね。
最後に拡大縮小です。
拡大縮小は物にたいしてしなければいけませんが、移動と回転は次の二通りで表現することが出来ます。
どちらが良いでしょうか?と聞きたいところですが、有無を言わさず1番を選ばせて頂きます。何故か?カメラを回転させたら、時々しか見えないではありませんか。もちろんある一点を見ながらカメラを回すことも出来ます。Direct3Dにとっては朝飯前です。ですが、コードの内容はちょっと面倒なので今回は却下です。暇があったらやってみましょう。
というわけで、物を移動させるのですが、頂点の座標をいちいち書き換えたりなどしません。めんどくさいです。そんなとき役に立つのが、ワールド変換です。簡単に言うと、ものを動かすのは嫌だから世界が動けというわけです。
device_.Transform.World = Matrix.~(~);
世界を動かすときにはここに「行列(Matrix)」と呼ばれる物を上の所にセットします。行列(Matrix)については・・・後で説明します。「変形の手順が入っている物」と覚えておけばいいです。
ちなみに「Transform」は変形させると言う意味です。
3Dには三つの軸があります。X,Y,Zです。移動ではそれぞれの軸について平行に移動させます。
device_.Transform.World = Matrix.Translation(2,2,2);
このコードを「BeginScene」の前に入れるだけです。
左から、(x,y,z)の移動です。いじってみてください。
回転は下のコードで行うことが出来ます。
device_.Transform.World = Matrix.RotationY(Environment.TickCount /300f);
移動と同じく、このコードを「BeginScene」の前に入れるだけです。
これらのそっくりさんとして、「RotationX」と「RotationZ」もあります。軽く説明しますと、引数(ラジアン)分だけその軸を中心に世界を回転させます。「Environment.TickCount」はシステム起動後の時間をミリ秒単位で教えてくれます。結構重宝します。
回転させてみると分かるのですが、この状態だと、半回転分の時間三角形が消えてしまいます。何故か分かりますか?
答えはDirect3Dが三角形の裏側を描画していないからです。何故そんなことをするのかって?それは高速化のためです。面には裏表があります。そこで、Direct3Dでは裏の面を描画しない事によって高速化を行っているのです。つまり、見えなかった部分はDirect3Dから、裏であるとされ描画が行われなかったのです。これを背面カリングと呼びます。(「cull」は『摘む、より抜く』と言う意味です)
この問題は意外と簡単に解決します。方法は二つあって「三角形を2まい重ねる」方法と「裏も描画するようにする」方法があります。今回は裏も描画するようにしましょう。
device_.RenderState.CullMode = Cull.None;
これを「BeginScene」の前に付け加えてください。これで私が想像した通り動くはずです。
下のコードでは拡大縮小を行うことが出来ます。
device_.Transform.World = Matrix.Scaling(2,2,2);
これも左から(x,y,z)方向への拡大縮小です。
ちょっと勉強しましょう。面の裏表はこちらから見たときに頂点が時計回りに配置されているかどうかで決まります。「時計回り=表」「反時計回り=裏」です。ですが1つ注意。「三角形ストリップ」は偶数番の三角形の時、裏表が反転します。
下は列挙型Cullの一覧です。ここで示した側をカリングします。
通常時は「CounterClockwise」になっています。
ごちゃごちゃしてしまってごめんなさい。