Esempio n. 1
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. 2
0
        public bool Intersects(volume obb2)
        {
            volume obb1;

            if (this.IsAabb)
            {
                obb1 = obb2;
                obb2 = this;
            }
            else
            {
                obb1 = this;
            }

            var d = new vector();
            var v = obb1.Center - obb2.Center;

            var eax = obb2.Ax * obb2.Extents.X;
            var eay = obb2.Ay * obb2.Extents.Y;
            var e1  = eax + eay;
            var e2  = eay - eax;

            d.X = Math.Abs(obb1.Ax.Dot(e1));
            d.Y = Math.Abs(obb1.Ax.Dot(e2));
            if (obb1.Extents.X + d.Max() < Math.Abs(obb1.Ax.Dot(v)))
            {
                return(false);
            }
            d.X = Math.Abs(obb1.Ay.Dot(e1));
            d.Y = Math.Abs(obb1.Ay.Dot(e2));
            if (obb1.Extents.Y + d.Max() < Math.Abs(obb1.Ay.Dot(v)))
            {
                return(false);
            }

            eax = obb1.Ax * obb1.Extents.X;
            eay = obb1.Ay * obb1.Extents.Y;
            e1  = eax + eay;
            e2  = eay - eax;
            d.X = Math.Abs(obb2.Ax.Dot(e1));
            d.Y = Math.Abs(obb2.Ax.Dot(e2));
            if (obb2.Extents.X + d.Max() < Math.Abs(obb2.Ax.Dot(v)))
            {
                return(false);
            }
            d.X = Math.Abs(obb2.Ay.Dot(e1));
            d.Y = Math.Abs(obb2.Ay.Dot(e2));
            if (obb2.Extents.Y + d.Max() < Math.Abs(obb2.Ay.Dot(v)))
            {
                return(false);
            }

            return(true);
        }
Esempio n. 3
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);
                        }
                    }
                }
            }
        }
Esempio n. 4
0
 /// <summary>
 /// 指定範囲に接触するアイテムを列挙する
 /// </summary>
 /// <param name="volume">境界ボリューム</param>
 /// <returns>列挙子</returns>
 public IEnumerable <T> Query(obb volume)
 {
     return(Query(volume, new HashSet <T>()));
 }