Skip to content

Commit

Permalink
Merge branch 'master' into translucent-pick-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
lilleyse authored Sep 17, 2018
2 parents 869c774 + 229fdf6 commit d726c4f
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 78 deletions.
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ Change Log

##### Fixes :wrench:
* Fixed picking for overlapping translucent primitives. [#7039](https://github.com/AnalyticalGraphicsInc/cesium/pull/7039)
* Fixed an issue in the 3D Tiles traversal where external tilesets would not always traverse to their root tile. [#7035](https://github.com/AnalyticalGraphicsInc/cesium/pull/7035)
* Fixed an issue in the 3D Tiles traversal where empty tiles would be selected instead of their nearest loaded ancestors. [#7011](https://github.com/AnalyticalGraphicsInc/cesium/pull/7011)
* Fixed an issue where scaling near zero with an model animation could cause rendering to stop. [#6954](https://github.com/AnalyticalGraphicsInc/cesium/pull/6954)
* Fixed bug where credits weren't displaying correctly if more than one viewer was initialized [#6965](expect(https://github.com/AnalyticalGraphicsInc/cesium/issues/6965)

### 1.49 - 2018-09-04
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/DistanceDisplayCondition.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ define([
*
* @example
* // Make a billboard that is only visible when the distance to the camera is between 10 and 20 meters.
* billboard.distanceDisplayCondition = new DistanceDisplayCondition(10.0 20.0);
* billboard.distanceDisplayCondition = new Cesium.DistanceDisplayCondition(10.0, 20.0);
*/
function DistanceDisplayCondition(near, far) {
near = defaultValue(near, 0.0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ define([
* Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883)), new Cesium.Cartesian3(0.0, 0.0, 1000000.0), new Cesium.Matrix4()),
* id : 'box',
* attributes : {
* show : new Cesium.DistanceDisplayConditionGeometryInstanceAttribute(100.0, 10000.0)
* distanceDisplayCondition : new Cesium.DistanceDisplayConditionGeometryInstanceAttribute(100.0, 10000.0)
* }
* });
*
Expand Down Expand Up @@ -123,10 +123,11 @@ define([
* @exception {DeveloperError} distanceDisplayCondition.far must be greater than distanceDisplayCondition.near
*
* @example
* var distanceDisplayCondition = new Cesium.DistanceDisplayCondition(100.0, 10000.0);
* var instance = new Cesium.GeometryInstance({
* geometry : geometry,
* attributes : {
* color : Cesium.DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition),
* distanceDisplayCondition : Cesium.DistanceDisplayConditionGeometryInstanceAttribute.fromDistanceDisplayCondition(distanceDisplayCondition)
* }
* });
*/
Expand Down
7 changes: 7 additions & 0 deletions Source/Core/Math.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,13 @@ define([
*/
CesiumMath.EPSILON20 = 0.00000000000000000001;

/**
* 0.000000000000000000001
* @type {Number}
* @constant
*/
CesiumMath.EPSILON21 = 0.000000000000000000001;

/**
* The gravitational parameter of the Earth in meters cubed
* per second squared as defined by the WGS84 model: 3.986004418e14
Expand Down
51 changes: 25 additions & 26 deletions Source/Core/Matrix4.js
Original file line number Diff line number Diff line change
Expand Up @@ -2211,31 +2211,6 @@ define([
Check.typeOf.object('matrix', matrix);
Check.typeOf.object('result', result);
//>>includeEnd('debug');

// Special case for a zero scale matrix that can occur, for example,
// when a model's node has a [0, 0, 0] scale.
if (Matrix3.equalsEpsilon(Matrix4.getRotation(matrix, scratchInverseRotation), scratchMatrix3Zero, CesiumMath.EPSILON7) &&
Cartesian4.equals(Matrix4.getRow(matrix, 3, scratchBottomRow), scratchExpectedBottomRow)) {

result[0] = 0.0;
result[1] = 0.0;
result[2] = 0.0;
result[3] = 0.0;
result[4] = 0.0;
result[5] = 0.0;
result[6] = 0.0;
result[7] = 0.0;
result[8] = 0.0;
result[9] = 0.0;
result[10] = 0.0;
result[11] = 0.0;
result[12] = -matrix[12];
result[13] = -matrix[13];
result[14] = -matrix[14];
result[15] = 1.0;
return result;
}

//
// Ported from:
// ftp://download.intel.com/design/PentiumIII/sml/24504301.pdf
Expand Down Expand Up @@ -2308,7 +2283,31 @@ define([
// calculate determinant
var det = src0 * dst0 + src1 * dst1 + src2 * dst2 + src3 * dst3;

if (Math.abs(det) < CesiumMath.EPSILON20) {
if (Math.abs(det) < CesiumMath.EPSILON21) {
// Special case for a zero scale matrix that can occur, for example,
// when a model's node has a [0, 0, 0] scale.
if (Matrix3.equalsEpsilon(Matrix4.getRotation(matrix, scratchInverseRotation), scratchMatrix3Zero, CesiumMath.EPSILON7) &&
Cartesian4.equals(Matrix4.getRow(matrix, 3, scratchBottomRow), scratchExpectedBottomRow)) {

result[0] = 0.0;
result[1] = 0.0;
result[2] = 0.0;
result[3] = 0.0;
result[4] = 0.0;
result[5] = 0.0;
result[6] = 0.0;
result[7] = 0.0;
result[8] = 0.0;
result[9] = 0.0;
result[10] = 0.0;
result[11] = 0.0;
result[12] = -matrix[12];
result[13] = -matrix[13];
result[14] = -matrix[14];
result[15] = 1.0;
return result;
}

throw new RuntimeError('matrix is not invertible because its determinate is zero.');
}

Expand Down
45 changes: 28 additions & 17 deletions Source/Scene/Cesium3DTilesetTraversal.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ define([
return tile._distanceToCamera;
}
var parent = tile.parent;
var useParentScreenSpaceError = defined(parent) && (!skipLevelOfDetail(tileset) || (tile._screenSpaceError === 0.0));
var useParentScreenSpaceError = defined(parent) && (!skipLevelOfDetail(tileset) || (tile._screenSpaceError === 0.0) || parent.hasTilesetContent);
var screenSpaceError = useParentScreenSpaceError ? parent._screenSpaceError : tile._screenSpaceError;
var rootScreenSpaceError = tileset.root._screenSpaceError;
return rootScreenSpaceError - screenSpaceError; // Map higher SSE to lower values (e.g. root tile is highest priority)
Expand Down Expand Up @@ -298,16 +298,25 @@ define([
return anyVisible;
}

function meetsScreenSpaceErrorEarly(tileset, tile, frameState) {
var parent = tile.parent;
if (!defined(parent) || parent.hasTilesetContent || (parent.refine !== Cesium3DTileRefine.ADD)) {
return false;
}

// Use parent's geometric error with child's box to see if the tile already meet the SSE
var sse = getScreenSpaceError(tileset, parent.geometricError, tile, frameState);
return sse <= tileset._maximumScreenSpaceError;
}

function updateTileVisibility(tileset, tile, frameState) {
updateVisibility(tileset, tile, frameState);

if (!isVisible(tile)) {
return;
}

// Use parent's geometric error with child's box to see if the tile already meet the SSE
var parent = tile.parent;
if (defined(parent) && (parent.refine === Cesium3DTileRefine.ADD) && getScreenSpaceError(tileset, parent.geometricError, tile, frameState) <= tileset._maximumScreenSpaceError) {
if (meetsScreenSpaceErrorEarly(tileset, tile, frameState)) {
tile._visible = false;
return;
}
Expand Down Expand Up @@ -438,6 +447,18 @@ define([
return tile._screenSpaceError > baseScreenSpaceError;
}

function canTraverse(tileset, tile) {
if (tile.children.length === 0) {
return false;
}
if (tile.hasTilesetContent) {
// Traverse external tileset to visit its root tile
// Don't traverse if the subtree is expired because it will be destroyed
return !tile.contentExpired;
}
return tile._screenSpaceError > tileset._maximumScreenSpaceError;
}

function executeTraversal(tileset, root, baseScreenSpaceError, maximumScreenSpaceError, frameState) {
// Depth-first traversal that traverses all visible tiles and marks tiles for selection.
// If skipLevelOfDetail is off then a tile does not refine until all children are loaded.
Expand All @@ -455,19 +476,11 @@ define([
var baseTraversal = inBaseTraversal(tileset, tile, baseScreenSpaceError);
var add = tile.refine === Cesium3DTileRefine.ADD;
var replace = tile.refine === Cesium3DTileRefine.REPLACE;
var children = tile.children;
var childrenLength = children.length;
var parent = tile.parent;
var parentRefines = !defined(parent) || parent._refines;
var traverse = (childrenLength > 0) && (tile._screenSpaceError > maximumScreenSpaceError);
var refines = false;

if (tile.hasTilesetContent && tile.contentExpired) {
// Don't traverse expired subtree because it will be destroyed
traverse = false;
}

if (traverse) {
if (canTraverse(tileset, tile)) {
refines = updateAndPushChildren(tileset, tile, stack, frameState) && parentRefines;
}

Expand Down Expand Up @@ -514,7 +527,6 @@ define([
function executeEmptyTraversal(tileset, root, frameState) {
// Depth-first traversal that checks if all nearest descendants with content are loaded. Ignores visibility.
var allDescendantsLoaded = true;
var maximumScreenSpaceError = tileset._maximumScreenSpaceError;
var stack = emptyTraversal.stack;
stack.push(root);

Expand All @@ -526,7 +538,7 @@ define([
var childrenLength = children.length;

// Only traverse if the tile is empty - traversal stop at descendants with content
var traverse = hasEmptyContent(tile) && (childrenLength > 0) && (tile._screenSpaceError > maximumScreenSpaceError);
var traverse = hasEmptyContent(tile) && canTraverse(tileset, tile);

// Traversal stops but the tile does not have content yet.
// There will be holes if the parent tries to refine to its children, so don't refine.
Expand Down Expand Up @@ -573,7 +585,6 @@ define([
* selected tiles must be no deeper than 15. This is still very unlikely.
*/
function traverseAndSelect(tileset, root, frameState) {
var maximumScreenSpaceError = tileset._maximumScreenSpaceError;
var stack = selectionTraversal.stack;
var ancestorStack = selectionTraversal.ancestorStack;
var lastAncestor;
Expand Down Expand Up @@ -606,7 +617,7 @@ define([
var shouldSelect = tile._shouldSelect;
var children = tile.children;
var childrenLength = children.length;
var traverse = (childrenLength > 0) && (tile._screenSpaceError > maximumScreenSpaceError);
var traverse = canTraverse(tileset, tile);

if (shouldSelect) {
if (add) {
Expand Down
32 changes: 32 additions & 0 deletions Specs/Core/Matrix4Spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -993,6 +993,38 @@ defineSuite([
expect(expected).toEqualEpsilon(result, CesiumMath.EPSILON20);
});

it('inverse behaves acceptably with near single precision zero scale matrix', function() {
var trs = new TranslationRotationScale(new Cartesian3(0.0, 0.0, 0.0),
Quaternion.fromAxisAngle(Cartesian3.UNIT_X, 0.0),
new Cartesian3(1.0e-7, 1.0e-7, 1.1e-7));

var matrix = Matrix4.fromTranslationRotationScale(trs);

var expected = new Matrix4(1e7, 0, 0, 0,
0, 1e7, 0, 0,
0, 0, (1.0/1.1)*1e7, 0,
0, 0, 0, 1);

var result = Matrix4.inverse(matrix, new Matrix4());
expect(expected).toEqualEpsilon(result, CesiumMath.EPSILON15);
});

it('inverse behaves acceptably with single precision zero scale matrix', function() {
var trs = new TranslationRotationScale(new Cartesian3(0.0, 0.0, 0.0),
Quaternion.fromAxisAngle(Cartesian3.UNIT_X, 0.0),
new Cartesian3(1.8e-8, 1.2e-8, 1.2e-8));

var matrix = Matrix4.fromTranslationRotationScale(trs);

var expected = new Matrix4(0, 0, 0, -matrix[12],
0, 0, 0, -matrix[13],
0, 0, 0, -matrix[14],
0, 0, 0, 1);

var result = Matrix4.inverse(matrix, new Matrix4());
expect(expected).toEqualEpsilon(result, CesiumMath.EPSILON20);
});

it('inverseTransformation works', function() {
var matrix = new Matrix4(1, 0, 0, 10,
0, 0, 1, 20,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
88
]
},
"geometricError": 240,
"geometricError": 70,
"refine": "ADD",
"content": {
"uri": "tileset2.json"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
20
]
},
"geometricError": 70,
"geometricError": 0,
"content": {
"uri": "tileset3/tileset3.json"
}
Expand Down
70 changes: 40 additions & 30 deletions Specs/Scene/Cesium3DTilesetSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -854,11 +854,15 @@ defineSuite([
});
});

function findTileByUrl(tiles, url) {
function findTileByUri(tiles, uri) {
var length = tiles.length;
for (var i = 0; i < length; ++i) {
if (tiles[i].content._resource.url.indexOf(url) >= 0) {
return tiles[i];
var tile = tiles[i];
var contentHeader = tile._header.content;
if (defined(contentHeader)) {
if (contentHeader.uri.indexOf(uri) >= 0) {
return tile;
}
}
}
return undefined;
Expand All @@ -877,10 +881,10 @@ defineSuite([
scene.renderForSpecs();

var root = tileset.root;
var llTile = findTileByUrl(root.children, 'll.b3dm');
var lrTile = findTileByUrl(root.children, 'lr.b3dm');
var urTile = findTileByUrl(root.children, 'ur.b3dm');
var ulTile = findTileByUrl(root.children, 'ul.b3dm');
var llTile = findTileByUri(root.children, 'll.b3dm');
var lrTile = findTileByUri(root.children, 'lr.b3dm');
var urTile = findTileByUri(root.children, 'ur.b3dm');
var ulTile = findTileByUri(root.children, 'ul.b3dm');

var selectedTiles = tileset._selectedTiles;
expect(selectedTiles[0]).toBe(root);
Expand Down Expand Up @@ -1079,8 +1083,7 @@ defineSuite([
//
return Cesium3DTilesTester.loadTileset(scene, tilesetReplacement1Url).then(function(tileset) {
tileset.root.geometricError = 90;
viewRootOnly();
scene.camera.zoomIn(20);
setZoom(80);
scene.renderForSpecs();

var statistics = tileset._statistics;
Expand Down Expand Up @@ -1364,6 +1367,15 @@ defineSuite([
});
});

it('always visits external tileset root', function() {
viewRootOnly();
return Cesium3DTilesTester.loadTileset(scene, tilesetOfTilesetsUrl).then(function(tileset) {
var statistics = tileset._statistics;
expect(statistics.visited).toEqual(2); // Visits external tileset tile, and external tileset root
expect(statistics.numberOfCommands).toEqual(1); // Renders external tileset root
});
});

it('set tile color', function() {
return Cesium3DTilesTester.loadTileset(scene, noBatchIdsUrl).then(function(tileset) {
// Get initial color
Expand Down Expand Up @@ -2765,29 +2777,27 @@ defineSuite([
});

it('immediatelyLoadDesiredLevelOfDetail', function() {
viewBottomLeft();
var tileset = scene.primitives.add(new Cesium3DTileset({
url : tilesetOfTilesetsUrl,
viewNothing();
return Cesium3DTilesTester.loadTileset(scene, tilesetUrl, {
immediatelyLoadDesiredLevelOfDetail : true
}));
return Cesium3DTilesTester.waitForReady(scene, tileset).then(function(tileset) {
scene.renderForSpecs();
return tileset.root.contentReadyPromise.then(function() {
tileset.root.refine = Cesium3DTileRefine.REPLACE;
tileset.root.children[0].refine = Cesium3DTileRefine.REPLACE;
tileset._allTilesAdditive = false;
}).then(function(tileset) {
var root = tileset.root;
var child = findTileByUri(root.children, 'll.b3dm');
tileset.root.refine = Cesium3DTileRefine.REPLACE;
tileset._allTilesAdditive = false;
viewBottomLeft();
return Cesium3DTilesTester.waitForTilesLoaded(scene, tileset).then(function(tileset) {
expect(isSelected(tileset, child));
expect(!isSelected(tileset, root));
expect(root.contentUnloaded).toBe(true);
// Renders child while parent loads
viewRootOnly();
scene.renderForSpecs();
expect(isSelected(tileset, child));
expect(!isSelected(tileset, root));
return Cesium3DTilesTester.waitForTilesLoaded(scene, tileset).then(function(tileset) {
var statistics = tileset._statistics;
expect(statistics.numberOfTilesWithContentReady).toBe(1);
// Renders child while parent loads
viewRootOnly();
scene.renderForSpecs();
expect(isSelected(tileset, tileset.root.children[0]));
expect(!isSelected(tileset, tileset.root));
return Cesium3DTilesTester.waitForTilesLoaded(scene, tileset).then(function(tileset) {
expect(!isSelected(tileset, tileset.root.children[0]));
expect(isSelected(tileset, tileset.root));
});
expect(!isSelected(tileset, child));
expect(isSelected(tileset, root));
});
});
});
Expand Down

0 comments on commit d726c4f

Please sign in to comment.