Moving dome

Hi there, I have tried a few solutions to my question and am a bit embaressed by my lack of knowledge in this field, but so keen to learn. I post below the various attempts I made to solve the problem and would be very grateful if someone could please help me to a) solve my problem and b) educate me a bit by answering my various questions or steering me in the direction of where I could begin to educate myself.... Thanks in advance!

CONTEXT: Tracing the path of moving vehicles. Receive new coordinates for the vehicle every two minutes. Vehicle is represented by a billboard. Am successfully moving the billboard with every new plot.

PROBLEM: Now want to focus on a particular vehicle by drawing a transparent dome on top of it and calculating then when any other vehicles are in the dome's radius. But first issue is HOW to move the dome's position???

ATTEMPTED SOLUTIONS: (working via sandcastle, posted the whole thing to make it easier...)
1. Attempted SphereGeometry --> Geometryinstance --> primitive as follows:

require(['Cesium'], function(Cesium) {
    "use strict";
    
    var viewer = new Cesium.Viewer('cesiumContainer');
    var scene = viewer.scene;
    var primitives = scene.primitives;
    var ellipsoid = viewer.centralBody.ellipsoid;
    viewer.centralBody.depthTestAgainstTerrain = true;

    // Create sphere and position with model matrix
    var height = -45000.0;
    var positionOnEllipsoid = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(-100.0, 40.0));
    var spheremodelMatrix = Cesium.Matrix4.multiplyByTranslation(
        Cesium.Transforms.eastNorthUpToFixedFrame(positionOnEllipsoid),
        new Cesium.Cartesian3(0.0, 0.0, height)
    );
    
    var sphereGeometry = new Cesium.SphereGeometry({
        vertexFormat : Cesium.VertexFormat.POSITION_AND_NORMAL,
        position : positionOnEllipsoid,
        radius : 90000.0
    });

    var sphereInstance = new Cesium.GeometryInstance({
        geometry : sphereGeometry,
        modelMatrix : spheremodelMatrix,
        id : 'dome',
        attributes : {
            color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 0.0, 0.0, 0.4))
         }
    });
    
    // Add sphere instance to primitives
    var dome = new Cesium.Primitive({
        geometryInstances : sphereInstance,
        appearance : new Cesium.PerInstanceColorAppearance({
            translucent : true//,
            //closed : true
        })
    });
    
    primitives.add(dome);
     
    function moveDome(scene, primitives, height, position, dome){
        var picked = scene.pick(position);
        if (Cesium.defined(picked)) {
            var prim = picked.primitive;
            var attributes = prim.getGeometryInstanceAttributes('dome');
            attributes.position = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(-102.0, 50.0));
        } else {
            throw new Error('not picked!!.');
        }
   }
    
    Sandcastle.addToolbarButton('moveDome', function() {
        moveDome(scene, primitives, height, positionOnEllipsoid, sphereInstance);
     });

    Sandcastle.finishedLoading();
});

Nope. get the error: Uncaught Error: not picked!!. (on line 51)
(I am passing through a bunch of parameters to the function because of all the various things I tried).
Still passing in the spereInstance I tried the function as:
    function moveDome(scene, primitives, height, position, dome){
        var positionOnEllipsoid = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(-102.0, 50.0));var spheremodelMatrix = Cesium.Matrix4.multiplyByTranslation(
      Cesium.Transforms.eastNorthUpToFixedFrame(positionOnEllipsoid),
      new Cesium.Cartesian3(0.0, 0.0, height)
    );
     //dome.setPosition(ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(-102.0, 50.0)));
     dome.setModel(spheremodelMatrix);
   }

Nope Error: Uncaught TypeError: Object [object Object] has no method 'setModel' (on line 50)
I tried dome.setModelMatrix(spheremodelMatrix); Nope
Then tried passing in the sphereGeometry - same result.
So then HOW do I get hold of the Vertex position and will changing it move the dome??

2. I did the same as above but using ellipsoids. No diff. HOW can one move it? Surely the position is an aspect of the Instance?

3. Then found Tamy's post on moving object where she used an EllipsoidPrimitive. This seems such a quick and elegant solution but!!: EllipsoidPrimitive doesn't obey the depthTestAgainstTerrain = true injunction ... also I actually also need to add an OutlineGeometry.

4. Then investigated a bit on DynamicObject bu didn't go to sandcastle here yet because couldn't find where DynamicEllipsoid has a position either - same problem as 2??

5. Finally, what about the boundingsphere - this has already methods to calculate distances to other objects but is the boundingSphere visible and can I add outline to it?

Lots of questions. Please excuse my ignorance.
Regards
Rencia

Hi Rencia,

You move the sphere by setting the model matrix. There is no ‘setModel’ function, but a ‘modelMatrix’ property. Because the its a sphere, the orientation doesn’t matter. You can change the dome position like this:

dome.modelMatrix = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix4.IDENTITY, cartesianPosition);

-Dan

Hi Dan, thanks. But nope, the sphere just disappears. I actually need a sphereOutline as part of the solution, both just gone. Full cleaned-up sandcastle code:

require(['Cesium'], function(Cesium) {
    "use strict";
    
    var viewer = new Cesium.Viewer('cesiumContainer');
    var scene = viewer.scene;
    var primitives = scene.primitives;
    var ellipsoid = viewer.centralBody.ellipsoid;
    viewer.centralBody.depthTestAgainstTerrain = true;

    // Create sphere are position with model matrix
    var height = -45000.0;
    var positionOnEllipsoid = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(-100.0, 40.0, 0.0));
    var spheremodelMatrix = Cesium.Matrix4.multiplyByTranslation(
        Cesium.Transforms.eastNorthUpToFixedFrame(positionOnEllipsoid),
        new Cesium.Cartesian3(0.0, 0.0, height)
    );

    var sphereGeometry = new Cesium.SphereGeometry({
        vertexFormat : Cesium.VertexFormat.POSITION_AND_NORMAL,
        position : positionOnEllipsoid,
        radius : 90000.0
    });

    var sphereInstance = new Cesium.GeometryInstance({
        geometry : sphereGeometry,
        modelMatrix : spheremodelMatrix,
        id : 'dome',
        attributes : {
            color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 0.0, 0.0, 0.4))
        }
    });
    
    // Add sphere instance to primitives
    var domePrimitive = new Cesium.Primitive({
        geometryInstances : sphereInstance,
        appearance : new Cesium.PerInstanceColorAppearance({
            translucent : true//,
            //closed : true
        })
    });
    
    primitives.add(domePrimitive);
    
    //sphereOutlineGeometry comes here
    var sphereOutlineGeometry = new Cesium.SphereOutlineGeometry({
        radius : 90000.0,
        stackPartitions : 8,
        slicePartitions: 8
    });
    
    var sphereOutlineInstance = new Cesium.GeometryInstance({
        geometry : sphereOutlineGeometry,
        modelMatrix : spheremodelMatrix,
        attributes : {
            color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.WHITE)
        }
    });
  
    var domeOutlinePrimitive = new Cesium.Primitive({
        geometryInstances : sphereOutlineInstance,
        appearance : new Cesium.PerInstanceColorAppearance({
            flat : true,
            renderState : {
                depthTest : {
                    enabled : true
                },
                lineWidth : Math.min(1.0, scene.context.getMaximumAliasedLineWidth())
            }
        })
    });
    
    primitives.add(domeOutlinePrimitive);
    
    function moveDome(sphere, sphereOutline){
        var cartesianPosition = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(-102.0, 50.0, 0.0));

        sphere.modelMatrix = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix4.IDENTITY, cartesianPosition);
        sphereOutline.modelMatrix = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix4.IDENTITY, cartesianPosition);
        
    }
    
    Sandcastle.addToolbarButton('moveDome', function() {
        moveDome(domePrimitive, domeOutlinePrimitive);
     });

    Sandcastle.finishedLoading();
});

I was also trying the EllipsoidGeometry flowing out of Tamy's post where you recommended I try EllipsoidGeometry instead of EllipsePrimitive. Have fed back on that post also.
Many thanks for your help.
R

Hi Dan, I figured I am cluttering up Tamy's post with my queries which are related so add the second solution I tried which resulted from there here as well. Changed to an EllipsoidGeometry as follows:

require(['Cesium'], function(Cesium) {
    "use strict";
    
    var viewer = new Cesium.Viewer('cesiumContainer');
    var scene = viewer.scene;
    var primitives = scene.primitives;
    var ellipsoid = viewer.centralBody.ellipsoid;
    viewer.centralBody.depthTestAgainstTerrain = true;

    var height = 0.0;

    // Create ellipsoid and place with model matrix
    var radii = new Cesium.Cartesian3(90000.0, 90000.0, 90000.0);
    var positionOnEllipsoid = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(-100.0, 40.0, 0.0));
        var modelMatrix = Cesium.Matrix4.multiplyByTranslation(
            Cesium.Transforms.eastNorthUpToFixedFrame(positionOnEllipsoid),
            new Cesium.Cartesian3(0.0, 0.0, height)
        );
    
        var ellipsoidGeometry = new Cesium.EllipsoidGeometry({
            vertexFormat : Cesium.PerInstanceColorAppearance.POSITION_AND_NORMAL,
            position : ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(-100.0, 40.0, 0.0)),
            radii : radii
        });
        var ellipsoidInstance = new Cesium.GeometryInstance({
            geometry : ellipsoidGeometry,
            modelMatrix : modelMatrix,
            id : 'dome',
            attributes : {
                color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 0.0, 0.0, 0.4))
            }
        });
    
    var objeto = new Cesium.EllipsoidPrimitive({
            geometryInstances : ellipsoidInstance,
            appearance : new Cesium.PerInstanceColorAppearance({
                translucent : true
            })
        });
    objeto.center = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(-100.0,40.0, 0.0));
        
    objeto.radii = new Cesium.Cartesian3(90000.0, 90000.0, 90000.0);
    primitives.add(objeto);
    
    //ellipsoidOutlineGeometry comes here
    var ellipsoidOutlineGeometry = new Cesium.EllipsoidOutlineGeometry({
  radii : radii,
  stackPartitions : 8,
  slicePartitions: 8
  });

  var ellipsoidOutlineInstance = new Cesium.GeometryInstance({
        geometry : ellipsoidOutlineGeometry,
        modelMatrix : modelMatrix,
        attributes : {
                      color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.WHITE)
        }
    });
    var outline = new Cesium.Primitive({
        geometryInstances : ellipsoidOutlineInstance,
        appearance : new Cesium.PerInstanceColorAppearance({
            flat : true,
            renderState : {
                depthTest : {
                    enabled : true
                },
                lineWidth : Math.min(1.0, scene.context.getMaximumAliasedLineWidth())
            }
        })
    });
    primitives.add(outline);
    
    function moveDome(objeto, outline){
        objeto.center = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(-102.0, 50.0, 0.0));

        var positionOnEllipsoid = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(-102.0, 50.0, 0.0));
        outline.modelMatrix = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix4.IDENTITY, positionOnEllipsoid);
   }
    
    Sandcastle.addToolbarButton('moveDome', function() {
        moveDome(objeto, outline);
     });

    Sandcastle.finishedLoading();
});

Note: the objeto needs the radii AS WELL otherwise don't see the ellipsoid. Still see the WHOLE ellipsoid, not listening to the depthTest.
Not sure if this is proper - to combine EllipsoidPrimitive with the geometryInstance preceding...
Once I have moved it, the depthTest is still not being honoured.

What to do about the outline?

Thanks so much for being there to help!
Regards
Rencia

Hi Rencia,

When you add a model matrix to a geometry instance, it’s “built-in” to the data for rendering. This is useful when batching multiple instances. For your case with a single geometry instance, you want to set the model matrix on the entire primitive. Otherwise, in moveDome, you would need to transform the geometry back to the identity and then to the new frame.

Here is your modified code from the first example you posted:

require([‘Cesium’], function(Cesium) {

“use strict”;

var viewer = new Cesium.Viewer(‘cesiumContainer’);

var scene = viewer.scene;

var primitives = scene.primitives;

var ellipsoid = viewer.centralBody.ellipsoid;

viewer.centralBody.depthTestAgainstTerrain = true;

// Create sphere are position with model matrix

var height = -45000.0;

var positionOnEllipsoid = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(-100.0, 40.0, 0.0));

var spheremodelMatrix = Cesium.Matrix4.multiplyByTranslation(

Cesium.Transforms.eastNorthUpToFixedFrame(positionOnEllipsoid),

new Cesium.Cartesian3(0.0, 0.0, height)

);

var sphereGeometry = new Cesium.SphereGeometry({

vertexFormat : Cesium.VertexFormat.POSITION_AND_NORMAL,

position : positionOnEllipsoid,

radius : 90000.0

});

var sphereInstance = new Cesium.GeometryInstance({

geometry : sphereGeometry,

//modelMatrix : spheremodelMatrix,

id : ‘dome’,

attributes : {

color : Cesium.ColorGeometryInstanceAttribute.fromColor(new Cesium.Color(1.0, 0.0, 0.0, 0.4))

}

});

// Add sphere instance to primitives

var domePrimitive = new Cesium.Primitive({

geometryInstances : sphereInstance,

appearance : new Cesium.PerInstanceColorAppearance({

translucent : true//,

//closed : true

})

});

domePrimitive.modelMatrix = spheremodelMatrix;

primitives.add(domePrimitive);

//sphereOutlineGeometry comes here

var sphereOutlineGeometry = new Cesium.SphereOutlineGeometry({

radius : 90000.0,

stackPartitions : 8,

slicePartitions: 8

});

var sphereOutlineInstance = new Cesium.GeometryInstance({

geometry : sphereOutlineGeometry,

//modelMatrix : spheremodelMatrix,

attributes : {

color : Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.WHITE)

}

});

var domeOutlinePrimitive = new Cesium.Primitive({

geometryInstances : sphereOutlineInstance,

appearance : new Cesium.PerInstanceColorAppearance({

flat : true,

renderState : {

depthTest : {

enabled : true

},

//lineWidth : Math.min(1.0, scene.context.getMaximumAliasedLineWidth())

}

})

});

domeOutlinePrimitive.modelMatrix = spheremodelMatrix;

primitives.add(domeOutlinePrimitive);

function moveDome(sphere, sphereOutline){

var cartesianPosition = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(-102.0, 50.0, 0.0));

//sphere.modelMatrix = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix4.IDENTITY, cartesianPosition);

//sphereOutline.modelMatrix = Cesium.Matrix4.fromRotationTranslation(Cesium.Matrix4.IDENTITY, cartesianPosition);

var modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(cartesianPosition);

domePrimitive.modelMatrix = modelMatrix;

domeOutlinePrimitive.modelMatrix = modelMatrix;

}

Sandcastle.addToolbarButton(‘moveDome’, function() {

moveDome(domePrimitive, domeOutlinePrimitive);

});

Sandcastle.finishedLoading();

});

I changed the model matrix to be a east-north-up frame because of the outline and I assumed you wanted “north” of the ellipsoid to point out from the ellipsoid’s surface.

Regards,

Dan

WotaStar!!! Thank you very much Dan! Sorted and works.
Regards
Rencia

Hi Dan, back again ... works wonderfully in 3D but morph to 2D and get weird shape, sphere is lost! Help please.. Drawing it correctly is one thing, but then the moving has to be consistent as well in the 2 scenes.

How would you "transform the geometry back to the identity and then to the new frame"?

Regards
Rencia

Hello,
it seems we have similar difficulties in 2D mod ( https://groups.google.com/forum/embed/?place=forum/cesium-dev&showsearch=true&showpopout=true&hideforumtitle=true&parenturl=http%3A%2F%2Fcesiumjs.org%2Fforum.html#!topic/cesium-dev/0J2KnPB5v64 ).
I'm also searching a solution ...

Hi, still struggling with getting the dome to show on the 2D. If the modelmatrix is part of the instance definition then no problem, 2D displays it as a circle - 100%. But when the modelmatrix is assigned to the primitive to enable moving it later, then no go, get a weird triangle across the screen in 2D.
Help please?
Thanks
Rgds
Rencia

Help help! Have upgraded to b28 but still can't get the moving domes to work in 2D. Reminding you guys about this, hoping while you working on the rendering issue for b29 you might address this as well?

Please let me know if there is a solution to this issue.
Thanks!
Regards
Rencia