state of Dojo/CesiumViewerWidget in the batching branch?

Hi,

I wonder what the state of the Dojo/CesiumViewerWidget class in the
batching branch is? In particular, should it be able to handle new types
of (geometry-based) primitives?

I seem to have an issue, with primitives that work with the 'simple'
CesiumWidget, but the very same doesn't work with CesiumViewerWidget.
for example:

    var widget = new CesiumViewerWidget({});
    widget.placeAt('cesiumContainer');
    widget.startup();

    var material = Cesium.Material.fromType(undefined,
Cesium.Material.ColorType);
    material.uniforms.color = new Cesium.Color(1.0, 1.0, 0.0, 0.75);
    var appearance = new Cesium.Appearance({
        renderState : {
            cull : {
                enabled : false
            },
            depthTest : {
                enabled : true
            },
            depthMask : false,
            blending : Cesium.BlendingState.ALPHA_BLEND
        },
        material : material
   });

        var scene = widget.scene;
        var ellipsoid = widget.centralBody.getEllipsoid();
        var primitives = scene.getPrimitives();

        // Create a simple polygon
        var polygon = new Cesium.PolygonGeometry({
            positions : ellipsoid.cartographicArrayToCartesianArray([
                            Cesium.Cartographic.fromDegrees(-72.0, 40.0),
                            Cesium.Cartographic.fromDegrees(-70.0, 35.0),
                            Cesium.Cartographic.fromDegrees(-75.0, 30.0),
                            Cesium.Cartographic.fromDegrees(-70.0, 30.0),
                            Cesium.Cartographic.fromDegrees(-68.0, 40.0)
                        ]),
            pickData : 'polygon1'
        });

        var primitive = new Cesium.Primitive({
            geometries : [ polygon ],
            appearance : appearance
        });
        primitives.add(primitive);

while the above code shows a polygon in a CesiumWidget, nothing is shown
in CesiumViewerWidget :frowning:

what am I doing wrong?

Akos

I looked into this, and it seems there is some mystical issue with
equating Enumerations.

the immediate reason for the Primitive not being rendered is that in the
update() function, the following test returns true:

frameState.mode !== SceneMode.SCENE3D

(which is part of the initial test to render at all), even though
frameState.mode is in fact SCENE3D (all of its properties equal to the
Enumeration definition of SCENE3D when printed out on the browser
JavaScript console)

I wonder what the underlying issue here is.

if I change the above test to:

frameState.mode.valueOf() !== SceneMode.SCENE3D.valueOf()

then this test will pass - but later a BufferUsage.validate() call will
fail - which is again made of checking Enumerations for equality.

this is quite strange. in the very same browser, everything the same but
the widget changed from CesiumViewerWidget to CesiumWidget, all works fine.

this is on Google Chrome / Linux

I seem to have pinpointed the actual location of the error, but I'm
quite clueless as to what causes it.

in the call stack, down until CompositePrimitive.prototype.update(), the
following holds true:

frameState.mode == SceneMode.SCENE3D

and there primitives[i].update(context, frameState, commandList); is
called, which leads to Primitive.prototype.update();

but in Primitive.prototype.update(), for some reason the same statement
is false:

frameState.mode == SceneMode.SCENE3D

moreover, if I send a fourth parameter to update, for example I send
either SceneMode.SCENE3D or SceneMode itself:

primitives[i].update(context, frameState, commandList, SceneMode);

than the value of the fourth parameter will not equal what was sent:

Primitive.prototype.update = function(context, frameState, commandList,
fourth) {
    console.log(fourth === SceneMode);

will display false

this is despite the fact that if I investigate any of these objects,
they seem to be the very same (they have the same properties, same
values for the properties, etc)

it seems as if the SceneMode object that is directly referenced from
Primitive is different than what CompositePrimitive (and above in the
callstack) is seeing.

this sounds very misterious to me :slight_smile:

Hi Ákos, are you by chance using both the Dojo CesiumViewerWidget and the combined Cesium.js in your example? That could cause your issue, because you essentially have two unrelated copies of the Cesium code loaded in the browser at the same time, and the reference equality checks won’t match across the two copies.

Can you post the HTML in your example, including the require syntax where you load the CesiumViewerWidget?

Scott

Hi �kos, are you by chance using both the Dojo CesiumViewerWidget and
the combined Cesium.js in your example? That could cause your issue,
because you essentially have two unrelated copies of the Cesium code
loaded in the browser at the same time, and the reference equality
checks won't match across the two copies.

I see - yes, I was thinking myself that two parallel copies of the same
thing are running

Can you post the HTML in your example, including the require syntax
where you load the CesiumViewerWidget?

sure, the HTML:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Open Aviation Map WebGL viewer</title>
    <script src="dojo-config.js"></script>
    <script
src="lib/ThirdParty/dojo-release-1.8.3-src/dojo/dojo.js"></script>
    <style>
      @import url(bucket.css);
      @import url(lib/Cesium/Widgets/Dojo/CesiumViewerWidget.css);
    </style>
  </head>
<body>
    <div id="cesiumContainer" class="fullSize"></div>
    <div id="loadingOverlay"><h1>Loading...</h1></div>
    <div id="toolbar"></div>
    <script src="main.js"></script>
</body>
</html>

the require in main.js:

require([
    'Cesium/Cesium',
    'Cesium/Widgets/Dojo/CesiumViewerWidget',
    'dojo/io-query',
    'OpenAviationMap',
], function(Cesium,
            CesiumViewerWidget,
            ioQuery,
            OpenAviationMap) {

and dojo-config.js:

var dojoConfig = {
    baseUrl : 'lib',

    // debug config for always refresh
    urlArgs: "v=" + (new Date()).getTime(),

    waitSeconds : 0,

    packages : [{
        name : 'dojo',
        location : 'ThirdParty/dojo-release-1.8.3-src/dojo'
    }, {
        name : 'dijit',
        location : 'ThirdParty/dojo-release-1.8.3-src/dijit'
    }, {
        name : 'Assets',
        location : 'Cesium/Assets'
    }, {
        name : 'Core',
        location : 'Cesium/Core'
    }, {
        name : 'DynamicScene',
        location : 'Cesium/DynamicScene'
    }, {
        name : 'Renderer',
        location : 'Cesium/Renderer'
    }, {
        name : 'Scene',
        location : 'Cesium/Scene'
    }, {
        name : 'Shaders',
        location : 'Cesium/Shaders'
    }, {
        name : 'ThirdParty',
        location : 'Cesium/ThirdParty'
    }, {
        name : 'Widgets',
        location : 'Cesium/Widgets'
    }, {
        name : 'Dojo',
        location : 'Cesium/Widgets/Dojo'
    }, {
        name : 'Workers',
        location : 'Cesium/Workers'
    }, {
        name : 'Cesium',
        location : 'Cesium'

    }, {
        name : 'OpenAviationMap',
        location : 'OpenAviationMap'
    }]
};

OK, it’s not a conflict between the combined Cesium.js, instead the issue is that the modules are available under two different module IDs. ‘Cesium/Cesium’ pulls in ‘Scene/SceneMode’, but ‘Cesium/Widgets/Dojo/CesiumViewerWidget’ pulls in ‘Cesium/Scene/SceneMode’ which is considered a different module.

Change your require call to require:

‘Widgets/Dojo/CesiumViewerWidget’,

instead of:

‘Cesium/Widgets/Dojo/CesiumViewerWidget’,

To further differentiate the ‘Cesium’ helper module that loads all of Cesium, don’t include it as a “package”, instead, use a “path” in the Dojo config to only map that one module.

Remove

{
name : ‘Cesium’,

    location : 'Cesium'

},

from the packages list, and add

paths : {'Cesium/Cesium' : 'Cesium/Cesium'},

to dojoConfig instead. This should prevent accidentally loading two copies of the code under different module IDs.

thanks, this did the trick!
this one didn’t work - as it seems the paths property would somehow
mess up against the baseUrl property
adding

Akos - I am happy that you brought this up. Although I am the original driver - to some extent - behind the current way we do enums, I no longer like it because of problems like this and with cloning (renderstates in particular). I suggest that we remove the Enumeration class and just use numeric values directly in our enum types as the benefits of the Enumeration class just aren’t as useful as they were when I was very new to JavaScript.

Scott, any thoughts?

Patrick

I also want to add that CesiumViewerWidget is going away soon, maybe even this week. We will be replacing it with a “Dojo-less” version that will be part of the combined Cesium.js. This work is being done in the Viewer branch, which I plan to open as a pull request soon.

Scott did you see this question?

Although I am the original driver - to some extent - behind the current way we do enums, I no longer like it because of problems like this and with cloning (renderstates in particular). I suggest that we remove the Enumeration class and just use numeric values directly in our enum types as the benefits of the Enumeration class just aren’t as useful as they were when I was very new to JavaScript.

Scott, any thoughts?

Thanks,

Patrick

I don’t know what problems with renderstate cloning you’re referring to, but in a few places we have Enumerations that are like the more sophisticated Java enums, which associate extra data and functionality with enum values, rather than the primitive C/C++ enums which are purely numeric values.

That said, those places could just as easily use object literals without the Enumeration class.