Check if a vertex is seen by the camera
-
On 08/02/2018 at 09:25, xxxxxxxx wrote:
How can I check if a specific vertex in a polygonal object is seen by a camera?
I just need to know if it is inside the camera fov.
I found a COFFEE code snippet that would do that but I can't seem to be able to re-write it in python -
On 08/02/2018 at 09:33, xxxxxxxx wrote:
Ok, never mind.
I got it -
On 09/02/2018 at 01:57, xxxxxxxx wrote:
Hi Rui,
Could you quickly share with the community the solution for your problem?
-
On 09/02/2018 at 04:05, xxxxxxxx wrote:
Actually, I found out that it works fine when the camera is facing some directions but it stops working when it faces others.
Still trying to fix that. -
On 09/02/2018 at 04:32, xxxxxxxx wrote:
This is my code, and it works fine, except when I rotate the camera around as some points are not considered inside the cone, at some camera orientations:
camm=cam.GetMg() campos=cam.GetAbsPos() camrot=cam.GetAbsRot() fov=cam[c4d.CAMERAOBJECT_FOV]/2.0 render=doc.GetFirstRenderData() xres=render[c4d.RDATA_XRES_VIRTUAL] yres=render[c4d.RDATA_YRES_VIRTUAL] yfov=fov*((1.0/xres)*yres) pol_obj_mt=pol_obj.GetMg() points=pol_obj.GetAllPoints() for pp in points: pt_pos=pp*pol_obj_mt angle=utils.VectorToHPB(pt_pos-campos) dangle=angle-camrot locpos=pt_pos*~camm if (locpos.z<=0 or dangle.x>=fov or dangle.x<=-fov or dangle.y>=yfov or dangle.y<=-yfov) : continue if(locpos.z>0 and (dangle.x<=fov or dangle.x>=-fov or dangle.y<=yfov or dangle.y>=-yfov)) : # the point is inside the camera cone
-
On 10/02/2018 at 06:47, xxxxxxxx wrote:
Maybe in this movie the problem becomes clearer:
-
On 11/02/2018 at 07:10, xxxxxxxx wrote:
Ok, made it work.
Had to make sure that the angle remained in the range 0 to PI*2 in some occasions and converted to the range -PI to +PI in others, like this:pi=3.1415926 pi2*2.0*pi def mod_angle(a) : if a<0: return (pi2+a)%pi2 return a%pi2 def mod_angle2(a) : a=mod_angle(a) if a>pi: return -pi2+a return a # ******************************************** camm=cam.GetMg() campos=cam.GetAbsPos() camrot=cam.GetAbsRot() camrot.x=mod_angle(camrot.x) camrot.y=mod_angle(camrot.y) camrot.z=mod_angle(camrot.z) fov=(cam[c4d.CAMERAOBJECT_FOV]+(2*tag[SBC_EXTRA]))/2.0 render=doc.GetFirstRenderData() xres=render[c4d.RDATA_XRES_VIRTUAL] yres=render[c4d.RDATA_YRES_VIRTUAL] yfov=fov*((1.0/xres)*yres) pol_obj_mt=pol_obj.GetMg() for i,pp in enumerate(points) : pt_pos=pp*pol_obj_mt angle=utils.VectorToHPB(pt_pos-campos) angle.x=mod_angle(angle.x) angle.y=mod_angle(angle.y) angle.z=mod_angle(angle.z) dangle=angle-camrot dangle.x=mod_angle2(dangle.x) dangle.y=mod_angle2(dangle.y) dangle.z=mod_angle2(dangle.z) locpos=pt_pos*~camm if (locpos.z<=0 or dangle.x>=fov or dangle.x<=-fov or dangle.y>=yfov or dangle.y<=-yfov) : continue if(locpos.z>0 and (dangle.x<=fov and dangle.x>=-fov and dangle.y<=yfov and dangle.y>=-yfov)) : # the point in within the camera cone
The problem now is that this seems to fail for vertical camera angles that are pointing downwards.
Can someone that is much more knowledgeable than me, check out if I'm doing something wrong.
I just need to make sure a point is within the camera cone, no matter how the camera is oriented. -
On 16/02/2018 at 07:59, xxxxxxxx wrote:
Hi Rui!
Sorry for the late reply.
It seems the camera for the calculation is used in the active view so you can rely on BaseView calculations.
So retrieve the active view, convert the point coordinate to camera space to check its Z (BaseView.WC()+BaseView.TestPointZ()), then to screen space to test its view visibility ((BaseView.CS()+BaseView.TestPoint())).
In the following code, point is the point coordinate in world space:visible = False pointCam = bd.WC(point) if bd.TestPointZ(pointCam) : pointScr = bd.CS(pointCam, False) visible = bd.TestPoint(pointScr.x, pointScr.y)
Note the code doesn't check for back-face culling.