Keep object in camera view

Started by
31 comments, last by davejones 5 years, 8 months ago

From the code you posted, it looks like the camera can track forward and backward and side to side (always parallel with the ground plane), but not up and down. For rotation, it looks like it can rotate side to side and up and down, but not roll.

Is that correct?

Advertisement
51 minutes ago, Zakwayda said:

From the code you posted, it looks like the camera can track forward and backward and side to side (always parallel with the ground plane), but not up and down. For rotation, it looks like it can rotate side to side and up and down, but not roll.

Is that correct?

I believe so yes. Its a script I am using from an asset I have purchased so if I am wrong I do apologise, but from the testing I have done your analysis appears to be correct. 

Here's a couple more questions (some more information about the desired behavior might make it easier to help).

It seems clear from the video you posted that you want tracking to be restricted so that the target object remains visible. What about yaw and pitch? If the camera rotates so that the object goes out of view, is that ok? Or do you want to disallow that?

Also, does the camera actually orbit, or does it just rotate in place? (I see reference to orbiting in the code, but the code looks like it just rotates in place.)

12 hours ago, Zakwayda said:

Here's a couple more questions (some more information about the desired behavior might make it easier to help).

It seems clear from the video you posted that you want tracking to be restricted so that the target object remains visible. What about yaw and pitch? If the camera rotates so that the object goes out of view, is that ok? Or do you want to disallow that?

Also, does the camera actually orbit, or does it just rotate in place? (I see reference to orbiting in the code, but the code looks like it just rotates in place.)

I want the camera to be restricted in terms of the area it can move around in. The video I posted shows how I would want tracking to behave. So yes I do wan't the tracking to be restricted. This is so that the camera isn't able to track an infinite distance away from the target object. In terms of yaw and pitch it is possible to yaw and pitch out of sight of the target. This isn't much of an issue. My goal is to keep the camera bounded within a certain area for pitch, roll and yaw. 

I'll admit I'm still not quite clear as to what you're after. You say you want to restrict the camera's position (and the video you posted seems to demonstrate clearly what you want), but you also say you want to restrict pitch, roll, and yaw, which are rotational parameters. Also, as far as I can tell at least, your camera doesn't roll.

In any case, although I haven't implemented this myself, here's what I'd probably try first.

I'd ignore pitch and make it a 2D problem, projected onto the ground plane (xz in this case, if I'm not mistaken). Project the point you want to keep in view onto the ground plane by replacing the original y value with 0. Then, using the field of view (I'm assuming perspective projection here) and the minimum and maximum distances from the object you want to allow, create a trapezoid in the ground plane. This trapezoid represents the current valid view area for the camera with respect to the object.

If the object is already in the trapezoid, you're good. Otherwise, compute the closest point on the trapezoid to the object position, and move the camera by the vector from the closest point to the object position. This should result in the object now being in view.

Maybe there's a simpler solution, but that's the simplest thing I can think of right now.

9 minutes ago, Zakwayda said:

I'll admit I'm still not quite clear as to what you're after. You say you want to restrict the camera's position (and the video you posted seems to demonstrate clearly what you want), but you also say you want to restrict pitch, roll, and yaw, which are rotational parameters. Also, as far as I can tell at least, your camera doesn't roll.

In any case, although I haven't implemented this myself, here's what I'd probably try first.

I'd ignore pitch and make it a 2D problem, projected onto the ground plane (xz in this case, if I'm not mistaken). Project the point you want to keep in view onto the ground plane by replacing the original y value with 0. Then, using the field of view (I'm assuming perspective projection here) and the minimum and maximum distances from the object you want to allow, create a trapezoid in the ground plane. This trapezoid represents the current valid view area for the camera with respect to the object.

If the object is already in the trapezoid, you're good. Otherwise, compute the closest point on the trapezoid to the object position, and move the camera by the vector from the closest point to the object position. This should result in the object now being in view.

Maybe there's a simpler solution, but that's the simplest thing I can think of right now.

In my own head I truly think its a simple solution, I'm just unable to implement what I want. In a nutshell I want the camera to be bounded within a specific area of the scene. This would be in 3D not 2D. 

I think that's the most straightforward solution I can think of at the moment.

I will clarify though that what I suggested is in fact a 3D solution. It's expressed in 2D because that seems to be sufficient for the problem as you've described it (that is, camera only moves parallel to the ground plane, camera only pitches and yaws, pitch is constrained, etc.). So the solution is a 3D solution, but it reduces to a 2D problem (which is actually good, since it makes it easier to implement).

Someone has to say it, and I apologise in advance as this will probably come across as overly critical, sorry I'm not very politically correct (we don't know your age / education / whether English is your first language / whether you have learning difficulties) : a lot of the confusion we are having is because a lot of your sentences don't make grammatical sense in English.

I have spent a bit of time trying to work out the meaning behind them...

Quote

I want the camera to be kept within a certain area in 3D space so that when its it can't infinity move out of view of the target object. 

This sentence doesn't parse in English.

Quote

 In terms of yaw and pitch it is possible to yaw and pitch out of sight of the target. This isn't much of an issue. My goal is to keep the camera bounded within a certain area for pitch, roll and yaw. 

This also makes no sense. Camera (location?) bounds have nothing to do with pitch, roll and yaw, which are rotations. I'm guessing what you are trying to say would be this (but I can't be sure):

In terms of camera yaw and pitch it is possible to move the viewpoint so that the target is no longer in view. This isn't much of an issue. My goal is to keep a certain area in view of the camera, rather than a particular target. 

However this seems to conflict with what you are asking here:

Quote

The camera is being used to rotate, pan and zoom in/around an object. At the moment I can move out of sight of the object. Is there a way to block the camera from going out of sight of the object?

Is the object doing the seeing, or the camera? Cameras are used to provide a viewpoint for rendering, so if anything sees, it is the camera, and not the object being viewed (unless of course you are talking about an AI object that does actually see?).

Quote

In a nutshell I want the camera to be bounded within a specific area of the scene. This would be in 3D not 2D. 

This parses but it is ambiguous, you want the camera location to be bounded or the view seen from the camera?

Programming in general, and the description of algorithms requires you to be very specific in your language. In natural language we get away with a certain amount of ambiguity, as the meaning can often be inferred from the context. But here when you use the word 'camera' you should specify what property of the camera you are referring to.

Also another part of the problem is perhaps unfamiliarity with the terms involved in 3D. This is understandable.

At a very basic level objects in 3D have a:

  • Location
  • Rotation (sometimes referred to as orientation) - this is often managed as either a Quaternion, Axis Angle, or Euler angles (yaw, pitch roll)

A camera has a location and a rotation, and in addition extra properties such as field of view and aspect ratio. All of these interact to determine what is seen by the camera, the view. So when you refer to a camera or object, you should be specific about which properties you are referring to. If you are unsure of a term, it usually only takes a quick search on wikipedia or similar.

In addition to keeping your sentences simple and specific, drawing diagrams may be useful as these are often helpful to convey ideas in 3D. Asking questions and conveying concepts about 3d graphics is not an easy thing to do, even for those who are very familiar with the subject, so please do not take this too harshly, more as practical advice.

As it is, you seem to be asking how to keep an object in view of the camera, but you don't mind if the object leaves the view of the camera.

36 minutes ago, lawnjelly said:

Someone has to say it, and I apologise in advance as this will probably come across as overly critical, sorry I'm not very politically correct (we don't know your age / education / whether English is your first language / whether you have learning difficulties) : a lot of the confusion we are having is because a lot of your sentences don't make grammatical sense in English.

I have spent a bit of time trying to work out the meaning behind them...

This sentence doesn't parse in English.

This also makes no sense. Camera (location?) bounds have nothing to do with pitch, roll and yaw, which are rotations. I'm guessing what you are trying to say would be this (but I can't be sure):

In terms of camera yaw and pitch it is possible to move the viewpoint so that the target is no longer in view. This isn't much of an issue. My goal is to keep a certain area in view of the camera, rather than a particular target. 

However this seems to conflict with what you are asking here:

Is the object doing the seeing, or the camera? Cameras are used to provide a viewpoint for rendering, so if anything sees, it is the camera, and not the object being viewed (unless of course you are talking about an AI object that does actually see?).

This parses but it is ambiguous, you want the camera location to be bounded or the view seen from the camera?

Programming in general, and the description of algorithms requires you to be very specific in your language. In natural language we get away with a certain amount of ambiguity, as the meaning can often be inferred from the context. But here when you use the word 'camera' you should specify what property of the camera you are referring to.

Also another part of the problem is perhaps unfamiliarity with the terms involved in 3D. This is understandable.

At a very basic level objects in 3D have a:

  • Location
  • Rotation (sometimes referred to as orientation) - this is often managed as either a Quaternion, Axis Angle, or Euler angles (yaw, pitch roll)

A camera has a location and a rotation, and in addition extra properties such as field of view and aspect ratio. All of these interact to determine what is seen by the camera, the view. So when you refer to a camera or object, you should be specific about which properties you are referring to. If you are unsure of a term, it usually only takes a quick search on wikipedia or similar.

In addition to keeping your sentences simple and specific, drawing diagrams may be useful as these are often helpful to convey ideas in 3D. Asking questions and conveying concepts about 3d graphics is not an easy thing to do, even for those who are very familiar with the subject, so please do not take this too harshly, more as practical advice.

As it is, you seem to be asking how to keep an object in view of the camera, but you don't mind if the object leaves the view of the camera.

Thank you for your detailed comment. Going forward with what you have said, I will try to clarify what it is I am trying to achieve.

- I have a 3D mesh in a scene.

- I  want to be able to track side to side and up/down with the 3D mesh as a reference point. I also want to rotate around the 3D mesh. 

- The 3D mesh would be the centre point about which rotation occurs 

- I want to be able to zoom in/out of the mesh

- I don't want to be able to infinitely track + or - in the x-axis

- I don't want to be able to infinitely move + or - in the Y-axis 

- The maximum zoom distance from the 3D mesh has to be finite. 

 

All of these inputs are to be usable with finger (touch inputs) and also using a computer mouse. I want the inputs to be finite so that the user can't get lost at a random part of the scene. The 3D mesh is in an area and that area needs to be "caged" (bounded, blocked) from getting out of that area. This is so that the user doesn't get lost. 

 

I apologise for any confusion caused and I do hope you can understand. I'd be open to any opinions/suggestions. 

Firstly well done for not getting wound up by my rant, major plus points, it shows considerable strength of character, most people are hugely overly sensitive to criticism. :)

Secondly that description is far easier for us to understand. Out of interest what are the objects going to be in the area? Are they planets, and are they going to be moving?

Using a reference point for the camera target sounds sensible, I'm now thinking of it as a follow cam, kind of like a third person camera.

The kind of things I'd be thinking of storing to calculate my camera would be:

  • Target position (vector3)
  • Zoom (camera distance from target)
  • Yaw (defined relative to target)
  • Pitch (defined relative to target)

This is all made much easier because there exists a unity function for rotating a camera to face a particular location:

Quaternion.LookRotation

This takes a look direction and a reference up direction.

So what you need to do is

  1. Calculate the camera position
  2. Calculate the vector from the camera to the target (ptTarget - ptCamera)
  3. Use the Quaternion.LookRotation to return a quaternion which you can set as the camera rotation

The most interesting bit is calculating the camera location based on the information I stored earlier. There's a few ways of doing this but here is one:

  1. You can do this by starting with a unit vector (vector of length 1) pointing out along your 'default' ground axis (where yaw = 0). This all depends how you define your map, I forget how unity does its axes, I usually use xy for ground and z is up.
  2. But essentially you can rotate your unit vector up by the pitch (there will be unity functions for rotating vectors along x, y and z), THEN rotate this result vector using the yaw.
  3. This gives you the direction to the camera. You now need to scale this vector by the distance to the camera (zoom). You can do this simply by multiplying the unit vector (it should still be length 1) by the distance to the camera. If for some reason your direction might not be length 1, you can use the Normalize function to change the length to 1 while keeping the same direction.
  4. So the camera location will be the target location PLUS this vector to the camera.

Set the translate of the camera to this location, set the rotate to the quaternion given by Quaternion.LookRotation, and you are in business.

There are other ways of doing things too, you can zoom by changing the field of view of the camera instead of modifying the distance. This can give a 'Hitchcock dolly zoom' effect if you modify it with distance at the same time.

Note this is assuming a perspective camera. If you want to use orthographic, the distance of the camera from the target doesn't matter, just the orthographic scale you use to determine the camera matrix.

Constraining the camera zoom can be done by capping the min / max distance. And constraining the target point is easy too, just do something like


if (x > x_max) x = x_max;
if (x < -x_max) x = -x_max;

for each axis, to get a bounding box, or for a sphere:


vector3 ptOffset = ptTarget - ptWorldCentre;
float dist =  ptOffset.Normalize(); // returns length

if (dist > max_dist)
{
	ptOffset *= max_dist;
	ptTarget = ptWorldCentre + ptOffset;
}

That's most of it, there's also determine which direction to move the target point when you track the view, but I'll leave that for the others to cover, too tired tonight! :)

This topic is closed to new replies.

Advertisement