プロフィール

Na-7

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


アクセスカウンター


最新記事


最新コメント


最新トラックバック


月別アーカイブ


カテゴリ


DATE: CATEGORY:スポンサー広告
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
深度バッファ設定後ユニット有
開発中のメイン画面
前回まで2Dだった地形が立体化した。見た目は良くなったが、課題もあるようだ。



◎地形の立体化

ユニットの表示方式が確定したので、今度は地形の立体化を試みます。

元々XNAで立体地形を作成したわけですが、地形種別を増やすとパフォーマンスが著しく低下してゲームにならなくなってしまうため、正射影画像を取得して板ポリゴンに貼り付けました。

これにより、上空から見ると立体的に見えるようになりましたが、地上から一人称視点で見渡すと平面だということがバレバレです。そこで、画像を板ポリゴンではなくメタセコイアの地形に貼り付けようと思います。

メタセコイアの地形は以前試したことがありますが、

・川などの地形種別が表現できない
・高さ情報を取得できない

この2点のために採用を諦めました。しかし今はこの2点を補うことができるので、改めて試してみようというわけです。



◎地形画像のマッピング

まずは、以前と同様にグレースケールマップから地形を自動作成します。

メタセコイア地形生成オプション

マップ画像を拡大して4×4=16枚にしたので、縦横の分割数も4で割り切れる数値(64)にしました。

次に、作成された地形にマップ画像を張り付けていきます。


1.マップ画像を読み込んだ材質を
  マッピング方式=平面で新規に作成

2.16×16個分の平面を選択

3.選択部処理→面に現在の材質を指定

4.マッピング機能で平面を選択し、シフトキーを押しながら
  マッピング基本図形を90度回転させて面の方向を調整

5.マッピング機能で選択面にフィット

  ※1マップ画像分完了

6.材質をコピーし、画像ファイルを差し替える

7.2、3、5を実施する
  (5を省くとXNAでおかしくなる)

  ※1マップ画像分完了

10.6~7を繰り返す


メタセコイアで地形画像のマッピング

分割数を増やして起伏を滑らかにしたり、自動や手動で頂点数を減らすことも可能ですが、細かい調整は後にして、まずはXNAで試しましょう。



◎入れ替えテスト

というわけで、板ポリゴンを立体地形に入れ替えました。

立体地形に入れ替え   立体地形に入れ替えズームアップ

ふむ…。
カメラをズームアップしても山が立体的に見えますし、パフォーマンスも出てるので、基本的にはイケそうですね。

しかし、山の方は映像がおかしい所があります。正射影画像を3Dモデルに貼り付けた影響かもしれません。

それと、静止画ではわかりませんが、地形のスクロールとユニットのスクロールがズレます。
板ポリゴンと入れ替えただけなのに倍率を合わせてもズレるので不思議に思いましたが、実は地形立体化の影響で空中に浮いてました。

とりあえず平原の平均的な高さに合わせましたが、ズームアップした状態でスクロールすると結構ズレます。ちゃんと高さ情報を取得して合わせないとダメっぽいのですが、以前はユニットの原点が中央か足元かだけでズレが生じたことを考えると、シビアな精度が要求されるかもしれません。

大丈夫かなぁ…。



◎2Dマップ画像の取得

2Dマップ画像を取得するなら、フリーのマップエディタでもできそうです。

ちょっと悩みましたが、理想のマップエディタを探し当てるのも面倒ですし、自由に改造できる柔軟性も考慮して、既存のマップ画像取得プログラムを改造して一括出力しました。

正射影000   平面正射影000
元の正射影画像(左図)と2D正射影画像(右図)

2D画像は、マップの起伏を一律にならして正射影で取得しました。法線の影響のためか影が付いてますが、むしろ微妙な変化が面白そうなので、これで試してみましょう。

2Dマップ画像に差し替え(JPG)   2Dマップ画像に差し替え(BMP)
jpg画像(左図)とbmp画像(右図)

むむ…以前よりは良くなったようですが、山の映像はまだおかしいですね。

それと、jpgとbmpでかなり雰囲気が違ったので両方挙げてみました。jpgだとぼやけるのでbmpにしようとしたのですが、bmpの輪郭が黒いのは何故でしょうか?



◎黒い原因と対処

bmpの輪郭が黒い理由が判明しました。
黒い部分には透明度が設定されてました。

元の3Dマップは複数のパターン画像を重ね合わせているので、境界線に透明度が設定されます。これをbmpフォーマットで保存すると、自動的に32ビットで保存されてしまうのです。

XNAでは保存する際のビット数を指定できないので、C#でBMPファイルを32ビット→24ビットに落とすプログラムを作成しました。

テストコード

しかし、実行すると32ビットBMPが作成されてしまいました。クローン作成後の PixelFormat を表示すると、Format32bppRgb でした。Bitmap.Clone()の引数でフォーマットを指定しても、ビット数は減らせないようです。

仕方がないのでピクセル単位でコピーしました。ちょっと遅いのが難点ですが、頻繁に使うわけでもないからまぁいいか。

採用コード



◎深度バッファ設定

山の映像が乱れる問題ですが、深度バッファを設定してないことが原因でした。深度バッファを設定したら直りました。

深度バッファ設定後

映像的にはOKですね。あとは地形とユニットのスクロールのズレだけです。



◎次回予告

次回は地形の高さを取得してユニットの配置を調整し、スクロールのズレの解消を目指します。これが成功すれば地形の作成/表示方式も確定ですね。

スポンサーサイト

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
複数ユニット表示方式変更後   複数ユニット表示方式変更後ズームアップ
開発中のメイン画面
部隊ユニットの表示方式を変更し、単体画像で人数分表示するようにした。画像やプログラムも併せて調整し、滑らかな画像と解像度を実現した。パフォーマンスも良好。



◎右利きと左利き

前回は取得した画像を全て使用しましたが、画像を反転すれば半分近く減らせますね。

でもちょっと待てよ?
画像を反転すると、武器を持つ手が急に切り替わって不自然に見える角度が出来てしまいます。これでは、画像切り替えの不自然さを軽減するために画像数を増やす意味が無い気がします。

というわけで、当面は反転画像を使用しません。



◎Immediateモード

画像取得プログラムを実行すると、何枚か画像取得に成功した後でエラーが発生することがあります。

保護されているメモリに読み取りまたは書き込み操作を行おうとしました。他のメモリが壊れていることが考えられます。

発生場所は spriteBatch.End() です。再度実行すると、問題無く全画像取得できたりします。

時々発生するということは、タイミングの問題かもしれないと思い、レンダーターゲットを戻した後でウエイトを入れてみましたが、現象変わらず。

ウエイトを入れる場所が悪いのかなぁ?
それとも、レンダーターゲットとスプライトバッチの相性?

結局、spriteBatch.Begin() の引数の SpriteSortMode を Immediate → Deferred としたら、以後エラーが発生しなくなりました。レンダーターゲットを変更する際は、Immediate モードを使用しない方が無難なようです。



◎あちこち修正

槍兵の複数ユニット画像を取得してメインプログラムに組み込み、ついでにあちこち修正しました。(試行錯誤中のコードを整理したら5分の1ぐらいになりました(^_^;)

槍兵蜂矢の陣

実際に表示すると、気になることが出てきました。


1つは陣形。騎兵用の陣形は槍兵に相応しくないですね。

とりあえず槍兵は2列横隊にしましたが、陣系数が増えると画像数がさらに増えることになります。

容量低減のために、解像度を800×600→320×240に変更しました。ファイルサイズが4分の1ぐらいになりました。

32方向×10枚×約12KB×4陣形×10種類=約160MB

まだちょっとデカいですが、一応現実的なレベルになってきました。


もう1つ気になったのは、ユニットが浮いて見えること。

単体ユニットの時に同様の問題が発生しましたが、その時は板ポリの原点を中央最下部に設定しました。単体ユニットは通常その辺が足元になるのでうまくいきましたが、複数ユニットの場合、真ん中の兵士の足元の位置を原点とする必要がありそうです。

結局、ユニットの種類ごとに補正値を比率で設定するようにしました。また、単体ユニットの画像も32方向で取得して混在表示できるようにしました。

槍兵横陣   槍兵横陣ズームアップ

解像度を落としたので、カメラをズームアップするとちょっと厳しいですが、モデルが動いているので何とか耐えられるレベルです。



◎複数ユニットの表示方式について

単体ユニットを表示してちょっと驚いたのですが、単体ユニット32方向の画像切り替えは全然カクカクしないので、普通の3Dモデル表示と比べても全く遜色ありません。ここまで違うと、複数ユニットのカクカクを何とかしたくなってきました。

複数ユニットがカクカクするのは、各兵士の表示位置がずれるからです。画像数はこれ以上増やしたくないので、単体画像を人数分表示するようにしたいですね。

問題はパフォーマンスです。draw回数が10倍増えるわけですからね。でも解像度を落としたから何とかなるかも…?

試しに槍兵1000体表示してみました。

槍兵1000体表示テスト

さすがに12fpsでちょっとキツいですが、ゲーム中の1画面に部隊がこれほど集中することは滅多に無いので、結構イケそうな気がしてきました。



◎実装

というわけで、複数ユニットの表示方式を単体画像で人数分表示するようにしました。ついでに、1部隊の表示人数を1~10人の範囲で指定できるようにしました。



おお~凄い!
全くカクカクしません!パフォーマンスも出てます!画像を240×240でギリギリ収まるように調整したのでアップもOK!
ついにここまで来たか~!!

ちなみに、陣形を増やしても画像数を増やす必要が無くなったので、ファイルサイズも低減しました!

32方向×10枚×約8KB×10種類=約25MB



◎次回予告

今回は画像取得プログラムの大活躍で調整が一気に進みました。(「出力→テスト実行→プログラム修正」を数十回繰り返しました。手作業でやったら死んでますw)

ゲームを作り始めてはや1年。解像度と滑らかさとパフォーマンスに四苦八苦してきましたが、ようやく満足できる状態になりました。応援して頂いた方々、どうもありがとうございました!

次回は城画像の取得、表示、地形の立体化などを行う予定です。今後も焦らず地道に頑張りますよ~!

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発

試行中のデモ画面
画像取得ツールで16方向×4枚=64枚の画像を出力し、プログラムに組み込んだ画面。16方向分の画像数の場合、向きの切り替えのカクカクが目立つ。



◎画像取得の準備

今回は、3Dアニメ画像自動取得ツールを作成し、槍騎兵部隊ユニットの全方向アニメ画像を取得します。槍騎兵はまだSoftimageに移行してないので、RokDeBone2で作成したモデルをACLで動かします。

しかし普通にアニメさせると、皆同じタイミングで動いてしまいます。

同じタイミングで走る槍騎兵

馬のランニングモーションが同じタイミングだと凄く不自然です。そこで、

controller.ElapsedTime = startTime;

こんな感じでモーションをずらそうとしたのですが、ずれません。

モデル、アニメーター、コントローラーのいずれかのインスタンスがコピーされてないのかと思い、半日ほど試行錯誤してしまいましたが、結局インスタンス等は何の問題もなく、ACLのElapsedTimeを勘違いしてただけでした。



◎ACLのElapsedTime

XNAの GameTime.ElapsedGameTime プロパティは「前回の更新から経過したゲーム時間」です。私はよく

timeCounter += (float)gameTime.ElapsedGameTime.TotalMilliseconds;

こんな感じでゲーム経過時間をミリ秒で取得しています。

一方、ACLの AnimationController.ElapsedTime は、アニメーション時間を表します。getだけでなくsetも可能なので、

controller.ElapsedTime = 300;

などとすると、その時間に該当するコマ(アニメフレーム)が表示されます。

私が勘違いしていたのは単位で、ミリセコンドよりもさらに小さい単位でした(マイクロセコンド?)。
だから300や3000程度ではほぼ同じ画像が表示されてしまうので、「個別に動かしているつもりなのに皆同じタイミングで動いてる」という状態になってました。

controller.ElapsedTime = (int)startTime * 100000;

こんな感じで値を十万単位で設定すると、別々のタイミングで動くようになりました。
…今までこれを知らずに余計な苦労してましたよ(笑)

個別のタイミングで走る槍騎兵



◎ライトのオン/オフ

任意のポーズがとれるようになったので、被写体を中心にカメラを16段階で回転するようにしました。

ライトオン正面   ライトオン背面

正面からは普通に表示されますが、背面から見ると真っ黒です。ライトが逆光だからです。

デフォルトライトをオフにするとこうなります。

ライトオフ正面   ライトオフ背面

いくら何でもこれはちょっとねぇ…。

というわけで、カメラに合わせてライトも回転させる必要がありそうです。



◎ライトの回転

BasicEffectのデフォルトライトはディレクショナルライトで、1方向に進むだけのシンプルなライトです。

しかし私はこれを思い通りに制御することができず、3Dテストプログラムの時は逆光のために幾つかのアイデアを諦めました。その後もずっと逆光を避けてモデルやカメラを配置してきましたが、いい加減まともに制御できるようにならないといけません。

ディレクショナルライトはVector3一つだけで方向を示しているので、恐らく原点からその座標に向かうベクトルを示しているのでしょう。だとすると、原点を中心に16段階で回転するように座標値を変換すれば良さそうです。最初はカメラと同様に回転させようとしましたが、もっと簡単な方法があることに気付きました。

先日、クォータニオンやMatrixの回転行列を調べた時に、MatrixやVector3のTransformと組み合わせて回転できることを知りました。その方法でやってみましょう。

Vector3 ret = Vector3.Transform(defaultDir[lightNo], Matrix.CreateRotationY(rot));

ライト回転正面   ライト回転背面

おお、できましたね!
Transformや回転行列をまともに使ったのは初めてですが、こんなに簡単になるとは…ちょっと感動かも(笑)

その後、カメラもこのやり方に改めました。ゴチャゴチャした計算式がスッキリして分かりやすくなりました。



◎ACLの画像をファイルに出力する

ようやく目的の画像が表示できるようになったので、前回確立した手法で画像ファイルを取得したら…空っぽでした。

空の画像

ACLは自動描画モードがデフォルトですが、これは多分Draw()実行後に描画しています。レンダーターゲット変更中に描画する必要があるため、手動描画コードを追加しました。

animator.Draw(gameTime);

手動描画深度バッファ無効

モデルが写るようになりましたが、モデルの足が鎧よりも手前に見えたりして、なんかヘンです。

これはレンダーターゲット先のデバイスが初期化された時に深度バッファがオフになっているからです。デバイスクリア後に深度バッファを有効にします。

graphics.GraphicsDevice.RenderState.DepthBufferEnable = true;

手動描画深度バッファ有効

ちゃんとした画像が取得できました!



◎連続画像の取得

画像枚数を指定すると均等間隔で画像ファイルを出力するようにしたいのですが、そのためにはモーション全体の再生時間を把握する必要があります。

騎兵モデルのループ時間を調べて割り出そうとしたのですが、これはAnimationController.Durationに格納されてました。これを利用して出力画像枚数を任意で指定できるようにしました。

ちなみに槍騎兵の場合「Duration = 3833333」でした。総フレーム数24枚、再生時間23/60秒ですので、ElapsedTimeの単位はやはりマイクロセコンドですね。


最後の仕上げとして、背景初期化時にアルファ値を指定して半透明とし、PNGファイルで保存するようにしました。

実行すると、64枚のPNGファイルが約20秒で出力されます。
手間暇かけていた画像取得作業が一気にラクになりました!(^^)



◎実装

取得した画像をメインプログラムに組み込みました。16方向だとやはりカクカクするので(冒頭参照)、32方向でも試してみました。



32方向×6枚=192枚(15MB)です。16方向と比べると、向きの切り替えが少しスムーズになりました。

こういうテストが気軽にできるのがいいですね。折角なので当面32方向でやります。



◎次回予告

今回は技術的に目新しいことは無いと思っていたのですが、新事実が意外とありましたね。これまで闇雲にやったり避けたりしてたことが改めて理解できました。

次回は、もうちょっと汎用的に使えるように細かい部分を手直ししつつ、槍兵と城の画像を取得します。できれば地形の立体化も試してみたいですね。

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
かんたんXNAその29
かんたんXNA その29 テクスチャへの描画 RenderTarget
時々お世話になる「かんたんXNA」で、レンダーターゲットのお勉強。XNA3.0ではバージョンが異なるコードもあるようだ。



◎GetTexture

前回コメントで、yohさんからRenderTarget2D.GetTexture()を教えて頂きました。

メソッド名がGetTextureで戻り値がTexture2Dなので、画面出力をテクスチャに落とせるんじゃないかと期待してしまいますが、ネット上でサンプルを探すと画面の初期化処理らしきもの(?)が多く、ツールに利用したものは見当たりません。

XNAのヘルプには
このレンダリング ターゲットに関連付けられている 2D テクスチャを取得します。
とあります。とりあえずヘルプのサンプルコードをコピペして実行したら、ブルースクリーンならぬパープルスクリーン状態になって、シャットダウンすらできなくなりました(汗)



◎レンダーターゲット

その後LAGさんから「先にレンダーターゲットを設定する必要がある」とご指摘を頂きました。レンダーターゲットについてもっと勉強しないといけないなぁ…。

というわけで、冒頭の記事ヘルプで勉強させて頂きました。

記事を読んでからヘルプを読むとわかりやすくて良いのですが、記事中のGraphicsDevice.ResolveRenderTargetメソッドや、GraphicsDeviceCapabilities.NumberSimultaneousRenderTargetsプロパティはXNA3.0では存在しないようです。多分仕様変更されたのでしょう。



◎またしてもハード

記事のコードをコピペして実行すると、
renderTarget = new RenderTarget2D(~);
の所で例外エラーになりました。
An unexpected error has occurred.

ここでしばらく試行錯誤しましたが、4番目の引数のnumberLevelsを0→1にしたらエラーが解消され動きました。

GetTextureのテスト
GetTextureで取得した画像を表示するテスト

引数の違いは、仕様変更の影響でしょうか?それとも私のハード環境の問題?

気になったのでネットで調べたら、こちらの記事に回答がありました。numberLevelsは、ミップマップを生成するレベルのことだっんですね。1つ勉強になりました。

それはともかく、またしてもハードでした。もはやお決まりのパターン…。

しかし回答でItoさんが言ってるように「テクスチャのサイズが2のn乗でないときにミップマップをサポートしないビデオカードは少なくない」なら、せめてもう少しわかりやすいエラーを返してくれたらいいのになぁ。



◎ファイル出力

画面出力をテクスチャに落とすことが出来たので、今度はテクスチャからファイルに落とします。

Texture2D.Save()

こんな便利なメソッドあったっけ?まぁ今まではテクスチャの加工生成方法がわからなかったから使えなかったのか。

Texture2D capturedTexture;
capturedTexture.Save("TestCapture01", ImageFileFormat.Bmp);


これで、BMPファイルが出力できました。
やった!これで全自動ツールが作れますよ~!



◎サンプルコード

というわけで、HPにサンプルコードをUPしました。

XNAの画面ハードコピー(スクリーンショット)取得サンプルコード



◎次回予告

ついに念願の「XNAの画面を自動的にファイルに落とす」が出来るようになりました!
yohさん、LAGさん、ありがとうございました!

次回は、この技術を使用して3Dアニメ画像自動取得ツールを作成し、槍兵、槍騎兵、城モデルの全方向アニメ画像を取得します。

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

| BLOG TOP |
DATE: CATEGORY:Softimage Mod Tool
FBXモデルの読み込み
Softimageで複数モデルを配置した画面
FBX書き出し/読み込み機能を利用すると、複数のモデルを配置できるが、シャドウリグの場合は問題があるようだ。



◎Softimageのリアルタイムシェーダ

今回は部隊ユニットの画像を取得します。できればXNAで自動化したいのですが、XNAで3D表示した画面をファイルに保存する部分が自動化できないので、Softimageで簡単にできないか試してみます。

槍騎兵はまだSoftimageに移行してないので、今回は槍兵を複数並べて画像を取得しようと思ったのですが…1つ忘れてました。

槍兵テクスチャ表示   槍兵DirectX9表示

槍兵を通常のテクスチャモードで表示とすると、白黒になります(左図)。リアルタイムシェーダ>DirectX9モードで表示すると、画像が乱れます(右図)。画像が乱れる原因は未だ謎ですが、このままでは画像が取得できません。



◎マテリアルを戻す

仕方がないので、まずマテリアルを元に戻します。

初期のマテリアル設定は消さずに残しておいたので、マテリアルマネージャから元のマテリアルをドラッグ&ドロップで選択し、エクスプローラの
Biped_Shadow→(メッシュ名)→Polygon Mesh→Clusters→(クラスタ名)→(マテリアル名)
にドロップしました。クラスタにマテリアルが1つの場合は、クラスタ名にドロップしてもOKです。

エクスプローラのクラスタ名とマテリアル名   マテリアルを戻した

戻す時は簡単だけど、やってることは本末転倒な気がするなぁ…。

待てよ?ビルボードでしか使わないモデルに関しては、今後XNAに持って行く必要が無いから、XNA向けの調整は不要ってことだよね?
一騎打ち以外は全部ビルボードでやりたくなってきましたw



◎文字の写り込み

ライトが明るすぎますが、そこら辺は後にして、先に連続画像が出力できるか確認します。これが出来ないと意味ないですからね。

ビューポートのキャプチャオプション   Windows画像とFAXビューアで表示した

ビューポートのキャプチャ機能で、こんな感じ(左図)に設定しました。出力された画像ファイルをビュワーで見ると、文字が写り込んでました(右図)。げげっ!これってもしかして使えないのでは?

しかしペイントやGIMP、XNAなどで確認すると、写り込みはありませんでした。ビュワー以外では表示されないようです。まずは一安心ですね。



◎邪魔者を消したい

ところで、左下の「XYZ軸」とその下にある「結果」という文字を非表示にしたいのですが、メニューを探してもなかなか見付からず、ネットで検索してようやく判明しました。

ディスプレイ>可視性オプションのビジュアルキュータブとステータスタブ

ディスプレイ>可視性オプション>ビジュアルキュータブ   ディスプレイ>可視性オプション>ステータスタブ

これで左下の邪魔者は消すことができたのですが、右下の「Softimage Mod Tool」という文字の消し方は不明です。これを消すのは無理っぽいなぁ…これは後でツールを作って消すことにします。



◎背景色とライト

背景色はカメラオプションメニュー>シーンのカラーでScene Colorsを起動し、ジオメトリビュータブで背景色を設定しました。

背景色の設定

RGBだけでなくアルファ値(透明色)も設定可能でした。これで手作業が1つ減りますね。


ライトは、XNA向けに付加したポイントライトを調整するか、別のライトに入れ替えようと考えていたのですが、ディスプレイタイプメニューのヘッドライトをチェックしたら普通に表示されました。とりあえずこれでいいやw



◎カメラの向きを変更する

被写体を16方向から写した画像を取得する方法は2通りあります。

A案:カメラを固定し、被写体を回転させる
B案:被写体を固定し、カメラが周りを一周する

モデルが単体の場合はA案も可能ですが、今後は複数のモデルを扱うので、B案でやります。

RokDeBone2ではB案が簡単にできましたが、Softimageでは自分でカメラの位置を計算し入力しなければならない気がします。これが意外と難しい…。

まず、ビューメニューでシーンカメラを選択します。この状態で注視点やカメラを選択すると、その座標が確認できます。

次に、エクスプローラでBiped_Shadowをマウス中ボタン選択し、カメラアイコンメニューの選択を中心にを選択します。この状態でナビゲーションツール(Sキー)やオービットツール(Oキー)等を使って角度を付け、斜め上から見た感じに調整します。

ここで注視点とカメラの座標を確認し、この2つの座標値を元に、カメラが回転する座標を求めます。

座標計算シート(PDF形式)

やっと座標が算出できました。中学生レベルの計算に2時間ぐらいかかりました(ーー;

で、90度のカメラ座標を入力すると被写体が横向きに…ならないな(汗)
計算ミス?…いや、何か違いますね。うーん…。

…あ、カメラと注視点にニュートラルポーズが設定されてました。それで座標系が違っていたのですね。ニュートラルポーズを解除して再計算したら、やっと被写体が横向きになりました。

被写体が横向きになった



◎モデルのコピペ

モデルを複数配置するには、どのような方法が考えられるでしょうか?

まず最初にBiped、Biped_Guide、Biped_Shadowをコピペしてみました。一応ペーストは出来たようですが、モデルを移動したり回転したり出来ません。

実はモデル単体の時も同様です。普通はそういうものなのか、シャドウリグを利用したためなのか、モデルの構造に問題があるのか不明ですが、この方法は諦めましょう。



◎dotXSIモデルの出力

次に、dotXSIモデルを書き出して複数読み込む方法を試みます。Biped_Shadowを選択してdotXSI書き出しを実行すると、

dotXSI書き出しエラー

こんなエラーが複数回表示されました。出力されたファイルを読み込んだら、やっぱり壊れてました。
ちなみに、何も選択しなかったり、BipedとBiped_Shadowを選択すると落ちました(--;

ヘルプを調べたら「Softimage対応Crosswalkは、dotXSIのバージョン5.0および6.0をサポートしています。」と記述されているので、ModTool7.5では書き込み機能は実行できないのかもしれません。もしそうだとしたら、メニューから書き込み機能を削除して欲しいものです。

この方法も諦めましょう。



◎FBXモデルの出力

次は、FBXでやってみます。

FBXモデルの読み込み

ようやく、まともに書き出し&読み込みが出来たようです。場所も移動できました。しかし一部のマテリアルが再現されてませんね。

実は書き込み時にUVマッピング関連の警告が1件表示されてました。以前試行錯誤中に自分で壊してしまったようです。その問題を対処したら警告がなくなり、全てのテクスチャマテリアルが再現されました。

しかしカラーマテリアルの部分は何故か再現されません。Clustersの下を確認すると、FBXモデルの下はクラスタ情報が「Point」だけになってました。

元のモデルのClustersの下   FBXモデルのClustersの下
元のモデル(左図)とFBXモデル(右図)

原因は不明ですが、全てテクスチャマテリアルに置き換えてからFBX出力すれば回避できるでしょう。



◎動きません

ようやくここまで来ましたが、最後に1つ大きな問題がありました。FBXで読み込んだモデルが動きません。

リグも必要なのかと思い、リグ、シャドウリグ、ついでにガイドも併せてFBX出力しました。するとSpearMan2の階層下にそれぞれ配置されました。

SpearMan2の階層下   FBXシャドウリグとリグ

FBXモデルの下に緑色の点がありますね?あれはFBXモデルのリグで、そちらはちゃんと動きます。リグが動くのに、シャドウリグが動かないということは、連携設定(コンストレイン?)が無視されたということでしょうか?

しかしよく見ると、シャドウリグも槍が少しだけ動きます。これはどういうことでしょうか?

…槍が少し動くのは、シャドウリグだけで構成したアニメが混じっているからだと思います。Crosswalk(モデル入出力機能)から見た場合、リグとシャドウリグはそれぞれ独立した別のモデルなので、モデルをまたぐ連携設定(コンストレイン?)は再現されない、と考えると辻褄が合いそうです。



◎次回予告

槍兵モデル作成時はXNAで直接動かすことを目指していたので、ボーンを減らすためにシャドウリグを使用したのがネックになりましたね。最初からビルボードを前提としていれば、(XNA連携不要になるので)話は全然違っていたと思います。

今後Softimageでビルボード専用モデルを作成した場合は、今回の方法で連続画像を取得できると思いますが、槍兵モデルはXNAを使用した方が良さそうですね。

というわけで、次回はXNAで複数モデル連続画像を取得します。

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
16方向ビルボード対応
開発中のメイン画面
ユニットの画像パターンを8方向から16方向に拡張し、カメラを移動した時の違和感を少なくした。



◎プログラム改修

前々回では、ビルボードのクォータニオンを取得し、頂点変換を行い、そこから角度を求めました。

その後yohさんからもっと簡単なやり方を教えて頂きましたので、プログラムを改修します。

まず、カメラの平面角度を求めます。
Vector3 tmpPos = mainMap.MapViewPos - billPos;
float viewPlaneRot = MathHelper.ToDegrees((float)Math.Atan2(tmpPos.Z * -1.0f, tmpPos.X));


次に、ユニットの向きはこれまでint型(=絵の番号)だったのですが、今後のことを考えてfloat型に変更します。また、絵の番号は真上(12時の方向)から時計周りに番号を振っていましたが、三角関数に合わせて右側(3時の方向)から反時計周りに振り直します。

最後に、カメラの平面角度とユニットの向きを差し引いた値(角度)から、絵の番号を判定します。



◎円周率の誤差?

ユニットの向きをint型からfloat型に変更し、

pos.X += ((timer / 5000) * moveSpeed) * (float)Math.Cos(MathHelper.ToRadians(rot));
pos.Z -= ((timer / 5000) * moveSpeed) * (float)Math.Sin(MathHelper.ToRadians(rot));


こんな感じでユニットのXZ座標をUpdateするようにしました。

一見すると狙い通りに動いてるようですが、座標値を確認すると微妙にずれているようです。例えば、rot=90として真上に向かってるつもりでも、X座標が徐々に変化します。円周率の誤差でしょうか?

このままだと、上下移動を繰り返しただけでも、微妙に左右にずれていくことになります。ゲーム性を考えると誤差の範囲と思いますが、テスト中の数値確認はやりにくいです。向きはintに戻した方がいいのかなぁ?うーん…。



◎アニメ画像取得

プログラムは一応できたようなので、槍兵のアニメ画像を取得します。

背景色はRokDeBone2で自由に指定できることに気が付いたので、わざわざGIMPで塗りかえる必要が無くなりました。これでかなり楽になりました。

それでも9方向分(左右反転すれば16方向分)のアニメ画像を取得するのに3時間近くかかりました。単純作業の繰り返しは精神的に疲れるなぁ…ブツブツ。



◎画像の反転

画像を左右反転して板ポリに貼り付けようとしましたが、それを一発で簡単にやる方法がわかりません。オプション設定とかで簡単に出来そうな気がしますが、ヘルプやネットで探しても見当たりません。何でかなぁ…。

わざわざ左右反転用カスタムエフェクトを作るのも面倒なので、UVを反転した板ポリゴンを作成して、左右反転したい場合はそちらのモデルに切り替えるようにしました。

こんな時、他のXNAユーザはどうしてるんでしょうか?



◎実行

ようやく画像が準備できたので、早速実行してみましょう。

うっ…画像読み込みが一気に遅くなりました。640×480の画像を720枚も読み込んでいるので、仕方ないですね。画像ファイルは圧縮されているので1枚あたり20KB以下ですが、メモリの方は結構やばいかもしれないなぁ…。



ほほう…モデルが静止してると、画像の切り替えが多少気になりますが、耐えられない程ではないかも?

面白いのは、アニメしながらの方がごまかしやすいってことですね。もともと切り替えアニメだし(笑)



◎総評

ビルボード&切替アニメで、カメラを近付けても3Dっぽく見えます。むしろ地形の方が2Dバレバレですね(^^;
地形については試したいことがあるので、後日やります。

今回は16方向×40コマでやりましたが、32方向×80コマでやると、もっと滑らかになるんでしょうね。でも今後ユニットの種類を増やした時の画像枚数を考えると、難しいかもしれません。そこら辺は後で調整ですね。

とりあえず、ユニットの表示方式はこれで確定しました。
yohさん、HOSSIEさん、どうもありがとうございました!



◎次回予告

次回は部隊ユニットの画像を取得します。以前の方法は大変なので、Softimageで簡単に作れないか試してみます。

テーマ : モンスターハンター総合 - ジャンル : ゲーム

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
関羽出陣
関羽出陣
三国志軍記のイベントCG。関羽が荊州北部の樊城を攻略すべく出陣する。関羽と赤兎馬の勇姿がメインシナリオの幕開けを高らかに宣言!



◎イベントCG初掲載!

以前予告した通り、月イチペースで三国志軍記のイベントCGをご紹介します。毎月の総括と目標のタイミングで掲載していく予定ですのでお楽しみに!



◎9月の目標達成度

・活動時間月160時間以上

実績:170h(達成率:100%)


・メイン画面の模索(70h)

実績:70hでメイン画面の方向性確定(達成率100%)


・全体スケジュールの見直し(12h)

実績:未着手(達成率:0%)


・契約手続き関連(8h)
・その他(10h)

実績:19hで契約手続き完了、CG監修実施(達成率100%)


・ブログ更新/HP更新(60h)

実績:47hでブログ/HP更新(達成率70%?)


メイン画面の方向性確定、契約手続き完了、新規開発着手など、9月はいろいろ進展しました!(^_^)



◎作業時間分析

作業時間集計2009年9月(PDF形式)

○良かった点
・いまいち気が乗らない日でも少しでもやるよう努めた
・各項目の作業時間がほぼ目標通りであった
・ブログ/HP比率を30%以下に収めた
・別件企画がスタートできた
・1日も休まず走った(活動じゃないけど(^^;)

○悪かった点
・HPの新しい記事が無い
・ブログの月刊登録数が過去最低


月間170hは久々ですね。9月は全体的に調子良かったです。作業時間の内訳はあまり気にしてませんでしたが、集計したらほぼ目標通りだったので自分でも驚きましたw

ブログ時間が27%というのは嬉しいのですが、月間登録数は8件で過去最低となってしまったのが残念です。HPの新ネタが無いのもちょっと寂しいですね。まぁこちらは先月頑張ったからいいか…。


ジョギングは3か月連続で休みナシです。そろそろ休みたかったのですが、傘なくても歩ける程度の小雨じゃ休む口実にならないなぁ(笑)



◎契約手続き

2DCGを担当して頂いている鳳雛さんとの契約手続きが正式に完了しました。ちゃんと収入印紙を貼った正式な著作権譲渡契約書に双方合意の上捺印しました。

最初に提案してから手続き完了まで半年近く経ってます。ネット上で互いに非面識なので、信頼関係を構築するのに時間がかかりました。直接会えればもっと早く出来たかもしれませんが、でも別に急ぐ必要もないのでそこはのんびりと。



◎新規開発

三国志軍記とは別件の企画をスタートしました。2つの開発を並行的に進めたいと1年前から考えていましたが、ようやく実現しました。(1本ずつ作るよりも、2本同時に作った方が効率は良くなります)

で、もう1つの企画というのは、SE(システムエンジニア)を主人公としたノベルゲームです。企画当初は自分一人でシナリオを全部書くつもりでしたが、色々な意味でよろしくないと思い直し、シナリオはセミプロライターのちゃいなタカシ氏に依頼しました。

まだスタートしたばかりで何も決まっていませんが、この作品で表現したいこととかネタとかは腐るほどあるので、それらをどのように加工しゲームとして面白い作品に仕上げていくかが課題です。

いずれ形が見えてきたら、このブログでもちょくちょく紹介していくつもりですのでよろしくお願いします。



◎メイン画面の基本方針

さて、三国志軍記に戻りますが、メイン画面の基本方針は「3Dで作成したイメージを2D画像に落としてパフォーマンスを向上する」で確定しました。画質やパフォーマンスは予想より良いし、過去に作成したプログラムやモデルが利用できるので、かなりいい感じです。

地形については、今後の拡張方式も含めてほぼ確定しました。
これまで1マップしか作っていませんが、荊州だけでも7~8マップは用意します。次回作では中国全土を網羅するわけですが、グレースケールマップとカラーマップを編集するだけで作成できるので、それほど苦にはならないと思います。(その前に、パターンを増やしたりちゃんと描き直す必要がありますが)

ユニットや静止モデルについては、ビルボードにするか否か未定ですが、近いうちに結論が出そうです。



◎進捗状況チェック

スケジュールは凍結中です。メイン画面の仕様を決定してから、スケジュールを見直します。



◎10月の目標

・活動時間月160時間以上

・メイン画面の模索(48h)

・全体スケジュールの見直し(12h)

・ブログ更新/HP更新(50h)

・別件企画(40h)

・その他(10h)



◎次回予告

ユニットの向きによって絵を切り替える手法で、16方向を試します。

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

| BLOG TOP |
DATE: CATEGORY:三国志軍記開発
8方向ビルボード対応
試行中の画面
ポリゴンの角度によって絵を切り替えることにより、ユニットの向きを再現した。しかし8方向切り替えは粗くて不自然らしい。



◎ビルボードとユニットの向き

ビルボードを実装すると、モデルが常にカメラの方を向きます。見た目には良いのですが、これでは部隊ユニットが実際にどちらを向いているかわからなくなってしまいます。

この問題に対処するため、ポリゴンの角度とユニットの向きによって絵を切り替えるという手法を試してみます。



◎クォータニオン?

板ポリゴンの向き(回転角度)はビルボードメソッドで設定しているので、その回転角度をMatrix.Decomposeメソッドで取得します。

問題は、このメソッドで返される回転角度はクォータニオンだという点です。
…クォータニオンって何?(汗)

こちらの記事によると、回転行列のようなものらしいですね。

記事内の行列図で、3×3の部分がR(回転)、4行目がT(移動)を表しているのはわかりますが、S(拡大縮小)が図示されてないのは何故なんでしょうか?
…って、疑問を全て調べていたらキリが無いので、今回は軽く触れる程度にします。


円柱状ビルボードメソッドで取得したクォータニオンの値を確認しました。

Vector3 scale2;
Quaternion rot2;
Vector3 pos2;
world.Decompose(out scale2, out rot2, out pos2);
Console.WriteLine("rot2 = " + rot2.ToString());


rot2 = {X:0 Y:0.9363021 Z:0 W:0.3511957}
rot2 = {X:0 Y:0.8923917 Z:0 W:-0.4512616}
rot2 = {X:0 Y:0.9186879 Z:0 W:-0.3949843}
rot2 = {X:0 Y:0.9905549 Z:0 W:-0.1371164}
rot2 = {X:0 Y:0.9555428 Z:0 W:0.2948525}


ふぅ~ん…Y軸を基準に回転してるのでXとZが0というのは分かりますが、Yの値は常に1.0というわけじゃないんですね。



◎オイラー角?

クォータニオンが回転を表すツールであることは理解しました。

これをY軸を回転軸とした角度に変換したい(XNA的に言うと、Matrix.CreateRotationY()の逆をしたい)わけですが、クォータニオンにはそれらしいメソッドが見当たりません。ネットで検索しようと思いましたが、そもそも目的の角度は何と言うのでしょうか?

先の記事でオイラー角という単語が出ていたので、「クォータニオンからオイラー角に変換する」とヤマをはって検索したら、どの記事も予想以上にややこしい雰囲気。

どうもこれは違うかなと思い、オイラー角について確認すると、こちらの記事で「本によって書いてあることが微妙に異なります。」とあるように、定義が曖昧なようです。

中にはロール・ピッチ・ヨー角もオイラー角の一種として書かれた本もあるようですが、通常はオイラー角は2軸、ロール・ピッチ・ヨー角は3軸として扱われるようですね。



◎頂点変換

クォータニオンや回転行列からオイラー角やロール・ピッチ・ヨー角にまともに変換しようとすると、ややこしい数式を理解しなければならないようです。

今回は1軸のみの回転なので、最終的には簡素な数式にできそうな気がしますが、それを私の頭でまともに導き出そうとしたら、恐ろしく時間がかかりそうです。

結局、角度を求めるのは諦めて、クォータニオンを利用した頂点変換を行い、頂点の位置から向きを判定するようにしました。



◎座標系がおかしい?

判定した向きが正しいか確認すると、見た目とずれている様子。なんか変だな~?

内部数値をいろいろ出力して確認すると、そもそもマップ系とユニット系の座標比率が2対1で異なってました。それでマップの端の方だと角度がずれる感じがしたのか…。

しかしこの座標比率の違いがどこで生じているのか、ソースを全部見直してもわかりませんでした。そもそもXNAのワールド座標比率は常に固定じゃないの??



◎原因はビルボード

半日がかりでようやく原因が判明しました。

前回記事で、ビルボード作成メソッドを
Matrix world = Matrix.CreateScale(10.0f)
  * Matrix.CreateConstrainedBillboard(pos, mainMap.MapViewPos, Vector3.Up, null, null)
  * Matrix.CreateTranslation(pos);

このように記述しましたが、最後の座標指定が余計でした。ビルボードメソッドは、回転だけでなく位置も作成することに気付いてなかったわけです。

「ヘルプではそんなこと一切触れてないじゃん!」と思って見直したら、ありました。

指定されたオブジェクト位置の周囲を回転する球面のビルボードを作成します。

このヘンな日本語は「座標も変換しますよ」という意味だったんですね。直訳系の日本語にハメられた気分です(苦笑)



◎さらにバグ修正

ビルボード関連でもう1つバグがありました。カメラを移動するとユニットの位置が微妙にズレてました。

高さ修正前モデル左上   高さ修正前モデル右上

画面を左にスクロールすると、槍兵が画面左上から右上に移動していきます。スクロール中は気付きにくいのですが、静止画を見ると、槍兵の立ち位置が(道の右側から左側に)微妙にズレてますね?これは、板ポリゴンの中心を原点として回転したからです。

足元を中心に回転するよう修正しました。

// 板ポリゴンのスケール
float scale = 10.0f;

// 板ポリゴンの原点を、中央から足下に移動する
Vector3 billPos = new Vector3(pos.X, pos.Y + scale / 2, pos.Z);

// 円柱状のビルボードを作成する
Matrix world = Matrix.CreateScale(scale)
* Matrix.CreateConstrainedBillboard(billPos, mainMap.MapViewPos, Vector3.Up, null, null);


高さ修正後モデル左上   高さ修正後モデル右上



◎ユニットの向きの再現

ビルボードが直ったところで、本題に戻ります。

判定した向きが正しいか確認すると…OKです。ビルボードの向きに応じて、8方向を示す値が取得できました。

この値と、ユニット本来の向きを比較して、表示すべき絵のパターンを判定しました。(冒頭図参照)


えーと…動画にすべきところですが、あえて静止画のみとさせて頂きます…。

プログラムは狙い通りに動きました。しかし絵の切り替わりは不自然でした。以前の簡易デモ動画は向きの切り替わりが不自然でしたが、あれと同じです。

ちなみに、まだ新しいアニメパターンを用意してないので、8方向中3方向しか再現されてません。



◎次回予告

8方向じゃダメですね。今度は16方向でやってみます。

…ということは、アニメパターンをあと13方向分用意しなくちゃいけないのか。左右反転させるとしても、あと7パターン。うへ~メンドクサイ。でも仕方ないですね。

10月になったので、次回は「9月の総括と10月の目標」です。

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

| BLOG TOP |

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