ol-cesium icon indicating copy to clipboard operation
ol-cesium copied to clipboard

Support layer opacity for vector points

Open ahocevar opened this issue 10 years ago • 19 comments

See https://github.com/openlayers/ol3-cesium/pull/144#issuecomment-71260965. This adds support for layer opacity on vector points. Layer and style opacity are combined on the billboard level.

ahocevar avatar Jan 29 '15 19:01 ahocevar

@ahocevar, I will look at your code next week when I am back from FOSDEM.

gberaudo avatar Jan 30 '15 08:01 gberaudo

I'm guessing you'll need to define your OL opacity attributes in the Cesium externs to avoid making the compiler angry. Otherwise the approach looks sound to me.

schmidtk avatar Jan 30 '15 23:01 schmidtk

@ahocevar, please see my comments. Your PR only deals with Point geometries; do you plan to implement support for the other kinds of geometries to make it look consistent?

gberaudo avatar Feb 02 '15 10:02 gberaudo

@gberaudo I'll see if I can make this work for other geometry types as well. Points were a lower hanging fruit than the rest though.

ahocevar avatar Feb 02 '15 10:02 ahocevar

@schmidtk:

I'm guessing you'll need to define your OL opacity attributes in the Cesium externs to avoid making the compiler angry.

Did you run git submodule update before building? The ol3 version currently used as submodule already has the layer opacity in the generated externs file.

ahocevar avatar Feb 03 '15 14:02 ahocevar

@gberaudo The primitives are now updated by an ol.core function. I added FIXMEs for switching to Cesium.Color.fromAlpha once we update Cesium again. Making this work for geometry types other than point will be more effort, so I'd appreciate if we can get this in just for points for now.

ahocevar avatar Feb 03 '15 16:02 ahocevar

@ahocevar, I feel it would be better to merge this PR in a dedicated branch of the project until support for all other geometries are added.

Otherwise, it will look strange with only the points opacity changing.

Is it OK for you?

gberaudo avatar Feb 03 '15 17:02 gberaudo

I do not see a way to change the opacity of other geometry types, other than recreating all primitives.

ahocevar avatar Feb 10 '15 15:02 ahocevar

You have to use Primitive#getGeometryInstanceAttributes and modify the color with the new opacity, but keep in mind that function will fail until the primitive is ready to render. We're also not setting the id field on GeometryInstance objects we create in core.js here and here, which we should be doing. That will also cause errors in the uncompiled version.

schmidtk avatar Feb 11 '15 00:02 schmidtk

This is what I tried, but after rendering the geometry instances of all primitives are undefined, so nothing can be changed.

ahocevar avatar Feb 11 '15 16:02 ahocevar

@ahocevar, here is a working Sandcastle example

Cesium.Math.setRandomNumberSeed(1234);
var viewer = new Cesium.Viewer('cesiumContainer');
var scene = viewer.scene;
var primitives = scene.primitives;
var solidWhite = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.WHITE);

var id = 'anid';
var rectangle = Cesium.Rectangle.fromDegrees(-92.0, 20.0, -86.0, 27.0);
var rectangleOutlineInstance = new Cesium.GeometryInstance({
    geometry : new Cesium.RectangleOutlineGeometry({
        rectangle : rectangle
    }),
    attributes : {
        color : solidWhite
    },
    id: id
});


var ro = primitives.add(new Cesium.Primitive({
    geometryInstances : [rectangleOutlineInstance],
    appearance : new Cesium.PerInstanceColorAppearance({
        flat : true,
        translucent : true,
        renderState : {
            lineWidth : Math.min(4.0, scene.maximumAliasedLineWidth)
        }
    })
}));

ro.readyPromise.then(function() {
    var i = 0;
    setInterval(function() {
        var attrs = ro.getGeometryInstanceAttributes(id);
        //var color = attrs.color;
        attrs.color[3] = i;
        attrs.color = attrs.color;
        i = i + 20;
        if (i > 255) {
            i = 0;
        }
    }, 100);
});

gberaudo avatar Feb 12 '15 10:02 gberaudo

I had found a similar example and implemented accordingly. As I said, the problem is that the primitive seems to forget about its geometry instances. I can push my non working code if you want to take a look.

ahocevar avatar Feb 12 '15 11:02 ahocevar

@ahocevar, Cesium deletes the reference to the geometry instances for performance reasons.

As suggested by @schmidtk, we need to set and keep a list of the geometry instance ids.

Please push your code somewhere and I will have a look.

gberaudo avatar Feb 12 '15 11:02 gberaudo

I just saw that we're not assigning an array to geometryInstances, but a single geometry instance. This is the cause of the problem.

ahocevar avatar Feb 12 '15 12:02 ahocevar

I just saw that we're not assigning an array to geometryInstances, but a single geometry instance. This is the cause of the problem.

At least it is part of the problem. The correct approach is probably really to assign ids.

ahocevar avatar Feb 12 '15 12:02 ahocevar

@gberaudo This is my code so far: https://github.com/openlayers/ol3-cesium/commit/3206bf7f174793d183c47946a4e3b5a141802760

ahocevar avatar Feb 12 '15 12:02 ahocevar

Do you know if Cesium uses the geometry instance id for anything other than lookup with getGeometryInstanceAttributes? If not, we can reuse a constant id instead of maintaining a list.

schmidtk avatar Feb 12 '15 18:02 schmidtk

@ahocevar, have a look to https://github.com/gberaudo/ol3-cesium/commit/84f566dc45ddb5c15951faead8ba8ea9f8978e29 for how to modify opacity after the primitive is rendered.

gberaudo avatar Feb 16 '15 09:02 gberaudo

Thanks @gberaudo, that works well. I'll try to complete this pull request when I get to it. Might be a long time from now though.

ahocevar avatar Feb 21 '15 10:02 ahocevar