/// <summary>
        /// コリジョンリストを列挙(再帰メソッド)
        /// </summary>
        /// <param name="MortonNum">モートン番号</param>
        /// <param name="BelongLevel">レベル</param>
        /// <param name="CollisionList">コリジョンリスト</param>
        private void GetCollisionList_Rec(int MortonNum, int BelongLevel, List <GeometryGroup> CollisionList)
        {
            int Elem = ToLinearSpace(MortonNum, BelongLevel);

            if (Elem < 0 || Elem >= CellNum || CellList[Elem] == null)
            {
                return;
            }

            GeometryTreeData Data = CellList[Elem].FirstData;

            // データが無くなるまで繰り返す。
            while (Data != null)
            {
                CollisionList.Add(Data.Object);
                Data = Data.Next;
            }

            // 子空間へ移動.
            int NextElem;

            // 子空間を巡る
            for (int i = 0; i < DivisionNum; i++)
            {
                NextElem = MortonNum * DivisionNum + 1 + i;

                // 空間分割数以上 or 対象空間が無い場合はスキップ。
                bool bSkip = (NextElem < 0 || NextElem >= CellNum || CellList[NextElem] == null);
                if (bSkip)
                {
                    continue;
                }

                // 子空間を検索.
                GetCollisionList_Rec(NextElem, BelongLevel, CollisionList);
            }
        }
Exemple #2
0
        /// <summary>
        /// 空間にTreeDataを登録する。
        /// </summary>
        /// <param name="Data">登録するTreeData</param>
        /// <returns>成功したらtrueを返す。</returns>
        public bool Push(GeometryTreeData Data)
        {
            // 二重登録.
            if (Data.Cell == this)
            {
                return(false);
            }

            Data.Cell = this;

            // まだ空間に一つも登録が無い場合は始めのデータとして登録。
            if (LatestData == null)
            {
                LatestData = Data;
                return(true);
            }

            // 最新のTreeDataの参照を更新.
            Data.Next       = LatestData;
            LatestData.Prev = Data;
            LatestData      = Data;

            return(true);
        }
        /// <summary>
        /// 登録.
        /// </summary>
        /// <param name="Left">左</param>
        /// <param name="Top">上</param>
        /// <param name="Right">右</param>
        /// <param name="Bottom">下</param>
        /// <param name="Front">手前</param>
        /// <param name="Back">奥</param>
        /// <param name="Data">登録するデータ</param>
        /// <returns>成功したらtrueを返す。</returns>
        public bool Register(float Left, float Top, float Right, float Bottom, float Front, float Back, GeometryTreeData Data)
        {
            // 指定領域の分オフセットして計算する。
            string FailedReason = "";

            if (!OffsetPosition(ref Left, ref Top, ref Right, ref Bottom, ref Front, ref Back, out FailedReason))
            {
                throw new Exception("OffsetPosition Failed. Reason:" + FailedReason);
            }

            // オブジェクトの境界領域からモートン番号を算出.
            int BelongLevel;
            int Elem = GetMortonNumber(Left, Top, Right, Bottom, Front, Back, out BelongLevel);

            Elem = ToLinearSpace(Elem, BelongLevel);

            // 算出されたモートン番号が生成した空間分割数より大きい場合はエラー
            if (Elem >= CellNum)
            {
                return(false);
            }

            // 算出されたモートン番号の空間が無い場合は新規作成.
            if (CellList[Elem] == null)
            {
                CreateNewCell(Elem);
            }

            return(CellList[Elem].Push(Data));
        }