Camera

Oct 28, 2007 at 5:31 AM
Though we have a camera class SceneNode objects are rendered using passed view and world matrix, they should be rendered using a camera. Passing the camera also makes it easy to create multiple views for a scene. Simply create a camera and pass it to the render. This makes it easy to create rear view mirrors, or survailance camaras. Further each camera could be extended with special rendering options, like shaders, which could add interesting effects. Like noise on a camera feed.

Any comments/ideas?
Coordinator
Oct 28, 2007 at 5:43 AM
That is similar to what I was going for. The only problem is that I cannot find a way to pass the camera by reference because you cannot pass derived classes by reference unless you either create a different function for each camera type (that is not going to happen), or you have to check the camera type and then 'cast' it with that type within the function. If you don't pass the camera by reference then you're incurring quite a performance hit verse passing simply a matrix or two (both by reference of course).
All of the view options (like rear view, surveillance, etc...) should occur through the view and projection matrices just fine. However the specific shader effect would need to be passed or defined somehow, not only that but the effects may be different for different effects, that would need to be accounted for.
Oct 28, 2007 at 6:05 AM
I have to admit that passing by ref just for performance is dangerous on so many levels that I really do not want to think about it. A simple solution to this is not passing it at all and make it available on the root node or create a camera manager on the Game and use that.
Oct 28, 2007 at 6:12 AM
I'm not sure it makes much difference if its camera or matrices being passed around. The scene graph doesn't care what kind of post-processing shaders are enabled, nor does it care about viewports. These are all defined and implemented at a higher-level.

LordIkon, the reason you can't pass derived classes by reference is that its already being passed by reference. All classes are reference types, meaning they are automatically passed by reference. The 'ref' keyword only really applies to value types (structs and atomic types like int, float, etc.).
Oct 28, 2007 at 6:27 AM
What?!? I think I need my school money back. classes aren't passed by reference, at least not in C#. While it's correct that you can change the content of a class passed you can't actually change the reference to the class, that will simply just be discarded when leaving the method.

What I think you mean is that when passing a reference type it's the reference to the type that is passed, and not the type itself (or a copy thereof). This is much "cheaper" than passing a value type which passes a whole copy of the value type. Therefore there is a performance gain by passing value types by ref
Oct 28, 2007 at 6:38 AM
Exactly, you pass a "reference" to the class to the callee. That's what pass-by-reference is. The parameter passed to the callee is the address of the instance of the class.

I'm not understanding what you're trying to say the difference is...
Oct 28, 2007 at 6:43 AM
There is a major difference between passing a reference type and a refererence to a reference type, consider below:

    class A
    {
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            A a = new A();
            DoA(a);
            Console.WriteLine(a == null);
        }
 
        private static void DoA(A a)
        {
            a = null;
        }
    }
This will result in false, as a isn't null. But changing this to ref A will result in true. This is a very dangerous situation, which can lead to very complex debug scenarios. But it might be perfectally legal and expected solution in specific cases.
Coordinator
Oct 28, 2007 at 6:44 AM
I'm not understanding either of you :OP

But seriously, I believe Shaw is right on this one, refer to this link: http://blogs.msdn.com/joelpob/archive/2004/07/19/187709.aspx. Classes, as objects, are passed by reference.

I don't care what is passed as long as we pass as little as possibly, and only pass things are actually going to be needed. I haven't looked at the code enough to make an informed decision yet. Although you'd think by UMLing the code and going through every class line by line I would understand it more :oP. I'm blazing through it so fast I'm not picking up a whole lot. Although I am learning the structure a little bit.
Oct 28, 2007 at 6:57 AM
Oh, of course there's a difference between passing a class by reference and a reference by reference. I didn't know we had extended the discussion to references-to-references. :)

All I was saying was when you pass a class instance to a method call in C#, you are passing the reference, not a copy. This is in contrast to C++, where class instances are passed-by-copy by default.
Coordinator
Oct 28, 2007 at 7:03 AM


Sturm wrote:
This will result in false, as a isn't null. But changing this to ref A will result in true. This is a very dangerous situation, which can lead to very complex debug scenarios. But it might be perfectally legal and expected solution in specific cases.


Well, certain systems that will not be changed often (hopefully), like the physics system, should be as efficient as possible. Anything critical to performance will need all the optimization that it can get, like passing by reference. If it isn't going to have a noticable performance impact, or it has a good chance of causing an issue, then I would say not to worry about passing by reference.
Oct 28, 2007 at 7:10 AM
The primary problem with pass-by-reference is inadvertently changing data you're not supposed to be changing. Imagine a matrix being passed to two functions by reference. If the first function makes a change to the matrix but isn't supposed to, then the second function call will get the modified matrix and potential give a bad result.

Now, references-to-references is another, dangerous matter. It's essentially like a pointer to a pointer in C++.
Oct 28, 2007 at 7:55 AM
So wouldn't the best solution here not be able to access the current camera for the scene? This way you could just inside any node write:
    this.Model.Effect[EffectParameterName.Projection] = this.Scene.ActiveCamera.Projection;
Oct 28, 2007 at 12:45 PM
That's similar to have I managed the camera in the mesh manager I posted a few days ago.

btw, everything in c# is passed by value by default. People like to think of classes being passed by reference, because the value of that varaible is a pointer to the class instance. So for all intents and purposes, classes are passed by reference, excpet as sturm pointed out, saying "a = new object()" will not change the value of the vaiable outside of the mehod, but if you pass by ref it will.
Oct 28, 2007 at 3:12 PM
Edited Oct 28, 2007 at 3:13 PM
{quote:Aphid}
btw, everything in c# is passed by value by default. People like to think of classes being passed by reference, because the value of that varaible is a pointer to the class instance. So for all intents and purposes, classes are passed by reference, excpet as sturm pointed out, saying "a = new object()" will not change the value of the vaiable outside of the mehod, but if you pass by ref it will.
{quote}

Yes, you're right, my mistake!
Oct 28, 2007 at 8:45 PM
Sturm, sorry for misunderstanding you earlier. I think we were just on two parallel lines of thought, I didn't realize you were trying to be so explicit. I was merely trying to explain to LordIkon that you don't need 'ref' on reference-types to be efficient.

LordIkon, you have experience with C/C++ right? If so, think of it this way: By default, classes in C# are passed like pointer parameters in C++, i.e.

public void MyFunc(MyClass a);   // C#
 
void MyFunc(MyClass* a);    // "Equivalent" C++

So, what this means is you can make changes to the instance and it'll be reflected in the caller. But, in terms of performance, the only part of the instance that is transferred to the callee is the address, not a copy of the data. Of course, this is a little different than pass-by-reference semantics. If you re-assign the reference, only the local reference is changed, not the caller's reference. What Sturm is referring to is "real" pass-by-reference semantics. This looks like:

public void MyFunc(ref MyClass a);  // C#
 
void MyFunc(MyClass** a);  // "Equivalent C++"
or
void MyFunc(MyClass& a);

Again, only an address is transferred to the callee. But, here, you can re-assign the reference and the caller will get the new reference, unlike in the previous case.
Coordinator
Oct 29, 2007 at 2:21 AM
Thanks for the full explaination Shaw, putting it in C++ terms does help, my background in school was only C++, any C# over the last 9 months was self-taught.
Oct 31, 2007 at 12:34 PM
I think we need a camera manager, I would easily imagine a scene having more than one camera. Also this would make the type of camera agnostic to the engine. So the engine could use a FPS or a RTS wothout having to do any change to the engine. Eventually in the editor the game designer could simply choose the type of camera which should be used, and voila the scene is rendered using that camera.
Oct 31, 2007 at 12:47 PM
Add it to the to-do list :)

Technically, the current FreeCamera could work as an RTS camera with the proper input -> camera mapping. What functionality is in an RTS camera that's not in other cameras?
Oct 31, 2007 at 2:14 PM
Basically a look-at-camera with being able to translate the look-at-point in X-Y-axis.
Mhm... and it arcs around that target's (mostly center point of the screen or some selected object) world-up-vector (Z-axis)... and in some games you can alter the height of the camera changing the perspective from a top-down view to something almost resembling a fps-view.

Perhaps someone else might be able to explain this more clearly.
Coordinator
Oct 31, 2007 at 9:01 PM
Your describing a combination of the free camera and its ability to strafe its position, except we'd need strafing up and down as well, and also the arc-ball camera with its ability to circle around a point.

I'll have to think about how to implement this. The strafing up and down would be very easy, in fact, before I publish v0.178 I'm setting up the camera movement on single functions that can be called, rather than a single move command. This way each camera can have its own overloaded strafe command that might act slightly different in each camera's case. I will setup up/down strafing as part of that.

I also don't like the free camera's limitation of rotation when looking almost directly up or down, I may have to implement a different movement/rotation system for the free camera.
Oct 31, 2007 at 9:54 PM
I think the best solution is to create specific cameras for each type of movement, and not try to solve all into one camera. If a custom camera is needed it should be easy for external devs to implement this and use it in the engine.

Someone could create a camera which would wobble along the z-axis based on the gameTime:
    public class CustomCamera : Camera
    {
        public override void Update(GameTime gameTime)
        {
            Vector3.Add(this.Position, new Vector3(0, 0, Math.Sin(gameTime))); // Hey this wouldn't work but that doesn't matter here ;)
        }
    }
Then when initializing the game that camera would get assigned like this:
        public override void InitializeCore()
        {
            CustomCamera camera = new CustomCamera();
            this.CameraManager.Add(camera);
            this.CameraManager.ActiveCamera = camera;
 
            ...
        }
Any number of cameras could be created but only one would be the active and the one used for rendering.
Coordinator
Nov 1, 2007 at 12:54 AM
I believe a single abstract camera class should have MANY helper functions that enables the engine user to pretty much create their own camera without having to create many of their own functions, and they can simply override or implement functions from the base camera class. Giving free camera the ability to strafe up and down isn't a bad thing even for an FPS camera, because you only map the input keys to the types of strafing you would want. For instance if I had camera that should only strafe left and right I simply wouldn't setup any keys to affect up and down strafing. I do agree however that there shouldn't be a GOD camera implementation for an engine, it would have to account for too many things.
Coordinator
Dec 1, 2007 at 1:44 AM
Sturm, I will be submitting v0.183 in a couple of days, mostly just bug fixes however, I'm done with features.

Oh, and if we can't figure out a design for at least the game class in a couple of days I propose that one of us simply starts a project with a nearly empty game class as a base so the core team can at least have something to place their changes.

I think I'd like to take the camera system, and as such, all I need to know from you guys is what information the game/scene manager will need from it, other than that I can take care of the rest. Cameras are fairly easy. I'm assuming you'll need a view matrix and projection matrix at the very least. Would you guys rather have the scene manager create a bounding frustum off of those matrices each frame, or have the camera system do it and pass it?
Dec 1, 2007 at 9:45 AM
With the new game, whoever does it can they ensure its 2.0 please? Ive had no end of problems using 2.0 with the 1.0 framework.
Dec 1, 2007 at 1:24 PM
Going forward, everything is 2.0.
Dec 1, 2007 at 1:58 PM
Good to know :)
Dec 3, 2007 at 6:48 AM
I wouldn't consider Camera to be all to easy to implement. You have to take special care when working with cameras. It's prob one of the most performance expensive elements in the engine, though not in itself. When you update the camera you have to make sure that you aren't updating the view frustrum, unless it's absolutely needed. Because if you do, we will need to retest all entities for visibility again. So the camera should only update when needed and not just on every cycle. You also have to define a way of indicating that the camera has changed the frustrum, either using a property or an event.
Coordinator
Dec 3, 2007 at 1:22 PM
Shouldn't be too difficult. Any action resulting in a position or rotation change for the camera will cause a 'dirty' flag to set to true. Each frame the flag is checked, and if true the frustum will update. It should be easy to check for movement or rotation of the camera as long as all movement is done through movement functions. This will mean that camera's position and rotation will need to be protected and if we need access to it, it'll be a 'get' only, through an accessor.
Dec 3, 2007 at 2:25 PM
I see no reason to have the rotation and position as private only. Setting the position and rotation of the camera should be public, so that custom triggers can set it. This will also make it easier for scripters to create special camera effects camera.Position += Math.Sin(dt / Math.PI; or some other strange thing.

If you can't directly set the property, you will need to give the position at construction, which makes the OM more complex, and only having relative movement makes it much more complex moving entities around.
Dec 3, 2007 at 6:01 PM
I would just provide SetPosition/SetOrientation methods (or if want to be .NET about it, Position and Orientation properties, happy Sturm? :) ). Full client access, and the camera will know when things change and can take appropriate action.
Dec 3, 2007 at 6:48 PM
Exactly what I had in mind :)
Coordinator
Dec 3, 2007 at 7:33 PM
If they're not private you'd have to compare the position and rotation from the previous frame to the current, and if they were different then update. If you want a boolean flag set, then you'd need to know when those changes occur, which could easily be inside of some set functions.

If we're talking about set methods that is exactly what I described in my post, in which they're protected, so they would require using methods. For example, the current template uses functions for (almost) all camera movement.

I guess I don't see the point of having 'set' methods if the variables are public.
Dec 3, 2007 at 8:22 PM
The variables shouldn't be public, only the properties should be public. That way the camera will always know when clients make a change.
Coordinator
Dec 3, 2007 at 8:58 PM
Edited Dec 4, 2007 at 3:03 AM
lol, I think we've all been talking about the same thing this whole time.

protected Vector3 Position;
 
public Vector3 position
{
     get { return Position; }
     set { 
               Position = value; 
               hasCamChanged = true; 
             }
}
Something like this? Or would the get accessor be alone and have the set as a separate function like SetPosition( Vector3 ... )?
Dec 4, 2007 at 12:01 AM
Might as well have them all as properties, to stick with the .NET-isms. Silly .NET, lol.
Coordinator
Dec 4, 2007 at 3:05 AM
Luckily this shouldn't be much of a performance issue, camera movement won't happen all the often per frame.

I do like accessors over the C++ style of creating a bunch of get/set functions, which I usually end up inlining in the header if they're simple or creating inline functions, both of which are slightly more of a pain in the ass than C# accessors.
Dec 4, 2007 at 3:34 AM
They are easier to type, too bad the Xbox CLR (and the Desktop CLR to an extent) sucks at automatically inlining them. :)

Two more questions I had about the camera:
  1. Are you keeping the Z-up coordinate system? I know the camera implementation itself isn't much affected by this, I'm just curious. When working on the rendering code a couple weeks ago, I ran into some issues with standard cube map face orientations needing to be adjusted based on how the hardware interprets the cube texture coordinates, i.e. the +/- Z and +/- Y directions needed to be rotated from the standard orientations. It's not a huge deal, I can just see it causing headaches for new users who are used to the standard DirectX/OpenGL coordinate systems.
  2. Are you going to use a matrix or a quaternion to represent orientation? My vote would be for quaternions.



Dec 4, 2007 at 9:27 AM
Edited Dec 4, 2007 at 9:33 AM


LordIkon wrote:
lol, I think we've all been talking about the same thing this whole time.

change to reflect coding guideline
protected Vector3 position;
 
public Vector3 Position
{
    get { return this.position; }
    set 
    { 
        this.position = value; 
        this.hasCamChanged = true; 
    }
}


You just ate the forbidden fruit. You will never know when position is updated. Because anyone can update position directly without setting the flag (Yes I know you have to inherit, but since we target developers, that makes everyone). A main issue here is that the physics engine needs direct access or the cost up updating will be too high, a possible workaround of this could be:

private Vector3 position;
 
public Vector3 Position
{
    get {return this.position;}
    set
    {
        this.position = value;
        this.hasUpdated = true;
    }
}
 
// Updates the entity using data from the physics engine.
public void Update(ref PhysicsData physicsData)
{
    this.position.X = physicsData.Position.X;
    ...
}
 
// PhysicsData would look like
public struct PhysicsData
{
    public Vector3 Position;
    ...
}

LordIkon wrote:
Or would the get accessor be alone and have the set as a separate function like SetPosition( Vector3 ... )?

No this is not a OM we want to present to users. Also I'm very interested in seeing how you are going to keep track of the hasUpdated flag, is it bound to update, or some other method, how and when do you determine that you can set this to false again?


LordIkon wrote:
Luckily this shouldn't be much of a performance issue, camera movement won't happen all the often per frame.

There is no difference between a Camera and a Model, they are all entities. You want this because you want to be able to take a camera and attach it to another entity and apply the output to a texture (Think survalience camera and monitor). Also any optimization performed to Entity would then automatically be applied to Camera.


shawmishrak wrote:
Might as well have them all as properties, to stick with the .NET-isms. Silly .NET, lol.

Right On !!! :)
Coordinator
Dec 4, 2007 at 1:35 PM
For this one case I agree that camera's position should be private, because there are few cameras in a game compared to entities, so updating their position through accessors may be ok. Normally I would say position should be protected, but we would easily run the risk of the hasUpdated flag not properly being set.

Treating the camera like a model is interesting and sounds like it would work out ok, I'll look into it.

I'll indeed be setting the flag to false at the beginning of the Update loop of the camera, because it is one thing we can guarantee is called each frame. I'd request that camera be one of the first things updated, so that any actions that occur during the frame AFTER camera's flag is set to false would then set it to true. When I go to set the flag to false I can simply check the state of the flag at that point, if it was true I would update the frustums.

So the Update process would start like this:

- If flag is true, update frustum and set to false, otherwise do nothing.
Dec 4, 2007 at 4:30 PM
I havent been following this thread, so this may have already been aksed. How it the updated flag set? It would be very useful for optimizing the network also if each object had this flag. That means I would only send its posistion if it had been updated.
Coordinator
Dec 4, 2007 at 5:04 PM
I don't think the network will need it. Each client's camera has the flag, which is set only when the camera moves or rotates. Then if the flag is set the frustum updates and sets the flag back to false.
Dec 4, 2007 at 6:37 PM
I was thinking that if there was this flag, I would only update those objects via the network. Having the camera with this flag serves no purpose from the networks view
Coordinator
Dec 4, 2007 at 9:18 PM
Having flags on things other than the camera is certain possible, I think Shaw may do something like that for physics. At this point I'm not sure how it'll interact with the network.
Dec 5, 2007 at 1:14 AM
We need to be careful here, having this type of flag often tend to blow up in your face. Suddenly you have 10 different flags all set at different times, this can be very tricky keeping track of and almost impossible to extend.

Another way of tracking this would be an OnPropertyChanged event, did you consider this?
Coordinator
Dec 5, 2007 at 3:16 AM
I didn't know about it. After some research I found it uses .NET 3.0, does XNA require 3.0? or only 2.0? Also, would it be easy to use in a game? I like my own types often because I know they can be tailored for a game, which unlike Windows apps, runs in frames, rather than on messages. Then again, I've done little Windows forms programming, or even .NET programming.
Dec 5, 2007 at 5:02 AM
I would stay away from anything requiring .NET 3.0 or 3.5. It just further increases the number of installation dependencies on end users, and there's no guarantee on Xbox support. The new Xbox assembly references in the 2.0 beta (Xbox versions of mscorlib.dll, system.dll, system.xml.dll) are versioned as 3.5, but they definitely do not include the full set of .NET 3.5 features. It's still a subset of .NET 2.0 (the Compact Framework subset).
Dec 5, 2007 at 6:00 AM
It does not require >2.0 It's just a eventing pattern.

You can create your own, or use the existing from ComponentModel (PropertyChangedEventHandler/Args If memory serves me right) You would then simply have the following pattern on all properties

public object Property1
{
    get {...}
    set
    {
        this.field1 = value;
        this.OnPropertyChanged(PropertyName.Property1);
    }
} 
Then the scenegraph would simply listen to the PropertyChanged event on camera and if the relevant property changed, it would rerun all visibility validation.
Coordinator
Dec 5, 2007 at 6:47 AM
Do you know what kind of overhead there is on this "listener", or a listener like this?
Dec 5, 2007 at 11:30 AM
It does add a possible virtual call and possible event. But since most entites do not update every single frame, well in most games only a subset of all entities actually update, also there would only be a few listeners, so I do think the runtime overhead is acceptable compared to the code complexity of updating all sorts of properties.
Coordinator
Dec 5, 2007 at 1:55 PM
After Shaw gets the base up I will start work on the camera. I'll probably just get the initial version up and running with minimal features. After that however I'll test out the OnPropertyChanged and see if the overhead is much more than a simple bool, if not it sounds like it could be easier. If I get it going with OnPropertyChanged and the overhead seems minimal I'll need to have someone test it on the 360 to make sure it is ok with it.
Dec 5, 2007 at 2:54 PM
I dont see it having that much overhead. The general rule of thumb, from fastest to slowest:

inline -> direct -> virtual -> delegate (events)

I'll try to dig up the article on how the exact performance differences, I think it was brought up at GameFest.
Dec 5, 2007 at 2:57 PM
The overhead compared to a simple bool is rather big, but that's not the issues. The real gain is simplifying code complexity. having 4 different bools for 4 different property changes, does make the update a lot more complex. Adding more properties to PropertyChanged adds zero complexity.
Coordinator
Dec 5, 2007 at 3:22 PM
I agree, but if the overhead ends up being big then I'd prefer a bool. If the overhead over 10,000 loops is only a couple ms or something similar then obviously it will make no real difference in performance and would be great to use.
Dec 5, 2007 at 3:27 PM
I found the slide. Interestingly, interface calls are more expensive than virtual calls. I figured they'd be implemented the same way internally via vtables, but whatever. The point is that delegates are measurably slower than virtual calls. For those unfamiliar with the performance aspects of .NET code, I would recommend reading the GameFest slides on the topic http://download.microsoft.com/download/e/7/e/e7e910d6-0ee1-4a33-a724-1e9a474f7265/Costs%20of%20Managed%20Code%20--%20The%20Avoidable%20and%20the%20Unavoidable.zip. All of the GameFest presentations are available at http://www.xnagamefest.com/presentations.htm.

If there are going to be several camera properties, and different actions needs to be taken depending on which property is changed (for example, changing position requires code X to run, but changing orientation requires code Y to run), then I think the OnPropertyChanged method allowing events to trigger based on which property was changed is good. However, if all property changes trigger only one update method, I think the bool is sufficient. Just have one bool for the whole class. Anytime a relevant property is changed, set the bool to true. In the per-frame update, if the bool is true, handle the change and set it back to false. This also avoids the problem of multiple camera updates per frame. You could potentially have multiple camera updates per frame. Imagine this scenario:

  1. Client code processes each movement axis differently. Based on user input, the camera is first translated up, then left, then forward, then rotation around local Y by 0.2 radians. (4 separate camera updates.)
  2. For each update, the OnPropertyChanged event is fired. The camera's view frustum and other medium-weight calculations occur. (That's four updates!)
  3. The end result is the same as if the camera update was done only after the last client command!
Coordinator
Dec 5, 2007 at 6:08 PM
For a camera at least, I thought a bool would be fairly simple, under the condition that position and rotation changes be enforced through accessors. This guarantees that any change in position or rotation of the camera would result in a viewmatrix update and frustum update.

However, this is because of the fact that a camera is indeed fairly simple. Other entities could be more difficult, especially where physics is concerned. An entity may be collided upon multiple times by multiple objects, affected by wind, then gravity, and buoyancy, etc.... and physics may require enough performance that accessors can not be enforced. In a case like this we may have to figure something else out.

Luckily my only concern at this point is a working efficient camera, which should not be too difficult.
Dec 5, 2007 at 6:44 PM
Since a camera is just an entity (or should be) you should have this settled before implementing. A possible solution would be to use a Begin/End pattern where the events wouldn't be raised until end is invoked.
Coordinator
Dec 5, 2007 at 11:46 PM
I don't believe camera will have to be an entity, or am at least skeptical. An entity has a draw function which may need camera parameters passed in, lighting parameters, etc. A camera would be the one producing some of this information, and wouldn't need these same parameters. Additionally, all entities may have mass, or elasticity (I'm just throwing stuff out there), which are presumably things no camera will need.
Dec 6, 2007 at 12:01 AM
Actually, the Draw method on entities will be agnostic towards cameras, lighting, etc. All they do is tell the renderer what geometry to draw, where in the world to draw it, and what material to use. The renderer takes care of the rest. The scene manager will take care of most of the culling. I agree that camera's will fit into the "entity" hierarchy somewhere. But they also have their own unique features and will most often be used directly referenced as a camera, not as a generic entity.
Coordinator
Dec 6, 2007 at 12:26 AM
I agree camera and entity have some common features, like a position and rotation, update() and draw() methods. I can't think of a whole lot more. I was considering giving the camera a bounding box based off its near frustum values for more accurate collision, but that would be different than any bounding setup that normal entities have.
Dec 6, 2007 at 4:54 AM
I think you might have a little too narrow of a definition of entity. For our purposes, an entity is anything in the game world. This includes physical, drawable objects like players, terrain, and furry little bunny rabbits that you can violently blow away with a sawed-off shotgun, but it also includes event triggers, ambient audio emitters, animation controllers, physics effects (like gravity sinks and such), lights, and everything else that is part of a game world. There will exist an entity hierarchy of which camera will be a part. Depending on the game, the majority of entities in the game world may not be drawable. The reason for having this hierarchy and treating everything as an entity on some level is to allow interactions. Say you want the camera to follow an object moving in the world. You attach that entity as the camera's target. Now, suppose you want to display the player's weapon. You can attach the weapon entity to the camera, with a certain position offset to place it in a FPS perspective relative to the camera. Intuitively it makes sense that the camera can "target" an entity, but the reverse is also true. A camera can be a target of an entity as well.

Speaking of this topic, we really need to flesh out the basics of this hierarchy.
Dec 6, 2007 at 5:21 AM
Edited Dec 6, 2007 at 5:23 AM
You have to abstract more. There are Entities and Drawable entities. As camera wouldn't actually be rendered. Only the root entry in the SceneGraph would need to know this differentiation eventhing else is bacially unaware. Then in the main game (which contains teh scene) you would do something similar to:

public class QSGame
{
        protected override void Draw(GameTime gameTime)
        {
            // Update frames per second count
            this.UpdateFps(gameTime);
 
            base.Draw(gameTime);
 
            // Draw the scene
            this.Scene.Draw(gameTime);
        }
 
        protected override void Update(GameTime gameTime)
        {
            // If the game isn't active just jump out
            if (this.IsActive == false)
            {
                return;
            }
 
            // Update mouse and keyboard first
            InputManager.Keyboard.Update(gameTime);
            InputManager.Mouse.Update(gameTime);
 
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            {
                this.Exit();
            }
 
            base.Update(gameTime);
 
            // Update the scene
            this.Scene.Update(gameTime);
        }
} 

The SceneManager (this.Scene) would know if a contianed node is renderable or not and invoke Update and Draw as appropriate. Since Camera is just an entity in the scene it get updated as well, you can define the rendering/update order so you could just set it to be updated first.
Coordinator
Dec 6, 2007 at 1:43 PM
I didn't know the extent of entities in our scene until just recently. In this case I guess camera will need to be an entity. How will you be checking collisions Shaw? Will be have CollidableEntity, or will our Entities have a bool on whether they will be checked for collisions?
Dec 6, 2007 at 2:21 PM
I do not think that the will be a CollidableEntity, bacially all entities will have a bounding spehere/box and as such can collide. Also the cost of casting to CollideableEntity would quickly become expensive. In order for an entity to not collide it would simply have a empty bounding sphere/box.

This way even the camera could collide with the environment. This would prevent the camera to get "stuck" in a wall or run thought the terrain.
Coordinator
Dec 6, 2007 at 3:09 PM
Edited Dec 6, 2007 at 3:20 PM
But shaw has said things like particle and audio emitters, and animation controllers, will be entities. We certainly don't need to check collision against those, and they wouldn't have bounding regions to begin with.

Here is a new thread on the entity hierarchy discussion:
https://www.codeplex.com/Thread/View.aspx?ProjectName=QuickStartEngine&ThreadId=18774
Coordinator
Dec 7, 2007 at 9:45 PM
For a camera interface I am designing I will likely need messages that I can pass objects and basic datatypes with. I haven't got the design worked out just yet, but lets say I wanted to send a message that specified which player's camera I wanted to view, and of the player's camera's, which type I wanted to see. I would need to pass the player reference (or entity reference), and the camera type (which could be an enumeration or integer). Will the messaging system allow for us to make custom messages, and if so, will the message be able to go straight to a desired interface. For example, I could send a message of a specific type that I have created, specify the information to be included with it, and then specify the interface I'd like to send the message to. I could possibly specify if I needed the message to be sent immediately (as in retrieve/send the info right now, and by the time I get to the next line of code I should have it), or if I send the message to a queue, and when the message happens it happens. Of course, sending a message to a queue would imply that I couldn't reliably use any information from that message that frame, or possibly even the next frame.
Dec 7, 2007 at 11:51 PM
The message system allows custom message data, so you would need to create a message id, and a new data type (class/struct) implementing IMessageData. The initial version will use broadcast so no targeting.

The message system is synced using update so there is no direct sending, this would also bee too complex keeping track of. But if it's needed we can rework the message system
Coordinator
Dec 9, 2007 at 7:41 PM
I've been thinking quite a bit about the camera system/interface, and wanted to bump some ideas off of you guys.

I was thinking of a system in which the camera's themselves belong to the entity. However, the camera interface would act as the authority for all cameras. It would handle all camera messages. In order to do this is would access the entity's list of cameras, and find the appropriate one (the one requested in a message), and then it could request whatever method was needed.

Here are some pros and cons:
  • Pros:
  • When an entity was deleted, their cameras would also be deleted properly. If the camera interface had all the cameras then when an entity was deleted it would have to send a message to the camera interface letting it know of its deletion, and then the camera interface would've had to find all cameras belonging to that player and delete them, or remove them from the interface at least.
  • We wouldn't need a list or dictionary of cameras stored in the camera interface, the list would be stored on the entity, and accessed through the camera interface. This makes search times for camera's much faster, as you're only looking through a list of cameras that belong to the requested entity, not through the list of all cameras and comparing to see if it belongs to the requested entity.

  • Cons:
  • The camera interface needs access to the full list of entities. This means the interface needs access to the scene manager, which has access to the scene, which has the entity list.

  • Both a Pro AND Con:
  • Entities could alter their own camera without the authority of the camera interface. However, this is beneficial from a performance standpoint, as the entity wouldn't be required to send a message to its own camera, but if it needed to perform special tasks that the camera interface did, then the entity still has the choice of going through the camera interface.

That is all I can think of for now.
Coordinator
Jan 23, 2008 at 1:49 PM
Referring to the questions about camera mount points, and fixed cameras. It will be entirely possible to have fixed cameras have a look at point eventually, but they may end up in a different class, like fixedTargetCamera, or I may just add a variable to each camera. In 0.182b some of the cameras can lock-on to targets and follow them already.

Each camera is mounted directly to an entity, I will be adding a mount offset to each camera to offset its position if needed. Right now the fixed camera already has this offset, so you can basically change the mount point and its viewing direction in relation to the entity. This is hard to test in the prototype without entities to rotate and control, but you can see this easily in 0.182b by tabbing through the different cameras.
Jan 23, 2008 at 5:04 PM
THe camera themself shouldn't have any offset this should be handled by the entity base, as they are the once controlling the mount points in the first place.
Coordinator
Jan 23, 2008 at 6:59 PM
There are mount points that the camera references, but many cameras need an offset. If a camera always has a direct mount how would it ever rotate around a character?

Fixed cameras may be the exception, but why have multiple mount points on the entity, when camera offsets can simply be specified, which allows for one main mount point on the entity?
Jan 23, 2008 at 8:16 PM
Each model can have different mount points at different locations on the model.

I wouldn't consider rotating something around a character to be a good candidate for mount points. Mount points are so binding child models to the parent model as specific, named locations, like the hand or head.