Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Model pick shaders do not use clipping planes #6184

Closed
bagnell opened this issue Feb 2, 2018 · 5 comments · Fixed by #6201
Closed

Model pick shaders do not use clipping planes #6184

bagnell opened this issue Feb 2, 2018 · 5 comments · Fixed by #6201

Comments

@bagnell
Copy link
Contributor

bagnell commented Feb 2, 2018

The clipping planes code is added to the model render fragment shader but not the pick fragment shader. In the below example, rotate the camera to be level with the clipping plane and pick where one of the towers would be if it wasn't clipped. It will still be highlighted.

// Add a clipping plane, a plane geometry to show the representation of the
// plane, and control the magnitude of the plane distance with the mouse.
// Clipping planes are not currently supported in Internet Explorer.

var viewer = new Cesium.Viewer('cesiumContainer', {
    infoBox: false,
    selectionIndicator: false
});
var scene = viewer.scene;

var clipObjects = ['BIM', 'Point Cloud', 'Instanced', 'Model'];
var viewModel = {
    debugBoundingVolumesEnabled : false,
    edgeStylingEnabled : true,
    exampleTypes : clipObjects,
    currentExampleType : clipObjects[0]
};

var targetY = 0.0;
var planeEntities = [];
var selectedPlane;

// Select plane when mouse down
var downHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
downHandler.setInputAction(function(movement) {
    var pickedObject = scene.pick(movement.position);
    if (Cesium.defined(pickedObject) &&
            Cesium.defined(pickedObject.id) &&
            Cesium.defined(pickedObject.id.plane)) {
        selectedPlane = pickedObject.id.plane;
        selectedPlane.material = Cesium.Color.WHITE.withAlpha(0.05);
        selectedPlane.outlineColor = Cesium.Color.WHITE;
        scene.screenSpaceCameraController.enableInputs = false;
    }
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);

// Release plane on mouse up
var upHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
upHandler.setInputAction(function() {
    if (Cesium.defined(selectedPlane)) {
        selectedPlane.material = Cesium.Color.WHITE.withAlpha(0.1);
        selectedPlane.outlineColor = Cesium.Color.WHITE;
        selectedPlane = undefined;
    }

    scene.screenSpaceCameraController.enableInputs = true;
}, Cesium.ScreenSpaceEventType.LEFT_UP);

// Update plane on mouse move
var moveHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
moveHandler.setInputAction(function(movement) {
    if (Cesium.defined(selectedPlane)) {
        var deltaY = movement.startPosition.y - movement.endPosition.y;
        targetY += deltaY;
    }
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

var scratchPlane = new Cesium.Plane(Cesium.Cartesian3.UNIT_X, 0.0);
function createPlaneUpdateFunction(plane, transform) {
    return function () {
        plane.distance = targetY;
        return Cesium.Plane.transform(plane, transform, scratchPlane);
    };
}

var tileset;
function loadTileset(url) {
    var clippingPlanes = [
        new Cesium.Plane(new Cesium.Cartesian3(0.0, 0.0, -1.0), -100.0)
    ];

    tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
        url : url,
        clippingPlanes : new Cesium.ClippingPlaneCollection({
            planes : clippingPlanes,
            edgeWidth : viewModel.edgeStylingEnabled ? 1.0 : 0.0
        })
    }));

    tileset.debugShowBoundingVolume = viewModel.debugBoundingVolumesEnabled;
    return tileset.readyPromise.then(function() {
        var boundingSphere = tileset.boundingSphere;
        var radius = boundingSphere.radius;

        viewer.zoomTo(tileset, new Cesium.HeadingPitchRange(0.5, -0.2, radius * 4.0));

        for (var i = 0; i < clippingPlanes.length; ++i) {
            var plane = clippingPlanes[i];
            var planeEntity = viewer.entities.add({
                position : boundingSphere.center,
                plane : {
                    dimensions : new Cesium.Cartesian2(radius * 2.5, radius * 2.5),
                    material : Cesium.Color.WHITE.withAlpha(0.1),
                    plane : new Cesium.CallbackProperty(createPlaneUpdateFunction(plane, tileset.modelMatrix), false),
                    outline : true,
                    outlineColor : Cesium.Color.WHITE
                }
            });

            planeEntities.push(planeEntity);
        }
    }).otherwise(function(error) {
        console.log(error);
    });
}

var modelEntityClippingPlanes;
function loadModel(url) {
    var clippingPlanes = [
        new Cesium.Plane(new Cesium.Cartesian3(0.0, 0.0, -1.0), -100.0)
    ];

    modelEntityClippingPlanes = new Cesium.ClippingPlaneCollection({
        planes : clippingPlanes,
        edgeWidth : viewModel.edgeStylingEnabled ? 1.0 : 0.0
    });

    function updateClippingPlanes() {
        return modelEntityClippingPlanes;
    }

    var position = Cesium.Cartesian3.fromDegrees(-123.0744619, 44.0503706, 100.0);
    var heading = Cesium.Math.toRadians(135.0);
    var pitch = 0.0;
    var roll = 0.0;
    var hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
    var orientation = Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
    var entity = viewer.entities.add({
        name : url,
        position : position,
        orientation : orientation,
        model : {
            uri : url,
            scale : 8,
            minimumPixelSize : 100.0,
            clippingPlanes : new Cesium.CallbackProperty(updateClippingPlanes, false)
        }
    });

    viewer.trackedEntity = entity;

    for (var i = 0; i < clippingPlanes.length; ++i) {
        var plane = clippingPlanes[i];
        var planeEntity = viewer.entities.add({
            position : position,
            plane : {
                dimensions : new Cesium.Cartesian2(300.0, 300.0),
                material : Cesium.Color.WHITE.withAlpha(0.1),
                plane : new Cesium.CallbackProperty(createPlaneUpdateFunction(plane, Cesium.Matrix4.IDENTITY), false),
                outline : true,
                outlineColor : Cesium.Color.WHITE
            }
        });

        planeEntities.push(planeEntity);
    }
}

// Power Plant design model provided by Bentley Systems
var bimUrl = Cesium.CesiumIon.createResource(1459, { accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIzNjUyM2I5Yy01YmRhLTQ0MjktOGI0Zi02MDdmYzBjMmY0MjYiLCJpZCI6NDQsImFzc2V0cyI6WzE0NTldLCJpYXQiOjE0OTkyNjQ3ODF9.SW_rwY-ic0TwQBeiweXNqFyywoxnnUBtcVjeCmDGef4' });
var pointCloudUrl = Cesium.CesiumIon.createResource(1460, { accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIyMzk2YzJiOS1jZGFmLTRlZmYtYmQ4MS00NTA3NjEwMzViZTkiLCJpZCI6NDQsImFzc2V0cyI6WzE0NjBdLCJpYXQiOjE0OTkyNjQ3NTV9.oWjvN52CRQ-dk3xtvD4e8ZnOHZhoWSpJLlw115mbQJM' });
var instancedUrl = '../../../Specs/Data/Cesium3DTiles/Instanced/InstancedOrientation/';
var modelUrl = '../../SampleData/models/CesiumAir/Cesium_Air.glb';

bimUrl.then(function(resource) {
    return loadTileset(resource);
});

// Track and create the bindings for the view model
var toolbar = document.getElementById('toolbar');
Cesium.knockout.track(viewModel);
Cesium.knockout.applyBindings(viewModel, toolbar);

Cesium.knockout.getObservable(viewModel, 'currentExampleType').subscribe(function(newValue) {
    reset();

    if (newValue === clipObjects[0]) {
        bimUrl.then(function(resource) {
            return loadTileset(resource);
        });
    } else if (newValue === clipObjects[1]) {
        pointCloudUrl.then(function(resource) {
            return loadTileset(resource);
        }).then(function() {
            tileset.clippingPlanes.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(tileset.boundingSphere.center);
        });
    } else if (newValue === clipObjects[2]) {
        loadTileset(instancedUrl).then(function() {
            tileset.clippingPlanes.modelMatrix = Cesium.Transforms.eastNorthUpToFixedFrame(tileset.boundingSphere.center);
        });
    } else {
        loadModel(modelUrl);
    }
});

Cesium.knockout.getObservable(viewModel, 'debugBoundingVolumesEnabled').subscribe(function(value) {
    if (Cesium.defined(tileset)) {
        tileset.debugShowBoundingVolume = value;
    }
});

Cesium.knockout.getObservable(viewModel, 'edgeStylingEnabled').subscribe(function(value) {
    var edgeWidth = value ? 1.0 : 0.0;

    if (Cesium.defined(tileset)) {
        tileset.clippingPlanes.edgeWidth = edgeWidth;
    }

    if (Cesium.defined(modelEntityClippingPlanes)) {
        modelEntityClippingPlanes.edgeWidth = edgeWidth;
    }
});

function reset() {
    viewer.entities.removeAll();
    viewer.scene.primitives.removeAll();
    planeEntities = [];
    targetY = 0.0;
}

// Information about the currently selected feature
    var selected = {
        feature: undefined,
        originalColor: new Cesium.Color()
    };

// Information about the currently highlighted feature
    var highlighted = {
        feature: undefined,
        originalColor: new Cesium.Color()
    };

// An entity object which will hold info about the currently selected feature for infobox display
    var selectedEntity = new Cesium.Entity();

// Color a feature on selection and show metadata in the InfoBox.
    var clickHandler = viewer.screenSpaceEventHandler.getInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
    viewer.screenSpaceEventHandler.setInputAction(function onLeftClick(movement) {
        // If a feature was previously selected, undo the highlight
        if (Cesium.defined(selected.feature)) {
            selected.feature.color = selected.originalColor;
            selected.feature = undefined;
        }

        // Pick a new feature
        var pickedFeature = viewer.scene.pick(movement.position);
        if (!Cesium.defined(pickedFeature)) {
            clickHandler(movement);
            return;
        }

        // Select the feature if it's not already selected
        if (selected.feature === pickedFeature) {
            return;
        }
        selected.feature = pickedFeature;

        // Save the selected feature's original color
        if (pickedFeature === highlighted.feature) {
            Cesium.Color.clone(highlighted.originalColor, selected.originalColor);
            highlighted.feature = undefined;
        } else {
            Cesium.Color.clone(pickedFeature.color, selected.originalColor);
        }

        // Highlight newly selected feature
        pickedFeature.color = Cesium.Color.LIME;

        if (!Cesium.defined(pickedFeature.getProperty)) {
            return;
        }

        // Set feature infobox description
        var featureName = pickedFeature.getProperty('name');
        selectedEntity.name = featureName;
        selectedEntity.description = 'Loading <div class="cesium-infoBox-loading"></div>';
        viewer.selectedEntity = selectedEntity;
        selectedEntity.description = '<table class="cesium-infoBox-defaultTable"><tbody>' +
                                     '<tr><th>BIN</th><td>' + pickedFeature.getProperty('BIN') + '</td></tr>' +
                                     '<tr><th>DOITT ID</th><td>' + pickedFeature.getProperty('DOITT_ID') + '</td></tr>' +
                                     '<tr><th>SOURCE ID</th><td>' + pickedFeature.getProperty('SOURCE_ID') + '</td></tr>' +
                                     '</tbody></table>';
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
@pjcozzi
Copy link
Contributor

pjcozzi commented Feb 7, 2018

Good catch @bagnell, I am surprised we let this through.

@likangning93 do you want to do this as part of your infinite clipping plane/box?

@likangning93
Copy link
Contributor

Verified that this seems to work fine with pointclouds at least.

@likangning93
Copy link
Contributor

Should be fixed with f7d078e

@pjcozzi
Copy link
Contributor

pjcozzi commented Feb 15, 2018

Very nice, thanks!!!

@mramato
Copy link
Contributor

mramato commented Feb 26, 2018

Removing priority next release, this will come in with #6201

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants