anykeyh
November 20, 2007, 9:52am
1
Dear jME users!
Currently i had tried to make smooth rotation to a wanted direction.
It's work, but just a little: The object rotate to the wanted direction, but not smoothly…
Here is my code, call in each updateWorldData(time):
if(wantsLookTo!=null) {
//Retrieve object current direction
direction = getWorldRotation().getRotationColumn(2);
//Retrieve wanted direction
Vector3f wantedDirection = wantsLookTo.subtract(getWorldTranslation());
//Retrieve wanted quaternion
Quaternion dest = new Quaternion();
if(!wantedDirection.cross(Vector3f.UNIT_Y).equals(Vector3f.ZERO)) {
dest.lookAt(wantedDirection, Vector3f.UNIT_Y);
} else {
dest.lookAt(wantedDirection, Vector3f.UNIT_Z);
}
//We get the current angle between direction and wantedDirection
float currentAngle = FastMath.abs(direction.angleBetween(wantedDirection));
//We compute the amount of slerp interpolation btw each quaternion
float amnt = Math.min(1.0f, ((getMaxRotateCount()*time)/currentAngle) );
//Compute rotation
getLocalRotation().slerp(dest, amnt); //Vecteur courant!
}
What's wrong?
Thanks in advance!
hevee
November 20, 2007, 10:10am
2
Have you verified that
amnt
contains valid values? You seem to be using slerp correctly, but the problem could still be in in the interpolation value…
lex
November 20, 2007, 6:20pm
3
The code seems alright, as long as getMaxRotateCount() is the rotation speed in radians per second and time is the time per frame.
It could be easier to figure out if it was possible to run the rotation in a simple test.
The object rotate to the wanted direction, but not smoothly...
Can you give me more details on what happens when it rotates.
anykeyh
November 22, 2007, 12:00am
4
In some case my model jump to the wanted direction in one frame
but I think I've solved:
Here:
float currentAngle = FastMath.abs(direction.angleBetween(wantedDirection));
I've update by this:
float currentAngle = FastMath.acos(dest.dot(getWorldRotation()));
This is another way to find angle between each direction, but I don't understand why in some case the first make problems (for my experience if anyone have an answer, i will appreciate so ;))
elix
November 22, 2007, 2:03pm
5
anykeyh said:
In some case my model jump to the wanted direction in one frame :|
but I think I've solved:
Here:
float currentAngle = FastMath.abs(direction.angleBetween(wantedDirection));
I've update by this:
float currentAngle = FastMath.acos(dest.dot(getWorldRotation()));
This is another way to find angle between each direction, but I don't understand why in some case the first make problems (for my experience if anyone have an answer, i will appreciate so ;))
anglebetween method assumes that both of the vectors are normalized, check api.
obidobi
November 23, 2007, 3:43am
6
I am new myself to jMonkey but was playing around with rotations and Quats. I did something like this to rotate an object to a given direction
if( m_hasNewDirection )
{
//Retrieve current direction
fromDirection = getWorldRotation().getRotationColumn(2);
//Retrieve wanted direction
toDirection = m_lookAt.subtract(getWorldTranslation());
toDirection.normalizeLocal();
fromDirection.cross( toDirection, m_rotationAxis );
m_rotationAxis.normalizeLocal();
m_rotationAngle = fromDirection.angleBetween( toDirection );
m_deltaAngle = m_rotationAngle;
m_fromQuat.lookAt( fromDirection, m_rotationAxis );
m_toQuat.lookAt( toDirection, m_rotationAxis );
m_hasNewDirection = false;
}
if( m_deltaAngle > 0 )
{
deltaAngle = m_rotationSpeed*time;
if( deltaAngle < m_deltaAngle )
{
m_deltaAngle -= deltaAngle;
}
else
{
m_deltaAngle = 0;
}
m_rotQuat.set( getLocalRotation() );
m_rotQuat.slerp( m_fromQuat,
m_toQuat,
(1 - m_deltaAngle/m_rotationAngle) );
direction = m_rotQuat.getRotationColumn(2);
upVector = getWorldRotation().getRotationColumn(1);
getLocalRotation().lookAt( direction,
upVector );
}
This worked for my simple test :). Just had a simple object always follow the camera with its look.