Rotating (pitching)

Hello all this might seem a newbie question but I have a problem with pitching. I have a spaceship spatial and if you press W or D it pitches either up or down.
This code snippet might help understand better: (this is in the onAnalog method)
[java]
if (name.equals(“PitchUp”)) {
ship.setLocalRotation(pitch);
degree = degree+1;
}
if (name.equals(“PitchDown”)) {
ship.setLocalRotation(pitch);
degree = degree-1;
}
[/java]

Pitch is defined as:

[java]
Quaternion pitch = new Quaternion();
pitch.fromAngleAxis(FastMath.PI*degree/180, new Vector3f(0, 0, 1));
[/java]
degree is just a field that starts off as 10.

When it rotates, it does the pitching as i wanted it to, but it sets all the other rotations as 0 so the yaw and roll is reset to 0. I would like to have the ship pitch, no matter what the roll and yaw angles are.
Thank you in advance for help!

Well dont use a new quaternion, use the current, transform to angels, modify, transform back, apply.

yeh, just modify the current transform relatively instead of absolute:

[java]
Quaternion pitch = new Quaternion().fromAngleNormalAxis(degree * FastMath.DEG_TO_RAD, Vector3f.UNIT_Z);
ship.rotate (0, 0 pitch);[/java]

@wezrule said: yeh, just modify the current transform relatively instead of absolute:

[java]
Quaternion pitch = new Quaternion().fromAngleNormalAxis(degree * FastMath.DEG_TO_RAD, Vector3f.UNIT_Z);
ship.rotate (0, 0 pitch);[/java]

I think you are mixing rotate methods. Also, this has the problem of being cumulative and it looks like he wants to keep the pitch degree separately.

To the OP, you basically have two choices:

  1. keep pitch, angle, yaw separately and always recompose them when needed. This is ok for Quake-style cameras but not really ok for “my spaceship can fly in any direction any time and up is always relative to me” cameras.
  2. only modify the pitch relatively, ie: don’t keep a “degree” that you add or remove from, just ship.rotate(0, 0, thisFramesPitch) I can’t see how you are doing your other angles so it’s hard to say what effect this will have.

I understand the relative transformation but using the code wezrule made, you cannot rotate with the parameters int, int, Quaternion. Do you know a way past this?
Thanks for the answers so far!

sorry, that should have been:

[java]ship.rotate (pitch);[/java]

yeh, what was I thinking ^^, [java]ship.rotate (0, 0, radian);[/java] does the same thing, as pspeed suggested

1 Like

Ah i managed to fix it using the relative rotation you all suggested (thanks!)
FYI:
[java]
Quaternion pitch = new Quaternion().fromAngleNormalAxis(FastMath.PI1/180, Vector3f.UNIT_Z);
Quaternion invPitch = new Quaternion().fromAngleNormalAxis(FastMath.PI
-1/180, Vector3f.UNIT_Z);

and
if (name.equals(“PitchUp”)) {
ship.rotate(pitch);
}
if (name.equals(“PitchDown”)) {
ship.rotate(invPitch);
}
[/java]

Edit 1: Thank you all for the answers! Very quick and helpful, I understand now.

@PTomfoolery said: Ah i managed to fix it using the relative rotation you both suggested (thanks!) FYI: [java] Quaternion pitch = new Quaternion().fromAngleNormalAxis(FastMath.PI*degree/180, Vector3f.UNIT_Z); Quaternion invPitch = new Quaternion().fromAngleNormalAxis(FastMath.PI*-degree/180, Vector3f.UNIT_Z); and if (name.equals("PitchUp")) { ship.rotate(pitch); } if (name.equals("PitchDown")) { ship.rotate(invPitch); } [/java]

Edit 1: Thank you all for the answers! Very quick and helpful, I understand now.

I think you get the same results from:

ship.rotate( 0, 0, FastMath.PI*-degree/180 )

…presuming degree is a per-frame value and not an accumulated value.

<cite>@pspeed said:</cite> I think you get the same results from:

ship.rotate( 0, 0, FastMath.PI*-degree/180 )

…presuming degree is a per-frame value and not an accumulated value.

Yes that was my mistake, it is now a set value of (1) instead of an incrementing field. XD

cool, yeh my original post probably should have used a 1 as well to avoid confusion.

You can also use the constant FastMath.DEG_TO_RAD instead of the Fastmath.PI/180.

I.e -1 * FastMath.DEG_TO_RAD (instead of FastMath.PI* -1/180)

Or if your actually going to keep it as 1, then its just FastMath.DEG_TO_RAD.

…and to be frame rate independent, don’t forget to multiply your delta by tpf. Figure out your rate of turn in “degrees per second” (or even better, radians per second) and then multiply it by tpf when calling rotate()

Sorry I don’t understand what delta is? What can you use rate of turn for?
:amused:

@PTomfoolery said: Sorry I don't understand what delta is? What can you use rate of turn for? :amused:

“delta” means change. Like when you rotate by 1 degree that is a 1 degree delta. The problem is that if you are doing this once per frame then at 30 FPS you rotate 30 degrees per second and at 60 FPS you rotate at 60 degrees per second… and at 1000 FPS you spin so fast you can’t see what’s going on.

So figure out how fast you want to turn in “degrees per second” (or even better just go ahead and precalculate radians per second) and then rotate( 0, 0, thatDeltaIJustDescribed * tpf )

1 Like

Ah i see thank you very much for all your help!

1 Like