Right now, the transform
contains a transform (of which I’m not sure where it’s coming from, and) that places the tileset a few meters above the ellipsoid surface (314 meters, specifically).
In order to change that, you can either modify that transform
in the tileset JSON directly, to place the tileset at the surface. Or you can modify that at runtime.
You can modify it at runtime, by setting the tileset.modelMatrix
.
and modelMatrix did not work
The matrix that I showed in the snippet did not fix the issue - it has to be set to the right value, which depends on your data.
To compute that, you can use the following:
// Take the cartesian position
// This is just the last column of the transform matrix
// that is stored in the tileset JSON
const cartesian = new Cesium.Cartesian3(
1476431.750024519, 5240687.803837782, 3311506.67842936);
// Compute the cartographic position
// to obtain the height above the ellipsoid
const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
// Compute the normal at the given cartesian position
const normal = Cesium.Ellipsoid.WGS84.geodeticSurfaceNormal(cartesian);
// Compute the translation that is required to place
// the tileset at the ellipsoid surface
const translation = Cesium.Cartesian3.multiplyByScalar(
normal, -cartographic.height, new Cesium.Cartesian3());
console.log(translation);
Then you can do
tileset.modelMatrix = Cesium.Matrix4.fromTranslation(
translation, new Cesium.Matrix4());
and that should fix it.
Alternatively, you can compute the new transform for the tileset JSON:
const originalTransform = Cesium.Matrix4.fromArray([0.83608746475470763,0.077899201067655882,-0.54303726000438168,0.0,-0.48953783601574752,0.55271892266965517,-0.67442901748954631,0.0,0.2476094876798236,0.82971893252830908,0.50025596909484127,0.0,1476431.7500245189,5240687.8038377818,3311506.67842936,1.0]);
const translationMatrix = Cesium.Matrix4.fromTranslation(
translation, new Cesium.Matrix4());
const newTransformMatrix = Cesium.Matrix4.multiply(translationMatrix, originalTransform, new Cesium.Matrix4());
const newTransform = Cesium.Matrix4.toArray(newTransformMatrix);
console.log(newTransform);
This will print
0.8360874647547076,0.07789920106765588,-0.5430372600043817,0,-0.4895378360157475,0.5527189226696552,-0.6744290174895463,0,0.2476094876798236,0.8297189325283091,0.5002559690948413,0,1476359.118534299,5240429.993773102,3311342.674474269,1
And when you put this into the transform
of the root node of your tileset JSON, then it should appear at the right place.
Unless you are enabling Cesium World Terrain. Then you have to use a different height.