Skip to content

Commit

Permalink
Merge pull request #2381 from AnalyticalGraphicsInc/hpr
Browse files Browse the repository at this point in the history
Heading-Pitch-Roll
  • Loading branch information
pjcozzi committed Jan 14, 2015
2 parents af0f698 + a844469 commit 247f746
Show file tree
Hide file tree
Showing 9 changed files with 710 additions and 218 deletions.
14 changes: 11 additions & 3 deletions Apps/Sandcastle/gallery/3D Models.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,14 @@
var viewer = new Cesium.Viewer('cesiumContainer');
var scene = viewer.scene;

function createModel(url, height) {
function createModel(url, height, heading, pitch, roll) {
height = Cesium.defaultValue(height, 0.0);
heading = Cesium.defaultValue(heading, 0.0);
pitch = Cesium.defaultValue(pitch, 0.0);
roll = Cesium.defaultValue(roll, 0.0);

var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, height));
var origin = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, height);
var modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(origin, heading, pitch, roll);

scene.primitives.removeAll(); // Remove previous model
var model = scene.primitives.add(Cesium.Model.fromGltf({
Expand Down Expand Up @@ -77,7 +81,11 @@
var options = [{
text : 'Aircraft',
onselect : function() {
createModel('../../SampleData/models/CesiumAir/Cesium_Air.gltf', 5000.0);
var height = 5000.0;
var heading = 0.0;
var pitch = Cesium.Math.toRadians(10.0);
var roll = Cesium.Math.toRadians(-20.0);
createModel('../../SampleData/models/CesiumAir/Cesium_Air.gltf', height, heading, pitch, roll);
}
}, {
text : 'Ground vehicle',
Expand Down
18 changes: 18 additions & 0 deletions Apps/Sandcastle/gallery/Camera.html
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,18 @@
}));
}

function setHeadingPitchRoll() {
Sandcastle.declare(setHeadingPitchRoll);

var camera = viewer.camera;
camera.setView({
position : Cesium.Cartesian3.fromDegrees(-75.5847, 40.0397, 1000.0),
heading : -Cesium.Math.PI_OVER_TWO,
pitch : -Cesium.Math.PI_OVER_FOUR,
roll : 0.0
});
}

function icrf(scene, time) {
if (scene.mode !== Cesium.SceneMode.SCENE3D) {
return;
Expand Down Expand Up @@ -181,6 +193,12 @@
Sandcastle.highlight(setReferenceFrame);
}
}, {
text : 'Set camera with heading, pitch, and roll',
onselect : function() {
setHeadingPitchRoll();
Sandcastle.highlight(setHeadingPitchRoll);
}
},{
text : 'View in ICRF',
onselect : function() {
viewInICRF();
Expand Down
7 changes: 7 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,17 @@ Change Log
* The `sourceUri` parameter to `GeoJsonDatasource.load` was deprecated in Cesium 1.4 and has been removed. Use options.sourceUri instead.
* `PolygonGraphics.positions` created by `GeoJSONDataSource` now evaluate to a `PolygonHierarchy` object instead of an array of positions.
* Deprecated
* `Camera.tilt` was deprecated in Cesium 1.6. It will be removed in Cesium 1.7. Use `Camera.pitch`.
* `Camera.heading` and `Camera.tilt` were deprecated in Cesium 1.6. They will become read-only in Cesium 1.7. Use `Camera.setView`.
* `Camera.setPositionCartographic` was deprecated in Cesium 1.6. It will be removed in Cesium 1.7. Use `Camera.setView`.
* `PolygonGraphics.positions` was deprecated and replaced with `PolygonGraphics.hierarchy`, whose value is a `PolygonHierarchy` instead of an array of positions. `PolygonGraphics.positions` will be removed in Cesium 1.8.
* The `Model.readyToRender` event was deprecated and will be removed in Cesium 1.9. Use the new 'Model.readyPromise' instead.
* Improved performance of asynchronous geometry creation (as much as 20% faster in some use cases). [#2342](https://github.com/AnalyticalGraphicsInc/cesium/issues/2342)
* Added `PolylineVolumeGraphics` and `Entity.polylineVolume`
* Added `Camera.setView` (which use heading, pitch, and roll) and `Camera.roll`.
* Added `Quaternion.fromHeadingPitchRoll` to create a rotation from heading, pitch, and roll angles.
* Added `Transforms.headingPitchRollToFixedFrame` to create a local frame from a position and heading/pitch/roll angles.
* Added `Transforms.headingPitchRollQuaternion` which is the quaternion rotation from `Transforms.headingPitchRollToFixedFrame`.
* Added `BillboardGraphics.imageSubRegion`, to enable custom texture atlas use for `Entity` instances.
* Added `CheckerboardMaterialProperty` to enable use of the checkerboard material with the entity API.
* Added `PolygonHierarchy` to make defining polygons with holes clearer.
Expand Down
34 changes: 34 additions & 0 deletions Source/Core/Quaternion.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,40 @@ define([
return result;
};

var scratchHPRQuaternion = new Quaternion();

/**
* Computes a rotation from the given heading, pitch and roll angles. Heading is the rotation about the
* negative z axis. Pitch is the rotation about the negative y axis. Roll is the rotation about
* the positive x axis.
*
* @param {Number} heading The heading angle in radians.
* @param {Number} pitch The pitch angle in radians.
* @param {Number} roll The roll angle in radians.
* @param {Quaternion} result The object onto which to store the result.
* @returns {Quaternion} The modified result parameter or a new Quaternion instance if none was provided.
*/
Quaternion.fromHeadingPitchRoll = function(heading, pitch, roll, result) {
//>>includeStart('debug', pragmas.debug);
if (!defined(heading)) {
throw new DeveloperError('heading is required.');
}
if (!defined(pitch)) {
throw new DeveloperError('pitch is required.');
}
if (!defined(roll)) {
throw new DeveloperError('roll is required.');
}
//>>includeEnd('debug');

var headingQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_Z, -heading, result);
var pitchQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_Y, -pitch, scratchHPRQuaternion);
result = Quaternion.multiply(headingQuaternion, pitchQuaternion, headingQuaternion);

var rollQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_X, roll, scratchHPRQuaternion);
return Quaternion.multiply(rollQuaternion, result, result);
};

var sampledQuaternionAxis = new Cartesian3();
var sampledQuaternionRotation = new Cartesian3();
var sampledQuaternionTempQuaternion = new Quaternion();
Expand Down
68 changes: 68 additions & 0 deletions Source/Core/Transforms.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ define([
'./Math',
'./Matrix3',
'./Matrix4',
'./Quaternion',
'./TimeConstants'
], function(
when,
Expand All @@ -34,6 +35,7 @@ define([
CesiumMath,
Matrix3,
Matrix4,
Quaternion,
TimeConstants) {
"use strict";

Expand Down Expand Up @@ -344,6 +346,72 @@ define([
return result;
};

var scratchHPRQuaternion = new Quaternion();
var scratchScale = new Cartesian3(1.0, 1.0, 1.0);
var scratchHPRMatrix4 = new Matrix4();

/**
* Computes a 4x4 transformation matrix from a reference frame with axes computed from the heading-pitch-roll angles
* centered at the provided origin to the provided ellipsoid's fixed reference frame. Heading is the rotation from the local north
* direction where a positive angle is increasing eastward. Pitch is the rotation from the local east-north plane. Positive pitch angles
* are above the plane. Negative pitch angles are below the plane. Roll is the first rotation applied about the local east axis.
*
* @param {Cartesian3} origin The center point of the local reference frame.
* @param {Number} heading The heading angle in radians.
* @param {Number} pitch The pitch angle in radians.
* @param {Number} roll The roll angle in radians.
* @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation.
* @param {Matrix4} [result] The object onto which to store the result.
* @returns {Matrix4} The modified result parameter or a new Matrix4 instance if none was provided.
*
* @example
* // Get the transform from local heading-pitch-roll at cartographic (0.0, 0.0) to Earth's fixed frame.
* var center = Cesium.Cartesian3.fromDegrees(0.0, 0.0);
* var heading = -Cesium.Math.PI_OVER_TWO;
* var pitch = Cesium.Math.PI_OVER_FOUR;
* var roll = 0.0;
* var transform = Cesium.Transforms.headingPitchRollToFixedFrame(center, heading, pitch, roll);
*/
Transforms.headingPitchRollToFixedFrame = function(origin, heading, pitch, roll, ellipsoid, result) {
// checks for required parameters happen in the called functions
var hprQuaternion = Quaternion.fromHeadingPitchRoll(heading, pitch, roll, scratchHPRQuaternion);
var hprMatrix = Matrix4.fromTranslationQuaternionRotationScale(Cartesian3.ZERO, hprQuaternion, scratchScale, scratchHPRMatrix4);
result = Transforms.eastNorthUpToFixedFrame(origin, ellipsoid, result);
return Matrix4.multiply(result, hprMatrix, result);
};

var scratchENUMatrix4 = new Matrix4();
var scratchHPRMatrix3 = new Matrix3();

/**
* Computes a quaternion from a reference frame with axes computed from the heading-pitch-roll angles
* centered at the provided origin. Heading is the rotation from the local north
* direction where a positive angle is increasing eastward. Pitch is the rotation from the local east-north plane. Positive pitch angles
* are above the plane. Negative pitch angles are below the plane. Roll is the first rotation applied about the local east axis.
*
* @param {Cartesian3} origin The center point of the local reference frame.
* @param {Number} heading The heading angle in radians.
* @param {Number} pitch The pitch angle in radians.
* @param {Number} roll The roll angle in radians.
* @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation.
* @param {Quaternion} [result] The object onto which to store the result.
* @returns {Quaternion} The modified result parameter or a new Quaternion instance if none was provided.
*
* @example
* // Get the quaternion from local heading-pitch-roll at cartographic (0.0, 0.0) to Earth's fixed frame.
* var center = Cesium.Cartesian3.fromDegrees(0.0, 0.0);
* var heading = -Cesium.Math.PI_OVER_TWO;
* var pitch = Cesium.Math.PI_OVER_FOUR;
* var roll = 0.0;
* var quaternion = Cesium.Transforms.headingPitchRollQuaternion(center, heading, pitch, roll);
*/
Transforms.headingPitchRollQuaternion = function(origin, heading, pitch, roll, ellipsoid, result) {
// checks for required parameters happen in the called functions
var transform = Transforms.headingPitchRollToFixedFrame(origin, heading, pitch, roll, ellipsoid, scratchENUMatrix4);
var rotation = Matrix4.getRotation(transform, scratchHPRMatrix3);
return Quaternion.fromRotationMatrix(rotation, result);
};


var gmstConstant0 = 6 * 3600 + 41 * 60 + 50.54841;
var gmstConstant1 = 8640184.812866;
Expand Down
Loading

0 comments on commit 247f746

Please sign in to comment.