RotateGesture3D auto constrained to axis

Hi,

On visionOS to manage entity rotation we can rely on RotateGesture3D. We can even with the constrainedToAxis parameter authorize only rotation on an x, y or z axis or even make combinations.

What I want to know is if it is possible to constrain the rotation on axis automatically. Let me explain, the functionality that I would like to implement is to constrain the rotation on an axis only once the user has started his gesture. The initial gesture the user makes should let us know which axis they want to rotate on.

This would be equivalent to activating a constraint automatically on one of the axes, as if we were defining the gesture on one of the axes.

RotateGesture3D(constrainedToAxis: .x)
RotateGesture3D(constrainedToAxis: .y)
RotateGesture3D(constrainedToAxis: .z)

Is it possible to do this?

If so, what would be the best way to do it?

A code example would be greatly appreciated.

Regards

Tof

Hi @ZeTof ,

There's no way to do this currently (at least that I could find!) so I'd really appreciate it if you filed a enhancement report at https://feedbackassistant.apple.com explaining your use case.

My attempt had been to chance a state variable that sets the axis to constrain while rotating, but since the RotateGesture onChanged closure is the only thing that is called as you rotate, it won't update the axis of constraint.

One idea that I can pitch for you to try is conditionally setting the rotation of each angle to constrain the axes as it's being updated:

 .gesture(RotateGesture3D()
            .targetedToAnyEntity()
            .onChanged({ value in
                
                let entity = value.entity
// state is the class shown below
                if !state.isRotating {
                    state.isRotating = true
                    state.startOrientation = .init(entity.orientation(relativeTo: nil))
                }
                let rotation = value.rotation
                var zRot = -rotation.axis.z
                var xRot = -rotation.axis.x
                var yRot = rotation.axis.y
                // conditionally set the rotation axes to 0 here based on the angle of rotation
                //...
                let flippedRotation = Rotation3D(angle: rotation.angle,
                                                 axis: RotationAxis3D(x: xRot,
                                                                      y: yRot,
                                                                      z: zRot))
                let newOrientation = state.startOrientation.rotated(by: flippedRotation)
                entity.setOrientation(.init(newOrientation), relativeTo: nil)
            })
                .onEnded({ value in
                    state.isRotating = false
                }))
public class EntityGestureState {
    
    /// The entity currently being dragged if a gesture is in progress.
    var targetedEntity: Entity?
    
   var currAxis: RotationAxis3D?
    
    // MARK: - Rotation
    
    /// The starting rotation value.
    var startOrientation = Rotation3D.identity
    
    /// Marks whether the app is currently handling a rotation gesture.
    var isRotating = false

}
RotateGesture3D auto constrained to axis
 
 
Q