Skip to content

Commit 122d3e7

Browse files
authored
Merge pull request #6755 from AnalyticalGraphicsInc/transform-region
Apply transform to "region" bounding volume type
2 parents 69b3e9d + 6872b2d commit 122d3e7

File tree

3 files changed

+50
-12
lines changed

3 files changed

+50
-12
lines changed

CHANGES.md

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Change Log
1313
#### Fixes :wrench:
1414
* Fixed bug causing billboards and labels to appear the wrong size when switching scene modes [#6745](https://github.com/AnalyticalGraphicsInc/cesium/issues/6745)
1515
* 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)
16+
* 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)
1617

1718
### 1.47 - 2018-07-02
1819

Source/Scene/Cesium3DTile.js

+47-9
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@ define([
88
'../Core/defineProperties',
99
'../Core/deprecationWarning',
1010
'../Core/destroyObject',
11+
'../Core/Ellipsoid',
1112
'../Core/getMagic',
1213
'../Core/Intersect',
1314
'../Core/JulianDate',
15+
'../Core/Math',
1416
'../Core/Matrix3',
1517
'../Core/Matrix4',
18+
'../Core/OrientedBoundingBox',
1619
'../Core/Rectangle',
1720
'../Core/Request',
1821
'../Core/RequestScheduler',
@@ -41,11 +44,14 @@ define([
4144
defineProperties,
4245
deprecationWarning,
4346
destroyObject,
47+
Ellipsoid,
4448
getMagic,
4549
Intersect,
4650
JulianDate,
51+
CesiumMath,
4752
Matrix3,
4853
Matrix4,
54+
OrientedBoundingBox,
4955
Rectangle,
5056
Request,
5157
RequestScheduler,
@@ -90,6 +96,9 @@ define([
9096
var parentTransform = defined(parent) ? parent.computedTransform : tileset.modelMatrix;
9197
var computedTransform = Matrix4.multiply(parentTransform, this.transform, new Matrix4());
9298

99+
var parentInitialTransform = defined(parent) ? parent._initialTransform : Matrix4.IDENTITY;
100+
this._initialTransform = Matrix4.multiply(parentInitialTransform, this.transform, new Matrix4());
101+
93102
/**
94103
* The final computed transform of this tile
95104
* @type {Matrix4}
@@ -882,6 +891,8 @@ define([
882891
var scratchHalfAxes = new Matrix3();
883892
var scratchCenter = new Cartesian3();
884893
var scratchRectangle = new Rectangle();
894+
var scratchOrientedBoundingBox = new OrientedBoundingBox();
895+
var scratchTransform = new Matrix4();
885896

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

902-
function createRegion(region, result) {
903-
var rectangleRegion = Rectangle.unpack(region, 0, scratchRectangle);
913+
function createBoxFromTransformedRegion(region, transform, initialTransform, result) {
914+
var rectangle = Rectangle.unpack(region, 0, scratchRectangle);
915+
var minimumHeight = region[4];
916+
var maximumHeight = region[5];
917+
918+
var orientedBoundingBox = OrientedBoundingBox.fromRectangle(rectangle, minimumHeight, maximumHeight, Ellipsoid.WGS84, scratchOrientedBoundingBox);
919+
var center = orientedBoundingBox.center;
920+
var halfAxes = orientedBoundingBox.halfAxes;
921+
922+
// A region bounding volume is not transformed by the transform in the tileset JSON,
923+
// but may be transformed by additional transforms applied in Cesium.
924+
// This is why the transform is calculated as the difference between the initial transform and the current transform.
925+
transform = Matrix4.multiplyTransformation(transform, Matrix4.inverseTransformation(initialTransform, scratchTransform), scratchTransform);
926+
center = Matrix4.multiplyByPoint(transform, center, center);
927+
var rotationScale = Matrix4.getRotation(transform, scratchMatrix);
928+
halfAxes = Matrix3.multiply(rotationScale, halfAxes, halfAxes);
929+
930+
if (defined(result) && (result instanceof TileOrientedBoundingBox)) {
931+
result.update(center, halfAxes);
932+
return result;
933+
}
934+
935+
return new TileOrientedBoundingBox(center, halfAxes);
936+
}
937+
938+
function createRegion(region, transform, initialTransform, result) {
939+
if (!Matrix4.equalsEpsilon(transform, initialTransform, CesiumMath.EPSILON8)) {
940+
return createBoxFromTransformedRegion(region, transform, initialTransform, result);
941+
}
904942

905943
if (defined(result)) {
906-
// Don't update regions when the transform changes
907944
return result;
908945
}
946+
947+
var rectangleRegion = Rectangle.unpack(region, 0, scratchRectangle);
948+
909949
return new TileBoundingRegion({
910950
rectangle : rectangleRegion,
911951
minimumHeight : region[4],
@@ -949,16 +989,14 @@ define([
949989
return createBox(boundingVolumeHeader.box, transform, result);
950990
}
951991
if (defined(boundingVolumeHeader.region)) {
952-
return createRegion(boundingVolumeHeader.region, result);
992+
return createRegion(boundingVolumeHeader.region, transform, this._initialTransform, result);
953993
}
954994
if (defined(boundingVolumeHeader.sphere)) {
955995
return createSphere(boundingVolumeHeader.sphere, transform, result);
956996
}
957997
throw new RuntimeError('boundingVolume must contain a sphere, region, or box');
958998
};
959999

960-
var scratchTransform = new Matrix4();
961-
9621000
/**
9631001
* Update the tile's transform. The transform is applied to the tile's bounding volumes.
9641002
*
@@ -978,12 +1016,12 @@ define([
9781016
// Update the bounding volumes
9791017
var header = this._header;
9801018
var content = this._header.content;
981-
this._boundingVolume = this.createBoundingVolume(header.boundingVolume, computedTransform, this._boundingVolume);
1019+
this._boundingVolume = this.createBoundingVolume(header.boundingVolume, this.computedTransform, this._boundingVolume);
9821020
if (defined(this._contentBoundingVolume)) {
983-
this._contentBoundingVolume = this.createBoundingVolume(content.boundingVolume, computedTransform, this._contentBoundingVolume);
1021+
this._contentBoundingVolume = this.createBoundingVolume(content.boundingVolume, this.computedTransform, this._contentBoundingVolume);
9841022
}
9851023
if (defined(this._viewerRequestVolume)) {
986-
this._viewerRequestVolume = this.createBoundingVolume(header.viewerRequestVolume, computedTransform, this._viewerRequestVolume);
1024+
this._viewerRequestVolume = this.createBoundingVolume(header.viewerRequestVolume, this.computedTransform, this._viewerRequestVolume);
9871025
}
9881026

9891027
// Destroy the debug bounding volumes. They will be generated fresh.

Specs/Scene/Batched3DModel3DTileContentSpec.js

+2-3
Original file line numberDiff line numberDiff line change
@@ -202,9 +202,7 @@ defineSuite([
202202
});
203203

204204
it('renders with a tile transform and region bounding volume', function() {
205-
return Cesium3DTilesTester.loadTileset(scene, withTransformRegionUrl).then(function(tileset) {
206-
Cesium3DTilesTester.expectRenderTileset(scene, tileset);
207-
});
205+
return expectRenderWithTransform(withTransformRegionUrl);
208206
});
209207

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

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

0 commit comments

Comments
 (0)