Пример #1
0
 public void SplitPrepare(Portal p)
 {
     Vertices = p.Vertices;
     Normal = p.Normal;
     Normal.MirrorNormal();
     Parent = null;
 }
Пример #2
0
        public static Frustum PortalFrustumIntersect(Portal portal, Frustum emitter, Render render)
        {
            if (portal.DestRoom == null)
                return null;

            if (portal.Normal.Distance(render.Camera.Position) < SPLIT_EPSILON)
                // non face or degenerate to the line portal
                return null;

            if (portal.DestRoom.Frustum.Count > 0 && emitter.HasParent(portal.DestRoom.Frustum[0]))
                return null; // Abort infinite loop!

            var inDist = false;
            var inFace = false;
            foreach (var v in portal.Vertices)
            {
                if (!inDist && render.Camera.Frustum.Normal.Distance(v) < render.Camera.DistFar)
                    inDist = true;
                if (!inFace && emitter.Normal.Distance(v) > 0.0)
                    inFace = true;
                if (inDist && inFace)
                    break;
            }

            if (!inDist || !inDist)
                return null;

            // Search for the first free room's frustum
            portal.DestRoom.Frustum.Add(new Frustum());
            var currentGen = portal.DestRoom.Frustum.Last();

            currentGen.SplitPrepare(portal); // prepare for clipping

            if (currentGen.SplitByPlane(emitter.Normal)) // splitting by main frustum clip plane
            {
                for (var i = 0; i < emitter.Vertices.Count; i++)
                {
                    if(!currentGen.SplitByPlane(emitter.Planes[i]))
                    {
                        portal.DestRoom.Frustum.RemoveAt(portal.DestRoom.Frustum.Count - 1);
                        return null;
                    }
                }

                currentGen.GenClipPlanes(render.Camera); // all is OK, let's generate clip planes

                currentGen.Parent = emitter; // add parent pointer
                currentGen.ParentsCount = emitter.ParentsCount + 1;

                portal.DestRoom.MaxPath = Math.Max(portal.DestRoom.MaxPath, currentGen.ParentsCount); // maximum path to the room
                return currentGen;
            }

            portal.DestRoom.Frustum.RemoveAt(portal.DestRoom.Frustum.Count - 1);

            return null;
        }