🔒 Locked
SLERP!
Advertisement
Original Post
Well, it's pretty much the only way you would want to interpolate quaternions. So if you're using quaternions, your question is more or less 'why do we need to interpolate'.
Ahh man, there are so many different ways to use interpolation. It's mostly about having a goal state and a current state, and smoothly switching between them. The mouse controlling a camera for example. You could have two camera states. One for the mouse to directly modify, and one the camera uses to set the view attributes. Then each frame, interpolate the camera from it's current state towards the mouse state based on time. You then get very smooth movement, but movement that is still sensitive to the difference between the states. The more difference there is between the mouse and camera state, the faster the camera will move.
Did I get lossed there? Sorry. I'll give some more examples if you're interested [smile]
Ahh man, there are so many different ways to use interpolation. It's mostly about having a goal state and a current state, and smoothly switching between them. The mouse controlling a camera for example. You could have two camera states. One for the mouse to directly modify, and one the camera uses to set the view attributes. Then each frame, interpolate the camera from it's current state towards the mouse state based on time. You then get very smooth movement, but movement that is still sensitive to the difference between the states. The more difference there is between the mouse and camera state, the faster the camera will move.
Did I get lossed there? Sorry. I'll give some more examples if you're interested [smile]
Yes -- I am *very* interested.
I think SLERP might be able to help fix the problem I am having with my camera. Right now my camera movement is pretty jerky and I was thinking that I might be able to use SLERP to make it better? Without getting into too much detail I have two quats to represent rotations about the x and y axes and I was wondering if SLERP might somehow help me here?
or maybe I am still missing the point...either way, please enlighten me :D
thanks!
I think SLERP might be able to help fix the problem I am having with my camera. Right now my camera movement is pretty jerky and I was thinking that I might be able to use SLERP to make it better? Without getting into too much detail I have two quats to represent rotations about the x and y axes and I was wondering if SLERP might somehow help me here?
or maybe I am still missing the point...either way, please enlighten me :D
thanks!
Using LERP can actually be better than SLERP if the angle between the two quaternions is small. LERP has much less CPU cost than SLERP.
My game computes the quaternion 20 times per second and interpolates in between for smooth motion. Most objects don't rotate much in a 20th of a second, so LERP is perfect for this approach. It is very smooth.
My game computes the quaternion 20 times per second and interpolates in between for smooth motion. Most objects don't rotate much in a 20th of a second, so LERP is perfect for this approach. It is very smooth.
I just want to clarify something here...
q_pitch.rotate_about_axis(vector_x_axis, pitch);
q_heading.rotate_about_axis(vector_y_axis, heading);
cross_result = q_pitch * q_heading;
cross_result.create_GL_matrix(rot_matrix);
glMultMatrixf(rot_matrix);
That's 5 lines of code from my camera update function. Basically it just makes two quats to represent the rotation about the x and y axes, multiplies them, and then gets a resultant rotation matrix which is applied to the scene.
You're telling me that instead of multiplying the two quats I could apply LERP or SLERP and then use the matrix form of the output quat as my rotation matrix? If that's the case then how exactly is it that multiplying two quats and (S)LERPing them is the same?
q_pitch.rotate_about_axis(vector_x_axis, pitch);
q_heading.rotate_about_axis(vector_y_axis, heading);
cross_result = q_pitch * q_heading;
cross_result.create_GL_matrix(rot_matrix);
glMultMatrixf(rot_matrix);
That's 5 lines of code from my camera update function. Basically it just makes two quats to represent the rotation about the x and y axes, multiplies them, and then gets a resultant rotation matrix which is applied to the scene.
You're telling me that instead of multiplying the two quats I could apply LERP or SLERP and then use the matrix form of the output quat as my rotation matrix? If that's the case then how exactly is it that multiplying two quats and (S)LERPing them is the same?
SLERP itself doesn't provide smooth movement. But add an extra state in there and a weighted average and you can make your camera so smooth you'll get sick.
Well, the interpolation will be much easier if you multiply those two axis rotations (?) into a single rotation quaternion.
Make an extra quaternion for the camera. I like to call this "Attempt", where the real rotations are called "Current". Make all of your camera rotation adjustments to the Attempt quaternion. Don't mess with the "Current" one outside of this next bit of code. Now get ready for a real dump load of code to fry your brain..
Heheh. Yep, that much code will kill ya. In case you don't use it much (as I don't either) powf is raising 0.995 to the power of [insert time]. For example, if 5 milliseconds passed, factor will be 0.995 * 0.995 * 0.995 * 0.995 * 0.995. Also, make sure your time is time in milliseconds, where 1.0 is one millisecond, and not 1 second [smile]
Let me know if I missed an important detail. And let me know if it works [grin]
edit: Oh yeah. You can adjust the 0.995 to different values for different smoothness. Lower numbers will show better response, while higher numbers will be smoother. I would recommend values between 0.980 to 0.998 or so.
edit2: Crap. I totally forgot to mention that the time_in_milliseconds is time passed that frame. Not total time or such. Just the amount of time that passed by for that frame.
My skeletal animation seems really jerky when I just LERP. And I'm keeping up with 300 fps (not much movement in that time). Perhaps I'm doing something else wrong there.
Well, the interpolation will be much easier if you multiply those two axis rotations (?) into a single rotation quaternion.
Make an extra quaternion for the camera. I like to call this "Attempt", where the real rotations are called "Current". Make all of your camera rotation adjustments to the Attempt quaternion. Don't mess with the "Current" one outside of this next bit of code. Now get ready for a real dump load of code to fry your brain..
if(Attempt != Current){ FLOAT factor = powf( 0.995f, time_in_milliseconds ); Current = Slerp( Current, Attempt, 1.0f - factor );}Heheh. Yep, that much code will kill ya. In case you don't use it much (as I don't either) powf is raising 0.995 to the power of [insert time]. For example, if 5 milliseconds passed, factor will be 0.995 * 0.995 * 0.995 * 0.995 * 0.995. Also, make sure your time is time in milliseconds, where 1.0 is one millisecond, and not 1 second [smile]
Let me know if I missed an important detail. And let me know if it works [grin]
edit: Oh yeah. You can adjust the 0.995 to different values for different smoothness. Lower numbers will show better response, while higher numbers will be smoother. I would recommend values between 0.980 to 0.998 or so.
edit2: Crap. I totally forgot to mention that the time_in_milliseconds is time passed that frame. Not total time or such. Just the amount of time that passed by for that frame.
Quote:
Original post by BS-er
Using LERP can actually be better than SLERP if the angle between the two quaternions is small. LERP has much less CPU cost than SLERP.
My skeletal animation seems really jerky when I just LERP. And I'm keeping up with 300 fps (not much movement in that time). Perhaps I'm doing something else wrong there.
Jerky just means that when you choose a new target orientation for the camera, it pops from its current orientation to the target all in one frame. S/LERP allows you to make the orientation only change part of the way each frame until it reaches the target over several frames.
Technically, 'jerk' is the change in acceleration in a certain amount of time. When you change orientations in one frame, implicitly you're accelerating the camera instantaneously to the new direction, then decelerating it to a sudden stop, which creates a very high amount of 'jerk'. By accelerating it over several frames, then allowing it to slow down when reaching the target, you smooth out the change in acceleration per unit time, which decreases the jerk.
Technically, 'jerk' is the change in acceleration in a certain amount of time. When you change orientations in one frame, implicitly you're accelerating the camera instantaneously to the new direction, then decelerating it to a sudden stop, which creates a very high amount of 'jerk'. By accelerating it over several frames, then allowing it to slow down when reaching the target, you smooth out the change in acceleration per unit time, which decreases the jerk.
Quote:
Original post by lazE
So you're saying that the reason why my camera is jerky is because I am not using (S)LERP? Wouldnt that just make everything slower?
Huh? Me? I didn't say that. You asked how to make your camera smoother. That should do it. You could get a simular effect by interpolating whatever values control your camera's rotation without using SLERP. You seemed eager to use SLERP, so I tried to show you a way to use.
As for making everything slower, BS-er was suggesting that LERP can be used instead when the angle differences are small. This usually isn't the case with cameras. Especially if they are manually controlled. I use SLERP 55 times per character, every frame in my engine. 40 characters with a 2ghz cpu = 70 fps, and that's with rendering 3800 textured triangles per character [grin]
thanks for all of the help so far -- youve been great.
ok so Ive written my slerp function and im trying to update the camera but...im running into a slight problem ;(
heres what basically happens in my camera class:
1) generate two quaternion rotations about x and y
2) q1*q2
3) the slerp bit you mentioned
4) take output of slerp and use it to do rotations on scene
all of that is fine but heres where i get confused... see the next step is to pull out the directions for my camera from the two original quaternions. the y coordinate is pulled from the x axis rotation quat and the x and z coordinates are pulled from a mult of q2*q1. so i need to slerp the camera into those quats but im not completely sure how to go about doing that. do i slerp into different quats or should i use the same current one? thanks again!
ok so Ive written my slerp function and im trying to update the camera but...im running into a slight problem ;(
heres what basically happens in my camera class:
1) generate two quaternion rotations about x and y
2) q1*q2
3) the slerp bit you mentioned
4) take output of slerp and use it to do rotations on scene
all of that is fine but heres where i get confused... see the next step is to pull out the directions for my camera from the two original quaternions. the y coordinate is pulled from the x axis rotation quat and the x and z coordinates are pulled from a mult of q2*q1. so i need to slerp the camera into those quats but im not completely sure how to go about doing that. do i slerp into different quats or should i use the same current one? thanks again!
By "pull x and z coordinates", do you mean x and z directions? As in which way is up, right, and forward?
I don't use OpenGL, so I'm not quite sure what is happening in the code you posted. What is quaternions and what is matrices? Do you convert your camera quat into a matrix for OpenGL? It's much easier to get the directions from a matrix.
If you do convert to a matrix, just use the matrix values as the directions. There is no extra calculations needed. Again, I'm not sure how OpenGL stores matrices, so I'm not sure how to tell you to pull them apart. In DirectX, a matrix is like this..
Where R is right, U is up, and F is forward.
edit: Sorry, I didn't pay enough attention to your code. It's not that difficult to see what's happening [smile]
Yes, just pull the directions from rot_matrix, if directions is what you really mean. If you instead want the angles or such of your camera, that is a different story. I can't really tell you an easy and safe way to get euler angles from a quat. Why do you need them?
I don't use OpenGL, so I'm not quite sure what is happening in the code you posted. What is quaternions and what is matrices? Do you convert your camera quat into a matrix for OpenGL? It's much easier to get the directions from a matrix.
If you do convert to a matrix, just use the matrix values as the directions. There is no extra calculations needed. Again, I'm not sure how OpenGL stores matrices, so I'm not sure how to tell you to pull them apart. In DirectX, a matrix is like this..
Rx, Ry, RzUx, Uy, UzFx, Fy, FzWhere R is right, U is up, and F is forward.
edit: Sorry, I didn't pay enough attention to your code. It's not that difficult to see what's happening [smile]
Yes, just pull the directions from rot_matrix, if directions is what you really mean. If you instead want the angles or such of your camera, that is a different story. I can't really tell you an easy and safe way to get euler angles from a quat. Why do you need them?
I think I was pretty unclear and gave a whole bunch of really unncessary information.
Baaaasically when I want to work with my camera I am going to be dealing with a few quaternions (let's call them q1 and q2).
a) q1 * q2 will be give me the rotation on the scene.
b) information in q1 will tell me the camera's y direction.
c) information in q2 * q1 will tell me the camera's x and z directions.
My question is this -- do I need to interpolate the quaternions in b) and c) to the same quaternion I need interpolate a) to or am I supposed to use different quaternions? For instance I will interpolate a to quaternion_a and so forth.
Thanks!
Baaaasically when I want to work with my camera I am going to be dealing with a few quaternions (let's call them q1 and q2).
a) q1 * q2 will be give me the rotation on the scene.
b) information in q1 will tell me the camera's y direction.
c) information in q2 * q1 will tell me the camera's x and z directions.
My question is this -- do I need to interpolate the quaternions in b) and c) to the same quaternion I need interpolate a) to or am I supposed to use different quaternions? For instance I will interpolate a to quaternion_a and so forth.
Thanks!
Why do you need the camera's directions? To move objects relative to the camera? If so, you just want to interpolate the final result of your quat rotations. Use q1 and q2 exactly the same as you have been. Combine those to form what I called Attempt. Interpolate, then used what I called Current to create your matrix. Then pull your camera's current directions from the matrix, rather than quats.
Let me know if I'm totally not making sense.
Let me know if I'm totally not making sense.
Do you know how to pull the camera's directions from a matrix?
Do you know the variable names of a GL matrix? Or just what each variable represents? I am totally clueless as to how they are stored. You can pull the camera directions from it. I just can't tell you exactly how, unless someone could explain how it's variables are setup.
Do you know the variable names of a GL matrix? Or just what each variable represents? I am totally clueless as to how they are stored. You can pull the camera directions from it. I just can't tell you exactly how, unless someone could explain how it's variables are setup.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement