Why change primitive ellipsoid's position failing?

I used EllipsoidGeometry and EllipsoidOutlineGeometry to create ellipsoids with outline like Entity did. I found that when using primitve way to do this, the only way to change the ellipsoid’s position is giving a modelMatrix value to it. however, this dosn’t work. I debuged and found that the ellipsoid’s modelMatrix changed when it is rendered, different to it’s initial value, but appears at the right position, so even I use the same modelMatrix (the initial value) of it, to change it’s position, it won’t work (it not stay, appears at another place). Why this would happen, does cesium do some other things before rendering a primitive ellipsoid? This behaves different to models, when changing model’s matrix, it’s position changes correctly.

the version of the cesium that I using is 1.116

please share code as Sandcastle

const viewer = new Cesium.Viewer(“cesiumContainer”);

const collection = new Cesium.PrimitiveCollection();

const radii = new Cesium.Cartesian3(30000, 15000, 10000);
const position = Cesium.Cartesian3.fromDegrees(104, 31, 50000);
const hpr = Cesium.HeadingPitchRoll.fromDegrees(0, 0, 0);
const modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(position, hpr);

const outline = new Cesium.GeometryInstance({
id: “_outline”,
modelMatrix,
geometry: new Cesium.EllipsoidOutlineGeometry({
radii,
stackPartitions: 16,
slicePartitions: 8,
}),
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.AQUAMARINE.withAlpha(0.5)),
},
});

const instance = new Cesium.GeometryInstance({
id: “instance”,
modelMatrix,
geometry: new Cesium.EllipsoidGeometry({
radii,
vertexFormat: Cesium.EllipsoidSurfaceAppearance.VERTEX_FORMAT,
}),
});

const instancePrimitive = new Cesium.Primitive({
asynchronous: false,
geometryInstances: instance,
appearance: new Cesium.EllipsoidSurfaceAppearance({
aboveGround: false,
material: Cesium.Material.fromType(“Color”, {
color: Cesium.Color.AQUAMARINE.withAlpha(0.25),
}),
}),
});

const outlinePrimitive = new Cesium.Primitive({
asynchronous: false,
geometryInstances: outline,
appearance: new Cesium.PerInstanceColorAppearance({
flat: true,
renderState: {
lineWidth: 1,
},
}),
});

collection.add(instancePrimitive);
collection.add(outlinePrimitive);
viewer.scene.primitives.add(collection);
viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(104, 31, 150000) });

setTimeout(() => {
//use the initial modelMatrix,but can’t stay its position
instancePrimitive.modelMatrix = modelMatrix;
outlinePrimitive.modelMatrix = modelMatrix;
viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(90, 61, 7000000) });
}, 10000);

//paste these code to Cesium Sandcastle, then you can see the whole situation

A GeometryInstance can have a modelMatrix. Let it be G.
A Primitive can also have a modelMatrix. Let it be P.
The primitive is finally rendered using multiplied matrix with G and P.
In you code
You set G. Let it be G0
You did not set P. so P will be the Idenity matrix. let it be I
At setTimeout you set P as G0.
So the primitive is rendered with the matrix, G0*G0.

See this Sandcastle

1 Like

Got it, I seemed forget about this, the primitive’s modelMatrix rendering, thanks anyway, this is really helpful.