プログレッシブメッシュの新しい自動LOD選択 (パート1/2)

ODA SDKs バージョン 21.4 以降、OdGiProgressiveMesh は OdGiProgressiveMesh::selectLOD() メソッドを呼び出すことで、詳細レベル (LOD) を自動的に選択できます。

OdGiProgressiveMesh は、カスタム (ユーザー定義) および補間選択の両方について、列挙型 OdGiProgressiveMesh::ProgressiveMeshAutoSelectLOD で説明されている LOD 選択メカニズムをサポートしています。

補間LOD選択

OdGiProgressiveMesh::kSqrInterpolation と OdGiProgressiveMesh::kSqrtInterpolation は、補間LOD選択の2つの方法を提供します。

これらのメソッドは、OdGiViewport を使用してメッシュ範囲の対角線をピクセル単位で再計算します。次に、minPixels と maxPixels の2つのしきい値を使用します。再計算された対角線の長さが minPixels 値より小さい場合、LOD 0 (最小) が使用されます。再計算された対角線の長さが maxPixels 値より大きい場合、numLODs() (最大) が使用されます。その他の場合、これらのメソッドは (minPixel, LOD 0) と (maxPixel, numLODs) の2点間で LOD を補間します。

 

LOD interpolation

 

OdGiProgressiveMesh::kSqrInterpolation は、二乗補間を使用します: LOD = A * 対角線 * 対角線 + B。二乗関数は急速に増加するため、このメソッドはメッシュの詳細度を低く保ち、パフォーマンスを向上させようとしますが、視覚的な単純化の欠陥が見られる場合があります。

OdGiProgressiveMesh::kSqrtInterpolation は、平方根補間を使用します: LOD = A * sqrt(対角線) + B。このメソッドはより詳細なメッシュを提示するため、視覚的な単純化の欠陥は目立たないはずです。ただし、メッシュが指定されたビューに対して「詳細すぎる」場合があり、パフォーマンスが低下する可能性があります。

補間LODのオプション

OdGiProgressiveMesh クラスには、補間LOD選択のための OdGiProgressiveMeshAutoLODSelectOptions クラスのインスタンスを指定する新しい setAutoSelectLODOptions() メソッドがあります。このクラスは、minPixels と maxPixels の補間しきい値を定義します。

OdUInt32 maxPixels() const;
OdUInt32 minPixels() const;

カスタムLOD選択

OdGiProgressiveMesh クラスは、カスタム (ユーザー定義) LOD 選択も提供します: OdGiProgressiveMesh::kCustom。この選択を使用する前に、OdGiProgressiveMeshAutoLODSelectCallback のインスタンスを実装し、OdGiProgressiveMesh::setCustomLODAutoSelectCallback() メソッドを使用して指定する必要があります。

実装されたコールバックメソッドは、プログレッシブメッシュの適切な詳細レベルを、区間 [0, numLODs()] の OdUInt32 値として返す必要があります。

virtual OdUInt32 selectLOD( const OdGiProgressiveMesh* pPM, const OdGiViewport* pView, const OdGeMatrix3d* pModelToWorldTransform ) const = 0;

間隔外のすべての値はエラーとして扱われ、詳細レベルは切り替わりません。

カスタムLODの例

OdGiProgressiveMeshクラスは、詳細レベルの線形補間を提供しません。ただし、カスタムの詳細レベル選択を使用して追加できます。

class OdGiLinearLODInterpolation : public OdGiProgressiveMeshAutoLODSelectCallback
{
public:
OdUInt32 selectLOD( const OdGiProgressiveMesh* pPM, const OdGiViewport* pView, const OdGeMatrix3d* pModelToWorldTransform )
{
  //Obtain extents diagonal
  double D = pPM->extents().diagonal().length();
  //Obtain viewport scales
  OdGePoint2d scale;
  pView->getNumPixelsInUnitSquare( pView->getCameraLocation(), scale, pView->isPerspective() );
  double maxDim = scale.x > scale.y ? scale.x : scale.y;
  //Scale diagonal
  maxDim *= D;
  //Interpolation options
  OdUInt32 minPx = pPM->autoSelectLODOptions().minPixels();
  OdUInt32 maxPx = pPM->autoSelectLODOptions().maxPixels();
  //Check interpolation interval
  if( maxDim < minPx ) return 0; //Less that minimum - always minimum LOD
  if( maxDim > maxPx ) return pPM->numLODs(); //More than maximum - always maximum LOD
  //Interpolation: LOD = A * pixels + B, where 0 = A * minPx + B and numLODs = A * maxPx + B
  double A = (double)( pPM->numLODs() ) / (double)( maxPx - minPx );
  double B = -1.0 * A * minPx;
  return (OdUInt32)( A * maxDim + B );
}
};
…
OdGiLinearLODInterpolation* linearLODInterpolation = new OdGiLinearLODInterpolation();
pPM->setCustomLODAutoSelectCallback( linearLODInterpolation );
pPM->selectLOD( OdGiProgressiveMesh::kCustom, pViewport );

このシリーズの次の記事では、Visualize SDKの新しい自動LOD選択の使用方法について説明します。

今すぐ始める

ODAソフトウェアを60日間無料でお試しください。
リスクなし、クレジットカード不要。

無料で試す