Rotate Object to Vector3f

Hi, i stuck again

My task is to rotate Object by value to it’s destination (where his destination).
I’m not using Spatial.lookAt because i need rotate object only by Y axis ( left, right )

I was looking for solution <span style=“text-decoration:underline;”>here</span>, but it didn’t help

I think I’m missing something in mind, need help

Here is peace of code which is responsible for rotating

[java]
final Vector3f vehiclePosition = mVehicle.getModel( ).getWorldTranslation( );
final Vector3f waypointPosition = mCurrentWaypoint.getPosition( );
final Vector3f direction = waypointPosition.subtract( vehiclePosition ).normalize( );

                final Quaternion targetRotation = mVehicle.getModel( ).getWorldRotation( );
                final Quaternion vehicleLocalRotation = mVehicle.getModel( ).getLocalRotation( );
                
                final Vector3f vehicleUpVector = vehicleLocalRotation.mult( Vector3f.UNIT_Y );
                targetRotation.lookAt( direction, vehicleUpVector );
                
                final Quaternion currentRotation = new Quaternion( );
                currentRotation.set( vehicleLocalRotation.getX( ), targetRotation.getY( ), vehicleLocalRotation.getZ( ), vehicleLocalRotation.getW( ) );
                
                mVehicle.getModel( ).setLocalRotation( currentRotation );

[/java]

The problems start after a long move. Object turns completely wrong, but it’s Quaternion is right

Can attach picture if it will help you understand my problem.

Why wouldn’t that be proper?

[java]thingie.lookAt(new Vector3f(0, yValue, 0), Vector3f.UNIT_Y);[/java]

I’m turning the car to it’s waypoint over some time that depends on maximum speed

Here is peace of code which is responsible for moving vehicle
[java]
final Vector3f vehiclePosition = mVehicle.getLocalTranslation( );
final Vector3f waypointPosition = mCurrentWaypoint.getPosition( );
final float distance = MathUtil.Distance2D( vehiclePosition, waypointPosition );

    if ( distance &lt; 0.1f )
        onWaypointReached( );
    else
    {
        final float deltaSpeed = mVehicle.mSpeed * timePerFrame;
        final Vector3f direction = waypointPosition.subtract( vehiclePosition );
        
        direction.normalizeLocal( ).multLocal( deltaSpeed );
        mVehicle.setLocalTranslation( vehiclePosition.addLocal( direction ) );
        
        updateRotation( );
    }

[/java]

Here is car rotation at start:

And here is rotation after some time:

Direction is totally fine, and Quatenion for getLocalRotation and from getWorldRotation shows exactly same value
What am i missing ?

[java]currentRotation.set( vehicleLocalRotation.getX( ), targetRotation.getY( ), vehicleLocalRotation.getZ( ), vehicleLocalRotation.getW( ) );[/java]

This will cause you some problems

1 Like
@wezrule said: [java]currentRotation.set( vehicleLocalRotation.getX( ), targetRotation.getY( ), vehicleLocalRotation.getZ( ), vehicleLocalRotation.getW( ) );[/java]

This will cause you some problems

i can’t see problem, please point me

@gforcer18 said: i can't see problem, please point me

That is the point. You can’t just mix the single values of two quaternions, its not like x,y,z describe rotations in angles around the single axes. What do you expect to happen by doing this?

1 Like

oh, god, finally i understood

if i’m using getWorldRotation then i shouldn’t mix it with getLocalRotation.

Thank’s

Nope, you’re not getting it. Although your reason above is true, that’s not the main problem you’re having.

Quaternion component values (x,y,z,w) are not humanly comprehensible. They do not mean anything without the context of the others.

Repeat as needed.

They are not angles. They are not vectors. They are not directions. For all practical purposes, they are magic values.

Do not try to understand them. Just learn to use the Quaternion as it is… and definitely don’t go mixing the values of one quaternion with the values of another. It’s nonsense.

2 Likes
@pspeed said: Quaternion component values (x,y,z,w) are not humanly comprehensible. They do not mean anything without the context of the others.

Repeat as needed.

They are not angles. They are not vectors. They are not directions. For all practical purposes, they are magic values.

Do not try to understand them. Just learn to use the Quaternion as it is… and definitely don’t go mixing the values of one quaternion with the values of another. It’s nonsense.

thanks, late but i still understood
i’ll try using slerp method

@pspeed said: Quaternion component values (x,y,z,w) are not humanly comprehensible.

http://www.maths.ed.ac.uk/~aar/papers/hanson.pdf

This is a book trying to state the same, just taking almost 600 pages to do so.

1 Like
@abies said: http://www.maths.ed.ac.uk/~aar/papers/hanson.pdf

This is a book trying to state the same, just taking almost 600 pages to do so.

Nice find. I’ve read the story of Hamilton’s walk before and always liked it.

I think if you can wrap your head easily around a complex number with three imaginary parts and/or clearly visualize a 4D sphere then you might have a chance of understanding what’s up. (P.S.: I cannot.)

But too many people look at four components with the first three named x,y,z (which is a shame) and think “angle axis”… and understanding slams shut in their face. :slight_smile:

It doesn’t help much that nearly every web site that has a section that starts “You can think of Quaternions kind of like…” is misleading at best or just plain wrong at worst.

Hi again

Here is my solution:
[java]
public final void onRotate( final float changeAmount, final Vector3f pDirection, final GameObject pObject, final float percentageDone )
{
final Quaternion vehicleLocalRotation = mVehicle.getLocalRotation( );
final Vector3f vehicleUpVector = vehicleLocalRotation.mult( Vector3f.UNIT_Y );

            final Quaternion targetRotation = mVehicle.getWorldRotation( );
            targetRotation.lookAt( pDirection, vehicleUpVector );
            
            vehicleLocalRotation.slerp( targetRotation, changeAmount );
            mVehicle.setLocalRotation( vehicleLocalRotation );
        }
        
        public final void onModificatorFinished( final Vector3f pDirection, final GameObject pObject, final Modificator pModificator )
        {
            final Quaternion vehicleLocalRotation = mVehicle.getLocalRotation( );
            final Vector3f vehicleUpVector = vehicleLocalRotation.mult( Vector3f.UNIT_Y );
            
            final Quaternion targetRotation = mVehicle.getWorldRotation( );
            targetRotation.lookAt( pDirection, vehicleUpVector );
            
            vehicleLocalRotation.slerp( targetRotation, 1f );
            mVehicle.setLocalRotation( vehicleLocalRotation );
        }

[/java]

Description:
I have mVehicle. that moves to next waypoint with different speed value. The task was to rotate vehicle in direction to waypoint for time that depends on vahicle speed and distance.

Calculation of changeAmount:
[java]
@Override
public final void onUpdate( final float timePerFrame ) throws Exception
{
if ( mFinished )
return;

    elapsedTime += timePerFrame;
    
    if ( elapsedTime &gt;= mDuration )
    {
        //Finish
        elapsedTime = mDuration;
        
        Stop( );
    }
    else
    {
        final float deltaTime = elapsedTime / mDuration;
        
        if ( remainingTime == 0 )//First call
        {
            //Use deltaTime
            mListener.onRotate( deltaTime, mDirection, mObject, deltaTime );
        }
        else
        {//Remaining time
            
            //Use remainDeltaTime
            if ( elapsedTime &gt;= remainingTime )
            {
                elapsedTime = mDuration;
                Stop( );
                return;
            }
            else
            {
                final float remainDeltaTime = elapsedTime / remainingTime;
                mListener.onRotate( remainDeltaTime, mDirection, mObject, deltaTime );
            }
        }
        
        remainingTime = mDuration - elapsedTime;
    }
}

[/java]

1 Like

This is new to me. If I wanted to set the rotation of one object to that of another (player location sent over a network, simplified):

[java]Quaternion q = new Quaternion();
q.set(spatial1.getRotation.getX(), spatial1.getRotation.getY(), spatial1.getRotation.getZ(), spatial1.getRotation.getW());
spatial2.setLocalRotation(q);[/java]

I do use this and it does work, but now I feel I don’t really understand it and it might be bug prone and is there a better way to do it?

I’d assumed it would because you’re getting the values of the first objects quaternion, sending them over the network and putting them right into another…

that is fine although I would use q = spatial.getLocalRotation().clone() instead. The original issue was with mixing 2 different quaternion values together