FPS Camera in Bullet Physics jitters

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
jwatson1993
Posts: 37
Joined: Fri Nov 04, 2011 12:15 am

FPS Camera in Bullet Physics jitters

Post by jwatson1993 »

So I've read a lot of posts about FPS cameras, but I haven't found any that I found useful. I'm using a btkinematiccharactercontroller because I finally got it to work, and it seems to do everything that I want. Instead of attaching an fps camera to it, I've decided to write my own code for camera rotation and translation. The problem I'm running into is that every few updates of the camera while it is in motion is in the wrong position. The scene looks like it is flashing, but in reality the camera is just in the wrong position every few frames. I think that the problem isn't with my mouse movement code, its with the way that I am structuring the updates.

Here's a video of the problem: http://youtu.be/fTU5vtNneRo complete with my character model from Blender Noob to Pro, haha

Because my game will have a lot of objects, some of which will have irrlicht scene nodes and some of which won't, I've decided to make every object pretty much an interface between irrlicht and bullet. Every object that renders on screen has an irrlicht scene node and a bullet collision object. They all derive from an IActor interface, and my game class has a container of IActors. Every game loop, my game iterates through the container and calls the act() method, which sets the node to the position of the collision object. Here's the player's act method:

Code: Select all

 
int Player::act()
{
    
    if(action_id !=P_SLEEP)
    {
        keyControl();//WASD calls btkinematiccharactercontroller::setWalkDirection
        
        mouseControl();//rotates camera based on mouse movement
        update();//repositions camera
    }//if it isn't sleeping
    
    return action_id;//part of FSM
}
 
And here's the relevant portion of the game loop:

Code: Select all

 
        cd_Physics.World->stepSimulation((clock()-TimeStamp)*.001f,6);//steps the physics world
    stepActors();//iterates through actors and calls act() for each one
    cd_Engine.smgr->drawAll();//this is just for testing, actually using xeffects. same jitter occurs in either one
    TimeStamp = clock();
    cd_Physics.World->debugDrawWorld();
 
I feel like the jitter is caused by the camera updating in the wrong time. I know that my loop has a lot of iteration, but I feel like that provides my game flexibility that simply making a custom scene node wouldn't. But in case it isn't, here's my mouse movement method:

Code: Select all

void Player::mouseControl()
{
    double sensitivity = 70;
    vector3df rotation = playCamera->getRotation();
    vector3df horizontal = rotation.getHorizontalAngle();
    ICursorControl* cursorControl = cd_Engine.device->getCursorControl();
    vector2df cursorPos = cursorControl->getRelativePosition();
    rotation.X += (cursorPos.Y-.5)*sensitivity;
    rotation.Y +=(cursorPos.X-.5)*sensitivity;
    if(rotation.Y>360)
        rotation.Y = rotation.Y-360;
    if(rotation.Y<-360)
        rotation.Y = rotation.Y+360;
    if(rotation.X >85)
        rotation.X = 85;
    if(rotation.X <-85)
        rotation.X = -85;
    rotation.Z =0;
    if(cursorPos.X!=.5 &&cursorPos.Y != .5)
        printf("Camera Rotation: %f %f %f\n",rotation.X, rotation.Y, rotation.Z);
    playCamera->setRotation(rotation);
    cursorControl->setPosition(.5f,.5f);
}//end of mousecontrol
And my WASD movement control

Code: Select all

void Player::keyControl()
{
    playCamera->updateAbsolutePosition();
    vector3df walkDir = playCamera->getTarget()-playCamera->getAbsolutePosition();
    double rotation=0;
    bool move = false;
    if(cd_Engine.receiver->keyDown('W'))
    {
        move = true;
        rotation = 0;
    }
    else if(cd_Engine.receiver->keyDown('S'))
    {
        move = true;
        rotation = 180;
    }
    if(cd_Engine.receiver->keyDown('A'))
    {
        rotation = 90;
        move = true;
    }
    else if(cd_Engine.receiver->keyDown('D'))
    {
        rotation = -90;
        move = true;
    }
    walkDir.rotateXZBy(rotation);
    setWalkDirection(btVector3(walkDir.X,0,walkDir.Z)*(move?1.0:0.0));
}
This is just too weird, and I've tried several different orders of the game loop methods. Maybe I should just attach an irrlicht FPS camera and set the speed to 0? Or perhaps I should just make customscenenodes and animators, and remove my abstraction layer. Thanks for any help.
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Re: FPS Camera in Bullet Physics jitters

Post by smso »

In general, you should update the target and up vector of the camera as well.

Regards from,
smso
jwatson1993
Posts: 37
Joined: Fri Nov 04, 2011 12:15 am

Re: FPS Camera in Bullet Physics jitters

Post by jwatson1993 »

I forgot to mention that I bound the target and rotation with playCamera->bindTargetAndRotation(true); What do you mean by "up vector?"

Edit: ok apparently explicitly setting the target is better than binding the target, when you've got multiple updates like I do. Fixed the problem. I feel dumb for not trying that sooner. I tried making it work by getting the target and then adjusting it, but apparently setting the camera rotation and then getting a directional vector is the way to go. The up vector shouldn't change, should it?
smso
Posts: 246
Joined: Fri Jun 04, 2010 3:28 pm
Location: Hong Kong

Re: FPS Camera in Bullet Physics jitters

Post by smso »

jwatson1993 wrote:The up vector shouldn't change, should it?
It depends.
If it is a top view camera from, say, an airplane looking down some terrain, the up vector may change.
If it is attached to a character who can look up and down, it changes.

Best regards,
smso
Post Reply