From ff1321ccd87e8f2fa45d58aa4be0e4c2832204a3 Mon Sep 17 00:00:00 2001 From: Matthew Amato Date: Thu, 26 Mar 2015 11:04:24 -0400 Subject: [PATCH] Changes after review 1. Bump model in Interpolation demo to minimumPixelSize of 64 2. Factor out rotation code from `VelocityOrientationProperty` into `Transforms.rotationMatrixFromPositionVelocity` --- Apps/Sandcastle/gallery/Interpolation.html | 2 +- Source/Core/Transforms.js | 41 +++++++++++++++++++ .../VelocityOrientationProperty.js | 35 +++++----------- .../VelocityOrientationPropertySpec.js | 32 ++++++++++++--- 4 files changed, 80 insertions(+), 30 deletions(-) diff --git a/Apps/Sandcastle/gallery/Interpolation.html b/Apps/Sandcastle/gallery/Interpolation.html index d2ed0fe2c595..3fdbb2ff1702 100644 --- a/Apps/Sandcastle/gallery/Interpolation.html +++ b/Apps/Sandcastle/gallery/Interpolation.html @@ -109,7 +109,7 @@ //Load the Cesium plane model to represent the entity model : { uri : '../../SampleData/models/CesiumAir/Cesium_Air.gltf', - minimumPixelSize : 32 + minimumPixelSize : 64 }, //Show the path as a pink line sampled in 1 second increments. diff --git a/Source/Core/Transforms.js b/Source/Core/Transforms.js index 41c3b976b4e8..f2c1e7445518 100644 --- a/Source/Core/Transforms.js +++ b/Source/Core/Transforms.js @@ -773,5 +773,46 @@ define([ return Cartesian2.fromCartesian4(tmp, result); }; + var normalScratch = new Cartesian3(); + var rightScratch = new Cartesian3(); + var upScratch = new Cartesian3(); + + /** + * @private + */ + Transforms.rotationMatrixFromPositionVelocity = function(position, velocity, ellipsoid, result) { + //>>includeStart('debug', pragmas.debug); + if (!defined(position)) { + throw new DeveloperError('position is required.'); + } + + if (!defined(velocity)) { + throw new DeveloperError('velocity is required.'); + } + //>>includeEnd('debug'); + + var normal = defaultValue(ellipsoid, Ellipsoid.WGS84).geodeticSurfaceNormal(position, normalScratch); + var right = Cartesian3.cross(velocity, normal, rightScratch); + var up = Cartesian3.cross(right, velocity, upScratch); + Cartesian3.cross(velocity, up, right); + Cartesian3.negate(right, right); + + if (!defined(result)) { + result = new Matrix3(); + } + + result[0] = velocity.x; + result[1] = velocity.y; + result[2] = velocity.z; + result[3] = right.x; + result[4] = right.y; + result[5] = right.z; + result[6] = up.x; + result[7] = up.y; + result[8] = up.z; + + return result; + }; + return Transforms; }); diff --git a/Source/DataSources/VelocityOrientationProperty.js b/Source/DataSources/VelocityOrientationProperty.js index 29fe6dc1af63..7ff29915de38 100644 --- a/Source/DataSources/VelocityOrientationProperty.js +++ b/Source/DataSources/VelocityOrientationProperty.js @@ -10,6 +10,7 @@ define([ '../Core/JulianDate', '../Core/Matrix3', '../Core/Quaternion', + '../Core/Transforms', './Property' ], function( Cartesian3, @@ -22,6 +23,7 @@ define([ JulianDate, Matrix3, Quaternion, + Transforms, Property) { "use strict"; @@ -130,12 +132,9 @@ define([ var position1Scratch = new Cartesian3(); var position2Scratch = new Cartesian3(); - var normalScratch = new Cartesian3(); - var directionScratch = new Cartesian3(); - var rightScratch = new Cartesian3(); - var upScratch = new Cartesian3(); + var velocityScratch = new Cartesian3(); var timeScratch = new JulianDate(); - var basisScratch = new Matrix3(); + var rotationScratch = new Matrix3(); var step = 1.0 / 60.0; /** @@ -175,27 +174,15 @@ define([ } } - var normal = defaultValue(this._ellipsoid, Ellipsoid.WGS84).geodeticSurfaceNormal(position1, normalScratch); - - var direction = Cartesian3.subtract(position2, position1, directionScratch); - Cartesian3.normalize(direction, direction); - - var right = Cartesian3.cross(direction, normal, rightScratch); - var up = Cartesian3.cross(right, direction, upScratch); - Cartesian3.cross(direction, up, right); - Cartesian3.negate(right, right); + if (Cartesian3.equals(position1, position2)) { + return undefined; + } - basisScratch[0] = direction.x; - basisScratch[1] = direction.y; - basisScratch[2] = direction.z; - basisScratch[3] = right.x; - basisScratch[4] = right.y; - basisScratch[5] = right.z; - basisScratch[6] = up.x; - basisScratch[7] = up.y; - basisScratch[8] = up.z; + var velocity = Cartesian3.subtract(position2, position1, velocityScratch); + Cartesian3.normalize(velocity, velocity); - return Quaternion.fromRotationMatrix(basisScratch, result); + var rotation = Transforms.rotationMatrixFromPositionVelocity(position1, velocity, this._ellipsoid, rotationScratch); + return Quaternion.fromRotationMatrix(rotationScratch, result); }; /** diff --git a/Specs/DataSources/VelocityOrientationPropertySpec.js b/Specs/DataSources/VelocityOrientationPropertySpec.js index 4c70cc95da86..c79a1115f52d 100644 --- a/Specs/DataSources/VelocityOrientationPropertySpec.js +++ b/Specs/DataSources/VelocityOrientationPropertySpec.js @@ -7,6 +7,8 @@ defineSuite([ 'Core/ExtrapolationType', 'Core/JulianDate', 'Core/Quaternion', + 'Core/Transforms', + 'DataSources/CallbackProperty', 'DataSources/SampledPositionProperty' ], function( VelocityOrientationProperty, @@ -16,6 +18,8 @@ defineSuite([ ExtrapolationType, JulianDate, Quaternion, + Transforms, + CallbackProperty, SampledPositionProperty) { "use strict"; /*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn*/ @@ -103,21 +107,28 @@ defineSuite([ }); it('works without result parameter', function() { - var times = [new JulianDate(0, 0), new JulianDate(1, 0)]; + var times = [new JulianDate(0, 0), new JulianDate(0, 1.0 / 60.0)]; var values = [Cartesian3.fromDegrees(0, 0, 0), Cartesian3.fromDegrees(1, 0, 0)]; + var velocity = Cartesian3.subtract(values[1], values[0], new Cartesian3()); + Cartesian3.normalize(velocity, velocity); var position = new SampledPositionProperty(); position.addSamples(times, values); var property = new VelocityOrientationProperty(position); - expect(property.getValue(times[0])).toEqual(new Quaternion(-0.49781357154789996, -0.5021769090497131, -0.50215778744446, -0.49779461608731784)); - expect(property.getValue(times[1])).toEqual(new Quaternion(-0.49781359332642117, -0.5021768874604212, -0.5021577659852654, -0.4977946379931618)); + var matrix = Transforms.rotationMatrixFromPositionVelocity(position.getValue(times[0]), velocity); + expect(property.getValue(times[0])).toEqual(Quaternion.fromRotationMatrix(matrix)); + + matrix = Transforms.rotationMatrixFromPositionVelocity(position.getValue(times[0]), velocity); + expect(property.getValue(times[1])).toEqual(Quaternion.fromRotationMatrix(matrix)); }); it('works with result parameter', function() { - var times = [new JulianDate(0, 0), new JulianDate(1, 0)]; + var times = [new JulianDate(0, 0), new JulianDate(0, 1.0 / 60.0)]; var values = [Cartesian3.fromDegrees(0, 0, 0), Cartesian3.fromDegrees(1, 0, 0)]; + var velocity = Cartesian3.subtract(values[1], values[0], new Cartesian3()); + Cartesian3.normalize(velocity, velocity); var position = new SampledPositionProperty(); position.addSamples(times, values); @@ -127,7 +138,18 @@ defineSuite([ var expected = new Cartesian3(); var result = property.getValue(times[0], expected); expect(result).toBe(expected); - expect(expected).toEqual(new Quaternion(-0.49781357154789996, -0.5021769090497131, -0.50215778744446, -0.49779461608731784)); + + var matrix = Transforms.rotationMatrixFromPositionVelocity(position.getValue(times[0]), velocity); + expect(expected).toEqual(Quaternion.fromRotationMatrix(matrix)); + }); + + it('is undefined at zero velocity', function() { + var position = new CallbackProperty(function() { + return Cartesian3.fromDegrees(0, 0, 0); + }, false); + + var property = new VelocityOrientationProperty(position); + expect(property.getValue(new JulianDate())).toBeUndefined(); }); it('returns undefined when position value is undefined', function() {