public static void Enter(IPortal portal, IPortalCommon portalable, float intersectT, bool ignorePortalVelocity = false, bool worldOnly = false) { Transform2 transform = portalable.GetTransform(); Transform2 velocity = portalable.GetVelocity(); //Copies are made just for debug purposes. The originals should not change before the EnterPortal callback. Transform2 transformCopy = transform.ShallowClone(); Transform2 velocityCopy = velocity.ShallowClone(); IPortalable cast = portalable as IPortalable; if (cast != null) { if (!worldOnly) { cast.SetTransform(Enter(portal, transform)); cast.SetVelocity(EnterVelocity(portal, intersectT, velocity, ignorePortalVelocity)); } } if (portalable.WorldTransform != null) { portalable.WorldTransform = Enter(portal, portalable.WorldTransform); portalable.WorldVelocity = EnterVelocity(portal, intersectT, portalable.WorldVelocity, ignorePortalVelocity); } //If a static actor enters a portal then it's no longer static. Actor actorCast = portalable as Actor; if (actorCast != null && actorCast.BodyType == BodyType.Static) { actorCast.SetBodyType(BodyType.Kinematic); } foreach (IPortalCommon p in portalable.Children) { p.Path.Enter(portal.Linked); } Debug.Assert(transform == transformCopy && velocity == velocityCopy); if (cast != null) { cast.EnterPortal?.Invoke(new EnterCallbackData(portal, cast, intersectT), transform, velocity); } }
private static void AddMargin(IEnumerable<IPortal> portals, IPortalCommon instance) { Transform2d transform = (Transform2d)instance.WorldTransform; foreach (IPortal p in portals.Where(item => item.OneSided && Portal.IsValid(item))) { Line exitLine = new Line(Vector2Ext.ToDouble(Portal.GetWorldVerts(p))); Vector2d position = transform.Position; double distanceToPortal = MathExt.PointLineDistance(position, exitLine, true); if (distanceToPortal < Portal.EnterMinDistance) { Vector2d exitNormal = (Vector2d)p.WorldTransform.GetRight(); Vector2d pos = exitNormal * (Portal.EnterMinDistance - (float)distanceToPortal); transform.Position += pos; instance.WorldTransform = (Transform2)transform; /*We return now rather than look for more portals that are too close because it is assumed that * portals will never be closer than 2 * Portal.EnterMinDistance*/ return; } } }
public EnterCallbackData(IPortal entrancePortal, IPortalCommon instance, double portalT) { EntrancePortal = entrancePortal; Instance = instance; PortalT = portalT; }
public PortalableMovement(IPortalCommon instance, Line startEnd, Transform2d previous) { Instance = instance; StartEnd = startEnd; Previous = previous; }
private static void PlaceOnPortal(IPortalCommon instance, IPortal portal, float t) { Line portalLine = new Line(Vector2Ext.ToDouble(Portal.GetWorldVerts(portal))); Transform2d transform = (Transform2d)instance.WorldTransform; transform.Position = (Vector2d)portalLine.Lerp(t); instance.WorldTransform = (Transform2)transform; }