Thoughts on Cameras for Nine

Sep 26, 2011 at 6:04 AM

Currently there are several: FreeCamera, Quaternioncamera, Screencamera, ModelViewerCamera. Some have input and are tightly bound to it.

It seems to me a camera should:

  • be a component, so it gets Update()
  • be a scene object, so it can be included in Scene.xml
  • be named, and accessible through a CameraManager or SceneManager
  • have a variety of ways to set/get its position, orientation, field of view, etc
  • conveniently handle concepts like which way is up, look at, track, dolly, zoom, etc
  • handle animation, as a transition from one state to another over time
  • handle input, as a command/continuous input to functions listed above.

I could imagine that the core camera is a passive class with lots of capabilities, and the camera animation and camera input classes could provide the component and scene object interfacing. Hopefully the animation/transition effects available for models and screens could be used for animating a camera. The camera input component still requires a wire-up as a separate configuration to determine which user input causes which camera action.

I could write most of it, but I have no idea how it would connect to the scene and animation components. Input is a separate topic.

Sep 26, 2011 at 6:42 AM
To interact with the SceneManager, the object must implement ISpatialQueryable to expose the bounding box.
For a camera, I think you should derive from Transformable so that we could attach the camera to a model bone in the future (Just like attaching lights, particles and models to another model).
Some implementation tricks:
- You can set the bounding box of the camera to be {min:Position, max:Position}, so that the size of the bounding box is zero but the scene manager can still get the camera position.
- When the position of the camera changes, don't forget to manually call the Transformable.OnBoundingBoxChanged explicitly.
- Make sure the position and facing of the camera changes according to the AbsoluteTransform property during OnTransformChanged.
For the naming issue, I'm going to provide a consistant way to name all objects. Two ways to achieve that, include a name property in a common base class (no such base class now), or add a new interface for it.
The animation system is a bit more complicated, as long as you are composing the animations in code, the existing animation classes can handle that just fine. The problem with it is that you cannot author animations in the content xml. But its on my to do list though.
Ideally you can add a lot of cameras to the scene, set their positions, bind them to objects. But there should be only 1 active camera (Or mutiple active cameras, with each one rendered to a certain area on the screen), and when you call something like SetCamera, there is a switch to control whether we should smooth the current view to the new camera.
Sep 26, 2011 at 2:36 PM

Yes, that makes sense. Thanks for the tips. Ideally those aspects of 'camera-ness' could be captured in a reusable component (/base class/service).

Re naming: the term 'fragile base class' comes to mind. Worth doing, but hopefully not too disruptive.

Re multiple cameras: absolutely. I think you need animation to produce cinematic effects, but it may be easiest to attach a camera to an entity and animate the entity, as a general purpose approach. Switching between cameras uses a transition (dissolve/fade/etc -- ask any Powerpoint user!)



Oct 3, 2011 at 3:50 AM

After spending some time wrestling with QuaternionCamera, I have some problems and currently no solutions.

The main primitive operations I think I would want are:

  1. move a distance along a vector (local or world coordinates)
  2. move a distance towards a point (world coordinates)
  3. rotate by an angle around a vector (local or world coordinates)
  4. rotate by an angle to look towards a point (world coordinates)
  5. optionally constrain the Up direction for all rotations (world coordinates)

From these primitives I think I can build every other type of camera, including orbit, follow, first person, spectator, pan/zoom, track/dolly etc and including smooth movements. Unfortunately my maths is letting me down, and the average quaternion tutorial is not much help, especially for local/world and constrained Up. Any suggestions or help appreciated. Happy to adapt/contribute any code.

Oct 5, 2011 at 10:58 AM
Edited Oct 5, 2011 at 10:59 AM

1. QuaternionCamera.MoveRelative/Move should allow you to move the camera towards a direction. You just need to call the Move/MoveRelative during each update.

2. Same as the above, use TargetPoint - QuaternionCamera.Position to get the direction to move.

3. Use Quaternion.Rotate(Axis, Angle).

4. Get the roll/yaw/pitch from the target point to the current camera position, then Quaternion.Roll/Yaw/Pitch.

5. QuaternionCamera currently uses relative rotations and does not enforce an Up axis.

Hope this helps and thanks Amer for contributing the QuaternionCamera code. I've also added you as a developer so feel free to contribute here and there.


Oct 6, 2011 at 12:46 AM

Yes, I agree that (1) and (2) are quite easy. The class doesn't quite do it, but the maths for that I can handle.

No, in (3) the class provides only world rotations. I think I've found the maths to do local rotations from another source.

In (4) I think the approach is to calculate a vector for the target point, derive a quaternion for the rotation, then interpolate the angle. [We want to swing around smoothly targeting a point over a period of time.]

It is (5) that is giving me the most difficulty. This camera starts up pointing at -Y. It seems to me that once you get it pointing at -Z with +Y as Up, then all you need is to rotate Y in world, X in local and no Z to make a first person camera. It isn't working out that way (yet).

I think the result should be a new QuaternionCamera with more API calls (and a couple of bug fixes). Sitting above that is a TrackingCamera which implements Update() so it can do tracking and targeting. On top of that is the CameraComponent which handles input, including key bindings. Different components and bindings give different camera styles. Should be interesting. I'll be happy to contribute it if I can get it all working.



Oct 6, 2011 at 8:32 AM


Let me see what i can do about your needs, probably we can provide more better camera support, yufeih i think you should make cameras more expandeable, now your using Z as Up vector, but maybe rest of Xna users uses Y as Up, maybe you can modify rest of camera to work even with Up vector (which by default is Z).