Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for entities as reference frames #2998

Closed
wants to merge 14 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Support for entities as reference frames, as well as "null" (arbitrar…
…y/unknown) reference frames

Modified CzmlDataSource to process ‘#id’ and null referenceFrames.
Added OrientationProperty (convertToReferenceFrame)
Modified PositionProperty (convertToReferenceFrame)
Added ReferenceEntity
Added OrientationPropertySpec
Fixed PositionPropertySpec tests and added new tests.
speigg committed Sep 3, 2015
commit 4bf87bbb9ccd9d952db6e426d9a50f1cf6955020
30 changes: 27 additions & 3 deletions Source/DataSources/CzmlDataSource.js
Original file line number Diff line number Diff line change
@@ -60,6 +60,7 @@ define([
'./PolylineOutlineMaterialProperty',
'./PositionPropertyArray',
'./RectangleGraphics',
'./ReferenceEntity',
'./ReferenceProperty',
'./SampledPositionProperty',
'./SampledProperty',
@@ -129,6 +130,7 @@ define([
PolylineOutlineMaterialProperty,
PositionPropertyArray,
RectangleGraphics,
ReferenceEntity,
ReferenceProperty,
SampledPositionProperty,
SampledProperty,
@@ -148,6 +150,21 @@ define([
return ReferenceProperty.fromString(collection, referenceString);
}

function makeReferenceEntity(collection, referenceFrameString, currentReferenceFrame) {
if (referenceFrameString === null) {
return null;
}

if (referenceFrameString[0] === '#') {
referenceFrameString = referenceFrameString.slice(1);
}

if (currentReferenceFrame instanceof ReferenceEntity && currentReferenceFrame.targetCollection === collection && currentReferenceFrame.targetId === referenceFrameString) {
return currentReferenceFrame;
}
return new ReferenceEntity(collection, referenceFrameString);
}

var scratchCartesian = new Cartesian3();
var scratchSpherical = new Spherical();
var scratchCartographic = new Cartographic();
@@ -605,8 +622,17 @@ define([
var isReference = defined(packetData.reference);
var hasInterval = defined(combinedInterval) && !combinedInterval.equals(Iso8601.MAXIMUM_INTERVAL);

var property = object[propertyName];

if (!isReference) {
referenceFrame = defaultValue(ReferenceFrame[packetData.referenceFrame], undefined);
var packetReferenceFrame = packetData.referenceFrame;
if (defined(packetReferenceFrame)) {
referenceFrame = ReferenceFrame[packetReferenceFrame];
if (!defined(referenceFrame)) {
var currentReferenceFrame = defined(property) && property.referenceFrame;
referenceFrame = makeReferenceEntity(entityCollection, packetReferenceFrame, currentReferenceFrame);
}
}
unwrappedInterval = unwrapCartesianInterval(packetData);
unwrappedIntervalLength = defaultValue(unwrappedInterval.length, 1);
isSampled = unwrappedIntervalLength > packedLength;
@@ -622,8 +648,6 @@ define([
return;
}

var property = object[propertyName];

var epoch;
var packetEpoch = packetData.epoch;
if (defined(packetEpoch)) {
223 changes: 223 additions & 0 deletions Source/DataSources/OrientationProperty.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
/*global define*/
define([
'../Core/defined',
'../Core/defineProperties',
'../Core/DeveloperError',
'../Core/Matrix3',
'../Core/Quaternion',
'../Core/ReferenceFrame',
'../Core/Transforms'
], function(
defined,
defineProperties,
DeveloperError,
Matrix3,
Quaternion,
ReferenceFrame,
Transforms) {
"use strict";

/**
* The interface for all {@link Property} objects that define a
* orientation as a {@link Quaternion}.
* This type defines an interface and cannot be instantiated directly.
*
* @alias OrientationProperty
* @constructor
*/
var OrientationProperty = function() {
DeveloperError.throwInstantiationError();
};

defineProperties(OrientationProperty.prototype, {
/**
* Gets a value indicating if this property is constant. A property is considered
* constant if getValue always returns the same result for the current definition.
* @memberof OrientationProperty.prototype
*
* @type {Boolean}
* @readonly
*/
isConstant : {
get : DeveloperError.throwInstantiationError
},
/**
* Gets the event that is raised whenever the definition of this property changes.
* The definition is considered to have changed if a call to getValue would return
* a different result for the same time.
* @memberof OrientationProperty.prototype
*
* @type {Event}
* @readonly
*/
definitionChanged : {
get : DeveloperError.throwInstantiationError
}
});

/**
* Gets the value of the property at the provided time relative to the position's reference frame.
* @function
*
* @param {JulianDate} time The time for which to retrieve the value.
* @param {Quaternion} [result] The object to store the value into, if omitted, a new instance is created and returned.
* @returns {Quaternion} The modified result parameter or a new instance if the result parameter was not supplied.
*/
OrientationProperty.prototype.getValue = DeveloperError.throwInstantiationError;

/**
* Compares this property to the provided property and returns
* <code>true</code> if they are equal, <code>false</code> otherwise.
*
* @param {Property} [other] The other property.
* @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise.
*/
OrientationProperty.prototype.equals = DeveloperError.throwInstantiationError;

function framesEqual(frame1, frame2) {
return frame1 && frame1.id ?
frame1.id === (frame2 && frame2.id) :
frame1 === frame2;
}

function frameParents(frame) {
var frames = [];
while (defined(frame) && frame !== null) {
frames.unshift(frame);
frame = frame.position && frame.position.referenceFrame;
}
return frames;
}

function lowestCommonAncestor(parents1, parents2) {
if (!framesEqual(parents1[0],parents2[0])) {
return -1;
}

var h = Math.min(parents1.length, parents2.length);
for (var i = 0; i <= h; i++) {
if (!framesEqual(parents1[i],parents2[i])) {
return i-1;
}
}

return -1;
}

var scratchIcrfToFixedMatrix3 = new Matrix3();
var scratchIcrfToFixed = new Quaternion();

function getIcrfToFixed(time) {
var icrfToFixedRotation = Transforms.computeIcrfToFixedMatrix(time, scratchIcrfToFixedMatrix3);
if (!defined(icrfToFixedRotation)) {
icrfToFixedRotation = Transforms.computeTemeToPseudoFixedMatrix(time, scratchIcrfToFixedMatrix3);
}
return Quaternion.fromRotationMatrix(icrfToFixedRotation, scratchIcrfToFixed);
}

var scratchMatrix3 = new Matrix3();
var scratchQuaternion = new Quaternion();

/**
* @private
*/
OrientationProperty.convertToReferenceFrame = function(time, value, inputFrame, outputFrame, result) {
if (!defined(value)) {
return value;
}
if (!defined(result)) {
result = new Quaternion();
}

if (inputFrame === outputFrame) {
return Quaternion.clone(value, result);
}

if (inputFrame === null || outputFrame === null) {
return undefined;
}

var inputFrameParents = frameParents(inputFrame);
var outputFrameParents = frameParents(outputFrame);
var lcaIndex = lowestCommonAncestor(inputFrameParents, outputFrameParents);
var lcaFrame = inputFrameParents[lcaIndex];

var inputOrientationAccumulator = function (accumulatedOrientationValue, frame) {
if (!defined(accumulatedOrientationValue)) {
return accumulatedOrientationValue;
}

var frameOrientationProperty = frame.orientation;
if (!defined(frameOrientationProperty)) {
return undefined;
}

var frameOrientationValue = frameOrientationProperty.getValue(time, scratchQuaternion);
if (!defined(frameOrientationValue)) {
return undefined;
}

return Quaternion.multiply(frameOrientationValue, accumulatedOrientationValue, accumulatedOrientationValue);
};

var outputOrientationAccumulator = function (accumulatedOrientationValue, frame) {
if (!defined(accumulatedOrientationValue)) {
return accumulatedOrientationValue;
}

var frameOrientationProperty = frame.orientation;
if (!defined(frameOrientationProperty)) {
return undefined;
}

var frameOrientationValue = frameOrientationProperty.getValue(time, scratchQuaternion);
if (!defined(frameOrientationValue)) {
return undefined;
}

Quaternion.conjugate(frameOrientationValue, frameOrientationValue);
return Quaternion.multiply(frameOrientationValue, accumulatedOrientationValue, accumulatedOrientationValue);
};

if (defined(lcaFrame)) {
inputFrameParents = inputFrameParents.slice(lcaIndex+1);
outputFrameParents = outputFrameParents.slice(lcaIndex+1);

var lcaFrameValue = inputFrameParents.reduceRight(inputOrientationAccumulator, Quaternion.clone(value, result));
if (!defined(lcaFrameValue)) {
return undefined;
}

return outputFrameParents.reduce(outputOrientationAccumulator, lcaFrameValue);
}

var inputRootFrame = inputFrameParents.shift();
var outputRootFrame = outputFrameParents.shift();
var fixedFrameValue, inertialFrameValue;

if (inputRootFrame === ReferenceFrame.INERTIAL && outputRootFrame === ReferenceFrame.FIXED) {
inertialFrameValue = inputFrameParents.reduceRight(inputOrientationAccumulator, Quaternion.clone(value, result));
if (!defined(inertialFrameValue)) {
return undefined;
}

fixedFrameValue = Quaternion.multiply(getIcrfToFixed(time), inertialFrameValue, result);
return outputFrameParents.reduce(outputOrientationAccumulator, fixedFrameValue);
}

if (inputRootFrame === ReferenceFrame.FIXED && outputRootFrame === ReferenceFrame.INERTIAL) {
fixedFrameValue = inputFrameParents.reduceRight(inputOrientationAccumulator, Quaternion.clone(value, result));
if (!defined(fixedFrameValue)) {
return undefined;
}

var fixedToIcrf = Quaternion.conjugate(getIcrfToFixed(time), scratchQuaternion);
inertialFrameValue = Quaternion.multiply(fixedToIcrf, fixedFrameValue, result);
return outputFrameParents.reduce(outputOrientationAccumulator, inertialFrameValue);
}

return undefined;
};

return OrientationProperty;
});
227 changes: 161 additions & 66 deletions Source/DataSources/PositionProperty.js
Original file line number Diff line number Diff line change
@@ -8,8 +8,7 @@ define([
'../Core/Matrix4',
'../Core/Quaternion',
'../Core/ReferenceFrame',
'../Core/Transforms',
'./Entity'
'../Core/Transforms'
], function(
Cartesian3,
defined,
@@ -19,8 +18,7 @@ define([
Matrix4,
Quaternion,
ReferenceFrame,
Transforms,
Entity) {
Transforms) {
"use strict";

/**
@@ -105,79 +103,176 @@ define([
*/
PositionProperty.prototype.equals = DeveloperError.throwInstantiationError;

function framesEqual(frame1, frame2) {
return frame1 && frame1.id ?
frame1.id === (frame2 && frame2.id) :
frame1 === frame2;
}

/**
* @private
*/
PositionProperty.convertToReferenceFrame = function(time, value, inputFrame, outputFrame, result, first) {
if(!defined(first)){
first = true;
}
if (!defined(value)) {
return value;
}
if (!defined(result)){
result = new Cartesian3();
function frameParents(frame) {
var frames = [];
while (defined(frame) && frame !== null) {
frames.unshift(frame);
frame = frame.position && frame.position.referenceFrame;
}
return frames;
}

if (inputFrame === outputFrame) {
return Cartesian3.clone(value, result);
function lowestCommonAncestor(parents1, parents2) {
if (!framesEqual(parents1[0],parents2[0])) {
return -1;
}

if (!defined(result)) {
result = new Cartesian3();
}

var scratchMatrix3 = new Matrix3();
var framePositionValue = new Cartesian3();
var frameOrientationValue = new Quaternion();
var subResult = new Cartesian3();

if (first && inputFrame instanceof Entity) {
var inFramePosition = inputFrame.position;
var inFrameReferenceFrame = inFramePosition.referenceFrame;
var inFramePositionValue = inFramePosition.getValueInReferenceFrame(time, inFrameReferenceFrame, framePositionValue);

var inFrameOrientationProperty = inputFrame.orientation;
if (defined(inFrameOrientationProperty)) {
var inFrameOrientation = inFrameOrientationProperty.getValue(time, frameOrientationValue);
Matrix3.fromQuaternion(inFrameOrientation, scratchMatrix3);
Matrix3.multiplyByVector(scratchMatrix3, value, result);
} else {
return Cartesian3.add(inFramePositionValue, value, result);
var h = Math.min(parents1.length, parents2.length);
for (var i = 0; i <= h; i++) {
if (!framesEqual(parents1[i],parents2[i])) {
return i-1;
}

subResult = PositionProperty.convertToReferenceFrame(time, inFramePositionValue, inFrameReferenceFrame, outputFrame, subResult);
return Cartesian3.add(subResult, result, result);
}

if (outputFrame instanceof Entity) {
var outFramePosition = outputFrame.position;
var outFrameReferenceFrame = outFramePosition.referenceFrame;
var outFramePositionValue = outFramePosition.getValueInReferenceFrame(time, outFrameReferenceFrame, framePositionValue);

var outFrameOrientationProperty = outputFrame.orientation;
if (defined(outFrameOrientationProperty)) {
var outFrameOrientation = outFrameOrientationProperty.getValue(time, frameOrientationValue);
Matrix3.fromQuaternion(Quaternion.conjugate(outFrameOrientation, outFrameOrientation), scratchMatrix3);
Matrix3.multiplyByVector(scratchMatrix3, value, result);
Cartesian3.subtract(result, outFramePositionValue, result);
} else {
Cartesian3.subtract(value, outFramePositionValue, result);
}
return PositionProperty.convertToReferenceFrame(time, result, outFrameReferenceFrame, outputFrame, result, false);
}
return -1;
}

var scratchIcrfToFixedMatrix3 = new Matrix3();

var icrfToFixed = Transforms.computeIcrfToFixedMatrix(time, scratchMatrix3);
function getIcrfToFixed(time) {
var icrfToFixed = Transforms.computeIcrfToFixedMatrix(time, scratchIcrfToFixedMatrix3);
if (!defined(icrfToFixed)) {
icrfToFixed = Transforms.computeTemeToPseudoFixedMatrix(time, scratchMatrix3);
}
if (inputFrame === ReferenceFrame.INERTIAL && outputFrame === ReferenceFrame.FIXED) {
return Matrix3.multiplyByVector(icrfToFixed, value, result);
}
if (inputFrame === ReferenceFrame.FIXED && outputFrame === ReferenceFrame.INERTIAL) {
return Matrix3.multiplyByVector(Matrix3.transpose(icrfToFixed, scratchMatrix3), value, result);
icrfToFixed = Transforms.computeTemeToPseudoFixedMatrix(time, scratchIcrfToFixedMatrix3);
}
return icrfToFixed;
}

var scratchMatrix3 = new Matrix3();
var scratchCartesian3 = new Cartesian3();
var scratchQuaternion = new Quaternion();

/**
* @private
*/
PositionProperty.convertToReferenceFrame = function(time, value, inputFrame, outputFrame, result) {
if (!defined(value)) {
return value;
}
if (!defined(result)) {
result = new Cartesian3();
}

if (inputFrame === outputFrame) {
return Cartesian3.clone(value, result);
}

if (inputFrame === null || outputFrame === null) {
return undefined;
}

var inputFrameParents = frameParents(inputFrame);
var outputFrameParents = frameParents(outputFrame);
var lcaIndex = lowestCommonAncestor(inputFrameParents, outputFrameParents);
var lcaFrame = inputFrameParents[lcaIndex];

var inputPositionAccumulator = function (accumulatedPositionValue, frame) {
if (!defined(accumulatedPositionValue)) {
return accumulatedPositionValue;
}

var framePositionProperty = frame.position;
if (!defined(framePositionProperty)) {
return undefined;
}

var frameReferenceFrame = framePositionProperty.referenceFrame;
var framePositionValue = framePositionProperty.getValueInReferenceFrame(time, frameReferenceFrame, scratchCartesian3);
if (!defined(framePositionValue)) {
return undefined;
}

var frameOrientationProperty = frame.orientation;
if (defined(frameOrientationProperty)) {
var frameOrientationValue = frameOrientationProperty.getValue(time, scratchQuaternion);
if (!defined(frameOrientationValue)) {
return undefined;
}

Matrix3.fromQuaternion(frameOrientationValue, scratchMatrix3);
Matrix3.multiplyByVector(scratchMatrix3, accumulatedPositionValue, accumulatedPositionValue);
return Cartesian3.add(framePositionValue, accumulatedPositionValue, accumulatedPositionValue);
}

return Cartesian3.add(framePositionValue, accumulatedPositionValue, accumulatedPositionValue);
};

var outputPositionAccumulator = function (accumulatedPositionValue, frame) {
if (!defined(accumulatedPositionValue)) {
return accumulatedPositionValue;
}

var framePositionProperty = frame.position;
if (!defined(framePositionProperty)) {
return undefined;
}

var frameReferenceFrame = framePositionProperty.referenceFrame;
var framePositionValue = framePositionProperty.getValueInReferenceFrame(time, frameReferenceFrame, scratchCartesian3);
if (!defined(framePositionValue)) {
return undefined;
}

accumulatedPositionValue = Cartesian3.subtract(accumulatedPositionValue, framePositionValue, accumulatedPositionValue);

var frameOrientationProperty = frame.orientation;
if (defined(frameOrientationProperty)) {
var frameOrientationValue = frameOrientationProperty.getValue(time, scratchQuaternion);
if (!defined(frameOrientationValue)) {
return undefined;
}

Quaternion.conjugate(frameOrientationValue, frameOrientationValue);
Matrix3.fromQuaternion(frameOrientationValue, scratchMatrix3);
Matrix3.multiplyByVector(scratchMatrix3, accumulatedPositionValue, accumulatedPositionValue);
}

return accumulatedPositionValue;
};

if (defined(lcaFrame)) {
inputFrameParents = inputFrameParents.slice(lcaIndex+1);
outputFrameParents = outputFrameParents.slice(lcaIndex+1);

var lcaFrameValue = inputFrameParents.reduceRight(inputPositionAccumulator, Cartesian3.clone(value, result));
if (!defined(lcaFrameValue)) {
return undefined;
}

return outputFrameParents.reduce(outputPositionAccumulator, lcaFrameValue);
}

var inputRootFrame = inputFrameParents.shift();
var outputRootFrame = outputFrameParents.shift();
var fixedFrameValue, inertialFrameValue;

if (inputRootFrame === ReferenceFrame.INERTIAL && outputRootFrame === ReferenceFrame.FIXED) {
inertialFrameValue = inputFrameParents.reduceRight(inputPositionAccumulator, Cartesian3.clone(value, result));
if (!defined(inertialFrameValue)) {
return undefined;
}

fixedFrameValue = Matrix3.multiplyByVector(getIcrfToFixed(time), inertialFrameValue, result);
return outputFrameParents.reduce(outputPositionAccumulator, fixedFrameValue);
}

if (inputRootFrame === ReferenceFrame.FIXED && outputRootFrame === ReferenceFrame.INERTIAL) {
fixedFrameValue = inputFrameParents.reduceRight(inputPositionAccumulator, Cartesian3.clone(value, result));
if (!defined(fixedFrameValue)) {
return undefined;
}

var fixedToIcrf = Matrix3.transpose(getIcrfToFixed(time), scratchMatrix3);
inertialFrameValue = Matrix3.multiplyByVector(fixedToIcrf, fixedFrameValue, result);
return outputFrameParents.reduce(outputPositionAccumulator, inertialFrameValue);
}

return undefined;
};

return PositionProperty;
160 changes: 160 additions & 0 deletions Source/DataSources/ReferenceEntity.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/*global define*/
define([
'../Core/defined',
'../Core/defineProperties',
'../Core/DeveloperError',
'../Core/Event',
'./Property'
], function(
defined,
defineProperties,
DeveloperError,
Event,
Property) {
"use strict";

function resolve(that) {
var targetEntity = that._targetEntity;

if (that._resolveEntity) {
targetEntity = that._targetCollection.getById(that._targetId);

if (defined(targetEntity)) {
that._targetEntity = targetEntity;
that._resolveEntity = false;
}
}
return targetEntity;
}

/**
* References an {@link Entity} in an {@link EntityCollection}.
*
* @alias ReferenceEntity
* @constructor
*
* @param {EntityCollection} targetCollection The entity collection which will be used to resolve the reference.
* @param {String} targetId The id of the entity which is being referenced.
*
*/
var ReferenceEntity = function(targetCollection, targetId) {
//>>includeStart('debug', pragmas.debug);
if (!defined(targetCollection)) {
throw new DeveloperError('targetCollection is required.');
}
if (!defined(targetId) || targetId === '') {
throw new DeveloperError('targetId is required.');
}
//>>includeEnd('debug');

this._targetCollection = targetCollection;
this._targetId = targetId;
this._targetEntity = undefined;
this._definitionChanged = new Event();
this._resolveEntity = true;

targetCollection.collectionChanged.addEventListener(ReferenceEntity.prototype._onCollectionChanged, this);
};

defineProperties(ReferenceEntity.prototype, {
/**
* Gets the event that is raised whenever the definition of this entity changes.
* The definition is changed whenever the referenced property's definition is changed.
* @memberof ReferenceEntity.prototype
* @type {Event}
* @readonly
*/
definitionChanged : {
get : function() {
return this._definitionChanged;
}
},
/**
* Gets the id of the entity being referenced.
* @memberof ReferenceEntity.prototype
* @type {String}
* @readonly
*/
id : {
get : function() {
return this._targetId;
}
},
/**
* Gets the position property of the entity being referenced.
* @memberof ReferenceProperty.prototype
* @type {ReferenceFrame}
* @readonly
*/
position : {
get : function() {
var entity = resolve(this);
return defined(entity) ? entity.position : undefined;
}
},
/**
* Gets the orientation property of the entity being referenced.
* @memberof ReferenceProperty.prototype
* @type {ReferenceFrame}
* @readonly
*/
orientation : {
get : function() {
var entity = resolve(this);
return defined(entity) ? entity.orientation : undefined;
}
},
/**
* Gets the id of the entity being referenced.
* @memberof ReferenceEntity.prototype
* @type {String}
* @readonly
*/
targetId : {
get : function() {
return this._targetId;
}
},
/**
* Gets the collection containing the entity being referenced.
* @memberof ReferenceEntity.prototype
* @type {EntityCollection}
* @readonly
*/
targetCollection : {
get : function() {
return this._targetCollection;
}
},
/**
* Gets the resolved instance of the underlying referenced entity.
* @memberof ReferenceEntity.prototype
* @type {Property}
* @readonly
*/
resolvedEntity : {
get : function() {
return resolve(this);
}
}
});

ReferenceEntity.prototype._onCollectionChanged = function(collection, added, removed) {
var targetEntity = this._targetEntity;
if (defined(targetEntity)) {
if (removed.indexOf(targetEntity) !== -1) {
this._resolveEntity = true;
} else if (this._resolveEntity) {
//If targetEntity is defined but resolveEntity is true, then the entity is detached
//and any change to the collection needs to incur an attempt to resolve in order to re-attach.
//without this if block, a reference that becomes re-attached will not signal definitionChanged
resolve(this);
if (!this._resolveEntity) {
this._definitionChanged.raiseEvent(this);
}
}
}
};

return ReferenceEntity;
});
38 changes: 38 additions & 0 deletions Specs/DataSources/OrientationPropertySpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*global defineSuite*/
defineSuite([
'DataSources/OrientationProperty',
'Core/Cartesian3',
'Core/JulianDate',
'Core/Math',
'Core/Quaternion',
'Core/ReferenceFrame',
'DataSources/ConstantPositionProperty',
'DataSources/ConstantProperty',
'DataSources/Entity'
], function(
OrientationProperty,
Cartesian3,
JulianDate,
CesiumMath,
Quaternion,
ReferenceFrame,
ConstantPositionProperty,
ConstantProperty,
Entity) {
"use strict";
/*global jasmine,describe,xdescribe,it,xit,expect,beforeEach,afterEach,beforeAll,afterAll,spyOn,runs,waits,waitsFor*/

var time = JulianDate.now();

it('Works with custom input referenceFrame', function() {
var referenceFrame = new Entity();
referenceFrame.position = new ConstantPositionProperty(new Cartesian3(100000, 200000, 300000));
referenceFrame.orientation = new ConstantProperty(new Quaternion(0, 0, 0, 1));

var value = new Quaternion(1, 0, 0, 1);
var result = OrientationProperty.convertToReferenceFrame(time, value, referenceFrame, ReferenceFrame.FIXED);

expect(result).toEqual(new Quaternion(1, 0, 0, 1));
});

});
56 changes: 47 additions & 9 deletions Specs/DataSources/PositionPropertySpec.js
Original file line number Diff line number Diff line change
@@ -64,10 +64,10 @@ defineSuite([
var value = new Cartesian3(1, 2, 3);
var result = PositionProperty.convertToReferenceFrame(time, value, referenceFrame2, ReferenceFrame.FIXED);

expect(result).toEqual(new Cartesian3(99601, 200197, 300602));
expect(result).toEqual(new Cartesian3(99603, 200201, 300602));
});

it('Works with custom ouput referenceFrame without orientation', function() {
it('Works with custom output referenceFrame without orientation', function() {
var referenceFrame = new Entity();
referenceFrame.position = new ConstantPositionProperty(new Cartesian3(100000, 200000, 300000));

@@ -77,7 +77,7 @@ defineSuite([
expect(result).toEqual(new Cartesian3(1, 2, 3));
});

it('Works with custom ouput referenceFrame with orientation', function() {
it('Works with custom output referenceFrame with orientation', function() {
var referenceFrame = new Entity();
referenceFrame.position = new ConstantPositionProperty(new Cartesian3(100000, 200000, 300000));
var orientation = new Quaternion(0, 0, 1, 1);
@@ -87,10 +87,10 @@ defineSuite([
var value = new Cartesian3(99998, 200001, 300003);
var result = PositionProperty.convertToReferenceFrame(time, value, ReferenceFrame.FIXED, referenceFrame);

expect(result).toEqual(new Cartesian3(1, 2, 3));
expect(result).toEqualEpsilon(new Cartesian3(1, 2, 3), CesiumMath.EPSILON7);
});

it('Works with custom chained ouput referenceFrame', function() {
it('Works with custom chained output referenceFrame', function() {
var referenceFrame = new Entity();
referenceFrame.position = new ConstantPositionProperty(new Cartesian3(100000, 200000, 300000));
var orientation = new Quaternion(0, 0, 1, 1);
@@ -103,10 +103,10 @@ defineSuite([
Quaternion.normalize(orientation, orientation);
referenceFrame2.orientation = new ConstantProperty(orientation);

var value = new Cartesian3(99601, 200197, 300602);
var value = new Cartesian3(99603, 200201, 300602);
var result = PositionProperty.convertToReferenceFrame(time, value, ReferenceFrame.FIXED, referenceFrame2);

expect(result).toEqual(new Cartesian3(1, 2, 3));
expect(result).toEqualEpsilon(new Cartesian3(1, 2, 3), CesiumMath.EPSILON7);
});

it('Works with custom input and output referenceFrames', function() {
@@ -125,6 +125,44 @@ defineSuite([
var value = new Cartesian3(1, 2, 3);
var result = PositionProperty.convertToReferenceFrame(time, value, referenceFrame2, referenceFrame);

expect(result).toEqual(new Cartesian3(197, 399, 602), CesiumMath.EPSILON7);
expect(result).toEqualEpsilon(new Cartesian3(201, 397, 602), CesiumMath.EPSILON7);
});

it('Works with custom input and output referenceFrames and null root referenceFrame', function() {
var referenceFrame = new Entity();
referenceFrame.position = new ConstantPositionProperty(new Cartesian3(100000, 200000, 300000), null);
var orientation = new Quaternion(0, 0, 1, 1);
Quaternion.normalize(orientation, orientation);
referenceFrame.orientation = new ConstantProperty(orientation);

var referenceFrame2 = new Entity();
referenceFrame2.position = new ConstantPositionProperty(new Cartesian3(200, 400, 600), referenceFrame);
orientation = new Quaternion(1, 0, 0, 1);
Quaternion.normalize(orientation, orientation);
referenceFrame2.orientation = new ConstantProperty(orientation);

var value = new Cartesian3(1, 2, 3);
var result = PositionProperty.convertToReferenceFrame(time, value, referenceFrame2, referenceFrame);

expect(result).toEqualEpsilon(new Cartesian3(201, 397, 602), CesiumMath.EPSILON7);
});

it('returns undefined when input and output referenceFrames are disconnected', function() {
var referenceFrame = new Entity();
referenceFrame.position = new ConstantPositionProperty(new Cartesian3(100000, 200000, 300000), null);
var orientation = new Quaternion(0, 0, 1, 1);
Quaternion.normalize(orientation, orientation);
referenceFrame.orientation = new ConstantProperty(orientation);

var referenceFrame2 = new Entity();
referenceFrame2.position = new ConstantPositionProperty(new Cartesian3(200, 400, 600), null);
orientation = new Quaternion(1, 0, 0, 1);
Quaternion.normalize(orientation, orientation);
referenceFrame2.orientation = new ConstantProperty(orientation);

var value = new Cartesian3(1, 2, 3);
var result = PositionProperty.convertToReferenceFrame(time, value, referenceFrame2, referenceFrame);

expect(result).toEqual(undefined);
});
});
});