地面の作成

地面の作成

 キャラクターが表示できたら、次は地面が必要ですね。(宇宙が舞台のゲームなら必要ありませんが。)

 Easy3Dには、キャラクターが地面を地面として認識するための便利な機能が提供されおり、 複雑な起伏の地表でも容易にちゃんと地表面を歩かせたりすることが出来ます。
今回はこの便利な機能を生かしつつ、地面を作成してみます。

 さて、Easy3Dで地面を作成するには2つの方法があります。
mqoファイルで作る方法と、BMPファイルから地面を作成する方法です。
mqoファイルで作成する場合、メタセコなどのモデリングソフトで作成することになり、 モデリングが苦手な人や起伏の激しい山などの地形は作るのが大変です。
そこで、今回はBMPファイルから地面を作成する方法を取り上げてみたいと思います。

なお多少説明不足な部分もありますのでEasy3Dの付属マニュアルe3dhsp_ground.htmも参照するようにしてください。

ファイルを用意する

 地面を作成するには、次の4つのBMPファイルが必要になります。
ペイントソフトなどを使用して作成してください。

  • 地面の高さ(座標)の情報の元になるBMPファイル
  • 地面のの情報の元になるBMPファイル
  • 地面のの情報の元になるBMPファイル
  • 地面、道、川の模様に使用するBMPファイル

今回は以下のような、3つ地形情報用画像を用意しました。
見やすいよう色分けしてありますが、実際は色は黒でも何でも構いません。

山
地面の座標情報
道
地面の道情報
川
地面の川情報

 この地形情報を元に作成した地形に、地面や道らしい色、水や芝生の模様などを表現する画像を貼り付けます。
今回は分かりやすくなるように、こんなのを用意しました。

テクスチャ画像
地面、道、川の模様



今回はやり方が大事なので、実際はもっとソレらしいものを作成しましょう。
ファイルは単なるBMP画像ファイルなので、一般のペンとソフトで作成可能です。
写真等を加工してリアルな質感を出すのもよさそうですね。

地面を作成

地面の作成はE3DLoadGroundBMP命令を用います。
後は通常のモデルと同様に扱います。


 E3DLoadGroundBMP 地面ファイル, 道ファイル, 川ファイル, 模様ファイル, maxx, maxz, divx, divz, maxheight, hsid

「地面ファイル, 道ファイル, 川ファイル, 模様ファイル」は、先ほどの説明した4つのファイルです。
hsid:地面モデルのID

maxx, maxzは、作成したい地面の縦と横の辺の広さを指定します。
maxx=10000,maxz=12000にすると、10000×12000の大きさの地面が作成されます。

divx, divzは、作成する地面のメッシュの荒さを指定します。値が大きいほど画像で与えられた情報を正確に再現します。
たとえば、divx = 20, divz = 20を指定した場合、下図のような状態になります。このときE3DLoadGroundBMP命令は、 縦線と横線が交差した点の情報のみを読み取って地面を作成します。
メッシュを細かく(値を大きく)取ればBMPを細かく読み取って滑らかな地面を作成しますが、その分頂点数が多くなってしまうため 注意が必要です。程よい値を設定しましょう。

メッシュイメージ


maxheightは、作成する地面の最大高低差を指定します。
色の濃さが高さに対応します。

高低差のイメージ

サンプル

地面

用意したファイルを用いて地面を作成して表示するサンプルです。
カメラを動かしてみたり、光源を作成しない場合などを試してみてください。
実行に必要なファイル:e3d3004.zip
解凍するとe3d3004.hspというファイルとMediaフォルダが出来ます。
e3d3004.hspをHSPスクリプトエディタから実行してください。




;
;	地面を作成する
;

#include "e3dhsp3.as"

	;/////////////////
	;
	;	初期化
	;
	wid = 0		;ウインドウID
	objid = -1	;オブジェクトID
	fullscreenflag = 0		;フルスクリーンフラグ
	bits = 16	;色数ビット数(fullscreenflag = 1 のときのみ有効)
	multisamplenum = 0		;アンチエイリアスのマルチサンプル数(0,2~16)
	;scid	スワップチェインID
	E3DInit wid, objid, fullscreenflag, bits, multisamplenum, scid

	;/////////////////
	;
	;	カメラの初期化
	;
	camposx = 0.0 : camposy = 2500.0 : camposz = 0.0
;	camposx = 0 : camposy = 0 : camposz = 4200	;デフォルト値
	E3DSetCameraPos camposx, camposy, camposz	;カメラ座標を設定
	targetx = 10		;注視点座標
	targety = camposy
	targetz = 10
	upvecx = 0		;カメラの上方向のベクトル
	upvecy = 1
	upvecz = 0
	E3DSetCameraTarget targetx, targety, targetz, upvecx, upvecy, upvecz	;カメラの注視点を設定
	;プロジェクションの設定
	proj_near = 100.0 : proj_far = 50000.0 : proj_fov = 45.0
	E3DSetProjection proj_near, proj_far, proj_fov

	;/////////////////
	;
	; ライトの設定
	;
	E3DCreateLight lid1 ;光源を作成
	lightdirx1 = 1 ;平行光の向き
	lightdiry1 = -1
	lightdirz1 = 0
	lightr1 = 255	;平行光の色
	lightg1 = 255
	lightb1 = 255
	E3DSetDirectionalLight lid1, lightdirx1, lightdiry1, lightdirz1, lightr1, lightg1, lightb1 ;光源を平行光源に設定

	;/////////////////
	;
	;	地面の作成
	;
	sdim pathbuf, 2048, 4
	pathbuf.0 = dir_cur + "\\Media\\yama.bmp"	;地面の座標情報
	pathbuf.1 = dir_cur + "\\Media\\michi.bmp"	;地面の道の情報
	pathbuf.2 = dir_cur + "\\Media\\kawa.bmp"	;地面の川の情報
	pathbuf.3 = dir_cur + "\\Media\\bazou.bmp"	;地面、道、川の模様を決める、BMPファイル

	;地面作成用の値
	mapsize = 60000.0		;X,Z座標の最大値
	mapdiv = 60			;座標の分割数
	mapheight = 3000.0	;高さの最大値

	E3DLoadGroundBMP pathbuf.0, pathbuf.1, pathbuf.2, pathbuf.3, mapsize, mapsize, mapdiv, mapdiv, mapheight, hsid0
	posx0 = 0.0 : posy0 = 0.0 : posz0 = 0.0
	degx0 = 0.0 : degy0 = 0.0 : degz0 = 0.0
	E3DSetPos hsid0, posx0, posy0, posz0	;地面表示位置を設定
	E3DSetDir hsid0, degx0, degy0, degz0	;地面の向きを設定
	frameno0 = 0	;モーションは使用しない。


;/////////////////
;
;	メインループ
;
*main
	E3DBeginScene	;-----シーンスタート
		E3DChkInView scid, hsid0	;モデルが、視野内にあるか判定

		;バックバッファへの書き込み作業を行う
		stick key
		if key&128 : goto *bye
		E3DRender scid1, hsid0, 0, frameno0, 0	;バックバッファにレンダリングする。(地面描画)

	E3DEndScene			;-----シーン終了
	E3DPresent scid1	;バックバッファの内容を、プライマリバッファに転送。描画する。

	E3DWaitByFPS 60, chkfps1 : await 0
	title ""+chkfps1 + " FPS"

goto *main


;/////////////////
;
;	終了処理
;
*bye
	E3DDestroyLight lid1	;ライトを破棄
	E3DBye
	end