プロフィール

Na-7

Author:Na-7
SE(システムエンジニア)として約15年間システム系ソフト会社を勤めあげ、2008年3月退社。現在、ゲーム制作会社設立を目指して活動中。


アクセスカウンター


最新記事


最新コメント


最新トラックバック


月別アーカイブ


カテゴリ


DATE: CATEGORY:スポンサー広告
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
DATE: CATEGORY:三国志軍記開発
マップ拡大01
開発中のメイン画面
マップが拡大されて広くなったが、幾つかの問題が発生したようだ。


◎城の位置

ネームプレートがまともになったので、ついでに城のネームプレートも復活させたのですが、そうなると城の位置が気になってきました。城の位置は最初からずれていたので、これを機に修正しましょう。

…基準点を襄陽/樊城と宛に決めて、地形テクスチャと合う位置に調整したのですが、他の城はこれで良いのでしょうか?良さそうなのと悪そうなのが混在して、判断がつきません(汗)



◎マップの拡大

そろそろマップを拡大したいと考えていたので、これを機にマップを拡大し、地形テクスチャを再作成しましょう。

というわけで、地形モデルを縦横2倍(面積4倍)に拡大しました。城と城の間の距離を考えると、これぐらいが丁度良さそうです。ただ、プレイヤーが全体を把握しようとすると、ちょっと広すぎるかもしれません。

うーん…拡大より縮小の方が簡単なので、とりあえず広めに作っておいて、後で縮小するか検討しましょう。

で、単純にスケールを倍にしただけだと地形テクスチャが荒く見えるので、地形テクスチャを1024×1024 → 2048×2048としました。

マップ画像1024   マップ画像2048
左図:1024×1024、右図:2048×2048

近くの地面をよく見ると、確かに2048×2048の方が細かいのですが、言われないと気付かないレベルです。

それよりも、2048×2048だと激重で37→6FPSとなってしまいました。多分キャッシュオーバーでしょうが、これではゲームになりません。美的効果も低いので1024×1024に戻します。



◎高さのズレ

マップ拡大に伴うXZ座標修正は一通り終えたのですが、よく見ると、城や兵士が地面にめり込むケースが増えたようです。以前から散見された現象ですが、マップ拡大でさらに目立つようになり、酷い時はユニット全体が完全に埋まってしまいます。

…で、あれこれ調べて原因らしきものが見付かりました。グレースケールマップの解像度を変更した際に、メタセコイアで地形モデルを拡大したのですが、拡大時の基準座標がXNAと異なっていた可能性があります。

メタセコイアで拡大せずにXNAで拡大し、XNAの座標系をそちらに合わせると修正できるかもしれません。しかしマップを修正する度にズレで悩むのはウンザリしてきたので、もっと柔軟に対応できるよう根本的な見直しをしましょう。



◎改善案

高さに関する情報は、現在下記の3つがあります。

・(メタセコイア上の)地形モデルの頂点の高さ
 →グレースケールマップが基準
 →拡大しない方が無難

・(XNA上の)地形モデルの頂点の高さ
 →地形モデルが基準
 →広さと高さの倍率を指定する

・(XNA上の)GetHeightの高さ(XNA)
 →グレースケールマップが基準
 →広さと高さの倍率を指定する
  (但し高さの倍率基準は上記と異なる)

地形の頂点数やスケールを変更すると、上記3点の整合性が崩れてユニットの高さがズレます。3つの関係を保とうとするからややこしくなるので、2番目と3番目の要素を合体させて要素を減らしましょう。

具体的には、GetHeightの基準値をグレースケールマップから地形モデルの頂点座標に変更します(XNAではグレースケールマップ不要とします)。



◎頂点データの数

サンプルプログラムを新規作成し、地形モデルの頂点データを取得すると、65×65=4225個ではなく4624個ありました。
(399個多い)

中身を確認すると、Positionの値が同一のデータが散見されました。テクスチャを複数マッピングした影響かもしれませんが、座標以外は不要なので、ソート後に削除します。



◎ソートの安定性

頂点データは順序不定なので、X及びZ座標でソートします。まずList型に代入し、Z座標でソートし、続けてX座標でソートすると…あれ?X座標はソートが反映されてますが、Z座標は順序不定です。中間では間違いなくソートされてるのに…?

その疑問の答えはこちらの『ちなみに、このSortメソッドは「安定していない」。』以降に書かれてました。
うわ、C#の仕様ですか!?(爆)


少し調べた限りでは.Net Frameworkに安定ソートは無さそうだったので、バブルソートを実装して対処しました。今のPCで数万件のソート速度に差は出ないから種類は何でも良いのですが、わざわざコードを記述する時点でスマートじゃない気がするなぁ(苦笑)


昔話。
8ビットPCの自作ゲームが遅くて、悩んだ末に逆写像ソートを実装したら、圧倒的な早さで衝撃を受けました。意外とシンプルなコードで、なぜこれでソートできるのか(しかも安定性あり)未だに原理が理解できませんw



◎技術資料

そんなこんなで、サンプルプログラムが完成しました。

地形モデルから高さを取得する

この方式は開発当初から望んでいたのですが、ようやく実装できるレベルに達した、というわけです^^



◎誤差

新方式に切り替えたついでに高度のズレが解消されると嬉しかったのですが、残念ながら現象は引き続き発生します。
原因を調べると…単なる誤差のようです(爆)

float a = 256.7f % 8.0f;
Console.WriteLine("a = "a.ToString());

これを実行すると

a = 0.7000122

と表示されます。floatの桁落ちによる誤差ですね。
誤差を減らすためにdouble型にキャストしたいのですが、どうも単純にはできないような…?

float a = 256.7f;
double b = (double)a;
Console.WriteLine("b = " + b.ToString());

実行結果は以下の通り。

b = 256.700012207031

double → float で誤差が生じるのは理解できますが、
float → double で誤差が生じるとは初耳です。

こんな時は…そうかdecimalを使うのですね。
よしこれで計算の誤差が減りましたよ。

…高さのズレ再発しました。
結局誤差は大した問題じゃなかったようです(><)



◎現状の再確認

フローに沿って座標値をトレースしても、他におかしな点はなさそうでした。座標値が正しいのに、なぜズレが発生するのでしょうか?

基本に戻って、ズレの状態を確認する所からやり直します。

GetHeight確認01   GetHeight確認02

確認用モデルをX=-88(左図)、X=-84(右図)で並べました。

X座標またはZ座標が頂点座標と一致する(8の倍数)と正確な高さを取得し(左図)、頂点座標から離れると高さがズレます(右図)。ちなみに、上記のdecimal方式で誤差を減らしても見た目変わりません。

ということは、

仮説A
GetHeightの計算ロジックがおかしい(または不正確)

仮説B
メタセコイアの地形生成ロジックとGetHeightの計算ロジックが合致しない

上記のどちらかと思いますが、頂点座標と一致する座標の高度は合致するので、仮説Bはありえないでしょう。ということは仮説Aってこと?でも、公式サンプルのボールは地面の上を正確に転がった気がするなぁ…うーん(ーー;



◎次回予告

地形を拡大した影響で、ズレが無視できないレベルになったので、何らかの結論を出すまで徹底的に追求します。

というわけで、次回は引き続き高さのズレを調査します。

…最悪サイズ戻すかも(ぼそっ)

スポンサーサイト

テーマ : ゲーム製作 関連 - ジャンル : ゲーム

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック


この記事にトラックバックする(FC2ブログユーザー)



copyright © ゲーム制作の舞台裏 all rights reserved.Powered by FC2ブログ
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。