private void MoveAreaBodies(BaseActiveArea fromActiveArea, BaseActiveArea toActiveArea) { var fromBodies = fromActiveArea.AreaBodies.Select(ab => ab.Body); var toBodies = toActiveArea.AreaBodies.Select(ab => ab.Body); foreach (var fromBody in fromBodies) { if (!toBodies.Contains(fromBody)) { toActiveArea.AddBody(fromBody); } } fromActiveArea.ClearBodies(); }
private void RemoveAreaBodyFromActiveArea(BaseActiveArea activeArea, AreaBody areaBody) { // remove it from this AA. activeArea.RemoveBody(areaBody); // if it's not in any other AA at this point, hibernate it. var isActiveAreasContainingBody = this.ActiveAreas.Any(aa => aa != activeArea && // is a different active area aa.AreaBodies.Select(aab => aab.Body).Contains(areaBody.Body)); // contains the body if (!isActiveAreasContainingBody) { // no other active area has this body in it, so go ahead and hibernate the body this.BodiesToHibernate.Add(areaBody.Body); } }
private bool BodyOverlapsOtherBodiesInActiveArea(BaseActiveArea activeArea, AreaBody areaBody) { for (var i = 0; i < activeArea.AreaBodies.Count; i++) { var otherAreaBody = activeArea.AreaBodies[i]; // it's the same AreaBody so skip it. if (areaBody == otherAreaBody) { continue; } if (areaBody.AABB.Overlaps(ref otherAreaBody.AABB)) { return(true); } } return(false); }
private void RemoveActiveArea(BaseActiveArea activeArea) { for (var i = activeArea.AreaBodies.Count - 1; i >= 0; i--) { var areaBody = activeArea.AreaBodies[i]; switch (areaBody.Body.BodyType) { case BodyType.Static: // okay, remove it. this.RemoveAreaBodyFromActiveArea(activeArea, areaBody); break; default: throw new InvalidOperationException("An active area is being removed which contains bodies which are not static."); } } // remove the active area this.ActiveAreas.Remove(activeArea); }
private void ProcessExpiredActiveArea(BaseActiveArea activeArea) { // if this is a body tracking AA, only remove if not within any other AA if (activeArea.AreaType == ActiveAreaType.BodyTracking) { var bodyActiveArea = activeArea as BodyActiveArea; var bodies = activeArea.AreaBodies.Select(ab => ab.Body); var isAnotherActiveAreaContainingBodiesInCommon = this.ActiveAreas.Any(aa => aa != activeArea && // ...a different active area aa.IsExpired == false && // ...isn't also an expired AA aa.AreaBodies.Select(aab => aab.Body).Intersect(bodies).Any()); // contains any bodies in common if (isAnotherActiveAreaContainingBodiesInCommon) { // abort further expiration processing for this active area return; } // TODO: // next... check if all bodies connected by joints are also expired... // if not... abort // bug... if joint is expired... but can't be removed due to above logic... would be hibernated and immediately awoken. // also... would have to recursively check all of that joined body's joined bodies... hmm. } // remove all area bodies from this active area... for (var bodyIndex = activeArea.AreaBodies.Count - 1; bodyIndex >= 0; bodyIndex--) { var areaBody = activeArea.AreaBodies[bodyIndex]; this.RemoveAreaBodyFromActiveArea(activeArea, areaBody); } // remove this active area... this.ActiveAreas.Remove(activeArea); }
public void UpdateAABB() { this.AABB = BaseActiveArea.CalculateBodyAABB(this.Body); }