CesiumGS / 3d-tiles-validator

Validator for 3D Tiles :vertical_traffic_light:
https://cesium.com
Apache License 2.0
428 stars 156 forks source link

load the b3dm file in cesium #20

Closed iWun closed 8 years ago

iWun commented 8 years ago

I have generated a b3dm file by the glbToB3dm tool.How to load the b3dm file in cesium?I have tried many way,but it didn't work. Thanks.

lilleyse commented 8 years ago

You need to build a tileset.json file that points to the b3dm. Check out some of the samples here: https://github.com/AnalyticalGraphicsInc/3d-tiles-samples

iWun commented 8 years ago

@lilleyse thanks for replying.I have studied some samples.But I don't know how to compute the boundingVolume in the tileset.json.Thanks a lot.

lilleyse commented 8 years ago

To start off you can try using a bounding sphere which should by easy to compute if you know the size of your model. The bounding sphere is 4 values: [centerX, centerY, centerZ, radius]. If the model isn't already geographically located, the center values can be 0, 0, 0 but you will most likely need to add a transform to the root node of the tileset, which you can compute with something like:

Cesium.Transforms.headingPitchRollToFixedFrame(Cesium.Cartesian3.fromRadians(longitude, latitude, height), 0.0, 0.0, 0.0);

If it is geographically located, you can ignore the tile transform but the bounding sphere center will need to be computed for the correct geographic position with

Cesium.Cartesian3.fromRadians(longitude, latitude, height)
iWun commented 8 years ago

thanks again

X-DX commented 6 years ago

please anyone tell me how to create a B3DM file only for particular region ? i have only glb file ... so what can i do to get a b3dm file ... and run it on cesium

like in the gltf we can make a objects(buildings) using sketchup tool . like a same way how can I make this objects and create a b3dm file of the particular region . please help.

lilleyse commented 6 years ago

Hi @X-DX, use glbToB3dm to convert the glb to b3dm and then create a tileset.json file. It might look something like this:

{
  "asset": {
    "version": "1.0"
  },
  "geometricError": 70,
  "root": {
    "transform": [
      0.9686356343768792,
      0.24848542777253735,
      0,
      0,
      -0.15986460744966327,
      0.623177611820219,
      0.765567091384559,
      0,
      0.19023226619126932,
      -0.7415555652213445,
      0.6433560667227647,
      0,
      1215011.9317263428,
      -4736309.3434217675,
      4081602.0044800863,
      1
    ],
    "refine": "REPLACE",
    "boundingVolume": {
      "sphere": [
        0,
        0,
        0,
        100
      ]
    },
    "geometricError": 0,
    "content": {
      "url": "root.b3dm"
    }
  }
}

If you want to change the location you can edit the transform. The Cesium code for generating a transform from longitude, latitude, and height looks like:

var transform = Cesium.Transforms.headingPitchRollToFixedFrame(Cesium.Cartesian3.fromRadians(longitude, latitude, height), new Cesium.HeadingPitchRoll());
var array = Cesium.Matrix4.toArray(transform);
console.log(array);
anirbansarkar823 commented 6 years ago

@lilleyse I have implemented the same code, for json file, after changing the transform matrix values, but still unable to get a view of the building on the cesium world terrain. Can you help me out in this matter?? a.txt

{ "asset": { "version": "1.0", "tilesetVersion":"1.0" }, "geometricError": 70, "root": { "transform": [0.7222528728192751, -0.6916290824598862, 0, 0, 0.3561308576607826, 0.3718995362807215, 0.8572406588210686, 0, -0.592892570307724, -0.6191445285310049, 0.5149159667984867, 0, -3784971.104011333, -3952561.1671609846, 3265170.1059846953, 1], "refine": "ADD", "boundingVolume": { "sphere": [ 0, 0, 0, 100 ] }, "geometricError": 10, "content": { "url": "nesac_building.b3dm" } } }

this was my code for the json

the below is my b3dm file nesac_building.zip

lilleyse commented 6 years ago

Hey @anirbansarkar823, try using the tileset.json posted above: https://github.com/AnalyticalGraphicsInc/3d-tiles-tools/issues/20#issuecomment-397819356

{
  "asset": {
    "version": "1.0"
  },
  "geometricError": 70,
  "root": {
    "transform": [
      0.9686356343768792,
      0.24848542777253735,
      0,
      0,
      -0.15986460744966327,
      0.623177611820219,
      0.765567091384559,
      0,
      0.19023226619126932,
      -0.7415555652213445,
      0.6433560667227647,
      0,
      1215011.9317263428,
      -4736309.3434217675,
      4081602.0044800863,
      1
    ],
    "refine": "REPLACE",
    "boundingVolume": {
      "sphere": [
        0,
        0,
        0,
        100
      ]
    },
    "geometricError": 0,
    "content": {
      "url": "root.b3dm"
    }
  }
}

Instead of setting the transform in the tileset.json you can also just set it an runtime. Here's a sample that places the tileset at a longitude and latitude and automatically finds the correct height on the Cesium world terrain.

var terrainProvider = Cesium.createWorldTerrain();
var viewer = new Cesium.Viewer('cesiumContainer', {
    terrainProvider: terrainProvider
});

var tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
    url: 'tileset.json'
}));

tileset.readyPromise.then(function(tileset) {
    var longitude = -64.57048;
    var latitude = -12.19160;
    var cartographic = Cesium.Cartographic.fromDegrees(longitude, latitude);
    var positions = [cartographic];
    Cesium.sampleTerrainMostDetailed(terrainProvider, positions).then(function() {
        // cartographic.height is updated
        var cartesian = Cesium.Cartographic.toCartesian(cartographic);
        var transform = Cesium.Transforms.headingPitchRollToFixedFrame(cartesian, new Cesium.HeadingPitchRoll());
        tileset._root.transform = transform;
        viewer.zoomTo(tileset);
    });
});
intckarl commented 6 years ago

@lilleyse hello I have json files and associated b3dm files, how can i put them into Cesium to display those b3dm models? Thank you

lilleyse commented 6 years ago

Hi @intckarl. You need to host the tileset on a server, for example the server in 3d-tiles-samples.

Then the code for loading a tileset in Cesium would look like:

var viewer = new Cesium.Viewer('cesiumContainer');

var tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
    url : 'http://localhost:8003/localTilesets/tileset.json' // Edit url as needed
}));

viewer.zoomTo(tileset, new Cesium.HeadingPitchRange(0, -0.5, 0));
intckarl commented 6 years ago

@lilleyse Thank you but one more question, please. So the b3dm file is just the model and the json file is the key file to put into Cesium, right? But I still don't understand how exactly to write a json file so it can correctly link to those b3dm models, could you be so kind to tell me?

lilleyse commented 6 years ago

Yeah, that's correct about b3dm and the json file.

If you just have a bunch of b3dm files, the two things you need to do are:

alx696 commented 5 years ago

@lilleyse Thanks very much! Your answer solved my problem. But required Cesium.createWorldTerrain() online. How to make it work offline without cost?

https://raw.githubusercontent.com/alx696/share/master/image/3DTiles%E6%A8%A1%E5%9E%8B%E6%AD%A3%E5%B8%B8%E8%B4%B4%E5%9C%B0.png

https://github.com/AnalyticalGraphicsInc/3d-tiles-tools/issues/20#issuecomment-399687836

Before that, my code:

      tileset.readyPromise
          .then((tileset) => {
            let boundingSphere = tileset.boundingSphere;
            let centerCartographic = Cesium.Cartographic.fromCartesian(boundingSphere.center);
            let centerCartesian3 = Cesium.Cartesian3.fromRadians(centerCartographic.longitude, centerCartographic.latitude, 0);
            let realPlaceCartesian3 = Cesium.Cartesian3.fromDegrees(114.4875, 30.4809, 0);
            let translationCartesian3 = Cesium.Cartesian3.subtract(realPlaceCartesian3, centerCartesian3, new Cesium.Cartesian3());
            tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translationCartesian3);

            viewer.zoomTo(tileset);
          });

The model Rotation was wrong. I have try lot, but not work.

https://raw.githubusercontent.com/alx696/share/master/image/3DTiles%E6%A8%A1%E5%9E%8B%E5%BC%82%E5%B8%B8%E7%BF%BB%E8%BD%AC-1.png

https://raw.githubusercontent.com/alx696/share/master/image/3DTiles%E6%A8%A1%E5%9E%8B%E5%BC%82%E5%B8%B8%E7%BF%BB%E8%BD%AC-2.png

bwyss commented 5 years ago

With this tool you can create b3dm files that include the tileset.json : https://github.com/PrincessGod/objTo3d-tiles

aryanxk02 commented 3 years ago

Hey @lilleyse what exactly does the tileset.json do? I suppose it geographically locates the 3D model on the cesium globe. And how do I exactly create a tileset.json file for any 3D file format (mostly .b3dm, .i3dm, CityGML). Guidance on this is appreciated, Thank You!