Skip to content

Commit

Permalink
Merge pull request #4922 from AnalyticalGraphicsInc/models-2d-rtc
Browse files Browse the repository at this point in the history
RTC and ECEF models in 2D/CV
  • Loading branch information
pjcozzi authored Jan 25, 2017
2 parents 2c1505f + b56485b commit 3ead620
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 8 deletions.
7 changes: 7 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Change Log
==========

### 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)
Expand Down Expand Up @@ -32,8 +33,10 @@ 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 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)

### 1.29 - 2017-01-02

* Improved 3D Models
* Added the ability to blend a `Model` with a color/translucency. Added `color`, `colorBlendMode`, and `colorBlendAmount` properties to `Model`, `ModelGraphics`, and CZML. Also added `ColorBlendMode` enum. [#4547](https://github.com/AnalyticalGraphicsInc/cesium/pull/4547)
* Added the ability to render a `Model` with a silhouette. Added `silhouetteColor` and `silhouetteSize` properties to `Model`, `ModelGraphics`, and CZML. [#4314](https://github.com/AnalyticalGraphicsInc/cesium/pull/4314)
Expand Down Expand Up @@ -70,6 +73,7 @@ Change Log
* Fixed `Cartographic.fromCartesian` when the cartesian is not on the ellipsoid surface. [#4611](https://github.com/AnalyticalGraphicsInc/cesium/issues/4611)

### 1.27 - 2016-11-01

* Deprecated
* Individual heading, pitch, and roll options to `Transforms.headingPitchRollToFixedFrame` and `Transforms.headingPitchRollQuaternion` have been deprecated and will be removed in 1.30. Pass the new `HeadingPitchRoll` object instead. [#4498](https://github.com/AnalyticalGraphicsInc/cesium/pull/4498)
* Breaking changes
Expand Down Expand Up @@ -208,9 +212,11 @@ Change Log
* Added `packArray` and `unpackArray` functions to `Cartesian2`, `Cartesian3`, and `Cartesian4`.

### 1.22.2 - 2016-06-14

* This is an npm only release to fix the improperly published 1.22.1. There were no code changes.

### 1.22.1 - 2016-06-13

* Fixed default Bing Key and added a watermark to notify users that they need to sign up for their own key.

### 1.22 - 2016-06-01
Expand Down Expand Up @@ -329,6 +335,7 @@ Change Log
* Fixed hole that appeared in the top of in dynamic ellipsoids

### 1.18 - 2016-02-01

* Breaking changes
* Removed support for `CESIUM_binary_glTF`. Use `KHR_binary_glTF` instead, which is the default for the online [COLLADA-to-glTF converter](http://cesiumjs.org/convertmodel.html).
* Deprecated
Expand Down
42 changes: 42 additions & 0 deletions Source/Core/Transforms.js
Original file line number Diff line number Diff line change
Expand Up @@ -1001,5 +1001,47 @@ define([
return result;
};

var swizzleMatrix = new Matrix4(
0.0, 0.0, 1.0, 0.0,
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 0.0, 1.0);

/**
* @private
*/
Transforms.wgs84To2DModelMatrix = function(projection, center, result) {
//>>includeStart('debug', pragmas.debug);
if (!defined(projection)) {
throw new DeveloperError('projection is required.');
}
if (!defined(center)) {
throw new DeveloperError('center is required.');
}
if (!defined(result)) {
throw new DeveloperError('result is required.');
}
//>>includeEnd('debug');

var ellipsoid = projection.ellipsoid;

var fromENU = Transforms.eastNorthUpToFixedFrame(center, ellipsoid, scratchFromENU);
var toENU = Matrix4.inverseTransformation(fromENU, scratchToENU);

var cartographic = ellipsoid.cartesianToCartographic(center, scratchCartographic);
var projectedPosition = projection.project(cartographic, scratchCartesian3Projection);
var newOrigin = scratchCartesian4NewOrigin;
newOrigin.x = projectedPosition.z;
newOrigin.y = projectedPosition.x;
newOrigin.z = projectedPosition.y;
newOrigin.w = 1.0;

var translation = Matrix4.fromTranslation(newOrigin, scratchFromENU);
Matrix4.multiply(swizzleMatrix, toENU, result);
Matrix4.multiply(translation, result, result);

return result;
};

return Transforms;
});
47 changes: 39 additions & 8 deletions Source/Scene/Model.js
Original file line number Diff line number Diff line change
Expand Up @@ -671,8 +671,10 @@ define([
this._pickIds = [];

// CESIUM_RTC extension
this._rtcCenter = undefined; // in world coordinates
this._rtcCenter = undefined; // reference to either 3D or 2D
this._rtcCenterEye = undefined; // in eye coordinates
this._rtcCenter3D = undefined; // in world coordinates
this._rtcCenter2D = undefined; // in projected world coordinates
}

defineProperties(Model.prototype, {
Expand Down Expand Up @@ -2494,10 +2496,13 @@ define([
// CESIUM_RTC extension
var mvRtc = new Matrix4();
return function() {
Matrix4.getTranslation(uniformState.model, scratchTranslationRtc);
Cartesian3.add(scratchTranslationRtc, model._rtcCenter, scratchTranslationRtc);
Matrix4.multiplyByPoint(uniformState.view, scratchTranslationRtc, scratchTranslationRtc);
return Matrix4.setTranslation(uniformState.modelView, scratchTranslationRtc, mvRtc);
if (defined(model._rtcCenter)) {
Matrix4.getTranslation(uniformState.model, scratchTranslationRtc);
Cartesian3.add(scratchTranslationRtc, model._rtcCenter, scratchTranslationRtc);
Matrix4.multiplyByPoint(uniformState.view, scratchTranslationRtc, scratchTranslationRtc);
return Matrix4.setTranslation(uniformState.modelView, scratchTranslationRtc, mvRtc);
}
return uniformState.modelView;
};
},
MODELVIEWPROJECTION : function(uniformState, model) {
Expand Down Expand Up @@ -3325,6 +3330,7 @@ define([
}

var scratchNodeStack = [];
var scratchComputedTranslation = new Cartesian4();
var scratchComputedMatrixIn2D = new Matrix4();

function updateNodeHierarchyModelMatrix(model, modelTransformChanged, justLoaded, projection) {
Expand All @@ -3338,7 +3344,20 @@ define([
var computedModelMatrix = model._computedModelMatrix;

if (model._mode !== SceneMode.SCENE3D) {
computedModelMatrix = Transforms.basisTo2D(projection, computedModelMatrix, scratchComputedMatrixIn2D);
var translation = Matrix4.getColumn(computedModelMatrix, 3, scratchComputedTranslation);
if (!Cartesian4.equals(translation, Cartesian4.UNIT_W)) {
computedModelMatrix = Transforms.basisTo2D(projection, computedModelMatrix, scratchComputedMatrixIn2D);
model._rtcCenter = model._rtcCenter3D;
} else {
var center = model.boundingSphere.center;
var to2D = Transforms.wgs84To2DModelMatrix(projection, center, scratchComputedMatrixIn2D);
computedModelMatrix = Matrix4.multiply(to2D, computedModelMatrix, scratchComputedMatrixIn2D);

if (defined(model._rtcCenter)) {
Matrix4.setTranslation(computedModelMatrix, Cartesian4.UNIT_W, computedModelMatrix);
model._rtcCenter = model._rtcCenter2D;
}
}
}

for (var i = 0; i < length; ++i) {
Expand Down Expand Up @@ -4091,8 +4110,20 @@ define([
if (this._state !== ModelState.FAILED) {
var extensions = this.gltf.extensions;
if (defined(extensions) && defined(extensions.CESIUM_RTC)) {
this._rtcCenter = Cartesian3.fromArray(extensions.CESIUM_RTC.center);
this._rtcCenterEye = new Cartesian3();
var center = Cartesian3.fromArray(extensions.CESIUM_RTC.center);
if (!Cartesian3.equals(center, Cartesian3.ZERO)) {
this._rtcCenter3D = center;

var projection = frameState.mapProjection;
var ellipsoid = projection.ellipsoid;
var cartographic = ellipsoid.cartesianToCartographic(this._rtcCenter3D);
var projectedCart = projection.project(cartographic);
Cartesian3.fromElements(projectedCart.z, projectedCart.x, projectedCart.y, projectedCart);
this._rtcCenter2D = projectedCart;

this._rtcCenterEye = new Cartesian3();
this._rtcCenter = this._rtcCenter3D;
}
}

this._loadResources = new LoadResources();
Expand Down
46 changes: 46 additions & 0 deletions Specs/Core/TransformsSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,34 @@ defineSuite([
expect(rotation2D).toEqualEpsilon(expected, CesiumMath.EPSILON3);
});

it('wgs84To2DModelMatrix creates a model matrix to transform vertices centered origin to 2D', function() {
var ellipsoid = Ellipsoid.WGS84;
var projection = new GeographicProjection(ellipsoid);
var origin = Cartesian3.fromDegrees(-72.0, 40.0, 100.0, ellipsoid);

var actual = Transforms.wgs84To2DModelMatrix(projection, origin, new Matrix4());
var expected = Matrix4.fromTranslation(origin);
Transforms.basisTo2D(projection, expected, expected);

var actualRotation = Matrix4.getRotation(actual, new Matrix3());
var expectedRotation = Matrix4.getRotation(expected, new Matrix3());
expect(actualRotation).toEqualEpsilon(expectedRotation, CesiumMath.EPSILON14);

var fromENU = Transforms.eastNorthUpToFixedFrame(origin, ellipsoid, new Matrix4());
var toENU = Matrix4.inverseTransformation(fromENU, new Matrix4());
var toENUTranslation = Matrix4.getTranslation(toENU, new Cartesian4());
var projectedTranslation = Matrix4.getTranslation(expected, new Cartesian4());

var expectedTranslation = new Cartesian4();
expectedTranslation.x = projectedTranslation.x + toENUTranslation.z;
expectedTranslation.y = projectedTranslation.y + toENUTranslation.x;
expectedTranslation.z = projectedTranslation.z + toENUTranslation.y;

var actualTranslation = Matrix4.getTranslation(actual, new Cartesian4());

expect(actualTranslation).toEqualEpsilon(expectedTranslation, CesiumMath.EPSILON14);
});

it('eastNorthUpToFixedFrame throws without an origin', function() {
expect(function() {
Transforms.eastNorthUpToFixedFrame(undefined, Ellipsoid.WGS84);
Expand Down Expand Up @@ -970,4 +998,22 @@ defineSuite([
Transforms.basisTo2D(new GeographicProjection(), Matrix4.IDENTITY, undefined);
}).toThrowDeveloperError();
});

it ('wgs84To2DModelMatrix throws without projection', function() {
expect(function() {
Transforms.wgs84To2DModelMatrix(undefined, Cartesian3.UNIT_X, new Matrix4());
}).toThrowDeveloperError();
});

it ('wgs84To2DModelMatrix throws without center', function() {
expect(function() {
Transforms.wgs84To2DModelMatrix(new GeographicProjection(), undefined, new Matrix4());
}).toThrowDeveloperError();
});

it ('wgs84To2DModelMatrix throws without result', function() {
expect(function() {
Transforms.wgs84To2DModelMatrix(new GeographicProjection(), Cartesian3.UNIT_X, undefined);
}).toThrowDeveloperError();
});
});
Binary file added Specs/Data/Models/Boxes-ECEF/ecef.glb
Binary file not shown.
45 changes: 45 additions & 0 deletions Specs/Scene/ModelSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ defineSuite([
var texturedBoxCustomUrl = './Data/Models/Box-Textured-Custom/CesiumTexturedBoxTest.gltf';
var texturedBoxKhrBinaryUrl = './Data/Models/Box-Textured-Binary/CesiumTexturedBoxTest.glb';
var boxRtcUrl = './Data/Models/Box-RTC/Box.gltf';
var boxesEcefUrl = './Data/Models/Boxes-ECEF/ecef.glb';
var cesiumAirUrl = './Data/Models/CesiumAir/Cesium_Air.gltf';
var cesiumAir_0_8Url = './Data/Models/CesiumAir/Cesium_Air_0_8.gltf';
var animBoxesUrl = './Data/Models/anim-test-1-boxes/anim-test-1-boxes.gltf';
Expand Down Expand Up @@ -266,6 +267,50 @@ defineSuite([
});
});

it('renders RTC in 2D', function() {
return loadModel(boxRtcUrl, {
modelMatrix : Matrix4.IDENTITY,
minimumPixelSize : 1
}).then(function(m) {
scene.morphTo2D(0.0);
verifyRender(m);
primitives.remove(m);
});
});

it('renders ECEF in 2D', function() {
return loadModel(boxesEcefUrl, {
modelMatrix : Matrix4.IDENTITY,
minimumPixelSize : undefined
}).then(function(m) {
scene.morphTo2D(0.0);
verifyRender(m);
primitives.remove(m);
});
});

it('renders RTC in CV', function() {
return loadModel(boxRtcUrl, {
modelMatrix : Matrix4.IDENTITY,
minimumPixelSize : 1
}).then(function(m) {
scene.morphToColumbusView(0.0);
verifyRender(m);
primitives.remove(m);
});
});

it('renders ECEF in CV', function() {
return loadModel(boxesEcefUrl, {
modelMatrix : Matrix4.IDENTITY,
minimumPixelSize : undefined
}).then(function(m) {
scene.morphToColumbusView(0.0);
verifyRender(m);
primitives.remove(m);
});
});

it('resolves readyPromise', function() {
return texturedBoxModel.readyPromise.then(function(model) {
verifyRender(model);
Expand Down

0 comments on commit 3ead620

Please sign in to comment.