Best camera integration with SceneInterface?

rated by 0 users
This post has 7 Replies | 4 Followers

Top 10 Contributor
Posts 1,104
SunBurn_Community_Licensee
SunBurn_Contributor
SunBurn_Pro_Licensee
Philippe Da Silva Posted: 02-12-2010 10:00 AM

Hi,

I'm currently evaluating more seriously SunBurn for a professional prototype I am working on and I am actually working on a quick & not so dirty game engine using SunBurn for the rendering stuff.

I would like to avoid making bad design decisions and would appreciate your help on a small question I have about Cameras.

Generally, I implement and manage my cameras as an entity or node of my Scene graph because I therefore apply all my world transformations for my whole scene tree either it is a camera or a mesh and that worked perfectly this far.

However, with SunBurn I have to think twice on the implementation.

It seems that I can either:

  • Use a set of Matrixes attached to my Game instance and change their properties with some Camera Helper class.
  • Use a GameComponent inherited Camera and attach the View, Projection and World properties to the SceneState during update or draw calls

But I couldn't see a good way to implement my cameras as a SceneObject because I don't have access to the World setter property where I would generally place my 'setDirtyCamera' events to refresh my View and Projection matrixes.

What would you recommend on a technical design point of view to implement Camera management?

Thanks,

Philippe

Top 10 Contributor
Posts 1,104
SunBurn_Community_Licensee
SunBurn_Contributor
SunBurn_Pro_Licensee
Top 25 Contributor
Posts 136
SunBurn_Community_Licensee
SunBurn_Contributor

Since the camera tends to move and behave differently from other scene objects (chasing, rotating with quaternions, spring camera, etc.) and yet needs to know information about the scene, I'd advise against the GameComponent idea. Going that route will mean you're either passing data back and forth each draw frame or exposing methods across game components to be called and it will be difficult to control when the camera states are set for rendering to a rendertarget for reflection maps, etc.

It really depends on your engine requirements though. If you only have one main camera and would rather set the view-proj-world manually on the special cases, then the GameComponent could definitely work well.

Hope that helps!

Top 10 Contributor
Posts 1,104
SunBurn_Community_Licensee
SunBurn_Contributor
SunBurn_Pro_Licensee

Thanks, I'm right now trying to implement a CameraManager GameComponent that will have a CurrentCamera property that I'll use for my rendering.

I'm thinking also on adding a ICameraOwner interface to my SceneObject instances so that a SceneObject can change the active camera set on the CameraManager when rendering. Not sure it will be effective but I can not see another way to use a Camera within 1.3 ;)

Top 10 Contributor
Posts 699
SunBurn_Community_Licensee
SunBurn_Contributor

You should use Services. They are very useful when you need to grab data from strange places. Small snippet of what it looks like in my own implementation:

            Camera camera = Engine.Services.GetService<Camera>();

            camera.Position = new Vector3(0, 20, 50);

With 'Engine' as a static class, 'Services' as IEServiceProvider (A class from InnovativeGames.net)

http://www.innovativegames.net/blog/2008/10/11/engine-tutorial-2/

MSDN resource that might help out if you're not using your own engine but instead us the 'Game' class.

http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.game.services.aspx

My camera class is not a SceneObject nor GameComponent. It's derived from 'Component' (more on that can be found on topmost url) and its view/projection/position is updated every frame by the game. Hopefully you can put this to any use... :)

Contributor on the SunBurn sgMotion Animation Library open source project.

Top 10 Contributor
Posts 4,546
Employee
SunBurn_Studio_Licensee

The ideas in this thread sound great, I just wanted to add an additional option.

The new manager / service architecture in SunBurn 1.3 allows you to replace any SunBurn manager with your own - it also allows you to create your own new managers.  If your camera system is fairly complex (using multiple cameras, with objects or the ui being able to toggle cameras at any time) it might be worth creating a camera manager.

We did something similar with the GameFest demo, though we only used simple orbiting cameras in the Reflection / Refraction scene, and a first-person camera in all other scenes.

Our camera manager class looked something like this:


    public class CameraManager : IManagerService
    {
        // type used to request this manager from the SceneInterface...
        public Type ManagerType { get { return typeof(CameraManager); } }
        // order the manager is process in relative to other managers...
        public int ManagerProcessOrder { get { return _ManagerProcessOrder; } set { _ManagerProcessOrder = value; } }
        private int _ManagerProcessOrder = 100;

        // current active camera....
        public ICamera CurrentCamera { get; }

        // add cameras to the manager...
        public void SubmitCamera(ICamera camera);

        // required by
IManager....
        public void ApplyPreferences(ILightingSystemPreferences preferences);
        public void Clear();
        public void Unload();
    }


The camera manager was then added to the SceneInterface after calling CreateDefaultManagers:


            sceneInterface = new SceneInterface(graphics);
            sceneInterface.CreateDefaultManagers(false, true, false);

            cameraManager = new CameraManager();
            sceneInterface.AddManager(cameraManager);


And could be retrieved by any code with access to the SceneInterface using:


           
CameraManager cameramanager = sceneInterface.GetManager<CameraManager>(true);


In our case the UI would cycle through the cameras using Next() / Previous() on the manager, but your custom code could find / set cameras by name, reference, or using any custom technique you like.

Finally the active camera was used to set the scene view matrix:


           
CameraManager cameramanager = sceneInterface.GetManager<CameraManager>(true);
            sceneState.BeginFrameRendering(
cameramanager.CurrentCamera.View, projection, gameTime, environment);


Let me know if this helps!

Follow me on Twitter – development and personal tweets
Awesome XNA Videos – Lighting, Rendering, and game videos

Top 10 Contributor
Posts 1,104
SunBurn_Community_Licensee
SunBurn_Contributor
SunBurn_Pro_Licensee

In your code, you seem to use at the end a local projection instead of a property attached to the camera instance. Any good reason for not doing so?

Top 10 Contributor
Posts 4,546
Employee
SunBurn_Studio_Licensee

Hi Philippe,

You can use whichever best fits your project.  I believe we used an app-level projection to decouple the cameras from the GraphicsDevice (the aspect ratio is required for the projection) and also because all of the cameras use a 70 degree fov.

If you want to implement camera dependent fovs then moving the projection to the camera-level would be best.

Let me know if this helps!

Follow me on Twitter – development and personal tweets
Awesome XNA Videos – Lighting, Rendering, and game videos

Page 1 of 1 (8 items) | RSS