Edit: Solved, see below
I want to determine the four points at which the camera’s viewing frustum intersects the plane z=0.
The position of camera is set to (0,0,0) and the zoom is controlled by the y-value of base.cam.
I’m using the code:
for point in (-1,-1), (-1, 1), (1, -1), (1, 1):
pos3d = Point3()
nearPoint = Point3()
farPoint = Point3()
base.camLens.extrude(point, nearPoint, farPoint)
if world.plane.intersectsLine(pos3d,
render.getRelativePoint(base.cam, nearPoint),
render.getRelativePoint(base.cam, farPoint)):
print pos3d
This works when the angle between camera and the plane is large (larger than ~15 degrees). However, when the angle is small, intersectsLine() creates an intersection point (pos3d in the above code) that is in the opposite direction. In other words, if the intersection point should have a small y-value, it creates an intersection point with a large y-value and vice versa.
Here’s the code that works:
def getFrustum(self):
""" Returns corners of the view frustum. Camera must use default fov. """
# Extrude near and far points from corners of display window
ntl = Point3(); ftl = Point3()
ntr = Point3(); ftr = Point3()
nbl = Point3(); fbl = Point3()
nbr = Point3(); fbr = Point3()
base.camLens.extrude(Point2(-1,1), ntl, ftl)
base.camLens.extrude(Point2(1,1), ntr, ftr)
base.camLens.extrude(Point2(-1,-1), nbl, fbl)
base.camLens.extrude(Point2(1,-1), nbr, fbr)
# Convert far points to world space
ftl = render.getRelativePoint(base.cam, ftl)
ftr = render.getRelativePoint(base.cam, ftr)
fbl = render.getRelativePoint(base.cam, fbl)
fbr = render.getRelativePoint(base.cam, fbr)
# Calculate z-intersect of lines passing through near and far points
tl = Point3()
tr = Point3()
bl = Point3()
br = Point3()
world.plane.intersectsLine(tl, render.getRelativePoint(base.cam, ntl), ftl)
world.plane.intersectsLine(tr, render.getRelativePoint(base.cam, ntr), ftr)
world.plane.intersectsLine(bl, render.getRelativePoint(base.cam, nbl), fbl)
world.plane.intersectsLine(br, render.getRelativePoint(base.cam, nbr), fbr)
# Return far points when z-intersect is behind camera
camPitch = camera.getP() % 360
if (camPitch == 0) or (345 < camPitch <= 360) or (165 < camPitch <= 180):
tl = ftl
tr = ftr
elif (180 < camPitch <= 195) or (0 < camPitch <= 15):
bl = fbl
br = fbr
return tl, tr, bl, br