Questions about the default Imagination Engine

Developer
Apr 15, 2007 at 9:30 PM
Question about dt....

Docs tell me that the default for TargetElapedTime is 0.0167 (1/60 second). And I can see that game.IsFixedTimeStep is true.

Yet every time I enter Calculate() in RigidBodyPhysicsService.cs, I see dt as about 0.5 (it varies, sometimes a little less ... 0.36). But Calculate() has as its first line

float dt = (float)(gameTime.ElapsedGameTime.TotalSeconds);

Why is this not 0.0167?
Developer
Apr 15, 2007 at 9:38 PM
Hmmm I just saw game.IsFixedTimeStep go to false. Not sure where this happens or why.
Developer
Apr 15, 2007 at 9:43 PM
I see IsFixedTimeStep go to false in LoadGraphicsContent in BallScreen.cs. Now I want to know why we are not using a fixed time step.
Developer
Apr 16, 2007 at 6:15 PM
I want to see how the ball is updated on the screen using the World matrix. I can see it on the lefthand side (needs to be on the LHS to have an effect) in the virtual Draw in Thing.cs.
effect.World = transformsmesh.ParentBone.Index * World;

Now the class Ball inherits from Thing, but it does not override Draw. The only overrides for Draw seem to be in Ballscreen, PauseScreen, and ScreenManager.

So I can see how the World matrix contains the translation and rotation information for an Update. But it's not clear to me (and yes, I've made an effort to discover this) how it is actually applied.

I'm still looking and may eventually find out, but you can save me a megacycle by giving me a couple of pointers. I want to use whatever this Imagination template is doing to plug in a new physics engine but need to understand how the current one works first.

The Calculate in RigidBodyServices.cs uses an Euler update and assumes a particular equation of motion (namely gravity with constraints). I'd like to generalize to have the engine return the results of a specified ordinary differential equation (ODE). We can have an anstract class ODE and inherit from it, adding specifics.
Coordinator
Apr 16, 2007 at 6:37 PM
The world matrix is used to convert the model's local coordinates to "world" or global coordinates that make sense for the scene being rendered. This happens during render time, and for the balls in ImagineBalls that's in the Draw method of BallsScreen. The draw code is here instead of in Ball partly because it's more efficent to batch together all the ball drawing at once (being able to share the same BasicEffect, etc).

We already have an abstract base class with the PhysicsService class... all the magic happens in the CalculatePhysics method. RigidBodyServices is just an implementation of PhysicsService. You should be able to build another class deriving from PhysicsService and use that instead. Is there something in the design that doesn't cut the mustard for generalization or abstraction?

I had debated about having some sort of a PhysicsData object off of Thing that contained all the relevant physics data (like position, velocity, etc) that the physics service could populate with its own derived version in case it had more data to track for each Thing. I decided against it for the time being since things like position and velocity seem to be pretty standardized around certain values (Vector3, etc), plus I didn't want to build in more abstraction than we needed. Maybe we do need that though... is that something you're looking for, or is there something else that isn't generalized enough?
Developer
Apr 16, 2007 at 8:16 PM
You know I can comment out the entire virtual Draw in Thing and the game still works.
//public virtual void Draw(GraphicsDevice device, Imagination.Display.Camera camera)

Look at ModelMesh.
Developer
Apr 16, 2007 at 10:31 PM

jasonmauer wrote:
The world matrix is used to convert the model's local coordinates to "world" or global coordinates that make sense for the scene being rendered. This happens during render time, and for the balls in ImagineBalls that's in the Draw method of BallsScreen. The draw code is here instead of in Ball partly because it's more efficent to batch together all the ball drawing at once (being able to share the same BasicEffect, etc).

Thanks ... that makes sense. The Draw() in Things.cs confused me ... and still does because it doesn't appear to be used.


We already have an abstract base class with the PhysicsService class... all the magic happens in the CalculatePhysics method. RigidBodyServices is just an implementation of PhysicsService. You should be able to build another class deriving from PhysicsService and use that instead. Is there something in the design that doesn't cut the mustard for generalization or abstraction?

I had debated about having some sort of a PhysicsData object off of Thing that contained all the relevant physics data (like position, velocity, etc) that the physics service could populate with its own derived version in case it had more data to track for each Thing. I decided against it for the time being since things like position and velocity seem to be pretty standardized around certain values (Vector3, etc), plus I didn't want to build in more abstraction than we needed. Maybe we do need that though... is that something you're looking for, or is there something else that isn't generalized enough?


I don't know ... the more I study what you have the better it looks. Calculate does include that Euler update. I'm still unfortunately in the mode of trying to uderstand the template. Granted, ne doesn't have to understand it perfectly to modify ... if that were true no one would ever be able to sustain code. But I need to get farther along.

The action seems to happen in mesh.Dra() in the Draw() of Ballscreen. I'm not clear how that collection of ModelMesh objects gets populated. Is this somehow happening behind the screnes.

Coordinator
Apr 16, 2007 at 11:46 PM
Thing.Draw() is cruft. I think I left it in there just to have that code to copy/paste somewhere else, but it isn't used. I thought about having Draw a part of Thing, and my general thought is that rendering should be owned more by Screen, not an individual Thing. There may be times where it makes sense to put Draw in Thing (and you could have the Screen class call down to Thing.Draw() in those cases)... but there are definitely times when it is non-optimal.

The ModelMesh objects are populated from the Content.Load<Model> call in LoadGraphicsContent() of GameScreen. The content pipeline does its magic in that one line to pull data from the .xnb file and load up the type you want, whether it's a 3D model, texture, etc.
Developer
Apr 17, 2007 at 9:00 AM
I'm puzzling though the coordinate system ...

I've tried putting in different values for Vector3 in the following line in BallScreen.cs and seeing what happens.
cueBall = new Ball(0, new Vector3(0f, 1f, 20f));

And I see the cueball appear in different places. But really what is happening here? What are the units and where is the origin? Why are the vector components in floats?

When the screen is initialized, what determines where the horizon is?

Another topic: I found a blog entry that describes how to run a game in Visual Studio Pro using Resharper. We discussed in one meeting how this was not possible. Does that mean that the hack described in this blog entry does not work? Has anyone heard of this hack before? Is it worth trying out?

http://www.chrisholmesonline.com/2007/02/26/five-minutes-to-building-xna-games-without-visual-studio-express/


Coordinator
Apr 17, 2007 at 3:28 PM
Vector components are floats because it would be pretty lame to only be able to render integers. Think of a ball rolling around; if it was rolling from (0,1,0) to (10,1,10) it would hit a bunch of fractions along the way (just like when you're driving you're travelling 5.2 miles, 5.3 miles, etc). Does that make sense?

What the units mean are for the application developer to decide. In ImagineBalls, a ball is 1 unit in diameter, which in the real world makes that 1 unit about 5 centimeters. You may have a racing game where a car model is 10 units long, putting the unit scale at around a foot. It is for you to determine as a developer what that unit means (and to make sure it means that consistently through your code).

The horizon is determined by the projection matrix, which we have wrapped up in the Camera class. Look for Matrix.CreatePerspectiveFieldOfView() and you'll see the far plane there.
Developer
Apr 17, 2007 at 4:43 PM
Thanks for being so responsive, Jason. Back in our first meeting, I asked what XNA was providing and the general answer was "not much, just connecting to the hw; you write all the game code"; but actually it provides a great deal. I may not have the terminolgy right yet, but what I see is rotations and translations calculated as quaternions, put in matrix form, assigned to an effect, and then the XNA engine takes care of updating the screen with those effects. This is a lot. I missed it at the time, but the "not much" was probably meant as ironic. But to use this framework successfully, one has to understand where that line is ... that is, what we write and what XNA does. And most of my questions have been probing where that line is.


jasonmauer wrote:
Vector components are floats because it would be pretty lame to only be able to render integers. Think of a ball rolling around; if it was rolling from (0,1,0) to (10,1,10) it would hit a bunch of fractions along the way (just like when you're driving you're travelling 5.2 miles, 5.3 miles, etc). Does that make sense?


Yes, certainly for units used in calculations. But what I was looking at was ball placement. By changing the vector component values in the Ball constructor, I can place the cueball at various positions. These positions can be floats and does make sense for consistency (use the same coordinates for calculations as position).

The default window I get seems to be 800 (across) by 600 (down) pixels. When I tried out placing my own sprite, I had code like

int MaxX = graphics.GraphicsDevice.Viewport.Width - myTexture.Width;
spritePosition1.X = MaxX;

where MaxX or any number I put there is an int. And so what I'm looking for is how the floats in the position vector get translated to what's needed for screen placement.


What the units mean are for the application developer to decide. In ImagineBalls, a ball is 1 unit in diameter, which in the real world makes that 1 unit about 5 centimeters. You may have a racing game where a car model is 10 units long, putting the unit scale at around a foot. It is for you to determine as a developer what that unit means (and to make sure it means that consistently through your code).


How and where do you determine that 1 unit is about 5 cm.? How and where does that unit determine an actual location on the screen?


The horizon is determined by the projection matrix, which we have wrapped up in the Camera class. Look for Matrix.CreatePerspectiveFieldOfView() and you'll see the far plane there.

Thanks, I missed this.

What do you think of Chris Holmes' hack?
Coordinator
Apr 17, 2007 at 5:06 PM
There are two coordinate systems we are dealing with at render time: the coordinate system of our 3D world, and the 2D coordinates of the pixels on our screen. Rasterization is what translates the data in our 3D system into pixels being lit up in the 2D screen coordinate system. This process is handled by the graphics card. All we need to do is tell the card what's in our 3D system and it will figure out how that maps to 2D.

Sprites are in the 2D coordinate system, and there will be cases (like billboarding, some particle effects, etc) where we'll want to draw the sprites around something in the 3D system. This is a similar problem to "picking", which is someone being able to click on the 2D screen with their 2D pointing device (mouse) and being able to determine what 3D object is underneath. Basically we do some math to convert and we're off to the races.

The 1 unit = 5cm thing... I created the ball model with a 1 unit diameter. I then searched online (much later, when the moonlike gravity started to bother me :) to find the actual measurements and mass of a billiard ball, which is where the 5cm comes from. (By the way, the units are not to scale in the current ImagineBalls app... need to add a unit scale to Imagination to fix that.)

The Resharper hack... if you like Resharper (which many people do), it's very handy. :)
Apr 18, 2007 at 4:09 AM
The Resharper hack is exactly what i've been looking for, thank god! Finally the power to slice and dice the codebase about 10x faster and 100x safer than in VS Express.
Developer
Apr 18, 2007 at 5:54 AM

TravisBrooks wrote:
The Resharper hack is exactly what i've been looking for, thank god! Finally the power to slice and dice the codebase about 10x faster and 100x safer than in VS Express.


So I've only read about and never used Resharper. An academic license is $50, and a personal license is $150. The personal license is out of my range. Is there some way we might qualify for an academic license?
Developer
Apr 18, 2007 at 6:00 AM
I'm still trying to understand ball placement. What I've been doing is modifying the following code in BallScreen.cs.

cueBall = new Ball(0, new Vector3(0f, 325f, 0f));
camera.Position = new Vector3(0.0f, 450.0f, 100.0f);

Is there some way of changing position without having to recompile? How can I enter coordinates into a running game? This would make working with the code much more productive.

What I want to understand is how those float coordinates translate into the 2D coordinates on the screen and how to affect that translation. When we place toasters, that's going to be very important.
Developer
Apr 18, 2007 at 6:09 AM
I wish I could upload screenshots in as easy way. (I did put an ODE.doc up on the this site using Visual Team Explorer. It's in a new directory called ImaginationDocs under the Source tab, which is now alive.) So if you map to the CodePlex server, you can pick up just that file or you could download and unzip the whole package.

But I noticed that with the coordinates in my last post, I see the cueball drop. It should I believe drop straight down and it does, but I noticed that its size changes. It's larger at the beginning of its drop than at the end. Am I not understanding perspective correctly? Why should the size of the ball change?
Developer
Apr 18, 2007 at 6:32 AM
I tried these ball and camera coordinates.

camera.Position = new Vector3(0.0f, 450.0f, 100.0f);
cueBall = new Ball(0, new Vector3(50f, 325f, 0f));

Here the ball starts dropping from the upper right corner and falls toward the lower left. I can’t think of a perspective or a camera angle that would make it look like this.