路線バス運転シミュレータ開発記

OMSIを使って路線バスの運転シミュレータを製作しています。備忘録的にゆるーく書いていきたいと思いますので、お付き合いいただければ幸いです。

当たり判定がうまくいかないとき

トンネルや橋のオブジェクトを作成したとき、自車が通過しようと思った部分が通過できずに跳ね返ってきてしまうことがあります。
これは当たり判定を行う際に、デフォルトではオブジェクト全体を囲むようなコリジョンメッシュが生成されるためで、scoファイルに以下の記載をすればオブジェクトの形状に即した当たり判定が行われるようになります。

[mesh]
xxx.o3d

[collision_mesh]
xxx.o3d

 通常、[collision_mesh]に指定する図形は[mesh]に指定しているものと同一で問題ないですが、複雑なオブジェクトの場合、それを当たり判定用のメッシュとして使うとコンピュータのパフォーマンスが落ちる可能性があるので、そういった場合は本来のメッシュに近似した簡略版を用意して[collision_mesh]として指定すれば良いかと思います。
それと、簡単なことでハマったので書き添えておきますが、以前[collision_mesh]にx形式のファイルを指定していたことがあったのですが、なぜか何度やっても当たり判定がうまくいきませんでした。
調べてみると、o3d形式のときは当たり判定がうまくいっているので、もしうまくしかないことがあったらその部分も確認すると良いかもしれません。
特に交差点オブジェクトを作成するときは必ずo3d形式を使った方が良いようです。x形式を使うとバスが通過できなかったり、物理計算に失敗するのかよくわかりませんが交差点の途中で突然暴走するということがありました。

いすゞエルガ

kamy_februaryさんからすでに初の日本型であるいすゞエルガが公開されていることは前にも紹介しましたが、この度葱急车辆制造さんからもいすゞエルガが公開されました。

www.youtube.com

葱急车辆制造さんのfacebookにダウンロード先のリンクがありますので、興味ある方はぜひお試しを。

https://www.facebook.com/NEGIKYU.WORKSHOP/

スプラインを作成するためのツール(まとめ)

■whistlehead Roadways V2 - Spline Generator

車線数や路面のテクスチャなどをドロップダウンリストから選択するだけで直感的にスプラインを作成できるツールがありましたのでご紹介します。
このツールを使えば、作成時にパス方向も指定できるので日本型の道路作成に役に立ちそうです。全路肩/半路肩など路肩幅のバリエーションまでつけられるのは驚きです。

f:id:poplar1930:20210701134412p:plain

このツールは以下のサイトからダウンロードできます。(初回のみ要登録)
https://fellowsfilm.com/downloads/whistlehead-roadways-v2-spline-generator.3156/

 

■Simple Spline Creator

上記のSpline Generatorとは異なり座標を指定してスプラインを作成していくタイプのツールです。自由度が高く、テクスチャ画像も自分で指定できますし、パスの方向も決められるので左側通行に対応したスプラインを作成できます。

また、ファイルの生成だけではなく既存のスプラインを読み込むこともできるので解析や改変にも役に立ちます。

f:id:poplar1930:20210617001859p:plain

このツールは以下のサイトからダウンロードできます。
https://reboot.omsi-webdisk.de/file/311-simple-spline-creator-1-1/

to spline機能にてオブジェクトをスプラインに据え付けられない問題

街灯や柵など道路沿いにオブジェクトを一定の間隔で自動的に配置できる[to spline]機能は非常に便利ですが、スプラインの長さが長くなってくるとエディタでうまく据え付けられない問題が生じます。

これはおそらく子スプラインが親スプラインからの相対的な位置によって管理されているため、親スプラインから離れたところにオブジェクトを配置しようとすると誤差が生じてしまっておかしな場所にオブジェクトが生成されてしまうのではないかと考えています。

実験では子スプラインが親スプラインから5km以上離れると、この現象が発生しやすくなっているようなので、5km以内に交差点オブジェクトを挟むなどして、一つのスプラインが一定の長さ以上にならないようにすれば回避できます。

ただし、高速道路や山間部の道路など交差点を挟むことが難しい場合は、スプラインではなく、パスの通った道路オブジェクトを作って、それを挟めば同様の効果が得られると思います。

"No both THs"を使用したときに交差点オブジェクトを連結できない問題

スプラインが周囲の地表よりも低くなるような場合、Align Terrainを"No both THs"に設定すると簡単に切土になりますが、こうして作成した切土のスプラインに交差点オブジェクトを連結しようとしてもうまくいきません。

オブジェクトはデフォルトで地表の高さにあわせて配置されるようになっていますが、道路が低くなっていても見えなくなっている地表は元の高さのままなのでその高さに配置しようとしてしまうのです。もちろん、z座標を変更すれば上下方向にオブジェクトを移動することはできるのですが、いざctrlキーを押してスプラインと連結しようとしてもやっぱりうまくいかないのです。

結局のところ、周囲の地表の高さよりも低くなる箇所で分岐しなくてはならなくなるような場合、Align Terrainの設定を使用するのではなく、面倒ですが素直にスプライン部分の地表の高さを低くする必要がありそうです。

透過テクスチャを使用する

Metasequoia上ではアルファチャネルを持ったPNGなどを指定すると透過部分が適切に表示されますが、xファイルに出力してそのままOMSIに読み込ませようとしても透過部分が適切に表示できないことがあります。

この場合、scoファイルを開いて以下のような構文を追加するとうまく表示されるようになります。(これも結構解決までに苦戦しました)

 [mesh]
xxx.o3d

'===以下追加部分===

[matl]
xxx.png
0

[matl_alpha]
1

 

地表高と路面高の違い

以前、地形の作成 - 路線バス運転シミュレータ開発記にてSRTMデータから地形を生成するという話を書きましたが、マップ作成に際して注意しなければならないのが、地表高と路面高は等しいとは限らないということです。
実際マップを作成してみるとわかりますが、SRTMデータから生成できる地形だけでは道路の高さまではわかりません。
盛土あるいは高架になっていれば道路は周囲の標高よりも高くなりますし、切土あるいはアンダーパスになっていれば低くなります。
そのため、ただ単に道路を地形に据え付けるというだけではどうしても実感味に欠けてしまいます。
実際の図面などが入手できれば問題ないのですが、すべての道路に対してそう簡単に入手できるとは思えません。

色々解決策を考えたのですが、今のところ思いついた方法が地理院地図のツールを使う方法です。
画面右上の[ツール]-[断面図]を選択して始点をクリック、終点をダブルクリックするとその区間の標高の変化を地図上の位置と照らし合わせながら見ることができます。
これを応用すればおよその路面高を導き出すことができるというわけです。
道路を分断するように使えば横断面図が得られ、道路に沿って使えば縦断面図が得られますのでぜひお試しを。

地理院地図
https://maps.gsi.go.jp

Metasequoiaを使用してオブジェクトを作成する際のメモ

OMSI2のマップ作成をしている方のほとんどがbelnderを使っているのではないかと思いますが、Metasequoiaを使っている場合の設定等を記載します。

・通常、Metasequoiaでx形式のファイルを読み込むことができないので、モデリングしたデータはmqo形式でも保存しておく。
Metasequoiaからo3d形式に直接出力することはできないので、x形式で出力後にOmsiXConv.exeを使ってo3dに変換する。
Metasequoiaからx形式で出力するときの設定は以下の通りとする。
→cm単位でモデリングしたときはデフォルトの拡大率0.0100、x:0桁とする。
→mm単位でモデリングしたときは拡大率0.0010、x:0桁とする。
※つまりはOMSIに出力するときにm単位になるようになればOK!
→座標軸はデフォルトのDirect3Dのままとし、左右を反転するにチェックを入れたままにする。
→オプションはデフォルトの設定のままとする。(法線スムージングとUVマッピングがON)

【重要】
Metasequoiaの材質でテクスチャを指定するとき、デフォルトでは画像ファイルの絶対パスが記録され、それが出力したxファイルにも埋め込まれてしまいますが、そうすると別の環境にオブジェクトを入れたときにテクスチャが表示されない現象が発生します。

したがって、材質設定画面から画像ファイルを指定したときに絶対パスが入ったらファイル名以外の部分を削除してしまいます。これで出力されたxファイルを毎回開いて絶対パスになっているものを置換しなくてよくなります。ただし、これをやると今度はMetasequoiaのほうで画像ファイルのパスがわからなくなり表示できなくなる場合があるので、マッピングが済んでからにするか、mqoファイルと同じフォルダに画像ファイルを置くようにすれば問題ありません。
なお、xファイル内で指定するパスはファイル名のみではなく、OMSIのフォルダ構造を意識したものにする必要があるのではないか(つまり相対パスにするということ)と考えたのですが、そのようなことをしなくてもファイル名だけ指定すればOMSIが自動的にファイルの場所を探しに行ってくれるようです。試したところ、OMSIフォルダ直下のTextureフォルダも参照できました。
それから、OmsiXConv.exeを使ってx形式からo3d形式に変換したときも、ファイルのパスは引き継がれているようです。

 

■OmsiXConv.exeは以下のURLから入手できます。
(OMSI 1+2 SDK-Toolsと書いてあるもの)

https://forum.omnibussimulator.de/forum/index.php?thread/27441-de-en-omsi-download-links-doku-sdk-sdk-tools-din-fonts/

 

逆にすでにあるxファイルMetasequoiaで編集したいときは、LithUnwrapにてx形式からobj形式に変換すると編集を行うことができます。obj形式で読み込むとき拡大率などを入力するダイアログが表示されますが、デフォルトのままで読み込むとm単位になります。もっと精度の高いモデリングをするときは、cm単位なら100、mm単位なら1000を入力します。

■LithUnwrapは以下のサイトから入手できます。
https://gamebanana.com/tools/6139

Sceneryobject (*.sco)

scoファイルは、主に建物や標識など自動車や人など別に定義されている以外のあらゆるオブジェクトを定義するものです。また、交差点のように車両や歩行者のパスを定義したり、信号機の動作周期データを定義したりすることもできます。
オブジェクトで使用するメッシュは配下のmodelフォルダに、オブジェクトで使用するテクスチャは配下のtextureフォルダに格納します。

Sceneryobjects

├─[*.sco file]

  ├─model
  └─texture

以下、テンプレートです。

'==============================================
' [groups] 省略可

' エディタ右側のペインに表示されるときのフォルダ分けを指定する。省略したときはフォルダに格納されずにルートに配置される。
' 階層数 (ルートなら0)
' フォルダ名を浅い方から列挙

' [friendlyname] 必須
' オブジェクト名

' [NightMapMode] 省略可

' 夜間照明モードを指定する(0-4)

' 0 : 街灯

' 1 : 連続的な照明のある建物

' 2 : 住宅 (23:00-翌6:00以外)

' 3 : 商業ビル (18:00-翌7:00以外)

' 4 : 学校 (15:00-翌7:00以外)

 ' [script] 省略可

' 調査中

' [varnamelist] 省略可

' 調査中

' [sound] 省略可

' 調査中

' [visible] 省略可

' 調査中

' [crossing_heightdeformation] 省略可

' 調査中

' [terrainhole] 省略可

' メッシュを使用して地形を切り取る

' メッシュ(*.o3d あるいは *.x)を指定

' [rendertype] 省略可
' 描画するタイミングを指定する

' presurface : 地形の描画前 (地形に穴を開けるときなど)

surface : 地形と同じ (道路など)

on_surface : 地形の後 (ヘルプ用の矢印など)

' 1 : 通常オブジェクトの描画前

' 2 : 通常オブジェクトと同じ (デフォルト)

' 3 : 通常オブジェクトの描画後

' 4 : 車両や歩行者の描画後 (ガラスなど透明性の高いオブジェクトなど)

' [complexity] 省略可
' 描画優先度(0-3)で0が最も優先度が高い

' 0 - 交差点、通常の建物、街灯、信号機、交通標識、バス停など非常に重要なオブジェクト

' 1 : バス停上屋、小さな建物など重要なオブジェクト

' 2 : ゴミ箱、電話ボックスなど道路沿いにある小さなオブジェクト

' 3 : 公園のベンチ、砂場など道路に面していないもの

' [LOD] 省略可

' 不明

' [mesh] 必須/複数可
' オブジェクト表示に使用するメッシュ(*.o3d あるいは *.x)を指定する

' [matl] 省略可

' 調査中

' [matl_alpha] 省略可

' 調査中

' [matl_envmap] 省略可

' 調査中

' [matl_change] 省略可

' 調査中

' [matl_item] 省略可

' 調査中

' [matl_nightmap] 省略可

' 調査中

' [collision_mesh] 省略可
' 当たり判定に使用するメッシュ(*.o3d あるいは *.x)を指定する。省略した場合は四角形で近似される。

' [nocollision] 省略可/パラメータなし

' このオブジェクトとの当たり判定を行わない

'[surface] 省略可/パラメータなし

' 地表と当たり判定が行われるようになる (交差点で使用)

' [fixed] 省略可/パラメータなし

' オブジェクトを固定して配置する。省略するとオブジェクトに衝突するしたとき飛んで行ってしまう。

' [boundingbox] 省略可

' 調査中

' [detail_factor] 省略可

' 調査中

' [particle_emitter] 省略可

' パーティクル効果

' [smoke] 省略可

' 煙などの効果

' [absheight] 省略可/パラメータなし

' オブジェクトの位置は地表からの相対位置ではなく、絶対位置として指定する (交差点などに使用)

' [onlyeditor] 省略可/パラメータなし

' ゲーム内ではパスだけ有効になり、メッシュはマップエディタでのみで表示される

' [petrolstation] 省略可

' オブジェクト付近で給油や洗車ができる (ガソリンスタンドで使用)

' [shadow] 省略可/パラメータなし
' オブジェクトに影をつける

' [new_attachment] 省略可/複数可

' アタッチできる場所を追加する

' attach_rot_zという行を入れて角度を入力

' attach_transという行を入れて

' オブジェクト内でのローカル座標(x,y,z)を指定

' [joinable] 省略可/パラメータなし

' 調査中

'==============================================

[groups]
2
Test Object
Bus Stop

[friendlyname]
Bus Stop (Andon)

[mesh]
Bus Stop (Andon).o3d

[fixed] 

 煙などの効果 (直前にしてた[mesh]に対して適用)

' ================================================ 

' 発煙位置 x

' 発煙位置 y

' 発煙位置 z

' 発煙方向 x

' 発煙方向 y

' 発煙方向 z

' 排出速度

' 速度変動率

' 周波数

' 拡散して見えなくなるまでの時間

' (不明)

' 落下係数

' (不明)

' (不明)

' 初期アルファ値

' アルファバリエーション

' 煙の色 R

' 煙の色 G

' 煙の色 B

' ================================================

[smoke]
0
0
17.7
0
0
1
0.6
0.1
6
2
0.98
-0.1
0.3
1
1
0.5
0.4
0.3
0.25

パーティクル効果 (調査中)

[particle_emitter]
-5.25
0.8
2.85
0
0
1
--PS_veloc--
0.5
0.2
--PS_freq--
10
1
--PS_livetime--
0.5
0.4
--PS_brakefactor--
0.95
0
--PS_g--
0
0
--PS_size_start--
0.3
0
--PS_size_grow--
-0.2
0
--PS_alpha_initial--
1
0
--PS_alpha_final--
0.2
0
--PS_RGB--
1.0
0
0.5
0
0.2
0
--PS_calcdist--
200
--PS_emissive--
--PS_bitmap--
texture\licht.bmp
0

 物理特性 (省略可)

'トン単位質量

[mass]

0.5

'慣性モーメント

[momentofintertia]

x軸

z軸

y軸

'重心

[cog]

重心位置x

重心位置y

重心位置z

 

 

 

交差点を左側通行にする

前回はスプライン(道路)を左側通行にする方法について書きましたが、交差点も左側通行にしなければ、AI Carが交差点に進入した瞬間に消えてしまう現象が起きます。
そこで試行錯誤の結果、以下の方法で左側通行にできることがわかりましたので書いておきます。
ただしこれはあくまで海外の配布オブジェクトを流用するためのテクニックみたいなもので、すべてのパスを削除して作り直すのが本来あるべき姿といえます。

 1)交差点を編集する前に、交差点に接続する予定のスプライン(sliファイル)をあらかじめSimpleSplineCreatorなどで左側通行に修正しておきます。

2)以下のサイトを開き、"OMSI 1+2 SDK-Tools"の"SDK-Tools"をクリックしてSDKをダウンロードする。
https://forum.omnibussimulator.de/forum/index.php?thread/27441-de-en-omsi-download-links-doku-sdk-sdk-tools-din-fonts/

3)zipを展開して、OMSIフォルダ直下にあるqtintf.dllとqtintf70.dllを展開後のフォルダにコピーします。

4)OmsiObjEditP.exeを起動し、編集する交差点(scoファイル)を開きます。

f:id:poplar1930:20210618074347p:plain

5)[Spline Templates]タブを開いて、インデックスごとに1)で修正したスプラインをロードします。すべてのインデックスにスプラインの割り当てが完了したら、[Path Edit]タブに戻ります。このテンプレートを適用することによってスプラインと交差点との接続状況がわかります。

6)[Index]を0から順にすべて見ていき、[Type]が"Street"となっているものがあったら、[Direction]を"Reverse"にします。これで車両は画面に表示されている矢印とは逆方向に移動するようになります。
なお、交差点でカーブするパスについては[Blinker]に"Left"あるいは"Right"の値が入っているかと思いますが、進行方向が逆になるので、曲がる方向も逆になり、元々の値とは逆の値をセットしてください。
交差点内で直進するパスについては[Blinker]が"Straight"にセットされていますが、"No"との違いがよくわからないのでそのままにしておきます。

7)次に交差点に進入あるいは進出する部分の短いパスがあるかと思いますが、進行方向が変わっているためそれぞれ[Traffic Lgts]を設定しなおす必要があります。
これは交差点に進入あるいは進出する際にどの信号機を参照してAI Carを制御するか決めるもので、"Main"に設定したとすると、AI Carはそのパスにいる間にMain側の信号機が変化するとそれに応じて発進したり停止したりします。
基本的に交差点に進入するパスは信号機を見なければなりませんので、[Traffic Lgts]を適切なものに設定し、交差点を進出するパスは[Traffic Lgts]を"<none>"に設定します。また、交差点内のパスについても信号機が変化したからといって交差点内で立ち往生されてしまうと困るので[Traffic Lgts]を"<none>"に設定します。

※実はこの設定をしていなくて、AI Carが交差点の途中で止まってしまう(=進出するパスで信号機を見てしまっている)現象が発生してしまい、結構悩みました。

8)以上で基本的な設定は完了ですが、外国仕様の信号機だと「緑→黄→赤→黄→緑」となっている場合がありますので、[Traffic Lights]-[Edit]から確認して必要に応じて国内仕様の「緑→黄→赤」に変更し、保存して終了です。