Traktorとかハイトマップで検索をかけてみに来ていただいているのに、
全然更新できてないです。

仕事が多忙すぎて、XNAを触れていないのが現状・・・。

現在はArdurinoと3D加速度センサー、水平測定センサーを使ってXNAのモデルを動かしたいなと画策しており、
Midiに繋いで楽器にしちゃおうとかも考えてたりするのです。
Traktorが自分の作ったコントローラーで操作できたら面白そうじゃないですか?


と、思いつつどれも触れていない現状なんですけどね。


ぼちぼちやっていきます。
ついこの前
われらがNative InstrumentsからTraktorの最新バージョンがリリースされました。
Traktor Pro

これまではTraktor2しか使った事がなくて、もっとこうして欲しい。あれ欲しい。これ欲しい。
と思っていた機能がすべて盛り込まれているじゃないっすか。

4トラックのミックス。
リバーブとディレイとフィルタと、もろもろのエフェクタ。
キューのしやすさ。
ビート検出の精度アップ。
アイソレータ(っぽい)機能とか。

音も良いし、操作性も直感的にできるようになってる。
多少2とインターフェースが違っててどうするんだろって悩むけど、
すぐわかるし、むしろ邪魔なところ似なくてよくなってる。
説明書は一切読んでないけど、雰囲気で解るし、英語も簡単だし、インターフェースも解りやすいのですんなり出来た。

あとは、ネット放送ができるみたいだな。IPとかポートを指定するメニューがあったから。
ふむぅ、そいつわ、エロイな。すげーえろいぞ!


あれって思ったのは
2に比べて曲の再生までが少しとろくなった気がする。
Audioのデバイス選んだら音が出なくなる現象が時々起こる。少し時間がたつとなるようになるんだけど。
あとは、トラックコレクションのトラックをダブルクリックしても演奏が始まらないことかな。
ま、気にならない程度ですよ。

これ、すごいわぁ・・・。
メニューからBeatPortへのリンクがあるのがステキだわw
クラブミュージック好きなんでしょ?って言われてる気がする。
はい、その通りです。

とても素敵なアプリだ。音楽好きなら買ってもそんはない。
一日中ずっとさわってれるよ。
こいつの使い方もちらちら書いていこうかな。自分のために。
久しぶりにXNAねた。

これまでは自機の動きしか考えてなかったので、戦車っぽく弾の発射機能を考える。

昔いじってた玉転がりサンプルのHeightmapCollisionで試してみよう。
今回は適当に一発だけ打てればいいやという事で、
打ったかどうかを判定するboolをグローバルに宣言してあげる。

あとは、弾のModelクラスとそれの座標を計算するメソッドをUpdateに追加して、
Drowで描写すればよいのだ。
簡単だね!

なので、
追加するのは
 弾を打ったか判定するbool
 弾を表すModel
 弾の位置を表すVector3
 弾の撃った方向を表すMatrix
を適当だねって思う心を押さえ込んで、グローバルに宣言する。


で、まずはLoadContentで弾を読み込む。
    sphereBoll = Content.Load<Model>("sphere"); //めんどくさいので玉と同じModelをつかう

つぎに、イベントを拾うためにHandleInputにスペースを押された時の動作を入れる。
まず、弾打boolをtrueにする。

で、打った場所と方向を保持するために現在の位置を 弾の位置を表すVector3、弾の撃った方向を表すMatrixに保持する。
ただし、保持するのは初回だけ(falseがtrueになったとき)なのでif文にbool値を加える。

//スペース押されたら玉発射
if(currentKeyboardState.IsKeyDown(Keys.Space) && !isShoot){
isShoot = true;
spherePosition2 = spherePosition;
sphereRollingMatrix2 = sphereFacingMatrix; //向いている方向
}

変数名が・・・w


あとは時間がたつごとにspherePosition2が「上手く」変化していけば弾が向いてるほうに打てるはずなので、
vector3(0, 0, -8f)を作って、向いている方向を掛けてあげたものをspherePosition2に足してあげればいいんだね!
コードにするとこんな感じだね!

if(isShoot) {
Vector3 a = new Vector3(0f, 0f, -10f);

spherePosition2 += Vector3.Transform(a, sphereRollingMatrix2);

        //有る程度移動したら弾を消したいので
iss++;
if(iss > 120) {
iss = 0;
isShoot = false;
}

}

これをさっきの後ろに書いてあげればいいんだ。
ほら、簡単でしょ?(私はちょっと苦労しましたが)


実際動かしてみると、山を突っ切って移動しちゃうんですよ。
当たり前ですねw
弾はハイトマップ考慮してないですもんね。
弾もハイトマップに合わせて動かすのは簡単なので省略。

次は弾が壁にぶつかったときに爆発するようにする。
衝突判定と光を出すアニメ(サンプルがあったと)を・・・。


コンクールに入賞した作品凄いですねぇ、普通に売り出せるぜ。
ぼちぼちしていこう。
アナログでおねがいします。
針はうごかない方向でおねがいします。
できれば文字は使用しないでください。







真ん中に棒があって、
枠から光を当てて、できた影で時間が解るってのはどうよ?
時間がたつと光の当てる場所が変わるんだぜ!!
昼間は太陽で代用できるんだぜ!
その隙に太陽光発電だ!
エコも兼ね備えたスペシャルな時計!
携帯機器で写真を撮るとまったく関係ない写真が撮れる機能が欲しいZE。
撮った写真はサーバーに送られて、他の人が撮った写真が送られてくるとかでよいんだ。

やっとこ、TankをHightMapで動かすサンプルを追っかけれました。
前回のサンプルと内容は似ているが、新しいメソッドなども使われてて
行列が苦手な私にはちょっとチンプン・・・。

-------------
ってことで、
まずはハイトMAPを作るためのパイプランから、

<TanksOnAHeightmapPipeline>
基本的には前回と同じなんだが、
フィールドにNormalsというVector3の二次元配列が増えている。
何を入れているのかなぁと下を見に行くと

MAPの[x,z]のポジションを保持させると同時に
Vector3 normal = (Vector3)geometry.Vertices.Channels[VertexChannelNames.Normal()][i];
のように「頂点チャンネル」を突っ込んでる。

って、MSDNには知ってて当然のように書いてますが、
「頂点チャンネル」って何さ?

MSDN曰く、「頂点が持っている任意のデータ」だそうだ。
家にはグラフィック専門用語辞書なんて粋なものはないから、ググってみると
どーも、頂点が持っているプロパティのようなものらしい。
今回はVector3に突っ込んでるので、
その頂点での傾きを表すベクトルなんではないかと。
(まちがってたらごめんなさい)


で、それをパイプラインのwriterでNomalsを書き出します。


>>>>>>>>>Tank.csへ
続いて、Tankを見てみる。
大まかには前回のボールのサンプルと同じだが、
HandleInputメソッドで
heightMapInfo.GetHeightAndNormal(newPosition,out newPosition.Y, out normal);
を使用してnormalを作って、それを元にタンクの傾きを決定している。

>>>>>>>HeightMapInfo
ってことで、GetHeightAndNormalを見る
・・・とLerpという謎メソッドが多用されている。

説明を見ると線形補完ですと!
なにそれ?
Wikipediaによると、「2点から、2点を結ぶ線上のある1点を算出する事」のようである。
でも、いまはVector3のようなベクトルナンですけど?

うーん、
原点をO
normals[left, top] をA
normals[left + 1, top] をB
として、
その3点が表す平面上の点(ってかベクトル)を算出しているのだ。おそらく。
Aが今の座標で、Bが移動先の座標ってことですな。

それを頭とお尻で行って、車両の傾きを決定。
最後に、単位ベクトルにすることで、方向だけを持ったベクトルにして終了

これを、Tankにセットしてあげる事でMapに合わせた傾きを持たす事ができてるんですね。

-------------
と、半分解ったようなわかってないような状態ですが、
傾きは恐らくこのような計算で行うんでしょう。

このサンプルとは関係はないけれども、
オブジェクト(タンク)の描写、ロジックはオブジェクト自体にもたさないといけないですね。
ふむふむ。
「MSDNを見てないので憶測が大量に混ざった内容となっております」

mapの情報は前回のHeightmapCollisionと同じ。
ただし、ContentsTypeWriterでnomalsというVector3を書き出している。

nomalsはmapのMeshのVertexChannelのvector2次元配列。
x,z座標を指定すれば、その位置の傾きなどの情報が入っているという事だと思う。


それを、Tank.csのキー入力時の処理に、戦車の位置を変更するvector(Matirxだったかな?)に作用させて
戦車の傾きを作っている(ように見える)。



そのほかの処理では、そこまで気になるようなところはなかった?気がする。
ほぼ同じように見えてもちょっと違うかもしれないので一応目を通す。


<自己課題>
カメラワークの箇所を見て、
キー入力で視点変化をさせれるようにしてみよう。
最近忙しくて、XNAの勉強が進んでいない。
ballの移動に関しては、キー入力の処理メソッドを観れば
(これまでのサンプルを理解してれば)大体解ると思うので、
飛ばして、ついにタンクの移動に着手しようと思う。

テストで実行したら、ちゃんとタンクの右前がわに傾いていたりしていたので、
思ってたよりも凄そうだ。早くみたい。

ふと、ビルなどの移動はどうするんだろうと思ったけれども、それは今度の課題という事にしよう。



私事だが、
とてもうれしいことが2つ続き
とてもかなしいことが2つ続いた。

あまりにいろんなことが一度に訪れて状況が良くわからんくなった。
うれしいことはもんだいなしでうれしかった。
泣きすぎですね。嬉しいんやさ。
かなしいことのひとつは問題なさそうな感じ。
かなしいことのひとつがきにかかるので、でんわでもしよう。


ドレス姿が綺麗だった。
背がちょっと大きくなってたね。
だんなは猫背。
おもしろかった。
うれしかった。
たのしかった。
よかった。

今日は幸せなまま寝る。
多少の寝不足と、仕事で作業が出来てきたのでちらちら見てる暇もなくなってきたので徐々に読み解いていこう。
ざっと見た感じ、前回の衝突判定よりも理解がしやすいような感じ。

今回はプロジェクトが2つあり、MAPを作成するためのパイプライン関連と、ゲームのメインロジックの二つである。
このサンプルの肝は、前者のパイプラインの処理だ。(多分)

パイプラインが何をするためのものかというかというと、
 「Contentsに登録されているテクスチャ(二次元の画像)を読み込むときに、
 パイプラインにテクスチャを通して、ゴニョゴニョ変換してMapを作っちゃおー」
という事だ!

普通にGameクラスでテクスチャを読み込んで、そこでMapを作成していってもいいけれど、
色んなMapが有るゲームを作るときに毎回そんなのやってられないから、
テクスチャ読み込んだときにMapに変えてくれよ!

という要望を実現するためにある。(Contentsの内容を読み込む際に、好きな型に変換できるってことです)

----------
で大まかな用語は理解したので実際に中を見る。
パイプライン(HeightmapCollisionPipeline)の中には
HeightMapInfoContent.cs と TerrainProcessor.cs が入っている。
プロセッサというのが、パイプライン処理の中で「読み込んだContentsの方を変換する」のを担当する。
ここでハイトマップを作っていると思えばよい。

もう一個のほうは作成したMapを新しいContentsに登録するためのクラスだ(多分)
ContentTypeWriterというクラスを継承しているクラスがそれを担当する。
HeightMapInfoContentはBeanのようなものだろう。

TerrainProcessorは少し観辛いが、
テクスチャをビットマップに変換して深度から高さを作成しているようだ。
(Processメソッド内の最初のforループ)
では、ここでのテクスチャとは何か?

それは実際にMapを使ってるGameクラスのほうを観ればいい。
Terrain.bmpを使ってるみたいだ。
そのファイルを開くと、モノトーンのおしゃれぶった画像が表示される。
さっきのforループから察するに、このファイルで白ければ白いほど地面が高くなりそうだ。

むずむずする人はBMPを書き換えてひとまず遊んでみるのも良いだろう。私は遊んだ。画像は秘密だ。


Processメソッドに戻って、
もう、言うまでもないかもしれないがforループ内の
   position.Y = (heightfield.GetPixel(x, y) - 1) * terrainBumpiness;
で高さを作っている。GetPixel(x,y)というのは0から1の値を戻すので、
Yの値は-1(クロ)から0(シロ)に倍率を書けた値が入る。


ざっとだが、
その後に反射光をつくり、テクスチャを貼り付けて(Mapの質感を作るって事です)
メッシュを作成する。(MeshBilder.FinishMesh())
(メッシュってのは複雑な(単一ポリゴンじゃない)ポリゴンの事だと思えばいいようだ。
今回で言うところのMap。)

これで、テクスチャからMapの作成は出来た。
Gameから読み出せるようにするために、なんとかContentクラスをnewしてやって
戻り値のTagに設定してやる。

これでテクスチャからMapの作成はほぼ終わり。


さて、bmpを適当に作ってみたり、倍率を変更したりして実行してみよー。
結構解ってきたな。ふむふむ。
そろそろ物理エンジンを乗っけてみようか。

衝突判定は明日にする。ねむい・・・。


---------------
このサンプルには地面はあるけど空がないのでSpriteBatchで固定でいいから書いてみよう。