Esempio n. 1
0
        /// <summary>
        /// 全セルの軸並行境界ボリュームを取得する
        /// </summary>
        /// <returns>境界ボリューム列</returns>
        public List <Tuple <aabb, int> > GetCellAabb()
        {
            var result = new List <Tuple <aabb, int> >();
            var cr     = new rangei(vectori.Zero, _CellMax);
            var cells  = _Cells;
            var stride = _Division.X;
            var iy     = cr.Min.X + cr.Min.Y * stride;
            var invs   = _InvTransformScale;
            var invt   = _CellExtent - _TransformTranslate;
            var aabb2  = new aabb(vector.Zero, _CellExtent);

            for (int y = cr.Min.Y; y <= cr.Max.Y; iy += stride, y++)
            {
                aabb2.Center.Y  = y * invs.Y;
                aabb2.Center.Y += invt.Y;

                for (int x = cr.Min.X, ix = iy; x <= cr.Max.X; ix++, x++)
                {
                    aabb2.Center.X  = x * invs.X;
                    aabb2.Center.X += invt.X;

                    result.Add(new Tuple <aabb, int>(aabb2, ix));
                }
            }

            return(result);
        }
Esempio n. 2
0
 public Obb2f(aabb aabb)
 {
     Center  = aabb.Center;
     Extents = aabb.Extents;
     Ax      = vector.AxisX;
     Ay      = vector.AxisY;
 }
Esempio n. 3
0
        /// <summary>
        /// 指定範囲に接触するアイテムを列挙する
        /// </summary>
        /// <param name="volume">境界ボリューム</param>
        /// <param name="excludes">列挙から除外するアイテム一覧、一度列挙されたものはこれに登録される</param>
        /// <returns>列挙子</returns>
        public IEnumerable <T> Query(obb volume, HashSet <T> excludes)
        {
            var isAabb1 = volume.IsAabb;
            var cells   = _Cells;

            foreach (var i in EnumCellIndices(volume, true))
            {
                var items = cells[i];
                for (int j = items.Count - 1; j != -1; j--)
                {
                    var item = items[j];
                    var obb2 = item.GetVolume();
                    if (obb2.IsAabb && isAabb1)
                    {
                        var aabb2 = new aabb(obb2.Center, obb2.Extents);
                        if (volume.IntersectsAsAabb(aabb2))
                        {
                            yield return(item);
                        }
                    }
                    else
                    {
                        if (volume.Intersects(obb2))
                        {
                            yield return(item);
                        }
                    }
                }
            }
        }
Esempio n. 4
0
        public bool IntersectsAsAabb(aabb aabb)
        {
            var v       = Center - aabb.Center;
            var extents = Extents;

            return(Math.Abs(v.X) <= extents.X + aabb.Extents.X && Math.Abs(v.Y) <= extents.Y + aabb.Extents.Y);
        }
Esempio n. 5
0
        /// <summary>
        /// 指定された範囲に接触するセルインデックスを列挙する
        /// </summary>
        /// <param name="obb">範囲</param>
        /// <param name="skipNullCell">アイテム数ゼロのセルを無視するかどうか</param>
        /// <returns>セルインデックス一覧</returns>
        IEnumerable <int> EnumCellIndices(obb obb, bool skipNullCell)
        {
            var cr     = CellRange(obb.Range);
            var cells  = _Cells;
            var stride = _Division.X;
            var iy     = cr.Min.X + cr.Min.Y * stride;
            var invs   = _InvTransformScale;
            var invt   = _CellExtent - _TransformTranslate;
            var isAabb = obb.IsAabb;
            var aabb2  = new aabb(new vector(), _CellExtent);

            for (int y = cr.Min.Y; y <= cr.Max.Y; iy += stride, y++)
            {
                aabb2.Center.Y  = y * invs.Y;
                aabb2.Center.Y += invt.Y;

                for (int x = cr.Min.X, ix = iy; x <= cr.Max.X; ix++, x++)
                {
                    if (skipNullCell)
                    {
                        var c = cells[ix];
                        if (c == null || c.Count == 0)
                        {
                            continue;
                        }
                    }

                    aabb2.Center.X  = x * invs.X;
                    aabb2.Center.X += invt.X;

                    if (isAabb)
                    {
                        if (obb.IntersectsAsAabb(aabb2))
                        {
                            yield return(ix);
                        }
                    }
                    else
                    {
                        var obb2 = new obb(aabb2);
                        if (obb.Intersects(obb2))
                        {
                            yield return(ix);
                        }
                    }
                }
            }
        }