public static void ComputePerspectiveFrustumCorners( ref Vector3 viewPosition, ref Vector3 viewDirection, ref Vector3 globalUpDirection, float fov, float nearDistance, float farDistance, float aspectRatio, out FrustumCorners corners) { float nearHeight = (float)(2 * Math.Tan(fov / 2.0) * nearDistance); float nearWidth = nearHeight * aspectRatio; float farHeight = (float)(2 * Math.Tan(fov / 2.0) * farDistance); float farWidth = farHeight * aspectRatio; Vector3 right = Vector3.Normalize(Vector3.Cross(viewDirection, globalUpDirection)); Vector3 up = Vector3.Normalize(Vector3.Cross(right, viewDirection)); Vector3 nearCenter = viewPosition + viewDirection * nearDistance; Vector3 farCenter = viewPosition + viewDirection * farDistance; corners.NearTopLeft = nearCenter - ((nearWidth / 2f) * right) + ((nearHeight / 2) * up); corners.NearTopRight = nearCenter + ((nearWidth / 2f) * right) + ((nearHeight / 2) * up); corners.NearBottomLeft = nearCenter - ((nearWidth / 2f) * right) - ((nearHeight / 2) * up); corners.NearBottomRight = nearCenter + ((nearWidth / 2f) * right) - ((nearHeight / 2) * up); corners.FarTopLeft = farCenter - ((farWidth / 2f) * right) + ((farHeight / 2) * up); corners.FarTopRight = farCenter + ((farWidth / 2f) * right) + ((farHeight / 2) * up); corners.FarBottomLeft = farCenter - ((farWidth / 2f) * right) - ((farHeight / 2) * up); corners.FarBottomRight = farCenter + ((farWidth / 2f) * right) - ((farHeight / 2) * up); }
public unsafe ContainmentType Contains(ref BoundingFrustum other) { int pointsContained = 0; FrustumCorners corners = other.GetCorners(); Vector3 * cornersPtr = (Vector3 *)&corners; for (int i = 0; i < 8; i++) { if (Contains(&cornersPtr[i]) != ContainmentType.Disjoint) { pointsContained++; } } if (pointsContained == 8) { return(ContainmentType.Contains); } else if (pointsContained == 0) { return(ContainmentType.Disjoint); } else { return(ContainmentType.Intersects); } }
public void GetCorners(out FrustumCorners corners) { PlaneIntersection(ref _planes.Near, ref _planes.Top, ref _planes.Left, out corners.NearTopLeft); PlaneIntersection(ref _planes.Near, ref _planes.Top, ref _planes.Right, out corners.NearTopRight); PlaneIntersection(ref _planes.Near, ref _planes.Bottom, ref _planes.Left, out corners.NearBottomLeft); PlaneIntersection(ref _planes.Near, ref _planes.Bottom, ref _planes.Right, out corners.NearBottomRight); PlaneIntersection(ref _planes.Far, ref _planes.Top, ref _planes.Left, out corners.FarTopLeft); PlaneIntersection(ref _planes.Far, ref _planes.Top, ref _planes.Right, out corners.FarTopRight); PlaneIntersection(ref _planes.Far, ref _planes.Bottom, ref _planes.Left, out corners.FarBottomLeft); PlaneIntersection(ref _planes.Far, ref _planes.Bottom, ref _planes.Right, out corners.FarBottomRight); }
public static unsafe void ComputeOrthographicBoundsForPerpectiveFrustum( ref FrustumCorners corners, ref Vector3 lightDir, float cameraFarDistance, out Matrix4x4 lightView, out OrthographicBounds bounds) { float nearClipOffset = 40.0f; Vector3 centroid = (corners.NearTopLeft + corners.NearTopRight + corners.NearBottomLeft + corners.NearBottomRight + corners.FarTopLeft + corners.FarTopRight + corners.FarBottomLeft + corners.FarBottomRight) / 8f; Vector3 lightOrigin = centroid - (lightDir * (cameraFarDistance + nearClipOffset)); lightView = Matrix4x4.CreateLookAt(lightOrigin, centroid, Vector3.UnitY); float * lightSpaceCornerFloats = stackalloc float[3 * 8]; Vector3 *lightSpaceCorners = (Vector3 *)lightSpaceCornerFloats; // Light-view-space lightSpaceCorners[0] = Vector3.Transform(corners.NearTopLeft, lightView); lightSpaceCorners[1] = Vector3.Transform(corners.NearTopRight, lightView); lightSpaceCorners[2] = Vector3.Transform(corners.NearBottomLeft, lightView); lightSpaceCorners[3] = Vector3.Transform(corners.NearBottomRight, lightView); lightSpaceCorners[4] = Vector3.Transform(corners.FarTopLeft, lightView); lightSpaceCorners[5] = Vector3.Transform(corners.FarTopRight, lightView); lightSpaceCorners[6] = Vector3.Transform(corners.FarBottomLeft, lightView); lightSpaceCorners[7] = Vector3.Transform(corners.FarBottomRight, lightView); bounds.MinX = lightSpaceCorners[0].X; bounds.MaxX = lightSpaceCorners[0].X; bounds.MinY = lightSpaceCorners[0].Y; bounds.MaxY = lightSpaceCorners[0].Y; bounds.MinZ = lightSpaceCorners[0].Z; bounds.MaxZ = lightSpaceCorners[0].Z; for (int i = 1; i < 8; i++) { if (lightSpaceCorners[i].X < bounds.MinX) { bounds.MinX = lightSpaceCorners[i].X; } if (lightSpaceCorners[i].X > bounds.MaxX) { bounds.MaxX = lightSpaceCorners[i].X; } if (lightSpaceCorners[i].Y < bounds.MinY) { bounds.MinY = lightSpaceCorners[i].Y; } if (lightSpaceCorners[i].Y > bounds.MaxY) { bounds.MaxY = lightSpaceCorners[i].Y; } if (lightSpaceCorners[i].Z < bounds.MinZ) { bounds.MinZ = lightSpaceCorners[i].Z; } if (lightSpaceCorners[i].Z > bounds.MaxZ) { bounds.MaxZ = lightSpaceCorners[i].Z; } } }