1. A concise explanation of the problem you're experiencing:
I'm relatively new at Cesium, and in spite of lots of googling, I'm stuck at this:
For spheres and cylinders I create a geometry (ie Cesium.SphereGeometry), and then a Cesium.GeometryInstance, and then a Cesium.Primitive.
All of this is done without reference to any particular latitude or longitude.
I then position the primitive on the earth as follows:
var position_on_ellipsoid = Cesium.Ellipsoid.WGS84.cartographicToCartesian(Cesium.Cartographic.fromDegrees( longitude,latitude, height ));
var sphere_model_matrix = Cesium.Transforms.eastNorthUpToFixedFrame(position_on_ellipsoid);
primitive.modelMatrix = sphere_model_matrix;
This works well - I can easily re-position a primitive by simply recomputing the modelMatrix without even knowing what the primitive is.
For PolygonGeometry, created through Cesium.PolygonGeometry.fromPositions(), the positions seem to be defined in terms of fixed latitude and longitude. ie
var positions = Cesium.Cartesian3.fromDegreesArrayHeights([
-80.0, 45.0, 0,
-85.0, 45.0, 0,
-85.0, 40.0, 0,
-80.0, 40.0, 0
]);
Using Cesium.PolygonGeometry( { polygonHierarchy : hierarchy}), the positions seems to be in radians relative to an origin at the north pole. A height of zero seems to be the surface of the earth.
Using this (below) to move the primitive at the origin shifts the primitive up by an earth's radius.
var model_matrix = Cesium.Transforms.eastNorthUpToFixedFrame(position_on_ellipsoid);
primitive.modelMatrix = model_matrix;
So to fix things (sort of), I translate the matrix down by the radius of the earth 6371000m (not quite correct I presume because the model used takes into account the non-spherical shape of the earth).
So how can I achieve this better (ie move a polygon byusing modelMatrix), presumably without having to fudge the earths radius? Or at least how can I get the earth's exact radius at a particular latitude and longitude?
2. A minimal code example. If you've found a bug, this helps us reproduce and repair it:
//this runs in the sandcastle. You need to manually zoom in to see the red polygon / box better.
function get_xyz_translation_matrix(x,y,z )
{
var instance_matrix = Cesium.Matrix4.IDENTITY.clone();
instance_matrix[Cesium.Matrix4.COLUMN3ROW0]= x;
instance_matrix[Cesium.Matrix4.COLUMN3ROW1]= y;
instance_matrix[Cesium.Matrix4.COLUMN3ROW2]= z;
return instance_matrix;
}
var viewer = new Cesium.Viewer('cesiumContainer');
var scene = viewer.scene;
var latitude =45;
var longitude =-80;
var height = 0;
var polygon_bottom_height_m = 0;
var polygon_top_height_m = 50000.0;
var x = 10000.0/ 6371000.0;
var y = 20000.0/ 6371000.0;
var z = 0.20 ;
var positions = Cesium.Cartesian3.unpackArray([-x, y, z,
x, y, z,
x, -y, z,
-x, -y, z,
]);
// console.log(JSON.stringify( positions));
var holes = ;
var hierarchy = new Cesium.PolygonHierarchy(positions, holes);
var geometry = new Cesium.PolygonGeometry(
{
polygonHierarchy : hierarchy,
extrudedHeight: polygon_bottom_height_m,
height : polygon_top_height_m,
vertexFormat : Cesium.VertexFormat.POSITION_AND_NORMAL,
perPositionHeight : false
});
var geometry_instance = new Cesium.GeometryInstance(
{
geometry : geometry,
attributes :
{
color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED)
}
});
var primitive = new Cesium.Primitive(
{
geometryInstances : geometry_instance,
appearance : new Cesium.PerInstanceColorAppearance(
{
translucent : true
})
});
var position_on_ellipsoid = Cesium.Ellipsoid.WGS84.cartographicToCartesian(Cesium.Cartographic.fromDegrees( longitude , latitude , height ));
var start_matrix = Cesium.Matrix4.IDENTITY.clone();
var result_matrix= Cesium.Matrix4.IDENTITY.clone();
Cesium.Matrix4.multiply(get_xyz_translation_matrix(0,0,-6371000 ), start_matrix, result_matrix );
start_matrix = result_matrix;
Cesium.Matrix4.multiply(Cesium.Transforms.eastNorthUpToFixedFrame(position_on_ellipsoid), start_matrix, result_matrix );
var model_matrix = result_matrix;
console.log( result_matrix.toString());
primitive.modelMatrix = model_matrix;
scene.primitives.add(primitive );
3. Context. Why do you need to do this? We might know a better way to accomplish your goal:
I am moving spheres and cylinder primitives around nicely by simply setting the primitive.modelMatrix this way. It would make adding polygons much easier if I can move them using primitive.modelMatrix as well, rather than recreate them with new points. I'd like to keep using primitives because the program I am modifying is already based on them
4. The Cesium version you're using, your operating system and browser.
Cesium 1.35, Windows 10 64 bit, Firefox 54.0.1 (32 bit)