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

RTC and ECEF models in 2D/CV #4922

Merged
merged 6 commits into from
Jan 25, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
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
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 @@ -31,8 +32,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 @@ -69,6 +72,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 @@ -207,9 +211,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 @@ -328,6 +334,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