Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411283 Posts in 69325 Topics- by 58380 Members - Latest Member: bob1029

March 29, 2024, 01:37:56 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Fitting a camera to a bounds
Pages: [1]
Print
Author Topic: Fitting a camera to a bounds  (Read 1611 times)
cow_trix
Level 0
***

Meat Popsicle


View Profile WWW
« on: March 28, 2017, 05:26:14 PM »

So I've been working on a problem for the past couple of days and I'm still not happy with my solution, so I was wondering if anyone out there has any ideas on how to solve it.

Basically, given some worldspace bounds and a camera, move the camera so that it both retains its original angle and best fits the bounds within it's frustum. You can see a simple diagram of the desired result below.



Performance is a key concern as this will be done many times per frame. Because of this, iterative solutions either need to be extremely cheap or limited in iterations. I've implemented a few solutions, but they tend to fail when a bounds is not very cubic and is thus distorted a lot by the camera's perspective at certain angles. In this situations, an important thing to think about is that the center of the bounds in worldspace is not where we want to center the camera.

Has anyone solved this before? Got a good solution for me?
Logged

I make games and you should play them.

Dritch - Voxel SciFi Adventure | voxul - Unity Voxel Framework
qMopey
Level 6
*


View Profile WWW
« Reply #1 on: March 28, 2017, 09:02:08 PM »

Since camera is fixed angle, pretty sure you can do line segment vs line segment intersection test to find the point of the camera. Fix each lines onto AABB min/max, where min and max are defined as min( dot( camera.side, aabb.vert ) ) and similar max.
Logged
AlexRamallo
Level 1
*


:0


View Profile WWW
« Reply #2 on: March 28, 2017, 09:15:39 PM »

I'm a bit confused by your description of the problem. What are you trying to accomplish here? A camera system that will always keep the game within view and at the edges of the screen? Because there are better ways to approach this problem than what you've described (unless I misunderstood).

You could just use a `lookat` type function to have the camera point to the center of the bounds at all times, while `orbiting` the camera around the bounds. Then all you have to do to keep it perfectly aligned with the frustum is calculate the zoom distance (or change the frustum itself).

One simple way I can think to calculate it would be to calculate the angle of the vectors from the camera to all the individual points of the bounds, then using the two with the most extreme angles, calculate the difference in the angle between those two and the camera's frustum. With that distance you can adjust the zoom (or the frustum).


This is of course assuming the `orbit` control scheme works for whatever you're trying to do.
Logged

cow_trix
Level 0
***

Meat Popsicle


View Profile WWW
« Reply #3 on: March 28, 2017, 09:23:54 PM »

Since camera is fixed angle, pretty sure you can do line segment vs line segment intersection test to find the point of the camera. Fix each lines onto AABB min/max, where min and max are defined as min( dot( camera.side, aabb.vert ) ) and similar max.

I can sort of see where you're going with that, but I don't think it would work. Would you maybe be able to explain more what you mean?

I'm a bit confused by your description of the problem. What are you trying to accomplish here? A camera system that will always keep the game within view and at the edges of the screen? Because there are better ways to approach this problem than what you've described (unless I misunderstood).

It's for an icon rendering system to spit out little renders of meshes.

You could just use a `lookat` type function to have the camera point to the center of the bounds at all times, while `orbiting` the camera around the bounds. Then all you have to do to keep it perfectly aligned with the frustum is calculate the zoom distance (or change the frustum itself).

One simple way I can think to calculate it would be to calculate the angle of the vectors from the camera to all the individual points of the bounds, then using the two with the most extreme angles, calculate the difference in the angle between those two and the camera's frustum. With that distance you can adjust the zoom (or the frustum).


This is of course assuming the `orbit` control scheme works for whatever you're trying to do.

Both the FoV and angle of the camera are fixed - the solution must be translation of the camera object.
Logged

I make games and you should play them.

Dritch - Voxel SciFi Adventure | voxul - Unity Voxel Framework
qMopey
Level 6
*


View Profile WWW
« Reply #4 on: March 28, 2017, 09:48:19 PM »

Of course it would work  Cool

Take the camera side vector. Then find the vertices on the AABB that are farthest in the direction of the positive side vector, and negative side vector. Then form two lines, one passes through each of these verts we just found, and both pass through the desired camera position. Find the line intersection point, and place the camera here.
Logged
bateleur
Level 10
*****



View Profile
« Reply #5 on: March 28, 2017, 11:32:52 PM »

It's for an icon rendering system to spit out little renders of meshes.

Unless there are literally thousands, I'd give them a camera each.

The reason is performance. A thousand cameras doesn't actually take a ridiculous amount of memory, but moving one camera a thousand times involves changing its transform each time and that's actually a fairly expensive operation (because Unity does a lot of automatic work behind the scenes every time you do it).
Logged

cow_trix
Level 0
***

Meat Popsicle


View Profile WWW
« Reply #6 on: March 29, 2017, 03:25:55 PM »

It's for an icon rendering system to spit out little renders of meshes.

Unless there are literally thousands, I'd give them a camera each.

The reason is performance. A thousand cameras doesn't actually take a ridiculous amount of memory, but moving one camera a thousand times involves changing its transform each time and that's actually a fairly expensive operation (because Unity does a lot of automatic work behind the scenes every time you do it).


Having tested both, there isn't a significant performance difference in this particular case, but thanks!

Of course it would work  Cool

Take the camera side vector. Then find the vertices on the AABB that are farthest in the direction of the positive side vector, and negative side vector. Then form two lines, one passes through each of these verts we just found, and both pass through the desired camera position. Find the line intersection point, and place the camera here.

I think I get ya, but it's forming the two lines correctly that is the difficult part. What does the math behind that look like? I've made a diagram to show what I'm thinking here.



By finding these two points, we're pretty much forming an ellipse by creating these two focal points (or actually an ellipsoid, but then what's the 3rd focal point? Max Y?). Anywhere on this ellipse, we can form two line meeting at 2*FoV, I think? So we need to find the point on this ellipsoid with a normal that matches the desired angle of the camera. I'm pretttty uncertain how to do that. Thoughts?
Logged

I make games and you should play them.

Dritch - Voxel SciFi Adventure | voxul - Unity Voxel Framework
Cheesegrater
Level 1
*



View Profile
« Reply #7 on: March 29, 2017, 07:47:27 PM »

You should be able to find the angle between your lookat direction and one of the sides of the box. (definition of dot product for one easy way). Lets use the bottom side in your diagram and we'll call it angle A.

Then the angle between the box and your camera about vmin is Pi - theta - A.

A point and an angle is enough to define a line, so do the same at the other vertex and you can then proceed with an intersection test.

Doing this in 3D complicates the calculations slightly, but the idea is the same.
Logged
qMopey
Level 6
*


View Profile WWW
« Reply #8 on: March 29, 2017, 11:48:08 PM »

It's easier than that.

The camera direction is already known, so just take the camera's frustum lines (the left and the right directions), and center each onto the AABB verts. Done.

As for the ellipsoid stuff, it doesn't seem necessary.

Edit:

A little more math, as requested  Waaagh!

Line can be defined as: p + d * t. p is point, d is a vector, t is a scalar. Since camera angle is fixed, the direction of all vectors regarding the camera are fixed. The forward vector is fixed, the side vector is fixed, and the frustum vectors are fixed. In this way, the lines of the camera frustum have constant d terms.

To define the lines to lay upon the AABB vertices, we say that p is a vert of the AABB.

Now p and d are known, solve for t. t represents how far along in the direction of d, starting at point p, the intersection point resides.

Solving for t is done by solving for the intersection of the two lines. I'm sure you can figure this part out.
« Last Edit: March 29, 2017, 11:59:17 PM by qMopey » Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic