[Solved] Manually apply parent transformations

Problems building or running the engine, queries about how to use features etc.
Post Reply
User avatar
alberts
Gremlin
Posts: 177
Joined: Fri Mar 31, 2006 8:43 am
Location: Granada-Cádiz-Jaén, Spain
x 20

[Solved] Manually apply parent transformations

Post by alberts »

Hi all,

I’m working on a basic camera control system plugin (which I plan to release for free when polished) but I’m having some problems when using a high tightness values for the camera. Hope you can help me.
The basic usage of the system is:

Code: Select all

void setupCameraControlSystem()
{
  …
  mCameraCS = new CCS::CameraControlSystem(…);

  CCS::ThirdPersonCameraMode* camMode1;
  camMode1 = new CCS::ThirdPersonCameraMode(…);
  mCameraCS->registerCameraMode(camMode1);     
  
  CCS::FirstPersonCameraMode* camMode2;
  camMode2 = new CCS::FirstPersonCameraMode(…);
  mCameraCS->registerCameraMode(camMode2);
  …
}
bool frameStarted(const FrameEvent &e) // Or main loop
{
  …
  mCameraCS->update(e.timeSinceLastFrame);
}
void CameraControlSystem::update(const Ogre::Real& timeSinceLastFrame)
{
  mCurrentCameraMode->update(timeSinceLastFrame);
  mCameraNode->setPosition(mCurrentCameraMode->getCameraPosition());
  mCameraNode->setOrientation(mCurrentCameraMode->getCameraOrientation());
}
The problem is common to most of the camera modes I’ve implemented but let suppose the simplest one, the “third person” mode. The easiest way to implement this camera mode is, obviously, to attach the camera node to the target node as a child. I don’t like this solution because I want the system to be as less as intrusive as possible, so I decided to apply the transformation “manually”.

Code: Select all

virtual void ThirdPersonCameraMode::update(const Ogre::Real &timeSinceLastFrame)
{            
  // Update camera position
  mCameraPosition = mCameraCS->getCameraTargetPosition() 
                + mCameraCS->getCameraTargetOrientation() * mRelativePositionToCameraTarget;

  // Update camera orientation
  mCameraOrientation = mCameraCS->getCameraTargetOrientation() * mRotationOffset;
  // mRotationOffset is the relative camera initial orientation. The following neither properly works 
  //mCameraOrientation = mCameraCS->getCameraTargetOrientation();
}
The problem is that, as you can see in this video, there is an annoying camera jittering. I’ve tried the float point consistent mode and the problem still persists. I’ve also tried to force the involved scene nodes to update their positions prior to the camera mode update, using the “_update” method, with the same result.

Do you know what the problem could be?
Many thanks in advance!
Last edited by alberts on Fri Nov 13, 2009 11:21 am, edited 1 time in total.
User avatar
tuan kuranes
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 2653
Joined: Wed Sep 24, 2003 8:07 am
Location: Haute Garonne, France
x 4
Contact:

Re: Manually apply parent transformations

Post by tuan kuranes »

Look like you update your node a frame too late, no ?
Trying to update on other event, best would be framerendering queued or framended ? doesn't solve the problem ?

Anyway many camera mode that use spring/mass, inertia, spline system would just avoid that as it smooth movement over time ?
User avatar
alberts
Gremlin
Posts: 177
Joined: Fri Mar 31, 2006 8:43 am
Location: Granada-Cádiz-Jaén, Spain
x 20

Re: Manually apply parent transformations

Post by alberts »

tuan kuranes wrote:Look like you update your node a frame too late, no ?
Trying to update on other event, best would be framerendering queued or framended ? doesn't solve the problem ?
Many thanks for your interests Tuan. I tried to update the camera in both framerenderingqueued and framended methods but the problem still persisted so I decided to keep using the frameStarted method.
tuan kuranes wrote:Anyway many camera mode that use spring/mass, inertia, spline system would just avoid that as it smooth movement over time ?
Yep. The problem arises only with high tightness values. That’s the reason I decided to introduce the “Attached” camera mode, where the cam is attached as a child node (tightness=1). The problem is that there is a range of tightness values which cannot be used (~0.8-0.999999).
User avatar
tuan kuranes
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 2653
Joined: Wed Sep 24, 2003 8:07 am
Location: Haute Garonne, France
x 4
Contact:

Re: Manually apply parent transformations

Post by tuan kuranes »

is there an easy way to reproduce that using the code in your SVN ?
User avatar
alberts
Gremlin
Posts: 177
Joined: Fri Mar 31, 2006 8:43 am
Location: Granada-Cádiz-Jaén, Spain
x 20

Re: Manually apply parent transformations

Post by alberts »

Yes. Just set tightness=1 when registering any ChaseFreeYaxAxis instance (main.cpp: 514). The fewer FPS value the more visible is the effect. You just can add a instruction like Sleep(30) in the frame listener to lower the FPS.

As you said in your previous message, is like the camera system were considering not the current target position but a previous one.

Thanks again for your time!
User avatar
tuan kuranes
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 2653
Joined: Wed Sep 24, 2003 8:07 am
Location: Haute Garonne, France
x 4
Contact:

Re: Manually apply parent transformations

Post by tuan kuranes »

Hard to dive in too precisely, really seems to be an problem of node _update call order.
What I suggest is to add you own NodeListenerto targetnode and cameranode, catching the nodeUpdated event and therefore get the correct order to use.
(if not just using the listener in your own code.)
User avatar
alberts
Gremlin
Posts: 177
Joined: Fri Mar 31, 2006 8:43 am
Location: Granada-Cádiz-Jaén, Spain
x 20

Re: Manually apply parent transformations

Post by alberts »

tuan kuranes wrote:Hard to dive in too precisely, really seems to be an problem of node _update call order.
What I suggest is to add you own NodeListenerto targetnode and cameranode, catching the nodeUpdated event and therefore get the correct order to use.
Many thanks Tuan again for your interest. I have moved the call to the update method of the camera system to the frameRenderingQueued event and I have also forced an update of the camera node at the end of that event.

Code: Select all

void CameraControlSystem::update(const Ogre::Real& timeSinceLastFrame)
{
  mCurrentCameraMode->update(timeSinceLastFrame);
  mCameraNode->setPosition(mCurrentCameraMode->getCameraPosition());
  mCameraNode->setOrientation(mCurrentCameraMode->getCameraOrientation());

  mCameraNode->_update(true,false);
}
As Tuan suggestted me, I have used the scenenode update listener to detect the changes order. As you can see in the following log, the position of the “head” scene node is equal to the position of the scene node the camera is attached to when the frameRenderingQueued event ends. So it should work! Despite that, it still seems that the camera node is being updated a bit after the head node (http://www.youtube.com/watch?v=erbhV6U2ZUA). :?

Code: Select all

00:33:50: Frame started. timeSinceLastFrame: 0.4
00:33:50: Head scenenode updated. New pos: -10.752 0 114.304. New orient: 0.999173 0 0.0406536 0
00:33:50: frameRenderingQueued
00:33:50: CurrentCameraMode: begin update()
00:33:50: cameraCurrentPosition = 0 0 0
00:33:50: Calculating new camera position...
00:33:50: cameraPosition = -10.752 0 114.304
00:33:50: CurrentCameraMode: end update()
00:33:50: CameraControlSystemSceneNode->setPosition(-10.752 0 114.304)
00:33:50: CameraControlSystemSceneNode updated. New pos: -10.752 0 114.304. New orient: 0.999173 0 0.0406536 0

00:33:50: Frame started. timeSinceLastFrame: 0.082
00:33:50: Head scenenode updated. New pos: -15.0026 0 144.991. New orient: 0.998697 0 0.0510242 0
00:33:50: frameRenderingQueued
00:33:50: CurrentCameraMode: begin update()
00:33:50: cameraCurrentPosition = -10.752 0 114.304
00:33:50: Calculating new camera position...
00:33:50: cameraPosition = -15.0026 0 144.991
00:33:50: CurrentCameraMode: end update()
00:33:50: CameraControlSystemSceneNode->setPosition(-15.0026 0 144.991)
00:33:50: CameraControlSystemSceneNode updated. New pos: -15.0026 0 144.991. New orient: 0.998697 0 0.0510242 0
...
I don't know what more to try. :cry:
User avatar
tuan kuranes
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 2653
Joined: Wed Sep 24, 2003 8:07 am
Location: Haute Garonne, France
x 4
Contact:

Re: Manually apply parent transformations

Post by tuan kuranes »

Can you try camera->update it from the Headnode listener ?
User avatar
alberts
Gremlin
Posts: 177
Joined: Fri Mar 31, 2006 8:43 am
Location: Granada-Cádiz-Jaén, Spain
x 20

Re: Manually apply parent transformations

Post by alberts »

tuan kuranes wrote:Can you try camera->update it from the Headnode listener ?
You got it right! :D

And now the _update method is not necessary. I need to think a bit how to incorporate this to the CCS because the node listener does not receive a timeSinceLastFrame value. But that's easy!!

Thanks again Tuan for your time.
User avatar
tuan kuranes
OGRE Retired Moderator
OGRE Retired Moderator
Posts: 2653
Joined: Wed Sep 24, 2003 8:07 am
Location: Haute Garonne, France
x 4
Contact:

Re: [Solved] Manually apply parent transformations

Post by tuan kuranes »

I need to think a bit how to incorporate this to the CCS because the node listener does not receive a timeSinceLastFrame value
That confirms it's an order update problem between when head node is updated, when you update camera, and when it's displayed. If you manage to figure that "order" you can avoid the listener thing.
Post Reply