JM3 – Missing something or setLocalTranslation bug?

No, I don’t. These are from motion plus, not accelerometer. In the following picture from Osculator you can check what I’m sending with which values.







The shaking happens only in rotation and the values I am receiving from Osculator do not justify that shaking. The position is as smooth as expected from the values I receive and there is no problem with that. See the following pictures that are taken in less than a second. You can see that the values are almost the same but the figure is instantly mirrored.



First screenshot



Second screenshot



Thank you for your willing to help so far!

I still have the problem, I tried to reduce the times I execute the code of the acceptMessage but I still have the mirroring effect…



Normen, I read again one of your answers and on second thought something does’t feel right to me. You have written the following:



You simply should not modify an object from two threads at the same time. Imagine this: The OSC thread calls the acceptMessage() method and directly modifies the rotation Matrix or Quaternion of the Spatial. It consists of 4 or more float values. The OSC thread starts writing these and has written only 2 of them when the OpenGL thread comes and reads all 4 of them to paint the Spatial → wrong rotation.



I understand the general idea, but on second thought how does this justify the mirroring since the values I receive from the WiiMote are almost the same? Even if OSC thread has written only the 2 of them what is so radical different in other 2 values to have the mirroring?



And now I have applied the Callable etc and I understand the usefulness of them, thanks to you, but the mirrored shaking remains.

I can’t exactly see in the screenshot, but which value is printed out, is it tmpRotateValueRoll or rotateValueRoll?

Just that I see you’re flipping the angle before setting it in this code:

[java]

if ((HDMoveListener.previousValueRoll > rotateValueRoll && rotateValueRoll > 0)

|| (HDMoveListener.previousValueRoll < rotateValueRoll && rotateValueRoll rotateValueRoll && rotateValueRoll > 0)

|| (HDMoveListener.previousValueRoll < rotateValueRoll && rotateValueRoll < 0)))

tmpRotateValueRoll = rotateValueRoll;

else

tmpRotateValueRoll = -1 * rotateValueRoll;[/java]

Can you perhaps print out the angle or the quaternion itself right before setting it on the object?

Well, problemo solved (well not exactly - read the post)! Thank you both guys! :slight_smile:



After your post Momoko_Fan I replaced that piece of code with the following line of code just for quick testing:



[java]tmpRotateValueRoll = rotateValueRoll;[/java]



and yes, the shaking has stopped!



However I remember that that piece of code was working just fine when I was using .rotate method. This is the reason I wasn’t searching the problem there. Besides (in order to answer your question too Momoko_Fan), the value that I was printing was tmpRotateValueRoll that I was using in the rotaion code. When I switched to setLocalRotation the shaking started.



That piece of code is also there for a reason. My shadow figure has to move left/right (and be able to look left/right) so with a press of a WiiMote button, I rotate the figure to look left or right. Tha piece of code is to make sure that the rotation with WiiMote is “rotated” too, because otherwise if I rotate left the WiiMote the figure rotates right and vise versa.



I also saw another problem. The button rotation of the figure in order to change left/right look doen’t work either. If I remove the rotation of the figure (with the rotation of WiiMote) and have the X/Y axis movement only it works. This is something I have noticed from the start but I thought it was from the shaking problem.



For the record here is the code of the “Button rotation”.



[java]

/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.

    */

    package guitesting.WiiOSC;



    import com.illposed.osc.OSCMessage;

    import com.jme3.math.FastMath;

    import com.jme3.scene.Spatial;

    import java.util.Date;

    import java.util.concurrent.Callable;

    import java.util.concurrent.ExecutionException;

    import java.util.concurrent.Future;

    import java.util.logging.Level;

    import java.util.logging.Logger;

    import main.ShadowMove;

    import main.TestBrickWall;



    /**

    *
  • @author andreas

    */

    public class PressBListener extends WiiOSCListener



    private ShadowMove nm;

    protected static Spatial tempShadowPuppet;



    public PressBListener()

    {

    super();

    this.nm = null;

    }



    public PressBListener(ShadowMove nm)

    {

    this.nm = nm;

    }



    @Override

    public void acceptMessage(Date date, OSCMessage oscm)

    {

    super.newOscMessageReceived();

    PressBListener.tempShadowPuppet = this.nm.getNionios();



    if (this.getOscMessagesReceivedNumber() % 2 == 1)

    {

    Future fut = this.nm.enqueue(new Callable()

    {



    public Void call() throws Exception

    {

    PressBListener.tempShadowPuppet.rotate(0, FastMath.PI, 0);

    HDMoveListener.shadowMovingLeft = !HDMoveListener.shadowMovingLeft;

    return null;

    }

    });

    try

    {

    //to retrieve return value (waits for call to finish, fire&forget otherwise):

    fut.get();

    }

    catch (InterruptedException ex)

    {

    Logger.getLogger(HDMoveListener.class.getName()).log(Level.SEVERE, null, ex);

    }

    catch (ExecutionException ex)

    {

    Logger.getLogger(HDMoveListener.class.getName()).log(Level.SEVERE, null, ex);

    }

    }

    }

    }

    [/java]



    I hope I didn’t confused you with my writing. For now I’m not asking directly for your help since I have some ideas for now to try (for example to change rotate with setLocalRotation in the above code too) and I don’t want to waste your time for everything. If you have any quick thoughts from the first reading, will be appreciated.



    I let you know if have any success with the things I’ll try (or you proposed me). Thank you so much for your time!

Now the shaking is no longer an issue, I figured it out completely. Thanks again!



The rotation problem I described above remains. I tried to replace rotate() in the above code with setLocalTranslation() but the problem remains. Is any conflict between the 2 calls for rotation?



With the button I rotate the shadow figure 180 degrees in the y axis and with WiiMote I rotate the shadow figure in z-axis. Why y-axis rotation doesn’t work when I enable z-axis rotation?

Glad you got it to work :smiley:

I am not sure if I can help you with the other issue, I am having some trouble understanding what the code does.

Hello! Do you have difficulty to understand my description or the last code I posted? If it is the second the only code that matters in logic level is the following:



[java]

PressBListener.tempShadowPuppet.rotate(0, FastMath.PI, 0);

HDMoveListener.shadowMovingLeft = !HDMoveListener.shadowMovingLeft;

[/java]



The second line exists because I want to know the direction my figures look (left or right). The change I made (replace the above code) and has the same behaviour is the following:



[java]

if(HDMoveListener.shadowMovingLeft)

PressBListener.tempShadowPuppet.setLocalRotation(new Quaternion().fromAngleAxis(FastMath.PI, new Vector3f(0, 1, 0)));

else

PressBListener.tempShadowPuppet.setLocalRotation(new Quaternion().fromAngleAxis(2*FastMath.PI, new Vector3f(0, 1, 0)));



HDMoveListener.shadowMovingLeft = !HDMoveListener.shadowMovingLeft;

[/java]



Both of them work if I remove the rotation of the figure in HDMoveListener (which I have also posted). By saying remove I mean to put in comments the following line of code in line 131:



[java]

HDMoveListener.tempShadowPuppet.setLocalRotation(new Quaternion().fromAngleAxis((float) Math.toRadians(tmpRotateValueRoll), new Vector3f(0, 0, 1)));

[/java]



It seems that there is a strange conflict.

I am still struggling with this. Is it possible to be some kind of conflict? Between the 2 rotations? It seems like that when I press B to accomplish rotation in Y axis by 180 degrees it is instantly cancelled by the rotation in z-axis which is made by rolling wiimote. Is it any way to avoid that?

You should probably store both rotations not directly in the spatial but as quaternions. Each time one of them is updated you combine them and apply that to the Spatial. Remember to store them in a thread safe way (e.g. synchronized accessors & multiply method) to avoid problems :wink:

I will try that tomorrow since I am very tired now, thanks. Has slerp() method (that I saw in rotate wiki) to do with that combination? If yes I don’t understand right now what the t argument in [java]public Quaternion slerp(Quaternion q1, Quaternion q2, float t)[/java] or changeAmnt argument in [java]public void slerp(Quaternion q2, float changeAmnt)[/java] are for (I saw the javadoc).

https://wiki.jmonkeyengine.org/legacy/doku.php/rotate

I tried the “adding rotations” from the wiki with no success. However I noticed something. By default the shadow figure looks to the left. If in the initialization I rotate it in order to look right by default, it doesn’t work except I deactivate the roll rotation in HDMoveListener (with comments). The strange thing is that this initial rotation (in order to look right instead of left) is made before I initialize the OSC thread. Ι don’t understand…

Me neither, I am sorry, I dont know what exactly you are talking about :slight_smile: But if you need some initial rotation, attach the model to another Node, rotate the model so its correct (localrotation!) and then just move/rotate the node with you WII.