different "unitQuaternion " behavior in CZML's "orientation" and "model>nodeTransformation"

Good evening,

I puzzled over this throughout the afternoon. Why do unitQuaternions behave differently between czml's "orientation" property and a czml model's "nodeTransformation" property.

The following Sandcastle code shows Cesium_Man.glb using both forms of unitQuaternion. Between 2AM and 10AM, I would expect him to change his heading 90degrees, but instead he jumps dramatically to his left before rotating forward about his hips.

The second form of unitQuaternion uses the nodeTransformation>rotation form of unitQuaternions and this movement is what I would expect. The neutral 0,0,0,1 (x,y,z,w) values rotates 90degrees to 0,1,0,0 before rotating back to the starting point.

This appears to have caused confusion on the forum in the past, and I see some resolutions using matrices. Using CZML, how can I make the first form of "orientation" unitQuaternions behave like the second (in other words, rotate to face the camera while staying vertical)?

Cheers, e

var czml = [{
    "id" : "document",
    "name" : "CZML Model",
    "version" : "1.0",
    "clock": {
        "interval": "2017-01-19T00:00:00Z/2017-01-19T23:59:59Z",
    }
}, {
    "id" : "model",
    "position" : {
        "cartographicDegrees" : [-77, 37, 100000]
    },
    "orientation":{
        "interpolationAlgorithm": "LINEAR",
        "interpolationDegree": 1,
    "unitQuaternion": [
                        "2017-01-19T02:00:00Z",0,0,0,1,
                        "2017-01-19T06:00:00Z",0,0,0,1,
      "2017-01-19T10:00:00Z",0,0,1,1
    ]
    },
    "model": {
        "gltf" : "../../SampleData/models/CesiumMan/Cesium_Man.glb",
        "runAnimations":false,
        "nodeTransformations": {
            "Skeleton_arm_joint_R__2_": {
                "rotation": {
                    "unitQuaternion":[
                        "2017-01-19T14:00:00Z",0,0,0,1,
                        "2017-01-19T18:00:00Z",0,1,0,0,
                        "2017-01-19T22:00:00Z",0,0,0,1
                    ]
                }
            }
        }
    }
}];

var viewer = new Cesium.Viewer('cesiumContainer');
var promise = viewer.dataSources.add(Cesium.CzmlDataSource.load(czml));

promise.then(function(dataSource){
    viewer.trackedEntity = dataSource.entities.getById('model');
}).otherwise(function(error){
    window.alert(error);
});

The unit quaternions work the same in both cases. Quaternions encode a rotation relative to a set of axes. The entity’s orientation is the rotation from body axes to the Earth fixed axes.

https://en.wikipedia.org/wiki/ECEF

If you modify your example to set a minimum pixel size on the model, you can zoom out and see that from 0200-0600 (the interval of time where you are using the identity quaternion for orientation) the model orientation is the same as earth fixed, and from 0600-1000 it rotates around Z.

For the periods of time where orientation is undefined (0000-0200 and 1000-2359) Cesium defaults to east-north-up.

In the case of the node transformations, the unit quaternion represents the rotation from that particular node to its parent node, which is why only part of the model rotates.

Thanks Scott.

I played with the Sandcastle and see that Cesium_Man likes lying down at the equator and standing upright at the north pole. Now the distinction between the two applications of quaternions is clearer. One orients a position in earth-fixed while the other rotates a model in eastNorthUp (ENU).

I have many models in my application loaded through CZML. Unless someone corrects me, I will control each model rotation by “nodeTransform.” And as for orienting the position, that will be left alone.

This is a big help. Thanks, e