[Closed] Is Point Visible in Camera View
Heeeeeeelp,
I have a camera and a point somwhere in space, how to calculate is that point visible from the camera . “Visible” means that point is inside camera cone.
Ok that shit i wrote genrates the camera cone as geometry, any idea how to check is my point inside the generated piramide or no ?
cam=$camera01
offset = 1000
Ccone=Pyramid widthsegs:1 depthSegs:1 heightsegs:1 width:0 depth:0 height:0
Ccone.transform=cam.transform
in coordsys #local move Ccone [0,0,-Offset]
hhfov=cam.fov
vvfov=2.0*atan(tan(hhfov/2.0)/(((renderWidth as float)/renderHeight)*renderPixelAspect))
Ccone.width=2*Offset*(sin(hhfov/2)/sin(90-(hhfov/2)))
Ccone.depth=2*Offset*(sin(vvfov/2)/sin(90-(vvfov/2)))
Ccone.height=offset
May be these scripts can help you:
CameraFaceCounter 0.2 http://www.scriptspot.com/3ds-max/camerafacecounter
Counts all faces within a Camera View Cone.
Blinders 1.02 http://www.scriptspot.com/3ds-max/blinders
what you do is create a box that follows your camera – everything inside this box at a given frame will be given a visibility track with a value of 1 – everything outside the box will be given a visibility track with a value of 0 – so now objects are only visible if it’s near the camera inside the box.
Take a look at the “How To … Develop A Vertex Renderer” topic in the MAXScript Help. It has a function to render a vertex into the image plane. If the point coordinates are outside of the render size (negative or less than the image width/height), then the point is not inside the frustrum.
Version 0.2 BETA Encrypted amzaing, the code is encrypted by some reason… must be something soooooo clever adn secret. Any way thank you for the responce. Looks like will fight that my own way.
See my post above, the solution is more or less there, inside the Help. A similar script is also available on my page for exporting from Max to Particle Illusion (both functions used the same concept, the one in the Help is a further development of the Illusion code)
That Beta script was encrypted back in 1998 or so. The real reason was not secrecy but me being ashamed of my spaghetti code.
Yep, there were times when I was learning how to script and my coding sucked big time…
Vport is very diferent than camera… i read all abvout vertex render even before ask for help here. Solution is not conected to gw.vport functions, will try some math , the problem is diference between vport and camera render view, try diferent pixel aspect ratios than 1 and will see what i am speaking about 8) Again simple old math will work best as i see. thank you all for the responce. Maybe some ray to camera aproach will work better.
Yeah, bobo i know your work and learn a lot of things from your scripts, respect, i am sure you have your own reasons to lock the code. But my personal beleive is that comunity must help each other, and in that light encrypting the code (in that case) is not very helpfull.
Preaching to the choir, right? You are talking to Bobo 10 years after that encryption. Sorry, I don’t even know if I have the source anymore.
As for render vs. viewport, you should keep in mind that the viewport shows the render aspects ONLY if Safe Frame is on. Regardless of your approach (measurign X and Y angles in camera space and comparing to half the horizontal and vertical FOVs or calculating the pixel coordinates), the viewport will not reflect your calculations if it is not set to Safe Frames. In other words, a point might not be visible in the viewport with Safe Frame off, but still be visible to the camera when rendering, or the other way round.
In the case of the pixel coordinates approach, all you have to do is divide the vertical size used in the function by the pixel aspect ratio. If pixel aspect is 1.0, everything will be like before. If pixel aspect is != 1.0 and the Image Aspect is locked, this will give you the actual render height. For example, at 640×480 and pixel aspect of 2.0, the Image Aspect would be 2.6667 and the render height should be assumed 240 instead of 480. If the Image Aspect is not locked, changing Pixel Aspect to 2.0 will set the Height to 960, then in the function the height will be adjusted to 480 and the calculation will match the Safe Frame display again. Obviously, the pixel approach requires the current viewport to be showing the camera in question, and the Safe Frame must be on.
The other approach is this:
*Take the point in world space and multiply by the inverse of the camera’s transform to get the point in camera space.
*The resulting point will have a negative Z if in front of the camera, positive if behind.
*If Z is negative, take the Point3 value, reset the Y component to 0 and you will have the projection of the point on the XZ plane of the camera. Now you can normalize this vector and calculate the angle relatively to the [0,0,-1] vector which represents the camera’s viewing axis. If this angle is higher than half the Horizontal FOV of the camera, the point is outside the frustrum
*If the X was inside the frustrum, take the original Point3 value again and replace the X component with 0 – this will give you the projection of the vector from camera POV to the point in camera space onto the YZ plane of the camera’s local coord. system. Again, normalize this vector and calculate the angle (acos (dot V1 V2)) between it and the [0,0,-1] vector of the -Z axis of the camera. If the result is greater than half the vertical FOV of the camera, then the point is outside the frustrum, otherwise it is inside.
fn isPointInCameraFrustrum thePoint theCamera =
(
thePosInCamera = thePoint * inverse theCamera.transform --point in camera space
if thePosInCamera.z < 0 then --if in front of the camera, calculate X and Y angles
(
thePos = copy thePosInCamera --copy the value
thePos.y = 0 --reset the Y axis
theAngleX = acos (dot (normalize thePos) [0,0,-1]) --calculate the X angle
thePos = copy thePosInCamera --copy the value again
thePos.x = 0 --reset the X axis
theAngleY = acos (dot (normalize thePos) [0,0,-1]) --calculate the Y angle
--get the aspect, compensate for pixel aspect:
r_aspect=(renderWidth as float)/renderHeight*renderPixelAspect
--calculate half the vertical FOV
VFOV = atan(tan(theCamera.fov/2.0)/r_aspect)
--return true if both angles are less then the halves of H and V FOV angles
theAngleX <= theCamera.fov/2 AND theAngleY <= VFOV
)
else false --return false if behind the camera's XY plane
)
isPointInCameraFrustrum $Point01.pos $Camera01 --pass a position and a camera
thaks man you ara monster !
Много благодаря за времето което си отделил за пор като мен. Де да бяха и другите хора такива… Наздраве.
Няма защо! Наздраве!
Good thing I have a laptop with Max here – I am on vacation in Sofia, but some habits never die, so here I am…
Please keep in mind I have barely tested the code – let me know if you find any problems.
Also, if you are going to test LOTS of points, change it to accept the inverse of the camera transform as argument in addition to the camera itself – calculating the inverse of a matrix is rather slow and could be performed just once for the current frame, then the result should be passed to the function to speed things up. Also, as I mentioned in the concept, you could bail out if the first angle is greater than the HFOV to avoid the second test completely.
Yeah, as i said the man is alien… THAKS BOBO, and i am so stupied to miss such elegant solution.