OpenVDB は本当に素晴らしいようで、ノードのアドレス指定は本当にスマートです。特にCSG操作など、理解できない操作がいくつかあります。これはコード例です。入力として 2 つの引数を取ります。
- 三角形のメッシュから作成されたレベル セットを表す、グリッドが 1 つだけの vdb 入力ファイル
- 操作の結果を格納する vdb 出力。
アルゴリズムは入力を受け取る必要があります。
- gridA に deepCopy を作成します
- gridB に deepCopy を作成します
- M_PI/4.0f の Y 軸に沿って gridB を回転します。
- gridA と gridB の間で csgUnion を実行します
- すべてのグリッドを vdb 出力ファイルに保存します。
衝突で高レベルの詳細を必要とする物理シミュレーションのために、classicoctree アルゴリズムの代わりに VDB グリッドをデータ コンテナーとして使用しようとしています。
ワールド座標とグリッド座標の間の変換の概念を理解しています。理解できないのは、剛体オブジェクトのようにレベルセットを平行移動または回転させるなど、ツリー内でデータの変換を実行する方法です。この例では、ワールドとラティスの間の変換のみを変更していると思います。
これが結果です (レベルセットとボリュームも同じです):初期グリッド変換さ
れたグリッド、回転が実行されているようです...
最終結果はありませんか?
提案はありますか?
添付: 1 つの例と、私が使用しているLINK REMOVED へのリンク (申し訳ありませんが、133MB です...)
#include <cmath>
#include "openvdb/openvdb.h"
#include "openvdb/util/Util.h"
#include "openvdb/io/Stream.h"
#include "openvdb/tools/Composite.h"
using namespace openvdb;
int main(int argc, char** argv) {
openvdb::initialize();
openvdb::io::File file(argv[1]);
file.open();
GridBase::Ptr baseGrid;
for (openvdb::io::File::NameIterator nameIter = file.beginName();
nameIter != file.endName(); ++nameIter)
{ baseGrid = file.readGrid(nameIter.gridName()); }
file.close();
FloatGrid::Ptr gridA = gridPtrCast<FloatGrid>(baseGrid);
FloatGrid::Ptr gridB = gridA->deepCopy();
FloatGrid::Ptr result = gridA ->deepCopy();
gridB->transform().postRotate(M_PI/4.0f, math::Y_AXIS);
tools::csgUnion(*result, *gridB);
openvdb::io::File file_out(argv[2]);
GridPtrVec grids;
grids.push_back(gridA);
grids.push_back(gridB);
grids.push_back(result);
file_out.write(grids);
file_out.close();
return 0;
}