LWJGL first person camera using jBullet

654 views Asked by At

I've got a camera set up, and I can move with WASD and rotate the view with the mouse. But now comes the problem: I want to add physics to the camera/player, so that it "interacts" with my other jBullet objects. How do I do that? I thought about creating a RigidBody for the camera and storing the position there, so that jBullet can apply its physics to the camera. Then, when I need to change something (the position), I could simply change it in the RigidBody. But I didn't find any methods for editing the position.

Can you push me in the right direction or maybe give me an example source code?

2

There are 2 answers

0
seemywingz On BEST ANSWER

I was asking the same question myself a few days ago. My solution was as Sierox said. To create a RigidBody of BoxShape and add that to the DynaicsWorld. To move the camera arund, apply force to its rigidbody. I have damping set to .999 for linear and 1 for angular to stop the camera when no force is applied, i.e. the player stops pressing the button.

I also use body.setAngularFactor(0); so the box isn't tumbling all over the place. Also set the mass really low as not to interfere too much with other objects, but still be able to jump on then and run into them, and otherwise be affected by them.

Remember to convert your x,y, and z coordinates to cartesian a plane so you move in the direction of the camera. i.e.

protected void setCartesian(){//set xyz to a standard plane
    yrotrad = (float) (yrot / 180 * Math.PI);
    xrotrad = (float) (xrot / 180 * Math.PI);
    float pd = (float) (Math.PI/180);
    x = (float) (-Math.cos(xrot*pd)*Math.sin(yrot*pd));
    z = (float) (-Math.cos(xrot*pd)*Math.cos(yrot*pd));
    //y = (float) Math.sin(xrot*pd);
}//..

public void forward(){// move forward from position in direction of camera
    setCartesian();
    x += (Math.sin(yrotrad))*spd;
    z -= (Math.cos(yrotrad))*spd;
    //y -= (Math.sin(xrotrad))*spd;
    body.applyForce(new Vector3f(x,0,z),getThrow());
}//..


public Vector3f getThrow(){// get relative position of the camera

    float nx=x,ny=y,nz=z;
    float xrotrad, yrotrad;
    yrotrad = (float) (yrot / 180 * Math.PI);
    xrotrad = (float) (xrot / 180 * Math.PI);
    nx += (Math.sin(yrotrad))*2;
    nz -= (Math.cos(yrotrad))*2;
    ny -= (Math.sin(xrotrad))*2;
    return new Vector3f(nx,ny,nz);
}//..

to jump just use body.setLinearVelocity(new Vector3f(0,jumpHt,0)); and set jumpHt to whatever velocity you wish.

I use getThrow to return a vector for other objects i may be "throwing" on screen or carrying. I hope I answered your question and didn't throw in too much non-essential information.I'll try and find the source that gave me this idea. I believe it was on the Bullet forums.

------- EDIT ------

Sorry to have left that part out

once you have the rigid body functioning properly you just have to get it's coordinates and apply that to your camera for example:

float mat[] = new float[16];

Transform t = new Transform();
t = body.getWorldTransform(t);
t.origin.get(mat);

        x = mat[0];
        y = mat[1];
        z = mat[2];

   gl.glRotatef(xrot, 1, 0, 0);  //rotate our camera on teh x-axis (left and right)
   gl.glRotatef(yrot, 0, 1, 0);  //rotate our camera on the y-axis (up and down)
   gl.glTranslatef(-x, -y, -z); //translate the screen to the position of our camera

In my case I'm using OpenGL for graphics. xrot and yrot represent the pitch and yaw of your camera. the code above gets the world transform in the form of a matrix and for the purposes of the camera you need only to pull the x,y, and z coordinates then apply the transform.

from here, to move the camera, you can set the linear velocity of the rigid body to move the camera or apply force.

2
Sierox On

Before you read this answer I would like to mention that I have a problem with the solution stated in my answer. You can follow my question about that problem so that you can have the solution too if you use this answer.

So. First, you need to create a new BoxShape:

CollisionShape cameraHolder = new BoxShape(SIZE OF CAMERAHOLDER);

And add it to your world so that it interacts with all the other objects. Now you need to change all the methods about camera movement (not rotation) so that the methods move your cameraHolder but not your camera. Then set the position of your Camera to the position of the cameraHolder.

Again, if you have a problem where you can't move properly, you can check my question and wait for an answer. You also can find a better way of doing this.

If you have problems or did not understand something about the answer, please state it as a comment.