地形データの制限
目次
はじめに
床面といえばgpfloor
なのですが、ポリゴンを使って複雑な地形とか作りたい!
今まで適当に作ったりはしてきたけど、制限とか注意点とかありそうだけどわからない!
ということで、やってて気づいた点についてまとめ。
今回は、サンプル実行にgpbファイルが必要なので、ダウンロードできるようにしておきました。
平面床をポリゴンで作る
Blenderで2ポリゴン(三角形2個)の四角形の平板を作ってみました。まずはこれで試してみます。 最初から複雑な形状をしても、問題が起きたときに原因がわかりにくくなるので、シンプルな形状です。
; カーソルキーで箱を動かすことができます
;
; 平らな床面をポリゴンで作成すると、ポリゴンの継ぎ目を通過する際に箱がつまづきます。
; まるでポリゴンの継ぎ目に、小さな段差があるような動きになります。
; gpboxで床面を作れば、このような現象は発生しません。
;
#include "hgimg4.as"
title "HGIMG4 Test"
; 環境構築
gpreset
setcls CLSMODE_SOLID, $8080FF
setpos GPOBJ_CAMERA, 0,2,10
; 箱ノード
gptexmat id_texmat, "res/qbox.png"
gpbox id_box, 1, -1, id_texmat
setpos id_box, 0, 1, 0
gppbind id_box, 1, 0.5
; 床ノード
; 自作ポリゴンで床を作成
gpload id_floor, "res/stage_1x1mesh"
setscale id_floor, 30, 1, 30
; 命令で床を作成
; gpfloor id_floor, 60, 60
; 床の物理設定
gppbind id_floor, 0, , GPPBIND_MESH
; ワイヤーフレーム表示
setobjmode id_floor, OBJ_WIRE, 0
*main
stick key,15
if key&128 : end
; カーソルキーで箱を動かす
if key&1 : gppapply id_box, GPPAPPLY_IMPULSE, -0.1, 0, 0
if key&4 : gppapply id_box, GPPAPPLY_IMPULSE, 0.1, 0, 0
if key&8 : gppapply id_box, GPPAPPLY_IMPULSE, 0 , 0, 0.1
if key&2 : gppapply id_box, GPPAPPLY_IMPULSE, 0 , 0, -0.1
; カメラ操作
getpos id_box,dx,dy,dz
gplookat GPOBJ_CAMERA, dx,dy,dz
; 描画
redraw 0
gpdraw
color
pos 8,8:mes "HGIMG4 sample"
redraw 1
await 1000/60
goto *main
カーソルキーで箱を動かせます。床面は、ワイヤーフレーム表示してあります。
動かしてみると、少しガタガタと揺れます。少し床に沈み込んでいるようにも見えます。 また、メッシュの継ぎ目の上を何度か通過させていると、まれに箱がつまづいてしまうことがあります。 まるで小さな段差に躓いたような挙動です。
gpfloor
やgpbox
で床を作った場合、箱は地面をすべるように滑らかに移動してつまづく事はありません。
どうやらポリゴンで自作した平面とgpfloor
などの命令で作成した平面では、物理設定をした場合の挙動が少し違うようです。
床面を作る場合の対策
前述の通り、物理設定で使用する地形データを準備する場合、ポリゴンだけで作成するとうまくいかない場合があるので使い分ける必要があります。
gpfloor
、gpbox
、gpplate
命令
凹凸がない平面の床を使用する場合に使用する。
ワイヤーフレーム表示すると継ぎ目が存在していることを確認できるが、特に問題にはならない。
gpload
命令(Blender等で自作した地形)
起伏や凸凹した地面を使用する場合に使用する。
平面内でポリゴンのつなぎ目があると、つなぎ目にわずかな段差があるかのような動作になってしまうことがある。
平面内での継ぎ目位置は影響が小さくなるようにするなどの注意が必要。
凹凸がある地形と、平面を必要とする地形が混在するような場合は、上記2つの方法を一緒に使うといいと思います。
地形データをBlender等で作成する際に平面部分は穴を空けておき、穴が開いている平面部分にはgpfloor
を設置する。
形状に多少の制限はありますが、今のところ他に選択肢はありません。
凹型の床との衝突判定
gppbind
命令の説明に、次のような一文があります。
地形といえば山谷(凹凸)があって当たり前、くぼんだ谷の部分が認識されないのであれば使い物になりません。 それでは困るので、実際にどの程度なら大丈夫なのか少し確認してみました。
テスト対象は、次の通り。左から平面、アーチ型、凹形の3Dモデル。一番右の凹形は、底が抜けているモデルとふさがっているモデルの2パターンです。
#include "hgimg4.as"
title "HGIMG4"
; 環境構築
gpreset
setcls CLSMODE_SOLID, $808080
; カメラを作成
setpos GPOBJ_CAMERA, 0, 15, 20
gplookat GPOBJ_CAMERA, 0, 0.5, 0
; 箱を作成
gptexmat id_texmat, "res/qbox.png"
gpbox id_box, 0.5, -1, id_texmat
setpos id_box, 0, 1, 0
gppbind id_box, 1, 0.5
; 箱をクローン
i = 0
d = 1.1
repeat 10
z = cnt
repeat 10
x = cnt
gpclone id_boxs(i), id_box
setpos id_boxs(i), d*x-5.0, 7.0, d*z-5.0
gppbind id_boxs(i), 1, 0.5
i++
loop
loop
; 床を作成
gpfloor id_floor, 30,30, $404040 ; 床ノードを追加
gppbind id_floor, 0 ; 床の物理設定を行なう
; 検証モデルを読み込み
z = 3.0
gpload id_model, "res/floor_plate" ; 板
;gpload id_model, "res/floor_arch" ; アーチ状
;gpload id_model, "res/floor_ou" ; 凹形(底がふさがっていない)
;gpload id_model, "res/box_ou" ; 凹形(閉じた形状)
setpos id_model, 0, 2, 0
setscale id_model, z,z,z
;setang id_model, M_PI, 0, deg2rad(30) ; 向きを変更
;gppbind id_model, 0, , GPPBIND_NOSCALE ; ノードのスケールを反映させない
gppbind id_model, 0, , GPPBIND_MESH ; ノードのモデルを反映させる
*main
stick key,15
if key&128 : end
; 描画
redraw 0
gpdraw
color 255,255,255
pos 8,8:mes "HGIMG4 sample"
redraw 1
await 1000/60
goto *main
「検証モデルを読み込み」の部分のコメントを書き換えて実行すると、各地形データを試せます。
板
少し飛び散ってわかりにくいですが、期待通りの結果です。
アーチ状
真ん中の谷部分まで箱が入り込んでいます。箱の向きも、谷の形状に合わせて傾いています。大丈夫そうですね。
凹形(底がふさがっていない)
意外にも正しく認識されました。左右の壁が垂直で、溝も深いので心配でしたが、ちゃんと形状通りに認識されています。 これなら問題ないのでは?
凹形(閉じた形状)
これまでの床モデルは、平面に凹凸を付けただけのものでしたが、この3Dモデルは閉じた図形なので、体積を持っています。 挙動が変わるかも…と思ったんですが、大丈夫でした。
凹凸が多用される地形データですが、心配するほどの問題はなさそうです。 さすがにトンネル形状だとどうなるかわかりませんが、不具合が出てから対策を考えればよさそうです。 もし床との衝突判定で不具合が出ても、床の3Dモデルデータを2つに分けて作って読み込めばいいだけなので大きな問題にはなりません。
まとめ
ポリゴンだけで床を作ると、物理設定では思わぬ不具合を招く場合があるとわかりました。
それでも平面部分をgpbox
等で置き換えればいいだけなので、大きな問題にはなりません。(形状に制限はありますが…)
物理設定を使う場合の地形データの注意点が分かったので、安心してデータを準備できるようになりました。
床の角度が緩やかな曲線を描くような場合、例えば何とかカートみたいなゲームのコースみたいな場合どうするよ、という問題はあるのですが…ポリゴン多くすればいいのかな?