Problems with PerspectiveLens and Visibility

Hi,

i have some problems with the standard base.camLens object.

I want to check if an object is inside the camera frustum (a check with base.camNode.isInView is not sufficient). For this i use the following code:

flags = base.camLens.makeBounds().contains(self.__model.getBounds())

I think this works IF I DON’T MOVE THE CAMERA. But if i move the camera (base.camera) then the intersection flags remain allways the same (independent from the actual visibility).

What is the problem here?

thx

You have to convert the bounding volume into the same coordinate space as the camera, similar to the way the point has to be transformed to use isInView(). You could do this by transforming the bounds by base.cam.getMat(self.__model). (Or maybe self.__model.getMat(base.cam), I’m not sure offhand which is the correct transform.)

But even this might not be very accurate, because the bounding volume might be a very loose bounds, especially after you have transformed it (transforming a bounding volume tends to make it looser). Also, it won’t take into account occlusion–the object will still register as being in front of the camera, even if it is behind a wall.

Still, it’s about as accurate as you can easily get on the CPU. To get more precise, you’d have to render it and see if it showed up in the results.

David

thx for your fast reply. It seems wo work better now :slight_smile:

I now use this code:

lensBounds = base.camLens.makeBounds() 
bounds = self.__model.getBounds()
bounds.xform(self.__model.getMat(base.cam))
flag = lensBounds.contains(bounds)

But i still have problems. I’m working on an peer-to-peer RTS Game (project at German University), which has hexagonal shaped game regions (for testing they are very small at the moment). Here is an example screenshot with 7 regions:

I want to test the visibility of the hexagon game regions, so that i can compute the fog-of-war only if necessary. Thats important, because of the peer-to-peer network the game world can become very big…

In the follwing screenshot there are all 7 regions inside the cam frustum und the flags all indicate this:

BUT when i zoom-in then also all regions are inside the frustum (partially), but the flags indicate this only for 4 of the 7 regions:

Any idea?

What are the precise values returned by the flags?

Note that the bounding-volume intersection test is also designed to be conservative rather than precise. If the test isn’t conclusive, it will report that the bounding volumes might intersect. But it will never report that the bounding volumes don’t intersect unless it is certain that they don’t.

If you are actually get a return value of 0 from the contains() function, for bounding volumes that do indeed partially intersect, then something might be wrong still with the transform.

David

The precise values for the flags (camera adjusted as seen in last screenshot) are:

3
3
3
0
3
0
0

So 3 of the 7 gameregions are not intersecting, but thats obviously wrong…

Any ideas whats wrong with the transformation?

Well, either the volumes really aren’t intersecting, or you are computing the wrong transform. Have you tried reversing the sense of getMat()?

David

Yes, i also tried the following code:

bounds.xform(base.cam.getMat(self.__model))

That’s not really working… if i completely zoom-out (as seen in the first screenshot), then i get only 0 flags…

When you have a look at the 3rd screenshot, there you see all 7 hexagon regions, so the boundings spheres should obviously intersect with the cam frustum, right?

thx

Hmm, try:

bounds.xform(self.__model.getParent().getMat(base.cam)) 

This is necessary because a node’s bounding volume is not pre-transformed by its node’s transform, so the relative transform should start by the node’s parent, not the node itself.

David

now it works perfectly! thx a lot! :smiley: