Accurate Bounding Box for 3D tiles

1. A concise explanation of the problem you’re experiencing.

The boundingsphere for a 3D tiles model is far larger than the actual boundaries the tiles live in. Need an accurate rectangle bounding box.

2. Context. Why do you need to do this? We might know a better way to accomplish your goal.

I’m trying to create a minimap with the orthophoto of the model. I need to give the image overlay the correct bounds.

3. The Cesium version you’re using, your operating system and browser.

latest, Windows 10, latest Chrome

Is this possible? I created a rectangle from the boundingsphere radius, but it was way way larger than the actual space taken up…

Is there anyway to go about calculating this information?

What is the bounding volume type used in your tileset.json? If they are regions you can get the rectangle with tile.contentBoundingVolume.rectangle. If they are boxes you can get the OrientedBoundingBox through tile.contentBoundingVolume.boundingVolume and call Rectangle.fromCartesianArray on its corners.

Let me know if either approach works for you.

hi,i get the orientedboundingbox of the 3dtiles,how can i get the accurate positions of the orientedboundingbox.hope to get your help.
below is the orientedboundingbox i get from the tileset.

  1. OrientedBoundingBox {center: Cartesian3, halfAxes: Matrix3}

  2. center: Cartesian3 {x: -2514943.3899317007, y: 3594509.891580003, z: 4614518.393052126}

  3. halfAxes: Matrix3 {0: -51.71415214854119, 1: -36.18239287479956, 2: 0, 3: 33.50745648929041, 4: -47.890964784826686, 5: 55.19484842836624, 6: -4.9060418502532075, 7: 7.0120236538532295, 8: 9.062468254772591}

  4. proto: Object

Hi @liliulei,

Could you clarify what you mean by the “accurate positions” of the OrientedBoundingBox? Are you asking how to get the positions of corners of the box?

Best reagrds,
Janine

hi @janine ,Thank you very much for your reply. Yes, I want to know the coordinates of the eight corners of the OrientedBoundingBox.I now know that the three column directions of halfaxes are the direction vectors of the three axes of OBB, and the corresponding half length of OBB in the axial direction. I want to know how to calculate the coordinates of the eight corners of OBB based on this. I have obtained an OBB according to (1,1,0), (- 1, - 1,0), (1, - 1,0), (1,1,1), (1, - 1,1), (1, - 1,1), (1, - 1,1), (1, - 1,1), (1, - 1,1), (1,1,1), which is the same as the assumption. But the half axis length of the three axis directions I got from the model I created is not what I imagined. The length, width and height of my model are 134m, 88m and 22m respectively, but the actual halfaxes are not these values. Hope to get your help. thank you very much.

Hi @liliulei,

Suppose I have an OrientedBoundingBox obb. In order to get the eight corners of obb, you would need to do the following:

  1. Identify the three axes in obb.halfAxes. The local x-axis is the first column, i.e. Matrix3.getColumn(obb.halfAxes, 0, new Cartesian3()). The local y-axis is the second column, and so on. We will call these xaxis, yaxis, and zaxis respectively.
  2. To calculate the “backmost, bottom-left” corner (i.e. the corner with (-X, -Y, -Z) in local space), you would need to do obb.center - xaxis - yaxis - zaxis.
  3. To calculate the “frontmost, bottom-right” corner (i.e. (X, -Y, Z)) you need to do obb.center + xaxis - yaxis + zaxis.
  4. And so on.

Best regards,
Janine

hi @janine ,i do as what you say,then i get three points and display them in the cesium viewer.the 1 and the 3 points are the bottom left and up right respectively.the 2 point is the center point. the code and figures are below:
var a =tileset._root._boundingVolume._orientedBoundingBox.halfAxes;

    var center =tileset._root._boundingVolume._orientedBoundingBox.center;

    var x = new Cesium.Cartesian3();

    var y = new Cesium.Cartesian3();

    var z = new Cesium.Cartesian3();

    Cesium.Matrix3.getColumn(a, 0, x);

    Cesium.Matrix3.getColumn(a, 1, y);

    Cesium.Matrix3.getColumn(a, 2, z);

    var temp1 = new Cesium.Cartesian3();

    var temp2 = new Cesium.Cartesian3();

    var temp3 = new Cesium.Cartesian3();

    Cesium.Cartesian3.subtract(center, x, temp1)

    Cesium.Cartesian3.subtract(temp1, y, temp2)

    Cesium.Cartesian3.subtract(temp2, z, temp3)

    console.log(temp3);

    let originPoint2 = new Cesium.Entity({

      id:'ceshi2',

      position: temp3,

      point: {

       color: Cesium.Color.RED,

       pixelSize: 35

    }});

    viewer.entities.add(originPoint2);

    var temp4 = new Cesium.Cartesian3();

    var temp5 = new Cesium.Cartesian3();

    var temp6 = new Cesium.Cartesian3();

    Cesium.Cartesian3.add(center, x, temp4)

    Cesium.Cartesian3.add(temp4, y, temp5)

    Cesium.Cartesian3.add(temp5, z, temp6)

    console.log(temp6);

    let originPoint3 = new Cesium.Entity({

      id:'ceshi3',

      position: temp6,

      point: {

       color: Cesium.Color.RED,

       pixelSize: 35

    }});

    viewer.entities.add(originPoint3);



based on what i have get through the code above,i think i can get a boundingbox as figure below:

but what i want to get is the bouding box as the figure below not the above:

hope to get you help!
Best regards
liliulei

Hi @liliulei,

I apologize for the delayed response. It’s hard to come up with an easy solution. If you could somehow get all of the positions of the mesh, you could call OrientedBoundingBox.fromPoints, but that may not be easily doable.

Unfortunately, this type of problem is better addressed during the tiling process, rather than at runtime. What tiler did you use to generate this tileset? The model tiler in Cesium ion tries to take into account off-center rotations of the model, so perhaps you could retile it there and see if that changes the box.

Best,
Janine

hi @janine .i use the cesium ion to get the tileset.i rotate the axis of the tileset,but i can not changs the box.maybe,i should change the axis of the model before tile it.then i can get the OBB of the model.
below is the figure about the axis of the model and the model.


below is the figure about the OBB of the model.

what you can see is that although i have rotated the model in the cesium ion,but i can rotate the axis of the model.i only can rotate the model itself no the axis of the model.
i tile another model through the cesium ion,whose axis is aligning the model boundary orientation,see the red and the green axis,as below.

you can see the obb of the model as below.

when i rotate the model in the cesium ion,the axis rotate with the model.as below.

also the obb of the model is as the obb of the origin model not rotated.
so i should edit the model in the 3d constructure software to make the axis of the model align the model orientation,so i can get the obb of the model easily.

I can tell you what I did, but I’m not sure it’s applicable to your level of accuracy unfortunately, but it works quite well for, for example, complex and non-uniform terrains and pointclouds (especially of larger sizes).

I iterate through all non-root tilesets, pick the center point and radius (easily available), and then create a new set of coordinates which I use a scattering technique from the center point (for example, 7 points in a circle around that point) at a distance that is logarithmic to the radius of those points (smaller for smaller sizes, larger for larger radiuses, etc.), and then do an inverse hull polygon to trace the final boundery. However, it often means there’s a small distance between the actual edge of the models and this boundry, but playing with the radius logarithmic formulae can cater for some of it. You might even do this as a strating point, and trim that outline polygon by sampling / picking every X distance towards the absolute center, and when you pick from your model (edge) use those. The first part above is fast enough, but with the picking you may need to add a few seconds for the sampling and reorder of the positions.

That’s the best run-time solution I’ve got, and I agree that perhaps the backend rendering process should be able to change things a bit. Not sure how much control you’ve got over it, but if you choose smaller regions for your sub-tilesets, the above method above can get you quite accurate, even without the picking towards the center method.

Cheers,

Alex

1 Like