# [SOLVED] Jme3 Beginner: How to rotate a spatial

I call this function at the update()

[java]public void rotateSpatial(float tpf, String type, String id, float degree, float rotation_time ) {

scale += tpf/rotation_time;

spatial.rotate(0, FastMath.PI * degree / 180, 0);

if(scale >= 1) //then you reached the end/destination

{

isMoving = false;

}

}[/java]

However the spatial keeps rotating in circles non stop. How can I make a spatial rotate a certain number of degrees that takes it a certain rotation time? Hoping to do so frame by frame (thats why update() calls the rotateSpatial())

Thanks

If you post this in the physics forum because you have added a RigidBodyControl to the spatial then you will have to move the spatial by applying forces or set the rigid body to kinematic mode. If not then you simply donâ€™t check for the isMoving boolean.

Even if I take it off it still doesnâ€™t stop rotating

I havenâ€™t done this before, but you should be able to interpolate it like you did with the translation. Using slerp from quaternions http://hub.jmonkeyengine.org/javadoc/com/jme3/math/Quaternion.html#slerp(com.jme3.math.Quaternion,%20com.jme3.math.Quaternion,%20float)

I need something similar to this (works for the moveSpatial perfectly)

[java]public void rotateSpatial(float tpf, String type, String id, float speed_deg, float rot_time ) {

end = new Vector3f (0,FastMath.PI * speed_deg / 18,0);

start = spatial.getLocalTranslation();

scale += tpf/10; //this will make it take 10 seconds to reach the end, from the the start

Vector3f newLocation = FastMath.interpolateLinear(scale, start, end); // this needs to be changed

spatial.setLocalTranslation(newLocation); // this needs to be changed to rotation something

if(scale >= 1) //then you reached the end/destination

{

isMoving = false;

}

}[/java]

[java]public void rotateSpation(float tpf, String type, String id, float degree, float rot_time ) {

start = new Vector3f (getRotation());

end = new Vector3f (setRotation(degree));

scale += tpf/rot_time; //this will make it take rot_time seconds to complete rotation

Vector3f newLocation = FastMath.interpolateLinear(scale, start, end);

cube.setLocalTranslation(newLocation);

if(scale >= 1) //then you reached the end/destination

{

isMoving = false;

}

}[/java]

Where

[java]

public Vector3f getRotation()

{

float[] rotation = cube.getLocalRotation().toAngles(null);

return new Vector3f(rotation[0],rotation[1],rotation[2]);

}

public Vector3f setRotation(float degrees)

{

return new Vector3f(0,FastMath.PI * degrees / 18,0);

}[/java]

It still doesnâ€™t work though. Is there a specific interpolation function for quaternions?

did you look at slerp like i posted? i think it does what you want

Yes I tried something like this:

[java]public void rotateSpatial(float tpf, String type, String id, float speed_deg, float rot_time ) {

rot_start = new Quaternion().set( spatial.getLocalRotation() );

rot_end = new Quaternion().set( spatial.getLocalRotation() ).multLocal(

new Quaternion().fromAngleNormalAxis( 0.5f, new Vector3f( 0, 1, 0 ) ) );

rot_start.normalize();

rot_end.normalize();

scale += tpf/rot_time; //this will make it take rot_time seconds to complete rotation

spatial.getLocalRotation().slerp( rot_start, rot_end, rot_time );

if(scale >= 1) //then you reached the end/destination

{

isMoving = false;

}

}[/java]

It rotates but still the same issue. Unlimited number of rotations when the function is called.

add .clone() here, see if it helps

rot_end = new Quaternion().set( spatial.getLocalRotation().clone() ).multLocal(

new Quaternion().fromAngleNormalAxis( 0.5f, new Vector3f( 0, 1, 0 ) ) );

nope same issue

now that i look at it, surely you donâ€™t want rot_start and rot_end continuously changing like that? I think you need to factor that out of the update loop so that it is called only once.

but thats how I did it with the moveSpatial() function and worked just fineâ€¦ could it be something wrong with the slerp()?

the update has something like this (which I think is not a bad design)

[java]update(float tpf)}{

counter += tpf;

if(rounded_counter >= trace_timer)

{

if(isMoving)

{

motionState(event, tpf, type, id, speed, x, y, z);

}

else if(scale == 0)

{

isMoving = true;

}

}

}[/java]

motionState could be a rotate, a movement, etccc

1 Like