今回は、UC-win/Road SDKに収録されているサンプルプログラムについて詳しく解説していきます。ポイントとなる個所については、ソースコードを用いて説明を行います。それ以外の場合については、特に断らない限りアプリケーションサービスをApplicationService、現在のプロジェクトをprojectの変数で表現しています。
|
UC-win/Roadの道路は平面線形、縦断線形、横断線形から構成されています。ここでは平面線形、縦断線形にアクセスします。任意の道路を作成、あるいはデータを読み込み、メニューから[ツール]−[Alignment
CSV Export..]を選択すると道路選択画面が表示されます。ここで道路を選択後、[Output
by CSV file format]ボタンをクリックすると、平面線形、縦断線形の方向変化点情報がcsv形式で出力されます。
|
|
|
平面線形 |
|
縦断線形 |
CSV形式の方向変化点情報が出力される |
■考え方1:平面図形
UC-win/Roadの平面線形は方向変化点(IP点)から構成されています。IP点のタイプは以下の通りです。このうち起点、終点はタイプ「1」になりますが、座標値のみが有効です。
1. 緩和曲線 − 円 − 緩和曲線
2. 緩和曲線 − 円
3. 緩和曲線
4. 円 − 緩和曲線
5. 円 |
たとえば、タイプが「1」の場合は、直線の方向が変化する位置で「緩和曲線
-> 円 -> 緩和曲線」の線形が入るというものです。緩和曲線はクロソイド曲線の一部で、入力したタイプごとにパラメータが決められますが、方向変化点の情報とはこのパラメータの情報になります。プロジェクトから道路、平面線形の方向変化点までは、次のような関係になります。
IF8ProjectForRoad (プロジェクト) → IF8Road(道路) → IF8TurningPoint(方向変化点) |
このIF8TurningPointでアクセスするパラメータの関係は以下の通りです。線形自体は左下から右上へ進みます。
平面線形の方向変化点へアクセスするには以下のように記述します。
var
road : IF8Road;
turningpoint : IF8TurningPoint;
i, j : integer;
begin
//プロジェクト内の道路は1からカウント
for i := 1 to project.numbrOfRoads do
begin
road := project.road[i]; //i番目の道路
//選択道路の方向変化点は1からカウント
for j := 1 to road.numberOfTurningPoints do
begin
turningpoint := road.turningpoint[j];
//j番目の道路
…
end;
end;
end; |
■考え方2:縦断線形
縦断線形も方向変化点で構成されますが、平面線形とは異なりVCLという考え方になります。VCLとは縦断線形の緩和曲線長を指します。線形上の実際の距離ではなく縦断線形の水平距離になります。
縦断線形へアクセスするには次のように記述します。
平面線形の方向変化点へアクセスするには以下のように記述します。
var
road : IF8Road;
turningpoint : IF8TurningPoint;
i, j : integer;
begin
//プロジェクト内の道路は1からカウント
for i := 1 to project.numbrOfRoads do
begin
road := project.road[i]; //i番目の道路
//選択道路の方向変化点は1からカウント
for j := 1 to road.numberOfTurningPoints do
begin
turningpoint := road.turningpoint[j];
//j番目の道路
…
end;
end;
end; |
SDKを使用して新規にプロジェクトを作成し、地形を追加後、道路(平面、縦断、断面)を追加します。道路の作成では、プロジェクトで新規に道路を追加後、平面線形、縦断線形、断面線形を作成していきます。
■道路の追加
プロジェクトに新規に道路を追加するには、以下のようにします。
var
road : IF8Road;
begin
road := project.CreateNewRoad;
…
end; |
■平面線形
追加した道路へ必要な方向変化点を追加します。使用するインタフェースは以下のとおりです。
起・終点以外は戻ってきたIF8TurningPointに対して必要なパラメータを設定します。
function IF8Road.CreateTurningPoint(x: double; y: double; tpType: TurningPointType)
: IF8TurningPoint;
x : X座標(東西方向) 地形左下が0
y : Y座標(南北方向) 地形左下0に対して、内部データは northDistance -
左下Y座標を入力します。
tyType : 方向変化点のタイプ |
■縦断線形
まず、以下のインタフェースにより道路に縦断線形を追加します。
procedure IF8Road.MakeVerticalCurve(const useActualHeights: Boolean = true
);
useActualHeight : true : 起、終点の標高が地形上。 false : 起、終点の標高が地形+0.5m。 |
縦断線形を追加した後、IF8Road.verticalCurveにより縦断線形を取得し、方向変化点を以下のインタフェースを使用して追加します。
function IF8VerticalCurve.InsertTurningPoint(x: Double; y: Double; out
index: Integer): boolean;
x : 追加する方向変化点のx座標(縦断線形の起点からの水平距離)
y : 追加する方向変化点のy座標(標高値)
index : 戻り値がTrueの場合、追加された位置が入る。 |
追加された方向変化点に対して必要なパラメータを設定します。
var
road : IF8Road;
verticalCurve : IF8VerticalCurve;
x,y, : double;
index : integer;
begin
verticalCurve := road.verticalCurve;
if verticalCurve.InsertTurningPoint(x, y, index) then
begin
verticalCurve.curvePoint[index].iSaveData....
end;
end; |
追加した方向変化点に対して、CurveSlopesにより実際の計算を行います。
■道路断面線形
道路断面線形は道路面、橋梁面、トンネル面の3つで構成されています。それぞれ左端から右端に向かって一筆書きのノード情報になります。断面を追加し、道路面、橋梁面、トンネル面を定義する手順は以下のようになります。
各処理を行うインタフェースは以下の通りです。
function IF8Road.AddSection : IF8Section;
//道路面のノード追加
function IF8Section.AddPoint(point: F8PointType) : integer;
point[1] : x座標 原点(線形が通るところ)を(0,0)としたときの水平方向オフセット、左側が負の値、右側が正の値
point[2]: y座標 原点からの鉛直方向オフセット
戻り値:インデックス
//道路面ノードへアクセス
property IF8Section.point[index:integer] : PluginSectionBitType;
index: インデックス。ノード追加直後であれば、AddPoint()の戻り値
//橋梁面のノードの追加
function IF8Section.AddBridgePoint(point: F8PointType) : integer;
//橋梁面ノードへアクセス
property IF8Section.bridgepoint[index:integer] : PluginSectionBitType;
//トンネル面のノードの追加
function IF8Section.AddTunnelPoint (point: F8PointType) : integer;
//トンネル面ノードへアクセス
property IF8Section.tunnelpoint[index:integer] : PluginSectionBitType;
|
■作成した断面を道路へ追加
作成した断面を道路へ追加するインタフェースは以下のとおりです。
var
road : IF8Road;
begin
road := project.CreateNewRoad;
…
end; |
このサンプルでは、SDKからどのようにメインカメラを制御するかを示します。メニューから[ツール]−[Control
Cameras...]を選択し、表示された画面からカメラ制御を行います。
■カメラへのアクセス
カメラの情報には視点位置、視点方向があり、それぞれへアクセスが可能です。
//カメラの視点位置
var
eye : GLPointType;
begin
eye := ApplicationService.MainOpenGL.Camera.Eye.point;
end;
//カメラ視点方向
var
view : GLPointType;
begin
view := ApplicationService.MainOpenGL.Camera.ViewPoint.point;
end; |
■カメラ位置の保存と削除
カメラ位置を保存(プロジェクトに追加)するには、以下のインタフェースを使用します。メイン画面からの通常操作でも、追加したカメラ位置への移動は可能です。
//カメラの視点位置
var
eye : GLPointType;
begin
eye := ApplicationService.MainOpenGL.Camera.Eye.point;
end;
//カメラ視点方向
var
view : GLPointType;
begin
view := ApplicationService.MainOpenGL.Camera.ViewPoint.point;
end; |
カメラ位置を削除するには、以下のインタフェースを使用します。
functin IF8ProjectForRoad.DeleteCamera(index : itneger) : boolean;
index : インデックス(1〜) |
追加済みのカメラ位置をカメラビューで表示/非表示するには、以下のインタフェースを使用します。
//カメラビューの表示
procedure IF8ProjectForRoad.OpenCameraView(index : integer);
index : 保存カメラ位置インデックス
//カメラビューの非表示
procedure IF8ProjectForRoad.CloseCameraView(index : integer);
index : 保存カメラ位置インデックス |
このサンプルでは3Dモデル、キャラクタ移動をSDKからの制御方法を示します。ツールメニュー「Import
Object Movement...」を選択し、3次元座標による移動位置を含んだテキストファイルを読み込みます。このテキストファイルはTabスペースで区切られたファイルで、この位置情報により配置されたMD3キャラクタモデルや3Dモデルがメイン画面上を歩き回ります。 また、ツールメニュー「Control
Fixed Models...」を選択し表示された画面では、選択した各モデルインスタンスをメイン画面上に配置します。
■コールバック関数
あるイベントの中で実行される処理をあらかじめ登録しておく関数を、コールバック関数といいます。UC-win/Roadではコールバック関数の関数のポインタを各イベントへ割り当てることで、各イベント毎に決められた引数に適切な値が返ってきます。
その結果、プラグイン側でその引数を用いて、モデルの状態などを再設定できるのです。コールバック関数が設定されていない場合は何も行いませんが、いったんコールバック関数が設定されると、指定された関数内でのの処理が実行されます。MD3キャラクタインスタンスの場合は、インスタンスの位置を設定できます。
procedure Move(dTimeInSeconds : double; Instance : IF8MovingObjectInstance);
dTimeInSeconds : フレーム間隔
Instance : 対象となるモデルインスタンス
//登録方法
var
instance : IF8MovingObjectInstance;
begin
if Assigned(Instance) then
begin
//コールバック関数の指定
Instance.onMove := self.Move;
end;
end; |
■MD3キャラクタモデル読み込み時の処理の流れ
MD3キャラクタモデルが読み込まれてUC-win/Roadへ登録され、実際にシミュレーションが実行される際の処理の流れは下の図の通りです。キャラクタモデルを歩行者として登録する際に、その動作を制御するコールバック関数を同時に登録します。
これによりシミュレーション時には、キャラクタモデルにコールバック関数が登録されていれば、UC-win/Road本体がそれを実行するように、関数が未登録であれば無視するように命令します。
|
■キャラクタモデル読み時の処理の流れ |
体験セミナーのお知らせ
|
|
(Up&Coming '11 晩秋の号掲載) |
|
|
>> 製品総合カタログ
>> プレミアム会員サービス
>> ファイナンシャルサポート
|