[Closed] camera zoom extents to fit
Hi.all
I have search internet about camera zoom extents. but no good answer. so put it here for talk about…
what I want it’s make one object in the center of the camera . then change the camera Fov to zoom extents . this is not different from the max default zoom select oject extents. becuase default way aways have more space around.
so. I just think whether can do it like the follow piont.
- make the camera pos.x= objec.x . camera pos.z= object.z. later make camera.z have a litte raise.
- use lookat . object.lookat=camera.—this just let object can in center of the camera view.
- this setp calculate the camera fov. —this is the main problem that I meet.
here is my simple start maxscript
rollout zoomcamera "zoomcamera" width:195 height:87
(
button btn1 "zoom extents camera" pos:[26,27] width:143 height:27
on btn1 pressed do
(
obj=Teapot()
obj.radius=200
CenterPivot obj
cam=freecamera()
rotate cam (angleaxis 90 [1,0,0])
cam.pos=[0,-1350,150]
cam.baseObject.targetDistance=1350
obj.lookat=cam
cam.pos.z=cam.pos.z+350
--then the blow step is main problem.
)
)
createdialog zoomcamera style:#(#style_minimizebox, #style_titlebar, #style_sysmenu)
there have some info that I find out in internet.
1. http://buchhofer.com/2008/08/maxscript-zoom-extents/
[B]2. http://forums.cgsociety.org/archive/index.php/t-860305.html
there have a goodidea about how to get the camera fov.
this is harefort’s code. but for me a litte hard to deal detail.[/B]
fMaxAngleX = 0.0
fMaxAngleY = 0.0
for i = 1 to $.verts.count do
(
p3ViewVector = $.verts[i].pos - nCamera.pos
p3ViewVectorProjX = p3CameraRightVector * (dot p3ViewVector p3CameraRightVector)
p3ViewVectorProjY = p3CameraUpVector * (dot p3ViewVector p3CameraUpVector)
fAngleX = acos (dot (normalize p3ViewVectorProjX) p3CameraForwardVector)
fAngleY = acos (dot (normalize p3ViewVectorProjY) p3CameraForwardVector)
fMaxAngleX = aMax #(fMaxAngleX , fAngleX)
fMaxAngleY = aMax #(fMaxAngleY , fAngleY)
)
nCamera.fov.x = fMaxAngleX * 2
nCamera.fov.y = fMaxAngleY * 2
3. the maxscript help also have a maxscipt. but I have test that. no so good.
fn ZE_Cam cam objs =
(
local max2, fov, asp, v -- declare local variables
-- define a function that returns the maximum value
-- of a set of values in an array
fn maxof vals = (local v=vals[1]; for v1 in vals do (if v1 > v do v=v1);v)
fov=0 -- initialize the fov value
asp=(renderWidth as float)/renderHeight -- calculate the renderer's image aspect ratio
in coordsys cam -- work in coordinate system of the camera
(
for obj in objs where obj != cam do -- loop across all objects except the camera
(
if obj.min.z >=0 do continue -- if object is behind camera, skip it
-- get max value of the object's bounding box, correcting for the image aspect ratio
-- in the y values
v = maxof #((abs obj.max.x),(abs obj.min.x),(abs (obj.max.y*asp)),(abs (obj.min.y*asp)))
fov = maxof #(fov,(2*atan(-v/obj.min.z))) -- increase fov if needed
)
)
cam.fov=fov -- set the camera's fov to the new fov value
)
-- test bed --
cam=$camera01 -- specify the camera to "zoom extent all" on
ZE_Cam cam $* -- call the function, passing the camera and an object set containing all objects
and the camera fov should need this
camera.fov=acos( (a^2+b^2-c^2)/(2ab))
about . a.b.c please see the attached file.
I use the viewport controls for this, not a real camera. It’s mostly a hack of zoomextents and then zoom 0.7x to close in a bit. It’s not the greatest but it works well enough with most of our assets.
I would like to use IntersectRay or IntersectRayEx something like this:
[ul]
[li]zoom extents[/li][li]trace rays to hit test for geometry in a 20×20 grid[/li][li]collect all the points that hit geometry[/li][li]convert the returned point to the viewport transform matrix[/li][li]check for min and max of all the points[/li][li]adjust the FOV of the viewport to get a tighter fit.[/li][/ul]I haven’t had time to look into this though.
the method is absolutely correct. to make it more accurate you can start zooming the view always from the same default initial state: position, orientation, fov.
I would like to use IntersectRay or IntersectRayEx something like this …
It’s not necessary. You can project all world verts positions to view and find the bbox in view coordinates for all verts. You don’t need “intersection” methods to get it.
thank you for Jonah Hawk and denisT.
Originally Posted by jonahhawk
I use the viewport controls for this, not a real camera. It’s mostly a hack of zoomextents and then zoom 0.7x to close in a bit. It’s not the greatest but it works well enough with most of our assets.
Yes, this way in generally .it’s Ok. but for me. I want exact way. so. I must choose the “IntersectRay ” or “bbox” way,
But, A litte hard for me for this.I dont know this before. I need take some time to study this… if somebady can help me write a litte maxscript. just simple maxscirpt. it’s good. Thank you very much…
here is how to get Veiw BBox for selected geometry nodes:
global easyViewSelectionBBox
unRegisterRedrawViewsCallback easyViewSelectionBBox
fn easyViewSelectionBBox =
(
nodes = for node in selection where iskindof node GeometryClass collect node
if nodes.count > 0 do
(
view = viewport.activeViewport
local bmin = [1e9,1e9,0], bmax = [-1e9,-1e9,0]
gw.setTransform (matrix3 1)
transPoint = gw.hTransPoint
for node in nodes do
(
mesh = snapshotasmesh node
for v=1 to mesh.numverts do
(
vp = transPoint (GetVert mesh v)
if vp.x < bmin.x do bmin.x = vp.x
if vp.x > bmax.x do bmax.x = vp.x
if vp.y < bmin.y do bmin.y = vp.y
if vp.y > bmax.y do bmax.y = vp.y
)
free mesh
)
w = (bmax.x - bmin.x) as integer
h = (bmax.y - bmin.y) as integer
rect = box2 bmin.x bmin.y w h
gw.hPolyline #(bmin, point3 bmax.x bmin.y 0, bmax, point3 bmin.x bmax.y 0) on rgb:#(orange,orange,orange,orange)
gw.hText (bmin + [5,h-20,0]) ("Size: [" + (w as string) + ", " + (h as string) + "]") color:orange
gw.enlargeUpdateRect rect
gw.updateScreen()
)
)
registerRedrawViewsCallback easyViewSelectionBBox
completeRedraw()
I hope this sample will be helpful for some rookie max scripter
Hi, denisT
The script running cool… it’s you . DenisT. you make my working easy…
I must need say thank you very much ! Thank you in advanced !!
Joe
I’ve made small (but essential) correction in my code of easyViewSelectionBBox to make it faster for Geometry Primitives.
I’ve thought a little more and made the function about two times faster… check the difference.
actually it’s three times faster
wow.thank you agian… I have no words to say… just say thank you (in advanced) * (in advanced)