public void SplitPrepare(Portal p) { Vertices = p.Vertices; Normal = p.Normal; Normal.MirrorNormal(); Parent = null; }
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; }