PolyFlags と AreaFlags の違いについて

いつもお世話になっております。
NavMesh まわりで質問させて頂きます。

PolyFlags と AreaFlags というフラグがありますが、この2つの違いはなんでしょうか?

PolyFlags と AreaFlags を取得してもいつも同じ数字になっています。
例えば、NavArea_Default の (AreaID,PolyFlags,AreaFlags) を表示させてみると
(63,1,1) となっています。他のプロジェクト定義の NavArea_*** でも同様な結果となります。

GetPolyFlags のコードをみてもいまいちピンときませんでした…

bool ARecastNavMesh::GetPolyFlags(NavNodeRef PolyID, uint16& PolyFlags, uint16& AreaFlags) const
{
	bool bFound = false;
	if (RecastNavMeshImpl)
	{
		uint8 AreaType = RECAST_DEFAULT_AREA;
		bFound = RecastNavMeshImpl->GetPolyData(PolyID, PolyFlags, AreaType);
		if (bFound)
		{
			const UClass* AreaClass = GetAreaClass(AreaType);
			const UNavArea* DefArea = AreaClass ? ((UClass*)AreaClass)->GetDefaultObject() : NULL;
			AreaFlags = DefArea ? DefArea->GetAreaFlags() : 0;
		}
	}

	return bFound;
}

NavLinkFlag が関係しているのかも…とはちらっと思いましたが、正確に理解したいので、参考となるドキュメントや Web Site などありましたら教えて頂けると助かります。

よろしくお願い致します。

お世話になっております。
ご質問頂いた2つのフラグは同一名称の定義が複数存在しているので、ARecastNavMesh::GetPolyFlags()の引数で使用されているものについて以下に説明します。

  • PolyFlag
    このフラグは「そのポリゴンが進行可能かどうか」を示すフラグで、その実態はdtPoly.flagsを参照します。dtPolyはdtMeshTileの一部であるようにタイルを分割ポリゴンに分割した際の情報となります。

  • AreaFlag
    このフラグは「指定のNavAreaが進行可能かどうか」を示すフラグで、その実態はUNavArea::AreaFlagを参照します。NavArea_DefaultなどはUNavArea::UNavAreaで定義されたAreaFlag=1のフラグによりそのエリアは進行可能ですが、UNavArea_NullやUNavArea_LowHeightなどはAreaFlag=0がコンストラクタで定義されているように進行不可能なエリアとしてフラグがセットされます。このフラグ自体はGetAreaFlags()を経由して他のクラスから参照され、他のクラスではこのフラグベースでエリア管理などを行う際に使用します。

ご質問頂いたフラグについては、各モジュールの引数や、クラスの変数といった非常に詳細な情報となりますので、この粒度の情報になりますと直接コードから読み解いて頂くのが一番確かな情報が得られるかと思います。Navmeshに関してはドキュメントなどでもあまり情報が無いのが事実ですが、少なくとも私自身このような詳細なレベルでの情報に関するドキュメントやサイトを見たことがございません。ご不明な点がございましたら直接ご質問頂けますと幸いです。よろしくお願いします。

返信ありがとうございます!!

正直申しまして、ご説明頂いた内容をまだ理解できておらず、追加で確認させて頂ければと思います。

「そのポリゴンが進行可能かどうか」と「指定のNavAreaが進行可能かどうか」の違いがよく分かっておりません。

具体的に dtPoly の以下の uint16/uint8 がどのように UE4 で使われているのか?という質問に変えさせて頂いてもよろしいでしょうか?

struct dtPoly
{
	/// The user defined polygon flags.
	unsigned short flags;
	/// The bit packed area id and polygon type.
	unsigned char areaAndtype;
};

お手数おかけいたしますが、よろしくお願い致します。

補足です。

その後、ARecastNavMesh::SetPolyArrayArea / GetPolyFlags を眺めていて思ったのですが、

  • dtPoly::flags には AreaId が格納される ( Default の場合は 63 など NavArea_*** の識別番号に相当 )
  • dtPoly::areaAndType には UNavArea::AreaFlags ( どの属性に対して通行許可するか表すビットフラグ ) が格納される
    という理解であってそうです。

Get が dtPoly から取得したものをさらに加工しているので話が複雑になっていそうな印象でした。

シンプルにいうと、特に何もしなければ、PolyFlags と AreaFlags は一致している。動的に PolyFlags をいじったり、NavLinkProxy がからむと一致しないケースがある…といったところでしょうか(全然シンプルじゃないですが…)

はい、上記でご説明頂いた「特に何もしなければ、PolyFlags と AreaFlags は一致している。動的に PolyFlags をいじったり、NavLinkProxy がからむと一致しないケースがある」という認識で良いかと思います。ユーザーが意図的にPolyFlgsを操作しない限りは基本的に一致するはずです。

NavAreaとPolygonの関係を分かりやすくするために以下の図が参考になるかもしれません。以下の図は、例えば「NavArea_Default のAreaClassを設定したNavModfierVolumeを配置した」ようなイメージです。この場合、Volumeの範囲に生成されたNavmeshはNavAreaがDefaultなので進行可能なエリアです。Volumeの配置によっては、図のようにタイルを跨ることからPolygonが4つに分割されて、4つのPolygon情報を持つことになりますが、いずれもNavAreaで指定された範囲で生成されたものなので、4つのPolygonのPolyFlagsにおいてもNavAreaのAreaFlagのフラグと同期することになります。