Camera is always 1 frame behind, what can I do about it? | 2024 edition
Posted: Sat Jul 27, 2024 4:56 pm
I am having a problem where I'm trying to get the camera to chase an object. For some reason, it actually works when following a node at the root level. If I want to get it to follow a node that is a child of another node, it's always 1 frame behind. Using getAbsolutePosition() only returns the position of that node from 1 frame ago. This means that the faster the parent object moves, the further behind the camera lags when chasing the child object.
In my update loop I run everything in this order:
I've experimented with all kinds of other combinations but I'd love to hear someone else's reasoning for why this should be a different way. The obvious thing of putting cameraChase() before beginScene() doesn't fix the camera lag even if I also put updateAllObjects() before beginScene() too.
I know about the updateAbsolutePosition() function but i'm not sure if its broken or if im not using it right. The following code performs exactly the same regardless of if the lines containing updateAbsolutePosition() are commented out or not.
The following modification of that same code results in also the exact same behavior
Literally all it takes to allow the camera to follow a root node without lagging behind at high speeds is this:
So.. besides trying to make something that calculates how fast objects are going and proactively sets the camera forward based on velocity to sort of balance out the to-me unfixable camera lag, what are some other things I can try? When updateAbsolutePosition() gets called, when do those changes, if any, become valid instead of being set to the previous frame's values?
Edit: well, darn. calculating velocities and moving the camera to where it should be 1 frame from "now" can't work if the parent object is rotating and the child object is moving because of the way pivoting changes the position. That's some really complicated math.
In my update loop I run everything in this order:
Code: Select all
irrDriver->beginScene(true, true, SColor(255,0,0,0));
physicsTick(); //tick the reactphysics3d physics engine
updateAllObjects(); //set the position of all the node objects to whatever the physics engine says they should be
cameraChase(); //whatever camera following code i'm currently testing
irrsmgr->drawAll();//scene manager
guienv->drawAll();//IGUIEnvironment
irrDriver->endScene();//IVideoDriver
I know about the updateAbsolutePosition() function but i'm not sure if its broken or if im not using it right. The following code performs exactly the same regardless of if the lines containing updateAbsolutePosition() are commented out or not.
Code: Select all
core::vector3df forward = thingToChase->getNode()->getRotation().rotationToDirection();
core::vector3df up = thingToChase->getNode()->getRotation().rotationToDirection(core::vector3df(0,1,0));
core::vector3df thingPosition = thingToChase->getNode()->getPosition();
thingToChase->getParentThing()->getNode()->updateAbsolutePosition();
thingToChase->getNode()->updateAbsolutePosition();
theCamera->updateAbsolutePosition();
theCamera->setPosition(thingPosition - forward);
theCamera->updateAbsolutePosition();
theCamera->setTarget(thingPosition + forward);
theCamera->setUpVector(up);
Code: Select all
thingToChase->getParentThing()->getNode()->updateAbsolutePosition();
thingToChase->getNode()->updateAbsolutePosition();
core::vector3df forward = thingToChase->getNode()->getRotation().rotationToDirection();
core::vector3df up = thingToChase->getNode()->getRotation().rotationToDirection(core::vector3df(0,1,0));
core::vector3df thingPosition = thingToChase->getNode()->getPosition();
theCamera->setPosition(thingPosition - forward);
theCamera->setTarget(thingPosition + forward);
theCamera->setUpVector(up);
Code: Select all
core::vector3df forward = thingToChase->getNode()->getRotation().rotationToDirection();
core::vector3df up = thingToChase->getNode()->getRotation().rotationToDirection(core::vector3df(0,1,0));
core::vector3df shipPosition = thingToChase->getNode()->getPosition();
theCamera->setPosition(shipPosition + (forward * -64.0f) + (up * 10.0f));
theCamera->setTarget(shipPosition);
Edit: well, darn. calculating velocities and moving the camera to where it should be 1 frame from "now" can't work if the parent object is rotating and the child object is moving because of the way pivoting changes the position. That's some really complicated math.