Beispiel #1
0
 public bool HasParent(Frustum parent)
 {
     var frustum = this;
     while(frustum != null)
     {
         if (parent == frustum)
             return true;
         frustum = frustum.Parent;
     }
     return false;
 }
Beispiel #2
0
        public void AddNewPolygonList(List<TransparentPolygonReference> p, Transform transform, Frustum frustum, Camera cam)
        {
            foreach (var pp in p)
            {
                var transformed = new Polygon();
                transformed.Vertices.Resize(pp.Polygon.Vertices.Count, () => new Vertex());
                transformed.Transform(pp.Polygon, transform);
                transformed.DoubleSide = pp.Polygon.DoubleSide;

                if(frustum.IsPolyVisible(transformed, cam))
                {
                    addPolygon(ref _root, new BSPFaceRef(transform, pp), transformed);
                }
            }
        }
Beispiel #3
0
        public void DrawFrustum(Frustum f)
        {
            for (var i = 0; i < f.Vertices.Count - 1; i++)
            {
                addLine(f.Vertices[i], f.Vertices[i + 1]);
            }

            addLine(f.Vertices.Last(), f.Vertices.First());
        }
Beispiel #4
0
        /// <summary>
        /// The recursion algorithm: go through the rooms with portal-frustum occlusion test.
        /// </summary>
        /// <param name="portal">Portal we entered to the room through</param>
        /// <param name="frus">Frustum that intersects the portal</param>
        /// <returns>Number of added rooms</returns>
        public int ProcessRoom(Portal portal, Frustum frus)
        {
            var destination = portal.DestRoom;
            var current = portal.CurrentRoom;

            if(current == null || !current.Active || destination == null || !destination.Active)
            {
                return 0;
            }

            var ret = 0;
            foreach (var p in destination.Portals)
            {
                if(p.DestRoom != null && p.DestRoom.Active && p.DestRoom != current)
                {
                    // The main function of portal renderer. Here comes the check.
                    var genFrus = Frustum.PortalFrustumIntersect(p, frus, this);
                    if(genFrus != null)
                    {
                        ret++;
                        AddRoom(p.DestRoom);
                        ProcessRoom(p, genFrus);
                    }
                }
            }
            return ret;
        }
Beispiel #5
0
 public void SplitPrepare(Portal p)
 {
     Vertices = p.Vertices;
     Normal = p.Normal;
     Normal.MirrorNormal();
     Parent = null;
 }
Beispiel #6
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;
        }