Dependent Rotations

Oki here are two drawings that might help explaining.

Dont Forget this is only when the blue marker is obscured, other times it works fine.

What I am able to do is get the webcam movement by analysing the model view matrix of the board (the 6 checkboard squares together). And it works gr8 when the blue marker is in the center of the board.

For example if I was to rotate 90


The diagrams surely makes a better explanation. Now let's see if we get a better understanding :D.

I understand that you can find the position and orientation of the board (probably provided by your AR library?). What you need to do is to translate and rotate your model in relation to the translation and rotation to the board.

If this is the case, the easiest way to achieve that with jME is to attach your model node to your board node. That way they will be linked and any modification made to the board will affect the model.


The problem here will be whether you work with world coordinates or local coordinates. Because from the moment you attach the model to your board, you need to work with it using its local coordinates.

The best way to start is to attach the model to the board before you modify model coordinates (when is it centered in its local reference system).  If you just do that, the model will move with the board.

To account for the model's marker independent movement, you would need to transform from world to local coordinates, since I can imagine your AR toolkit is only providing you global coordinates.

Since your model is actually independent from the board, one option would be to attach it only when the marker is not visible.

0) First you update the position of the board.

1.1) When the model marker dissapears, we attach it to the board (note that this is not completely natural: your model could be outside the board?).

2.2) Now the model is attached but its coordinates are not correct, because its coordinates were previously world coordinates, and now they depend on the board's position and orientation). To solve this, we convert them from world coordinates to local coordinates:

// Converts model translation to local coordinates, now that it is attached to the board

board.worldToLocal(model.getWorldTranslation(), model.getWorldTranslation());

2.3) We now need to update the model's world vectors.


3) As soon as you get information again from the model's marker, you detach the model and set its coordinates.

I hope this helps now :D. However I am not sure about model orientation… let's see.

Honestly I am not the best person to answer this anyway.

thanks a lot for the quick post I will try it right now!

well I cant say it got better or not cause I still cant make the node rotate :S I thought it would be just like in the orbiting example…

I suggest you use matrix math to solve this problem. Splitting the matrices into rotation/translation makes the problem a lot harder.

To see if I understand the problem, I'll recap. You get two matrices from artoolkit. One for the blue marker, and one for the board. You want the model to follow the blue marker. If the blue marker is hidden, you want the model to follow the board. So the model is attached to the board relative to where the blue marker was last visible.

I would solve this the following way. Create two spatials on the root. One for the blue marker and one for the board. Every frame you update the translation/rotation of the spatials to match artoolkit. When the blue marker is visible you attach the model to the blue spatial. When the blue marker is hidden you reattach the model from the blue spatial to the board spatial. The trick now is to insert a another spatial inbetween the board and model. This spatial will contain a matrix that transforms from board space into the last seen blue space.

If A is the last known blue marker modelview matrix, B is the board modelview matrix (at the time the blue marker was last seen), then the inbetween matrix C could be (I suck at this so it's probably wrong):

C=A matrixMul matrixInvert(B)

This transform never changes as long as the blue marker is hidden. When the board modelview matrix is updated the model will stay attached relative to the board.

so I would have this

spatial node - normal artoolkit model view matrix


    |__ "C" node - in between matrix


                      |_ "blue" model


ho! my head is starting to hurt :frowning: could anyone tell me the best way to change between nodes in this particular case ?

You don't have to reatach, since it might be slow, depending on how JME implements it.

Instead you could have the following structure:






if blue marker is visible

  set markerNode transform to blue marker model view matrix

  set compensationNode to identity

else if blue marker is hidden and border marker is visible

  set markerNode to board model view matrix

  set compensationNode to the in between matrix

The important thing is to include the in between matrix when the blue marker is hidden

oki so this is what i have done

compensationNode = new Node();
markerNode= new Node();
compensationNode .attachChild(aux.getModel());

then when detected I do this:

Vector3f position = matrix.toTranslationVector();

Quaternion orientation = matrix.toRotationQuat();

markerNode.updateGeometricState(0, true);
Matrix4f identity = new Matrix4f();
identity .loadIdentity();
compensationNode.updateGeometricState(0, true);

lastDetectedMatrix= matrix;

and when in the first frame it  is not detected I do this:

betweenMatrix = lastBoardMatrix.mult(lastDetectedMatrix.invert());

and in every not detected frame

        Quaternion orientation = newBoardMatrix.toRotationQuat();
        Vector3f posicao = newBoardMatrix.toTranslationVector();
        Quaternion qdif = betweenMatrix .toRotationQuat();
        compensationNode.getLocalTranslation().set(betweenMatrix .toTranslationVector());


        markerNode.updateGeometricState(0, true);
        betweenMatrix .updateGeometricState(0, true);
        betweenMatrix .updateRenderState();

I have tried to change the other and all but it didnt work, I have been studying you idea and it really should be workign :S.
I think the problem must be in the way I am obtaining the betweenMatrix, cause even when I just rotate the compensationNode it will rotate in a really strange way, and when I translate it disappears from screen, when it should just move a little ...

And again I would like to thank everyone that has been trying to help me ;)

The betweenMatrix might be:

betweenMatrix = lastBoardMatrix.invert().mult(lastDetectedMatrix);

The board matrix is the one has to be inverted. I'm not completely sure if it needs to be left or right of the blue matrix. You should try both.

The equation I've tried to solve is:

boardMatrix * compensationMatrix = blueMatrix

Wich means that if you attach the compenstion node to the board node, you'll end up with the same transform as the blue marker.

changing to

betweenMatrix = lastBoardMatrix.invert()).mult(lastDetectedMatrix;

puts the marker rotating fine, but the translation continues with problems :(
If i just cover the blue marker and make only translation movements to the board everything works fine BUT if i rotate it starts to make arc movements.

To test things out I commented the part where I translate the compensationNode, and as expected the blue model was positioned in the center of the board but kept is own rotation even while moving and rotating the board.

I guess there must be a problem with the order in witch I am applying the rotation and translation to the node :S any ideas ?

well another stupid video to show whats happening lol the teapot is in the center of the modelNode, and the line is the betweenMatrix.toTranslationVecto(), if u see carefully the teapot and the model marker have always the same rotation so its working right the problem is with the vector that shouldnt have any indepent rotation :S

I have to admit I have not idee where the bug is. I can try to give some debug tips. You have to try to narrow down where to problem is.

I suggest that you don't hide the "blue" marker, and calculate the compensation matrix every frame. Draw two models, one at the blue marker, and one at the board+compensation node. The two models should be drawn at exactly the same position/rotation (maybe draw two models so you can see both if they use the same transform). If they are not then the compensation matrix may be wrong, or there may be a bug in the way the matrices are applied to the jme nodes.

Another thing you could try is to do some sanity checks on the matrices you get from artoolkit. The blue marker should be on the same plane as the board.

Thanks for your help tom, I will try to get some sleep now and tomorrow I will try to do some more debug and post more results.

EDIT the ideia that I posted was wrong but my problem with nodes continues the same /EDIT

Could anyone please give me a better explanation of what happens and what I should do when rotating separate nodes ? I have been testing with the simple planet and moon example and I havent been having any of this strange problems :S

PS: do you think it would be better to make a separate post just about my problem with nodes ?

Again thanks for all the help you guys have been giving me :smiley:

Well just to make sure the in-between matrix was working I took a different approach,and used the the board matrix on the markerNode and a compensation matrix between the board matrix and the last detected matrix from the marker.

So I got this:






if blue marker is visible

  set markerNode to board model view matrix

  set compensationNode to the between matrix (calculate a new one)

else if blue marker is hidden and border marker is visible

  set markerNode to board model view matrix

  set compensationNode to the in between matrix  (use the last one detected)

When the maker is detected everything works gr8 so the matrix is being well calculated.

When its not detected if I just translate the board it works gr8 only problem is when I make rotations.

I am starting to think this as nothing to do with the nodes order in which they are applied cause if it works gr8 when detected it should still be working after, what I think it may be is some problem with the rotation matrix.