【问题标题】:Cesium - why is scene.pickPositionSupported false铯 - 为什么scene.pickPositionSupported是假的
【发布时间】:2016-03-21 22:25:48
【问题描述】:

我最终想在我的房子顶部画一个多边形。我能做到。

问题在于,在缩小、放大和旋转(或相机移动)时,多边形不会粘在我家的顶部。我从this answer 那里得到了很大的帮助。所以,现在我正在尝试浏览示例代码,但是我需要学习很多 Cesium 方法和功能。

我试图遵循的示例代码位于the gold standard that appears to be baked into the existing camera controller here

我调用 testMe,mousePosition 为 Cartesian3,SceneMode 为 3D,所以执行 pickGlobe

这是我的代码:

var pickedPosition;
var scratchZoomPickRay = new Cesium.Ray();
var scratchPickCartesian = new Cesium.Cartesian3();
function testMe(mousePosition) {
    if (Cesium.defined(scene.globe)) { 
        if(scene.mode !== Cesium.SceneMode.SCENE2D) {
            pickedPosition = pickGlobe(viewer, mousePosition, scratchPickCartesian);
        } else {
            pickedPosition = camera.getPickRay(mousePosition, scratchZoomPickRay).origin;
        }
    }
}

var pickGlobeScratchRay = new Cesium.Ray();
var scratchDepthIntersection = new Cesium.Cartesian3();
var scratchRayIntersection = new Cesium.Cartesian3();    
function pickGlobe(viewer, mousePosition, result) {

    var globe = scene.globe;
    var camera = scene.camera;

    if (!Cesium.defined(globe)) {
        return undefined;
    }

    var depthIntersection;
    if (scene.pickPositionSupported) {
        depthIntersection = scene.pickPosition(mousePosition, scratchDepthIntersection);
    }

    var ray = camera.getPickRay(mousePosition, pickGlobeScratchRay);
    var rayIntersection = globe.pick(ray, scene, scratchRayIntersection);

    var pickDistance;
    if(Cesium.defined(depthIntersection)) {
        pickDistance = Cesium.Cartesian3.distance(depthIntersection, camera.positionWC);
    } else {
        pickDistance = Number.POSITIVE_INFINITY;
    }

    var rayDistance;
    if(Cesium.defined(rayIntersection)) {
        rayDistance = Cesium.Cartesian3.distance(rayIntersection, camera.positionWC);
    } else {
        rayDistance = Number.POSITIVE_INFINITY;
    }

    var scratchCenterPosition = new Cesium.Cartesian3();
    if (pickDistance < rayDistance) {
        var cart = Cesium.Cartesian3.clone(depthIntersection, result);
        return cart;
    }

    var cart = Cesium.Cartesian3.clone(rayIntersection, result);
    return cart;
}

这是我的问题:

结果如下:

以下是我要让此代码正常工作的问题:

1.如何将 scene.pickPositionSupported 设置为 true? 我在 Windows 10 上使用 Chrome。我在示例代码中找不到任何关于此的内容,而且我对文档或 Google 的运气并不好。

2。为什么 rayIntersection 没有设置? 光线和场景在空的 Cartesian3 中有值和 scratchRayIntersection。

我认为如果我可以让这两个语句正常工作,我可能可以让 pickGlobe 方法的其余部分正常工作。

WebGLGraphics 报告:

我点击了Get WebGL立方体正在旋转!

【问题讨论】:

  • 可以发WebGL Report的截图吗?看起来pickPositionSupported 来自WEBGL_depth_texture。缺少这种扩展是一种阻碍。你有什么3D显卡? Win10 上的 Chrome 49 适合我。
  • 我的 3D 显卡是 Intel(R) HD Graphics 4600。我更新了 Chrome,但不知道如何获取/安装扩展。我将使用 WebGL 报告更新我的问题。
  • Firefox 似乎也不支持它。
  • 嗨,露西小姐,这里有些奇怪。 WEBGL_depth_texture 是一个得到很好支持的扩展,实际上您的 WebGL 报告屏幕截图显示该扩展已在您的系统上启用。根据铯源,这应该直接导致viewer.scene.pickPositionSupported 成为true,因为该路径上没有其他逻辑。我还没有时间深入研究您发布的示例代码,但我想知道您的scene 是否真的不是viewer.scene
  • 另一件要尝试的事情:找到最近的山,用鼠标抓住山顶附近,稍微移动一下。如果您抓取的土地与鼠标指针同步移动,则表示该值为 true 并且深度纹理有效。如果土地迅速从鼠标指针上滑开,这意味着你抓住了椭球体。

标签: javascript cesium


【解决方案1】:

选择位置要求底层 WebGL 实现支持深度纹理,通过 WEBGL_depth_texture 或 WEBKIT_WEBGL_depth_texture 扩展。 scene.pickPositionSupported 返回 false,因为缺少此扩展。您可以通过转到http://webglreport.com/ 并查看扩展列表来验证这一点;我在那里列出了以上两个。您无法在代码本身中做任何事情来使其突然返回 true,这是底层浏览器的反映。

话虽如此,我知道 Chrome 支持深度纹理并且可以在 Windows 10 上运行,所以这听起来可能是显卡驱动程序问题。我完全希望为您的系统下载和安装最新的驱动程序来解决问题。

至于 rayIntersection,通过快速查看您的代码,我只希望在鼠标实际位于地球上时定义它,但情况可能并非总是如此。如果您可以将其简化为可运行的Sandcastle 示例,我将更容易调试。

【讨论】:

  • 显然,我不够聪明,无法弄清楚如何安装扩展。一点帮助?
  • 你误会了,没有安装扩展,完全由浏览器决定。您最好的做法是确保您的视频卡驱动程序是最新的。你能分享 webglreport.com 的输出吗?你用的是什么显卡?
  • 我的 3D 显卡是 Intel(R) HD Graphics 4600,它是最新的。我还更新了 Chrome。我用 WebGL 报告更新了我的问题。
  • Firefox 似乎也不支持它。
【解决方案2】:

好的。所以事实证明我有一个完全混乱的铯环境。我不得不删除它并在我的项目中重新安装它(npm install cesium --save-dev)。然后我不得不修复一些路径,瞧!它奏效了。感谢你们俩的帮助。

【讨论】:

  • 抱歉,我还没有机会回到这个话题,但我真的很高兴你明白了!
猜你喜欢
  • 1970-01-01
  • 2012-04-24
  • 1970-01-01
  • 1970-01-01
  • 2018-07-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-13
  • 2020-02-14
相关资源
最近更新 更多