オブジェクトコンテナーとしてのシーングラフ?


8

シーングラフには、ゲームオブジェクトを表すゲームノードが含まれています。一見すると、たとえばstd :: vector <>の代わりに、シーングラフをゲームオブジェクトの物理コンテナーとして使用するのが現実的であるように見えるかもしれません。

私の質問は、ゲームオブジェクトを含めるためにシーングラフを使用することは現実的ですか、またはstd :: vector <>などの別のコンテナーに格納されたオブジェクトを保持しながら、シーンオブジェクト/ノードのリンケージを定義するためだけに使用する必要がありますか?


誰かがアイデアを持っていますか?シーングラフを使用してゲームアクター/ノードを整理し、次にベクターを使用して、多方向のSceneGraphツリーをソートするよりも高速なさまざまなソートを実行する予定です。
Bunkai.Satori、2011

@すべて:もう1つ質問があります。SceneGraphにはマップ全体が含まれていますか、それともマップ部分だけが含まれている必要がありますか?明らかに、プレーヤーがマップ上を移動すると、シーングラフが継続的に更新されます。
Bunkai.Satori

回答:


5

使用するシーン管理のタイプを決定することは、実行しようとしているロジックのタイプに大きく依存します。シーンのさまざまなコンシューマーを考慮してください。

レンダリングコンシューマ

レンダラーはおそらく、任意の時点でユーザーに現在表示されているものを知りたいだけです。高速カリング用のバウンディングボリューム階層が必要です(BVH wikiの記事)。 これにより、ボートの境界が視錐台の外側にあるため、ボート内の椅子を描画する必要がないことがわかります。これはoctreeに埋め込まれている場合があります。

それはまた、椅子がボートの内側の背中にあり、ボートが最終的に見えるようになると、いくつかの波でボートが上下に動いていることを知りたいかもしれません。このようにして、椅子の頂点の最終的な世界座標を見つけることで、椅子とボートの変換を連結し、それを使って処理を行うことができます(これにより、プログラマーとしての作業も簡単になります)。

この問題を見るもう1つの方法は、レンダラーが適切なカードを実行している可能性があり、最終的には、テクスチャ、シェーダー、マテリアル、ライティング、変換状態の変化を最小限に抑えるために、三角形の山を並べ替えることを望んでいることです。このラストは、おそらくパフォーマンス面でBVHよりも役立つでしょう。

ゲームロジック消費者

ゲームロジックは、メッセージングシステムによって互いに通信できるもののフラットリストを必要とするだけなので、std :: vectorで十分です。

ゲームはまた、誰が何に最も近いかを追跡する方法を必要とする場合があるため、そのような場合、ある種の[最も近い] [3]情報が役立つ場合があります。これはBVHでも提供できますが、グラフを上下に移動しなければならないのは面倒です。

ゲームは、Aを移動すると、AのアイテムBも移動することを知りたいだけかもしれません。その場合、一種の変換階層に戻ります。

物理学の消費者

ゲームの物理学では、非常に高速な衝突検出のために、屋内空間の[特別な表現] [4]が必要になる場合があります。あるいは、衝突する可能性のあるものを効率的に見つけるために、ある種のoctreeまたは[空間ハッシュ] [5]を使用する場合があります。

上記の物理データ構造はどれも、Java3Dの意味で「シーングラフ」のようには見えません。

オーディオ消費者

オーディオエンジンは、サウンドの減衰と伝搬を計算するために、ジオメトリ、おそらく潜在的に表示される(可聴)セット、または何らかの境界ボリューム階層を必要としています。繰り返しになりますが、シーンのジオメトリのグラフである可能性もありますが、実際には通常の種類のシーングラフではありません。

最終的には... ...実際のアプリケーションのニーズによって異なります。まず、フラットリストを使用して、問題が発生する場所を確認することをお勧めします。変換の階層を持つフラットリストを試すこともできます。これは、効率以外の理由で役立つ1種類のシーングラフであるためです。

幸運を!


@ChrisE:すばらしい質問には+1。私の意見では、これがここでの最良の回答です。したがって、これを承認済みの回答としてマークしましょう。私が正しく理解していれば、シーングラフが必ずしも最終的なソリューションであるとは限らないことを証明しました。特にゲームロジックでは、関連オブジェクトの変換(スケール、移動)を更新する正しい方法としてシーングラフを見ていますか?例:ボート上に椅子があるので、ボートが移動すると椅子の座標が更新されますか?または、相対座標の更新に対するより良い解決策がありますか?
Bunkai.Satori

@ChrisE:上記に加えて、シーングラフを使用する場合、それ自体をシーンの唯一のオブジェクトホルダーとして使用できますか、またはシーン以外に別のコンテナー(std :: vector <>など)を使用することをお勧めしますグラフ?
Bunkai.Satori

2
私は実際にそれを提案している最中だった。各ノードがゲームオブジェクトへの参照を含む変換階層(ここでは、ノードに1つの親と複数の子があり、子がノード間で共有されていないn-aryツリー)を維持しようとします。ゲームオブジェクトは、別個のフラットな配列(たとえば、std :: vector)に保持されます。
ChrisE、2011

更新中は、フラットリストをforeachしてゲームロジックを実行できます。相対移動が発生するたびに(たとえば、椅子がボート上で前進するとき)、変換階層を使用して、ウォーキングによって最終的なローカルから世界への変換を見つけます。オブジェクトの親をアップし、それらの変換を連結します。これは、(相対的な動きを単純化して)最適な変換階層を使用し、オブジェクトの便利なリストを保持できるようにします。
ChrisE、2011

さらなる改善は、各オブジェクトのダーティフラグと、変換階層内のその上のすべての変換を維持することです。キャッシュされた親から世界への変換(先ほど述べた変換)は、オブジェクトの位置を更新する場合、行列の乗算(親から世界への変換による親への相対変換)を1回実行するだけでよいことを意味します。相対変換を更新するたびに、ダーティフラグも更新します。
ChrisE、2011

3

ゲームオブジェクトのコンテナとしてシーングラフを使用しない理由は1つあります。それはインスタンス化です。一部のリソースを再利用する場合は、実際のコピーを複数持つよりも、シーングラフからリソースを数回参照するほうがはるかに理にかなっています。


@Jari:良い答えには+1。私が理解しているように、一般的なアプローチは、レンダリング可能なメッシュの個別のコンテナーを持つことです。シーングラフは通常、レンダリング可能なメッシュコンテナーを参照して、オブジェクトの形状情報を取得します。さらに、すべてのシーングラフノードには変換情報が含まれています。ヤリは、このような設計を持って、私はそれはまだゲーム・ノード用に別のstd ::ベクトル<>コンテナを持っていることが推奨されている場合..速くソートの目的で、または別の理由のために言って、知っていただきたいと思います
Bunkai.Satori

2
依存する-AIや物理学などの処理を高速化するために、ノードの線形リストを実際にいくつか持つと便利な場合があります。しかし、他に問題があるかどうかを確認したら、そこに行きます。
Jari Komppa、2011

したがって、結論として、最初はシーン内のすべてのオブジェクトを含むSceneGraphが1つだけであっても問題ありません。カメラ、ライト、トリガーもシーングラフに含める必要がある場合は、アドバイスをいただけますか?
Bunkai.Satori

変換階層の影響を受けるものはすべてシーングラフ内にある必要がありますが、シーングラフに所有権を与えるのではなく、(アニメーション、物理など)処理を簡単にするためにそれらを他の場所に保存します。
Jari Komppa、2011

ヤリを理解した。ありがとう。小さいバージョンから始めて、後で必要に応じて処理を簡単にするために別のコンテナーを追加します。
Bunkai.Satori

2

オブジェクトモデルとビューモデル(シーングラフ)を分離することは、通常は良い考えです。

この件に関する記事をご覧ください。

これにより、オブジェクトプールを使用できるようになります。これは、効率的なメモリ管理に不可欠です。


貢献度が高い場合は+1。記事を読みました。プログラミングパターンについて説明します。正しく理解した場合、オブジェクトモデルはシーン内のオブジェクトのリストを一種のstd:vector <>コンテナーに整理しますが、ViewModelはシーングラフに整理された同じオブジェクトを含みますか?ただし、現在表示されているオブジェクトのみがシーングラフに含まれますか?
Bunkai.Satori

そして、カメラ、トリガー、ライトはどうですか?それらもシーングラフの一部になりますか?
Bunkai.Satori

@ Bunkai.Satoriええと、シーングラフに画面に表示されないものがあるかもしれません。シーングラフを作成したら、可視ノードをレンダリングする前に、シーングラフに対してカリングアルゴリズムを実行できます。カメラのライトとトリガーは、モデルとビューモデルの両方に存在できます。
Nailer、2011

お返事をありがとうございます。カリングについて述べたように、実際にはどのようにカリングを行っていますか?シーン全体がシーングラフに含まれていますか、それとも表示されている部分のみですか?シーン全体がシーングラフ内にある場合、可視領域のみをOpenGL / DirectX APIに送信するために、シーングラフ全体がフレームごとに移動されますか?可視部分は通常、シーン全体の5%未満であるため、シーン全体がフレーム単位でAPIに送信されることはないと思います。あるいは、フレームごとに完全なトラベラーなしで最も近いエリアをすばやく取得するために、シーングラフが何らかの形で編成されていますか?
Bunkai.Satori

シーングラフにシーン全体を入れます。特定の基準に基づいてグラフのバランスを調整します(たとえば、それからocツリーを作成できます)。ツリーを走査し、境界ボックスが視錐台にあるかどうかに基づいて、「可視」、「部分的に可視」、「非可視」のノードを決定します。基本的に、SGノードへの参照とフラグのみで構成される超軽量の「可視性グラフ」を作成できます。錐台カリングの後、再びツリーをトラバースしてオクルージョンカリングを実行できます。すべてのフレーム、またはカメラやシーンが「ダーティ」とマークされているすべてのフレームのカリングをやり直します。
ネイラー、2011
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.