Skip to content

Commit

Permalink
Merge pull request #6755 from AnalyticalGraphicsInc/transform-region
Browse files Browse the repository at this point in the history
Apply transform to "region" bounding volume type
  • Loading branch information
ggetz authored Jul 11, 2018
2 parents 69b3e9d + 6872b2d commit 122d3e7
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Change Log
#### Fixes :wrench:
* Fixed bug causing billboards and labels to appear the wrong size when switching scene modes [#6745](https://github.com/AnalyticalGraphicsInc/cesium/issues/6745)
* Fixed a bug that was preventing 3D Tilesets on the opposite side of the globe from being occluded [#6714](https://github.com/AnalyticalGraphicsInc/cesium/issues/6714)
* Fixed a bug where 3D Tilesets using the `region` bounding volume don't get transformed when the tileset's `modelMatrix` changes. [6755](https://github.com/AnalyticalGraphicsInc/cesium/pull/6755)

### 1.47 - 2018-07-02

Expand Down
56 changes: 47 additions & 9 deletions Source/Scene/Cesium3DTile.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@ define([
'../Core/defineProperties',
'../Core/deprecationWarning',
'../Core/destroyObject',
'../Core/Ellipsoid',
'../Core/getMagic',
'../Core/Intersect',
'../Core/JulianDate',
'../Core/Math',
'../Core/Matrix3',
'../Core/Matrix4',
'../Core/OrientedBoundingBox',
'../Core/Rectangle',
'../Core/Request',
'../Core/RequestScheduler',
Expand Down Expand Up @@ -41,11 +44,14 @@ define([
defineProperties,
deprecationWarning,
destroyObject,
Ellipsoid,
getMagic,
Intersect,
JulianDate,
CesiumMath,
Matrix3,
Matrix4,
OrientedBoundingBox,
Rectangle,
Request,
RequestScheduler,
Expand Down Expand Up @@ -90,6 +96,9 @@ define([
var parentTransform = defined(parent) ? parent.computedTransform : tileset.modelMatrix;
var computedTransform = Matrix4.multiply(parentTransform, this.transform, new Matrix4());

var parentInitialTransform = defined(parent) ? parent._initialTransform : Matrix4.IDENTITY;
this._initialTransform = Matrix4.multiply(parentInitialTransform, this.transform, new Matrix4());

/**
* The final computed transform of this tile
* @type {Matrix4}
Expand Down Expand Up @@ -882,6 +891,8 @@ define([
var scratchHalfAxes = new Matrix3();
var scratchCenter = new Cartesian3();
var scratchRectangle = new Rectangle();
var scratchOrientedBoundingBox = new OrientedBoundingBox();
var scratchTransform = new Matrix4();

function createBox(box, transform, result) {
var center = Cartesian3.fromElements(box[0], box[1], box[2], scratchCenter);
Expand All @@ -899,13 +910,42 @@ define([
return new TileOrientedBoundingBox(center, halfAxes);
}

function createRegion(region, result) {
var rectangleRegion = Rectangle.unpack(region, 0, scratchRectangle);
function createBoxFromTransformedRegion(region, transform, initialTransform, result) {
var rectangle = Rectangle.unpack(region, 0, scratchRectangle);
var minimumHeight = region[4];
var maximumHeight = region[5];

var orientedBoundingBox = OrientedBoundingBox.fromRectangle(rectangle, minimumHeight, maximumHeight, Ellipsoid.WGS84, scratchOrientedBoundingBox);
var center = orientedBoundingBox.center;
var halfAxes = orientedBoundingBox.halfAxes;

// A region bounding volume is not transformed by the transform in the tileset JSON,
// but may be transformed by additional transforms applied in Cesium.
// This is why the transform is calculated as the difference between the initial transform and the current transform.
transform = Matrix4.multiplyTransformation(transform, Matrix4.inverseTransformation(initialTransform, scratchTransform), scratchTransform);
center = Matrix4.multiplyByPoint(transform, center, center);
var rotationScale = Matrix4.getRotation(transform, scratchMatrix);
halfAxes = Matrix3.multiply(rotationScale, halfAxes, halfAxes);

if (defined(result) && (result instanceof TileOrientedBoundingBox)) {
result.update(center, halfAxes);
return result;
}

return new TileOrientedBoundingBox(center, halfAxes);
}

function createRegion(region, transform, initialTransform, result) {
if (!Matrix4.equalsEpsilon(transform, initialTransform, CesiumMath.EPSILON8)) {
return createBoxFromTransformedRegion(region, transform, initialTransform, result);
}

if (defined(result)) {
// Don't update regions when the transform changes
return result;
}

var rectangleRegion = Rectangle.unpack(region, 0, scratchRectangle);

return new TileBoundingRegion({
rectangle : rectangleRegion,
minimumHeight : region[4],
Expand Down Expand Up @@ -949,16 +989,14 @@ define([
return createBox(boundingVolumeHeader.box, transform, result);
}
if (defined(boundingVolumeHeader.region)) {
return createRegion(boundingVolumeHeader.region, result);
return createRegion(boundingVolumeHeader.region, transform, this._initialTransform, result);
}
if (defined(boundingVolumeHeader.sphere)) {
return createSphere(boundingVolumeHeader.sphere, transform, result);
}
throw new RuntimeError('boundingVolume must contain a sphere, region, or box');
};

var scratchTransform = new Matrix4();

/**
* Update the tile's transform. The transform is applied to the tile's bounding volumes.
*
Expand All @@ -978,12 +1016,12 @@ define([
// Update the bounding volumes
var header = this._header;
var content = this._header.content;
this._boundingVolume = this.createBoundingVolume(header.boundingVolume, computedTransform, this._boundingVolume);
this._boundingVolume = this.createBoundingVolume(header.boundingVolume, this.computedTransform, this._boundingVolume);
if (defined(this._contentBoundingVolume)) {
this._contentBoundingVolume = this.createBoundingVolume(content.boundingVolume, computedTransform, this._contentBoundingVolume);
this._contentBoundingVolume = this.createBoundingVolume(content.boundingVolume, this.computedTransform, this._contentBoundingVolume);
}
if (defined(this._viewerRequestVolume)) {
this._viewerRequestVolume = this.createBoundingVolume(header.viewerRequestVolume, computedTransform, this._viewerRequestVolume);
this._viewerRequestVolume = this.createBoundingVolume(header.viewerRequestVolume, this.computedTransform, this._viewerRequestVolume);
}

// Destroy the debug bounding volumes. They will be generated fresh.
Expand Down
5 changes: 2 additions & 3 deletions Specs/Scene/Batched3DModel3DTileContentSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,7 @@ defineSuite([
});

it('renders with a tile transform and region bounding volume', function() {
return Cesium3DTilesTester.loadTileset(scene, withTransformRegionUrl).then(function(tileset) {
Cesium3DTilesTester.expectRenderTileset(scene, tileset);
});
return expectRenderWithTransform(withTransformRegionUrl);
});

it('picks with batch table', function() {
Expand Down Expand Up @@ -392,6 +390,7 @@ defineSuite([
var newHPR = new HeadingPitchRoll();
var newTransform = Transforms.headingPitchRollToFixedFrame(newCenter, newHPR);
tileset._root.transform = newTransform;
scene.camera.lookAt(newCenter, new HeadingPitchRange(0.0, 0.0, 15.0));
scene.renderForSpecs();

expectedModelTransform = Matrix4.multiply(tileset._root.computedTransform, rtcTransform, expectedModelTransform);
Expand Down

0 comments on commit 122d3e7

Please sign in to comment.