cesium icon indicating copy to clipboard operation
cesium copied to clipboard

Cesium3DTileset modelMatrix reset error

Open wonphll536 opened this issue 1 year ago • 6 comments

What happened?

I applied the transformation matrix to Cesium3DTileset and reapplied the initial value, but an error occurred. image

Reproduction steps

  1. Create Cesium3DTeilset
  2. Clone the original modelMatrix
  3. Apply any transformation matrix
  4. Apply original modelMatrix ---> Error occurs after

I applied the above process to Sandcastle. If you wait a while after running, an error will occur.

Sandcastle example

https://sandcastle.cesium.com/#c=tVTfb9MwEP5XrIiHFAUnA/aydRWom8TDEGgrPEVibnJNDY5d2ZeWber/zsV2tmzrHnmomvPd9333y66Mdsi2EnZg2RnTsGNzcLJr+U9/lpZJ5e250SikBlsmGbsvNWNuLWqzcycMbQdZqfeT01KXWgEylAocINlob0N0PCINsRMSB5Xw9+F8Edx8ZU37w6q0hzBWJpzn16LdKDgXKPIn0XnEPHzkUYP/dkaXSU/Rp8RiedxVoIFvrGwlyi04Luo6jZgDgY0yS+A1bHC9AIefGyrf4QKspQ+qoy97jLozpl2YmHmkzYI1ausXELXUzXeJ1fpK6AYigLGCF9nw/a7gxw/GUNbSdLrHXm/WYIFbIuoce8ve8yKEToaS96wSxM9SStbYSZhARaM2CrgyTXpz0TuYMj6ZQeGEvbn3iP2NZ+nHOYhLTU0Tyrf6kmBQ9+272ILGS+mQGmbTVacrlEanI0VklTIafrUCrfxLbYt9+Ortj9x7hynw1tSggisbdy1Gp5Mwp0gsLJrGis1aVo/E89GpX6f+gFxCPx3N83bSzJG2+2Fpgobr7EpU8JTes33w5FfUQKFdpB5nRH3WjcSuhuyQU+DYV4QRjpXNahXuy38VPipeCKMl3j7M6IPqrltSSIVROuQZ6WK7Xq79Iz6dPBd8bTX6MhePyaSjxAL8wNYQS6DzAf0vz1lY9jlF+XcLcCFbMB2mtKhns7Crr7GNt9dz7jN2XBSFvyCT0yRLpg5vFcyG2/pJthtjkXX0itHrhUCvl6Da82VX/SH6yrmQPWPTfAyd1nLLZH124MWlLIRz5Fl1Sl3LOyiT2TSn+BfQeKO/bcEqcduHrY9ml+GQcz7NyTyMRGPUUthnzP8A

Environment

Browser: Chrome CesiumJS Version: 1.117 Operating System: window10

wonphll536 avatar May 28 '24 01:05 wonphll536

(Edit: This was also posted in the forum at https://community.cesium.com/t/cesium3d-tileset-model-matrix-reset-error/32477 )


  • When the transform is modified, then this will cause a call to Cesium3DTile.updateTransform, which updates the bounding volume of the tile by calling createBoundingVolume
  • When the tile defines a region in its bounding volume header, it will create the tile bounding volume by calling createRegion
    • Important: It will pass in the current bounding volume of the tile as the result parameter, to be filled with the data from this region
  • The createRegion function tries to fill the result parameter, assuming that it is a TileBoundingRegion
  • But... when the transform changed, then the createRegion will not return a TileBoundingRegion. Instead, it will return a TileOrientedBoundingBox, by calling createBoxFromTransformedRegion

So to summarize: Changing the transform (by setting the modelMatrix) will convert all TileBoundingRegion into TileOrientedBoundingBox instances. Changing the transform again will trigger the update process, which find the region in the tile, and then assumes that the tile bounding volume is a TileBoundingRegion, even though it was previously changed to be a TileOrientedBoundingBox.

There could be some ... "pragmatic" ... fixes for this, involving some if (result instanceof TileOrientedBoundingBox) doNotTryToFillItWithRegionData(), but the details are to be sorted out...

javagl avatar May 28 '24 15:05 javagl

This could be a one-line fix in the createRegion function in Cesium3DTile. We already check if the transform has been changed, and if so, return a TileOrientedBoundingBox instead of a TileBoundingRegion.

So this:

  if (
    !Matrix4.equalsEpsilon(transform, initialTransform, CesiumMath.EPSILON8)
  ) {
    return createBoxFromTransformedRegion(

could become this:

  if (
    !Matrix4.equalsEpsilon(transform, initialTransform, CesiumMath.EPSILON8) ||
    result instanceof TileOrientedBoundingBox
  ) {
    return createBoxFromTransformedRegion(

jjhembd avatar Jun 05 '24 19:06 jjhembd

I am part of the JTC Flagship program and would like to work on this issue please!

slimkevo avatar Aug 24 '24 01:08 slimkevo

@slimkevo Sounds good!

ggetz avatar Aug 26 '24 14:08 ggetz

@ggetz Hello, I wanted some feedback on whether this is an appropriate way to update and reload a 3D tileset in Cesium.

const viewer = new Cesium.Viewer("cesiumContainer", {
  shadows: true,
});

let tileset;
try {
  tileset = await Cesium.Cesium3DTileset.fromUrl(
    "../SampleData/Cesium3DTiles/Tilesets/Tileset/tileset.json"
  );
  viewer.scene.primitives.add(tileset);
  viewer.scene.globe.depthTestAgainstTerrain = true;
  viewer.zoomTo(
    tileset,
    new Cesium.HeadingPitchRange(
      0.0,
      -0.5,
      tileset.boundingSphere.radius * 2.0
    )
  );
} catch (error) {
  console.log(`Error loading tileset: ${error}`);
}

tileset.initialTilesLoaded.addEventListener(function() {
  const clone_matrix = Cesium.Matrix4.clone(tileset.modelMatrix, new Cesium.Matrix4());
  const cartographic = Cesium.Cartographic.fromCartesian(
    tileset.boundingSphere.center
  );
  const surface = Cesium.Cartesian3.fromRadians(
    cartographic.longitude,
    cartographic.latitude,
    0.0
  );
  const offset = Cesium.Cartesian3.fromRadians(
    cartographic.longitude,
    cartographic.latitude,
    100
  );
  const translation = Cesium.Cartesian3.subtract(
    offset,
    surface,
    new Cesium.Cartesian3()
  );
  const matrix = Cesium.Matrix4.fromTranslation(translation);
  tileset.modelMatrix = matrix;
  
  setTimeout(async () => {
    // Remove the tileset from the scene
    viewer.scene.primitives.remove(tileset);

    // Create a new instance of the tileset
    tileset = await Cesium.Cesium3DTileset.fromUrl(
      "../SampleData/Cesium3DTiles/Tilesets/Tileset/tileset.json"
    );

    // Update the modelMatrix
    tileset.modelMatrix = clone_matrix;

    // Add the new tileset to the scene
    viewer.scene.primitives.add(tileset);
  }, 5000);
});

Could creating a new instance of the tileset every time lead to performance issues?

slimkevo avatar Sep 20 '24 16:09 slimkevo

Hi @slimkevo, is this code snippet intended to reproduce the issue, or to solve the issue?

I would generally not recommend recreating the tileset unless it's for debugging purposes only. Re-creating the tileset could lead to performance impacts and shouldn't be necessary for updating the modelMatrix property.

ggetz avatar Sep 20 '24 17:09 ggetz