Skip to content

Commit

Permalink
Add dito.ts for bounding volume computations
Browse files Browse the repository at this point in the history
  • Loading branch information
javagl committed Nov 7, 2023
1 parent a4cdad7 commit ab27a46
Show file tree
Hide file tree
Showing 8 changed files with 1,027 additions and 21 deletions.
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ specs/data/
tsconfig.json
.prettierrc.json
ThirdParty.json
ThirdParty.extra.json
src/ktx/external/basis_encoder.js
8 changes: 8 additions & 0 deletions ThirdParty.extra.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[
{
"name": "dito.ts",
"license": ["BSD-2-Clause"],
"url": "https://github.com/Esri/dito.ts",
"notes": "Commit a7cfa662d1a6d6f0f387deaa1fb9d8edb6f298bc"
}
]
1 change: 0 additions & 1 deletion specs/tilesetProcessing/TilesetJsonCreatorSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,5 +150,4 @@ describe("TilesetJsonCreator", function () {
.toString();
expect(outputJsonString).toEqual(goldenJsonString);
});

});
30 changes: 15 additions & 15 deletions src/tilesetProcessing/BoundingVolumes.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { Cartesian3, Ellipsoid, Matrix4, Rectangle } from "cesium";
import { Ellipsoid } from "cesium";
import { Matrix4 } from "cesium";
import { Cartesian3 } from "cesium";
import { Rectangle } from "cesium";
import { Matrix3 } from "cesium";
import { OrientedBoundingBox } from "cesium";

import { BoundingVolume } from "../structure/BoundingVolume";

import { OrientedBoundingBoxes } from "./OrientedBoundingBoxes";

/**
* Utility methods for bounding volume computations.
*
Expand All @@ -24,19 +30,13 @@ export class BoundingVolumes {
}

/**
* Compute a tightly-fitting bounding volume box for the given points
* Compute a bounding volume box for the given points.
*
* @param points - The points, as 3-element arrays
* @returns The bounding volume box
*/
static createBoundingVolumeBoxFromPoints(points: number[][]) {
const positions = points.map(
(p: number[]) => new Cartesian3(p[0], p[1], p[2])
);
const obb = OrientedBoundingBox.fromPoints(positions);
const result = Array<number>(12);
OrientedBoundingBox.pack(obb, result, 0);
return result;
return OrientedBoundingBoxes.fromPoints(points);
}

/**
Expand Down Expand Up @@ -72,6 +72,7 @@ export class BoundingVolumes {

/**
* Creates a bounding volume box from the given minimum and maximum point
* of an axis-aligned bounding box.
*
* @param min - The minimum, as a 3-element array
* @param max - The minimum, as a 3-element array
Expand All @@ -94,7 +95,8 @@ export class BoundingVolumes {
* This is the center- and half-axis representation of the
* `boundingVolume.box` that is described at
* https://github.com/CesiumGS/3d-tiles/tree/main/specification#box,
* computed from the minimum- and maximum point of a box.
* computed from the minimum- and maximum point of an axis-aligned
* bounding box.
*
* @param minX - The minimum x
* @param minY - The minimum y
Expand Down Expand Up @@ -194,7 +196,7 @@ export class BoundingVolumes {
* @returns The bounding volume box
*/
static computeBoundingVolumeBoxFromBoundingVolume(
boundingVolume: BoundingVolume,
boundingVolume: BoundingVolume
): number[] | undefined {
if (boundingVolume.box) {
return boundingVolume.box.slice();
Expand All @@ -206,7 +208,7 @@ export class BoundingVolumes {
}
if (boundingVolume.sphere) {
return BoundingVolumes.computeBoundingVolumeBoxFromSphere(
boundingVolume.sphere,
boundingVolume.sphere
);
}
return undefined;
Expand Down Expand Up @@ -238,9 +240,7 @@ export class BoundingVolumes {
* @param sphere - The sphere, as a 4-element array (center+radius)
* @returns - The bounding volume box
*/
private static computeBoundingVolumeBoxFromSphere(
sphere: number[]
) {
private static computeBoundingVolumeBoxFromSphere(sphere: number[]) {
const center = Cartesian3.unpack(sphere);
const radius = sphere[3];
const result = [
Expand Down
81 changes: 81 additions & 0 deletions src/tilesetProcessing/OrientedBoundingBoxes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { Quaternion } from "cesium";
import { Matrix4 } from "cesium";
import { Cartesian3 } from "cesium";
import { OrientedBoundingBox } from "cesium";

import { computeOBB } from "./external/dito";
import { Obb } from "./external/dito";

/**
* Methods for computing oriented bounding boxes.
*
* @internal
*/
export class OrientedBoundingBoxes {
/**
* Compute a bounding volume box for the given points.
*
* This will return the 12-element array that can be used
* as the `boundingVolume.box` in a tileset JSON.
*
* @param points - The points, as 3-element arrays
* @returns The bounding volume box
*/
static fromPoints(points: number[][]): number[] {
//return OrientedBoundingBoxes.fromPointsCesium(points);
return OrientedBoundingBoxes.fromPointsDitoTs(points);
}

/**
* Implementation of 'fromPoints' based on CesiumJS
*
* @param points - The points, as 3-element arrays
* @returns The bounding volume box
*/
static fromPointsCesium(points: number[][]): number[] {
const positions = points.map(
(p: number[]) => new Cartesian3(p[0], p[1], p[2])
);
const obb = OrientedBoundingBox.fromPoints(positions, undefined);
const result = Array<number>(12);
OrientedBoundingBox.pack(obb, result, 0);
return result;
}

/**
* Implementation of 'fromPoints' based on dito.ts
*
* @param points - The points, as 3-element arrays
* @returns The bounding volume box
*/
static fromPointsDitoTs(points: number[][]): number[] {
const attribute = {
data: points.flat(),
size: 3,
offsetIdx: 0,
strideIdx: 3,
};
const obb: Obb = {
center: new Float64Array(3),
halfSize: new Float32Array(3),
quaternion: new Float32Array(4),
};
computeOBB(attribute, obb);

const translation = Cartesian3.unpack([...obb.center]);
const rotation = Quaternion.unpack([...obb.quaternion]);
const scale = Cartesian3.unpack(
[...obb.halfSize].map((v: number) => v * 2)
);
const matrix = Matrix4.fromTranslationQuaternionRotationScale(
translation,
rotation,
scale,
new Matrix4()
);
const cesiumObb = OrientedBoundingBox.fromTransformation(matrix, undefined);
const result = Array<number>(12);
OrientedBoundingBox.pack(cesiumObb, result, 0);
return result;
}
}
10 changes: 5 additions & 5 deletions src/tilesetProcessing/TilesetJsonCreator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ export class TilesetJsonCreator {
* If the tile does not have children, then this will return
* a bounding volume box that is created from the bounding
* volume of the given tile.
*
*
* Otherwise, it will compute the bounding volumes of the
* children, transform each of them with the child transform,
* and return the union of these transformed child bounding
Expand All @@ -176,12 +176,12 @@ export class TilesetJsonCreator {

/**
* Compute the bounding box for a tile with the given children.
*
* This will compute the bounding volumes of the children,
* transform each of them with the child transform, and
*
* This will compute the bounding volumes of the children,
* transform each of them with the child transform, and
* return the union of these transformed child bounding
* volumes.
*
*
* @param children - The children
* @returns The bounding volume box
*/
Expand Down
36 changes: 36 additions & 0 deletions src/tilesetProcessing/external/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
The file 'dito.ts' is taken from https://github.com/Esri/dito.ts

Commit a7cfa662d1a6d6f0f387deaa1fb9d8edb6f298bc (with minor changes to prevent type errors)

Original license statement:

---

This project is distributed under the following BSD license:

Copyright 2018 Stefan Eilemann.
Copyright 2011 Thomas Larsson and Linus Kallberg (C++ implementation).
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this list of
conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice, this list
of conditions and the following disclaimer in the documentation and/or other materials
provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THOMAS LARSSON AND LINUS KALLBERG ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THOMAS LARSSON, LINUS
KALLBERG, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

---

Loading

0 comments on commit ab27a46

Please sign in to comment.