オノデラの研究日記 in わんくま

思いついたネタを気ままに書いていくブログ

ホーム 連絡をする 同期する ( RSS 2.0 ) Login
投稿数  209  : 記事  5  : コメント  5982  : トラックバック  40

ニュース

プロフィール

  • ●おのでら
    宮城県在住
    主に業務向けソフトを製作

Twitter

ニュース

主なリンク

XNA 関連リンク

アイテム

ゲーマーカード

その他

記事カテゴリ

書庫

日記カテゴリ

2008年7月27日 #

 3Dゲームなどでキャラクターの頭上に名前を表示したい場合など、キャラクターの3次元空間位置から文字を表示すべきスクリーン座標を算出する必要があります。

 一件難しい計算しなければいけないように思えますが、実はポリゴンの頂点データが3次元座標からスクリーン座標に変換される計算式と同じ方法で求められるので、特に新しい知識が必要になることはありません。

 さらに簡単に計算できるメソッドも用意されているので、特に計算しなければいけないようなコードは書かなくても大丈夫です。

3次元座標からスクリーンへの座標変換

フィールド

 サンプルでは3つのモデルを表示させているので、Model と 3つの位置情報である Vector[3] を定義しています。また、動きがわかりやすいようにカメラ用の自動回転角度を定義しています。

/// <summary>
/// モデル
/// </summary>
private Model model = null;

/// <summary>
/// 位置の配列
/// </summary>
private Vector3[] positions = new Vector3[3];

/// <summary>
/// カメラの水平回転角度
/// </summary>
private float theta = 0.0f;

更新処理

 カメラを自動回転させるための回転角度をゲーム経過時間から求めています。

// カメラの水平角度を自動更新
this.theta = (float)gameTime.TotalGameTime.TotalSeconds / 2.0f;

描画前処理

 スプライトを描画後は深度バッファが無効になっている場合があるので、DepthBufferEnable プロパティを true に設定しておきます。

 すでに作成済みのビューマトリックスに対して Y軸回転マトリックスを掛け合わせると、カメラの位置を注視点を軸に回転させることができます。マトリックスの掛け合わせる順番には注意してください。

// Zバッファを有効にする
this.GraphicsDevice.RenderState.DepthBufferEnable = true;

// ビューマトリックスに回転を合成算出
Matrix rotatedView = Matrix.CreateRotationY(this.theta) * this.view;

ビューポートの取得

 Viewport は3次元空間座標からスクリーン座標に変換するメソッドが用意されているので、GraphicsDevice から取得しておきます。

// ビューポート取得
Viewport viewport = this.GraphicsDevice.Viewport;

3次元座標からスクリーンの座標算出

 3次元空間座標からスクリーン座標を求めるには Viewport.Project メソッドを使うだけで簡単に求められます。

 第1引数に変換元の3次元空間位置を指定し、第2引数にプロジェクションマトリックス、第3引数にビューマトリックスを指定します。すると、戻り値としてスクリーン上の座標が取得できます。

 あとは、Vector3 から X, Y の値を取り出せば、テキストの表示位置をして使用することができます。(Z は深度位置になります)

// 3次元座標からスクリーンの座標算出
Vector3 v3 = viewport.Project(this.positions[i],
                                this.projection,
                                rotatedView,
                                Matrix.Identity);
Vector2 screenPosition = new Vector2(v3.X, v3.Y);

// テキスト描画
this.spriteBatch.DrawString(this.font, "Model " + (i + 1).ToString(),
    screenPosition, Color.White);

サンプルプロジェクト

静的サイト

posted @ 19:26 | Feedback (3)