2

モデル I/O フレームワークを使用して、Scene Kit で使用する .obj ファイルをインポートしようとしています。最初は単純な MDLAsset initWithURL: 関数を使用しましたが、メッシュを SCNGeometry に転送した後、この関数がメッシュを三角測量していることに気付きました。これにより、各面に 3 つの一意の頂点があり、境界面の同じ位置に別々の頂点が存在するようになります。これは私の他の関数でいくつかの大きな問題を引き起こしていたので、代わりに MDLAsset initWithURL:vertexDescriptor:bufferAllocator:preserveTopology 関数を使用し、preserveTopology を YES に設定し、記述子/アロケータをデフォルトの nil に設定して修正しようとしました。この保存されたトポロジにより、頂点の複製の問題が解決されたため、面/エッジはすべて良好でしたが、その過程で法線データが失われました。

法線が失われたということは、複数のインデックス作成を意味するのではありません。つまり、preserveTopology を YES に設定した後、バッファには法線値がまったく含まれていませんでした。以前は v1/n1/v2/n2... で、ストライドは 24 バイト (3 次元 * 4 バイト/float * 2 属性) でしたが、現在はバッファーの前半が v1/v2/... で、ストライドは 12 で、バッファの後半全体はちょうど 0.0 浮動小数点数です。

また、Geometry の SCNGeometrySources を見ると、2 つのソースがあり、1 つはセマンティック kGeometrySourceSemanticVertex で、もう 1 つはセマンティック kGeometrySourceSemanticNormal です。セマンティック頂点ソースには位置データが含まれ、セマンティック法線ソースには法線データが含まれると考えるでしょう。しかし、そうではありません。preserveTopology の設定に関係なく、同じ値を持つ位置データと通常データの両方を格納できるサイズのバッファーです。したがって、法線データがないと言ったとき、これらのバッファの両方、セマンティック頂点とセマンティック法線が v1/n1/v2/n2... から v1/v2/.../(0.0, 0.0, 0.0)/(0.0, 0.0, 0.0)/... mdlmesh のバッファ (シーン キットに転送する前) に移動したところ、同じ問題が見つかったので、問題は initWithURL にあるはずです。

したがって、デフォルトの頂点記述子とバッファ アロケータに何か問題があるに違いないと考え (nil を使用していたため)、これら 2 つの可能なデータ形式に一致する独自のものを作成しようとしました。残念ながら、多くのことを試みた後、うまくいくものを手に入れることができませんでした。

これをどのように行うべきかについてのアイデアはありますか? .obj ファイルをインポートするために、MDLAsset に適切な vertexDescriptor と bufferAllocator を与える方法 (ここでは nil で十分だと思います)。ありがとう

4

1 に答える 1

3

頂点と法線を含む obj ファイルには、v 行で示される頂点、vn 行で示される法線、および f 行で示される面があります。

v と vn の行は予想される浮動小数点値であり、f の行は次の形式になります -

f v0//n0 v1//n1 など

OpenGL と Metal では複数のインデックス作成が許可されていないため、頂点が複製される最初の効果が見られます。例えば、

f 0//0 1//2 2//0

頂点ごとに異なるインデックスが必要になるため、頂点バッファーとしては機能しません。そのため、典型的な OBJ パーサーは、顔が次のようになる新しい頂点を作成する必要があります。

f 0//0 1//1 2//2

トポロジを保持するオプションは役に立ちません。メッシュの接続性と形状は維持されますが (三角測量は行われず、共有エッジは共有されたままです)、頂点コンポーネントごとに 1 つのインデックスが適用されます。

解決策の 1 つは、OBJ ファイルを出力するツールがエクスポート中に単一のインデックスを使用するようにすることです (それがオプションである場合)。

もう 1 つのオプションは、これですぐに問題が解決するわけではありませんが、モデル I/O レベルで複数のインデックス作成がサポートされるように要求を提出することです。SceneKit は、レンダリングできる必要があるため、一意にインデックスを作成する必要があります。

別のオプションは、複数のインデックスを持たない PLY のような形式を使用することです。

于 2016-04-09T16:23:52.763 に答える