| using System; |
| using System.Collections.Generic; |
| using UnityEngine; |
| using UnityEngine.Timeline; |
|
|
| namespace UnityEditor.Timeline |
| { |
| interface IBounds |
| { |
| Rect boundingRect { get; } |
| } |
|
|
| class SpacePartitioner |
| { |
| internal class CachedList<T> |
| { |
| public static readonly List<T> Instance = new List<T>(1000); |
| } |
|
|
| struct Entry : IInterval |
| { |
| public object item { get; set; } |
| public long intervalStart { get; set; } |
| public long intervalEnd { get; set; } |
| public Rect bounds { get; set; } |
|
|
| private const float kPrecision = 100.0f; |
| private const float kMaxFloat = (float)long.MaxValue; |
| private const float kMinFloat = (float)long.MinValue; |
|
|
| static public Int64 FromFloat(float f) |
| { |
| if (Single.IsPositiveInfinity(f)) |
| return long.MaxValue; |
| if (Single.IsNegativeInfinity(f)) |
| return long.MinValue; |
|
|
| f = Mathf.Clamp(f, kMinFloat, kMaxFloat); |
| f = Mathf.Clamp(f * kPrecision, kMinFloat, kMaxFloat); |
| return (long)(f); |
| } |
| } |
|
|
| const EventType k_GuiEventLock = EventType.Repaint; |
|
|
| IntervalTree<Entry> m_Tree = new IntervalTree<Entry>(); |
| List<Entry> m_CacheList = new List<Entry>(); |
|
|
| public void Clear() |
| { |
| m_Tree.Clear(); |
| } |
|
|
| public void AddBounds(IBounds bounds) |
| { |
| AddBounds(bounds, bounds.boundingRect); |
| } |
|
|
| public void AddBounds(object item, Rect rect) |
| { |
| if (item == null) |
| throw new ArgumentNullException("item"); |
|
|
| m_Tree.Add(new Entry() |
| { |
| intervalStart = Entry.FromFloat(rect.yMin), |
| intervalEnd = Entry.FromFloat(rect.yMax), |
| bounds = rect, |
| item = item |
| } |
| ); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public IEnumerable<T> GetItemsAtPosition<T>(Vector2 position) |
| { |
| return GetItemsInArea<T>(new Rect(position.x, position.y, 1, 1)); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public IEnumerable<T> GetItemsInArea<T>(Rect area) |
| { |
| m_CacheList.Clear(); |
| m_Tree.IntersectsWithRange(long.MinValue, long.MaxValue, m_CacheList); |
|
|
| var list = CachedList<T>.Instance; |
| list.Clear(); |
| foreach (var i in m_CacheList) |
| { |
| if (i.item is T && i.bounds.Overlaps(area)) |
| list.Add((T)i.item); |
| } |
| return list; |
| } |
|
|
| public void DebugDraw(Color fillColor, Color outlineColor) |
| { |
| m_CacheList.Clear(); |
| m_Tree.IntersectsWithRange(long.MinValue, long.MaxValue, m_CacheList); |
| HandleUtility.ApplyWireMaterial(); |
|
|
| foreach (var item in m_CacheList) |
| { |
| Handles.DrawSolidRectangleWithOutline(item.bounds, fillColor, outlineColor); |
| } |
| } |
| } |
| } |
|
|