Camera Integration

Started by
15 comments, last by Shael 14 years, 2 months ago
This has probably been asked before but I couldn't find anything in my search. But anyway, right now I have a pretty general camera class which can be inserted into a scene graph along with other game objects. But I have a few questions as to where do go next in the design: 1. How are cameras usually integrated/managed in a game engine? 2. How do they link with a player class, or other game objects? 3. How is input handled in regards to player control and camera movement? For example, does the camera listen for input then pass this onto its children (player, etc), or does the player listen and pass it to the camera, or is this the wrong way about it? I plan to have all kinds of camera types. Eg. FPS, RPG, RTS, and also cameras for shadow maps, and others that render to render-targets (eg. security cameras). So I'm looking for a way that I can manage all this easily. Look forward to your input :)
Advertisement
In my engine written in C, I have a camera structure that contains an up vector, x,y, and z rotations in degrees, the position of the camera, and where the camera is looking. A function rotates the camera's focal point to look ahead based on the rotations, as to allow the application to rotate the camera, or directly change where it is looking. After that, I have a function set up similar to gluLookAt(), which multiplies onto my projection and modelview matrices in my software renderer. Not sure what API you are using to render, but that is how I do it. Forgive me if I misunderstood anything.
That's not really what I was looking for. I know how to setup a camera and move it around. My question is what controls the cameras, and how is user input handled in terms of a player class and a camera. Does the player take input and then pass it to a camera, or does a camera take input and pass that onto the player to update its movement, or is there something better than both of those ways?
Really depends on the API. On something like OpenGL, that uses something like a Modelview matrix, you would pass the data to the camera, then use the camera data with the API, and draw the player like normal. On other APIs with a static "camera", you might pass data to the camera, and then from the camera to each object in the scene. Some might integrate a camera into the API, but how my OpenGL and software renderer handle the camera is that the camera is no more than a structure of data, of which is supplied in appropriate ways to the API. A quick for-instance. Say you have a camera which corresponds to the player's first person viewpoint. In an API like OpenGL or mine, you would handle input, which would change the camera's variables if called for. The scene is then drawn, as the API transforms the vertices with the camera's information supplied through API calls. Other, more static, APIs would have you poll for input, change the camera's variables, and say you rotate the camera by 90 degrees. You would then rotate every object in the scene yourself by 90 degrees, the value stored in the camera class/struct. Both ways, each object is transformed with the camera's data; the difference is how the graphics pipeline is implemented, and whether the API or the application itself handles transformations.
Quote:Original post by Ectara
Really depends on the API. On something like OpenGL, that uses something like a Modelview matrix, you would pass the data to the camera, then use the camera data with the API, and draw the player like normal. On other APIs with a static "camera", you might pass data to the camera, and then from the camera to each object in the scene. Some might integrate a camera into the API, but how my OpenGL and software renderer handle the camera is that the camera is no more than a structure of data, of which is supplied in appropriate ways to the API. A quick for-instance. Say you have a camera which corresponds to the player's first person viewpoint. In an API like OpenGL or mine, you would handle input, which would change the camera's variables if called for. The scene is then drawn, as the API transforms the vertices with the camera's information supplied through API calls. Other, more static, APIs would have you poll for input, change the camera's variables, and say you rotate the camera by 90 degrees. You would then rotate every object in the scene yourself by 90 degrees, the value stored in the camera class/struct. Both ways, each object is transformed with the camera's data; the difference is how the graphics pipeline is implemented, and whether the API or the application itself handles transformations.
I'm not entirely sure that's what the OP is asking about (I could be wrong though).

@The OP: Although I don't think there's any one 'correct' solution to the problem you mention, my own feeling is that a camera object should not be concerned with user input, or with control schemes in general. Instead, cameras should be *attached* to objects that implement these behaviors.

If you think of a game or other real-time simulation in terms of the model-view-controller pattern, a camera object would fall squarely into the 'view' category, and would neither influence the model directly, nor interact directly with user input.

For my own projects I use a component-based system (which is fairly common these days, I think), in which a camera is simply a component attached to an entity. It doesn't know anything about user input, control schemes, or anything like that. If I want a first-person camera, I attach a camera to the entity whose point of view I want to represent. If I want a third-person camera, I attach a camera to an entity that implements some sort of 'follow another entity' behavior. If I want a 'security camera' or something of that sort, I attach a camera to an entity that is stationary, or perhaps pans back and forth periodically over a designated area.

In each case, the fact that there's a camera attached to the object is somewhat incidental. If you removed the camera component, the entity would keep doing what it was doing previously; it doesn't care (or even know, necessarily) that there's a camera attached to it.

The camera component itself deals only with strictly camera-related concerns, such as clearing the frame buffer, setting up viewport, projection, and view transforms, culling objects to its view frustum, and so on.

Anyway, that's just my take on it. As I said earlier, there's really no one 'right' way to do it, so it really just comes down to the specific needs of your application and your own personal preferences.
If it isn't, my apologies. I seem to be misunderstanding.
Sorry I thought I was pretty clear on my explaination, but I guess not.

jyk: That is the sort of answer I was looking for :)

Going with the approach that a camera is attached to entities, and you say the entities should continue to function as they would without a camera attached, because they don't know about it. How does the camera behavior change if the entity it's attached to doesn't know about it?

Eg. What actually sends commands to the camera to "RotatePitch" or "MoveForward" etc? Does the entity the camera is attached to control the camera behavior?

Also, in terms of a scene-graph would the camera be a child of entity node? or something else?

I'm just trying to tie all systems together nicely. Any design ideas are very welcome :)
Quote:Going with the approach that a camera is attached to entities, and you say the entities should continue to function as they would without a camera attached, because they don't know about it. How does the camera behavior change if the entity it's attached to doesn't know about it?

Eg. What actually sends commands to the camera to "RotatePitch" or "MoveForward" etc? Does the entity the camera is attached to control the camera behavior?
In my component system (which is similar to the system used by Unity, and I believe is fairly typical overall), each entity has a 'transform' component that all the other components associated with the entity can access. The camera component's access to the transform is read-only; it doesn't need to modify it, it just needs to know what it is. Other components, such as physics, AI, or player control components, do modify the transform.

So in other words, the camera doesn't need its own 'rotate' or 'move' functions because it shares a transform with other components that do the rotating and moving - does that make sense? That's why you can remove the camera component without affecting the behavior of the entity; since the camera component's relationship with the other components is 'read-only', removing the camera component has no effect on the entity or on any of the other components.

Note that you can apply the idea of cameras being attached to entities whether or not you're using a component-based system; I'm just describing it in those terms because that's how my own system is set up.
Quote:Also, in terms of a scene-graph would the camera be a child of entity node? or something else?
The scene graph for my game is very simple, so I can't really comment in detail on that aspect of things. I will say though that I don't think the relationship between nodes in the scene graph necessarily needs to exactly mirror the relationships between entities or between entities and components. In fact, my scene graph (such as it may be), doesn't know anything about entities; it just knows about 'renderable' components.
Sounds like a pretty flexible approach. So in your system for a Player entity you might have a layout such as:

PlayerEntity
- FPSMovement
- Camera

Meaning that the Camera and FPSMovement components attach to the PlayerEntity. This would then mean that FPSMovement takes input from somewhere and uses it to change the player transform? And the Camera just reads the transform and uses it to display the view?

If I'm wrong about the input, how do you handle it? and for more complex systems how do the components communicate with each other?

Thanks for your time!
Quote:Sounds like a pretty flexible approach. So in your system for a Player entity you might have a layout such as:

PlayerEntity
- FPSMovement
- Camera

Meaning that the Camera and FPSMovement components attach to the PlayerEntity. This would then mean that FPSMovement takes input from somewhere and uses it to change the player transform? And the Camera just reads the transform and uses it to display the view?
You got it :)
Quote:and for more complex systems how do the components communicate with each other?
There are multiple approaches to the problem of inter- and intra-entity communication, and there have been some pretty in-depth discussions on the topic here in the past. (I don't have any thread links handy, but a search for 'messaging system' or 'component system' should turn up some of these threads.)

For intra-entity communication (i.e. communication between components in the same entity), the components just store references to each other. When the entity is first added to the simulation, each component gets an opportunity to run an 'on start' function to do any initial setup it needs to do. Each component holds a reference to the parent entity, and through this reference they can request references to other components, e.g.:
transform = parent_entity->get_component<Transform>();
It's not an 'ideal' system in terms of software design (it involves polymorphic downcasts, for one thing), but I think it's fairly standard for an 'entity as collection of components' component system, and I've found it to work very well from a practical point of view.

Communication between entities is a different issue. I used to have a messaging system in place that allowed for sending messages and registering 'listeners' for specific types of messages, but it wasn't particularly well designed. Since then I've moved most of the game logic to Lua, which so far at least has completely obviated the need for any kind of inter-entity messaging system on the C++ side.

This topic is closed to new replies.

Advertisement