Skip to content

Commit

Permalink
Apply tile transform before exaggerating bounding volumes
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeshurun Hembd committed Nov 30, 2023
1 parent 1f60eee commit 55d6dfa
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 63 deletions.
156 changes: 94 additions & 62 deletions packages/engine/Source/Scene/Cesium3DTile.js
Original file line number Diff line number Diff line change
Expand Up @@ -1715,6 +1715,16 @@ function createRegion(region, transform, initialTransform, result) {

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

if (defined(result)) {
result.rectangle = rectangleRegion;
result.minimumHeight = region[4];
result.maximumHeight = region[5];
// The TileBoundingRegion was already constructed with the default
// WGS84 ellipsoid, so keep it consistent when updating.
result.computeBoundingVolumes(Ellipsoid.WGS84);
return result;
}

return new TileBoundingRegion({
rectangle: rectangleRegion,
minimumHeight: region[4],
Expand Down Expand Up @@ -1751,10 +1761,6 @@ function createSphere(sphere, transform, result) {
return new TileBoundingSphere(center, radius);
}

const scratchBoundingSphere = new BoundingSphere();
const scratchExaggeratedBox = new Array(OrientedBoundingBox.packedLength);
const scratchExaggeratedSphere = new Array(BoundingSphere.packedLength);

/**
* Create a bounding volume from the tile's bounding volume header.
*
Expand Down Expand Up @@ -1797,80 +1803,106 @@ Cesium3DTile.prototype.createBoundingVolume = function (

const { box, region, sphere } = boundingVolumeHeader;
if (defined(box)) {
if (this._verticalExaggeration === 1.0) {
return createBox(box, transform, result);
}
const exaggeratedCorners = OrientedBoundingBox.unpack(
box,
0,
scratchOrientedBoundingBox
)
.computeCorners()
.map((corner) =>
VerticalExaggeration.getPosition(
corner,
Ellipsoid.WGS84,
this._verticalExaggeration,
this._verticalExaggerationRelativeHeight,
corner
)
const tileOrientedBoundingBox = createBox(box, transform, result);
if (this._verticalExaggeration !== 1.0) {
exaggerateBoundingBox(
tileOrientedBoundingBox,
this._verticalExaggeration,
this._verticalExaggerationRelativeHeight
);
const exaggeratedBox = OrientedBoundingBox.pack(
OrientedBoundingBox.fromPoints(
exaggeratedCorners,
scratchOrientedBoundingBox
),
scratchExaggeratedBox
);
return createBox(exaggeratedBox, transform, result);
}
return tileOrientedBoundingBox;
}
if (defined(region)) {
const exaggeratedRegion = region.slice();
exaggeratedRegion[4] = VerticalExaggeration.getHeight(
exaggeratedRegion[4],
this._verticalExaggeration,
this._verticalExaggerationRelativeHeight
);
exaggeratedRegion[5] = VerticalExaggeration.getHeight(
exaggeratedRegion[5],
this._verticalExaggeration,
this._verticalExaggerationRelativeHeight
);
return createRegion(
exaggeratedRegion,
const tileBoundingVolume = createRegion(
region,
transform,
this._initialTransform,
result
);
if (this._verticalExaggeration === 1.0) {
return tileBoundingVolume;
}
if (tileBoundingVolume instanceof TileOrientedBoundingBox) {
exaggerateBoundingBox(
tileBoundingVolume,
this._verticalExaggeration,
this._verticalExaggerationRelativeHeight
);
} else {
tileBoundingVolume.minimumHeight = VerticalExaggeration.getHeight(
tileBoundingVolume.minimumHeight,
this._verticalExaggeration,
this._verticalExaggerationRelativeHeight
);
tileBoundingVolume.maximumHeight = VerticalExaggeration.getHeight(
tileBoundingVolume.maximumHeight,
this._verticalExaggeration,
this._verticalExaggerationRelativeHeight
);
tileBoundingVolume.computeBoundingVolumes(Ellipsoid.WGS84);
}
return tileBoundingVolume;
}
if (defined(sphere)) {
if (this._verticalExaggeration === 1.0) {
return createSphere(sphere, transform, result);
const tileBoundingSphere = createSphere(sphere, transform, result);
if (this._verticalExaggeration !== 1.0) {
const exaggeratedCenter = VerticalExaggeration.getPosition(
tileBoundingSphere.center,
Ellipsoid.WGS84,
this._verticalExaggeration,
this._verticalExaggerationRelativeHeight,
scratchCenter
);
const exaggeratedRadius =
tileBoundingSphere.radius * this._verticalExaggeration;
tileBoundingSphere.update(exaggeratedCenter, exaggeratedRadius);
}
const boundingSphere = BoundingSphere.unpack(
sphere,
0,
scratchBoundingSphere
);
boundingSphere.center = VerticalExaggeration.getPosition(
boundingSphere.center,
Ellipsoid.WGS84,
this._verticalExaggeration,
this._verticalExaggerationRelativeHeight,
boundingSphere.center
);
boundingSphere.radius *= this._verticalExaggeration;
const exaggeratedSphere = BoundingSphere.pack(
boundingSphere,
scratchExaggeratedSphere
);
return createSphere(exaggeratedSphere, transform, result);
return tileBoundingSphere;
}
throw new RuntimeError(
"boundingVolume must contain a sphere, region, or box"
);
};

const scratchExaggeratedCorners = Cartesian3.unpackArray(
new Array(8 * 3).fill(0)
);

/**
* Exaggerates the bounding box of a tile based on the provided exaggeration factors.
*
* @private
* @param {TileOrientedBoundingBox} tileOrientedBoundingBox - The oriented bounding box of the tile.
* @param {number} exaggeration - The exaggeration factor to apply to the tile's bounding box.
* @param {number} exaggerationRelativeHeight - The height relative to which exaggeration will be applied.
*/
function exaggerateBoundingBox(
tileOrientedBoundingBox,
exaggeration,
exaggerationRelativeHeight
) {
const exaggeratedCorners = tileOrientedBoundingBox.boundingVolume
.computeCorners(scratchExaggeratedCorners)
.map((corner) =>
VerticalExaggeration.getPosition(
corner,
Ellipsoid.WGS84,
exaggeration,
exaggerationRelativeHeight,
corner
)
);
const exaggeratedBox = OrientedBoundingBox.fromPoints(
exaggeratedCorners,
scratchOrientedBoundingBox
);
tileOrientedBoundingBox.update(
exaggeratedBox.center,
exaggeratedBox.halfAxes
);
}

/**
* Update the tile's transform. The transform is applied to the tile's bounding volumes.
*
Expand Down
2 changes: 1 addition & 1 deletion packages/engine/Source/Scene/TileOrientedBoundingBox.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ Object.defineProperties(TileOrientedBoundingBox.prototype, {
*
* @memberof TileOrientedBoundingBox.prototype
*
* @type {object}
* @type {OrientedBoundingBox}
* @readonly
*/
boundingVolume: {
Expand Down

0 comments on commit 55d6dfa

Please sign in to comment.