Jump to content
  • Advertisement
Sign in to follow this  
aeroxr1

position camera for object to fit in screen height

This topic is 1485 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi to everyone :)
 
I have an 3d model and I want to set my camera to fit all the object in screen height.
 
How Can I do ? I know the object width and the height, but I don't know how do I do to calculate the fov and camera position in according to screen resolution .
 
On portrait mode it is all  ok , but in landscape the camera is too zoomed :(

I'm attached two screenshot :)

Share this post


Link to post
Share on other sites
Advertisement

This problem can be solved with a little trigonometry. If you draw it out on paper, it may be easier to visualize.  First draw a point that represents the camera position. This is what we're going to find.  Then draw a vertical line some distance away.  This represents where the model is located, and the length represents the height of the model.  Then draw 3 lines from the point to the top of the line, middle of the line, and bottom of the line. This forms two right angle triangles.  

 

Using the top triangle and what we know about the model height and the vertical field of view of your camera (the angle between the two diagonal lines in your drawing), we can solve the problem using the trig function: tan(angle) = opposite / adjacent; where angle is half of your vertical fov angle (because we divided the space in two with the middle line), opposite is half of the model height (again because the space was divided in two to get right triangles), and adjacent is the distance the camera is from the model.

 

So:

tan( fovy / 2 ) = ( modelHeight / 2 ) / cameraDistance

 

Now solve for cameraDistance:
cameraDistance = ( modelHeight / 2 ) / tan( fovy / 2 )

 

Then place your camera:
cameraPos.z = modelPos.z - cameraDistance (if you are using left handed coordinate system where +z goes into screen, otherwise negate cameraDistance if using right handed coordinate system)

 

You can add a little extra offset to cameraDistance if you want a little extra space between the edge of the screen.

 

You can do this also for the model width if you need to by substituting in the width instead of height and the horizontal fov instead of vertical.  To compute the horizontal fov, multiply the vertical fov by the aspect ratio of the camera.

Edited by megadan

Share this post


Link to post
Share on other sites


cameraDistance = ( modelHeight / 2 ) / tan( fovy / 2 )

 

If you want to fit any model completely, then you should fit the model's bounding sphere within the camera, not just the model's height or width.

Share this post


Link to post
Share on other sites

Thanks for your time smile.png You are special ! smile.png Thanks ! ! ! 
(my english is much bad and I don't know many positive adjectives to describe a good person biggrin.png

 

I do in this way :
 


float[] bb = calcBoundingBox();
box_h = (bb[3] - bb[2]); // model height


Camera camera = world.getCamera();
if(width < height)
{ 
camera.setPosition(0,-box_h/2,0);
camera.moveCamera(Camera.CAMERA_MOVEOUT, 70);  //la sposto indietro
camera.lookAt(new SimpleVector(0, -box_h/2, 0));
}
else
{
float fovy=camera.getYFOV();


double cameraDistance = ( box_h / 2 ) / Math.tan( fovy / 2 );


camera.setPosition(0,-box_h/2,(float)cameraDistance-100);


camera.lookAt(new SimpleVector(0, -box_h/2, 0)); 


}
Without -100 the model didn't correctly fit in the display, but it was too zoomed.. 
Why ?
If I want regolate the camera also depending from resolution and model height ? smile.png
 
The coordinate system are : Coordsystem.png
 
 
I have calculated The bounding box of my model in this way :
	protected float[] calcBoundingBox() {
		float[] box = null;
		
		for (Animated3D skin : modello) {
			float[] skinBB = skin.getMesh().getBoundingBox();
			
			if (box == null) {
				box = skinBB;
			} else {
				// x
				box[0] = Math.min(box[0], skinBB[0]);
				box[1] = Math.max(box[1], skinBB[1]);
				// y
				box[2] = Math.min(box[2], skinBB[2]);
				box[3] = Math.max(box[3], skinBB[3]);
				// z
				box[4] = Math.min(box[4], skinBB[4]);
				box[5] = Math.max(box[5], skinBB[5]);
			}
		}
		return box;
	}
Edited by aeroxr1

Share this post


Link to post
Share on other sites

It looks like your positive z axis goes into the screen, so you will need to negate cameraDistance when you set the camera position instead of subtracting 100.

Share this post


Link to post
Share on other sites

If I set negative cameraDistance without subtracting 100 in this way :

camera.setPosition(0,-box_h/2,-(float)cameraDistance);

I see the back of the model, and it still remains too zoomed like in attached figure :(

Share this post


Link to post
Share on other sites

What are the values of box_h and fovy?  What is the world position of the model, and which part of the model is at that location?

Share this post


Link to post
Share on other sites

What are the values of box_h and fovy?  What is the world position of the model, and which part of the model is at that location?

 

fovy is calculated automatically from the 3d engine depending from fovx. But I can get the value of fovy with this function : 

float fovy=camera.getYFOV();

My model is in position : 0,0,0

 

Today I will give you the accurate values biggrin.png

 

edit :

fov_y = -1

box_h= 69,6417

 

Moreover the author of jpct answer me:
"I'm not sure...might be caused by the near clipping plane. Maybe your calculation assumes it to be a z=0 but it's actually at z=1 by default" 

Edited by aeroxr1

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!