Camera one frame behind?

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
TheGolem

Camera one frame behind?

Post by TheGolem »

Hi folks,

I think I found a bug in the camera management. Here is what happens:
I use a Custom Camera Scene Node, I write my own Event Management that is. The respective code should be well known, I use the old RotationX/RotationY Stuff. However, the bug is showing while I do this every frame:

Code: Select all

	Player.Position += Player.Direction * Player.Speed;
	vector3df pos = vector3df(Player.Position.X, Player.Position.Y, Player.Position.Z + 10);
	pos.rotateYZBy(RotationY, Player.Position);
	pos.rotateXZBy(RotationX, Player.Position);
	PlayerNode->setPosition(Player.Position);
	Camera->setPosition(pos);
	Camera->setTarget(Player.Position);
It should be apparent what the code does, it is moving the Player in the given direction at the given speed, positions the camera 10 units behind the player, does the mouse-related camera rotation, sets the PlayerNode to the position, and sets the Camera Target to the very same position. That should make the cam always have the Node in focus, right? Wrong. The bigger the Speed is, so the bigger the delta position is (if you want to put it like that), the more the cams focus stays behind the PlayerNode. This bug becomes apparent at various times, this is the most easy to explain ;)

Anyone noticed anything similar? Is this a bug in the Engine? Or am I being dumb?
Boogle
Posts: 162
Joined: Fri Nov 21, 2003 3:16 pm
Location: Toronto, Canada

Post by Boogle »

I believe the reason is: When setting the position of an ISceneNode (which the camera is), this sets the RelativeTranslation variable only. The RelativeTranslation value does not affect the ISceneNode's AbsoluteTransformation matrix until after the scene is rendered (during the OnPostRender method call). The setTarget function of the camera, however, affects the camera's target immediately. This means that while the player object and camera object aren't moved to their new location until the next frame, the target is immediatly looking at where the player should be. A quick fix would be to call the OnPostRender method of the camera and player nodes immediately after setting their position. This may screw with any Scene Node Animations you have attached to the objects however.

Or my logic could be off, but I'm pretty sure this is what's happening.. :D
sirshane
Posts: 31
Joined: Tue Oct 14, 2003 5:02 am
Contact:

Post by sirshane »

Is there any specific reason why transformations are updated AFTER the frame has been completed? This doesn't make much sense to me, and causes problems like above. It would seem logical that transformations be updated before a frame is rendered.
-Shane
niko
Site Admin
Posts: 1759
Joined: Fri Aug 22, 2003 4:44 am
Location: Vienna, Austria
Contact:

Post by niko »

If the scenemanager would have done it in this order:

Code: Select all

loop
{
  SceneManager::drawAll():
  {
    SceneManager animates all nodes;
    SceneManager draws all nodes;
  }
} //end loop;
You would have had no chance to influence the position of the nodes before they get drawed. So there would be the possiblilty, that they are drawed in a position you won't like at all.
In the way it is done, you have the chance to do this:

Code: Select all

loop
{
  SceneManager::drawAll():
  {
    SceneManager draws all nodes;
    SceneManager animates all nodes;    
  }
  you change positions of the nodes
    if they are not where you want them;
} //end loop;
Boogle
Posts: 162
Joined: Fri Nov 21, 2003 3:16 pm
Location: Toronto, Canada

Post by Boogle »

Is it possible to have the current RelativeTranslation, RelativeRotation, and RelativeScale take effect before the render, then render, then animate?

ie:

Code: Select all

loop
{
   SceneManager::drawAll();
   {
      SceneManager updates absolute transform matrix
      SceneManager draws all nodes
      SceneManager animates all nodes
   }
}
The getPosition method, etc would continue to be accurate after this, as the scene node animators affect the RelativeTranslation, etc of the scene node. And it would also have the benefit of using our setPosition calls on the next frame, rather then the frame after next (which is rather unintuitive).

Edit: Also, the way it currently works, we may be able to detect that the scene node is in the wrong place and update it immediately after rendering, but these changes won't take effect until the frame after as well.
Post Reply