Zoom in perspective exactly to objects size
I have used this dirty hack (viewport.zoom .75) in code below to approximately get the viewport of the perspective to fill the viewport as best it can and also reset the VP the way I like.
viewport.ResetAllViews() --resets to Max Standard actionMan.executeAction 0 "311" --frames all viewports viewport.zoom .75 --fix to make perspective view appear closer viewport.setGridVisibility #all false --turns off all grids actionMan.executeAction 0 "40829" --show statistics actionMan.executeAction 0 "63547" -- Views: Viewport Materials Display as Realistic with Maps
This works fine but I was searching for a more accurate solution and I got a fn from Dennis T on another forum to get the bounding size of objects in a scene. I've searched hi and low for the answer on how the viewport.ZoomToBounds System Global Variable actually works in relation to this and also how to get the zoom to work. Searching now 3 hours and no luck.
CODE I HAVE SO FAR:
global ZoomToObjBB fn ZoomToObjBB = ( viewport.ResetAllViews() --resets to Max Standard actionMan.executeAction 0 "311" --frames all viewports --viewport.zoom .75 --fix to make perspective view appear closer viewport.setGridVisibility #all false --turns off all grids actionMan.executeAction 0 "40829" --show statistics actionMan.executeAction 0 "63547" -- Views: Viewport Materials Display as Realistic with Maps nodes = for node in objects 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 print bmin.x print bmin.y print bmax.x print bmax.y print w print h viewport.ZoomToBounds false (point3 w h 0) (point3 w h 0) completeRedraw() ) ) ZoomToObjBB()
Any help would be greatly appreciated from you experts out there :)
Comments
At long last, it is done
Hello, been working on this for a while now. Finally got it working (tried quite a few methods). The script goes through all the points in a given mesh and saves the positions of each of these points. The script then checks the translation of these points relative to the camera field of view lines (camera FOV Cone lines). The points which are furthest away from these lines are the points which the camera field of view lines should intersect. I then calculate the intersection points between the two FOV lines (one time for xy plane and another time for yz plane). Then I create a camera and place it on the correct coordinates depending on the calculation results (for line intersection points).
You can change the *teapot* wildcard in line to change what object is selected (change the wildcard so it selects the obj(s) of your choice.
The script corrects for change of render resolution automatically. For 'padding' you can add a percentage increase to the camera's distance from the object so you'll have a bit of space around the object (atm the viewport edges are perfectly aligned with the selected object verts so no space around obj). If you want some more detailed info on how it works I'll be happy to explain.
You could probably modify the code to link it to a shortcut key (activate on keypress) and make it zoom the viewport rather then place a correctly zoomed camera if this is needed for your application.
Hope this helps.
-Maarten
Thanks. It's a step forward
Thanks. It's a step forward but in a destructive way unfortunately.
Thanks for trying to get it to work but this wouldn't work for my use. I clean up folders using a batch script which runs selected scripts on max file and this would be too destructive and slow on objects such as trees etc.
some study material
And here we have some study material regarding perspective projection
http://www.songho.ca/opengl/gl_projectionmatrix.html
Use Hold/Fetch
Perhaps you can use hold/fetch functions in 3ds max to make it less destructive, hold before zoom operation and fetch after to get the original model state back. If you remove the print/format lines from the script it will be faster. probably won't take more than a few seconds per model (depending on mesh complexity). You can quite easily remove the lines where a new freecamera is created and aligned. You could then replace these lines with a few simple lines to take a camera in your scene (or all cameras) and align them to the correct zoom positions.
The camera in this zoom script is also aligned with one of the axis (it has a standard location) which I forgot about (was writing this as a part of a personal project). But I should be able to modify it so that it works with cameras in all angles. It is a matter of changing a few formulas and variables. Will take some time but is definitely possible.
Could you explain what about my method is 'destructive'?
You could perhaps modify the function so that it only goes through a specified part of the verts. Could you explain in more detail what exactly you want to do with the script, Are you trying to zoom in the camera on the object in your scenes? perhaps I can help.
I am not sure what other method could be used to zoom 100% accurately on the object. If you could somehow only look at the points which are most likely going to be close to the edges of the screen (close to the camera's field of view lines) this would be nice but this is hard to define.
If you could determine which points in the mesh the viewport should be zoomed on you could make it faster probably. Not sure how one would do this though. We can try though :) So the plan would be to find a way to determine which points lie most to the left, right, top and bottom of the current(/specified) viewport. Then the camera can be zoomed in on these points (This last zooming in on the points part would be the same as in the script I uploaded a few days ago). We cannot rely on the screen coordinate system to find the correct points bacause this does not take perspective into account...
If you can think of another way to define these 'zoom points' I'd be happy to hear it from you :) I've added an image to show what I mean by zoom points. (see red points on model in image) Note that these points are not always the object's max and min x,y,z values (try setting up a scene and rotating the object if you want to see for yourself). They are in a way the object's maximum and minimum values but relative to the camera's FOV (Field of view) Lines. I tried getting the object's max and min values in this coordinatesystem but could not get it to work, you can try also, perhaps you'll get better results. By the way, I think 3ds max's obj.max.x (and similar) functions use a similar method as I am using with the 'perspective zoom' script , as in the function looks at all the points in the object (x value in the case of obj.max.x) and returns (the function returns) the maximum value of x in this array. I could be wrong on this though :P
The zoom should not be 100% accurate per se because you always want some room around your model (aka padding). You could perhaps go through the models in steps of 10 vertices, which would be less accurate but would yield relatively good results if the vertex density of the models is somewhat uniform.
Perhaps you could also make the amount of vertecis the script goes over(/skips) each step depend on the distance of the last vertex it calculated (the distance relative to one of the field of view lines) so that the closer it gets to the FOV line the smaller the steps (and it will be more accurate closer to the FOV lines). But for that I'd need a better understanding of vertex order in 3d models.
Anyways, good luck and please let me know if you know/find something :)
-Maarten
Wow!! Nice write up there
Wow!! Nice write up there Maarten. I'm busy with a script at the moment but hopefully I have enough spare time to procrastinate on this again :P
I will definitely come back to this at some point but for now it's not no.1 on the list of things to do.
Good work Maarten.
Had any luck with this?
I am working on a very similar problem in maxscript (zoom exactly on obj.size in perspective). I think I found a good method but will have to test it and see if I can optimize it, will share results when some progress has been made.
-Maarten
I gave up after a while. I
I gave up after a while. I was hoping someone more cleverer than myself would jump on board! :P
I look forward to seeing your findings.
Bump
I've still had no luck with this.