インタレスト ポイントを使用する

インタレストポイントは、カスタム データを特定位置の NavMesh に空間化し、特定の空間領域内に存在するそのポイントをすばやく取得できるオブジェクトです。

PointOfInterest クラスの各インスタンスは、ゲーム内で表すオブジェクトまたはデータの型を識別するために設定できる整数 ID と(つまり、カバー ポイント、狙撃ポイントなどとして識別するために)、ゲーム内の特定のオブジェクトを参照するために設定できる void ポインタ(つまり、武器または弾薬オブジェクト、ヘルス パックなど)を保持します。

インタレスト ポイントは実行時に完全に管理されます。地形用に NavMesh を事前生成するデータ生成処理の一部ではありません。必要なときにいつでも実行時にインタレスト ポイントを作成し、必要に応じて新しい位置に移動し、空間クエリを使用して取得できます。

ゲーム側クラス

PointOfInterest の初期化と破棄を管理するためのクラスをゲーム内で設定する必要があります。ゲーム内に既に、PointOfInterest によって Gameware Navigation World 内に表されるオブジェクトのライフスパンを管理するクラスがある場合があります。その場合は、そのクラスを使用できます。

例: [Tutorial_PointOfInterest.cpp のコード]

class MyGamePointOfInterest
{
public:
    MyGamePointOfInterest() : m_navPointOfInterest(KY_NULL) {}

    void Initialize(Kaim::World* world, const Kaim::Vec3f& position);
    void Destroy();

    void SetPosition(const Kaim::Vec3f& newPosition);

    Kaim::Ptr<Kaim::PointOfInterest> m_navPointOfInterest;
    ...
};

初期化

PointOfInterest を初期化するには、PointOfInterestInitConfig 設定クラスのインスタンスを提供する必要があります。このクラスは、PointOfInterest で必要なデータで設定します。少なくとも以下を設定する必要があります。

例: [Tutorial_PointOfInterest.cpp のコード]

void MyGamePointOfInterest::Initialize(Kaim::World* world, const Kaim::Vec3f& position)
{
    ...
    // Set up the PointOfInterestInitConfig
    Kaim::PointOfInterestInitConfig pointOfInterestInitConfig;
    pointOfInterestInitConfig.m_world = world;
    pointOfInterestInitConfig.m_startPosition = position;
    pointOfInterestInitConfig.m_poiType = Kaim::PointOfInterestType_FirstClient;

    // Create and initialize the point of interest, and add it to its World
    m_navPointOfInterest = *KY_NEW Kaim::PointOfInterest;
    m_navPointOfInterest->Init(pointOfInterestInitConfig);
    m_navPointOfInterest->AddToWorld();

    // Set a pointer to your own data
    m_navPointOfInterest->SetUserData(this);
    ...
}

アップデート

PointOfInterest によって表されるゲーム内のオブジェクトの位置または他のデータが変更されるたびに、新しい状態を反映するように PointOfInterest を更新する必要があります。PointofInterest::SetPosition() 関数を使用して、新しい状態を反映することができます。

PointOfInterest はすぐに変更されないことに注意してください。更新は World の次の更新まで遅延されます。

例: [Tutorial_PointOfInterest.cpp のコード]

void MyGamePointOfInterest::SetPosition(const Kaim::Vec3f& newPosition)
{
    m_navPointOfInterest->SetPosition(newPosition);
}

破棄

PointOfInterest を破棄するには:

例: [Tutorial_PointOfInterest.cpp のコード]

void MyGamePointOfInterest::Destroy()
{
    m_navPointOfInterest->RemoveFromWorld();
    m_navPointOfInterest = KY_NULL;
}

インタレスト ポイントを取得する

インタレスト ポイントは、内部 SpatializedPoint オブジェクトを使用して NavMesh に空間化されます。同じメカニズムは、Bot や動的障害物などの空間化された WorldElements の他のクラスでも使用されます。特定のバウンディング ボックス内の空間化されたポイントを取得するには、SpatializedPointCollectorInAABBQuery クラスのインスタンスを作成して起動します。

デフォルトではクエリはすべての種類の空間化されたポイントを取得しますが、クエリにフィルタを提供して、結果にインタレスト ポイントだけが含まれるようにできます。

例: [Tutorial_PointOfInterest.cpp のコード]

void CollectAndRenderNearbyPointsOfInterest(Kaim::Database* database, const Kaim::Vec3f& collectorBoxCenter, KyFloat32 collectorBoxHalfExtentFloat)
{
    ...

    // Set up a filter
    Kaim::SpatializedPointCollectorFilter_SelectiveCollect selectiveCollect;
    selectiveCollect.Select(Kaim::SpatializedPointObjectType_PointOfInterest);

    // Instantiate the query
    Kaim::SpatializedPointCollectorInAABBQuery<Kaim::SpatializedPointCollectorFilter_SelectiveCollect> query(selectiveCollect);
    query.BindToDatabase(database);

    // Set up the query parameters
    const Kaim::Vec3f collectorBoxHalfExtentVec3f(collectorBoxHalfExtentFloat, collectorBoxHalfExtentFloat, collectorBoxHalfExtentFloat);
    const Kaim::Box3f collectorBoxExtent(collectorBoxHalfExtentVec3f, collectorBoxHalfExtentVec3f);
    query.Initialize(collectorBoxCenter, collectorBoxExtent);

    // Perform the query
    query.PerformQueryBlocking();
    ...

クエリが完了すると、結果を反復して、関心ポイントを処理できます。たとえば、次のコードでは、Navigation Lab でレンダリングするために、各インタレスト ポイントの ID をビジュアル デバッグ フレームワークにプッシュしています。[Tutorial_PointOfInterest.cpp からのコード]

    ...

    Kaim::ScopedDisplayList displayList(database->GetWorld(), Kaim::DisplayList_Enable);
    displayList.InitSingleFrameLifespan("Nearby POIs", "Tutorial_PointOfInterest");
    Kaim::VisualShapeColor displayColor;
    displayColor.m_lineColor = Kaim::VisualColor::Magenta;
    displayList.PushBox(query.ComputeAABB(), displayColor);
    if (query.GetResult() == Kaim::SPATIALIZEDPOINTCOLLECTOR_DONE)
    {
        Kaim::QueryDynamicOutput* queryDynamicOutput = query.GetQueryDynamicOutput();
        if (queryDynamicOutput)
        {
            for(KyUInt32 i = 0; i < queryDynamicOutput->GetSpatializedPointCount(); ++i)
            {
                Kaim::SpatializedPoint* spatializedPoint = queryDynamicOutput->GetSpatializedPoint(i);
                if (spatializedPoint)
                {
                    const Kaim::Vec3f& position = spatializedPoint->GetPosition();
                    displayList.PushArrow(position + Kaim::Vec3f::UnitZ(), position, 0.1f, displayColor);
                    if (spatializedPoint->GetObjectType() == Kaim::SpatializedPointObjectType_PointOfInterest)
                    {
                        Kaim::StringStream displayText;
                        Kaim::PointOfInterest* pointOfInterest = (Kaim::PointOfInterest*)spatializedPoint->GetObject();
                        MyGamePointOfInterest* myGamePointOfInterest = (MyGamePointOfInterest*)pointOfInterest->GetUserData();
                        displayText << "   POI #" << myGamePointOfInterest->m_id;
                        displayList.PushText(position + Kaim::Vec3f::UnitZ(), Kaim::VisualColor::White, displayText.CStr());
                    }
                }
            }
        }
    }
}