From 0c3aa34402a863a0e2873924db2f6f838b568fd6 Mon Sep 17 00:00:00 2001 From: Farouk Abdou Date: Wed, 18 Jan 2017 08:55:00 +0100 Subject: [PATCH 01/11] First implementation of fixedFrameConverter --- Source/Core/Transforms.js | 486 ++++++++++++++------------------------ 1 file changed, 171 insertions(+), 315 deletions(-) diff --git a/Source/Core/Transforms.js b/Source/Core/Transforms.js index b9ebfef6f1ff..d6f6dba64d0c 100644 --- a/Source/Core/Transforms.js +++ b/Source/Core/Transforms.js @@ -51,10 +51,165 @@ define([ * @exports Transforms */ var Transforms = {}; + const vectorProductLocalFrame = { + up: { + south: 'east', + north: 'west', + west: 'south', + east: 'north' + }, + down: { + south: 'west', + north: 'east', + west: 'north', + east: 'south' + }, + south: { + up: 'west', + down: 'east', + west: 'down', + east: 'up' + }, + north: { + up: 'east', + down: 'west', + west: 'up', + east: 'down' + }, + west: { + up: 'north', + down: 'south', + north: 'down', + south: 'up' + }, + east: { + up: 'south', + down: 'north', + north: 'up', + south: 'down' + } + }; + + const degeneratePositionLocalFrame = { + north: [ + -1, 0, 0 + ], + east: [ + 0, 1, 0 + ], + up: [ + 0, 0, 1 + ], + south: [ + 1, 0, 0 + ], + west: [ + 0, -1, 0 + ], + down: [0, 0, -1] + }; + /** + * Generates a function that computes a 4x4 transformation matrix from a reference frame + * centered at the provided origin to the provided ellipsoid's fixed reference frame. + * @param {String} firstAxis name of the first axis of the local reference frame. Must be + * east, north, up, west, south or down. + * @param {String} secondAxis name of the second axis of the local reference frame. Must be + * east, north, up, west, south or down. + * @return {localFrameToFixedFrameGenerator~resultat} The function that will computes a + * 4x4 transformation matrix from a reference frame, with first axis and second axis compliant with the parameters, + */ + Transforms.localFrameToFixedFrameGenerator = function( firstAxis, secondAxis) { + if (!vectorProductLocalFrame.hasOwnProperty(firstAxis) || !vectorProductLocalFrame[firstAxis].hasOwnProperty(secondAxis)) { + throw new DeveloperError('firstAxis and secondAxis must be east, north, up, west, south or down.'); + } + var thirdAxis = vectorProductLocalFrame[firstAxis][secondAxis]; + var calculateCartesian = { + east: new Cartesian3(), + north: new Cartesian3(), + up: new Cartesian3(), + west: new Cartesian3(), + south: new Cartesian3(), + down: new Cartesian3() + }; + var firstCartesian = new Cartesian3(); + var secondCartesian = new Cartesian3(); + var thirdCartesian = new Cartesian3(); + + /** + * [resultat description] + * @param {Cartesian3} origin The center point of the local reference frame. + * @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. + */ + var resultat= function(origin, ellipsoid, result) { + //>>includeStart('debug', pragmas.debug); + if (!defined(origin)) { + throw new DeveloperError('origin is required.'); + } + //>>includeEnd('debug'); + if (!defined(result)) { + result = new Matrix4(); + } + // If x and y are zero, assume origin is at a pole, which is a special case. + if (CesiumMath.equalsEpsilon(origin.x, 0.0, CesiumMath.EPSILON14) && CesiumMath.equalsEpsilon(origin.y, 0.0, CesiumMath.EPSILON14)) { + var sign = CesiumMath.sign(origin.z); + + Cartesian3.unpack(degeneratePositionLocalFrame[firstAxis], 0, firstCartesian); + if (firstAxis !== 'east' && firstAxis !== 'west') { + Cartesian3.multiplyByScalar(firstCartesian, sign, firstCartesian); + } + + Cartesian3.unpack(degeneratePositionLocalFrame[secondAxis], 0, secondCartesian); + if (secondAxis !== 'east' && secondAxis !== 'west') { + Cartesian3.multiplyByScalar(secondCartesian, sign, secondCartesian); + } + + Cartesian3.unpack(degeneratePositionLocalFrame[thirdAxis], 0, thirdCartesian); + if (thirdAxis !== 'east' && thirdAxis !== 'west') { + Cartesian3.multiplyByScalar(thirdCartesian, sign, thirdCartesian); + } + } else { + + ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + ellipsoid.geodeticSurfaceNormal(origin, calculateCartesian.up); - var eastNorthUpToFixedFrameNormal = new Cartesian3(); - var eastNorthUpToFixedFrameTangent = new Cartesian3(); - var eastNorthUpToFixedFrameBitangent = new Cartesian3(); + var up = calculateCartesian.up; + var east = calculateCartesian.east; + east.x = -origin.y; + east.y = origin.x; + east.z = 0.0; + Cartesian3.normalize(east, calculateCartesian.east); + Cartesian3.cross(up, east, calculateCartesian.north); + + Cartesian3.multiplyByScalar(calculateCartesian.up, -1, calculateCartesian.down); + Cartesian3.multiplyByScalar(calculateCartesian.east, -1, calculateCartesian.west); + Cartesian3.multiplyByScalar(calculateCartesian.north, -1, calculateCartesian.south); + + firstCartesian = calculateCartesian[firstAxis]; + secondCartesian = calculateCartesian[secondAxis]; + thirdCartesian = calculateCartesian[thirdAxis]; + } + result[0] = firstCartesian.x; + result[1] = firstCartesian.y; + result[2] = firstCartesian.z; + result[3] = 0.0; + result[4] = secondCartesian.x; + result[5] = secondCartesian.y; + result[6] = secondCartesian.z; + result[7] = 0.0; + result[8] = thirdCartesian.x; + result[9] = thirdCartesian.y; + result[10] = thirdCartesian.z; + result[11] = 0.0; + result[12] = origin.x; + result[13] = origin.y; + result[14] = origin.z; + result[15] = 1.0; + return result; + }; + return resultat; + } /** * Computes a 4x4 transformation matrix from a reference frame with an east-north-up axes @@ -76,86 +231,7 @@ define([ * var center = Cesium.Cartesian3.fromDegrees(0.0, 0.0); * var transform = Cesium.Transforms.eastNorthUpToFixedFrame(center); */ - Transforms.eastNorthUpToFixedFrame = function(origin, ellipsoid, result) { - //>>includeStart('debug', pragmas.debug); - if (!defined(origin)) { - throw new DeveloperError('origin is required.'); - } - //>>includeEnd('debug'); - - // If x and y are zero, assume origin is at a pole, which is a special case. - if (CesiumMath.equalsEpsilon(origin.x, 0.0, CesiumMath.EPSILON14) && - CesiumMath.equalsEpsilon(origin.y, 0.0, CesiumMath.EPSILON14)) { - var sign = CesiumMath.sign(origin.z); - if (!defined(result)) { - return new Matrix4( - 0.0, -sign, 0.0, origin.x, - 1.0, 0.0, 0.0, origin.y, - 0.0, 0.0, sign, origin.z, - 0.0, 0.0, 0.0, 1.0); - } - result[0] = 0.0; - result[1] = 1.0; - result[2] = 0.0; - result[3] = 0.0; - result[4] = -sign; - result[5] = 0.0; - result[6] = 0.0; - result[7] = 0.0; - result[8] = 0.0; - result[9] = 0.0; - result[10] = sign; - result[11] = 0.0; - result[12] = origin.x; - result[13] = origin.y; - result[14] = origin.z; - result[15] = 1.0; - return result; - } - - var normal = eastNorthUpToFixedFrameNormal; - var tangent = eastNorthUpToFixedFrameTangent; - var bitangent = eastNorthUpToFixedFrameBitangent; - - ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - ellipsoid.geodeticSurfaceNormal(origin, normal); - - tangent.x = -origin.y; - tangent.y = origin.x; - tangent.z = 0.0; - Cartesian3.normalize(tangent, tangent); - - Cartesian3.cross(normal, tangent, bitangent); - - if (!defined(result)) { - return new Matrix4( - tangent.x, bitangent.x, normal.x, origin.x, - tangent.y, bitangent.y, normal.y, origin.y, - tangent.z, bitangent.z, normal.z, origin.z, - 0.0, 0.0, 0.0, 1.0); - } - result[0] = tangent.x; - result[1] = tangent.y; - result[2] = tangent.z; - result[3] = 0.0; - result[4] = bitangent.x; - result[5] = bitangent.y; - result[6] = bitangent.z; - result[7] = 0.0; - result[8] = normal.x; - result[9] = normal.y; - result[10] = normal.z; - result[11] = 0.0; - result[12] = origin.x; - result[13] = origin.y; - result[14] = origin.z; - result[15] = 1.0; - return result; - }; - - var northEastDownToFixedFrameNormal = new Cartesian3(); - var northEastDownToFixedFrameTangent = new Cartesian3(); - var northEastDownToFixedFrameBitangent = new Cartesian3(); + Transforms.eastNorthUpToFixedFrame = Transforms.localFrameToFixedFrameGenerator('east','north'); /** * Computes a 4x4 transformation matrix from a reference frame with an north-east-down axes @@ -177,82 +253,7 @@ define([ * var center = Cesium.Cartesian3.fromDegrees(0.0, 0.0); * var transform = Cesium.Transforms.northEastDownToFixedFrame(center); */ - Transforms.northEastDownToFixedFrame = function(origin, ellipsoid, result) { - //>>includeStart('debug', pragmas.debug); - if (!defined(origin)) { - throw new DeveloperError('origin is required.'); - } - //>>includeEnd('debug'); - - if (CesiumMath.equalsEpsilon(origin.x, 0.0, CesiumMath.EPSILON14) && - CesiumMath.equalsEpsilon(origin.y, 0.0, CesiumMath.EPSILON14)) { - // The poles are special cases. If x and y are zero, assume origin is at a pole. - var sign = CesiumMath.sign(origin.z); - if (!defined(result)) { - return new Matrix4( - -sign, 0.0, 0.0, origin.x, - 0.0, 1.0, 0.0, origin.y, - 0.0, 0.0, -sign, origin.z, - 0.0, 0.0, 0.0, 1.0); - } - result[0] = -sign; - result[1] = 0.0; - result[2] = 0.0; - result[3] = 0.0; - result[4] = 0.0; - result[5] = 1.0; - result[6] = 0.0; - result[7] = 0.0; - result[8] = 0.0; - result[9] = 0.0; - result[10] = -sign; - result[11] = 0.0; - result[12] = origin.x; - result[13] = origin.y; - result[14] = origin.z; - result[15] = 1.0; - return result; - } - - var normal = northEastDownToFixedFrameNormal; - var tangent = northEastDownToFixedFrameTangent; - var bitangent = northEastDownToFixedFrameBitangent; - - ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - ellipsoid.geodeticSurfaceNormal(origin, normal); - - tangent.x = -origin.y; - tangent.y = origin.x; - tangent.z = 0.0; - Cartesian3.normalize(tangent, tangent); - - Cartesian3.cross(normal, tangent, bitangent); - - if (!defined(result)) { - return new Matrix4( - bitangent.x, tangent.x, -normal.x, origin.x, - bitangent.y, tangent.y, -normal.y, origin.y, - bitangent.z, tangent.z, -normal.z, origin.z, - 0.0, 0.0, 0.0, 1.0); - } - result[0] = bitangent.x; - result[1] = bitangent.y; - result[2] = bitangent.z; - result[3] = 0.0; - result[4] = tangent.x; - result[5] = tangent.y; - result[6] = tangent.z; - result[7] = 0.0; - result[8] = -normal.x; - result[9] = -normal.y; - result[10] = -normal.z; - result[11] = 0.0; - result[12] = origin.x; - result[13] = origin.y; - result[14] = origin.z; - result[15] = 1.0; - return result; - }; + Transforms.northEastDownToFixedFrame = Transforms.localFrameToFixedFrameGenerator('north','east'); /** * Computes a 4x4 transformation matrix from a reference frame with an north-up-east axes @@ -274,82 +275,7 @@ define([ * var center = Cesium.Cartesian3.fromDegrees(0.0, 0.0); * var transform = Cesium.Transforms.northUpEastToFixedFrame(center); */ - Transforms.northUpEastToFixedFrame = function(origin, ellipsoid, result) { - //>>includeStart('debug', pragmas.debug); - if (!defined(origin)) { - throw new DeveloperError('origin is required.'); - } - //>>includeEnd('debug'); - - // If x and y are zero, assume origin is at a pole, which is a special case. - if (CesiumMath.equalsEpsilon(origin.x, 0.0, CesiumMath.EPSILON14) && - CesiumMath.equalsEpsilon(origin.y, 0.0, CesiumMath.EPSILON14)) { - var sign = CesiumMath.sign(origin.z); - if (!defined(result)) { - return new Matrix4( - -sign, 0.0, 0.0, origin.x, - 0.0, 0.0, 1.0, origin.y, - 0.0, sign, 0.0, origin.z, - 0.0, 0.0, 0.0, 1.0); - } - result[0] = -sign; - result[1] = 0.0; - result[2] = 0.0; - result[3] = 0.0; - result[4] = 0.0; - result[5] = 0.0; - result[6] = sign; - result[7] = 0.0; - result[8] = 0.0; - result[9] = 1.0; - result[10] = 0.0; - result[11] = 0.0; - result[12] = origin.x; - result[13] = origin.y; - result[14] = origin.z; - result[15] = 1.0; - return result; - } - - var normal = eastNorthUpToFixedFrameNormal; - var tangent = eastNorthUpToFixedFrameTangent; - var bitangent = eastNorthUpToFixedFrameBitangent; - - ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - ellipsoid.geodeticSurfaceNormal(origin, normal); - - tangent.x = -origin.y; - tangent.y = origin.x; - tangent.z = 0.0; - Cartesian3.normalize(tangent, tangent); - - Cartesian3.cross(normal, tangent, bitangent); - - if (!defined(result)) { - return new Matrix4( - bitangent.x, normal.x, tangent.x, origin.x, - bitangent.y, normal.y, tangent.y, origin.y, - bitangent.z, normal.z, tangent.z, origin.z, - 0.0, 0.0, 0.0, 1.0); - } - result[0] = bitangent.x; - result[1] = bitangent.y; - result[2] = bitangent.z; - result[3] = 0.0; - result[4] = normal.x; - result[5] = normal.y; - result[6] = normal.z; - result[7] = 0.0; - result[8] = tangent.x; - result[9] = tangent.y; - result[10] = tangent.z; - result[11] = 0.0; - result[12] = origin.x; - result[13] = origin.y; - result[14] = origin.z; - result[15] = 1.0; - return result; - }; + Transforms.northUpEastToFixedFrame = Transforms.localFrameToFixedFrameGenerator('north','up'); /** * Computes a 4x4 transformation matrix from a reference frame with an north-west-up axes @@ -371,82 +297,7 @@ define([ * var center = Cesium.Cartesian3.fromDegrees(0.0, 0.0); * var transform = Cesium.Transforms.northWestUpToFixedFrame(center); */ - Transforms.northWestUpToFixedFrame = function(origin, ellipsoid, result) { - //>>includeStart('debug', pragmas.debug); - if (!defined(origin)) { - throw new DeveloperError('origin is required.'); - } - //>>includeEnd('debug'); - - // If x and y are zero, assume origin is at a pole, which is a special case. - if (CesiumMath.equalsEpsilon(origin.x, 0.0, CesiumMath.EPSILON14) && - CesiumMath.equalsEpsilon(origin.y, 0.0, CesiumMath.EPSILON14)) { - var sign = CesiumMath.sign(origin.z); - if (!defined(result)) { - return new Matrix4( - -sign, 0.0, 0.0, origin.x, - 0.0, -1.0, 0.0, origin.y, - 0.0, 0.0, sign, origin.z, - 0.0, 0.0, 0.0, 1.0); - } - result[0] = -sign; - result[1] = 0.0; - result[2] = 0.0; - result[3] = 0.0; - result[4] = 0.0; - result[5] = -1.0; - result[6] = 0.0; - result[7] = 0.0; - result[8] = 0.0; - result[9] = 0.0; - result[10] = sign; - result[11] = 0.0; - result[12] = origin.x; - result[13] = origin.y; - result[14] = origin.z; - result[15] = 1.0; - return result; - } - - var normal = eastNorthUpToFixedFrameNormal;//Up - var tangent = eastNorthUpToFixedFrameTangent;//East - var bitangent = eastNorthUpToFixedFrameBitangent;//North - - ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - ellipsoid.geodeticSurfaceNormal(origin, normal); - - tangent.x = -origin.y; - tangent.y = origin.x; - tangent.z = 0.0; - Cartesian3.normalize(tangent, tangent); - - Cartesian3.cross(normal, tangent, bitangent); - - if (!defined(result)) { - return new Matrix4( - bitangent.x, -tangent.x, normal.x, origin.x, - bitangent.y, -tangent.y, normal.y, origin.y, - bitangent.z, -tangent.z, normal.z, origin.z, - 0.0, 0.0, 0.0, 1.0); - } - result[0] = bitangent.x; - result[1] = bitangent.y; - result[2] = bitangent.z; - result[3] = 0.0; - result[4] = -tangent.x; - result[5] = -tangent.y; - result[6] = -tangent.z; - result[7] = 0.0; - result[8] = normal.x; - result[9] = normal.y; - result[10] = normal.z; - result[11] = 0.0; - result[12] = origin.x; - result[13] = origin.y; - result[14] = origin.z; - result[15] = 1.0; - return result; -}; + Transforms.northWestUpToFixedFrame = Transforms.localFrameToFixedFrameGenerator('north','west'); var scratchHPRQuaternion = new Quaternion(); var scratchScale = new Cartesian3(1.0, 1.0, 1.0); @@ -461,6 +312,8 @@ define([ * @param {Cartesian3} origin The center point of the local reference frame. * @param {HeadingPitchRoll} headingPitchRoll The heading, pitch, and roll. * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation. + * @param {function} [fixedFrameTransform=Transforms.eastNorthUpToFixedFrame] A 4x4 transformation matrix from a reference frame + * to the provided ellipsoid's fixed reference frame * @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. * @@ -473,16 +326,17 @@ define([ * var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); * var transform = Cesium.Transforms.headingPitchRollToFixedFrame(center, hpr); */ - Transforms.headingPitchRollToFixedFrame = function(origin, headingPitchRoll, ellipsoid, result) { + Transforms.headingPitchRollToFixedFrame = function(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result) { Check.typeOf.object(headingPitchRoll, 'headingPitchRoll'); var heading = headingPitchRoll.heading; var pitch = headingPitchRoll.pitch; var roll = headingPitchRoll.roll; // checks for required parameters happen in the called functions + fixedFrameTransform=defaultValue(fixedFrameConverter,Transforms.eastNorthUpToFixedFrame); var hprQuaternion = Quaternion.fromHeadingPitchRoll(heading, pitch, roll, scratchHPRQuaternion); var hprMatrix = Matrix4.fromTranslationQuaternionRotationScale(Cartesian3.ZERO, hprQuaternion, scratchScale, scratchHPRMatrix4); - result = Transforms.eastNorthUpToFixedFrame(origin, ellipsoid, result); + result = fixedFrameTransform(origin, ellipsoid, result); return Matrix4.multiply(result, hprMatrix, result); }; @@ -498,6 +352,8 @@ define([ * @param {Cartesian3} origin The center point of the local reference frame. * @param {HeadingPitchRoll} headingPitchRoll The heading, pitch, and roll. * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation. + * @param {function} [fixedFrameTransform=Transforms.eastNorthUpToFixedFrame] A 4x4 transformation matrix from a reference frame + * to the provided ellipsoid's fixed reference frame * @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. * @@ -510,10 +366,10 @@ define([ * var hpr = new HeadingPitchRoll(heading, pitch, roll); * var quaternion = Cesium.Transforms.headingPitchRollQuaternion(center, hpr); */ - Transforms.headingPitchRollQuaternion = function(origin, headingPitchRoll, ellipsoid, result) { + Transforms.headingPitchRollQuaternion = function(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result) { // checks for required parameters happen in the called functions Check.typeOf.object(headingPitchRoll, 'headingPitchRoll'); - var transform = Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, scratchENUMatrix4); + var transform = Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid,fixedFrameTransform, scratchENUMatrix4); var rotation = Matrix4.getRotation(transform, scratchHPRMatrix3); return Quaternion.fromRotationMatrix(rotation, result); }; From d1d9206a3e1eb7b9859c4641f197c902ca4cca29 Mon Sep 17 00:00:00 2001 From: Farouk Abdou Date: Sat, 21 Jan 2017 00:38:31 +0100 Subject: [PATCH 02/11] adding ability to change the local frame for orientations --- .../{development => }/HeadingPitchRoll.html | 28 +-- Apps/Sandcastle/gallery/HeadingPitchRoll.jpg | Bin 0 -> 24445 bytes .../Sandcastle/gallery/LocalToFixedFrame.html | 228 +++++++++++++++++ Apps/Sandcastle/gallery/LocalToFixedFrame.jpg | Bin 0 -> 24445 bytes .../development/3D Models Node Explorer.html | 15 +- .../gallery/development/HeadingPitchRoll.jpg | Bin 24887 -> 0 bytes Source/Core/Quaternion.js | 32 ++- Source/Core/Transforms.js | 47 ++-- Source/Scene/Camera.js | 30 ++- Specs/Core/HeadingPitchRollSpec.js | 7 +- Specs/Core/QuaternionSpec.js | 24 +- Specs/Core/TransformsSpec.js | 236 ++++++++++++++++-- 12 files changed, 559 insertions(+), 88 deletions(-) rename Apps/Sandcastle/gallery/{development => }/HeadingPitchRoll.html (92%) create mode 100644 Apps/Sandcastle/gallery/HeadingPitchRoll.jpg create mode 100644 Apps/Sandcastle/gallery/LocalToFixedFrame.html create mode 100644 Apps/Sandcastle/gallery/LocalToFixedFrame.jpg delete mode 100644 Apps/Sandcastle/gallery/development/HeadingPitchRoll.jpg diff --git a/Apps/Sandcastle/gallery/development/HeadingPitchRoll.html b/Apps/Sandcastle/gallery/HeadingPitchRoll.html similarity index 92% rename from Apps/Sandcastle/gallery/development/HeadingPitchRoll.html rename to Apps/Sandcastle/gallery/HeadingPitchRoll.html index a58c6fae485e..82d507368d34 100644 --- a/Apps/Sandcastle/gallery/development/HeadingPitchRoll.html +++ b/Apps/Sandcastle/gallery/HeadingPitchRoll.html @@ -4,7 +4,7 @@ - + Cesium Demo @@ -70,9 +70,10 @@

Loading...

var viewer = new Cesium.Viewer('cesiumContainer'); var canvas = viewer.canvas; canvas.setAttribute('tabindex', '0'); // needed to put focus on the canvas -canvas.onclick = function() { - canvas.focus(); -}; +canvas.addEventListener('click',function(){ + canvas.focus(); +}); +canvas.focus(); var scene = viewer.scene; @@ -101,13 +102,15 @@

Loading...

var hpRoll = new Cesium.HeadingPitchRoll(); var hpRange = new Cesium.HeadingPitchRange(); var speed = 10; +var deltaRadians = Cesium.Math.toRadians(3.0); var position = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, 5000.0); var speedVector = new Cesium.Cartesian3(); +var fixedFrameTransform = Cesium.Transforms.localFrameToFixedFrameGenerator('north','west'); var planePrimitive = scene.primitives.add(Cesium.Model.fromGltf({ url : '../../SampleData/models/CesiumAir/Cesium_Air.glb', - modelMatrix : Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll), + modelMatrix : Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll, Cesium.Ellipsoid.WGS84, fixedFrameTransform), minimumPixelSize : 128 })); @@ -128,19 +131,16 @@

Loading...

hpRange.pitch = pitch; hpRange.range = r * 50.0; camera.lookAt(center, hpRange); - update(); }); -document.addEventListener('keyup', function(e) { - var deltaRadians = Cesium.Math.toRadians(3.0); - +document.addEventListener('keydown', function(e) { switch (e.keyCode) { case 40: if (e.shiftKey) { // speed down speed = Math.max(--speed, 1); } else { - // pitch down until + // pitch down hpRoll.pitch -= deltaRadians; if (hpRoll.pitch < -Cesium.Math.TWO_PI) { hpRoll.pitch += Cesium.Math.TWO_PI; @@ -150,9 +150,9 @@

Loading...

case 38: if (e.shiftKey) { // speed up - speed = Math.max(speed++, 100); + speed = Math.min(++speed, 100); } else { - // pitch up until Math.PI/2 + // pitch up hpRoll.pitch += deltaRadians; if (hpRoll.pitch > Cesium.Math.TWO_PI) { hpRoll.pitch -= Cesium.Math.TWO_PI; @@ -161,7 +161,7 @@

Loading...

break; case 39: if (e.shiftKey) { - // roll right until Math.PI/2 + // roll right hpRoll.roll += deltaRadians; if (hpRoll.roll > Cesium.Math.TWO_PI) { hpRoll.roll -= Cesium.Math.TWO_PI; @@ -208,7 +208,7 @@

Loading...

speedVector = Cesium.Cartesian3.multiplyByScalar(Cesium.Cartesian3.UNIT_X, speed / 10, speedVector); position = Cesium.Matrix4.multiplyByPoint(planePrimitive.modelMatrix, speedVector, position); pathPosition.addSample(Cesium.JulianDate.now(), position); - Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll, undefined, planePrimitive.modelMatrix); + Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll, Cesium.Ellipsoid.WGS84, fixedFrameTransform, planePrimitive.modelMatrix); if (fromBehind.checked) { // Zoom to model diff --git a/Apps/Sandcastle/gallery/HeadingPitchRoll.jpg b/Apps/Sandcastle/gallery/HeadingPitchRoll.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cf389152b4832ab644d8dea89be8c5612443e81a GIT binary patch literal 24445 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»nJ45bG9M=NGSfazbj34~yo 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 k#`0@74*<7gVzr5STDGgUURi9_%o(oL>j + + + + + + + + Cesium Demo + + + + + + +
+
+

Loading...

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
Click on the 3D window then use the keyboard to change settings.
Heading: °
← to left/→ to right
Pitch: °
↑ to up/↓ to down
roll: °
← + ⇧ left/→ + ⇧ right
+
+ + + diff --git a/Apps/Sandcastle/gallery/LocalToFixedFrame.jpg b/Apps/Sandcastle/gallery/LocalToFixedFrame.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cf389152b4832ab644d8dea89be8c5612443e81a GIT binary patch literal 24445 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»nJ45bG9M=NGSfazbj34~yo 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

|(%74&T_QAXivAY!{I?%B_WHyEjWp3kW&Np- zQcLR+wZE31O||5|Mg2AoO*LzO;4$wN*zbIA@lWE8r3L>0f&T#EIl5m2E|07DLr1W- z@ZW*-4MtxB>iW-w&EA`>-gsle`b4)^(s+O2*Tda4XA{b8An@vFHd8_2d9F0Oo}1zK z#XpF8uf<;i_@BleESdD{O@HB)my5J-3V36{J{i&Vp9J_1;zz^(02x{6Y2l3r!g?2n zF4s$c3^lfeVSj3tFzMbH_;cZAn%}~H8nM!}(u&n)ILpKL^7o~$y9Iq$XqU|G4YhE; zyB&THFE%Ef@z3^(`(!#Lm&J>ywHv)(!FD>7()e59*^6J){1G>U6F_ekY6HNHs(8ap z({&9SUcZjl#Rpc0QM=S8)OCwH+y4L+c;a1d4;*V>w162)_7XHh%@mGt}#3x>xOtW7BMGdxw{vf!syU}#m;)2)0Y8zJYrIw4W>3S^or4`$Z z#o}qugrQbZle2Eodh)Go(_ImhsXl3Hz1v&ej+#UJznS8#`#$OyaZW6?!Tz%0?Zxh) zFU(dy62Yf=?+%R4i-z!^yhupkc!SDj{{V?%uS;j}W5iwt*J9Ugb=zbXl4~ueU3t*z z*S3P=P1P){ZsV}lyf<;ACZ}#LG<%3|(jT^I8iW&Sx+T?~sbQmDTNGE4vpjXz`$V^2 zW}lb$Jdu=YN!#K0q4puymj3`}&7D52@h9Vsr{W!N#-1+thZd)*TzH4Wy6&L%-WTv7 zwztMgp6=~mM@ivuft=Q;z zOXFw6eKovwt6%uO>i+=79wO5GVXOFJ`s>1f4z(RKLh--FEob0foAFaohQ{;4D`%u= z{wDZu@ZZH=2ZKt|^x1UXKSP^A@b;Ue>6$LP;{}wWv{{Ze%lGoxeVBG%-SS3?tnGWN z^2Piy-KhTnbjrQ>!TU&Seh}4sAFBLLwZ71GUj*qM1J(37{4d~>qw2mI(e#}}XrolO zPXwUUyh*0(dcD@8Z{wS^e;mbdwi?3tjO*GylY42g@ejt|7(PFEX4^^lq45su#iv8p zWWDgTH+nCFG@E@IeNu0Tm%5Tz-RK?-)3rS&%Td&|{{RRJ?JG;Ti$}ZDtY@*h)2Fxa zcf-gua*A=xv8lUaC!<{<+AsNhm;5k7tmP=C(^iI@vFq&b)6M z*+la)LpA)R-QImr>8|M(i4D^je9xo!Q&`nC4+mUZjVkL%(zT6y!rHE>r7h)_tK!zYx6?0l%Ui3}@TQ|U zeNRKPzp*HyIi5OPx5P>7{IFeZ(mj$Z+D}baO`{dRCuD4RE8_RYe}&0#3t$RpaQ(N$r-lcJ4s(7o#-x0N&%UkQanDu+d@M+b} z#2OWizLSgLPud6K=Yup|3dh3UJ=HXi7ihj9*1SP);xy2F6?LjwJ=eqU0QeTd+fVUU zq2asF6kAwc*!W`d-^E%y7dHA|h?h?Ap0TXKs_WWv-dU7Z%P_`W{{CD404zH%?vI{U zj@vJ@9`Rkf7~UlK$?-?U-W?tr)_h?R(JbcGA3@PH{{R7eFw!(#Dto;%;+~kZ>H2*5_qv3BBwL%yi#YUUQi{?U zrai)>ULs8^+uW!8@axHU^L_iX29ljOWp?7;irY1|+itCA)bI!%^@iwcw3gPS*T;rrced|mxlDz@cx};r1*zV z@o_~wK537=zOgG`XBuz$SMmhqB%Q3Tqq0kWUoRu)ANW(=CjS7R?F;_^0(B4mR#8P2 g+x?-8{{Wxw{{R4|{{YAdRjH@F+oJyfr+!EO*#zl!4FCWD diff --git a/Source/Core/Quaternion.js b/Source/Core/Quaternion.js index ea095baf1e23..ff7689ed735d 100644 --- a/Source/Core/Quaternion.js +++ b/Source/Core/Quaternion.js @@ -4,9 +4,11 @@ define([ './Check', './defaultValue', './defined', + './deprecationWarning', './DeveloperError', './FeatureDetection', './freezeObject', + './HeadingPitchRoll', './Math', './Matrix3' ], function( @@ -14,9 +16,11 @@ define([ Check, defaultValue, defined, + deprecationWarning, DeveloperError, FeatureDetection, freezeObject, + HeadingPitchRoll, CesiumMath, Matrix3) { 'use strict'; @@ -184,17 +188,29 @@ define([ * @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) { + Quaternion.fromHeadingPitchRoll = function(headingOrHeadingPitchRoll, pitchOrResult, roll, result) { //>>includeStart('debug', pragmas.debug); - Check.typeOf.number(heading, 'heading'); - Check.typeOf.number(pitch, 'pitch'); - Check.typeOf.number(roll, 'roll'); + if (headingOrHeadingPitchRoll instanceof HeadingPitchRoll) { + Check.typeOf.object(headingOrHeadingPitchRoll, 'HeadingPitchRoll'); + } else { + Check.typeOf.number(headingOrHeadingPitchRoll, 'heading'); + Check.typeOf.number(pitchOrResult, 'pitch'); + Check.typeOf.number(roll, 'roll'); + } //>>includeEnd('debug'); - - var rollQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_X, roll, scratchHPRQuaternion); - var pitchQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_Y, -pitch, result); + deprecationWarning('Quaternion.fromHeadingPitchRoll(heading, pitch, roll,result)', 'The method was deprecated in Cesium 1.31 and will be removed in version 1.32. ' + + 'Use Quaternion.fromHeadingPitchRoll(hpr,result) where hpr is a HeadingPitchRoll'); + var hpr; + if (headingOrHeadingPitchRoll instanceof HeadingPitchRoll) { + hpr = headingOrHeadingPitchRoll; + result = pitchOrResult; + } else { + hpr = new HeadingPitchRoll(headingOrHeadingPitchRoll, pitchOrResult, roll); + } + var rollQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_X, hpr.roll, scratchHPRQuaternion); + var pitchQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_Y, -hpr.pitch, result); result = Quaternion.multiply(pitchQuaternion, rollQuaternion, pitchQuaternion); - var headingQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_Z, -heading, scratchHPRQuaternion); + var headingQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_Z, -hpr.heading, scratchHPRQuaternion); return Quaternion.multiply(headingQuaternion, result, result); }; diff --git a/Source/Core/Transforms.js b/Source/Core/Transforms.js index d6f6dba64d0c..85ab059197ba 100644 --- a/Source/Core/Transforms.js +++ b/Source/Core/Transforms.js @@ -8,6 +8,7 @@ define([ './Check', './defaultValue', './defined', + './deprecationWarning', './DeveloperError', './EarthOrientationParameters', './EarthOrientationParametersSample', @@ -30,6 +31,7 @@ define([ Check, defaultValue, defined, + deprecationWarning, DeveloperError, EarthOrientationParameters, EarthOrientationParametersSample, @@ -51,7 +53,7 @@ define([ * @exports Transforms */ var Transforms = {}; - const vectorProductLocalFrame = { + var vectorProductLocalFrame = { up: { south: 'east', north: 'west', @@ -90,7 +92,7 @@ define([ } }; - const degeneratePositionLocalFrame = { + var degeneratePositionLocalFrame = { north: [ -1, 0, 0 ], @@ -112,9 +114,9 @@ define([ * Generates a function that computes a 4x4 transformation matrix from a reference frame * centered at the provided origin to the provided ellipsoid's fixed reference frame. * @param {String} firstAxis name of the first axis of the local reference frame. Must be - * east, north, up, west, south or down. + * 'east', 'north', 'up', 'west', 'south' or 'down'. * @param {String} secondAxis name of the second axis of the local reference frame. Must be - * east, north, up, west, south or down. + * 'east', 'north', 'up', 'west', 'south' or 'down'. * @return {localFrameToFixedFrameGenerator~resultat} The function that will computes a * 4x4 transformation matrix from a reference frame, with first axis and second axis compliant with the parameters, */ @@ -209,7 +211,7 @@ define([ return result; }; return resultat; - } + }; /** * Computes a 4x4 transformation matrix from a reference frame with an east-north-up axes @@ -312,7 +314,7 @@ define([ * @param {Cartesian3} origin The center point of the local reference frame. * @param {HeadingPitchRoll} headingPitchRoll The heading, pitch, and roll. * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation. - * @param {function} [fixedFrameTransform=Transforms.eastNorthUpToFixedFrame] A 4x4 transformation matrix from a reference frame + * @param {function} [fixedFrameTransformOrResult=Transforms.eastNorthUpToFixedFrame] A 4x4 transformation matrix from a reference frame * to the provided ellipsoid's fixed reference frame * @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. @@ -326,17 +328,20 @@ define([ * var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll); * var transform = Cesium.Transforms.headingPitchRollToFixedFrame(center, hpr); */ - Transforms.headingPitchRollToFixedFrame = function(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result) { - Check.typeOf.object(headingPitchRoll, 'headingPitchRoll'); - var heading = headingPitchRoll.heading; - var pitch = headingPitchRoll.pitch; - var roll = headingPitchRoll.roll; + Transforms.headingPitchRollToFixedFrame = function(origin, headingPitchRoll, ellipsoid, fixedFrameTransformOrResult, result) { + Check.typeOf.object(headingPitchRoll, 'HeadingPitchRoll'); // checks for required parameters happen in the called functions - fixedFrameTransform=defaultValue(fixedFrameConverter,Transforms.eastNorthUpToFixedFrame); - var hprQuaternion = Quaternion.fromHeadingPitchRoll(heading, pitch, roll, scratchHPRQuaternion); + deprecationWarning('Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, result)', 'The method was deprecated in Cesium 1.31 and will be removed in version 1.32. ' + + 'Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result) where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator)'); + if(fixedFrameTransformOrResult instanceof Matrix4){ + result = fixedFrameTransformOrResult; + fixedFrameTransformOrResult = undefined; + } + fixedFrameTransformOrResult=defaultValue(fixedFrameTransformOrResult,Transforms.eastNorthUpToFixedFrame); + var hprQuaternion = Quaternion.fromHeadingPitchRoll(headingPitchRoll, scratchHPRQuaternion); var hprMatrix = Matrix4.fromTranslationQuaternionRotationScale(Cartesian3.ZERO, hprQuaternion, scratchScale, scratchHPRMatrix4); - result = fixedFrameTransform(origin, ellipsoid, result); + result = fixedFrameTransformOrResult(origin, ellipsoid, result); return Matrix4.multiply(result, hprMatrix, result); }; @@ -352,7 +357,7 @@ define([ * @param {Cartesian3} origin The center point of the local reference frame. * @param {HeadingPitchRoll} headingPitchRoll The heading, pitch, and roll. * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation. - * @param {function} [fixedFrameTransform=Transforms.eastNorthUpToFixedFrame] A 4x4 transformation matrix from a reference frame + * @param {function} [fixedFrameTransformOrResult=Transforms.eastNorthUpToFixedFrame] A 4x4 transformation matrix from a reference frame * to the provided ellipsoid's fixed reference frame * @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. @@ -366,10 +371,16 @@ define([ * var hpr = new HeadingPitchRoll(heading, pitch, roll); * var quaternion = Cesium.Transforms.headingPitchRollQuaternion(center, hpr); */ - Transforms.headingPitchRollQuaternion = function(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result) { + Transforms.headingPitchRollQuaternion = function(origin, headingPitchRoll, ellipsoid, fixedFrameTransformOrResult, result) { // checks for required parameters happen in the called functions - Check.typeOf.object(headingPitchRoll, 'headingPitchRoll'); - var transform = Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid,fixedFrameTransform, scratchENUMatrix4); + Check.typeOf.object(headingPitchRoll, 'HeadingPitchRoll'); + deprecationWarning('Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, result)', 'The method was deprecated in Cesium 1.31 and will be removed in version 1.32. ' + + 'Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result) where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator)'); + if(fixedFrameTransformOrResult instanceof Quaternion){ + result = fixedFrameTransformOrResult; + fixedFrameTransformOrResult = undefined; + } + var transform = Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid,fixedFrameTransformOrResult, scratchENUMatrix4); var rotation = Matrix4.getRotation(transform, scratchHPRMatrix3); return Quaternion.fromRotationMatrix(rotation, result); }; diff --git a/Source/Scene/Camera.js b/Source/Scene/Camera.js index 66ea1413be01..c7bc713790d8 100644 --- a/Source/Scene/Camera.js +++ b/Source/Scene/Camera.js @@ -14,6 +14,7 @@ define([ '../Core/EllipsoidGeodesic', '../Core/Event', '../Core/HeadingPitchRange', + '../Core/HeadingPitchRoll', '../Core/Intersect', '../Core/IntersectionTests', '../Core/Math', @@ -42,6 +43,7 @@ define([ EllipsoidGeodesic, Event, HeadingPitchRange, + HeadingPitchRoll, Intersect, IntersectionTests, CesiumMath, @@ -963,14 +965,15 @@ define([ var scratchSetViewMatrix3 = new Matrix3(); var scratchSetViewCartographic = new Cartographic(); - function setView3D(camera, position, heading, pitch, roll) { + function setView3D(camera, position, hpr) { var currentTransform = Matrix4.clone(camera.transform, scratchSetViewTransform1); var localTransform = Transforms.eastNorthUpToFixedFrame(position, camera._projection.ellipsoid, scratchSetViewTransform2); camera._setTransform(localTransform); Cartesian3.clone(Cartesian3.ZERO, camera.position); + hpr.heading = hpr.heading - CesiumMath.PI_OVER_TWO; - var rotQuat = Quaternion.fromHeadingPitchRoll(heading - CesiumMath.PI_OVER_TWO, pitch, roll, scratchSetViewQuaternion); + var rotQuat = Quaternion.fromHeadingPitchRoll(hpr, scratchSetViewQuaternion); var rotMat = Matrix3.fromQuaternion(rotQuat, scratchSetViewMatrix3); Matrix3.getColumn(rotMat, 0, camera.direction); @@ -980,7 +983,7 @@ define([ camera._setTransform(currentTransform); } - function setViewCV(camera, position, heading, pitch, roll, convert) { + function setViewCV(camera, position,hpr, convert) { var currentTransform = Matrix4.clone(camera.transform, scratchSetViewTransform1); camera._setTransform(Matrix4.IDENTITY); @@ -992,8 +995,9 @@ define([ } Cartesian3.clone(position, camera.position); } + hpr.heading = hpr.heading - CesiumMath.PI_OVER_TWO; - var rotQuat = Quaternion.fromHeadingPitchRoll(heading - CesiumMath.PI_OVER_TWO, pitch, roll, scratchSetViewQuaternion); + var rotQuat = Quaternion.fromHeadingPitchRoll(hpr, scratchSetViewQuaternion); var rotMat = Matrix3.fromQuaternion(rotQuat, scratchSetViewMatrix3); Matrix3.getColumn(rotMat, 0, camera.direction); @@ -1003,10 +1007,7 @@ define([ camera._setTransform(currentTransform); } - function setView2D(camera, position, heading, convert) { - var pitch = -CesiumMath.PI_OVER_TWO; - var roll = 0.0; - + function setView2D(camera, position, hpr, convert) { var currentTransform = Matrix4.clone(camera.transform, scratchSetViewTransform1); camera._setTransform(Matrix4.IDENTITY); @@ -1033,7 +1034,10 @@ define([ } if (camera._scene.mapMode2D === MapMode2D.ROTATE) { - var rotQuat = Quaternion.fromHeadingPitchRoll(heading - CesiumMath.PI_OVER_TWO, pitch, roll, scratchSetViewQuaternion); + hpr.heading = hpr.heading - CesiumMath.PI_OVER_TWO; + hpr.pitch = -CesiumMath.PI_OVER_TWO; + hpr.roll = 0.0; + var rotQuat = Quaternion.fromHeadingPitchRoll(hpr, scratchSetViewQuaternion); var rotMat = Matrix3.fromQuaternion(rotQuat, scratchSetViewMatrix3); Matrix3.getColumn(rotMat, 2, camera.up); @@ -1160,14 +1164,16 @@ define([ var pitch = defaultValue(orientation.pitch, -CesiumMath.PI_OVER_TWO); var roll = defaultValue(orientation.roll, 0.0); + var hpr = new HeadingPitchRoll(heading, pitch, roll); + this._suspendTerrainAdjustment = true; if (mode === SceneMode.SCENE3D) { - setView3D(this, destination, heading, pitch, roll); + setView3D(this, destination, hpr); } else if (mode === SceneMode.SCENE2D) { - setView2D(this, destination, heading, convert); + setView2D(this, destination, hpr, convert); } else { - setViewCV(this, destination, heading, pitch, roll, convert); + setViewCV(this, destination, hpr, convert); } }; diff --git a/Specs/Core/HeadingPitchRollSpec.js b/Specs/Core/HeadingPitchRollSpec.js index 93c150ea666e..920b4c05896c 100644 --- a/Specs/Core/HeadingPitchRollSpec.js +++ b/Specs/Core/HeadingPitchRollSpec.js @@ -38,9 +38,14 @@ defineSuite([ [30 * deg2rad, 30 * deg2rad, 30 * deg2rad], [-30 * deg2rad, -30 * deg2rad, 45 * deg2rad] ]; + var hpr = new HeadingPitchRoll(); for (var i = 0; i < testingTab.length; i++) { var init = testingTab[i]; - var result = HeadingPitchRoll.fromQuaternion(Quaternion.fromHeadingPitchRoll(init[0], init[1], init[2])); + hpr.heading = init[0]; + hpr.pitch = init[1]; + hpr.roll = init[2]; + + var result = HeadingPitchRoll.fromQuaternion(Quaternion.fromHeadingPitchRoll(hpr)); expect(init[0]).toEqualEpsilon(result.heading, CesiumMath.EPSILON11); expect(init[1]).toEqualEpsilon(result.pitch, CesiumMath.EPSILON11); expect(init[2]).toEqualEpsilon(result.roll, CesiumMath.EPSILON11); diff --git a/Specs/Core/QuaternionSpec.js b/Specs/Core/QuaternionSpec.js index 7310a599acc0..c8e42b98f34d 100644 --- a/Specs/Core/QuaternionSpec.js +++ b/Specs/Core/QuaternionSpec.js @@ -2,12 +2,14 @@ defineSuite([ 'Core/Quaternion', 'Core/Cartesian3', + 'Core/HeadingPitchRoll', 'Core/Math', 'Core/Matrix3', 'Specs/createPackableSpecs' ], function( Quaternion, Cartesian3, + HeadingPitchRoll, CesiumMath, Matrix3, createPackableSpecs) { @@ -105,25 +107,29 @@ defineSuite([ it('fromHeadingPitchRoll with just heading', function() { var angle = CesiumMath.toRadians(20.0); - var quaternion = Quaternion.fromHeadingPitchRoll(angle, 0.0, 0.0); + var hpr = new HeadingPitchRoll(angle, 0.0, 0.0); + var quaternion = Quaternion.fromHeadingPitchRoll(hpr); expect(Matrix3.fromQuaternion(quaternion)).toEqualEpsilon(Matrix3.fromRotationZ(-angle), CesiumMath.EPSILON11); }); it('fromHeadingPitchRoll with just pitch', function() { var angle = CesiumMath.toRadians(20.0); - var quaternion = Quaternion.fromHeadingPitchRoll(0.0, angle, 0.0); + var hpr = new HeadingPitchRoll(0.0, angle, 0.0); + var quaternion = Quaternion.fromHeadingPitchRoll(hpr); expect(Matrix3.fromQuaternion(quaternion)).toEqualEpsilon(Matrix3.fromRotationY(-angle), CesiumMath.EPSILON11); }); it('fromHeadingPitchRoll with just roll', function() { var angle = CesiumMath.toRadians(20.0); - var quaternion = Quaternion.fromHeadingPitchRoll(0.0, 0.0, angle); + var hpr = new HeadingPitchRoll( 0.0, 0.0, angle); + var quaternion = Quaternion.fromHeadingPitchRoll(hpr); expect(Matrix3.fromQuaternion(quaternion)).toEqualEpsilon(Matrix3.fromRotationX(angle), CesiumMath.EPSILON11); }); it('fromHeadingPitchRoll with all angles (1)', function() { var angle = CesiumMath.toRadians(20.0); - var quaternion = Quaternion.fromHeadingPitchRoll(angle, angle, angle); + var hpr = new HeadingPitchRoll( angle, angle, angle); + var quaternion = Quaternion.fromHeadingPitchRoll(hpr); var expected = Matrix3.fromRotationX(angle); Matrix3.multiply(Matrix3.fromRotationY(-angle), expected, expected); Matrix3.multiply(Matrix3.fromRotationZ(-angle), expected, expected); @@ -134,7 +140,8 @@ defineSuite([ var heading = CesiumMath.toRadians(180.0); var pitch = CesiumMath.toRadians(-45.0); var roll = CesiumMath.toRadians(45.0); - var quaternion = Quaternion.fromHeadingPitchRoll(heading, pitch, roll); + var hpr = new HeadingPitchRoll( heading, pitch, roll); + var quaternion = Quaternion.fromHeadingPitchRoll(hpr); var expected = Matrix3.fromRotationX(roll); Matrix3.multiply(Matrix3.fromRotationY(-pitch), expected, expected); Matrix3.multiply(Matrix3.fromRotationZ(-heading), expected, expected); @@ -143,8 +150,9 @@ defineSuite([ it('fromHeadingPitchRoll works with result parameter', function() { var angle = CesiumMath.toRadians(20.0); + var hpr = new HeadingPitchRoll(0.0, 0.0, angle); var result = new Quaternion(); - var quaternion = Quaternion.fromHeadingPitchRoll(0.0, 0.0, angle, result); + var quaternion = Quaternion.fromHeadingPitchRoll(hpr, result); var expected = Quaternion.fromRotationMatrix(Matrix3.fromRotationX(angle)); expect(quaternion).toBe(result); expect(quaternion).toEqualEpsilon(expected, CesiumMath.EPSILON11); @@ -652,7 +660,7 @@ defineSuite([ Quaternion.fromRotationMatrix(undefined); }).toThrowDeveloperError(); }); - +/* it('fromHeadingPitchRoll throws with undefined heading', function() { expect(function() { Quaternion.fromHeadingPitchRoll(undefined, 0.0, 0.0); @@ -670,7 +678,7 @@ defineSuite([ Quaternion.fromHeadingPitchRoll(0.0, 0.0, undefined); }).toThrowDeveloperError(); }); - +*/ it('clone returns undefined with no parameter', function() { expect(Quaternion.clone()).toBeUndefined(); }); diff --git a/Specs/Core/TransformsSpec.js b/Specs/Core/TransformsSpec.js index 1d4682ca3b7a..3c47369a13c9 100644 --- a/Specs/Core/TransformsSpec.js +++ b/Specs/Core/TransformsSpec.js @@ -231,6 +231,150 @@ defineSuite([ expect(Matrix4.getColumn(returnedResult, 3, new Cartesian4())).toEqual(expectedTranslation); // translation }); + it('normal use of localFrameToFixedFrameGenerator', function() { + var cartesianTab = [ + new Cartesian3(0.0, 0.0, 1.0), + new Cartesian3(0.0, 0.0, -1.0), + new Cartesian3(10.0, 20.0, 30.0), + new Cartesian3(-10.0, -20.0, -30.0), + new Cartesian3(-25.0, 60.0, -1.0), + new Cartesian3(9.0, 0.0, -7.0) + ]; + + var converterTab = [ + { + converter: Transforms.localFrameToFixedFrameGenerator('north', 'east'), + order: ['north', 'east', 'down'] + }, { + converter: Transforms.localFrameToFixedFrameGenerator('north', 'west'), + order: ['north', 'west', 'up'] + }, { + converter: Transforms.localFrameToFixedFrameGenerator('north', 'up'), + order: ['north', 'up', 'east'] + }, { + converter: Transforms.localFrameToFixedFrameGenerator('north', 'down'), + order: ['north', 'down', 'west'] + }, { + converter: Transforms.localFrameToFixedFrameGenerator('south', 'east'), + order: ['south', 'east', 'up'] + }, { + converter: Transforms.localFrameToFixedFrameGenerator('south', 'west'), + order: ['south', 'west', 'down'] + }, { + converter: Transforms.localFrameToFixedFrameGenerator('south', 'up'), + order: ['south', 'up', 'west'] + }, { + converter: Transforms.localFrameToFixedFrameGenerator('south', 'down'), + order: ['south', 'down', 'east'] + }, { + converter: Transforms.localFrameToFixedFrameGenerator('east', 'north'), + order: ['east', 'north', 'up'] + }, { + converter: Transforms.localFrameToFixedFrameGenerator('east', 'south'), + order: ['east', 'south', 'down'] + }, { + converter: Transforms.localFrameToFixedFrameGenerator('east', 'up'), + order: ['east', 'up', 'south'] + }, { + converter: Transforms.localFrameToFixedFrameGenerator('east', 'down'), + order: ['east', 'down', 'north'] + }, { + converter: Transforms.localFrameToFixedFrameGenerator('west', 'north'), + order: ['west', 'north', 'down'] + }, { + converter: Transforms.localFrameToFixedFrameGenerator('west', 'south'), + order: ['west', 'south', 'up'] + }, { + converter: Transforms.localFrameToFixedFrameGenerator('west', 'up'), + order: ['west', 'up', 'north'] + }, { + converter: Transforms.localFrameToFixedFrameGenerator('west', 'down'), + order: ['west', 'down', 'south'] + }, { + converter: Transforms.localFrameToFixedFrameGenerator('up', 'north'), + order: ['up', 'north', 'west'] + }, { + converter: Transforms.localFrameToFixedFrameGenerator('up', 'south'), + order: ['up', 'south', 'east'] + }, { + converter: Transforms.localFrameToFixedFrameGenerator('up', 'east'), + order: ['up', 'east', 'north'] + }, { + converter: Transforms.localFrameToFixedFrameGenerator('up', 'west'), + order: ['up', 'west', 'south'] + } + ]; + + function testAllLocalFrame(classicalENUMatrix, position) { + var ENUColumn = new Cartesian4(); + var converterColumn = new Cartesian4(); + for (var i = 0; i < converterTab.length; i++) { + var converterMatrix = (converterTab[i].converter)(position, Ellipsoid.UNIT_SPHERE); + var order = converterTab[i].order; + // check translation + Matrix4.getColumn(classicalENUMatrix, 3, ENUColumn); + Matrix4.getColumn(converterMatrix, 3, converterColumn); + expect(ENUColumn).toEqual(converterColumn); + // check axis + for (var j = 0; j < 3; j++) { + Matrix4.getColumn(converterMatrix, j, converterColumn); + var axisName = order[j]; + if (axisName === 'east') { + Matrix4.getColumn(classicalENUMatrix, 0, ENUColumn); + } else if (axisName === 'west') { + Matrix4.getColumn(classicalENUMatrix, 0, ENUColumn); + Cartesian4.negate(ENUColumn, ENUColumn); + } else if (axisName === 'north') { + Matrix4.getColumn(classicalENUMatrix, 1, ENUColumn); + } else if (axisName === 'south') { + Matrix4.getColumn(classicalENUMatrix, 1, ENUColumn); + Cartesian4.negate(ENUColumn, ENUColumn); + } else if (axisName === 'up') { + Matrix4.getColumn(classicalENUMatrix, 2, ENUColumn); + } else if (axisName === 'down') { + Matrix4.getColumn(classicalENUMatrix, 2, ENUColumn); + Cartesian4.negate(ENUColumn, ENUColumn); + } + expect(ENUColumn).toEqual(converterColumn); + } + } + } + + for (var i = 0; i < cartesianTab.length; i++) { + var cartesian = cartesianTab[i]; + var classicalEastNorthUpReferential = Transforms.eastNorthUpToFixedFrame(cartesian, Ellipsoid.UNIT_SPHERE); + testAllLocalFrame(classicalEastNorthUpReferential,cartesian); + } + }); + + it('abnormal use of localFrameToFixedFrameGenerator', function() { + function checkDeveloperError(firstAxis,secondAxis){ + expect(function() { + Transforms.localFrameToFixedFrameGenerator(firstAxis, secondAxis); + }).toThrowDeveloperError(); + } + checkDeveloperError(undefined,undefined); + checkDeveloperError('north',undefined); + checkDeveloperError(undefined,'north'); + checkDeveloperError('south',undefined); + checkDeveloperError('northe','southe'); + + checkDeveloperError('north','north'); + checkDeveloperError('north','south'); + checkDeveloperError('south','north'); + checkDeveloperError('south','south'); + + checkDeveloperError('up','up'); + checkDeveloperError('up','down'); + checkDeveloperError('down','up'); + checkDeveloperError('down','down'); + + checkDeveloperError('east','east'); + checkDeveloperError('east','west'); + checkDeveloperError('west','east'); + checkDeveloperError('west','west'); + }); + it('headingPitchRollToFixedFrame works without a result parameter', function() { var origin = new Cartesian3(1.0, 0.0, 0.0); var heading = CesiumMath.toRadians(20.0); @@ -238,7 +382,7 @@ defineSuite([ var roll = CesiumMath.toRadians(40.0); var hpr = new HeadingPitchRoll(heading, pitch, roll); - var expectedRotation = Matrix3.fromQuaternion(Quaternion.fromHeadingPitchRoll(heading, pitch, roll)); + var expectedRotation = Matrix3.fromQuaternion(Quaternion.fromHeadingPitchRoll(hpr)); var expectedX = Matrix3.getColumn(expectedRotation, 0, new Cartesian3()); var expectedY = Matrix3.getColumn(expectedRotation, 1, new Cartesian3()); var expectedZ = Matrix3.getColumn(expectedRotation, 2, new Cartesian3()); @@ -259,14 +403,14 @@ defineSuite([ expect(actualTranslation).toEqual(origin); }); - it('headingPitchRollToFixedFrame works with a HeadingPitchRoll object and without a result parameter', function() { + it('headingPitchRollToFixedFrame works with a HeadingPitchRoll object and without a result parameter and a fixedFrameTransform', function() { var origin = new Cartesian3(1.0, 0.0, 0.0); var heading = CesiumMath.toRadians(20.0); var pitch = CesiumMath.toRadians(30.0); var roll = CesiumMath.toRadians(40.0); var hpr = new HeadingPitchRoll(heading, pitch, roll); - var expectedRotation = Matrix3.fromQuaternion(Quaternion.fromHeadingPitchRoll(heading, pitch, roll)); + var expectedRotation = Matrix3.fromQuaternion(Quaternion.fromHeadingPitchRoll(hpr)); var expectedX = Matrix3.getColumn(expectedRotation, 0, new Cartesian3()); var expectedY = Matrix3.getColumn(expectedRotation, 1, new Cartesian3()); var expectedZ = Matrix3.getColumn(expectedRotation, 2, new Cartesian3()); @@ -287,14 +431,14 @@ defineSuite([ expect(actualTranslation).toEqual(origin); }); - it('headingPitchRollToFixedFrame works with a result parameter', function() { + it('headingPitchRollToFixedFrame works with a HeadingPitchRoll object and without a result parameter', function() { var origin = new Cartesian3(1.0, 0.0, 0.0); var heading = CesiumMath.toRadians(20.0); var pitch = CesiumMath.toRadians(30.0); var roll = CesiumMath.toRadians(40.0); var hpr = new HeadingPitchRoll(heading, pitch, roll); - var expectedRotation = Matrix3.fromQuaternion(Quaternion.fromHeadingPitchRoll(heading, pitch, roll)); + var expectedRotation = Matrix3.fromQuaternion(Quaternion.fromHeadingPitchRoll(hpr)); var expectedX = Matrix3.getColumn(expectedRotation, 0, new Cartesian3()); var expectedY = Matrix3.getColumn(expectedRotation, 1, new Cartesian3()); var expectedZ = Matrix3.getColumn(expectedRotation, 2, new Cartesian3()); @@ -303,28 +447,26 @@ defineSuite([ Cartesian3.fromElements(expectedY.z, expectedY.x, expectedY.y, expectedY); Cartesian3.fromElements(expectedZ.z, expectedZ.x, expectedZ.y, expectedZ); - var result = new Matrix4(); - var returnedResult = Transforms.headingPitchRollToFixedFrame(origin, hpr, Ellipsoid.UNIT_SPHERE, result); + var returnedResult = Transforms.headingPitchRollToFixedFrame(origin, hpr, Ellipsoid.UNIT_SPHERE, Transforms.eastNorthUpToFixedFrame); var actualX = Cartesian3.fromCartesian4(Matrix4.getColumn(returnedResult, 0, new Cartesian4())); var actualY = Cartesian3.fromCartesian4(Matrix4.getColumn(returnedResult, 1, new Cartesian4())); var actualZ = Cartesian3.fromCartesian4(Matrix4.getColumn(returnedResult, 2, new Cartesian4())); var actualTranslation = Cartesian3.fromCartesian4(Matrix4.getColumn(returnedResult, 3, new Cartesian4())); - expect(returnedResult).toBe(result); expect(actualX).toEqual(expectedX); expect(actualY).toEqual(expectedY); expect(actualZ).toEqual(expectedZ); expect(actualTranslation).toEqual(origin); }); - it('headingPitchRollToFixedFrame works with a HeadingPitchRoll object and a result parameter', function() { + it('headingPitchRollToFixedFrame works with a result parameter', function() { var origin = new Cartesian3(1.0, 0.0, 0.0); var heading = CesiumMath.toRadians(20.0); var pitch = CesiumMath.toRadians(30.0); var roll = CesiumMath.toRadians(40.0); var hpr = new HeadingPitchRoll(heading, pitch, roll); - var expectedRotation = Matrix3.fromQuaternion(Quaternion.fromHeadingPitchRoll(heading, pitch, roll)); + var expectedRotation = Matrix3.fromQuaternion(Quaternion.fromHeadingPitchRoll(hpr)); var expectedX = Matrix3.getColumn(expectedRotation, 0, new Cartesian3()); var expectedY = Matrix3.getColumn(expectedRotation, 1, new Cartesian3()); var expectedZ = Matrix3.getColumn(expectedRotation, 2, new Cartesian3()); @@ -334,7 +476,7 @@ defineSuite([ Cartesian3.fromElements(expectedZ.z, expectedZ.x, expectedZ.y, expectedZ); var result = new Matrix4(); - var returnedResult = Transforms.headingPitchRollToFixedFrame(origin, hpr, Ellipsoid.UNIT_SPHERE, result); + var returnedResult = Transforms.headingPitchRollToFixedFrame(origin, hpr, Ellipsoid.UNIT_SPHERE, Transforms.eastNorthUpToFixedFrame, result); var actualX = Cartesian3.fromCartesian4(Matrix4.getColumn(returnedResult, 0, new Cartesian4())); var actualY = Cartesian3.fromCartesian4(Matrix4.getColumn(returnedResult, 1, new Cartesian4())); var actualZ = Cartesian3.fromCartesian4(Matrix4.getColumn(returnedResult, 2, new Cartesian4())); @@ -347,6 +489,56 @@ defineSuite([ expect(actualTranslation).toEqual(origin); }); + it('headingPitchRollToFixedFrame works with a custom fixedFrameTransform', function() { + var origin = new Cartesian3(1.0, 0.0, 0.0); + var heading = CesiumMath.toRadians(20.0); + var pitch = CesiumMath.toRadians(30.0); + var roll = CesiumMath.toRadians(40.0); + var hpr = new HeadingPitchRoll(heading, pitch, roll); + + var expectedRotation = Matrix3.fromQuaternion(Quaternion.fromHeadingPitchRoll(hpr)); + var expectedEast = Matrix3.getColumn(expectedRotation, 0, new Cartesian3()); // east + var expectedNorth = Matrix3.getColumn(expectedRotation, 1, new Cartesian3()); // north + var expectedUp = Matrix3.getColumn(expectedRotation, 2, new Cartesian3()); // up + + Cartesian3.fromElements(expectedEast.z, expectedEast.x, expectedEast.y, expectedEast); + Cartesian3.fromElements(expectedNorth.z, expectedNorth.x, expectedNorth.y, expectedNorth); + Cartesian3.fromElements(expectedUp.z, expectedUp.x, expectedUp.y, expectedUp); + + var result = new Matrix4(); + var returnedResult = Transforms.headingPitchRollToFixedFrame(origin, hpr, Ellipsoid.UNIT_SPHERE, Transforms.eastNorthUpToFixedFrame, result); + var actualEast = Cartesian3.fromCartesian4(Matrix4.getColumn(returnedResult, 0, new Cartesian4())); // east + var actualNorth = Cartesian3.fromCartesian4(Matrix4.getColumn(returnedResult, 1, new Cartesian4())); // north + var actualUp = Cartesian3.fromCartesian4(Matrix4.getColumn(returnedResult, 2, new Cartesian4())); // up + var actualTranslation = Cartesian3.fromCartesian4(Matrix4.getColumn(returnedResult, 3, new Cartesian4())); + + expect(returnedResult).toBe(result); + expect(actualEast).toEqual(expectedEast); + expect(actualNorth).toEqual(expectedNorth); + expect(actualUp).toEqual(expectedUp); + expect(actualTranslation).toEqual(origin); + + + var UNEFixedFrameConverter = Transforms.localFrameToFixedFrameGenerator('west','south'); // up north east + returnedResult = Transforms.headingPitchRollToFixedFrame(origin, hpr, Ellipsoid.UNIT_SPHERE, UNEFixedFrameConverter, result); + actualEast = Cartesian3.fromCartesian4(Matrix4.getColumn(returnedResult, 0, new Cartesian4())); // east + actualEast.y = -actualEast.y; + actualEast.z= -actualEast.z; + actualNorth = Cartesian3.fromCartesian4(Matrix4.getColumn(returnedResult, 1, new Cartesian4())); // north + actualNorth.y = -actualNorth.y; + actualNorth.z= -actualNorth.z; + actualUp = Cartesian3.fromCartesian4(Matrix4.getColumn(returnedResult, 2, new Cartesian4())); // up + actualUp.y = -actualUp.y; + actualUp.z= -actualUp.z; + actualTranslation = Cartesian3.fromCartesian4(Matrix4.getColumn(returnedResult, 3, new Cartesian4())); + + expect(returnedResult).toBe(result); + expect(actualEast).toEqual(expectedEast); + expect(actualNorth).toEqual(expectedNorth); + expect(actualUp).toEqual(expectedUp); + expect(actualTranslation).toEqual(origin); + }); + it('headingPitchRollQuaternion works without a result parameter', function() { var origin = new Cartesian3(1.0, 0.0, 0.0); var heading = CesiumMath.toRadians(20.0); @@ -357,12 +549,12 @@ defineSuite([ var transform = Transforms.headingPitchRollToFixedFrame(origin, hpr, Ellipsoid.UNIT_SPHERE); var expected = Matrix4.getRotation(transform, new Matrix3()); - var quaternion = Transforms.headingPitchRollQuaternion(origin, hpr, Ellipsoid.UNIT_SPHERE); + var quaternion = Transforms.headingPitchRollQuaternion(origin, hpr, Ellipsoid.UNIT_SPHERE, Transforms.eastNorthUpToFixedFrame); var actual = Matrix3.fromQuaternion(quaternion); expect(actual).toEqualEpsilon(expected, CesiumMath.EPSILON11); }); - it('headingPitchRollQuaternion works with a HeadingPitchRoll object and without a result parameter', function() { + it('headingPitchRollQuaternion works with a result parameter', function() { var origin = new Cartesian3(1.0, 0.0, 0.0); var heading = CesiumMath.toRadians(20.0); var pitch = CesiumMath.toRadians(30.0); @@ -372,12 +564,14 @@ defineSuite([ var transform = Transforms.headingPitchRollToFixedFrame(origin, hpr, Ellipsoid.UNIT_SPHERE); var expected = Matrix4.getRotation(transform, new Matrix3()); - var quaternion = Transforms.headingPitchRollQuaternion(origin, hpr, Ellipsoid.UNIT_SPHERE); + var result = new Quaternion(); + var quaternion = Transforms.headingPitchRollQuaternion(origin, hpr, Ellipsoid.UNIT_SPHERE, Transforms.eastNorthUpToFixedFrame, result); var actual = Matrix3.fromQuaternion(quaternion); + expect(quaternion).toBe(result); expect(actual).toEqualEpsilon(expected, CesiumMath.EPSILON11); }); - it('headingPitchRollQuaternion works with a result parameter', function() { + it('headingPitchRollQuaternion works without a custom fixedFrameTransform', function() { var origin = new Cartesian3(1.0, 0.0, 0.0); var heading = CesiumMath.toRadians(20.0); var pitch = CesiumMath.toRadians(30.0); @@ -388,24 +582,26 @@ defineSuite([ var expected = Matrix4.getRotation(transform, new Matrix3()); var result = new Quaternion(); - var quaternion = Transforms.headingPitchRollQuaternion(origin, hpr, Ellipsoid.UNIT_SPHERE, result); + var quaternion = Transforms.headingPitchRollQuaternion(origin, hpr, Ellipsoid.UNIT_SPHERE, undefined, result); var actual = Matrix3.fromQuaternion(quaternion); expect(quaternion).toBe(result); expect(actual).toEqualEpsilon(expected, CesiumMath.EPSILON11); }); - it('headingPitchRollQuaternion works with a HeadingPitchRoll object and a result parameter', function() { + + it('headingPitchRollQuaternion works with a custom fixedFrameTransform', function() { var origin = new Cartesian3(1.0, 0.0, 0.0); var heading = CesiumMath.toRadians(20.0); var pitch = CesiumMath.toRadians(30.0); var roll = CesiumMath.toRadians(40.0); var hpr = new HeadingPitchRoll(heading, pitch, roll); + var fixedFrameTransform = Transforms.localFrameToFixedFrameGenerator('west','south'); - var transform = Transforms.headingPitchRollToFixedFrame(origin, hpr, Ellipsoid.UNIT_SPHERE); + var transform = Transforms.headingPitchRollToFixedFrame(origin, hpr, Ellipsoid.UNIT_SPHERE, fixedFrameTransform); var expected = Matrix4.getRotation(transform, new Matrix3()); var result = new Quaternion(); - var quaternion = Transforms.headingPitchRollQuaternion(origin, hpr, Ellipsoid.UNIT_SPHERE, result); + var quaternion = Transforms.headingPitchRollQuaternion(origin, hpr, Ellipsoid.UNIT_SPHERE, fixedFrameTransform, result); var actual = Matrix3.fromQuaternion(quaternion); expect(quaternion).toBe(result); expect(actual).toEqualEpsilon(expected, CesiumMath.EPSILON11); @@ -919,7 +1115,7 @@ defineSuite([ it('headingPitchRollToFixedFrame throws without an origin', function() { expect(function() { - Transforms.headingPitchRollToFixedFrame(undefined, 0.0, 0.0, 0.0); + Transforms.headingPitchRollToFixedFrame(undefined, new HeadingPitchRoll()); }).toThrowDeveloperError(); }); From 603ef8669fe90193551b919aac06d6b6b4dc0229 Mon Sep 17 00:00:00 2001 From: Farouk Abdou Date: Sat, 21 Jan 2017 09:59:16 +0100 Subject: [PATCH 03/11] update the examples --- Apps/Sandcastle/gallery/HeadingPitchRoll.html | 4 +- .../Sandcastle/gallery/LocalToFixedFrame.html | 36 +++++++++++------- Apps/Sandcastle/gallery/LocalToFixedFrame.jpg | Bin 24445 -> 26556 bytes 3 files changed, 24 insertions(+), 16 deletions(-) diff --git a/Apps/Sandcastle/gallery/HeadingPitchRoll.html b/Apps/Sandcastle/gallery/HeadingPitchRoll.html index 82d507368d34..31406f2146e3 100644 --- a/Apps/Sandcastle/gallery/HeadingPitchRoll.html +++ b/Apps/Sandcastle/gallery/HeadingPitchRoll.html @@ -4,8 +4,8 @@ - - + + Cesium Demo diff --git a/Apps/Sandcastle/gallery/LocalToFixedFrame.html b/Apps/Sandcastle/gallery/LocalToFixedFrame.html index 58e8b220e21e..9e17c8e2787c 100644 --- a/Apps/Sandcastle/gallery/LocalToFixedFrame.html +++ b/Apps/Sandcastle/gallery/LocalToFixedFrame.html @@ -5,7 +5,7 @@ - + Cesium Demo @@ -76,37 +76,38 @@

Loading...

var localFrames = [ { pos: Cesium.Cartesian3.fromDegrees(-123.075, 44.045000, 5000.0), - converter: Cesium.Transforms.localFrameToFixedFrameGenerator('east','north'), - comments: 'Classical East North Up\nlocal Frame', offset: 300 + converter: Cesium.Transforms.eastNorthUpToFixedFrame , + comments: 'Classical East North Up\nlocal Frame' }, { - pos: Cesium.Cartesian3.fromDegrees(-123.075, 44.050000, 5000.0), + pos: Cesium.Cartesian3.fromDegrees(-123.075, 44.050000, 5500.0), converter: Cesium.Transforms.localFrameToFixedFrameGenerator('north','west'), - comments: 'North West Up\nlocal Frame', offset: -300 + comments: 'North West Up\nlocal Frame' }, { - pos: Cesium.Cartesian3.fromDegrees(-123.075, 44.040000, 5000.0), + pos: Cesium.Cartesian3.fromDegrees(-123.075, 44.040000, 4500.0), converter: Cesium.Transforms.localFrameToFixedFrameGenerator('south','up'), - comments: 'South Up West\nlocal Frame', offset: -300 + comments: 'South Up West\nlocal Frame' }, { - pos: Cesium.Cartesian3.fromDegrees(-123.075, 44.055000, 5000.0), + pos: Cesium.Cartesian3.fromDegrees(-123.075, 44.050000, 4500.0), converter: Cesium.Transforms.localFrameToFixedFrameGenerator('up','east'), - comments: 'Up East North\nlocal Frame', offset: 300 + comments: 'Up East North\nlocal Frame' }, { - pos: Cesium.Cartesian3.fromDegrees(-123.075, 44.035000, 5000.0), + pos: Cesium.Cartesian3.fromDegrees(-123.075, 44.040000, 5500.0), converter: Cesium.Transforms.localFrameToFixedFrameGenerator('down','east'), - comments: 'Down East South\nlocal Frame', offset: 300 }, + comments: 'Down East South\nlocal Frame' + }, ]; var primitives= []; +var hprRollZero = new Cesium.HeadingPitchRoll(); for( var i = 0; i < localFrames.length; i++){ var position = localFrames[i].pos; var converter = localFrames[i].converter; var comments = localFrames[i].comments; - var offset = localFrames[i].offset; var planePrimitive = scene.primitives.add(Cesium.Model.fromGltf({ url : '../../SampleData/models/CesiumAir/Cesium_Air.glb', modelMatrix : Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll, Cesium.Ellipsoid.WGS84, converter), @@ -114,8 +115,15 @@

Loading...

})); primitives.push({primitive: planePrimitive, converter: converter, position: position }); + var modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(position, hprRollZero, Cesium.Ellipsoid.WGS84, converter); + scene.primitives.add(new Cesium.DebugModelMatrixPrimitive({ + modelMatrix : modelMatrix, + length : 300.0, + width : 10.0 + })); + var positionLabel = position.clone(); - positionLabel.z = position.z + offset; + positionLabel.z = position.z + 300.0; viewer.entities.add({ position : positionLabel, label : { @@ -126,7 +134,7 @@

Loading...

outlineWidth : 2, style : Cesium.LabelStyle.FILL_AND_OUTLINE, verticalOrigin : Cesium.VerticalOrigin.CENTER, - HorizontalOrigin : Cesium.HorizontalOrigin.LEFT + HorizontalOrigin : Cesium.HorizontalOrigin.RIGHT } }); } diff --git a/Apps/Sandcastle/gallery/LocalToFixedFrame.jpg b/Apps/Sandcastle/gallery/LocalToFixedFrame.jpg index cf389152b4832ab644d8dea89be8c5612443e81a..5c652c277d08ffc0500911b3688c9404fe950c7d 100644 GIT binary patch literal 26556 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»nJ45bG9M=NGSfazbj34~yo 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 k#`0@74*<7gVzr5STDGgUURi9_%o(oL>j Date: Sun, 22 Jan 2017 10:13:29 +0100 Subject: [PATCH 04/11] update CHANGES.md and resize images in gallery --- Apps/Sandcastle/gallery/HeadingPitchRoll.jpg | Bin 24445 -> 13616 bytes Apps/Sandcastle/gallery/LocalToFixedFrame.jpg | Bin 26556 -> 28333 bytes CHANGES.md | 4 ++++ 3 files changed, 4 insertions(+) diff --git a/Apps/Sandcastle/gallery/HeadingPitchRoll.jpg b/Apps/Sandcastle/gallery/HeadingPitchRoll.jpg index cf389152b4832ab644d8dea89be8c5612443e81a..6074ed758ac59ab8e41807686e5ca41c9ffd2525 100644 GIT binary patch delta 13549 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%0Dd?S^tVqo-N1EXyjXdP1>OyIhT18`vA;DIsO1 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»nJ45bG9M=NGSfazbj34~yo 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 literal 26556 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 Date: Mon, 30 Jan 2017 10:18:43 +0100 Subject: [PATCH 05/11] update CHANGES.md --- CHANGES.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 1a7a0543aff4..f121be63bc0d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,13 +5,10 @@ Change Log * Deprecated * The properties `url` and `key` will be removed from `GeocoderViewModel` in 1.31. These properties will be available on geocoder services that support them, like `BingMapsGeocoderService`. * The function `createBinormalAndBitangent` of `GeometryPipeline` will be removed in 1.31. Use the function `createTangentAndBitangent` instead. [#4856](https://github.com/AnalyticalGraphicsInc/cesium/pull/4856) -<<<<<<< HEAD * The function `Quaternion.fromHeadingPitchRoll(heading, pitch, roll,result)` will be removed in 1.32. Use `Quaternion.fromHeadingPitchRoll(hpr,result)` instead where hpr is a HeadingPitchRoll. * The function `Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, result)` will be removed in 1.32. Use `Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result)` instead where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator). * The function `Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, result)` will be removed in 1.32. Use `Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result)` instead where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator). -======= * The enums `MIDDLE_DOUBLE_CLICK` and `RIGHT_DOUBLE_CLICK` from `ScreenSpaceEventType` have been deprecated and will be removed in 1.31. [#4910](https://github.com/AnalyticalGraphicsInc/cesium/pull/4910) ->>>>>>> upstream/master * Breaking changes * Removed separate `heading`, `pitch`, `roll` parameters from `Transform.headingPitchRollToFixedFrame` and `Transform.headingPitchRollQuaternion`. Pass a `headingPitchRoll` object instead. [#4843](https://github.com/AnalyticalGraphicsInc/cesium/pull/4843) * The property `binornmal` has been renamed to `bitangent` for `Geometry` and `VertexFormat`. [#4856](https://github.com/AnalyticalGraphicsInc/cesium/pull/4856) From ee49f0b6487b7e77e51ee4729ee7584e1c2f90d3 Mon Sep 17 00:00:00 2001 From: Farouk Abdou Date: Tue, 31 Jan 2017 00:07:29 +0100 Subject: [PATCH 06/11] correct checks --- Source/Core/Quaternion.js | 2 +- Source/Core/Transforms.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Source/Core/Quaternion.js b/Source/Core/Quaternion.js index 31eeeebc79e7..521a59b290a1 100644 --- a/Source/Core/Quaternion.js +++ b/Source/Core/Quaternion.js @@ -191,7 +191,7 @@ define([ Quaternion.fromHeadingPitchRoll = function(headingOrHeadingPitchRoll, pitchOrResult, roll, result) { //>>includeStart('debug', pragmas.debug); if (headingOrHeadingPitchRoll instanceof HeadingPitchRoll) { - Check.typeOf.object(headingOrHeadingPitchRoll, 'HeadingPitchRoll'); + Check.typeOf.object('headingPitchRoll',headingOrHeadingPitchRoll ); } else { Check.typeOf.number(headingOrHeadingPitchRoll, 'heading'); Check.typeOf.number(pitchOrResult, 'pitch'); diff --git a/Source/Core/Transforms.js b/Source/Core/Transforms.js index 997b855ce125..4b1f6926f6ea 100644 --- a/Source/Core/Transforms.js +++ b/Source/Core/Transforms.js @@ -329,7 +329,7 @@ define([ * var transform = Cesium.Transforms.headingPitchRollToFixedFrame(center, hpr); */ Transforms.headingPitchRollToFixedFrame = function(origin, headingPitchRoll, ellipsoid, fixedFrameTransformOrResult, result) { - Check.typeOf.object(headingPitchRoll, 'HeadingPitchRoll'); + Check.typeOf.object( 'HeadingPitchRoll', headingPitchRoll); // checks for required parameters happen in the called functions deprecationWarning('Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, result)', 'The method was deprecated in Cesium 1.31 and will be removed in version 1.32. ' + @@ -373,7 +373,7 @@ define([ */ Transforms.headingPitchRollQuaternion = function(origin, headingPitchRoll, ellipsoid, fixedFrameTransformOrResult, result) { // checks for required parameters happen in the called functions - Check.typeOf.object(headingPitchRoll, 'HeadingPitchRoll'); + Check.typeOf.object( 'HeadingPitchRoll', headingPitchRoll); deprecationWarning('Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, result)', 'The method was deprecated in Cesium 1.31 and will be removed in version 1.32. ' + 'Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result) where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator)'); if(fixedFrameTransformOrResult instanceof Quaternion){ From 8f4edca81d33c714302e5a13626264f4a29aff01 Mon Sep 17 00:00:00 2001 From: Farouk Abdou Date: Wed, 1 Feb 2017 07:12:39 +0100 Subject: [PATCH 07/11] correct changes --- CHANGES.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index dde2f5329c2e..00ca2d010cc2 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,16 +5,13 @@ Change Log * Deprecated * The properties `url` and `key` will be removed from `GeocoderViewModel` in 1.31. These properties will be available on geocoder services that support them, like `BingMapsGeocoderService`. -<<<<<<< HEAD * The function `createBinormalAndBitangent` of `GeometryPipeline` will be removed in 1.31. Use the function `createTangentAndBitangent` instead. [#4856](https://github.com/AnalyticalGraphicsInc/cesium/pull/4856) * The function `Quaternion.fromHeadingPitchRoll(heading, pitch, roll,result)` will be removed in 1.32. Use `Quaternion.fromHeadingPitchRoll(hpr,result)` instead where hpr is a HeadingPitchRoll. * The function `Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, result)` will be removed in 1.32. Use `Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result)` instead where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator). * The function `Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, result)` will be removed in 1.32. Use `Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result)` instead where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator). * The enums `MIDDLE_DOUBLE_CLICK` and `RIGHT_DOUBLE_CLICK` from `ScreenSpaceEventType` have been deprecated and will be removed in 1.31. [#4910](https://github.com/AnalyticalGraphicsInc/cesium/pull/4910) * The function `GeometryPipeline.computeBinormalAndTangent` will be removed in 1.31. Use the function `GeometryPipeline.createTangentAndBitangent` instead. [#4856](https://github.com/AnalyticalGraphicsInc/cesium/pull/4856) -======= * The function `GeometryPipeline.computeBinormalAndTangent` will be removed in 1.31. Use `GeometryPipeline.createTangentAndBitangent` instead. [#4856](https://github.com/AnalyticalGraphicsInc/cesium/pull/4856) ->>>>>>> upstream/master * The enums `MIDDLE_DOUBLE_CLICK` and `RIGHT_DOUBLE_CLICK` from `ScreenSpaceEventType` have been deprecated and will be removed in 1.31. [#4910](https://github.com/AnalyticalGraphicsInc/cesium/pull/4910) * Breaking changes * Removed separate `heading`, `pitch`, `roll` parameters from `Transform.headingPitchRollToFixedFrame` and `Transform.headingPitchRollQuaternion`. Pass a `HeadingPitchRoll` object instead. [#4843](https://github.com/AnalyticalGraphicsInc/cesium/pull/4843) @@ -36,13 +33,10 @@ Change Log * Fixed a bug that affected dynamic graphics with time-dynamic modelMatrix. [#4907](https://github.com/AnalyticalGraphicsInc/cesium/pull/4907) * Fixed `Geocoder` autocomplete drop down visibility in Firefox. [#4916](https://github.com/AnalyticalGraphicsInc/cesium/issues/4916) * Added `Rectangle.fromRadians`. -<<<<<<< HEAD * `TerrainProvider` now optionally exposes an `availability` property that can be used to query the terrain level that is available at a location or in a rectangle. Currently only `CesiumTerrainProvider` exposes this property. * Added `sampleTerrainMostDetailed` to sample the height of an array of positions using the best available terrain data at each point. This requires a `TerrainProvider` with the `availability` property. * Added `Transforms.localFrameToFixedFrameGenerator` to generate a function that computes a 4x4 transformation matrix from a local reference frame to fixed reference frame. -======= * Updated the morph so the default view in Columbus View is now angled. [#3878](https://github.com/AnalyticalGraphicsInc/cesium/issues/3878) ->>>>>>> upstream/master * Added 2D and Columbus View support for models using the RTC extension or whose vertices are in WGS84 coordinates. [#4922](https://github.com/AnalyticalGraphicsInc/cesium/pull/4922) * The attribute `perInstanceAttribute` of `DebugAppearance` has been made optional and defaults to `false`. * Fixed a bug that would cause a crash when `debugShowFrustums` is enabled with OIT. [#4864](https://github.com/AnalyticalGraphicsInc/cesium/pull/4864) From c6df6ccb98a9260095ec2642a424ed5225e8bd41 Mon Sep 17 00:00:00 2001 From: Farouk Abdou Date: Wed, 8 Feb 2017 22:47:12 +0100 Subject: [PATCH 08/11] update changes.md --- CHANGES.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 1283d757721a..5038b2d7b58f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,10 @@ Change Log ========== ### 1.31 - 2017-03-01 +* Deprecated + * The function `Quaternion.fromHeadingPitchRoll(heading, pitch, roll,result)` will be removed in 1.32. Use `Quaternion.fromHeadingPitchRoll(hpr,result)` instead where hpr is a HeadingPitchRoll. + * The function `Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, result)` will be removed in 1.32. Use `Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result)` instead where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator). + * The function `Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, result)` will be removed in 1.32. Use `Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result)` instead where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator). * Added support to `DebugCameraPrimitive` to draw multifrustum planes. The attribute `debugShowFrustumPlanes` of `Scene` and `frustumPlanes` of `CesiumInspector` toggles this. `FrameState` has been augmented to include `frustumSplits` which is a `Number[]` of the near/far planes of the camera frustums. * Enable rendering `GroundPrimitives` on hardware without the `EXT_frag_depth` extension; however, this could cause artifacts for certain viewing angles. * Added compressed texture support. [#4758](https://github.com/AnalyticalGraphicsInc/cesium/pull/4758) @@ -10,15 +14,13 @@ Change Log * Added new `PixelFormat` and `WebGLConstants` enums from WebGL extensions `WEBGL_compressed_s3tc`, `WEBGL_compressed_texture_pvrtc`, and `WEBGL_compressed_texture_etc1`. * Added `CompressedTextureBuffer`. * Improved `RectangleGeometry` by skipping unecessary logic in the code [#4948](https://github.com/AnalyticalGraphicsInc/cesium/pull/4948) +* * Added `Transforms.localFrameToFixedFrameGenerator` to generate a function that computes a 4x4 transformation matrix from a local reference frame to fixed reference frame. ### 1.30 - 2017-02-01 * Deprecated * The properties `url` and `key` will be removed from `GeocoderViewModel` in 1.31. These properties will be available on geocoder services that support them, like `BingMapsGeocoderService`. * The function `createBinormalAndBitangent` of `GeometryPipeline` will be removed in 1.31. Use the function `createTangentAndBitangent` instead. [#4856](https://github.com/AnalyticalGraphicsInc/cesium/pull/4856) - * The function `Quaternion.fromHeadingPitchRoll(heading, pitch, roll,result)` will be removed in 1.32. Use `Quaternion.fromHeadingPitchRoll(hpr,result)` instead where hpr is a HeadingPitchRoll. - * The function `Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, result)` will be removed in 1.32. Use `Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result)` instead where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator). - * The function `Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, result)` will be removed in 1.32. Use `Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result)` instead where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator). * The enums `MIDDLE_DOUBLE_CLICK` and `RIGHT_DOUBLE_CLICK` from `ScreenSpaceEventType` have been deprecated and will be removed in 1.31. [#4910](https://github.com/AnalyticalGraphicsInc/cesium/pull/4910) * The function `GeometryPipeline.computeBinormalAndTangent` will be removed in 1.31. Use the function `GeometryPipeline.createTangentAndBitangent` instead. [#4856](https://github.com/AnalyticalGraphicsInc/cesium/pull/4856) * The function `GeometryPipeline.computeBinormalAndTangent` will be removed in 1.31. Use `GeometryPipeline.createTangentAndBitangent` instead. [#4856](https://github.com/AnalyticalGraphicsInc/cesium/pull/4856) @@ -45,7 +47,6 @@ Change Log * Added `Rectangle.fromRadians`. * `TerrainProvider` now optionally exposes an `availability` property that can be used to query the terrain level that is available at a location or in a rectangle. Currently only `CesiumTerrainProvider` exposes this property. * Added `sampleTerrainMostDetailed` to sample the height of an array of positions using the best available terrain data at each point. This requires a `TerrainProvider` with the `availability` property. -* Added `Transforms.localFrameToFixedFrameGenerator` to generate a function that computes a 4x4 transformation matrix from a local reference frame to fixed reference frame. * Updated the morph so the default view in Columbus View is now angled. [#3878](https://github.com/AnalyticalGraphicsInc/cesium/issues/3878) * Added 2D and Columbus View support for models using the RTC extension or whose vertices are in WGS84 coordinates. [#4922](https://github.com/AnalyticalGraphicsInc/cesium/pull/4922) * The attribute `perInstanceAttribute` of `DebugAppearance` has been made optional and defaults to `false`. From 17f8a3f0be1d95f16000be86bb225363fd5627e3 Mon Sep 17 00:00:00 2001 From: Farouk Abdou Date: Thu, 9 Feb 2017 00:10:07 +0100 Subject: [PATCH 09/11] update in regards of the code review --- CHANGES.md | 8 +- Source/Core/Quaternion.js | 17 ++-- Source/Core/Transforms.js | 148 ++++++++++++++++++----------------- Source/Scene/Camera.js | 15 ++-- Specs/Core/QuaternionSpec.js | 18 ----- 5 files changed, 97 insertions(+), 109 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 5038b2d7b58f..ffbb36c3f1e3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,9 +3,9 @@ Change Log ### 1.31 - 2017-03-01 * Deprecated - * The function `Quaternion.fromHeadingPitchRoll(heading, pitch, roll,result)` will be removed in 1.32. Use `Quaternion.fromHeadingPitchRoll(hpr,result)` instead where hpr is a HeadingPitchRoll. - * The function `Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, result)` will be removed in 1.32. Use `Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result)` instead where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator). - * The function `Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, result)` will be removed in 1.32. Use `Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result)` instead where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator). + * The function `Quaternion.fromHeadingPitchRoll(heading, pitch, roll,result)` will be removed in 1.33. Use `Quaternion.fromHeadingPitchRoll(hpr,result)` instead where hpr is a HeadingPitchRoll. + * The function `Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, result)` will be removed in 1.33. Use `Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result)` instead where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator). + * The function `Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, result)` will be removed in 1.33. Use `Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result)` instead where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator). * Added support to `DebugCameraPrimitive` to draw multifrustum planes. The attribute `debugShowFrustumPlanes` of `Scene` and `frustumPlanes` of `CesiumInspector` toggles this. `FrameState` has been augmented to include `frustumSplits` which is a `Number[]` of the near/far planes of the camera frustums. * Enable rendering `GroundPrimitives` on hardware without the `EXT_frag_depth` extension; however, this could cause artifacts for certain viewing angles. * Added compressed texture support. [#4758](https://github.com/AnalyticalGraphicsInc/cesium/pull/4758) @@ -21,8 +21,6 @@ Change Log * Deprecated * The properties `url` and `key` will be removed from `GeocoderViewModel` in 1.31. These properties will be available on geocoder services that support them, like `BingMapsGeocoderService`. * The function `createBinormalAndBitangent` of `GeometryPipeline` will be removed in 1.31. Use the function `createTangentAndBitangent` instead. [#4856](https://github.com/AnalyticalGraphicsInc/cesium/pull/4856) - * The enums `MIDDLE_DOUBLE_CLICK` and `RIGHT_DOUBLE_CLICK` from `ScreenSpaceEventType` have been deprecated and will be removed in 1.31. [#4910](https://github.com/AnalyticalGraphicsInc/cesium/pull/4910) - * The function `GeometryPipeline.computeBinormalAndTangent` will be removed in 1.31. Use the function `GeometryPipeline.createTangentAndBitangent` instead. [#4856](https://github.com/AnalyticalGraphicsInc/cesium/pull/4856) * The function `GeometryPipeline.computeBinormalAndTangent` will be removed in 1.31. Use `GeometryPipeline.createTangentAndBitangent` instead. [#4856](https://github.com/AnalyticalGraphicsInc/cesium/pull/4856) * The enums `MIDDLE_DOUBLE_CLICK` and `RIGHT_DOUBLE_CLICK` from `ScreenSpaceEventType` have been deprecated and will be removed in 1.31. [#4910](https://github.com/AnalyticalGraphicsInc/cesium/pull/4910) * Breaking changes diff --git a/Source/Core/Quaternion.js b/Source/Core/Quaternion.js index 521a59b290a1..10b4cde99adc 100644 --- a/Source/Core/Quaternion.js +++ b/Source/Core/Quaternion.js @@ -176,6 +176,9 @@ define([ }; var scratchHPRQuaternion = new Quaternion(); + var scratchHeadingQuaternion = new Quaternion(); + var scratchPitchQuaternion = new Quaternion(); + var scratchRollQuaternion = new Quaternion(); /** * Computes a rotation from the given heading, pitch and roll angles. Heading is the rotation about the @@ -198,20 +201,20 @@ define([ Check.typeOf.number(roll, 'roll'); } //>>includeEnd('debug'); - deprecationWarning('Quaternion.fromHeadingPitchRoll(heading, pitch, roll,result)', 'The method was deprecated in Cesium 1.31 and will be removed in version 1.32. ' + - 'Use Quaternion.fromHeadingPitchRoll(hpr,result) where hpr is a HeadingPitchRoll'); var hpr; if (headingOrHeadingPitchRoll instanceof HeadingPitchRoll) { hpr = headingOrHeadingPitchRoll; result = pitchOrResult; } else { + deprecationWarning('Quaternion.fromHeadingPitchRoll(heading, pitch, roll,result)', 'The method was deprecated in Cesium 1.32 and will be removed in version 1.33. ' + + 'Use Quaternion.fromHeadingPitchRoll(hpr,result) where hpr is a HeadingPitchRoll'); hpr = new HeadingPitchRoll(headingOrHeadingPitchRoll, pitchOrResult, roll); } - var rollQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_X, hpr.roll, scratchHPRQuaternion); - var pitchQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_Y, -hpr.pitch, result); - result = Quaternion.multiply(pitchQuaternion, rollQuaternion, pitchQuaternion); - var headingQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_Z, -hpr.heading, scratchHPRQuaternion); - return Quaternion.multiply(headingQuaternion, result, result); + scratchRollQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_X, hpr.roll, scratchHPRQuaternion); + scratchPitchQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_Y, -hpr.pitch, result); + result = Quaternion.multiply(scratchPitchQuaternion, scratchRollQuaternion, scratchPitchQuaternion); + scratchHeadingQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_Z, -hpr.heading, scratchHPRQuaternion); + return Quaternion.multiply(scratchHeadingQuaternion, result, result); }; var sampledQuaternionAxis = new Cartesian3(); diff --git a/Source/Core/Transforms.js b/Source/Core/Transforms.js index 4b1f6926f6ea..a0ffcf02a443 100644 --- a/Source/Core/Transforms.js +++ b/Source/Core/Transforms.js @@ -110,6 +110,18 @@ define([ ], down: [0, 0, -1] }; + + var scratchCalculateCartesian = { + east: new Cartesian3(), + north: new Cartesian3(), + up: new Cartesian3(), + west: new Cartesian3(), + south: new Cartesian3(), + down: new Cartesian3() + }; + var scratchFirstCartesian = new Cartesian3(); + var scratchSecondCartesian = new Cartesian3(); + var scratchThirdCartesian = new Cartesian3(); /** * Generates a function that computes a 4x4 transformation matrix from a reference frame * centered at the provided origin to the provided ellipsoid's fixed reference frame. @@ -122,87 +134,78 @@ define([ */ Transforms.localFrameToFixedFrameGenerator = function( firstAxis, secondAxis) { if (!vectorProductLocalFrame.hasOwnProperty(firstAxis) || !vectorProductLocalFrame[firstAxis].hasOwnProperty(secondAxis)) { - throw new DeveloperError('firstAxis and secondAxis must be east, north, up, west, south or down.'); + throw new DeveloperError('firstAxis and secondAxis must be east, north, up, west, south or down.'); } var thirdAxis = vectorProductLocalFrame[firstAxis][secondAxis]; - var calculateCartesian = { - east: new Cartesian3(), - north: new Cartesian3(), - up: new Cartesian3(), - west: new Cartesian3(), - south: new Cartesian3(), - down: new Cartesian3() - }; - var firstCartesian = new Cartesian3(); - var secondCartesian = new Cartesian3(); - var thirdCartesian = new Cartesian3(); + /** - * [resultat description] + * Computes a 4x4 transformation matrix from a reference frame + * centered at the provided origin to the provided ellipsoid's fixed reference frame. + * @callback Transforms~LocalFrameToFixedFrame * @param {Cartesian3} origin The center point of the local reference frame. * @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. */ - var resultat= function(origin, ellipsoid, result) { + var resultat = function(origin, ellipsoid, result) { //>>includeStart('debug', pragmas.debug); if (!defined(origin)) { - throw new DeveloperError('origin is required.'); + throw new DeveloperError('origin is required.'); } //>>includeEnd('debug'); if (!defined(result)) { - result = new Matrix4(); + result = new Matrix4(); } // If x and y are zero, assume origin is at a pole, which is a special case. if (CesiumMath.equalsEpsilon(origin.x, 0.0, CesiumMath.EPSILON14) && CesiumMath.equalsEpsilon(origin.y, 0.0, CesiumMath.EPSILON14)) { - var sign = CesiumMath.sign(origin.z); - - Cartesian3.unpack(degeneratePositionLocalFrame[firstAxis], 0, firstCartesian); - if (firstAxis !== 'east' && firstAxis !== 'west') { - Cartesian3.multiplyByScalar(firstCartesian, sign, firstCartesian); - } - - Cartesian3.unpack(degeneratePositionLocalFrame[secondAxis], 0, secondCartesian); - if (secondAxis !== 'east' && secondAxis !== 'west') { - Cartesian3.multiplyByScalar(secondCartesian, sign, secondCartesian); - } - - Cartesian3.unpack(degeneratePositionLocalFrame[thirdAxis], 0, thirdCartesian); - if (thirdAxis !== 'east' && thirdAxis !== 'west') { - Cartesian3.multiplyByScalar(thirdCartesian, sign, thirdCartesian); - } + var sign = CesiumMath.sign(origin.z); + + Cartesian3.unpack(degeneratePositionLocalFrame[firstAxis], 0, scratchFirstCartesian); + if (firstAxis !== 'east' && firstAxis !== 'west') { + Cartesian3.multiplyByScalar(scratchFirstCartesian, sign, scratchFirstCartesian); + } + + Cartesian3.unpack(degeneratePositionLocalFrame[secondAxis], 0, scratchSecondCartesian); + if (secondAxis !== 'east' && secondAxis !== 'west') { + Cartesian3.multiplyByScalar(scratchSecondCartesian, sign, scratchSecondCartesian); + } + + Cartesian3.unpack(degeneratePositionLocalFrame[thirdAxis], 0, scratchThirdCartesian); + if (thirdAxis !== 'east' && thirdAxis !== 'west') { + Cartesian3.multiplyByScalar(scratchThirdCartesian, sign, scratchThirdCartesian); + } } else { - - ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - ellipsoid.geodeticSurfaceNormal(origin, calculateCartesian.up); - - var up = calculateCartesian.up; - var east = calculateCartesian.east; - east.x = -origin.y; - east.y = origin.x; - east.z = 0.0; - Cartesian3.normalize(east, calculateCartesian.east); - Cartesian3.cross(up, east, calculateCartesian.north); - - Cartesian3.multiplyByScalar(calculateCartesian.up, -1, calculateCartesian.down); - Cartesian3.multiplyByScalar(calculateCartesian.east, -1, calculateCartesian.west); - Cartesian3.multiplyByScalar(calculateCartesian.north, -1, calculateCartesian.south); - - firstCartesian = calculateCartesian[firstAxis]; - secondCartesian = calculateCartesian[secondAxis]; - thirdCartesian = calculateCartesian[thirdAxis]; + ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + ellipsoid.geodeticSurfaceNormal(origin, scratchCalculateCartesian.up); + + var up = scratchCalculateCartesian.up; + var east = scratchCalculateCartesian.east; + east.x = -origin.y; + east.y = origin.x; + east.z = 0.0; + Cartesian3.normalize(east, scratchCalculateCartesian.east); + Cartesian3.cross(up, east, scratchCalculateCartesian.north); + + Cartesian3.multiplyByScalar(scratchCalculateCartesian.up, -1, scratchCalculateCartesian.down); + Cartesian3.multiplyByScalar(scratchCalculateCartesian.east, -1, scratchCalculateCartesian.west); + Cartesian3.multiplyByScalar(scratchCalculateCartesian.north, -1, scratchCalculateCartesian.south); + + scratchFirstCartesian = scratchCalculateCartesian[firstAxis]; + scratchSecondCartesian = scratchCalculateCartesian[secondAxis]; + scratchThirdCartesian = scratchCalculateCartesian[thirdAxis]; } - result[0] = firstCartesian.x; - result[1] = firstCartesian.y; - result[2] = firstCartesian.z; + result[0] = scratchFirstCartesian.x; + result[1] = scratchFirstCartesian.y; + result[2] = scratchFirstCartesian.z; result[3] = 0.0; - result[4] = secondCartesian.x; - result[5] = secondCartesian.y; - result[6] = secondCartesian.z; + result[4] = scratchSecondCartesian.x; + result[5] = scratchSecondCartesian.y; + result[6] = scratchSecondCartesian.z; result[7] = 0.0; - result[8] = thirdCartesian.x; - result[9] = thirdCartesian.y; - result[10] = thirdCartesian.z; + result[8] = scratchThirdCartesian.x; + result[9] = scratchThirdCartesian.y; + result[10] = scratchThirdCartesian.z; result[11] = 0.0; result[12] = origin.x; result[13] = origin.y; @@ -314,8 +317,8 @@ define([ * @param {Cartesian3} origin The center point of the local reference frame. * @param {HeadingPitchRoll} headingPitchRoll The heading, pitch, and roll. * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation. - * @param {function} [fixedFrameTransformOrResult=Transforms.eastNorthUpToFixedFrame] A 4x4 transformation matrix from a reference frame - * to the provided ellipsoid's fixed reference frame + * @param {Transforms~LocalFrameToFixedFrame} [fixedFrameTransformOrResult=Transforms.eastNorthUpToFixedFrame] A 4x4 transformation + * matrix from a reference frame to the provided ellipsoid's fixed reference frame * @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. * @@ -329,14 +332,16 @@ define([ * var transform = Cesium.Transforms.headingPitchRollToFixedFrame(center, hpr); */ Transforms.headingPitchRollToFixedFrame = function(origin, headingPitchRoll, ellipsoid, fixedFrameTransformOrResult, result) { + //>>includeStart('debug', pragmas.debug); Check.typeOf.object( 'HeadingPitchRoll', headingPitchRoll); + //>>includeEnd('debug'); // checks for required parameters happen in the called functions - deprecationWarning('Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, result)', 'The method was deprecated in Cesium 1.31 and will be removed in version 1.32. ' + - 'Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result) where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator)'); if(fixedFrameTransformOrResult instanceof Matrix4){ - result = fixedFrameTransformOrResult; - fixedFrameTransformOrResult = undefined; + result = fixedFrameTransformOrResult; + fixedFrameTransformOrResult = undefined; + deprecationWarning('Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, result)', 'The method was deprecated in Cesium 1.31 and will be removed in version 1.33. ' + + 'Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result) where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator)'); } fixedFrameTransformOrResult = defaultValue(fixedFrameTransformOrResult,Transforms.eastNorthUpToFixedFrame); var hprQuaternion = Quaternion.fromHeadingPitchRoll(headingPitchRoll, scratchHPRQuaternion); @@ -357,8 +362,8 @@ define([ * @param {Cartesian3} origin The center point of the local reference frame. * @param {HeadingPitchRoll} headingPitchRoll The heading, pitch, and roll. * @param {Ellipsoid} [ellipsoid=Ellipsoid.WGS84] The ellipsoid whose fixed frame is used in the transformation. - * @param {function} [fixedFrameTransformOrResult=Transforms.eastNorthUpToFixedFrame] A 4x4 transformation matrix from a reference frame - * to the provided ellipsoid's fixed reference frame + * @param {Transforms~LocalFrameToFixedFrame} [fixedFrameTransformOrResult=Transforms.eastNorthUpToFixedFrame] A 4x4 transformation + * matrix from a reference frame to the provided ellipsoid's fixed reference frame * @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. * @@ -372,13 +377,14 @@ define([ * var quaternion = Cesium.Transforms.headingPitchRollQuaternion(center, hpr); */ Transforms.headingPitchRollQuaternion = function(origin, headingPitchRoll, ellipsoid, fixedFrameTransformOrResult, result) { - // checks for required parameters happen in the called functions + //>>includeStart('debug', pragmas.debug); Check.typeOf.object( 'HeadingPitchRoll', headingPitchRoll); - deprecationWarning('Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, result)', 'The method was deprecated in Cesium 1.31 and will be removed in version 1.32. ' + - 'Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result) where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator)'); + //>>includeEnd('debug'); if(fixedFrameTransformOrResult instanceof Quaternion){ result = fixedFrameTransformOrResult; fixedFrameTransformOrResult = undefined; + deprecationWarning('Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, result)', 'The method was deprecated in Cesium 1.31 and will be removed in version 1.33. ' + + 'Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result) where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator)'); } var transform = Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid,fixedFrameTransformOrResult, scratchENUMatrix4); var rotation = Matrix4.getRotation(transform, scratchHPRMatrix3); diff --git a/Source/Scene/Camera.js b/Source/Scene/Camera.js index c7bc713790d8..d2ee120847fc 100644 --- a/Source/Scene/Camera.js +++ b/Source/Scene/Camera.js @@ -1086,6 +1086,7 @@ define([ endTransform : undefined }; + var scratchHpr = new HeadingPitchRoll(); /** * Sets the camera position, orientation and transform. * @@ -1160,20 +1161,18 @@ define([ orientation = directionUpToHeadingPitchRoll(this, destination, orientation, scratchSetViewOptions.orientation); } - var heading = defaultValue(orientation.heading, 0.0); - var pitch = defaultValue(orientation.pitch, -CesiumMath.PI_OVER_TWO); - var roll = defaultValue(orientation.roll, 0.0); - - var hpr = new HeadingPitchRoll(heading, pitch, roll); + scratchHpr.heading = defaultValue(orientation.heading, 0.0); + scratchHpr.pitch = defaultValue(orientation.pitch, -CesiumMath.PI_OVER_TWO); + scratchHpr.roll = defaultValue(orientation.roll, 0.0); this._suspendTerrainAdjustment = true; if (mode === SceneMode.SCENE3D) { - setView3D(this, destination, hpr); + setView3D(this, destination, scratchHpr); } else if (mode === SceneMode.SCENE2D) { - setView2D(this, destination, hpr, convert); + setView2D(this, destination, scratchHpr, convert); } else { - setViewCV(this, destination, hpr, convert); + setViewCV(this, destination, scratchHpr, convert); } }; diff --git a/Specs/Core/QuaternionSpec.js b/Specs/Core/QuaternionSpec.js index c8e42b98f34d..ca4861320cab 100644 --- a/Specs/Core/QuaternionSpec.js +++ b/Specs/Core/QuaternionSpec.js @@ -660,25 +660,7 @@ defineSuite([ Quaternion.fromRotationMatrix(undefined); }).toThrowDeveloperError(); }); -/* - it('fromHeadingPitchRoll throws with undefined heading', function() { - expect(function() { - Quaternion.fromHeadingPitchRoll(undefined, 0.0, 0.0); - }).toThrowDeveloperError(); - }); - - it('fromHeadingPitchRoll throws with undefined pitch', function() { - expect(function() { - Quaternion.fromHeadingPitchRoll(0.0, undefined, 0.0); - }).toThrowDeveloperError(); - }); - it('fromHeadingPitchRoll throws with undefined roll', function() { - expect(function() { - Quaternion.fromHeadingPitchRoll(0.0, 0.0, undefined); - }).toThrowDeveloperError(); - }); -*/ it('clone returns undefined with no parameter', function() { expect(Quaternion.clone()).toBeUndefined(); }); From 96cbf0f820eef4410303ffaefd4f0765c891cfcb Mon Sep 17 00:00:00 2001 From: Farouk Abdou Date: Fri, 10 Feb 2017 00:46:17 +0100 Subject: [PATCH 10/11] made a cache for localFrameToFixedFrameGenerator --- CHANGES.md | 3 - Source/Core/Quaternion.js | 17 +++-- Source/Core/Transforms.js | 139 ++++++++++++++++++++------------------ 3 files changed, 82 insertions(+), 77 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 0b18f8a4e0c5..9949a1bef24f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,15 +2,12 @@ Change Log ========== ### 1.31 - 2017-03-01 -<<<<<<< HEAD * Deprecated * The function `Quaternion.fromHeadingPitchRoll(heading, pitch, roll,result)` will be removed in 1.33. Use `Quaternion.fromHeadingPitchRoll(hpr,result)` instead where hpr is a HeadingPitchRoll. * The function `Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, result)` will be removed in 1.33. Use `Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result)` instead where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator). * The function `Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, result)` will be removed in 1.33. Use `Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result)` instead where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator). -======= * Breaking changes * Corrected spelling of `Color.FUCHSIA` from `Color.FUSCHIA` ->>>>>>> upstream/master * Added support to `DebugCameraPrimitive` to draw multifrustum planes. The attribute `debugShowFrustumPlanes` of `Scene` and `frustumPlanes` of `CesiumInspector` toggles this. `FrameState` has been augmented to include `frustumSplits` which is a `Number[]` of the near/far planes of the camera frustums. * Enable rendering `GroundPrimitives` on hardware without the `EXT_frag_depth` extension; however, this could cause artifacts for certain viewing angles. * Added compressed texture support. [#4758](https://github.com/AnalyticalGraphicsInc/cesium/pull/4758) diff --git a/Source/Core/Quaternion.js b/Source/Core/Quaternion.js index 10b4cde99adc..cd19446e2fc8 100644 --- a/Source/Core/Quaternion.js +++ b/Source/Core/Quaternion.js @@ -194,21 +194,20 @@ define([ Quaternion.fromHeadingPitchRoll = function(headingOrHeadingPitchRoll, pitchOrResult, roll, result) { //>>includeStart('debug', pragmas.debug); if (headingOrHeadingPitchRoll instanceof HeadingPitchRoll) { - Check.typeOf.object('headingPitchRoll',headingOrHeadingPitchRoll ); + Check.typeOf.object('headingPitchRoll', headingOrHeadingPitchRoll); } else { - Check.typeOf.number(headingOrHeadingPitchRoll, 'heading'); - Check.typeOf.number(pitchOrResult, 'pitch'); - Check.typeOf.number(roll, 'roll'); + Check.typeOf.number(headingOrHeadingPitchRoll, 'heading'); + Check.typeOf.number(pitchOrResult, 'pitch'); + Check.typeOf.number(roll, 'roll'); } //>>includeEnd('debug'); var hpr; if (headingOrHeadingPitchRoll instanceof HeadingPitchRoll) { - hpr = headingOrHeadingPitchRoll; - result = pitchOrResult; + hpr = headingOrHeadingPitchRoll; + result = pitchOrResult; } else { - deprecationWarning('Quaternion.fromHeadingPitchRoll(heading, pitch, roll,result)', 'The method was deprecated in Cesium 1.32 and will be removed in version 1.33. ' + - 'Use Quaternion.fromHeadingPitchRoll(hpr,result) where hpr is a HeadingPitchRoll'); - hpr = new HeadingPitchRoll(headingOrHeadingPitchRoll, pitchOrResult, roll); + deprecationWarning('Quaternion.fromHeadingPitchRoll(heading, pitch, roll,result)', 'The method was deprecated in Cesium 1.32 and will be removed in version 1.33. ' + 'Use Quaternion.fromHeadingPitchRoll(hpr,result) where hpr is a HeadingPitchRoll'); + hpr = new HeadingPitchRoll(headingOrHeadingPitchRoll, pitchOrResult, roll); } scratchRollQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_X, hpr.roll, scratchHPRQuaternion); scratchPitchQuaternion = Quaternion.fromAxisAngle(Cartesian3.UNIT_Y, -hpr.pitch, result); diff --git a/Source/Core/Transforms.js b/Source/Core/Transforms.js index a0ffcf02a443..e63824a7c152 100644 --- a/Source/Core/Transforms.js +++ b/Source/Core/Transforms.js @@ -111,6 +111,8 @@ define([ down: [0, 0, -1] }; + var localFrameToFixedFrameCache = {}; + var scratchCalculateCartesian = { east: new Cartesian3(), north: new Cartesian3(), @@ -148,71 +150,78 @@ define([ * @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. */ - var resultat = function(origin, ellipsoid, result) { - //>>includeStart('debug', pragmas.debug); - if (!defined(origin)) { - throw new DeveloperError('origin is required.'); - } - //>>includeEnd('debug'); - if (!defined(result)) { - result = new Matrix4(); - } - // If x and y are zero, assume origin is at a pole, which is a special case. - if (CesiumMath.equalsEpsilon(origin.x, 0.0, CesiumMath.EPSILON14) && CesiumMath.equalsEpsilon(origin.y, 0.0, CesiumMath.EPSILON14)) { - var sign = CesiumMath.sign(origin.z); - - Cartesian3.unpack(degeneratePositionLocalFrame[firstAxis], 0, scratchFirstCartesian); - if (firstAxis !== 'east' && firstAxis !== 'west') { - Cartesian3.multiplyByScalar(scratchFirstCartesian, sign, scratchFirstCartesian); - } - - Cartesian3.unpack(degeneratePositionLocalFrame[secondAxis], 0, scratchSecondCartesian); - if (secondAxis !== 'east' && secondAxis !== 'west') { - Cartesian3.multiplyByScalar(scratchSecondCartesian, sign, scratchSecondCartesian); - } - - Cartesian3.unpack(degeneratePositionLocalFrame[thirdAxis], 0, scratchThirdCartesian); - if (thirdAxis !== 'east' && thirdAxis !== 'west') { - Cartesian3.multiplyByScalar(scratchThirdCartesian, sign, scratchThirdCartesian); - } - } else { - ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); - ellipsoid.geodeticSurfaceNormal(origin, scratchCalculateCartesian.up); - - var up = scratchCalculateCartesian.up; - var east = scratchCalculateCartesian.east; - east.x = -origin.y; - east.y = origin.x; - east.z = 0.0; - Cartesian3.normalize(east, scratchCalculateCartesian.east); - Cartesian3.cross(up, east, scratchCalculateCartesian.north); - - Cartesian3.multiplyByScalar(scratchCalculateCartesian.up, -1, scratchCalculateCartesian.down); - Cartesian3.multiplyByScalar(scratchCalculateCartesian.east, -1, scratchCalculateCartesian.west); - Cartesian3.multiplyByScalar(scratchCalculateCartesian.north, -1, scratchCalculateCartesian.south); - - scratchFirstCartesian = scratchCalculateCartesian[firstAxis]; - scratchSecondCartesian = scratchCalculateCartesian[secondAxis]; - scratchThirdCartesian = scratchCalculateCartesian[thirdAxis]; - } - result[0] = scratchFirstCartesian.x; - result[1] = scratchFirstCartesian.y; - result[2] = scratchFirstCartesian.z; - result[3] = 0.0; - result[4] = scratchSecondCartesian.x; - result[5] = scratchSecondCartesian.y; - result[6] = scratchSecondCartesian.z; - result[7] = 0.0; - result[8] = scratchThirdCartesian.x; - result[9] = scratchThirdCartesian.y; - result[10] = scratchThirdCartesian.z; - result[11] = 0.0; - result[12] = origin.x; - result[13] = origin.y; - result[14] = origin.z; - result[15] = 1.0; - return result; - }; + var resultat; + var hashAxis = firstAxis + secondAxis; + if (defined(localFrameToFixedFrameCache[hashAxis])) { + resultat = localFrameToFixedFrameCache[hashAxis]; + } else { + resultat = function(origin, ellipsoid, result) { + //>>includeStart('debug', pragmas.debug); + if (!defined(origin)) { + throw new DeveloperError('origin is required.'); + } + //>>includeEnd('debug'); + if (!defined(result)) { + result = new Matrix4(); + } + // If x and y are zero, assume origin is at a pole, which is a special case. + if (CesiumMath.equalsEpsilon(origin.x, 0.0, CesiumMath.EPSILON14) && CesiumMath.equalsEpsilon(origin.y, 0.0, CesiumMath.EPSILON14)) { + var sign = CesiumMath.sign(origin.z); + + Cartesian3.unpack(degeneratePositionLocalFrame[firstAxis], 0, scratchFirstCartesian); + if (firstAxis !== 'east' && firstAxis !== 'west') { + Cartesian3.multiplyByScalar(scratchFirstCartesian, sign, scratchFirstCartesian); + } + + Cartesian3.unpack(degeneratePositionLocalFrame[secondAxis], 0, scratchSecondCartesian); + if (secondAxis !== 'east' && secondAxis !== 'west') { + Cartesian3.multiplyByScalar(scratchSecondCartesian, sign, scratchSecondCartesian); + } + + Cartesian3.unpack(degeneratePositionLocalFrame[thirdAxis], 0, scratchThirdCartesian); + if (thirdAxis !== 'east' && thirdAxis !== 'west') { + Cartesian3.multiplyByScalar(scratchThirdCartesian, sign, scratchThirdCartesian); + } + } else { + ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84); + ellipsoid.geodeticSurfaceNormal(origin, scratchCalculateCartesian.up); + + var up = scratchCalculateCartesian.up; + var east = scratchCalculateCartesian.east; + east.x = -origin.y; + east.y = origin.x; + east.z = 0.0; + Cartesian3.normalize(east, scratchCalculateCartesian.east); + Cartesian3.cross(up, east, scratchCalculateCartesian.north); + + Cartesian3.multiplyByScalar(scratchCalculateCartesian.up, -1, scratchCalculateCartesian.down); + Cartesian3.multiplyByScalar(scratchCalculateCartesian.east, -1, scratchCalculateCartesian.west); + Cartesian3.multiplyByScalar(scratchCalculateCartesian.north, -1, scratchCalculateCartesian.south); + + scratchFirstCartesian = scratchCalculateCartesian[firstAxis]; + scratchSecondCartesian = scratchCalculateCartesian[secondAxis]; + scratchThirdCartesian = scratchCalculateCartesian[thirdAxis]; + } + result[0] = scratchFirstCartesian.x; + result[1] = scratchFirstCartesian.y; + result[2] = scratchFirstCartesian.z; + result[3] = 0.0; + result[4] = scratchSecondCartesian.x; + result[5] = scratchSecondCartesian.y; + result[6] = scratchSecondCartesian.z; + result[7] = 0.0; + result[8] = scratchThirdCartesian.x; + result[9] = scratchThirdCartesian.y; + result[10] = scratchThirdCartesian.z; + result[11] = 0.0; + result[12] = origin.x; + result[13] = origin.y; + result[14] = origin.z; + result[15] = 1.0; + return result; + }; + localFrameToFixedFrameCache[hashAxis] = resultat; + } return resultat; }; From 1ca538ad0726ebeb9bf072101ecfbaac9f11b2db Mon Sep 17 00:00:00 2001 From: Dan Bagnell Date: Fri, 10 Feb 2017 11:59:36 -0500 Subject: [PATCH 11/11] Fix whitespace and remove duplicate entries from CHANGES.md. --- Apps/Sandcastle/gallery/HeadingPitchRoll.html | 9 +- .../Sandcastle/gallery/LocalToFixedFrame.html | 151 +++++----- CHANGES.md | 3 - Source/Core/Transforms.js | 120 ++++---- Specs/Core/TransformsSpec.js | 272 +++++++++--------- 5 files changed, 271 insertions(+), 284 deletions(-) diff --git a/Apps/Sandcastle/gallery/HeadingPitchRoll.html b/Apps/Sandcastle/gallery/HeadingPitchRoll.html index 31406f2146e3..7597de58a5fc 100644 --- a/Apps/Sandcastle/gallery/HeadingPitchRoll.html +++ b/Apps/Sandcastle/gallery/HeadingPitchRoll.html @@ -70,8 +70,8 @@

Loading...

var viewer = new Cesium.Viewer('cesiumContainer'); var canvas = viewer.canvas; canvas.setAttribute('tabindex', '0'); // needed to put focus on the canvas -canvas.addEventListener('click',function(){ - canvas.focus(); +canvas.addEventListener('click', function() { + canvas.focus(); }); canvas.focus(); @@ -106,7 +106,7 @@

Loading...

var position = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, 5000.0); var speedVector = new Cesium.Cartesian3(); -var fixedFrameTransform = Cesium.Transforms.localFrameToFixedFrameGenerator('north','west'); +var fixedFrameTransform = Cesium.Transforms.localFrameToFixedFrameGenerator('north', 'west'); var planePrimitive = scene.primitives.add(Cesium.Model.fromGltf({ url : '../../SampleData/models/CesiumAir/Cesium_Air.glb', @@ -217,7 +217,8 @@

Loading...

hpRange.pitch = hpRoll.pitch; camera.lookAt(center, hpRange); } -});//Sandcastle_End +}); +//Sandcastle_End Sandcastle.finishedLoading(); } if (typeof Cesium !== "undefined") { diff --git a/Apps/Sandcastle/gallery/LocalToFixedFrame.html b/Apps/Sandcastle/gallery/LocalToFixedFrame.html index 9e17c8e2787c..744e647fa37a 100644 --- a/Apps/Sandcastle/gallery/LocalToFixedFrame.html +++ b/Apps/Sandcastle/gallery/LocalToFixedFrame.html @@ -58,8 +58,8 @@

Loading...

var viewer = new Cesium.Viewer('cesiumContainer'); var canvas = viewer.canvas; canvas.setAttribute('tabindex', '0'); // needed to put focus on the canvas -canvas.addEventListener('click',function(){ - canvas.focus(); +canvas.addEventListener('click', function() { + canvas.focus(); }); canvas.focus(); @@ -74,69 +74,69 @@

Loading...

var deltaRadians = Cesium.Math.toRadians(1.0); var localFrames = [ - { - pos: Cesium.Cartesian3.fromDegrees(-123.075, 44.045000, 5000.0), - converter: Cesium.Transforms.eastNorthUpToFixedFrame , - comments: 'Classical East North Up\nlocal Frame' - }, - { - pos: Cesium.Cartesian3.fromDegrees(-123.075, 44.050000, 5500.0), - converter: Cesium.Transforms.localFrameToFixedFrameGenerator('north','west'), - comments: 'North West Up\nlocal Frame' - }, - { - pos: Cesium.Cartesian3.fromDegrees(-123.075, 44.040000, 4500.0), - converter: Cesium.Transforms.localFrameToFixedFrameGenerator('south','up'), - comments: 'South Up West\nlocal Frame' - }, - { - pos: Cesium.Cartesian3.fromDegrees(-123.075, 44.050000, 4500.0), - converter: Cesium.Transforms.localFrameToFixedFrameGenerator('up','east'), - comments: 'Up East North\nlocal Frame' - }, - { - pos: Cesium.Cartesian3.fromDegrees(-123.075, 44.040000, 5500.0), - converter: Cesium.Transforms.localFrameToFixedFrameGenerator('down','east'), - comments: 'Down East South\nlocal Frame' - }, + { + pos : Cesium.Cartesian3.fromDegrees(-123.075, 44.045000, 5000.0), + converter : Cesium.Transforms.eastNorthUpToFixedFrame, + comments : 'Classical East North Up\nlocal Frame' + }, + { + pos : Cesium.Cartesian3.fromDegrees(-123.075, 44.050000, 5500.0), + converter : Cesium.Transforms.localFrameToFixedFrameGenerator('north', 'west'), + comments : 'North West Up\nlocal Frame' + }, + { + pos : Cesium.Cartesian3.fromDegrees(-123.075, 44.040000, 4500.0), + converter : Cesium.Transforms.localFrameToFixedFrameGenerator('south', 'up'), + comments : 'South Up West\nlocal Frame' + }, + { + pos : Cesium.Cartesian3.fromDegrees(-123.075, 44.050000, 4500.0), + converter : Cesium.Transforms.localFrameToFixedFrameGenerator('up', 'east'), + comments : 'Up East North\nlocal Frame' + }, + { + pos : Cesium.Cartesian3.fromDegrees(-123.075, 44.040000, 5500.0), + converter : Cesium.Transforms.localFrameToFixedFrameGenerator('down', 'east'), + comments : 'Down East South\nlocal Frame' + }, ]; -var primitives= []; +var primitives = []; var hprRollZero = new Cesium.HeadingPitchRoll(); -for( var i = 0; i < localFrames.length; i++){ - var position = localFrames[i].pos; - var converter = localFrames[i].converter; - var comments = localFrames[i].comments; - var planePrimitive = scene.primitives.add(Cesium.Model.fromGltf({ - url : '../../SampleData/models/CesiumAir/Cesium_Air.glb', - modelMatrix : Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll, Cesium.Ellipsoid.WGS84, converter), - minimumPixelSize : 128 - })); +for (var i = 0; i < localFrames.length; i++) { + var position = localFrames[i].pos; + var converter = localFrames[i].converter; + var comments = localFrames[i].comments; + var planePrimitive = scene.primitives.add(Cesium.Model.fromGltf({ + url : '../../SampleData/models/CesiumAir/Cesium_Air.glb', + modelMatrix : Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll, Cesium.Ellipsoid.WGS84, converter), + minimumPixelSize : 128 + })); - primitives.push({primitive: planePrimitive, converter: converter, position: position }); - var modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(position, hprRollZero, Cesium.Ellipsoid.WGS84, converter); - scene.primitives.add(new Cesium.DebugModelMatrixPrimitive({ - modelMatrix : modelMatrix, - length : 300.0, - width : 10.0 - })); + primitives.push({primitive : planePrimitive, converter : converter, position : position}); + var modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(position, hprRollZero, Cesium.Ellipsoid.WGS84, converter); + scene.primitives.add(new Cesium.DebugModelMatrixPrimitive({ + modelMatrix : modelMatrix, + length : 300.0, + width : 10.0 + })); - var positionLabel = position.clone(); - positionLabel.z = position.z + 300.0; - viewer.entities.add({ - position : positionLabel, - label : { - text : comments, - font : '24px Helvetica', - fillColor : Cesium.Color.SKYBLUE, - outlineColor : Cesium.Color.BLACK, - outlineWidth : 2, - style : Cesium.LabelStyle.FILL_AND_OUTLINE, - verticalOrigin : Cesium.VerticalOrigin.CENTER, - HorizontalOrigin : Cesium.HorizontalOrigin.RIGHT - } - }); + var positionLabel = position.clone(); + positionLabel.z = position.z + 300.0; + viewer.entities.add({ + position : positionLabel, + label : { + text : comments, + font : '24px Helvetica', + fillColor : Cesium.Color.SKYBLUE, + outlineColor : Cesium.Color.BLACK, + outlineWidth : 2, + style : Cesium.LabelStyle.FILL_AND_OUTLINE, + verticalOrigin : Cesium.VerticalOrigin.CENTER, + HorizontalOrigin : Cesium.HorizontalOrigin.RIGHT + } + }); } primitives[0].primitive.readyPromise.then(function(model) { @@ -161,18 +161,18 @@

Loading...

document.addEventListener('keydown', function(e) { switch (e.keyCode) { case 40: - // pitch down - hpRoll.pitch -= deltaRadians; - if (hpRoll.pitch < -Cesium.Math.TWO_PI) { - hpRoll.pitch += Cesium.Math.TWO_PI; - } + // pitch down + hpRoll.pitch -= deltaRadians; + if (hpRoll.pitch < -Cesium.Math.TWO_PI) { + hpRoll.pitch += Cesium.Math.TWO_PI; + } break; case 38: - // pitch up - hpRoll.pitch += deltaRadians; - if (hpRoll.pitch > Cesium.Math.TWO_PI) { - hpRoll.pitch -= Cesium.Math.TWO_PI; - } + // pitch up + hpRoll.pitch += deltaRadians; + if (hpRoll.pitch > Cesium.Math.TWO_PI) { + hpRoll.pitch -= Cesium.Math.TWO_PI; + } break; case 39: if (e.shiftKey) { @@ -217,13 +217,14 @@

Loading...

pitchSpan.innerHTML = Cesium.Math.toDegrees(hpRoll.pitch).toFixed(1); rollSpan.innerHTML = Cesium.Math.toDegrees(hpRoll.roll).toFixed(1); - for( var i = 0; i < primitives.length; i++){ - var primitive = primitives[i].primitive; - var converter = primitives[i].converter; - var position = primitives[i].position; - Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll, Cesium.Ellipsoid.WGS84, converter, primitive.modelMatrix); + for (var i = 0; i < primitives.length; i++) { + var primitive = primitives[i].primitive; + var converter = primitives[i].converter; + var position = primitives[i].position; + Cesium.Transforms.headingPitchRollToFixedFrame(position, hpRoll, Cesium.Ellipsoid.WGS84, converter, primitive.modelMatrix); } -});//Sandcastle_End +}); +//Sandcastle_End Sandcastle.finishedLoading(); } if (typeof Cesium !== "undefined") { diff --git a/CHANGES.md b/CHANGES.md index 91500641faf4..f8a4db7ca6f1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -25,7 +25,6 @@ Change Log * Deprecated * The properties `url` and `key` will be removed from `GeocoderViewModel` in 1.31. These properties will be available on geocoder services that support them, like `BingMapsGeocoderService`. - * The function `createBinormalAndBitangent` of `GeometryPipeline` will be removed in 1.31. Use the function `createTangentAndBitangent` instead. [#4856](https://github.com/AnalyticalGraphicsInc/cesium/pull/4856) * The function `GeometryPipeline.computeBinormalAndTangent` will be removed in 1.31. Use `GeometryPipeline.createTangentAndBitangent` instead. [#4856](https://github.com/AnalyticalGraphicsInc/cesium/pull/4856) * The enums `MIDDLE_DOUBLE_CLICK` and `RIGHT_DOUBLE_CLICK` from `ScreenSpaceEventType` have been deprecated and will be removed in 1.31. [#4910](https://github.com/AnalyticalGraphicsInc/cesium/pull/4910) * Breaking changes @@ -48,8 +47,6 @@ Change Log * Fixed a bug that affected dynamic graphics with time-dynamic modelMatrix. [#4907](https://github.com/AnalyticalGraphicsInc/cesium/pull/4907) * Fixed `Geocoder` autocomplete drop down visibility in Firefox. [#4916](https://github.com/AnalyticalGraphicsInc/cesium/issues/4916) * Added `Rectangle.fromRadians`. -* `TerrainProvider` now optionally exposes an `availability` property that can be used to query the terrain level that is available at a location or in a rectangle. Currently only `CesiumTerrainProvider` exposes this property. -* Added `sampleTerrainMostDetailed` to sample the height of an array of positions using the best available terrain data at each point. This requires a `TerrainProvider` with the `availability` property. * Updated the morph so the default view in Columbus View is now angled. [#3878](https://github.com/AnalyticalGraphicsInc/cesium/issues/3878) * Added 2D and Columbus View support for models using the RTC extension or whose vertices are in WGS84 coordinates. [#4922](https://github.com/AnalyticalGraphicsInc/cesium/pull/4922) * The attribute `perInstanceAttribute` of `DebugAppearance` has been made optional and defaults to `false`. diff --git a/Source/Core/Transforms.js b/Source/Core/Transforms.js index e63824a7c152..75547a76aa2f 100644 --- a/Source/Core/Transforms.js +++ b/Source/Core/Transforms.js @@ -53,73 +53,64 @@ define([ * @exports Transforms */ var Transforms = {}; + var vectorProductLocalFrame = { - up: { - south: 'east', - north: 'west', - west: 'south', - east: 'north' - }, - down: { - south: 'west', - north: 'east', - west: 'north', - east: 'south' - }, - south: { - up: 'west', - down: 'east', - west: 'down', - east: 'up' - }, - north: { - up: 'east', - down: 'west', - west: 'up', - east: 'down' - }, - west: { - up: 'north', - down: 'south', - north: 'down', - south: 'up' - }, - east: { - up: 'south', - down: 'north', - north: 'up', - south: 'down' - } + up : { + south : 'east', + north : 'west', + west : 'south', + east : 'north' + }, + down : { + south : 'west', + north : 'east', + west : 'north', + east : 'south' + }, + south : { + up : 'west', + down : 'east', + west : 'down', + east : 'up' + }, + north : { + up : 'east', + down : 'west', + west : 'up', + east : 'down' + }, + west : { + up : 'north', + down : 'south', + north : 'down', + south : 'up' + }, + east : { + up : 'south', + down : 'north', + north : 'up', + south : 'down' + } }; var degeneratePositionLocalFrame = { - north: [ - -1, 0, 0 - ], - east: [ - 0, 1, 0 - ], - up: [ - 0, 0, 1 - ], - south: [ - 1, 0, 0 - ], - west: [ - 0, -1, 0 - ], - down: [0, 0, -1] + north : [-1, 0, 0], + east : [0, 1, 0], + up : [0, 0, 1], + south : [1, 0, 0], + west : [0, -1, 0], + down : [0, 0, -1] }; var localFrameToFixedFrameCache = {}; var scratchCalculateCartesian = { - east: new Cartesian3(), - north: new Cartesian3(), - up: new Cartesian3(), - west: new Cartesian3(), - south: new Cartesian3(), - down: new Cartesian3() + east : new Cartesian3(), + north : new Cartesian3(), + up : new Cartesian3(), + west : new Cartesian3(), + south : new Cartesian3(), + down : new Cartesian3() }; var scratchFirstCartesian = new Cartesian3(); var scratchSecondCartesian = new Cartesian3(); @@ -140,7 +131,6 @@ define([ } var thirdAxis = vectorProductLocalFrame[firstAxis][secondAxis]; - /** * Computes a 4x4 transformation matrix from a reference frame * centered at the provided origin to the provided ellipsoid's fixed reference frame. @@ -349,8 +339,7 @@ define([ if(fixedFrameTransformOrResult instanceof Matrix4){ result = fixedFrameTransformOrResult; fixedFrameTransformOrResult = undefined; - deprecationWarning('Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, result)', 'The method was deprecated in Cesium 1.31 and will be removed in version 1.33. ' + - 'Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result) where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator)'); + deprecationWarning('Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, result)', 'The method was deprecated in Cesium 1.31 and will be removed in version 1.33. Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result) where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator)'); } fixedFrameTransformOrResult = defaultValue(fixedFrameTransformOrResult,Transforms.eastNorthUpToFixedFrame); var hprQuaternion = Quaternion.fromHeadingPitchRoll(headingPitchRoll, scratchHPRQuaternion); @@ -389,11 +378,10 @@ define([ //>>includeStart('debug', pragmas.debug); Check.typeOf.object( 'HeadingPitchRoll', headingPitchRoll); //>>includeEnd('debug'); - if(fixedFrameTransformOrResult instanceof Quaternion){ - result = fixedFrameTransformOrResult; - fixedFrameTransformOrResult = undefined; - deprecationWarning('Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, result)', 'The method was deprecated in Cesium 1.31 and will be removed in version 1.33. ' + - 'Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result) where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator)'); + if (fixedFrameTransformOrResult instanceof Quaternion) { + result = fixedFrameTransformOrResult; + fixedFrameTransformOrResult = undefined; + deprecationWarning('Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, result)', 'The method was deprecated in Cesium 1.31 and will be removed in version 1.33. Transforms.headingPitchRollQuaternion(origin, headingPitchRoll, ellipsoid, fixedFrameTransform, result) where fixedFrameTransform is a a 4x4 transformation matrix (see Transforms.localFrameToFixedFrameGenerator)'); } var transform = Transforms.headingPitchRollToFixedFrame(origin, headingPitchRoll, ellipsoid,fixedFrameTransformOrResult, scratchENUMatrix4); var rotation = Matrix4.getRotation(transform, scratchHPRMatrix3); diff --git a/Specs/Core/TransformsSpec.js b/Specs/Core/TransformsSpec.js index d9a42f74112d..365f6dad36d6 100644 --- a/Specs/Core/TransformsSpec.js +++ b/Specs/Core/TransformsSpec.js @@ -232,147 +232,148 @@ defineSuite([ }); it('normal use of localFrameToFixedFrameGenerator', function() { - var cartesianTab = [ - new Cartesian3(0.0, 0.0, 1.0), - new Cartesian3(0.0, 0.0, -1.0), - new Cartesian3(10.0, 20.0, 30.0), - new Cartesian3(-10.0, -20.0, -30.0), - new Cartesian3(-25.0, 60.0, -1.0), - new Cartesian3(9.0, 0.0, -7.0) - ]; - - var converterTab = [ - { - converter: Transforms.localFrameToFixedFrameGenerator('north', 'east'), - order: ['north', 'east', 'down'] - }, { - converter: Transforms.localFrameToFixedFrameGenerator('north', 'west'), - order: ['north', 'west', 'up'] - }, { - converter: Transforms.localFrameToFixedFrameGenerator('north', 'up'), - order: ['north', 'up', 'east'] - }, { - converter: Transforms.localFrameToFixedFrameGenerator('north', 'down'), - order: ['north', 'down', 'west'] - }, { - converter: Transforms.localFrameToFixedFrameGenerator('south', 'east'), - order: ['south', 'east', 'up'] - }, { - converter: Transforms.localFrameToFixedFrameGenerator('south', 'west'), - order: ['south', 'west', 'down'] - }, { - converter: Transforms.localFrameToFixedFrameGenerator('south', 'up'), - order: ['south', 'up', 'west'] - }, { - converter: Transforms.localFrameToFixedFrameGenerator('south', 'down'), - order: ['south', 'down', 'east'] - }, { - converter: Transforms.localFrameToFixedFrameGenerator('east', 'north'), - order: ['east', 'north', 'up'] - }, { - converter: Transforms.localFrameToFixedFrameGenerator('east', 'south'), - order: ['east', 'south', 'down'] - }, { - converter: Transforms.localFrameToFixedFrameGenerator('east', 'up'), - order: ['east', 'up', 'south'] - }, { - converter: Transforms.localFrameToFixedFrameGenerator('east', 'down'), - order: ['east', 'down', 'north'] - }, { - converter: Transforms.localFrameToFixedFrameGenerator('west', 'north'), - order: ['west', 'north', 'down'] - }, { - converter: Transforms.localFrameToFixedFrameGenerator('west', 'south'), - order: ['west', 'south', 'up'] - }, { - converter: Transforms.localFrameToFixedFrameGenerator('west', 'up'), - order: ['west', 'up', 'north'] - }, { - converter: Transforms.localFrameToFixedFrameGenerator('west', 'down'), - order: ['west', 'down', 'south'] - }, { - converter: Transforms.localFrameToFixedFrameGenerator('up', 'north'), - order: ['up', 'north', 'west'] - }, { - converter: Transforms.localFrameToFixedFrameGenerator('up', 'south'), - order: ['up', 'south', 'east'] - }, { - converter: Transforms.localFrameToFixedFrameGenerator('up', 'east'), - order: ['up', 'east', 'north'] - }, { - converter: Transforms.localFrameToFixedFrameGenerator('up', 'west'), - order: ['up', 'west', 'south'] - } - ]; - - function testAllLocalFrame(classicalENUMatrix, position) { - var ENUColumn = new Cartesian4(); - var converterColumn = new Cartesian4(); - for (var i = 0; i < converterTab.length; i++) { - var converterMatrix = (converterTab[i].converter)(position, Ellipsoid.UNIT_SPHERE); - var order = converterTab[i].order; - // check translation - Matrix4.getColumn(classicalENUMatrix, 3, ENUColumn); - Matrix4.getColumn(converterMatrix, 3, converterColumn); - expect(ENUColumn).toEqual(converterColumn); - // check axis - for (var j = 0; j < 3; j++) { - Matrix4.getColumn(converterMatrix, j, converterColumn); - var axisName = order[j]; - if (axisName === 'east') { - Matrix4.getColumn(classicalENUMatrix, 0, ENUColumn); - } else if (axisName === 'west') { - Matrix4.getColumn(classicalENUMatrix, 0, ENUColumn); - Cartesian4.negate(ENUColumn, ENUColumn); - } else if (axisName === 'north') { - Matrix4.getColumn(classicalENUMatrix, 1, ENUColumn); - } else if (axisName === 'south') { - Matrix4.getColumn(classicalENUMatrix, 1, ENUColumn); - Cartesian4.negate(ENUColumn, ENUColumn); - } else if (axisName === 'up') { - Matrix4.getColumn(classicalENUMatrix, 2, ENUColumn); - } else if (axisName === 'down') { - Matrix4.getColumn(classicalENUMatrix, 2, ENUColumn); - Cartesian4.negate(ENUColumn, ENUColumn); + var cartesianTab = [ + new Cartesian3(0.0, 0.0, 1.0), + new Cartesian3(0.0, 0.0, -1.0), + new Cartesian3(10.0, 20.0, 30.0), + new Cartesian3(-10.0, -20.0, -30.0), + new Cartesian3(-25.0, 60.0, -1.0), + new Cartesian3(9.0, 0.0, -7.0) + ]; + + var converterTab = [ + { + converter : Transforms.localFrameToFixedFrameGenerator('north', 'east'), + order : ['north', 'east', 'down'] + }, { + converter : Transforms.localFrameToFixedFrameGenerator('north', 'west'), + order : ['north', 'west', 'up'] + }, { + converter : Transforms.localFrameToFixedFrameGenerator('north', 'up'), + order : ['north', 'up', 'east'] + }, { + converter : Transforms.localFrameToFixedFrameGenerator('north', 'down'), + order : ['north', 'down', 'west'] + }, { + converter : Transforms.localFrameToFixedFrameGenerator('south', 'east'), + order : ['south', 'east', 'up'] + }, { + converter : Transforms.localFrameToFixedFrameGenerator('south', 'west'), + order : ['south', 'west', 'down'] + }, { + converter : Transforms.localFrameToFixedFrameGenerator('south', 'up'), + order : ['south', 'up', 'west'] + }, { + converter : Transforms.localFrameToFixedFrameGenerator('south', 'down'), + order : ['south', 'down', 'east'] + }, { + converter : Transforms.localFrameToFixedFrameGenerator('east', 'north'), + order : ['east', 'north', 'up'] + }, { + converter : Transforms.localFrameToFixedFrameGenerator('east', 'south'), + order : ['east', 'south', 'down'] + }, { + converter : Transforms.localFrameToFixedFrameGenerator('east', 'up'), + order : ['east', 'up', 'south'] + }, { + converter : Transforms.localFrameToFixedFrameGenerator('east', 'down'), + order : ['east', 'down', 'north'] + }, { + converter : Transforms.localFrameToFixedFrameGenerator('west', 'north'), + order : ['west', 'north', 'down'] + }, { + converter : Transforms.localFrameToFixedFrameGenerator('west', 'south'), + order : ['west', 'south', 'up'] + }, { + converter : Transforms.localFrameToFixedFrameGenerator('west', 'up'), + order : ['west', 'up', 'north'] + }, { + converter : Transforms.localFrameToFixedFrameGenerator('west', 'down'), + order : ['west', 'down', 'south'] + }, { + converter : Transforms.localFrameToFixedFrameGenerator('up', 'north'), + order : ['up', 'north', 'west'] + }, { + converter : Transforms.localFrameToFixedFrameGenerator('up', 'south'), + order : ['up', 'south', 'east'] + }, { + converter : Transforms.localFrameToFixedFrameGenerator('up', 'east'), + order : ['up', 'east', 'north'] + }, { + converter : Transforms.localFrameToFixedFrameGenerator('up', 'west'), + order : ['up', 'west', 'south'] + } + ]; + + function testAllLocalFrame(classicalENUMatrix, position) { + var ENUColumn = new Cartesian4(); + var converterColumn = new Cartesian4(); + for (var i = 0; i < converterTab.length; i++) { + var converterMatrix = (converterTab[i].converter)(position, Ellipsoid.UNIT_SPHERE); + var order = converterTab[i].order; + // check translation + Matrix4.getColumn(classicalENUMatrix, 3, ENUColumn); + Matrix4.getColumn(converterMatrix, 3, converterColumn); + expect(ENUColumn).toEqual(converterColumn); + // check axis + for (var j = 0; j < 3; j++) { + Matrix4.getColumn(converterMatrix, j, converterColumn); + var axisName = order[j]; + if (axisName === 'east') { + Matrix4.getColumn(classicalENUMatrix, 0, ENUColumn); + } else if (axisName === 'west') { + Matrix4.getColumn(classicalENUMatrix, 0, ENUColumn); + Cartesian4.negate(ENUColumn, ENUColumn); + } else if (axisName === 'north') { + Matrix4.getColumn(classicalENUMatrix, 1, ENUColumn); + } else if (axisName === 'south') { + Matrix4.getColumn(classicalENUMatrix, 1, ENUColumn); + Cartesian4.negate(ENUColumn, ENUColumn); + } else if (axisName === 'up') { + Matrix4.getColumn(classicalENUMatrix, 2, ENUColumn); + } else if (axisName === 'down') { + Matrix4.getColumn(classicalENUMatrix, 2, ENUColumn); + Cartesian4.negate(ENUColumn, ENUColumn); + } + expect(ENUColumn).toEqual(converterColumn); + } } - expect(ENUColumn).toEqual(converterColumn); - } } - } - for (var i = 0; i < cartesianTab.length; i++) { - var cartesian = cartesianTab[i]; - var classicalEastNorthUpReferential = Transforms.eastNorthUpToFixedFrame(cartesian, Ellipsoid.UNIT_SPHERE); - testAllLocalFrame(classicalEastNorthUpReferential,cartesian); - } + for (var i = 0; i < cartesianTab.length; i++) { + var cartesian = cartesianTab[i]; + var classicalEastNorthUpReferential = Transforms.eastNorthUpToFixedFrame(cartesian, Ellipsoid.UNIT_SPHERE); + testAllLocalFrame(classicalEastNorthUpReferential, cartesian); + } }); it('abnormal use of localFrameToFixedFrameGenerator', function() { - function checkDeveloperError(firstAxis,secondAxis){ - expect(function() { - Transforms.localFrameToFixedFrameGenerator(firstAxis, secondAxis); - }).toThrowDeveloperError(); - } - checkDeveloperError(undefined,undefined); - checkDeveloperError('north',undefined); - checkDeveloperError(undefined,'north'); - checkDeveloperError('south',undefined); - checkDeveloperError('northe','southe'); - - checkDeveloperError('north','north'); - checkDeveloperError('north','south'); - checkDeveloperError('south','north'); - checkDeveloperError('south','south'); - - checkDeveloperError('up','up'); - checkDeveloperError('up','down'); - checkDeveloperError('down','up'); - checkDeveloperError('down','down'); - - checkDeveloperError('east','east'); - checkDeveloperError('east','west'); - checkDeveloperError('west','east'); - checkDeveloperError('west','west'); + function checkDeveloperError(firstAxis, secondAxis) { + expect(function() { + Transforms.localFrameToFixedFrameGenerator(firstAxis, secondAxis); + }).toThrowDeveloperError(); + } + + checkDeveloperError(undefined, undefined); + checkDeveloperError('north', undefined); + checkDeveloperError(undefined, 'north'); + checkDeveloperError('south', undefined); + checkDeveloperError('northe', 'southe'); + + checkDeveloperError('north', 'north'); + checkDeveloperError('north', 'south'); + checkDeveloperError('south', 'north'); + checkDeveloperError('south', 'south'); + + checkDeveloperError('up', 'up'); + checkDeveloperError('up', 'down'); + checkDeveloperError('down', 'up'); + checkDeveloperError('down', 'down'); + + checkDeveloperError('east', 'east'); + checkDeveloperError('east', 'west'); + checkDeveloperError('west', 'east'); + checkDeveloperError('west', 'west'); }); it('headingPitchRollToFixedFrame works without a result parameter', function() { @@ -518,7 +519,6 @@ defineSuite([ expect(actualUp).toEqual(expectedUp); expect(actualTranslation).toEqual(origin); - var UNEFixedFrameConverter = Transforms.localFrameToFixedFrameGenerator('west','south'); // up north east returnedResult = Transforms.headingPitchRollToFixedFrame(origin, hpr, Ellipsoid.UNIT_SPHERE, UNEFixedFrameConverter, result); actualEast = Cartesian3.fromCartesian4(Matrix4.getColumn(returnedResult, 0, new Cartesian4())); // east