RE: Calculation of new View Frustum
Hi.
We implemented a portal rendering system in Haddd 1.6 but it was discarded in the end.
Here is the constructor that creates a new Frustum from a given portal:
Code:
/// <summary>
/// Creates an instance of HFrustum from the given portal
/// </summary>
public HFrustum(HPortal portal, Vector3 cameraPosition)
{
planes = new List<Plane>(portal.Vertices.Count);
// Distance from the portal plane to the camera position
float distance = portal.Plane.Dot(cameraPosition);
// If the camera is behind the portal, that is, if the camera position is not on the side
// the portal's plane normal is pointing to, we have to invert the order of the vertices so the
// frustum planes (their normals) are facing in the correct direction
bool reverse = distance < 0.0f;
int i, i2, vertexIndex, nextVertexIndex;
for (i = 0; i < portal.Vertices.Count; i++)
{
// Index to the next vertex in the portal
i2 = (i + 1) % portal.Vertices.Count;
// Calculate vertex indices depending if we have to invert the order of the portal vertices
vertexIndex = reverse ? portal.Vertices.Count - i - 1 : i;
nextVertexIndex = reverse ? portal.Vertices.Count - i2 - 1 : i2;
// Reference to the vertices
Vector3 v1 = portal.Vertices[vertexIndex];
Vector3 v2 = portal.Vertices[nextVertexIndex];
// Calculates a frustum plane given the three points we have
Plane plane = Plane.FromPoints(cameraPosition, v1, v2);
planes.Add(plane);
}
}
In HPortal, "Vertices" is the list of vertices that makes up the portal (they have to be in the correct order, I can't remember if it was clock-wise o counter clock-wise) and "Plane" is just the plane where the portal is contained.
Hope that helps.
========================================
Once again i'm stuck,
The frustum code works perfectly, but i'm attempting to clip my portals before that are fed through to this function.
I'm battling with clipping the portal polygon to the original planes of the frustum (Left, Right, Top and Bottom).
I'm using the JMath.ClipToPlane, but i'm not to sure how to clip the polygon to all the planes easily with correct results,
and efficiently.
If any of you can point me in the right direction, that would be fantastic
Thanks once again in advance.
--------
Hi.
Those are methods from our old portal class:
Code:
public void ClipToPlane(Plane plane)
{
if (!(plane.A != 0 || plane.B != 0 || plane.C != 0))
return;
List<Vector3> auxVerts = new List<Vector3>();
for (int i = 0; i < vertices.Count; i++)
{
int i2 = (i + 1) % vertices.Count;
Vector3 v1 = vertices[i];
Vector3 v2 = vertices[i2];
float dist1 = plane.Dot(v1);
float dist2 = plane.Dot(v2);
if (dist1 < 0 && dist2 < 0)
continue;
if (dist1 > 0 && dist2 > 0)
{
auxVerts.Add(v1);
}
else if (dist1 > 0)
{
auxVerts.Add(v1);
auxVerts.Add(Plane.IntersectLine(plane, v1, v2));
}
else
{
auxVerts.Add(Plane.IntersectLine(plane, v1, v2));
}
}
if (auxVerts.Count >= 3)
vertices = auxVerts;
else
vertices.Clear();
}
public static HPortal ClipToFrustum(HPortal portal, HFrustum frustum)
{
HPortal oPortal = (HPortal)portal.Clone();
foreach (Plane plane in frustum.Planes)
{
// The method ClipToPlane clips the portal and returns the section that is in the positive side of the plane,
// that is, the side where the plane's normal is pointing to. But in the case of frustum clipping, the
// positive side of the planes is outwards so that's why we have to invert the frustum plane's normal
// so that the section we obtain from the clipped portal is the one inside the frustum and not outside.
oPortal.ClipToPlane(Plane.Scale(plane, -1.0f));
}
return oPortal;
}