/// <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); }
public Obb2f(aabb aabb) { Center = aabb.Center; Extents = aabb.Extents; Ax = vector.AxisX; Ay = vector.AxisY; }
/// <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); } } } } }
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); }
/// <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); } } } } }