Open sophia-xll opened 5 years ago
By the way, I have tried children:box of tileset.json not equal to T0T1B1.
It is not entirely clear what you compared here.
These are the input files:
tileset.json
{
"asset": { "version": "1.0" },
"geometricError": 1319.96566351801,
"root": {
"boundingVolume": {
"box": [
1.04773789644241e-9, -0.504322739783674, -0.616247923113406,
5641.31597575976, 0, 0,
0, 6311.33777747117, 0,
0, 0, 25.8459681412205
]
},
"children": [
{
"boundingVolume": {
"box": [
2797.89169446776, -3133.07355675142, 12.5403080463512,
2843.42428129305, 0, 0, 0, 3180.84259900837, 0, 0, 0,
15.1854221645246
]
},
"content": { "url": "tileset_1_1_0.json" },
"geometricError": 164.995707939751,
"refine": "REPLACE"
}
],
"geometricError": 329.991415879503,
"refine": "REPLACE",
"transform": [
-0.895897517499185, -0.444260777177997, 0, 0, 0.283927872032897,
-0.572569735547873, 0.769122136866122, 0, -0.341690798268945,
0.689054613072027, 0.639101821764334, 0, -2176357.29229105,
4388848.16197401, 4070680.03399528, 1
]
}
}
and tileset_1_1_0.json
{
"asset": { "version": "1.0" },
"root": {
"boundingVolume": {
"box": [
2.3283064365387e-10, -0.113443724578246, 3.57330994307995,
2843.42474428168, 0, 0,
0, 3179.80389127671, 0,
0, 0, 15.5025072079152
]
},
"children": [],
"content": { "url": "1/1/0.b3dm" },
"geometricError": 164.995707939751,
"refine": "REPLACE",
"transform": [
0.999999837172188, 0.00036471139259886, -0.000438909100338114, 0,
-0.000364495423816037, 0.999999812521052, 0.000492037546955482, 0,
0.000439088469750899, -0.000491877486479553, 0.999999782628903, 0,
2796.72426339705, -3132.95792494155, 8.96653714217246, 1
]
}
}
They can be loaded with the following sandcastle:
// Create a viewer, add the tileset, and zoom to the tileset
const viewer = new Cesium.Viewer("cesiumContainer");
const tileset = viewer.scene.primitives.add(
new Cesium.Cesium3DTileset({
url: "http://localhost:8003/tileset.json",
debugShowBoundingVolume: true,
maximumScreenSpaceError: 1.0,
})
);
const offset = new Cesium.HeadingPitchRange(
0,
Cesium.Math.toRadians(-67.5),
40000.0
);
viewer.zoomTo(tileset, offset);
/**
* Creates an OrientedBoundingBox from an array of numbers, as
* it is given in the tileset JSON input
*
* @param {Number[]} box The array
* @returns The OrientedBoundingBox
*/
function createOrientedBoundingBox(box) {
const center = Cesium.Cartesian3.fromElements(
box[0],
box[1],
box[2],
new Cesium.Cartesian3()
);
const halfAxes = Cesium.Matrix3.fromArray(box, 3, new Cesium.Matrix3());
return new Cesium.OrientedBoundingBox(center, halfAxes);
}
/**
* Transforms the given oriented bounding box with the given
* transform, and returns the result
*
* @param {OrientedBoundingBox} obb The oriented bounding box
* @param {Matrix4} transform The transform
* @returns The transformed oriented bounding box
*/
function transformOrientedBoundingBox(obb, transform) {
const center = Cesium.Matrix4.multiplyByPoint(
transform,
obb.center,
new Cesium.Cartesian3()
);
const rotationScale = Cesium.Matrix4.getMatrix3(
transform,
new Cesium.Matrix3()
);
const halfAxes = Cesium.Matrix3.multiply(
rotationScale,
obb.halfAxes,
new Cesium.Matrix3()
);
return new Cesium.OrientedBoundingBox(center, halfAxes);
}
// After all tiles have been loaded, print some bounding volume information:
tileset.allTilesLoaded.addEventListener(function () {
// NOTE: The following lines make MANY assumptions about the
// structure of the tileset, and are tailored SPECIFICALLY
// for this example:
const transform0 = tileset.root.transform;
const externalRoot = tileset.root.children[0].content.tile.children[0];
const transform1 = externalRoot.transform;
const externalRootBox = externalRoot.boundingVolume.boundingVolume;
// Compute the product of the root transform, and of the
// root transform of the external tileset
const T0 = Cesium.Matrix4.fromArray(transform0, 0, new Cesium.Matrix4());
const T1 = Cesium.Matrix4.fromArray(transform1, 0, new Cesium.Matrix4());
const P = Cesium.Matrix4.multiply(T0, T1, new Cesium.Matrix4());
// Create an oriented bounding box from the original input
// in the (external) tileset JSON file
const boxFromInputJson = [
2.3283064365387e-10, -0.113443724578246, 3.57330994307995, 2843.42474428168,
0, 0, 0, 3179.80389127671, 0, 0, 0, 15.5025072079152,
];
const originalChildBox = createOrientedBoundingBox(boxFromInputJson);
// Print a comparison of
// - the original bounding box of the external tileset
// - the result of transforming this bounding box with T0*t1
// - the bounding box of the external tileset root,
// as it was loaded with CesiumJS
console.log("originalChildBox:");
console.log(" center " + originalChildBox.center);
console.log(" halfAxes " + originalChildBox.halfAxes);
const transformed = transformOrientedBoundingBox(originalChildBox, P);
console.log("transformed:");
console.log(" center " + transformed.center);
console.log(" halfAxes " + transformed.halfAxes);
console.log("externalRootBox:");
console.log(" center " + externalRootBox.center);
console.log(" halfAxes " + externalRootBox.halfAxes);
//debugger;
});
The output will be
originalChildBox:
center (2.3283064365387e-10, -0.113443724578246, 3.57330994307995)
halfAxes (2843.42474428168, 0, 0)
(0, 3179.80389127671, 0)
(0, 0, 15.5025072079152)
transformed:
center (-2179756.7235751543, 4389408.229815634, 4068278.332300388)
halfAxes (-2546.6958814336103, 903.3385461820669, -5.305326306015831)
(-1264.6755963022426, -1819.0661398295, 10.683413748708821)
(5.919066787294536e-14, 2446.657032950468, 9.901813631454507)
externalRootBox:
center (-2179756.7235751543, 4389408.229815634, 4068278.332300388)
halfAxes (-2546.6958814336103, 903.3385461820669, -5.305326306015831)
(-1264.6755963022426, -1819.0661398295, 10.683413748708821)
(5.919066787294536e-14, 2446.657032950468, 9.901813631454507)
The originalChildBox
is the bounding box that was given in the tileset_1_1_0.json
file. This bounding box is transformed with T0 * T1
(which are the transforms from tileset.json
and tileset_1_1_0.json
, respectively). The result is equal to the bounding box that is obtained directly from the external tileset root, after it was loaded with CesiumJS.
So usually, the bounding box of a single child eventually should be T0*T1*B1
.
(It becomes trickier whe this does not only involve a bounding box, but also regions or spheres (or just multiple bounding boxes). But the overall idea of spatial consistency can be maintained there as well)
According to 3dtiles-spec: An additional tile transform may be applied to transform a tile's local coordinate system to the parent tile's coordinate system.
I know how to calculate transform:
Howerer, how to calculate coordinate with 'transform' and 'boundingVolume:box'?
tileset.json: {"asset": {"version": "1.0"}, "geometricError": 1319.96566351801, "root": { "boundingVolume": { "box": [ 1.04773789644241e-9, -0.504322739783674, -0.616247923113406, 5641.31597575976, 0, 0, 0, 6311.33777747117, 0, 0, 0, 25.8459681412205] }, "children": [ { "boundingVolume": { "box": [ 2797.89169446776, -3133.07355675142, 12.5403080463512, 2843.42428129305, 0, 0, 0, 3180.84259900837, 0, 0, 0, 15.1854221645246 ]}, "content": {"url": "tileset_1_1_0.json"}, "geometricError": 164.995707939751, "refine": "REPLACE" }] "geometricError": 329.991415879503, "refine": "REPLACE", "transform": [ -0.895897517499185, -0.444260777177997, 0, 0, 0.283927872032897, -0.572569735547873, 0.769122136866122, 0, -0.341690798268945, 0.689054613072027, 0.639101821764334, 0, -2176357.29229105, 4388848.16197401, 4070680.03399528, 1 ] } }
tileset_1_1_0.json: {"asset": {"version": "1.0"}, "root": { "boundingVolume": { "box": [ 2.3283064365387e-10, -0.113443724578246, 3.57330994307995, 2843.42474428168, 0, 0, 0, 3179.80389127671, 0, 0, 0, 15.5025072079152] }, "children": [], "content": {"url": "1/1/0.b3dm"}, "geometricError": 164.995707939751, "refine": "REPLACE", "transform": [ 0.999999837172188, 0.00036471139259886, -0.000438909100338114, 0, -0.000364495423816037, 0.999999812521052, 0.000492037546955482, 0, 0.000439088469750899, -0.000491877486479553, 0.999999782628903, 0, 2796.72426339705, -3132.95792494155, 8.96653714217246, 1] } }
How to calculate children'box of tileset.json according to tileset_1_1_0.json? By the way, I have tried
children:box
of tileset.json not equal toT0*T1*B1
.