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.75k stars 3.46k forks source link

pickFromRay or drillPickFromRay Can only be executed once successfully #7759

Open wbhshy opened 5 years ago

wbhshy commented 5 years ago

pickFromRay or drillPickFromRay Can only be executed once successfully, the second time will die in a while loop this is the test code: ` function PointVsibilityAnalysis () { var positions = []; var pointsEntity = []; var vaHandler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); vaHandler.setInputAction(function (movement) { var cartesian = viewer.scene.pickPosition(movement.position); var cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian); var lng = Cesium.Math.toDegrees(cartographic.longitude); var lat = Cesium.Math.toDegrees(cartographic.latitude);

    var height = cartographic.height; 
    height = height < 0 ? 0 : height;
    cartesian = Cesium.Cartesian3.fromDegreesArrayHeights([lng, lat, height])[0];
    var point = viewer.entities.add({
        position: cartesian,
        point: {
            pixelSize: 5,
            color: Cesium.Color.RED,
            outlineColor: Cesium.Color.WHITE,
            outlineWidth: 2,
            heightReference: Cesium.HeightReference.none
        }
    });
    pointsEntity.push(point);
    positions.push(cartesian);
    if (positions.length == 2) {
        vaHandler.destroy();
        vaHandler = null;
        var drillPick = true;
        var obj2Excute = pointsEntity;

        var start = positions[0];
        var end = positions[1];
        var direction = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(end, start, new Cesium.Cartesian3()), new Cesium.Cartesian3());
        var ray = new Cesium.Ray(start, direction);
        var results = [];
        if (drillPick) {
            results = viewer.scene.drillPickFromRay(ray, 10, obj2Excute);
        }
        else {
            var result = viewer.scene.pickFromRay(ray, obj2Excute);
            if (Cesium.defined(result)) {
                results = [result];
            }
        }
        if (results.length != 0) {
            var vEntity = viewer.entities.add({
                position: results[0].position,
                point: {
                    pixelSize: 5,
                    color: Cesium.Color.YELLOW,
                    outlineColor: Cesium.Color.RED,
                    outlineWidth: 1,
                    heightReference: Cesium.HeightReference.none,
                    disableDepthTestDistance: Number.POSITIVE_INFINITY
                }
            });
            positions.splice(1, 0, results[0].position);
            var options = {
                polyline: {
                    show: true,
                    positions: [positions[0], positions[1]],
                    material: Cesium.Color.BLUE,
                    width: 3
                }
            };
            var vBlueEntity = viewer.entities.add(options);
            var options2 = {
                polyline: {
                    show: true,
                    positions: [positions[1], positions[2]],
                    material: Cesium.Color.RED,
                    width: 3
                }
            };
            var vRedEntity = viewer.entities.add(options2);
        }
    }

}, Cesium.ScreenSpaceEventType.LEFT_CLICK);`
OmarShehata commented 5 years ago

Do you mean you're getting an error? Can you put together a minimal Sandcastle example we can run to replicate this problem?

hpinkos commented 5 years ago

@wbhshy If you're picking more than once before the scene renders, you need to call scene.render() before picking again.

If this doesn't fix the issue you're seeing, feel free to re-open this issue with steps to reproduce the issue. Thanks!

lilleyse commented 5 years ago

Pick from ray shouldn't need to call scene.render() between calls. I'm curious to see a Sandcastle demo too. I tried the code above but wasn't sure how to trigger the problem.

wbhshy commented 5 years ago

Pick from ray shouldn't need to call scene.render() between calls. I'm curious to see a Sandcastle demo too. I tried the code above but wasn't sure how to trigger the problem.

@lilleyse

pickfromray.zip

ad you 3dtiles,and click button,select 2 point, the first time is success,and the second time,failed . my english is poor.sorry

gitgitczl commented 5 years ago

I have the same problem.Draw only once.This is my code. `$("#viewFrom").click(function() { var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); handler.setInputAction(function(evt) { handler.destroy(); handler = null; var ray = viewer.camera.getPickRay(evt.position); if (!ray) return; var cartesian = viewer.scene.globe.pick(ray, viewer.scene); viewPoint = createPoint(cartesian, "firstPoint"); }, Cesium.ScreenSpaceEventType.LEFT_CLICK); });

    $("#aimPoint").click(function() {
        var handler2 = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
        handler2.setInputAction(function(evt) { 
            viewer.scene.render();
            var ray = viewer.camera.getPickRay(evt.position);
            if (!ray) return;
            var cartesian = viewer.scene.globe.pick(ray, viewer.scene);
            var aimPoint = createPoint(cartesian, "secondPoint");
            var nowViewP = viewPoint;
            showLine(nowViewP,aimPoint);
            handler2.destroy();
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    });

    function createPoint(cartesian, text) {
        viewer.scene.render();
        return viewer.entities.add({
            position: cartesian,
            point: {
                pixelSize: 5,
                color: Cesium.Color.YELLOW,
                outlineColor: Cesium.Color.RED,
                outlineWidth: 1,
                heightReference: Cesium.HeightReference.none,
            },
            label: {
                disableDepthTestDistance: Number.POSITIVE_INFINITY,
                text: text || ""
            }
        });
    }

    function showLine(p1, p2) {
        if(!p1||!p2) return ;
        var drillPick = true;
        var pointsArr = [];
        pointsArr.push(p1);
        pointsArr.push(p2);
        var start = p1.position.getValue().clone();
        var end = p2.position.getValue().clone();
        var direction = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(end, start, new Cesium.Cartesian3()), new Cesium
            .Cartesian3());
        var ray = new Cesium.Ray(start, direction);
        if(!ray) return ;
        var results = [];
        var obj2Excute = pointsArr;
        if (drillPick) {
            try{
                results = viewer.scene.  (ray, 10, obj2Excute);
            }catch(e){
                console.log(e);
            }
        } else {
            result = viewer.scene.pickFromRay(ray, obj2Excute);
            if (Cesium.defined(result)) {
                results = [result];
            }
        }
        if (results.length != 0) {
            viewer.entities.add({
                position: results[0].position,
                point: {
                    pixelSize: 5,
                    color: Cesium.Color.YELLOW,
                    outlineColor: Cesium.Color.RED,
                    outlineWidth: 1,
                    heightReference: Cesium.HeightReference.none,

                }
            });
            var blueLine = {
                polyline: {
                    show: true,
                    positions: [start, results[0].position],
                    material: Cesium.Color.BLUE,
                    width: 3
                }
            };
            viewer.entities.add(blueLine);
            var redLine = {
                polyline: {
                    show: true,
                    positions: [results[0].position, end],
                    material: Cesium.Color.RED,
                    width: 3
                }
            };
            viewer.entities.add(redLine);

        }
        viewer.scene.render();
    }`

when i draw agin,My browser will crash;

OmarShehata commented 5 years ago

Here is @wbhshy 's code in a Sandcastle from this comment https://github.com/AnalyticalGraphicsInc/cesium/issues/7759#issuecomment-485349765 above. It seems to be made to only work for the first 2 clicks? I'm not sure how to get it to crash.

I haven't run @gitgitczl 's code but it looks like it's creating a new event listener on each click? I wonder if that may be causing issues. Can you post the full text of the crash you get? Or better yet a Sandcastle example (https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/) we can run. You can do this by putting your code there, then clicking "Share" at the top and pasting the link you get here.

wbhshy commented 5 years ago

@OmarShehata @lilleyse this is the Sandcastle example Sandcastle example

liyangis commented 5 years ago

I run your example but it seems ok!

liyangis commented 5 years ago

It happens sometimes ,version 1.60.beyond that,It finds the position of intersection every time

gitgitczl commented 5 years ago

yeah, Now I know the reason.if you use ellipsoid entity ,will not crash,but the results are not accurate.Sometimes no collision point is detected,so i cannot find intersection of model and line.

------------------ 原始邮件 ------------------ 发件人: "liyangis"notifications@github.com; 发送时间: 2019年9月3日(星期二) 下午3:18 收件人: "AnalyticalGraphicsInc/cesium"cesium@noreply.github.com; 抄送: "到重庆 哈哈哈"819576814@qq.com;"Mention"mention@noreply.github.com; 主题: Re: [AnalyticalGraphicsInc/cesium] pickFromRay or drillPickFromRayCan only be executed once successfully (#7759)

It happens sometimes ,version 1.60.beyond that,It finds the position of intersection every time

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

gitgitczl commented 5 years ago

之前是想通过这个方法做线和模型的碰撞检测,后来发现这个方法不准确,有的时候找不到线和模型的交点,明明是有交点的,但是却显示没有,很奇怪。不知道你有没有好的方法做这种类似碰撞检测的功能!

------------------ 原始邮件 ------------------ 发件人: "liyangis"notifications@github.com; 发送时间: 2019年9月3日(星期二) 下午3:18 收件人: "AnalyticalGraphicsInc/cesium"cesium@noreply.github.com; 抄送: ""819576814@qq.com;"Mention"mention@noreply.github.com; 主题: Re: [AnalyticalGraphicsInc/cesium] pickFromRay or drillPickFromRayCan only be executed once successfully (#7759)

It happens sometimes ,version 1.60.beyond that,It finds the position of intersection every time

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

liyangis commented 5 years ago

我只是想做 通视线分析,发现 每次都有交点返回(交点竟然在起点终点连线后面,终点的后面和3dties相交),不准确,这个方法在api里没有,觉得可能还有问题

gitgitczl commented 5 years ago

加个好友吧 qq 819576814 验证 曹志良

------------------ 原始邮件 ------------------ 发件人: "liyangis"notifications@github.com; 发送时间: 2019年9月3日(星期二) 下午3:33 收件人: "AnalyticalGraphicsInc/cesium"cesium@noreply.github.com; 抄送: ""819576814@qq.com;"Mention"mention@noreply.github.com; 主题: Re: [AnalyticalGraphicsInc/cesium] pickFromRay or drillPickFromRayCan only be executed once successfully (#7759)

我只是想做 通视线分析,发现 每次都有交点返回(交点竟然在起点终点连线后面,终点的后面和3dties相交),不准确,这个方法在api里没有,觉得可能还有问题

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

liyangis commented 5 years ago

碰撞检测目前还没有做到,只是发现如果鼠标移动前进的时候是有碰撞检测的,但左右移动的时候没有

DagerD commented 4 years ago

I met similar problem. Is Cesium team working on it? Or maybe there is workaround?

wbhshy commented 4 years ago

I met similar problem. Is Cesium team working on it? Or maybe there is workaround? try ellipse instead point

gitgitczl commented 4 years ago

use ellipsoidGraphic 

------------------ 原始邮件 ------------------ 发件人: "wbhshy"<notifications@github.com>; 发送时间: 2020年4月13日(星期一) 上午9:39 收件人: "CesiumGS/cesium"<cesium@noreply.github.com>; 抄送: "多年以后"<819576814@qq.com>; "Mention"<mention@noreply.github.com>; 主题: Re: [CesiumGS/cesium] pickFromRay or drillPickFromRay Can only be executed once successfully (#7759)

I met similar problem. Is Cesium team working on it? Or maybe there is workaround? try ellipse instead point

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

DagerD commented 4 years ago

I met similar problem. Is Cesium team working on it? Or maybe there is workaround? try ellipse instead point

I didn't understand. That is how i try to use this function:

const ellipsoid = this.cesiumViewer.scene.globe.ellipsoid;
const start = this.getViewer().camera.position;
const end = this.getViewer().camera.pickEllipsoid(new Cesium.Cartesian3(clickedPosition.x, clickedPosition.y), ellipsoid);
const direction = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(end, start, new Cesium.Cartesian3()), new Cesium.Cartesian3());
const ray = new Cesium.Ray(start, direction);
const intersections = this.cesiumViewer.scene.drillPickFromRay(ray);

The infinite loop happens on last string "const intersections =..."

wbhshy commented 4 years ago

I met similar problem. Is Cesium team working on it? Or maybe there is workaround? try ellipse instead point

I didn't understand. That is how i try to use this function:

const ellipsoid = this.cesiumViewer.scene.globe.ellipsoid;
const start = this.getViewer().camera.position;
const end = this.getViewer().camera.pickEllipsoid(new Cesium.Cartesian3(clickedPosition.x, clickedPosition.y), ellipsoid);
const direction = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(end, start, new Cesium.Cartesian3()), new Cesium.Cartesian3());
const ray = new Cesium.Ray(start, direction);
const intersections = this.cesiumViewer.scene.drillPickFromRay(ray);

The infinite loop happens on last string "const intersections =..."

viewer.scene.drillPickFromRay(ray, 10, obj2Excute);
look the code first floor

ggetz commented 1 month ago

Also reported on the forum.