1

In my code, I am currently loading an Entity using the .loadAsync(named: String) method, then adding to my existing AnchorEntity. As a test, I am then rotating my Entity 90°, and would like to determine how to then get the current angle of rotation.

The long-term intent is that I am going to allow users to rotate a model, but want to limit the rotation to a certain degree (I.E., the user can rotate the pitch of the model to 90° or -90°, but no further than that). Without being able to know the current angle of rotation for the Entity, I am unsure what logic I could use to limit this.

Entity.loadAsync(named: "myModel.usdz")
    .receive(on: RunLoop.main)
    .sink { completion in
        // ...
    } receiveValue: { [weak self] entity in

        guard let self = self else { return }
        self.objectAnchor.addChild(entity)
        scene.addAnchor(objectAnchor)
        
        let transform = Transform(pitch: .pi / 2,
                                    yaw: .zero,
                                   roll: .zero)
        
        entity.setOrientation(transform.rotation,
                                  relativeTo: nil)
        
        print(entity.orientation)

        // Sample Output: simd_quatf(real: 0.7071069, 
        //                           imag: SIMD3<Float>(0.7071067, 0.0, 0.0))
    }
    .store(in: &subscriptions)

I would have expected entity.orientation to give me something like 90.0 or 1.57 (.pi / 2), but unsure how I can get the current rotation of the Entity in a form that would align with expected angles.

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
ZbadhabitZ
  • 2,753
  • 1
  • 25
  • 45

1 Answers1

2

simd_quatf

In RealityKit 2.0, when retrieving simd_quatf structure's values from .orientation and .transform.rotation instance properties, the default initializer brings real (scalar) and imaginary (vector) parts of a Quaternion:

public init(real: Float, imag: SIMD3<Float>)

Hamilton's quaternion expression looks like this:

enter image description here

In your case, the value 0.707 corresponds to a rotation angle of 45 degrees. If you set both real (a) and imag.x (bi) to 0.707, you'll get a total rotation angle of 90 degrees for X axis.

enter image description here

It's easy to check:

let quaternion = simd_quatf(real: 0.707, imag: [0.707, 0, 0])   // 90 degrees
entity.orientation = quaternion

To check what "readable" model's orientation is, use regular parameters from another initializer:

public init(angle: Float, axis: SIMD3<Float>)

print(entity.orientation.angle)         // 1.5707964
print(entity.orientation.axis)          // SIMD3<Float>(0.99999994, 0.0, 0.0)
Andy Jazz
  • 49,178
  • 17
  • 136
  • 220
  • 1
    Thank you so much for the detailed reply, @Andy Jazz! I did not realize that the rotation properties were leveraging the mathematical calculations applicable to the quaternion, and had more-so expected than the `entity.orientation.angle` output would be a per-axis angle calculation. Would you suggest any particular documentation or reading resources to better understand how to best calculate the per-axis angle of a quaternion rotation (IE to know the angle of the pitch vs. yaw)? Again, thank you for the reply, this was so helpful and thorough. – ZbadhabitZ Jun 19 '22 at 18:09
  • Hi @ZbadhabitZ, Any documentation on the subject of 4x4 matrices, Quaternions and Eulers would be helpful. )) https://simple.wikipedia.org/wiki/Pitch,_yaw,_and_roll – Andy Jazz Jun 19 '22 at 18:17
  • 1
    Thank you, @Andy Jazz! I very much appreciate your helpful and detailed answer as well as this resource. This has been a great help and I am certain this information will help other developers interested in RealityKit and rotation, as well. – ZbadhabitZ Jun 20 '22 at 03:26