Author Topic: FPS style camera rotation? HELP!  (Read 3896 times)

Offline LRFLEW

  • byte
  • *
  • Posts: 17
    • View Profile
FPS style camera rotation? HELP!
« on: March 13, 2012, 08:44:50 pm »
I'm trying to get started on my first FPS game, and I love that this API exists, as I would never get anywhere without it, but I'm so lost right now with the camera. 

I looked at the wiki (after first trying to figure out the api by itself), and have tried the code there for the fps camera, but that doesn't seem to work right.  I'm testing this by placing a triangle in front of the camera and using a MouseMotionListener to track the mouse movements and a Robot to prevent the cursor from running away (although it's not a perfect setup, but I'll deal with that later).  The problem is the code on the wiki makes no sense, and the outcome makes about as much sense as the code itself.  The triangle seems to warp and distort around as I look.  I can even get the triangle to appear rectangular, which befuddles me.  If there's an object behind me, no amount of looking around seems to find it. 

Also the code itself makes little sense in what functions are used.  Why does the yaw change with camera.rotateAxis() and the pitch with camera.rotateX()?  Why not camera.rotateY()? and why not camera.rotateCameraX() and camera.rotateCameraY()?!?

I need some clarification as to what's going on here and how I should fix it.  Any help is appreciated.

EDIT: Ok, after another look at the code, I realized that the thing I said about not being able to see something behind me was just a problem with the counter clockwise-ness of the vertices, but I am definitely getting a single triangle to have four sides, which totally and completely befuddles me.
« Last Edit: March 13, 2012, 10:24:56 pm by LRFLEW »

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12035
    • View Profile
    • http://www.jpct.net
Re: FPS style camera rotation? HELP!
« Reply #1 on: March 13, 2012, 11:32:31 pm »
I'm not 100% sure what the problem is...do you have a screen shot? The code in the wiki is fine, it has to be something else.

Offline LRFLEW

  • byte
  • *
  • Posts: 17
    • View Profile
Re: FPS style camera rotation? HELP!
« Reply #2 on: March 14, 2012, 04:48:22 am »
do you have a screen shot? The code in the wiki is fine, it has to be something else.

Ok, here is both the code I used, and a snapshot of a particularly weird point where the triangle suggested a trapezoid shape.  (note that you can see four sides, if only a little of some of them)

AND please tell me the difference is between camera.rotateAxis(camera.getYAxis(), dx / 500f), camera.rotateY(dx / 550f), and camera.rotateCameraY(dx / 500f)

<Note, links have been removed as the files are no longer hosted>
« Last Edit: March 15, 2012, 10:19:28 pm by LRFLEW »

Offline kburden000

  • byte
  • *
  • Posts: 7
    • View Profile
Re: FPS style camera rotation? HELP!
« Reply #3 on: March 14, 2012, 06:46:34 am »
I can answer the camera pitch/yaw behavior portion of your question.
To wit why does the camera appear to ROLL when you try to turn it.
Remember that you have two different "coordinate systems" involved World and Camera
Also that cameras are usually pointed towards something ( usually as the result of a LookAt )
meaning that the UP Vectors in the two systems are NOT parallel.
What's an UP vector? Look it UP ;)

Imagine that you're in your world looking down at your object.
This means that your head may be bent at the neck. That is to say that your head is not straight up.
Now when you rotate your head about a single axis you're doing it in head ( i.e. camera ) coordinate system.
That means your turning it about your neck, not about your body.
Since your neck is bent it's like twisting your neck while looking down, the ground appears to swing back and forth.
What you want is to turn your whole body. not just twist your neck.

Here's some code I use.

Code: [Select]
private void turnLeft( float amt)
{
SimpleVector upOld = world.getCamera().getUpVector();
SimpleVector dirOld = world.getCamera().getDirection();
// Amt is in pi rads so its value would be something like 0.1f
// NOTE which world axis to rotate around
// depends on your coordinate system
// That is use whichever is the "UP" vector in your system
// So try different positions for the amt var say X or Z instead
// of Y as shown below in order to get the effect you want
SimpleVector rotation = new SimpleVector(0, amt, 0);
upOld = upOld.rotate(rotation);
dirOld = dirOld.rotate(rotation);
world.getCamera().setOrientation(dirOld, upOld);
}

It rotates the camera  along the "body" axis which unlike the neck axis is normal ( orthagonal/perpendicular) to the ground.
The camera ( i.e your head ) goes along for the ride and turns without changing your so called pitch/yaw.

Hope this explains things for you.
« Last Edit: March 14, 2012, 07:01:46 am by kburden000 »

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12035
    • View Profile
    • http://www.jpct.net
Re: FPS style camera rotation? HELP!
« Reply #4 on: March 14, 2012, 09:17:44 am »
Thanks for the test case. This is caused by the clipping on the view plane. You are very close to that triangle and the triangle is very small. By default, your triangle actually falls into the view plane (z=1), which makes the clipped result look strange. This isn't a real world scenario...try this instead:

Code: [Select]
room.addTriangle(new SimpleVector(10, -10, 1), new SimpleVector(-10, -10, 1), new SimpleVector(0, 10, 1));
...
camera.setPosition(0, 0, -10);

Offline LRFLEW

  • byte
  • *
  • Posts: 17
    • View Profile
Re: FPS style camera rotation? HELP!
« Reply #5 on: March 14, 2012, 04:32:04 pm »
That means your turning it about your neck, not about your body.
Oh :P.  That makes a lot more sense.  Thank you very much!

This is caused by the clipping on the view plane. You are very close to that triangle and the triangle is very small.
I didn't think that would have been so much of an issue, but the code you provided fixed the problem, so it had to be the issue.  Thanks. 

Now I have two more, somewhat related questions that have popped up through working this out.

1) I want keep track of the current angle, not the change in angle needed to rotate.  This is because along with wanting to be able to ask jPCT if I have a ray-colision for when the weapon gets fired, I also need to be able to communicate to a server where my player is, both in place and in rotation, so that it can verify my hits.  I can keep track of both a delta and a total, but I'm worried that there might be a bug, the numbers go out of sync, and I can't get the numbers back into place.  Is there a way to SET the pitch/yaw angle?

EDIT: Ok, I went ahead and looked at the javadocs and (yes) the JD-GUI of the Matrix class to see if I can understand what's going on, and WOW THAT'S COMPLICATED!  I might need to look into it deeper if I plan on understanding what the heck is going on there and how I can utilize it to set pitch and yaw values...

2) I had thought that 1 in the word object would represent something like 1 foot, but obviously it's a lot closer than that.  About how big of a box would I need to make a 10 foot (3 meter) cube room? (I do realize that I would need to first invert() the box)
« Last Edit: March 14, 2012, 10:54:18 pm by LRFLEW »

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12035
    • View Profile
    • http://www.jpct.net
Re: FPS style camera rotation? HELP!
« Reply #6 on: March 15, 2012, 12:18:59 am »
Why not simply transfer the rotation matrix? At least that's what i'm doing...

There is no matching between a unit in world space and in the real world. You should use a reasonable value though, like 10 units=1 meter or similar.

Offline LRFLEW

  • byte
  • *
  • Posts: 17
    • View Profile
Re: FPS style camera rotation? HELP!
« Reply #7 on: March 15, 2012, 04:23:47 am »
Why not simply transfer the rotation matrix?
That makes sense.  Now I just need to serialize it...

There is no matching between a unit in world space and in the real world. You should use a reasonable value though, like 10 units=1 meter or similar.
I had a feeling that there was no universal unit for this, but with the standard FOV of 1.25, 10 seems quite close.  Is there a standard at all between FOV and distance when it comes to making things look like it's normal sized?  Should the player's hit box be at least 1 in front of the player to prevent the clipping that I saw in the code I provided? This is my first experience with 3d game development, so I don't really understand how the units will inevitably add up. 

Offline EgonOlsen

  • Administrator
  • quad
  • *****
  • Posts: 12035
    • View Profile
    • http://www.jpct.net
Re: FPS style camera rotation? HELP!
« Reply #8 on: March 15, 2012, 08:37:56 pm »
Fov actually doesn't matter. What matters is the position of the camera relative to the model. An example: I have this rpg project going on and the scaling of the dungeon was much different from the scaling of the terrain. In the dungeon, 10 units were similar to 2m, but outside, 10 units were similar to ~30cm. This caused the problem, that the collision ellipsoid had to be changed between both scenarios and the arrows of the bow appeared much to large in the dungeon etc. So i rescaled everything inside the dungeon by a factor of ~7...the mesh itself, the camera position and the collision ellipsoid. The visual outcome is exactly the same as before...just with the correctly sized arrows and no need to fiddle around with the ellipsoid. What i'm trying to say with this: It doesn't matter as long as you scale everything, not just the mesh. Just keep it within a reasonable range.