Hi,
I'm trying to compose two rotation transformations to a model, on two different axes, as demonstrated on the left example:

This is the code I tried:
Node donutModel = new Node();
Quaternion rotation1 = Quaternion.axisAngle(new Vector3(1.0f, 0.0f, 0.0f), 90); // rotate X axis 90 degrees
Quaternion rotation2 = Quaternion.axisAngle(new Vector3(0.0f, 1.0f, 0.0f), 90); // rotate Y axis 90 degrees
donutModel.setWorldRotation(rotation1);
donutModel.setWorldRotation(rotation2);
However, it looks like the second setWorldRotation() line overlaps the first one...
What is the correct way to compose rotations?
Hi @itanbp , I have not yet tried, but had found the following example in Kotlin. Maybe, it is useful: https://proandroiddev.com/building-arcore-apps-using-sceneform-part-4-9bb8374eaab4
To compose two quaternions, use the multiply method.
@gstanlo thanks!
I have tried below code for a rotate 3D object on both axes but still, it's not worked.
```
// Create the Anchor.
Anchor anchor = hitResult.createAnchor();
AnchorNode anchorNode = new AnchorNode(anchor);
anchorNode.setParent(arFragment.getArSceneView().getScene());
TransformableNode node = new TransformableNode(arFragment.getTransformationSystem());
node.setParent(anchorNode);
node.select();
Node andy = new Node();
andy.setParent(node);
andy.setRenderable(andyRenderable);
//andy.setWorldRotation(new Quaternion(new Vector3(0, 0, 1), 0));
Quaternion rotation1 = Quaternion.axisAngle(new Vector3(1.0f, 0.0f, 0.0f), 90); // rotate X axis 90 degrees
Quaternion rotation2 = Quaternion.axisAngle(new Vector3(0.0f, 1.0f, 0.0f), 90); // rotate Y axis 90 degrees
andy.setLocalRotation(Quaternion.multiply(rotation1, rotation2));
```
I suggest trying to rotate a child of the TransformableNode that is just a regular Node instead of the TransformableNode itself. The TransformableNode has a RotationController the controls the rotation of the node via a twist gesture.
As per your suggestion, I have applied rotation to transformableNode like this still it's not worked.
Anchor anchor = hitResult.createAnchor();
AnchorNode anchorNode = new AnchorNode(anchor);
anchorNode.setParent(arFragment.getArSceneView().getScene());
Quaternion rotation1 =
Quaternion.axisAngle(new Vector3(1.0f, 0.0f, 0.0f), 90); // rotate X axis 90 degrees
Quaternion rotation2 =
Quaternion.axisAngle(new Vector3(0.0f, 1.0f, 0.0f), 90); // rotate Y axis 90 degrees
TransformableNode node = new TransformableNode(arFragment.getTransformationSystem());
node.setParent(anchorNode);
node.select();
node.setWorldRotation(Quaternion.multiply(rotation1, rotation2));
Node andy = new Node();
andy.setParent(node);
andy.setRenderable(andyRenderable);
Try calling setLocalRotation or setWorldRotation on the object andy instead of node. The node is a TransformableNode, which means that the rotation is driven by the RotationController accessible via TransformableNode.getRotationController.
As you see my first comment in which I have already tried to setLocalRotation or setWorldRotation to andy still rotation is not working as expected.
Can you try andy.set* instead of node.set*?
@gstanlo Yes I have tried andy.setWorldRotation as well as andy.setLocalRotation.
```
Anchor anchor = hitResult.createAnchor();
AnchorNode anchorNode = new AnchorNode(anchor);
anchorNode.setParent(arFragment.getArSceneView().getScene());
TransformableNode node = new TransformableNode(arFragment.getTransformationSystem());
node.setParent(anchorNode);
node.select();
Node andy = new Node();
andy.setParent(node);
andy.setRenderable(andyRenderable);
Quaternion rotation1 = Quaternion.axisAngle(new Vector3(1.0f, 0.0f, 0.0f), 90); // rotate X axis 90 degrees
Quaternion rotation2 = Quaternion.axisAngle(new Vector3(0.0f, 1.0f, 0.0f), 90); // rotate Y axis 90 degrees
andy.setLocalRotation(Quaternion.multiply(rotation1, rotation2));
```
Is this not working properly? What happens?
@gstanlo model is rotated only in a y-direction. It is not rotated in an x-direction.
That should be working properly. Have you tried animating the angle to show the rotation?
I tested your code like this:
arFragment.getArSceneView().getScene().setOnUpdateListener(frameTime -> {
if (andy!=null) {
Quaternion rotation1 = Quaternion.axisAngle(new Vector3(1.0f, 0.0f, 0.0f), frameTime.getStartSeconds() * 50);
Quaternion rotation2 = Quaternion.axisAngle(new Vector3(0.0f, 1.0f, 0.0f), frameTime.getStartSeconds() * 25);
andy.setLocalRotation(Quaternion.multiply(rotation1, rotation2));
}
});
and you can see it rotating on two axes
Thanks, it's working. I have not put a code inside setOnUpdateListener that's why it's not working.
@gstanlo
this code doesn't work with the sceneview. how can i rotate the node to x or y axis in sceneview.
The listener code is only to show that the local rotation is changing. It should still work outside an update, it just won't animate.
Additionally, you should still be able to use update listeners in SceneViews. setOnUpdateListener is a method on Scene, which you can acquire from a SceneView object with getScene
@mistrydarshan99 @gstanlo
can you guys tell me how can i remove hand moving in scene ?
@basitsaleemmb could you open a new issue for this if it's not related to composing rotations?
Can we compose 3 rotations on a node?