はじめに
プログレッシブメッシュは、レンダリングパフォーマンスを向上させるために使用できる特殊なオブジェクトです。たとえば、多数の面を持つ大きなシェルは画面上で非常に小さく表示されることがあり、通常、それら(およびシェル全体)が画面上でどれほど小さくても、すべての面は独立してレンダリングされます。
プログレッシブメッシュを使用すると、詳細レベル (LOD) を変更し、元のシェルのより適切なバージョンを取得できます。たとえば、現在の LOD を下げて、シェルに含まれる面を大幅に減らすことができます。画面上で小さいため、視覚的な欠陥は認識されません。
他の LOD 関連技術とは対照的に、プログレッシブメッシュは、0 (利用可能な最小表現) から最大 LOD (元のシェル表現) までの任意の LOD にリアルタイムで LOD を切り替えることができます。
メモリ使用量の観点から見ると、占有メモリは、現在の LOD 表現と、LOD 間の切り替えを提供する LOD 情報のリストの 2 つのグループに分けられます。
- 最初のグループのサイズは現在の LOD に依存します。ゼロの場合、表現は非常に小さく、LOD の増加とともに線形に増加します。
- 2 番目のグループのサイズは各 LOD で一定であり、そのサイズは最大 LOD 表現のメモリ使用量に匹敵します。
ODAはバージョン22.10以降、プログレッシブメッシュの部分的な読み込みをサポートしています。部分的なプログレッシブメッシュの読み込み中、記述されたLOD情報リストはRAMに保存されず、ファイルストリームに保持されるため、メモリ使用量が大幅に削減されます。この場合、LODの切り替えは遅くなりますが、パフォーマンスの低下はごくわずかである可能性があります。
部分読み込みにOdGiProgressiveMeshを使用する
OdGiProgressiveMeshインターフェースは、プログレッシブメッシュの部分的な読み込みをサポートするように拡張されています。LOD情報をメモリに保持せず、代わりにOdGiDataExtractorの顧客が実装したインスタンスを使用して、必要に応じてLODデータにアクセスします。
部分読み込みのためのOdGiProgressiveMeshメソッド
部分読み込みの場合、OdGiProgressiveMeshGeneratorには次のメソッドがあります。
virtual OdGiProgressiveMeshPtr createPartialProgressiveMeshFrom( OdStreamBuf* pBuff, OdGiDataExtractor* pDataExtractor,
const OdGiProgressiveMeshObjectIdConverter* pConverter = NULL,
OdGiProgressiveMesh::ProgressiveMeshStreamVersion version = OdGiProgressiveMesh::kVersionActual ) const = 0;
さらに、OdGiProgressiveMeshExには次のメソッドがあります。
virtual bool readPartialProgressiveMeshExFrom( OdStreamBuf* pBuff, OdGiDataExtractor* pDataExtractor, const OdGiProgressiveMeshObjectIdConverter* pConverter = NULL,
OdGiProgressiveMesh::ProgressiveMeshStreamVersion version = OdGiProgressiveMesh::kVersionActual ) = 0;
これらのメソッドは、元のcreateProgressiveMeshFromおよびreadProgressiveMeshExFromメソッドに似ていますが、LOD情報をメモリに保持する代わりにOdGiDataExtractorのインスタンスを使用します。OdGiProgressiveMeshには、いくつかのメソッドもあります。
-
プログレッシブメッシュが部分モードであるかどうかを定義します。virtual bool isInPartialMode() const = 0; -
LOD情報をメモリに強制的に読み込み、部分モードを終了します。これは、部分モードでプログレッシブメッシュの読み込みに使用されるファイルを書き換える場合に役立つことがあります。この場合、ストリームが変更される可能性があるため、エクストラクタと計算されたオフセットが有効であるという保証はありません。virtual void endPartialMode() = 0;
部分読み込みにOdGiDataExtractorを使用する
OdGiDataExtractorクラスは、データ抽出インターフェースを定義します。各オブジェクトは異なる方法でエクストラクタを使用する可能性があるため、エクストラクタの実装は現在処理している正確なデータを知ることはできません。代わりに、オブジェクトはエクストラクタに異なるデータ型を登録し、登録されたデータを抽出したいときにエクストラクタに通知します。
データ登録には、dataIdの開始を登録し、その終了を登録する2つのOdGiDataExtractorメソッドを使用します。
virtual bool registerDataBegin( OdUInt8 dataId, OdUInt64 localOffset ) = 0;
virtual bool registerDataEnd( OdUInt8 dataId, OdUInt64 localOffset ) = 0;
オブジェクトがデータを抽出する前に、次のメソッドを使用して抽出を開始する必要があります。
virtual bool beginExtraction( OdUInt8 dataId ) = 0;
通常、このメソッドでは、エクストラクタは登録されたdataIdの先頭を見る必要がありますが、実装によって異なる場合があります。オブジェクトが必要なすべてのデータを抽出した後、次のメソッドを使用して抽出を終了する必要があります。
virtual bool endExtraction( OdUInt8 dataId ) = 0;
通常、このメソッドはエクストラクタをリセットします。beginExtraction()とendExtraction()の間、オブジェクトは次のメソッドを使用してデータを抽出できます。
virtual void extractBytes( void* buffer, OdUInt32 numBytes ) = 0;
OdGiDataExtractorには、extractBytes()に基づいたデフォルトの実装を持ついくつかのヘルパーメソッドもあります。
また、オブジェクトは以下を使用できます。
virtual bool seekFromLocalOffset( OdUInt64 offset ) = 0;
この場合のオフセット値は、dataIdの開始が0として計算されるローカルdataIdオフセットであることに注意してください。
部分読み込みにOdTvProgressiveMeshを使用する
VSFXファイルから読み込まれる各OdTvProgressiveMeshは、部分的なプログレッシブメッシュ読み込みの2つのバージョンをサポートしています。OdTvFactoryIdクラスのreadVSFXメソッドには、OdTvVSFXReadOptionsオプションパラメータがあります。これらのオプションには、次のいずれかになるprogressiveMeshModeフィールドがあります。
- OdTvVSFXReadOptions::kNormalMode — プログレッシブメッシュを通常モードで読み込みます。
- OdTvVSFXReadOptions::kPartialMode — プログレッシブメッシュを純粋な部分モードで読み込みます。
- OdTvVSFXReadOptions::kFastPartialMode — プログレッシブメッシュを部分モードの高速ハイブリッドで読み込みます。VSFファイルからのOdTvProgressiveMeshは部分的な読み込みをサポートしていません。
OdTvVSFXReadOptions::kPartialMode
これは純粋な部分モードです。プログレッシブメッシュはLOD情報をメモリに保存せず、各LODの詳細を個別に1つずつ抽出します。そのため、メモリ使用量は常に最小限に抑えられます。一方、各LODの詳細の抽出にはファイルストリームアクセスが必要なため、LODの切り替えは非常に遅くなります。ただし、メモリ使用量が重要なケースでは良い解決策となり得ます。
OdTvVSFXReadOptions::kFastPartialMode
これは部分モードの高速ハイブリッドです。プログレッシブメッシュはLOD情報をメモリに保存しません。ただし、LODを切り替える必要がある場合、ファイルストリームからLOD情報全体のリストを読み込みます。LODの切り替えが完了すると、LOD情報のリストをアンロードします。したがって、LODの切り替えを実行する際にはメモリ使用量が増加しますが、完了後は再びメモリ使用量が最小限になります。このアプローチにより、パフォーマンスの低下はほとんど知覚できないレベルにまで抑えられます。