/***************************************************/ /**** Private Methods ****/ /***************************************************/ private static List <Avalue> EvaluateAvalue(Audience audience, AvalueSettings settings, Polyline playingArea, bool parallelProcess) { if (!SetGlobals(settings)) { return(new List <Avalue>()); } if (m_AvalueSettings.CalculateOcclusion) { SetKDTree(audience); } if (parallelProcess) { ConcurrentBag <Avalue> resultCollection = new ConcurrentBag <Avalue>(); Parallel.ForEach(audience.Spectators, s => { resultCollection.Add(ClipView(s, s.SetViewVector(), playingArea)); }); return(resultCollection.ToList()); } else { List <Avalue> results = new List <Avalue>(); foreach (Spectator s in audience.Spectators) { results.Add(ClipView(s, s.SetViewVector(), playingArea)); } return(results); } }
public static List <List <Avalue> > AvalueAnalysis(List <Audience> audience, AvalueSettings settings, ActivityArea activityArea) { List <List <Avalue> > results = new List <List <Avalue> >(); foreach (Audience a in audience) { results.Add(EvaluateAvalue(a, settings, activityArea)); } return(results); }
/***************************************************/ /**** Private Methods ****/ /***************************************************/ private static List <Avalue> EvaluateAvalue(Audience audience, AvalueSettings settings, ActivityArea activityArea) { List <Avalue> results = new List <Avalue>(); KDTree <Spectator> spectatorTree = null; if (settings.CalculateOcclusion) { spectatorTree = SetKDTree(audience); } foreach (Spectator s in audience.Spectators) { Vector rowVector = Geometry.Query.CrossProduct(Vector.ZAxis, s.Head.PairOfEyes.ViewDirection); Vector viewVect = activityArea.ActivityFocalPoint - s.Head.PairOfEyes.ReferenceLocation; results.Add(ClipView(s, rowVector, viewVect, settings, activityArea, spectatorTree)); } return(results); }
/***************************************************/ private static bool SetGlobals(AvalueSettings settings) { m_AvalueSettings = settings == null ? new AvalueSettings() : settings; m_FarClippingPlaneDistance = settings.FarClippingPlaneDistance; if (m_AvalueSettings.EffectiveConeOfVision.ControlPoints.Count == 0) { double halfWidth = m_AvalueSettings.EffectiveConeOfVisionWidth / 2; double halfHeight = m_AvalueSettings.EffectiveConeOfVisionHeight / 2; List <Point> points = new List <Point>() { Geometry.Create.Point(-halfWidth, -halfHeight, m_AvalueSettings.NearClippingPlaneDistance), Geometry.Create.Point(halfWidth, -halfHeight, m_AvalueSettings.NearClippingPlaneDistance), Geometry.Create.Point(halfWidth, halfHeight, m_AvalueSettings.NearClippingPlaneDistance), Geometry.Create.Point(-halfWidth, halfHeight, m_AvalueSettings.NearClippingPlaneDistance), Geometry.Create.Point(-halfWidth, -halfHeight, m_AvalueSettings.NearClippingPlaneDistance) }; m_AvalueSettings.EffectiveConeOfVision = Geometry.Create.Polyline(points); Reflection.Compute.RecordNote("No Cone Of Vision was provided by the user the default Cone Of Vision has been created."); } if (!m_AvalueSettings.EffectiveConeOfVision.IsPlanar() || !m_AvalueSettings.EffectiveConeOfVision.IsPlanar()) { Reflection.Compute.RecordError("Cone Of Vision should be planar and closed."); return(false); } //get the view angle from the cone double halfAngle = double.MinValue; foreach (Point p in m_AvalueSettings.EffectiveConeOfVision.ControlPoints) { //project to XZ and make vector Vector v = Geometry.Create.Vector(new Point(), p.Project(Plane.XZ)); double a = Geometry.Query.Angle(Vector.ZAxis, v); if (a > halfAngle) { halfAngle = a; } } m_ConeOfVisionAngle = halfAngle * 2; return(true); }
public static List <List <Avalue> > AvalueAnalysis(this List <Audience> audience, Polyline playingArea, AvalueSettings settings = null, bool parallelProcess = false) { List <List <Avalue> > results = new List <List <Avalue> >(); if (audience == null || settings == null || playingArea == null) { BH.Engine.Reflection.Compute.RecordError("Cannot query the AvalueAnalysis if the audience, settings, or playing area are null."); return(results); } foreach (Audience a in audience) { results.Add(EvaluateAvalue(a, settings, playingArea, parallelProcess)); } return(results); }
public static List <Avalue> AvalueAnalysis(Audience audience, AvalueSettings settings, ActivityArea activityArea) { List <Avalue> results = EvaluateAvalue(audience, settings, activityArea); return(results); }
/***************************************************/ private static Avalue ClipView(Spectator spectator, Vector rowV, Vector viewVect, AvalueSettings settings, ActivityArea activityArea, KDTree <Spectator> tree) { Avalue result = new Avalue(); Vector viewY = Geometry.Query.CrossProduct(viewVect, rowV); Vector viewX = Geometry.Query.CrossProduct(viewVect, viewY); viewVect = viewVect.Normalise(); Vector shift = viewVect * settings.EyeFrameDist; Point shiftOrigin = spectator.Head.PairOfEyes.ReferenceLocation + shift; Point viewClipOrigin = spectator.Head.PairOfEyes.ReferenceLocation + 2 * shift; //planes need orientation Plane viewPlane = Geometry.Create.Plane(shiftOrigin, viewVect); Plane viewClip = Geometry.Create.Plane(viewClipOrigin, viewVect); //get the view cone result.ViewCone = Create.ViewCone(viewY, viewX, shiftOrigin, 1, settings.ConeType); //find part of activity area to project Polyline clippedArea = ClipActivityArea(viewClip, activityArea); //project the pitch result.FullActivityArea = ProjectPolylineToPlane(viewPlane, clippedArea, spectator.Head.PairOfEyes.ReferenceLocation); //clip the pitch against the viewcone result.ClippedActivityArea = ClipActivityArea(result.FullActivityArea, result.ViewCone, spectator, viewPlane); //calculate the avalue result.AValue = result.ClippedActivityArea.Sum(x => x.Area()) / result.ViewCone.ConeArea * 100; //clip heads infront if (settings.CalculateOcclusion) { List <Spectator> occludingSpectators = GetPotentialOcclusion(spectator, tree, 3); if (occludingSpectators.Count > 0) { List <Polyline> occludingClippedHeads = ClipHeads(occludingSpectators, spectator, viewPlane, result.ClippedActivityArea); if (occludingClippedHeads.Count > 0) { result.Heads = occludingClippedHeads; result.Occulsion = occludingClippedHeads.Sum(x => x.Area()) / result.ViewCone.ConeArea * 100; CheckPolylineGeo(occludingClippedHeads); } } } return(result); }