There is a parameter roll in UI [Edit Current Viewpoint]. It means rotating the camera around its front-to-back axis. A positive value rotates the camera counterclockwise, and a negative value rotates it clockwise.
In API perspective, a rotation around world axes (WCS) is configured by Viewpoint.Rotation (Rotation3D) which is in 3D space defined as a quaternion. From quaternion, it can also tell something like roll, yaw, pitch. One post kindly provides the mathematical equations:
https://answers.unity.com/questions/416169/finding-pitchrollyaw-from-quaternions.html
These are defined in aircraft principal axes. In Navisworks space, when the up vector is Y+, right vector is X+, and view direction is Z-, the roll can be calculated from quaternion (Viewpoint.Rotation) by the equations above. However, in other cases when the up vector is different, roll in UI means what it indicates: rotating the camera around its front-to-back axis. Unfortunately, I do not find any API which tells roll in UI.
While in math, once we know the base up vector, current up vector, we can calculate the roll ourselves.
- Viewpoint.WorldUpVector: initial base up vector when user [Set Viewpoint Up]
- Viewpoint.GetCamera(): a json string which contains many information such as
- current up vector
- current view direction (reversed vector of forward vector)
since view direction will keep the same when setting roll, the roll value will be the angle from current right to the base right (aligned with initial up vector).
The code below prints out the roll in aircraft principal axes and the roll in Navisworks UI.
[Serializable]
public class cameraInfoClass
{
public double[] UpDirection { get; set; }
public double[] WorldRightDirection { get; set; }
public double[] ViewDirection { get; set; }
}
public override int Execute(params string[] parameters)
{
//current viewpoint
Viewpoint oViewpoint =
Autodesk.Navisworks.Api.Application.ActiveDocument.CurrentViewpoint;
//current world up vector. The vector defined by user.
//Same to UI >> [Edit Viewpoint] >>
UnitVector3D worldUpVec = null;
if (oViewpoint.HasWorldUpVector)
worldUpVec = oViewpoint.WorldUpVector;
else
return 0;
//A rotation in 3D space defined as a quaternion.
Rotation3D rotation = oViewpoint.Rotation;
//*****
//Aircraft principal axes: X+: right, Y+: up, Z-: view direction
// roll: around Z-
// pitch: around X+
// yaw: around X+
//from https://answers.unity.com/questions/416169/finding-pitchrollyaw-from-quaternions.html
//roll = Mathf.Atan2(2*y*w - 2*x*z, 1 - 2*y*y - 2*z*z);
//pitch = Mathf.Atan2(2 * x * w - 2 * y * z, 1 - 2 * x * x - 2 * z * z);
//yaw = Mathf.Asin(2 * x * y + 2 * z * w);
double aircraft_roll = Math.Atan2((2 * rotation.B * rotation.D)
- (2 * rotation.A * rotation.C),
1 - (2 * rotation.B * rotation.B)
- (2 * rotation.C * rotation.C));
double aircraft_roll_degree = aircraft_roll * 180 / Math.PI;
double aircraft_pitch = Math.Atan2((2 * rotation.A * rotation.D)
- (2 * rotation.B * rotation.C),
1 - (2 * rotation.A * rotation.A)
- (2 * rotation.C * rotation.C));
double aircraft_pitch_degree = aircraft_pitch * 180 / Math.PI;
double aircraft_yaw = Math.Asin((2 * rotation.A * rotation.B)
+ (2 * rotation.C * rotation.D));
double aircraft_yaw_degree = aircraft_yaw * 180 / Math.PI;
//*****
//get camera parameters which contains more data we need to calculate roll of Navisworks UI
string cameraStr = oViewpoint.GetCamera();
cameraInfoClass cameraStrJson = JsonConvert.DeserializeObject(cameraStr);
//current up vector
Vector3D currentUpVec = new Vector3D(cameraStrJson.UpDirection[0],
cameraStrJson.UpDirection[1],
cameraStrJson.UpDirection[2]);
Vector3D currentViewDir = new Vector3D(-cameraStrJson.ViewDirection[0],
-cameraStrJson.ViewDirection[1],
-cameraStrJson.ViewDirection[2]);
//current right vector
Vector3D currentRightVec = currentUpVec.Cross(currentViewDir);
//current world right vector is when the viewpoint
//is aligned with an intial up vector.Initially, roll of UI is 0
Vector3D currentWorldRightVec = worldUpVec.Cross(currentViewDir);
//get roll of UI in degree
double UI_roll_degree = currentRightVec.Angle(currentWorldRightVec) * 180 / Math.PI;
MessageBox.Show("aircraft_roll:" + aircraft_roll
+ "\naircraft_pitch:" + aircraft_pitch_degree
+ "\naircraft_yaw:" + aircraft_yaw_degree
+ "\nUI roll:" + UI_roll_degree);
return 0;
}