示例#1
0
 public void IsInsideFOVTest9()
 {
     float x = -2;
     float y = 2;
     for (double i = 0; i < Math.PI * 2; i += Math.PI / 20)
     {
         Vector2 viewPoint = new Vector2(x - 1, y);
         LineF lookLine = new LineF(new Vector2(x + 1, y), (float)i, 1f);
         LineF line = new LineF(new Vector2(x, y + 0.5f), new Vector2(x, y - 0.5f));
         Assert.IsTrue(line.IsInsideFOV(viewPoint, lookLine));
     }
 }
示例#2
0
 private static bool _isPortalValid(IPortal previous, IPortal next, Vector2 viewPos)
 {
     //skip this portal if it isn't linked
     if (!Portal.IsValid(next))
     {
         return false;
     }
     //or it's the exit portal
     if (previous != null && next == previous.Linked)
     {
         return false;
     }
     //or if the portal is one sided and the view point is on the wrong side
     Vector2[] pv2 = Portal.GetWorldVerts(next);
     LineF portalLine = new LineF(pv2);
     if (next.OneSided)
     {
         if (portalLine.GetSideOf(pv2[0] + next.WorldTransform.GetRight()) != portalLine.GetSideOf(viewPos))
         {
             return false;
         }
     }
     //or if this portal isn't inside the fov of the exit portal
     if (previous != null)
     {
         LineF portalEnterLine = new LineF(Portal.GetWorldVerts(previous.Linked));
         if (!portalEnterLine.IsInsideFOV(viewPos, portalLine))
         {
             return false;
         }
     }
     return true;
 }
示例#3
0
 public void IsInsideFOVTest7()
 {
     float x = 0;
     float y = 0;
     for (double i = 0; i < Math.PI * 2; i += Math.PI / 20)
     {
         Scene scene = new Scene();
         FloatPortal p0 = new FloatPortal(scene);
         Entity node = new Entity(scene);
         Transform2.SetPosition(node, new Vector2(x, y));
         Transform2.SetRotation(node, (float)(i + Math.PI / 4));
         p0.SetParent(node);
         PortalCommon.UpdateWorldTransform(scene);
         Vector2 viewPoint = new Vector2(x + (float)Math.Cos(i), y + (float)Math.Sin(i));
         Vector2 lookPoint = new Vector2(x + (float)Math.Cos(i) * 2, y + (float)Math.Sin(i) * 2);
         LineF line = new LineF(Vector2Ext.Transform(Portal.GetVerts(p0), p0.GetWorldTransform().GetMatrix()));
         Assert.IsFalse(line.IsInsideFOV(viewPoint, lookPoint));
     }
 }
示例#4
0
        private static bool CalculatePortalViews(IPortal portal, IPortal portalEnter, IList<IPortal> portals, Matrix4 viewMatrix, Vector2 viewPos, Vector2 viewPosPrevious, PortalView portalView, Matrix4 portalMatrix, List<Func<bool>> actionList)
        {
            const float AREA_EPSILON = 0.0001f;
            Clipper c = new Clipper();
            //The clipper must be set to strictly simple. Otherwise polygons might have duplicate vertices which causes poly2tri to generate incorrect results.
            c.StrictlySimple = true;

            if (!_isPortalValid(portalEnter, portal, viewPos))
            {
                return false;
            }

            Vector2[] fov = Vector2Ext.Transform(Portal.GetFov(portal, viewPos, 500, 3), portalMatrix);
            if (MathExt.GetArea(fov) < AREA_EPSILON)
            {
                return false;
            }
            List<IntPoint> pathFov = ClipperConvert.ToIntPoint(fov);

            var viewNew = new List<List<IntPoint>>();

            c.AddPath(pathFov, PolyType.ptSubject, true);
            c.AddPaths(portalView.Paths, PolyType.ptClip, true);
            c.Execute(ClipType.ctIntersection, viewNew);
            c.Clear();

            if (viewNew.Count <= 0)
            {
                return false;
            }
            c.AddPaths(viewNew, PolyType.ptSubject, true);
            foreach (IPortal other in portals)
            {
                if (other == portal)
                {
                    continue;
                }
                if (!_isPortalValid(portalEnter, other, viewPos))
                {
                    continue;
                }
                //Skip this portal if it's inside the current portal's FOV.
                LineF portalLine = new LineF(Portal.GetWorldVerts(portal));
                LineF portalOtherLine = new LineF(Portal.GetWorldVerts(other));
                if (portalLine.IsInsideFOV(viewPos, portalOtherLine))
                {
                    continue;
                }
                Vector2[] otherFov = Vector2Ext.Transform(Portal.GetFov(other, viewPos, 500, 3), portalMatrix);
                if (MathExt.GetArea(otherFov) < AREA_EPSILON)
                {
                    continue;
                }
                otherFov = MathExt.SetWinding(otherFov, true);
                List<IntPoint> otherPathFov = ClipperConvert.ToIntPoint(otherFov);
                c.AddPath(otherPathFov, PolyType.ptClip, true);
            }
            var viewNewer = new List<List<IntPoint>>();
            c.Execute(ClipType.ctDifference, viewNewer, PolyFillType.pftNonZero, PolyFillType.pftNonZero);
            c.Clear();
            if (viewNewer.Count <= 0)
            {
                return false;
            }

            Vector2 viewPosNew = Vector2Ext.Transform(viewPos, Portal.GetLinkedMatrix(portal, portal.Linked));
            Vector2 viewPosPreviousNew = Vector2Ext.Transform(viewPosPrevious, Portal.GetLinkedMatrix(portal, portal.Linked));

            Matrix4 portalMatrixNew = Portal.GetLinkedMatrix(portal.Linked, portal) * portalMatrix;
            Matrix4 viewMatrixNew = portalMatrixNew * viewMatrix;

            LineF[] lines = Portal.GetFovLines(portal, viewPos, 500);
            lines[0] = lines[0].Transform(portalMatrix);
            lines[1] = lines[1].Transform(portalMatrix);
            LineF[] linesPrevious = Portal.GetFovLines(portal, viewPosPrevious, 500);
            linesPrevious[0] = linesPrevious[0].Transform(portalMatrix);
            linesPrevious[1] = linesPrevious[1].Transform(portalMatrix);

            LineF portalWorldLine = new LineF(Portal.GetWorldVerts(portal));
            portalWorldLine = portalWorldLine.Transform(portalMatrix);
            PortalView portalViewNew = new PortalView(portalView, viewMatrixNew, viewNewer, lines, linesPrevious, portalWorldLine);

            foreach (IPortal p in portals)
            {
                actionList.Add(() =>
                    CalculatePortalViews(p, portal, portals, viewMatrix, viewPosNew, viewPosPreviousNew, portalViewNew, portalMatrixNew, actionList)
                );
            }
            return true;
        }