Checking if Model is Visible

I know this has been asked before, but I have a bit of a twist.

I have been using the following to see if a model is on screen:

    def IsInView(self,pos):

        p1 = main.cam.getRelativePoint(render,pos)

        if not main.camLens.project(p1,Point2()):
            return False
        return True

The problem is this is checking if the center of the model is in view, and not including the corners.

I need to check for the center, then so much on the X and Z axes to make sure the hole thing is off the screen.

Any ideas?

Well, I really haven’t the time to test in python or clean that up, so I just copied it from a project. It used to work nice… Maybe that can help.

bool CameraNode::is_in_view(const NodePath& object){
	PT(CameraNode) cn = CameraControl::get_instance()->get_current_camera();
	PT(BoundingVolume) lens_bounds = cn->get_real_camera()->get_lens()->make_bounds();
	PT(GeometricBoundingVolume) bounds = DCAST(GeometricBoundingVolume, object.get_bounds());

	bounds->xform(object.get_parent().get_mat(*cn));
	return lens_bounds->contains(bounds);
}

Maybe, something like this:

def IsInView(self, object):
	lensBounds = base.cam.makeBounds()
	bounds = object.getBounds()
	bounds.xform(object.getParent().getMat(base.cam)
	return lensBounds.contains(bounds)
lensBounds = base.cam.makeBounds()
AttributeError: 'libpanda.NodePath' object has no attribute 'makeBounds'

Not working.
[/code]

Try:

lensBounds = base.cam.node().getLens().makeBounds()

Works perfectly! Thanks!

Hi guys,

Just to elaborate a bit on a similar subject, how would you implement the detection of objects:

(1) that are fully in the camera frustum
(2) AND are located at a distance D in a range [r1,r2] from the camera, ie r1 < D < r2

Thanks for your hints

Something like that:

distanceSq = (object.getPos(render) - cam.getPos(render)).lengthSquared()
if((distanceSq < r2*r2) and (distanceSq > r1*r1) and isInView(object)) return true
return false

Hi Heek,

Well that’s not exactly what I meant, ie this supposes that you ‘know’ the object(s) to check.

What I mean is that the objects are expected to ‘rise hand’ by themselves. if they happen to be in the frustum and at distance D, r1<D<r2.

To do so I had in mind an approach based on collision detection (ie with sphere (r1) and a reverse sphere (r2))
but I’m afraid that this is not a smart way in term of performances…

Well… I guess you can extend a PandaNode and use the cull_callback to do the distance maths. Something like that happens in the LodNode I suppose.
You can do that with an RenderAttrib/RenderEffect as well, although you should have some caution because at that time, the cull check has already been made…

But, the simplest you can do is: simply use a task to do the check and raise hands… :wink:

Thanks for your suggestion.

I’m not certain I get it correctly: if I set a cull_callback, I suppose I have to set it to all potential objects that may happen to verify the requested distance conditions.

Since I don’t know whose objects will be in this case, I’ll have to do it for all in the scene, right?

So I’m afraid there is a high price to pay in term of performances, don’t you think so?

Put a collision body into the view frustum that perfectly covers it. Sounds like the easiest method to me.

Ok, if I get it right:

have a collision body (a cone) located in the frustum at a distance r1 with a cone height of r2-r1.
then isolate each object that has entered (or is still) into collision

I’ll give it a try. Thanks
Jean-Claude