CesiumGS / cesium

An open-source JavaScript library for world-class 3D globes and maps :earth_americas:
https://cesium.com/cesiumjs/
Apache License 2.0
12.98k stars 3.5k forks source link

globe.pick() sometimes returns a hit which isn't closest #3423

Open chris-cooper opened 8 years ago

chris-cooper commented 8 years ago

This occurs when geometry is overlapping. The points circled in red are actually obscured by the mountain in front so shouldn't have been picked.

image

I ran this repro from the current Cesium sandcastle with a relatively small window size (as pictured) on Ubuntu Chrome.

var viewer = new Cesium.Viewer('cesiumContainer');
var camera = viewer.camera;
var scene = viewer.scene;
var globe = scene.globe;

var cesiumTerrainProviderMeshes = new Cesium.CesiumTerrainProvider({
    url: '//assets.agi.com/stk-terrain/world',
    requestWaterMask: true,
    requestVertexNormals: true
});
viewer.terrainProvider = cesiumTerrainProviderMeshes;

var target = new Cesium.Cartesian3(-2489625.0836225147, -4393941.44443024, 3882535.9454173897);
var offset = new Cesium.Cartesian3(-6857.40902037546, 412.3284835694358, 2147.5545426812023);
viewer.camera.lookAt(target, offset);
viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);

function runTest() {
    console.log("Running test now!");
    var n = 200;
    for (var y = 0; y <= n; ++y) {
        for (var x = 0; x <= n; ++x) {
            var name = "<" + x + "," + y + ">";
            var windowCoordinates = {
                x: x * window.innerWidth / n + Math.random(),
                y: y * window.innerHeight / n + Math.random()
            };
            var ray = camera.getPickRay(windowCoordinates);
            var intersection = globe.pick(ray, scene);
            if(!Cesium.defined(intersection)){
              continue;
            }

            viewer.entities.add({
                name: name,
                position: intersection,
                billboard: {
                    verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                    scale: 0.3,
                    image: '../images/facility.gif'
                }
            });

        }
    }
}

console.log("Just waiting for terrain to load...");
setTimeout(runTest, 10000);

Possibly related to https://github.com/AnalyticalGraphicsInc/cesium/issues/3411

duvifn commented 7 years ago

You can find the reasons for this behavior here