[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

Wezrule had the answer:



for #2 – I really think it’s what i told you before about rot_start and rot_end continuously changing. Even for the moveSpatial() your doing it wrong, but the only reason its working is because your end Vector never changes so it will eventually reach there, while in your rotation function, your end Vector is based on the start vector of the spatial each frame so in effect is never reachable, which is probably why your getting those weird effects. You just need to initialize them once and then interpolate between them