Civil Engineer's Forum-FORUM8
このページをスタートページに設定する QR

Facebook - FORUM8

Twitter - FORUM8

YouTube - FORUM8

 サイトマップ | ご利用条件 | お問い合わせ | 英語翻訳サイト | Japanese | English | Korean | CHS/CHT | Vietnam | Francais | Europe

9
 EXODUSプラグイン
今回は、EXODUSの解析結果をUC-win/Roadで可視化するために開発されたプラグインの基本的な活用方法について、サンプルコードを用いて解説します。あらかじめ保存された解析結果を再生する形で、UC-win/Roadの人間キャラクタオブジェクトを制御する仕組みとなっています。
 3Dキャラクタの機能と制御

UC-win/Roadのキャラクタオブジェクトの仕様
 UC-win/Roadのキャラクタオブジェクトの機能は、人、動物などの移動しながら複雑な動きをするものに適用されます。こういった動きを保存するために、md3というファイル形式を採用しています。1つのキャラクタモデルには、さまざまな動きを再現するために複数のアニメーションデータが保存されており、任意の動きを表現できます。しかし、たとえば歩くアニメーションの場合に移動速度を時速30キロに設定すると、人間の動きとして不自然になってしまうため、時速1キロから10キロの範囲で設定してやるのが適切です。

 このため、UC-win/Roadではアニメーション毎に適切な移動速度を設定できるよう設定画面が用意されており、移動時にモデル移動速度に比例した速さでアニメーションを再生することができます。

 UC-win/RoadのSDKを使用すれば、キャラクタモデルの移動を制御することで、上記のような処理を実装できます。

キャラクタに関連するオブジェクト
 UC-win/Roadでキャラクタを動かして描画するには2つのオブジェクトを使用します。1つはキャラクタの描画に必要なポリゴン情報、すなわち、アニメーション情報を持つオブジェクトです。これはQuakeIII呼ばれるオブジェクトでで、当初はQuakeIIIというゲームのために開発されたキャラクタデータ形式です。

 もう1つは、CharacterInstanceというオブジェクトで、UC-win/RoadのVR空間の中にキャラクタの配置・移動を行うために使用されます。このオブジェクトは位置情報、移動の計算、アニメーションの状態を管理するオブジェクトです。1つのCharacterInstanceは1つのQuakeIIIオブジェクトを参照します。また、複数のCharacterInstanceが同じQuakeIIIオブジェクトを参照することも可能です。車でいえば、複数の人が同じ型の車を運転できますが、この車の型は1つの共通のデータということになります。

 データ構造では、キャラクタの形状に関する情報は1カ所で保存し(QuakeIII)、複数のインスタンス(CharacterInstance)に適用します。そのためUC-win/Roadでキャラクタの動きを制御する時は、QuakeIIIオブジェクトを事前に読み込む必要があります。MD3キャラクタのクラス構造は図1の通りです。

サンプルプログラムのソースコード
 次のソースコードでは、UC-win/Roadのキャラクタのインスタンスを生成し、初期位置を設定しています。この例ではキャラクタを一時的なオブジェクトとして生成します。

function CreateNewInstance(project: IF8ProjectForRoad):
   IF8CharacterInstance;
   var
      startPosition : GLPointType;

   begin
   // プロジェクトが存在するかどうかを確認し、
   // MD3キャラクタモデルが1つ以上かどうかをチェックします。
if Assigned(project) and (project.numberOfCharacters > 0) then
     begin
     //1つ目のmd3キャラクタを使用し、キャラクタの
     // インスタンスを生成します。
     result := project.CreateCharacterInstance
                 (project.character[1], true);

     //初期位置を一時的な変数に設定し、
     // キャラクタインスタンスのプロパティに代入します。
     startPosition[_x] := 5000;
     startPosition[_y] := 0;
     startPosition[_z] := 5000;
     startPosition[_z] := 0;
     newInstance.instancePosition := startPosition;
     end;
end;


 キャラクタの動きを制御する

UC-win/Roadのシミュレーションとの同期
 通常、UC-win/Roadの交通シミュレーションの一部としてキャラクタの動きを計算します。プラグインでキャラクタのインスタンスを制御する場合は、本体の計算と同期して制御する必要があります。交通シミュレーションの計算では各車両の位置とキャラクタの位置を画面上に表示する前に計算します。表示するフレーム毎に1回計算を行いますが、VR空間の3次元データの複雑さによって、フレームの更新レートは変動します。そのため、可変の時間差に対応した計算を行う必要があります。

 移動の計算自体は移動するものや数学モデルによってさまざまな方法がありますが、バーチャルリアリティのシミュレーションでは、ある物の姿勢から次の姿勢を計算します。その際、姿勢と姿勢の時間差を使用して移動量を計算します。下記は一定の速度で直線にそった動きの例です。この例は、時間差が可変の場合でも使用可能な計算方法です。

procedure CalculatePosition(dtInSeconds : double; const CurrentX,
   CurrentY : double; out X, Y : double);
     const
       SPEED = 10; // メートル毎秒
       DirectionX = 1.41421;
               // 移動の方向ベクトル、X座標
       DirectionY = 1.41421;
               // 移動の方向ベクトル、Y座標
       //方向ベクトルを単位ベクトルとします。

     begin
     //dtInSeconds後の新しいX座標を計算します。
     X := CurrentX + SPEED * dtInSeconds * DirectionX;
     //dtInSeconds後の新しいY座標を計算します。
      Y := CurrentY + SPEED * dtInSeconds * DirectionY;
end;

キャラクタ位置の制御
 ここではあらかじめ保存された移動の設定を、実際の時間で再現させる処理を説明します。まず、情報の保存形式を決める必要があります。汎用性を考慮し、姿勢(位置と方向)情報を時間によって保存するものとします。変数の型は以下のように宣言します。


type

   //位置情報、方向、時刻の保存レコード
   //timeで指定された時刻にキャラクタあるいは移動物体が
   //positionの位置、orientationの方向で表示されると考えます。
   RoutePointType = record
     time : double; //時刻
   position : array [1..3] of double; //3D座標
   orientation : array [1..3] of double; //3Dベクトル
     end;

   //キャラクタあるいは移動物体が移動するルートを
   //RoutePointTypeの配列で定義します。
   RouteType = array of RoutePointType;

図1 MD3キャラクタのクラス構造

 この型により決まった時刻での姿勢情報が保存されます。この動きを表現するには、保存されている姿勢でキャラクタを表示させ、実際に経過した時間によって適切な位置を計算します。このように、時間によって表示する姿勢を更新していくことで動きの表現が可能です。

 ただし、UC-win/Roadで描画を行う時刻に合わせて姿勢情報を計算する必要があります。その場合は、UC-win/Roadの描画時刻とルートに保存されている姿勢の時刻が異なる可能性があるため、UC-win/Roadの描画時刻に最も近い姿勢情報(直前と直後)を補間することで、滑らかな動きの表現が可能になります。

道路の平面線形
 Roadオブジェクトの下にある各TurningPointは、平面線形のIP点(Intersection Point)を定義します。これは道路直線空間の延長線が交差する点になります。平面線形はTurningPointの配列で定義され、その配列はRoadオブジェクトのturningPointプロパティからアクセスします。

図2 キャラクタの移動の再現の仕組み

 コールバック関数を使用してキャラクタの姿勢を更新するタイミングを、UC-win/Road本体によって教えてもらうようにします。生成したキャラクタのOnMoveイベントプロパティに関数を割り当てると、キャラクタの姿勢を更新する際に、割り当てた関数が呼ばれます。この関数でキャラクタの動きを計算し、姿勢情報を更新します。

 ここまでで、生成したキャラクタの姿勢を更新するところまではできましたが、UC-win/Roadのキャラクタインスタンスをあらかじめ保存されているルートに対応させる必要があります。複数の方法が考えられますが、ここでは新しいクラスでルートとキャラクタインスタンスを対応させます。具体的には、このクラスでルートの情報を保存し、キャラクタのOnMoveイベントにこのクラスのメソッドを割り当てます。

 キャラクタインスタンスがUC-win/Road本体から削除される時、OnDetroyイベントを使えば、プラグイン側で関係する情報を解放することができます。また、ルート情報をテキストファイルから読み込む機能なども、このクラスで実装すると便利です。最終的に下記のようなクラス宣言になります。

   unit Move;

   interface

   uses
     Classes,
     F8OpenGL,
     PluginCore;

   type

     // ルートで1つのノードを保存するレコード
     // ここではF8OpenGLで宣言されている
     // ポイントタイプを使用します。
     RoutePointType = record
       time: double; // 時刻
       position: GLPointType; // 3D座標
       orientation: GLPointType; // 3Dベクトル
     end;

   // キャラクタインスタンスとルート情報を対応させるクラス
   MoveClass = class
   private
     // 現在管理するキャラクタインスタンスのインタフェース
     p_Instance: IF8MovingObjectInstance;
     // ルートの中で現在の姿勢情報インデックスを保持する変数
     currentPointIndex: integer;
     // ルートの中で現在の時刻を保持する変数
     time: double;
     // ルートの中身を保持する変数
     route: array of RoutePointType;

     // キャラクタインスタンスを割り当てる際に呼び出す関数。
     // この関数は以下宣言されているMyInstanceプロパティ
     // 代入時に自動的に呼ばれます。
     procedure SetInstance
     (const Value: IF8MovingObjectInstance);

   public
     // オブジェクトの生成
     constructor Create(source: TStrings);
     // オブジェクトの開放
     destructor Destroy; override;
     // UC-win/Road本体が動きの計算を要求する際に
     // 呼び出す関数。
     procedure Move(dTimeInSeconds: double; Instance:
     IF8MovingObjectInstance);
     // UC-win/Road本体側でキャラクタインスタンスが
     // 削除される際に呼び出す関数。
     procedure InstanceDestroy(Instance: IF8DBObject);
     // 初期化に用いる関数。最初の位置に戻します。
     function GetFirstPosition: GLPointType;
     // 現在対応するキャラクタインスタンスにアクセスするための
     // プロパティ。
     property MyInstance
       : IF8MovingObjectInstance read p_Instance
          write SetInstance;

 このクラスのメソッドの実装は以下の通りになります。

   implementation

   uses
     SysUtils;

   { MoveClass }

   // ===================================================
   // オブジェクトの生成と初期化
   // 初期化ではCSVファイルから時刻と姿勢情報を読み込んで
   // ルート変数にデータを保持します。
   // CSVファイルの形式は下記の通り。
   // 時刻,位置のX座標,位置のY座標,位置のZ座標,ヨー角,
   // ピッチ角,ロール角
   // 例:
   // 0,5000,2,5000,1.5707963267948966192313216916398,0,0
   // 5,5005,3,5000,0,0,0
   // 10,5005,4,5005,0.78539816339744830961566084581988,0,0
   // 15,5010,5,5010,-2.3561944901923449288469825374596,0,0
   //20,5000,2,5000,1.5707963267948966192313216916398,0,0
   // ==================================================
   constructor MoveClass.Create(source: TStrings);
     var
       i: integer;
       node: RoutePointType;

     begin
     // メンバーの初期化
     time := 0;
     currentPointIndex := 0;
     p_Instance := nil;
     // CSVファイルの中身の読み込み
     source.CommaText := source.Text;
     SetLength(route, source.Count div 7);
     i := 0;
     while i < source.Count do
       begin
       node.time := StrToFloat(source[i]);
       Inc(i);
       node.position[_x] := StrToFloat(source[i]);
       Inc(i);
       node.position[_y] := StrToFloat(source[i]);
       Inc(i);
       node.position[_z] := StrToFloat(source[i]);
       Inc(i);
       node.orientation[_x] := StrToFloat(source[i]);
       Inc(i);
       node.orientation[_y] := StrToFloat(source[i]);
       Inc(i);
       node.orientation[_z] := StrToFloat(source[i]);
       Inc(i);
       route[i div 7 - 1] := node;
     end;
   end;

   // ==================================================
   // オブジェクトの解放
   // ==================================================

   destructor MoveClass.Destroy;
     begin
     MyInstance := nil;
     end;

   // ==================================================
   // 初期化に使用する関数。最初の位置を戻します。
   // ==================================================

   function MoveClass.GetFirstPosition: GLPointType;
     begin
     if High(route) >= 0 then
     result := route[0].position;
     end;
   // ==================================================
   // UC-win/Road本体側でキャラクタインスタンスが
   // 削除される時に呼ぶ関数です。
   // キャラクタインスタンスのインタフェースを解放します。
   // ==================================================
   procedure MoveClass.InstanceDestroy
               (Instance: IF8DBObject);
     begin
     p_Instance := nil;
     end;

   // ==================================================
   // UC-win/Road本体が動きの計算を要求する時に呼ぶ関数。
   // あらかじめ読み込んだルートデータから位置を計算し
   // キャラクタインスタンスに反映させます。
   // ==================================================
   procedure MoveClass.Move(dTimeInSeconds: double;
        Instance: IF8MovingObjectInstance);

     function LookForNode: boolean;
       var
         i: integer;

     begin
     result := false;
     // 現在の位置からルートの中で該当する位置を検索。
     // 見つかったら、現在の位置を更新します。
     for i := currentPointIndex to High(route) - 1 do
       begin
       if (route[i].time <= time) and (route[i + 1].time > time) then
         begin
         currentPointIndex := i;
         result := true;
         Break;
         end;
       end;
     end;

   var
       // 位置の計算に使う変数。
       position: GLPointType;
       p1: GLPointType;
       p2: GLPointType;

(以下、省略)

以上のような記述になります。

 最終的に開発するプラグイン側では、キャラクタインスタンスの生成、削除などを管理するプログラムが必要となりますが、ここでは省略します。

体験セミナーのお知らせ
 UC-win/Road SDKセミナー
日時 2012年 7月20日(金) 13:30〜17:00
受講費 ¥15,750(税込)
本会場 フォーラムエイト東京本社 GTタワーセミナールーム
TV会議システムにて東京・大阪・名古屋・福岡・仙台同時開催

     
前ページ    インデックス    次ページ
(Up&Coming '12 夏の号掲載)
戻る
Up&Coming

FORUM8


お問合せ窓口




[ ユーザー紹介 ]
櫻井工業株式会社
株式会社TEAM IWAKIRI PRODUCTS
[ 開催報告 ]
第17回FORUM8デザインフェスティバル






>> 製品総合カタログ


>> プレミアム会員サービス
>> ファイナンシャルサポート

最近リリースした製品
3次元鋼管矢板基礎の設計計算(部分係数法・H29道示対応) Ver.4
UC-1・UC-1 Cloud 統合版 BOXカルバート
電子納品支援ツール Ver.17
柔構造樋門の設計・3D配筋 Ver.17
建築杭基礎の設計計算 Ver.10

キャンペーン実施中
地方創生・国土強靭化 FORUM8セミナーフェアキャンペーン
レンタルアクセス同時購入キャンペーン・過去レンタルキャンペーン
Shade3D・F8VPS 20%OFFキャンペーン

セミナー・イベントカレンダー
開催間近のセミナー
4/2  ブロックUIプログラ
  ミングツールで学ぶ
  ジュニア・プログラミング
4/3  動的解析
4/4  下水道耐震設計体験
4/5  Shade3D-F8VPS
  メタバース入門

ソフトウェア/支援サービス
VRソフト(バーチャルリアリティ)
《UC-winシリーズ》
・道路・シミュレータ
・ドライブ・シミュレータ
・マイクロ・シミュレーション
・避難解析・シミュレーション
>>その他VRソフト
FEM解析ソフト
・3次元プレート動的非線形解析
・2次元動的非線形解析
・総合有限要素法解析システム
>>その他FEM解析ソフト
土木・建築・設計ソフト
《UC-1シリーズ》
・構造解析/断面
・橋梁上部工
・橋梁下部工
・基礎工
・仮設工
・道路土工
・港湾
・水工
・地盤解析
・CAD/CIM、建設会計
・維持管理・地震リスク
・建築
・船舶/避難
>>その他土木・建築・設計ソフト
クラウド
《スパコンクラウド®》
・スパコンクラウドサービス
《VR-Cloud®》
・リアルタイムVRシステム
解析支援サービス/サポート
・UC-win/Roadサポートシステム
・設計成果チェック支援サービス
・Engineer's Studio®解析支援
・地盤解析支援サービス
・EXODUS/SMARTFIRE解析支援
・xpswmm解析支援サービス
・建物エネルギーシミュレーション
・3Dレーザスキャン・モデリング
・3D模型サービス
・3D報告書・図面サービス
>>その他支援サービス
各種ソリューション
・耐震診断/解析
・鋼橋設計
・橋梁新工法
・建築設計
・自治体
・医療系VRシステム
・パーキングソリューション
・ECOソリューション
>>その他ソリューション