public static bool GetRectSpacesDoOverlap(RectSpace space, RectSpace container) { return(RectContainsPoint(space.lowerLeft, container) || RectContainsPoint(space.upperLeft, container) || RectContainsPoint(space.upperRight, container) || RectContainsPoint(space.lowerRight, container)); }
public static RectSpace TransformWithOffset(this RectSpace space, Vector2 transformation) { space.lowerLeft -= (Vector3)transformation; space.upperLeft -= (Vector3)transformation; space.upperRight -= (Vector3)transformation; space.lowerRight -= (Vector3)transformation; return(space); }
public RectSpace(RectSpace s) { markedForRemoval = false; lowerLeft = s.lowerLeft; upperLeft = s.upperLeft; upperRight = s.upperRight; lowerRight = s.lowerRight; }
public static Vector2 GetRectSpaceOverlap( RectSpace element, RectSpace container, RectContainerElement.DragElementContainerBoundary mode) { Vector2 overlap = Vector2.zero; if (mode == RectContainerElement.DragElementContainerBoundary.Edge) { // X overlap if (element.left < container.left) { overlap = new Vector2(element.left - container.left, overlap.y); } if (element.right > container.right) { overlap = new Vector2(element.right - container.right, overlap.y); } // Y overlap if (element.top > container.top) { overlap = new Vector2(overlap.x, element.top - container.top); } if (element.bottom < container.bottom) { overlap = new Vector2(overlap.x, element.bottom - container.bottom); } } else { // X overlap if (element.center.x < container.left) { overlap = new Vector2(element.center.x - container.left, overlap.y); } if (element.center.x > container.right) { overlap = new Vector2(element.center.x - container.right, overlap.y); } // Y overlap if (element.center.y > container.top) { overlap = new Vector2(overlap.x, element.center.y - container.top); } if (element.center.y < container.bottom) { overlap = new Vector2(overlap.x, element.center.y - container.bottom); } } return(overlap); }
void IUIDynamicElementListener.OnDynamicElementUpdate(IUIDynamicElement d) { // If this update is not from the source, that means it's coming from our container if (d != _source) { _containerSpace = new RectSpace(_explicitContainer); _source.ForceUpdate(); } }
public static RectSpace[] GetSplitSpacesFromObstacle(RectSpace obstacle, RectSpace spaceToSplit) { // Left, top, right, bottom List <RectSpace> splitSpaces = new List <RectSpace>(); // Left space splitSpaces.Add(new RectSpace { lowerLeft = spaceToSplit.lowerLeft, upperLeft = spaceToSplit.upperLeft, upperRight = new Vector3(obstacle.left, spaceToSplit.top, 0), lowerRight = new Vector3(obstacle.left, spaceToSplit.bottom, 0), }); // Top space splitSpaces.Add(new RectSpace { lowerLeft = new Vector3(spaceToSplit.left, obstacle.top, 0), upperLeft = spaceToSplit.upperLeft, upperRight = spaceToSplit.upperRight, lowerRight = new Vector3(spaceToSplit.right, obstacle.top, 0), }); // Right space splitSpaces.Add(new RectSpace { lowerLeft = new Vector3(obstacle.right, spaceToSplit.bottom, 0), upperLeft = new Vector3(obstacle.right, spaceToSplit.top, 0), upperRight = spaceToSplit.upperRight, lowerRight = spaceToSplit.lowerLeft, }); // Bottom space splitSpaces.Add(new RectSpace { lowerLeft = spaceToSplit.lowerLeft, upperLeft = new Vector3(spaceToSplit.left, obstacle.bottom, 0), upperRight = new Vector3(spaceToSplit.right, obstacle.bottom, 0), lowerRight = spaceToSplit.lowerRight, }); // Remove any created spaces that are too small // const float epsilon = 0.001f; // for (int i = splitSpaces.Count - 1; i >= 0; i--) // { // if (Mathf.Abs(splitSpaces[i].top - splitSpaces[i].bottom) <= epsilon || // Mathf.Abs(splitSpaces[i].left - splitSpaces[i].right) <= epsilon) // { // splitSpaces.RemoveAt(i); // } // } return(splitSpaces.ToArray()); }
private void RefreshGroupFreeSpaces() { // Get container from group _positionEvaluationSpace = _group.GetGroupedElementEvaluationBoundary( this, _boundaryMode, new RectSpace(_source.dynamicTransform), _containerSpace, _currentElementFreeSpaces, out _currentElementFreeSpaces); }
private static bool RectContainsPoint(Vector3 point, RectSpace rect) { bool contains = true; if (point.x < rect.left || point.x > rect.right) { contains = false; } else if (point.y < rect.bottom || point.y > rect.top) { contains = false; } return(contains); }
/// <summary> /// Calculates and returns the array of navigable RectSpaces formed in a group by all of the /// group elements, excluding the given active element. /// </summary> private static RectSpace[] CalculateFreeSpacesForGroupedElement( RectContainerElement activeElement, List <RectContainerElement> allGroupElements, RectSpace activeElementContainer) { // Gather list of obstacles List <RectSpace> obstacles = new List <RectSpace>(); foreach (RectContainerElement e in allGroupElements) { if (e != activeElement) { obstacles.Add(new RectSpace(e._source.dynamicTransform)); } } List <RectSpace> freeSpaces = new List <RectSpace>(); freeSpaces.Add(activeElementContainer); foreach (RectSpace obstacle in obstacles) { // Is this obstacle overlapping with any known freespaces? List <RectSpace> createdFreeSpaces = new List <RectSpace>(); foreach (var space in freeSpaces) { if (RectBoundariesUtility.GetRectSpacesDoOverlap(obstacle, space)) { space.markedForRemoval = true; createdFreeSpaces.AddRange( RectBoundariesUtility.GetSplitSpacesFromObstacle(obstacle, space)); } } // Remove marked spaces for (int i = freeSpaces.Count - 1; i >= 0; i--) { if (freeSpaces[i].markedForRemoval) { freeSpaces.Remove(freeSpaces[i]); } } // Add created spaces freeSpaces.AddRange(createdFreeSpaces); } return(freeSpaces.ToArray()); }
/// <summary> /// Calculates and returns a list of the freespaces within which the given element is /// completely contained (not overlapping any edges). /// </summary> private static List <RectSpace> CalculateEnclosingFreeSpacesForGroupedElement( RectContainerElement activeElement, RectContainerElement.DragElementContainerBoundary boundaryMode, RectSpace element, RectSpace[] freespaces) { List <RectSpace> containingSpaces = new List <RectSpace>(); foreach (RectSpace space in freespaces) { if (RectBoundariesUtility.GetRectSpaceOverlap(element, space, boundaryMode) == Vector2.zero) { containingSpaces.Add(space); } } return(containingSpaces); }
public void SetContainerType( DragElementContainerType containerType, RectTransform container, IUIDynamicElement dynamicContainer) { _explicitContainer = container; _dynamicContainer = dynamicContainer; _containerType = containerType; switch (_containerType) { case DragElementContainerType.Screen: case DragElementContainerType.SafeArea: _containerSpace = new RectSpace(RectBoundariesUtility.GetScreenCorners()); GourdUI.Device.RegisterScreenUpdateListener(this); break; case DragElementContainerType.Parent: _containerSpace = new RectSpace(_explicitContainer); _dynamicContainer?.SubscribeDynamicElementListener(this); break; } _currentElementFreeSpaces.Add(_containerSpace); }
Tuple<Vector2, bool, bool> IUIDynamicElementPositionFilter.GetFilteredPosition() { // Refersh container if (_group != null) { RefreshGroupFreeSpaces(); } else { _positionEvaluationSpace = _containerSpace; } // Find the overlap with the current container Vector2 boundaryOverlap = RectBoundariesUtility.GetRectSpaceOverlap( new RectSpace(_source.dynamicTransform), _positionEvaluationSpace, _boundaryMode); return new Tuple<Vector2, bool, bool>( boundaryOverlap, boundaryOverlap.x != 0, boundaryOverlap.y != 0); }
void IScreenRectUpdateListener.OnScreenRectUpdated(Rect rect) { _containerSpace = new RectSpace(RectBoundariesUtility.GetScreenCorners()); _source.ForceUpdate(); }
/// <summary> /// Returns the FreeSpaces within which the given element is completely contained, AFTER /// any overlap corrects have been applied. /// </summary> public RectSpace GetGroupedElementEvaluationBoundary( RectContainerElement activeElement, RectContainerElement.DragElementContainerBoundary boundaryMode, RectSpace activeSpace, RectSpace containerSpace, List <RectSpace> previousFreeSpaces, out List <RectSpace> newFreeSpaces) { // Get the free spaces RectSpace[] freespaces = CalculateFreeSpacesForGroupedElement( activeElement, _elements, containerSpace); // Is our element fully contained within any space? List <RectSpace> fs = CalculateEnclosingFreeSpacesForGroupedElement( activeElement, boundaryMode, activeSpace, freespaces); // If we didn't find a space, that means our element is overlapping // We want to apply the correction temporarily, re-check to find the correct space, // And then try again to find the new evaluation container space if (fs.Count == 0) { // Get overlap distances for each previous freespace Vector2[] overlapDistances = new Vector2[previousFreeSpaces.Count]; for (int i = 0; i < previousFreeSpaces.Count; i++) { overlapDistances [i] = RectBoundariesUtility.GetRectSpaceOverlap( activeSpace, previousFreeSpaces[i], boundaryMode); } // Which overlap distance was closest? That's the one we want! RectSpace evalSpace = previousFreeSpaces[0]; Vector2 evalDistance = Vector2.zero; float currentClosestDistance = float.MaxValue; for (int i = 0; i < previousFreeSpaces.Count; i++) { if (overlapDistances[i].sqrMagnitude < currentClosestDistance) { currentClosestDistance = overlapDistances[i].sqrMagnitude; evalDistance = overlapDistances[i]; evalSpace = previousFreeSpaces[i]; } } // Now we can re-evaluate current spaces for transformed element RectSpace corrected = new RectSpace(activeSpace).TransformWithOffset(evalDistance); List <RectSpace> postCorrectionFS = CalculateEnclosingFreeSpacesForGroupedElement( activeElement, boundaryMode, corrected, freespaces); newFreeSpaces = postCorrectionFS.Count > 0 ? postCorrectionFS : new List <RectSpace> { containerSpace }; // return(evalSpace); } newFreeSpaces = fs.Count > 0 ? fs : new List <RectSpace> { containerSpace }; return(fs[0]); }