Skip to content

Collider.ColliderManager ​

当たり判定関連 / コライダーの識別子

所属:collisionのAPI解説 · 全モジュール索引

読み方 ​

このページは実ファイルから生成したソース照合用資料です。公開関数の引数・戻り値の型、オーバーロード、列挙値を確認できます。public/protected/privateを区別し、privateメンバーを呼び出し例に使わないでください。コメントは原文であり、古い説明や誤記を含む場合があります。利用条件・訂正は上記のAPI解説と既知の制約を優先してください。

元ファイル:ProjectName/code/Collision/ColliderManager/ColliderManager.ixx。確認基準:08f9fa53。

インターフェースとインライン実装 ​

cpp
export module Collider.ColliderManager;

import <queue>;
import <vector>;
import <memory>;
import <functional>;
import <unordered_map>;
import <string>;
import <future>;

import MyLib.Math.Vector2;
import Collider;
import Collider.RectCollider;
import Collider.TileCollider;
import Collider.CircleCollider;
import Object.MapInfo;

using namespace math;

/// <summary>
/// 当たり判定関連
/// </summary>
export namespace col2d
{
    /// <summary>
    /// コライダーの識別子
    /// </summary>
    export struct ColliderID
    {
        uint32_t index = 0xFFFFFFFF;    // インデックス(既定値は無効)
        uint16_t generation;     // 生成世代
    };

    /// <summary>
    /// コライダー管理
    /// </summary>
    export class ColliderManager final
    {
    public:
        /// <summary>
        /// コンストラクタ
        /// </summary>
        ColliderManager() = default;

        /// <summary>
        /// デストラクタ
        /// </summary>
        ~ColliderManager() = default;

        /// <summary>
        /// コライダーを生成
        /// </summary>
        /// <typeparam name="T">コライダーの型</typeparam>
        /// <typeparam name="Args">コライダーの生成時に渡す引数の型</typeparam>
        /// <param name="def">コライダー定義</param>
        /// <param name="ownerID">所有者のID</param>
        /// <param name="args">コライダー生成時に渡す引数</param>
        /// <returns>生成されたコライダーの識別子</returns>
        template<typename T, typename... Args>
        [[nodiscard]] inline ColliderID CreateCollider(ColliderDef* def, const uint32_t& ownerID, Args&&... args)
        {
            auto col = std::make_unique<T>(def, std::forward<Args>(args)...);
            col->GenerateCategory(ownerID);
            ColliderID id = CreateID();
            m_colliders[id.index] = std::move(col);
            return id;
        }

        /// <summary>
        /// 矩形コライダーを生成
        /// </summary>
        /// <param name="def">コライダー定義</param>
        /// <param name="size">サイズ</param>
        /// <param name="ownerID">所有者のID</param>
        /// <returns>生成されたコライダーの識別子</returns>
        [[nodiscard]] inline ColliderID CreateRectCollider(ColliderDef* def, const Vector2f& size, const uint32_t& ownerID = 0)
        {
            return CreateCollider<RectCollider>(def, ownerID, size);
        }

        /// <summary>
        /// 円コライダーを生成
        /// </summary>
        /// <param name="def">コライダー定義</param>
        /// <param name="radius">半径</param>
        /// <param name="ownerID">所有者のID</param>
        /// <returns>生成されたコライダーの識別子</returns>
        [[nodiscard]] inline ColliderID CreateCircleCollider(ColliderDef* def, float radius, const uint32_t& ownerID = 0)
        {
            return CreateCollider<CircleCollider>(def, ownerID, radius);
        }

        /// <summary>
        /// タイルコライダーを生成
        /// </summary>
        /// <param name="def">コライダー定義</param>
        /// <param name="ownerID">所有者のID</param>
        /// <returns>生成されたコライダーの識別子</returns>
        [[nodiscard]] inline ColliderID CreateTileCollider(ColliderDef* def, const object::MapInfo& info, std::string fileName, const uint32_t& ownerID = 0)
        {
            return CreateCollider<TileCollider>(def, ownerID, info, fileName);
        }

        /// <summary>
        /// タイルコライダーを生成
        /// </summary>
        /// <param name="def">コライダー定義</param>
        /// <param name="ownerID">所有者のID</param>
        /// <returns>生成されたコライダーの識別子</returns>
        [[nodiscard]] inline ColliderID CreateTileCollider(ColliderDef* def, std::shared_future<object::MapInfo> info, std::string fileName, const uint32_t& ownerID = 0)
        {
            return CreateCollider<TileCollider>(def, ownerID, info, fileName);
        }

        /// <summary>
        /// コライダーを削除
        /// </summary>
        /// <param name="id">コライダーの識別子</param>
        void Destroy(const ColliderID& id);

        /// <summary>
        /// コライダーを取得
        /// </summary>
        /// <param name="id">コライダーの識別子</param>
        /// <returns>コライダーへのポインタ</returns>
        Collider* GetCollider(const ColliderID& id) const;

        /// <summary>
        /// コライダーの更新処理
        /// </summary>
        void Step();

        /// <summary>
        /// マスクを追加
        /// </summary>
        /// <param name="id">コライダーの識別子</param>
        /// <param name="shape">形状の種類</param>
        /// <param name="ownerID">所有者のID</param>
        void AddMask(const ColliderID& id, const uint32_t& shape, const uint32_t& ownerID)
        {
            // 世代が一致しない(古い/無効な)IDは無視する
            if (Collider* collider = GetCollider(id))
            {
                collider->GetFilter().AddMask(shape, ownerID);
            }
        }

        /// <summary>
        /// 衝突時イベントを追加
        /// </summary>
        /// <param name="id">コライダーの識別子</param>
        /// <param name="key">対象のイベントを識別するためのキー</param>
        /// <param name="event">追加するイベント</param>
        void AddEvent(const ColliderID& id, const uint64_t& key, ContactListener event)
        {
            // 世代が一致しない(古い/無効な)IDは無視する
            if (Collider* collider = GetCollider(id))
            {
                collider->AddEvent(key, event);
            }
        }

    private:
        /// <summary>
        /// コライダーの識別子を生成
        /// </summary>
        /// <returns>生成されたコライダーの識別子</returns>
        ColliderID CreateID();

        /// <summary>
        /// IDスロット
        /// </summary>
        /// <remarks>
        /// スロットは削除せず、vectorのサイズが単調増加する採番カウンターを兼ねる。
        /// generationは「次にこのindexへ割り当てる/現在有効な世代」を表す。
        /// Destroy時にのみ世代を進め、CreateIDでは進めない。
        /// </remarks>
        struct IDSlot
        {
            uint16_t generation = 0;    // 現在の世代
            bool alive = false;         // 使用中か
        };

        /// <summary>
        /// IDが現在有効か(範囲内・使用中・世代一致)
        /// </summary>
        bool IsValid(const ColliderID& id) const
        {
            return id.index < m_slots.size()
                && m_slots[id.index].alive
                && m_slots[id.index].generation == id.generation;
        }

        std::queue<uint32_t> m_freeIndex;   // 再利用可能なindex(重複登録しない)
        std::vector<IDSlot> m_slots;        // index毎の世代と使用状態
        std::unordered_map<uint32_t, std::unique_ptr<Collider>> m_colliders; // コライダーのマップ
    };
}

コード確認基準:08f9fa53 · C++実機検証は別途実施