position camera for object to fit in screen height

Started by
6 comments, last by aeroxr1 9 years, 6 months ago
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 :)
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.


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.

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;
	}

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.

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 :(

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?

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"

This topic is closed to new replies.

Advertisement